diff --git a/emulator/8608emulator.c b/emulator/8608emulator.c index 56d804c..c51e5e9 100644 --- a/emulator/8608emulator.c +++ b/emulator/8608emulator.c @@ -42,7 +42,7 @@ #define ldi cpu->instr = readmemory(cpu->i); cpu->cycle = 0; #define addf(x,y) { x=(x+y); cpu->cf=x>=256; x&=0xFF; setzf(x); } #define subf(x,y) addf(x,-y); -#define cmpf(x,y) { int t=x-y; cpu->cf=(t>=256); setzf(t); } +#define cmpf(x,y) { int t=x-y; cpu->cf=(t<0); 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); @@ -80,6 +80,7 @@ struct CPU { int irq; int ifg; int rfg; + int ien; int instr; int cycle; int instrpre; @@ -130,14 +131,15 @@ 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) { +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->instr = 0xF2; } + if(cpu->irq && !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; } } diff --git a/emulator/8608emulator.dll b/emulator/8608emulator.dll index c7f8e0a..99234ec 100644 Binary files a/emulator/8608emulator.dll and b/emulator/8608emulator.dll differ diff --git a/emulator/8608emulator.lua b/emulator/8608emulator.lua index 896cd6b..a3d94ef 100644 --- a/emulator/8608emulator.lua +++ b/emulator/8608emulator.lua @@ -11,6 +11,7 @@ local lg = love.graphics local li = love.image local le = love.event local lt = love.timer +local lk = love.keyboard ---- local function InitColorset() @@ -43,7 +44,7 @@ local function handleEvents(cpu, mem) end local RegDisplay = { - scrX = 384+16, scrY = 32, + scrX = 384+16, scrY = 32+8, width = 128, height = 192, fontWidth = 8, fontHeight = 12, registers = { @@ -63,7 +64,8 @@ local RegDisplay = { 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 = "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}, }, @@ -107,8 +109,9 @@ local function RedrawRegDisplay(rd, cpu, mem) end local ReadMemory +local WriteMemory local StackDisplay = { - scrX = 8+384+32+6, scrY = 32+192+32, + scrX = 8+384+32+6, scrY = 32+192+32-4, lines = 16, fontHeight = 12, } local function InitStackDisplay(sd) @@ -130,11 +133,11 @@ end local MemoryDisplays = { { - scrX = 8, scrY = 32+192+32, + scrX = 8, scrY = 32+192+32-4, columns = 16, columnSpace = 4, rows = 16, fontHeight = 12, showAscii = false, - addr = 0x0000, + addr = 0x3000, highlightTime = 8, }, } @@ -205,9 +208,9 @@ local function RedrawMemoryDisplay(md, cpu, mem) end local ProgramDisplay = { - scrX = 8+384+8+128+8, scrY = 32, + scrX = 8+384+8+128+8, scrY = 32+8, fontHeight = 12, - numLines = 35, + numLines = 34, highlightTime = 8, } local function pdLinesFromDasm(dasm) @@ -301,20 +304,12 @@ local CharDisplay = { width = 64*6, height = 16*12, rows = 16, cols = 64, fontWidth = 6, fontHeight = 12, - scrX = 8, scrY = 32, + scrX = 8, scrY = 32+8, addrChar = 0x0800, addrColor = 0x0C00, } local function InitCharDisplay(cd) lg.print("Char Display", cd.scrX, cd.scrY-16) - cd.chars = {} - cd.colors = {} - cd.highlight = {} - for a = 0, cd.rows*cd.cols-1 do - cd.chars[a] = "" - cd.colors[a] = ColorSet[1] - cd.highlight[a] = false - end cd.font = lg.newFont("consola.ttf", cd.fontHeight-1, "mono") end @@ -346,19 +341,92 @@ local keycodes = require("keycodes") local CPURequestInterrupt local function KeyboardOnKey(kb, key, press, cpu, mem) local code = keycodes[key] or keycodes["invalid"] - table.insert(kb.queue, code) + 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) +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("[ESC] Toggle keyboard", 0, lk.isDown("escape"), 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 }, @@ -371,6 +439,9 @@ local peripherals = { 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, + }, } ---- @@ -413,7 +484,7 @@ end ReadMemory = function(mem, addr) return mem.c.data[addr%65536]%256 end -local function WriteMemory(mem, addr, val) +WriteMemory = function(mem, addr, val) if mem.c.canwrite[addr%65536]~=0 then mem.c.data[addr%65536] = val%256 end @@ -445,21 +516,22 @@ struct CPU { 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); +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) +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) + countleft = cpuDll.TickCPU(cpu.c, mem.c, countleft, countinstrs and 1 or 0, breakaddr or 0xFFFFFFFF) handleEvents(cpu, mem) end end @@ -470,6 +542,10 @@ CPURequestInterrupt = function(cpu) cpu.c.irq = 1; end +function RunToNextInstr(cpu) + +end + ---- local function RedrawVideoDisplay(vd, mem) @@ -497,9 +573,11 @@ local function RedrawCharDisplay(cd, mem) local abase = cy*cd.cols + cx local achar = cd.addrChar + abase local acolor = cd.addrColor + abase - local colorid = ReadMemory(mem, acolor)%64 + local colormem = ReadMemory(mem, acolor) + local colorid = colormem%64 + local highlight = colormem>=128 lg.setColor(ColorSet[colorid]) - if cd.highlight[a] then + 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 @@ -524,7 +602,7 @@ local function InitWindowCanvas() lg.setFont(InfoFont) lg.print("8608 CPU Emulator", 4, 4) end -local function RedrawWindow() +local function RedrawWindow(usekeyboard, runcpu) lg.setCanvas(WindowCanvas) lg.setFont(InfoFont) RedrawCharDisplay(CharDisplay, Memory) @@ -534,6 +612,7 @@ local function RedrawWindow() 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 @@ -547,6 +626,7 @@ function love.load() InitMemory(Memory, peripherals) InitWindowCanvas() InitCPU(CPU) + InitGPIO(GPIO) --InitVideoDisplay(VideoDisplay) InitCharDisplay(CharDisplay) InitRegDisplay(RegDisplay) @@ -560,24 +640,38 @@ 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) + TickCPU(CPU, Memory, CPUSpeed, false, nil) end - RedrawWindow() + RedrawWindow(UseKeyboard, RunCPU) lg.setColor(1,1,1) lg.draw(WindowCanvas, 0, 0, 0, 2, 2) - lg.print(CPU.c.frame) end + function love.keypressed(k) - if k=="escape" then le.quit() - elseif k=="t" then TickCPU(CPU, Memory, 1, true ) - elseif k=="e" then TickCPU(CPU, Memory, 1, false) - elseif k=="r" then RunCPU = not RunCPU - elseif k=="i" then CPU.c.irq = 1 - else KeyboardOnKey(Keyboard, k, true, CPU, Memory) + if k=="escape" 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 + end + end end end +function love.keyreleased(k) + if k~="escape" and UseKeyboard then KeyboardOnKey(Keyboard, k, false, CPU, Memory) end +end diff --git a/emulator/instructions_gen.c b/emulator/instructions_gen.c index 5bfbb12..24e9fb9 100644 --- a/emulator/instructions_gen.c +++ b/emulator/instructions_gen.c @@ -1,6 +1,6 @@ // 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; lni; } +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_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; } @@ -73,9 +73,9 @@ void cpu_instr_51_1(struct CPU* const cpu, struct Memory* const mem) { if(!cpu-> 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_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_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; } @@ -445,6 +445,8 @@ void cpu_instr_241_0(struct CPU* const cpu, struct Memory* const mem) { cpu->rfg 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_255_0(struct CPU* const cpu, struct Memory* const mem) { lni; } CPUInstruction CPUInstructions[256][8] = { @@ -693,8 +695,8 @@ CPUInstruction CPUInstructions[256][8] = { {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}, - {0,0,0,0,0,0,0,0}, - {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}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, diff --git a/emulator/keycodes.lua b/emulator/keycodes.lua index 9e40dc5..fb1aa34 100644 --- a/emulator/keycodes.lua +++ b/emulator/keycodes.lua @@ -18,6 +18,7 @@ return { ["="] = 25, [","] = 26, ["."] = 27, + ["-"] = 28, ["/"] = 29, ["`"] = 30, diff --git a/instructionList.txt b/instructionList.txt index 062bb90..a752f9d 100644 --- a/instructionList.txt +++ b/instructionList.txt @@ -6,6 +6,8 @@ run F1 1 Resume non-interrupt execution brk F3 1 Trigger interrupt irt F4 1 Return from interrupt nop FF 1 Do nothing +ien F5 1 Enbale interrupts +idi F6 1 Disable interrupts 16-bit Inc/Dec (I): inc p 12 1 P++ @@ -127,8 +129,8 @@ rts E1 3 I=*(----S)+1 jpr imm8 31 2 I+=imm8 jnz imm8 30 2 I+=imm8 if !Zero jpz imm8 32 2 I+=imm8 if Zero -jlt imm8 33 2 I+=imm8 if !Carry -jge imm8 34 2 I+=imm8 if Carry +jge imm8 33 2 I+=imm8 if !Carry +jlt imm8 34 2 I+=imm8 if Carry jgt imm8 35 2 I+=imm8 if !Zero & Carry jle imm8 36 2 I+=imm8 if Zero | !Carry @@ -238,7 +240,7 @@ ldq p 8E 1 Q=P lds p 8F 1 S=P ldv p 90 1 V=P -Opcodes used: 226/255 +Opcodes used: 228/255 0123456789ABCDEF 00 | C--------------- 10 | UUIIUIIUUUUUUUUU @@ -255,4 +257,4 @@ B0 | AAAAAAAAAAAAAAAA C0 | BBBBBBBBBBBBWWWW D0 | AAAAAAAAAAAAAAAA E0 | MJJJJJXXXSS----- -F0 | CCCCC----------C +F0 | CCCCCCC--------C diff --git a/readme.txt b/readme.txt index d857140..b3a071c 100644 --- a/readme.txt +++ b/readme.txt @@ -1,5 +1,7 @@ -8608 +8608 - an 8-bit data, 16-bit address, CISC architecture. + +For a list of instructions, see instructionList.txt How to use the assembler: 1. Install bllua3 from https://notabug.org/redo/bllua3 @@ -11,4 +13,6 @@ How to use the assembler: 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 "your_path/assembler-8608.lua" "other_path/filename.asm" -For a list of instructions, see instructionList.txt +How to use the emulator: +1. Install love2d from https://love2d.org +2. Open a command prompt in the "emulator" folder and run "love . C:/path/filename.asm" diff --git a/rom-8608-defs.lua b/rom-8608-defs.lua index 0838e59..e09fc7e 100644 --- a/rom-8608-defs.lua +++ b/rom-8608-defs.lua @@ -130,13 +130,15 @@ operations = { 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; lni;"} }, + { mnem="rst" , opcode=0x00, {"base","intFlgClk","irqFlgClk","runFlgClk","runFlgVal","clearRegs","loadInstr"}, desc="Clear all registers and set I=0", ccode={"cpu.a=0; cpu.b=0; cpu.c=0; cpu.u=0; cpu.t=0; cpu.p=0; cpu.q=0; cpu.s=0; cpu.v=0; cpu.i=0; cpu.cf=0; cpu.nz=0; cpu.irq=0; cpu.ifg=0; cpu.rfg=1; cpu.ien=0; lni;"} }, { mnem="hlt" , opcode=0xF0, {"runFlgClk","instrNext"}, desc="Halt non-interrupt execution", ccode={"cpu.rfg=0; lni;"} }, { mnem="run" , opcode=0xF1, {"runFlgClk","runFlgVal","instrNext"}, desc ="Resume non-interrupt execution", ccode={"cpu.rfg=1; lni;"} }, { mnem="int" , opcode=0xF2, {"instrSwapIV","intFlgVal","intFlgClk","irqFlgClk"}, ccode={"cpu.irq=0; cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=(t-1)%65536; lni;"} }, { mnem="brk" , opcode=0xF3, {"instrSwapIV","adwInc","intFlgVal","intFlgClk"}, desc="Trigger interrupt", ccode={"cpu.ifg=1; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} }, { mnem="irt" , opcode=0xF4, {"instrSwapIV","adwInc","intFlgClk"}, desc="Return from interrupt", ccode={"cpu.ifg=0; int t=cpu.i; cpu.i=cpu.v; cpu.v=t; lni;"} }, { mnem="nop" , opcode=0xFF, {"instrNext"}, desc="Do nothing", ccode={"lni;"}, }, + { mnem="ien" , opcode=0xF5, {"instrNext"}, desc="Enbale interrupts", ccode={"cpu.ien=1; lni;"}, }, + { mnem="idi" , opcode=0xF6, {"instrNext"}, desc="Disable interrupts", ccode={"cpu.ien=0; lni;"}, }, { category = "16-bit Inc/Dec", catlet="I" }, { mnem="inc p" , opcode=0x12, {"adwlP","adwInc","adwSaveP","instrNext"}, desc="P++", ccode={"cpu.p++; lni;"} }, @@ -258,10 +260,10 @@ instructions = { { mnem="jpr imm8" , opcode=0x31, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub1"}, {"jmpRelT"}, desc="I+=imm8", ccode={"loadimmedt","jmprelt"} }, { mnem="jnz imm8" , opcode=0x30, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NZ" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Zero" , ccode={"loadimmedt","if( cpu.nz ) { jmprelt } else { lni }"} }, { mnem="jpz imm8" , opcode=0x32, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0Z" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero" , ccode={"loadimmedt","if(!cpu.nz ) { jmprelt } else { lni }"} }, - { mnem="jlt imm8" , opcode=0x33, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Carry" , ccode={"loadimmedt","if(!cpu.cf ) { jmprelt } else { lni }"} }, - { mnem="jge imm8" , opcode=0x34, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0C" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Carry" , ccode={"loadimmedt","if( cpu.cf ) { jmprelt } else { lni }"} }, - { mnem="jgt imm8" , opcode=0x35, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"jmpRelT"}, {"instrNext"}, desc="I+=imm8 if !Zero & Carry", ccode={"loadimmedt","if( cpu.nz && cpu.cf) { jmprelt } else { lni }"} }, - { mnem="jle imm8" , opcode=0x36, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC","instrNext0Z"}, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero | !Carry", ccode={"loadimmedt","if(!cpu.nz && !cpu.cf) { jmprelt } else { lni }"} }, + { mnem="jge imm8" , opcode=0x33, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0NC" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if !Carry" , ccode={"loadimmedt","if(!cpu.cf ) { jmprelt } else { lni }"} }, + { mnem="jlt imm8" , opcode=0x34, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0C" }, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Carry" , ccode={"loadimmedt","if( cpu.cf ) { jmprelt } else { lni }"} }, + { mnem="jgt imm8" , opcode=0x35, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0C","instrNext0Z"}, {}, {"jmpRelT"}, {"instrNext"}, desc="I+=imm8 if !Zero & Carry", ccode={"loadimmedt","if(cpu.nz && (!cpu.cf)) { jmprelt } else { lni }"} }, + { mnem="jle imm8" , opcode=0x36, jmp=true, rel=true, ncycles=2, {"loadImmed","memSaveT","instrSub23Cond","instrNext0C","instrNext0Z"}, {}, {"instrNext"}, {"jmpRelT"}, desc="I+=imm8 if Zero | !Carry", ccode={"loadimmedt","if((!cpu.nz) || cpu.cf) { jmprelt } else { lni }"} }, { category = "Stack", catlet="S" }, { mnem="psh a" , opcode=0x40, {"pushReg","alurA","instrSub1"}, {"instrNext"}, desc="*(S++)=A", ccode={"pushbyte(cpu.a);","lni;"} },