112 lines
3.5 KiB
C
112 lines
3.5 KiB
C
// IIgs toolbox helpers — minimal inline-asm wrappers for the most
|
|
// commonly-used Apple IIgs system calls.
|
|
//
|
|
// Toolbox dispatch on the IIgs goes through the Tool Locator at
|
|
// $E10000. Each routine is identified by a 16-bit "tool number"
|
|
// (low byte = tool set, high byte = function within set), loaded
|
|
// into X, and called via JSL $E10000.
|
|
//
|
|
// Args go on the stack (push order: rightmost first), then the
|
|
// caller pushes a result-space slot if the routine returns something
|
|
// non-i16-or-pointer, then JSL.
|
|
//
|
|
// This header keeps things simple: each function inlines a tiny
|
|
// asm block specific to that call. No #include guards on bigger
|
|
// abstractions; users that want full toolbox coverage should write
|
|
// their own wrappers using the same pattern.
|
|
//
|
|
// LIMITATIONS:
|
|
// - Only a handful of routines wrapped. Calypsi has full toolbox.
|
|
// - No error-handling — caller checks the return.
|
|
// - Single-bank only. Cross-bank toolbox calls need different
|
|
// dispatch logic.
|
|
|
|
#ifndef IIGS_TOOLBOX_H
|
|
#define IIGS_TOOLBOX_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
// Tool number convention: high byte = function, low byte = tool set.
|
|
// Common tool sets: 04 = Misc, 0E = QuickDraw II, 18 = Window Mgr.
|
|
|
|
// Misc Tool Set ---------------------------------------------------
|
|
|
|
// WriteCString (Misc Tool $290B) — write a NUL-terminated string to
|
|
// the text screen. Arg: 16-bit pointer pushed before the call.
|
|
// Returns nothing.
|
|
static inline void TBoxWriteCString(const char *s) {
|
|
__asm__ volatile (
|
|
"pha\n" // push C-string pointer
|
|
"ldx #0x290B\n" // tool number (function 0x29, set 0x0B)
|
|
"jsl 0xe10000\n" // tool dispatcher
|
|
:
|
|
: "a"(s)
|
|
: "x", "y", "memory"
|
|
);
|
|
}
|
|
|
|
// SysBeep (Misc Tool $0303) — short beep through the speaker.
|
|
static inline void TBoxBeep(void) {
|
|
__asm__ volatile (
|
|
"ldx #0x0303\n"
|
|
"jsl 0xe10000\n"
|
|
:
|
|
:
|
|
: "x", "y", "memory"
|
|
);
|
|
}
|
|
|
|
// ReadKey (Event Mgr; simplified — actually KeyTrans/etc). Returns
|
|
// the next pending key in A, or 0 if none. This wraps GetNextEvent
|
|
// internally on a real GS; for the simple console harness it polls
|
|
// the keyboard buffer.
|
|
static inline char TBoxReadKey(void) {
|
|
char r;
|
|
__asm__ volatile (
|
|
"ldx #0x250A\n" // GetEvent (placeholder; refine in real port)
|
|
"jsl 0xe10000\n"
|
|
: "=a"(r)
|
|
:
|
|
: "x", "y", "memory"
|
|
);
|
|
return r;
|
|
}
|
|
|
|
// ConsoleQuit — clean program shutdown via GS/OS Quit. Pushes a
|
|
// pConditionTbl pointer (here, 0 for no condition) before JSL.
|
|
static inline void TBoxQuit(void) {
|
|
__asm__ volatile (
|
|
"pea 0\n" // pConditionTbl = NULL
|
|
"pea 0\n" // pParm
|
|
"ldx #0x2029\n" // GS/OS Quit
|
|
"jsl 0xe100a8\n" // GS/OS dispatcher (different addr)
|
|
:
|
|
:
|
|
: "x", "y", "memory"
|
|
);
|
|
while (1) {} // unreachable
|
|
}
|
|
|
|
// QuickDraw II ----------------------------------------------------
|
|
|
|
// QDStartUp / QDShutDown (sketches — real ones take more args).
|
|
// Real apps typically use QuickDraw II via the "shell" startup
|
|
// sequence; this is for educational/sim scenarios.
|
|
static inline void TBoxQDStartUp(void) {
|
|
__asm__ volatile (
|
|
"pea 0\n" "pea 0\n" "pea 0\n" // dummy direct-page handle
|
|
"ldx #0x0204\n"
|
|
"jsl 0xe10000\n"
|
|
:
|
|
:
|
|
: "x", "y", "memory"
|
|
);
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif // IIGS_TOOLBOX_H
|