more emulator features, sub # instr
This commit is contained in:
@@ -4,7 +4,12 @@
|
||||
-- This file deals mostly with the user interface, controls, and high-level functions.
|
||||
-- Emulation of the CPU internals is done by the 8608emulator.dll library. See 8608emulator.c for details.
|
||||
|
||||
-- Number of frames to highlight memory and instructions when they're accessed
|
||||
local MainHighlightTime = 8
|
||||
-- If true, char display renders in default print fallback mode; otherwise, terminal print mode is used
|
||||
local PrintMode = true
|
||||
-- Maximum number of CPU cycles per frame
|
||||
local MaxTicksPerFrame = 555
|
||||
|
||||
require("colorset")
|
||||
local ffi = require("ffi")
|
||||
@@ -17,6 +22,11 @@ local lk = love.keyboard
|
||||
local la = love.audio
|
||||
|
||||
local PlaySound
|
||||
local CPURequestInterrupt
|
||||
local TimerSchedule
|
||||
local TickCPU
|
||||
|
||||
local jsrInstrs = {0x20, 0x2C, 0x0C}
|
||||
|
||||
----
|
||||
local function InitColorset()
|
||||
@@ -220,15 +230,17 @@ local ProgramDisplay = {
|
||||
fontHeight = 12,
|
||||
numLines = 34,
|
||||
highlightTime = MainHighlightTime,
|
||||
maxChars = 30,
|
||||
}
|
||||
local function toPrintableChar(v)
|
||||
if v>=0x20 and v<=0x7E then return string.char(v)
|
||||
else return "\\x"..string.format("%02X", v) end
|
||||
end
|
||||
local function pdLinesFromDasm(dasm)
|
||||
local div = " | "
|
||||
local function pdLinesFromDasm(dasm, maxChars)
|
||||
local div = "|"
|
||||
local lines, addrLines, lineAddrs = {}, {}, {}
|
||||
local function addDasmLine(addr, data, text)
|
||||
text = text:sub(1, maxChars - #div*2 - 8)
|
||||
local dataStr = ""
|
||||
if data then
|
||||
local dt = {}
|
||||
@@ -274,7 +286,7 @@ local function pdLinesFromDasm(dasm)
|
||||
local datastr = {}
|
||||
for v in datah:gfind("[0-9a-fA-F][0-9a-fA-F]") do
|
||||
if #data>=maxlen then
|
||||
addDasmLine(addr+len-#data, data, "\""..table.concat(datastr.."\""))
|
||||
addDasmLine(addr+len-#data, data, "\""..table.concat(datastr).."\"")
|
||||
data = {}
|
||||
datastr = {}
|
||||
end
|
||||
@@ -285,7 +297,7 @@ local function pdLinesFromDasm(dasm)
|
||||
if len<=maxlen then
|
||||
addDasmLine(addr, data, text)
|
||||
elseif #data>0 then
|
||||
addDasmLine(addr+len-#data, data, "\""..table.concat(datastr.."\""))
|
||||
addDasmLine(addr+len-#data, data, "\""..table.concat(datastr).."\"")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -298,7 +310,7 @@ local function InitProgramDisplay(pd, dasmText)
|
||||
lg.print("Program", pd.scrX, pd.scrY-12)
|
||||
lg.rectangle("line", pd.scrX, pd.scrY, pd.width, pd.height)
|
||||
pd.firstLine = 1
|
||||
pd.lines, pd.addrLines, pd.lineAddrs = pdLinesFromDasm(dasmText)
|
||||
pd.lines, pd.addrLines, pd.lineAddrs = pdLinesFromDasm(dasmText, pd.maxChars)
|
||||
pd.midLine = math.floor(pd.numLines/2)
|
||||
pd.init = true
|
||||
end
|
||||
@@ -368,7 +380,7 @@ local function InitCharDisplay(cd)
|
||||
end
|
||||
|
||||
local Keyboard = {
|
||||
addrRange = {0x0500, 0x05FF},
|
||||
addrRange = {0xF100, 0xF1FF},
|
||||
queueSize = 16,
|
||||
queue = {},
|
||||
interrupts = false,
|
||||
@@ -392,7 +404,6 @@ local function KeyboardOnWrite(addr, cpu, mem, kb)
|
||||
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
|
||||
@@ -431,10 +442,11 @@ local function RedrawKeyInfo(x, y, uk, run)
|
||||
printHighlight("[R] "..(run and "Stop" or "Run "), 23, lk.isDown("r"), x, y)
|
||||
if not run then
|
||||
printHighlight("[S] Step" , 33, lk.isDown("s"), x, y)
|
||||
end
|
||||
-- printHighlight("[T] Tick once" , 48, lk.isDown("t"), x, y)
|
||||
printHighlight("[I] Interrupt" , 43, lk.isDown("i"), x, y)
|
||||
printHighlight("[Q] Quit" , 70, lk.isDown("q"), x, y)
|
||||
printHighlight("[X] Step Over" , 43, lk.isDown("x"), x, y)
|
||||
end
|
||||
printHighlight("[I] Interrupt" , 58, lk.isDown("i"), x, y)
|
||||
printHighlight("[Q] Quit" , 73, lk.isDown("q"), x, y)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -471,12 +483,15 @@ local function gpioDiv(addr, cpu, mem, gpio)
|
||||
WriteMemory(mem, base+0x02, math.floor(gpio.divLeft/gpio.divRight))
|
||||
WriteMemory(mem, base+0x03, gpio.divLeft%gpio.divRight)
|
||||
end
|
||||
local function gpioPopcount(v)
|
||||
return 0 -- todo
|
||||
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,
|
||||
[0x04] = function(addr, cpu, mem, gpio) WriteMemory(mem, addr, gpioPopcount(ReadMemory(mem, addr))) end,
|
||||
[0x05] = function(addr, cpu, mem, gpio) gpio.timerCount = 60/10; WriteMemory(mem, addr, 0); end
|
||||
}
|
||||
local function GPIOOnWrite(addr, cpu, mem, gpio)
|
||||
@@ -516,31 +531,124 @@ local function InitConsole(con)
|
||||
con.prevInputIdx = 0
|
||||
con.tempError = nil
|
||||
end
|
||||
local function RedrawConsole(con)
|
||||
local function RedrawConsole(con, kb)
|
||||
lg.setColor(0,0,0)
|
||||
lg.rectangle("fill", con.scrX, con.scrY, con.width, con.height)
|
||||
lg.setColor(1,1,1)
|
||||
lg.rectangle("line", con.scrX, con.scrY, con.width, con.height)
|
||||
if con.blinkFrame < con.blinkFrames/2 then
|
||||
local curx, cury = con.scrX + #con.input*7 + 2, con.scrY+3
|
||||
lg.rectangle("fill", curx, cury, 8, 12)
|
||||
end
|
||||
con.blinkFrame = con.blinkFrame + 1
|
||||
if con.blinkFrame >= con.blinkFrames then con.blinkFrame = 0 end
|
||||
if #con.input==0 then
|
||||
lg.setColor(0.5,0.5,0.5)
|
||||
lg.print(con.tempError or "Type a Command (@addr | addr=byte | addr=byte1 byte2 ...)", con.scrX+2+8, con.scrY+4)
|
||||
else
|
||||
lg.print(con.input, con.scrX+2, con.scrY+4)
|
||||
if not kb then
|
||||
if con.blinkFrame < con.blinkFrames/2 then
|
||||
local curx, cury = con.scrX + #con.input*7 + 2, con.scrY+3
|
||||
lg.rectangle("fill", curx, cury, 8, 12)
|
||||
end
|
||||
con.blinkFrame = con.blinkFrame + 1
|
||||
if con.blinkFrame >= con.blinkFrames then con.blinkFrame = 0 end
|
||||
if #con.input==0 then
|
||||
lg.setColor(0.5,0.5,0.5)
|
||||
lg.print(con.tempError or "Enter Command (>ticks | !addr | @addr | addr=byte | addr=byte1 byte2...)", con.scrX+2+8, con.scrY+4)
|
||||
else
|
||||
lg.print(con.input, con.scrX+2, con.scrY+4)
|
||||
end
|
||||
end
|
||||
end
|
||||
local function ConsoleError(con, err)
|
||||
con.tempError = err
|
||||
end
|
||||
local function ConsoleExec(con, mem)
|
||||
local function conWriteDataBlock(con, mem, addr, data)
|
||||
local writeTime = 2
|
||||
ConsoleError(con, "Writing")
|
||||
for i, byte in ipairs(data) do
|
||||
TimerSchedule((i-1)*writeTime, function()
|
||||
if con.tempError ~= nil then
|
||||
con.tempError = con.tempError .. "."
|
||||
end
|
||||
mem.c.data[(addr+i-1)%65536] = byte
|
||||
PlaySound("write")
|
||||
end)
|
||||
end
|
||||
TimerSchedule((#data-1)*writeTime, function()
|
||||
PlaySound("writeDone")
|
||||
PlaySound("success")
|
||||
ConsoleError(con, "Wrote " .. #data .. " byte" .. (#data>1 and "s" or "") .. " to address $" .. string.format("%04X", addr))
|
||||
end)
|
||||
end
|
||||
local function tickCpuOnce(cpu, mem, byInstr)
|
||||
TickCPU(cpu, mem, 1, byInstr, nil)
|
||||
end
|
||||
local function tickCpuUntil(con, cpu, mem, contfunc, strfunc, donestr, step)
|
||||
con.tempError = ""
|
||||
local tickTime = 1
|
||||
local tickStep, byInstr
|
||||
if step then
|
||||
tickStep = step
|
||||
byInstr = true
|
||||
else
|
||||
tickStep = MaxTicksPerFrame
|
||||
byInstr = false
|
||||
end
|
||||
local i = 1
|
||||
local recFunc
|
||||
recFunc = function()
|
||||
for j = 1, tickStep do
|
||||
if contfunc(i) then
|
||||
tickCpuOnce(cpu, mem, byInstr)
|
||||
else
|
||||
PlaySound("writeDone")
|
||||
PlaySound("success")
|
||||
ConsoleError(con, donestr)
|
||||
return
|
||||
end
|
||||
i = i+1
|
||||
end
|
||||
if con.tempError ~= nil then
|
||||
con.tempError = strfunc(i)
|
||||
end
|
||||
PlaySound("write")
|
||||
TimerSchedule(tickTime, recFunc)
|
||||
end
|
||||
recFunc()
|
||||
end
|
||||
local function tickCpuStepOver(con, cpu, mem, pd)
|
||||
local stepOver = false
|
||||
for _, v in ipairs(jsrInstrs) do
|
||||
if cpu.c.instr == v then
|
||||
stepOver = true
|
||||
end
|
||||
end
|
||||
if not stepOver then
|
||||
tickCpuOnce(cpu, mem, true)
|
||||
return
|
||||
end
|
||||
|
||||
local line = pd.addrLines and pd.addrLines[(cpu.c.i-1)%65536]
|
||||
if not line then
|
||||
tickCpuOnce(cpu, mem, true)
|
||||
return
|
||||
end
|
||||
local addr
|
||||
while not addr do
|
||||
line = line+1
|
||||
local addrs = pd.lineAddrs[line]
|
||||
if not addrs then
|
||||
tickCpuOnce(cpu, mem, true)
|
||||
return
|
||||
end
|
||||
addr = addrs[1]
|
||||
end
|
||||
--print(string.format("%04X", addr))
|
||||
tickCpuUntil(con, cpu, mem,
|
||||
--function() return (cpu.c.i ~= (addr+1)%65536) and (cpu.c.rfg==1) end,
|
||||
function() return (cpu.c.i ~= (addr+1)%65536) end,
|
||||
function() return "Running to address $" .. string.format("%04X", addr) end,
|
||||
nil,
|
||||
nil
|
||||
)
|
||||
end
|
||||
local function ConsoleExec(con, cpu, mem)
|
||||
PlaySound("enter")
|
||||
if con.input=="" then
|
||||
PlaySound("error")
|
||||
con.tempError = nil
|
||||
return
|
||||
end
|
||||
|
||||
@@ -564,6 +672,69 @@ local function ConsoleExec(con, mem)
|
||||
MemoryDisplays[1].addr = addr
|
||||
ConsoleError(con, "Memory display set to address $" .. string.format("%04X", addr))
|
||||
PlaySound("success")
|
||||
elseif ip:sub(1, 1)=="!" then
|
||||
if RunCPU then
|
||||
ConsoleError(con, "CPU must be paused to change execution")
|
||||
PlaySound("error")
|
||||
return
|
||||
end
|
||||
local rest = ip:sub(2, #ip)
|
||||
local addr = tonumber(rest, 16)
|
||||
if not addr then
|
||||
ConsoleError(con, "Error: Expected a hex number")
|
||||
PlaySound("error")
|
||||
return
|
||||
end
|
||||
if addr<0 then addr = 0 end
|
||||
if addr>65535 then addr = 65535 end
|
||||
cpu.c.i = (addr+1)%65536
|
||||
cpu.c.cycle = 0
|
||||
cpu.c.instr = ReadMemory(mem, addr)
|
||||
ConsoleError(con, "CPU instruction pointer set to $" .. string.format("%04X", addr))
|
||||
PlaySound("success")
|
||||
elseif ip:sub(1, 2)==">>" then
|
||||
if RunCPU then
|
||||
ConsoleError(con, "CPU must be paused to step")
|
||||
PlaySound("error")
|
||||
return
|
||||
end
|
||||
local rest = ip:sub(3, #ip)
|
||||
local addr = tonumber(rest, 16)
|
||||
if not addr then
|
||||
ConsoleError(con, "Error: Expected a hex number")
|
||||
PlaySound("error")
|
||||
return
|
||||
end
|
||||
if addr<0 then addr = 0 end
|
||||
if addr>65535 then addr = 65535 end
|
||||
tickCpuUntil(con, cpu, mem,
|
||||
function() return cpu.c.i ~= (addr+1)%65536 end,
|
||||
function() return "Running to address $" .. string.format("%04X", addr) end,
|
||||
"Ran to address " .. string.format("%04X", addr),
|
||||
nil
|
||||
)
|
||||
elseif ip:sub(1, 1)==">" then
|
||||
if RunCPU then
|
||||
ConsoleError(con, "CPU must be paused to single-step")
|
||||
PlaySound("error")
|
||||
return
|
||||
end
|
||||
local rest = ip:sub(2, #ip)
|
||||
local steps = tonumber(rest, 16)
|
||||
if rest=="" then steps = 1 end
|
||||
if not steps then
|
||||
ConsoleError(con, "Error: Expected a hex number")
|
||||
PlaySound("error")
|
||||
return
|
||||
end
|
||||
if steps<1 then steps = 1 end
|
||||
if steps>65535 then steps = 65535 end
|
||||
tickCpuUntil(con, cpu, mem,
|
||||
function(i) return i<=steps; end,
|
||||
function(i) return "Step $"..string.format("%X", i).."/$"..string.format("%X", steps) end,
|
||||
"Ran $" .. string.format("%02X", steps) .. " steps",
|
||||
steps<(MaxTicksPerFrame/4) and steps or nil
|
||||
)
|
||||
elseif ip:find("=") then
|
||||
local addrS, rest = ip:match("^ *([0-9a-fA-F]+) *= *([0-9a-fA-F ]+)$")
|
||||
local addr = tonumber(addrS or "", 16)
|
||||
@@ -582,27 +753,27 @@ local function ConsoleExec(con, mem)
|
||||
end
|
||||
table.insert(data, byte)
|
||||
end
|
||||
for i, byte in ipairs(data) do
|
||||
mem.c.data[(addr+i-1)%65536] = byte
|
||||
PlaySound("write", i)
|
||||
end
|
||||
PlaySound("writeDone", #data)
|
||||
PlaySound("success", #data)
|
||||
ConsoleError(con, "Wrote " .. #data .. " byte" .. (#data>1 and "s" or "") .. " to address $" .. string.format("%04X", addr))
|
||||
|
||||
conWriteDataBlock(con, mem, addr, data)
|
||||
else
|
||||
ConsoleError(con, "Error: Unknown command")
|
||||
PlaySound("error")
|
||||
end
|
||||
end
|
||||
local function shiftDown()
|
||||
return lk.isDown("lshift") or lk.isDown("rshift")
|
||||
end
|
||||
local function ConsoleKey(con, k, mem)
|
||||
local function ConsoleKey(con, k, cpu, mem)
|
||||
local add
|
||||
if k=="backspace" then con.input = con.input:sub(1, #con.input-1)
|
||||
elseif shiftDown() and k=="1" then add = "!"
|
||||
elseif shiftDown() and k=="2" then add = "@"
|
||||
elseif shiftDown() and k=="." then add = ">"
|
||||
elseif k>="0" and k<="9" then add = k
|
||||
elseif #k==1 and k>="a" and k<="f" then add = k:upper()
|
||||
elseif k=="=" then add = "="
|
||||
elseif k=="space" then add = " "
|
||||
elseif k=="return" then ConsoleExec(con, mem)
|
||||
elseif k=="return" then ConsoleExec(con, cpu, mem)
|
||||
elseif k=="up" and con.prevInputs[con.prevInputIdx+1] then
|
||||
if con.prevInputIdx==0 then con.prevInputs[0] = con.input end
|
||||
con.prevInputIdx = con.prevInputIdx + 1
|
||||
@@ -637,6 +808,10 @@ local soundNames = {
|
||||
"success",
|
||||
"write","writeDone",
|
||||
}
|
||||
local soundCounts = {
|
||||
--["step"] = 100,
|
||||
["write"] = 100,
|
||||
}
|
||||
local function InitSound()
|
||||
for _, name in ipairs(soundNames) do
|
||||
local sound = {
|
||||
@@ -645,33 +820,36 @@ local function InitSound()
|
||||
lastPlayed = 0,
|
||||
}
|
||||
local fn = "content/" .. name .. ".wav"
|
||||
for i = 1, 4 do
|
||||
for i = 1, soundCounts[name] or 4 do
|
||||
table.insert(sound.sources, la.newSource(fn, "static"))
|
||||
end
|
||||
Sounds[name] = sound
|
||||
end
|
||||
end
|
||||
local SoundFrame = 0
|
||||
local QueuedSounds = {}
|
||||
PlaySound = function(name, delay)
|
||||
if (not delay) or delay==0 then
|
||||
local sound = Sounds[name] or error("no sound with name: " .. name)
|
||||
sound.lastPlayed = (sound.lastPlayed % #sound.sources) + 1
|
||||
sound.sources[sound.lastPlayed]:play()
|
||||
else
|
||||
local time = SoundFrame + delay
|
||||
QueuedSounds[time] = QueuedSounds[time] or {}
|
||||
table.insert(QueuedSounds[time], name)
|
||||
end
|
||||
PlaySound = function(name)
|
||||
local sound = Sounds[name] or error("no sound with name: " .. name)
|
||||
sound.lastPlayed = (sound.lastPlayed % #sound.sources) + 1
|
||||
sound.sources[sound.lastPlayed]:play()
|
||||
end
|
||||
local function UpdateSound()
|
||||
if QueuedSounds[SoundFrame] then
|
||||
for _, name in ipairs(QueuedSounds[SoundFrame]) do
|
||||
PlaySound(name)
|
||||
|
||||
----
|
||||
-- Timer
|
||||
|
||||
local TimerFrame = 0
|
||||
local TimerSchedules = {}
|
||||
TimerSchedule = function(time, func)
|
||||
local frame = TimerFrame + time
|
||||
TimerSchedules[frame] = TimerSchedules[frame] or {}
|
||||
table.insert(TimerSchedules[frame], func)
|
||||
end
|
||||
local function UpdateTimer()
|
||||
if TimerSchedules[TimerFrame] then
|
||||
for _, func in ipairs(TimerSchedules[TimerFrame]) do
|
||||
func()
|
||||
end
|
||||
QueuedSounds[SoundFrame] = nil
|
||||
TimerSchedules[TimerFrame] = nil
|
||||
end
|
||||
SoundFrame = SoundFrame + 1
|
||||
TimerFrame = TimerFrame + 1
|
||||
end
|
||||
|
||||
|
||||
@@ -777,7 +955,7 @@ local CPU = {
|
||||
c = ffi.new("struct CPU"),
|
||||
}
|
||||
local cpuDll = ffi.load("8608emulator.dll")
|
||||
local function TickCPU(cpu, mem, count, countinstrs, breakaddr)
|
||||
TickCPU = function(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)
|
||||
@@ -792,10 +970,6 @@ CPURequestInterrupt = function(cpu)
|
||||
cpu.c.irq = 1;
|
||||
end
|
||||
|
||||
function RunToNextInstr(cpu)
|
||||
|
||||
end
|
||||
|
||||
----
|
||||
|
||||
--local function RedrawVideoDisplay(vd, mem)
|
||||
@@ -825,20 +999,32 @@ local function RedrawCharDisplay(cd, mem)
|
||||
local acolor = cd.addrColor + abase
|
||||
local colormem = ReadMemory(mem, acolor)
|
||||
local colorid = colormem%64
|
||||
local highlight = colormem>=128
|
||||
local highlight = PrintMode or colormem>=128
|
||||
lg.setColor(ColorSet[colorid])
|
||||
local scrx = cd.scrX + cx*cd.fontWidth
|
||||
local scry = cd.scrY + cy*cd.fontHeight
|
||||
local scrw = cd.fontWidth
|
||||
local scrh = cd.fontHeight
|
||||
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)
|
||||
lg.rectangle("fill", scrx, scry, scrw, scrh)
|
||||
if PrintMode then lg.setColor(1,1,1) else lg.setColor(0,0,0) end
|
||||
end
|
||||
local val = ReadMemory(mem, achar)%128
|
||||
if val>=32 then
|
||||
if val>=0x20 and val<=0x7F then -- printable ascii
|
||||
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
|
||||
lg.print(char, scrx, scry)
|
||||
elseif val>=0x10 and val<=0x17 then -- solid color
|
||||
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)
|
||||
lg.rectangle("fill", scrx, scry, scrw, scrh)
|
||||
elseif val>=0x80 and val<=0x8F then -- 2x2 pixels
|
||||
lg.setColor(0,0,0)
|
||||
if val %2==1 then lg.rectangle("fill", scrx+scrw/2, scry+scrh/2, scrw/2, scrh/2) end -- bottom right
|
||||
if math.floor(val/2)%2==1 then lg.rectangle("fill", scrx , scry+scrh/2, scrw/2, scrh/2) end -- bottom left
|
||||
if math.floor(val/4)%2==1 then lg.rectangle("fill", scrx+scrw/2, scry , scrw/2, scrh/2) end -- top right
|
||||
if math.floor(val/4)%2==1 then lg.rectangle("fill", scrx , scry , scrw/2, scrh/2) end -- top left
|
||||
elseif val>=0xA0 and val<=0xDF then -- kana
|
||||
-- todo
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -861,9 +1047,9 @@ local function RedrawWindow(usekeyboard, runcpu)
|
||||
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)
|
||||
RedrawConsole(Console)
|
||||
RedrawFPSCounter(128, 4)
|
||||
RedrawKeyInfo(128+64+16, 4, usekeyboard, runcpu)
|
||||
RedrawConsole(Console, usekeyboard)
|
||||
|
||||
lg.setCanvas()
|
||||
end
|
||||
@@ -955,13 +1141,14 @@ local function endFrame()
|
||||
end
|
||||
|
||||
local RunCPU = false
|
||||
local CPUSpeed = 555
|
||||
local CPUSpeed = MaxTicksPerFrame
|
||||
local UseKeyboard = false
|
||||
function love.draw()
|
||||
startFrame()
|
||||
|
||||
UpdateTimer()
|
||||
|
||||
UpdateGPIO(GPIO, CPU, Memory)
|
||||
UpdateSound()
|
||||
|
||||
CPU.c.frame = CPU.c.frame + 1
|
||||
if RunCPU then
|
||||
@@ -984,14 +1171,14 @@ function love.keypressed(k)
|
||||
KeyboardOnKey(Keyboard, k, true, CPU, Memory)
|
||||
else
|
||||
if k=="q" then le.quit()
|
||||
elseif k=="s" and not RunCPU then TickCPU(CPU, Memory, 1, true , nil); PlaySound("step");
|
||||
elseif k=="s" and (not RunCPU) then tickCpuOnce(CPU, Memory, true); PlaySound("step");
|
||||
elseif k=="x" and (not RunCPU) then tickCpuStepOver(Console, CPU, Memory, ProgramDisplay); PlaySound("step");
|
||||
--elseif k=="t" then TickCPU(CPU, Memory, 1, false, nil)
|
||||
--elseif k=="o" then RunToNextInstr(cpu)
|
||||
elseif k=="r" then RunCPU = not RunCPU; PlaySound(RunCPU and "runOn" or "runOff");
|
||||
elseif k=="i" then CPU.c.irq = 1; PlaySound("interrupt");
|
||||
--elseif k=="u" then CPU.c.rfg = 1
|
||||
else
|
||||
ConsoleKey(Console, k, Memory)
|
||||
ConsoleKey(Console, k, CPU, Memory)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user