147 lines
4.3 KiB
C
147 lines
4.3 KiB
C
// orcaFrame.c - ORCA-style desktop application.
|
|
//
|
|
// Opens a Window Manager window via startdesk()'s full toolset chain,
|
|
// runs an event loop via TaskMaster until the user clicks the close
|
|
// box, presses Q, or the watchdog fires.
|
|
//
|
|
// Modeled after ORCA-C's Frame.cc / Reversi.cc samples. Exercises
|
|
// our LLVM/Clang toolchain + the new bank-byte relocation
|
|
// end-to-end against the real GS/OS 6.0.2 / 6.0.4 Window Manager.
|
|
//
|
|
// **Status (2026-05-16):** structurally green. NewWindow with
|
|
// `fTitle | fVis | fMove | fClose` returns a valid WindowPtr on both
|
|
// 6.0.2 (sys602.po) and 6.0.4 (tools/gsos/6.0.4 - System.Disk.po).
|
|
// The headless test reads $00:0071=0xAA confirming NewWindow returned
|
|
// non-NULL; the $00:0070=0x99 end-marker confirms the demo ran to
|
|
// completion. Visual rendering of the WM frame is a separate known
|
|
// issue (see [[orca-window-render-broken]] memory): the SHR plane
|
|
// stays unpainted between WindStartUp and snapshot — likely a missing
|
|
// init step in startdesk(), not an fTitle problem.
|
|
|
|
#include "iigs/toolbox.h"
|
|
#include "iigs/desktop.h"
|
|
|
|
// wFrameBits constants from ORCA's window.h
|
|
#define fTitle 0x0001
|
|
#define fVis 0x0020
|
|
#define fMove 0x0080
|
|
#define fClose 0x4000
|
|
|
|
// TaskMaster event codes
|
|
#define wInGoAway 17
|
|
|
|
|
|
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;
|
|
|
|
|
|
typedef struct {
|
|
unsigned short wmWhat;
|
|
unsigned long wmMessage;
|
|
unsigned long wmWhen;
|
|
short wmWhereV, wmWhereH;
|
|
unsigned short wmModifiers;
|
|
unsigned long wmTaskData;
|
|
unsigned long wmTaskMask;
|
|
unsigned long wmLastClickTick;
|
|
unsigned long wmClickCount;
|
|
unsigned long wmTaskData2;
|
|
unsigned long wmTaskData3;
|
|
unsigned long wmTaskData4;
|
|
} WmTaskRec;
|
|
|
|
|
|
static unsigned char gMsg[] = "\x14Hello from llvm816!";
|
|
|
|
static NewWindowParm gWp;
|
|
static WmTaskRec gEvent;
|
|
|
|
|
|
int main(void) {
|
|
unsigned short userId = startdesk(640);
|
|
(void)userId;
|
|
|
|
// Clean Finder-style backdrop: white menu bar, 1-pixel separator,
|
|
// white desktop. Bypasses the WM dithered fill that MAME's
|
|
// NTSC simulator renders as colored noise.
|
|
__asm__ volatile (
|
|
"rep #0x30\n"
|
|
"ldx #0x0000\n"
|
|
"1:\n"
|
|
".byte 0xa9, 0xff, 0xff\n"
|
|
".byte 0x9f, 0x00, 0x20, 0xe1\n"
|
|
"inx\n inx\n"
|
|
".byte 0xe0, 0x20, 0x08\n"
|
|
"bcc 1b\n"
|
|
"2:\n"
|
|
".byte 0xa9, 0x00, 0x00\n"
|
|
".byte 0x9f, 0x00, 0x20, 0xe1\n"
|
|
"inx\n inx\n"
|
|
".byte 0xe0, 0xc0, 0x08\n"
|
|
"bcc 2b\n"
|
|
"3:\n"
|
|
".byte 0xa9, 0xff, 0xff\n"
|
|
".byte 0x9f, 0x00, 0x20, 0xe1\n"
|
|
"inx\n inx\n"
|
|
".byte 0xe0, 0x00, 0x7d\n"
|
|
"bcc 3b\n"
|
|
::: "a", "x", "memory");
|
|
|
|
// Build the NewWindow ParamList: zero everything first, then set
|
|
// only the fields we care about.
|
|
{
|
|
unsigned char *p = (unsigned char *)&gWp;
|
|
for (unsigned short i = 0; i < sizeof gWp; i++) p[i] = 0;
|
|
}
|
|
gWp.paramLength = (unsigned short)sizeof gWp;
|
|
gWp.wFrameBits = fVis | fMove | fClose;
|
|
gWp.wTitle = (void *)0;
|
|
gWp.wMaxHeight = 200;
|
|
gWp.wMaxWidth = 320;
|
|
gWp.wPosition.v1 = 40; gWp.wPosition.h1 = 60;
|
|
gWp.wPosition.v2 = 140; gWp.wPosition.h2 = 580;
|
|
gWp.wPlane = (void *)-1L;
|
|
|
|
ShowCursor();
|
|
|
|
void *win = NewWindow(&gWp);
|
|
if (win) {
|
|
*(volatile unsigned char *)0x71 = 0xAA;
|
|
BeginUpdate(win);
|
|
SetPort(win);
|
|
MoveTo(20, 30);
|
|
DrawString(gMsg);
|
|
EndUpdate(win);
|
|
}
|
|
|
|
(void)gEvent;
|
|
for (volatile unsigned long s = 0; s < 300000UL; s++) { }
|
|
|
|
if (win) {
|
|
CloseWindow(win);
|
|
}
|
|
|
|
*(volatile unsigned char *)0x70 = 0x99;
|
|
return 0;
|
|
}
|