Skip to content

Blitter screen copy where the DMA chip plays the sound - #10

Merged
diegoparrilla merged 2 commits into
release/v1.1.0from
epic/17-blitter-screen-copy
Sep 30, 2026
Merged

diegoparrilla merged 2 commits into
release/v1.1.0from
epic/17-blitter-screen-copy

Conversation

@diegoparrilla

Copy link
Copy Markdown
Contributor

What

On a machine with a blitter the ST can copy each frame to the screen with the blitter instead of the 68000's MOVEM loop. By default it does so only where the DMA sound chip plays the sound (an STE, a Mega STE), and keeps the MOVEM loop on the YM path.

  • userfw asks TOS for a blitter at boot (XBIOS Blitmode(-1)) and reports it after the hello ($FB8Exx, st_session_features(), stSessionFeatures over SWD).
  • The blitter writes each 48-byte chunk where the predecrement MOVEM would (destination Y increment −94, then the tail), so the RP's cart framebuffer layout is unchanged. It owns the bus 40 chunks at a time (about 1 ms, under an IKBD byte's 1.28 ms); interrupts run between pieces.
  • Shared slot 7 ($FA402C, CART_BLIT_MODE_OFFSET), read every VBL, picks the copy: fb_set_copy_mode() with auto (the default), CPU or blitter, plus the chunks per piece.
  • FB_SLACK_REPORT now measures with MFP Timer-A (no interrupt, 81 µs a count), on both sound paths; one byte at $FB8Bxx ($FB8Cxx is free again). Still off by default.

Why only on the DMA path

Both copies are bound by the bus (8 cycles a word against MOVEM's 9). While the blitter owns the bus, Timer-B's YM samples wait. Measured on a Mega ST (YM sound, blitter fitted):

Copy Slack after the blit Sound (440 Hz tone)
CPU 0.2–0.3 ms reference
Blitter sharing the bus none, 25 fps –
Blitter, 4 / 7 chunks a piece 0.4 / 1.0 ms audibly rougher
Blitter, 40 chunks a piece 3.4 ms breaks (Timer-B ticks dropped)

On a Mega STE (TOS 2.06, 8 MHz, DMA sound): 1.9–2.0 ms with the CPU, 3.3–3.4 ms with the blitter, the tone unchanged, and 50 fps with the mouse moved flat out.

Tests

  • make -C tests/host test: test_chunk_layout.c models the blitter's copy (in one run and in pieces of 1, 7, 40, 255 and 666 chunks) against every pixel drawn; test_layout.py checks the new shared constants and the Timer-A count.
  • Mega ST, debug build: blitter detected, every copy mode from the host, the screen correct, ESC to GEM (desktop and a window drawn by TOS) and a reset back into the app, the mouse with 40-chunk pieces (no IKBD overrun or resync).
  • Mega STE, debug build: the measurements above, the tone A/B, the mouse flat out with music.
  • Mega STE, release build: the menu, demos 1–4, the input test with the mouse, ESC to GEM and a reset: 50 fps, no late audio slice or underrun, no IKBD error.

userfw asks TOS for a blitter at boot (XBIOS Blitmode) and reports it
after the hello ($FB8Exx, st_session_features()). The blitter copies the
frame where the MOVEM loop would: a 48-byte chunk per line going forward
in the cart framebuffer, the destination going back a chunk per line
(Y increment -94) from the page's last chunk, then the tail. It owns the
bus 40 chunks at a time (about 1 ms, under an IKBD byte's 1.28 ms), and
the interrupts run between pieces.

A word in shared slot 7, read every VBL, picks the copy
(fb_set_copy_mode()): auto takes the blitter when the sound goes through
the DMA chip and the CPU on the YM path, where the blitter's pieces delay
Timer-B's samples. On a Mega ST even 4-chunk pieces made a test tone
audibly rougher for 0.15 ms gained, and sharing the bus took longer than
a VBL. On a Mega STE the blit now ends 3.3 ms before the next VBL against
1.9 ms with MOVEM, with the sound unchanged and 50 fps with the mouse
moved flat out. The RP can force the CPU or the blitter.

FB_SLACK_REPORT measures with MFP Timer-A, restarted at each VBL without
its interrupt, so it works on both sound paths; the ST reports one byte
at $FB8Bxx. The host test models the blitter's copy, in one run and in
pieces; test_layout.py checks the new shared constants. Debug builds
take copy_mode from the host; swd.py counters shows the ST's features.
What the blitter does and where it copies by default, the measurements
behind that choice on a Mega ST and a Mega STE, fb_set_copy_mode(),
shared slot 7, the $FB8Bxx and $FB8Exx windows, the Timer-A slack report,
and the copy_mode debug command.
@diegoparrilla
diegoparrilla merged commit e58a8ff into release/v1.1.0 Sep 30, 2026
2 checks passed
@diegoparrilla
diegoparrilla deleted the epic/17-blitter-screen-copy branch September 30, 2026 12:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant