mirror of
https://git.k-space.ee/arti/vt1200.git
synced 2026-11-01 12:14:56 +02:00
feat(rx): mask interrupts for good -- the OS timer was halving the frame rate
Spec 8.9 decides the payload may kill the resident OS; this is the first half of that, and it is a rate fix as much as a robustness one. With the OS still ticking, the payload's 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, frames_rx from the payload's own status frames). That is scheduling, not decode -- the loop itself runs ~20k iterations/s. VID_OWN_CPU (default 1) takes one DINT before the main loop and makes vid_eint_() a no-op, so nothing preempts the LANCE poll. Measured on the same one-tile stream: OS ticking (before) 15.0 fps accepted, 400 frames in 15.4 s DINT at startup 24.0 fps accepted, 385/400 frames, drops=0 and, paced differently, 31.5 fps with 387/400 -- the sender, not the terminal, is now the throttle (its socket blocks once the tap's drain rate is exceeded) Consequence stated where it is made: the OS's drivers stop being serviced, so its console and network stack are gone for good. The payload owns the machine once it takes the LANCE either way. The harness reaches the payload through the debugger, not the OS, so the replay modes are unaffected -- verified: modes tiles, delta and replay all RESULT PASS with their pixel checkers after the change. Set VID_OWN_CPU=0 at build time to reproduce the old burst-EINT behaviour for a comparison run.
This commit is contained in:
1 parent
d211ff0770
commit
8de6d94e84
1 file changed
+31
@@ -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 (;;) {
|
||||
|
||||
Reference in new issue
Block a user