fix conditions, add ien flag, improve keyboard, add gpio
This commit is contained in:
parent
4af6f46a51
commit
b75ff48300
@ -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.
@ -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
|
||||||
|
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=="r" then RunCPU = not RunCPU
|
||||||
elseif k=="i" then CPU.c.irq = 1
|
elseif k=="i" then CPU.c.irq = 1
|
||||||
else KeyboardOnKey(Keyboard, k, true, CPU, Memory)
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
function love.keyreleased(k)
|
||||||
|
if k~="escape" and UseKeyboard then KeyboardOnKey(Keyboard, k, false, CPU, Memory) end
|
||||||
|
end
|
||||||
|
@ -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},
|
||||||
|
@ -18,6 +18,7 @@ return {
|
|||||||
["="] = 25,
|
["="] = 25,
|
||||||
[","] = 26,
|
[","] = 26,
|
||||||
["."] = 27,
|
["."] = 27,
|
||||||
|
["-"] = 28,
|
||||||
["/"] = 29,
|
["/"] = 29,
|
||||||
["`"] = 30,
|
["`"] = 30,
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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;"} },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user