mirror of
https://git.k-space.ee/arti/vt1200.git
synced 2026-11-01 12:14:56 +02:00
152 lines
4.3 KiB
Lua
152 lines
4.3 KiB
Lua
-- load_mame.lua -- debugger entry for the Bad Apple payload.
|
|
--
|
|
-- Loads the payload at bit 0x018C0000 and the movie at bit 0x00080000, then
|
|
-- enters the payload at the OS idle loop. This is the development path; the
|
|
-- real delivery path is tools/load.sh (rdebug + LANCE).
|
|
--
|
|
-- Env:
|
|
-- BA_MODE=one|play (one is the only mode implemented here)
|
|
-- BA_MOVIE movie file (default bad-apple/data/test_movie.bin)
|
|
-- BA_PAYLOAD raw payload (default bad-apple/player/build/player.bin)
|
|
-- BA_ENV player.env with ENTRY_PTR (default .../player.env)
|
|
-- BA_AT load frame (default 2500)
|
|
-- BA_END inspection/exit frame (default 2600)
|
|
|
|
local function hex(v, w)
|
|
return string.format("%0" .. (w or 8) .. "X", v)
|
|
end
|
|
|
|
local machine = manager.machine
|
|
local cpu = machine.devices[':maincpu']
|
|
local dbg = machine.debugger
|
|
local prog = cpu.spaces['program']
|
|
|
|
if not dbg then
|
|
print("BA ERROR: debugger not enabled; pass -debug")
|
|
machine:exit()
|
|
return
|
|
end
|
|
|
|
local ORIGIN = 0x018C0000
|
|
local MOVIE = 0x00080000
|
|
local MARK = 0x01810000
|
|
local ENTRY_PC = 0x3F579970
|
|
local AT = tonumber(os.getenv("BA_AT") or "2500")
|
|
local STOP_AT = tonumber(os.getenv("BA_END") or "2600")
|
|
local MOVIE_PATH = os.getenv("BA_MOVIE") or "bad-apple/data/test_movie.bin"
|
|
local PAYLOAD_PATH = os.getenv("BA_PAYLOAD") or "bad-apple/player/build/player.bin"
|
|
local ENV_PATH = os.getenv("BA_ENV") or "bad-apple/player/build/player.env"
|
|
|
|
local function read_all(path)
|
|
local f, err = io.open(path, "rb")
|
|
if not f then
|
|
print("BA ERROR: cannot open " .. path .. ": " .. tostring(err))
|
|
machine:exit()
|
|
return nil
|
|
end
|
|
local data = f:read("*a")
|
|
f:close()
|
|
return data
|
|
end
|
|
|
|
local function entry_from_env()
|
|
local explicit = os.getenv("BA_ENTRY")
|
|
if explicit then
|
|
return tonumber(explicit)
|
|
end
|
|
local f = io.open(ENV_PATH, "r")
|
|
if not f then
|
|
return ORIGIN
|
|
end
|
|
for line in f:lines() do
|
|
local value = line:match("ENTRY_PTR=0x(%x+)")
|
|
if value then
|
|
f:close()
|
|
return tonumber(value, 16)
|
|
end
|
|
end
|
|
f:close()
|
|
return ORIGIN
|
|
end
|
|
|
|
local payload = read_all(PAYLOAD_PATH)
|
|
local movie = read_all(MOVIE_PATH)
|
|
if not payload or not movie then
|
|
return
|
|
end
|
|
local entry = entry_from_env()
|
|
print(string.format("BA: payload %d bytes, movie %d bytes, entry %s",
|
|
#payload, #movie, hex(entry)))
|
|
|
|
local function write_bytes(data, base)
|
|
local i
|
|
for i = 0, #data - 1 do
|
|
prog:write_u8(base + i * 8, data:byte(i + 1))
|
|
end
|
|
end
|
|
|
|
local function verify(data, base)
|
|
local i
|
|
for i = 0, #data - 1 do
|
|
if prog:read_u8(base + i * 8) ~= data:byte(i + 1) then
|
|
return false, i
|
|
end
|
|
end
|
|
return true, 0
|
|
end
|
|
|
|
local loaded = false
|
|
local entered = false
|
|
local done = false
|
|
local frames = 0
|
|
|
|
local function load_and_enter()
|
|
write_bytes(payload, ORIGIN)
|
|
write_bytes(movie, MOVIE)
|
|
local ok, bad = verify(payload, ORIGIN)
|
|
if not ok then
|
|
print("BA ERROR: payload readback mismatch at byte " .. bad)
|
|
machine:exit()
|
|
return
|
|
end
|
|
ok, bad = verify(movie, MOVIE)
|
|
if not ok then
|
|
print("BA ERROR: movie readback mismatch at byte " .. bad)
|
|
machine:exit()
|
|
return
|
|
end
|
|
print("BA: loaded; breakpoint at " .. hex(ENTRY_PC))
|
|
dbg:command("bpset " .. hex(ENTRY_PC) .. ",,{ pc = " .. hex(entry) .. " ; g }")
|
|
end
|
|
|
|
emu.register_frame_done(function()
|
|
frames = frames + 1
|
|
if frames == AT and not loaded then
|
|
loaded = true
|
|
load_and_enter()
|
|
end
|
|
if loaded and not entered and prog:read_u16(MARK) == 0x0000
|
|
and prog:read_u16(MARK + 0x10 * 8) == 0x0001 then
|
|
entered = true
|
|
done = true
|
|
print(string.format("BA: STATUS=painted at frame %d; FRAME=%d",
|
|
frames, prog:read_u16(MARK)))
|
|
end
|
|
if loaded and not done and frames > AT + 30 then
|
|
local err = prog:read_u32(MARK)
|
|
if err ~= 0 then
|
|
print(string.format("BA ERROR: marker %s at frame %d",
|
|
hex(err), frames))
|
|
machine:exit()
|
|
end
|
|
end
|
|
if frames >= STOP_AT then
|
|
print(string.format("BA: end at frame %d (loaded=%s done=%s)",
|
|
frames, tostring(loaded), tostring(done)))
|
|
machine:exit()
|
|
end
|
|
end, "vt1200-badapple-loader")
|
|
|
|
dbg.visible_cpu = cpu
|
|
dbg.execution_state = 'run'
|