]> git.the-white-hart.net Git - atmega/siggen.git/commitdiff
Add operand decoding and fix lots of problems
authoruser <none>
Tue, 8 Aug 2023 06:20:36 +0000 (01:20 -0500)
committeruser <none>
Tue, 8 Aug 2023 06:20:36 +0000 (01:20 -0500)
asm_2/bytecode.txt
asm_2/interp.asm

index b08b4b623a02d3d19ded598f242994a420f71ee9..dbf48edfdabd96da6f761186f0a90875ea370e56 100644 (file)
@@ -21,6 +21,7 @@ vf - Flags
 
 Instruction encoding:
 
+FXYN
                v[x], v[y]
 0XY0   add
 0XY1   sub
index cd808d302729f45cde936b6765dff28cc69ff87a..f32ec83b14e43cd813e81f02cb7f38098864d145 100644 (file)
@@ -19,7 +19,7 @@
 ; r12  |
 ; r13 h/
 ; r14 ----- New flags register value (VF)
-; r15
+; r15 ----- Saved instruction F field
 ; r16 l\___ Pointer to V[X]
 ; r17 h/
 ; r18
 reset:
        ; ----- Disable interrupts and set stack pointer to top of SRAM
 
-       eor     r25, r25
+       clr     r25
        out     SREG, r25
        ldi     r25, HIGH(RAMEND)
        out     SPH, r25
@@ -120,63 +120,72 @@ reset:
        ; --------------------------------------------------------------
        ; Main loop
 loop:
-       ; Check for pin change interrupt and debounce
+       ; Check for pin change interrupt flag and debounce switches
        ; TODO
 
        ; Fetch instruction
-       movw    ZL, r2
-       lpm     r4, Z+
+       movw    ZL, r2     ; Put bytecode PC into Z
+       lsl     ZL         ; *2 to get a byte address from a word address
+       rol     ZH
+       lpm     r4, Z+     ; Load a word and increment
        lpm     r5, Z+
-       movw    r2, ZL
+       lsr     ZH         ; /2 to get a word address from a byte address
+       ror     ZL
+       movw    r2, ZL     ; Save updated bytecode PC
 
        ; Decode first operand, always register V[X]
-       mov     r16, r5
-       andi    r16, 0x0f
-       lsl     r16
-       lsl     r16
-       ldi     r17, 0x00
+       mov     r24, r5    ; Extract X field from instruction
+       andi    r24, 0x0f
+       lsl     r24        ; *4 to get an offset from an index
+       lsl     r24
+       clr     r25        ; Add offset to base address of registers
        ldi     ZL, LOW(interp_regs)
        ldi     ZH, HIGH(interp_regs)
-       movw    r16, ZL
-       ld      r6, Z+
-       ld      r7, Z+
-       ld      r8, Z+
-       ld      r9, Z+
-
-       ; Decode second operand based on instruction type
-       mov     r10, r5
-       asr     r10
-       asr     r10
-       asr     r10
-       asr     r10
-       eor     r0, r0
+       add     ZL, r24
+       adc     ZH, r25
+       movw    r16, ZL    ; Save the reg addr for use as destination later
+       ldd     r6, Z+0    ; Load operand value
+       ldd     r7, Z+1
+       ldd     r8, Z+2
+       ldd     r9, Z+3
+
+       ; Decode second operand based on instruction F field
+       mov     r24, r5    ; Extract F field from instruction
+       lsr     r24
+       lsr     r24
+       lsr     r24
+       lsr     r24
+       clr     r25        ; Add base address of operand-dispatch jumptable
        ldi     ZL, LOW(operand_jumptable)
        ldi     ZH, HIGH(operand_jumptable)
-       add     ZL, r10
-       adc     ZH, r0
-       ijmp
+       add     ZL, r24
+       adc     ZH, r25
+       mov     r15, r24   ; Save the F field for decoding instruction later
+       ijmp               ; Jump to whatever code decodes the other operand
 _decode_done:
 
-       ; Dispatch based on instruction type
+       ; Dispatch based on instruction F field
+       mov     r24, r15   ; Recover saved F field from instruction
+       clr     r25        ; Add base address of instruction-dispatch jumptable
        ldi     ZL, LOW(f_dispatch_jumptable)
        ldi     ZH, HIGH(f_dispatch_jumptable)
-       eor     r0, r0
-       add     ZL, r10
-       adc     ZH, r0
+       add     ZL, r24
+       adc     ZH, r25
+       ijmp               ; Jump to whatever code runs this type of instruction
 _dispatch_done_writeback_flags:
+       ldi     r24, 0xc3  ; Index of the VF register (0xf * 4)
+       clr     r25        ; Add offset to base address of registers
        ldi     ZL, LOW(interp_regs)
        ldi     ZH, HIGH(interp_regs)
-       ldi     r25, 0x0e*4
-       add     ZL, r25
-       eor     r0, r0
-       adc     ZH, r0
-       st      Z, r14
+       add     ZL, r24
+       adc     ZH, r25
+       st      Z, r14     ; Store the flag byte generated by the instruction
 _dispatch_done_writeback_reg:
-       movw    ZL, r16
-       st      Z+, r6
-       st      Z+, r7
-       st      Z+, r8
-       st      Z+, r9
+       movw    ZL, r16    ; Recover the pointer to V[X]
+       std     Z+0, r6    ; Save the instruction result to the register
+       std     Z+1, r7
+       std     Z+2, r8
+       std     Z+3, r9
 _dispatch_done:
 
        rjmp    loop
