update and improve emulator

This commit is contained in:
Redo 2024-08-11 02:39:37 -06:00
parent 5f78ead08b
commit 4ae98df548
53 changed files with 6200 additions and 1434 deletions

View File

@ -1,11 +1,11 @@
-- 8608-definition.lua
-- This file contains the formal definitions for each instruction in the 8608 architecture.
-- It is used by generate-architecture.lua to generate the following:
-- This file contains information about the instruction set and microcode for the 8608 architecture.
-- It is used by generate-architecture.lua, alongside the instruction definitions in 8608-instructions.lua, to generate the following:
-- instructionList.txt, a human-readable list of all instructions.
-- 8608.asm, a set of definitions for CustomAsm that allows it to assemble 8608 programs.
-- The microcode ROM data, which is built into the physical CPU to control it.
return {
local arch8608 = {
-- List of every control line in the CPU
-- Organized by bit position within the four microcode ROMs
@ -14,8 +14,8 @@ roms = {
"alulU", "alulT", "alulC", "alulB", "alulA", "alurIL", "alurIH", "alurVL",
"alurVH", "alurSL", "alurSH", "alurQL", "alurQH", "alurPL", "alurPH", "alurU",
"alurT", "alurC", "alurB", "alurA", "alur1", "alur2", "alurm1", "alurm2",
"adrrhU", "adrrhC", "adrrlT", "adrrTX", "adrrlB", "adrrBX", "adwrhU", "adwrhC",
"adwrlT", "adwrTX", "adwrlB", "adwrBX", "adwlI", "adwlV", "adwlS", "adwlQ",
"adrrhU", "adrrhC", "adrrlT", "adrrTX", "_", "adrr2A", "adwrhU", "adwrhC",
"adwrlT", "adwrTX", "adwrlA", "adwrAX", "adwlI", "adwlV", "adwlS", "adwlQ",
"adwlP", "adrlI", "adrlV", "adrlS", "adrlQ", "adrlP", "aluAdd", "adwSaveV",
"aluRun", "aluRInv", "aluCinOn", "aluCinC", "memWriteAlur", "adrInc", "adwInc", "aluXor",
"aluIor", "aluAnd", "memWriteAlur", "adrOut", "adrSaveI", "adwSaveP", "adwSaveQ", "adwSaveS",
@ -30,7 +30,7 @@ roms = {
"instrNext2", "instrNext1", "instrNext0", "memSaveU", "memSaveT", "memSaveC", "memSaveB", "memSaveA",
} },
{ pos = {66, 16, 0}, size = {32, 32, 32}, signals = {
"adrr1", "adrrm1", "adrrm2", "adrr2", "adwrm1", "adwrm2", "adwr2", "adwr1",
"adrr1", "adrrm1", "adrrm4", "adrr2", "adwrm1", "adwrm2", "adwr2", "adwr1",
"memRead", "memWrite", "runFlgVal", "runFlgClk", "intFlgVal", "intFlgClk", "irqFlgClk", "always1",
"aluShiftArith", "aluShiftRoll", "aluShiftRight", "aluShift", "alurF", "_", "_", "_",
"_", "_", "_", "_", "_", "_", "_", "_",
@ -52,7 +52,7 @@ operations = {
instrSub6 = {"base","instrLoadSub","instrNext2","instrNext1", },
instrSub7 = {"base","instrLoadSub","instrNext2","instrNext1","instrNext0"},
instrSub23Cond = {"base","instrLoadSub","instrNext1"},
instrSwapIV = {"base","adwlI","adwSaveV","adrlV","adrSaveI","loadInstr"},
-- instrSwapIV = {"base","adwlI","adwSaveV","adrlV","adrSaveI","loadInstr"},
instrPreload = {"adrlI","adrInc","adrSaveI","adrOut","memRead","instrLoadSel","instrLoadPre"},
instrNextPre = {"base","instrPre","instrLoad","instrLoadSub"},
@ -70,12 +70,14 @@ operations = {
loadImmedT = {"loadImmed","memSaveT"},
loadImm161 = {"loadImmed","memSaveU"},
loadImm162 = {"loadImmed","memSaveT"},
loadStackRel = {"adrlS","adrrTX","loadReg"},
--loadStackRel = {"adrlS","adrrTX","loadReg"},
loadStackRel = {"adrrlT","loadReg"},
loadStackRelT = {"loadStackRel","memSaveT"},
loadStackRelU = {"loadStackRel","memSaveU"},
loadStackRel161 = {"loadStackRel", "memSaveU"},
loadStackRel162 = {"loadStackRel","adrInc","memSaveT"},
storeStackRel = {"adrlS","adrrTX","storeReg"},
--storeStackRel = {"adrlS","adrrTX","storeReg"},
storeStackRel = {"adrrlT","storeReg"},
storeStackRel161 = {"storeStackRel" },
storeStackRel162 = {"storeStackRel","adrInc"},
storeStackRelU = {"storeStackRel","alurU"},
@ -84,16 +86,18 @@ operations = {
store161 = { "storeReg"},
store162 = {"adrInc","storeReg"},
loadUTU = {"adrrUT", "loadReg","memSaveU"},
loadUTUP = {"adrrUT","adrlP","loadReg","memSaveU"},
loadUTUQ = {"adrrUT","adrlQ","loadReg","memSaveU"},
storeUT = {"adrrUT", "storeReg"},
storeUTP = {"adrrUT","adrlP","storeReg"},
storeUTQ = {"adrrUT","adrlQ","storeReg"},
memSaveFlags = {"memSaveNZ"},
load16FE1 = {"adrrm4","adrr2","load161"},
load16FE2 = {"adrrm4","adrr2","load162"},
load16FC1 = {"adrrm4", "load161"},
load16FC2 = {"adrrm4", "load162"},
adwrUT = {"adwrhU","adwrlT"},
adrrUT = {"adrrhU","adrrlT"},
adwrCB = {"adwrhC","adwrlB"},
-- adwrCB = {"adwrhC","adwrlB"},
adwIncUT = {"adwrUT", "adwInc"},
adwIncUTP = {"adwrUT","adwlP","adwInc"},
adwIncUTQ = {"adwrUT","adwlQ","adwInc"},
@ -104,12 +108,14 @@ operations = {
incQ = {"adwQ","adwInc"},
incP2 = {"adwP","adwr2"},
incQ2 = {"adwP","adwr2"},
saveIV = {"adwlI","adwSaveV"},
jmpRelT = {"instrNext","adrrTX"},
jmpAbs = {"base","loadInstr","adrSaveI"},
jmpAbsUT = {"jmpAbs","adrrUT"},
jmpAbsP = {"jmpAbs","adrlP"},
jmpAbsQ = {"jmpAbs","adrlQ"},
jmpAbsV = {"jmpAbs","adrlV"},
saveRetAddr = {"adwlI","adwInc","adwSaveQ"},
pushRetAddr1 = {"alurIH","pushReg"},
pushRetAddr2 = {"alurIL","pushReg"},
@ -141,294 +147,77 @@ operations = {
"adwSaveP","adwSaveQ","adwSaveS","adwSaveV",
"adrSaveI",
"aluSaveNZ","aluSaveCarry",
}
"intFlgClk",
"irqFlgClk",
"runFlgClk","runFlgVal",
},
},
-- List of definitions for every instruction
-- Each instruction definition contains:
-- Mnemonic: The mnemonic used to generate the assembler definitions and instruction list.
-- This is what must literally appear in the assembly code in order to generate this instruction, other than immediate values.
-- "imm8" means an 8-bit value.
-- "imm16" means a 16-bit value.
-- Opcode: The machine code byte that represents this operation.
-- Used by the assembler generator to map mnemonics to opcodes.
-- Used by the microcode generator to place the instruction's data within the microcode ROM, which is addressed by opcode.
-- List of control signals: Specifies the control lines that will be activated by the microcode when the instruction is executed.
-- Instructions may take multiple clock cycles. To convey this, each clock cycle is represented by an independent list of microcode signals.
-- Under the hood, the microcode ROM uses a 10-bit address: 8 bits for the opcode, and 2 bits for the clock cycle.
-- Because of this, each opcode may only use up to 4 clock cycles.
-- If more are required, the least significant bit of the opcode can be set by a control line, incrementing the opcode.
-- This causes one instruction to use up multiple opcodes.
-- The need for this is determined automatically by the microcode generator: whenever an instruction specifies more than 4 lists of control signals.
-- Description: A brief description of the instruction. Used to generate the instruction list.
-- C Code: Used to generate an emulator (as part of a separate project).
-- Categories can be specified. These serve only to organize the instruction list.
-- The category letter determines what letter will be used to represent the instructions in the opcode map, located at the bottom of the instruction list.
instructions = {
{ category = "Control", catlet="C" },
{ mnem="rst" , opcode=0x00, {"base","intFlgClk","irqFlgClk","runFlgClk","runFlgVal","clearRegs","loadInstr"}, desc="Clear all registers and set I=0", ccode={"cpu.a=0; cpu.b=0; cpu.c=0; cpu.u=0; cpu.t=0; cpu.p=0; cpu.q=0; cpu.s=0; cpu.v=0; cpu.i=0; cpu.cf=0; cpu.nz=0; cpu.irq=0; cpu.ifg=0; cpu.rfg=1; cpu.ien=0; lni;"} },
{ mnem="hlt" , opcode=0xF0, {"runFlgClk","instrNext"}, desc="Halt non-interrupt execution", ccode={"cpu.rfg=0; lni;"} },
{ mnem="run" , opcode=0xF1, {"runFlgClk","runFlgVal","instrNext"}, desc ="Resume non-interrupt execution", ccode={"cpu.rfg=1; lni;"} },
{ mnem="int" , opcode=0xF2, {"instrSwapIV","intFlgVal","intFlgClk","irqFlgClk"}, ccode={"cpu.irq=0; cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=(t-1)%65536; lni;"} },
{ mnem="brk" , opcode=0xF3, {"instrSwapIV","adwInc","intFlgVal","intFlgClk"}, desc="Trigger interrupt", ccode={"cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} },
{ mnem="irt" , opcode=0xF4, {"instrSwapIV","adwInc","intFlgClk"}, desc="Return from interrupt", ccode={"cpu.ifg=0; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} },
{ mnem="nop" , opcode=0xFF, {"instrNext"}, desc="Do nothing", ccode={"lni;"}, },
{ mnem="ien" , opcode=0xF5, {"instrNext"}, desc="Enbale interrupts", ccode={"cpu.ien=1; lni;"}, }, -- todo
{ mnem="idi" , opcode=0xF6, {"instrNext"}, desc="Disable interrupts", ccode={"cpu.ien=0; lni;"}, }, -- todo
{ category = "16-bit Inc/Dec", catlet="I" },
{ mnem="inc p" , opcode=0x12, {"adwlP","adwInc","adwSaveP","instrNext"}, desc="P++", ccode={"cpu.p++; lni;"} },
{ mnem="dec p" , opcode=0x15, {"adwlP","adwrm1","adwSaveP","instrNext"}, desc="P--", ccode={"cpu.p--; lni;"} },
{ mnem="inc q" , opcode=0x13, {"adwlQ","adwInc","adwSaveQ","instrNext"}, desc="Q++", ccode={"cpu.q++; lni;"} },
{ mnem="dec q" , opcode=0x16, {"adwlQ","adwrm1","adwSaveQ","instrNext"}, desc="Q--", ccode={"cpu.q--; lni;"} },
{ category = "8-bit Unary", catlet="U" },
{ mnem="inc a" , opcode=0x10, {"aluA","alur1" ,"aluOpAdd" ,"instrNext"}, desc="A++, set flags" , ccode={"addf(cpu.a, 1 ); lni;"} },
{ mnem="dec a" , opcode=0x11, {"aluA","alurm1","aluOpAdd" ,"instrNext"}, desc="A--, set flags" , ccode={"addf(cpu.a,-1 ); lni;"} },
{ mnem="icc a" , opcode=0x1B, {"aluA", "aluOpAddC","instrNext"}, desc="A+=CF, set flags", ccode={"addf(cpu.a,cpu.cf); lni;"} },
{ mnem="inc b" , opcode=0x19, {"aluB","alur1" ,"aluOpAdd" ,"instrNext"}, desc="B++, set flags" , ccode={"addf(cpu.b, 1 ); lni;"} },
{ mnem="dec b" , opcode=0x1A, {"aluB","alurm1","aluOpAdd" ,"instrNext"}, desc="B--, set flags" , ccode={"addf(cpu.b,-1 ); lni;"} },
{ mnem="icc b" , opcode=0x1C, {"aluB", "aluOpAddC","instrNext"}, desc="B+=CF, set flags", ccode={"addf(cpu.b,cpu.cf); lni;"} },
{ mnem="inc c" , opcode=0x17, {"aluC","alur1" ,"aluOpAdd" ,"instrNext"}, desc="C++, set flags" , ccode={"addf(cpu.c, 1 ); lni;"} },
{ mnem="dec c" , opcode=0x18, {"aluC","alurm1","aluOpAdd" ,"instrNext"}, desc="C--, set flags" , ccode={"addf(cpu.c,-1 ); lni;"} },
{ mnem="icc c" , opcode=0x1D, {"aluC", "aluOpAddC","instrNext"}, desc="C+=CF, set flags", ccode={"addf(cpu.c,cpu.cf); lni;"} },
{ mnem="tst a" , opcode=0x14, {"alulA", "aluOpCmp" ,"instrNext"}, desc="Set flags according to A-0", ccode={"tst(cpu.a); lni;"} },
{ mnem="tst b" , opcode=0x1E, {"alulB", "aluOpCmp" ,"instrNext"}, desc="Set flags according to B-0", ccode={"tst(cpu.b); lni;"} },
{ mnem="tst c" , opcode=0x1F, {"alulC", "aluOpCmp" ,"instrNext"}, desc="Set flags according to C-0", ccode={"tst(cpu.c); lni;"} },
{ mnem="inc *s+imm8" , opcode=0x2B, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alur1" ,"aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)++, set flags" , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u, 1 );","instrloadpre"} },
{ mnem="dec *s+imm8" , opcode=0x2C, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alurm1","aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)--, set flags" , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,-1 );","instrloadpre"} },
{ mnem="icc *s+imm8" , opcode=0x2D, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU", "aluOpAddC","instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="*(S+imm8)+=CF, set flags", ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,cpu.cf);","instrloadpre"} },
{ mnem="tst *s+imm8" , opcode=0x2E, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"alulU", "aluOpCmp" ,"instrNext"}, desc="Set flags according to *(S+imm8)-0", ccode={"loadimmedt","loadstackrelu","tst(cpu.u); lni;"} },
{ category = "16-bit Arithmetic", catlet = "X"},
{ mnem="adp imm8" , opcode=0x4A, {"loadImmedT","instrSub1"}, {"adwP","adwrTX","instrNext"}, desc="P+=imm8 signed", ccode={"loadimmedt","cpu.p+=signed8(cpu.t); lni;"} },
{ mnem="adq imm8" , opcode=0x4B, {"loadImmedT","instrSub1"}, {"adwQ","adwrTX","instrNext"}, desc="Q+=imm8 signed", ccode={"loadimmedt","cpu.q+=signed8(cpu.t); lni;"} },
{ mnem="ads imm8" , opcode=0x4C, {"loadImmedT","instrSub1"}, {"adwS","adwrTX","instrNext"}, desc="S+=imm8 signed", ccode={"loadimmedt","cpu.s+=signed8(cpu.t); lni;"} },
{ mnem="adp b" , opcode=0xE6, {"adwP","adwrBX","instrNext"}, desc="P+=B signed", ccode={"cpu.p+=signed8(cpu.b); lni;"} },
{ mnem="adq b" , opcode=0xE7, {"adwQ","adwrBX","instrNext"}, desc="Q+=B signed", ccode={"cpu.q+=signed8(cpu.b); lni;"} },
{ mnem="ads b" , opcode=0xE8, {"adwS","adwrBX","instrNext"}, desc="S+=B signed", ccode={"cpu.s+=signed8(cpu.b); lni;"} },
{ category = "8-bit Arithmetic/Logic", catlet="A" },
{ mnem="add imm8" , opcode=0x24, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="A+=imm8, set flags" , ccode={"loadimmedt","addf(cpu.a,cpu.t); lni;"} },
{ mnem="adb imm8" , opcode=0x72, {"loadImmedT","instrSub1"}, {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="B+=imm8, set flags" , ccode={"loadimmedt","addf(cpu.b,cpu.t); lni;"} },
{ mnem="adc imm8" , opcode=0x73, {"loadImmedT","instrSub1"}, {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="C+=imm8, set flags" , ccode={"loadimmedt","addf(cpu.c,cpu.t); lni;"} },
{ mnem="acc imm8" , opcode=0x78, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="A+=imm8+CF, set flags" , ccode={"loadimmedt","addf(cpu.a,cpu.t+cpu.cf); lni;"} },
{ mnem="cmp imm8" , opcode=0x71, {"loadImmedT","instrSub1"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="set flags according to A-imm8" , ccode={"loadimmedt","cmpf(cpu.a,cpu.t); lni;"} },
{ mnem="and imm8" , opcode=0x74, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="A&=imm8, set zero flag" , ccode={"loadimmedt","cpu.a&=cpu.t; setzf(cpu.a); lni;"} },
{ mnem="ior imm8" , opcode=0x75, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="A|=imm8, set zero flag" , ccode={"loadimmedt","cpu.a|=cpu.t; setzf(cpu.a); lni;"} },
{ mnem="xor imm8" , opcode=0x76, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="A^=imm8, set zero flag" , ccode={"loadimmedt","cpu.a^=cpu.t; setzf(cpu.a); lni;"} },
{ mnem="shl imm8" , opcode=0xD0, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="A<<=imm8, set zero flag" , ccode={"loadimmedt","cpu.a<<=cpu.t; setzf(cpu.a); lni;"} },
{ mnem="shr imm8" , opcode=0xD1, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="A>>=imm8, set zero flag" , ccode={"loadimmedt","cpu.a>>=cpu.t; setzf(cpu.a); lni;"} },
{ mnem="rol imm8" , opcode=0xD2, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=imm8, set zero flag" , ccode={"loadimmedt","cpu.a=rol(cpu.a,cpu.t); setzf(cpu.a); lni;"} },
{ mnem="ror imm8" , opcode=0xD3, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=imm8, set zero flag" , ccode={"loadimmedt","cpu.a=ror(cpu.a,cpu.t); setzf(cpu.a); lni;"} },
{ mnem="sra imm8" , opcode=0xD4, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=imm8, set zero flag" , ccode={"loadimmedt","cpu.a=sra(cpu.a,cpu.t); setzf(cpu.a); lni;"} },
{ mnem="add *s+imm8" , opcode=0xAE, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="A+=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u); lni;"} },
{ mnem="adb *s+imm8" , opcode=0x9B, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="B+=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.b,cpu.u); lni;"} },
{ mnem="adc *s+imm8" , opcode=0x9C, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="C+=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.c,cpu.u); lni;"} },
{ mnem="sub *s+imm8" , opcode=0xAF, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSub" ,"instrNext"}, desc="A-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.a,cpu.u); lni;"} },
{ mnem="sbb *s+imm8" , opcode=0x9D, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpSub" ,"instrNext"}, desc="B-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.b,cpu.u); lni;"} },
{ mnem="sbc *s+imm8" , opcode=0x9E, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.c,cpu.u); lni;"} },
{ mnem="acc *s+imm8" , opcode=0xB5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="A+=*(S+imm8)+CF, set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u+cpu.cf); lni;"} },
{ mnem="scc *s+imm8" , opcode=0xB7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSubC","instrNext"}, desc="A-=*(S+imm8)+CF, set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,-cpu.u+cpu.cf); lni;"} },
{ mnem="cmp *s+imm8" , opcode=0xB0, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="set flags according to A-*(S+imm8)", ccode={"loadimmedt","loadstackrelu","cmpf(cpu.a,cpu.u); lni;"} },
{ mnem="and *s+imm8" , opcode=0xB1, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="A&=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a&=cpu.u; setzf(cpu.a); lni;"} },
{ mnem="ior *s+imm8" , opcode=0xB2, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="A|=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a|=cpu.u; setzf(cpu.a); lni;"} },
{ mnem="xor *s+imm8" , opcode=0xB3, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="A^=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a^=cpu.u; setzf(cpu.a); lni;"} },
{ mnem="shl *s+imm8" , opcode=0xD5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a<<=cpu.u; setzf(cpu.a); lni;"} },
{ mnem="shr *s+imm8" , opcode=0xD6, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a>>=cpu.u; setzf(cpu.a); lni;"} },
{ mnem="rol *s+imm8" , opcode=0xD7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=rol(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
{ mnem="ror *s+imm8" , opcode=0xD8, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=ror(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
{ mnem="sra *s+imm8" , opcode=0xD9, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=sra(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
{ mnem="add b" , opcode=0xA0, {"aluA", "alurB","aluOpAdd" ,"instrNext"}, desc="A+=B, set flags" , ccode={"addf(cpu.a,cpu.b); lni;"} },
{ mnem="adc b" , opcode=0x9F, {"aluC", "alurB","aluOpAdd" ,"instrNext"}, desc="C+=B, set flags" , ccode={"addf(cpu.c,cpu.b); lni;"} },
{ mnem="sub b" , opcode=0xA1, {"aluA", "alurB","aluOpSub" ,"instrNext"}, desc="A-=B, set flags" , ccode={"subf(cpu.a,cpu.b); lni;"} },
{ mnem="sbc b" , opcode=0xB6, {"aluC", "alurB","aluOpSub" ,"instrNext"}, desc="C-=B, set flags" , ccode={"subf(cpu.c,cpu.b); lni;"} },
{ mnem="acc b" , opcode=0xB8, {"aluA", "alurB","aluOpAddC","instrNext"}, desc="A+=B+CF, set flags" , ccode={"addf(cpu.a,cpu.b+cpu.cf); lni;"} },
{ mnem="scc b" , opcode=0xB9, {"aluA", "alurB","aluOpSubC","instrNext"}, desc="A-=B+CF, set flags" , ccode={"addf(cpu.a,-cpu.b+cpu.cf); lni;"} },
{ mnem="cmp b" , opcode=0xA2, {"alulA","alurB","aluOpSub" ,"instrNext"}, desc="set flags according to A-B" , ccode={"cmpf(cpu.a,cpu.b); lni;"} },
{ mnem="and b" , opcode=0xA3, {"aluA", "alurB","aluOpAnd" ,"instrNext"}, desc="A&=B, set zero flag" , ccode={"cpu.a&=cpu.b; setzf(cpu.a); lni;"} },
{ mnem="ior b" , opcode=0xA4, {"aluA", "alurB","aluOpIor" ,"instrNext"}, desc="A|=B, set zero flag" , ccode={"cpu.a|=cpu.b; setzf(cpu.a); lni;"} },
{ mnem="xor b" , opcode=0xA5, {"aluA", "alurB","aluOpXor" ,"instrNext"}, desc="A^=B, set zero flag" , ccode={"cpu.a^=cpu.b; setzf(cpu.a); lni;"} },
{ mnem="shl b" , opcode=0xDA, {"aluA", "alurB","aluOpShl" ,"instrNext"}, desc="A<<=B, set zero flag" , ccode={"cpu.a<<=cpu.b; setzf(cpu.a); lni;"} },
{ mnem="shr b" , opcode=0xDB, {"aluA", "alurB","aluOpShr" ,"instrNext"}, desc="A>>=B, set zero flag" , ccode={"cpu.a>>=cpu.b; setzf(cpu.a); lni;"} },
{ mnem="rol b" , opcode=0xDC, {"aluA", "alurB","aluOpRol" ,"instrNext"}, desc="A<<<=B, set zero flag" , ccode={"cpu.a=rol(cpu.a,cpu.b); setzf(cpu.a); lni;"} },
{ mnem="ror b" , opcode=0xDD, {"aluA", "alurB","aluOpRor" ,"instrNext"}, desc="A>>>=B, set zero flag" , ccode={"cpu.a=ror(cpu.a,cpu.b); setzf(cpu.a); lni;"} },
{ mnem="sra b" , opcode=0xDE, {"aluA", "alurB","aluOpSra" ,"instrNext"}, desc="A>>a=B, set zero flag" , ccode={"cpu.a=sra(cpu.a,cpu.b); setzf(cpu.a); lni;"} },
{ mnem="add c" , opcode=0xA7, {"aluA", "alurC","aluOpAdd" ,"instrNext"}, desc="A+=C, set flags" , ccode={"addf(cpu.a,cpu.c); lni;"} },
{ mnem="adb c" , opcode=0xBD, {"aluB", "alurC","aluOpAdd" ,"instrNext"}, desc="B+=C, set flags" , ccode={"addf(cpu.b,cpu.c); lni;"} },
{ mnem="sub c" , opcode=0xA8, {"aluA", "alurC","aluOpSub" ,"instrNext"}, desc="A-=C, set flags" , ccode={"subf(cpu.a,cpu.c); lni;"} },
{ mnem="sbb c" , opcode=0xBC, {"aluB", "alurC","aluOpSub" ,"instrNext"}, desc="B-=C, set flags" , ccode={"subf(cpu.b,cpu.c); lni;"} },
{ mnem="acc c" , opcode=0xBA, {"aluA", "alurC","aluOpAddC","instrNext"}, desc="A+=C+CF, set flags" , ccode={"addf(cpu.a,cpu.c+cpu.cf); lni;"} },
{ mnem="scc c" , opcode=0xBB, {"aluA", "alurC","aluOpSubC","instrNext"}, desc="A-=C+CF, set flags" , ccode={"addf(cpu.a,-cpu.c+cpu.cf); lni;"} },
{ mnem="cmp c" , opcode=0xA9, {"alulA","alurC","aluOpSub" ,"instrNext"}, desc="set flags according to A-C" , ccode={"cmpf(cpu.a,cpu.c); lni;"} },
{ mnem="and c" , opcode=0xAA, {"aluA", "alurC","aluOpAnd" ,"instrNext"}, desc="A&=C, set zero flag" , ccode={"cpu.a&=cpu.c; setzf(cpu.a); lni;"} },
{ mnem="ior c" , opcode=0xAB, {"aluA", "alurC","aluOpIor" ,"instrNext"}, desc="A|=C, set zero flag" , ccode={"cpu.a|=cpu.c; setzf(cpu.a); lni;"} },
{ mnem="xor c" , opcode=0xAC, {"aluA", "alurC","aluOpXor" ,"instrNext"}, desc="A^=C, set zero flag" , ccode={"cpu.a^=cpu.c; setzf(cpu.a); lni;"} },
{ mnem="shl c" , opcode=0xDF, {"aluA", "alurC","aluOpShl" ,"instrNext"}, desc="A<<=C, set zero flag" , ccode={"cpu.a<<=cpu.c; setzf(cpu.a); lni;"} },
{ mnem="shr c" , opcode=0x4D, {"aluA", "alurC","aluOpShr" ,"instrNext"}, desc="A>>=C, set zero flag" , ccode={"cpu.a>>=cpu.c; setzf(cpu.a); lni;"} },
{ mnem="rol c" , opcode=0x3E, {"aluA", "alurC","aluOpRol" ,"instrNext"}, desc="A<<<=C, set zero flag" , ccode={"cpu.a=rol(cpu.a,cpu.c); setzf(cpu.a); lni;"} },
{ mnem="ror c" , opcode=0x3F, {"aluA", "alurC","aluOpRor" ,"instrNext"}, desc="A>>>=C, set zero flag" , ccode={"cpu.a=ror(cpu.a,cpu.c); setzf(cpu.a); lni;"} },
{ mnem="sra c" , opcode=0x2F, {"aluA", "alurC","aluOpSra" ,"instrNext"}, desc="A>>a=C, set zero flag" , ccode={"cpu.a=sra(cpu.a,cpu.c); setzf(cpu.a); lni;"} },
{ mnem="adb a" , opcode=0xBE, {"aluB", "alurA","aluOpAdd" ,"instrNext"}, desc="B+=A, set flags" , ccode={"addf(cpu.b,cpu.a); lni;"} },
{ mnem="sbb a" , opcode=0xBF, {"aluB", "alurA","aluOpSub" ,"instrNext"}, desc="B-=A, set flags" , ccode={"subf(cpu.b,cpu.a); lni;"} },
{ mnem="adc a" , opcode=0x4E, {"aluC", "alurA","aluOpAdd" ,"instrNext"}, desc="C+=A, set flags" , ccode={"addf(cpu.c,cpu.a); lni;"} },
{ mnem="sbc a" , opcode=0x4F, {"aluC", "alurA","aluOpSub" ,"instrNext"}, desc="C-=A, set flags" , ccode={"subf(cpu.c,cpu.a); lni;"} },
{ category = "Jumps" , catlet="J" },
{ mnem="jmp imm16" , opcode=0x60, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT" }, desc="I=imm16" , ccode={"loadimm161","loadimm162","jmpabsut"} },
{ mnem="jsr imm16" , opcode=0x63, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT","saveRetAddr"}, desc="I=imm16, Q=I", ccode={"loadimm161","loadimm162","jmpabsut saveretaddr"} },
{ mnem="jss imm16" , opcode=0xE2, jmp=true, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushRetAddr1","instrSub3"}, {"pushRetAddr2","instrSub4"}, {"jmpAbsUT"}, desc="I=imm16, *(S++++)=I-1", ccode={"loadimm161","loadimm162","pushretaddr1","pushretaddr2","jmpabsut"} },
{ mnem="jmp p" , opcode=0x64, {"jmpAbsP" }, desc="I=P" , ccode={"jmpabsp"} },
{ mnem="jmp q" , opcode=0x66, {"jmpAbsQ" }, desc="I=Q" , ccode={"jmpabsq"} },
{ mnem="jsr p" , opcode=0x65, {"jmpAbsP","saveRetAddr"}, desc="I=P, Q=I", ccode={"jmpabsp","saveretaddr"} },
{ mnem="jsr q" , opcode=0x67, {"jmpAbsQ","saveRetAddr"}, desc="I=Q, Q=I", ccode={"jmpabsq","saveretaddr"} },
{ mnem="jss p" , opcode=0xE4, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsP"}, desc="I=P, *(S++++)=I-1", ccode={"pushretaddr1","pushretaddr2","jmpabsp"} },
{ mnem="jss q" , opcode=0xE5, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsQ"}, desc="I=Q, *(S++++)=I-1", ccode={"pushretaddr1","pushretaddr2","jmpabsq"} },
{ mnem="rts" , opcode=0xE1, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"jmpAbsUT","adrInc"}, desc="I=*(----S)+1", ccode={"pop161","pop162","jmpabsutplus1"} },
{ mnem="jpr imm8" , opcode=0x31, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub1"}, {"jmpRelT"}, desc="I+=imm8", ccode={"loadimmedt","jmprelt"} },
{ mnem="jnz imm8" , opcode=0x30, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NZ" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Zero" , ccode={"loadimmedt","if( cpu.nz ) { jmprelt } else { lni }"} },
{ mnem="jpz imm8" , opcode=0x32, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0Z" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero" , ccode={"loadimmedt","if(!cpu.nz ) { jmprelt } else { lni }"} },
{ mnem="jlt imm8" , opcode=0x33, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Carry" , ccode={"loadimmedt","if(!cpu.cf ) { jmprelt } else { lni }"} },
{ mnem="jge imm8" , opcode=0x34, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0C" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Carry" , ccode={"loadimmedt","if( cpu.cf ) { jmprelt } else { lni }"} },
{ mnem="jgt imm8" , opcode=0x35, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"jmpRelT"}, {"instrNext"}, desc="I+=imm8 if !Zero & Carry", ccode={"loadimmedt","if( cpu.nz && cpu.cf ) { jmprelt } else { lni }"} },
{ mnem="jle imm8" , opcode=0x36, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero | !Carry", ccode={"loadimmedt","if((!cpu.nz) || (!cpu.cf)) { jmprelt } else { lni }"} },
{ category = "Stack" , catlet="S" },
{ mnem="psh a" , opcode=0x40, {"pushReg","alurA","instrSub1"}, {"instrNext"}, desc="*(S++)=A", ccode={"pushbyte(cpu.a);","lni;"} },
{ mnem="psh b" , opcode=0x44, {"pushReg","alurB","instrSub1"}, {"instrNext"}, desc="*(S++)=B", ccode={"pushbyte(cpu.b);","lni;"} },
{ mnem="psh c" , opcode=0x45, {"pushReg","alurC","instrSub1"}, {"instrNext"}, desc="*(S++)=C", ccode={"pushbyte(cpu.c);","lni;"} },
{ mnem="psh f" , opcode=0xE9, {"pushReg","alurF","instrSub1"}, {"instrNext"}, desc="*(S++)=F", ccode={"int f = cpu.nz | (cpu.cf<<1); pushbyte(f);","lni;"} },
{ mnem="psh p" , opcode=0x41, {"pushReg","alurPH","instrSub1"}, {"pushReg","alurPL","instrSub2"}, {"instrNext"}, desc="*(S++++)=P", ccode={"push161(cpu.p);","push162(cpu.p);","lni;"} },
{ mnem="psh q" , opcode=0x46, {"pushReg","alurQH","instrSub1"}, {"pushReg","alurQL","instrSub2"}, {"instrNext"}, desc="*(S++++)=Q", ccode={"push161(cpu.q);","push162(cpu.q);","lni;"} },
{ mnem="pop a" , opcode=0x42, {"popReg","memSaveA","instrSub1"}, {"instrNext"}, desc="A=*(--S)", ccode={"cpu.a=popbyte;","lni;"} },
{ mnem="pop b" , opcode=0x47, {"popReg","memSaveB","instrSub1"}, {"instrNext"}, desc="B=*(--S)", ccode={"cpu.b=popbyte;","lni;"} },
{ mnem="pop c" , opcode=0x48, {"popReg","memSaveC","instrSub1"}, {"instrNext"}, desc="C=*(--S)", ccode={"cpu.c=popbyte;","lni;"} },
{ mnem="pop f" , opcode=0xEA, {"popReg","memSaveF","instrSub1"}, {"instrNext"}, desc="F=*(--S)", ccode={"int f=popbyte; cpu.nz = f&1; cpu.cf = (f>>1)&1;","lni;"} },
{ mnem="pop p" , opcode=0x43, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*(----S)", ccode={"pop161","pop162","cpu.p=wordut; lni;"} },
{ mnem="pop q" , opcode=0x49, {"pop161","instrSub1"}, {"pop162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*(----S)", ccode={"pop161","pop162","cpu.q=wordut; lni;"} },
{ mnem="psh imm8" , opcode=0x3B, {"loadImmedT","instrSub1"}, {"pushReg","alurT","instrSub2"}, {"instrNext"}, desc="*(S++)=imm8", ccode={"loadimmedt;","pushbyte(cpu.t);","lni;"} },
{ mnem="phw imm16" , opcode=0x3C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushReg","alurU","instrSub3"}, {"pushReg","alurT","instrSub4"}, {"instrNext"}, desc="*(S++++)=imm16", ccode={"loadimm161","loadimm162","pushbyte(cpu.u);","pushbyte(cpu.t);","lni;"} }, -- 0x3D
{ category = "8-bit Load/Store", catlet="B" },
{ mnem="lda imm8" , opcode=0x20, {"loadImmed", "memSaveA","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=imm8, update zero flag", ccode={"cpu.a=loadimmed; setzf(cpu.a);","lni;"} },
{ mnem="ldb imm8" , opcode=0x26, {"loadImmed", "memSaveB","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=imm8, update zero flag", ccode={"cpu.b=loadimmed; setzf(cpu.b);","lni;"} },
{ mnem="ldc imm8" , opcode=0x27, {"loadImmed", "memSaveC","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=imm8, update zero flag", ccode={"cpu.c=loadimmed; setzf(cpu.c);","lni;"} },
{ mnem="lda *s+imm8" , opcode=0x28, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveA","memSaveFlags","instrSub2"}, {"instrNext"}, desc="A=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.a=loadstackrel; setzf(cpu.a);","lni;"} },
{ mnem="ldb *s+imm8" , opcode=0x29, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveB","memSaveFlags","instrSub2"}, {"instrNext"}, desc="B=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.b=loadstackrel; setzf(cpu.b);","lni;"} },
{ mnem="ldc *s+imm8" , opcode=0x2A, {"loadImmedT","instrSub1"}, {"loadStackRel","memSaveC","memSaveFlags","instrSub2"}, {"instrNext"}, desc="C=*s+imm8, update zero flag", ccode={"loadimmedt;","cpu.c=loadstackrel; setzf(cpu.c);","lni;"} },
{ mnem="sta *s+imm8" , opcode=0x96, {"loadImmedT","instrSub1"}, {"storeStackRel","alurA","instrSub2"}, {"instrNext"}, desc="*s+imm8=A", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
{ mnem="stb *s+imm8" , opcode=0x97, {"loadImmedT","instrSub1"}, {"storeStackRel","alurB","instrSub2"}, {"instrNext"}, desc="*s+imm8=B", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
{ mnem="stc *s+imm8" , opcode=0x98, {"loadImmedT","instrSub1"}, {"storeStackRel","alurC","instrSub2"}, {"instrNext"}, desc="*s+imm8=C", ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
{ mnem="lda *imm16" , opcode=0x51, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "loadReg", "memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.a=loadut; setzf(cpu.a);", "lni;"} },
{ mnem="ldb *imm16" , opcode=0x56, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "loadReg", "memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.b=loadut; setzf(cpu.b);", "lni;"} },
{ mnem="ldc *imm16" , opcode=0x57, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "loadReg", "memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.c=loadut; setzf(cpu.c);", "lni;"} },
{ mnem="sta *imm16" , opcode=0x50, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "storeReg","alurA", "instrSub3"}, {"instrNext"}, desc="*imm16=A", ccode={"loadimm161","loadimm162","storeut(cpu.a);", "lni;"} },
{ mnem="stb *imm16" , opcode=0x58, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "storeReg","alurB", "instrSub3"}, {"instrNext"}, desc="*imm16=B", ccode={"loadimm161","loadimm162","storeut(cpu.b);", "lni;"} },
{ mnem="stc *imm16" , opcode=0x59, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "storeReg","alurC", "instrSub3"}, {"instrNext"}, desc="*imm16=C", ccode={"loadimm161","loadimm162","storeut(cpu.c);", "lni;"} },
{ mnem="lda *p+imm16", opcode=0x01, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","loadReg", "memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*P+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.a=loadput; setzf(cpu.a);","lni;"} },
{ mnem="ldb *p+imm16", opcode=0xF7, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","loadReg", "memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*P+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.b=loadput; setzf(cpu.b);","lni;"} },
{ mnem="ldc *p+imm16", opcode=0xFE, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","loadReg", "memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*P+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.c=loadput; setzf(cpu.c);","lni;"} },
{ mnem="lda *q+imm16", opcode=0xEB, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","loadReg", "memSaveA","memSaveFlags","instrSub3"}, {"instrNext"}, desc="A=*Q+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.a=loadqut; setzf(cpu.a);","lni;"} },
{ mnem="ldb *q+imm16", opcode=0x08, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","loadReg", "memSaveB","memSaveFlags","instrSub3"}, {"instrNext"}, desc="B=*Q+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.b=loadqut; setzf(cpu.b);","lni;"} },
{ mnem="ldc *q+imm16", opcode=0x09, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","loadReg", "memSaveC","memSaveFlags","instrSub3"}, {"instrNext"}, desc="C=*Q+imm16, update zero flag", ccode={"loadimm161","loadimm162","cpu.c=loadqut; setzf(cpu.c);","lni;"} },
{ mnem="sta *p+imm16", opcode=0x0A, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","storeReg","alurA", "instrSub3"}, {"instrNext"}, desc="*P+imm16=A", ccode={"loadimm161","loadimm162","storeput(cpu.a);", "lni;"} },
{ mnem="stb *p+imm16", opcode=0x0B, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","storeReg","alurB", "instrSub3"}, {"instrNext"}, desc="*P+imm16=B", ccode={"loadimm161","loadimm162","storeput(cpu.b);", "lni;"} },
{ mnem="stc *p+imm16", opcode=0x0C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlP","storeReg","alurC", "instrSub3"}, {"instrNext"}, desc="*P+imm16=C", ccode={"loadimm161","loadimm162","storeput(cpu.c);", "lni;"} },
{ mnem="sta *q+imm16", opcode=0x0D, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","storeReg","alurA", "instrSub3"}, {"instrNext"}, desc="*Q+imm16=A", ccode={"loadimm161","loadimm162","storequt(cpu.a);", "lni;"} },
{ mnem="stb *q+imm16", opcode=0x0E, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","storeReg","alurB", "instrSub3"}, {"instrNext"}, desc="*Q+imm16=B", ccode={"loadimm161","loadimm162","storequt(cpu.b);", "lni;"} },
{ mnem="stc *q+imm16", opcode=0x0F, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT","adrlQ","storeReg","alurC", "instrSub3"}, {"instrNext"}, desc="*Q+imm16=C", ccode={"loadimm161","loadimm162","storequt(cpu.c);", "lni;"} },
{ mnem="lda *p" , opcode=0x53, {"adrlP","loadReg", "memSaveA", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P, update zero flag", ccode={"cpu.a=loadp; setzf(cpu.a);","lni;"} },
{ mnem="ldb *p" , opcode=0x5E, {"adrlP","loadReg", "memSaveB", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P, update zero flag", ccode={"cpu.b=loadp; setzf(cpu.b);","lni;"} },
{ mnem="ldc *p" , opcode=0x5F, {"adrlP","loadReg", "memSaveC", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P, update zero flag", ccode={"cpu.c=loadp; setzf(cpu.c);","lni;"} },
{ mnem="lda *q" , opcode=0x55, {"adrlQ","loadReg", "memSaveA", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q, update zero flag", ccode={"cpu.a=loadq; setzf(cpu.a);","lni;"} },
{ mnem="ldb *q" , opcode=0x61, {"adrlQ","loadReg", "memSaveB", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q, update zero flag", ccode={"cpu.b=loadq; setzf(cpu.b);","lni;"} },
{ mnem="ldc *q" , opcode=0x62, {"adrlQ","loadReg", "memSaveC", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q, update zero flag", ccode={"cpu.c=loadq; setzf(cpu.c);","lni;"} },
{ mnem="sta *p" , opcode=0x52, {"adrlP","storeReg","alurA", "instrSub1"}, {"instrNext"}, desc="*P=A", ccode={"storep(cpu.a);","lni;"} },
{ mnem="stb *p" , opcode=0x5A, {"adrlP","storeReg","alurB", "instrSub1"}, {"instrNext"}, desc="*P=B", ccode={"storep(cpu.b);","lni;"} },
{ mnem="stc *p" , opcode=0x5B, {"adrlP","storeReg","alurC", "instrSub1"}, {"instrNext"}, desc="*P=C", ccode={"storep(cpu.c);","lni;"} },
{ mnem="sta *q" , opcode=0x54, {"adrlQ","storeReg","alurA", "instrSub1"}, {"instrNext"}, desc="*Q=A", ccode={"storeq(cpu.a);","lni;"} },
{ mnem="stb *q" , opcode=0x5C, {"adrlQ","storeReg","alurB", "instrSub1"}, {"instrNext"}, desc="*Q=B", ccode={"storeq(cpu.b);","lni;"} },
{ mnem="stc *q" , opcode=0x5D, {"adrlQ","storeReg","alurC", "instrSub1"}, {"instrNext"}, desc="*Q=C", ccode={"storeq(cpu.c);","lni;"} },
{ mnem="lda *p++" , opcode=0xC6, {"adrlP","loadReg", "memSaveA","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*P++, update zero flag", ccode={"cpu.a=loadpinc; setzf(cpu.a);","lni;"} },
{ mnem="ldb *p++" , opcode=0xC7, {"adrlP","loadReg", "memSaveB","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*P++, update zero flag", ccode={"cpu.b=loadpinc; setzf(cpu.b);","lni;"} },
{ mnem="ldc *p++" , opcode=0xC8, {"adrlP","loadReg", "memSaveC","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*P++, update zero flag", ccode={"cpu.c=loadpinc; setzf(cpu.c);","lni;"} },
{ mnem="lda *q++" , opcode=0xC9, {"adrlQ","loadReg", "memSaveA","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="A=*Q++, update zero flag", ccode={"cpu.a=loadqinc; setzf(cpu.a);","lni;"} },
{ mnem="ldb *q++" , opcode=0xCA, {"adrlQ","loadReg", "memSaveB","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="B=*Q++, update zero flag", ccode={"cpu.b=loadqinc; setzf(cpu.b);","lni;"} },
{ mnem="ldc *q++" , opcode=0xCB, {"adrlQ","loadReg", "memSaveC","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="C=*Q++, update zero flag", ccode={"cpu.c=loadqinc; setzf(cpu.c);","lni;"} },
{ mnem="sta *p++" , opcode=0xC0, {"adrlP","storeReg","alurA", "incP", "instrSub1"}, {"instrNext"}, desc="*P++=A", ccode={"storepinc(cpu.a);","lni;"} },
{ mnem="stb *p++" , opcode=0xC1, {"adrlP","storeReg","alurB", "incP", "instrSub1"}, {"instrNext"}, desc="*P++=B", ccode={"storepinc(cpu.b);","lni;"} },
{ mnem="stc *p++" , opcode=0xC2, {"adrlP","storeReg","alurC", "incP", "instrSub1"}, {"instrNext"}, desc="*P++=C", ccode={"storepinc(cpu.c);","lni;"} },
{ mnem="sta *q++" , opcode=0xC3, {"adrlQ","storeReg","alurA", "incQ", "instrSub1"}, {"instrNext"}, desc="*Q++=A", ccode={"storeqinc(cpu.a);","lni;"} },
{ mnem="stb *q++" , opcode=0xC4, {"adrlQ","storeReg","alurB", "incQ", "instrSub1"}, {"instrNext"}, desc="*Q++=B", ccode={"storeqinc(cpu.b);","lni;"} },
{ mnem="stc *q++" , opcode=0xC5, {"adrlQ","storeReg","alurC", "incQ", "instrSub1"}, {"instrNext"}, desc="*Q++=C", ccode={"storeqinc(cpu.c);","lni;"} },
{ category = "16-bit Load/Store", catlet="W" },
{ mnem="ldp imm16" , opcode=0x21, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; lni;"} },
{ mnem="ldq imm16" , opcode=0x23, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; lni;"} },
{ mnem="lds imm16" , opcode=0x25, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveS","instrNext"}, desc="S=imm16", ccode={"loadimm161","loadimm162","cpu.s=wordut; lni;"} },
{ mnem="ldv imm16" , opcode=0x22, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adwrUT","adwSaveV","instrNext"}, desc="V=imm16", ccode={"loadimm161","loadimm162","cpu.v=wordut; lni;"} },
{ mnem="ldp *s+imm8" , opcode=0x7A, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} },
{ mnem="ldq *s+imm8" , opcode=0x7B, {"loadImmedT","instrSub1"}, {"loadStackRel161","instrSub2"}, {"loadStackRel162","instrSub3"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*S+imm8", ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} },
{ mnem="stp *s+imm8" , opcode=0x7E, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurPH","instrSub2"}, {"storeStackRel162","alurPL","instrSub3"}, {"instrNext"}, desc="*S+imm8=P", ccode={"loadimmedt","storestackrel161(cpu.p);","storestackrel162(cpu.p);","lni;"} },
{ mnem="stq *s+imm8" , opcode=0x7F, {"loadImmedT","instrSub1"}, {"storeStackRel161","alurQH","instrSub2"}, {"storeStackRel162","alurQL","instrSub3"}, {"instrNext"}, desc="*S+imm8=Q", ccode={"loadimmedt","storestackrel161(cpu.q);","storestackrel162(cpu.q);","lni;"} },
{ mnem="ldp *imm16" , opcode=0x68, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU" ,"adwIncUT", "adwSaveP","instrSub3"}, {"adrlP","loadRegT", "instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0x69
{ mnem="ldq *imm16" , opcode=0x6A, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU" ,"adwIncUT", "adwSaveQ","instrSub3"}, {"adrlQ","loadRegT", "instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0x6B
{ mnem="stp *imm16" , opcode=0x6C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT" ,"alurPH", "instrSub3"}, {"storeUT","adrInc","alurPL", "instrSub4"}, { "instrNext"}, desc="*imm16=P", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.p));","storeutp1(lobyte(cpu.p));","lni;" } }, -- 0x6D
{ mnem="stq *imm16" , opcode=0x6E, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT" ,"alurQH", "instrSub3"}, {"storeUT","adrInc","alurQL", "instrSub4"}, { "instrNext"}, desc="*imm16=Q", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.q));","storeutp1(lobyte(cpu.q));","lni;" } }, -- 0x6F
{ mnem="ldp *p+imm16", opcode=0xEC, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUP","adwIncUTP","adwSaveP","instrSub3"}, {"adrlP","loadRegT", "instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*P+imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0xED
{ mnem="ldq *p+imm16", opcode=0xEE, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUP","adwIncUTP","adwSaveQ","instrSub3"}, {"adrlQ","loadRegT", "instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P+imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0xEF
{ mnem="ldp *q+imm16", opcode=0xF8, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUQ","adwIncUTQ","adwSaveP","instrSub3"}, {"adrlP","loadRegT", "instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q+imm16", ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0xF9
{ mnem="ldq *q+imm16", opcode=0xFA, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTUQ","adwIncUTQ","adwSaveQ","instrSub3"}, {"adrlQ","loadRegT", "instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*Q+imm16", ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0xFB
{ mnem="stq *p+imm16", opcode=0x06, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUTQ","alurQH", "instrSub3"}, {"storeUTQ","adrInc","alurQL","instrSub4"}, { "instrNext"}, desc="*P+imm16=Q", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.q));","storeutp1(lobyte(cpu.q));","lni;" } }, -- 0x07
{ mnem="stp *q+imm16", opcode=0xFC, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUTP","alurPH", "instrSub3"}, {"storeUTP","adrInc","alurPL","instrSub4"}, { "instrNext"}, desc="*Q+imm16=P", ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.p));","storeutp1(lobyte(cpu.p));","lni;" } }, -- 0xFD
{ mnem="ldp *p" , opcode=0x92, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*P", ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} },
{ mnem="ldq *p" , opcode=0x93, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P", ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.q=wordut; lni;"} },
{ mnem="ldp *q" , opcode=0x94, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q", ccode={"cpu.u=loadq;","cpu.t=loadqp1;","cpu.p=wordut; lni;"} },
{ mnem="ldq *q" , opcode=0x95, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*Q", ccode={"cpu.u=loadq;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} },
{ mnem="stp *q" , opcode=0x7C, {"adrlQ","store161","alurPH","instrSub1"}, {"adrlQ","store162","alurPL","instrSub2"}, {"instrNext"}, desc="*Q=P", ccode={"storeq(hibyte(cpu.p));","storeqp1(lobyte(cpu.p));","lni;"} },
{ mnem="stq *p" , opcode=0x7D, {"adrlP","store161","alurQH","instrSub1"}, {"adrlP","store162","alurQL","instrSub2"}, {"instrNext"}, desc="*P=Q", ccode={"storep(hibyte(cpu.q));","storepp1(lobyte(cpu.q));","lni;"} },
{ mnem="ldq *p++" , opcode=0xCC, {"adrlP","load161","instrSub1"}, {"adrlP","load162","instrSub2","incP2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Q=*P++++", ccode={"cpu.u=loadpinc;","cpu.t=loadpinc;","cpu.q=wordut; lni;"} },
{ mnem="ldp *q++" , opcode=0xCD, {"adrlQ","load161","instrSub1"}, {"adrlQ","load162","instrSub2","incQ2"}, {"adwrUT","adwSaveP","instrNext"}, desc="P=*Q++++", ccode={"cpu.u=loadqinc;","cpu.t=loadqinc;","cpu.p=wordut; lni;"} },
{ mnem="stp *q++" , opcode=0xCE, {"adrlQ","store161","alurPH","instrSub1"}, {"adrlQ","store162","alurPL","instrSub2","incQ2"}, {"instrNext"}, desc="*Q++++=P", ccode={"storeqinc(hibyte(cpu.p));","storeqinc(lobyte(cpu.p));","lni;"} },
{ mnem="stq *p++" , opcode=0xCF, {"adrlP","store161","alurQH","instrSub1"}, {"adrlP","store162","alurQL","instrSub2","incP2"}, {"instrNext"}, desc="*P++++=Q", ccode={"storepinc(hibyte(cpu.q));","storepinc(lobyte(cpu.q));","lni;"} },
{ category = "Moves" , catlet="M" },
{ mnem="lda b" , opcode=0x80, {"alurB" ,"aluOpMov","aluSaveA","instrNext"}, desc="A=B", ccode={"cpu.a=cpu.b; lni;"} },
{ mnem="lda c" , opcode=0x81, {"alurC" ,"aluOpMov","aluSaveA","instrNext"}, desc="A=C", ccode={"cpu.a=cpu.c; lni;"} },
{ mnem="ldb a" , opcode=0x82, {"alurA" ,"aluOpMov","aluSaveB","instrNext"}, desc="B=A", ccode={"cpu.b=cpu.a; lni;"} },
{ mnem="ldb c" , opcode=0x83, {"alurC" ,"aluOpMov","aluSaveB","instrNext"}, desc="B=C", ccode={"cpu.b=cpu.c; lni;"} },
{ mnem="ldc a" , opcode=0x84, {"alurA" ,"aluOpMov","aluSaveC","instrNext"}, desc="C=A", ccode={"cpu.c=cpu.a; lni;"} },
{ mnem="ldc b" , opcode=0x85, {"alurB" ,"aluOpMov","aluSaveC","instrNext"}, desc="C=B", ccode={"cpu.c=cpu.b; lni;"} },
{ mnem="lda pl" , opcode=0x86, {"alurPL","aluOpMov","aluSaveA","instrNext"}, desc="A=P&FF", ccode={"cpu.a=lobyte(cpu.p); lni;"} },
{ mnem="lda ph" , opcode=0x87, {"alurPH","aluOpMov","aluSaveA","instrNext"}, desc="A=P>>8", ccode={"cpu.a=hibyte(cpu.p); lni;"} },
{ mnem="lda ql" , opcode=0x88, {"alurQL","aluOpMov","aluSaveA","instrNext"}, desc="A=Q&FF", ccode={"cpu.a=lobyte(cpu.q); lni;"} },
{ mnem="lda qh" , opcode=0x89, {"alurQH","aluOpMov","aluSaveA","instrNext"}, desc="A=Q>>8", ccode={"cpu.a=hibyte(cpu.q); lni;"} },
{ mnem="ldb pl" , opcode=0x37, {"alurPL","aluOpMov","aluSaveB","instrNext"}, desc="B=P&FF", ccode={"cpu.b=lobyte(cpu.p); lni;"} },
{ mnem="ldc ph" , opcode=0x38, {"alurPH","aluOpMov","aluSaveC","instrNext"}, desc="C=P>>8", ccode={"cpu.c=hibyte(cpu.p); lni;"} },
{ mnem="ldb ql" , opcode=0x39, {"alurQL","aluOpMov","aluSaveB","instrNext"}, desc="B=Q&FF", ccode={"cpu.b=lobyte(cpu.q); lni;"} },
{ mnem="ldc qh" , opcode=0x3A, {"alurQH","aluOpMov","aluSaveC","instrNext"}, desc="C=Q>>8", ccode={"cpu.c=hibyte(cpu.q); lni;"} },
{ mnem="ldp q" , opcode=0x8A, {"adwlQ" , "adwSaveP","instrNext"}, desc="P=Q", ccode={"cpu.p=cpu.q; lni;"} },
{ mnem="ldp s" , opcode=0x8B, {"adwlS" , "adwSaveP","instrNext"}, desc="P=S", ccode={"cpu.p=cpu.s; lni;"} },
{ mnem="ldp v" , opcode=0x8C, {"adwlV" , "adwSaveP","instrNext"}, desc="P=V", ccode={"cpu.p=cpu.v; lni;"} },
{ mnem="ldp i" , opcode=0x8D, {"adwlI" , "adwSaveP","instrNext"}, desc="P=I", ccode={"cpu.p=cpu.i; lni;"} },
{ mnem="ldp cb" , opcode=0x91, {"adwrCB", "adwSaveP","instrNext"}, desc="P=(C<<8)+B", ccode={"cpu.p=wordcb; lni;"} },
{ mnem="ldq cb" , opcode=0xE0, {"adwrCB", "adwSaveQ","instrNext"}, desc="Q=(C<<8)+B", ccode={"cpu.q=wordcb; lni;"} },
{ mnem="ldq p" , opcode=0x8E, {"adwlP" , "adwSaveQ","instrNext"}, desc="Q=P", ccode={"cpu.q=cpu.p; lni;"} },
{ mnem="lds p" , opcode=0x8F, {"adwlP" , "adwSaveS","instrNext"}, desc="S=P", ccode={"cpu.s=cpu.p; lni;"} },
{ mnem="ldv p" , opcode=0x90, {"adwlP" , "adwSaveV","instrNext"}, desc="V=P", ccode={"cpu.v=cpu.p; lni;"} },
-- Shortcuts for instruction descriptions
-- These strings will be substituted into instruction descriptions wherever their [key] occurs
descShortcuts = {
{"%mem", "a value from memory"},
{"%mem16", "a value from memory"},
{"%imm8", "a given 8-bit value"},
{"%imm16", "a given 16-bit value"},
{"%A", "the value in the A register"},
{"%B", "the value in the B register"},
{"%C", "the value in the C register"},
{"%xInc16", "increment the X register by 2 bytes"},
{"%yInc16", "increment the Y register by 2 bytes"},
{"%xInc", "increment the X register"},
{"%yInc", "increment the Y register"},
{"%Xin16", "the 16-bit value in memory at the address in X"},
{"%Yinn16", "the 16-bit value in memory at the address in Y"},
{"%xIn", "the value in memory at the address in X"},
{"%yIn", "the value in memory at the address in Y"},
{"%XofsIn16", "the 16-bit value in memory at the address (X plus a given 8-bit offset)"},
{"%YofsIn16", "the 16-bit value in memory at the address (Y plus a given 8-bit offset)"},
{"%XofsIn", "the value in memory at the address (X plus a given 8-bit offset)"},
{"%YofsIn", "the value in memory at the address (Y plus a given 8-bit offset)"},
{"%Xofs", "the address (X plus a given 8-bit offset)"},
{"%Yofs", "the address (Y plus a given 8-bit offset)"},
{"%X", "the 16-bit value in the X register"},
{"%Y", "the 16-bit value in the Y register"},
{"%adrX", "the address in X"},
{"%adrY", "the address in Y"},
{"%zpgIn16", "the 16-bit value in memory at a given 8-bit address"},
{"%zpgIn", "the value in memory at a given 8-bit address"},
{"%zpg", "an given 8-bit address"},
{"%absIn16", "the 16-bit value in memory at a given 16-bit address"},
{"%absIn", "the value in memory at a given 16-bit address"},
{"%abs", "a given 16-bit address"},
{"%alu", "and store the result in the A register"},
{"%flags", " and set the Carry Flag and Zero Flag according to the result"},
{"%zflag", " and set the Zero Flag according to the result"},
{"%cmp", "Set the Carry Flag and Zero Flag according to the result of subtracting"},
{"%brel", "Add a signed 8-bit offset to the Program Counter, jumping forward or backward in the program"},
{"%brelc", "Otherwise, do nothing"},
{"%if", "If the result of the last math operation was"},
{"%zFlgMem", "and set the Zero Flag according to the value loaded"},
},
-- Aliases for instructions
-- Used to generate the assembler definitions.
-- imm8neg instead of imm8 means the immediate value will be negated when assembling.
transformMnemonic = function(mnem)
mnem = mnem:gsub("zpg", "imm8u")
mnem = mnem:gsub("ofs", "imm8u")
mnem = mnem:gsub("rel", "imm8rel")
mnem = mnem:gsub("abs", "imm16")
mnem = mnem:gsub("ind", "imm16")
mnem = mnem:gsub("#", "#imm8")
mnem = mnem:gsub("#imm8#imm8", "#imm16")
return mnem
end,
aliases = {
["jpz imm8" ] = {"jeq imm8"},
["jnz imm8" ] = {"jne imm8"},
["jmp q" ] = {"ret" },
["add imm8" ] = {"sub imm8neg"},
["adb imm8" ] = {"sbb imm8neg"},
["adc imm8" ] = {"sbc imm8neg"},
["acc imm8" ] = {"scc imm8neg"},
-- ["jmp q" ] = {"ret" },
["ADD imm8" ] = {"SUB imm8neg"},
-- ["adb imm8" ] = {"sbb imm8neg"},
-- ["adc imm8" ] = {"sbc imm8neg"},
["ADC imm8" ] = {"SBC imm8neg"},
},
-- Filename to generate the assembler definitions file to.
@ -458,3 +247,5 @@ Each instruction is described in order of: Mnemonic, Opcode, Clock cycles, Descr
]],
}
return arch8608

297
8608-instructions.lua Normal file
View File

@ -0,0 +1,297 @@
-- 8608-instructions.lua
-- This file contains the formal definitions for each instruction in the 8608 architecture.
-- It is used by generate-architecture.lua, alongside the definitions in 8608-definition.lua, to generate the following:
-- instructionList.txt, a human-readable list of all instructions.
-- 8608.asm, a set of definitions for CustomAsm that allows it to assemble 8608 programs.
-- The microcode ROM data, which is built into the physical CPU to control it.
-- List of definitions for every instruction
-- Each instruction definition contains:
-- Mnemonic: The mnemonic used to generate the assembler definitions and instruction list.
-- This is what must literally appear in the assembly code in order to generate this instruction, other than immediate values.
-- "imm8" means an 8-bit value.
-- "imm16" means a 16-bit value.
-- Opcode: The machine code byte that represents this operation.
-- Used by the assembler generator to map mnemonics to opcodes.
-- Used by the microcode generator to place the instruction's data within the microcode ROM, which is addressed by opcode.
-- List of control signals: Specifies the control lines that will be activated by the microcode when the instruction is executed.
-- Instructions may take multiple clock cycles. To convey this, each clock cycle is represented by an independent list of microcode signals.
-- Under the hood, the microcode ROM uses a 10-bit address: 8 bits for the opcode, and 2 bits for the clock cycle.
-- Because of this, each opcode may only use up to 4 clock cycles.
-- If more are required, the least significant bit of the opcode can be set by a control line, incrementing the opcode.
-- This causes one instruction to use up multiple opcodes.
-- The need for this is determined automatically by the microcode generator: whenever an instruction specifies more than 4 lists of control signals.
-- Description: A brief description of the instruction. Used to generate the instruction list.
-- C Code: Used to generate an emulator (as part of a separate project).
-- Categories can be specified. These serve only to organize the instruction list.
-- The category letter determines what letter will be used to represent the instructions in the opcode map, located at the bottom of the instruction list.
local instructions = {
{ category = "Control", catlet="C" },
{ mnem="RST" , opcode=0x41, {"clearRegs","load16FC1","instrSub1"},{"load16FC2","instrSub2"},{ "jmpAbsUT"}, desc="Clear all registers and flags, load the Program Counter from memory addresses $FFFC-$FFFD, and execute the code at the address given by those bytes" , ccode={"cpu.a=0; cpu.b=0; cpu.c=0; cpu.u=0; cpu.t=0; cpu.p=0; cpu.q=0; cpu.s=0; cpu.v=0; cpu.i=0; cpu.cf=0; cpu.nz=0; cpu.rfg=1; cpu.ien=0; cpu.irq=0; cpu.ifg=0; cpu.u=readmemory(0xFFFC);","cpu.t=readmemory(0xFFFD);","jmpabsut;"} },
{ mnem="INT" , opcode=0x01, { "load16FE1","instrSub1"},{"load16FE2","instrSub2"},{"intFlgVal","intFlgClk","irqFlgClk","saveIV", "jmpAbsUT"}, ccode={" cpu.irq=0; cpu.ifg=1; cpu.u=readmemory(0xFFFE);","cpu.t=readmemory(0xFFFF);","cpu.v=(cpu.i-1)%65536; jmpabsut;"} },
{ mnem="BRK" , opcode=0x00, { "load16FE1","instrSub1"},{"load16FE2","instrSub2"},{"intFlgVal","intFlgClk" ,"saveIV","adwInc","jmpAbsUT"}, desc="Trigger an interrupt from software, saving the current Program Counter in the V register and jumping to the Interrupt Vector stored at memory addresses $FFFE-$FFFF", ccode={" cpu.ifg=1; cpu.u=readmemory(0xFFFE);","cpu.t=readmemory(0xFFFF);","cpu.v=(cpu.i )%65536; jmpabsut;"} },
{ mnem="RTI" , opcode=0x40, {"adwInc","intFlgClk","jmpAbsV"}, desc="Return from an interrupt, resuming normal execution where it left off when the interrupt occurred", ccode={"cpu.ifg=0; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} },
{ mnem="NOP" , opcode=0xEA, {"instrNext"}, desc="Do nothing", ccode={"lni;"}, },
{ mnem="CLI" , opcode=0x58, {"instrNext"}, desc="Enable interrupts to be triggered by external hardware", ccode={"cpu.ien=1; lni;"}, }, -- todo
{ mnem="SEI" , opcode=0x78, {"instrNext"}, desc="Disable interrupts being triggered by external hardware", ccode={"cpu.ien=0; lni;"}, }, -- todo
{ mnem="HLT" , opcode=0x18, {"runFlgClk","instrNext"}, desc="Clear the Run Flag, preventing the CPU from running until an interrupt is triggered", ccode={"cpu.rfg=0; lni;"} },
{ mnem="RUN" , opcode=0x38, {"runFlgClk","runFlgVal","instrNext"}, desc ="Set the Run Flag, allowing the CPU to run once the current interrupt finishes", ccode={"cpu.rfg=1; lni;"} },
-- { category = "16-bit Increment/Decrement", catlet="I" },
-- { mnem="INX" , opcode=0x11, {"adwlP","adwInc","adwSaveP","instrNext"}, desc="Increment the 16-bit X register", ccode={"cpu.p++; lni;"} },
-- { mnem="DEX" , opcode=0x31, {"adwlP","adwrm1","adwSaveP","instrNext"}, desc="Decrement the 16-bit X register", ccode={"cpu.p--; lni;"} },
-- { mnem="INY" , opcode=0x51, {"adwlQ","adwInc","adwSaveQ","instrNext"}, desc="Increment the 16-bit Y register", ccode={"cpu.q++; lni;"} },
-- { mnem="DEY" , opcode=0x71, {"adwlQ","adwrm1","adwSaveQ","instrNext"}, desc="Decrement the 16-bit Y register", ccode={"cpu.q--; lni;"} },
{ category = "8-bit Unary Arithmetic", catlet="U" },
{ mnem="INC A" , opcode=0xF6, {"aluA","alur1" ,"aluOpAdd" ,"instrNext"}, desc="Increment the A register, %flags" , ccode={"addf(cpu.a, 1 ); lni;"} },
{ mnem="DEC A" , opcode=0xD6, {"aluA","alurm1","aluOpAdd" ,"instrNext"}, desc="Decrement the A register, %flags" , ccode={"addf(cpu.a,-1 ); lni;"} },
{ mnem="ICC A" , opcode=0x57, {"aluA", "aluOpAddC","instrNext"}, desc="Add the Carry Flag to the A register, %flags", ccode={"addf(cpu.a,cpu.cf); lni;"} },
{ mnem="INC B" , opcode=0xFE, {"aluB","alur1" ,"aluOpAdd" ,"instrNext"}, desc="Increment the B register, %flags" , ccode={"addf(cpu.b, 1 ); lni;"} },
{ mnem="DEC B" , opcode=0xDE, {"aluB","alurm1","aluOpAdd" ,"instrNext"}, desc="Decrement the B register, %flags" , ccode={"addf(cpu.b,-1 ); lni;"} },
{ mnem="ICC B" , opcode=0x5F, {"aluB", "aluOpAddC","instrNext"}, desc="Add the Carry Flag to the B register, %flags", ccode={"addf(cpu.b,cpu.cf); lni;"} },
{ mnem="INC C" , opcode=0xFA, {"aluC","alur1" ,"aluOpAdd" ,"instrNext"}, desc="Increment the C register, %flags" , ccode={"addf(cpu.c, 1 ); lni;"} },
{ mnem="DEC C" , opcode=0xDA, {"aluC","alurm1","aluOpAdd" ,"instrNext"}, desc="Decrement the C register, %flags" , ccode={"addf(cpu.c,-1 ); lni;"} },
{ mnem="ICC C" , opcode=0x5B, {"aluC", "aluOpAddC","instrNext"}, desc="Add the Carry Flag to the C register, %flags", ccode={"addf(cpu.c,cpu.cf); lni;"} },
-- { mnem="TST A" , opcode=0x , {"alulA", "aluOpCmp" ,"instrNext"}, desc="Set flags according to A-0", ccode={"tst(cpu.a); lni;"} },
-- { mnem="TST B" , opcode=0x , {"alulB", "aluOpCmp" ,"instrNext"}, desc="Set flags according to B-0", ccode={"tst(cpu.b); lni;"} },
-- { mnem="TST C" , opcode=0x , {"alulC", "aluOpCmp" ,"instrNext"}, desc="Set flags according to C-0", ccode={"tst(cpu.c); lni;"} },
{ mnem="INC zpg" , opcode=0xE6, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alur1" ,"aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="Increment the value at %zpg, %flags" , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u, 1 );","storestackrelu; instrloadpre"} },
{ mnem="DEC zpg" , opcode=0xC6, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU","alurm1","aluOpAdd" ,"instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="Decrement the value at %zpg, %flags" , ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,-1 );","storestackrelu; instrloadpre"} },
{ mnem="ICC zpg" , opcode=0x47, {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"aluU", "aluOpAddC","instrSub3","instrPreload"}, {"storeStackRelU","instrNextPre"}, desc="Add the Carrry Flag to the value at %zpg, %flags", ccode={"loadimmedt","loadstackrelu","instrpreload; addf(cpu.u,cpu.cf);","storestackrelu; instrloadpre"} },
-- { mnem="TST zpg" , opcode=0x , {"loadImmedT","instrSub1"}, {"loadStackRelU","instrSub2"}, {"alulU", "aluOpCmp" ,"instrNext"}, desc="Set flags according to *(S+imm8)-0", ccode={"loadimmedt","loadstackrelu","tst(cpu.u); lni;"} },
{ category = "8-bit Arithmetic and Logic", catlet="A" },
{ mnem="ADD #" , opcode=0x6B, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="Add %imm8 to %A, %flags" , ccode={"loadimmedt","addf(cpu.a,cpu.t); lni;"} },
-- { mnem="ADB #" , opcode=0x , {"loadImmedT","instrSub1"}, {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="" , ccode={"loadimmedt","addf(cpu.b,cpu.t); lni;"} },
-- { mnem="ADC #" , opcode=0x , {"loadImmedT","instrSub1"}, {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="" , ccode={"loadimmedt","addf(cpu.c,cpu.t); lni;"} },
{ mnem="ADC #" , opcode=0x69, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="Add %imm8 plus the Carry Flag to %A, %flags" , ccode={"loadimmedt","addf(cpu.a,cpu.t+cpu.cf); lni;"} },
{ mnem="CMP #" , opcode=0xC9, {"loadImmedT","instrSub1"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="%cmp %imm8 from %A" , ccode={"loadimmedt","cmpf(cpu.a,cpu.t); lni;"} },
{ mnem="AND #" , opcode=0x29, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="Bitwise AND %A with %imm8, %zflag" , ccode={"loadimmedt","cpu.a&=cpu.t; setzf(cpu.a); lni;"} },
{ mnem="ORA #" , opcode=0x09, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="Bitwise OR %A with %imm8, %zflag" , ccode={"loadimmedt","cpu.a|=cpu.t; setzf(cpu.a); lni;"} },
{ mnem="EOR #" , opcode=0x49, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="Bitwise Exclusive OR %A with %imm8, %zflag" , ccode={"loadimmedt","cpu.a^=cpu.t; setzf(cpu.a); lni;"} },
{ mnem="ASL #" , opcode=0x15, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="Bit-shift %A left by a given number of bits, %zflag" , ccode={"loadimmedt","cpu.a<<=cpu.t; setzf(cpu.a); lni;"} },
{ mnem="LSR #" , opcode=0x55, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="Bit-shift %A right by a given number of bits, %zflag" , ccode={"loadimmedt","cpu.a>>=cpu.t; setzf(cpu.a); lni;"} },
{ mnem="ROL #" , opcode=0x35, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="Bit-rotate %A left by a given number of bits, %zflag" , ccode={"loadimmedt","cpu.a=rol(cpu.a,cpu.t); setzf(cpu.a); lni;"} },
{ mnem="ROR #" , opcode=0x75, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="Bit-rotate %A right by a given number of bits, %zflag" , ccode={"loadimmedt","cpu.a=ror(cpu.a,cpu.t); setzf(cpu.a); lni;"} },
-- { mnem="ASR #" , opcode=0x , {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=imm8, set zero flag" , ccode={"loadimmedt","cpu.a=sra(cpu.a,cpu.t); setzf(cpu.a); lni;"} },
{ mnem="ADD zpg" , opcode=0x67, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAdd" ,"instrNext"}, desc="Add %zpgIn to %A, %flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u); lni;"} },
-- { mnem="adb zpg" , opcode=0x , {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpAdd" ,"instrNext"}, desc="B+=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.b,cpu.u); lni;"} },
-- { mnem="adc zpg" , opcode=0x , {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpAdd" ,"instrNext"}, desc="C+=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.c,cpu.u); lni;"} },
{ mnem="SUB zpg" , opcode=0xE7, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSub" ,"instrNext"}, desc="Subtract %zpgIn from %A, %flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.a,cpu.u); lni;"} },
-- { mnem="sbb zpg" , opcode=0x , {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluB", "alurT","aluOpSub" ,"instrNext"}, desc="B-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.b,cpu.u); lni;"} },
-- { mnem="sbc zpg" , opcode=0x , {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=*(S+imm8), set flags" , ccode={"loadimmedt","loadstackrelu","subf(cpu.c,cpu.u); lni;"} },
{ mnem="ADC zpg" , opcode=0x65, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAddC","instrNext"}, desc="Add %zpgIn plus the Carry Flag to %A, %flags" , ccode={"loadimmedt","loadstackrelu","addf(cpu.a,cpu.u+cpu.cf); lni;"} },
{ mnem="SBC zpg" , opcode=0xE5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSubC","instrNext"}, desc="Subtract %zpgIn from %A including the Carry Flag, %flags", ccode={"loadimmedt","loadstackrelu","addf(cpu.a,-cpu.u+cpu.cf); lni;"} },
{ mnem="CMP zpg" , opcode=0xC5, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"alulA","alurT","aluOpSub" ,"instrNext"}, desc="%cmp %zpgIn from %A" , ccode={"loadimmedt","loadstackrelu","cmpf(cpu.a,cpu.u); lni;"} },
{ mnem="AND zpg" , opcode=0x25, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnd" ,"instrNext"}, desc="Bitwise AND %A with %zpgIn, %flags" , ccode={"loadimmedt","loadstackrelu","cpu.a&=cpu.u; setzf(cpu.a); lni;"} },
{ mnem="ORA zpg" , opcode=0x05, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpIor" ,"instrNext"}, desc="Bitwise OR %A with %zpgIn, %flags" , ccode={"loadimmedt","loadstackrelu","cpu.a|=cpu.u; setzf(cpu.a); lni;"} },
{ mnem="EOR zpg" , opcode=0x45, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpXor" ,"instrNext"}, desc="Bitwise Exclusive OR %A with %zpgIn, %flags" , ccode={"loadimmedt","loadstackrelu","cpu.a^=cpu.u; setzf(cpu.a); lni;"} },
-- { mnem="ASL zpg" , opcode=0x , {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShl" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a<<=cpu.u; setzf(cpu.a); lni;"} },
-- { mnem="LSR zpg" , opcode=0x , {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpShr" ,"instrNext"}, desc="A<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a>>=cpu.u; setzf(cpu.a); lni;"} },
-- { mnem="ROL zpg" , opcode=0x , {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRol" ,"instrNext"}, desc="A<<<=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=rol(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
-- { mnem="ROR zpg" , opcode=0x , {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpRor" ,"instrNext"}, desc="A>>>=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=ror(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
-- { mnem="ASR zpg" , opcode=0x , {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpSra" ,"instrNext"}, desc="A>>a=*(S+imm8), set zero flag" , ccode={"loadimmedt","loadstackrelu","cpu.a=sra(cpu.a,cpu.u); setzf(cpu.a); lni;"} },
{ mnem="ADD B" , opcode=0x7F, {"aluA", "alurB","aluOpAdd" ,"instrNext"}, desc="Add %B to %A, %flags" , ccode={"addf(cpu.a,cpu.b); lni;"} },
-- { mnem="adc B" , opcode=0x , {"aluC", "alurB","aluOpAdd" ,"instrNext"}, desc="C+=B, set flags" , ccode={"addf(cpu.c,cpu.b); lni;"} },
{ mnem="SUB B" , opcode=0xFF, {"aluA", "alurB","aluOpSub" ,"instrNext"}, desc="Subtract %B from %A, %flags" , ccode={"subf(cpu.a,cpu.b); lni;"} },
-- { mnem="sbc B" , opcode=0x , {"aluC", "alurB","aluOpSub" ,"instrNext"}, desc="C-=B, set flags" , ccode={"subf(cpu.c,cpu.b); lni;"} },
{ mnem="ADC B" , opcode=0x7D, {"aluA", "alurB","aluOpAddC","instrNext"}, desc="Add %B plus the Carry Flag to %A, %flags" , ccode={"addf(cpu.a,cpu.b+cpu.cf); lni;"} },
{ mnem="SBC B" , opcode=0xFD, {"aluA", "alurB","aluOpSubC","instrNext"}, desc="Subtract %B form %A including the Carry Flag, %flags" , ccode={"addf(cpu.a,-cpu.b+cpu.cf); lni;"} },
{ mnem="CMP B" , opcode=0xDD, {"alulA","alurB","aluOpSub" ,"instrNext"}, desc="%cmp %B from %A" , ccode={"cmpf(cpu.a,cpu.b); lni;"} },
{ mnem="AND B" , opcode=0x3D, {"aluA", "alurB","aluOpAnd" ,"instrNext"}, desc="Bitwise AND %A with %B, %flags" , ccode={"cpu.a&=cpu.b; setzf(cpu.a); lni;"} },
{ mnem="ORA B" , opcode=0x1D, {"aluA", "alurB","aluOpIor" ,"instrNext"}, desc="Bitwise OR %A with %B, %flags" , ccode={"cpu.a|=cpu.b; setzf(cpu.a); lni;"} },
{ mnem="EOR B" , opcode=0x5D, {"aluA", "alurB","aluOpXor" ,"instrNext"}, desc="Bitwise Exclusive OR %A with %B, %flags" , ccode={"cpu.a^=cpu.b; setzf(cpu.a); lni;"} },
-- { mnem="ASL B" , opcode=0x , {"aluA", "alurB","aluOpShl" ,"instrNext"}, desc="A<<=B, set zero flag" , ccode={"cpu.a<<=cpu.b; setzf(cpu.a); lni;"} },
-- { mnem="LSR B" , opcode=0x , {"aluA", "alurB","aluOpShr" ,"instrNext"}, desc="A>>=B, set zero flag" , ccode={"cpu.a>>=cpu.b; setzf(cpu.a); lni;"} },
-- { mnem="ROL B" , opcode=0x , {"aluA", "alurB","aluOpRol" ,"instrNext"}, desc="A<<<=B, set zero flag" , ccode={"cpu.a=rol(cpu.a,cpu.b); setzf(cpu.a); lni;"} },
-- { mnem="ROR B" , opcode=0x , {"aluA", "alurB","aluOpRor" ,"instrNext"}, desc="A>>>=B, set zero flag" , ccode={"cpu.a=ror(cpu.a,cpu.b); setzf(cpu.a); lni;"} },
-- { mnem="ASR B" , opcode=0x , {"aluA", "alurB","aluOpSra" ,"instrNext"}, desc="A>>a=B, set zero flag" , ccode={"cpu.a=sra(cpu.a,cpu.b); setzf(cpu.a); lni;"} },
{ mnem="ADD C" , opcode=0x7B, {"aluA", "alurC","aluOpAdd" ,"instrNext"}, desc="Add %C to %A, %flags" , ccode={"addf(cpu.a,cpu.c); lni;"} },
-- { mnem="adb C" , opcode=0x , {"aluB", "alurC","aluOpAdd" ,"instrNext"}, desc="B+=C, set flags" , ccode={"addf(cpu.b,cpu.c); lni;"} },
{ mnem="SUB C" , opcode=0xFB, {"aluA", "alurC","aluOpSub" ,"instrNext"}, desc="Subtract %C from %A, %flags" , ccode={"subf(cpu.a,cpu.c); lni;"} },
-- { mnem="sbb C" , opcode=0x , {"aluB", "alurC","aluOpSub" ,"instrNext"}, desc="B-=C, set flags" , ccode={"subf(cpu.b,cpu.c); lni;"} },
{ mnem="ADC C" , opcode=0x79, {"aluA", "alurC","aluOpAddC","instrNext"}, desc="Add %C plus the Carry Flag to %A, %flags" , ccode={"addf(cpu.a,cpu.c+cpu.cf); lni;"} },
{ mnem="SBC C" , opcode=0xF9, {"aluA", "alurC","aluOpSubC","instrNext"}, desc="Subtract %C form %A including the Carry Flag, %flags" , ccode={"addf(cpu.a,-cpu.c+cpu.cf); lni;"} },
{ mnem="CMP C" , opcode=0xD9, {"alulA","alurC","aluOpSub" ,"instrNext"}, desc="%cmp %C from %A" , ccode={"cmpf(cpu.a,cpu.c); lni;"} },
{ mnem="AND C" , opcode=0x39, {"aluA", "alurC","aluOpAnd" ,"instrNext"}, desc="Bitwise AND %A with %C, %flags" , ccode={"cpu.a&=cpu.c; setzf(cpu.a); lni;"} },
{ mnem="ORA C" , opcode=0x19, {"aluA", "alurC","aluOpIor" ,"instrNext"}, desc="Bitwise OR %A with %C, %flags" , ccode={"cpu.a|=cpu.c; setzf(cpu.a); lni;"} },
{ mnem="EOR C" , opcode=0x59, {"aluA", "alurC","aluOpXor" ,"instrNext"}, desc="Bitwise Exclusive OR %A with %C, %flags" , ccode={"cpu.a^=cpu.c; setzf(cpu.a); lni;"} },
-- { mnem="ASL C" , opcode=0x , {"aluA", "alurC","aluOpShl" ,"instrNext"}, desc="A<<=C, set zero flag" , ccode={"cpu.a<<=cpu.c; setzf(cpu.a); lni;"} },
-- { mnem="LSR C" , opcode=0x , {"aluA", "alurC","aluOpShr" ,"instrNext"}, desc="A>>=C, set zero flag" , ccode={"cpu.a>>=cpu.c; setzf(cpu.a); lni;"} },
-- { mnem="ROL C" , opcode=0x , {"aluA", "alurC","aluOpRol" ,"instrNext"}, desc="A<<<=C, set zero flag" , ccode={"cpu.a=rol(cpu.a,cpu.c); setzf(cpu.a); lni;"} },
-- { mnem="ROR C" , opcode=0x , {"aluA", "alurC","aluOpRor" ,"instrNext"}, desc="A>>>=C, set zero flag" , ccode={"cpu.a=ror(cpu.a,cpu.c); setzf(cpu.a); lni;"} },
-- { mnem="ASR C" , opcode=0x , {"aluA", "alurC","aluOpSra" ,"instrNext"}, desc="A>>a=C, set zero flag" , ccode={"cpu.a=sra(cpu.a,cpu.c); setzf(cpu.a); lni;"} },
-- { mnem="adb a" , opcode=0x , {"aluB", "alurA","aluOpAdd" ,"instrNext"}, desc="B+=A, set flags" , ccode={"addf(cpu.b,cpu.a); lni;"} },
-- { mnem="sbb a" , opcode=0x , {"aluB", "alurA","aluOpSub" ,"instrNext"}, desc="B-=A, set flags" , ccode={"subf(cpu.b,cpu.a); lni;"} },
-- { mnem="adc a" , opcode=0x , {"aluC", "alurA","aluOpAdd" ,"instrNext"}, desc="C+=A, set flags" , ccode={"addf(cpu.c,cpu.a); lni;"} },
-- { mnem="sbc a" , opcode=0x , {"aluC", "alurA","aluOpSub" ,"instrNext"}, desc="C-=A, set flags" , ccode={"subf(cpu.c,cpu.a); lni;"} },
{ category = "Conditional Branches", catlet="B"},
{ mnem="BNE rel" , opcode=0xD0, ncycles=2, {"loadImmedT","instrSub23Cond","instrNext0NZ" }, {}, {"instrNext"}, {"jmpRelT"}, desc="%if not 0, %brel; %brelc" , ccode={"loadimmedt","if( cpu.nz ) { jmprelt } else { lni }"} },
{ mnem="BEQ rel" , opcode=0xF0, ncycles=2, {"loadImmedT","instrSub23Cond","instrNext0Z" }, {}, {"instrNext"}, {"jmpRelT"}, desc="%if 0, %brel; %brelc" , ccode={"loadimmedt","if(!cpu.nz ) { jmprelt } else { lni }"} },
{ mnem="BLT rel" , opcode=0x90, ncycles=2, {"loadImmedT","instrSub23Cond","instrNext0NC" }, {}, {"instrNext"}, {"jmpRelT"}, desc="%if negative, %brel; %brelc" , ccode={"loadimmedt","if(!cpu.cf ) { jmprelt } else { lni }"} },
{ mnem="BGE rel" , opcode=0xB0, ncycles=2, {"loadImmedT","instrSub23Cond","instrNext0C" }, {}, {"instrNext"}, {"jmpRelT"}, desc="%if positive or 0, %brel; %brelc", ccode={"loadimmedt","if( cpu.cf ) { jmprelt } else { lni }"} },
{ mnem="BGT rel" , opcode=0x30, ncycles=2, {"loadImmedT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"jmpRelT"}, {"instrNext"}, desc="%if positive, %brel; %brelc" , ccode={"loadimmedt","if( cpu.nz && cpu.cf ) { jmprelt } else { lni }"} },
{ mnem="BLE rel" , opcode=0x10, ncycles=2, {"loadImmedT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"instrNext"}, {"jmpRelT"}, desc="%if negative or 0, %brel; %brelc", ccode={"loadimmedt","if((!cpu.nz) || (!cpu.cf)) { jmprelt } else { lni }"} },
{ mnem="BRA rel" , opcode=0x98, {"loadImmedT", "instrSub1"}, {"jmpRelT"}, desc="%brel" , ccode={"loadimmedt", "jmprelt" } },
{ category = "16-bit Arithmetic", catlet = "X"},
{ mnem="ADX #" , opcode=0xE8, {"loadImmedT","instrSub1"}, {"adwP","adwrTX","instrNext"}, desc="Add %imm8 to the 16-bit X register" , ccode={ "loadimmedt","cpu.p=(cpu.p+signed8(cpu.t))%65536; lni;"} },
{ mnem="ADY #" , opcode=0xC8, {"loadImmedT","instrSub1"}, {"adwQ","adwrTX","instrNext"}, desc="Add %imm8 to the 16-bit Y register" , ccode={ "loadimmedt","cpu.q=(cpu.q+signed8(cpu.t))%65536; lni;"} },
-- { mnem="ADS #" , opcode=0x , {"loadImmedT","instrSub1"}, {"adwS","adwrTX","instrNext"}, desc="S+=imm8 signed" , ccode={ "loadimmedt","cpu.s=(cpu.s+signed8(cpu.t))%65536; lni;"} },
{ mnem="ADX ##" , opcode=0x8A, {"loadImm161","instrSub1"},{"loadImm162","instrSub2"}, {"adwP","adwrUT","instrNext"}, desc="Add %imm16 to the 16-bit X register" , ccode={"loadimm161","loadimm162","cpu.p=(cpu.p+wordut )%65536; lni;"} },
{ mnem="ADY ##" , opcode=0x88, {"loadImm161","instrSub1"},{"loadImm162","instrSub2"}, {"adwQ","adwrUT","instrNext"}, desc="Add %imm16 to the 16-bit Y register" , ccode={"loadimm161","loadimm162","cpu.q=(cpu.p+wordut )%65536; lni;"} },
{ mnem="ADX A" , opcode=0xFC, {"adwP","adwrAX","instrNext"}, desc="Add the 8-bit signed value in the A register to the 16-bit X register", ccode={ "cpu.p=(cpu.p+signed8(cpu.a))%65536; lni;"} },
{ mnem="ADY A" , opcode=0xDC, {"adwQ","adwrAX","instrNext"}, desc="Add the 8-bit signed value in the A register to the 16-bit Y register", ccode={ "cpu.q=(cpu.p+signed8(cpu.a))%65536; lni;"} },
-- { mnem="ADS A" , opcode=0x , {"adwS","adwrAX","instrNext"}, desc="S+=B signed", ccode={"cpu.s+=signed8(cpu.b); lni;"} },
{ category = "Jumps" , catlet="J" },
{ mnem="JMP abs" , opcode=0xCC, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT" }, desc="Jump - Set the Program Counter to %imm16, executing the code at that address" , ccode={"loadimm161","loadimm162", "jmpabsut" } },
-- { mnem="jsy abs" , opcode=0x , {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"jmpAbsUT","saveRetAddr"}, desc="I=imm16, Q=I" , ccode={"loadimm161","loadimm162", "jmpabsut saveretaddr"} },
{ mnem="JSR abs" , opcode=0x20, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushRetAddr1","instrSub3"}, {"pushRetAddr2","instrSub4"}, {"jmpAbsUT" }, desc="Jump to Subroutine - Save the Program Counter on the Stack, then set it to %imm16, executing the code at that address" , ccode={"loadimm161","loadimm162","pushretaddr1","pushretaddr2", "jmpabsut" } }, -- 0x21
{ mnem="JMP [ind]", opcode=0x6C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"load161","adrrUT", "adrSaveI","instrSub3"}, {"load162","adrlI","instrSub4"}, {"jmpAbsUT" }, desc="Load a subroutine pointer from memory at a given 16-bit address, then jump to that subroutine, saving the return address on the stack.", ccode={"loadimm161","loadimm162", "cpu.i=(wordut+cpu.a)%65536;cpu.u=readmemory(cpu.i);","cpu.t=readmemory((cpu.i+1)%65536);","jmpabsut" } }, -- 0x6D
{ mnem="JSR [ind]", opcode=0x2C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushRetAddr1","instrSub3"}, {"pushRetAddr2","instrSub4"}, {"load161","adrrUT", "adrSaveI","instrSub5"}, {"load162","adrlI","instrSub6"}, {"jmpAbsUT" }, desc="Load a code pointer from memory at a given 16-bit address, then jump to that code." , ccode={"loadimm161","loadimm162","pushretaddr1","pushretaddr2","cpu.i=(wordut+cpu.a)%65536;cpu.u=readmemory(cpu.i);","cpu.t=readmemory((cpu.i+1)%65536);","jmpabsut" } }, -- 0x2D
{ mnem="JMP [ind,A]",opcode=0x4C,{"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"load161","adrrUT","adrr2A","adrSaveI","instrSub3"}, {"load162","adrlI","instrSub4"}, {"jmpAbsUT" }, desc="Load a subroutine pointer from memory at a given 16-bit address, then jump to that subroutine, saving the return address on the stack.", ccode={"loadimm161","loadimm162", "cpu.i=(wordut+cpu.a)%65536;cpu.u=readmemory(cpu.i);","cpu.t=readmemory((cpu.i+1)%65536);","jmpabsut" } }, -- 0x6D
{ mnem="JSR [ind,A]",opcode=0x0C,{"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushRetAddr1","instrSub3"}, {"pushRetAddr2","instrSub4"}, {"load161","adrrUT","adrr2A","adrSaveI","instrSub5"}, {"load162","adrlI","instrSub6"}, {"jmpAbsUT" }, desc="Load a code pointer from memory at a given 16-bit address, then jump to that code." , ccode={"loadimm161","loadimm162","pushretaddr1","pushretaddr2","cpu.i=(wordut+cpu.a)%65536;cpu.u=readmemory(cpu.i);","cpu.t=readmemory((cpu.i+1)%65536);","jmpabsut" } }, -- 0x2D
{ mnem="JMP X" , opcode=0x64, {"jmpAbsP" }, desc="Set the Program Counter to the 16-bit value in the X register, executing the code at that address" , ccode={ "jmpabsp" } },
{ mnem="JMP Y" , opcode=0x44, {"jmpAbsQ" }, desc="Set the Program Counter to the 16-bit value in the Y register, executing the code at that address" , ccode={ "jmpabsq" } },
-- { mnem="jsy X" , opcode=0x , {"jmpAbsP" ,"saveRetAddr"}, desc="I=P, Q=I" , ccode={ "jmpabsp saveretaddr"} },
-- { mnem="jsy Y" , opcode=0x , {"jmpAbsQ" ,"saveRetAddr"}, desc="I=Q, Q=I" , ccode={ "jmpabsq saveretaddr"} },
{ mnem="JSR X" , opcode=0x24, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsP" }, desc="Save the Program Counter on the Stack, then set it to %X, executing the code at that address" , ccode={ "pushretaddr1","pushretaddr2", "jmpabsp" } },
{ mnem="JSR Y" , opcode=0x04, {"pushRetAddr1","instrSub1"}, {"pushRetAddr2","instrSub2"}, {"jmpAbsQ" }, desc="Save the Program Counter on the Stack, then set it to %Y, executing the code at that address" , ccode={ "pushretaddr1","pushretaddr2", "jmpabsq" } },
{ mnem="RTS" , opcode=0x60, {"pop161" ,"instrSub1"}, {"pop162" ,"instrSub2"}, {"jmpAbsUT","adrInc" }, desc="Retrieve the Program Counter from the stack, returning to where the last JSR instruction was executed" , ccode={"pop161" ,"pop162" , "jmpabsutplus1" } },
{ category = "Stack", catlet="S" },
{ mnem="PHA" , opcode=0x48, {"pushReg","alurA" ,"instrSub1"}, { "instrNext"}, desc="Push %A onto the Stack" , ccode={"pushbyte(cpu.a);","lni;"} },
{ mnem="PHB" , opcode=0x5C, {"pushReg","alurB" ,"instrSub1"}, { "instrNext"}, desc="Push %B onto the Stack" , ccode={"pushbyte(cpu.b);","lni;"} },
{ mnem="PHC" , opcode=0x1C, {"pushReg","alurC" ,"instrSub1"}, { "instrNext"}, desc="Push %C onto the Stack" , ccode={"pushbyte(cpu.c);","lni;"} },
{ mnem="PHP" , opcode=0x08, {"pushReg","alurF" ,"instrSub1"}, { "instrNext"}, desc="Push a byte containing the Carry Flag and Zero Flag onto the Stack" , ccode={"int f = cpu.nz | (cpu.cf<<1); pushbyte(f);","lni;"} },
{ mnem="PHX" , opcode=0x54, {"pushReg","alurPH","instrSub1"}, {"pushReg","alurPL" ,"instrSub2"}, { "instrNext"}, desc="Push %X onto the Stack" , ccode={"push161(cpu.p);","push162(cpu.p);","lni;"} },
{ mnem="PHY" , opcode=0x14, {"pushReg","alurQH","instrSub1"}, {"pushReg","alurQL" ,"instrSub2"}, { "instrNext"}, desc="Push %Y onto the Stack" , ccode={"push161(cpu.q);","push162(cpu.q);","lni;"} },
{ mnem="PLA" , opcode=0x68, {"popReg","memSaveA","instrSub1"}, { "instrNext"}, desc="Pull a byte from the Stack, and store it in the A register" , ccode={"cpu.a=popbyte;","lni;"} },
{ mnem="PLB" , opcode=0x7C, {"popReg","memSaveB","instrSub1"}, { "instrNext"}, desc="Pull a byte from the Stack, and store it in the B register" , ccode={"cpu.b=popbyte;","lni;"} },
{ mnem="PLC" , opcode=0x3C, {"popReg","memSaveC","instrSub1"}, { "instrNext"}, desc="Pull a byte from the Stack, and store it in the C register" , ccode={"cpu.c=popbyte;","lni;"} },
{ mnem="PLP" , opcode=0x28, {"popReg","memSaveF","instrSub1"}, { "instrNext"}, desc="Pull a byte from the Stack, and use it to set the Carry Flag and Zero flag" , ccode={"int f=popbyte; cpu.nz = f&1; cpu.cf = (f>>1)&1;","lni;"} },
{ mnem="PLX" , opcode=0x74, {"pop161", "instrSub1"}, {"pop162", "instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="Pull two bytes from the stack, and store the resulting 16-bit value in the X register", ccode={"pop161","pop162","cpu.p=wordut; lni;"} },
{ mnem="PLY" , opcode=0x34, {"pop161", "instrSub1"}, {"pop162", "instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Pull two bytes from the stack, and store the resulting 16-bit value in the Y register", ccode={"pop161","pop162","cpu.q=wordut; lni;"} },
-- { mnem="psh imm8" , opcode=0x , {"loadImmedT","instrSub1"}, {"pushReg","alurT","instrSub2"}, {"instrNext"}, desc="*(S++)=imm8", ccode={"loadimmedt;","pushbyte(cpu.t);","lni;"} },
-- { mnem="phw imm16", opcode=0x , {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"pushReg","alurU","instrSub3"}, {"pushReg","alurT","instrSub4"}, {"instrNext"}, desc="*(S++++)=imm16", ccode={"loadimm161","loadimm162","pushbyte(cpu.u);","pushbyte(cpu.t);","lni;"} }, -- 0x3D
{ category = "8-bit Load/Store", catlet="B" },
{ mnem="LDA #" , opcode=0xA9, {"loadImmed" , "memSaveA", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="Set the A register to %imm8" , ccode={"cpu.a=loadimmed; setzf(cpu.a);","lni;"} },
{ mnem="LDB #" , opcode=0xAB, {"loadImmed" , "memSaveB", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="Set the B register to %imm8" , ccode={"cpu.b=loadimmed; setzf(cpu.b);","lni;"} },
{ mnem="LDC #" , opcode=0x2B, {"loadImmed" , "memSaveC", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="Set the C register to %imm8" , ccode={"cpu.c=loadimmed; setzf(cpu.c);","lni;"} },
{ mnem="LDA zpg" , opcode=0xA5, {"loadImmedT","instrSub1"}, {"loadStackRel" , "memSaveA", "memSaveFlags","instrSub2"}, {"instrNext"}, desc="Set the A register to %zpgIn, %zFlgMem" , ccode={"loadimmedt;","cpu.a=loadstackrel; setzf(cpu.a);","lni;"} },
{ mnem="LDB zpg" , opcode=0xA7, {"loadImmedT","instrSub1"}, {"loadStackRel" , "memSaveB", "memSaveFlags","instrSub2"}, {"instrNext"}, desc="Set the B register to %zpgIn, %zFlgMem" , ccode={"loadimmedt;","cpu.b=loadstackrel; setzf(cpu.b);","lni;"} },
{ mnem="LDC zpg" , opcode=0x27, {"loadImmedT","instrSub1"}, {"loadStackRel" , "memSaveC", "memSaveFlags","instrSub2"}, {"instrNext"}, desc="Set the C register to %zpgIn, %zFlgMem" , ccode={"loadimmedt;","cpu.c=loadstackrel; setzf(cpu.c);","lni;"} },
{ mnem="STA zpg" , opcode=0x85, {"loadImmedT","instrSub1"}, {"storeStackRel", "alurA", "instrSub2"}, {"instrNext"}, desc="Store %A in memory at %zpg" , ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
{ mnem="STB zpg" , opcode=0x87, {"loadImmedT","instrSub1"}, {"storeStackRel", "alurB", "instrSub2"}, {"instrNext"}, desc="Store %B in memory at %zpg" , ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
{ mnem="STC zpg" , opcode=0x07, {"loadImmedT","instrSub1"}, {"storeStackRel", "alurC", "instrSub2"}, {"instrNext"}, desc="Store %C in memory at %zpg" , ccode={"loadimmedt;","storestackrel(cpu.a);","lni;"} },
{ mnem="LDA abs" , opcode=0xED, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "loadReg" ,"memSaveA", "memSaveFlags","instrSub3"}, {"instrNext"}, desc="Set the A register to %absIn, %zFlgMem" , ccode={"loadimm161","loadimm162","cpu.a=loadut; setzf(cpu.a);", "lni;"} },
{ mnem="LDB abs" , opcode=0xEF, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "loadReg" ,"memSaveB", "memSaveFlags","instrSub3"}, {"instrNext"}, desc="Set the B register to %absIn, %zFlgMem" , ccode={"loadimm161","loadimm162","cpu.b=loadut; setzf(cpu.b);", "lni;"} },
{ mnem="LDC abs" , opcode=0x6F, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "loadReg" ,"memSaveC", "memSaveFlags","instrSub3"}, {"instrNext"}, desc="Set the C register to %absIn, %zFlgMem" , ccode={"loadimm161","loadimm162","cpu.c=loadut; setzf(cpu.c);", "lni;"} },
{ mnem="STA abs" , opcode=0xCD, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "storeReg","alurA", "instrSub3"}, {"instrNext"}, desc="Store %A in memory at %abs" , ccode={"loadimm161","loadimm162","storeut(cpu.a);", "lni;"} },
{ mnem="STB abs" , opcode=0xCF, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "storeReg","alurB", "instrSub3"}, {"instrNext"}, desc="Store %B in memory at %abs" , ccode={"loadimm161","loadimm162","storeut(cpu.b);", "lni;"} },
{ mnem="STC abs" , opcode=0x4F, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"adrrUT", "storeReg","alurC", "instrSub3"}, {"instrNext"}, desc="Store %C in memory at %abs" , ccode={"loadimm161","loadimm162","storeut(cpu.c);", "lni;"} },
{ mnem="LDA X" , opcode=0xA1, {"adrlP", "loadReg" ,"memSaveA", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="Set the A register to %xIn, %zFlgMem" , ccode={"cpu.a=loadp; setzf(cpu.a);","lni;"} },
{ mnem="LDB X" , opcode=0xA3, {"adrlP", "loadReg" ,"memSaveB", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="Set the B register to %xIn, %zFlgMem" , ccode={"cpu.b=loadp; setzf(cpu.b);","lni;"} },
{ mnem="LDC X" , opcode=0x23, {"adrlP", "loadReg" ,"memSaveC", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="Set the C register to %xIn, %zFlgMem" , ccode={"cpu.c=loadp; setzf(cpu.c);","lni;"} },
{ mnem="LDA Y" , opcode=0xB1, {"adrlQ", "loadReg" ,"memSaveA", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="Set the A register to %yIn, %zFlgMem" , ccode={"cpu.a=loadq; setzf(cpu.a);","lni;"} },
{ mnem="LDB Y" , opcode=0xB3, {"adrlQ", "loadReg" ,"memSaveB", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="Set the B register to %yIn, %zFlgMem" , ccode={"cpu.b=loadq; setzf(cpu.b);","lni;"} },
{ mnem="LDC Y" , opcode=0x33, {"adrlQ", "loadReg" ,"memSaveC", "memSaveFlags","instrSub1"}, {"instrNext"}, desc="Set the C register to %yIn, %zFlgMem" , ccode={"cpu.c=loadq; setzf(cpu.c);","lni;"} },
{ mnem="STA X" , opcode=0x81, {"adrlP", "storeReg","alurA", "instrSub1"}, {"instrNext"}, desc="Store %A in memory at %adrX" , ccode={"storep(cpu.a);","lni;"} },
{ mnem="STB X" , opcode=0x83, {"adrlP", "storeReg","alurB", "instrSub1"}, {"instrNext"}, desc="Store %B in memory at %adrX" , ccode={"storep(cpu.b);","lni;"} },
{ mnem="STC X" , opcode=0x03, {"adrlP", "storeReg","alurC", "instrSub1"}, {"instrNext"}, desc="Store %C in memory at %adrX" , ccode={"storep(cpu.c);","lni;"} },
{ mnem="STA Y" , opcode=0x91, {"adrlQ", "storeReg","alurA", "instrSub1"}, {"instrNext"}, desc="Store %A in memory at %adrY" , ccode={"storeq(cpu.a);","lni;"} },
{ mnem="STB Y" , opcode=0x93, {"adrlQ", "storeReg","alurB", "instrSub1"}, {"instrNext"}, desc="Store %B in memory at %adrY" , ccode={"storeq(cpu.b);","lni;"} },
{ mnem="STC Y" , opcode=0x13, {"adrlQ", "storeReg","alurC", "instrSub1"}, {"instrNext"}, desc="Store %C in memory at %adrY" , ccode={"storeq(cpu.c);","lni;"} },
{ mnem="LDA X+" , opcode=0xE1, {"adrlP", "loadReg" ,"memSaveA","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="Set the A register to %xIn, %xInc, %zFlgMem", ccode={"cpu.a=loadpinc; setzf(cpu.a);","lni;"} },
{ mnem="LDB X+" , opcode=0xE3, {"adrlP", "loadReg" ,"memSaveB","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="Set the B register to %xIn, %xInc, %zFlgMem", ccode={"cpu.b=loadpinc; setzf(cpu.b);","lni;"} },
{ mnem="LDC X+" , opcode=0x63, {"adrlP", "loadReg" ,"memSaveC","incP","memSaveFlags","instrSub1"}, {"instrNext"}, desc="Set the C register to %xIn, %xInc, %zFlgMem", ccode={"cpu.c=loadpinc; setzf(cpu.c);","lni;"} },
{ mnem="LDA Y+" , opcode=0xF1, {"adrlQ", "loadReg" ,"memSaveA","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="Set the A register to %yIn, %yInc, %zFlgMem", ccode={"cpu.a=loadqinc; setzf(cpu.a);","lni;"} },
{ mnem="LDB Y+" , opcode=0xF3, {"adrlQ", "loadReg" ,"memSaveB","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="Set the B register to %yIn, %yInc, %zFlgMem", ccode={"cpu.b=loadqinc; setzf(cpu.b);","lni;"} },
{ mnem="LDC Y+" , opcode=0x73, {"adrlQ", "loadReg" ,"memSaveC","incQ","memSaveFlags","instrSub1"}, {"instrNext"}, desc="Set the C register to %yIn, %yInc, %zFlgMem", ccode={"cpu.c=loadqinc; setzf(cpu.c);","lni;"} },
{ mnem="STA X+" , opcode=0xC1, {"adrlP", "storeReg","alurA", "incP", "instrSub1"}, {"instrNext"}, desc="Store %A in memory at %adrX, and %xInc" , ccode={"storepinc(cpu.a);","lni;"} },
{ mnem="STB X+" , opcode=0xC3, {"adrlP", "storeReg","alurB", "incP", "instrSub1"}, {"instrNext"}, desc="Store %B in memory at %adrX, and %xInc" , ccode={"storepinc(cpu.b);","lni;"} },
{ mnem="STC X+" , opcode=0x43, {"adrlP", "storeReg","alurC", "incP", "instrSub1"}, {"instrNext"}, desc="Store %C in memory at %adrX, and %xInc" , ccode={"storepinc(cpu.c);","lni;"} },
{ mnem="STA Y+" , opcode=0xD1, {"adrlQ", "storeReg","alurA", "incQ", "instrSub1"}, {"instrNext"}, desc="Store %A in memory at %adrY, and %yInc" , ccode={"storeqinc(cpu.a);","lni;"} },
{ mnem="STB Y+" , opcode=0xD3, {"adrlQ", "storeReg","alurB", "incQ", "instrSub1"}, {"instrNext"}, desc="Store %B in memory at %adrY, and %yInc" , ccode={"storeqinc(cpu.b);","lni;"} },
{ mnem="STC Y+" , opcode=0x53, {"adrlQ", "storeReg","alurC", "incQ", "instrSub1"}, {"instrNext"}, desc="Store %C in memory at %adrY, and %yInc" , ccode={"storeqinc(cpu.c);","lni;"} },
{ mnem="LDA X,ofs", opcode=0xBD, {"loadImmedT","instrSub1"}, {"adrlP","adrrlT","loadReg" ,"memSaveA", "memSaveFlags","instrSub2"}, {"instrNext"}, desc="Set the A register to %XofsIn, %zFlgMem" , ccode={"loadimm161","loadimm162","cpu.a=loadput; setzf(cpu.a);","lni;"} },
{ mnem="LDB X,ofs", opcode=0xBF, {"loadImmedT","instrSub1"}, {"adrlP","adrrlT","loadReg" ,"memSaveB", "memSaveFlags","instrSub2"}, {"instrNext"}, desc="Set the B register to %XofsIn, %zFlgMem" , ccode={"loadimm161","loadimm162","cpu.b=loadput; setzf(cpu.b);","lni;"} },
{ mnem="LDC X,ofs", opcode=0x3F, {"loadImmedT","instrSub1"}, {"adrlP","adrrlT","loadReg" ,"memSaveC", "memSaveFlags","instrSub2"}, {"instrNext"}, desc="Set the C register to %XofsIn, %zFlgMem" , ccode={"loadimm161","loadimm162","cpu.c=loadput; setzf(cpu.c);","lni;"} },
{ mnem="LDA Y,ofs", opcode=0xB9, {"loadImmedT","instrSub1"}, {"adrlQ","adrrlT","loadReg" ,"memSaveA", "memSaveFlags","instrSub2"}, {"instrNext"}, desc="Set the A register to %YofsIn, %zFlgMem" , ccode={"loadimm161","loadimm162","cpu.a=loadqut; setzf(cpu.a);","lni;"} },
{ mnem="LDB Y,ofs", opcode=0xBB, {"loadImmedT","instrSub1"}, {"adrlQ","adrrlT","loadReg" ,"memSaveB", "memSaveFlags","instrSub2"}, {"instrNext"}, desc="Set the B register to %YofsIn, %zFlgMem" , ccode={"loadimm161","loadimm162","cpu.b=loadqut; setzf(cpu.b);","lni;"} },
{ mnem="LDC Y,ofs", opcode=0x3B, {"loadImmedT","instrSub1"}, {"adrlQ","adrrlT","loadReg" ,"memSaveC", "memSaveFlags","instrSub2"}, {"instrNext"}, desc="Set the C register to %YofsIn, %zFlgMem" , ccode={"loadimm161","loadimm162","cpu.c=loadqut; setzf(cpu.c);","lni;"} },
{ mnem="STA X,ofs", opcode=0x9D, {"loadImmedT","instrSub1"}, {"adrlP","adrrlT","storeReg","alurA", "instrSub2"}, {"instrNext"}, desc="Store %A in memory at %Xofs" , ccode={"loadimm161","loadimm162","storeput(cpu.a);", "lni;"} },
{ mnem="STB X,ofs", opcode=0x9F, {"loadImmedT","instrSub1"}, {"adrlP","adrrlT","storeReg","alurB", "instrSub2"}, {"instrNext"}, desc="Store %A in memory at %Xofs" , ccode={"loadimm161","loadimm162","storeput(cpu.b);", "lni;"} },
{ mnem="STC X,ofs", opcode=0x1F, {"loadImmedT","instrSub1"}, {"adrlP","adrrlT","storeReg","alurC", "instrSub2"}, {"instrNext"}, desc="Store %A in memory at %Xofs" , ccode={"loadimm161","loadimm162","storeput(cpu.c);", "lni;"} },
{ mnem="STA Y,ofs", opcode=0x99, {"loadImmedT","instrSub1"}, {"adrlQ","adrrlT","storeReg","alurA", "instrSub2"}, {"instrNext"}, desc="Store %A in memory at %Yofs" , ccode={"loadimm161","loadimm162","storequt(cpu.a);", "lni;"} },
{ mnem="STB Y,ofs", opcode=0x9B, {"loadImmedT","instrSub1"}, {"adrlQ","adrrlT","storeReg","alurB", "instrSub2"}, {"instrNext"}, desc="Store %A in memory at %Yofs" , ccode={"loadimm161","loadimm162","storequt(cpu.b);", "lni;"} },
{ mnem="STC Y,ofs", opcode=0x1B, {"loadImmedT","instrSub1"}, {"adrlQ","adrrlT","storeReg","alurC", "instrSub2"}, {"instrNext"}, desc="Store %A in memory at %Yofs" , ccode={"loadimm161","loadimm162","storequt(cpu.c);", "lni;"} },
{ category = "16-bit Load/Store", catlet="W" },
{ mnem="LDX ##" , opcode=0xAA, {"loadImm161" ,"instrSub1"}, {"loadImm162" ,"instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="Set the X register to %imm16" , ccode={"loadimm161","loadimm162","cpu.p=wordut; lni;"} },
{ mnem="LDY ##" , opcode=0xA8, {"loadImm161" ,"instrSub1"}, {"loadImm162" ,"instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Set the X register to %imm16" , ccode={"loadimm161","loadimm162","cpu.q=wordut; lni;"} },
-- { mnem="lds imm16", opcode=0x , {"loadImm161" ,"instrSub1"}, {"loadImm162" ,"instrSub2"}, {"adwrUT","adwSaveS","instrNext"}, desc="S=imm16" , ccode={"loadimm161","loadimm162","cpu.s=wordut; lni;"} },
-- { mnem="ldv imm16", opcode=0x , {"loadImm161" ,"instrSub1"}, {"loadImm162" ,"instrSub2"}, {"adwrUT","adwSaveV","instrNext"}, desc="V=imm16" , ccode={"loadimm161","loadimm162","cpu.v=wordut; lni;"} },
{ mnem="LDX zpg" , opcode=0xA6, {"loadImmedT","instrSub1"}, {"loadStackRel161" ,"instrSub2"}, {"loadStackRel162" ,"instrSub3"}, {"adwrUT","adwSaveP","instrNext"}, desc="Set the X register to %zpgIn16" , ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} },
{ mnem="LDY zpg" , opcode=0xA4, {"loadImmedT","instrSub1"}, {"loadStackRel161" ,"instrSub2"}, {"loadStackRel162" ,"instrSub3"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Set the Y register to %zpgIn16" , ccode={"loadimmedt","loadstackrel161","loadstackrel162","cpu.p=wordut; lni;"} },
{ mnem="STX zpg" , opcode=0x86, {"loadImmedT","instrSub1"}, {"storeStackRel161" ,"alurPH" ,"instrSub2"}, {"storeStackRel162" ,"alurPL" ,"instrSub3"}, { "instrNext"}, desc="Store %X in memory at %zpg" , ccode={"loadimmedt","storestackrel161(cpu.p);","storestackrel162(cpu.p);","lni;"} },
{ mnem="STY zpg" , opcode=0x84, {"loadImmedT","instrSub1"}, {"storeStackRel161" ,"alurQH" ,"instrSub2"}, {"storeStackRel162" ,"alurQL" ,"instrSub3"}, { "instrNext"}, desc="Store %Y in memory at %zpg" , ccode={"loadimmedt","storestackrel161(cpu.q);","storestackrel162(cpu.q);","lni;"} },
{ mnem="LDX abs" , opcode=0xAE, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU","adwIncUT" ,"adwSaveP","instrSub3"}, {"adrlP","loadRegT" ,"instrSub4"}, {"adwrUT","adwSaveP","instrNext"}, desc="Set the X register to %absIn16" , ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} }, -- 0x69
{ mnem="LDY abs" , opcode=0xAC, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"loadUTU","adwIncUT" ,"adwSaveQ","instrSub3"}, {"adrlQ","loadRegT" ,"instrSub4"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Set the Y register to %absIn16" , ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} }, -- 0x6B
{ mnem="STX abs" , opcode=0x8E, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT" ,"alurPH" ,"instrSub3"}, {"storeUT","adrInc" ,"alurPL" ,"instrSub4"}, { "instrNext"}, desc="Store %X in memory at %abs" , ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.p));","storeutp1(lobyte(cpu.p));","lni;" } }, -- 0x6D
{ mnem="STY abs" , opcode=0x8C, {"loadImm161","instrSub1"}, {"loadImm162","instrSub2"}, {"storeUT" ,"alurQH" ,"instrSub3"}, {"storeUT","adrInc" ,"alurQL" ,"instrSub4"}, { "instrNext"}, desc="Store %X in memory at %abs" , ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.q));","storeutp1(lobyte(cpu.q));","lni;" } }, -- 0x6F
{ mnem="LDX X,ofs", opcode=0xBE, {"loadImmedT","instrSub1"}, {"adrlP","adrrlT","loadReg" ,"memSaveU","instrSub2"}, {"adrlP","adrrlT","adrInc","loadReg" ,"memSaveT","instrSub3"}, {"adwrUT","adwSaveP","instrNext"}, desc="Set the X register to %XofsIn16" , ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} },
{ mnem="LDX Y,ofs", opcode=0xBA, {"loadImmedT","instrSub1"}, {"adrlQ","adrrlT","loadReg" ,"memSaveU","instrSub2"}, {"adrlP","adrrlT","adrInc","loadReg" ,"memSaveT","instrSub3"}, {"adwrUT","adwSaveP","instrNext"}, desc="Set the Y register to %XofsIn16" , ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} },
{ mnem="LDY X,ofs", opcode=0xBC, {"loadImmedT","instrSub1"}, {"adrlP","adrrlT","loadReg" ,"memSaveU","instrSub2"}, {"adrlP","adrrlT","adrInc","loadReg" ,"memSaveT","instrSub3"}, {"adwrUT","adwSaveP","instrNext"}, desc="Set the X register to %YofsIn16" , ccode={"loadimm161","loadimm162","cpu.p=wordut; cpu.u=loadut;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} },
{ mnem="LDY Y,ofs", opcode=0xB8, {"loadImmedT","instrSub1"}, {"adrlQ","adrrlT","loadReg" ,"memSaveU","instrSub2"}, {"adrlP","adrrlT","adrInc","loadReg" ,"memSaveT","instrSub3"}, {"adwrUT","adwSaveP","instrNext"}, desc="Set the Y register to %YofsIn16" , ccode={"loadimm161","loadimm162","cpu.q=wordut; cpu.u=loadut;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} },
{ mnem="STX Y,ofs", opcode=0x9A, {"loadImmedT","instrSub1"}, {"adrlQ","adrrlT","storeReg","alurPH" ,"instrSub2"}, {"adrlP","adrrlT","adrInc","storeReg","alurPL" ,"instrSub3"}, { "instrNext"}, desc="Store %X in memory at %Yofs" , ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.p));","storeutp1(lobyte(cpu.p));","lni;" } },
{ mnem="STY X,ofs", opcode=0x9C, {"loadImmedT","instrSub1"}, {"adrlP","adrrlT","storeReg","alurQH" ,"instrSub2"}, {"adrlP","adrrlT","adrInc","storeReg","alurQL" ,"instrSub3"}, { "instrNext"}, desc="Store %Y in memory at %Xofs" , ccode={"loadimm161","loadimm162","storeut(hibyte(cpu.q));","storeutp1(lobyte(cpu.q));","lni;" } },
{ mnem="LDX X" , opcode=0xA2, {"adrlP","load161" ,"instrSub1"}, {"adrlP","load162" ,"instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="Set the X register to %Xin16" , ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.p=wordut; lni;"} },
{ mnem="LDY X" , opcode=0xA0, {"adrlP","load161" ,"instrSub1"}, {"adrlP","load162" ,"instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Set the Y register to %Xin16" , ccode={"cpu.u=loadp;","cpu.t=loadpp1;","cpu.q=wordut; lni;"} },
{ mnem="LDX Y" , opcode=0xB2, {"adrlQ","load161" ,"instrSub1"}, {"adrlQ","load162" ,"instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="Set the X register to %Yin16" , ccode={"cpu.u=loadq;","cpu.t=loadqp1;","cpu.p=wordut; lni;"} },
{ mnem="LDY Y" , opcode=0xE2, {"adrlQ","load161" ,"instrSub1"}, {"adrlQ","load162" ,"instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Set the Y register to %Yin16" , ccode={"cpu.u=loadq;","cpu.t=loadqp1;","cpu.q=wordut; lni;"} },
{ mnem="STX Y" , opcode=0x92, {"adrlQ","store161" ,"alurPH" ,"instrSub1"}, {"adrlQ","store162" ,"alurPL" ,"instrSub2"}, { "instrNext"}, desc="Store %X in memory at %adrY" , ccode={"storeq(hibyte(cpu.p));","storeqp1(lobyte(cpu.p));","lni;"} },
{ mnem="STY X" , opcode=0x80, {"adrlP","store161" ,"alurQH" ,"instrSub1"}, {"adrlP","store162" ,"alurQL" ,"instrSub2"}, { "instrNext"}, desc="Store %Y in memory at %adrX" , ccode={"storep(hibyte(cpu.q));","storepp1(lobyte(cpu.q));","lni;"} },
{ mnem="LDX Y+" , opcode=0xF2, {"adrlQ","load161" ,"instrSub1"}, {"adrlQ","load162" ,"incQ2" ,"instrSub2"}, {"adwrUT","adwSaveP","instrNext"}, desc="Set the X register to %Yin16, %Yinc16", ccode={"cpu.u=loadqinc;","cpu.t=loadqinc;","cpu.p=wordut; lni;"} },
{ mnem="LDY X+" , opcode=0xE0, {"adrlP","load161" ,"instrSub1"}, {"adrlP","load162" ,"incP2" ,"instrSub2"}, {"adwrUT","adwSaveQ","instrNext"}, desc="Set the Y register to %Xin16, %Xinc16", ccode={"cpu.u=loadpinc;","cpu.t=loadpinc;","cpu.q=wordut; lni;"} },
{ mnem="STX Y+" , opcode=0xD2, {"adrlQ","store161" ,"alurPH" ,"instrSub1"}, {"adrlQ","store162","incQ2" ,"alurPL" ,"instrSub2"}, { "instrNext"}, desc="Store %X in memory at %adrY, %Yinc16" , ccode={"storeqinc(hibyte(cpu.p));","storeqinc(lobyte(cpu.p));","lni;"} },
{ mnem="STY X+" , opcode=0xC0, {"adrlP","store161" ,"alurQH" ,"instrSub1"}, {"adrlP","store162","incP2" ,"alurQL" ,"instrSub2"}, { "instrNext"}, desc="Store %Y in memory at %adrX, %Xinc16" , ccode={"storepinc(hibyte(cpu.q));","storepinc(lobyte(cpu.q));","lni;"} },
{ category = "Moves", catlet="M" },
{ mnem="TBA" , opcode=0x97, {"alurB" ,"aluOpMov","aluSaveA","instrNext"}, desc="Copy %B into the A register", ccode={"cpu.a=cpu.b; lni;"} },
{ mnem="TCA" , opcode=0x17, {"alurC" ,"aluOpMov","aluSaveA","instrNext"}, desc="Copy %C into the A register", ccode={"cpu.a=cpu.c; lni;"} },
{ mnem="TAB" , opcode=0xB7, {"alurA" ,"aluOpMov","aluSaveB","instrNext"}, desc="Copy %A into the B register", ccode={"cpu.b=cpu.a; lni;"} },
{ mnem="TCB" , opcode=0xD7, {"alurC" ,"aluOpMov","aluSaveB","instrNext"}, desc="Copy %C into the B register", ccode={"cpu.b=cpu.c; lni;"} },
{ mnem="TAC" , opcode=0x37, {"alurA" ,"aluOpMov","aluSaveC","instrNext"}, desc="Copy %A into the C register", ccode={"cpu.c=cpu.a; lni;"} },
{ mnem="TBC" , opcode=0xF7, {"alurB" ,"aluOpMov","aluSaveC","instrNext"}, desc="Copy %B into the C register", ccode={"cpu.c=cpu.b; lni;"} },
-- { mnem="lda pl" , opcode=0x , {"alurPL","aluOpMov","aluSaveA","instrNext"}, desc="A=P&FF" , ccode={"cpu.a=lobyte(cpu.p); lni;"} },
-- { mnem="lda ph" , opcode=0x , {"alurPH","aluOpMov","aluSaveA","instrNext"}, desc="A=P>>8" , ccode={"cpu.a=hibyte(cpu.p); lni;"} },
-- { mnem="lda ql" , opcode=0x , {"alurQL","aluOpMov","aluSaveA","instrNext"}, desc="A=Q&FF" , ccode={"cpu.a=lobyte(cpu.q); lni;"} },
-- { mnem="lda qh" , opcode=0x , {"alurQH","aluOpMov","aluSaveA","instrNext"}, desc="A=Q>>8" , ccode={"cpu.a=hibyte(cpu.q); lni;"} },
-- { mnem="ldb pl" , opcode=0x , {"alurPL","aluOpMov","aluSaveB","instrNext"}, desc="B=P&FF" , ccode={"cpu.b=lobyte(cpu.p); lni;"} },
-- { mnem="ldc ph" , opcode=0x , {"alurPH","aluOpMov","aluSaveC","instrNext"}, desc="C=P>>8" , ccode={"cpu.c=hibyte(cpu.p); lni;"} },
-- { mnem="ldb ql" , opcode=0x , {"alurQL","aluOpMov","aluSaveB","instrNext"}, desc="B=Q&FF" , ccode={"cpu.b=lobyte(cpu.q); lni;"} },
-- { mnem="ldc qh" , opcode=0x , {"alurQH","aluOpMov","aluSaveC","instrNext"}, desc="C=Q>>8" , ccode={"cpu.c=hibyte(cpu.q); lni;"} },
{ mnem="TYX" , opcode=0xB4, {"adwlQ" , "adwSaveP","instrNext"}, desc="Copy %Y into the 16-bit X register", ccode={"cpu.p=cpu.q; lni;"} },
{ mnem="TXY" , opcode=0x94, {"adwlP" , "adwSaveQ","instrNext"}, desc="Copy %X into the 16-bit Y register", ccode={"cpu.q=cpu.p; lni;"} },
{ mnem="TVX" , opcode=0xB6, {"adwlV" , "adwSaveP","instrNext"}, desc="Copy the 16-bit Interrupt Return Address into the X register", ccode={"cpu.v=cpu.p; lni;"} },
{ mnem="TXV" , opcode=0x96, {"adwlP" , "adwSaveV","instrNext"}, desc="Copy %X into the 16-bit Interrupt Return Address register", ccode={"cpu.p=cpu.v; lni;"} },
-- { mnem="ldp i" , opcode=0x , {"adwlI" , "adwSaveP","instrNext"}, desc="P=I", ccode={"cpu.p=cpu.i; lni;"} },
-- { mnem="ldp cb" , opcode=0x , {"adwrCB", "adwSaveP","instrNext"}, desc="P=(C<<8)+B", ccode={"cpu.p=wordcb; lni;"} },
-- { mnem="ldq cb" , opcode=0x , {"adwrCB", "adwSaveQ","instrNext"}, desc="Q=(C<<8)+B", ccode={"cpu.q=wordcb; lni;"} },
{ mnem="TAS" , opcode=0x95, {"adwrlA", "adwSaveS","instrNext"}, desc="Copy %A into the 8-bit Stack Pointer register", ccode={"cpu.p=cpu.s; lni;"} },
{ mnem="TSA" , opcode=0xB5, {"alurSL","aluOpMov","aluSaveB","instrNext"}, desc="Copy the 8-bit Stack Pointer into the A register", ccode={"cpu.s=cpu.p; lni;"} },
}
if not __ARCH_INCLUDED then
local arch8608 = require("8608-definition")
arch8608.instructions = instructions
local gen = require("generate-architecture")
gen(arch8608, true, true)
end
return instructions

986
8608.asm
View File

@ -1,798 +1,202 @@
; 8608.asm
; Include this file into a customasm assembly file to use the 8608 architecture, like so:
; Include this file into a CustomAsm assembly file to use the 8608 architecture, like so:
; #include "8608.asm"
; See CustomAsm for more info: https://github.com/hlorenzi/customasm
; Generated by generate-architecture.lua using the definitions in 8608-definition.lua
; Definitions for all instructions in the 8608 architecture.
#subruledef rel8 {
{addr} => {
reladdr = addr - $ - 2
assert(reladdr <= 127, "Relative jump target is too far away")
assert(reladdr >= -128, "Relative jump target is too far away")
reladdr`8
}
}
#subruledef neg8 {
{value} => {
mvalue = -value
mvalue`8
}
}
#ruledef {
rst => $00
hlt => $F0
run => $F1
int => $F2
brk => $F3
irt => $F4
nop => $FF
ien => $F5
idi => $F6
inc p => $12
dec p => $15
inc q => $13
dec q => $16
inc a => $10
dec a => $11
icc a => $1B
inc b => $19
dec b => $1A
icc b => $1C
inc c => $17
dec c => $18
icc c => $1D
tst a => $14
tst b => $1E
tst c => $1F
inc *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$2B @ value`8
}
inc *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$2B @ mvalue`8
}
dec *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$2C @ value`8
}
dec *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$2C @ mvalue`8
}
icc *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$2D @ value`8
}
icc *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$2D @ mvalue`8
}
tst *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$2E @ value`8
}
tst *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$2E @ mvalue`8
}
adp {value: i8} => $4A @ value
adq {value: i8} => $4B @ value
ads {value: i8} => $4C @ value
adp b => $E6
adq b => $E7
ads b => $E8
add {value: i8} => $24 @ value
sub {value:i8} => {
mvalue = -value
$24 @ mvalue`8
}
adb {value: i8} => $72 @ value
sbb {value:i8} => {
mvalue = -value
$72 @ mvalue`8
}
adc {value: i8} => $73 @ value
sbc {value:i8} => {
mvalue = -value
$73 @ mvalue`8
}
acc {value: i8} => $78 @ value
scc {value:i8} => {
mvalue = -value
$78 @ mvalue`8
}
cmp {value: i8} => $71 @ value
and {value: i8} => $74 @ value
ior {value: i8} => $75 @ value
xor {value: i8} => $76 @ value
shl {value: i8} => $D0 @ value
shr {value: i8} => $D1 @ value
rol {value: i8} => $D2 @ value
ror {value: i8} => $D3 @ value
sra {value: i8} => $D4 @ value
add *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$AE @ value`8
}
add *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$AE @ mvalue`8
}
adb *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$9B @ value`8
}
adb *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$9B @ mvalue`8
}
adc *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$9C @ value`8
}
adc *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$9C @ mvalue`8
}
sub *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$AF @ value`8
}
sub *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$AF @ mvalue`8
}
sbb *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$9D @ value`8
}
sbb *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$9D @ mvalue`8
}
sbc *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$9E @ value`8
}
sbc *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$9E @ mvalue`8
}
acc *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$B5 @ value`8
}
acc *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$B5 @ mvalue`8
}
scc *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$B7 @ value`8
}
scc *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$B7 @ mvalue`8
}
cmp *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$B0 @ value`8
}
cmp *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$B0 @ mvalue`8
}
and *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$B1 @ value`8
}
and *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$B1 @ mvalue`8
}
ior *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$B2 @ value`8
}
ior *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$B2 @ mvalue`8
}
xor *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$B3 @ value`8
}
xor *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$B3 @ mvalue`8
}
shl *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$D5 @ value`8
}
shl *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$D5 @ mvalue`8
}
shr *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$D6 @ value`8
}
shr *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$D6 @ mvalue`8
}
rol *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$D7 @ value`8
}
rol *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$D7 @ mvalue`8
}
ror *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$D8 @ value`8
}
ror *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$D8 @ mvalue`8
}
sra *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$D9 @ value`8
}
sra *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$D9 @ mvalue`8
}
add b => $A0
adc b => $9F
sub b => $A1
sbc b => $B6
acc b => $B8
scc b => $B9
cmp b => $A2
and b => $A3
ior b => $A4
xor b => $A5
shl b => $DA
shr b => $DB
rol b => $DC
ror b => $DD
sra b => $DE
add c => $A7
adb c => $BD
sub c => $A8
sbb c => $BC
acc c => $BA
scc c => $BB
cmp c => $A9
and c => $AA
ior c => $AB
xor c => $AC
shl c => $DF
shr c => $4D
rol c => $3E
ror c => $3F
sra c => $2F
adb a => $BE
sbb a => $BF
adc a => $4E
sbc a => $4F
jmp {value: i16} => $60 @ value
jsr {value: i16} => $63 @ value
jss {value: i16} => $E2 @ value
jmp p => $64
jmp q => $66
ret => $66
jsr p => $65
jsr q => $67
jss p => $E4
jss q => $E5
rts => $E1
jpr {addr} => {
reladdr = addr - $ - 2
assert(reladdr <= 127, "jpr: Relative jump target is too far away")
assert(reladdr >= -128, "jpr: Relative jump target is too far away")
$31 @ reladdr`8
}
jnz {addr} => {
reladdr = addr - $ - 2
assert(reladdr <= 127, "jnz: Relative jump target is too far away")
assert(reladdr >= -128, "jnz: Relative jump target is too far away")
$30 @ reladdr`8
}
jne {addr} => {
reladdr = addr - $ - 2
assert(reladdr <= 127, "jne: Relative jump target is too far away")
assert(reladdr >= -128, "jne: Relative jump target is too far away")
$30 @ reladdr`8
}
jpz {addr} => {
reladdr = addr - $ - 2
assert(reladdr <= 127, "jpz: Relative jump target is too far away")
assert(reladdr >= -128, "jpz: Relative jump target is too far away")
$32 @ reladdr`8
}
jeq {addr} => {
reladdr = addr - $ - 2
assert(reladdr <= 127, "jeq: Relative jump target is too far away")
assert(reladdr >= -128, "jeq: Relative jump target is too far away")
$32 @ reladdr`8
}
jlt {addr} => {
reladdr = addr - $ - 2
assert(reladdr <= 127, "jlt: Relative jump target is too far away")
assert(reladdr >= -128, "jlt: Relative jump target is too far away")
$33 @ reladdr`8
}
jge {addr} => {
reladdr = addr - $ - 2
assert(reladdr <= 127, "jge: Relative jump target is too far away")
assert(reladdr >= -128, "jge: Relative jump target is too far away")
$34 @ reladdr`8
}
jgt {addr} => {
reladdr = addr - $ - 2
assert(reladdr <= 127, "jgt: Relative jump target is too far away")
assert(reladdr >= -128, "jgt: Relative jump target is too far away")
$35 @ reladdr`8
}
jle {addr} => {
reladdr = addr - $ - 2
assert(reladdr <= 127, "jle: Relative jump target is too far away")
assert(reladdr >= -128, "jle: Relative jump target is too far away")
$36 @ reladdr`8
}
psh a => $40
psh b => $44
psh c => $45
psh f => $E9
psh p => $41
psh q => $46
pop a => $42
pop b => $47
pop c => $48
pop f => $EA
pop p => $43
pop q => $49
psh {value: i8} => $3B @ value
phw {value: i16} => $3C @ value
lda {value: i8} => $20 @ value
ldb {value: i8} => $26 @ value
ldc {value: i8} => $27 @ value
lda *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$28 @ value`8
}
lda *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$28 @ mvalue`8
}
ldb *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$29 @ value`8
}
ldb *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$29 @ mvalue`8
}
ldc *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$2A @ value`8
}
ldc *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$2A @ mvalue`8
}
sta *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$96 @ value`8
}
sta *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$96 @ mvalue`8
}
stb *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$97 @ value`8
}
stb *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$97 @ mvalue`8
}
stc *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$98 @ value`8
}
stc *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$98 @ mvalue`8
}
lda *{value: i16} => $51 @ value
ldb *{value: i16} => $56 @ value
ldc *{value: i16} => $57 @ value
sta *{value: i16} => $50 @ value
stb *{value: i16} => $58 @ value
stc *{value: i16} => $59 @ value
lda *p+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$01 @ value`16
}
lda *p-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$01 @ mvalue`16
}
ldb *p+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$F7 @ value`16
}
ldb *p-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$F7 @ mvalue`16
}
ldc *p+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$FE @ value`16
}
ldc *p-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$FE @ mvalue`16
}
lda *q+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$EB @ value`16
}
lda *q-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$EB @ mvalue`16
}
ldb *q+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$08 @ value`16
}
ldb *q-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$08 @ mvalue`16
}
ldc *q+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$09 @ value`16
}
ldc *q-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$09 @ mvalue`16
}
sta *p+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$0A @ value`16
}
sta *p-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$0A @ mvalue`16
}
stb *p+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$0B @ value`16
}
stb *p-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$0B @ mvalue`16
}
stc *p+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$0C @ value`16
}
stc *p-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$0C @ mvalue`16
}
sta *q+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$0D @ value`16
}
sta *q-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$0D @ mvalue`16
}
stb *q+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$0E @ value`16
}
stb *q-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$0E @ mvalue`16
}
stc *q+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$0F @ value`16
}
stc *q-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$0F @ mvalue`16
}
lda *p => $53
ldb *p => $5E
ldc *p => $5F
lda *q => $55
ldb *q => $61
ldc *q => $62
sta *p => $52
stb *p => $5A
stc *p => $5B
sta *q => $54
stb *q => $5C
stc *q => $5D
lda *p++ => $C6
ldb *p++ => $C7
ldc *p++ => $C8
lda *q++ => $C9
ldb *q++ => $CA
ldc *q++ => $CB
sta *p++ => $C0
stb *p++ => $C1
stc *p++ => $C2
sta *q++ => $C3
stb *q++ => $C4
stc *q++ => $C5
ldp {value: i16} => $21 @ value
ldq {value: i16} => $23 @ value
lds {value: i16} => $25 @ value
ldv {value: i16} => $22 @ value
ldp *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$7A @ value`8
}
ldp *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$7A @ mvalue`8
}
ldq *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$7B @ value`8
}
ldq *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$7B @ mvalue`8
}
stp *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$7E @ value`8
}
stp *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$7E @ mvalue`8
}
stq *s+{value: i8} => {
assert(value <= 127, "Relative address is too far away")
assert(value >= -128, "Relative address is too far away")
$7F @ value`8
}
stq *s-{value: i8} => {
mvalue = -value
assert(mvalue <= 127, "Relative address is too far away")
assert(mvalue >= -128, "Relative address is too far away")
$7F @ mvalue`8
}
ldp *{value: i16} => $68 @ value
ldq *{value: i16} => $6A @ value
stp *{value: i16} => $6C @ value
stq *{value: i16} => $6E @ value
ldp *p+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$EC @ value`16
}
ldp *p-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$EC @ mvalue`16
}
ldq *p+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$EE @ value`16
}
ldq *p-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$EE @ mvalue`16
}
ldp *q+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$F8 @ value`16
}
ldp *q-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$F8 @ mvalue`16
}
ldq *q+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$FA @ value`16
}
ldq *q-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$FA @ mvalue`16
}
stq *p+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$06 @ value`16
}
stq *p-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$06 @ mvalue`16
}
stp *q+{value: i16} => {
assert(value <= 32767, "Relative address is too far away")
assert(value >= -32768, "Relative address is too far away")
$FC @ value`16
}
stp *q-{value: i16} => {
mvalue = -value
assert(mvalue <= 32767, "Relative address is too far away")
assert(mvalue >= -32768, "Relative address is too far away")
$FC @ mvalue`16
}
ldp *p => $92
ldq *p => $93
ldp *q => $94
ldq *q => $95
stp *q => $7C
stq *p => $7D
ldq *p++ => $CC
ldp *q++ => $CD
stp *q++ => $CE
stq *p++ => $CF
lda b => $80
lda c => $81
ldb a => $82
ldb c => $83
ldc a => $84
ldc b => $85
lda pl => $86
lda ph => $87
lda ql => $88
lda qh => $89
ldb pl => $37
ldc ph => $38
ldb ql => $39
ldc qh => $3A
ldp q => $8A
ldp s => $8B
ldp v => $8C
ldp i => $8D
ldp cb => $91
ldq cb => $E0
ldq p => $8E
lds p => $8F
ldv p => $90
RST => $41
BRK => $00
RTI => $40
NOP => $EA
CLI => $58
SEI => $78
HLT => $18
RUN => $38
INC A => $F6
DEC A => $D6
ICC A => $57
INC B => $FE
DEC B => $DE
ICC B => $5F
INC C => $FA
DEC C => $DA
ICC C => $5B
INC {value: u8} => $E6 @ value
DEC {value: u8} => $C6 @ value
ICC {value: u8} => $47 @ value
ADD #{value: i8} => $6B @ value
ADC #{value: i8} => $69 @ value
CMP #{value: i8} => $C9 @ value
AND #{value: i8} => $29 @ value
ORA #{value: i8} => $09 @ value
EOR #{value: i8} => $49 @ value
ASL #{value: i8} => $15 @ value
LSR #{value: i8} => $55 @ value
ROL #{value: i8} => $35 @ value
ROR #{value: i8} => $75 @ value
ADD {value: u8} => $67 @ value
SUB {value: u8} => $E7 @ value
ADC {value: u8} => $65 @ value
SBC {value: u8} => $E5 @ value
CMP {value: u8} => $C5 @ value
AND {value: u8} => $25 @ value
ORA {value: u8} => $05 @ value
EOR {value: u8} => $45 @ value
ADD B => $7F
SUB B => $FF
ADC B => $7D
SBC B => $FD
CMP B => $DD
AND B => $3D
ORA B => $1D
EOR B => $5D
ADD C => $7B
SUB C => $FB
ADC C => $79
SBC C => $F9
CMP C => $D9
AND C => $39
ORA C => $19
EOR C => $59
BNE {value: rel8} => $D0 @ value
BEQ {value: rel8} => $F0 @ value
BLT {value: rel8} => $90 @ value
BGE {value: rel8} => $B0 @ value
BGT {value: rel8} => $30 @ value
BLE {value: rel8} => $10 @ value
BRA {value: rel8} => $98 @ value
ADX #{value: i8} => $E8 @ value
ADY #{value: i8} => $C8 @ value
ADX #{value: i16} => $8A @ value
ADY #{value: i16} => $88 @ value
ADX A => $FC
ADY A => $DC
JMP {value: i16} => $CC @ value
JSR {value: i16} => $20 @ value
JMP [{value: i16}] => $6C @ value
JSR [{value: i16}] => $2C @ value
JMP [{value: i16},A] => $4C @ value
JSR [{value: i16},A] => $0C @ value
JMP X => $64
JMP Y => $44
JSR X => $24
JSR Y => $04
RTS => $60
PHA => $48
PHB => $5C
PHC => $1C
PHP => $08
PHX => $54
PHY => $14
PLA => $68
PLB => $7C
PLC => $3C
PLP => $28
PLX => $74
PLY => $34
LDA #{value: i8} => $A9 @ value
LDB #{value: i8} => $AB @ value
LDC #{value: i8} => $2B @ value
LDA {value: u8} => $A5 @ value
LDB {value: u8} => $A7 @ value
LDC {value: u8} => $27 @ value
STA {value: u8} => $85 @ value
STB {value: u8} => $87 @ value
STC {value: u8} => $07 @ value
LDA {value: i16} => $ED @ value
LDB {value: i16} => $EF @ value
LDC {value: i16} => $6F @ value
STA {value: i16} => $CD @ value
STB {value: i16} => $CF @ value
STC {value: i16} => $4F @ value
LDA X => $A1
LDB X => $A3
LDC X => $23
LDA Y => $B1
LDB Y => $B3
LDC Y => $33
STA X => $81
STB X => $83
STC X => $03
STA Y => $91
STB Y => $93
STC Y => $13
LDA X+ => $E1
LDB X+ => $E3
LDC X+ => $63
LDA Y+ => $F1
LDB Y+ => $F3
LDC Y+ => $73
STA X+ => $C1
STB X+ => $C3
STC X+ => $43
STA Y+ => $D1
STB Y+ => $D3
STC Y+ => $53
LDA X,{value: u8} => $BD @ value
LDB X,{value: u8} => $BF @ value
LDC X,{value: u8} => $3F @ value
LDA Y,{value: u8} => $B9 @ value
LDB Y,{value: u8} => $BB @ value
LDC Y,{value: u8} => $3B @ value
STA X,{value: u8} => $9D @ value
STB X,{value: u8} => $9F @ value
STC X,{value: u8} => $1F @ value
STA Y,{value: u8} => $99 @ value
STB Y,{value: u8} => $9B @ value
STC Y,{value: u8} => $1B @ value
LDX #{value: i16} => $AA @ value
LDY #{value: i16} => $A8 @ value
LDX {value: u8} => $A6 @ value
LDY {value: u8} => $A4 @ value
STX {value: u8} => $86 @ value
STY {value: u8} => $84 @ value
LDX {value: i16} => $AE @ value
LDY {value: i16} => $AC @ value
STX {value: i16} => $8E @ value
STY {value: i16} => $8C @ value
LDX X,{value: u8} => $BE @ value
LDX Y,{value: u8} => $BA @ value
LDY X,{value: u8} => $BC @ value
LDY Y,{value: u8} => $B8 @ value
STX Y,{value: u8} => $9A @ value
STY X,{value: u8} => $9C @ value
LDX X => $A2
LDY X => $A0
LDX Y => $B2
LDY Y => $E2
STX Y => $92
STY X => $80
LDX Y+ => $F2
LDY X+ => $E0
STX Y+ => $D2
STY X+ => $C0
TBA => $97
TCA => $17
TAB => $B7
TCB => $D7
TAC => $37
TBC => $F7
TYX => $B4
TXY => $94
TVX => $B6
TXV => $96
TAS => $95
TSA => $B5
}

1
architecture.md Normal file
View File

@ -0,0 +1 @@
WIP

View File

@ -0,0 +1,20 @@
@echo off
rem This is the main process to run the 8608 Emulator.
rem To use it, simply drag an .asm file onto this batch file.
if [%1] == [] goto noarg
cd /d %~dp0
mkdir temp
"third-party/customasm/customasm.exe" -f binary -o "temp/temp.bin" %~dpnx1
"third-party/customasm/customasm.exe" -f annotated -o "temp/temp.lis" %~dpnx1
"third-party/love/love.exe" %~dp0 "temp/temp.bin"
goto done
:noarg
echo No input file specified.
echo Drag-and-drop an assembly code file onto this .bat file to use the emulator.
echo.
pause
:done

155
emulator/8608emulator.c Normal file
View File

@ -0,0 +1,155 @@
// 8608emulator.c
// This is the backend portion of the 8608 emulator application.
// It uses the generated instruction code from instructions_gen.c to emulate the internals of the 8608 CPU.
// It is included into the application by 8608emulator.lua, which provides the frontend.
#define lobyte(x) (x&0xFF)
#define hibyte(x) ((x>>8)&0xFF)
#define wordfrombytes(h,l) (((h<<8)&0xFF00)|(l&0xFF))
#define popbyte readmemory(((--cpu->s)%256)+0x0100)
#define loadimmed readmemory(cpu->i++)
#define loadstackrel readmemory(cpu->t)
#define loadstackrelp1 readmemory(cpu->t+1)
#define wordut (wordfrombytes(cpu->u, cpu->t))
#define wordcb (wordfrombytes(cpu->c, cpu->b))
#define loadut readmemory(wordut)
#define loadutp1 readmemory((wordut+1)%65536)
#define loadp readmemory(cpu->p)
#define loadq readmemory(cpu->q)
#define loadpinc readmemory((cpu->p++)%65536)
#define loadqinc readmemory((cpu->q++)%65536)
#define loadpp1 readmemory((cpu->p+1)%65536)
#define loadqp1 readmemory((cpu->q+1)%65536)
#define loadput readmemory((cpu->p+wordut)%65536)
#define loadqut readmemory((cpu->q+wordut)%65536)
#define signed8(x) (x>=128 ? x|0xFF00 : x)
#define setzf(x) cpu->nz=(x!=0);
#define loadimmedt cpu->t = loadimmed;
#define loadimm161 cpu->u = loadimmed;
#define loadimm162 cpu->t = loadimmed;
#define loadstackrelu cpu->u = loadstackrel;
#define storestackrel(x) writememory(cpu->t, x);
#define storestackrelu storestackrel(cpu->u);
#define storestackrel161(x) writememory(cpu->t , hibyte(x));
#define storestackrel162(x) writememory(cpu->t+1, lobyte(x));
#define loadstackrel161 cpu->u=loadstackrel;
#define loadstackrel162 cpu->t=loadstackrelp1;
#define storeut(x) writememory(wordut, x);
#define storeutp1(x) writememory((wordut+1)%65536, x);
#define storep(x) writememory(cpu->p, x);
#define storeq(x) writememory(cpu->q, x);
#define storepinc(x) writememory(cpu->p++, x);
#define storeqinc(x) writememory(cpu->q++, x);
#define storepp1(x) writememory((cpu->p+1)%65536, x);
#define storeqp1(x) writememory((cpu->q+1)%65536, x);
#define storeput(x) writememory((cpu->p+wordut)%65536, x);
#define storequt(x) writememory((cpu->q+wordut)%65536, x);
#define pushretaddr1 writememory(((cpu->s++)%256)+0x0100, hibyte((cpu->i-1)%65536));
#define pushretaddr2 writememory(((cpu->s++)%256)+0x0100, lobyte((cpu->i-1)%65536));
#define lni cpu->instr = readmemory(cpu->i++); cpu->cycle = 0;
#define ldi cpu->instr = readmemory(cpu->i); cpu->cycle = 0;
#define addf(x,y) { x=(x+y)&0x1FF; cpu->cf=x>=256; x&=0xFF; setzf(x); }
#define subf(x,y) addf(x,(-y)&0xFF);
#define cmpf(x,y) { int t=x+((-y)&0xFF); cpu->cf=t>=256; t&=0xFF; setzf(t); }
#define rol(x,y) x=(x<<y)|(x>>(8-y));
#define ror(x,y) x=(x>>y)|(x<<(8-y));
#define sra(x,y) x=(x>>y);
#define jmpabsp cpu->i=cpu->p; lni;
#define jmpabsq cpu->i=cpu->q; lni;
#define jmpabsut cpu->i=wordut; lni;
#define jmpabsutplus1 cpu->i=(wordut+1)%65536; lni;
#define pushbyte(b) writememory(((cpu->s++)%256)+0x0100, b);
#define push161(x) pushbyte(hibyte(x));
#define push162(x) pushbyte(lobyte(x));
#define pop161 cpu->t=popbyte;
#define pop162 cpu->u=popbyte;
#define tst(x) cpu->cf = x>=128; cpu->nz = x!=0;
#define instrpreload cpu->instrpre = loadimmed;
#define instrloadpre cpu->instr = cpu->instrpre; cpu->cycle = 0;
#define jmprelt cpu->i = (cpu->i + signed8(cpu->t))%65536; lni;
#define saveretaddr cpu->q = (cpu->i+1)%65536;
#define readmemory(x) _readmemory(cpu, mem, x)
#define writememory(x, y) _writememory(cpu, mem, x, y)
struct CPU {
int a;
int b;
int c;
int u;
int t;
int p;
int q;
int s;
int v;
int i;
int cf;
int nz;
int irq;
int ifg;
int rfg;
int ien;
int instr;
int cycle;
int instrpre;
int frame;
};
struct Event {
int id;
int addr;
};
struct Memory {
int data[65536];
int canwrite[65536];
int writes[65536];
int reads[65536];
int onread[65536];
int onwrite[65536];
struct Event events[4096];
int numevents;
};
void postEvent(struct Memory* const mem, int id, int addr) {
if(mem->numevents<4096) {
mem->events[mem->numevents].id = id;
mem->events[mem->numevents].addr = addr;
mem->numevents++;
}
}
int _readmemory(const struct CPU* const cpu, struct Memory* const mem, const int addr) {
int addr2 = addr%65536;
mem->reads[addr2] = cpu->frame;
if(mem->onread[addr2]) {
postEvent(mem, mem->onread[addr2], addr2);
}
return mem->data[addr2];
}
int _writememory(const struct CPU* const cpu, struct Memory* const mem, const int addr, const int data) {
int addr2 = addr%65536;
if(mem->canwrite[addr2]) {
mem->writes[addr2] = cpu->frame;
mem->data[addr2] = data%256;
}
if(mem->onwrite[addr2]) {
postEvent(mem, mem->onwrite[addr2], addr2);
}
}
typedef void(*CPUInstruction)(struct CPU* const cpu, struct Memory* const mem);
#include "instructions_gen.c"
int TickCPU(struct CPU* const cpu, struct Memory* const mem, const int count, const int countinstrs, const int breakaddr) {
int i = 0;
while(i<count) {
if(cpu->irq && !cpu->ifg && cpu->cycle==0 && cpu->ien) { cpu->instr = 0x01; }
if(cpu->rfg || cpu->ifg || (cpu->irq && cpu->ien)) {
CPUInstruction instr = CPUInstructions[cpu->instr][cpu->cycle];
if(instr) instr(cpu, mem);
if(!countinstrs || cpu->cycle==0) { i++; }
if(cpu->i==breakaddr) { i = count; break; }
} else { i = count; break; }
if(mem->numevents!=0) { break; }
}
return count-i;
}

BIN
emulator/8608emulator.dll Normal file

Binary file not shown.

1001
emulator/8608emulator.lua Normal file

File diff suppressed because it is too large Load Diff

79
emulator/colorset.lua Normal file
View File

@ -0,0 +1,79 @@
-- Colorset definitions
-- This is used by the emulator to convert color codes into colors for the text and video displays.
-- It should correspond with the colorset used in-game.
-- Colors are listed in order of color code from 0 to 63.
-- The format is 8-bit RGBA. The alpha channel is currently ignored.
ColorSet = {
{222,52,52,255},
{166,65,65,255},
{220,215,144,255},
{231,193,110,255},
{57,180,74,255},
{0,128,64,255},
{50,105,227,255},
{49,79,145,255},
{196,17,14,255},
{112,17,10,255},
{255,191,0,255},
{168,98,0,255},
{38,107,22,255},
{28,82,17,255},
{165,189,210,255},
{105,145,170,255},
{198,105,156,255},
{145,68,92,255},
{239,202,217,255},
{225,175,153,255},
{255,125,64,255},
{160,66,22,255},
{165,234,240,255},
{85,175,205,255},
{178,169,231,255},
{139,90,176,255},
{229,175,121,255},
{100,50,0,255},
{232,114,0,255},
{191,54,0,255},
{138,178,141,255},
{37,69,69,255},
{240,239,235,255},
{221,216,214,255},
{188,184,182,255},
{163,158,153,255},
{124,124,117,255},
{87,86,80,255},
{45,45,42,255},
{17,17,14,255},
{207,175,144,255},
{189,158,121,255},
{177,138,102,255},
{154,112,79,255},
{119,82,56,255},
{87,59,35,255},
{61,36,14,255},
{40,23,8,255},
{127,52,52,190},
{196,136,52,190},
{55,90,25,190},
{160,180,255,180},
{10,45,80,180},
{31,22,8,200},
{230,228,225,150},
{18,18,18,150},
{199,178,156,255},
{150,135,120,255},
{115,99,87,255},
{85,70,65,255},
{54,47,45,255},
{255,255,255,255},
{0,0,0,255},
{255,255,255,50},
}

11
emulator/conf.lua Normal file
View File

@ -0,0 +1,11 @@
WindowScale = 2
WindowX = 800
WindowY = 480
function love.conf(t)
t.console = true
t.window.width = WindowX*WindowScale
t.window.height = WindowY*WindowScale
t.window.title = "8608 Emulator"
end

Binary file not shown.

BIN
emulator/content/enter.wav Normal file

Binary file not shown.

BIN
emulator/content/error.wav Normal file

Binary file not shown.

Binary file not shown.

BIN
emulator/content/keyOff.wav Normal file

Binary file not shown.

BIN
emulator/content/keyOn.wav Normal file

Binary file not shown.

BIN
emulator/content/runOff.wav Normal file

Binary file not shown.

BIN
emulator/content/runOn.wav Normal file

Binary file not shown.

BIN
emulator/content/start.wav Normal file

Binary file not shown.

BIN
emulator/content/step.wav Normal file

Binary file not shown.

Binary file not shown.

BIN
emulator/content/write.wav Normal file

Binary file not shown.

Binary file not shown.

71
emulator/gendefs.lua Normal file
View File

@ -0,0 +1,71 @@
-- gendefs.lua
-- This code generates instructions_gen.c from the instruction definitions in 8608-instructions.lua.
-- It is executed as part of the compilation process for the 8608 emulator DLL.
local function fixCode(code)
code = code:gsub("cpu%.", "cpu%->")
if
not code:find("lni") and
not code:find("instrloadpre") and
not code:find("jmp") and
not code:find("ldi")
then code = code.." cpu->cycle++;" end
return code
end
local function lineFromInstr(instr)
local cycleLines = {}
for cycle = 0, 7 do
if instr and instr.ccode[cycle+1] then
cycleLines[cycle+1] = string.format("cpu_instr_%i_%i", instr.opcode, cycle)
else
cycleLines[cycle+1] = 0
end
end
return string.format("{%s},", table.concat(cycleLines, ","))
end
local function codeFromInstr(instr, lines)
for i, code in ipairs(instr.ccode) do
local cycle = i-1
local line = string.format(
"void cpu_instr_%i_%i(struct CPU* const cpu, struct Memory* const mem) { %s }",
instr.opcode, cycle,
fixCode(code)
)
table.insert(lines, line)
end
end
local ccode = [[
// Auto-generated by gendefs.lua
%s
CPUInstruction CPUInstructions[256][8] = {
%s
};
]]
local function ccodeFromArch(arch)
local instrsByOpcode = {}
for i, instr in ipairs(arch.instructions) do
if instr.opcode then instrsByOpcode[instr.opcode] = instr end
end
local instrLines = {}
local funcLines = {}
for opcode = 0, 255 do
local instr = instrsByOpcode[opcode]
instrLines[opcode+1] = lineFromInstr(instr)
if instr then codeFromInstr(instr, funcLines) end
end
return string.format(ccode,
table.concat(funcLines, "\n"),
table.concat(instrLines, "\n\t")
)
end
__ARCH_INCLUDED = true
local arch = dofile("../8608-definition.lua")
arch.instructions = dofile("../8608-instructions.lua")
local fo = io.open("instructions_gen.c", "w")
fo:write(ccodeFromArch(arch))
fo:close()

View File

@ -0,0 +1,7 @@
rem This is the procedure to generate the C code for the emulator backend
rem from the instruction definitions in the parent directory,
rem and compile it.
luajit gendefs.lua
gcc 8608emulator.c -shared -Ofast -o 8608emulator.dll
pause

712
emulator/instructions_gen.c Normal file
View File

@ -0,0 +1,712 @@
// Auto-generated by gendefs.lua
void cpu_instr_0_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ifg=1; cpu->u=readmemory(0xFFFE); cpu->cycle++; }
void cpu_instr_0_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=readmemory(0xFFFF); cpu->cycle++; }
void cpu_instr_0_2(struct CPU* const cpu, struct Memory* const mem) { cpu->v=(cpu->i )%65536; jmpabsut; }
void cpu_instr_1_0(struct CPU* const cpu, struct Memory* const mem) { cpu->irq=0; cpu->ifg=1; cpu->u=readmemory(0xFFFE); cpu->cycle++; }
void cpu_instr_1_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=readmemory(0xFFFF); cpu->cycle++; }
void cpu_instr_1_2(struct CPU* const cpu, struct Memory* const mem) { cpu->v=(cpu->i-1)%65536; jmpabsut; }
void cpu_instr_3_0(struct CPU* const cpu, struct Memory* const mem) { storep(cpu->c); cpu->cycle++; }
void cpu_instr_3_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_4_0(struct CPU* const cpu, struct Memory* const mem) { pushretaddr1 cpu->cycle++; }
void cpu_instr_4_1(struct CPU* const cpu, struct Memory* const mem) { pushretaddr2 cpu->cycle++; }
void cpu_instr_4_2(struct CPU* const cpu, struct Memory* const mem) { jmpabsq }
void cpu_instr_5_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_5_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; }
void cpu_instr_5_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a|=cpu->u; setzf(cpu->a); lni; }
void cpu_instr_7_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; }
void cpu_instr_7_1(struct CPU* const cpu, struct Memory* const mem) { storestackrel(cpu->a); cpu->cycle++; }
void cpu_instr_7_2(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_8_0(struct CPU* const cpu, struct Memory* const mem) { int f = cpu->nz | (cpu->cf<<1); pushbyte(f); cpu->cycle++; }
void cpu_instr_8_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_9_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_9_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a|=cpu->t; setzf(cpu->a); lni; }
void cpu_instr_12_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_12_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_12_2(struct CPU* const cpu, struct Memory* const mem) { pushretaddr1 cpu->cycle++; }
void cpu_instr_12_3(struct CPU* const cpu, struct Memory* const mem) { pushretaddr2 cpu->cycle++; }
void cpu_instr_12_4(struct CPU* const cpu, struct Memory* const mem) { cpu->i=(wordut+cpu->a)%65536;cpu->u=readmemory(cpu->i); cpu->cycle++; }
void cpu_instr_12_5(struct CPU* const cpu, struct Memory* const mem) { cpu->t=readmemory((cpu->i+1)%65536); cpu->cycle++; }
void cpu_instr_12_6(struct CPU* const cpu, struct Memory* const mem) { jmpabsut }
void cpu_instr_16_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_16_1(struct CPU* const cpu, struct Memory* const mem) { if((!cpu->nz) || (!cpu->cf)) { jmprelt } else { lni } }
void cpu_instr_19_0(struct CPU* const cpu, struct Memory* const mem) { storeq(cpu->c); cpu->cycle++; }
void cpu_instr_19_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_20_0(struct CPU* const cpu, struct Memory* const mem) { push161(cpu->q); cpu->cycle++; }
void cpu_instr_20_1(struct CPU* const cpu, struct Memory* const mem) { push162(cpu->q); cpu->cycle++; }
void cpu_instr_20_2(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_21_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_21_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a<<=cpu->t; setzf(cpu->a); lni; }
void cpu_instr_23_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=cpu->c; lni; }
void cpu_instr_24_0(struct CPU* const cpu, struct Memory* const mem) { cpu->rfg=0; lni; }
void cpu_instr_25_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a|=cpu->c; setzf(cpu->a); lni; }
void cpu_instr_27_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_27_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_27_2(struct CPU* const cpu, struct Memory* const mem) { storequt(cpu->c); cpu->cycle++; }
void cpu_instr_27_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_28_0(struct CPU* const cpu, struct Memory* const mem) { pushbyte(cpu->c); cpu->cycle++; }
void cpu_instr_28_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_29_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a|=cpu->b; setzf(cpu->a); lni; }
void cpu_instr_31_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_31_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_31_2(struct CPU* const cpu, struct Memory* const mem) { storeput(cpu->c); cpu->cycle++; }
void cpu_instr_31_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_32_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_32_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_32_2(struct CPU* const cpu, struct Memory* const mem) { pushretaddr1 cpu->cycle++; }
void cpu_instr_32_3(struct CPU* const cpu, struct Memory* const mem) { pushretaddr2 cpu->cycle++; }
void cpu_instr_32_4(struct CPU* const cpu, struct Memory* const mem) { jmpabsut }
void cpu_instr_35_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadp; setzf(cpu->c); cpu->cycle++; }
void cpu_instr_35_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_36_0(struct CPU* const cpu, struct Memory* const mem) { pushretaddr1 cpu->cycle++; }
void cpu_instr_36_1(struct CPU* const cpu, struct Memory* const mem) { pushretaddr2 cpu->cycle++; }
void cpu_instr_36_2(struct CPU* const cpu, struct Memory* const mem) { jmpabsp }
void cpu_instr_37_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_37_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; }
void cpu_instr_37_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=cpu->u; setzf(cpu->a); lni; }
void cpu_instr_39_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; }
void cpu_instr_39_1(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadstackrel; setzf(cpu->c); cpu->cycle++; }
void cpu_instr_39_2(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_40_0(struct CPU* const cpu, struct Memory* const mem) { int f=popbyte; cpu->nz = f&1; cpu->cf = (f>>1)&1; cpu->cycle++; }
void cpu_instr_40_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_41_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_41_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=cpu->t; setzf(cpu->a); lni; }
void cpu_instr_43_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadimmed; setzf(cpu->c); cpu->cycle++; }
void cpu_instr_43_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_44_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_44_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_44_2(struct CPU* const cpu, struct Memory* const mem) { pushretaddr1 cpu->cycle++; }
void cpu_instr_44_3(struct CPU* const cpu, struct Memory* const mem) { pushretaddr2 cpu->cycle++; }
void cpu_instr_44_4(struct CPU* const cpu, struct Memory* const mem) { cpu->i=(wordut+cpu->a)%65536;cpu->u=readmemory(cpu->i); cpu->cycle++; }
void cpu_instr_44_5(struct CPU* const cpu, struct Memory* const mem) { cpu->t=readmemory((cpu->i+1)%65536); cpu->cycle++; }
void cpu_instr_44_6(struct CPU* const cpu, struct Memory* const mem) { jmpabsut }
void cpu_instr_48_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_48_1(struct CPU* const cpu, struct Memory* const mem) { if( cpu->nz && cpu->cf ) { jmprelt } else { lni } }
void cpu_instr_51_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadq; setzf(cpu->c); cpu->cycle++; }
void cpu_instr_51_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_52_0(struct CPU* const cpu, struct Memory* const mem) { pop161 cpu->cycle++; }
void cpu_instr_52_1(struct CPU* const cpu, struct Memory* const mem) { pop162 cpu->cycle++; }
void cpu_instr_52_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; }
void cpu_instr_53_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_53_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a=rol(cpu->a,cpu->t); setzf(cpu->a); lni; }
void cpu_instr_55_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=cpu->a; lni; }
void cpu_instr_56_0(struct CPU* const cpu, struct Memory* const mem) { cpu->rfg=1; lni; }
void cpu_instr_57_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=cpu->c; setzf(cpu->a); lni; }
void cpu_instr_59_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_59_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_59_2(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadqut; setzf(cpu->c); cpu->cycle++; }
void cpu_instr_59_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_60_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=popbyte; cpu->cycle++; }
void cpu_instr_60_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_61_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=cpu->b; setzf(cpu->a); lni; }
void cpu_instr_63_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_63_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_63_2(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadput; setzf(cpu->c); cpu->cycle++; }
void cpu_instr_63_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_64_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ifg=0; int t=cpu->i; cpu->i=cpu->v; cpu->v=t; lni; }
void cpu_instr_65_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=0; cpu->b=0; cpu->c=0; cpu->u=0; cpu->t=0; cpu->p=0; cpu->q=0; cpu->s=0; cpu->v=0; cpu->i=0; cpu->cf=0; cpu->nz=0; cpu->rfg=1; cpu->ien=0; cpu->irq=0; cpu->ifg=0; cpu->u=readmemory(0xFFFC); cpu->cycle++; }
void cpu_instr_65_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=readmemory(0xFFFD); cpu->cycle++; }
void cpu_instr_65_2(struct CPU* const cpu, struct Memory* const mem) { jmpabsut; }
void cpu_instr_67_0(struct CPU* const cpu, struct Memory* const mem) { storepinc(cpu->c); cpu->cycle++; }
void cpu_instr_67_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_68_0(struct CPU* const cpu, struct Memory* const mem) { jmpabsq }
void cpu_instr_69_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_69_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; }
void cpu_instr_69_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a^=cpu->u; setzf(cpu->a); lni; }
void cpu_instr_71_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_71_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; }
void cpu_instr_71_2(struct CPU* const cpu, struct Memory* const mem) { instrpreload; addf(cpu->u,cpu->cf); cpu->cycle++; }
void cpu_instr_71_3(struct CPU* const cpu, struct Memory* const mem) { storestackrelu; instrloadpre }
void cpu_instr_72_0(struct CPU* const cpu, struct Memory* const mem) { pushbyte(cpu->a); cpu->cycle++; }
void cpu_instr_72_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_73_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_73_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a^=cpu->t; setzf(cpu->a); lni; }
void cpu_instr_76_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_76_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_76_2(struct CPU* const cpu, struct Memory* const mem) { cpu->i=(wordut+cpu->a)%65536;cpu->u=readmemory(cpu->i); cpu->cycle++; }
void cpu_instr_76_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=readmemory((cpu->i+1)%65536); cpu->cycle++; }
void cpu_instr_76_4(struct CPU* const cpu, struct Memory* const mem) { jmpabsut }
void cpu_instr_79_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_79_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_79_2(struct CPU* const cpu, struct Memory* const mem) { storeut(cpu->c); cpu->cycle++; }
void cpu_instr_79_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_83_0(struct CPU* const cpu, struct Memory* const mem) { storeqinc(cpu->c); cpu->cycle++; }
void cpu_instr_83_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_84_0(struct CPU* const cpu, struct Memory* const mem) { push161(cpu->p); cpu->cycle++; }
void cpu_instr_84_1(struct CPU* const cpu, struct Memory* const mem) { push162(cpu->p); cpu->cycle++; }
void cpu_instr_84_2(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_85_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_85_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a>>=cpu->t; setzf(cpu->a); lni; }
void cpu_instr_87_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->cf); lni; }
void cpu_instr_88_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ien=1; lni; }
void cpu_instr_89_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a^=cpu->c; setzf(cpu->a); lni; }
void cpu_instr_91_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c,cpu->cf); lni; }
void cpu_instr_92_0(struct CPU* const cpu, struct Memory* const mem) { pushbyte(cpu->b); cpu->cycle++; }
void cpu_instr_92_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_93_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a^=cpu->b; setzf(cpu->a); lni; }
void cpu_instr_95_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->b,cpu->cf); lni; }
void cpu_instr_96_0(struct CPU* const cpu, struct Memory* const mem) { pop161 cpu->cycle++; }
void cpu_instr_96_1(struct CPU* const cpu, struct Memory* const mem) { pop162 cpu->cycle++; }
void cpu_instr_96_2(struct CPU* const cpu, struct Memory* const mem) { jmpabsutplus1 }
void cpu_instr_99_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadpinc; setzf(cpu->c); cpu->cycle++; }
void cpu_instr_99_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_100_0(struct CPU* const cpu, struct Memory* const mem) { jmpabsp }
void cpu_instr_101_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_101_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; }
void cpu_instr_101_2(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->u+cpu->cf); lni; }
void cpu_instr_103_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_103_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; }
void cpu_instr_103_2(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->u); lni; }
void cpu_instr_104_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=popbyte; cpu->cycle++; }
void cpu_instr_104_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_105_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_105_1(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->t+cpu->cf); lni; }
void cpu_instr_107_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_107_1(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->t); lni; }
void cpu_instr_108_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_108_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_108_2(struct CPU* const cpu, struct Memory* const mem) { cpu->i=(wordut+cpu->a)%65536;cpu->u=readmemory(cpu->i); cpu->cycle++; }
void cpu_instr_108_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=readmemory((cpu->i+1)%65536); cpu->cycle++; }
void cpu_instr_108_4(struct CPU* const cpu, struct Memory* const mem) { jmpabsut }
void cpu_instr_111_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_111_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_111_2(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadut; setzf(cpu->c); cpu->cycle++; }
void cpu_instr_111_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_115_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadqinc; setzf(cpu->c); cpu->cycle++; }
void cpu_instr_115_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_116_0(struct CPU* const cpu, struct Memory* const mem) { pop161 cpu->cycle++; }
void cpu_instr_116_1(struct CPU* const cpu, struct Memory* const mem) { pop162 cpu->cycle++; }
void cpu_instr_116_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; }
void cpu_instr_117_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_117_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a=ror(cpu->a,cpu->t); setzf(cpu->a); lni; }
void cpu_instr_120_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ien=0; lni; }
void cpu_instr_121_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->c+cpu->cf); lni; }
void cpu_instr_123_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->c); lni; }
void cpu_instr_124_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=popbyte; cpu->cycle++; }
void cpu_instr_124_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_125_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->b+cpu->cf); lni; }
void cpu_instr_127_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->b); lni; }
void cpu_instr_128_0(struct CPU* const cpu, struct Memory* const mem) { storep(hibyte(cpu->q)); cpu->cycle++; }
void cpu_instr_128_1(struct CPU* const cpu, struct Memory* const mem) { storepp1(lobyte(cpu->q)); cpu->cycle++; }
void cpu_instr_128_2(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_129_0(struct CPU* const cpu, struct Memory* const mem) { storep(cpu->a); cpu->cycle++; }
void cpu_instr_129_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_131_0(struct CPU* const cpu, struct Memory* const mem) { storep(cpu->b); cpu->cycle++; }
void cpu_instr_131_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_132_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_132_1(struct CPU* const cpu, struct Memory* const mem) { storestackrel161(cpu->q); cpu->cycle++; }
void cpu_instr_132_2(struct CPU* const cpu, struct Memory* const mem) { storestackrel162(cpu->q); cpu->cycle++; }
void cpu_instr_132_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_133_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; }
void cpu_instr_133_1(struct CPU* const cpu, struct Memory* const mem) { storestackrel(cpu->a); cpu->cycle++; }
void cpu_instr_133_2(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_134_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_134_1(struct CPU* const cpu, struct Memory* const mem) { storestackrel161(cpu->p); cpu->cycle++; }
void cpu_instr_134_2(struct CPU* const cpu, struct Memory* const mem) { storestackrel162(cpu->p); cpu->cycle++; }
void cpu_instr_134_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_135_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; }
void cpu_instr_135_1(struct CPU* const cpu, struct Memory* const mem) { storestackrel(cpu->a); cpu->cycle++; }
void cpu_instr_135_2(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_136_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_136_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_136_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=(cpu->p+wordut )%65536; lni; }
void cpu_instr_138_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_138_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_138_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=(cpu->p+wordut )%65536; lni; }
void cpu_instr_140_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_140_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_140_2(struct CPU* const cpu, struct Memory* const mem) { storeut(hibyte(cpu->q)); cpu->cycle++; }
void cpu_instr_140_3(struct CPU* const cpu, struct Memory* const mem) { storeutp1(lobyte(cpu->q)); cpu->cycle++; }
void cpu_instr_140_4(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_142_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_142_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_142_2(struct CPU* const cpu, struct Memory* const mem) { storeut(hibyte(cpu->p)); cpu->cycle++; }
void cpu_instr_142_3(struct CPU* const cpu, struct Memory* const mem) { storeutp1(lobyte(cpu->p)); cpu->cycle++; }
void cpu_instr_142_4(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_144_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_144_1(struct CPU* const cpu, struct Memory* const mem) { if(!cpu->cf ) { jmprelt } else { lni } }
void cpu_instr_145_0(struct CPU* const cpu, struct Memory* const mem) { storeq(cpu->a); cpu->cycle++; }
void cpu_instr_145_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_146_0(struct CPU* const cpu, struct Memory* const mem) { storeq(hibyte(cpu->p)); cpu->cycle++; }
void cpu_instr_146_1(struct CPU* const cpu, struct Memory* const mem) { storeqp1(lobyte(cpu->p)); cpu->cycle++; }
void cpu_instr_146_2(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_147_0(struct CPU* const cpu, struct Memory* const mem) { storeq(cpu->b); cpu->cycle++; }
void cpu_instr_147_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_148_0(struct CPU* const cpu, struct Memory* const mem) { cpu->q=cpu->p; lni; }
void cpu_instr_149_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p=cpu->s; lni; }
void cpu_instr_150_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p=cpu->v; lni; }
void cpu_instr_151_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=cpu->b; lni; }
void cpu_instr_152_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_152_1(struct CPU* const cpu, struct Memory* const mem) { jmprelt }
void cpu_instr_153_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_153_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_153_2(struct CPU* const cpu, struct Memory* const mem) { storequt(cpu->a); cpu->cycle++; }
void cpu_instr_153_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_154_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_154_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_154_2(struct CPU* const cpu, struct Memory* const mem) { storeut(hibyte(cpu->p)); cpu->cycle++; }
void cpu_instr_154_3(struct CPU* const cpu, struct Memory* const mem) { storeutp1(lobyte(cpu->p)); cpu->cycle++; }
void cpu_instr_154_4(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_155_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_155_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_155_2(struct CPU* const cpu, struct Memory* const mem) { storequt(cpu->b); cpu->cycle++; }
void cpu_instr_155_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_156_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_156_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_156_2(struct CPU* const cpu, struct Memory* const mem) { storeut(hibyte(cpu->q)); cpu->cycle++; }
void cpu_instr_156_3(struct CPU* const cpu, struct Memory* const mem) { storeutp1(lobyte(cpu->q)); cpu->cycle++; }
void cpu_instr_156_4(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_157_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_157_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_157_2(struct CPU* const cpu, struct Memory* const mem) { storeput(cpu->a); cpu->cycle++; }
void cpu_instr_157_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_159_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_159_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_159_2(struct CPU* const cpu, struct Memory* const mem) { storeput(cpu->b); cpu->cycle++; }
void cpu_instr_159_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_160_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadp; cpu->cycle++; }
void cpu_instr_160_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; }
void cpu_instr_160_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; }
void cpu_instr_161_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadp; setzf(cpu->a); cpu->cycle++; }
void cpu_instr_161_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_162_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadp; cpu->cycle++; }
void cpu_instr_162_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; }
void cpu_instr_162_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; }
void cpu_instr_163_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadp; setzf(cpu->b); cpu->cycle++; }
void cpu_instr_163_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_164_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_164_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrel161 cpu->cycle++; }
void cpu_instr_164_2(struct CPU* const cpu, struct Memory* const mem) { loadstackrel162 cpu->cycle++; }
void cpu_instr_164_3(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; }
void cpu_instr_165_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; }
void cpu_instr_165_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadstackrel; setzf(cpu->a); cpu->cycle++; }
void cpu_instr_165_2(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_166_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_166_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrel161 cpu->cycle++; }
void cpu_instr_166_2(struct CPU* const cpu, struct Memory* const mem) { loadstackrel162 cpu->cycle++; }
void cpu_instr_166_3(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; }
void cpu_instr_167_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; }
void cpu_instr_167_1(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadstackrel; setzf(cpu->b); cpu->cycle++; }
void cpu_instr_167_2(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_168_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_168_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_168_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; }
void cpu_instr_169_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadimmed; setzf(cpu->a); cpu->cycle++; }
void cpu_instr_169_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_170_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_170_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_170_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; }
void cpu_instr_171_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadimmed; setzf(cpu->b); cpu->cycle++; }
void cpu_instr_171_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_172_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_172_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_172_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; cpu->u=loadut; cpu->cycle++; }
void cpu_instr_172_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; }
void cpu_instr_172_4(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; }
void cpu_instr_174_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_174_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_174_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; cpu->u=loadut; cpu->cycle++; }
void cpu_instr_174_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; }
void cpu_instr_174_4(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; }
void cpu_instr_176_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_176_1(struct CPU* const cpu, struct Memory* const mem) { if( cpu->cf ) { jmprelt } else { lni } }
void cpu_instr_177_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadq; setzf(cpu->a); cpu->cycle++; }
void cpu_instr_177_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_178_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadq; cpu->cycle++; }
void cpu_instr_178_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; }
void cpu_instr_178_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; }
void cpu_instr_179_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadq; setzf(cpu->b); cpu->cycle++; }
void cpu_instr_179_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_180_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p=cpu->q; lni; }
void cpu_instr_181_0(struct CPU* const cpu, struct Memory* const mem) { cpu->s=cpu->p; lni; }
void cpu_instr_182_0(struct CPU* const cpu, struct Memory* const mem) { cpu->v=cpu->p; lni; }
void cpu_instr_183_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=cpu->a; lni; }
void cpu_instr_184_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_184_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_184_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; cpu->u=loadut; cpu->cycle++; }
void cpu_instr_184_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; }
void cpu_instr_184_4(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; }
void cpu_instr_185_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_185_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_185_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadqut; setzf(cpu->a); cpu->cycle++; }
void cpu_instr_185_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_186_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_186_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_186_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; cpu->u=loadut; cpu->cycle++; }
void cpu_instr_186_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; }
void cpu_instr_186_4(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; }
void cpu_instr_187_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_187_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_187_2(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadqut; setzf(cpu->b); cpu->cycle++; }
void cpu_instr_187_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_188_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_188_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_188_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; cpu->u=loadut; cpu->cycle++; }
void cpu_instr_188_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; }
void cpu_instr_188_4(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; }
void cpu_instr_189_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_189_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_189_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadput; setzf(cpu->a); cpu->cycle++; }
void cpu_instr_189_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_190_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_190_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_190_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; cpu->u=loadut; cpu->cycle++; }
void cpu_instr_190_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; }
void cpu_instr_190_4(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; }
void cpu_instr_191_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_191_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_191_2(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadput; setzf(cpu->b); cpu->cycle++; }
void cpu_instr_191_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_192_0(struct CPU* const cpu, struct Memory* const mem) { storepinc(hibyte(cpu->q)); cpu->cycle++; }
void cpu_instr_192_1(struct CPU* const cpu, struct Memory* const mem) { storepinc(lobyte(cpu->q)); cpu->cycle++; }
void cpu_instr_192_2(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_193_0(struct CPU* const cpu, struct Memory* const mem) { storepinc(cpu->a); cpu->cycle++; }
void cpu_instr_193_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_195_0(struct CPU* const cpu, struct Memory* const mem) { storepinc(cpu->b); cpu->cycle++; }
void cpu_instr_195_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_197_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_197_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; }
void cpu_instr_197_2(struct CPU* const cpu, struct Memory* const mem) { cmpf(cpu->a,cpu->u); lni; }
void cpu_instr_198_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_198_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; }
void cpu_instr_198_2(struct CPU* const cpu, struct Memory* const mem) { instrpreload; addf(cpu->u,-1 ); cpu->cycle++; }
void cpu_instr_198_3(struct CPU* const cpu, struct Memory* const mem) { storestackrelu; instrloadpre }
void cpu_instr_200_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_200_1(struct CPU* const cpu, struct Memory* const mem) { cpu->q=(cpu->q+signed8(cpu->t))%65536; lni; }
void cpu_instr_201_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_201_1(struct CPU* const cpu, struct Memory* const mem) { cmpf(cpu->a,cpu->t); lni; }
void cpu_instr_204_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_204_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_204_2(struct CPU* const cpu, struct Memory* const mem) { jmpabsut }
void cpu_instr_205_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_205_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_205_2(struct CPU* const cpu, struct Memory* const mem) { storeut(cpu->a); cpu->cycle++; }
void cpu_instr_205_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_207_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_207_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_207_2(struct CPU* const cpu, struct Memory* const mem) { storeut(cpu->b); cpu->cycle++; }
void cpu_instr_207_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_208_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_208_1(struct CPU* const cpu, struct Memory* const mem) { if( cpu->nz ) { jmprelt } else { lni } }
void cpu_instr_209_0(struct CPU* const cpu, struct Memory* const mem) { storeqinc(cpu->a); cpu->cycle++; }
void cpu_instr_209_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_210_0(struct CPU* const cpu, struct Memory* const mem) { storeqinc(hibyte(cpu->p)); cpu->cycle++; }
void cpu_instr_210_1(struct CPU* const cpu, struct Memory* const mem) { storeqinc(lobyte(cpu->p)); cpu->cycle++; }
void cpu_instr_210_2(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_211_0(struct CPU* const cpu, struct Memory* const mem) { storeqinc(cpu->b); cpu->cycle++; }
void cpu_instr_211_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_214_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-1 ); lni; }
void cpu_instr_215_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=cpu->c; lni; }
void cpu_instr_217_0(struct CPU* const cpu, struct Memory* const mem) { cmpf(cpu->a,cpu->c); lni; }
void cpu_instr_218_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c,-1 ); lni; }
void cpu_instr_220_0(struct CPU* const cpu, struct Memory* const mem) { cpu->q=(cpu->p+signed8(cpu->a))%65536; lni; }
void cpu_instr_221_0(struct CPU* const cpu, struct Memory* const mem) { cmpf(cpu->a,cpu->b); lni; }
void cpu_instr_222_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->b,-1 ); lni; }
void cpu_instr_224_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadpinc; cpu->cycle++; }
void cpu_instr_224_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpinc; cpu->cycle++; }
void cpu_instr_224_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; }
void cpu_instr_225_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadpinc; setzf(cpu->a); cpu->cycle++; }
void cpu_instr_225_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_226_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadq; cpu->cycle++; }
void cpu_instr_226_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; }
void cpu_instr_226_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; }
void cpu_instr_227_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadpinc; setzf(cpu->b); cpu->cycle++; }
void cpu_instr_227_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_229_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_229_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; }
void cpu_instr_229_2(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-cpu->u+cpu->cf); lni; }
void cpu_instr_230_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_230_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; }
void cpu_instr_230_2(struct CPU* const cpu, struct Memory* const mem) { instrpreload; addf(cpu->u, 1 ); cpu->cycle++; }
void cpu_instr_230_3(struct CPU* const cpu, struct Memory* const mem) { storestackrelu; instrloadpre }
void cpu_instr_231_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_231_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; }
void cpu_instr_231_2(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->a,cpu->u); lni; }
void cpu_instr_232_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_232_1(struct CPU* const cpu, struct Memory* const mem) { cpu->p=(cpu->p+signed8(cpu->t))%65536; lni; }
void cpu_instr_234_0(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_237_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_237_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_237_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadut; setzf(cpu->a); cpu->cycle++; }
void cpu_instr_237_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_239_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; }
void cpu_instr_239_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; }
void cpu_instr_239_2(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadut; setzf(cpu->b); cpu->cycle++; }
void cpu_instr_239_3(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_240_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; }
void cpu_instr_240_1(struct CPU* const cpu, struct Memory* const mem) { if(!cpu->nz ) { jmprelt } else { lni } }
void cpu_instr_241_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadqinc; setzf(cpu->a); cpu->cycle++; }
void cpu_instr_241_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_242_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadqinc; cpu->cycle++; }
void cpu_instr_242_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqinc; cpu->cycle++; }
void cpu_instr_242_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; }
void cpu_instr_243_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadqinc; setzf(cpu->b); cpu->cycle++; }
void cpu_instr_243_1(struct CPU* const cpu, struct Memory* const mem) { lni; }
void cpu_instr_246_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a, 1 ); lni; }
void cpu_instr_247_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=cpu->b; lni; }
void cpu_instr_249_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-cpu->c+cpu->cf); lni; }
void cpu_instr_250_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c, 1 ); lni; }
void cpu_instr_251_0(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->a,cpu->c); lni; }
void cpu_instr_252_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p=(cpu->p+signed8(cpu->a))%65536; lni; }
void cpu_instr_253_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-cpu->b+cpu->cf); lni; }
void cpu_instr_254_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->b, 1 ); lni; }
void cpu_instr_255_0(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->a,cpu->b); lni; }
CPUInstruction CPUInstructions[256][8] = {
{cpu_instr_0_0,cpu_instr_0_1,cpu_instr_0_2,0,0,0,0,0},
{cpu_instr_1_0,cpu_instr_1_1,cpu_instr_1_2,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_3_0,cpu_instr_3_1,0,0,0,0,0,0},
{cpu_instr_4_0,cpu_instr_4_1,cpu_instr_4_2,0,0,0,0,0},
{cpu_instr_5_0,cpu_instr_5_1,cpu_instr_5_2,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_7_0,cpu_instr_7_1,cpu_instr_7_2,0,0,0,0,0},
{cpu_instr_8_0,cpu_instr_8_1,0,0,0,0,0,0},
{cpu_instr_9_0,cpu_instr_9_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_12_0,cpu_instr_12_1,cpu_instr_12_2,cpu_instr_12_3,cpu_instr_12_4,cpu_instr_12_5,cpu_instr_12_6,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_16_0,cpu_instr_16_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_19_0,cpu_instr_19_1,0,0,0,0,0,0},
{cpu_instr_20_0,cpu_instr_20_1,cpu_instr_20_2,0,0,0,0,0},
{cpu_instr_21_0,cpu_instr_21_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_23_0,0,0,0,0,0,0,0},
{cpu_instr_24_0,0,0,0,0,0,0,0},
{cpu_instr_25_0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_27_0,cpu_instr_27_1,cpu_instr_27_2,cpu_instr_27_3,0,0,0,0},
{cpu_instr_28_0,cpu_instr_28_1,0,0,0,0,0,0},
{cpu_instr_29_0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_31_0,cpu_instr_31_1,cpu_instr_31_2,cpu_instr_31_3,0,0,0,0},
{cpu_instr_32_0,cpu_instr_32_1,cpu_instr_32_2,cpu_instr_32_3,cpu_instr_32_4,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_35_0,cpu_instr_35_1,0,0,0,0,0,0},
{cpu_instr_36_0,cpu_instr_36_1,cpu_instr_36_2,0,0,0,0,0},
{cpu_instr_37_0,cpu_instr_37_1,cpu_instr_37_2,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_39_0,cpu_instr_39_1,cpu_instr_39_2,0,0,0,0,0},
{cpu_instr_40_0,cpu_instr_40_1,0,0,0,0,0,0},
{cpu_instr_41_0,cpu_instr_41_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_43_0,cpu_instr_43_1,0,0,0,0,0,0},
{cpu_instr_44_0,cpu_instr_44_1,cpu_instr_44_2,cpu_instr_44_3,cpu_instr_44_4,cpu_instr_44_5,cpu_instr_44_6,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_48_0,cpu_instr_48_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_51_0,cpu_instr_51_1,0,0,0,0,0,0},
{cpu_instr_52_0,cpu_instr_52_1,cpu_instr_52_2,0,0,0,0,0},
{cpu_instr_53_0,cpu_instr_53_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_55_0,0,0,0,0,0,0,0},
{cpu_instr_56_0,0,0,0,0,0,0,0},
{cpu_instr_57_0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_59_0,cpu_instr_59_1,cpu_instr_59_2,cpu_instr_59_3,0,0,0,0},
{cpu_instr_60_0,cpu_instr_60_1,0,0,0,0,0,0},
{cpu_instr_61_0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_63_0,cpu_instr_63_1,cpu_instr_63_2,cpu_instr_63_3,0,0,0,0},
{cpu_instr_64_0,0,0,0,0,0,0,0},
{cpu_instr_65_0,cpu_instr_65_1,cpu_instr_65_2,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_67_0,cpu_instr_67_1,0,0,0,0,0,0},
{cpu_instr_68_0,0,0,0,0,0,0,0},
{cpu_instr_69_0,cpu_instr_69_1,cpu_instr_69_2,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_71_0,cpu_instr_71_1,cpu_instr_71_2,cpu_instr_71_3,0,0,0,0},
{cpu_instr_72_0,cpu_instr_72_1,0,0,0,0,0,0},
{cpu_instr_73_0,cpu_instr_73_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_76_0,cpu_instr_76_1,cpu_instr_76_2,cpu_instr_76_3,cpu_instr_76_4,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_79_0,cpu_instr_79_1,cpu_instr_79_2,cpu_instr_79_3,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_83_0,cpu_instr_83_1,0,0,0,0,0,0},
{cpu_instr_84_0,cpu_instr_84_1,cpu_instr_84_2,0,0,0,0,0},
{cpu_instr_85_0,cpu_instr_85_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_87_0,0,0,0,0,0,0,0},
{cpu_instr_88_0,0,0,0,0,0,0,0},
{cpu_instr_89_0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_91_0,0,0,0,0,0,0,0},
{cpu_instr_92_0,cpu_instr_92_1,0,0,0,0,0,0},
{cpu_instr_93_0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_95_0,0,0,0,0,0,0,0},
{cpu_instr_96_0,cpu_instr_96_1,cpu_instr_96_2,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_99_0,cpu_instr_99_1,0,0,0,0,0,0},
{cpu_instr_100_0,0,0,0,0,0,0,0},
{cpu_instr_101_0,cpu_instr_101_1,cpu_instr_101_2,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_103_0,cpu_instr_103_1,cpu_instr_103_2,0,0,0,0,0},
{cpu_instr_104_0,cpu_instr_104_1,0,0,0,0,0,0},
{cpu_instr_105_0,cpu_instr_105_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_107_0,cpu_instr_107_1,0,0,0,0,0,0},
{cpu_instr_108_0,cpu_instr_108_1,cpu_instr_108_2,cpu_instr_108_3,cpu_instr_108_4,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_111_0,cpu_instr_111_1,cpu_instr_111_2,cpu_instr_111_3,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_115_0,cpu_instr_115_1,0,0,0,0,0,0},
{cpu_instr_116_0,cpu_instr_116_1,cpu_instr_116_2,0,0,0,0,0},
{cpu_instr_117_0,cpu_instr_117_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_120_0,0,0,0,0,0,0,0},
{cpu_instr_121_0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_123_0,0,0,0,0,0,0,0},
{cpu_instr_124_0,cpu_instr_124_1,0,0,0,0,0,0},
{cpu_instr_125_0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_127_0,0,0,0,0,0,0,0},
{cpu_instr_128_0,cpu_instr_128_1,cpu_instr_128_2,0,0,0,0,0},
{cpu_instr_129_0,cpu_instr_129_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_131_0,cpu_instr_131_1,0,0,0,0,0,0},
{cpu_instr_132_0,cpu_instr_132_1,cpu_instr_132_2,cpu_instr_132_3,0,0,0,0},
{cpu_instr_133_0,cpu_instr_133_1,cpu_instr_133_2,0,0,0,0,0},
{cpu_instr_134_0,cpu_instr_134_1,cpu_instr_134_2,cpu_instr_134_3,0,0,0,0},
{cpu_instr_135_0,cpu_instr_135_1,cpu_instr_135_2,0,0,0,0,0},
{cpu_instr_136_0,cpu_instr_136_1,cpu_instr_136_2,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_138_0,cpu_instr_138_1,cpu_instr_138_2,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_140_0,cpu_instr_140_1,cpu_instr_140_2,cpu_instr_140_3,cpu_instr_140_4,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_142_0,cpu_instr_142_1,cpu_instr_142_2,cpu_instr_142_3,cpu_instr_142_4,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_144_0,cpu_instr_144_1,0,0,0,0,0,0},
{cpu_instr_145_0,cpu_instr_145_1,0,0,0,0,0,0},
{cpu_instr_146_0,cpu_instr_146_1,cpu_instr_146_2,0,0,0,0,0},
{cpu_instr_147_0,cpu_instr_147_1,0,0,0,0,0,0},
{cpu_instr_148_0,0,0,0,0,0,0,0},
{cpu_instr_149_0,0,0,0,0,0,0,0},
{cpu_instr_150_0,0,0,0,0,0,0,0},
{cpu_instr_151_0,0,0,0,0,0,0,0},
{cpu_instr_152_0,cpu_instr_152_1,0,0,0,0,0,0},
{cpu_instr_153_0,cpu_instr_153_1,cpu_instr_153_2,cpu_instr_153_3,0,0,0,0},
{cpu_instr_154_0,cpu_instr_154_1,cpu_instr_154_2,cpu_instr_154_3,cpu_instr_154_4,0,0,0},
{cpu_instr_155_0,cpu_instr_155_1,cpu_instr_155_2,cpu_instr_155_3,0,0,0,0},
{cpu_instr_156_0,cpu_instr_156_1,cpu_instr_156_2,cpu_instr_156_3,cpu_instr_156_4,0,0,0},
{cpu_instr_157_0,cpu_instr_157_1,cpu_instr_157_2,cpu_instr_157_3,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_159_0,cpu_instr_159_1,cpu_instr_159_2,cpu_instr_159_3,0,0,0,0},
{cpu_instr_160_0,cpu_instr_160_1,cpu_instr_160_2,0,0,0,0,0},
{cpu_instr_161_0,cpu_instr_161_1,0,0,0,0,0,0},
{cpu_instr_162_0,cpu_instr_162_1,cpu_instr_162_2,0,0,0,0,0},
{cpu_instr_163_0,cpu_instr_163_1,0,0,0,0,0,0},
{cpu_instr_164_0,cpu_instr_164_1,cpu_instr_164_2,cpu_instr_164_3,0,0,0,0},
{cpu_instr_165_0,cpu_instr_165_1,cpu_instr_165_2,0,0,0,0,0},
{cpu_instr_166_0,cpu_instr_166_1,cpu_instr_166_2,cpu_instr_166_3,0,0,0,0},
{cpu_instr_167_0,cpu_instr_167_1,cpu_instr_167_2,0,0,0,0,0},
{cpu_instr_168_0,cpu_instr_168_1,cpu_instr_168_2,0,0,0,0,0},
{cpu_instr_169_0,cpu_instr_169_1,0,0,0,0,0,0},
{cpu_instr_170_0,cpu_instr_170_1,cpu_instr_170_2,0,0,0,0,0},
{cpu_instr_171_0,cpu_instr_171_1,0,0,0,0,0,0},
{cpu_instr_172_0,cpu_instr_172_1,cpu_instr_172_2,cpu_instr_172_3,cpu_instr_172_4,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_174_0,cpu_instr_174_1,cpu_instr_174_2,cpu_instr_174_3,cpu_instr_174_4,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_176_0,cpu_instr_176_1,0,0,0,0,0,0},
{cpu_instr_177_0,cpu_instr_177_1,0,0,0,0,0,0},
{cpu_instr_178_0,cpu_instr_178_1,cpu_instr_178_2,0,0,0,0,0},
{cpu_instr_179_0,cpu_instr_179_1,0,0,0,0,0,0},
{cpu_instr_180_0,0,0,0,0,0,0,0},
{cpu_instr_181_0,0,0,0,0,0,0,0},
{cpu_instr_182_0,0,0,0,0,0,0,0},
{cpu_instr_183_0,0,0,0,0,0,0,0},
{cpu_instr_184_0,cpu_instr_184_1,cpu_instr_184_2,cpu_instr_184_3,cpu_instr_184_4,0,0,0},
{cpu_instr_185_0,cpu_instr_185_1,cpu_instr_185_2,cpu_instr_185_3,0,0,0,0},
{cpu_instr_186_0,cpu_instr_186_1,cpu_instr_186_2,cpu_instr_186_3,cpu_instr_186_4,0,0,0},
{cpu_instr_187_0,cpu_instr_187_1,cpu_instr_187_2,cpu_instr_187_3,0,0,0,0},
{cpu_instr_188_0,cpu_instr_188_1,cpu_instr_188_2,cpu_instr_188_3,cpu_instr_188_4,0,0,0},
{cpu_instr_189_0,cpu_instr_189_1,cpu_instr_189_2,cpu_instr_189_3,0,0,0,0},
{cpu_instr_190_0,cpu_instr_190_1,cpu_instr_190_2,cpu_instr_190_3,cpu_instr_190_4,0,0,0},
{cpu_instr_191_0,cpu_instr_191_1,cpu_instr_191_2,cpu_instr_191_3,0,0,0,0},
{cpu_instr_192_0,cpu_instr_192_1,cpu_instr_192_2,0,0,0,0,0},
{cpu_instr_193_0,cpu_instr_193_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_195_0,cpu_instr_195_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_197_0,cpu_instr_197_1,cpu_instr_197_2,0,0,0,0,0},
{cpu_instr_198_0,cpu_instr_198_1,cpu_instr_198_2,cpu_instr_198_3,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_200_0,cpu_instr_200_1,0,0,0,0,0,0},
{cpu_instr_201_0,cpu_instr_201_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_204_0,cpu_instr_204_1,cpu_instr_204_2,0,0,0,0,0},
{cpu_instr_205_0,cpu_instr_205_1,cpu_instr_205_2,cpu_instr_205_3,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_207_0,cpu_instr_207_1,cpu_instr_207_2,cpu_instr_207_3,0,0,0,0},
{cpu_instr_208_0,cpu_instr_208_1,0,0,0,0,0,0},
{cpu_instr_209_0,cpu_instr_209_1,0,0,0,0,0,0},
{cpu_instr_210_0,cpu_instr_210_1,cpu_instr_210_2,0,0,0,0,0},
{cpu_instr_211_0,cpu_instr_211_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_214_0,0,0,0,0,0,0,0},
{cpu_instr_215_0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_217_0,0,0,0,0,0,0,0},
{cpu_instr_218_0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_220_0,0,0,0,0,0,0,0},
{cpu_instr_221_0,0,0,0,0,0,0,0},
{cpu_instr_222_0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_224_0,cpu_instr_224_1,cpu_instr_224_2,0,0,0,0,0},
{cpu_instr_225_0,cpu_instr_225_1,0,0,0,0,0,0},
{cpu_instr_226_0,cpu_instr_226_1,cpu_instr_226_2,0,0,0,0,0},
{cpu_instr_227_0,cpu_instr_227_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_229_0,cpu_instr_229_1,cpu_instr_229_2,0,0,0,0,0},
{cpu_instr_230_0,cpu_instr_230_1,cpu_instr_230_2,cpu_instr_230_3,0,0,0,0},
{cpu_instr_231_0,cpu_instr_231_1,cpu_instr_231_2,0,0,0,0,0},
{cpu_instr_232_0,cpu_instr_232_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_234_0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_237_0,cpu_instr_237_1,cpu_instr_237_2,cpu_instr_237_3,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_239_0,cpu_instr_239_1,cpu_instr_239_2,cpu_instr_239_3,0,0,0,0},
{cpu_instr_240_0,cpu_instr_240_1,0,0,0,0,0,0},
{cpu_instr_241_0,cpu_instr_241_1,0,0,0,0,0,0},
{cpu_instr_242_0,cpu_instr_242_1,cpu_instr_242_2,0,0,0,0,0},
{cpu_instr_243_0,cpu_instr_243_1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_246_0,0,0,0,0,0,0,0},
{cpu_instr_247_0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{cpu_instr_249_0,0,0,0,0,0,0,0},
{cpu_instr_250_0,0,0,0,0,0,0,0},
{cpu_instr_251_0,0,0,0,0,0,0,0},
{cpu_instr_252_0,0,0,0,0,0,0,0},
{cpu_instr_253_0,0,0,0,0,0,0,0},
{cpu_instr_254_0,0,0,0,0,0,0,0},
{cpu_instr_255_0,0,0,0,0,0,0,0},
};

113
emulator/keycodes.lua Normal file
View File

@ -0,0 +1,113 @@
-- These are the keycodes provided by the keyboard peripheral to the CPU within the emulator.
-- copied from Brick_LuaLogic/bricks/input/keyboard-global.lua
return {
["backspace"] = 8,
["tab"] = 9,
["return"] = 13,
["lshift"] = 16,
["lcontrol"] = 17,
["lalt"] = 18,
-- this block does not match vkey codes
["rshift"] = 20,
["rcontrol"] = 21,
["ralt"] = 22,
-- this block does not match vkey codes
[";"] = 24,
["="] = 25,
[","] = 26,
["."] = 27,
["/"] = 29,
["`"] = 30,
["space"] = 32,
["pageup"] = 33,
["pagedown"] = 34,
["end"] = 35,
["home"] = 36,
["left"] = 37,
["up"] = 38,
["right"] = 39,
["down"] = 40,
["insert"] = 45,
["delete"] = 46,
["0"] = 48,
["1"] = 49,
["2"] = 50,
["3"] = 51,
["4"] = 52,
["5"] = 53,
["6"] = 54,
["7"] = 55,
["8"] = 56,
["9"] = 57,
-- this block does not match vkey codes
["["] = 60,
["\\"] = 61,
["]"] = 62,
["apostrophe"] = 63,
["a"] = 65,
["b"] = 66,
["c"] = 67,
["d"] = 68,
["e"] = 69,
["f"] = 70,
["g"] = 71,
["h"] = 72,
["i"] = 73,
["j"] = 74,
["k"] = 75,
["l"] = 76,
["m"] = 77,
["n"] = 78,
["o"] = 79,
["p"] = 80,
["q"] = 81,
["r"] = 82,
["s"] = 83,
["t"] = 84,
["u"] = 85,
["v"] = 86,
["w"] = 87,
["x"] = 88,
["y"] = 89,
["z"] = 90,
["numpad0"] = 96,
["numpad1"] = 97,
["numpad2"] = 98,
["numpad3"] = 99,
["numpad4"] = 100,
["numpad5"] = 101,
["numpad6"] = 102,
["numpad7"] = 103,
["numpad8"] = 104,
["numpad9"] = 105,
["*"] = 106,
["+"] = 107,
["numpadenter"] = 108,
["minus"] = 109,
["numpaddecimal"] = 110,
--["/"] = 111, -- already 29
["f1"] = 112,
["f2"] = 113,
["f3"] = 114,
["f4"] = 115,
["f5"] = 116,
["f6"] = 117,
["f7"] = 118,
["f8"] = 119,
["f9"] = 120,
["f10"] = 121,
["f11"] = 122,
["f12"] = 123,
["invalid"] = 127,
}

1
emulator/main.lua Normal file
View File

@ -0,0 +1 @@
require("8608emulator")

BIN
emulator/temp/temp.bin Normal file

Binary file not shown.

16
emulator/temp/temp.hex Normal file
View File

@ -0,0 +1,16 @@
outp | addr | data (base 16)
ff00:0 | ff00 | ; PRINTCHAR:
ff00:0 | ff00 | aa ff 0d ; LDX #HELLOSTR
ff03:0 | ff03 | a8 c0 00 ; LDY #$C000
ff06:0 | ff06 | ; PRINTLP:
ff06:0 | ff06 | e1 ; LDA X+
ff07:0 | ff07 | 48 ; PHA
ff08:0 | ff08 | d1 ; STA Y+
ff09:0 | ff09 | d0 fb ; BNE PRINTLP
ff0b:0 | ff0b | 18 ; HLT
ff0c:0 | ff0c | 41 ; RST
ff0d:0 | ff0d | ; HELLOSTR:
ff0d:0 | ff0d | 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 00 ; "Hello, world!\0"
fffc:0 | fffc | ff 00 ; PRINTCHAR
fffe:0 | fffe | 00 00 ; 0

18
emulator/temp/temp.lis Normal file
View File

@ -0,0 +1,18 @@
outp | addr | data (base 16)
0:0 | 0 | ; FAIL:
0:0 | 0 | fa ; INC C
1:0 | 1 | 98 fd ; BRA FAIL
3:0 | 3 | ; RESET:
3:0 | 3 | 58 ; CLI
4:0 | 4 | fe ; INC B
5:0 | 5 | cd f0 05 ; STA TIMER
8:0 | 8 | 18 ; HLT
9:0 | 9 | 98 f8 ; BRA RESET
b:0 | b | 41 ; RST
c:0 | c | ; INTERRUPT:
c:0 | c | f6 ; INC A
d:0 | d | 38 ; RUN
e:0 | e | 40 ; RTI
fffc:0 | fffc | 00 03 ; RESET
fffe:0 | fffe | 00 0c ; INTERRUPT

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Binary file not shown.

BIN
emulator/third-party/love/OpenAL32.dll vendored Normal file

Binary file not shown.

BIN
emulator/third-party/love/SDL2.dll vendored Normal file

Binary file not shown.

1440
emulator/third-party/love/changes.txt vendored Normal file

File diff suppressed because it is too large Load Diff

BIN
emulator/third-party/love/game.ico vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

1355
emulator/third-party/love/license.txt vendored Normal file

File diff suppressed because it is too large Load Diff

BIN
emulator/third-party/love/love.dll vendored Normal file

Binary file not shown.

BIN
emulator/third-party/love/love.exe vendored Normal file

Binary file not shown.

BIN
emulator/third-party/love/love.ico vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

BIN
emulator/third-party/love/lovec.exe vendored Normal file

Binary file not shown.

BIN
emulator/third-party/love/lua51.dll vendored Normal file

Binary file not shown.

BIN
emulator/third-party/love/mpg123.dll vendored Normal file

Binary file not shown.

BIN
emulator/third-party/love/msvcp120.dll vendored Normal file

Binary file not shown.

BIN
emulator/third-party/love/msvcr120.dll vendored Normal file

Binary file not shown.

111
emulator/third-party/love/readme.txt vendored Normal file
View File

@ -0,0 +1,111 @@
LÖVE is an *awesome* framework you can use to make 2D games in Lua. It's free, open-source, and works on Windows, macOS, Linux, Android, and iOS.
[![Build Status: Windows](https://ci.appveyor.com/api/projects/status/chc0hdr08wv1d5c7?svg=true)](https://ci.appveyor.com/project/slime73/love)
[![Build Status: Github CI](https://github.com/love2d/love/workflows/continuous-integration/badge.svg)](https://github.com/love2d/love/actions?query=workflow%3Acontinuous-integration)
Documentation
-------------
We use our [wiki][wiki] for documentation.
If you need further help, feel free to ask on our [forums][forums], our [Discord server][discord], or our [subreddit][subreddit].
Repository
----------
We use the 'main' branch for patch development of the current major release, and therefore it should not be considered stable.
There may also be a branch for the next major version in development, which is named after that version.
We tag all our releases (since we started using mercurial and git), and have binary downloads available for them.
Experimental changes are developed in a separate [love-experiments][love-experiments] repository.
Builds
------
Files for releases are in the [releases][releases] section on GitHub. [The site][site] has links to files and additional platform content for the latest release.
There are also unstable/nightly builds:
- Builds for some platforms are automatically created after each commit and are available through GitHub's CI interfaces.
- For ubuntu linux they are in [ppa:bartbes/love-unstable][unstableppa]
- For arch linux there's [love-git][aur] in the AUR.
Contributing
------------
The best places to contribute are through the issue tracker and the official Discord server or IRC channel.
For code contributions, pull requests and patches are welcome. Be sure to read the [source code style guide][codestyle].
Changes and new features typically get discussed in the issue tracker or on Discord or the forums before a pull request is made.
Compilation
-----------
### Windows
Follow the instructions at the [megasource][megasource] repository page.
### *nix
Run `platform/unix/automagic` from the repository root, then run ./configure and make.
$ platform/unix/automagic
$ ./configure
$ make
When using a source release, automagic has already been run, and the first step can be skipped.
### macOS
Download or clone [this repository][dependencies-apple] and copy, move, or symlink the `macOS/Frameworks` subfolder into love's `platform/xcode/macosx` folder.
Then use the Xcode project found at `platform/xcode/love.xcodeproj` to build the `love-macosx` target.
### iOS
Building for iOS requires macOS and Xcode.
#### LÖVE 11.4 and newer
Download the `love-apple-dependencies` zip file corresponding to the LÖVE version being used from the [Releases page][dependencies-ios],
unzip it, and place the `iOS/libraries` subfolder into love's `platform/xcode/ios` folder.
Or, download or clone [this repository][dependencies-apple] and copy, move, or symlink the `iOS/libraries` subfolder into love's `platform/xcode/ios` folder.
Then use the Xcode project found at `platform/xcode/love.xcodeproj` to build the `love-ios` target.
See `readme-iOS.rtf` for more information.
#### LÖVE 11.3 and older
Download the `ios-libraries` zip file corresponding to the LÖVE version being used from the [Releases page][dependencies-ios],
unzip it, and place the `include` and `libraries` subfolders into love's `platform/xcode/ios` folder.
Then use the Xcode project found at `platform/xcode/love.xcodeproj` to build the `love-ios` target.
See `readme-iOS.rtf` for more information.
### Android
Visit the [Android build repository][android-repository] for build instructions.
Dependencies
------------
- SDL2
- OpenGL 2.1+ / OpenGL ES 2+
- OpenAL
- Lua / LuaJIT / LLVM-lua
- FreeType
- ModPlug
- mpg123
- Vorbisfile
- Theora
[site]: https://love2d.org
[wiki]: https://love2d.org/wiki
[forums]: https://love2d.org/forums
[discord]: https://discord.gg/rhUets9
[subreddit]: https://www.reddit.com/r/love2d
[dependencies-apple]: https://github.com/love2d/love-apple-dependencies
[dependencies-ios]: https://github.com/love2d/love/releases
[megasource]: https://github.com/love2d/megasource
[unstableppa]: https://launchpad.net/~bartbes/+archive/love-unstable
[aur]: https://aur.archlinux.org/packages/love-git
[love-experiments]: https://github.com/slime73/love-experiments
[codestyle]: https://love2d.org/wiki/Code_Style
[android-repository]: https://github.com/love2d/love-android
[releases]: https://github.com/love2d/love/releases

View File

@ -1,6 +1,6 @@
-- generate-architecture.lua
-- This program uses the definitions in 8608-definition.lua to generate the assembler definitions, instruction list, and microcode.
-- Also see 8608-definition.lua
-- This program uses the definitions in 8610-definition.lua to generate the assembler definitions, instruction list, and microcode.
-- Also see 8610-definition.lua
local debugInfo = {}
local function getDebugInfo()
@ -9,11 +9,13 @@ end
local function hex(n) return string.format("%02X", n) end
local function cycleAddSignals(cycle, cyc2, cyc2t, ops, sigs)
local function cycleAddSignals(cycle, cyc2, cyc2t, ops, sigs, opsUsed, sigsUsed)
for _, name in ipairs(cycle) do
if ops[name] then
cycleAddSignals(ops[name], cyc2, cyc2t, ops, sigs)
opsUsed[name] = true
cycleAddSignals(ops[name], cyc2, cyc2t, ops, sigs, opsUsed, sigsUsed)
elseif sigs[name] then
sigsUsed[name] = true
if not cyc2t[name] then
cyc2t[name] = true
table.insert(cyc2, name)
@ -25,19 +27,17 @@ local function cycleAddSignals(cycle, cyc2, cyc2t, ops, sigs)
end
end
end
local function cycleSimplify(cycle, ops, sigs)
local function cycleSimplify(cycle, ops, sigs, opsUsed, sigsUsed)
local cyc2, cyc2t = {}, {}
cycleAddSignals(cycle, cyc2, cyc2t, ops, sigs)
cycleAddSignals(cycle, cyc2, cyc2t, ops, sigs, opsUsed, sigsUsed)
return cyc2
end
local function cycleToUcycle(cycle, ops, sigs)
local function cycleToUcycle(cycle, ops, sigs, opsUsed, sigsUsed)
local ucycle = {}
local cyc2 = cycleSimplify(cycle, ops, sigs)
local hasbase = false
local cyc2 = cycleSimplify(cycle, ops, sigs, opsUsed, sigsUsed)
local nonempty = false
for _, name in ipairs(cyc2) do
nonempty = true
if name=="always1" then hasbase = true end
local sig = sigs[name]
assert(sig, "no signal named "..name)
for i, sbit in ipairs(sig) do
@ -46,13 +46,12 @@ local function cycleToUcycle(cycle, ops, sigs)
ucycle[sbit.rom][sbit.bit] = true
end
end
if nonempty and (not hasbase) then error("cycle has no base"..getDebugInfo()) end
return ucycle
end
local function encodeInstruction(opcode, instr, ucode, ops, sigs)
local function encodeInstruction(opcode, instr, ucode, ops, sigs, opsUsed, sigsUsed)
for sub, cycle in ipairs(instr) do
debugInfo.sub = sub-1
local ucycle = cycleToUcycle(cycle, ops, sigs)
local ucycle = cycleToUcycle(cycle, ops, sigs, opsUsed, sigsUsed)
local uaddr = opcode*4 + (sub-1)
assert(not ucode[uaddr], "overused ucode addr "..uaddr)
ucode[uaddr] = ucycle
@ -73,88 +72,83 @@ local function sigsFromRoms(roms)
return sigs
end
local relJmpStr = [[
%s {addr} => {
local subruleDefs = [[
#subruledef rel8 {
{addr} => {
reladdr = addr - $ - 2
assert(reladdr <= 127, "%s: Relative jump target is too far away")
assert(reladdr >= -128, "%s: Relative jump target is too far away")
%s @ reladdr`8
}]]
local wordRelStr = [[
%s+{value: i%i} => {
assert(value <= %i, "Relative address is too far away")
assert(value >= %i, "Relative address is too far away")
%s @ value`%i
assert(reladdr <= 127, "Relative jump target is too far away")
assert(reladdr >= -128, "Relative jump target is too far away")
reladdr`8
}
%s-{value: i%i} => {
mvalue = -value
assert(mvalue <= %i, "Relative address is too far away")
assert(mvalue >= %i, "Relative address is too far away")
%s @ mvalue`%i
}]]
local byteNegStr = [[
%s {value:i8} => {
mvalue = -value
%s @ mvalue`8
}
]]
#subruledef neg8 {
{value} => {
mvalue = -value
mvalue`8
}
}]]
local function getAsmCode(mnem, instr)
local reljmp = instr.jmp and instr.rel
local opcodeS = string.format("$%02X", instr.opcode)
if reljmp then
assert(mnem:find("imm8"), "relative jump without imm8")
local mnemPart = mnem:gsub(" imm8", "")
return string.format(relJmpStr,
mnemPart, mnemPart, mnemPart,
opcodeS
)
elseif mnem:find("%+imm") then
local mnemPart, bitsS = mnem:match("^([^%+]+)%+imm([0-9]+)$")
local bits = tonumber(bitsS)
local maxVal = math.pow(2, bits-1)-1
local minVal = -math.pow(2, bits-1)
return string.format(wordRelStr,
mnemPart, bits, maxVal, minVal, opcodeS, bits,
mnemPart, bits, maxVal, minVal, opcodeS, bits
)
elseif mnem:find("imm8neg") then
mnemPart = mnem:match("^([^ ]+) imm8neg$")
return string.format(byteNegStr, mnemPart, opcodeS)
elseif mnem:find("imm8") then
local mnemPreImm = mnem
mnem = mnem:gsub("imm8rel", "{value: rel8}")
mnem = mnem:gsub("imm8neg", "{value: neg8}")
mnem = mnem:gsub("imm8s" , "{value: s8}")
mnem = mnem:gsub("imm8u" , "{value: u8}")
mnem = mnem:gsub("imm8" , "{value: i8}" )
return mnem.." => "..opcodeS.." @ value"
elseif mnem:find("imm16") then
mnem = mnem:gsub("imm16" , "{value: i16}" )
return mnem.." => "..opcodeS.." @ value"
else
if mnem == mnemPreImm then
return mnem.." => "..opcodeS
else
return mnem.." => "..opcodeS.." @ value"
end
end
local function getAsmsFromInstr(instr, aliases)
local mnem = instr.mnem
local function getAsmsFromInstr(mnem, instr, aliases)
local t = {}
if mnem then
table.insert(t, getAsmCode(mnem, instr))
if aliases[mnem] then
if aliases and aliases[mnem] then
for _, mnem2 in ipairs(aliases[mnem]) do
table.insert(t, getAsmCode(mnem2, instr))
end
end
end
return t
end
local function transformDescription(arch, desc)
if arch.descShortcuts then
for _, sc in ipairs(arch.descShortcuts) do
pat, rep = unpack(sc)
pat = pat:gsub("%%", "%%%%")
desc = desc:gsub(pat, rep)
end
end
return desc
end
local function printUnusedThing(thing, all, used)
for name, _ in pairs(all) do
if not used[name] then
print("Unused "..thing..": "..name)
end
end
end
local function printUnused(ops, sigs, opsUsed, sigsUsed)
printUnusedThing("Macro-operation", ops, opsUsed)
printUnusedThing("Control Signal", sigs, sigsUsed)
end
local asmDataStr = [[
%s
#ruledef {
%s
}
]]
local function archToUcode(arch)
local function archToUcode(arch, writeFiles)
local sigs = sigsFromRoms(arch.roms)
local ops = arch.operations
local sigsUsed = {}
local opsUsed = {}
local ucode = {}
local opcodesUsed = {}
local numOpcodesUsed = 0
@ -162,10 +156,15 @@ local function archToUcode(arch)
local asmlines = {}
local catlet = "X"
for _, instr in ipairs(arch.instructions) do
if instr.category then
if instr.category or instr.catlet then
assert(instr.catlet, "category header has no catlet")
catlet = instr.catlet
if instr.category then
assert(not instr.mnem, "mnem in category header")
assert(not instr.opcode, "opcode in category header")
table.insert(infolines, "\n")
table.insert(infolines, instr.category.." ("..catlet.."):\n")
end
else
local mnem = instr.mnem or error("instr has no mnem")
local opcode = instr.opcode or error("instr has no opcode "..mnem)
@ -176,36 +175,42 @@ local function archToUcode(arch)
if len>1 then assert(opcode%2==0, "len>1 on odd opcode") end
for i = 1, len do
local opcode2 = opcode+i-1
assert(not opcodesUsed[opcode2], "overused opcode "..hex(opcode))
opcodesUsed[opcode2] = catlet
if opcodesUsed[opcode2] then
local other = opcodesUsed[opcode2]
error("overused opcode "..hex(opcode2)..": "..mnem.." part "..i.." overwrites "..other[2].." part "..other[3])
end
opcodesUsed[opcode2] = {catlet, mnem, i}
numOpcodesUsed = numOpcodesUsed+1
end
debugInfo.mnem = mnem
encodeInstruction(opcode, instr, ucode, ops, sigs)
encodeInstruction(opcode, instr, ucode, ops, sigs, opsUsed, sigsUsed)
if instr.desc then
table.insert(infolines, mnem..(" "):rep(13-#mnem)..hex(opcode).." "..ncycles.." "..instr.desc.."\n")
end
local desc = transformDescription(arch, instr.desc)
table.insert(infolines, mnem..(" "):rep(13-#mnem)..hex(opcode).." "..ncycles.." "..desc.."\n")
local asms = getAsmsFromInstr(instr, arch.aliases)
local mnem2 = arch.transformMnemonic and arch.transformMnemonic(mnem) or mnem
local asms = getAsmsFromInstr(mnem2, instr, arch.aliases)
for _, a in ipairs(asms) do table.insert(asmlines, a) end
end
end
end
local lt = {"Opcodes used: "..numOpcodesUsed.."/255\n", " "}
printUnused(ops, sigs, opsUsed, sigsUsed)
local lt = {"Opcodes used: "..numOpcodesUsed.."/256\n", " "}
for i = 0, 15 do table.insert(lt, hex(i):sub(2, 2)) end
table.insert(lt, "\n")
for line = 0, 255, 16 do
table.insert(lt, hex(line).." | ")
for opcode = line, line+15 do
if opcodesUsed[opcode] then table.insert(lt, opcodesUsed[opcode])
if opcodesUsed[opcode] then table.insert(lt, opcodesUsed[opcode][1])
else table.insert(lt, "-") end
end
table.insert(lt, "\n")
end
local writeFiles = true
if writeFiles then
-- Output instruction list
local info = arch.instructionListHeader..table.concat(infolines).."\n"..table.concat(lt)
@ -219,7 +224,10 @@ local function archToUcode(arch)
end
-- Output customASM definitions
local asmTable = arch.assemblerDefsHeader..string.format(asmDataStr, table.concat(asmlines, "\n\t"))
local asmTable = arch.assemblerDefsHeader..string.format(asmDataStr,
subruleDefs,
table.concat(asmlines, "\n\t")
)
local fo = io.open(arch.assemblerDefsFile, "w")
if fo then
fo:write(asmTable)
@ -277,11 +285,12 @@ local function buildBricks(bricks)
end
end
local function buildArch(arch)
local ucode = archToUcode(arch)
local function generateArchitecture(arch, writeFiles, build)
local ucode = archToUcode(arch, writeFiles)
if build then
local bricks = ucodeToBricks(ucode, arch.roms)
buildBricks(bricks)
end
end
local arch = require("8608-definition")
buildArch(arch)
return generateArchitecture

1
getting-started.md Normal file
View File

@ -0,0 +1 @@
WIP

BIN
instruction-map.ods Normal file

Binary file not shown.

View File

@ -7,271 +7,219 @@ Instructions are encoded as the opcode, followed by any immediate values.
Each instruction is described in order of: Mnemonic, Opcode, Clock cycles, Description
Control (C):
rst 00 1 Clear all registers and set I=0
hlt F0 1 Halt non-interrupt execution
run F1 1 Resume non-interrupt execution
brk F3 1 Trigger interrupt
irt F4 1 Return from interrupt
nop FF 1 Do nothing
ien F5 1 Enbale interrupts
idi F6 1 Disable interrupts
RST 41 3 Clear all registers and flags, load the Program Counter from memory addresses $FFFC-$FFFD, and execute the code at the address given by those bytes
BRK 00 3 Trigger an interrupt from software, saving the current Program Counter in the V register and jumping to the Interrupt Vector stored at memory addresses $FFFE-$FFFF
RTI 40 1 Return from an interrupt, resuming normal execution where it left off when the interrupt occurred
NOP EA 1 Do nothing
CLI 58 1 Enable interrupts to be triggered by external hardware
SEI 78 1 Disable interrupts being triggered by external hardware
HLT 18 1 Clear the Run Flag, preventing the CPU from running until an interrupt is triggered
RUN 38 1 Set the Run Flag, allowing the CPU to run once the current interrupt finishes
16-bit Inc/Dec (I):
inc p 12 1 P++
dec p 15 1 P--
inc q 13 1 Q++
dec q 16 1 Q--
8-bit Unary Arithmetic (U):
INC A F6 1 Increment the A register, and set the Carry Flag and Zero Flag according to the result
DEC A D6 1 Decrement the A register, and set the Carry Flag and Zero Flag according to the result
ICC A 57 1 Add the Carry Flag to the A register, and set the Carry Flag and Zero Flag according to the result
INC B FE 1 Increment the B register, and set the Carry Flag and Zero Flag according to the result
DEC B DE 1 Decrement the B register, and set the Carry Flag and Zero Flag according to the result
ICC B 5F 1 Add the Carry Flag to the B register, and set the Carry Flag and Zero Flag according to the result
INC C FA 1 Increment the C register, and set the Carry Flag and Zero Flag according to the result
DEC C DA 1 Decrement the C register, and set the Carry Flag and Zero Flag according to the result
ICC C 5B 1 Add the Carry Flag to the C register, and set the Carry Flag and Zero Flag according to the result
INC zpg E6 4 Increment the value at an given 8-bit address, and set the Carry Flag and Zero Flag according to the result
DEC zpg C6 4 Decrement the value at an given 8-bit address, and set the Carry Flag and Zero Flag according to the result
ICC zpg 47 4 Add the Carrry Flag to the value at an given 8-bit address, and set the Carry Flag and Zero Flag according to the result
8-bit Unary (U):
inc a 10 1 A++, set flags
dec a 11 1 A--, set flags
icc a 1B 1 A+=CF, set flags
inc b 19 1 B++, set flags
dec b 1A 1 B--, set flags
icc b 1C 1 B+=CF, set flags
inc c 17 1 C++, set flags
dec c 18 1 C--, set flags
icc c 1D 1 C+=CF, set flags
tst a 14 1 Set flags according to A-0
tst b 1E 1 Set flags according to B-0
tst c 1F 1 Set flags according to C-0
inc *s+imm8 2B 4 *(S+imm8)++, set flags
dec *s+imm8 2C 4 *(S+imm8)--, set flags
icc *s+imm8 2D 4 *(S+imm8)+=CF, set flags
tst *s+imm8 2E 3 Set flags according to *(S+imm8)-0
8-bit Arithmetic and Logic (A):
ADD # 6B 2 Add a given 8-bit value to the value in the A register, and set the Carry Flag and Zero Flag according to the result
ADC # 69 2 Add a given 8-bit value plus the Carry Flag to the value in the A register, and set the Carry Flag and Zero Flag according to the result
CMP # C9 2 Set the Carry Flag and Zero Flag according to the result of subtracting a given 8-bit value from the value in the A register
AND # 29 2 Bitwise AND the value in the A register with a given 8-bit value, and set the Zero Flag according to the result
ORA # 09 2 Bitwise OR the value in the A register with a given 8-bit value, and set the Zero Flag according to the result
EOR # 49 2 Bitwise Exclusive OR the value in the A register with a given 8-bit value, and set the Zero Flag according to the result
ASL # 15 2 Bit-shift the value in the A register left by a given number of bits, and set the Zero Flag according to the result
LSR # 55 2 Bit-shift the value in the A register right by a given number of bits, and set the Zero Flag according to the result
ROL # 35 2 Bit-rotate the value in the A register left by a given number of bits, and set the Zero Flag according to the result
ROR # 75 2 Bit-rotate the value in the A register right by a given number of bits, and set the Zero Flag according to the result
ADD zpg 67 3 Add the value in memory at a given 8-bit address to the value in the A register, and set the Carry Flag and Zero Flag according to the result
SUB zpg E7 3 Subtract the value in memory at a given 8-bit address from the value in the A register, and set the Carry Flag and Zero Flag according to the result
ADC zpg 65 3 Add the value in memory at a given 8-bit address plus the Carry Flag to the value in the A register, and set the Carry Flag and Zero Flag according to the result
SBC zpg E5 3 Subtract the value in memory at a given 8-bit address from the value in the A register including the Carry Flag, and set the Carry Flag and Zero Flag according to the result
CMP zpg C5 3 Set the Carry Flag and Zero Flag according to the result of subtracting the value in memory at a given 8-bit address from the value in the A register
AND zpg 25 3 Bitwise AND the value in the A register with the value in memory at a given 8-bit address, and set the Carry Flag and Zero Flag according to the result
ORA zpg 05 3 Bitwise OR the value in the A register with the value in memory at a given 8-bit address, and set the Carry Flag and Zero Flag according to the result
EOR zpg 45 3 Bitwise Exclusive OR the value in the A register with the value in memory at a given 8-bit address, and set the Carry Flag and Zero Flag according to the result
ADD B 7F 1 Add the value in the B register to the value in the A register, and set the Carry Flag and Zero Flag according to the result
SUB B FF 1 Subtract the value in the B register from the value in the A register, and set the Carry Flag and Zero Flag according to the result
ADC B 7D 1 Add the value in the B register plus the Carry Flag to the value in the A register, and set the Carry Flag and Zero Flag according to the result
SBC B FD 1 Subtract the value in the B register form the value in the A register including the Carry Flag, and set the Carry Flag and Zero Flag according to the result
CMP B DD 1 Set the Carry Flag and Zero Flag according to the result of subtracting the value in the B register from the value in the A register
AND B 3D 1 Bitwise AND the value in the A register with the value in the B register, and set the Carry Flag and Zero Flag according to the result
ORA B 1D 1 Bitwise OR the value in the A register with the value in the B register, and set the Carry Flag and Zero Flag according to the result
EOR B 5D 1 Bitwise Exclusive OR the value in the A register with the value in the B register, and set the Carry Flag and Zero Flag according to the result
ADD C 7B 1 Add the value in the C register to the value in the A register, and set the Carry Flag and Zero Flag according to the result
SUB C FB 1 Subtract the value in the C register from the value in the A register, and set the Carry Flag and Zero Flag according to the result
ADC C 79 1 Add the value in the C register plus the Carry Flag to the value in the A register, and set the Carry Flag and Zero Flag according to the result
SBC C F9 1 Subtract the value in the C register form the value in the A register including the Carry Flag, and set the Carry Flag and Zero Flag according to the result
CMP C D9 1 Set the Carry Flag and Zero Flag according to the result of subtracting the value in the C register from the value in the A register
AND C 39 1 Bitwise AND the value in the A register with the value in the C register, and set the Carry Flag and Zero Flag according to the result
ORA C 19 1 Bitwise OR the value in the A register with the value in the C register, and set the Carry Flag and Zero Flag according to the result
EOR C 59 1 Bitwise Exclusive OR the value in the A register with the value in the C register, and set the Carry Flag and Zero Flag according to the result
Conditional Branches (B):
BNE rel D0 2 If the result of the last math operation was not 0, Add a signed 8-bit offset to the Program Counter, jumping forward or backward in the program; Add a signed 8-bit offset to the Program Counter, jumping forward or backward in the programc
BEQ rel F0 2 If the result of the last math operation was 0, Add a signed 8-bit offset to the Program Counter, jumping forward or backward in the program; Add a signed 8-bit offset to the Program Counter, jumping forward or backward in the programc
BLT rel 90 2 If the result of the last math operation was negative, Add a signed 8-bit offset to the Program Counter, jumping forward or backward in the program; Add a signed 8-bit offset to the Program Counter, jumping forward or backward in the programc
BGE rel B0 2 If the result of the last math operation was positive or 0, Add a signed 8-bit offset to the Program Counter, jumping forward or backward in the program; Add a signed 8-bit offset to the Program Counter, jumping forward or backward in the programc
BGT rel 30 2 If the result of the last math operation was positive, Add a signed 8-bit offset to the Program Counter, jumping forward or backward in the program; Add a signed 8-bit offset to the Program Counter, jumping forward or backward in the programc
BLE rel 10 2 If the result of the last math operation was negative or 0, Add a signed 8-bit offset to the Program Counter, jumping forward or backward in the program; Add a signed 8-bit offset to the Program Counter, jumping forward or backward in the programc
BRA rel 98 2 Add a signed 8-bit offset to the Program Counter, jumping forward or backward in the program
16-bit Arithmetic (X):
adp imm8 4A 2 P+=imm8 signed
adq imm8 4B 2 Q+=imm8 signed
ads imm8 4C 2 S+=imm8 signed
adp b E6 1 P+=B signed
adq b E7 1 Q+=B signed
ads b E8 1 S+=B signed
8-bit Arithmetic/Logic (A):
add imm8 24 2 A+=imm8, set flags
adb imm8 72 2 B+=imm8, set flags
adc imm8 73 2 C+=imm8, set flags
acc imm8 78 2 A+=imm8+CF, set flags
cmp imm8 71 2 set flags according to A-imm8
and imm8 74 2 A&=imm8, set zero flag
ior imm8 75 2 A|=imm8, set zero flag
xor imm8 76 2 A^=imm8, set zero flag
shl imm8 D0 2 A<<=imm8, set zero flag
shr imm8 D1 2 A>>=imm8, set zero flag
rol imm8 D2 2 A<<<=imm8, set zero flag
ror imm8 D3 2 A>>>=imm8, set zero flag
sra imm8 D4 2 A>>a=imm8, set zero flag
add *s+imm8 AE 3 A+=*(S+imm8), set flags
adb *s+imm8 9B 3 B+=*(S+imm8), set flags
adc *s+imm8 9C 3 C+=*(S+imm8), set flags
sub *s+imm8 AF 3 A-=*(S+imm8), set flags
sbb *s+imm8 9D 3 B-=*(S+imm8), set flags
sbc *s+imm8 9E 3 C-=*(S+imm8), set flags
acc *s+imm8 B5 3 A+=*(S+imm8)+CF, set flags
scc *s+imm8 B7 3 A-=*(S+imm8)+CF, set flags
cmp *s+imm8 B0 3 set flags according to A-*(S+imm8)
and *s+imm8 B1 3 A&=*(S+imm8), set zero flag
ior *s+imm8 B2 3 A|=*(S+imm8), set zero flag
xor *s+imm8 B3 3 A^=*(S+imm8), set zero flag
shl *s+imm8 D5 3 A<<=*(S+imm8), set zero flag
shr *s+imm8 D6 3 A<<=*(S+imm8), set zero flag
rol *s+imm8 D7 3 A<<<=*(S+imm8), set zero flag
ror *s+imm8 D8 3 A>>>=*(S+imm8), set zero flag
sra *s+imm8 D9 3 A>>a=*(S+imm8), set zero flag
add b A0 1 A+=B, set flags
adc b 9F 1 C+=B, set flags
sub b A1 1 A-=B, set flags
sbc b B6 1 C-=B, set flags
acc b B8 1 A+=B+CF, set flags
scc b B9 1 A-=B+CF, set flags
cmp b A2 1 set flags according to A-B
and b A3 1 A&=B, set zero flag
ior b A4 1 A|=B, set zero flag
xor b A5 1 A^=B, set zero flag
shl b DA 1 A<<=B, set zero flag
shr b DB 1 A>>=B, set zero flag
rol b DC 1 A<<<=B, set zero flag
ror b DD 1 A>>>=B, set zero flag
sra b DE 1 A>>a=B, set zero flag
add c A7 1 A+=C, set flags
adb c BD 1 B+=C, set flags
sub c A8 1 A-=C, set flags
sbb c BC 1 B-=C, set flags
acc c BA 1 A+=C+CF, set flags
scc c BB 1 A-=C+CF, set flags
cmp c A9 1 set flags according to A-C
and c AA 1 A&=C, set zero flag
ior c AB 1 A|=C, set zero flag
xor c AC 1 A^=C, set zero flag
shl c DF 1 A<<=C, set zero flag
shr c 4D 1 A>>=C, set zero flag
rol c 3E 1 A<<<=C, set zero flag
ror c 3F 1 A>>>=C, set zero flag
sra c 2F 1 A>>a=C, set zero flag
adb a BE 1 B+=A, set flags
sbb a BF 1 B-=A, set flags
adc a 4E 1 C+=A, set flags
sbc a 4F 1 C-=A, set flags
ADX # E8 2 Add a given 8-bit value to the 16-bit X register
ADY # C8 2 Add a given 8-bit value to the 16-bit Y register
ADX ## 8A 3 Add a given 16-bit value to the 16-bit X register
ADY ## 88 3 Add a given 16-bit value to the 16-bit Y register
ADX A FC 1 Add the 8-bit signed value in the A register to the 16-bit X register
ADY A DC 1 Add the 8-bit signed value in the A register to the 16-bit Y register
Jumps (J):
jmp imm16 60 3 I=imm16
jsr imm16 63 3 I=imm16, Q=I
jss imm16 E2 5 I=imm16, *(S++++)=I-1
jmp p 64 1 I=P
jmp q 66 1 I=Q
jsr p 65 1 I=P, Q=I
jsr q 67 1 I=Q, Q=I
jss p E4 3 I=P, *(S++++)=I-1
jss q E5 3 I=Q, *(S++++)=I-1
rts E1 3 I=*(----S)+1
jpr imm8 31 2 I+=imm8
jnz imm8 30 2 I+=imm8 if !Zero
jpz imm8 32 2 I+=imm8 if Zero
jlt imm8 33 2 I+=imm8 if !Carry
jge imm8 34 2 I+=imm8 if Carry
jgt imm8 35 2 I+=imm8 if !Zero & Carry
jle imm8 36 2 I+=imm8 if Zero | !Carry
JMP abs CC 3 Jump - Set the Program Counter to a given 16-bit value, executing the code at that address
JSR abs 20 5 Jump to Subroutine - Save the Program Counter on the Stack, then set it to a given 16-bit value, executing the code at that address
JMP [ind] 6C 5 Load a subroutine pointer from memory at a given 16-bit address, then jump to that subroutine, saving the return address on the stack.
JSR [ind] 2C 7 Load a code pointer from memory at a given 16-bit address, then jump to that code.
JMP [ind,A] 4C 5 Load a subroutine pointer from memory at a given 16-bit address, then jump to that subroutine, saving the return address on the stack.
JSR [ind,A] 0C 7 Load a code pointer from memory at a given 16-bit address, then jump to that code.
JMP X 64 1 Set the Program Counter to the 16-bit value in the X register, executing the code at that address
JMP Y 44 1 Set the Program Counter to the 16-bit value in the Y register, executing the code at that address
JSR X 24 3 Save the Program Counter on the Stack, then set it to the 16-bit value in the X register, executing the code at that address
JSR Y 04 3 Save the Program Counter on the Stack, then set it to the 16-bit value in the Y register, executing the code at that address
RTS 60 3 Retrieve the Program Counter from the stack, returning to where the last JSR instruction was executed
Stack (S):
psh a 40 2 *(S++)=A
psh b 44 2 *(S++)=B
psh c 45 2 *(S++)=C
psh f E9 2 *(S++)=F
psh p 41 3 *(S++++)=P
psh q 46 3 *(S++++)=Q
pop a 42 2 A=*(--S)
pop b 47 2 B=*(--S)
pop c 48 2 C=*(--S)
pop f EA 2 F=*(--S)
pop p 43 3 P=*(----S)
pop q 49 3 Q=*(----S)
psh imm8 3B 3 *(S++)=imm8
phw imm16 3C 5 *(S++++)=imm16
PHA 48 2 Push the value in the A register onto the Stack
PHB 5C 2 Push the value in the B register onto the Stack
PHC 1C 2 Push the value in the C register onto the Stack
PHP 08 2 Push a byte containing the Carry Flag and Zero Flag onto the Stack
PHX 54 3 Push the 16-bit value in the X register onto the Stack
PHY 14 3 Push the 16-bit value in the Y register onto the Stack
PLA 68 2 Pull a byte from the Stack, and store it in the A register
PLB 7C 2 Pull a byte from the Stack, and store it in the B register
PLC 3C 2 Pull a byte from the Stack, and store it in the C register
PLP 28 2 Pull a byte from the Stack, and use it to set the Carry Flag and Zero flag
PLX 74 3 Pull two bytes from the stack, and store the resulting 16-bit value in the X register
PLY 34 3 Pull two bytes from the stack, and store the resulting 16-bit value in the Y register
8-bit Load/Store (B):
lda imm8 20 2 A=imm8, update zero flag
ldb imm8 26 2 B=imm8, update zero flag
ldc imm8 27 2 C=imm8, update zero flag
lda *s+imm8 28 3 A=*s+imm8, update zero flag
ldb *s+imm8 29 3 B=*s+imm8, update zero flag
ldc *s+imm8 2A 3 C=*s+imm8, update zero flag
sta *s+imm8 96 3 *s+imm8=A
stb *s+imm8 97 3 *s+imm8=B
stc *s+imm8 98 3 *s+imm8=C
lda *imm16 51 4 A=*imm16, update zero flag
ldb *imm16 56 4 B=*imm16, update zero flag
ldc *imm16 57 4 C=*imm16, update zero flag
sta *imm16 50 4 *imm16=A
stb *imm16 58 4 *imm16=B
stc *imm16 59 4 *imm16=C
lda *p+imm16 01 4 A=*P+imm16, update zero flag
ldb *p+imm16 F7 4 B=*P+imm16, update zero flag
ldc *p+imm16 FE 4 C=*P+imm16, update zero flag
lda *q+imm16 EB 4 A=*Q+imm16, update zero flag
ldb *q+imm16 08 4 B=*Q+imm16, update zero flag
ldc *q+imm16 09 4 C=*Q+imm16, update zero flag
sta *p+imm16 0A 4 *P+imm16=A
stb *p+imm16 0B 4 *P+imm16=B
stc *p+imm16 0C 4 *P+imm16=C
sta *q+imm16 0D 4 *Q+imm16=A
stb *q+imm16 0E 4 *Q+imm16=B
stc *q+imm16 0F 4 *Q+imm16=C
lda *p 53 2 A=*P, update zero flag
ldb *p 5E 2 B=*P, update zero flag
ldc *p 5F 2 C=*P, update zero flag
lda *q 55 2 A=*Q, update zero flag
ldb *q 61 2 B=*Q, update zero flag
ldc *q 62 2 C=*Q, update zero flag
sta *p 52 2 *P=A
stb *p 5A 2 *P=B
stc *p 5B 2 *P=C
sta *q 54 2 *Q=A
stb *q 5C 2 *Q=B
stc *q 5D 2 *Q=C
lda *p++ C6 2 A=*P++, update zero flag
ldb *p++ C7 2 B=*P++, update zero flag
ldc *p++ C8 2 C=*P++, update zero flag
lda *q++ C9 2 A=*Q++, update zero flag
ldb *q++ CA 2 B=*Q++, update zero flag
ldc *q++ CB 2 C=*Q++, update zero flag
sta *p++ C0 2 *P++=A
stb *p++ C1 2 *P++=B
stc *p++ C2 2 *P++=C
sta *q++ C3 2 *Q++=A
stb *q++ C4 2 *Q++=B
stc *q++ C5 2 *Q++=C
LDA # A9 2 Set the A register to a given 8-bit value
LDB # AB 2 Set the B register to a given 8-bit value
LDC # 2B 2 Set the C register to a given 8-bit value
LDA zpg A5 3 Set the A register to the value in memory at a given 8-bit address, and set the Zero Flag according to the value loaded
LDB zpg A7 3 Set the B register to the value in memory at a given 8-bit address, and set the Zero Flag according to the value loaded
LDC zpg 27 3 Set the C register to the value in memory at a given 8-bit address, and set the Zero Flag according to the value loaded
STA zpg 85 3 Store the value in the A register in memory at an given 8-bit address
STB zpg 87 3 Store the value in the B register in memory at an given 8-bit address
STC zpg 07 3 Store the value in the C register in memory at an given 8-bit address
LDA abs ED 4 Set the A register to the value in memory at a given 16-bit address, and set the Zero Flag according to the value loaded
LDB abs EF 4 Set the B register to the value in memory at a given 16-bit address, and set the Zero Flag according to the value loaded
LDC abs 6F 4 Set the C register to the value in memory at a given 16-bit address, and set the Zero Flag according to the value loaded
STA abs CD 4 Store the value in the A register in memory at a given 16-bit address
STB abs CF 4 Store the value in the B register in memory at a given 16-bit address
STC abs 4F 4 Store the value in the C register in memory at a given 16-bit address
LDA X A1 2 Set the A register to the value in memory at the address in X, and set the Zero Flag according to the value loaded
LDB X A3 2 Set the B register to the value in memory at the address in X, and set the Zero Flag according to the value loaded
LDC X 23 2 Set the C register to the value in memory at the address in X, and set the Zero Flag according to the value loaded
LDA Y B1 2 Set the A register to the value in memory at the address in Y, and set the Zero Flag according to the value loaded
LDB Y B3 2 Set the B register to the value in memory at the address in Y, and set the Zero Flag according to the value loaded
LDC Y 33 2 Set the C register to the value in memory at the address in Y, and set the Zero Flag according to the value loaded
STA X 81 2 Store the value in the A register in memory at the address in X
STB X 83 2 Store the value in the B register in memory at the address in X
STC X 03 2 Store the value in the C register in memory at the address in X
STA Y 91 2 Store the value in the A register in memory at the address in Y
STB Y 93 2 Store the value in the B register in memory at the address in Y
STC Y 13 2 Store the value in the C register in memory at the address in Y
LDA X+ E1 2 Set the A register to the value in memory at the address in X, increment the X register, and set the Zero Flag according to the value loaded
LDB X+ E3 2 Set the B register to the value in memory at the address in X, increment the X register, and set the Zero Flag according to the value loaded
LDC X+ 63 2 Set the C register to the value in memory at the address in X, increment the X register, and set the Zero Flag according to the value loaded
LDA Y+ F1 2 Set the A register to the value in memory at the address in Y, increment the Y register, and set the Zero Flag according to the value loaded
LDB Y+ F3 2 Set the B register to the value in memory at the address in Y, increment the Y register, and set the Zero Flag according to the value loaded
LDC Y+ 73 2 Set the C register to the value in memory at the address in Y, increment the Y register, and set the Zero Flag according to the value loaded
STA X+ C1 2 Store the value in the A register in memory at the address in X, and increment the X register
STB X+ C3 2 Store the value in the B register in memory at the address in X, and increment the X register
STC X+ 43 2 Store the value in the C register in memory at the address in X, and increment the X register
STA Y+ D1 2 Store the value in the A register in memory at the address in Y, and increment the Y register
STB Y+ D3 2 Store the value in the B register in memory at the address in Y, and increment the Y register
STC Y+ 53 2 Store the value in the C register in memory at the address in Y, and increment the Y register
LDA X,ofs BD 3 Set the A register to the value in memory at the address (X plus a given 8-bit offset), and set the Zero Flag according to the value loaded
LDB X,ofs BF 3 Set the B register to the value in memory at the address (X plus a given 8-bit offset), and set the Zero Flag according to the value loaded
LDC X,ofs 3F 3 Set the C register to the value in memory at the address (X plus a given 8-bit offset), and set the Zero Flag according to the value loaded
LDA Y,ofs B9 3 Set the A register to the value in memory at the address (Y plus a given 8-bit offset), and set the Zero Flag according to the value loaded
LDB Y,ofs BB 3 Set the B register to the value in memory at the address (Y plus a given 8-bit offset), and set the Zero Flag according to the value loaded
LDC Y,ofs 3B 3 Set the C register to the value in memory at the address (Y plus a given 8-bit offset), and set the Zero Flag according to the value loaded
STA X,ofs 9D 3 Store the value in the A register in memory at the address (X plus a given 8-bit offset)
STB X,ofs 9F 3 Store the value in the A register in memory at the address (X plus a given 8-bit offset)
STC X,ofs 1F 3 Store the value in the A register in memory at the address (X plus a given 8-bit offset)
STA Y,ofs 99 3 Store the value in the A register in memory at the address (Y plus a given 8-bit offset)
STB Y,ofs 9B 3 Store the value in the A register in memory at the address (Y plus a given 8-bit offset)
STC Y,ofs 1B 3 Store the value in the A register in memory at the address (Y plus a given 8-bit offset)
16-bit Load/Store (W):
ldp imm16 21 3 P=imm16
ldq imm16 23 3 Q=imm16
lds imm16 25 3 S=imm16
ldv imm16 22 3 V=imm16
ldp *s+imm8 7A 4 P=*S+imm8
ldq *s+imm8 7B 4 Q=*S+imm8
stp *s+imm8 7E 4 *S+imm8=P
stq *s+imm8 7F 4 *S+imm8=Q
ldp *imm16 68 5 P=*imm16
ldq *imm16 6A 5 Q=*imm16
stp *imm16 6C 5 *imm16=P
stq *imm16 6E 5 *imm16=Q
ldp *p+imm16 EC 5 P=*P+imm16
ldq *p+imm16 EE 5 Q=*P+imm16
ldp *q+imm16 F8 5 P=*Q+imm16
ldq *q+imm16 FA 5 Q=*Q+imm16
stq *p+imm16 06 5 *P+imm16=Q
stp *q+imm16 FC 5 *Q+imm16=P
ldp *p 92 3 P=*P
ldq *p 93 3 Q=*P
ldp *q 94 3 P=*Q
ldq *q 95 3 Q=*Q
stp *q 7C 3 *Q=P
stq *p 7D 3 *P=Q
ldq *p++ CC 3 Q=*P++++
ldp *q++ CD 3 P=*Q++++
stp *q++ CE 3 *Q++++=P
stq *p++ CF 3 *P++++=Q
LDX ## AA 3 Set the X register to a given 16-bit value
LDY ## A8 3 Set the X register to a given 16-bit value
LDX zpg A6 4 Set the X register to the 16-bit value in memory at a given 8-bit address
LDY zpg A4 4 Set the Y register to the 16-bit value in memory at a given 8-bit address
STX zpg 86 4 Store the 16-bit value in the X register in memory at an given 8-bit address
STY zpg 84 4 Store the 16-bit value in the Y register in memory at an given 8-bit address
LDX abs AE 5 Set the X register to the 16-bit value in memory at a given 16-bit address
LDY abs AC 5 Set the Y register to the 16-bit value in memory at a given 16-bit address
STX abs 8E 5 Store the 16-bit value in the X register in memory at a given 16-bit address
STY abs 8C 5 Store the 16-bit value in the X register in memory at a given 16-bit address
LDX X,ofs BE 4 Set the X register to the 16-bit value in memory at the address (X plus a given 8-bit offset)
LDX Y,ofs BA 4 Set the Y register to the 16-bit value in memory at the address (X plus a given 8-bit offset)
LDY X,ofs BC 4 Set the X register to the 16-bit value in memory at the address (Y plus a given 8-bit offset)
LDY Y,ofs B8 4 Set the Y register to the 16-bit value in memory at the address (Y plus a given 8-bit offset)
STX Y,ofs 9A 4 Store the 16-bit value in the X register in memory at the address (Y plus a given 8-bit offset)
STY X,ofs 9C 4 Store the 16-bit value in the Y register in memory at the address (X plus a given 8-bit offset)
LDX X A2 3 Set the X register to the 16-bit value in memory at the address in X
LDY X A0 3 Set the Y register to the 16-bit value in memory at the address in X
LDX Y B2 3 Set the X register to the 16-bit value in the Y registerin16
LDY Y E2 3 Set the Y register to the 16-bit value in the Y registerin16
STX Y 92 3 Store the 16-bit value in the X register in memory at the address in Y
STY X 80 3 Store the 16-bit value in the Y register in memory at the address in X
LDX Y+ F2 3 Set the X register to the 16-bit value in the Y registerin16, the 16-bit value in the Y registerinc16
LDY X+ E0 3 Set the Y register to the 16-bit value in memory at the address in X, the 16-bit value in the X registerinc16
STX Y+ D2 3 Store the 16-bit value in the X register in memory at the address in Y, the 16-bit value in the Y registerinc16
STY X+ C0 3 Store the 16-bit value in the Y register in memory at the address in X, the 16-bit value in the X registerinc16
Moves (M):
lda b 80 1 A=B
lda c 81 1 A=C
ldb a 82 1 B=A
ldb c 83 1 B=C
ldc a 84 1 C=A
ldc b 85 1 C=B
lda pl 86 1 A=P&FF
lda ph 87 1 A=P>>8
lda ql 88 1 A=Q&FF
lda qh 89 1 A=Q>>8
ldb pl 37 1 B=P&FF
ldc ph 38 1 C=P>>8
ldb ql 39 1 B=Q&FF
ldc qh 3A 1 C=Q>>8
ldp q 8A 1 P=Q
ldp s 8B 1 P=S
ldp v 8C 1 P=V
ldp i 8D 1 P=I
ldp cb 91 1 P=(C<<8)+B
ldq cb E0 1 Q=(C<<8)+B
ldq p 8E 1 Q=P
lds p 8F 1 S=P
ldv p 90 1 V=P
TBA 97 1 Copy the value in the B register into the A register
TCA 17 1 Copy the value in the C register into the A register
TAB B7 1 Copy the value in the A register into the B register
TCB D7 1 Copy the value in the C register into the B register
TAC 37 1 Copy the value in the A register into the C register
TBC F7 1 Copy the value in the B register into the C register
TYX B4 1 Copy the 16-bit value in the Y register into the 16-bit X register
TXY 94 1 Copy the 16-bit value in the X register into the 16-bit Y register
TVX B6 1 Copy the 16-bit Interrupt Return Address into the X register
TXV 96 1 Copy the 16-bit value in the X register into the 16-bit Interrupt Return Address register
TAS 95 1 Copy the value in the A register into the 8-bit Stack Pointer register
TSA B5 1 Copy the 8-bit Stack Pointer into the A register
Opcodes used: 244/255
Opcodes used: 189/256
0123456789ABCDEF
00 | CB----WWBBBBBBBB
10 | UUIIUIIUUUUUUUUU
20 | BWWWAWBBBBBUUUUA
30 | JJJJJJJMMMMSSSAA
40 | SSSSSSSSSSXXXAAA
50 | BBBBBBBBBBBBBBBB
60 | JBBJJJJJWWWWWWWW
70 | -AAAAAA-A-WWWWWW
80 | MMMMMMMMMMMMMMMM
90 | MMWWWWBBB--AAAAA
A0 | AAAAAA-AAAAAA-AA
B0 | AAAA-AAAAAAAAAAA
C0 | BBBBBBBBBBBBWWWW
D0 | AAAAAAAAAAAAAAAA
E0 | MJJJJJXXXSSBWWWW
F0 | CCCCCCCBWWWWWWBC
00 | CC-BJA-BSA--JJ--
10 | B--BSA-MCA-BSA-B
20 | JJ-BJA-BSA-BJJ--
30 | B--BSA-MCA-BSA-B
40 | CC-BJA-USA--JJ-B
50 | ---BSA-UCA-USA-U
60 | J--BJA-ASA-AJJ-B
70 | ---BSA--CA-ASA-A
80 | WB-BWBWBX-X-WWWW
90 | BBWBMMMMBBWBWB-B
A0 | WBWBWBWBWBWBWWWW
B0 | BBWBMMMMWBWBWBWB
C0 | WB-B-AU-XA--JB-B
D0 | BBWB--UM-AU-XAU-
E0 | WBWB-AUAX-C--B-B
F0 | BBWB--UM-AUAXAUA

View File

@ -37,9 +37,6 @@ Keycodes are 7-bit Windows VKey codes, plus a press/release bit. If the MSB is 1
Result will be 0 if the buffer is empty.<br>
If 1 is written to `$0500`, an interrupt will be triggered whenever a key event is available. Write 0 to disable again.
## Serial Peripheral Interface
Not yet implemented.
## Robot Controller
Write to `$0701` to control a 1x1f-sized "robot" that can place and destroy bricks.<br>
Each bit indicates an action; if that bit is set, that action will be taken. From MSB to LSB: Plant brick, destroy brick, move forward, backward, left, right, up, down.<br>

View File

@ -1,9 +1,16 @@
# 8608 - An 8-bit data, 16-bit address, CISC architecture.
For a description of the architecture and a list of instructions, see [instructionList.txt](instructionList.txt).
For a quick guide on how to use this project, see [getting-started.md](getting-started.md)<br>
For a memory map of the 8608-based computer, see [memoryMap.md](memoryMap.md).
For a detailed description of the architecture, see [architecture.md](architecture.md)<br>
For a list of instructions, see [instructionList.txt](instructionList.txt)
For a memory map of the 8608-based computer, see [memoryMap.md](memoryMap.md)
To assemble programs, use CustomAsm: [https://github.com/hlorenzi/customasm](https://github.com/hlorenzi/customasm)<br>
Simply include the 8608 architecture file into your program: [8608.asm](8608.asm).<br>
`#include "8608/8608.asm"`
To use the emulator, simply drag-and-drop an assembly code file onto [emulator/8608-emulator.bat](emulator/8608-emulator.bat)
You must include the 8608 architecture file into your assembly code: [8608.asm](8608.asm)<br>
`#include "8608/8608.asm"`<br>
Note: This project depends on several pieces of free and open-source software,<br>
whose binaries are included in the repository:<br>
customasm: [https://github.com/hlorenzi/customasm](https://github.com/hlorenzi/customasm)<br>
LÖVE: [https://love2d.org/](https://love2d.org/)