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 -- 8608-definition.lua
-- This file contains the formal definitions for each instruction in the 8608 architecture. -- This file contains information about the instruction set and microcode for the 8608 architecture.
-- It is used by generate-architecture.lua to generate the following: -- 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. -- instructionList.txt, a human-readable list of all instructions.
-- 8608.asm, a set of definitions for CustomAsm that allows it to assemble 8608 programs. -- 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. -- 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 -- List of every control line in the CPU
-- Organized by bit position within the four microcode ROMs -- Organized by bit position within the four microcode ROMs
@ -14,8 +14,8 @@ roms = {
"alulU", "alulT", "alulC", "alulB", "alulA", "alurIL", "alurIH", "alurVL", "alulU", "alulT", "alulC", "alulB", "alulA", "alurIL", "alurIH", "alurVL",
"alurVH", "alurSL", "alurSH", "alurQL", "alurQH", "alurPL", "alurPH", "alurU", "alurVH", "alurSL", "alurSH", "alurQL", "alurQH", "alurPL", "alurPH", "alurU",
"alurT", "alurC", "alurB", "alurA", "alur1", "alur2", "alurm1", "alurm2", "alurT", "alurC", "alurB", "alurA", "alur1", "alur2", "alurm1", "alurm2",
"adrrhU", "adrrhC", "adrrlT", "adrrTX", "adrrlB", "adrrBX", "adwrhU", "adwrhC", "adrrhU", "adrrhC", "adrrlT", "adrrTX", "_", "adrr2A", "adwrhU", "adwrhC",
"adwrlT", "adwrTX", "adwrlB", "adwrBX", "adwlI", "adwlV", "adwlS", "adwlQ", "adwrlT", "adwrTX", "adwrlA", "adwrAX", "adwlI", "adwlV", "adwlS", "adwlQ",
"adwlP", "adrlI", "adrlV", "adrlS", "adrlQ", "adrlP", "aluAdd", "adwSaveV", "adwlP", "adrlI", "adrlV", "adrlS", "adrlQ", "adrlP", "aluAdd", "adwSaveV",
"aluRun", "aluRInv", "aluCinOn", "aluCinC", "memWriteAlur", "adrInc", "adwInc", "aluXor", "aluRun", "aluRInv", "aluCinOn", "aluCinC", "memWriteAlur", "adrInc", "adwInc", "aluXor",
"aluIor", "aluAnd", "memWriteAlur", "adrOut", "adrSaveI", "adwSaveP", "adwSaveQ", "adwSaveS", "aluIor", "aluAnd", "memWriteAlur", "adrOut", "adrSaveI", "adwSaveP", "adwSaveQ", "adwSaveS",
@ -30,7 +30,7 @@ roms = {
"instrNext2", "instrNext1", "instrNext0", "memSaveU", "memSaveT", "memSaveC", "memSaveB", "memSaveA", "instrNext2", "instrNext1", "instrNext0", "memSaveU", "memSaveT", "memSaveC", "memSaveB", "memSaveA",
} }, } },
{ pos = {66, 16, 0}, size = {32, 32, 32}, signals = { { 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", "memRead", "memWrite", "runFlgVal", "runFlgClk", "intFlgVal", "intFlgClk", "irqFlgClk", "always1",
"aluShiftArith", "aluShiftRoll", "aluShiftRight", "aluShift", "alurF", "_", "_", "_", "aluShiftArith", "aluShiftRoll", "aluShiftRight", "aluShift", "alurF", "_", "_", "_",
"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_",
@ -52,7 +52,7 @@ operations = {
instrSub6 = {"base","instrLoadSub","instrNext2","instrNext1", }, instrSub6 = {"base","instrLoadSub","instrNext2","instrNext1", },
instrSub7 = {"base","instrLoadSub","instrNext2","instrNext1","instrNext0"}, instrSub7 = {"base","instrLoadSub","instrNext2","instrNext1","instrNext0"},
instrSub23Cond = {"base","instrLoadSub","instrNext1"}, 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"}, instrPreload = {"adrlI","adrInc","adrSaveI","adrOut","memRead","instrLoadSel","instrLoadPre"},
instrNextPre = {"base","instrPre","instrLoad","instrLoadSub"}, instrNextPre = {"base","instrPre","instrLoad","instrLoadSub"},
@ -70,12 +70,14 @@ operations = {
loadImmedT = {"loadImmed","memSaveT"}, loadImmedT = {"loadImmed","memSaveT"},
loadImm161 = {"loadImmed","memSaveU"}, loadImm161 = {"loadImmed","memSaveU"},
loadImm162 = {"loadImmed","memSaveT"}, loadImm162 = {"loadImmed","memSaveT"},
loadStackRel = {"adrlS","adrrTX","loadReg"}, --loadStackRel = {"adrlS","adrrTX","loadReg"},
loadStackRel = {"adrrlT","loadReg"},
loadStackRelT = {"loadStackRel","memSaveT"}, loadStackRelT = {"loadStackRel","memSaveT"},
loadStackRelU = {"loadStackRel","memSaveU"}, loadStackRelU = {"loadStackRel","memSaveU"},
loadStackRel161 = {"loadStackRel", "memSaveU"}, loadStackRel161 = {"loadStackRel", "memSaveU"},
loadStackRel162 = {"loadStackRel","adrInc","memSaveT"}, loadStackRel162 = {"loadStackRel","adrInc","memSaveT"},
storeStackRel = {"adrlS","adrrTX","storeReg"}, --storeStackRel = {"adrlS","adrrTX","storeReg"},
storeStackRel = {"adrrlT","storeReg"},
storeStackRel161 = {"storeStackRel" }, storeStackRel161 = {"storeStackRel" },
storeStackRel162 = {"storeStackRel","adrInc"}, storeStackRel162 = {"storeStackRel","adrInc"},
storeStackRelU = {"storeStackRel","alurU"}, storeStackRelU = {"storeStackRel","alurU"},
@ -84,16 +86,18 @@ operations = {
store161 = { "storeReg"}, store161 = { "storeReg"},
store162 = {"adrInc","storeReg"}, store162 = {"adrInc","storeReg"},
loadUTU = {"adrrUT", "loadReg","memSaveU"}, loadUTU = {"adrrUT", "loadReg","memSaveU"},
loadUTUP = {"adrrUT","adrlP","loadReg","memSaveU"},
loadUTUQ = {"adrrUT","adrlQ","loadReg","memSaveU"},
storeUT = {"adrrUT", "storeReg"}, storeUT = {"adrrUT", "storeReg"},
storeUTP = {"adrrUT","adrlP","storeReg"}, storeUTP = {"adrrUT","adrlP","storeReg"},
storeUTQ = {"adrrUT","adrlQ","storeReg"}, storeUTQ = {"adrrUT","adrlQ","storeReg"},
memSaveFlags = {"memSaveNZ"}, memSaveFlags = {"memSaveNZ"},
load16FE1 = {"adrrm4","adrr2","load161"},
load16FE2 = {"adrrm4","adrr2","load162"},
load16FC1 = {"adrrm4", "load161"},
load16FC2 = {"adrrm4", "load162"},
adwrUT = {"adwrhU","adwrlT"}, adwrUT = {"adwrhU","adwrlT"},
adrrUT = {"adrrhU","adrrlT"}, adrrUT = {"adrrhU","adrrlT"},
adwrCB = {"adwrhC","adwrlB"}, -- adwrCB = {"adwrhC","adwrlB"},
adwIncUT = {"adwrUT", "adwInc"}, adwIncUT = {"adwrUT", "adwInc"},
adwIncUTP = {"adwrUT","adwlP","adwInc"}, adwIncUTP = {"adwrUT","adwlP","adwInc"},
adwIncUTQ = {"adwrUT","adwlQ","adwInc"}, adwIncUTQ = {"adwrUT","adwlQ","adwInc"},
@ -104,12 +108,14 @@ operations = {
incQ = {"adwQ","adwInc"}, incQ = {"adwQ","adwInc"},
incP2 = {"adwP","adwr2"}, incP2 = {"adwP","adwr2"},
incQ2 = {"adwP","adwr2"}, incQ2 = {"adwP","adwr2"},
saveIV = {"adwlI","adwSaveV"},
jmpRelT = {"instrNext","adrrTX"}, jmpRelT = {"instrNext","adrrTX"},
jmpAbs = {"base","loadInstr","adrSaveI"}, jmpAbs = {"base","loadInstr","adrSaveI"},
jmpAbsUT = {"jmpAbs","adrrUT"}, jmpAbsUT = {"jmpAbs","adrrUT"},
jmpAbsP = {"jmpAbs","adrlP"}, jmpAbsP = {"jmpAbs","adrlP"},
jmpAbsQ = {"jmpAbs","adrlQ"}, jmpAbsQ = {"jmpAbs","adrlQ"},
jmpAbsV = {"jmpAbs","adrlV"},
saveRetAddr = {"adwlI","adwInc","adwSaveQ"}, saveRetAddr = {"adwlI","adwInc","adwSaveQ"},
pushRetAddr1 = {"alurIH","pushReg"}, pushRetAddr1 = {"alurIH","pushReg"},
pushRetAddr2 = {"alurIL","pushReg"}, pushRetAddr2 = {"alurIL","pushReg"},
@ -141,294 +147,77 @@ operations = {
"adwSaveP","adwSaveQ","adwSaveS","adwSaveV", "adwSaveP","adwSaveQ","adwSaveS","adwSaveV",
"adrSaveI", "adrSaveI",
"aluSaveNZ","aluSaveCarry", "aluSaveNZ","aluSaveCarry",
} "intFlgClk",
"irqFlgClk",
"runFlgClk","runFlgVal",
},
}, },
-- List of definitions for every instruction -- Shortcuts for instruction descriptions
-- Each instruction definition contains: -- These strings will be substituted into instruction descriptions wherever their [key] occurs
-- Mnemonic: The mnemonic used to generate the assembler definitions and instruction list. descShortcuts = {
-- This is what must literally appear in the assembly code in order to generate this instruction, other than immediate values. {"%mem", "a value from memory"},
-- "imm8" means an 8-bit value. {"%mem16", "a value from memory"},
-- "imm16" means a 16-bit value. {"%imm8", "a given 8-bit value"},
-- Opcode: The machine code byte that represents this operation. {"%imm16", "a given 16-bit value"},
-- Used by the assembler generator to map mnemonics to opcodes. {"%A", "the value in the A register"},
-- Used by the microcode generator to place the instruction's data within the microcode ROM, which is addressed by opcode. {"%B", "the value in the B register"},
-- List of control signals: Specifies the control lines that will be activated by the microcode when the instruction is executed. {"%C", "the value in the C register"},
-- Instructions may take multiple clock cycles. To convey this, each clock cycle is represented by an independent list of microcode signals. {"%xInc16", "increment the X register by 2 bytes"},
-- Under the hood, the microcode ROM uses a 10-bit address: 8 bits for the opcode, and 2 bits for the clock cycle. {"%yInc16", "increment the Y register by 2 bytes"},
-- Because of this, each opcode may only use up to 4 clock cycles. {"%xInc", "increment the X register"},
-- If more are required, the least significant bit of the opcode can be set by a control line, incrementing the opcode. {"%yInc", "increment the Y register"},
-- This causes one instruction to use up multiple opcodes. {"%Xin16", "the 16-bit value in memory at the address in X"},
-- The need for this is determined automatically by the microcode generator: whenever an instruction specifies more than 4 lists of control signals. {"%Yinn16", "the 16-bit value in memory at the address in Y"},
-- Description: A brief description of the instruction. Used to generate the instruction list. {"%xIn", "the value in memory at the address in X"},
-- C Code: Used to generate an emulator (as part of a separate project). {"%yIn", "the value in memory at the address in Y"},
-- Categories can be specified. These serve only to organize the instruction list. {"%XofsIn16", "the 16-bit value in memory at the address (X plus a given 8-bit offset)"},
-- 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. {"%YofsIn16", "the 16-bit value in memory at the address (Y plus a given 8-bit offset)"},
instructions = { {"%XofsIn", "the value in memory at the address (X plus a given 8-bit offset)"},
{ category = "Control", catlet="C" }, {"%YofsIn", "the value in memory at the address (Y plus a given 8-bit offset)"},
{ 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;"} }, {"%Xofs", "the address (X plus a given 8-bit offset)"},
{ mnem="hlt" , opcode=0xF0, {"runFlgClk","instrNext"}, desc="Halt non-interrupt execution", ccode={"cpu.rfg=0; lni;"} }, {"%Yofs", "the address (Y plus a given 8-bit offset)"},
{ mnem="run" , opcode=0xF1, {"runFlgClk","runFlgVal","instrNext"}, desc ="Resume non-interrupt execution", ccode={"cpu.rfg=1; lni;"} }, {"%X", "the 16-bit value in the X register"},
{ 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;"} }, {"%Y", "the 16-bit value in the Y register"},
{ 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;"} }, {"%adrX", "the address in X"},
{ 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;"} }, {"%adrY", "the address in Y"},
{ mnem="nop" , opcode=0xFF, {"instrNext"}, desc="Do nothing", ccode={"lni;"}, }, {"%zpgIn16", "the 16-bit value in memory at a given 8-bit address"},
{ mnem="ien" , opcode=0xF5, {"instrNext"}, desc="Enbale interrupts", ccode={"cpu.ien=1; lni;"}, }, -- todo {"%zpgIn", "the value in memory at a given 8-bit address"},
{ mnem="idi" , opcode=0xF6, {"instrNext"}, desc="Disable interrupts", ccode={"cpu.ien=0; lni;"}, }, -- todo {"%zpg", "an given 8-bit address"},
{"%absIn16", "the 16-bit value in memory at a given 16-bit address"},
{ category = "16-bit Inc/Dec", catlet="I" }, {"%absIn", "the value in memory at a given 16-bit address"},
{ mnem="inc p" , opcode=0x12, {"adwlP","adwInc","adwSaveP","instrNext"}, desc="P++", ccode={"cpu.p++; lni;"} }, {"%abs", "a given 16-bit address"},
{ mnem="dec p" , opcode=0x15, {"adwlP","adwrm1","adwSaveP","instrNext"}, desc="P--", ccode={"cpu.p--; lni;"} }, {"%alu", "and store the result in the A register"},
{ mnem="inc q" , opcode=0x13, {"adwlQ","adwInc","adwSaveQ","instrNext"}, desc="Q++", ccode={"cpu.q++; lni;"} }, {"%flags", " and set the Carry Flag and Zero Flag according to the result"},
{ mnem="dec q" , opcode=0x16, {"adwlQ","adwrm1","adwSaveQ","instrNext"}, desc="Q--", ccode={"cpu.q--; lni;"} }, {"%zflag", " and set the Zero Flag according to the result"},
{"%cmp", "Set the Carry Flag and Zero Flag according to the result of subtracting"},
{ category = "8-bit Unary", catlet="U" }, {"%brel", "Add a signed 8-bit offset to the Program Counter, jumping forward or backward in the program"},
{ mnem="inc a" , opcode=0x10, {"aluA","alur1" ,"aluOpAdd" ,"instrNext"}, desc="A++, set flags" , ccode={"addf(cpu.a, 1 ); lni;"} }, {"%brelc", "Otherwise, do nothing"},
{ mnem="dec a" , opcode=0x11, {"aluA","alurm1","aluOpAdd" ,"instrNext"}, desc="A--, set flags" , ccode={"addf(cpu.a,-1 ); lni;"} }, {"%if", "If the result of the last math operation was"},
{ mnem="icc a" , opcode=0x1B, {"aluA", "aluOpAddC","instrNext"}, desc="A+=CF, set flags", ccode={"addf(cpu.a,cpu.cf); lni;"} }, {"%zFlgMem", "and set the Zero Flag according to the value loaded"},
{ 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;"} },
}, },
-- Aliases for instructions -- Aliases for instructions
-- Used to generate the assembler definitions. -- Used to generate the assembler definitions.
-- imm8neg instead of imm8 means the immediate value will be negated when assembling. -- 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 = { aliases = {
["jpz imm8" ] = {"jeq imm8"}, -- ["jmp q" ] = {"ret" },
["jnz imm8" ] = {"jne imm8"}, ["ADD imm8" ] = {"SUB imm8neg"},
["jmp q" ] = {"ret" }, -- ["adb imm8" ] = {"sbb imm8neg"},
["add imm8" ] = {"sub imm8neg"}, -- ["adc imm8" ] = {"sbc imm8neg"},
["adb imm8" ] = {"sbb imm8neg"}, ["ADC imm8" ] = {"SBC imm8neg"},
["adc imm8" ] = {"sbc imm8neg"},
["acc imm8" ] = {"scc imm8neg"},
}, },
-- Filename to generate the assembler definitions file to. -- 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

984
8608.asm
View File

@ -1,798 +1,202 @@
; 8608.asm ; 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" ; #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 ; Generated by generate-architecture.lua using the definitions in 8608-definition.lua
; Definitions for all instructions in the 8608 architecture. ; Definitions for all instructions in the 8608 architecture.
#ruledef { #subruledef rel8 {
rst => $00 {addr} => {
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 reladdr = addr - $ - 2
assert(reladdr <= 127, "jpr: Relative jump target is too far away") assert(reladdr <= 127, "Relative jump target is too far away")
assert(reladdr >= -128, "jpr: Relative jump target is too far away") assert(reladdr >= -128, "Relative jump target is too far away")
$31 @ reladdr`8 reladdr`8
} }
jnz {addr} => { }
reladdr = addr - $ - 2 #subruledef neg8 {
assert(reladdr <= 127, "jnz: Relative jump target is too far away") {value} => {
assert(reladdr >= -128, "jnz: Relative jump target is too far away") mvalue = -value
$30 @ reladdr`8 mvalue`8
} }
jne {addr} => { }
reladdr = addr - $ - 2 #ruledef {
assert(reladdr <= 127, "jne: Relative jump target is too far away") RST => $41
assert(reladdr >= -128, "jne: Relative jump target is too far away") BRK => $00
$30 @ reladdr`8 RTI => $40
} NOP => $EA
jpz {addr} => { CLI => $58
reladdr = addr - $ - 2 SEI => $78
assert(reladdr <= 127, "jpz: Relative jump target is too far away") HLT => $18
assert(reladdr >= -128, "jpz: Relative jump target is too far away") RUN => $38
$32 @ reladdr`8 INC A => $F6
} DEC A => $D6
jeq {addr} => { ICC A => $57
reladdr = addr - $ - 2 INC B => $FE
assert(reladdr <= 127, "jeq: Relative jump target is too far away") DEC B => $DE
assert(reladdr >= -128, "jeq: Relative jump target is too far away") ICC B => $5F
$32 @ reladdr`8 INC C => $FA
} DEC C => $DA
jlt {addr} => { ICC C => $5B
reladdr = addr - $ - 2 INC {value: u8} => $E6 @ value
assert(reladdr <= 127, "jlt: Relative jump target is too far away") DEC {value: u8} => $C6 @ value
assert(reladdr >= -128, "jlt: Relative jump target is too far away") ICC {value: u8} => $47 @ value
$33 @ reladdr`8 ADD #{value: i8} => $6B @ value
} ADC #{value: i8} => $69 @ value
jge {addr} => { CMP #{value: i8} => $C9 @ value
reladdr = addr - $ - 2 AND #{value: i8} => $29 @ value
assert(reladdr <= 127, "jge: Relative jump target is too far away") ORA #{value: i8} => $09 @ value
assert(reladdr >= -128, "jge: Relative jump target is too far away") EOR #{value: i8} => $49 @ value
$34 @ reladdr`8 ASL #{value: i8} => $15 @ value
} LSR #{value: i8} => $55 @ value
jgt {addr} => { ROL #{value: i8} => $35 @ value
reladdr = addr - $ - 2 ROR #{value: i8} => $75 @ value
assert(reladdr <= 127, "jgt: Relative jump target is too far away") ADD {value: u8} => $67 @ value
assert(reladdr >= -128, "jgt: Relative jump target is too far away") SUB {value: u8} => $E7 @ value
$35 @ reladdr`8 ADC {value: u8} => $65 @ value
} SBC {value: u8} => $E5 @ value
jle {addr} => { CMP {value: u8} => $C5 @ value
reladdr = addr - $ - 2 AND {value: u8} => $25 @ value
assert(reladdr <= 127, "jle: Relative jump target is too far away") ORA {value: u8} => $05 @ value
assert(reladdr >= -128, "jle: Relative jump target is too far away") EOR {value: u8} => $45 @ value
$36 @ reladdr`8 ADD B => $7F
} SUB B => $FF
psh a => $40 ADC B => $7D
psh b => $44 SBC B => $FD
psh c => $45 CMP B => $DD
psh f => $E9 AND B => $3D
psh p => $41 ORA B => $1D
psh q => $46 EOR B => $5D
pop a => $42 ADD C => $7B
pop b => $47 SUB C => $FB
pop c => $48 ADC C => $79
pop f => $EA SBC C => $F9
pop p => $43 CMP C => $D9
pop q => $49 AND C => $39
psh {value: i8} => $3B @ value ORA C => $19
phw {value: i16} => $3C @ value EOR C => $59
lda {value: i8} => $20 @ value BNE {value: rel8} => $D0 @ value
ldb {value: i8} => $26 @ value BEQ {value: rel8} => $F0 @ value
ldc {value: i8} => $27 @ value BLT {value: rel8} => $90 @ value
lda *s+{value: i8} => { BGE {value: rel8} => $B0 @ value
assert(value <= 127, "Relative address is too far away") BGT {value: rel8} => $30 @ value
assert(value >= -128, "Relative address is too far away") BLE {value: rel8} => $10 @ value
$28 @ value`8 BRA {value: rel8} => $98 @ value
} ADX #{value: i8} => $E8 @ value
lda *s-{value: i8} => { ADY #{value: i8} => $C8 @ value
mvalue = -value ADX #{value: i16} => $8A @ value
assert(mvalue <= 127, "Relative address is too far away") ADY #{value: i16} => $88 @ value
assert(mvalue >= -128, "Relative address is too far away") ADX A => $FC
$28 @ mvalue`8 ADY A => $DC
} JMP {value: i16} => $CC @ value
ldb *s+{value: i8} => { JSR {value: i16} => $20 @ value
assert(value <= 127, "Relative address is too far away") JMP [{value: i16}] => $6C @ value
assert(value >= -128, "Relative address is too far away") JSR [{value: i16}] => $2C @ value
$29 @ value`8 JMP [{value: i16},A] => $4C @ value
} JSR [{value: i16},A] => $0C @ value
ldb *s-{value: i8} => { JMP X => $64
mvalue = -value JMP Y => $44
assert(mvalue <= 127, "Relative address is too far away") JSR X => $24
assert(mvalue >= -128, "Relative address is too far away") JSR Y => $04
$29 @ mvalue`8 RTS => $60
} PHA => $48
ldc *s+{value: i8} => { PHB => $5C
assert(value <= 127, "Relative address is too far away") PHC => $1C
assert(value >= -128, "Relative address is too far away") PHP => $08
$2A @ value`8 PHX => $54
} PHY => $14
ldc *s-{value: i8} => { PLA => $68
mvalue = -value PLB => $7C
assert(mvalue <= 127, "Relative address is too far away") PLC => $3C
assert(mvalue >= -128, "Relative address is too far away") PLP => $28
$2A @ mvalue`8 PLX => $74
} PLY => $34
sta *s+{value: i8} => { LDA #{value: i8} => $A9 @ value
assert(value <= 127, "Relative address is too far away") LDB #{value: i8} => $AB @ value
assert(value >= -128, "Relative address is too far away") LDC #{value: i8} => $2B @ value
$96 @ value`8 LDA {value: u8} => $A5 @ value
} LDB {value: u8} => $A7 @ value
sta *s-{value: i8} => { LDC {value: u8} => $27 @ value
mvalue = -value STA {value: u8} => $85 @ value
assert(mvalue <= 127, "Relative address is too far away") STB {value: u8} => $87 @ value
assert(mvalue >= -128, "Relative address is too far away") STC {value: u8} => $07 @ value
$96 @ mvalue`8 LDA {value: i16} => $ED @ value
} LDB {value: i16} => $EF @ value
stb *s+{value: i8} => { LDC {value: i16} => $6F @ value
assert(value <= 127, "Relative address is too far away") STA {value: i16} => $CD @ value
assert(value >= -128, "Relative address is too far away") STB {value: i16} => $CF @ value
$97 @ value`8 STC {value: i16} => $4F @ value
} LDA X => $A1
stb *s-{value: i8} => { LDB X => $A3
mvalue = -value LDC X => $23
assert(mvalue <= 127, "Relative address is too far away") LDA Y => $B1
assert(mvalue >= -128, "Relative address is too far away") LDB Y => $B3
$97 @ mvalue`8 LDC Y => $33
} STA X => $81
stc *s+{value: i8} => { STB X => $83
assert(value <= 127, "Relative address is too far away") STC X => $03
assert(value >= -128, "Relative address is too far away") STA Y => $91
$98 @ value`8 STB Y => $93
} STC Y => $13
stc *s-{value: i8} => { LDA X+ => $E1
mvalue = -value LDB X+ => $E3
assert(mvalue <= 127, "Relative address is too far away") LDC X+ => $63
assert(mvalue >= -128, "Relative address is too far away") LDA Y+ => $F1
$98 @ mvalue`8 LDB Y+ => $F3
} LDC Y+ => $73
lda *{value: i16} => $51 @ value STA X+ => $C1
ldb *{value: i16} => $56 @ value STB X+ => $C3
ldc *{value: i16} => $57 @ value STC X+ => $43
sta *{value: i16} => $50 @ value STA Y+ => $D1
stb *{value: i16} => $58 @ value STB Y+ => $D3
stc *{value: i16} => $59 @ value STC Y+ => $53
lda *p+{value: i16} => { LDA X,{value: u8} => $BD @ value
assert(value <= 32767, "Relative address is too far away") LDB X,{value: u8} => $BF @ value
assert(value >= -32768, "Relative address is too far away") LDC X,{value: u8} => $3F @ value
$01 @ value`16 LDA Y,{value: u8} => $B9 @ value
} LDB Y,{value: u8} => $BB @ value
lda *p-{value: i16} => { LDC Y,{value: u8} => $3B @ value
mvalue = -value STA X,{value: u8} => $9D @ value
assert(mvalue <= 32767, "Relative address is too far away") STB X,{value: u8} => $9F @ value
assert(mvalue >= -32768, "Relative address is too far away") STC X,{value: u8} => $1F @ value
$01 @ mvalue`16 STA Y,{value: u8} => $99 @ value
} STB Y,{value: u8} => $9B @ value
ldb *p+{value: i16} => { STC Y,{value: u8} => $1B @ value
assert(value <= 32767, "Relative address is too far away") LDX #{value: i16} => $AA @ value
assert(value >= -32768, "Relative address is too far away") LDY #{value: i16} => $A8 @ value
$F7 @ value`16 LDX {value: u8} => $A6 @ value
} LDY {value: u8} => $A4 @ value
ldb *p-{value: i16} => { STX {value: u8} => $86 @ value
mvalue = -value STY {value: u8} => $84 @ value
assert(mvalue <= 32767, "Relative address is too far away") LDX {value: i16} => $AE @ value
assert(mvalue >= -32768, "Relative address is too far away") LDY {value: i16} => $AC @ value
$F7 @ mvalue`16 STX {value: i16} => $8E @ value
} STY {value: i16} => $8C @ value
ldc *p+{value: i16} => { LDX X,{value: u8} => $BE @ value
assert(value <= 32767, "Relative address is too far away") LDX Y,{value: u8} => $BA @ value
assert(value >= -32768, "Relative address is too far away") LDY X,{value: u8} => $BC @ value
$FE @ value`16 LDY Y,{value: u8} => $B8 @ value
} STX Y,{value: u8} => $9A @ value
ldc *p-{value: i16} => { STY X,{value: u8} => $9C @ value
mvalue = -value LDX X => $A2
assert(mvalue <= 32767, "Relative address is too far away") LDY X => $A0
assert(mvalue >= -32768, "Relative address is too far away") LDX Y => $B2
$FE @ mvalue`16 LDY Y => $E2
} STX Y => $92
lda *q+{value: i16} => { STY X => $80
assert(value <= 32767, "Relative address is too far away") LDX Y+ => $F2
assert(value >= -32768, "Relative address is too far away") LDY X+ => $E0
$EB @ value`16 STX Y+ => $D2
} STY X+ => $C0
lda *q-{value: i16} => { TBA => $97
mvalue = -value TCA => $17
assert(mvalue <= 32767, "Relative address is too far away") TAB => $B7
assert(mvalue >= -32768, "Relative address is too far away") TCB => $D7
$EB @ mvalue`16 TAC => $37
} TBC => $F7
ldb *q+{value: i16} => { TYX => $B4
assert(value <= 32767, "Relative address is too far away") TXY => $94
assert(value >= -32768, "Relative address is too far away") TVX => $B6
$08 @ value`16 TXV => $96
} TAS => $95
ldb *q-{value: i16} => { TSA => $B5
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
} }

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

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 Each instruction is described in order of: Mnemonic, Opcode, Clock cycles, Description
Control (C): Control (C):
rst 00 1 Clear all registers and set I=0 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
hlt F0 1 Halt non-interrupt execution 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
run F1 1 Resume non-interrupt execution RTI 40 1 Return from an interrupt, resuming normal execution where it left off when the interrupt occurred
brk F3 1 Trigger interrupt NOP EA 1 Do nothing
irt F4 1 Return from interrupt CLI 58 1 Enable interrupts to be triggered by external hardware
nop FF 1 Do nothing SEI 78 1 Disable interrupts being triggered by external hardware
ien F5 1 Enbale interrupts HLT 18 1 Clear the Run Flag, preventing the CPU from running until an interrupt is triggered
idi F6 1 Disable interrupts RUN 38 1 Set the Run Flag, allowing the CPU to run once the current interrupt finishes
16-bit Inc/Dec (I): 8-bit Unary Arithmetic (U):
inc p 12 1 P++ INC A F6 1 Increment the A register, and set the Carry Flag and Zero Flag according to the result
dec p 15 1 P-- DEC A D6 1 Decrement the A register, and set the Carry Flag and Zero Flag according to the result
inc q 13 1 Q++ ICC A 57 1 Add the Carry Flag to the A register, and set the Carry Flag and Zero Flag according to the result
dec q 16 1 Q-- 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): 8-bit Arithmetic and Logic (A):
inc a 10 1 A++, set flags 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
dec a 11 1 A--, set flags 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
icc a 1B 1 A+=CF, set flags 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
inc b 19 1 B++, set flags 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
dec b 1A 1 B--, set flags 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
icc b 1C 1 B+=CF, set flags 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
inc c 17 1 C++, set flags 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
dec c 18 1 C--, set flags 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
icc c 1D 1 C+=CF, set flags 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
tst a 14 1 Set flags according to A-0 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
tst b 1E 1 Set flags according to B-0 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
tst c 1F 1 Set flags according to C-0 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
inc *s+imm8 2B 4 *(S+imm8)++, set flags 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
dec *s+imm8 2C 4 *(S+imm8)--, set flags 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
icc *s+imm8 2D 4 *(S+imm8)+=CF, set flags 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
tst *s+imm8 2E 3 Set flags according to *(S+imm8)-0 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): 16-bit Arithmetic (X):
adp imm8 4A 2 P+=imm8 signed ADX # E8 2 Add a given 8-bit value to the 16-bit X register
adq imm8 4B 2 Q+=imm8 signed ADY # C8 2 Add a given 8-bit value to the 16-bit Y register
ads imm8 4C 2 S+=imm8 signed ADX ## 8A 3 Add a given 16-bit value to the 16-bit X register
adp b E6 1 P+=B signed ADY ## 88 3 Add a given 16-bit value to the 16-bit Y register
adq b E7 1 Q+=B signed ADX A FC 1 Add the 8-bit signed value in the A register to the 16-bit X register
ads b E8 1 S+=B signed ADY A DC 1 Add the 8-bit signed value in the A register to the 16-bit Y register
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
Jumps (J): Jumps (J):
jmp imm16 60 3 I=imm16 JMP abs CC 3 Jump - Set the Program Counter to a given 16-bit value, executing the code at that address
jsr imm16 63 3 I=imm16, Q=I 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
jss imm16 E2 5 I=imm16, *(S++++)=I-1 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.
jmp p 64 1 I=P JSR [ind] 2C 7 Load a code pointer from memory at a given 16-bit address, then jump to that code.
jmp q 66 1 I=Q 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 p 65 1 I=P, Q=I JSR [ind,A] 0C 7 Load a code pointer from memory at a given 16-bit address, then jump to that code.
jsr q 67 1 I=Q, Q=I JMP X 64 1 Set the Program Counter to the 16-bit value in the X register, executing the code at that address
jss p E4 3 I=P, *(S++++)=I-1 JMP Y 44 1 Set the Program Counter to the 16-bit value in the Y register, executing the code at that address
jss q E5 3 I=Q, *(S++++)=I-1 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
rts E1 3 I=*(----S)+1 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
jpr imm8 31 2 I+=imm8 RTS 60 3 Retrieve the Program Counter from the stack, returning to where the last JSR instruction was executed
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
Stack (S): Stack (S):
psh a 40 2 *(S++)=A PHA 48 2 Push the value in the A register onto the Stack
psh b 44 2 *(S++)=B PHB 5C 2 Push the value in the B register onto the Stack
psh c 45 2 *(S++)=C PHC 1C 2 Push the value in the C register onto the Stack
psh f E9 2 *(S++)=F PHP 08 2 Push a byte containing the Carry Flag and Zero Flag onto the Stack
psh p 41 3 *(S++++)=P PHX 54 3 Push the 16-bit value in the X register onto the Stack
psh q 46 3 *(S++++)=Q PHY 14 3 Push the 16-bit value in the Y register onto the Stack
pop a 42 2 A=*(--S) PLA 68 2 Pull a byte from the Stack, and store it in the A register
pop b 47 2 B=*(--S) PLB 7C 2 Pull a byte from the Stack, and store it in the B register
pop c 48 2 C=*(--S) PLC 3C 2 Pull a byte from the Stack, and store it in the C register
pop f EA 2 F=*(--S) PLP 28 2 Pull a byte from the Stack, and use it to set the Carry Flag and Zero flag
pop p 43 3 P=*(----S) PLX 74 3 Pull two bytes from the stack, and store the resulting 16-bit value in the X register
pop q 49 3 Q=*(----S) PLY 34 3 Pull two bytes from the stack, and store the resulting 16-bit value in the Y register
psh imm8 3B 3 *(S++)=imm8
phw imm16 3C 5 *(S++++)=imm16
8-bit Load/Store (B): 8-bit Load/Store (B):
lda imm8 20 2 A=imm8, update zero flag LDA # A9 2 Set the A register to a given 8-bit value
ldb imm8 26 2 B=imm8, update zero flag LDB # AB 2 Set the B register to a given 8-bit value
ldc imm8 27 2 C=imm8, update zero flag LDC # 2B 2 Set the C register to a given 8-bit value
lda *s+imm8 28 3 A=*s+imm8, update zero flag 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 *s+imm8 29 3 B=*s+imm8, update zero flag 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 *s+imm8 2A 3 C=*s+imm8, update zero flag 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 *s+imm8 96 3 *s+imm8=A STA zpg 85 3 Store the value in the A register in memory at an given 8-bit address
stb *s+imm8 97 3 *s+imm8=B STB zpg 87 3 Store the value in the B register in memory at an given 8-bit address
stc *s+imm8 98 3 *s+imm8=C STC zpg 07 3 Store the value in the C register in memory at an given 8-bit address
lda *imm16 51 4 A=*imm16, update zero flag 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 *imm16 56 4 B=*imm16, update zero flag 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 *imm16 57 4 C=*imm16, update zero flag 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 *imm16 50 4 *imm16=A STA abs CD 4 Store the value in the A register in memory at a given 16-bit address
stb *imm16 58 4 *imm16=B STB abs CF 4 Store the value in the B register in memory at a given 16-bit address
stc *imm16 59 4 *imm16=C STC abs 4F 4 Store the value in the C register in memory at a given 16-bit address
lda *p+imm16 01 4 A=*P+imm16, update zero flag 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 *p+imm16 F7 4 B=*P+imm16, update zero flag 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 *p+imm16 FE 4 C=*P+imm16, update zero flag 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 *q+imm16 EB 4 A=*Q+imm16, update zero flag 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 *q+imm16 08 4 B=*Q+imm16, update zero flag 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 *q+imm16 09 4 C=*Q+imm16, update zero flag 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 *p+imm16 0A 4 *P+imm16=A STA X 81 2 Store the value in the A register in memory at the address in X
stb *p+imm16 0B 4 *P+imm16=B STB X 83 2 Store the value in the B register in memory at the address in X
stc *p+imm16 0C 4 *P+imm16=C STC X 03 2 Store the value in the C register in memory at the address in X
sta *q+imm16 0D 4 *Q+imm16=A STA Y 91 2 Store the value in the A register in memory at the address in Y
stb *q+imm16 0E 4 *Q+imm16=B STB Y 93 2 Store the value in the B register in memory at the address in Y
stc *q+imm16 0F 4 *Q+imm16=C STC Y 13 2 Store the value in the C register in memory at the address in Y
lda *p 53 2 A=*P, update zero flag 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 *p 5E 2 B=*P, update zero flag 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 *p 5F 2 C=*P, update zero flag 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 *q 55 2 A=*Q, update zero flag 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 *q 61 2 B=*Q, update zero flag 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 *q 62 2 C=*Q, update zero flag 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 *p 52 2 *P=A STA X+ C1 2 Store the value in the A register in memory at the address in X, and increment the X register
stb *p 5A 2 *P=B STB X+ C3 2 Store the value in the B register in memory at the address in X, and increment the X register
stc *p 5B 2 *P=C STC X+ 43 2 Store the value in the C register in memory at the address in X, and increment the X register
sta *q 54 2 *Q=A STA Y+ D1 2 Store the value in the A register in memory at the address in Y, and increment the Y register
stb *q 5C 2 *Q=B STB Y+ D3 2 Store the value in the B register in memory at the address in Y, and increment the Y register
stc *q 5D 2 *Q=C STC Y+ 53 2 Store the value in the C register in memory at the address in Y, and increment the Y register
lda *p++ C6 2 A=*P++, update zero flag 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 *p++ C7 2 B=*P++, update zero flag 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 *p++ C8 2 C=*P++, update zero flag 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 *q++ C9 2 A=*Q++, update zero flag 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 *q++ CA 2 B=*Q++, update zero flag 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 *q++ CB 2 C=*Q++, update zero flag 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 *p++ C0 2 *P++=A 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 *p++ C1 2 *P++=B 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 *p++ C2 2 *P++=C 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 *q++ C3 2 *Q++=A 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 *q++ C4 2 *Q++=B 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 *q++ C5 2 *Q++=C 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): 16-bit Load/Store (W):
ldp imm16 21 3 P=imm16 LDX ## AA 3 Set the X register to a given 16-bit value
ldq imm16 23 3 Q=imm16 LDY ## A8 3 Set the X register to a given 16-bit value
lds imm16 25 3 S=imm16 LDX zpg A6 4 Set the X register to the 16-bit value in memory at a given 8-bit address
ldv imm16 22 3 V=imm16 LDY zpg A4 4 Set the Y register to the 16-bit value in memory at a given 8-bit address
ldp *s+imm8 7A 4 P=*S+imm8 STX zpg 86 4 Store the 16-bit value in the X register in memory at an given 8-bit address
ldq *s+imm8 7B 4 Q=*S+imm8 STY zpg 84 4 Store the 16-bit value in the Y register in memory at an given 8-bit address
stp *s+imm8 7E 4 *S+imm8=P LDX abs AE 5 Set the X register to the 16-bit value in memory at a given 16-bit address
stq *s+imm8 7F 4 *S+imm8=Q LDY abs AC 5 Set the Y register to the 16-bit value in memory at a given 16-bit address
ldp *imm16 68 5 P=*imm16 STX abs 8E 5 Store the 16-bit value in the X register in memory at a given 16-bit address
ldq *imm16 6A 5 Q=*imm16 STY abs 8C 5 Store the 16-bit value in the X register in memory at a given 16-bit address
stp *imm16 6C 5 *imm16=P 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)
stq *imm16 6E 5 *imm16=Q 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)
ldp *p+imm16 EC 5 P=*P+imm16 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)
ldq *p+imm16 EE 5 Q=*P+imm16 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)
ldp *q+imm16 F8 5 P=*Q+imm16 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)
ldq *q+imm16 FA 5 Q=*Q+imm16 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)
stq *p+imm16 06 5 *P+imm16=Q LDX X A2 3 Set the X register to the 16-bit value in memory at the address in X
stp *q+imm16 FC 5 *Q+imm16=P LDY X A0 3 Set the Y register to the 16-bit value in memory at the address in X
ldp *p 92 3 P=*P LDX Y B2 3 Set the X register to the 16-bit value in the Y registerin16
ldq *p 93 3 Q=*P LDY Y E2 3 Set the Y register to the 16-bit value in the Y registerin16
ldp *q 94 3 P=*Q STX Y 92 3 Store the 16-bit value in the X register in memory at the address in Y
ldq *q 95 3 Q=*Q STY X 80 3 Store the 16-bit value in the Y register in memory at the address in X
stp *q 7C 3 *Q=P 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
stq *p 7D 3 *P=Q 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
ldq *p++ CC 3 Q=*P++++ 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
ldp *q++ CD 3 P=*Q++++ 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
stp *q++ CE 3 *Q++++=P
stq *p++ CF 3 *P++++=Q
Moves (M): Moves (M):
lda b 80 1 A=B TBA 97 1 Copy the value in the B register into the A register
lda c 81 1 A=C TCA 17 1 Copy the value in the C register into the A register
ldb a 82 1 B=A TAB B7 1 Copy the value in the A register into the B register
ldb c 83 1 B=C TCB D7 1 Copy the value in the C register into the B register
ldc a 84 1 C=A TAC 37 1 Copy the value in the A register into the C register
ldc b 85 1 C=B TBC F7 1 Copy the value in the B register into the C register
lda pl 86 1 A=P&FF TYX B4 1 Copy the 16-bit value in the Y register into the 16-bit X register
lda ph 87 1 A=P>>8 TXY 94 1 Copy the 16-bit value in the X register into the 16-bit Y register
lda ql 88 1 A=Q&FF TVX B6 1 Copy the 16-bit Interrupt Return Address into the X register
lda qh 89 1 A=Q>>8 TXV 96 1 Copy the 16-bit value in the X register into the 16-bit Interrupt Return Address register
ldb pl 37 1 B=P&FF TAS 95 1 Copy the value in the A register into the 8-bit Stack Pointer register
ldc ph 38 1 C=P>>8 TSA B5 1 Copy the 8-bit Stack Pointer into the A register
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
Opcodes used: 244/255 Opcodes used: 189/256
0123456789ABCDEF 0123456789ABCDEF
00 | CB----WWBBBBBBBB 00 | CC-BJA-BSA--JJ--
10 | UUIIUIIUUUUUUUUU 10 | B--BSA-MCA-BSA-B
20 | BWWWAWBBBBBUUUUA 20 | JJ-BJA-BSA-BJJ--
30 | JJJJJJJMMMMSSSAA 30 | B--BSA-MCA-BSA-B
40 | SSSSSSSSSSXXXAAA 40 | CC-BJA-USA--JJ-B
50 | BBBBBBBBBBBBBBBB 50 | ---BSA-UCA-USA-U
60 | JBBJJJJJWWWWWWWW 60 | J--BJA-ASA-AJJ-B
70 | -AAAAAA-A-WWWWWW 70 | ---BSA--CA-ASA-A
80 | MMMMMMMMMMMMMMMM 80 | WB-BWBWBX-X-WWWW
90 | MMWWWWBBB--AAAAA 90 | BBWBMMMMBBWBWB-B
A0 | AAAAAA-AAAAAA-AA A0 | WBWBWBWBWBWBWWWW
B0 | AAAA-AAAAAAAAAAA B0 | BBWBMMMMWBWBWBWB
C0 | BBBBBBBBBBBBWWWW C0 | WB-B-AU-XA--JB-B
D0 | AAAAAAAAAAAAAAAA D0 | BBWB--UM-AU-XAU-
E0 | MJJJJJXXXSSBWWWW E0 | WBWB-AUAX-C--B-B
F0 | CCCCCCCBWWWWWWBC 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> 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. 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 ## Robot Controller
Write to `$0701` to control a 1x1f-sized "robot" that can place and destroy bricks.<br> 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> 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. # 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> To use the emulator, simply drag-and-drop an assembly code file onto [emulator/8608-emulator.bat](emulator/8608-emulator.bat)
Simply include the 8608 architecture file into your program: [8608.asm](8608.asm).<br> You must include the 8608 architecture file into your assembly code: [8608.asm](8608.asm)<br>
`#include "8608/8608.asm"` `#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/)