65816-llvm-mos/demos/cursorProbe.c
Scott Duensing da095402ec Updated
2026-06-02 23:17:57 -05:00

86 lines
2.8 KiB
C

// cursorProbe.c - Phase 2.5 cursor-helpers smoke harness.
//
// Brings up the full desktop tool chain via startdesk() so that
// InitCursor() (the Cursor Mgr invariant the iigsCursorPush/Pop
// routines require) has been satisfied, then exercises the push/pop
// stack with both ROM shapes (busy/arrow) and an explicit Register
// of the originally-installed cursor. Marker progression:
//
// $70 = 0x10 after startdesk()'s InitCursor() - sanity
// $70 = 0x20 after iigsCursorPushBusy() returned 0
// $70 = 0x30 after iigsCursorPushArrow() returned 0
// $70 = 0x40 after iigsCursorPop() returned 0
// $70 = 0x50 after iigsCursorPop() returned 0 (back to original)
// $70 = 0x99 at end-of-main (all helpers green)
//
// A hang or stack imbalance in any push/pop wrapper would prevent the
// final marker. An assertion path (NULL save buffer / overflow /
// underflow) trips a return code != 0 and we set 0xFE instead, so the
// harness can distinguish "ran but bad rc" from "hung".
//
// Build with: bash demos/build.sh cursorProbe
// Run with: bash scripts/runViaFinder.sh demos/cursorProbe.omf \
// --check 0x70=0x99
#include "iigs/desktop.h"
#include "iigs/cursor.h"
#include "iigs/toolbox.h"
int main(void) {
unsigned short userId = startdesk(640);
(void)userId;
volatile unsigned char *marker = (volatile unsigned char *)0x70;
*marker = 0x10;
// GetCursorAdr() must return non-NULL after startdesk() ran
// InitCursor(); register that pointer as the registered fallback
// so an underflow Pop has somewhere to land. Note: registering
// the live ROM cursor pointer (not a copy) is intentional - this
// is the fallback, not a saved snapshot, and the ROM shape lives
// at a fixed address in $E1 ROM bank.
void *initial = GetCursorAdr();
if (initial) {
iigsCursorRegister((const IigsCursorT *)initial);
}
// Push busy. The ROM wristwatch should now be the active cursor.
if (iigsCursorPushBusy() != 0) {
*marker = 0xFE;
goto done;
}
*marker = 0x20;
// Push arrow on top of busy. InitCursor() reinstalls the ROM
// arrow shape and stacks the busy underneath.
if (iigsCursorPushArrow() != 0) {
*marker = 0xFE;
goto done;
}
*marker = 0x30;
// Pop -> busy active again.
if (iigsCursorPop() != 0) {
*marker = 0xFE;
goto done;
}
*marker = 0x40;
// Pop -> originally-installed cursor active again.
if (iigsCursorPop() != 0) {
*marker = 0xFE;
goto done;
}
*marker = 0x50;
// All helpers green; final success marker.
*marker = 0x99;
done:
// Give the headless harness a window to snapshot the marker
// before falling out of main into crt0's tear-down.
for (volatile unsigned long s = 0; s < 200000UL; s++) { }
return 0;
}