128 lines
4.1 KiB
C
128 lines
4.1 KiB
C
// helloWindow.c - GS/OS app that opens a Window Manager window and
|
|
// draws a greeting in it. Runs under real GS/OS 6.0.2 in MAME.
|
|
//
|
|
// What this exercises:
|
|
// - The full Window Manager StartUp chain (Memory + QD + Event +
|
|
// Scheduler + Window).
|
|
// - NewWindow ParamList with paramLength = sizeof (ORCA Clock.cc /
|
|
// Reversi.cc convention).
|
|
// - SetPort / ShowWindow / MoveTo / DrawString round-trip.
|
|
// - Event-driven keypress wait via GetNextEvent.
|
|
// - The W65816 backend's bank-byte relocation:
|
|
// `gWp.wTitle = gTitle` stores a 32-bit pointer where the bank
|
|
// byte is materialized via the new LDAi16imm_bank pseudo
|
|
// (lowered to `lda $BE` reading PBR from a crt0-set DP slot).
|
|
// Toolbox calls now receive correct `bank:offset` pointers for
|
|
// any `&global` argument — no wrapper-side workarounds needed.
|
|
//
|
|
// Why fTitle is NOT set in wFrameBits despite wTitle being valid:
|
|
// The Window Manager hangs trying to render a titled window without
|
|
// Font Manager initialization. A "real" titled-window demo would
|
|
// need to drive QDStartUp's font allocation and possibly start the
|
|
// Font Manager (FMStartUp) — that's the next milestone.
|
|
|
|
#include "iigs/toolbox.h"
|
|
|
|
#define fVis 0x0020
|
|
#define fMove 0x0080
|
|
#define fZoom 0x0100
|
|
#define fGrow 0x0400
|
|
#define fClose 0x4000
|
|
#define fTitle 0x8000
|
|
|
|
|
|
typedef struct { short v1, h1, v2, h2; } Rect;
|
|
|
|
typedef struct {
|
|
unsigned short paramLength;
|
|
unsigned short wFrameBits;
|
|
void *wTitle;
|
|
unsigned long wRefCon;
|
|
Rect wZoom;
|
|
void *wColor;
|
|
short wYOrigin, wXOrigin;
|
|
short wDataH, wDataV;
|
|
short wMaxHeight, wMaxWidth;
|
|
short wScrollVer, wScrollHor;
|
|
short wPageVer, wPageHor;
|
|
unsigned long wInfoRefCon;
|
|
short wInfoHeight;
|
|
void *wFrameDefProc;
|
|
void *wInfoDefProc;
|
|
void *wContDefProc;
|
|
Rect wPosition;
|
|
void *wPlane;
|
|
void *wStorage;
|
|
} NewWindowParm;
|
|
|
|
|
|
// Pascal strings: leading length byte, then characters.
|
|
static unsigned char gTitle[] = "\x09llvm816!!";
|
|
static unsigned char gMsg[] = "\x14Hello from llvm816!";
|
|
|
|
// ParamList in BSS so the bank byte of &gWp resolves to PBR via the
|
|
// new LDAi16imm_bank reloc path.
|
|
static NewWindowParm gWp;
|
|
|
|
|
|
static unsigned short blockAddr(void *handle) {
|
|
return (unsigned short)(unsigned long)*(void **)handle;
|
|
}
|
|
|
|
|
|
int main(void) {
|
|
unsigned short userId = MMStartUp();
|
|
|
|
void *dpH = NewHandle(0x900UL, userId, 0xC005, (void *)0);
|
|
unsigned short dpBase = blockAddr(dpH);
|
|
|
|
QDStartUp(dpBase, 0, 0xA0, userId);
|
|
EMStartUp((unsigned short)(dpBase + 0x100), 0x14, 0, 0,
|
|
0x14F, 0xC7, userId);
|
|
SchStartUp();
|
|
WindStartUp(userId);
|
|
|
|
// Zero the parm block, then set only the fields we want non-zero.
|
|
{
|
|
unsigned char *p = (unsigned char *)&gWp;
|
|
for (unsigned short i = 0; i < sizeof gWp; i++) {
|
|
p[i] = 0;
|
|
}
|
|
}
|
|
gWp.paramLength = (unsigned short)sizeof gWp;
|
|
// fVis+fMove only — fTitle requires Font Manager startup (FMStartUp
|
|
// with proper DP allocation) which is a TODO for the full ORCA-
|
|
// style desktop init. wTitle is still set to prove the new
|
|
// R_W65816_BANK16 reloc produces the correct bank byte at runtime
|
|
// (even though WM doesn't dereference it without fTitle).
|
|
gWp.wFrameBits = fVis | fMove;
|
|
gWp.wTitle = gTitle;
|
|
gWp.wMaxHeight = 200;
|
|
gWp.wMaxWidth = 320;
|
|
gWp.wPosition.v1 = 40; gWp.wPosition.h1 = 30;
|
|
gWp.wPosition.v2 = 140; gWp.wPosition.h2 = 290;
|
|
gWp.wPlane = (void *)-1L;
|
|
|
|
void *win = NewWindow(&gWp);
|
|
if (win) {
|
|
SetPort(win);
|
|
ShowWindow(win);
|
|
MoveTo(20, 30);
|
|
DrawString(gMsg);
|
|
}
|
|
|
|
// Brief visible linger before checking events (so snapshot demos can
|
|
// capture the window). Then wait for a real keypress.
|
|
for (volatile unsigned long s = 0; s < 400000UL; s++) { }
|
|
|
|
short evt[8];
|
|
while (1) {
|
|
if (GetNextEvent(0xFFFF, evt)) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
SysBeep();
|
|
*(volatile unsigned char *)0x70 = 0x99;
|
|
return 0;
|
|
}
|