add memory access highlighting to emulator

This commit is contained in:
Redo 2022-12-07 13:13:17 -06:00
parent 59f7db27f1
commit 4af6f46a51
3 changed files with 64 additions and 43 deletions

View File

@ -36,8 +36,8 @@
#define storeq(x) writememory(cpu->q, x);
#define storeqinc(x) writememory(cpu->q++, x);
#define storeqp1(x) writememory((cpu->q+1)%65536, x);
#define pushretaddr1 writememory(cpu->s++, hibyte(cpu->i));
#define pushretaddr2 writememory(cpu->s++, lobyte(cpu->i));
#define pushretaddr1 writememory(cpu->s++, hibyte((cpu->i-1)%65536));
#define pushretaddr2 writememory(cpu->s++, lobyte((cpu->i-1)%65536));
#define lni 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); }
@ -83,7 +83,7 @@ struct CPU {
int instr;
int cycle;
int instrpre;
int tick;
int frame;
};
struct Event {
int id;
@ -109,7 +109,7 @@ void postEvent(struct Memory* const mem, int id, int addr) {
}
int _readmemory(const struct CPU* const cpu, struct Memory* const mem, const int addr) {
int addr2 = addr%65536;
mem->reads[addr2] = cpu->tick;
mem->reads[addr2] = cpu->frame;
if(mem->onread[addr2]) {
postEvent(mem, mem->onread[addr2], addr2);
}
@ -118,7 +118,7 @@ int _readmemory(const struct CPU* const cpu, struct Memory* const mem, const int
int _writememory(const struct CPU* const cpu, struct Memory* const mem, const int addr, const int data) {
int addr2 = addr%65536;
if(mem->canwrite[addr2]) {
mem->writes[addr2] = cpu->tick;
mem->writes[addr2] = cpu->frame;
mem->data[addr2] = data%256;
}
if(mem->onwrite[addr2]) {

Binary file not shown.

View File

@ -91,11 +91,11 @@ local function RedrawRegDisplay(rd, cpu, mem)
lg.setColor(0,0,0)
lg.rectangle("fill", rd.scrX+reg.x+(rd.fontWidth*(4-reg.w)), rd.scrY+reg.y, rd.fontWidth*reg.w, rd.fontHeight)
lg.setColor(1,1,1)
local val = cpu.data[reg.idx]%(math.pow(16, reg.w))
local val = cpu.c[reg.idx]%(math.pow(16, reg.w))
printValue(val, reg.w, rd.scrX+reg.x, rd.scrY+reg.y, rd.fontWidth)
end
for i, flg in pairs(rd.flags) do
local val = cpu.data[flg.idx]
local val = cpu.c[flg.idx]
if val~=0 then
lg.setColor(1,1,1)
else
@ -122,7 +122,7 @@ local function RedrawStackDisplay(sd, cpu, mem)
lg.rectangle("fill", sd.scrX, sd.scrY, sd.width, sd.height)
lg.setColor(1,1,1)
for i = 1, sd.lines do
local addr = (cpu.data.s-i)%65536
local addr = (cpu.c.s-i)%65536
local val = ReadMemory(mem, addr)
lg.print(string.format("%04X -%2i %02X", addr, i, val), sd.scrX+8, sd.scrY+8+(12*(i-1)))
end
@ -134,7 +134,7 @@ local MemoryDisplays = {
columns = 16, columnSpace = 4, rows = 16,
fontHeight = 12,
showAscii = false,
addr = 0x1000,
addr = 0x0000,
highlightTime = 8,
},
}
@ -145,7 +145,6 @@ local function InitMemoryDisplay(md)
md.height = 12+md.fontHeight*md.rows
lg.print("Memory", md.scrX, md.scrY-16)
lg.rectangle("line", md.scrX, md.scrY, md.width+1, md.height+1)
md.ticksDrawn = {}; for i = 1, md.highlightTime do md.ticksDrawn[i] = 0 end;
end
local function RedrawMemoryDisplay(md, cpu, mem)
lg.setColor(0,0,0)
@ -153,15 +152,15 @@ local function RedrawMemoryDisplay(md, cpu, mem)
lg.setColor(1,1,1)
local highlightAddrs = {}
highlightAddrs[cpu.data.p] = "P"
highlightAddrs[cpu.data.q] = "Q"
highlightAddrs[cpu.data.s] = "S"
highlightAddrs[cpu.data.v] = "V"
highlightAddrs[(cpu.data.i-1)%65536] = "I"
highlightAddrs[cpu.c.p] = "P"
highlightAddrs[cpu.c.q] = "Q"
highlightAddrs[cpu.c.s] = "S"
highlightAddrs[cpu.c.v] = "V"
highlightAddrs[(cpu.c.i-1)%65536] = "I"
local cw = 7
local tickDraw = md.ticksDrawn[1]
local tickDraw = cpu.c.frame-md.highlightTime
for l = 1, md.rows do
local addr = md.addr + (l-1)*md.columns
local lx = md.scrX+8
@ -203,17 +202,16 @@ local function RedrawMemoryDisplay(md, cpu, mem)
end
end
end
table.insert(md.ticksDrawn, cpu.data.tick)
table.remove(md.ticksDrawn, 1)
end
local ProgramDisplay = {
scrX = 8+384+8+128+8, scrY = 32,
fontHeight = 12,
numLines = 35,
highlightTime = 8,
}
local function pdLinesFromDasm(dasm)
local lines, addrLines = {}, {}
local lines, addrLines, lineAddrs = {}, {}, {}
for line in dasm:gmatch("[^\n]+") do
if line~="..." then
local addrh, datah, rest = line:match("^(.+) | (.+) | +(.+)$")
@ -223,19 +221,22 @@ local function pdLinesFromDasm(dasm)
local addr = tonumber(addrh, 16)
if label then
table.insert(lines, " | "..label..":")
--table.insert(lines, " | "..label..":")
table.insert(lines, " | "..label..":")
lineidx = #lines
end
table.insert(lines, addrh.." | "..text)
--table.insert(lines, addrh.." | "..text)
table.insert(lines, addrh.." | "..datah.." | "..text)
local lineidx = #lines
local len = 0; for _ in datah:gfind("[0-9a-fA-F][0-9a-fA-F]") do len = len+1 end;
for i = 1, len do addrLines[addr+i-1] = lineidx end
lineAddrs[lineidx] = addr
else
table.insert(lines, "")
end
end
return lines, addrLines
return lines, addrLines, lineAddrs
end
local function InitProgramDisplay(pd, data, code, arch)
pd.width = 256
@ -246,25 +247,43 @@ local function InitProgramDisplay(pd, data, code, arch)
pd.data = data
pd.code = code
local dasm = asm.disassembleMemory(data, code, arch)
pd.lines, pd.addrLines = pdLinesFromDasm(dasm)
pd.lines, pd.addrLines, pd.lineAddrs = pdLinesFromDasm(dasm)
pd.midLine = math.floor(pd.numLines/2)
end
local function RedrawProgramDisplay(pd, cpu)
local function RedrawProgramDisplay(pd, cpu, mem)
lg.setColor(0,0,0)
lg.rectangle("fill", pd.scrX, pd.scrY, pd.width-1, pd.height-1)
lg.setColor(1,1,1)
local instrAddr = (cpu.data.i-1)%65536
for lineidx = pd.firstLine, pd.firstLine+pd.numLines-1 do
local line = pd.lines[lineidx]
if line then
local x, y = pd.scrX+8, pd.scrY+8+(lineidx-1)*pd.fontHeight
lg.print(line, x, y)
if pd.addrLines[instrAddr]==lineidx then
lg.rectangle("line", x, y, pd.width-18, pd.fontHeight-1)
end
local rectwidth = pd.width-18
local rectheight = pd.fontHeight-1
local tickDraw = cpu.c.frame-pd.highlightTime
local instrAddr = (cpu.c.i-1)%65536
local instrLine = pd.addrLines[instrAddr]
if instrLine then
if pd.firstLine > instrLine then pd.firstLine = math.max(instrLine-pd.midLine, 1)
elseif pd.firstLine+pd.numLines-1 < instrLine then pd.firstLine = math.min(instrLine-pd.numLines+pd.midLine, #pd.lines-pd.numLines+1)
end
end
--lg.print(pd.dasm or "nil", pd.scrX+8, pd.scrY+8)
local screenlineidx = 0
for lineidx = pd.firstLine, pd.firstLine+pd.numLines-1 do
local line = pd.lines[lineidx]
local lineaddr = pd.lineAddrs[lineidx]
if line then
local x, y = pd.scrX+8, pd.scrY+4+screenlineidx*pd.fontHeight
if lineaddr and mem.c.reads[lineaddr] > tickDraw then
lg.rectangle("line", x, y, rectwidth, rectheight)
end
if instrLine==lineidx then
lg.rectangle("fill", x, y, rectwidth, rectheight)
lg.setColor(0,0,0)
end
lg.print(line, x, y)
lg.setColor(1,1,1)
end
screenlineidx = screenlineidx + 1
end
end
local VideoDisplay = {
@ -428,26 +447,27 @@ struct CPU {
int rfg;
int instr;
int cycle;
int tick;
int instrpre;
int frame;
};
int TickCPU(struct CPU* const cpu, struct Memory* const mem, const int count, const int countinstrs);
]]
local CPU = {
data = ffi.new("struct CPU"),
c = ffi.new("struct CPU"),
}
local cpuDll = ffi.load("8608emulator.dll")
local function TickCPU(cpu, mem, count, countinstrs)
local countleft = count
while countleft>0 do
countleft = cpuDll.TickCPU(cpu.data, mem.c, countleft, countinstrs and 1 or 0)
countleft = cpuDll.TickCPU(cpu.c, mem.c, countleft, countinstrs and 1 or 0)
handleEvents(cpu, mem)
end
end
local function InitCPU(cpu)
cpu.data.rfg = 1;
cpu.c.rfg = 1;
end
CPURequestInterrupt = function(cpu)
cpu.data.irq = 1;
cpu.c.irq = 1;
end
----
@ -511,7 +531,7 @@ local function RedrawWindow()
--RedrawVideoDisplay(VideoDisplay, Memory)
RedrawRegDisplay(RegDisplay, CPU, Memory)
RedrawStackDisplay(StackDisplay, CPU, Memory)
RedrawProgramDisplay(ProgramDisplay, CPU)
RedrawProgramDisplay(ProgramDisplay, CPU, Memory)
for _, md in ipairs(MemoryDisplays) do RedrawMemoryDisplay(md, CPU, Memory) end
RedrawFPSCounter(128+32, 4)
@ -531,7 +551,7 @@ function love.load()
InitCharDisplay(CharDisplay)
InitRegDisplay(RegDisplay)
InitStackDisplay(StackDisplay)
local data, code = AssembleToMemory(Memory, "../../8608programs/emutest.asm", Arch)
local data, code = AssembleToMemory(Memory, arg[2] or "../../8608programs/emutest.asm", Arch)
InitProgramDisplay(ProgramDisplay, data, code, Arch)
for _, md in ipairs(MemoryDisplays) do InitMemoryDisplay(md) end
RedrawWindow()
@ -541,7 +561,7 @@ end
local RunCPU = false
local CPUSpeed = 4999
function love.draw()
CPU.data.tick = CPU.data.tick+1
CPU.c.frame = CPU.c.frame + 1
if RunCPU then
TickCPU(CPU, Memory, CPUSpeed, false)
end
@ -550,13 +570,14 @@ function love.draw()
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.data.irq = 1
elseif k=="i" then CPU.c.irq = 1
else KeyboardOnKey(Keyboard, k, true, CPU, Memory)
end
end