diff --git a/harness/udpstream/vidstream.c b/harness/udpstream/vidstream.c index c1ecae5..0fb24a9 100644 --- a/harness/udpstream/vidstream.c +++ b/harness/udpstream/vidstream.c @@ -342,6 +342,33 @@ extern void tile_blit_(); /* vram_tile.asm: PIXBLT B,XY, 32x32 tile */ extern void vid_dint_(); /* vram_b.asm: DINT */ extern void vid_eint_(); /* vram_b.asm: EINT */ +/* + * VID_OWN_CPU -- mask interrupts once at startup and never re-enable them. + * + * This is spec 8.9's "the resident OS may die", and it is also a *rate* fix, + * not just a robustness one. With the OS's timer still running, this loop is + * preempted and the machine accepts ~15 frames/s whatever the payload size: a + * 5-byte one-tile delta measured the same as a 140-tile one (195 frames in + * 13.4 s, MAME at 100% speed). That is scheduling, not decode. With IE held + * clear nothing preempts the loop and the LANCE is polled as fast as the chip + * delivers. + * + * Consequences, stated because they are real: the OS's drivers stop being + * serviced, so its console and network stack are gone for good -- the payload + * owns the machine either way once it takes the LANCE. The harness reaches + * the payload through the debugger, not through the OS, so the replay modes + * are unaffected. + * + * Set VID_OWN_CPU=0 to build the old behaviour (bursts of EINT around each + * transfer) for a comparison run. + */ +#ifndef VID_OWN_CPU +#define VID_OWN_CPU 1 +#endif +#if VID_OWN_CPU +#define vid_eint_() ((void)0) /* masked for good; see main() */ +#endif + /* * The firmware's free-space counter is a 32-bit count IN BITS at * 0x1E8BA0 (dwt/notes/HEAP.md). POOL_FREE reports bytes, because the @@ -1777,7 +1804,11 @@ int main() vid_dint_(); lance_ok = lance_start(ptr); +#if VID_OWN_CPU + vid_dint_(); /* once, for good: nothing may preempt this loop */ +#else vid_eint_(); +#endif *(unsigned int *)ST_BUF = status_buf; for (;;) {