diff --git a/.gitignore b/.gitignore deleted file mode 100644 index da66e67..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.vscode -programs \ No newline at end of file diff --git a/rom-8608-defs.lua b/8608-definition.lua similarity index 93% rename from rom-8608-defs.lua rename to 8608-definition.lua index 366a301..f8cc852 100644 --- a/rom-8608-defs.lua +++ b/8608-definition.lua @@ -1,6 +1,14 @@ +-- 8608-definition.lua +-- This file contains the formal definitions for each instruction in the 8608 architecture. +-- It is used by generate-architecture.lua to generate the following: +-- instructionList.txt, a human-readable list of all instructions. +-- 8608.asm, a set of definitions for CustomAsm that allows it to assemble 8608 programs. +-- The microcode ROM data, which is built into the physical CPU to control it. return { +-- List of every control line in the CPU +-- Organized by bit position within the four microcode ROMs roms = { { pos = {0, 0, 0}, size = {64, 16, 64}, signals = { "alulU", "alulT", "alulC", "alulB", "alulA", "alurIL", "alurIH", "alurVL", @@ -29,6 +37,9 @@ roms = { } }, }, +-- Macro operations +-- These can be used as a shortcut to convey that multiple control lines should be set +-- Macro definitions may contain other macros operations = { base = {"always1"}, @@ -115,7 +126,6 @@ operations = { aluOpAnd = {"aluRun","aluAnd" , "aluSaveNZ"}, aluOpIor = {"aluRun","aluIor" , "aluSaveNZ"}, aluOpXor = {"aluRun","aluXor" , "aluSaveNZ"}, - aluOpAnn = {"aluRun","aluAnd","aluRInv", "aluSaveNZ"}, aluOpCmp = {"aluOpSub"}, aluOpInc = {"aluOpAdd","aluCinOn"}, aluOpDec = {"aluOpAdd","aluRInv"}, @@ -134,6 +144,26 @@ operations = { } }, +-- List of definitions for every instruction +-- Each instruction definition contains: +-- Mnemonic: The mnemonic used to generate the assembler definitions and instruction list. +-- This is what must literally appear in the assembly code in order to generate this instruction, other than immediate values. +-- "imm8" means an 8-bit value. +-- "imm16" means a 16-bit value. +-- Opcode: The machine code byte that represents this operation. +-- Used by the assembler generator to map mnemonics to opcodes. +-- Used by the microcode generator to place the instruction's data within the microcode ROM, which is addressed by opcode. +-- List of control signals: Specifies the control lines that will be activated by the microcode when the instruction is executed. +-- Instructions may take multiple clock cycles. To convey this, each clock cycle is represented by an independent list of microcode signals. +-- Under the hood, the microcode ROM uses a 10-bit address: 8 bits for the opcode, and 2 bits for the clock cycle. +-- Because of this, each opcode may only use up to 4 clock cycles. +-- If more are required, the least significant bit of the opcode can be set by a control line, incrementing the opcode. +-- This causes one instruction to use up multiple opcodes. +-- The need for this is determined automatically by the microcode generator: whenever an instruction specifies more than 4 lists of control signals. +-- Description: A brief description of the instruction. Used to generate the instruction list. +-- C Code: Used to generate an emulator (as part of a separate project). +-- Categories can be specified. These serve only to organize the instruction list. +-- The category letter determines what letter will be used to represent the instructions in the opcode map, located at the bottom of the instruction list. instructions = { { category = "Control", catlet="C" }, { mnem="rst" , opcode=0x00, {"base","intFlgClk","irqFlgClk","runFlgClk","runFlgVal","clearRegs","loadInstr"}, desc="Clear all registers and set I=0", ccode={"cpu.a=0; cpu.b=0; cpu.c=0; cpu.u=0; cpu.t=0; cpu.p=0; cpu.q=0; cpu.s=0; cpu.v=0; cpu.i=0; cpu.cf=0; cpu.nz=0; cpu.irq=0; cpu.ifg=0; cpu.rfg=1; cpu.ien=0; lni;"} }, @@ -182,16 +212,11 @@ instructions = { { 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="sub imm8" , opcode=0x70, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpSub" ,"instrNext"}, desc="A-=imm8, set flags" , ccode={"loadimmedt","subf(cpu.a,cpu.t); lni;"} }, - { mnem="sbb imm8" , opcode=0x99, {"loadImmedT","instrSub1"}, {"aluB", "alurT","aluOpSub" ,"instrNext"}, desc="B-=imm8, set flags" , ccode={"loadimmedt","subf(cpu.b,cpu.t); lni;"} }, - { mnem="sbc imm8" , opcode=0x9A, {"loadImmedT","instrSub1"}, {"aluC", "alurT","aluOpSub" ,"instrNext"}, desc="C-=imm8, set flags" , ccode={"loadimmedt","subf(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="scc imm8" , opcode=0x79, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpSubC","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="ann imm8" , opcode=0x77, {"loadImmedT","instrSub1"}, {"aluA", "alurT","aluOpAnn" ,"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;"} }, @@ -209,7 +234,6 @@ instructions = { { 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="ann *s+imm8" , opcode=0xB4, {"loadImmedT","instrSub1"}, {"loadStackRelT","instrSub2"}, {"aluA", "alurT","aluOpAnn" ,"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;"} }, @@ -225,7 +249,6 @@ instructions = { { 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="ann b" , opcode=0xA6, {"aluA", "alurB","aluOpAnn" ,"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;"} }, @@ -241,7 +264,6 @@ instructions = { { 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="ann c" , opcode=0xAD, {"aluA", "alurC","aluOpAnn" ,"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;"} }, @@ -396,10 +418,43 @@ instructions = { { mnem="ldv p" , opcode=0x90, {"adwlP" , "adwSaveV","instrNext"}, desc="V=P", ccode={"cpu.v=cpu.p; lni;"} }, }, +-- Aliases for instructions +-- Used to generate the assembler definitions. +-- imm8neg instead of imm8 means the immediate value will be negated when assembling. aliases = { ["jpz imm8" ] = {"jeq imm8"}, ["jnz imm8" ] = {"jne imm8"}, ["jmp q" ] = {"ret" }, + ["add imm8" ] = {"sub imm8neg"}, + ["adb imm8" ] = {"sbb imm8neg"}, + ["adc imm8" ] = {"sbc imm8neg"}, + ["acc imm8" ] = {"scc imm8neg"}, }, +-- Filename to generate the assembler definitions file to. +assemblerDefsFile = "8608.asm", +-- Header to be inserted at the top of the assembler definitions file +assemblerDefsHeader = [[ +; 8608.asm +; Include this file into a CustomAsm assembly file to use the 8608 architecture, like so: +; #include "8608.asm" +; See CustomAsm for more info: https://github.com/hlorenzi/customasm + +; Generated by generate-architecture.lua using the definitions in 8608-definition.lua +; Definitions for all instructions in the 8608 architecture. +]], + +-- Filename to generate the instruction listing file to. +instructionListFile = "instructionList.txt", +-- Header to be inserted at the top of the instruction listing file +instructionListHeader = [[ +instructionList.txt +List of all instructions in the 8608 architecture. + +Instructions are encoded as the opcode, followed by any immediate values. +16-bit immediates are encoded in big-endian byte order. + +Each instruction is described in order of: Mnemonic, Opcode, Clock cycles, Description +]], + } diff --git a/arch-8608.asm b/8608.asm similarity index 94% rename from arch-8608.asm rename to 8608.asm index ff43bef..f45e96a 100644 --- a/arch-8608.asm +++ b/8608.asm @@ -1,5 +1,9 @@ +; 8608.asm +; Include this file into a customasm assembly file to use the 8608 architecture, like so: +; #include "8608.asm" -; Instruction list (Auto-generated from rom-8608-defs.lua by rom-8608-build.lua) +; Generated by generate-architecture.lua using the definitions in 8608-definition.lua +; Definitions for all instructions in the 8608 architecture. #ruledef { rst => $00 hlt => $F0 @@ -77,18 +81,33 @@ 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 - sub {value: i8} => $70 @ value - sbb {value: i8} => $99 @ value - sbc {value: i8} => $9A @ value + sbc {value:i8} => { + mvalue = -value + $73 @ mvalue`8 + } + acc {value: i8} => $78 @ value - scc {value: i8} => $79 @ 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 - ann {value: i8} => $77 @ value shl {value: i8} => $D0 @ value shr {value: i8} => $D1 @ value rol {value: i8} => $D2 @ value @@ -226,17 +245,6 @@ assert(mvalue >= -128, "Relative address is too far away") $B3 @ mvalue`8 } - ann *s+{value: i8} => { - assert(value <= 127, "Relative address is too far away") - assert(value >= -128, "Relative address is too far away") - $B4 @ value`8 - } - ann *s-{value: i8} => { - mvalue = -value - assert(mvalue <= 127, "Relative address is too far away") - assert(mvalue >= -128, "Relative address is too far away") - $B4 @ mvalue`8 - } shl *s+{value: i8} => { assert(value <= 127, "Relative address is too far away") assert(value >= -128, "Relative address is too far away") @@ -302,7 +310,6 @@ and b => $A3 ior b => $A4 xor b => $A5 - ann b => $A6 shl b => $DA shr b => $DB rol b => $DC @@ -318,7 +325,6 @@ and c => $AA ior c => $AB xor c => $AC - ann c => $AD shl c => $DF shr c => $4D rol c => $3E diff --git a/arch-8608-template.asm b/arch-8608-template.asm deleted file mode 100644 index 286747e..0000000 --- a/arch-8608-template.asm +++ /dev/null @@ -1,5 +0,0 @@ - -; Instruction list (Auto-generated from rom-8608-defs.lua by rom-8608-build.lua) -#ruledef { - %s -} diff --git a/arch8608.ods b/arch8608.ods deleted file mode 100644 index a5dc945..0000000 Binary files a/arch8608.ods and /dev/null differ diff --git a/assembler-8608-deprecated.lua b/assembler-8608-deprecated.lua deleted file mode 100644 index cdea5e0..0000000 --- a/assembler-8608-deprecated.lua +++ /dev/null @@ -1,723 +0,0 @@ - -local function loadutf8table(fn) - local tt = {} - for l in io.lines(fn) do if l~="" then - local c, d = l:match("^([^ ]+) (.+)$") - local t = {}; for v in d:gmatch("[^ ]+") do table.insert(t, tonumber(v, 16)) end; - tt[c] = t - end end - return tt -end -local utf8table = loadutf8table((RelPath or "./").."utf8table.txt") - -local function trim(s) return s:gsub("^ +", ""):gsub(" +$", "").."" end -local function getutf8len(c) - local d = c:byte() - if bit.band(d, 0xE0)==0xC0 then return 2 - elseif bit.band(d, 0xF0)==0xE0 then return 3 - elseif bit.band(d, 0xF8)==0xF0 then return 4 - else error("invalid utf8 first byte: "..string.format("%02X", d)) end -end -local function validWordsFromInstrs(instrs) - local words = {} - for mnem, _ in pairs(instrs) do - for word in mnem:gmatch("[^ ]+") do - words[word] = true - end - end - return words -end -local function lobyte(n) return n%256 end -local function hibyte(n) return math.floor(n/256) end -local function decodeNumber(n) - n = trim(n) - local sign = 1; if n:sub(1, 1)=="-" then sign = -1; n = n:sub(2, #n); end; - if n:sub(1, 1)=="$" then return sign*(tonumber(n:sub(2, #n ), 16) or error("invalid hex number "..n)), math.ceil((#n-1)/2) - elseif n:sub(1, 2)=="0x" then return sign*(tonumber(n:sub(3, #n ), 16) or error("invalid hex number "..n)), math.ceil((#n-2)/2) - elseif n:sub(#n, #n)=="h" and n:find("^[0-9a-fA-F]+h$") then return sign*(tonumber(n:sub(1, #n-1), 16) or error("invalid hex number "..n)), math.ceil((#n-1)/2) - elseif n:sub(1, 2)=="0b" then return sign*(tonumber(n:sub(3, #n ), 2) or error("invalid binary number "..n)), math.ceil((#n-2)/8) - elseif n:sub(#n, #n)=="b" and n:find("^[01]+b$") then return sign*(tonumber(n:sub(1, #n-1), 2) or error("invalid binary number "..n)), math.ceil((#n-1)/8) - elseif n:sub(1, 3)=="lo(" and n:sub(#n, #n)==")" then return lobyte(decodeNumber(n:sub(4, #n-1))), 1 - elseif n:sub(1, 3)=="hi(" and n:sub(#n, #n)==")" then return hibyte(decodeNumber(n:sub(4, #n-1))), 1 - elseif n:find("^[0-9]+$") then - local v = sign*(tonumber(n) or error("invalid decimal number "..n)) - if v>=-128 and v<=255 then return v, 1 - elseif v>=-32768 and v<=65535 then return v, 2 - else error("out-of-range number "..v) end - else - return nil - end -end -local function mnemFromLine(line, instrs, validWords) - local imms = {} - local function addNum(n) - n = trim(n) - local val, len = decodeNumber(n) - assert(val and len, "invalid number "..n) - local linei8 = line:gsub(n, "imm8", 1, true):lower() - local linei16 = line:gsub(n, "imm16", 1, true):lower() - if len==1 and (not instrs[linei8]) and instrs[linei16] then len = 2 end - table.insert(imms, { val = val, len = len } ) - return " imm"..(len*8).." " - end - local function addLabel(n) - n = trim(n) - local len = 2 - local linei8 = line:gsub(n, "imm8", 1, true):lower() - if instrs[linei8] then len = 1 end - table.insert(imms, { label = n, len = len } ) - return " imm"..(len*8).." " - end - - local mnem = " "..line:gsub(" ", " ").." " - mnem = mnem:gsub("%- *", " %+%-") - mnem = mnem:gsub("([%*%+])", " %1 ") - mnem = mnem:gsub(" %-?%$[0-9a-fA-F]+ " , function(n) return addNum (n) end) - mnem = mnem:gsub(" %-?0x[0-9a-fA-F]+ " , function(n) return addNum (n) end) - mnem = mnem:gsub(" %-?0b[01]+ " , function(n) return addNum (n) end) - mnem = mnem:gsub(" %-?[0-9a-fA-F]+h " , function(n) if not validWords[trim(n)] then return addNum (n) end end) - mnem = mnem:gsub(" %-?[01]+b " , function(n) if not validWords[trim(n)] then return addNum (n) end end) - mnem = mnem:gsub(" %-?[0-9]+ " , function(n) if not validWords[trim(n)] then return addNum (n) end end) - mnem = mnem:gsub(" [a-zA-Z_][a-zA-Z0-9_%.]* ", function(n) if not validWords[trim(n)] then return addLabel(n) end end) - mnem = trim(mnem):gsub(" +", " "):lower() - - if not instrs[mnem] then mnem = mnem:gsub("%+ imm", "imm") end - - return mnem, imms -end -local function addByte(state, val, code) - assert(val>=-128 and val<=255, "invalid byte "..val) - assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr)) - state.memory[state.curAddr] = val%256 - if code then state.codeMap[state.curAddr] = true end - state.curAddr = state.curAddr + 1 -end -local function addWord(state, val, code) - assert(val>=0 and val<=65535, "invalid word "..val) - addByte(state, math.floor(val/256), code) - addByte(state, val%256, code) -end -local function addSpace(state, len) - for i = 1, len do - assert(state.memory[state.curAddr]==nil, "overwriting memory at $"..string.format("%04X", state.curAddr)) - state.memory[state.curAddr] = false - state.curAddr = state.curAddr + 1 - end -end -local function assembleInstruction(line, state, instrs, validWords) - local mnem, imms = mnemFromLine(line, instrs, validWords) - local opcode = instrs[mnem] or error("invalid instruction \""..line.."\" (mnem \""..mnem.."\")") - local writeimms = true - local padlen = 0 - local isInstr - if type(opcode)=="function" then - padlen, writeimms = opcode(imms) - addSpace(state, padlen) - elseif opcode>=0 then - isInstr = true - addByte(state, opcode, isInstr) - end - if writeimms then - for _, imm in ipairs(imms) do - if imm.val then - if imm.len==1 then addByte(state, imm.val, isInstr) - elseif imm.len==2 then addWord(state, imm.val, isInstr) - else error("invalid imm len") end - elseif imm.label then - table.insert(state.labelReplacements, { - name = imm.label, - addr = state.curAddr, - len = imm.len, - rel = imm.len==1, - isCode = isInstr, - }) - state.curAddr = state.curAddr + imm.len - else error("invalid imm") end - end - end -end -local directiveFunctions = { - fn = function(state, fn) state.fileName = fn end, - ln = function(state, ln) state.lineNum = tonumber(ln) end, - org = function(state, addr) state.curAddr = decodeNumber(addr) or error("Invalid origin \""..addr.."\"") end, - align = function(state, alns) local aln = decodeNumber(alns); if state.curAddr % aln ~= 0 then state.curAddr = state.curAddr + (aln - state.curAddr%aln) end end, - define = true, - space = function(state, amts) local amt = decodeNumber(amts); state.curAddr = state.curAddr + amt; end, -} -local function postEvaluateExpression(expr, labels) - -end -local function assembleCode(code, instrs, uexprs) - local validWords = validWordsFromInstrs(instrs) - - local state = { - lineNum = 0, - fileName = "", - curAddr = 0, - memory = {}, - codeMap = {}, - labelReplacements = {}, - labelAddrs = {}, - } - - for line in code:gmatch("[^\n]+") do - line = trim(line) - if line:sub(1, 1)=="." then -- directive - local dir, rest = line:match("^%.([^ ]+) *(.*)$") - assert(dir and rest, "no directive on line "..line) - local dirf = directiveFunctions[dir] or error("invalid directive "..dir) - dirf(state, rest) - elseif line:sub(#line, #line)==":" then -- label - local name = line:sub(1, #line-1) - assert(not state.labelAddrs[name], "redefinition of label "..name) - state.labelAddrs[name] = state.curAddr - elseif line:find("[^ ]") then - assembleInstruction(line, state, instrs, validWords) - end - end - - for _, rep in ipairs(state.labelReplacements) do - local expr = uexprs[rep.name] - if expr then - local val = postEvaluateExpression(expr, state.labelAddrs) - if rep.len==1 then addByte(state, val, rep.isCode) - elseif rep.len==2 then addWord(state, val, rep.isCode) - else error("invalid expr replace len "..rep.len) end - else - local labelAddr = state.labelAddrs[rep.name] or error("no label named "..rep.name) - state.curAddr = rep.addr - if rep.len==1 then addByte(state, labelAddr-(rep.addr+1), rep.isCode) - elseif rep.len==2 then addWord(state, labelAddr , rep.isCode) - else error("invalid labelreplace len "..rep.len) end - end - end - - return state.memory, state.codeMap -end - -local function readFile(fn) - local fi, err = io.open(fn, "r") - if not fi then error("could not open file "..fn..": "..err) end - local text = fi:read("*a") - fi:close() - return text -end - -local function separateCommas(l) - local c = {}; for a in l:gmatch("[^,]+") do table.insert(c, trim(a)) end; return c; -end -local function evaluateExpression(expr, uexprs) - expr = expr:gsub("[^%+%-%*%/]+", function(word) - local val = decodeNumber(word) or error("invalid number in expression: "..word) - return val - end) - assert(not expr:find("[^a-zA-Z0-9_%(%)%+%-%*%/ \t\r\n]"), "invalid char in expression: "..expr) - local exprf = loadstring("return "..expr) - local eval = exprf() or error("invalid expr: "..expr) - return eval -end -local function preprocessCode(code) - code = "\n"..code.."\n" - - -- apply brace labels and scoped labels - local curscope = "" - local codet = {} - local wordt = {} - local lastword = "" - local function addword(word) - lastword = word - if word:sub(1, 1)=="." and not directiveFunctions[word:sub(2, #word)] then word = curscope..word end - table.insert(codet, word) - end - for i = 1, #code do - local c = code:sub(i, i) - if c:find("[%.a-zA-Z0-9_]") then table.insert(wordt, c) - else - if #wordt>0 then - addword(table.concat(wordt)) - wordt = {} - end - if c==":" and lastword:sub(1, 1)~="." and not lastword:find("_BRACE_") then - curscope = lastword - end - table.insert(codet, c) - end - end - - code = "\n"..table.concat(codet).."\n" - - -- apply function macros - local funcmacros = {} - code = code:gsub(".define ([%.a-zA-Z0-9_]+)%(([^%)]+)%) ([^\n]+)", function(name, args, repl) - local argt = separateCommas(args) - for argidx, arg in ipairs(argt) do assert(not arg:find("[^a-zA-Z0-9_]"), "invalid character in macro arg name: "..name.." "..arg) end - repl = " "..repl.." " - local invoc = 0 - funcmacros[name] = function(b, callargs) - invoc = invoc + 1 - local callargt = separateCommas(callargs) - local callrepl = repl - for argidx, arg in ipairs(argt) do - local callarg = callargt[argidx] - callrepl = callrepl:gsub("([^a-zA-Z0-9_])"..arg.."([^a-zA-Z0-9_])", "%1"..callarg.."%2") - end - callrepl = callrepl:gsub("(_BRACE_[0-9]+_)", "%1"..invoc.."_") - return b..callrepl - end - return "" - end) - for name, replf in pairs(funcmacros) do code = code:gsub("([^a-zA-Z0-9_])"..name.." *%(([^%)]+)%)", replf) end - - -- apply simple macros - local simplemacros = {} - code = code:gsub("%.define +([%.a-zA-Z0-9_]+) +([^\n]+)", function(name, repl) - assert(not simplemacros[name], "Redefinition of macro "..name) - simplemacros[name] = repl - return "" - end) - --for name, repl in pairs(simplemacros) do code = code:gsub(name, repl, 1, true) end - for name, repl in pairs(simplemacros) do - local invoc = 0 - code = code:gsub("([^a-zA-Z0-9_])"..name.."([^a-zA-Z0-9_])", function(b, a) - invoc = invoc+1 - return b..(repl:gsub("(_BRACE_[0-9]+_)", "%1"..invoc.."_"))..a - end) - print(name, code) - end - - code = code:gsub("\\\\", "\n") - - local uexprs = {} - - local codet = {} - local exprt = {} - local parenLevel = 0 - for i = 1, #code do - local c = code:sub(i, i) - if c=="(" then - if parenLevel>0 then table.insert(exprt, c) end - parenLevel = parenLevel+1 - elseif c==")" then - parenLevel = parenLevel-1 - if parenLevel==0 then - table.insert(codet, evaluateExpression(table.concat(exprt), uexprs)) - exprt = {} - else - table.insert(exprt, c) - end - else - if parenLevel==0 then table.insert(codet, c) - else table.insert(exprt, c) end - end - end - code = table.concat(codet) - - return code, uexprs -end -local function fixCode(code) - code = code:gsub(",", " ") - code = code:gsub(":([^\\/])", ":\n%1") - code = code:gsub("[ \t]+:", ":") - code = code:gsub("%]", " %] ") - code = code:gsub("%[", " %[ ") - code = code:gsub("%*", " %* ") - code = code:gsub("\n[ \t\r\n]*", "\n") - code = code:gsub(" +", " ") - - return code -end -local stringEscapes = { ["\\"] = "\\", ["n"] = "\n", ["r"] = "\r", ["t"] = "\t", ["0"] = "\0", ["\""] = "\"", ["\'"] = "\'", } -local prefixIdx = 0 -local function prefixCode(code, fn) -- fix strings, add line numbers - prefixIdx = prefixIdx + 1 - - local outt = {} - local outnextnl = {} - local linenum = 1 - local skipnl = false - local function last() return outt[#outt] end - local function out(c) assert(type(c)=="string"); table.insert(outt, c); end - local function outn(n) out("$"..string.format("%02X", n)) out("\\") end - local function outnext(c) assert(type(c)=="string"); table.insert(outnextnl, c); end - local state = "code" -- code, comment, string, stringesc, commentml - - local lastbracelabel = 0 - local function bracelabel() lastbracelabel = lastbracelabel+1; return "_BRACE_"..string.format("%02d", prefixIdx)..lastbracelabel.."_"; end - local bracestack = {} - local bracehasmid = {} - local lastnl = false - - local utf8str = "" - local utf8len = 0 - - local function newline() - lastnl = true - for _, v in ipairs(outnextnl) do - if v=="\n" and skipnl then out("\\") - else out(v) end - end; outnextnl = {}; - end - - out(".ln 1"); out("\n"); - local i = 1 - while i <= #code do - local c = code:sub(i, i) - local cn = code:sub(i+1, i+1) - local cp = code:sub(i-1, i-1) - - if state=="code" then - if c=="\r" then - elseif c=="\n" then -- (c=="/" and cn~="/" and cn~="*") - linenum = linenum+1 - if not skipnl then out("\n") out(".ln "..linenum); out("\n"); end - newline() - skipnl = false - elseif c=="#" or c==";" or (c=="/" and cn=="/") then state = "comment" - elseif c=="/" and cn=="*" then state = "commentml" - elseif c=="\t" or c==" " then if (not lastnl) then out(" ") end - elseif c=="\"" then state = "string" lastnl = false - elseif c=="\\" then skipnl = true; out("\\"); - elseif c==":" then out(c); if skipnl then out("\\") else out("\n") end; lastnl = true; - elseif c:find("^[a-zA-Z0-9_%.%$%(%)%*,%[%]%+%-%*%/]$") then out(c); lastnl = false - elseif c=="{" then - table.insert(bracestack, bracelabel()) - if not lastnl then out(bracestack[#bracestack].."MID") end - outnext(bracestack[#bracestack].."START:"); outnext("\n"); - elseif c=="}" then - if not lastnl then out(bracestack[#bracestack].."START") end - if not bracehasmid[#bracestack] then outnext(bracestack[#bracestack].."MID:"); outnext("\n"); end - outnext(bracestack[#bracestack].."END:"); outnext("\n"); - bracehasmid[#bracestack] = nil - bracestack[#bracestack] = nil - elseif c=="|" then - if not lastnl then out(bracestack[#bracestack].."END") end - outnext(bracestack[#bracestack].."MID:"); outnext("\n"); - bracehasmid[#bracestack] = true - else error("invalid char "..c) end - elseif state=="comment" then - if c=="\n" then state = "code" out("\n") newline() end - elseif state=="commentml" then - if c=="/" and cp=="*" then state = "code" end - elseif state=="string" then - if c=="\\" then state = "stringesc" - elseif c=="\"" then state = "code" - elseif c:byte()>=128 then - utf8str = c - utf8len = getutf8len(c) - state = "stringutf8" - else outn(c:byte()) end - elseif state=="stringesc" then - outn(string.byte(stringEscapes[c] or error("invalid escape "..c))); state = "string"; - elseif state=="stringutf8" then - utf8str = utf8str..c - if #utf8str == utf8len then - local valt = utf8table[utf8str] - if not valt then local datastr = ""; for i = 1, #utf8str do datastr = datastr .. string.format("%02X ", utf8str:sub(i, i):byte()) end; - error("Unrecognized UTF-8 character: "..datastr); end - for i, v in ipairs(valt) do outn(v) end - state = "string" - end - end - - i = i+1 - end - assert(#bracestack==0, "unclosed brace") - local code2 = table.concat(outt) - - return code2 -end -local function fixFilename(fn) - fn = fn:gsub("[^a-zA-Z0-9_]", "_") - return fn -end -local function includeFile(fn) - local code = readFile(fn) - code = prefixCode(code, fn) - local fnf = fixFilename(fn) - code = ".fn "..fnf.."\n"..code - code = code:gsub(".include ([^\r\n]+)", function(fn2) - fn2 = fn:gsub("[^\\/]+$", "")..fn2 - return "\n"..includeFile(fn2).."\n"..".fn "..fnf.."\n" - end) - return code -end -local function instrsFromArch(arch) - local function arraySize(imms) local s = 1; for i = 1, #imms do s = s*(imms[i].val or error("invalid array size")) end; return s; end - local instrs = { - imm8 = function() return 0, true end, - imm16 = function() return 0, true end, - byte = function() return 1, false end, - word = function() return 2, false end, - ["byte imm8"] = function() return 0, true end, - ["word imm16"] = function() return 0, true end, - ["byte [ imm8 ]" ] = function(imms) return arraySize(imms) , false end, - ["byte [ imm16 ]"] = function(imms) return arraySize(imms) , false end, - ["word [ imm8 ]" ] = function(imms) return arraySize(imms)*2, false end, - ["word [ imm16 ]"] = function(imms) return arraySize(imms)*2, false end, - } - local function addMnem(mnem, opcode) - instrs[mnem] = opcode - if mnem:find("%*") then instrs[mnem:gsub("%*", "%[").." ]"] = opcode end - end - for _, instr in ipairs(arch.instructions) do - if instr.mnem then - local mnem = instr.mnem - mnem = mnem:gsub("([%*%+%-])", " %1 ") - mnem = trim(mnem):gsub(" +", " ") - addMnem(mnem, instr.opcode) - local alias = arch.aliases[trim(mnem)] - if alias then for _, v in ipairs(alias) do addMnem(v, instr.opcode) end end - end - end - return instrs -end -local function assembleFile(fn, arch) - local code = includeFile(fn) - code, uexprs = preprocessCode(code) - code = fixCode(code) - local instrs = instrsFromArch(arch) - local mem, code = assembleCode(code, instrs, uexprs) - return mem, code -end - -local function mnemsFromArch(arch) - local mnems = {} - for _, instr in ipairs(arch.instructions) do - if instr.mnem then - local len = 1 - for l in instr.mnem:gmatch("imm([0-9]+)") do len = len + tonumber(l)/8 end - mnems[instr.opcode] = { mnem = instr.mnem, rel = instr.rel, jmp = instr.jmp, len = len, } - end - end - return mnems -end -local function toSigned8(x) return x>=128 and x-256 or x end -local function disassembleMemory(mem, code, arch) - local mnems = mnemsFromArch(arch) - - local addr = 0 - local function nextByte(d) local b = mem[addr]; addr = addr+1; return b or d; end - local lastaddr = 0 - local jmpaddrs = {} - while addr<=0xFFFF do - local startaddr = addr - local opcode = nextByte() - if opcode and ((not code) or code[startaddr]) then - local mnem = mnems[opcode] - if mnem then - if mnem.jmp then - local jmpdest - if mnem.rel then jmpdest = toSigned8(nextByte(0)) + addr - else jmpdest = nextByte(0)*256 + nextByte(0) - end - if jmpdest then - if not jmpaddrs[jmpdest] then - jmpaddrs[jmpdest] = { rel = mnem.rel, from = {}, } - end - table.insert(jmpaddrs[jmpdest].from, startaddr) - jmpaddrs[jmpdest].rel = jmpaddrs[jmpdest].rel and mnem.rel - end - else - addr = addr + mnem.len - 1 - end - end - end - end - local labelnum, subnum = 0, 0 - for _, jmp in pairs(jmpaddrs) do - if jmp.rel then jmp.name = "label_" ..labelnum; labelnum = labelnum+1; - else jmp.name = "subroutine_"..subnum ; subnum = subnum +1; end - end - - local lines = {} - addr = 0 - while addr<=0xFFFF do - local startaddr = addr - local opcode = nextByte() - if opcode and ((not code) or code[startaddr]) then - local line = {} - local mnem = mnems[opcode].mnem or "???" - table.insert(line, trim(mnem:gsub("imm[0-9]+", ""))) - local tlen = 1 - for lens in mnem:gmatch("imm([0-9]+)") do local len = tonumber(lens)/8 - if len==1 then - local data = nextByte(0) - local jmp - if mnems[opcode].rel then - local jmpdest = (addr + toSigned8(data))%65536 - jmp = jmpaddrs[jmpdest] - if jmp then - table.insert(line, jmp.name) - --table.insert(line, ";") - --table.insert(line, "$"..string.format("%04X", jmpdest)..",") - end - end - if not jmp then table.insert(line, "$"..string.format("%02X", data)) end - elseif len==2 then - local data = nextByte(0)*256 + nextByte(0) - local jmp - if mnems[opcode].jmp then - local jmpdest = data - jmp = jmpaddrs[jmpdest] - if jmp then - table.insert(line, jmp.name) - --table.insert(line, ";") - end - end - if not jmp then table.insert(line, "$"..string.format("%04X", data)) end - else error("invalid imm len") end - tlen = tlen + len - end - local lineb = {} - for i = addr-tlen, addr-1 do - table.insert(lineb, string.format("%02X", mem[i] or 0)) - end - local label = "" - local jmp = jmpaddrs[startaddr] - if jmp then label = jmp.name..":" end - local lb = table.concat(lineb, " ") - if lastaddr~=addr-tlen then table.insert(lines, "...") end - table.insert(lines, string.format("%04X", addr-tlen).." | "..(" "):rep(8-#lb)..lb.." | "..(" "):rep(13-#label)..label.." "..table.concat(line, " ")) - lastaddr = addr - end - end - return table.concat(lines, "\n") -end -local function memToHex(hex) - local mem = {} - local addr = 0 - for d in hex:gmatch("[0-9a-fA-F][0-9a-fA-F]") do - mem[addr] = tonumber(d, 16) - addr = addr+1 - end - return mem -end -local function disassembleHex(hex, arch) - return disassembleMemory(memToHex(hex), arch) -end - -local printableCharsS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`-=[]\\;\',./~!@#$%^&*()_+{}|:\"<> " -local printableChars = {}; for i = 1, #printableCharsS do printableChars[printableCharsS:sub(i, i)] = true end; -local function toPrintableChar(n) - local c = string.char(n) - return printableChars[c] and c or "?" -end -local function printMemory(mem) - local anynonempty = false - local lastbase = -16 - local lastline = "" - local numreps = 0 - local lines = {} - local function closereps(base) - if numreps~=0 then - table.insert(lines, "(repeated "..numreps.." more times, up to "..string.format("%04X", base+15)..")") - numreps = 0 - end - end - for base = 0, 0xFFF0, 16 do - local line = {} - local strt = {} - local nonempty = false - for addr = base, base+15 do - if addr%4==0 then table.insert(line, " ") end - if mem[addr]==false then - nonempty = true - table.insert(line, "XX ") - table.insert(strt, "X") - elseif mem[addr] then - nonempty = true - table.insert(line, string.format("%02X", mem[addr]).." ") - table.insert(strt, toPrintableChar(mem[addr])) - else - table.insert(line, "-- ") - table.insert(strt, "-") - end - end - if nonempty then - local l = table.concat(line) - if l~=lastline or base~=lastbase+16 then - closereps(base-16) - if base ~= lastbase+16 then table.insert(lines, "...") end - table.insert(lines, string.format("%04X", base).." | "..l.." | "..table.concat(strt)) - else - numreps = numreps+1 - end - lastline = l - lastbase = base - anynonempty = true - end - end - closereps(lastbase) - if not anynonempty then table.insert(lines, "Empty") end - - return table.concat(lines, "\n") -end - -local HasTs = ts~=nil -local ts = ts or { - call = function() end, - eval = function() end, -} -ts.eval [[ - function commandShiftBrick(%x, %y, %z) { commandToServer('shiftBrick', %x, %y, %z); } - function commandPlantBrick() { commandToServer('plantBrick'); } -]] -local function plantBrickAt(brickpos, pos) - local dx, dy, dz = pos[1]-brickpos[1], pos[2]-brickpos[2], pos[3]-brickpos[3] - ts.call("commandShiftBrick", dy, -dx, dz) - ts.call("commandPlantBrick") - brickpos[1], brickpos[2], brickpos[3] = pos[1], pos[2], pos[3] -end -local function buildMemory(mem, romsize, offset, len) - offset = offset or 0 - - local rombytes = romsize[1]*romsize[2]*romsize[3]/8 - if len and len>rombytes then error("rom not big enough to hold "..len.." bytes (holds "..rombytes..")") end - if not len then - for i = 0, 0xFFFF do - if mem[i] and (i=offset+rombytes) then error("memory does not fit in rom at addr "..string.format("%04X", i)) end - end - end - - local brickpos = {0, 0, 0} - for x = 0, romsize[1]-1 do - for y = 0, romsize[2]-1 do - for z = 0, romsize[3]-1 do - local addr = offset + ((romsize[3]/8)*(x + y*romsize[1]) + math.floor(z/8)) - local pow = math.pow(2, z%8) - local data = (addr>=offset and ((not len) or addr0 and lastLabel[numDots-1].."."..noDots or label - lastLabel[numDots] = fullLabel - symbols[addr] = fullLabel - else - if comment:match("^[a-z]+") then - for i, v in ipairs(data) do - mem [addr+i-1] = v - code[addr+i-1] = true - end - else - for i, v in ipairs(data) do - mem [addr+i-1] = v - end - end - end - end - end - - return mem, code, symbols -end - -local function fullPath(fn) - return popenResult(getCodeDir().."\\fullPath.bat \""..fn.."\"") -end - -local function assembleFile(fn, arch) - local fnf = fullPath(fn) - --local out = popenResult("customasm -p -q --format hexstr \""..fnf.."\"") - --return memFromCustomasmHexstr(out) - local out = popenResult("customasm -p -q --format annotated,base:16,group:2 \""..fnf.."\"") - return memFromCustomasmAnnotated(out) -end - -local function mnemsFromArch(arch) - local mnems = {} - for _, instr in ipairs(arch.instructions) do - if instr.mnem then - local len = 1 - for l in instr.mnem:gmatch("imm([0-9]+)") do len = len + tonumber(l)/8 end - mnems[instr.opcode] = { mnem = instr.mnem, rel = instr.rel, jmp = instr.jmp, len = len, } - end - end - return mnems -end - -local function symbolCrunchDots(s) return s:gsub("[^%.]+%.", "%.").."" end - -local function toSigned8(x) return x>=128 and x-256 or x end -local function disassembleMemory(arch, mem, code, symbols) - local mnems = mnemsFromArch(arch) - - local addr = 0 - local function nextByte(d) local b = mem[addr]; addr = addr+1; return b or d; end - local lastaddr = 0 - local jmpaddrs = {} - while addr<=0xFFFF do - local startaddr = addr - local opcode = nextByte() - if opcode and ((not code) or code[startaddr]) then - local mnem = mnems[opcode] - if mnem then - if mnem.jmp then - local jmpdest - if mnem.rel then jmpdest = toSigned8(nextByte(0)) + addr - else jmpdest = nextByte(0)*256 + nextByte(0) - end - if jmpdest then - if not jmpaddrs[jmpdest] then - jmpaddrs[jmpdest] = { rel = mnem.rel, from = {}, } - end - table.insert(jmpaddrs[jmpdest].from, startaddr) - jmpaddrs[jmpdest].rel = jmpaddrs[jmpdest].rel and mnem.rel - end - else - addr = addr + mnem.len - 1 - end - end - end - end - local labelnum, subnum = 0, 0 - for dest, jmp in pairs(jmpaddrs) do - if symbols[dest] then jmp.name = symbolCrunchDots(symbols[dest]) - elseif jmp.rel then jmp.name = "label_" ..labelnum; labelnum = labelnum+1; - else jmp.name = "subroutine_"..subnum ; subnum = subnum +1; end - end - - local maxLabelLen = 20 - local lines = {} - addr = 0 - while addr<=0xFFFF do - local startaddr = addr - local opcode = nextByte() - if opcode and ((not code) or code[startaddr]) then - local line = {} - local mnem = mnems[opcode].mnem or "???" - table.insert(line, trim(mnem:gsub("imm[0-9]+", ""))) - local tlen = 1 - for lens in mnem:gmatch("imm([0-9]+)") do local len = tonumber(lens)/8 - if len==1 then - local data = nextByte(0) - local jmp - if mnems[opcode].rel then - local jmpdest = (addr + toSigned8(data))%65536 - jmp = jmpaddrs[jmpdest] - if jmp then - table.insert(line, jmp.name) - --table.insert(line, ";") - --table.insert(line, "$"..string.format("%04X", jmpdest)..",") - end - end - if not jmp then table.insert(line, "$"..string.format("%02X", data)) end - elseif len==2 then - local data = nextByte(0)*256 + nextByte(0) - local jmp - if mnems[opcode].jmp then - local jmpdest = data - jmp = jmpaddrs[jmpdest] - if jmp then - table.insert(line, jmp.name) - --table.insert(line, ";") - end - end - if not jmp then table.insert(line, "$"..string.format("%04X", data)) end - else error("invalid imm len") end - tlen = tlen + len - end - local lineb = {} - for i = addr-tlen, addr-1 do - table.insert(lineb, string.format("%02X", mem[i] or 0)) - end - local label = "" - local jmp = jmpaddrs[startaddr] - if symbols[startaddr] then label = symbolCrunchDots(symbols[startaddr])..":" - elseif jmp then label = jmp.name..":" end - local lb = table.concat(lineb, " ") - if lastaddr~=addr-tlen then table.insert(lines, "...") end - table.insert(lines, string.format("%04X", addr-tlen).." | "..(" "):rep(8-#lb)..lb.." | "..(" "):rep(maxLabelLen-#label)..label.." "..table.concat(line, " ")) - lastaddr = addr - elseif opcode and opcode~=0 then - table.insert(lines, "data: "..string.format("%02X", opcode)) - end - end - return table.concat(lines, "\n") -end -local function memToHex(hex) - local mem = {} - local addr = 0 - for d in hex:gmatch("[0-9a-fA-F][0-9a-fA-F]") do - mem[addr] = tonumber(d, 16) - addr = addr+1 - end - return mem -end -local function disassembleHex(hex, arch) - return disassembleMemory(arch, memToHex(hex), nil, nil) -end - -local printableCharsS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789`-=[]\\;\',./~!@#$%^&*()_+{}|:\"<> " -local printableChars = {}; for i = 1, #printableCharsS do printableChars[printableCharsS:sub(i, i)] = true end; -local function toPrintableChar(n) - local c = string.char(n) - return printableChars[c] and c or "?" -end -local function printMemory(mem) - local anynonempty = false - local lastbase = -16 - local lastline = "" - local numreps = 0 - local lines = {} - local function closereps(base) - if numreps~=0 then - table.insert(lines, "(repeated "..numreps.." more times, up to "..string.format("%04X", base+15)..")") - numreps = 0 - end - end - for base = 0, 0xFFF0, 16 do - local line = {} - local strt = {} - local nonempty = false - for addr = base, base+15 do - if addr%4==0 then table.insert(line, " ") end - if mem[addr]==false then - nonempty = true - table.insert(line, "XX ") - table.insert(strt, "X") - elseif mem[addr] then - nonempty = true - table.insert(line, string.format("%02X", mem[addr]).." ") - table.insert(strt, toPrintableChar(mem[addr])) - else - table.insert(line, "-- ") - table.insert(strt, "-") - end - end - if nonempty then - local l = table.concat(line) - if l~=lastline or base~=lastbase+16 then - closereps(base-16) - if base ~= lastbase+16 then table.insert(lines, "...") end - table.insert(lines, string.format("%04X", base).." | "..l.." | "..table.concat(strt)) - else - numreps = numreps+1 - end - lastline = l - lastbase = base - anynonempty = true - end - end - closereps(lastbase) - if not anynonempty then table.insert(lines, "Empty") end - - return table.concat(lines, "\n") -end - -local HasTs = ts~=nil -local ts = ts or { - call = function() end, - eval = function() end, -} -ts.eval [[ - function commandShiftBrick(%x, %y, %z) { commandToServer('shiftBrick', %x, %y, %z); } - function commandPlantBrick() { commandToServer('plantBrick'); } -]] -local function plantBrickAt(brickpos, pos) - local dx, dy, dz = pos[1]-brickpos[1], pos[2]-brickpos[2], pos[3]-brickpos[3] - ts.call("commandShiftBrick", dy, -dx, dz) - ts.call("commandPlantBrick") - brickpos[1], brickpos[2], brickpos[3] = pos[1], pos[2], pos[3] -end -local function buildMemory(mem, romsize, offset, len) - offset = offset or 0 - - local rombytes = romsize[1]*romsize[2]*romsize[3]/8 - if len and len>rombytes then error("rom not big enough to hold "..len.." bytes (holds "..rombytes..")") end - if not len then - for i = 0, 0xFFFF do - if mem[i] and (i=offset+rombytes) then error("memory does not fit in rom at addr "..string.format("%04X", i)) end - end - end - - local brickpos = {0, 0, 0} - for x = 0, romsize[1]-1 do - for y = 0, romsize[2]-1 do - for z = 0, romsize[3]-1 do - local addr = offset + ((romsize[3]/8)*(x + y*romsize[1]) + math.floor(z/8)) - local pow = math.pow(2, z%8) - local data = (addr>=offset and ((not len) or addrrombytes then error("rom not big enough to hold "..len.." bytes (holds "..rombytes..")") end - if not len then - for i = 0, 0xFFFF do - if mem[i] and (i=offset+rombytes) then error("memory does not fit in rom at addr "..string.format("%04X", i)) end - end - end - - local brickpos = {0, 0, 0} - for x = 0, romsize[1]-1 do - for y = 0, romsize[2]-1 do - for z = 0, romsize[3]-1 do - local addr = offset + ((romsize[3]/8)*(x + y*romsize[1]) + math.floor(z/8)) - local pow = math.pow(2, z%8) - local data = (addr>=offset and ((not len) or addr>8)&0xFF) -#define wordfrombytes(h,l) (((h<<8)&0xFF00)|(l&0xFF)) -#define popbyte readmemory(--cpu->s) -#define loadimmed readmemory(cpu->i++) -#define loadstackrel readmemory((cpu->s+signed8(cpu->t))%65536) -#define loadstackrelp1 readmemory((cpu->s+signed8(cpu->t)+1)%65536) -#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->s+signed8(cpu->t), x); -#define storestackrel161(x) writememory((cpu->s+signed8(cpu->t) )%65536, hibyte(x)); -#define storestackrel162(x) writememory((cpu->s+signed8(cpu->t)+1)%65536, 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++, hibyte((cpu->i-1)%65536)); -#define pushretaddr2 writememory(cpu->s++, 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<>(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++, 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; -#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(iirq && !cpu->ifg && cpu->cycle==0 && cpu->ien) { cpu->instr = 0xF2; } - if(cpu->rfg || cpu->ifg || cpu->irq) { - 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; -} diff --git a/emulator/8608emulator.dll b/emulator/8608emulator.dll deleted file mode 100644 index bc03b77..0000000 Binary files a/emulator/8608emulator.dll and /dev/null differ diff --git a/emulator/8608emulator.lua b/emulator/8608emulator.lua deleted file mode 100644 index 3ea4b96..0000000 --- a/emulator/8608emulator.lua +++ /dev/null @@ -1,678 +0,0 @@ ---love 1 - -require("colorset") -local ffi = require("ffi") -RelPath = "../" -AsmIncluded = true -local asm = dofile("../assembler-8608.lua") -local Arch = dofile("../rom-8608-defs.lua") - -local lg = love.graphics -local li = love.image -local le = love.event -local lt = love.timer -local lk = love.keyboard - ----- -local function InitColorset() - for i = 0, 63 do - local c = ColorSet[i+1] - ColorSet[i] = { - c[1]/255, - c[2]/255, - c[3]/255, - } - ColorSet[i+1] = nil - end -end - -local eventTypes = {} -local function registerEvent(mem, addrFirst, addrLast, read, write, func) - table.insert(eventTypes, func) - local id = #eventTypes - for addr = addrFirst, addrLast do - if read then mem.c.onread [addr] = id end - if write then mem.c.onwrite[addr] = id end - end -end -local function handleEvents(cpu, mem) - for i = 0, mem.c.numevents-1 do - local event = mem.c.events[i] - eventTypes[event.id](event.addr, cpu, mem) - end - mem.c.numevents = 0 -end - -local RegDisplay = { - scrX = 384+16, scrY = 32+8, - width = 128, height = 192, - fontWidth = 8, fontHeight = 12, - registers = { - { name = "A" , idx = "a" , x=8,y=8 ,w=2}, - { name = "B" , idx = "b" , x=8,y=8+16 ,w=2}, - { name = "C" , idx = "c" , x=8,y=8+16* 2,w=2}, - { name = "U" , idx = "u" , x=8,y=8+16* 3,w=2}, - { name = "T" , idx = "t" , x=8,y=8+16* 4,w=2}, - { name = "P" , idx = "p" , x=8,y=8+16* 5,w=4}, - { name = "Q" , idx = "q" , x=8,y=8+16* 6,w=4}, - { name = "S" , idx = "s" , x=8,y=8+16* 7,w=4}, - { name = "V" , idx = "v" , x=8,y=8+16* 8,w=4}, - { name = "I" , idx = "i" , x=8,y=8+16* 9,w=4}, - { name = "Ins", idx = "instr", x=8,y=8+16*10,w=2}, - { name = "Cyc", idx = "cycle", x=64+8-16,y=8+16*10,w=2}, - }, - flags = { - { name = "CF" , idx = "cf" , x=64+8,y=8 }, - { name = "NZ" , idx = "nz" , x=64+8,y=8+16 }, - { name = "IRq", idx = "irq", x=64+8,y=8+16*2}, - { name = "IEn", idx = "ien", x=64+8,y=8+16*5}, - { name = "Int", idx = "ifg", x=64+8,y=8+16*3}, - { name = "Run", idx = "rfg", x=64+8,y=8+16*4}, - }, -} -local function InitRegDisplay(rd) - lg.print("Registers", rd.scrX, rd.scrY-16) - lg.rectangle("line", rd.scrX, rd.scrY, rd.width, rd.height+1) - for i, reg in ipairs(rd.registers) do - lg.rectangle("line", rd.scrX+reg.x+(rd.fontWidth*(4-reg.w)), rd.scrY+reg.y, rd.fontWidth*reg.w+1, rd.fontHeight+1) - lg.print(reg.name, rd.scrX+reg.x+32+4, reg.y + rd.scrY) - end - for i, flg in pairs(rd.flags) do - lg.rectangle("line", rd.scrX+flg.x, rd.scrY+flg.y, rd.fontHeight+1, rd.fontHeight+1) - lg.print(flg.name, rd.scrX+flg.x+rd.fontHeight+4, flg.y+rd.scrY) - end -end -local function printValue(val, w, x, y, fw) - for i = 1, w do - local v = math.floor(val/math.pow(16,i-1))%16 - lg.print(string.format("%01X", v), x+(fw*(4-i)), y+1) - end -end -local function RedrawRegDisplay(rd, cpu, mem) - for i, reg in ipairs(rd.registers) do - lg.setColor(0,0,0) - lg.rectangle("fill", rd.scrX+reg.x+(rd.fontWidth*(4-reg.w)), rd.scrY+reg.y, rd.fontWidth*reg.w, rd.fontHeight) - lg.setColor(1,1,1) - local val = cpu.c[reg.idx]%(math.pow(16, reg.w)) - printValue(val, reg.w, rd.scrX+reg.x, rd.scrY+reg.y, rd.fontWidth) - end - for i, flg in pairs(rd.flags) do - local val = cpu.c[flg.idx] - if val~=0 then - lg.setColor(1,1,1) - else - lg.setColor(0,0,0) - end - lg.rectangle("fill", rd.scrX+flg.x, rd.scrY+flg.y, rd.fontHeight, rd.fontHeight) - end - lg.setColor(1,1,1) -end - -local ReadMemory -local WriteMemory -local StackDisplay = { - scrX = 8+384+32+6, scrY = 32+192+32-4, - lines = 16, fontHeight = 12, -} -local function InitStackDisplay(sd) - sd.width = 96+1 - sd.height = 12+(sd.lines*sd.fontHeight) - lg.print("Stack", sd.scrX, sd.scrY-16) - lg.rectangle("line", sd.scrX, sd.scrY, sd.width+1, sd.height+1) -end -local function RedrawStackDisplay(sd, cpu, mem) - lg.setColor(0,0,0) - lg.rectangle("fill", sd.scrX, sd.scrY, sd.width, sd.height) - lg.setColor(1,1,1) - for i = 1, sd.lines do - local addr = (cpu.c.s-i)%65536 - local val = ReadMemory(mem, addr) - lg.print(string.format("%04X -%2i %02X", addr, i, val), sd.scrX+8, sd.scrY+8+(12*(i-1))) - end -end - -local MemoryDisplays = { - { - scrX = 8, scrY = 32+192+32-4, - columns = 16, columnSpace = 4, rows = 16, - fontHeight = 12, - showAscii = false, - addr = 0x3000, - highlightTime = 8, - }, -} -local function InitMemoryDisplay(md) - local cw = 7 - md.mainCols = 9+md.columns*3+md.columnSpace-1 - md.width = cw*(md.mainCols)+cw*(md.showAscii and (md.columns+5) or 0)-8 - md.height = 12+md.fontHeight*md.rows - lg.print("Memory", md.scrX, md.scrY-16) - lg.rectangle("line", md.scrX, md.scrY, md.width+1, md.height+1) -end -local function RedrawMemoryDisplay(md, cpu, mem) - lg.setColor(0,0,0) - lg.rectangle("fill", md.scrX, md.scrY, md.width, md.height) - lg.setColor(1,1,1) - - local highlightAddrs = {} - highlightAddrs[cpu.c.p] = "P" - highlightAddrs[cpu.c.q] = "Q" - highlightAddrs[cpu.c.s] = "S" - highlightAddrs[cpu.c.v] = "V" - highlightAddrs[(cpu.c.i-1)%65536] = "I" - - local cw = 7 - - local tickDraw = cpu.c.frame-md.highlightTime - for l = 1, md.rows do - local addr = md.addr + (l-1)*md.columns - local lx = md.scrX+8 - local ly = md.scrY+8+(md.fontHeight*(l-1)) - lg.print(string.format("%04X", addr).." | ", lx, ly) - lx = lx+(cw*7) - for x = 1, md.columns do - local a = addr + (x-1) - local v = ReadMemory(mem, a) - if highlightAddrs[a] then - lg.line(lx, ly, lx, ly+11) - lg.line(lx-1, ly, lx+15, ly) - lg.line(lx-1, ly+11, lx+15, ly+11) - lg.print(highlightAddrs[a], lx-cw, ly) - end - if mem.c.writes[a] > tickDraw then - lg.rectangle("fill",lx-1,ly,cw*2+2,11) - lg.setColor(0,0,0) - end - lg.print(string.format("%02X", v), lx, ly) - lg.setColor(1,1,1) - if mem.c.reads[a] > tickDraw then - lg.rectangle("line", lx-1, ly, cw*2+2+1, 11+1) - end - lx = lx+(cw*3) - if x%md.columnSpace==0 then lx = lx+cw end - end - if md.showAscii then - lg.print("|", lx, ly) - lx = lx+cw - end - if md.showAscii then - for x = 1, md.columns do - local a = addr + (x-1) - local v = ReadMemory(mem, a) - if v>=128 then v = 0 end - local c = string.char(v) - lg.print(c, md.scrX+lx+((x-1)*cw), md.scrY+8+(12*(l-1))) - end - end - end -end - -local ProgramDisplay = { - scrX = 8+384+8+128+8, scrY = 32+8, - fontHeight = 12, - numLines = 34, - highlightTime = 8, -} -local function pdLinesFromDasm(dasm) - local lines, addrLines, lineAddrs = {}, {}, {} - for line in dasm:gmatch("[^\n]+") do - if line~="..." then - local addrh, datah, rest = line:match("^(.+) | (.+) | +(.+)$") - local text = rest - local label = nil - if rest:find(":") then label, text = rest:match("^(.+): (.+)$") end - local addr = tonumber(addrh, 16) - - if label then - --table.insert(lines, " | "..label..":") - table.insert(lines, " | "..label..":") - lineidx = #lines - end - --table.insert(lines, addrh.." | "..text) - table.insert(lines, addrh.." | "..datah.." | "..text) - - local lineidx = #lines - local len = 0; for _ in datah:gfind("[0-9a-fA-F][0-9a-fA-F]") do len = len+1 end; - for i = 1, len do addrLines[addr+i-1] = lineidx end - lineAddrs[lineidx] = addr - else - table.insert(lines, "") - end - end - return lines, addrLines, lineAddrs -end -local function InitProgramDisplay(pd, arch, data, code, symbols) - pd.width = 256 - pd.height = 12+pd.fontHeight*pd.numLines-3 - lg.print("Program", pd.scrX, pd.scrY-16) - lg.rectangle("line", pd.scrX, pd.scrY, pd.width, pd.height) - pd.firstLine = 1 - pd.data = data - pd.code = code - local dasm = asm.disassembleMemory(arch, data, code, symbols) - pd.lines, pd.addrLines, pd.lineAddrs = pdLinesFromDasm(dasm) - pd.midLine = math.floor(pd.numLines/2) -end -local function RedrawProgramDisplay(pd, cpu, mem) - lg.setColor(0,0,0) - lg.rectangle("fill", pd.scrX, pd.scrY, pd.width-1, pd.height-1) - lg.setColor(1,1,1) - - local rectwidth = pd.width-18 - local rectheight = pd.fontHeight-1 - local tickDraw = cpu.c.frame-pd.highlightTime - - local instrAddr = (cpu.c.i-1)%65536 - local instrLine = pd.addrLines[instrAddr] - if instrLine then - if pd.firstLine > instrLine then pd.firstLine = math.max(instrLine-pd.midLine, 1) - elseif pd.firstLine+pd.numLines-1 < instrLine then pd.firstLine = math.min(instrLine-pd.numLines+pd.midLine, #pd.lines-pd.numLines+1) - end - end - local screenlineidx = 0 - for lineidx = pd.firstLine, pd.firstLine+pd.numLines-1 do - local line = pd.lines[lineidx] - local lineaddr = pd.lineAddrs[lineidx] - if line then - local x, y = pd.scrX+8, pd.scrY+4+screenlineidx*pd.fontHeight - if lineaddr and mem.c.reads[lineaddr] > tickDraw then - lg.rectangle("line", x, y, rectwidth, rectheight) - end - if instrLine==lineidx then - lg.rectangle("fill", x, y, rectwidth, rectheight) - lg.setColor(0,0,0) - end - lg.print(line, x, y) - lg.setColor(1,1,1) - end - screenlineidx = screenlineidx + 1 - end -end - -local VideoDisplay = { - width = 256, height = 128, - scrX = 8, scrY = 256, - addr = 0x8000, -} -local function InitVideoDisplay(vd) - lg.print("Video Display", vd.scrX, vd.scrY-16) - vd.imageData = li.newImageData(vd.width, vd.height) - lg.setColor(1,1,1) - lg.rectangle("line", vd.scrX, vd.scrY, vd.width+1, vd.height+1) -end -local CharDisplay = { - width = 64*6, height = 16*12, - rows = 16, cols = 64, - fontWidth = 6, fontHeight = 12, - scrX = 8, scrY = 32+8, - addrChar = 0x0800, - addrColor = 0x0C00, -} -local function InitCharDisplay(cd) - lg.print("Char Display", cd.scrX, cd.scrY-16) - cd.font = lg.newFont("consola.ttf", cd.fontHeight-1, "mono") -end - -local Keyboard = { - addrRange = {0x0500, 0x05FF}, - queueSize = 16, - queue = {}, - interrupts = false, - queueEmpty = true, -} -local function kbSetNext(kb, cpu, mem) - local newval = kb.queue[1] or 0 - if mem.c.data[kb.addrRange[1]] ~= newval then - for a = kb.addrRange[1], kb.addrRange[2] do - mem.c.data[a] = newval - end - end -end -local function KeyboardOnRead(addr, cpu, mem, kb) - table.remove(kb.queue, 1) - kbSetNext(kb, cpu, mem) -end -local function KeyboardOnWrite(addr, cpu, mem, kb) - local val = mem.c.data[addr] - kb.interrupts = val~=0 - mem.c.data[addr] = kb.queue[1] or 0 -end -local keycodes = require("keycodes") -local CPURequestInterrupt -local function KeyboardOnKey(kb, key, press, cpu, mem) - local code = keycodes[key] or keycodes["invalid"] - if code==0x7F then print("invalid key: "..key) end - table.insert(kb.queue, code + (press and 128 or 0)) - if #kb.queue > kb.queueSize then table.remove(kb.queue, 1) end - kb.queueEmpty = false - kbSetNext(kb, cpu, mem) - if kb.interrupts then CPURequestInterrupt(cpu) end -end - -local function RedrawFPSCounter(x, y) - lg.setColor(0,0,0) - lg.rectangle("fill",x,y,64,12) - lg.setColor(1,1,1) - lg.print("FPS: "..lt.getFPS(), x,y) -end -local function printHighlight(s, o, h, x, y) - x = x+o*7 - local w = 7*#s - lg.setColor(1,1,1) - if h then - lg.rectangle("fill", x, y, w, 12) - lg.setColor(0,0,0) - end - lg.print(s, x, y) -end -local function RedrawKeyInfo(x, y, uk, run) - lg.setColor(0,0,0) - lg.rectangle("fill",x,y,768,12) - lg.setColor(1,1,1) - printHighlight("[F4] Toggle keyboard", 0, lk.isDown("f4"), x, y) - lg.setColor(1,1,1) - if uk then - printHighlight("Keystrokes passed to device", 23, false, x, y) - else - printHighlight("[R] "..(run and "Stop" or "Run "), 23, lk.isDown("r"), x, y) - printHighlight("[T] Tick once", 33, lk.isDown("t"), x, y) - printHighlight("[S] Step once", 48, lk.isDown("s"), x, y) - printHighlight("[Q] Quit", 63, lk.isDown("q"), x, y) - end -end - -local GPIO = {} -local function InitGPIO(gpio) - gpio.mulLeft = 0 - gpio.mulRight = 0 - gpio.divLeft = 0 - gpio.divRight = 0 - gpio.intQueued = false -end -local function UpdateGPIO(gpio, cpu, mem) - if gpio.intQueued then - gpio.intQueued = false - CPURequestInterrupt(cpu) - end -end -local function gpioSetValue(name, func) - return function(addr, cpu, mem, gpio) - gpio[name] = ReadMemory(mem, addr) - func(addr, cpu, mem, gpio) - end -end -local function gpioMul(addr, cpu, mem, gpio) - local base = math.floor(addr/256)*256 - local res = gpio.mulLeft*gpio.mulRight - WriteMemory(mem, base+0x00, math.floor(res/256)) - WriteMemory(mem, base+0x01, res%256) -end -local function gpioDiv(addr, cpu, mem, gpio) - local base = math.floor(addr/256)*256 - WriteMemory(mem, base+0x02, math.floor(gpio.divLeft/gpio.divRight)) - WriteMemory(mem, base+0x03, gpio.divLeft%gpio.divRight) -end -local gpioFunctions = { - [0x00] = gpioSetValue("mulLeft" , gpioMul), - [0x01] = gpioSetValue("mulRight", gpioMul), - [0x02] = gpioSetValue("divLeft" , gpioDiv), - [0x03] = gpioSetValue("divRight", gpioDiv), - [0x04] = function(addr, cpu, mem, gpio) WriteMemory(mem, addr, gpioPopcount(readMemory(mem, addr))) end, - [0x05] = function(addr, cpu, mem, gpio) gpio.intQueued = true; WriteMemory(mem, addr, 0); end -} -local function GPIOOnWrite(addr, cpu, mem, gpio) - local offset = addr%256 - local func = gpioFunctions[offset] - if func then - func(addr, cpu, mem, gpio) - end -end - -local peripherals = { - CharDisplay = { range = {0x0800, 0x0FFF}, write = true }, - BootROM = { range = {0x0000, 0x03FF}, write = false }, - SystemRAM = { range = {0x1000, 0x1FFF}, write = true }, - UserROM = { range = {0x2000, 0x2FFF}, write = false }, - UserRAM = { range = {0x3000, 0x3FFF}, write = true }, - VideoDisplay = { range = {0x8000, 0xFFFF}, write = true }, - Keyboard = { range = {0x0500, 0x05FF}, write = true, - onread = function(addr, cpu, mem) KeyboardOnRead (addr, cpu, mem, Keyboard) end, - onwrite = function(addr, cpu, mem) KeyboardOnWrite(addr, cpu, mem, Keyboard) end, - }, - GPIO = { range = {0x0400, 0x04FF}, write = true, - onwrite = function(addr, cpu, mem) GPIOOnWrite(addr, cpu, mem, GPIO) end, - }, -} - ----- -ffi.cdef [[ -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; -}; -]] -local Memory = { - c = ffi.new("struct Memory"), -} -local function InitMemory(mem, pers) - for i = 0, 65535 do - mem.c.data[i] = 0 - mem.c.canwrite[i] = 0 - mem.c.writes[i] = 0 - mem.c.reads[i] = 0 - mem.c.onread[i] = 0 - mem.c.onwrite[i] = 0 - end - for k, per in pairs(pers) do - if per.onread then registerEvent(mem, per.range[1], per.range[2], true , false, per.onread ) end - if per.onwrite then registerEvent(mem, per.range[1], per.range[2], false, true , per.onwrite) end - for a = per.range[1], per.range[2] do - mem.c.canwrite[a] = (per.write and 1 or 0) - end - end -end -ReadMemory = function(mem, addr) - return mem.c.data[addr%65536]%256 -end -WriteMemory = function(mem, addr, val) - if mem.c.canwrite[addr%65536]~=0 then - mem.c.data[addr%65536] = val%256 - end -end -local function AssembleToMemory(mem, fn, arch) - local data, code, symbols = asm.assembleFile(fn) - for addr = 0, 65535 do - if data[addr] then - mem.c.data[addr] = data[addr] - end - end - return data, code, symbols -end - -ffi.cdef [[ -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; -}; -int TickCPU(struct CPU* const cpu, struct Memory* const mem, const int count, const int countinstrs, const int breakaddr); -]] -local CPU = { - c = ffi.new("struct CPU"), -} -local cpuDll = ffi.load("8608emulator.dll") -local function TickCPU(cpu, mem, count, countinstrs, breakaddr) - local countleft = count - while countleft>0 do - countleft = cpuDll.TickCPU(cpu.c, mem.c, countleft, countinstrs and 1 or 0, breakaddr or 0xFFFFFFFF) - handleEvents(cpu, mem) - end -end -local function InitCPU(cpu) - cpu.c.rfg = 1; -end -CPURequestInterrupt = function(cpu) - cpu.c.irq = 1; -end - -function RunToNextInstr(cpu) - -end - ----- - -local function RedrawVideoDisplay(vd, mem) - local vd = VideoDisplay - for y = 0, vd.height-1 do - for x = 0, vd.width-1 do - local a = vd.addr + y*vd.width + x - local colorid = ReadMemory(mem, a)%64 - local color = ColorSet[colorid] - vd.imageData:setPixel(x, y, color[1], color[2], color[3]) - end - end - local img = lg.newImage(vd.imageData) - lg.setColor(1,1,1) - lg.draw(img, vd.scrX, vd.scrY) -end -local function RedrawCharDisplay(cd, mem) - lg.rectangle("line", cd.scrX, cd.scrY, cd.width+1, cd.height+1) - lg.setColor(0,0,0) - lg.rectangle("fill", cd.scrX, cd.scrY, cd.width, cd.height) - lg.setFont(cd.font) - local cd = CharDisplay - for cy = 0, cd.rows-1 do - for cx = 0, cd.cols-1 do - local abase = cy*cd.cols + cx - local achar = cd.addrChar + abase - local acolor = cd.addrColor + abase - local colormem = ReadMemory(mem, acolor) - local colorid = colormem%64 - local highlight = colormem>=128 - lg.setColor(ColorSet[colorid]) - if highlight then - lg.rectangle("fill", cd.scrX + cx*cd.fontWidth, cd.scrY + cy*cd.fontHeight, cd.fontWidth, cd.fontHeight) - lg.setColor(0, 0, 0) - end - local val = ReadMemory(mem, achar)%128 - if val>=32 then - local char = string.char(val) - lg.print(char, cd.scrX + cx*cd.fontWidth, cd.scrY + cy*cd.fontHeight) - elseif val>=16 and val<=31 then - local r, g, b = math.floor(val/4)%2, math.floor(val/2)%2, val%2 - lg.setColor(r, g, b) - lg.rectangle("fill", cd.scrX + cx*cd.fontWidth, cd.scrY + cy*cd.fontHeight, cd.fontWidth, cd.fontHeight) - end - end - end - lg.setColor(1,1,1) - lg.setFont(InfoFont) -end -local function InitWindowCanvas() - WindowCanvas = lg.newCanvas(WindowX, WindowY) - lg.setCanvas(WindowCanvas) - lg.setColor(1,1,1) - lg.setFont(InfoFont) - lg.print("8608 CPU Emulator", 4, 4) -end -local function RedrawWindow(usekeyboard, runcpu) - lg.setCanvas(WindowCanvas) - lg.setFont(InfoFont) - RedrawCharDisplay(CharDisplay, Memory) - --RedrawVideoDisplay(VideoDisplay, Memory) - RedrawRegDisplay(RegDisplay, CPU, Memory) - RedrawStackDisplay(StackDisplay, CPU, Memory) - RedrawProgramDisplay(ProgramDisplay, CPU, Memory) - for _, md in ipairs(MemoryDisplays) do RedrawMemoryDisplay(md, CPU, Memory) end - RedrawFPSCounter(128+32, 4) - RedrawKeyInfo(128+32+64+16, 4, usekeyboard, runcpu) - - lg.setCanvas() -end - -function love.load() - InitColorset() - lg.setDefaultFilter("nearest", "nearest") - lg.setLineWidth(1) - lg.setLineStyle("rough") - InfoFont = lg.newFont("consola.ttf", 12, "mono") - InitMemory(Memory, peripherals) - InitWindowCanvas() - InitCPU(CPU) - InitGPIO(GPIO) - --InitVideoDisplay(VideoDisplay) - InitCharDisplay(CharDisplay) - InitRegDisplay(RegDisplay) - InitStackDisplay(StackDisplay) - local data, code, symbols = AssembleToMemory(Memory, arg[2] or "../../8608programs/emutest.asm", Arch) - InitProgramDisplay(ProgramDisplay, Arch, data, code, symbols) - for _, md in ipairs(MemoryDisplays) do InitMemoryDisplay(md) end - RedrawWindow() - lg.setCanvas() -end - -local RunCPU = false -local CPUSpeed = 4999 -local UseKeyboard = false -function love.draw() - UpdateGPIO(GPIO, CPU, Memory) - - CPU.c.frame = CPU.c.frame + 1 - if RunCPU then - TickCPU(CPU, Memory, CPUSpeed, false, nil) - end - - RedrawWindow(UseKeyboard, RunCPU) - - lg.setColor(1,1,1) - lg.draw(WindowCanvas, 0, 0, 0, 2, 2) -end - -function love.keypressed(k) - if k=="f4" then - UseKeyboard = not UseKeyboard - else - if UseKeyboard then - KeyboardOnKey(Keyboard, k, true, CPU, Memory) - else - if k=="q" then le.quit() - elseif k=="s" then TickCPU(CPU, Memory, 1, true , nil) - elseif k=="t" then TickCPU(CPU, Memory, 1, false, nil) - elseif k=="o" then RunToNextInstr(cpu) - elseif k=="r" then RunCPU = not RunCPU - elseif k=="i" then CPU.c.irq = 1 - elseif k=="u" then CPU.c.rfg = 1 - end - end - end -end -function love.keyreleased(k) - if k~="f4" and UseKeyboard then KeyboardOnKey(Keyboard, k, false, CPU, Memory) end -end diff --git a/emulator/colorset.lua b/emulator/colorset.lua deleted file mode 100644 index d1e8b07..0000000 --- a/emulator/colorset.lua +++ /dev/null @@ -1,74 +0,0 @@ - -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}, -} diff --git a/emulator/conf.lua b/emulator/conf.lua deleted file mode 100644 index 62ce7cc..0000000 --- a/emulator/conf.lua +++ /dev/null @@ -1,10 +0,0 @@ - -WindowScale = 2 -WindowX = 800 -WindowY = 480 - -function love.conf(t) - t.console = true - t.window.width = WindowX*WindowScale - t.window.height = WindowY*WindowScale -end diff --git a/emulator/consola.ttf b/emulator/consola.ttf deleted file mode 100644 index e881ca4..0000000 Binary files a/emulator/consola.ttf and /dev/null differ diff --git a/emulator/gendefs.lua b/emulator/gendefs.lua deleted file mode 100644 index 1f6f3e2..0000000 --- a/emulator/gendefs.lua +++ /dev/null @@ -1,66 +0,0 @@ - -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 - -local arch = dofile("../rom-8608-defs.lua") -local fo = io.open("instructions_gen.c", "w") -fo:write(ccodeFromArch(arch)) -fo:close() diff --git a/emulator/instructions_gen.c b/emulator/instructions_gen.c deleted file mode 100644 index d474d06..0000000 --- a/emulator/instructions_gen.c +++ /dev/null @@ -1,787 +0,0 @@ -// Auto-generated by gendefs.lua - -void cpu_instr_0_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->irq=0; cpu->ifg=0; cpu->rfg=1; cpu->ien=0; lni; } -void cpu_instr_1_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_1_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_1_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadput; setzf(cpu->a); cpu->cycle++; } -void cpu_instr_1_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_6_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_6_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_6_2(struct CPU* const cpu, struct Memory* const mem) { storeut(hibyte(cpu->q)); cpu->cycle++; } -void cpu_instr_6_3(struct CPU* const cpu, struct Memory* const mem) { storeutp1(lobyte(cpu->q)); cpu->cycle++; } -void cpu_instr_6_4(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_8_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_8_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_8_2(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadqut; setzf(cpu->b); cpu->cycle++; } -void cpu_instr_8_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_9_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_9_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_9_2(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadqut; setzf(cpu->c); cpu->cycle++; } -void cpu_instr_9_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_10_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_10_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_10_2(struct CPU* const cpu, struct Memory* const mem) { storeput(cpu->a); cpu->cycle++; } -void cpu_instr_10_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_11_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_11_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_11_2(struct CPU* const cpu, struct Memory* const mem) { storeput(cpu->b); cpu->cycle++; } -void cpu_instr_11_3(struct CPU* const cpu, struct Memory* const mem) { 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) { storeput(cpu->c); cpu->cycle++; } -void cpu_instr_12_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_13_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_13_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_13_2(struct CPU* const cpu, struct Memory* const mem) { storequt(cpu->a); cpu->cycle++; } -void cpu_instr_13_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_14_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_14_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_14_2(struct CPU* const cpu, struct Memory* const mem) { storequt(cpu->b); cpu->cycle++; } -void cpu_instr_14_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_15_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_15_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_15_2(struct CPU* const cpu, struct Memory* const mem) { storequt(cpu->c); cpu->cycle++; } -void cpu_instr_15_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_16_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a, 1 ); lni; } -void cpu_instr_17_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-1 ); lni; } -void cpu_instr_18_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p++; lni; } -void cpu_instr_19_0(struct CPU* const cpu, struct Memory* const mem) { cpu->q++; lni; } -void cpu_instr_20_0(struct CPU* const cpu, struct Memory* const mem) { tst(cpu->a); lni; } -void cpu_instr_21_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p--; lni; } -void cpu_instr_22_0(struct CPU* const cpu, struct Memory* const mem) { cpu->q--; lni; } -void cpu_instr_23_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c, 1 ); lni; } -void cpu_instr_24_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c,-1 ); lni; } -void cpu_instr_25_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->b, 1 ); lni; } -void cpu_instr_26_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->b,-1 ); lni; } -void cpu_instr_27_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->cf); lni; } -void cpu_instr_28_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->b,cpu->cf); lni; } -void cpu_instr_29_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c,cpu->cf); lni; } -void cpu_instr_30_0(struct CPU* const cpu, struct Memory* const mem) { tst(cpu->b); lni; } -void cpu_instr_31_0(struct CPU* const cpu, struct Memory* const mem) { tst(cpu->c); lni; } -void cpu_instr_32_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadimmed; setzf(cpu->a); cpu->cycle++; } -void cpu_instr_32_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_33_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_33_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_33_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } -void cpu_instr_34_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_34_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_34_2(struct CPU* const cpu, struct Memory* const mem) { cpu->v=wordut; lni; } -void cpu_instr_35_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_35_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_35_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; } -void cpu_instr_36_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_36_1(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->t); lni; } -void cpu_instr_37_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_37_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_37_2(struct CPU* const cpu, struct Memory* const mem) { cpu->s=wordut; lni; } -void cpu_instr_38_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadimmed; setzf(cpu->b); cpu->cycle++; } -void cpu_instr_38_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_39_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadimmed; setzf(cpu->c); cpu->cycle++; } -void cpu_instr_39_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_40_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; } -void cpu_instr_40_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadstackrel; setzf(cpu->a); cpu->cycle++; } -void cpu_instr_40_2(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->b=loadstackrel; setzf(cpu->b); cpu->cycle++; } -void cpu_instr_41_2(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_42_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; } -void cpu_instr_42_1(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadstackrel; setzf(cpu->c); cpu->cycle++; } -void cpu_instr_42_2(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_43_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_43_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_43_2(struct CPU* const cpu, struct Memory* const mem) { instrpreload; addf(cpu->u, 1 ); cpu->cycle++; } -void cpu_instr_43_3(struct CPU* const cpu, struct Memory* const mem) { instrloadpre } -void cpu_instr_44_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_44_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_44_2(struct CPU* const cpu, struct Memory* const mem) { instrpreload; addf(cpu->u,-1 ); cpu->cycle++; } -void cpu_instr_44_3(struct CPU* const cpu, struct Memory* const mem) { instrloadpre } -void cpu_instr_45_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_45_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_45_2(struct CPU* const cpu, struct Memory* const mem) { instrpreload; addf(cpu->u,cpu->cf); cpu->cycle++; } -void cpu_instr_45_3(struct CPU* const cpu, struct Memory* const mem) { instrloadpre } -void cpu_instr_46_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_46_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_46_2(struct CPU* const cpu, struct Memory* const mem) { tst(cpu->u); lni; } -void cpu_instr_47_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=sra(cpu->a,cpu->c); setzf(cpu->a); lni; } -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 ) { jmprelt } else { lni } } -void cpu_instr_49_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_49_1(struct CPU* const cpu, struct Memory* const mem) { jmprelt } -void cpu_instr_50_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_50_1(struct CPU* const cpu, struct Memory* const mem) { if(!cpu->nz ) { jmprelt } else { lni } } -void cpu_instr_51_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_51_1(struct CPU* const cpu, struct Memory* const mem) { if(!cpu->cf ) { jmprelt } else { lni } } -void cpu_instr_52_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_52_1(struct CPU* const cpu, struct Memory* const mem) { if( cpu->cf ) { jmprelt } else { 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) { if( cpu->nz && cpu->cf ) { jmprelt } else { lni } } -void cpu_instr_54_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_54_1(struct CPU* const cpu, struct Memory* const mem) { if((!cpu->nz) || (!cpu->cf)) { jmprelt } else { lni } } -void cpu_instr_55_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=lobyte(cpu->p); lni; } -void cpu_instr_56_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=hibyte(cpu->p); lni; } -void cpu_instr_57_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=lobyte(cpu->q); lni; } -void cpu_instr_58_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=hibyte(cpu->q); lni; } -void cpu_instr_59_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; } -void cpu_instr_59_1(struct CPU* const cpu, struct Memory* const mem) { pushbyte(cpu->t); cpu->cycle++; } -void cpu_instr_59_2(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_60_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_60_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_60_2(struct CPU* const cpu, struct Memory* const mem) { pushbyte(cpu->u); cpu->cycle++; } -void cpu_instr_60_3(struct CPU* const cpu, struct Memory* const mem) { pushbyte(cpu->t); cpu->cycle++; } -void cpu_instr_60_4(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_62_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=rol(cpu->a,cpu->c); setzf(cpu->a); lni; } -void cpu_instr_63_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=ror(cpu->a,cpu->c); setzf(cpu->a); lni; } -void cpu_instr_64_0(struct CPU* const cpu, struct Memory* const mem) { pushbyte(cpu->a); cpu->cycle++; } -void cpu_instr_64_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_65_0(struct CPU* const cpu, struct Memory* const mem) { push161(cpu->p); cpu->cycle++; } -void cpu_instr_65_1(struct CPU* const cpu, struct Memory* const mem) { push162(cpu->p); cpu->cycle++; } -void cpu_instr_65_2(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_66_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=popbyte; cpu->cycle++; } -void cpu_instr_66_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_67_0(struct CPU* const cpu, struct Memory* const mem) { pop161 cpu->cycle++; } -void cpu_instr_67_1(struct CPU* const cpu, struct Memory* const mem) { pop162 cpu->cycle++; } -void cpu_instr_67_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } -void cpu_instr_68_0(struct CPU* const cpu, struct Memory* const mem) { pushbyte(cpu->b); cpu->cycle++; } -void cpu_instr_68_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_69_0(struct CPU* const cpu, struct Memory* const mem) { pushbyte(cpu->c); cpu->cycle++; } -void cpu_instr_69_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_70_0(struct CPU* const cpu, struct Memory* const mem) { push161(cpu->q); cpu->cycle++; } -void cpu_instr_70_1(struct CPU* const cpu, struct Memory* const mem) { push162(cpu->q); cpu->cycle++; } -void cpu_instr_70_2(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_71_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=popbyte; cpu->cycle++; } -void cpu_instr_71_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_72_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=popbyte; 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) { pop161 cpu->cycle++; } -void cpu_instr_73_1(struct CPU* const cpu, struct Memory* const mem) { pop162 cpu->cycle++; } -void cpu_instr_73_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; } -void cpu_instr_74_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_74_1(struct CPU* const cpu, struct Memory* const mem) { cpu->p+=signed8(cpu->t); lni; } -void cpu_instr_75_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_75_1(struct CPU* const cpu, struct Memory* const mem) { cpu->q+=signed8(cpu->t); lni; } -void cpu_instr_76_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_76_1(struct CPU* const cpu, struct Memory* const mem) { cpu->s+=signed8(cpu->t); lni; } -void cpu_instr_77_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a>>=cpu->c; setzf(cpu->a); lni; } -void cpu_instr_78_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c,cpu->a); lni; } -void cpu_instr_79_0(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->c,cpu->a); lni; } -void cpu_instr_80_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_80_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_80_2(struct CPU* const cpu, struct Memory* const mem) { storeut(cpu->a); cpu->cycle++; } -void cpu_instr_80_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_81_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_81_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_81_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadut; setzf(cpu->a); cpu->cycle++; } -void cpu_instr_81_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_82_0(struct CPU* const cpu, struct Memory* const mem) { storep(cpu->a); cpu->cycle++; } -void cpu_instr_82_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_83_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadp; setzf(cpu->a); 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) { storeq(cpu->a); cpu->cycle++; } -void cpu_instr_84_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_85_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadq; setzf(cpu->a); cpu->cycle++; } -void cpu_instr_85_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_86_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_86_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_86_2(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadut; setzf(cpu->b); cpu->cycle++; } -void cpu_instr_86_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_87_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_87_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_87_2(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadut; setzf(cpu->c); cpu->cycle++; } -void cpu_instr_87_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_88_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_88_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_88_2(struct CPU* const cpu, struct Memory* const mem) { storeut(cpu->b); cpu->cycle++; } -void cpu_instr_88_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_89_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_89_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_89_2(struct CPU* const cpu, struct Memory* const mem) { storeut(cpu->c); cpu->cycle++; } -void cpu_instr_89_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_90_0(struct CPU* const cpu, struct Memory* const mem) { storep(cpu->b); cpu->cycle++; } -void cpu_instr_90_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_91_0(struct CPU* const cpu, struct Memory* const mem) { storep(cpu->c); cpu->cycle++; } -void cpu_instr_91_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_92_0(struct CPU* const cpu, struct Memory* const mem) { storeq(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) { storeq(cpu->c); cpu->cycle++; } -void cpu_instr_93_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_94_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadp; setzf(cpu->b); cpu->cycle++; } -void cpu_instr_94_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_95_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadp; setzf(cpu->c); cpu->cycle++; } -void cpu_instr_95_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_96_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_96_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_96_2(struct CPU* const cpu, struct Memory* const mem) { jmpabsut } -void cpu_instr_97_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadq; setzf(cpu->b); cpu->cycle++; } -void cpu_instr_97_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_98_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadq; setzf(cpu->c); cpu->cycle++; } -void cpu_instr_98_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_99_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_99_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_99_2(struct CPU* const cpu, struct Memory* const mem) { jmpabsut saveretaddr } -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) { jmpabsp } -void cpu_instr_101_1(struct CPU* const cpu, struct Memory* const mem) { saveretaddr cpu->cycle++; } -void cpu_instr_102_0(struct CPU* const cpu, struct Memory* const mem) { jmpabsq } -void cpu_instr_103_0(struct CPU* const cpu, struct Memory* const mem) { jmpabsq } -void cpu_instr_103_1(struct CPU* const cpu, struct Memory* const mem) { saveretaddr cpu->cycle++; } -void cpu_instr_104_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_104_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_104_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; cpu->u=loadut; cpu->cycle++; } -void cpu_instr_104_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; } -void cpu_instr_104_4(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } -void cpu_instr_106_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_106_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_106_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; cpu->u=loadut; cpu->cycle++; } -void cpu_instr_106_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; } -void cpu_instr_106_4(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; 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) { storeut(hibyte(cpu->p)); cpu->cycle++; } -void cpu_instr_108_3(struct CPU* const cpu, struct Memory* const mem) { storeutp1(lobyte(cpu->p)); cpu->cycle++; } -void cpu_instr_108_4(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_110_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_110_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_110_2(struct CPU* const cpu, struct Memory* const mem) { storeut(hibyte(cpu->q)); cpu->cycle++; } -void cpu_instr_110_3(struct CPU* const cpu, struct Memory* const mem) { storeutp1(lobyte(cpu->q)); cpu->cycle++; } -void cpu_instr_110_4(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_112_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_112_1(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->a,cpu->t); lni; } -void cpu_instr_113_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_113_1(struct CPU* const cpu, struct Memory* const mem) { cmpf(cpu->a,cpu->t); lni; } -void cpu_instr_114_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_114_1(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->b,cpu->t); lni; } -void cpu_instr_115_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_115_1(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c,cpu->t); lni; } -void cpu_instr_116_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_116_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=cpu->t; setzf(cpu->a); 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|=cpu->t; setzf(cpu->a); lni; } -void cpu_instr_118_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_118_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a^=cpu->t; setzf(cpu->a); lni; } -void cpu_instr_119_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_119_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=~cpu->t; setzf(cpu->a); lni; } -void cpu_instr_120_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_120_1(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->t+cpu->cf); lni; } -void cpu_instr_121_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_121_1(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-cpu->t+cpu->cf); lni; } -void cpu_instr_122_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_122_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrel161 cpu->cycle++; } -void cpu_instr_122_2(struct CPU* const cpu, struct Memory* const mem) { loadstackrel162 cpu->cycle++; } -void cpu_instr_122_3(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } -void cpu_instr_123_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_123_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrel161 cpu->cycle++; } -void cpu_instr_123_2(struct CPU* const cpu, struct Memory* const mem) { loadstackrel162 cpu->cycle++; } -void cpu_instr_123_3(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } -void cpu_instr_124_0(struct CPU* const cpu, struct Memory* const mem) { storeq(hibyte(cpu->p)); cpu->cycle++; } -void cpu_instr_124_1(struct CPU* const cpu, struct Memory* const mem) { storeqp1(lobyte(cpu->p)); cpu->cycle++; } -void cpu_instr_124_2(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_125_0(struct CPU* const cpu, struct Memory* const mem) { storep(hibyte(cpu->q)); cpu->cycle++; } -void cpu_instr_125_1(struct CPU* const cpu, struct Memory* const mem) { storepp1(lobyte(cpu->q)); cpu->cycle++; } -void cpu_instr_125_2(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_126_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_126_1(struct CPU* const cpu, struct Memory* const mem) { storestackrel161(cpu->p); cpu->cycle++; } -void cpu_instr_126_2(struct CPU* const cpu, struct Memory* const mem) { storestackrel162(cpu->p); cpu->cycle++; } -void cpu_instr_126_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_127_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_127_1(struct CPU* const cpu, struct Memory* const mem) { storestackrel161(cpu->q); cpu->cycle++; } -void cpu_instr_127_2(struct CPU* const cpu, struct Memory* const mem) { storestackrel162(cpu->q); cpu->cycle++; } -void cpu_instr_127_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_128_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=cpu->b; lni; } -void cpu_instr_129_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=cpu->c; lni; } -void cpu_instr_130_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=cpu->a; lni; } -void cpu_instr_131_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=cpu->c; lni; } -void cpu_instr_132_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=cpu->a; lni; } -void cpu_instr_133_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=cpu->b; lni; } -void cpu_instr_134_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=lobyte(cpu->p); lni; } -void cpu_instr_135_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=hibyte(cpu->p); lni; } -void cpu_instr_136_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=lobyte(cpu->q); lni; } -void cpu_instr_137_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=hibyte(cpu->q); lni; } -void cpu_instr_138_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p=cpu->q; lni; } -void cpu_instr_139_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p=cpu->s; lni; } -void cpu_instr_140_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p=cpu->v; lni; } -void cpu_instr_141_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p=cpu->i; lni; } -void cpu_instr_142_0(struct CPU* const cpu, struct Memory* const mem) { cpu->q=cpu->p; lni; } -void cpu_instr_143_0(struct CPU* const cpu, struct Memory* const mem) { cpu->s=cpu->p; lni; } -void cpu_instr_144_0(struct CPU* const cpu, struct Memory* const mem) { cpu->v=cpu->p; lni; } -void cpu_instr_145_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordcb; lni; } -void cpu_instr_146_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadp; cpu->cycle++; } -void cpu_instr_146_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; } -void cpu_instr_146_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } -void cpu_instr_147_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadp; cpu->cycle++; } -void cpu_instr_147_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; } -void cpu_instr_147_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; } -void cpu_instr_148_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadq; cpu->cycle++; } -void cpu_instr_148_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; } -void cpu_instr_148_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } -void cpu_instr_149_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadq; cpu->cycle++; } -void cpu_instr_149_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; } -void cpu_instr_149_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; } -void cpu_instr_150_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; } -void cpu_instr_150_1(struct CPU* const cpu, struct Memory* const mem) { storestackrel(cpu->a); cpu->cycle++; } -void cpu_instr_150_2(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_151_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt; cpu->cycle++; } -void cpu_instr_151_1(struct CPU* const cpu, struct Memory* const mem) { storestackrel(cpu->a); cpu->cycle++; } -void cpu_instr_151_2(struct CPU* const cpu, struct Memory* const mem) { 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) { storestackrel(cpu->a); cpu->cycle++; } -void cpu_instr_152_2(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_153_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_153_1(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->b,cpu->t); lni; } -void cpu_instr_154_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_154_1(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->c,cpu->t); lni; } -void cpu_instr_155_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_155_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_155_2(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->b,cpu->u); lni; } -void cpu_instr_156_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_156_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_156_2(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c,cpu->u); lni; } -void cpu_instr_157_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_157_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_157_2(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->b,cpu->u); lni; } -void cpu_instr_158_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_158_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_158_2(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->c,cpu->u); lni; } -void cpu_instr_159_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->c,cpu->b); lni; } -void cpu_instr_160_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->b); lni; } -void cpu_instr_161_0(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->a,cpu->b); lni; } -void cpu_instr_162_0(struct CPU* const cpu, struct Memory* const mem) { cmpf(cpu->a,cpu->b); lni; } -void cpu_instr_163_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=cpu->b; setzf(cpu->a); lni; } -void cpu_instr_164_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a|=cpu->b; setzf(cpu->a); lni; } -void cpu_instr_165_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a^=cpu->b; setzf(cpu->a); lni; } -void cpu_instr_166_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=~cpu->b; setzf(cpu->a); lni; } -void cpu_instr_167_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->c); lni; } -void cpu_instr_168_0(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->a,cpu->c); lni; } -void cpu_instr_169_0(struct CPU* const cpu, struct Memory* const mem) { cmpf(cpu->a,cpu->c); lni; } -void cpu_instr_170_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=cpu->c; setzf(cpu->a); lni; } -void cpu_instr_171_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a|=cpu->c; setzf(cpu->a); lni; } -void cpu_instr_172_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a^=cpu->c; setzf(cpu->a); lni; } -void cpu_instr_173_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=~cpu->c; setzf(cpu->a); lni; } -void cpu_instr_174_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_174_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_174_2(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->u); lni; } -void cpu_instr_175_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_175_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_175_2(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->a,cpu->u); 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) { loadstackrelu cpu->cycle++; } -void cpu_instr_176_2(struct CPU* const cpu, struct Memory* const mem) { cmpf(cpu->a,cpu->u); lni; } -void cpu_instr_177_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_177_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_177_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=cpu->u; setzf(cpu->a); lni; } -void cpu_instr_178_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_178_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_178_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a|=cpu->u; setzf(cpu->a); lni; } -void cpu_instr_179_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_179_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_179_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a^=cpu->u; setzf(cpu->a); lni; } -void cpu_instr_180_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_180_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_180_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a&=~cpu->u; setzf(cpu->a); lni; } -void cpu_instr_181_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_181_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_181_2(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->u+cpu->cf); lni; } -void cpu_instr_182_0(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->c,cpu->b); lni; } -void cpu_instr_183_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_183_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_183_2(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-cpu->u+cpu->cf); lni; } -void cpu_instr_184_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->b+cpu->cf); lni; } -void cpu_instr_185_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-cpu->b+cpu->cf); lni; } -void cpu_instr_186_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,cpu->c+cpu->cf); lni; } -void cpu_instr_187_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->a,-cpu->c+cpu->cf); lni; } -void cpu_instr_188_0(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->b,cpu->c); lni; } -void cpu_instr_189_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->b,cpu->c); lni; } -void cpu_instr_190_0(struct CPU* const cpu, struct Memory* const mem) { addf(cpu->b,cpu->a); lni; } -void cpu_instr_191_0(struct CPU* const cpu, struct Memory* const mem) { subf(cpu->b,cpu->a); lni; } -void cpu_instr_192_0(struct CPU* const cpu, struct Memory* const mem) { storepinc(cpu->a); cpu->cycle++; } -void cpu_instr_192_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_193_0(struct CPU* const cpu, struct Memory* const mem) { storepinc(cpu->b); cpu->cycle++; } -void cpu_instr_193_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_194_0(struct CPU* const cpu, struct Memory* const mem) { storepinc(cpu->c); cpu->cycle++; } -void cpu_instr_194_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_195_0(struct CPU* const cpu, struct Memory* const mem) { storeqinc(cpu->a); cpu->cycle++; } -void cpu_instr_195_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_196_0(struct CPU* const cpu, struct Memory* const mem) { storeqinc(cpu->b); cpu->cycle++; } -void cpu_instr_196_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_197_0(struct CPU* const cpu, struct Memory* const mem) { storeqinc(cpu->c); cpu->cycle++; } -void cpu_instr_197_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_198_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadpinc; setzf(cpu->a); cpu->cycle++; } -void cpu_instr_198_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_199_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadpinc; setzf(cpu->b); cpu->cycle++; } -void cpu_instr_199_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_200_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadpinc; setzf(cpu->c); cpu->cycle++; } -void cpu_instr_200_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_201_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadqinc; setzf(cpu->a); cpu->cycle++; } -void cpu_instr_201_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_202_0(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadqinc; setzf(cpu->b); cpu->cycle++; } -void cpu_instr_202_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_203_0(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadqinc; setzf(cpu->c); cpu->cycle++; } -void cpu_instr_203_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_204_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadpinc; cpu->cycle++; } -void cpu_instr_204_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpinc; cpu->cycle++; } -void cpu_instr_204_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; } -void cpu_instr_205_0(struct CPU* const cpu, struct Memory* const mem) { cpu->u=loadqinc; cpu->cycle++; } -void cpu_instr_205_1(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqinc; cpu->cycle++; } -void cpu_instr_205_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } -void cpu_instr_206_0(struct CPU* const cpu, struct Memory* const mem) { storeqinc(hibyte(cpu->p)); cpu->cycle++; } -void cpu_instr_206_1(struct CPU* const cpu, struct Memory* const mem) { storeqinc(lobyte(cpu->p)); cpu->cycle++; } -void cpu_instr_206_2(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_207_0(struct CPU* const cpu, struct Memory* const mem) { storepinc(hibyte(cpu->q)); cpu->cycle++; } -void cpu_instr_207_1(struct CPU* const cpu, struct Memory* const mem) { storepinc(lobyte(cpu->q)); cpu->cycle++; } -void cpu_instr_207_2(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) { cpu->a<<=cpu->t; setzf(cpu->a); lni; } -void cpu_instr_209_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_209_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a>>=cpu->t; setzf(cpu->a); lni; } -void cpu_instr_210_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_210_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a=rol(cpu->a,cpu->t); setzf(cpu->a); lni; } -void cpu_instr_211_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_211_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a=ror(cpu->a,cpu->t); setzf(cpu->a); lni; } -void cpu_instr_212_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_212_1(struct CPU* const cpu, struct Memory* const mem) { cpu->a=sra(cpu->a,cpu->t); setzf(cpu->a); lni; } -void cpu_instr_213_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_213_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_213_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a<<=cpu->u; setzf(cpu->a); lni; } -void cpu_instr_214_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_214_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_214_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a>>=cpu->u; setzf(cpu->a); lni; } -void cpu_instr_215_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_215_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_215_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=rol(cpu->a,cpu->u); setzf(cpu->a); lni; } -void cpu_instr_216_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_216_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_216_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=ror(cpu->a,cpu->u); setzf(cpu->a); lni; } -void cpu_instr_217_0(struct CPU* const cpu, struct Memory* const mem) { loadimmedt cpu->cycle++; } -void cpu_instr_217_1(struct CPU* const cpu, struct Memory* const mem) { loadstackrelu cpu->cycle++; } -void cpu_instr_217_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=sra(cpu->a,cpu->u); setzf(cpu->a); lni; } -void cpu_instr_218_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a<<=cpu->b; setzf(cpu->a); lni; } -void cpu_instr_219_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a>>=cpu->b; setzf(cpu->a); lni; } -void cpu_instr_220_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=rol(cpu->a,cpu->b); setzf(cpu->a); lni; } -void cpu_instr_221_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=ror(cpu->a,cpu->b); setzf(cpu->a); lni; } -void cpu_instr_222_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a=sra(cpu->a,cpu->b); setzf(cpu->a); lni; } -void cpu_instr_223_0(struct CPU* const cpu, struct Memory* const mem) { cpu->a<<=cpu->c; setzf(cpu->a); lni; } -void cpu_instr_224_0(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordcb; lni; } -void cpu_instr_225_0(struct CPU* const cpu, struct Memory* const mem) { pop161 cpu->cycle++; } -void cpu_instr_225_1(struct CPU* const cpu, struct Memory* const mem) { pop162 cpu->cycle++; } -void cpu_instr_225_2(struct CPU* const cpu, struct Memory* const mem) { jmpabsutplus1 } -void cpu_instr_226_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_226_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_226_2(struct CPU* const cpu, struct Memory* const mem) { pushretaddr1 cpu->cycle++; } -void cpu_instr_226_3(struct CPU* const cpu, struct Memory* const mem) { pushretaddr2 cpu->cycle++; } -void cpu_instr_226_4(struct CPU* const cpu, struct Memory* const mem) { jmpabsut } -void cpu_instr_228_0(struct CPU* const cpu, struct Memory* const mem) { pushretaddr1 cpu->cycle++; } -void cpu_instr_228_1(struct CPU* const cpu, struct Memory* const mem) { pushretaddr2 cpu->cycle++; } -void cpu_instr_228_2(struct CPU* const cpu, struct Memory* const mem) { jmpabsp } -void cpu_instr_229_0(struct CPU* const cpu, struct Memory* const mem) { pushretaddr1 cpu->cycle++; } -void cpu_instr_229_1(struct CPU* const cpu, struct Memory* const mem) { pushretaddr2 cpu->cycle++; } -void cpu_instr_229_2(struct CPU* const cpu, struct Memory* const mem) { jmpabsq } -void cpu_instr_230_0(struct CPU* const cpu, struct Memory* const mem) { cpu->p+=signed8(cpu->b); lni; } -void cpu_instr_231_0(struct CPU* const cpu, struct Memory* const mem) { cpu->q+=signed8(cpu->b); lni; } -void cpu_instr_232_0(struct CPU* const cpu, struct Memory* const mem) { cpu->s+=signed8(cpu->b); lni; } -void cpu_instr_233_0(struct CPU* const cpu, struct Memory* const mem) { int f = cpu->nz | (cpu->cf<<1); pushbyte(f); cpu->cycle++; } -void cpu_instr_233_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_234_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_234_1(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_235_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_235_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_235_2(struct CPU* const cpu, struct Memory* const mem) { cpu->a=loadqut; setzf(cpu->a); cpu->cycle++; } -void cpu_instr_235_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_236_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_236_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_236_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; cpu->u=loadut; cpu->cycle++; } -void cpu_instr_236_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; } -void cpu_instr_236_4(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } -void cpu_instr_238_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_238_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_238_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; cpu->u=loadut; cpu->cycle++; } -void cpu_instr_238_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; } -void cpu_instr_238_4(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; } -void cpu_instr_240_0(struct CPU* const cpu, struct Memory* const mem) { cpu->rfg=0; lni; } -void cpu_instr_241_0(struct CPU* const cpu, struct Memory* const mem) { cpu->rfg=1; lni; } -void cpu_instr_242_0(struct CPU* const cpu, struct Memory* const mem) { cpu->irq=0; cpu->ifg=1; int t=cpu->i; cpu->i=cpu->v; cpu->v=(t-1)%65536; lni; } -void cpu_instr_243_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ifg=1; int t=cpu->i; cpu->i=cpu->v; cpu->v=t; lni; } -void cpu_instr_244_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_245_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ien=1; lni; } -void cpu_instr_246_0(struct CPU* const cpu, struct Memory* const mem) { cpu->ien=0; lni; } -void cpu_instr_247_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_247_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_247_2(struct CPU* const cpu, struct Memory* const mem) { cpu->b=loadput; setzf(cpu->b); cpu->cycle++; } -void cpu_instr_247_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_248_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_248_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_248_2(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; cpu->u=loadut; cpu->cycle++; } -void cpu_instr_248_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadpp1; cpu->cycle++; } -void cpu_instr_248_4(struct CPU* const cpu, struct Memory* const mem) { cpu->p=wordut; lni; } -void cpu_instr_250_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_250_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_250_2(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; cpu->u=loadut; cpu->cycle++; } -void cpu_instr_250_3(struct CPU* const cpu, struct Memory* const mem) { cpu->t=loadqp1; cpu->cycle++; } -void cpu_instr_250_4(struct CPU* const cpu, struct Memory* const mem) { cpu->q=wordut; lni; } -void cpu_instr_252_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_252_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_252_2(struct CPU* const cpu, struct Memory* const mem) { storeut(hibyte(cpu->p)); cpu->cycle++; } -void cpu_instr_252_3(struct CPU* const cpu, struct Memory* const mem) { storeutp1(lobyte(cpu->p)); cpu->cycle++; } -void cpu_instr_252_4(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_254_0(struct CPU* const cpu, struct Memory* const mem) { loadimm161 cpu->cycle++; } -void cpu_instr_254_1(struct CPU* const cpu, struct Memory* const mem) { loadimm162 cpu->cycle++; } -void cpu_instr_254_2(struct CPU* const cpu, struct Memory* const mem) { cpu->c=loadput; setzf(cpu->c); cpu->cycle++; } -void cpu_instr_254_3(struct CPU* const cpu, struct Memory* const mem) { lni; } -void cpu_instr_255_0(struct CPU* const cpu, struct Memory* const mem) { lni; } - -CPUInstruction CPUInstructions[256][8] = { - {cpu_instr_0_0,0,0,0,0,0,0,0}, - {cpu_instr_1_0,cpu_instr_1_1,cpu_instr_1_2,cpu_instr_1_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}, - {0,0,0,0,0,0,0,0}, - {cpu_instr_6_0,cpu_instr_6_1,cpu_instr_6_2,cpu_instr_6_3,cpu_instr_6_4,0,0,0}, - {0,0,0,0,0,0,0,0}, - {cpu_instr_8_0,cpu_instr_8_1,cpu_instr_8_2,cpu_instr_8_3,0,0,0,0}, - {cpu_instr_9_0,cpu_instr_9_1,cpu_instr_9_2,cpu_instr_9_3,0,0,0,0}, - {cpu_instr_10_0,cpu_instr_10_1,cpu_instr_10_2,cpu_instr_10_3,0,0,0,0}, - {cpu_instr_11_0,cpu_instr_11_1,cpu_instr_11_2,cpu_instr_11_3,0,0,0,0}, - {cpu_instr_12_0,cpu_instr_12_1,cpu_instr_12_2,cpu_instr_12_3,0,0,0,0}, - {cpu_instr_13_0,cpu_instr_13_1,cpu_instr_13_2,cpu_instr_13_3,0,0,0,0}, - {cpu_instr_14_0,cpu_instr_14_1,cpu_instr_14_2,cpu_instr_14_3,0,0,0,0}, - {cpu_instr_15_0,cpu_instr_15_1,cpu_instr_15_2,cpu_instr_15_3,0,0,0,0}, - {cpu_instr_16_0,0,0,0,0,0,0,0}, - {cpu_instr_17_0,0,0,0,0,0,0,0}, - {cpu_instr_18_0,0,0,0,0,0,0,0}, - {cpu_instr_19_0,0,0,0,0,0,0,0}, - {cpu_instr_20_0,0,0,0,0,0,0,0}, - {cpu_instr_21_0,0,0,0,0,0,0,0}, - {cpu_instr_22_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}, - {cpu_instr_26_0,0,0,0,0,0,0,0}, - {cpu_instr_27_0,0,0,0,0,0,0,0}, - {cpu_instr_28_0,0,0,0,0,0,0,0}, - {cpu_instr_29_0,0,0,0,0,0,0,0}, - {cpu_instr_30_0,0,0,0,0,0,0,0}, - {cpu_instr_31_0,0,0,0,0,0,0,0}, - {cpu_instr_32_0,cpu_instr_32_1,0,0,0,0,0,0}, - {cpu_instr_33_0,cpu_instr_33_1,cpu_instr_33_2,0,0,0,0,0}, - {cpu_instr_34_0,cpu_instr_34_1,cpu_instr_34_2,0,0,0,0,0}, - {cpu_instr_35_0,cpu_instr_35_1,cpu_instr_35_2,0,0,0,0,0}, - {cpu_instr_36_0,cpu_instr_36_1,0,0,0,0,0,0}, - {cpu_instr_37_0,cpu_instr_37_1,cpu_instr_37_2,0,0,0,0,0}, - {cpu_instr_38_0,cpu_instr_38_1,0,0,0,0,0,0}, - {cpu_instr_39_0,cpu_instr_39_1,0,0,0,0,0,0}, - {cpu_instr_40_0,cpu_instr_40_1,cpu_instr_40_2,0,0,0,0,0}, - {cpu_instr_41_0,cpu_instr_41_1,cpu_instr_41_2,0,0,0,0,0}, - {cpu_instr_42_0,cpu_instr_42_1,cpu_instr_42_2,0,0,0,0,0}, - {cpu_instr_43_0,cpu_instr_43_1,cpu_instr_43_2,cpu_instr_43_3,0,0,0,0}, - {cpu_instr_44_0,cpu_instr_44_1,cpu_instr_44_2,cpu_instr_44_3,0,0,0,0}, - {cpu_instr_45_0,cpu_instr_45_1,cpu_instr_45_2,cpu_instr_45_3,0,0,0,0}, - {cpu_instr_46_0,cpu_instr_46_1,cpu_instr_46_2,0,0,0,0,0}, - {cpu_instr_47_0,0,0,0,0,0,0,0}, - {cpu_instr_48_0,cpu_instr_48_1,0,0,0,0,0,0}, - {cpu_instr_49_0,cpu_instr_49_1,0,0,0,0,0,0}, - {cpu_instr_50_0,cpu_instr_50_1,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,0,0,0,0,0,0}, - {cpu_instr_53_0,cpu_instr_53_1,0,0,0,0,0,0}, - {cpu_instr_54_0,cpu_instr_54_1,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}, - {cpu_instr_58_0,0,0,0,0,0,0,0}, - {cpu_instr_59_0,cpu_instr_59_1,cpu_instr_59_2,0,0,0,0,0}, - {cpu_instr_60_0,cpu_instr_60_1,cpu_instr_60_2,cpu_instr_60_3,cpu_instr_60_4,0,0,0}, - {0,0,0,0,0,0,0,0}, - {cpu_instr_62_0,0,0,0,0,0,0,0}, - {cpu_instr_63_0,0,0,0,0,0,0,0}, - {cpu_instr_64_0,cpu_instr_64_1,0,0,0,0,0,0}, - {cpu_instr_65_0,cpu_instr_65_1,cpu_instr_65_2,0,0,0,0,0}, - {cpu_instr_66_0,cpu_instr_66_1,0,0,0,0,0,0}, - {cpu_instr_67_0,cpu_instr_67_1,cpu_instr_67_2,0,0,0,0,0}, - {cpu_instr_68_0,cpu_instr_68_1,0,0,0,0,0,0}, - {cpu_instr_69_0,cpu_instr_69_1,0,0,0,0,0,0}, - {cpu_instr_70_0,cpu_instr_70_1,cpu_instr_70_2,0,0,0,0,0}, - {cpu_instr_71_0,cpu_instr_71_1,0,0,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,cpu_instr_73_2,0,0,0,0,0}, - {cpu_instr_74_0,cpu_instr_74_1,0,0,0,0,0,0}, - {cpu_instr_75_0,cpu_instr_75_1,0,0,0,0,0,0}, - {cpu_instr_76_0,cpu_instr_76_1,0,0,0,0,0,0}, - {cpu_instr_77_0,0,0,0,0,0,0,0}, - {cpu_instr_78_0,0,0,0,0,0,0,0}, - {cpu_instr_79_0,0,0,0,0,0,0,0}, - {cpu_instr_80_0,cpu_instr_80_1,cpu_instr_80_2,cpu_instr_80_3,0,0,0,0}, - {cpu_instr_81_0,cpu_instr_81_1,cpu_instr_81_2,cpu_instr_81_3,0,0,0,0}, - {cpu_instr_82_0,cpu_instr_82_1,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,0,0,0,0,0,0}, - {cpu_instr_85_0,cpu_instr_85_1,0,0,0,0,0,0}, - {cpu_instr_86_0,cpu_instr_86_1,cpu_instr_86_2,cpu_instr_86_3,0,0,0,0}, - {cpu_instr_87_0,cpu_instr_87_1,cpu_instr_87_2,cpu_instr_87_3,0,0,0,0}, - {cpu_instr_88_0,cpu_instr_88_1,cpu_instr_88_2,cpu_instr_88_3,0,0,0,0}, - {cpu_instr_89_0,cpu_instr_89_1,cpu_instr_89_2,cpu_instr_89_3,0,0,0,0}, - {cpu_instr_90_0,cpu_instr_90_1,0,0,0,0,0,0}, - {cpu_instr_91_0,cpu_instr_91_1,0,0,0,0,0,0}, - {cpu_instr_92_0,cpu_instr_92_1,0,0,0,0,0,0}, - {cpu_instr_93_0,cpu_instr_93_1,0,0,0,0,0,0}, - {cpu_instr_94_0,cpu_instr_94_1,0,0,0,0,0,0}, - {cpu_instr_95_0,cpu_instr_95_1,0,0,0,0,0,0}, - {cpu_instr_96_0,cpu_instr_96_1,cpu_instr_96_2,0,0,0,0,0}, - {cpu_instr_97_0,cpu_instr_97_1,0,0,0,0,0,0}, - {cpu_instr_98_0,cpu_instr_98_1,0,0,0,0,0,0}, - {cpu_instr_99_0,cpu_instr_99_1,cpu_instr_99_2,0,0,0,0,0}, - {cpu_instr_100_0,0,0,0,0,0,0,0}, - {cpu_instr_101_0,cpu_instr_101_1,0,0,0,0,0,0}, - {cpu_instr_102_0,0,0,0,0,0,0,0}, - {cpu_instr_103_0,cpu_instr_103_1,0,0,0,0,0,0}, - {cpu_instr_104_0,cpu_instr_104_1,cpu_instr_104_2,cpu_instr_104_3,cpu_instr_104_4,0,0,0}, - {0,0,0,0,0,0,0,0}, - {cpu_instr_106_0,cpu_instr_106_1,cpu_instr_106_2,cpu_instr_106_3,cpu_instr_106_4,0,0,0}, - {0,0,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}, - {cpu_instr_110_0,cpu_instr_110_1,cpu_instr_110_2,cpu_instr_110_3,cpu_instr_110_4,0,0,0}, - {0,0,0,0,0,0,0,0}, - {cpu_instr_112_0,cpu_instr_112_1,0,0,0,0,0,0}, - {cpu_instr_113_0,cpu_instr_113_1,0,0,0,0,0,0}, - {cpu_instr_114_0,cpu_instr_114_1,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,0,0,0,0,0,0}, - {cpu_instr_117_0,cpu_instr_117_1,0,0,0,0,0,0}, - {cpu_instr_118_0,cpu_instr_118_1,0,0,0,0,0,0}, - {cpu_instr_119_0,cpu_instr_119_1,0,0,0,0,0,0}, - {cpu_instr_120_0,cpu_instr_120_1,0,0,0,0,0,0}, - {cpu_instr_121_0,cpu_instr_121_1,0,0,0,0,0,0}, - {cpu_instr_122_0,cpu_instr_122_1,cpu_instr_122_2,cpu_instr_122_3,0,0,0,0}, - {cpu_instr_123_0,cpu_instr_123_1,cpu_instr_123_2,cpu_instr_123_3,0,0,0,0}, - {cpu_instr_124_0,cpu_instr_124_1,cpu_instr_124_2,0,0,0,0,0}, - {cpu_instr_125_0,cpu_instr_125_1,cpu_instr_125_2,0,0,0,0,0}, - {cpu_instr_126_0,cpu_instr_126_1,cpu_instr_126_2,cpu_instr_126_3,0,0,0,0}, - {cpu_instr_127_0,cpu_instr_127_1,cpu_instr_127_2,cpu_instr_127_3,0,0,0,0}, - {cpu_instr_128_0,0,0,0,0,0,0,0}, - {cpu_instr_129_0,0,0,0,0,0,0,0}, - {cpu_instr_130_0,0,0,0,0,0,0,0}, - {cpu_instr_131_0,0,0,0,0,0,0,0}, - {cpu_instr_132_0,0,0,0,0,0,0,0}, - {cpu_instr_133_0,0,0,0,0,0,0,0}, - {cpu_instr_134_0,0,0,0,0,0,0,0}, - {cpu_instr_135_0,0,0,0,0,0,0,0}, - {cpu_instr_136_0,0,0,0,0,0,0,0}, - {cpu_instr_137_0,0,0,0,0,0,0,0}, - {cpu_instr_138_0,0,0,0,0,0,0,0}, - {cpu_instr_139_0,0,0,0,0,0,0,0}, - {cpu_instr_140_0,0,0,0,0,0,0,0}, - {cpu_instr_141_0,0,0,0,0,0,0,0}, - {cpu_instr_142_0,0,0,0,0,0,0,0}, - {cpu_instr_143_0,0,0,0,0,0,0,0}, - {cpu_instr_144_0,0,0,0,0,0,0,0}, - {cpu_instr_145_0,0,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,cpu_instr_147_2,0,0,0,0,0}, - {cpu_instr_148_0,cpu_instr_148_1,cpu_instr_148_2,0,0,0,0,0}, - {cpu_instr_149_0,cpu_instr_149_1,cpu_instr_149_2,0,0,0,0,0}, - {cpu_instr_150_0,cpu_instr_150_1,cpu_instr_150_2,0,0,0,0,0}, - {cpu_instr_151_0,cpu_instr_151_1,cpu_instr_151_2,0,0,0,0,0}, - {cpu_instr_152_0,cpu_instr_152_1,cpu_instr_152_2,0,0,0,0,0}, - {cpu_instr_153_0,cpu_instr_153_1,0,0,0,0,0,0}, - {cpu_instr_154_0,cpu_instr_154_1,0,0,0,0,0,0}, - {cpu_instr_155_0,cpu_instr_155_1,cpu_instr_155_2,0,0,0,0,0}, - {cpu_instr_156_0,cpu_instr_156_1,cpu_instr_156_2,0,0,0,0,0}, - {cpu_instr_157_0,cpu_instr_157_1,cpu_instr_157_2,0,0,0,0,0}, - {cpu_instr_158_0,cpu_instr_158_1,cpu_instr_158_2,0,0,0,0,0}, - {cpu_instr_159_0,0,0,0,0,0,0,0}, - {cpu_instr_160_0,0,0,0,0,0,0,0}, - {cpu_instr_161_0,0,0,0,0,0,0,0}, - {cpu_instr_162_0,0,0,0,0,0,0,0}, - {cpu_instr_163_0,0,0,0,0,0,0,0}, - {cpu_instr_164_0,0,0,0,0,0,0,0}, - {cpu_instr_165_0,0,0,0,0,0,0,0}, - {cpu_instr_166_0,0,0,0,0,0,0,0}, - {cpu_instr_167_0,0,0,0,0,0,0,0}, - {cpu_instr_168_0,0,0,0,0,0,0,0}, - {cpu_instr_169_0,0,0,0,0,0,0,0}, - {cpu_instr_170_0,0,0,0,0,0,0,0}, - {cpu_instr_171_0,0,0,0,0,0,0,0}, - {cpu_instr_172_0,0,0,0,0,0,0,0}, - {cpu_instr_173_0,0,0,0,0,0,0,0}, - {cpu_instr_174_0,cpu_instr_174_1,cpu_instr_174_2,0,0,0,0,0}, - {cpu_instr_175_0,cpu_instr_175_1,cpu_instr_175_2,0,0,0,0,0}, - {cpu_instr_176_0,cpu_instr_176_1,cpu_instr_176_2,0,0,0,0,0}, - {cpu_instr_177_0,cpu_instr_177_1,cpu_instr_177_2,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,cpu_instr_179_2,0,0,0,0,0}, - {cpu_instr_180_0,cpu_instr_180_1,cpu_instr_180_2,0,0,0,0,0}, - {cpu_instr_181_0,cpu_instr_181_1,cpu_instr_181_2,0,0,0,0,0}, - {cpu_instr_182_0,0,0,0,0,0,0,0}, - {cpu_instr_183_0,cpu_instr_183_1,cpu_instr_183_2,0,0,0,0,0}, - {cpu_instr_184_0,0,0,0,0,0,0,0}, - {cpu_instr_185_0,0,0,0,0,0,0,0}, - {cpu_instr_186_0,0,0,0,0,0,0,0}, - {cpu_instr_187_0,0,0,0,0,0,0,0}, - {cpu_instr_188_0,0,0,0,0,0,0,0}, - {cpu_instr_189_0,0,0,0,0,0,0,0}, - {cpu_instr_190_0,0,0,0,0,0,0,0}, - {cpu_instr_191_0,0,0,0,0,0,0,0}, - {cpu_instr_192_0,cpu_instr_192_1,0,0,0,0,0,0}, - {cpu_instr_193_0,cpu_instr_193_1,0,0,0,0,0,0}, - {cpu_instr_194_0,cpu_instr_194_1,0,0,0,0,0,0}, - {cpu_instr_195_0,cpu_instr_195_1,0,0,0,0,0,0}, - {cpu_instr_196_0,cpu_instr_196_1,0,0,0,0,0,0}, - {cpu_instr_197_0,cpu_instr_197_1,0,0,0,0,0,0}, - {cpu_instr_198_0,cpu_instr_198_1,0,0,0,0,0,0}, - {cpu_instr_199_0,cpu_instr_199_1,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}, - {cpu_instr_202_0,cpu_instr_202_1,0,0,0,0,0,0}, - {cpu_instr_203_0,cpu_instr_203_1,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,0,0,0,0,0}, - {cpu_instr_206_0,cpu_instr_206_1,cpu_instr_206_2,0,0,0,0,0}, - {cpu_instr_207_0,cpu_instr_207_1,cpu_instr_207_2,0,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,0,0,0,0,0,0}, - {cpu_instr_211_0,cpu_instr_211_1,0,0,0,0,0,0}, - {cpu_instr_212_0,cpu_instr_212_1,0,0,0,0,0,0}, - {cpu_instr_213_0,cpu_instr_213_1,cpu_instr_213_2,0,0,0,0,0}, - {cpu_instr_214_0,cpu_instr_214_1,cpu_instr_214_2,0,0,0,0,0}, - {cpu_instr_215_0,cpu_instr_215_1,cpu_instr_215_2,0,0,0,0,0}, - {cpu_instr_216_0,cpu_instr_216_1,cpu_instr_216_2,0,0,0,0,0}, - {cpu_instr_217_0,cpu_instr_217_1,cpu_instr_217_2,0,0,0,0,0}, - {cpu_instr_218_0,0,0,0,0,0,0,0}, - {cpu_instr_219_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}, - {cpu_instr_223_0,0,0,0,0,0,0,0}, - {cpu_instr_224_0,0,0,0,0,0,0,0}, - {cpu_instr_225_0,cpu_instr_225_1,cpu_instr_225_2,0,0,0,0,0}, - {cpu_instr_226_0,cpu_instr_226_1,cpu_instr_226_2,cpu_instr_226_3,cpu_instr_226_4,0,0,0}, - {0,0,0,0,0,0,0,0}, - {cpu_instr_228_0,cpu_instr_228_1,cpu_instr_228_2,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,0,0,0,0,0,0,0}, - {cpu_instr_231_0,0,0,0,0,0,0,0}, - {cpu_instr_232_0,0,0,0,0,0,0,0}, - {cpu_instr_233_0,cpu_instr_233_1,0,0,0,0,0,0}, - {cpu_instr_234_0,cpu_instr_234_1,0,0,0,0,0,0}, - {cpu_instr_235_0,cpu_instr_235_1,cpu_instr_235_2,cpu_instr_235_3,0,0,0,0}, - {cpu_instr_236_0,cpu_instr_236_1,cpu_instr_236_2,cpu_instr_236_3,cpu_instr_236_4,0,0,0}, - {0,0,0,0,0,0,0,0}, - {cpu_instr_238_0,cpu_instr_238_1,cpu_instr_238_2,cpu_instr_238_3,cpu_instr_238_4,0,0,0}, - {0,0,0,0,0,0,0,0}, - {cpu_instr_240_0,0,0,0,0,0,0,0}, - {cpu_instr_241_0,0,0,0,0,0,0,0}, - {cpu_instr_242_0,0,0,0,0,0,0,0}, - {cpu_instr_243_0,0,0,0,0,0,0,0}, - {cpu_instr_244_0,0,0,0,0,0,0,0}, - {cpu_instr_245_0,0,0,0,0,0,0,0}, - {cpu_instr_246_0,0,0,0,0,0,0,0}, - {cpu_instr_247_0,cpu_instr_247_1,cpu_instr_247_2,cpu_instr_247_3,0,0,0,0}, - {cpu_instr_248_0,cpu_instr_248_1,cpu_instr_248_2,cpu_instr_248_3,cpu_instr_248_4,0,0,0}, - {0,0,0,0,0,0,0,0}, - {cpu_instr_250_0,cpu_instr_250_1,cpu_instr_250_2,cpu_instr_250_3,cpu_instr_250_4,0,0,0}, - {0,0,0,0,0,0,0,0}, - {cpu_instr_252_0,cpu_instr_252_1,cpu_instr_252_2,cpu_instr_252_3,cpu_instr_252_4,0,0,0}, - {0,0,0,0,0,0,0,0}, - {cpu_instr_254_0,cpu_instr_254_1,cpu_instr_254_2,cpu_instr_254_3,0,0,0,0}, - {cpu_instr_255_0,0,0,0,0,0,0,0}, -}; diff --git a/emulator/keycodes.lua b/emulator/keycodes.lua deleted file mode 100644 index d797e97..0000000 --- a/emulator/keycodes.lua +++ /dev/null @@ -1,114 +0,0 @@ - --- copied from Brick_LuaLogic/bricks/input/keyboard-global.luas - -return { - ["backspace"] = 8, - ["tab"] = 9, - ["return"] = 13, - - ["lshift"] = 16, - ["lctrl"] = 17, --["lcontrol"] = 17, - ["lalt"] = 18, - - -- this block does not match vkey codes - ["rshift"] = 20, - ["rctrl"] = 21, --["rcontrol"] = 21, - ["ralt"] = 22, - - -- this block does not match vkey codes - [";"] = 24, - ["="] = 25, - [","] = 26, - ["."] = 27, - ["-"] = 28, -- not in bl - ["/"] = 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, - ["\'"] = 63, --["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, - - ["kp0"] = 96, --["numpad0"] = 96, - ["kp1"] = 97, --["numpad1"] = 97, - ["kp2"] = 98, --["numpad2"] = 98, - ["kp3"] = 99, --["numpad3"] = 99, - ["kp4"] = 100, --["numpad4"] = 100, - ["kp5"] = 101, --["numpad5"] = 101, - ["kp6"] = 102, --["numpad6"] = 102, - ["kp7"] = 103, --["numpad7"] = 103, - ["kp8"] = 104, --["numpad8"] = 104, - ["kp9"] = 105, --["numpad9"] = 105, - ["kp*"] = 106, --["*"] = 106, - ["kp+"] = 107, --["+"] = 107, - ["kpenter"] = 108, --["numpadenter"] = 108, - ["kp-"] = 109, --["minus"] = 109, - ["kp."] = 110, --["numpaddecimal"] = 110, - ["kp/"] = 111, --["/"] = 111, - - ["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, -} diff --git a/emulator/main.lua b/emulator/main.lua deleted file mode 100644 index ce8bf5c..0000000 --- a/emulator/main.lua +++ /dev/null @@ -1 +0,0 @@ -require("8608emulator") diff --git a/examples/_hwdefs.asm b/examples/_hwdefs.asm deleted file mode 100644 index 2e6c1c7..0000000 --- a/examples/_hwdefs.asm +++ /dev/null @@ -1,47 +0,0 @@ - -.define SYSROM $0000 -.define GPIO $0400 -.define KEYBOARD $0500 -.define PERIPH $0600 -.define ROBOT $0700 -.define SCREEN $0800 -.define SCRCLR $0C00 -.define SYSRAM $1000 -.define USERROM $2000 -.define USERRAM $3000 - -;.define FUNC .space 1 \ .align $10 \ -.define FUNC .space 1 \ - -; I/O devices - -.org GPIO - io: - .mulLeft: .mulHigh: .mulResultHigh: byte - .mulRight: .mulLow: .mulResultLow: .mulResult: byte - .dividend: .quotient: byte - .divisor: .remainder: byte - .popcount: byte - .timer: byte - byte[(256-6)] - -.org KEYBOARD - keyboard: - .queue: .int: byte - byte[(256-1)] - -.org PERIPH - byte[256] - -.org ROBOT - robot: - .color: byte - .control: byte - byte[(256-2)] - -.org SCREEN - screen: - .char: byte[1024] - .color: byte[1024] - -.org $0000 diff --git a/examples/clear_screen.asm b/examples/clear_screen.asm deleted file mode 100644 index 1d63917..0000000 --- a/examples/clear_screen.asm +++ /dev/null @@ -1,30 +0,0 @@ -.include _hwdefs.asm -.include _clrdefs.asm - -;; Variables -.org SYSRAM -stack: byte[128] - -;; Main -.org SYSROM -lds stack -jss cls - -hlt - -;; Clear the screen -FUNC cls: - ldp screen.char - ldc $00 ;; Blank - ldq screen.color - ldb CLR_BLACK ;; Black - .cls_loop: { - stc *p++ - stb *q++ - lda pl - cmp (lo(COLOR)) - jnz .cls_loop - lda ph - cmp (hi(COLOR)) - jnz } -rts diff --git a/examples/editor2.asm b/examples/editor2.asm deleted file mode 100644 index 9c8aa1c..0000000 --- a/examples/editor2.asm +++ /dev/null @@ -1,288 +0,0 @@ - -.include hwdefs.asm - -.define CursorBlinkTicks 20 - -.org SYSROM - lds stack - ldv interrupt - ldp screen.char - - jss clearscreen - - lda 0 - sta *cursorTimer - - { - lda 1 - sta *io.timer - hlt - jss handleKeys - jss blinkCursorTick - jpr } - - ;----------- - - FUNC / { / irt - interrupt: - ;stp *inttempp - ;ldp s / stp *inttemps - ;lds intstack - ;psh f / psh a / psh b / psh c / psh q - - run - - ;pop q / pop c / pop b / pop a / pop f - ;ldp *inttemps / lds p - ;ldp *inttempp - jpr } - - FUNC handleKeys: - lda *keyboard.queue - jpz { - jss keypressed - jpr handleKeys - } - rts - - FUNC blinkCursorTick: - lda *cursorTimer - jnz { - ldp *screenPos - ldc ph / ldb pl / adc $04 / ldp cb ; get color addr from screen pos - ;lda *p / xor $80 / sta *p ; toggle highlight bit - lda *p / xor $03 / sta *p ; toggle black/white - - lda CursorBlinkTicks - } - dec a - sta *cursorTimer - rts - - FUNC numshifts: ")!@#$%^&*(" - FUNC keys_2430: ";=,.-/`" - FUNC keys_2430_shift: ":+<>_?~" - FUNC keys_6063: "[\\]'" - FUNC keys_6063_shift: "{|}\"" - FUNC keys_numpad: "0123456789*+\n-./" - FUNC keys_numpad_shift: "0123456789*+\n_.?" - - FUNC keypressed: ; key in a - ldb a - - ; check for shift - and $7F - cmp $10 / jpz keyShift / cmp $14 / jnz keyNoShift - keyShift: - lda b / and $80 / shr 7 / sta *shiftDown - rts - keyNoShift: - - lda b - and $80 - jnz { / rts / } - - lda b - and $7F - ; ldp *screenPos / sta *p++ / stp *screenPos - ; jss printhex / lda b - cmp "A" / jlt { / cmp "Z" / jgt { ; letter - ldb *shiftDown / jnz { - add $20 - } - jss printchar - rts - } / } - cmp "0" / jlt { / cmp "9" / jgt { ; number - ldb *shiftDown / jpz { - sub "0" / ldb a / ldp numshifts / adp b - lda *p - } - jss printchar - rts - } / } - ldp keys_2430 / ldq keys_2430_shift / ldb 24 / ldc 30 / jss printcharblock ; symbols - ldp keys_6063 / ldq keys_6063_shift / ldb 60 / ldc 63 / jss printcharblock - ldp keys_numpad / ldq keys_numpad_shift / ldb 96 / ldc 111 / jss printcharblock - cmp 13 / jnz { ; newline - jss clearCursor - ldp *screenPos - ldb pl / ldc ph - lda b / and $C0 / ldb a - ldp cb - adp $40 - stp *screenPos - jss updateMoveScreen - rts - } - cmp 9 / jnz { ; tab - - rts - } - cmp 32 / jnz { / lda 32 / jsr printchar / rts / } ; space - cmp 8 / jnz { ; backspace - ldc 1 / jss moveback - rts - } - cmp 37 / jnz { ; left - ldc 0 / jss moveback - rts - } - cmp 39 / jnz { ; right - jss clearCursor - ldp *screenPos - lda ph / cmp $0B / jnz { - lda pl / cmp $FF / jnz { - rts - } - } - adp 1 - stp *screenPos - rts - } - jss printhex - rts - - FUNC moveforward: - - rts - - FUNC moveback: ; c = delete char (bool) - jss clearCursor - ldp *screenPos - lda ph / cmp $08 / jnz { - lda pl / tst a / jnz { - rts - } - } - adp -1 - lda *p / jpz { ; one character - tst c / jpz { - lda 0 / sta *p - } - stp *screenPos - jpr | ; blank line - { - lda pl / and $3F ; stop at beginning of line - adp -1 - jpz | - lda *p - jpz } - adp 1 - stp *screenPos - } - rts - - FUNC printcharblock: - cmp b / jlt { / cmp c / jgt { - ldc *shiftDown / jpz { - ldp q - } - sub b / ldb a / adp b - lda *p / jss printchar - pop q / rts - } / } - rts - - FUNC clearCursor: - psh a / psh b / psh c - ldp *screenPos - ldc ph / ldb pl / adc $04 / ldp cb ; get highlight addr from screen pos - ;lda *p / and $7F / sta *p ; clear highlight bit - lda $3E / sta *p ; set to black - lda 0 / sta *cursorTimer - pop c / pop b / pop a - rts - - FUNC updateMoveScreen: - ldp *screenPos - lda ph - cmp $0C - jnz { - jss moveScreenUp - } - rts - - FUNC printchar: - jss clearCursor - ldp *screenPos / sta *p++ / stp *screenPos - jss updateMoveScreen - rts - - FUNC moveScreenUp: - ldp (SCREEN+$40) - ldq (SCREEN) - ldb $0F / { - ldc $40 / { - lda *p++ / sta *q++ - dec c - jnz } - dec b - jnz } - stq *screenPos - ldb $00 - ldc $20 - ldp (SCRCLR+$40*$0F) - lda $40 / { - stb *q++ - stc *p++ - dec a - jnz } - rts - - FUNC printhex: - ldp *screenPos - ldb a - and $F0 - shr 4 - add "0" - cmp "9" / jle { / add 7 / } - jss printchar - lda b - and $0F - add "0" - cmp "9" / jle { / add 7 / } - jss printchar - lda 0 - jss printchar - stp *screenPos - rts - - FUNC clearscreen: - ldp screen.char / stp *screenPos - ldq screen.color - lda $00 ; blank - ;ldb $20 ; white color, no highlight - ldb $3E ; black color, no highlight - ldc 128 ; 128*8 = 4k of each p and q - { - sta *p++ - stb *q++ - sta *p++ - stb *q++ - sta *p++ - stb *q++ - sta *p++ - stb *q++ - sta *p++ - stb *q++ - sta *p++ - stb *q++ - sta *p++ - stb *q++ - sta *p++ - stb *q++ - dec c - jnz } - rts - -.org SYSRAM - inttempp: word - inttemps: word - intstack: byte[(128-4)] - stack: byte[128] - -.org USERRAM - screenPos: word - shiftDown: byte - cursorTimer: byte diff --git a/examples/fibonacci.asm b/examples/fibonacci.asm deleted file mode 100644 index 63a632e..0000000 --- a/examples/fibonacci.asm +++ /dev/null @@ -1,8 +0,0 @@ -lda 1 -ldb 0 - -fib_loop: -ldc b -ldb a -add c -jlt fib_loop ; Stop when carry flag is set \ No newline at end of file diff --git a/examples/functions.asm b/examples/functions.asm deleted file mode 100644 index e52cfc1..0000000 --- a/examples/functions.asm +++ /dev/null @@ -1,50 +0,0 @@ -.include _hwdefs.asm -.include _clrdefs.asm - -;; Defines -.define VARS $0100 - -;; Variables -.org SYSRAM -stack: byte[128] - -.org VARS -hello_str: "Hello world!\0" - -;; Main -.org SYSROM -lds stack - -jss cls - -ldp screen.char -ldq hello_str -jss print - -hlt - -;; Clear the screen -FUNC cls: - ldp screen.char - ldc $00 ;; Blank - ldq screen.color - ldb CLR_BLACK ;; Black - .cls_loop: { - stc *p++ - stb *q++ - lda pl - cmp (lo(COLOR)) - jnz .cls_loop - lda ph - cmp (hi(COLOR)) - jnz } -rts - -;; Print string (Q) to the current screen cursor (P) -FUNC print: - lda *q++ - jpz .print_end - sta *p++ - jmp print - .print_end: -rts diff --git a/examples/helloworld.asm b/examples/helloworld.asm deleted file mode 100644 index d33bc46..0000000 --- a/examples/helloworld.asm +++ /dev/null @@ -1,16 +0,0 @@ -.org $0100 ; Static data -hello_str: -"Hello world\0" - -.org $0000 ; Program must start at $0000 -ldp $0800 ; Char display -ldq hello_str - -print: -lda *q++ -jpz print_end -sta *p++ -jmp print - -print_end: -hlt diff --git a/examples/increment_reg.asm b/examples/increment_reg.asm deleted file mode 100644 index 38112ac..0000000 --- a/examples/increment_reg.asm +++ /dev/null @@ -1,8 +0,0 @@ -; This program adds 1 to register A until it equals 64, then halts. - -loop: -inc a -cmp 64 -jnz loop - -hlt \ No newline at end of file diff --git a/fullPath.bat b/fullPath.bat deleted file mode 100644 index b1d7fba..0000000 --- a/fullPath.bat +++ /dev/null @@ -1 +0,0 @@ -@echo %~dpnx1 diff --git a/rom-8608-build.lua b/generate-architecture.lua similarity index 85% rename from rom-8608-build.lua rename to generate-architecture.lua index 180f25e..d93df67 100644 --- a/rom-8608-build.lua +++ b/generate-architecture.lua @@ -1,3 +1,6 @@ +-- generate-architecture.lua +-- This program uses the definitions in 8608-definition.lua to generate the assembler definitions, instruction list, and microcode. +-- Also see 8608-definition.lua local debugInfo = {} local function getDebugInfo() @@ -89,6 +92,12 @@ local wordRelStr = [[ 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 reljmp = instr.jmp and instr.rel @@ -110,6 +119,9 @@ local function getAsmCode(mnem, instr) 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" @@ -134,6 +146,11 @@ local function getAsmsFromInstr(instr, aliases) return t end +local asmDataStr = [[ +#ruledef { + %s +} +]] local function archToUcode(arch) local sigs = sigsFromRoms(arch.roms) local ops = arch.operations @@ -188,26 +205,28 @@ local function archToUcode(arch) table.insert(lt, "\n") end - -- Output instruction list - local info = table.concat(infolines).."\n"..table.concat(lt) - --print(info) - local fo = io.open("instructionList.txt", "w") - if fo then - fo:write(info) - fo:close() - end - - - -- Output customASM definitions - local fi = io.open("arch-8608-template.asm") - local asmDataStr = fi:read("*a") - fi:close() - - local asmTable = string.format(asmDataStr, table.concat(asmlines, "\n\t")) - local fo = io.open("arch-8608.asm", "w") - if fo then - fo:write(asmTable) - fo:close() + local writeFiles = true + if writeFiles then + -- Output instruction list + local info = arch.instructionListHeader..table.concat(infolines).."\n"..table.concat(lt) + --print(info) + local fo = io.open(arch.instructionListFile, "w") + if fo then + fo:write(info) + fo:close() + else + print("Could not open \""..arch.instructionListFile.."\" for write") + end + + -- Output customASM definitions + local asmTable = arch.assemblerDefsHeader..string.format(asmDataStr, table.concat(asmlines, "\n\t")) + local fo = io.open(arch.assemblerDefsFile, "w") + if fo then + fo:write(asmTable) + fo:close() + else + print("Could not open \""..arch.assemblerDefsFile.."\" for write") + end end return ucode @@ -264,5 +283,5 @@ local function buildArch(arch) buildBricks(bricks) end -local arch = require("rom-8608-defs") +local arch = require("8608-definition") buildArch(arch) diff --git a/instructionList.txt b/instructionList.txt index 37bf07c..3d42a1e 100644 --- a/instructionList.txt +++ b/instructionList.txt @@ -1,3 +1,10 @@ +instructionList.txt +List of all instructions in the 8608 architecture. + +Instructions are encoded as the opcode, followed by any immediate values. +16-bit immediates are encoded in big-endian byte order. + +Each instruction is described in order of: Mnemonic, Opcode, Clock cycles, Description Control (C): rst 00 1 Clear all registers and set I=0 @@ -45,16 +52,11 @@ ads b E8 1 S+=B signed add imm8 24 2 A+=imm8, set flags adb imm8 72 2 B+=imm8, set flags adc imm8 73 2 C+=imm8, set flags -sub imm8 70 2 A-=imm8, set flags -sbb imm8 99 2 B-=imm8, set flags -sbc imm8 9A 2 C-=imm8, set flags acc imm8 78 2 A+=imm8+CF, set flags -scc imm8 79 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 -ann imm8 77 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 @@ -72,7 +74,6 @@ 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 -ann *s+imm8 B4 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 @@ -88,7 +89,6 @@ 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 -ann b A6 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 @@ -104,7 +104,6 @@ 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 -ann c AD 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 @@ -258,7 +257,7 @@ ldq p 8E 1 Q=P lds p 8F 1 S=P ldv p 90 1 V=P -Opcodes used: 252/255 +Opcodes used: 244/255 0123456789ABCDEF 00 | CB----WWBBBBBBBB 10 | UUIIUIIUUUUUUUUU @@ -267,11 +266,11 @@ Opcodes used: 252/255 40 | SSSSSSSSSSXXXAAA 50 | BBBBBBBBBBBBBBBB 60 | JBBJJJJJWWWWWWWW -70 | AAAAAAAAAAWWWWWW +70 | -AAAAAA-A-WWWWWW 80 | MMMMMMMMMMMMMMMM -90 | MMWWWWBBBAAAAAAA -A0 | AAAAAAAAAAAAAAAA -B0 | AAAAAAAAAAAAAAAA +90 | MMWWWWBBB--AAAAA +A0 | AAAAAA-AAAAAA-AA +B0 | AAAA-AAAAAAAAAAA C0 | BBBBBBBBBBBBWWWW D0 | AAAAAAAAAAAAAAAA E0 | MJJJJJXXXSSBWWWW diff --git a/memoryMap.md b/memoryMap.md index d87c386..869cdfa 100644 --- a/memoryMap.md +++ b/memoryMap.md @@ -1,45 +1,48 @@ -## Boot ROM -Execution starts here, at address `$0000`.
-The main program is located here, or the OS bootloader if an OS is present. + +## Main RAM +8 KiB of random-access memory.
+Located at addresses `$8000` to `$9FFF`.
+Programs can write data to these addresses, and retrieve the data at a later time.
+Machine code can also be stored here and executed. + +## Text Display +Write ASCII values to addresses `$2000` to `$27FF` to display characters at certain positions on the screen.
+`$2000` is the top left, `$27FF` is the bottom right.
+Rows are 64 bytes long.
+For example, `$2040` would be the first character of the second row from the top.
+Values can also be read back out of the display memory, as if it were RAM. + +## Text Display Color +Write 6-bit color IDs to addresses `$0C00` to `$0FFF` to set the color of characters on the screen.
+If the most significant bit is 1, the character and background colors will be inverted, i.e. highlighted.
+Values can also be read back out of the display color memory, as if it were RAM. + +## Main ROM +1 KiB of read-only memory.
+Located at addresses `$0000` to `$03FF`.
+When the CPU is first turned on, or is reset, it will start executing code from here, starting at address `$0000`.
+Bricks can be physically placed on top of the ROM brick to set bits within the ROM.
+A bootloader, operating system, or hex monitor may be loaded here. ## GPIO -Contains hardware multiplication (`$0400 * $0401 -> $0400`) and division (`$0402 / $0403 -> $0402 r $0403`), popcount (`$0404 -> $0404`), and a timer (`$0405`).
-Value written to timer register = number of game ticks (32 ms) between interrupt triggers.
-Write 0 to disable. +Contains hardware multiplication, division, popcount, and a timer.
+When two 8-bit values are written to the multiplier registers `$0400` and `$0401`, the result will be available as a big-endian 16-bit value at `$0400`. Read from `$0401` to retrieve an 8-bit result.
+When two 8-bit values are written to the divider registers `$0402` and `$0403`, the quotient can be read from `$0402` and the remainder from `$0403`
+When any 8-bit value is written to the timer register `$0404`, the popcount of that value (The number of bits that are 1) can be read from the same location. +When any value is written to the timer register at `$0405`, an interrupt will be triggered after 32 milliseconds. ## Keyboard -Read address `$0500` to get the next key event
-7-bit Windows VKey code, MSB 1 = press, 0 = release
-Returns 0 if buffer is empty. -Write 1 to `$0500` to enable keyboard interrupts, 0 to disable. +Read address `$0500` to get the next keycode from the buffer.
+Keycodes are 7-bit Windows VKey codes, plus a press/release bit. If the MSB is 1, the event is a key press; if 0, a release.
+Result will be 0 if the buffer is empty.
+If 1 is written to `$0500`, an interrupt will be triggered whenever a key event is available. Write 0 to disable again. ## Serial Peripheral Interface Not yet implemented. ## Robot Controller -Write to `$0701` to control the robot. Each bit is an action - MSB to LSB: Plant brick, destroy brick, move forward, backward, left, right, up, down.
-Write a 6-bit color ID to `$0700` to set the color of the bricks the robot plants.
-Read `$0700` to get the color of the brick the robot is on. MSB = brick exists. Returns 0 if no brick. - - -## Text Display -Write ASCII values to `$0800` to `$0BFF` to display characters at certain positions on screen.
-`$0800` is top left, `$0BFF` is bottom right, rows are 64 bytes. - -## Text Display Color -Write 6-bit color IDs to `$0C00` to `$0FFF` to set the color of characters on screen.
-MSB = whether to invert character mask (i.e. for highlighting). - -## System RAM -The OS may use this memory for the stack, system variables, etc.
-If no OS is present, this memory can be used for any purpose, etc.
-Located at `$1000` to `$1FFF`. - -## User ROM -User program and data can go here.
-If no OS is present, the boot ROM will need to jump into this code.
-Located at `$2000` to `$2FFF`. - -## User RAM -Your code can use this memory for variables, arrays, a heap, etc.
-Located at `$3000` to `$3FFF`. +Write to `$0701` to control a 1x1f-sized "robot" that can place and destroy bricks.
+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.
+Write a 6-bit color ID to `$0700` to set the color of the bricks the robot will plant.
+Read `$0700` to get the color of the brick the robot is currently overlapping. If the MSB is 1, a brick exists at this location. Result will be 0 if no brick is present.
+The robot should only be given new actions once per game tick. The timer at `$0405` can be used for this purpose. diff --git a/readme.md b/readme.md index 4e4b167..523efc9 100644 --- a/readme.md +++ b/readme.md @@ -1,31 +1,9 @@ # 8608 - An 8-bit data, 16-bit address, CISC architecture. -For a list of instructions, see [instructionList.txt](instructionList.txt). +For a description of the architecture and a list of instructions, see [instructionList.txt](instructionList.txt). -## How to use the assembler: -1. Install `bllua3` from [https://notabug.org/redo/bllua3](https://notabug.org/redo/bllua3) -2. Download this repo into `Add-Ons/8608` or anywhere within one of Blockland's main directories. -3. In BL console, execute: - ``` - luaexec("Add-Ons/8608/assembler-8608.lua"); - ``` -4. To assemble a program, place a 1x1f ghost brick on the top-left corner of the ROM, face forward, and in BL console do: - ``` - AssembleBuildFile("Add-Ons/8608/examples/program.asm", "RomX RomY RomZ"); - ``` - where `RomX` is the width of the ROM, `RomY` is the depth front to back, and `RomZ` is the height in bits, i.e., "16 16 8". +For a memory map of the 8608-based computer, see [memoryMap.md](memoryMap.md). - You can also run the assembler from the command line to get a memory dump and disassembly in stdout, if you have lua installed: - ``` - luajit "Add-Ons/8608/assembler-8608.lua" "Add-Ons/8608/examples/program.asm" - ``` - -## How to use the emulator: -1. Install love2d from [https://love2d.org](https://love2d.org) -2. Open a command prompt in the "emulator" folder and run: - ``` - love . C:/path/filename.asm - ``` - -## Memory Map -[memory map](memoryMap.md) +To assemble programs, use CustomAsm: [https://github.com/hlorenzi/customasm](https://github.com/hlorenzi/customasm)
+Simply include the 8608 architecture file into your program: [8608.asm](8608.asm).
+`#include "8608/8608.asm"` diff --git a/utf8table.txt b/utf8table.txt deleted file mode 100644 index 05a2346..0000000 --- a/utf8table.txt +++ /dev/null @@ -1,88 +0,0 @@ -。 A1 -「 A2 -」 A3 -、 A4 -・ A5 -ヲ A6 -ァ A7 -ィ A8 -ゥ A9 -ェ AA -ォ AB -ャ AC -ュ AD -ョ AE -ッ AF -ー B0 -ア B1 -イ B2 -ウ B3 -エ B4 -オ B5 -カ B6 -キ B7 -ク B8 -ケ B9 -コ BA -サ BB -シ BC -ス BD -セ BE -ソ BF -タ C0 -チ C1 -ツ C2 -テ C3 -ト C4 -ナ C5 -ニ C6 -ヌ C7 -ネ C8 -ノ C9 -ハ CA -ヒ CB -フ CC -ヘ CD -ホ CE -マ CF -ミ D0 -ム D1 -メ D2 -モ D3 -ヤ D4 -ユ D5 -ヨ D6 -ラ D7 -リ D8 -ル D9 -レ DA -ロ DB -ワ DC -ン DD -゛ DE -゜ DF -ガ B6 DE -ギ B7 DE -グ B8 DE -ゲ B9 DE -ゴ BA DE -ザ BB DE -ジ BC DE -ズ BD DE -ゼ BE DE -ゾ BF DE -ダ C0 DE -ヂ C1 DE -ヅ C2 DE -デ C3 DE -ド C4 DE -バ CA DE -ビ CB DE -ブ CC DE -ベ CD DE -ボ CE DE -パ CA DF -ピ CB DF -プ CC DF -ペ CD DF -ポ CE DF