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