From: user Date: Tue, 8 Aug 2023 06:20:36 +0000 (-0500) Subject: Add operand decoding and fix lots of problems X-Git-Url: https://git.the-white-hart.net/?a=commitdiff_plain;h=e26be31c8febb4bedd72139f57b8e6aa4ca88035;p=atmega%2Fsiggen.git Add operand decoding and fix lots of problems --- diff --git a/asm_2/bytecode.txt b/asm_2/bytecode.txt index b08b4b6..dbf48ed 100644 --- a/asm_2/bytecode.txt +++ b/asm_2/bytecode.txt @@ -21,6 +21,7 @@ vf - Flags Instruction encoding: +FXYN v[x], v[y] 0XY0 add 0XY1 sub diff --git a/asm_2/interp.asm b/asm_2/interp.asm index cd808d3..f32ec83 100644 --- a/asm_2/interp.asm +++ b/asm_2/interp.asm @@ -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 @@ -106,7 +106,7 @@ 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: