feat(badapple): full 30s stream and MAME exactness

This commit is contained in:
arti committed 2026-11-01 10:16:12 +02:00
1 parent 150a6d86c0
commit 116356a975
7 files changed
+102 -33

No files matched your search

+31
View File
@@ -0,0 +1,31 @@
{
"cost_us": {
"max": 37991,
"mean": 7472.0695503699535,
"p50": 7948,
"p95": 12011
},
"data_bytes": 2401942,
"dirty_tiles": {
"max": 320,
"mean": 44.899829254410925,
"p50": 47,
"p95": 72
},
"display_hz": 72,
"dropped": 43,
"frame_count": 1757,
"height": 512,
"rects": {
"max": 1175,
"mean": 393.14968696642,
"p50": 409,
"p95": 670
},
"scale": 2,
"source_fps": 60,
"source_frames": 1800,
"tile": 32,
"video": "/tmp/opencode/badapple-real/hd60.mp4",
"width": 640
}
+5
View File
@@ -39,6 +39,11 @@ _fill_run_:
move *sp+, b2, 1
rets
.globl _vid_dint_
_vid_dint_:
dint
rets
.globl _fill_init_
_fill_init_:
setf 32, 0, 1
+10
View File
@@ -11,9 +11,12 @@
#define CTRL_PACE (MARK + 0x28 * 8)
#define CTRL_MOVIE (MARK + 0x2C * 8)
#define CTRL_MOVIELEN (MARK + 0x30 * 8)
#define CTRL_WAIT (MARK + 0x34 * 8)
#define CTRL_READY (MARK + 0x38 * 8)
extern void fill_run_();
extern void fill_init_();
extern void vid_dint_();
unsigned int fill_daddr;
unsigned int fill_dydx;
@@ -77,6 +80,7 @@ int main()
unsigned int movie_len;
int rc;
vid_dint_();
fill_init_();
/* Display interrupt at line 1: our only timebase. Interrupts stay off;
@@ -95,6 +99,12 @@ int main()
movie_len = MOVIE_MAX;
}
if (*(unsigned int *)CTRL_WAIT != 0) {
*(unsigned int *)(MARK + 0x10 * 8) = 0x10; /* takeover, waiting for data */
while (*(unsigned int *)CTRL_READY == 0) {
}
}
rc = movie_open((unsigned char *)movie_base, movie_len, &header);
if (rc != 0) {
*(unsigned int *)MARK = 0xBAD00001;
+21 -12
View File
@@ -1,26 +1,30 @@
/* movie.c -- pure decoder for the BAPL tile-delta movie format.
*
* C89-compatible: the 1987 TMS34010 compiler has no stdint.h and no mixed
* declarations. The host test compiles this same file with gcc -std=c99.
* K&R C: the 1987 TMS34010 compiler has no const, no ANSI prototypes and no
* stdint.h. The host test compiles this same file with gcc -std=c99.
*/
#include "movie.h"
#define HEADER_SIZE 36
#define INDEX_ENTRY_SIZE 6
static unsigned int rd16(const unsigned char *p)
static unsigned int rd16(p)
unsigned char *p;
{
return (unsigned int)p[0] | ((unsigned int)p[1] << 8);
}
static unsigned long rd32(const unsigned char *p)
static unsigned long rd32(p)
unsigned char *p;
{
return (unsigned long)p[0] | ((unsigned long)p[1] << 8)
| ((unsigned long)p[2] << 16) | ((unsigned long)p[3] << 24);
}
int movie_open(const unsigned char *data, unsigned long len,
struct movie_header *header)
int movie_open(data, len, header)
unsigned char *data;
unsigned long len;
struct movie_header *header;
{
unsigned int version;
@@ -57,10 +61,13 @@ int movie_open(const unsigned char *data, unsigned long len,
return 0;
}
int movie_decode_frame(const unsigned char *data, unsigned long len,
unsigned int frame,
const struct movie_header *header,
movie_fill_fn fill, void *ctx)
int movie_decode_frame(data, len, frame, header, fill, ctx)
unsigned char *data;
unsigned long len;
unsigned int frame;
struct movie_header *header;
movie_fill_fn fill;
void *ctx;
{
unsigned long index_off;
unsigned long off;
@@ -142,7 +149,9 @@ int movie_decode_frame(const unsigned char *data, unsigned long len,
return 0;
}
unsigned int movie_checksum(const unsigned char *data, unsigned long len)
unsigned int movie_checksum(data, len)
unsigned char *data;
unsigned long len;
{
unsigned long sum = 0;
unsigned long i;
@@ -151,7 +160,7 @@ unsigned int movie_checksum(const unsigned char *data, unsigned long len)
return 0;
}
for (i = 0; i < len; i++) {
sum = (sum + data[i]) & 0xFFFFFFFFUL;
sum = (sum + data[i]) & 0xFFFFFFFF;
}
return (unsigned int)sum;
}
+5 -11
View File
@@ -1,6 +1,7 @@
#ifndef BADAPPLE_MOVIE_H
#define BADAPPLE_MOVIE_H
/* K&R declarations: the 1987 TI compiler has no ANSI prototypes. */
struct movie_header {
unsigned int width;
unsigned int height;
@@ -15,17 +16,10 @@ struct movie_header {
unsigned int display_hz;
};
typedef void (*movie_fill_fn)(int x, int y, int w, int h, int color,
void *ctx);
typedef void (*movie_fill_fn)();
int movie_open(const unsigned char *data, unsigned long len,
struct movie_header *header);
int movie_decode_frame(const unsigned char *data, unsigned long len,
unsigned int frame,
const struct movie_header *header,
movie_fill_fn fill, void *ctx);
unsigned int movie_checksum(const unsigned char *data, unsigned long len);
int movie_open();
int movie_decode_frame();
unsigned int movie_checksum();
#endif
+28 -9
View File
@@ -36,6 +36,7 @@ local STOP_AT = tonumber(os.getenv("BA_END") or "2600")
local START = tonumber(os.getenv("BA_START") or "0")
local COUNT = tonumber(os.getenv("BA_COUNT") or "0")
local PACE = tonumber(os.getenv("BA_PACE") or "0")
local WAIT = tonumber(os.getenv("BA_WAIT") or "0")
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"
@@ -113,6 +114,7 @@ end
local loaded = false
local entered = false
local done = false
local movie_sent = false
local frames = 0
local function load_and_enter()
@@ -128,17 +130,20 @@ local function load_and_enter()
prog:write_u32(MARK + 0x28 * 8, PACE)
prog:write_u32(MARK + 0x2C * 8, MOVIE)
prog:write_u32(MARK + 0x30 * 8, #movie)
-- Arm the entry breakpoint before the large movie write; the write blocks
-- emulation, so it cannot fire until the movie is in place.
prog:write_u32(MARK + 0x34 * 8, WAIT)
prog:write_u32(MARK + 0x38 * 8, 0)
dbg:command("bpset " .. hex(ENTRY_PC) .. ",,{ pc = " .. hex(entry) .. " ; g }")
write_bytes(movie, MOVIE)
ok, bad = verify(movie, MOVIE)
if not ok then
print("BA ERROR: movie readback mismatch at byte " .. bad)
machine:exit()
return
if WAIT == 0 then
write_bytes(movie, MOVIE)
ok, bad = verify(movie, MOVIE)
if not ok then
print("BA ERROR: movie readback mismatch at byte " .. bad)
machine:exit()
return
end
end
print(string.format("BA: loaded; start=%d count=%d pace=%d", START, COUNT, PACE))
print(string.format("BA: loaded; start=%d count=%d pace=%d wait=%d",
START, COUNT, PACE, WAIT))
end
emu.register_frame_done(function()
@@ -147,6 +152,20 @@ emu.register_frame_done(function()
loaded = true
load_and_enter()
end
if loaded and WAIT == 1 and not movie_sent
and prog:read_u16(MARK + 0x10 * 8) == 0x10 then
movie_sent = true
print("BA: takeover seen; sending movie to low RAM")
write_bytes(movie, MOVIE)
local ok, bad = verify(movie, MOVIE)
if not ok then
print("BA ERROR: movie readback mismatch at byte " .. bad)
machine:exit()
return
end
prog:write_u32(MARK + 0x38 * 8, 1)
print("BA: movie ready")
end
if loaded and not entered then
local status = prog:read_u16(MARK + 0x10 * 8)
if status == 1 or status == 2 then
+2 -1
View File
@@ -18,6 +18,7 @@ BA_COUNT=${BA_COUNT:-0}
BA_AT=${BA_AT:-2500}
BA_END=${BA_END:-3000}
BA_MOVIE_BASE=${BA_MOVIE_BASE:-0x01D00000}
BA_WAIT=${BA_WAIT:-0}
if [ "$MODE" = "play" ]; then
BA_PACE=${BA_PACE:-1}
@@ -27,7 +28,7 @@ cd "$ROOT"
VT1200_SKIP_LEVEL1=1 \
BA_MOVIE="$BA_MOVIE" BA_PACE="$BA_PACE" BA_START="$BA_START" \
BA_COUNT="$BA_COUNT" BA_AT="$BA_AT" BA_END="$BA_END" \
BA_MOVIE_BASE="$BA_MOVIE_BASE" \
BA_MOVIE_BASE="$BA_MOVIE_BASE" BA_WAIT="$BA_WAIT" \
"$M" vt1200 -rompath harness/mame/roms -video none -sound none -nothrottle \
-skip_gameinfo -debug -debugger none \
-autoboot_script "$ROOT/bad-apple/tools/load_mame.lua" -autoboot_delay 0