fix conditions, add ien flag, improve keyboard, add gpio

This commit is contained in:
Redo 2023-01-04 13:29:55 -06:00
parent 4af6f46a51
commit b75ff48300
8 changed files with 160 additions and 53 deletions

View File

@ -42,7 +42,7 @@
#define ldi 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); cpu->cf=x>=256; x&=0xFF; setzf(x); } #define addf(x,y) { x=(x+y); cpu->cf=x>=256; x&=0xFF; setzf(x); }
#define subf(x,y) addf(x,-y); #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<<y)|(x>>(8-y)); #define rol(x,y) x=(x<<y)|(x>>(8-y));
#define ror(x,y) x=(x>>y)|(x<<(8-y)); #define ror(x,y) x=(x>>y)|(x<<(8-y));
#define sra(x,y) x=(x>>y); #define sra(x,y) x=(x>>y);
@ -80,6 +80,7 @@ struct CPU {
int irq; int irq;
int ifg; int ifg;
int rfg; int rfg;
int ien;
int instr; int instr;
int cycle; int cycle;
int instrpre; int instrpre;
@ -130,14 +131,15 @@ typedef void(*CPUInstruction)(struct CPU* const cpu, struct Memory* const mem);
#include "instructions_gen.c" #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; int i = 0;
while(i<count) { while(i<count) {
if(cpu->irq && !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) { if(cpu->rfg || cpu->ifg || cpu->irq) {
CPUInstruction instr = CPUInstructions[cpu->instr][cpu->cycle]; CPUInstruction instr = CPUInstructions[cpu->instr][cpu->cycle];
if(instr) instr(cpu, mem); if(instr) instr(cpu, mem);
if(!countinstrs || cpu->cycle==0) { i++; } if(!countinstrs || cpu->cycle==0) { i++; }
if(cpu->i==breakaddr) { i = count; break; }
} else { i = count; break; } } else { i = count; break; }
if(mem->numevents!=0) { break; } if(mem->numevents!=0) { break; }
} }

Binary file not shown.

View File

@ -11,6 +11,7 @@ local lg = love.graphics
local li = love.image local li = love.image
local le = love.event local le = love.event
local lt = love.timer local lt = love.timer
local lk = love.keyboard
---- ----
local function InitColorset() local function InitColorset()
@ -43,7 +44,7 @@ local function handleEvents(cpu, mem)
end end
local RegDisplay = { local RegDisplay = {
scrX = 384+16, scrY = 32, scrX = 384+16, scrY = 32+8,
width = 128, height = 192, width = 128, height = 192,
fontWidth = 8, fontHeight = 12, fontWidth = 8, fontHeight = 12,
registers = { registers = {
@ -63,7 +64,8 @@ local RegDisplay = {
flags = { flags = {
{ name = "CF" , idx = "cf" , x=64+8,y=8 }, { name = "CF" , idx = "cf" , x=64+8,y=8 },
{ name = "NZ" , idx = "nz" , x=64+8,y=8+16 }, { 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 = "Int", idx = "ifg", x=64+8,y=8+16*3},
{ name = "Run", idx = "rfg", x=64+8,y=8+16*4}, { name = "Run", idx = "rfg", x=64+8,y=8+16*4},
}, },
@ -107,8 +109,9 @@ local function RedrawRegDisplay(rd, cpu, mem)
end end
local ReadMemory local ReadMemory
local WriteMemory
local StackDisplay = { 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, lines = 16, fontHeight = 12,
} }
local function InitStackDisplay(sd) local function InitStackDisplay(sd)
@ -130,11 +133,11 @@ end
local MemoryDisplays = { local MemoryDisplays = {
{ {
scrX = 8, scrY = 32+192+32, scrX = 8, scrY = 32+192+32-4,
columns = 16, columnSpace = 4, rows = 16, columns = 16, columnSpace = 4, rows = 16,
fontHeight = 12, fontHeight = 12,
showAscii = false, showAscii = false,
addr = 0x0000, addr = 0x3000,
highlightTime = 8, highlightTime = 8,
}, },
} }
@ -205,9 +208,9 @@ local function RedrawMemoryDisplay(md, cpu, mem)
end end
local ProgramDisplay = { local ProgramDisplay = {
scrX = 8+384+8+128+8, scrY = 32, scrX = 8+384+8+128+8, scrY = 32+8,
fontHeight = 12, fontHeight = 12,
numLines = 35, numLines = 34,
highlightTime = 8, highlightTime = 8,
} }
local function pdLinesFromDasm(dasm) local function pdLinesFromDasm(dasm)
@ -301,20 +304,12 @@ local CharDisplay = {
width = 64*6, height = 16*12, width = 64*6, height = 16*12,
rows = 16, cols = 64, rows = 16, cols = 64,
fontWidth = 6, fontHeight = 12, fontWidth = 6, fontHeight = 12,
scrX = 8, scrY = 32, scrX = 8, scrY = 32+8,
addrChar = 0x0800, addrChar = 0x0800,
addrColor = 0x0C00, addrColor = 0x0C00,
} }
local function InitCharDisplay(cd) local function InitCharDisplay(cd)
lg.print("Char Display", cd.scrX, cd.scrY-16) 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") cd.font = lg.newFont("consola.ttf", cd.fontHeight-1, "mono")
end end
@ -346,19 +341,92 @@ local keycodes = require("keycodes")
local CPURequestInterrupt local CPURequestInterrupt
local function KeyboardOnKey(kb, key, press, cpu, mem) local function KeyboardOnKey(kb, key, press, cpu, mem)
local code = keycodes[key] or keycodes["invalid"] 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 if #kb.queue > kb.queueSize then table.remove(kb.queue, 1) end
kb.queueEmpty = false kb.queueEmpty = false
kbSetNext(kb, cpu, mem) kbSetNext(kb, cpu, mem)
if kb.interrupts then CPURequestInterrupt(cpu) end if kb.interrupts then CPURequestInterrupt(cpu) end
end end
local function RedrawFPSCounter(x,y) local function RedrawFPSCounter(x, y)
lg.setColor(0,0,0) lg.setColor(0,0,0)
lg.rectangle("fill",x,y,64,12) lg.rectangle("fill",x,y,64,12)
lg.setColor(1,1,1) lg.setColor(1,1,1)
lg.print("FPS: "..lt.getFPS(), x,y) lg.print("FPS: "..lt.getFPS(), x,y)
end 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 = { local peripherals = {
CharDisplay = { range = {0x0800, 0x0FFF}, write = true }, CharDisplay = { range = {0x0800, 0x0FFF}, write = true },
@ -371,6 +439,9 @@ local peripherals = {
onread = function(addr, cpu, mem) KeyboardOnRead (addr, cpu, mem, Keyboard) end, onread = function(addr, cpu, mem) KeyboardOnRead (addr, cpu, mem, Keyboard) end,
onwrite = function(addr, cpu, mem) KeyboardOnWrite(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) ReadMemory = function(mem, addr)
return mem.c.data[addr%65536]%256 return mem.c.data[addr%65536]%256
end end
local function WriteMemory(mem, addr, val) WriteMemory = function(mem, addr, val)
if mem.c.canwrite[addr%65536]~=0 then if mem.c.canwrite[addr%65536]~=0 then
mem.c.data[addr%65536] = val%256 mem.c.data[addr%65536] = val%256
end end
@ -445,21 +516,22 @@ struct CPU {
int irq; int irq;
int ifg; int ifg;
int rfg; int rfg;
int ien;
int instr; int instr;
int cycle; int cycle;
int instrpre; int instrpre;
int frame; 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 = { local CPU = {
c = ffi.new("struct CPU"), c = ffi.new("struct CPU"),
} }
local cpuDll = ffi.load("8608emulator.dll") local cpuDll = ffi.load("8608emulator.dll")
local function TickCPU(cpu, mem, count, countinstrs) local function TickCPU(cpu, mem, count, countinstrs, breakaddr)
local countleft = count local countleft = count
while countleft>0 do 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) handleEvents(cpu, mem)
end end
end end
@ -470,6 +542,10 @@ CPURequestInterrupt = function(cpu)
cpu.c.irq = 1; cpu.c.irq = 1;
end end
function RunToNextInstr(cpu)
end
---- ----
local function RedrawVideoDisplay(vd, mem) local function RedrawVideoDisplay(vd, mem)
@ -497,9 +573,11 @@ local function RedrawCharDisplay(cd, mem)
local abase = cy*cd.cols + cx local abase = cy*cd.cols + cx
local achar = cd.addrChar + abase local achar = cd.addrChar + abase
local acolor = cd.addrColor + 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]) 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.rectangle("fill", cd.scrX + cx*cd.fontWidth, cd.scrY + cy*cd.fontHeight, cd.fontWidth, cd.fontHeight)
lg.setColor(0, 0, 0) lg.setColor(0, 0, 0)
end end
@ -524,7 +602,7 @@ local function InitWindowCanvas()
lg.setFont(InfoFont) lg.setFont(InfoFont)
lg.print("8608 CPU Emulator", 4, 4) lg.print("8608 CPU Emulator", 4, 4)
end end
local function RedrawWindow() local function RedrawWindow(usekeyboard, runcpu)
lg.setCanvas(WindowCanvas) lg.setCanvas(WindowCanvas)
lg.setFont(InfoFont) lg.setFont(InfoFont)
RedrawCharDisplay(CharDisplay, Memory) RedrawCharDisplay(CharDisplay, Memory)
@ -534,6 +612,7 @@ local function RedrawWindow()
RedrawProgramDisplay(ProgramDisplay, CPU, Memory) RedrawProgramDisplay(ProgramDisplay, CPU, Memory)
for _, md in ipairs(MemoryDisplays) do RedrawMemoryDisplay(md, CPU, Memory) end for _, md in ipairs(MemoryDisplays) do RedrawMemoryDisplay(md, CPU, Memory) end
RedrawFPSCounter(128+32, 4) RedrawFPSCounter(128+32, 4)
RedrawKeyInfo(128+32+64+16, 4, usekeyboard, runcpu)
lg.setCanvas() lg.setCanvas()
end end
@ -547,6 +626,7 @@ function love.load()
InitMemory(Memory, peripherals) InitMemory(Memory, peripherals)
InitWindowCanvas() InitWindowCanvas()
InitCPU(CPU) InitCPU(CPU)
InitGPIO(GPIO)
--InitVideoDisplay(VideoDisplay) --InitVideoDisplay(VideoDisplay)
InitCharDisplay(CharDisplay) InitCharDisplay(CharDisplay)
InitRegDisplay(RegDisplay) InitRegDisplay(RegDisplay)
@ -560,24 +640,38 @@ end
local RunCPU = false local RunCPU = false
local CPUSpeed = 4999 local CPUSpeed = 4999
local UseKeyboard = false
function love.draw() function love.draw()
UpdateGPIO(GPIO, CPU, Memory)
CPU.c.frame = CPU.c.frame + 1 CPU.c.frame = CPU.c.frame + 1
if RunCPU then if RunCPU then
TickCPU(CPU, Memory, CPUSpeed, false) TickCPU(CPU, Memory, CPUSpeed, false, nil)
end end
RedrawWindow() RedrawWindow(UseKeyboard, RunCPU)
lg.setColor(1,1,1) lg.setColor(1,1,1)
lg.draw(WindowCanvas, 0, 0, 0, 2, 2) lg.draw(WindowCanvas, 0, 0, 0, 2, 2)
lg.print(CPU.c.frame)
end end
function love.keypressed(k) function love.keypressed(k)
if k=="escape" then le.quit() if k=="escape" then
elseif k=="t" then TickCPU(CPU, Memory, 1, true ) UseKeyboard = not UseKeyboard
elseif k=="e" then TickCPU(CPU, Memory, 1, false) else
elseif k=="r" then RunCPU = not RunCPU if UseKeyboard then
elseif k=="i" then CPU.c.irq = 1 KeyboardOnKey(Keyboard, k, true, CPU, Memory)
else 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
end end
function love.keyreleased(k)
if k~="escape" and UseKeyboard then KeyboardOnKey(Keyboard, k, false, CPU, Memory) end
end

View File

@ -1,6 +1,6 @@
// Auto-generated by gendefs.lua // 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_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_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_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_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_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_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_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_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_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_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_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_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_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; } void cpu_instr_255_0(struct CPU* const cpu, struct Memory* const mem) { lni; }
CPUInstruction CPUInstructions[256][8] = { 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_242_0,0,0,0,0,0,0,0},
{cpu_instr_243_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_244_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},
{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}, {0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0},

View File

@ -18,6 +18,7 @@ return {
["="] = 25, ["="] = 25,
[","] = 26, [","] = 26,
["."] = 27, ["."] = 27,
["-"] = 28,
["/"] = 29, ["/"] = 29,
["`"] = 30, ["`"] = 30,

View File

@ -6,6 +6,8 @@ run F1 1 Resume non-interrupt execution
brk F3 1 Trigger interrupt brk F3 1 Trigger interrupt
irt F4 1 Return from interrupt irt F4 1 Return from interrupt
nop FF 1 Do nothing nop FF 1 Do nothing
ien F5 1 Enbale interrupts
idi F6 1 Disable interrupts
16-bit Inc/Dec (I): 16-bit Inc/Dec (I):
inc p 12 1 P++ inc p 12 1 P++
@ -127,8 +129,8 @@ rts E1 3 I=*(----S)+1
jpr imm8 31 2 I+=imm8 jpr imm8 31 2 I+=imm8
jnz imm8 30 2 I+=imm8 if !Zero jnz imm8 30 2 I+=imm8 if !Zero
jpz imm8 32 2 I+=imm8 if Zero jpz imm8 32 2 I+=imm8 if Zero
jlt imm8 33 2 I+=imm8 if !Carry jge imm8 33 2 I+=imm8 if !Carry
jge imm8 34 2 I+=imm8 if Carry jlt imm8 34 2 I+=imm8 if Carry
jgt imm8 35 2 I+=imm8 if !Zero & Carry jgt imm8 35 2 I+=imm8 if !Zero & Carry
jle imm8 36 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 lds p 8F 1 S=P
ldv p 90 1 V=P ldv p 90 1 V=P
Opcodes used: 226/255 Opcodes used: 228/255
0123456789ABCDEF 0123456789ABCDEF
00 | C--------------- 00 | C---------------
10 | UUIIUIIUUUUUUUUU 10 | UUIIUIIUUUUUUUUU
@ -255,4 +257,4 @@ B0 | AAAAAAAAAAAAAAAA
C0 | BBBBBBBBBBBBWWWW C0 | BBBBBBBBBBBBWWWW
D0 | AAAAAAAAAAAAAAAA D0 | AAAAAAAAAAAAAAAA
E0 | MJJJJJXXXSS----- E0 | MJJJJJXXXSS-----
F0 | CCCCC----------C F0 | CCCCCCC--------C

View File

@ -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: How to use the assembler:
1. Install bllua3 from https://notabug.org/redo/bllua3 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: 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" 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"

View File

@ -130,13 +130,15 @@ operations = {
instructions = { instructions = {
{ category = "Control", catlet="C" }, { 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="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="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="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="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="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="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" }, { category = "16-bit Inc/Dec", catlet="I" },
{ mnem="inc p" , opcode=0x12, {"adwlP","adwInc","adwSaveP","instrNext"}, desc="P++", ccode={"cpu.p++; lni;"} }, { 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="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="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="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=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="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","instrNext0NC","instrNext0Z"}, {}, {"jmpRelT"}, {"instrNext"}, desc="I+=imm8 if !Zero & Carry", ccode={"loadimmedt","if( cpu.nz && 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","instrNext0NC","instrNext0Z"}, {}, {"instrNext"}, {"jmpRelT"}, 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" }, { category = "Stack", catlet="S" },
{ mnem="psh a" , opcode=0x40, {"pushReg","alurA","instrSub1"}, {"instrNext"}, desc="*(S++)=A", ccode={"pushbyte(cpu.a);","lni;"} }, { mnem="psh a" , opcode=0x40, {"pushReg","alurA","instrSub1"}, {"instrNext"}, desc="*(S++)=A", ccode={"pushbyte(cpu.a);","lni;"} },