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

@@ -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