// 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; }