]> git.the-white-hart.net Git - atmega/siggen.git/commitdiff
Add more instructions
authoruser <none>
Sun, 13 Aug 2023 20:21:01 +0000 (15:21 -0500)
committeruser <none>
Sun, 13 Aug 2023 20:21:01 +0000 (15:21 -0500)
Still have to do div/mod, some IO instructions, and fix flags for some
others.

The encoding should be crystalized enough by now to write macros for
assembling bytecode and start testing on hardware.

asm_2/bytecode.txt
asm_2/interp.asm

index efd5dd9338e3c030a370a78f715bbc1c98830bce..121da15959df7818974969cc712f173f932b2dbf 100644 (file)
@@ -1,21 +1,21 @@
 Bytecode "registers" and calling convention
 
-v0 - Temporary / Return value
+v0 -- Temporary / Return value
 v1 \
 v2 |
-v3 |
-v4 | Arguments / Non-saved
+v3 |_ Arguments / Non-saved
+v4 |
 v5 |
-v6 |
-v7 /
-v8 \
-v9 |
-va | Saved
+v6 /
+v7 \
+v8 |
+v9 |_ Saved
+va |
 vb |
 vc /
-vd - SP
-ve - RA
-vf - Flags
+vd -- SP
+ve -- RA
+vf -- Flags
 
 
 
@@ -87,22 +87,22 @@ FXYN
 AXYn   lph     (program rom load)
 
                pc+sext(nn)
-B0nn   bz
-B1nn   bnz
-B2nn   bgt
-B3nn   blt
-B4nn   blte
-B5nn   bgte
-B6nn   bc
-B7nn   bnc
-B8nn
-B9nn
-BAnn
-BBnn
-BCnn
-BDnn
-BEnn
-BFnn
+B0nn   jtab    v[0], pc+sext(nn) (jump table - jump to v[0]+pc+sext(nn))
+B1nn   jtab    v[1], pc+sext(nn) (jump table - jump to v[1]+pc+sext(nn))
+B2nn   jtab    v[2], pc+sext(nn) (jump table - jump to v[2]+pc+sext(nn))
+B3nn   jtab    v[3], pc+sext(nn) (jump table - jump to v[3]+pc+sext(nn))
+B4nn   jtab    v[4], pc+sext(nn) (jump table - jump to v[4]+pc+sext(nn))
+B5nn   jtab    v[5], pc+sext(nn) (jump table - jump to v[5]+pc+sext(nn))
+B6nn   blt
+B7nn   bge
+B8nn   bv
+B9nn   bnv
+BAnn   bmi
+BBnn   bpl
+BCnn   bz      (also beq)
+BDnn   bnz     (also bne)
+BEnn   bc      (also blo - unsigned below)
+BFnn   bnc     (also bae - unsigned above or equal)
 
 Cnnn   jal     pc+sext(nnn) (implicit VE as link register)
 Dnnn   jmp     pc+sext(nnn)
index 109fa9a0f69bf08286f2dd29678f334ed5ca893a..0c163048cc984e87eb1a8ea0d76970700bbbdeb9 100644 (file)
@@ -460,22 +460,22 @@ imm4_dispatch_jumptable:
        rjmp    exec_aout
 
 branch_dispatch_jumptable:
+       rjmp    exec_jtab
+       rjmp    exec_jtab
+       rjmp    exec_jtab
+       rjmp    exec_jtab
+       rjmp    exec_jtab
+       rjmp    exec_jtab
+       rjmp    exec_blt
+       rjmp    exec_bge
+       rjmp    exec_bv
+       rjmp    exec_bnv
+       rjmp    exec_bmi
+       rjmp    exec_bpl
        rjmp    exec_bz
        rjmp    exec_bnz
-       rjmp    exec_bgt
-       rjmp    exec_blt
-       rjmp    exec_blte
-       rjmp    exec_bgte
-       rjmp    exec_bc
-       rjmp    exec_bnc
-       rjmp    exec_nop
-       rjmp    exec_nop
-       rjmp    exec_nop
-       rjmp    exec_nop
-       rjmp    exec_nop
-       rjmp    exec_nop
-       rjmp    exec_nop
-       rjmp    exec_nop
+       rjmp    exec_c
+       rjmp    exec_nc
 
 
 dispatch_alu:
@@ -830,14 +830,127 @@ _ror_done:
        rjmp    _dispatch_done
 
 
-       ; TODO: I/O instructions
 exec_spi:
+       movw    ZL, r6
+_spi_byte_loop:
+       dec     r10
+       brcs    _spi_done
+       ld      r25, Z
+       out     SPDR, r25
+_spi_wait_loop:
+       in      r25, SPSR
+       sbrs    r25, SPIF
+       rjmp    _spi_wait_loop
+       in      r25, SPDR
+       st      Z+, r25
+       rjmp    _spi_byte_loop
+_spi_done:
+       rjmp    _dispatch_done
+
+
 exec_mft:
 exec_mtt:
