M = manager.machine CPU = M.devices[":maincpu"] SP = CPU.spaces["program"] FLAG,STAT,NREAD,BUF = 0x18000,0x18004,0x18008,0x20000 TOTAL = 16*65536 local f=io.open("bench.bin","rb"); local d=f:read("a"); f:close() CODE={} ; for i=1,#d do CODE[i]=string.byte(d,i) end print("[BENCH] loaded bench.bin bytes="..#d) STATE,T0,NFIRE = "wait",nil,0 local function T() local t=M.time return t.seconds + t.attoseconds/1e18 end local function P(s) print("[BENCH] "..s) end local function tick() NFIRE = NFIRE + 1 if NFIRE==1 then P("notifier firing OK") end local t=T() if STATE=="wait" then if t < 5.0 then return end for i=1,#CODE do SP:write_u8(0x10000+i-1, CODE[i]) end SP:write_u32(FLAG,0); SP:write_u32(STAT,0); SP:write_u32(NREAD,0); SP:write_u32(BUF,0) CPU.state["SR"].value=0x2000 CPU.state["SP"].value=0x8000 CPU.state["PC"].value=0x10000 STATE="run" P(string.format("injected t=%.3f frames=%d",t,NFIRE)) return end if STATE=="run" then local fl=SP:read_u32(FLAG) if fl==1 and not T0 then T0=t; P(string.format("started t=%.4f",t)) end if fl==0xFF then STATE="done" local dt=t-(T0 or t) P(string.format("DONE reads=%d status=%08X",SP:read_u32(NREAD),SP:read_u32(STAT))) P(string.format("elapsed=%.4f s bytes=%d",dt,TOTAL)) if dt>0 then P(string.format("THROUGHPUT = %.1f KB/s",TOTAL/1024/dt)) end P(string.format("buf=%08X %08X",SP:read_u32(BUF),SP:read_u32(BUF+4))) M:exit() elseif fl==0xEE then STATE="done"; P(string.format("READ FAILED status=%08X reads=%d",SP:read_u32(STAT),SP:read_u32(NREAD))); M:exit() elseif t>25 then STATE="done" P(string.format("TIMEOUT flag=%08X status=%08X reads=%d PC=%08X SR=%04X", fl,SP:read_u32(STAT),SP:read_u32(NREAD),CPU.state["PC"].value,CPU.state["SR"].value)) M:exit() end end end SUB = emu.add_machine_frame_notifier(function() local ok,err = pcall(tick) if not ok then print("[BENCH] LUA ERROR: "..tostring(err)); M:exit() end end) print("[BENCH] subscription="..tostring(SUB))