75 lines
3.4 KiB
C
75 lines
3.4 KiB
C
// midiProbe.c - exercise the Note Synth toolset ($19) dispatcher
|
|
// path. Verifies the wrapper-to-toolset dispatch round trip:
|
|
//
|
|
// 1. iigsSoundProbeInit (MMStartUp + SoundStartUp) -- bare prereq.
|
|
// 2. NSVersion() -- returns the Note Synth ROM-resident version
|
|
// word; works without a prior NSStartUp because
|
|
// the toolset is always present.
|
|
// 3. NSStatus() -- returns the current toolset state.
|
|
// 4. AllNotesOff() -- silent (no audible side effect even if the
|
|
// toolset never had a StartUp); pure dispatch.
|
|
//
|
|
// Why NOT a full NSStartUp + NoteOn + NoteOff sequence? NSStartUp
|
|
// takes a pointer to a complex InstrumentT struct (envelope list,
|
|
// wave list with topKey/waveAddress/waveSize tuples, etc.). Getting
|
|
// the layout exactly right is fiddly and not what this smoke is
|
|
// trying to measure. Smoke goal is: "is the Note Synth dispatcher
|
|
// callable from llvm816-emitted code, and does the wrapper return
|
|
// without scribbling on the stack?" Three round-trip calls answer
|
|
// that.
|
|
//
|
|
// If $70 = 0x42 after this runs, the Note Synth wrapper layer is
|
|
// healthy. (Audible playback through NSStartUp / NoteOn / NoteOff
|
|
// is exercised when a real app uses it -- not part of THIS smoke.)
|
|
//
|
|
// Build with: bash demos/build.sh midiProbe
|
|
// Run with: bash scripts/runViaFinder.sh demos/midiProbe.omf
|
|
// --check 0x70=0x42
|
|
|
|
#include "iigs/sound.h"
|
|
#include "iigs/toolbox.h"
|
|
|
|
|
|
int main(void) {
|
|
*(volatile unsigned char *)0x76 = 0xAA; // pre-init alive marker
|
|
|
|
// Sound Manager must be up before Note Synth dispatch is willing
|
|
// to do real work. iigsSoundProbeInit() does MMStartUp +
|
|
// SoundStartUp idempotently (it's a no-op if Finder already did
|
|
// it).
|
|
unsigned short userId = iigsSoundProbeInit();
|
|
(void)userId;
|
|
*(volatile unsigned char *)0x77 = 0xBB; // post-iigsSoundProbeInit marker
|
|
|
|
// NSVersion: pre-StartUp call that returns the toolset's ROM
|
|
// version word. The toolset is in ROM on every IIgs so this
|
|
// always succeeds even if NSStartUp would not. We capture the
|
|
// result to a marker so a regression in the wrapper (wrong
|
|
// dispatcher ID, missed result pull, etc.) shows up as an
|
|
// unexpected $79 byte. $78/$79 = ROM version BCD.
|
|
unsigned short ver = NSVersion();
|
|
*(volatile unsigned char *)0x78 = (unsigned char)(ver >> 8);
|
|
*(volatile unsigned char *)0x79 = (unsigned char)(ver & 0xFF);
|
|
*(volatile unsigned char *)0x71 = 0x11; // post-NSVersion marker
|
|
|
|
// NSStatus: returns the toolset state (0 = uninited, non-zero =
|
|
// started). Like NSVersion, no StartUp required to call it.
|
|
// The return value isn't fixed (depends on whether Finder /
|
|
// earlier code brought it up), so we just check the wrapper
|
|
// returns at all.
|
|
(void)NSStatus();
|
|
*(volatile unsigned char *)0x73 = 0x22; // post-NSStatus marker
|
|
|
|
// AllNotesOff: side-effect-only dispatch. Silent if the
|
|
// toolset was never started; harmless otherwise. Proves a
|
|
// 0-arg / 0-result wrapper round-trips cleanly.
|
|
AllNotesOff();
|
|
*(volatile unsigned char *)0x74 = 0x33; // post-AllNotesOff marker
|
|
|
|
// Final smoke marker: the full sequence completed.
|
|
*(volatile unsigned char *)0x70 = 0x42;
|
|
|
|
// Linger so the snapshot harness can sample the marker.
|
|
for (volatile unsigned long s = 0; s < 600000UL; s++) { }
|
|
return 0;
|
|
}
|