+       ; TODO: countdown timer
+       rjmp    _dispatch_done
+
+
 exec_din:
+       ; Read port values
+       in      r24, PINB
+       in      r25, PINC
+
+       ; Shift desired value into LSB
+_din_loop:
+       dec     r10
+       brcs    _din_loop_done
+
+       clc
+       ror     r25
+       ror     r24
+
+       rjmp    _din_loop
+_din_loop_done:
+
+       ; Extract port LSB and put into result LSB
+       andi    r24, 0x01
+       ldi     r25, 0xfe
+       and     r6, r25
+       or      r6, r24
+
+       rjmp    _dispatch_done
+
+
 exec_dout:
+       ; Extract LSB from first operand
+       ldi     r23, 0x01
+       and     r6, r23
+       clr     r7
+
+       ; Mask of all bits except LSB
+       ldi     r24, 0xfe
+       ldi     r25, 0xff
+
+       ; Rotate LSB and mask into position specified by second operand
+_dout_loop:
+       dec     r10
+       brcs    _dout_loop_done
+
+       sec
+       rol     r24
+       rol     r25
+
+       clc
+       rol     r6
+       rol     r7
+
+       rjmp    _dout_loop
+_dout_loop_done:
+
+       ; Read-modify-write
+       in      r22, PORTB
+       in      r23, PORTC
+       and     r22, r24
+       and     r23, r25
+       or      r22, r6
+       or      r23, r7
+       out     PORTB, r22
+       out     PORTC, r23
+
+       rjmp    _dispatch_done
+
+
 exec_ain:
+       ; Set the ADC source
+       lds     r25, ADMUX
+       andi    r25, 0xf0
+       mov     r24, r10
+       andi    r24, 0x0f
+       or      r25, r24
+       sts     ADMUX, r25
+
+       ; Trigger a single conversion
+       lds     r25, ADCSRA
+       ori     r25, (1 << ADSC)
+       sts     ADCSRA, r25
+
+       ; Wait for conversion to complete
+_ain_wait:
+       lds     r25, ADCSRA
+       sbrs    r25, ADIF
+       rjmp    _ain_wait
+       sts     ADCSRA, r25
+
+       ; Read value from ADC
+       lds     r6, ADCL
+       lds     r7, ADCH
+       clr     r8
+       clr     r9
+
+       rjmp    _dispatch_done
+
+
 exec_aout:
+       ; TODO: PWM output
        rjmp    _dispatch_done
 
 
@@ -950,7 +1063,9 @@ exec_stw:
 
 
 exec_ext:
-       ; Return address into temporaries
+       ; Can't use regular call/ret instructions, they take more than 3 cycles
+
+       ; Put the return address into temporaries
        ldi     r24, LOW(_ext_done)
        ldi     r25, HIGH(_ext_done)
 
@@ -961,15 +1076,63 @@ _ext_done:
        rjmp    _dispatch_done
 
 
-       ; TODO: conditional branches
+exec_jtab:
+       add     r10, r6    ; Add V[X] to PC+sext(nn)
+       adc     r11, r7
+       movw    r2, r10
+       rjmp    _dispatch_done
+
+
+exec_blt:
+       sbrc    r14, 4
+       movw    r2, r10    ; Branch if S bit is set
+       rjmp    _dispatch_done
+exec_bge:
+       sbrs    r14, 4
+       movw    r2, r10    ; Branch if S bit is clear
+       rjmp    _dispatch_done
+
+
+exec_bv:
+       sbrc    r14, 3
+       movw    r2, r10    ; Branch if V bit is set
+       rjmp    _dispatch_done
+exec_bnv:
+       sbrs    r14, 3
+       movw    r2, r10    ; Branch if V bit is clear
+       rjmp    _dispatch_done
+
+
+exec_bmi:
+       sbrc    r14, 2
+       movw    r2, r10    ; Branch if N bit is set
+       rjmp    _dispatch_done
+exec_bpl:
+       sbrs    r14, 2
+       movw    r2, r10    ; Branch if N bit is clear
+       rjmp    _dispatch_done
+
+
 exec_bz:
+       sbrc    r14, 1
+       movw    r2, r10    ; Branch if Z bit is set
+       rjmp    _dispatch_done
 exec_bnz:
-exec_bgt:
-exec_blt:
-exec_blte:
-exec_bgte:
-exec_bc:
-exec_bnc:
+       sbrs    r14, 1
+       movw    r2, r10    ; Branch if Z bit is clear
+       rjmp    _dispatch_done
+
+
+exec_c:
+       sbrc    r14, 0
+       movw    r2, r10    ; Branch if C bit is set
+       rjmp    _dispatch_done
+exec_nc:
+       sbrs    r14, 0
+       movw    r2, r10    ; Branch if C bit is clear
+       rjmp    _dispatch_done
+
+
 exec_jmp:
        movw    r2, r10
        rjmp    _dispatch_done