@@ -203,30 +212,145 @@ operand_jumptable:
        .dw     operand_none
        .dw     operand_none
 
+
+; ----- V[Y]
 operand_VY:
+       mov     r24, r4
+       andi    r24, 0xf0
+       lsr     r24
+       lsr     r24
+       clr     r25
+       ldi     ZL, LOW(interp_regs)
+       ldi     ZH, HIGH(interp_regs)
+       add     ZL, r24
+       adc     ZH, r25
+       ldd     r10, Z+0
+       ldd     r11, Z+1
+       ldd     r12, Z+2
+       ldd     r13, Z+3
+
        rjmp    _decode_done
 
+
+; ----- 32-bit immediate following instruction
 operand_imm32:
+       movw    ZL, r2     ; Put bytecode PC into Z
+       lsl     ZL         ; *2 to get a byte address from a word address
+       rol     ZH
+       lpm     r10, Z+    ; Load four bytes and increment
+       lpm     r11, Z+
+       lpm     r14, Z+
+       lpm     r13, Z+
+       lsr     ZH         ; /2 to get a word address from a byte address
+       ror     ZL
+       movw    r2, ZL     ; Save updated bytecode PC
+
        rjmp    _decode_done
 
+
+; ----- 4-bit zero-extended immediate within instruction
 operand_Y:
+       mov     r10, r4
+       lsr     r10
+       lsr     r10
+       lsr     r10
+       lsr     r10
+       clr     r11
+       clr     r12
+       clr     r13
+
        rjmp    _decode_done
 
+
+; ----- V[Y] + 4-bit zero-extended immediate within instruction
 operand_VY_N:
-       rjmp    _decode_done
+       ; Load V[Y]
+       mov     r24, r4
+       andi    r24, 0xf0
+       lsr     r24
+       lsr     r24
+       clr     r25
+       ldi     ZL, LOW(interp_regs)
+       ldi     ZH, HIGH(interp_regs)
+       add     ZL, r24
+       adc     ZH, r25
+       ldd     r10, Z+0
+       ldd     r11, Z+1
+       ldd     r12, Z+2
+       ldd     r13, Z+3
+
+       ; Add N
+       mov     r24, r4
+       andi    r24, 0x0f
+       clr     r25
+       add     r10, r24
+       adc     r11, r25
+       adc     r12, r25
+       adc     r13, r25
 
-operand_ssNN:
        rjmp    _decode_done
 
+
+; ----- Zero-extended 12-bit immediate within instruction
 operand_0NNN:
+       movw    r10, r4
+       ldi     r25, 0x0f
+       and     r11, r25
+       clr     r12
+       clr     r13
        rjmp    _decode_done
 
+
+; ----- PC + sign-extended 8-bit immediate within instruction
 operand_PC_ssNN:
+       ; Sign-extend 8-bit immediate
+       mov     r10, r4
+       clr     r11
+       clr     r12
+       clr     r13
+       sbrs    r10, 7
+       rjmp    _sext_done_PCssNN
+       com     r11
+       com     r12
+       com     r13
+_sext_done_PCssNN:
+
+       ; Add PC
+       clr     r25
+       add     r10, r2
+       adc     r11, r3
+       adc     r12, r25
+       adc     r13, r25
+
        rjmp    _decode_done
 
+
+; ----- PC + sign-extended 12-bit immediate within instruction
 operand_PC_sNNN:
+       ; Sign-extend 12-bit immediate
+       movw    r10, r4
+       ldi     r25, 0x0f
+       and     r11, r25
+       clr     r12
+       clr     r13
+       sbrs    r11, 3
+       rjmp    _sext_done_PCsNNN
+       ldi     r25, 0xf0
+       or      r11, r25
+       com     r12
+       com     r13
+_sext_done_PCsNNN:
+
+       ; Add PC
+       clr     r25
+       add     r10, r2
+       adc     r11, r3
+       adc     r12, r25
+       adc     r13, r25
+
        rjmp    _decode_done
 
+
 operand_none:
        rjmp    _decode_done
 
@@ -308,35 +432,36 @@ branch_dispatch_jumptable:
 
 
 dispatch_alu:
+       mov     r24, r4
+       andi    r24, 0x0f
+       clr     r25
        ldi     ZL, LOW(alu_dispatch_jumptable)
        ldi     ZH, HIGH(alu_dispatch_jumptable)
-       mov     r25, r4
-       andi    r25, 0x0f
-       eor     r1, r1
-       add     ZL, r0
-       adc     ZH, r1
+       add     ZL, r24
+       adc     ZH, r25
        ijmp
 
 dispatch_imm4:
+       mov     r24, r4
+       andi    r24, 0x0f
+       clr     r25
        ldi     ZL, LOW(imm4_dispatch_jumptable)
        ldi     ZH, HIGH(imm4_dispatch_jumptable)
-       mov     r25, r4
-       andi    r25, 0x0f
-       eor     r1, r1
-       add     ZL, r0
-       adc     ZH, r1
+       add     ZL, r24
+       adc     ZH, r25
        ijmp
 
 dispatch_branch:
+       mov     r24, r5
+       andi    r24, 0x0f
+       clr     r25
        ldi     ZL, LOW(branch_dispatch_jumptable)
        ldi     ZH, HIGH(branch_dispatch_jumptable)
-       mov     r25, r5
-       andi    r25, 0x0f
-       eor     r1, r1
-       add     ZL, r0
-       adc     ZH, r1
+       add     ZL, r24
+       adc     ZH, r25
        ijmp
 
+
 exec_nop:
 exec_add:
 exec_sub: