From: user Date: Sun, 13 Aug 2023 23:18:27 +0000 (-0500) Subject: Add Tortoise-Bytecode assembly macros X-Git-Url: https://git.the-white-hart.net/?a=commitdiff_plain;h=cae6f7febe76b13e529dbe527a09c72a54f79152;p=atmega%2Fsiggen.git Add Tortoise-Bytecode assembly macros --- diff --git a/asm_2/interp.asm b/asm_2/interp.asm index 0c16304..e34f2a4 100644 --- a/asm_2/interp.asm +++ b/asm_2/interp.asm @@ -1,5 +1,7 @@ .include "./m328Pdef.inc" +.include "./tbc.inc" + ; ------------------------------------------------------------------------------ ; Registers @@ -104,14 +106,10 @@ ; Bytecode entry: - .dw 0x1106 - .dw 0xbeef - .dw 0xdead - .dw 0x1206 - .dw 0xcafe - .dw 0xbeef - .dw 0x0120 - .dw 0xdff8 + T_MOVI V1, 0xdeadbeef + T_MOVI V2, 0xbeefcafe + T_ADD V1, V2 + T_JMP entry ; ------------------------------------------------------------------------------ @@ -252,7 +250,7 @@ operand_jumptable: rjmp operand_VY_N rjmp operand_VY_N rjmp operand_VY_N - rjmp operand_none + rjmp operand_VY_N rjmp operand_PC_ssNN rjmp operand_PC_sNNN rjmp operand_PC_sNNN diff --git a/asm_2/tbc.inc b/asm_2/tbc.inc new file mode 100644 index 0000000..754481d --- /dev/null +++ b/asm_2/tbc.inc @@ -0,0 +1,706 @@ +; ------------------------------------------------------------------------------ +; Tortoise Bytecode Assembly Macros and Quick Reference +; ------------------------------------------------------------------------------ +; +; Registers: +; +; V0 / TM -- Temporary +; V1 / A0 \ +; V2 / A1 | +; V3 / A2 |_ Argument/Caller-saved +; V4 / A3 | +; V5 / A4 | +; V6 / A5 / +; V7 / S0 \ +; V8 / S1 | +; V9 / S2 |_ Callee-saved +; VA / S3 | +; VB / S4 | +; VC / S5 / +; VD / SP -- Stack Pointer +; VE / RA -- Return Address +; VF / FL -- Flags (---svnzc) +; +; +; Instructions and pseudoinstructions: +; +; T_ADD vx, vy Add T_ADDI vx, imm32 Add +; T_SUB vx, vy Subtract T_SUBI vx, imm32 Subtract +; T_AND vx, vy Logical AND T_ANDI vx, imm32 Logical AND +; T_OR vx, vy Logical OR T_ORI vx, imm32 Logical OR +; T_XOR vx, vy Logical XOR T_XORI vx, imm32 Logical XOR +; T_NOR vx, vy Logical NOR T_NORI vx, imm32 Logical NOR +; T_MOV vx, vy Copy value T_MOVI vx, imm32 Copy value +; T_MUL vx, vy Multiply T_MULI vx, imm32 Multiply +; T_DIV vx, vy Divide T_DIVI vx, imm32 Divide +; T_CMP vx, vy Compare T_CMPI vx, imm32 Compare +; T_TEST vx, vy Test (AND) T_TESTI vx, imm32 Test (AND) +; T_NOT vx Logical NOT T_NEG vx 2's complement +; T_CLR vx Load zero T_NOP Do nothing +; T_ADDS vx, imm4 Add T_SHRL vx, imm4 Log. shift right +; T_SUBS vx, imm4 Subtract T_SHRA vx, imm4 Arith. shift right +; T_MOVS vx, imm4 Copy value T_ROL vx, imm4 Rotate left +; T_SHL vx, imm4 Shift left T_ROR vx, imm4 Rotate right +; +; +; T_LDB vx, vy, n Load 8 [VY+n] T_STB vx, vy, n Store 8 [VY+n] +; T_LDH vx, vy, n Load 16 [VY+n] T_STH vx, vy, n Store 16 [VY+n] +; T_LDW vx, vy, n Load 32 [VY+n] T_STW vx, vy, n Store 32 [VY+n] +; T_LPB vx, vy, n Load ROM 8 [VY+n] +; T_LPH vx, vy, n Load ROM 16 [VY+n] +; T_LPW vx, vy, n Load ROM 32 [VY+n] +; +; +; T_BZ label Branch if zero +; T_BNZ label Branch if not zero +; T_BEQ label Branch if equal +; T_BNE label Branch if not equal +; T_BLT label Branch if less-than (signed) +; T_BGE label Branch if greater-than or equal (signed) +; T_BLO label Branch if lower (unsigned) +; T_BAE label Branch if above or equal (unsigned) +; T_BMI label Branch if minus (negative) +; T_BPL label Branch if plus (zero or positive) +; T_BC label Branch if carry +; T_BNC label Branch if no carry +; T_BV label Branch if overflow +; T_BNV label Branch if no overflow +; +; +; T_JMP label Jump to label +; T_JTAB vx, label Jump to label+VX (V0-V5 only) +; T_JAL label Jump to label, return address in VE/RA +; T_JALR vx, vy Jump to address in VY, return address in VX +; T_JALI vx, imm32 Jump to imm32, return address in VX +; T_EXT label Jump to label and execute as AVR assembly +; (return address in r24:r25) +; +; ------------------------------------------------------------------------------ + + +; ------------------------------------------------------------------------------ +; Variable/register definitions + +.equ V0 = 0x0 +.equ V1 = 0x1 +.equ V2 = 0x2 +.equ V3 = 0x3 +.equ V4 = 0x4 +.equ V5 = 0x5 +.equ V6 = 0x6 +.equ V7 = 0x7 +.equ V8 = 0x8 +.equ V9 = 0x9 +.equ VA = 0xa +.equ VB = 0xb +.equ VC = 0xc +.equ VD = 0xd +.equ VE = 0xe +.equ VF = 0xf + +; Alternate names +.equ TM = V0 +.equ A0 = V1 +.equ A1 = V2 +.equ A2 = V3 +.equ A3 = V4 +.equ A4 = V5 +.equ A5 = V6 +.equ S0 = V7 +.equ S1 = V8 +.equ S2 = V9 +.equ S3 = VA +.equ S4 = VB +.equ S5 = VC +.equ SP = VD +.equ RA = VE +.equ FL = Vf + + +; ------------------------------------------------------------------------------ +; Instruction building macros + + +; ----- Group 0x0, register-register + +.macro T_ADD + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x0 << 12) | (@0 << 8) | (@1 << 4) | (0x0) +.endmacro + +.macro T_SUB + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x0 << 12) | (@0 << 8) | (@1 << 4) | (0x1) +.endmacro + +.macro T_AND + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x0 << 12) | (@0 << 8) | (@1 << 4) | (0x2) +.endmacro + +.macro T_OR + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x0 << 12) | (@0 << 8) | (@1 << 4) | (0x3) +.endmacro + +.macro T_XOR + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x0 << 12) | (@0 << 8) | (@1 << 4) | (0x4) +.endmacro + +.macro T_NOR + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x0 << 12) | (@0 << 8) | (@1 << 4) | (0x5) +.endmacro + +.macro T_MOV + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x0 << 12) | (@0 << 8) | (@1 << 4) | (0x6) +.endmacro + +.macro T_MUL + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x0 << 12) | (@0 << 8) | (@1 << 4) | (0x7) +.endmacro + +.macro T_DIV + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x0 << 12) | (@0 << 8) | (@1 << 4) | (0x8) +.endmacro + +.macro T_CMP + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x0 << 12) | (@0 << 8) | (@1 << 4) | (0x9) +.endmacro + +.macro T_TEST + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x0 << 12) | (@0 << 8) | (@1 << 4) | (0xa) +.endmacro + +.macro T_JALR + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x0 << 12) | (@0 << 8) | (@1 << 4) | (0xf) +.endmacro + +.macro T_NOT + T_NOR @0, @0 +.endmacro + + +; ----- Group 0x1, register-immediate (32-bit) + +.macro T_ADDI + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x1 << 12) | (@0 << 8) | (0 << 4) | (0x0) + .dw LWRD(@1) + .dw HWRD(@1) +.endmacro + +.macro T_SUBI + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x1 << 12) | (@0 << 8) | (0 << 4) | (0x1) + .dw LWRD(@1) + .dw HWRD(@1) +.endmacro + +.macro T_ANDI + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x1 << 12) | (@0 << 8) | (0 << 4) | (0x2) + .dw LWRD(@1) + .dw HWRD(@1) +.endmacro + +.macro T_ORI + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x1 << 12) | (@0 << 8) | (0 << 4) | (0x3) + .dw LWRD(@1) + .dw HWRD(@1) +.endmacro + +.macro T_XORI + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x1 << 12) | (@0 << 8) | (0 << 4) | (0x4) + .dw LWRD(@1) + .dw HWRD(@1) +.endmacro + +.macro T_NORI + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x1 << 12) | (@0 << 8) | (0 << 4) | (0x5) + .dw LWRD(@1) + .dw HWRD(@1) +.endmacro + +.macro T_MOVI + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x1 << 12) | (@0 << 8) | (0 << 4) | (0x6) + .dw LWRD(@1) + .dw HWRD(@1) +.endmacro + +.macro T_MULI + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x1 << 12) | (@0 << 8) | (0 << 4) | (0x7) + .dw LWRD(@1) + .dw HWRD(@1) +.endmacro + +.macro T_DIVI + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x1 << 12) | (@0 << 8) | (0 << 4) | (0x8) + .dw LWRD(@1) + .dw HWRD(@1) +.endmacro + +.macro T_CMPI + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x1 << 12) | (@0 << 8) | (0 << 4) | (0x9) + .dw LWRD(@1) + .dw HWRD(@1) +.endmacro + +.macro T_TESTI + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x1 << 12) | (@0 << 8) | (0 << 4) | (0xa) + .dw LWRD(@1) + .dw HWRD(@1) +.endmacro + +.macro T_JALI + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .dw (0x1 << 12) | (@0 << 8) | (0 << 4) | (0xf) + .dw LWRD(@1) + .dw HWRD(@1) +.endmacro + + +; ----- Group 2, register-immediate (4-bit) + +.macro T_ADDS + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0x0) +.endmacro + +.macro T_SUBS + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0x1) +.endmacro + +.macro T_MOVS + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0x2) +.endmacro + +.macro T_SHL + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0x3) +.endmacro + +.macro T_SHRL + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0x4) +.endmacro + +.macro T_SHRA + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0x5) +.endmacro + +.macro T_ROL + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0x6) +.endmacro + +.macro T_ROR + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0x7) +.endmacro + +.macro T_SPI + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0x9) +.endmacro + +.macro T_MFT + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0xa) +.endmacro + +.macro T_MTT + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0xb) +.endmacro + +.macro T_DIN + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0xc) +.endmacro + +.macro T_DOUT + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0xd) +.endmacro + +.macro T_AIN + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0xe) +.endmacro + +.macro T_AOUT + .if @0 < 0 || @0 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0xf) +.endmacro + +.macro T_NEG + T_NOT @0 + T_ADDS @0, 1 +.endmacro + + +; ----- Groups 3-A,F, Load/store + +.macro T_LDB + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @2 < 0 || @2 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x3 << 12) | (@0 << 8) | (@1 << 4) | (@2) +.endmacro + +.macro T_LDH + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @2 < 0 || @2 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x4 << 12) | (@0 << 8) | (@1 << 4) | (@2) +.endmacro + +.macro T_LDW + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @2 < 0 || @2 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x5 << 12) | (@0 << 8) | (@1 << 4) | (@2) +.endmacro + +.macro T_STB + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @2 < 0 || @2 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x6 << 12) | (@0 << 8) | (@1 << 4) | (@2) +.endmacro + +.macro T_STH + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @2 < 0 || @2 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x7 << 12) | (@0 << 8) | (@1 << 4) | (@2) +.endmacro + +.macro T_STW + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @2 < 0 || @2 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x8 << 12) | (@0 << 8) | (@1 << 4) | (@2) +.endmacro + +.macro T_LPB + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @2 < 0 || @2 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0x9 << 12) | (@0 << 8) | (@1 << 4) | (@2) +.endmacro + +.macro T_LPH + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @2 < 0 || @2 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0xa << 12) | (@0 << 8) | (@1 << 4) | (@2) +.endmacro + +.macro T_LPW + .if @0 < 0 || @0 > 0xf || @1 < 0 || @1 > 0xf + .error "Tortoise Bytecode: invalid variable register" + .endif + .if @2 < 0 || @2 > 0xf + .error "Tortoise Bytecode: immediate value outside 4-bit range" + .endif + .dw (0xf << 12) | (@0 << 8) | (@1 << 4) | (@2) +.endmacro + + +; ----- Group B, branches + +.macro T_JTAB + .if @0 < 0 || @0 > 0x5 + .error "Tortoise Bytecode: invalid variable register (V0-V5 for JTAB)" + .endif + .if (@1-(PC+1)) < -0x80 || (@1-(PC+1)) >= 0x80 + .error "Tortoise Bytecode: branch target out of range" + .endif + .dw (0xb << 12) | (@0 << 8) | (@1-(PC+1)) +.endmacro + +.macro T_BLT + .if (@0-(PC+1)) < -0x80 || (@0-(PC+1)) >= 0x80 + .error "Tortoise Bytecode: branch target out of range" + .endif + .dw (0xb6 << 8) | (@0-(PC+1)) +.endmacro + +.macro T_BGE + .if (@0-(PC+1)) < -0x80 || (@0-(PC+1)) >= 0x80 + .error "Tortoise Bytecode: branch target out of range" + .endif + .dw (0xb7 << 8) | (@0-(PC+1)) +.endmacro + +.macro T_BV + .if (@0-(PC+1)) < -0x80 || (@0-(PC+1)) >= 0x80 + .error "Tortoise Bytecode: branch target out of range" + .endif + .dw (0xb8 << 8) | (@0-(PC+1)) +.endmacro + +.macro T_BNV + .if (@0-(PC+1)) < -0x80 || (@0-(PC+1)) >= 0x80 + .error "Tortoise Bytecode: branch target out of range" + .endif + .dw (0xb9 << 8) | (@0-(PC+1)) +.endmacro + +.macro T_BMI + .if (@0-(PC+1)) < -0x80 || (@0-(PC+1)) >= 0x80 + .error "Tortoise Bytecode: branch target out of range" + .endif + .dw (0xba << 8) | (@0-(PC+1)) +.endmacro + +.macro T_BPL + .if (@0-(PC+1)) < -0x80 || (@0-(PC+1)) >= 0x80 + .error "Tortoise Bytecode: branch target out of range" + .endif + .dw (0xbb << 8) | (@0-(PC+1)) +.endmacro + +.macro T_BZ + .if (@0-(PC+1)) < -0x80 || (@0-(PC+1)) >= 0x80 + .error "Tortoise Bytecode: branch target out of range" + .endif + .dw (0xbc << 8) | (@0-(PC+1)) +.endmacro + +.macro T_BNZ + .if (@0-(PC+1)) < -0x80 || (@0(PC+1)) >= 0x80 + .error "Tortoise Bytecode: branch target out of range" + .endif + .dw (0xbd << 8) | (@0-(PC+1)) +.endmacro + +.macro T_BC + .if (@0-(PC+1)) < -0x80 || (@0-(PC+1)) >= 0x80 + .error "Tortoise Bytecode: branch target out of range" + .endif + .dw (0xbe << 8) | (@0-(PC+1)) +.endmacro + +.macro T_BNC + .if (@0-(PC+1)) < -0x80 || (@0-(PC+1)) >= 0x80 + .error "Tortoise Bytecode: branch target out of range" + .endif + .dw (0xbf << 8) | (@0-(PC+1)) +.endmacro + +.macro T_BEQ + T_BZ @0 +.endmacro + +.macro T_BNE + T_BNZ @0 +.endmacro + +.macro T_BLO + T_BC @0 +.endmacro + +.macro T_BAE + T_BNC @0 +.endmacro + + +; ----- Miscellaneous + +.macro T_JAL + .if (@0-(PC+1)) < -0x800 || (@0-(PC+1)) >= 0x800 + .error "Tortoise Bytecode: jump target out of range" + .endif + .dw (0xc << 12) | ((HIGH(@0-(PC+1))&0x0f) << 8) | LOW(@0-(PC+1)) +.endmacro + +.macro T_JMP + .if (@0-(PC+1)) < -0x800 || (@0-(PC+1)) >= 0x800 + .error "Tortoise Bytecode: jump target out of range" + .endif + .dw (0xd << 12) | ((HIGH(@0-(PC+1))&0x0f) << 8) | LOW(@0-(PC+1)) +.endmacro + +.macro T_EXT + .if @0 < 0 || @0 > 0xfff + .error "Tortoise Bytecode: EXT target out of range" + .endif + .dw (0xe << 12) | (HIGH(@0)&0x0f) | LOW(@0) +.endmacro + +.macro T_CLR + T_XOR @0, @0 +.endmacro + +.macro T_NOP + .dw 0x000E +.endmacro +