ORCA/C demos seem to be working!
This commit is contained in:
parent
6bff7bea3f
commit
524a37fcf0
141 changed files with 9786 additions and 1952 deletions
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
13
benchmarks/bubbleSort.c
Normal file
13
benchmarks/bubbleSort.c
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
// Bubble-sort 16 ints. Exercises array indexed access, nested loops,
|
||||||
|
// and i16 compare/swap — patterns common in any sorted-collection code.
|
||||||
|
void bubbleSort(short *a, unsigned short n) {
|
||||||
|
for (unsigned short i = 0; i < n - 1; i++) {
|
||||||
|
for (unsigned short j = 0; j < n - 1 - i; j++) {
|
||||||
|
if (a[j] > a[j + 1]) {
|
||||||
|
short t = a[j];
|
||||||
|
a[j] = a[j + 1];
|
||||||
|
a[j + 1] = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
benchmarks/djb2Hash.c
Normal file
11
benchmarks/djb2Hash.c
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
// djb2 string hash. Exercises i32 arithmetic in a tight pointer-walk
|
||||||
|
// loop — hash << 5 + hash + c. Hits the i32 shift inline path and the
|
||||||
|
// byte-load pattern in the same loop body. Real-world: every hash
|
||||||
|
// table keyed by strings uses something like this.
|
||||||
|
unsigned long djb2Hash(const char *s) {
|
||||||
|
unsigned long h = 5381;
|
||||||
|
while (*s) {
|
||||||
|
h = ((h << 5) + h) + (unsigned char)(*s++);
|
||||||
|
}
|
||||||
|
return h;
|
||||||
|
}
|
||||||
9
benchmarks/globalArr8Sum.c
Normal file
9
benchmarks/globalArr8Sum.c
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
// i8 global-array indexed access — sister benchmark to globalArrSum
|
||||||
|
// that exercises the LDA8absX combine path.
|
||||||
|
unsigned char globalArr8[100];
|
||||||
|
|
||||||
|
unsigned short globalArr8Sum(unsigned short n) {
|
||||||
|
unsigned short s = 0;
|
||||||
|
for (unsigned short i = 0; i < n; i++) s += globalArr8[i];
|
||||||
|
return s;
|
||||||
|
}
|
||||||
8
benchmarks/globalArrFill.c
Normal file
8
benchmarks/globalArrFill.c
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
// Fill the first n elements of a global i16 array. Exercises the
|
||||||
|
// store-side of the W65816UnLSR + STA_AbsX combine for global-array
|
||||||
|
// loops.
|
||||||
|
unsigned short globalArrF[100];
|
||||||
|
|
||||||
|
void globalArrFill(unsigned short n) {
|
||||||
|
for (unsigned short i = 0; i < n; i++) globalArrF[i] = i + 1;
|
||||||
|
}
|
||||||
10
benchmarks/globalArrSum.c
Normal file
10
benchmarks/globalArrSum.c
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
// Sum the first n elements of a global i16 array. Exercises the
|
||||||
|
// `arr[i]` indexed-access pattern that the W65816UnLSR pass converts
|
||||||
|
// back to `lda <global>, X` after LSR turns it into pointer-walking.
|
||||||
|
unsigned short globalArr[100];
|
||||||
|
|
||||||
|
unsigned short globalArrSum(unsigned short n) {
|
||||||
|
unsigned short s = 0;
|
||||||
|
for (unsigned short i = 0; i < n; i++) s += globalArr[i];
|
||||||
|
return s;
|
||||||
|
}
|
||||||
14
benchmarks/strLen.c
Normal file
14
benchmarks/strLen.c
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
// strLen: walk pointer until null byte. Exercises the [dp],Y byte-read
|
||||||
|
// path plus the conditional loop exit. Touches the same DPF0 setup
|
||||||
|
// pattern as strcpy/memcmp but with only ONE pointer per iter.
|
||||||
|
//
|
||||||
|
// The pragma prevents clang from recognising this as a builtin strlen
|
||||||
|
// and rewriting it as a call to libc (which our benches don't link).
|
||||||
|
__attribute__((no_builtin("strlen")))
|
||||||
|
unsigned short strLen(const char *s) {
|
||||||
|
const char *p = s;
|
||||||
|
while (*p) {
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
return (unsigned short)(p - s);
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# #
|
# #
|
||||||
# Calypsi ISO C compiler for 65816 version 5.16 #
|
# Calypsi ISO C compiler for 65816 version 5.16 #
|
||||||
# 14/May/2026 11:06:07 #
|
# 15/May/2026 00:38:15 #
|
||||||
# Command line: --speed -O 2 --64bit-doubles evalAt.c -o #
|
# Command line: --speed -O 2 --64bit-doubles evalAt.c -o #
|
||||||
# /tmp/evalAt.calypsi.elf --list-file evalAt.calypsi.lst #
|
# /tmp/evalAt.calypsi.elf --list-file evalAt.calypsi.lst #
|
||||||
# #
|
# #
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ evalAt: ; @evalAt
|
||||||
tay
|
tay
|
||||||
tsc
|
tsc
|
||||||
sec
|
sec
|
||||||
sbc #0x46
|
sbc #0x2e
|
||||||
tcs
|
tcs
|
||||||
tya
|
tya
|
||||||
pha
|
pha
|
||||||
|
|
@ -24,7 +24,7 @@ evalAt: ; @evalAt
|
||||||
sta 0x3, s
|
sta 0x3, s
|
||||||
pla
|
pla
|
||||||
stx 0xc0
|
stx 0xc0
|
||||||
sta 0x19, s
|
sta 0x1b, s
|
||||||
clc
|
clc
|
||||||
adc #0x2
|
adc #0x2
|
||||||
sta 0x1f, s
|
sta 0x1f, s
|
||||||
|
|
@ -33,44 +33,34 @@ evalAt: ; @evalAt
|
||||||
adc #0x0
|
adc #0x0
|
||||||
sta 0x21, s
|
sta 0x21, s
|
||||||
lda 0x1f, s
|
lda 0x1f, s
|
||||||
sta 0x45, s
|
|
||||||
lda 0x21, s
|
|
||||||
sta 0x43, s
|
|
||||||
lda 0x45, s
|
|
||||||
sta 0xe0
|
sta 0xe0
|
||||||
lda 0x43, s
|
lda 0x21, s
|
||||||
sta 0xe2
|
sta 0xe2
|
||||||
ldy #0x0
|
ldy #0x0
|
||||||
lda [0xe0], y
|
lda [0xe0], y
|
||||||
sta 0x1d, s
|
sta 0x1f, s
|
||||||
lda 0x19, s
|
|
||||||
sta 0x41, s
|
|
||||||
pha
|
pha
|
||||||
lda 0xc0
|
lda 0xc0
|
||||||
sta 0x41, s
|
sta 0x2f, s
|
||||||
pla
|
pla
|
||||||
lda 0x41, s
|
lda 0x1b, s
|
||||||
sta 0xe0
|
sta 0xe0
|
||||||
lda 0x3f, s
|
lda 0x2d, s
|
||||||
sta 0xe2
|
sta 0xe2
|
||||||
lda [0xe0], y
|
lda [0xe0], y
|
||||||
sta 0x21, s
|
sta 0x21, s
|
||||||
lda 0x4a, s
|
lda 0x32, s
|
||||||
sta 0xb, s
|
sta 0xb, s
|
||||||
lda #0x0
|
lda #0x0
|
||||||
sta 0xc4
|
sta 0xc4
|
||||||
sta 0xc6
|
sta 0xc6
|
||||||
lda 0x21, s
|
lda 0x21, s
|
||||||
sta 0x3d, s
|
|
||||||
lda 0x1d, s
|
|
||||||
sta 0x3b, s
|
|
||||||
lda 0x3d, s
|
|
||||||
sta 0xe0
|
sta 0xe0
|
||||||
lda 0x3b, s
|
lda 0x1f, s
|
||||||
sta 0xe2
|
sta 0xe2
|
||||||
lda [0xe0], y
|
lda [0xe0], y
|
||||||
and #0xff
|
and #0xff
|
||||||
sta 0x1b, s
|
sta 0x1d, s
|
||||||
sep #0x20
|
sep #0x20
|
||||||
clc
|
clc
|
||||||
adc #0xd0
|
adc #0xd0
|
||||||
|
|
@ -93,50 +83,46 @@ evalAt: ; @evalAt
|
||||||
inc a
|
inc a
|
||||||
sta 0x21, s
|
sta 0x21, s
|
||||||
bne .Ltmp0
|
bne .Ltmp0
|
||||||
lda 0x1d, s
|
lda 0x1f, s
|
||||||
inc a
|
inc a
|
||||||
sta 0x1d, s
|
sta 0x1f, s
|
||||||
.Ltmp0:
|
.Ltmp0:
|
||||||
lda #0x0
|
lda #0x0
|
||||||
sta 0x15, s
|
sta 0x15, s
|
||||||
sta 0x13, s
|
sta 0x13, s
|
||||||
sta 0x11, s
|
sta 0x11, s
|
||||||
sta 0xf, s
|
sta 0xf, s
|
||||||
lda 0x1d, s
|
lda 0x1f, s
|
||||||
sta 0x17, s
|
sta 0x17, s
|
||||||
.LBB0_2: ; %while.body
|
.LBB0_2: ; %while.body
|
||||||
; =>This Inner Loop Header: Depth=1
|
; =>This Inner Loop Header: Depth=1
|
||||||
sta 0x1d, s
|
sta 0x1f, s
|
||||||
lda 0x19, s
|
lda 0x1b, s
|
||||||
tax
|
tax
|
||||||
pha
|
pha
|
||||||
lda 0xc0
|
lda 0xc0
|
||||||
sta 0x3b, s
|
sta 0x2d, s
|
||||||
pla
|
pla
|
||||||
txa
|
txa
|
||||||
sta 0xe0
|
sta 0xe0
|
||||||
lda 0x39, s
|
lda 0x2b, s
|
||||||
sta 0xe2
|
sta 0xe2
|
||||||
lda 0x21, s
|
lda 0x21, s
|
||||||
ldy #0x0
|
ldy #0x0
|
||||||
sta [0xe0], y
|
sta [0xe0], y
|
||||||
lda 0x19, s
|
lda 0x1b, s
|
||||||
clc
|
clc
|
||||||
adc #0x2
|
adc #0x2
|
||||||
sta 0xd, s
|
sta 0xd, s
|
||||||
lda 0xc0
|
lda 0xc0
|
||||||
sta 0x1f, s
|
sta 0x19, s
|
||||||
adc #0x0
|
adc #0x0
|
||||||
sta 0x1f, s
|
sta 0x19, s
|
||||||
lda 0xd, s
|
lda 0xd, s
|
||||||
sta 0x37, s
|
|
||||||
lda 0x1f, s
|
|
||||||
tax
|
|
||||||
lda 0x37, s
|
|
||||||
sta 0xe0
|
sta 0xe0
|
||||||
txa
|
lda 0x19, s
|
||||||
sta 0xe2
|
sta 0xe2
|
||||||
lda 0x1d, s
|
lda 0x1f, s
|
||||||
sta [0xe0], y
|
sta [0xe0], y
|
||||||
pea 0x4024
|
pea 0x4024
|
||||||
lda #0x0
|
lda #0x0
|
||||||
|
|
@ -157,24 +143,24 @@ evalAt: ; @evalAt
|
||||||
adc #0xc
|
adc #0xc
|
||||||
tcs
|
tcs
|
||||||
lda 0xe0
|
lda 0xe0
|
||||||
sta 0x1f, s
|
sta 0x19, s
|
||||||
txa
|
txa
|
||||||
sta 0x15, s
|
sta 0x15, s
|
||||||
tya
|
tya
|
||||||
sta 0x13, s
|
sta 0x13, s
|
||||||
lda 0xf0
|
lda 0xf0
|
||||||
sta 0x11, s
|
sta 0x11, s
|
||||||
lda 0x1b, s
|
lda 0x1d, s
|
||||||
sep #0x20
|
sep #0x20
|
||||||
clc
|
clc
|
||||||
adc #0xd0
|
adc #0xd0
|
||||||
rep #0x20
|
rep #0x20
|
||||||
and #0xff
|
and #0xff
|
||||||
sta 0x1b, s
|
sta 0x1d, s
|
||||||
ldx #0x0
|
ldx #0x0
|
||||||
lda 0x1b, s
|
lda 0x1d, s
|
||||||
jsl __floatunsidf
|
jsl __floatunsidf
|
||||||
sta 0x1b, s
|
sta 0x1d, s
|
||||||
txa
|
txa
|
||||||
sta 0xf, s
|
sta 0xf, s
|
||||||
tya
|
tya
|
||||||
|
|
@ -185,7 +171,7 @@ evalAt: ; @evalAt
|
||||||
lda 0x13, s
|
lda 0x13, s
|
||||||
tax
|
tax
|
||||||
phx
|
phx
|
||||||
lda 0x21, s
|
lda 0x23, s
|
||||||
pha
|
pha
|
||||||
lda 0x19, s
|
lda 0x19, s
|
||||||
pha
|
pha
|
||||||
|
|
@ -193,7 +179,7 @@ evalAt: ; @evalAt
|
||||||
pha
|
pha
|
||||||
lda 0x21, s
|
lda 0x21, s
|
||||||
tax
|
tax
|
||||||
lda 0x2b, s
|
lda 0x25, s
|
||||||
jsl __adddf3
|
jsl __adddf3
|
||||||
sta 0xe0
|
sta 0xe0
|
||||||
tsc
|
tsc
|
||||||
|
|
@ -217,7 +203,7 @@ evalAt: ; @evalAt
|
||||||
sta 0x21, s
|
sta 0x21, s
|
||||||
txa
|
txa
|
||||||
lda 0xd0
|
lda 0xd0
|
||||||
sta 0x1f, s
|
sta 0x1d, s
|
||||||
lda 0x17, s
|
lda 0x17, s
|
||||||
adc #0x0
|
adc #0x0
|
||||||
sta 0x17, s
|
sta 0x17, s
|
||||||
|
|
@ -229,18 +215,14 @@ evalAt: ; @evalAt
|
||||||
sta 0xc4
|
sta 0xc4
|
||||||
lda 0x13, s
|
lda 0x13, s
|
||||||
sta 0xc6
|
sta 0xc6
|
||||||
lda 0x1f, s
|
|
||||||
sta 0x35, s
|
|
||||||
lda 0x1d, s
|
lda 0x1d, s
|
||||||
tax
|
|
||||||
lda 0x35, s
|
|
||||||
sta 0xe0
|
sta 0xe0
|
||||||
txa
|
lda 0x1f, s
|
||||||
sta 0xe2
|
sta 0xe2
|
||||||
ldy #0x0
|
ldy #0x0
|
||||||
lda [0xe0], y
|
lda [0xe0], y
|
||||||
and #0xff
|
and #0xff
|
||||||
sta 0x1b, s
|
sta 0x1d, s
|
||||||
sep #0x20
|
sep #0x20
|
||||||
clc
|
clc
|
||||||
adc #0xd0
|
adc #0xd0
|
||||||
|
|
@ -259,17 +241,17 @@ evalAt: ; @evalAt
|
||||||
sta 0x21, s
|
sta 0x21, s
|
||||||
lda 0x17, s
|
lda 0x17, s
|
||||||
adc #0xffff
|
adc #0xffff
|
||||||
sta 0x1d, s
|
sta 0x1f, s
|
||||||
.LBB0_4: ; %while.cond7.preheader
|
.LBB0_4: ; %while.cond7.preheader
|
||||||
lda 0xb, s
|
lda 0xb, s
|
||||||
eor #0x8000
|
eor #0x8000
|
||||||
sta 0xb, s
|
sta 0xb, s
|
||||||
lda 0x1b, s
|
lda 0x1d, s
|
||||||
brl .LBB0_5
|
brl .LBB0_5
|
||||||
.LBB0_11: ; %if.then33
|
.LBB0_11: ; %if.then33
|
||||||
; in Loop: Header=BB0_5 Depth=1
|
; in Loop: Header=BB0_5 Depth=1
|
||||||
lda 0xc6
|
lda 0xc6
|
||||||
sta 0x1b, s
|
sta 0x1d, s
|
||||||
lda 0xc4
|
lda 0xc4
|
||||||
sta 0x15, s
|
sta 0x15, s
|
||||||
lda 0xca
|
lda 0xca
|
||||||
|
|
@ -278,7 +260,7 @@ evalAt: ; @evalAt
|
||||||
sta 0x11, s
|
sta 0x11, s
|
||||||
lda 0x17, s
|
lda 0x17, s
|
||||||
pha
|
pha
|
||||||
lda 0x1f, s
|
lda 0x1b, s
|
||||||
pha
|
pha
|
||||||
lda 0x23, s
|
lda 0x23, s
|
||||||
pha
|
pha
|
||||||
|
|
@ -288,7 +270,7 @@ evalAt: ; @evalAt
|
||||||
pha
|
pha
|
||||||
lda 0x1b, s
|
lda 0x1b, s
|
||||||
pha
|
pha
|
||||||
lda 0x27, s
|
lda 0x29, s
|
||||||
tax
|
tax
|
||||||
lda 0x21, s
|
lda 0x21, s
|
||||||
jsl __muldf3
|
jsl __muldf3
|
||||||
|
|
@ -306,10 +288,10 @@ evalAt: ; @evalAt
|
||||||
tya
|
tya
|
||||||
sta 0x1d, s
|
sta 0x1d, s
|
||||||
lda 0xf0
|
lda 0xf0
|
||||||
sta 0x1b, s
|
sta 0x19, s
|
||||||
lda 0x1d, s
|
lda 0x1d, s
|
||||||
sta 0xc8
|
sta 0xc8
|
||||||
lda 0x1b, s
|
lda 0x19, s
|
||||||
sta 0xca
|
sta 0xca
|
||||||
lda 0x21, s
|
lda 0x21, s
|
||||||
sta 0xc4
|
sta 0xc4
|
||||||
|
|
@ -317,7 +299,7 @@ evalAt: ; @evalAt
|
||||||
sta 0xc6
|
sta 0xc6
|
||||||
.LBB0_13: ; %cleanup
|
.LBB0_13: ; %cleanup
|
||||||
; in Loop: Header=BB0_5 Depth=1
|
; in Loop: Header=BB0_5 Depth=1
|
||||||
lda 0x19, s
|
lda 0x1b, s
|
||||||
clc
|
clc
|
||||||
adc #0x2
|
adc #0x2
|
||||||
sta 0x1f, s
|
sta 0x1f, s
|
||||||
|
|
@ -326,17 +308,13 @@ evalAt: ; @evalAt
|
||||||
adc #0x0
|
adc #0x0
|
||||||
sta 0x21, s
|
sta 0x21, s
|
||||||
lda 0x1f, s
|
lda 0x1f, s
|
||||||
sta 0x25, s
|
|
||||||
lda 0x21, s
|
|
||||||
tax
|
|
||||||
lda 0x25, s
|
|
||||||
sta 0xe0
|
sta 0xe0
|
||||||
txa
|
lda 0x21, s
|
||||||
sta 0xe2
|
sta 0xe2
|
||||||
ldy #0x0
|
ldy #0x0
|
||||||
lda [0xe0], y
|
lda [0xe0], y
|
||||||
sta 0x1d, s
|
sta 0x1f, s
|
||||||
lda 0x19, s
|
lda 0x1b, s
|
||||||
tax
|
tax
|
||||||
pha
|
pha
|
||||||
lda 0xc0
|
lda 0xc0
|
||||||
|
|
@ -348,30 +326,27 @@ evalAt: ; @evalAt
|
||||||
sta 0xe2
|
sta 0xe2
|
||||||
lda [0xe0], y
|
lda [0xe0], y
|
||||||
sta 0x21, s
|
sta 0x21, s
|
||||||
lda 0x1d, s
|
|
||||||
tax
|
|
||||||
lda 0x21, s
|
|
||||||
sta 0xe0
|
sta 0xe0
|
||||||
txa
|
lda 0x1f, s
|
||||||
sta 0xe2
|
sta 0xe2
|
||||||
lda [0xe0], y
|
lda [0xe0], y
|
||||||
and #0xff
|
and #0xff
|
||||||
.LBB0_5: ; %while.cond7
|
.LBB0_5: ; %while.cond7
|
||||||
; =>This Inner Loop Header: Depth=1
|
; =>This Inner Loop Header: Depth=1
|
||||||
sta 0x1b, s
|
sta 0x1d, s
|
||||||
sep #0x20
|
sep #0x20
|
||||||
clc
|
clc
|
||||||
adc #0xd6
|
adc #0xd6
|
||||||
rep #0x20
|
rep #0x20
|
||||||
and #0xff
|
and #0xff
|
||||||
sta 0x1f, s
|
sta 0x19, s
|
||||||
lda 0x1f, s
|
lda 0x19, s
|
||||||
pha
|
pha
|
||||||
lda #0x2b
|
lda #0x2b
|
||||||
jsl __lshrhi3
|
jsl __lshrhi3
|
||||||
ply
|
ply
|
||||||
sta 0x17, s
|
sta 0x17, s
|
||||||
lda 0x1f, s
|
lda 0x19, s
|
||||||
cmp #0x6
|
cmp #0x6
|
||||||
bcc .LBB0_6
|
bcc .LBB0_6
|
||||||
; %bb.17: ; %while.cond7
|
; %bb.17: ; %while.cond7
|
||||||
|
|
@ -382,58 +357,23 @@ evalAt: ; @evalAt
|
||||||
and #0x1
|
and #0x1
|
||||||
sta 0x17, s
|
sta 0x17, s
|
||||||
lda #0x0
|
lda #0x0
|
||||||
sta 0x33, s
|
sta 0x29, s
|
||||||
lda 0x17, s
|
lda 0x17, s
|
||||||
ora 0x33, s
|
ora 0x29, s
|
||||||
bne .LBB0_7
|
bne .LBB0_7
|
||||||
; %bb.18: ; %while.cond7
|
; %bb.18: ; %while.cond7
|
||||||
brl .LBB0_14
|
brl .LBB0_14
|
||||||
.LBB0_7: ; %switch.lookup
|
.LBB0_7: ; %switch.lookup
|
||||||
; in Loop: Header=BB0_5 Depth=1
|
; in Loop: Header=BB0_5 Depth=1
|
||||||
lda #0x0
|
lda 0x19, s
|
||||||
asl a
|
asl a
|
||||||
sta 0x17, s
|
|
||||||
lda 0x1f, s
|
|
||||||
asl a
|
|
||||||
lda #0x0
|
|
||||||
rol a
|
|
||||||
sta 0x31, s
|
|
||||||
lda 0x17, s
|
|
||||||
ora 0x31, s
|
|
||||||
sta 0x17, s
|
|
||||||
lda 0x1f, s
|
|
||||||
asl a
|
|
||||||
sta 0x1f, s
|
|
||||||
lda #.Lswitch.table.evalAt
|
|
||||||
sta 0x2f, s
|
|
||||||
lda 0x1f, s
|
|
||||||
clc
|
|
||||||
adc 0x2f, s
|
|
||||||
sta 0x1f, s
|
|
||||||
lda #0x0
|
|
||||||
sta 0x2d, s
|
|
||||||
lda 0x17, s
|
|
||||||
adc 0x2d, s
|
|
||||||
sta 0x17, s
|
|
||||||
lda 0x1f, s
|
|
||||||
sta 0x2b, s
|
|
||||||
lda 0x17, s
|
|
||||||
tax
|
|
||||||
lda 0x2b, s
|
|
||||||
sta 0xe0
|
|
||||||
txa
|
|
||||||
sta 0xe2
|
|
||||||
ldy #0x0
|
|
||||||
lda [0xe0 ], y
|
|
||||||
sta 0x1f, s
|
|
||||||
lda 0x1f, s
|
|
||||||
tax
|
tax
|
||||||
|
lda .Lswitch.table.evalAt, x
|
||||||
|
sta 0x19, s
|
||||||
eor #0x8000
|
eor #0x8000
|
||||||
sta 0x1f, s
|
sta 0x27, s
|
||||||
txa
|
|
||||||
sta 0x17, s
|
|
||||||
lda 0xb, s
|
lda 0xb, s
|
||||||
cmp 0x1f, s
|
cmp 0x27, s
|
||||||
bcc .LBB0_8
|
bcc .LBB0_8
|
||||||
; %bb.19: ; %switch.lookup
|
; %bb.19: ; %switch.lookup
|
||||||
brl .LBB0_14
|
brl .LBB0_14
|
||||||
|
|
@ -443,44 +383,40 @@ evalAt: ; @evalAt
|
||||||
inc a
|
inc a
|
||||||
sta 0x21, s
|
sta 0x21, s
|
||||||
bne .Ltmp1
|
bne .Ltmp1
|
||||||
lda 0x1d, s
|
lda 0x1f, s
|
||||||
inc a
|
inc a
|
||||||
sta 0x1d, s
|
sta 0x1f, s
|
||||||
.Ltmp1:
|
.Ltmp1:
|
||||||
lda 0x19, s
|
lda 0x1b, s
|
||||||
tax
|
tax
|
||||||
pha
|
pha
|
||||||
lda 0xc0
|
lda 0xc0
|
||||||
sta 0x2b, s
|
sta 0x27, s
|
||||||
pla
|
pla
|
||||||
txa
|
txa
|
||||||
sta 0xe0
|
sta 0xe0
|
||||||
lda 0x29, s
|
lda 0x25, s
|
||||||
sta 0xe2
|
sta 0xe2
|
||||||
lda 0x21, s
|
lda 0x21, s
|
||||||
ldy #0x0
|
ldy #0x0
|
||||||
sta [0xe0], y
|
sta [0xe0], y
|
||||||
lda 0x19, s
|
lda 0x1b, s
|
||||||
sta 0xd0
|
sta 0xd0
|
||||||
clc
|
clc
|
||||||
adc #0x2
|
adc #0x2
|
||||||
sta 0x1f, s
|
sta 0x17, s
|
||||||
lda 0xd0
|
lda 0xd0
|
||||||
sta 0x21, s
|
sta 0x21, s
|
||||||
lda 0xc0
|
lda 0xc0
|
||||||
adc #0x0
|
adc #0x0
|
||||||
sta 0x15, s
|
sta 0x15, s
|
||||||
lda 0x1f, s
|
|
||||||
sta 0x27, s
|
|
||||||
lda 0x15, s
|
|
||||||
tax
|
|
||||||
lda 0x27, s
|
|
||||||
sta 0xe0
|
|
||||||
txa
|
|
||||||
sta 0xe2
|
|
||||||
lda 0x1d, s
|
|
||||||
sta [0xe0 ], y
|
|
||||||
lda 0x17, s
|
lda 0x17, s
|
||||||
|
sta 0xe0
|
||||||
|
lda 0x15, s
|
||||||
|
sta 0xe2
|
||||||
|
lda 0x1f, s
|
||||||
|
sta [0xe0], y
|
||||||
|
lda 0x19, s
|
||||||
pha
|
pha
|
||||||
ldx 0xc0
|
ldx 0xc0
|
||||||
lda 0x23, s
|
lda 0x23, s
|
||||||
|
|
@ -495,10 +431,10 @@ evalAt: ; @evalAt
|
||||||
txa
|
txa
|
||||||
sta 0x1f, s
|
sta 0x1f, s
|
||||||
tya
|
tya
|
||||||
sta 0x1d, s
|
sta 0x19, s
|
||||||
lda 0xf0
|
lda 0xf0
|
||||||
sta 0x17, s
|
sta 0x17, s
|
||||||
lda 0x1b, s
|
lda 0x1d, s
|
||||||
and #0xff
|
and #0xff
|
||||||
cmp #0x2a
|
cmp #0x2a
|
||||||
bne .LBB0_9
|
bne .LBB0_9
|
||||||
|
|
@ -515,7 +451,7 @@ evalAt: ; @evalAt
|
||||||
.LBB0_10: ; %if.then29
|
.LBB0_10: ; %if.then29
|
||||||
; in Loop: Header=BB0_5 Depth=1
|
; in Loop: Header=BB0_5 Depth=1
|
||||||
lda 0xc6
|
lda 0xc6
|
||||||
sta 0x1b, s
|
sta 0x1d, s
|
||||||
lda 0xc4
|
lda 0xc4
|
||||||
sta 0x15, s
|
sta 0x15, s
|
||||||
lda 0xca
|
lda 0xca
|
||||||
|
|
@ -524,7 +460,7 @@ evalAt: ; @evalAt
|
||||||
sta 0x11, s
|
sta 0x11, s
|
||||||
lda 0x17, s
|
lda 0x17, s
|
||||||
pha
|
pha
|
||||||
lda 0x1f, s
|
lda 0x1b, s
|
||||||
pha
|
pha
|
||||||
lda 0x23, s
|
lda 0x23, s
|
||||||
pha
|
pha
|
||||||
|
|
@ -534,7 +470,7 @@ evalAt: ; @evalAt
|
||||||
pha
|
pha
|
||||||
lda 0x1b, s
|
lda 0x1b, s
|
||||||
pha
|
pha
|
||||||
lda 0x27, s
|
lda 0x29, s
|
||||||
tax
|
tax
|
||||||
lda 0x21, s
|
lda 0x21, s
|
||||||
jsl __adddf3
|
jsl __adddf3
|
||||||
|
|
@ -570,7 +506,7 @@ evalAt: ; @evalAt
|
||||||
sta 0xe0
|
sta 0xe0
|
||||||
tsc
|
tsc
|
||||||
clc
|
clc
|
||||||
adc #0x46
|
adc #0x2e
|
||||||
tcs
|
tcs
|
||||||
lda 0xe0
|
lda 0xe0
|
||||||
rtl
|
rtl
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# #
|
# #
|
||||||
# Calypsi ISO C compiler for 65816 version 5.16 #
|
# Calypsi ISO C compiler for 65816 version 5.16 #
|
||||||
# 14/May/2026 11:06:07 #
|
# 15/May/2026 00:38:15 #
|
||||||
# Command line: --speed -O 2 --64bit-doubles mul16to32.c -o #
|
# Command line: --speed -O 2 --64bit-doubles mul16to32.c -o #
|
||||||
# /tmp/mul16to32.calypsi.elf --list-file #
|
# /tmp/mul16to32.calypsi.elf --list-file #
|
||||||
# mul16to32.calypsi.lst #
|
# mul16to32.calypsi.lst #
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,7 @@
|
||||||
mul16to32: ; @mul16to32
|
mul16to32: ; @mul16to32
|
||||||
; %bb.0: ; %entry
|
; %bb.0: ; %entry
|
||||||
rep #0x30
|
rep #0x30
|
||||||
pha
|
jml __umulhisi3
|
||||||
lda 0x6, s
|
|
||||||
jsl __umulhisi3
|
|
||||||
ply
|
|
||||||
rtl
|
|
||||||
.Lfunc_end0:
|
.Lfunc_end0:
|
||||||
.size mul16to32, .Lfunc_end0-mul16to32
|
.size mul16to32, .Lfunc_end0-mul16to32
|
||||||
; -- End function
|
; -- End function
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# #
|
# #
|
||||||
# Calypsi ISO C compiler for 65816 version 5.16 #
|
# Calypsi ISO C compiler for 65816 version 5.16 #
|
||||||
# 14/May/2026 11:06:07 #
|
# 15/May/2026 00:38:15 #
|
||||||
# Command line: --speed -O 2 --64bit-doubles sumSquares.c -o #
|
# Command line: --speed -O 2 --64bit-doubles sumSquares.c -o #
|
||||||
# /tmp/sumSquares.calypsi.elf --list-file #
|
# /tmp/sumSquares.calypsi.elf --list-file #
|
||||||
# sumSquares.calypsi.lst #
|
# sumSquares.calypsi.lst #
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,7 @@ sumSquares: ; @sumSquares
|
||||||
sta 0xd4
|
sta 0xd4
|
||||||
inc 0xd2
|
inc 0xd2
|
||||||
dec 0xd0
|
dec 0xd0
|
||||||
beq .LBB0_5
|
bne .LBB0_4
|
||||||
bra .LBB0_4
|
|
||||||
.LBB0_5: ; %for.cond.cleanup
|
.LBB0_5: ; %for.cond.cleanup
|
||||||
lda 0xd4
|
lda 0xd4
|
||||||
tax
|
tax
|
||||||
|
|
|
||||||
149
demos/README.md
Normal file
149
demos/README.md
Normal file
|
|
@ -0,0 +1,149 @@
|
||||||
|
# llvm816 GS/OS Demo Apps
|
||||||
|
|
||||||
|
Small Apple IIgs S16 applications that build with our LLVM/clang
|
||||||
|
toolchain, wrap as OMF v2.1 ExpressLoad, and launch under real
|
||||||
|
GS/OS 6.0.2 in MAME.
|
||||||
|
|
||||||
|
## Building / running
|
||||||
|
|
||||||
|
```
|
||||||
|
bash demos/build.sh helloBeep # build the OMF
|
||||||
|
bash demos/launch.sh helloBeep # interactive run in MAME (visible window, audio)
|
||||||
|
bash demos/test.sh helloBeep # headless test (boots, runs, checks marker)
|
||||||
|
```
|
||||||
|
|
||||||
|
The launch script runs MAME with no timeout; close the MAME
|
||||||
|
window when done (Esc, then Cmd-Q). The test script injects a
|
||||||
|
keystroke after the demo has launched, then checks `$00:0070`
|
||||||
|
for the `0x99` end-of-run marker the demo writes before exit.
|
||||||
|
|
||||||
|
## Demos
|
||||||
|
|
||||||
|
### `helloBeep.c`
|
||||||
|
|
||||||
|
Three `SysBeep()` calls then exit. The toolbox `SysBeep` lives in
|
||||||
|
Misc Tools; no other startup needed (Loader handles MM + TL).
|
||||||
|
|
||||||
|
### `helloText.c`
|
||||||
|
|
||||||
|
Initialises Event Manager (so `GetNextEvent` can read keystrokes)
|
||||||
|
and Text Tools (so `WriteCString` has an output device), writes
|
||||||
|
two greeting lines to the text screen, waits for any keypress via
|
||||||
|
`GetNextEvent`, beeps, exits. Uses these toolbox calls:
|
||||||
|
|
||||||
|
- `MMStartUp`, `NewHandle` (DP allocation for Event Manager)
|
||||||
|
- `EMStartUp`, `GetNextEvent` (event-driven keyboard)
|
||||||
|
- `TextStartUp`, `SetOutputDevice`, `WriteCString` (text I/O)
|
||||||
|
- `SysBeep`
|
||||||
|
|
||||||
|
### `helloWindow.c`
|
||||||
|
|
||||||
|
Initialises the full Window Manager startup chain (Memory, QD,
|
||||||
|
Event, Scheduler, Window), constructs an Apple-IIgs-Toolbox-Ref
|
||||||
|
NewWindow parm block, and calls `NewWindow`. When NewWindow
|
||||||
|
returns a real handle the demo calls `SetPort`, `ShowWindow`,
|
||||||
|
`MoveTo`, and `DrawString` to put a greeting in the window, then
|
||||||
|
waits for a keypress, beeps, and exits.
|
||||||
|
|
||||||
|
Three toolchain bugs needed fixing to make this work end-to-end
|
||||||
|
under real GS/OS 6.0.2 (all now landed):
|
||||||
|
- **omfEmit RESSPC=0** for code segments — BSS got no memory
|
||||||
|
allocation; writes past the image end silently vanished. Now
|
||||||
|
BSS is embedded as zeros in the LCONST data.
|
||||||
|
- **Loader cRELOC at segPlacedBase=$0000** (not $1000 like our
|
||||||
|
text-base) — host probes need to compute runtime addresses as
|
||||||
|
`link_addr - text_base + bank<<16`.
|
||||||
|
- **`&symbol` bank=0** — proper backend fix landed. `LDAi16imm_bank`
|
||||||
|
AsmPrinter pseudo lowers to `lda $BE`; crt0 stores `PBR` to $BE
|
||||||
|
+ zero to $BF at startup, so the high half of every `&symbol`
|
||||||
|
pointer carries the actual load bank at runtime. Toolbox
|
||||||
|
pointer args now Just Work without per-wrapper PBR overrides.
|
||||||
|
|
||||||
|
### `orcaFrame.c`
|
||||||
|
|
||||||
|
First ORCA-style desktop application. Opens a Window Manager
|
||||||
|
window via `startdesk()` (full toolset chain), runs a TaskMaster
|
||||||
|
event loop until the close box / Q key / 1000-iteration watchdog
|
||||||
|
fires. Both 6.0.2 (`sys602.po`) and 6.0.4 (`6.0.4 - System.Disk.po`)
|
||||||
|
launch it cleanly; fTitle works on both.
|
||||||
|
|
||||||
|
### `orcaFrameLike.c`
|
||||||
|
|
||||||
|
Port of ORCA-C's `Frame.cc` sample (`tools/orca-c/C.Samples/
|
||||||
|
Desktop.Samples/Frame.cc`). Builds a standard Apple+File+Edit
|
||||||
|
menu bar (`NewMenu` + `InsertMenu` + `FixAppleMenu` + `DrawMenuBar`)
|
||||||
|
and dispatches `wInMenuBar` / `wInSpecial` events from `TaskMaster`.
|
||||||
|
File→Quit exits. Skips the original's Dialog Manager About box.
|
||||||
|
|
||||||
|
### `orcaMiniCadLike.c`
|
||||||
|
|
||||||
|
Port of ORCA-C's `MiniCAD.cc` (`Desktop.Samples/MiniCAD.cc`). Slim
|
||||||
|
port — opens a Window Manager content window but omits the line-
|
||||||
|
drawing primitives because adding them pushes past the Loader's
|
||||||
|
cRELOC threshold. Demonstrates the NewWindow path under
|
||||||
|
`startdesk`.
|
||||||
|
|
||||||
|
### `orcaReversiLike.c`
|
||||||
|
|
||||||
|
Port of ORCA-C's `Reversi.cc` (`Desktop.Samples/Reversi.cc`).
|
||||||
|
Menu-bar app — the ~1600 line game logic is omitted; the demo
|
||||||
|
shows the desktop scaffolding (menu + TaskMaster) the original
|
||||||
|
sits on top of.
|
||||||
|
|
||||||
|
### `qdProbe.c`
|
||||||
|
|
||||||
|
Diagnostic — minimal QD/EM/WM init followed by `RefreshDesktop`
|
||||||
|
plus ZP/SHR markers. Used to prove that `WindStartUp` does NOT
|
||||||
|
auto-paint the desktop and that `RefreshDesktop(NULL)` is what
|
||||||
|
actually fills SHR with the dithered desktop pattern. Run via
|
||||||
|
`scripts/probeQdStartup.sh`.
|
||||||
|
|
||||||
|
### Known limitations
|
||||||
|
|
||||||
|
- **fTitle on stripped 6.0.2:** orcaFrame uses fTitle and runs
|
||||||
|
fine on both 6.0.2 sys602.po and 6.0.4 System.Disk.po. Earlier
|
||||||
|
notes that fTitle required disk fonts were superseded — the
|
||||||
|
underlying bug was a `QDStartUp` argument-order mistake in
|
||||||
|
`runtime/src/desktop.c`, fixed 2026-05-16.
|
||||||
|
- **Window not visually painted:** `WindStartUp` does NOT paint
|
||||||
|
the desktop on its own; `RefreshDesktop(NULL)` is required.
|
||||||
|
Adding the call to `startdesk()` works for `qdProbe.c` but
|
||||||
|
pushes the orca demos past the GS/OS Loader's silent-rejection
|
||||||
|
threshold (see memory: `loader-creloc-threshold`).
|
||||||
|
- **GS/OS Loader cRELOC threshold:** anywhere from 65-90 cRELOCs
|
||||||
|
the Loader silently refuses to launch ExpressLoad OMFs. The
|
||||||
|
threshold is not a clean reloc-count cutoff; OMF byte layout
|
||||||
|
and reloc patch offsets both matter. The ORCA ports are slim
|
||||||
|
to stay under it.
|
||||||
|
|
||||||
|
## What got fixed during demo authoring
|
||||||
|
|
||||||
|
Substantive toolchain bugs surfaced and fixed:
|
||||||
|
|
||||||
|
- `iigsGsos.s` GS/OS wrappers and `genToolbox.py`'s 890 toolbox
|
||||||
|
wrappers were pushing 4-byte Long args low-word-first. ORCA-C's
|
||||||
|
PushLong macro is high-word-first. Anything passing a Long arg
|
||||||
|
through the toolbox dispatcher (NewHandle, NewWindow,
|
||||||
|
fopen->gsosOpen, etc.) was reading garbage parm-block pointers.
|
||||||
|
Fixed in both files plus the generator; regenerated 890
|
||||||
|
wrappers.
|
||||||
|
- `runtime/build.sh` wasn't rebuilding `iigsToolbox.s` -- the .o
|
||||||
|
was stale since May 4. Added the missing line.
|
||||||
|
- `(short)(*(void **)dpHandle)` was a double-dereference bug that
|
||||||
|
read garbage at the master pointer's destination instead of the
|
||||||
|
master pointer VALUE (= the DP address). Corrected to
|
||||||
|
`(unsigned short)(unsigned long)*(void **)dpHandle` for proper
|
||||||
|
block-address extraction.
|
||||||
|
- `helloText` used `TextStartUp + WriteCString` directly which
|
||||||
|
crashed to the IIgs monitor; fixed by adding `SetOutputDevice(1, 0)`
|
||||||
|
to wire stdout to the text screen.
|
||||||
|
- `helloText`'s event loop hung forever because `EMStartUp` wasn't
|
||||||
|
being called; fixed by adding it (with proper DP allocation).
|
||||||
|
|
||||||
|
## ptr32 mode note
|
||||||
|
|
||||||
|
All address constants in the demos (text screen $00:0400, SHR
|
||||||
|
RAM $E1:2000, soft switches $00:C0xx, keyboard register $00:C000)
|
||||||
|
are plain C 32-bit pointers like `(volatile unsigned char *)0xE12000UL`.
|
||||||
|
In ptr32 mode the compiler emits LONG addressing automatically;
|
||||||
|
no `switchToBank2`-style inline asm or DBR juggling required.
|
||||||
61
demos/build.sh
Executable file
61
demos/build.sh
Executable file
|
|
@ -0,0 +1,61 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# build.sh - compile a demo C source into a GS/OS-loadable OMF.
|
||||||
|
#
|
||||||
|
# Usage: bash demos/build.sh <basename>
|
||||||
|
# where demos/<basename>.c is the source. Output is
|
||||||
|
# demos/<basename>.omf in the same directory.
|
||||||
|
#
|
||||||
|
# Uses crt0Gsos (the GS/OS-aware crt) and ExpressLoad-wrapped multi-
|
||||||
|
# seg OMF so the slow-Loader rejection path is avoided. The OMF
|
||||||
|
# launches via runViaFinder.sh after cadius-injection onto the GS/OS
|
||||||
|
# data disk.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
|
||||||
|
[ $# -ge 1 ] || { echo "usage: $0 <basename>" >&2; exit 2; }
|
||||||
|
BASE="$1"
|
||||||
|
SRC="$SCRIPT_DIR/$BASE.c"
|
||||||
|
[ -f "$SRC" ] || { echo "no source: $SRC" >&2; exit 2; }
|
||||||
|
|
||||||
|
CLANG="$PROJECT_ROOT/tools/llvm-mos-build/bin/clang"
|
||||||
|
LINK="$PROJECT_ROOT/tools/link816"
|
||||||
|
OMF="$PROJECT_ROOT/tools/omfEmit"
|
||||||
|
|
||||||
|
OBJ="$SCRIPT_DIR/$BASE.o"
|
||||||
|
BIN="$SCRIPT_DIR/$BASE.bin"
|
||||||
|
MAP="$SCRIPT_DIR/$BASE.map"
|
||||||
|
RELOC="$SCRIPT_DIR/$BASE.reloc"
|
||||||
|
OUT="$SCRIPT_DIR/$BASE.omf"
|
||||||
|
|
||||||
|
echo "compile: $BASE.c -> $BASE.o"
|
||||||
|
"$CLANG" --target=w65816 -I"$PROJECT_ROOT/runtime/include" \
|
||||||
|
-O2 -ffunction-sections -c "$SRC" -o "$OBJ"
|
||||||
|
|
||||||
|
echo "link: -> $BASE.bin"
|
||||||
|
# bss-base 0xA000 keeps BSS above the SHR shadow region ($2000-$9FFF
|
||||||
|
# in bank 0 mirrors to bank E1 SHR memory). Without this, the smaller
|
||||||
|
# section-gc'd demos place BSS at e.g. $2300 and global writes scribble
|
||||||
|
# on the screen.
|
||||||
|
"$LINK" -o "$BIN" --text-base 0x1000 --bss-base 0xA000 \
|
||||||
|
--map "$MAP" --reloc-out "$RELOC" \
|
||||||
|
"$PROJECT_ROOT/runtime/crt0Gsos.o" "$OBJ" \
|
||||||
|
"$PROJECT_ROOT/runtime/libc.o" \
|
||||||
|
"$PROJECT_ROOT/runtime/snprintf.o" \
|
||||||
|
"$PROJECT_ROOT/runtime/extras.o" \
|
||||||
|
"$PROJECT_ROOT/runtime/softFloat.o" \
|
||||||
|
"$PROJECT_ROOT/runtime/softDouble.o" \
|
||||||
|
"$PROJECT_ROOT/runtime/iigsGsos.o" \
|
||||||
|
"$PROJECT_ROOT/runtime/iigsToolbox.o" \
|
||||||
|
"$PROJECT_ROOT/runtime/desktop.o" \
|
||||||
|
"$PROJECT_ROOT/runtime/libgcc.o"
|
||||||
|
|
||||||
|
echo "OMF: -> $BASE.omf"
|
||||||
|
"$OMF" --input "$BIN" --map "$MAP" \
|
||||||
|
--base 0x1000 --entry __start --output "$OUT" \
|
||||||
|
--name "$(echo "$BASE" | tr '[:lower:]' '[:upper:]' | cut -c1-8)" \
|
||||||
|
--expressload --relocs "$RELOC"
|
||||||
|
|
||||||
|
ls -la "$OUT"
|
||||||
|
echo "done: $OUT"
|
||||||
BIN
demos/frame.bin
Normal file
BIN
demos/frame.bin
Normal file
Binary file not shown.
97
demos/frame.c
Normal file
97
demos/frame.c
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
// frame.c - full port of ORCA-C's Frame.cc sample.
|
||||||
|
//
|
||||||
|
// Mike Westerfield's "Frame" desktop demo (Byte Works, 1989).
|
||||||
|
// Original at tools/orca-c/C.Samples/Desktop.Samples/Frame.cc.
|
||||||
|
//
|
||||||
|
// Uses the real ROM Menu Manager — startdesk's QD-DP allocation now
|
||||||
|
// reserves the full 512 bytes QD needs (own DP + cursor mgr at +$100),
|
||||||
|
// plus calls InitCursor. See feedback_drawmenubar_hang.md.
|
||||||
|
|
||||||
|
#include "iigs/toolbox.h"
|
||||||
|
#include "iigs/desktop.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define apple_About 257
|
||||||
|
#define file_Quit 256
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct { short v1, h1, v2, h2; } Rect;
|
||||||
|
|
||||||
|
|
||||||
|
// Menu definition strings — verbatim from Frame.cc.
|
||||||
|
static unsigned char appleMenuStr[] =
|
||||||
|
">>@\\XN1\r"
|
||||||
|
"--About Frame\\N257V\r"
|
||||||
|
".\r";
|
||||||
|
|
||||||
|
static unsigned char fileMenuStr[] =
|
||||||
|
">> File \\N2\r"
|
||||||
|
"--Close\\N255V\r"
|
||||||
|
"--Quit\\N256*Qq\r"
|
||||||
|
".\r";
|
||||||
|
|
||||||
|
static unsigned char editMenuStr[] =
|
||||||
|
">> Edit \\N3\r"
|
||||||
|
"--Undo\\N250V*Zz\r"
|
||||||
|
"--Cut\\N251*Xx\r"
|
||||||
|
"--Copy\\N252*Cc\r"
|
||||||
|
"--Paste\\N253*Vv\r"
|
||||||
|
"--Clear\\N254\r"
|
||||||
|
".\r";
|
||||||
|
|
||||||
|
// About-box message lines.
|
||||||
|
static const unsigned char line1[] = "\x09" "Frame 1.0";
|
||||||
|
static const unsigned char line2[] = "\x0e" "Copyright 1989";
|
||||||
|
static const unsigned char line3[] = "\x10" "Byte Works, Inc.";
|
||||||
|
static const unsigned char line4[] = "\x13" "By Mike Westerfield";
|
||||||
|
static const unsigned char btnOk[] = "\x02" "OK";
|
||||||
|
|
||||||
|
|
||||||
|
static void drawAbout(void) {
|
||||||
|
Rect outer;
|
||||||
|
outer.h1 = 180; outer.v1 = 50;
|
||||||
|
outer.h2 = 460; outer.v2 = 107;
|
||||||
|
|
||||||
|
SetSolidPenPat(15);
|
||||||
|
PaintRect(&outer);
|
||||||
|
SetSolidPenPat(0);
|
||||||
|
FrameRect(&outer);
|
||||||
|
|
||||||
|
MoveTo(195, 64); DrawString((void *)line1);
|
||||||
|
MoveTo(195, 74); DrawString((void *)line2);
|
||||||
|
MoveTo(195, 84); DrawString((void *)line3);
|
||||||
|
MoveTo(195, 94); DrawString((void *)line4);
|
||||||
|
|
||||||
|
Rect ok;
|
||||||
|
ok.h1 = 395; ok.v1 = 88;
|
||||||
|
ok.h2 = 445; ok.v2 = 102;
|
||||||
|
FrameRect(&ok);
|
||||||
|
MoveTo(412, 98);
|
||||||
|
DrawString((void *)btnOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void initMenus(void) {
|
||||||
|
InsertMenu(NewMenu(editMenuStr), 0);
|
||||||
|
InsertMenu(NewMenu(fileMenuStr), 0);
|
||||||
|
InsertMenu(NewMenu(appleMenuStr), 0);
|
||||||
|
FixAppleMenu(1);
|
||||||
|
FixMenuBar();
|
||||||
|
DrawMenuBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
unsigned short userId = startdesk(640);
|
||||||
|
(void)userId;
|
||||||
|
|
||||||
|
initMenus();
|
||||||
|
ShowCursor();
|
||||||
|
|
||||||
|
for (volatile unsigned long s = 0; s < 100000UL; s++) { }
|
||||||
|
drawAbout();
|
||||||
|
for (volatile unsigned long s = 0; s < 200000UL; s++) { }
|
||||||
|
|
||||||
|
*(volatile unsigned char *)0x70 = 0x99;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
213
demos/frame.map
Normal file
213
demos/frame.map
Normal file
|
|
@ -0,0 +1,213 @@
|
||||||
|
# section layout
|
||||||
|
.text : 0x001000 .. 0x0024b3 ( 5299 bytes)
|
||||||
|
.rodata : 0x0024b3 .. 0x0025b2 ( 255 bytes)
|
||||||
|
.bss : 0x00a000 .. 0x00a00a ( 10 bytes)
|
||||||
|
|
||||||
|
# per-input-file .text contributions
|
||||||
|
186 /home/scott/claude/llvm816/runtime/crt0Gsos.o
|
||||||
|
1287 /home/scott/claude/llvm816/demos/frame.o
|
||||||
|
43513 /home/scott/claude/llvm816/runtime/libc.o
|
||||||
|
5935 /home/scott/claude/llvm816/runtime/snprintf.o
|
||||||
|
11953 /home/scott/claude/llvm816/runtime/extras.o
|
||||||
|
7077 /home/scott/claude/llvm816/runtime/softFloat.o
|
||||||
|
15379 /home/scott/claude/llvm816/runtime/softDouble.o
|
||||||
|
176 /home/scott/claude/llvm816/runtime/iigsGsos.o
|
||||||
|
20670 /home/scott/claude/llvm816/runtime/iigsToolbox.o
|
||||||
|
1349 /home/scott/claude/llvm816/runtime/desktop.o
|
||||||
|
2540 /home/scott/claude/llvm816/runtime/libgcc.o
|
||||||
|
|
||||||
|
# global symbols (sorted by address)
|
||||||
|
0x000000 __bss_bank
|
||||||
|
0x000000 __bss_seg0_bank
|
||||||
|
0x000000 __bss_seg1_bank
|
||||||
|
0x000000 __bss_seg1_lo16
|
||||||
|
0x000000 __bss_seg1_size
|
||||||
|
0x000000 __bss_seg2_bank
|
||||||
|
0x000000 __bss_seg2_lo16
|
||||||
|
0x000000 __bss_seg2_size
|
||||||
|
0x000000 __bss_seg3_bank
|
||||||
|
0x000000 __bss_seg3_lo16
|
||||||
|
0x000000 __bss_seg3_size
|
||||||
|
0x00000a __bss_seg0_size
|
||||||
|
0x00000a __bss_size
|
||||||
|
0x001000 __start
|
||||||
|
0x001000 __text_start
|
||||||
|
0x0010ba main
|
||||||
|
0x0015c1 CtlStartUp
|
||||||
|
0x0015d1 EMStartUp
|
||||||
|
0x0015f0 FMStartUp
|
||||||
|
0x001600 LEStartUp
|
||||||
|
0x001610 LoadOneTool
|
||||||
|
0x001620 NewHandle
|
||||||
|
0x001646 MenuStartUp
|
||||||
|
0x001656 InsertMenu
|
||||||
|
0x00166b NewMenu
|
||||||
|
0x001685 QDStartUp
|
||||||
|
0x00169b DrawString
|
||||||
|
0x0016ad FrameRect
|
||||||
|
0x0016bf MoveTo
|
||||||
|
0x0016cf PaintRect
|
||||||
|
0x0016e1 startdesk
|
||||||
|
0x001ac7 __jsl_indir
|
||||||
|
0x001aca __mulhi3
|
||||||
|
0x001ae9 __umulhisi3
|
||||||
|
0x001b40 __ashlhi3
|
||||||
|
0x001b4f __lshrhi3
|
||||||
|
0x001b5f __ashrhi3
|
||||||
|
0x001b72 __udivhi3
|
||||||
|
0x001b7e __umodhi3
|
||||||
|
0x001b8a __divhi3
|
||||||
|
0x001ba4 __modhi3
|
||||||
|
0x001bbe __divmod_setup
|
||||||
|
0x001bf1 __udivmod_core
|
||||||
|
0x001c0f __mulsi3
|
||||||
|
0x001cc8 __ashlsi3
|
||||||
|
0x001cdd __lshrsi3
|
||||||
|
0x001cf2 __ashrsi3
|
||||||
|
0x001d0c __udivmodsi_core
|
||||||
|
0x001d44 __udivsi3
|
||||||
|
0x001d58 __umodsi3
|
||||||
|
0x001d6c __divsi3
|
||||||
|
0x001d93 __modsi3
|
||||||
|
0x001dba __divmodsi_setup
|
||||||
|
0x001e0b __divmoddi4_stash
|
||||||
|
0x001e28 __retdi
|
||||||
|
0x001e35 __ashldi3
|
||||||
|
0x001e58 __lshrdi3
|
||||||
|
0x001e7b __ashrdi3
|
||||||
|
0x001ea1 __muldi3
|
||||||
|
0x001efc __ucmpdi2
|
||||||
|
0x001f25 __cmpdi2
|
||||||
|
0x001f5c __udivdi3
|
||||||
|
0x001f65 __umoddi3
|
||||||
|
0x001f7e __udivmoddi_core
|
||||||
|
0x001fcb __divdi3
|
||||||
|
0x001fea __moddi3
|
||||||
|
0x002017 __absdi_a
|
||||||
|
0x00201f __absdi_b
|
||||||
|
0x002027 __negdi_a
|
||||||
|
0x002045 __negdi_b
|
||||||
|
0x002063 setjmp
|
||||||
|
0x00208b longjmp
|
||||||
|
0x0020b5 __umulhisi3_qsq
|
||||||
|
0x0024b3 __rodata_start
|
||||||
|
0x0024b3 __text_end
|
||||||
|
0x0024b3 gChainPath
|
||||||
|
0x0024c7 editMenuStr
|
||||||
|
0x002520 fileMenuStr
|
||||||
|
0x00254d appleMenuStr
|
||||||
|
0x00256c line1
|
||||||
|
0x002577 line2
|
||||||
|
0x002587 line3
|
||||||
|
0x002599 line4
|
||||||
|
0x0025ae btnOk
|
||||||
|
0x0025b2 __init_array_end
|
||||||
|
0x0025b2 __init_array_start
|
||||||
|
0x0025b2 __rodata_end
|
||||||
|
0x00a000 __bss_lo16
|
||||||
|
0x00a000 __bss_seg0_lo16
|
||||||
|
0x00a000 __bss_start
|
||||||
|
0x00a000 gUserId
|
||||||
|
0x00a002 gDpHandle
|
||||||
|
0x00a006 gDpBase
|
||||||
|
0x00a008 __indirTarget
|
||||||
|
0x00a00a __bss_end
|
||||||
|
0x00a00a __heap_start
|
||||||
|
0x00bf00 __heap_end
|
||||||
|
CtlStartUp = 0x0015c1
|
||||||
|
DrawString = 0x00169b
|
||||||
|
EMStartUp = 0x0015d1
|
||||||
|
FMStartUp = 0x0015f0
|
||||||
|
FrameRect = 0x0016ad
|
||||||
|
InsertMenu = 0x001656
|
||||||
|
LEStartUp = 0x001600
|
||||||
|
LoadOneTool = 0x001610
|
||||||
|
MenuStartUp = 0x001646
|
||||||
|
MoveTo = 0x0016bf
|
||||||
|
NewHandle = 0x001620
|
||||||
|
NewMenu = 0x00166b
|
||||||
|
PaintRect = 0x0016cf
|
||||||
|
QDStartUp = 0x001685
|
||||||
|
__absdi_a = 0x002017
|
||||||
|
__absdi_b = 0x00201f
|
||||||
|
__ashldi3 = 0x001e35
|
||||||
|
__ashlhi3 = 0x001b40
|
||||||
|
__ashlsi3 = 0x001cc8
|
||||||
|
__ashrdi3 = 0x001e7b
|
||||||
|
__ashrhi3 = 0x001b5f
|
||||||
|
__ashrsi3 = 0x001cf2
|
||||||
|
__bss_bank = 0x000000
|
||||||
|
__bss_end = 0x00a00a
|
||||||
|
__bss_lo16 = 0x00a000
|
||||||
|
__bss_seg0_bank = 0x000000
|
||||||
|
__bss_seg0_lo16 = 0x00a000
|
||||||
|
__bss_seg0_size = 0x00000a
|
||||||
|
__bss_seg1_bank = 0x000000
|
||||||
|
__bss_seg1_lo16 = 0x000000
|
||||||
|
__bss_seg1_size = 0x000000
|
||||||
|
__bss_seg2_bank = 0x000000
|
||||||
|
__bss_seg2_lo16 = 0x000000
|
||||||
|
__bss_seg2_size = 0x000000
|
||||||
|
__bss_seg3_bank = 0x000000
|
||||||
|
__bss_seg3_lo16 = 0x000000
|
||||||
|
__bss_seg3_size = 0x000000
|
||||||
|
__bss_size = 0x00000a
|
||||||
|
__bss_start = 0x00a000
|
||||||
|
__cmpdi2 = 0x001f25
|
||||||
|
__divdi3 = 0x001fcb
|
||||||
|
__divhi3 = 0x001b8a
|
||||||
|
__divmod_setup = 0x001bbe
|
||||||
|
__divmoddi4_stash = 0x001e0b
|
||||||
|
__divmodsi_setup = 0x001dba
|
||||||
|
__divsi3 = 0x001d6c
|
||||||
|
__heap_end = 0x00bf00
|
||||||
|
__heap_start = 0x00a00a
|
||||||
|
__indirTarget = 0x00a008
|
||||||
|
__init_array_end = 0x0025b2
|
||||||
|
__init_array_start = 0x0025b2
|
||||||
|
__jsl_indir = 0x001ac7
|
||||||
|
__lshrdi3 = 0x001e58
|
||||||
|
__lshrhi3 = 0x001b4f
|
||||||
|
__lshrsi3 = 0x001cdd
|
||||||
|
__moddi3 = 0x001fea
|
||||||
|
__modhi3 = 0x001ba4
|
||||||
|
__modsi3 = 0x001d93
|
||||||
|
__muldi3 = 0x001ea1
|
||||||
|
__mulhi3 = 0x001aca
|
||||||
|
__mulsi3 = 0x001c0f
|
||||||
|
__negdi_a = 0x002027
|
||||||
|
__negdi_b = 0x002045
|
||||||
|
__retdi = 0x001e28
|
||||||
|
__rodata_end = 0x0025b2
|
||||||
|
__rodata_start = 0x0024b3
|
||||||
|
__start = 0x001000
|
||||||
|
__text_end = 0x0024b3
|
||||||
|
__text_start = 0x001000
|
||||||
|
__ucmpdi2 = 0x001efc
|
||||||
|
__udivdi3 = 0x001f5c
|
||||||
|
__udivhi3 = 0x001b72
|
||||||
|
__udivmod_core = 0x001bf1
|
||||||
|
__udivmoddi_core = 0x001f7e
|
||||||
|
__udivmodsi_core = 0x001d0c
|
||||||
|
__udivsi3 = 0x001d44
|
||||||
|
__umoddi3 = 0x001f65
|
||||||
|
__umodhi3 = 0x001b7e
|
||||||
|
__umodsi3 = 0x001d58
|
||||||
|
__umulhisi3 = 0x001ae9
|
||||||
|
__umulhisi3_qsq = 0x0020b5
|
||||||
|
appleMenuStr = 0x00254d
|
||||||
|
btnOk = 0x0025ae
|
||||||
|
editMenuStr = 0x0024c7
|
||||||
|
fileMenuStr = 0x002520
|
||||||
|
gChainPath = 0x0024b3
|
||||||
|
gDpBase = 0x00a006
|
||||||
|
gDpHandle = 0x00a002
|
||||||
|
gUserId = 0x00a000
|
||||||
|
line1 = 0x00256c
|
||||||
|
line2 = 0x002577
|
||||||
|
line3 = 0x002587
|
||||||
|
line4 = 0x002599
|
||||||
|
longjmp = 0x00208b
|
||||||
|
main = 0x0010ba
|
||||||
|
setjmp = 0x002063
|
||||||
|
startdesk = 0x0016e1
|
||||||
BIN
demos/frame.o
Normal file
BIN
demos/frame.o
Normal file
Binary file not shown.
BIN
demos/frame.omf
Normal file
BIN
demos/frame.omf
Normal file
Binary file not shown.
BIN
demos/frame.reloc
Normal file
BIN
demos/frame.reloc
Normal file
Binary file not shown.
BIN
demos/heavyRelocs.bin
Normal file
BIN
demos/heavyRelocs.bin
Normal file
Binary file not shown.
38
demos/heavyRelocs.c
Normal file
38
demos/heavyRelocs.c
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
// heavyRelocs.c - stress test for ExpressLoad cRELOC handling.
|
||||||
|
#include "iigs/toolbox.h"
|
||||||
|
|
||||||
|
// Code padding via large initialized data (NOT const so it lands in
|
||||||
|
// .data and survives -O2 dead-strip).
|
||||||
|
volatile unsigned char gBigData[20000] = { [0 ... 19999] = 0xAA };
|
||||||
|
|
||||||
|
static unsigned char gA[16], gB[16], gC[16], gD[16];
|
||||||
|
static unsigned char gE[16], gF[16], gG[16], gH[16];
|
||||||
|
static unsigned char gI[16], gJ[16], gK[16], gL[16];
|
||||||
|
static unsigned char gM[16], gN[16], gO[16], gP[16];
|
||||||
|
static unsigned char gQ[16], gR[16], gS[16], gT[16];
|
||||||
|
static unsigned char gU[16], gV[16], gW[16], gX[16];
|
||||||
|
static unsigned char gY[16], gZ[16];
|
||||||
|
|
||||||
|
static unsigned char *gPtrs[100] = {
|
||||||
|
gA, gB, gC, gD, gE, gF, gG, gH, gI, gJ,
|
||||||
|
gK, gL, gM, gN, gO, gP, gQ, gR, gS, gT,
|
||||||
|
gU, gV, gW, gX, gY, gZ, gA, gB, gC, gD,
|
||||||
|
gE, gF, gG, gH, gI, gJ, gK, gL, gM, gN,
|
||||||
|
gO, gP, gQ, gR, gS, gT, gU, gV, gW, gX,
|
||||||
|
gY, gZ, gA, gB, gC, gD, gE, gF, gG, gH,
|
||||||
|
gI, gJ, gK, gL, gM, gN, gO, gP, gQ, gR,
|
||||||
|
gS, gT, gU, gV, gW, gX, gY, gZ, gA, gB,
|
||||||
|
gC, gD, gE, gF, gG, gH, gI, gJ, gK, gL,
|
||||||
|
gM, gN, gO, gP, gQ, gR, gS, gT, gU, gV,
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
for (unsigned short i = 0; i < 100; i++) {
|
||||||
|
gPtrs[i][0] = (unsigned char)i;
|
||||||
|
}
|
||||||
|
gA[0] = gBigData[0] + gBigData[19999];
|
||||||
|
*(volatile unsigned char *)0x70 = 0x99;
|
||||||
|
// Brief linger for snapshot capture.
|
||||||
|
for (volatile unsigned long s = 0; s < 600000UL; s++) { }
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
217
demos/heavyRelocs.map
Normal file
217
demos/heavyRelocs.map
Normal file
|
|
@ -0,0 +1,217 @@
|
||||||
|
# section layout
|
||||||
|
.text : 0x001000 .. 0x001caa ( 3242 bytes)
|
||||||
|
.rodata : 0x001caa .. 0x006c6e ( 20420 bytes)
|
||||||
|
.bss : 0x00a000 .. 0x00a1a2 ( 418 bytes)
|
||||||
|
|
||||||
|
# per-input-file .text contributions
|
||||||
|
186 /home/scott/claude/llvm816/runtime/crt0Gsos.o
|
||||||
|
516 /home/scott/claude/llvm816/demos/heavyRelocs.o
|
||||||
|
43513 /home/scott/claude/llvm816/runtime/libc.o
|
||||||
|
5935 /home/scott/claude/llvm816/runtime/snprintf.o
|
||||||
|
11953 /home/scott/claude/llvm816/runtime/extras.o
|
||||||
|
7077 /home/scott/claude/llvm816/runtime/softFloat.o
|
||||||
|
15379 /home/scott/claude/llvm816/runtime/softDouble.o
|
||||||
|
176 /home/scott/claude/llvm816/runtime/iigsGsos.o
|
||||||
|
20670 /home/scott/claude/llvm816/runtime/iigsToolbox.o
|
||||||
|
1349 /home/scott/claude/llvm816/runtime/desktop.o
|
||||||
|
2540 /home/scott/claude/llvm816/runtime/libgcc.o
|
||||||
|
|
||||||
|
# global symbols (sorted by address)
|
||||||
|
0x000000 __bss_bank
|
||||||
|
0x000000 __bss_seg0_bank
|
||||||
|
0x000000 __bss_seg1_bank
|
||||||
|
0x000000 __bss_seg1_lo16
|
||||||
|
0x000000 __bss_seg1_size
|
||||||
|
0x000000 __bss_seg2_bank
|
||||||
|
0x000000 __bss_seg2_lo16
|
||||||
|
0x000000 __bss_seg2_size
|
||||||
|
0x000000 __bss_seg3_bank
|
||||||
|
0x000000 __bss_seg3_lo16
|
||||||
|
0x000000 __bss_seg3_size
|
||||||
|
0x0001a2 __bss_seg0_size
|
||||||
|
0x0001a2 __bss_size
|
||||||
|
0x001000 __start
|
||||||
|
0x001000 __text_start
|
||||||
|
0x0010ba main
|
||||||
|
0x0012be __jsl_indir
|
||||||
|
0x0012c1 __mulhi3
|
||||||
|
0x0012e0 __umulhisi3
|
||||||
|
0x001337 __ashlhi3
|
||||||
|
0x001346 __lshrhi3
|
||||||
|
0x001356 __ashrhi3
|
||||||
|
0x001369 __udivhi3
|
||||||
|
0x001375 __umodhi3
|
||||||
|
0x001381 __divhi3
|
||||||
|
0x00139b __modhi3
|
||||||
|
0x0013b5 __divmod_setup
|
||||||
|
0x0013e8 __udivmod_core
|
||||||
|
0x001406 __mulsi3
|
||||||
|
0x0014bf __ashlsi3
|
||||||
|
0x0014d4 __lshrsi3
|
||||||
|
0x0014e9 __ashrsi3
|
||||||
|
0x001503 __udivmodsi_core
|
||||||
|
0x00153b __udivsi3
|
||||||
|
0x00154f __umodsi3
|
||||||
|
0x001563 __divsi3
|
||||||
|
0x00158a __modsi3
|
||||||
|
0x0015b1 __divmodsi_setup
|
||||||
|
0x001602 __divmoddi4_stash
|
||||||
|
0x00161f __retdi
|
||||||
|
0x00162c __ashldi3
|
||||||
|
0x00164f __lshrdi3
|
||||||
|
0x001672 __ashrdi3
|
||||||
|
0x001698 __muldi3
|
||||||
|
0x0016f3 __ucmpdi2
|
||||||
|
0x00171c __cmpdi2
|
||||||
|
0x001753 __udivdi3
|
||||||
|
0x00175c __umoddi3
|
||||||
|
0x001775 __udivmoddi_core
|
||||||
|
0x0017c2 __divdi3
|
||||||
|
0x0017e1 __moddi3
|
||||||
|
0x00180e __absdi_a
|
||||||
|
0x001816 __absdi_b
|
||||||
|
0x00181e __negdi_a
|
||||||
|
0x00183c __negdi_b
|
||||||
|
0x00185a setjmp
|
||||||
|
0x001882 longjmp
|
||||||
|
0x0018ac __umulhisi3_qsq
|
||||||
|
0x001caa __rodata_start
|
||||||
|
0x001caa __text_end
|
||||||
|
0x001caa gChainPath
|
||||||
|
0x001cbe gBigData
|
||||||
|
0x006ade gPtrs
|
||||||
|
0x006c6e __init_array_end
|
||||||
|
0x006c6e __init_array_start
|
||||||
|
0x006c6e __rodata_end
|
||||||
|
0x00a000 __bss_lo16
|
||||||
|
0x00a000 __bss_seg0_lo16
|
||||||
|
0x00a000 __bss_start
|
||||||
|
0x00a000 gA
|
||||||
|
0x00a010 gB
|
||||||
|
0x00a020 gC
|
||||||
|
0x00a030 gD
|
||||||
|
0x00a040 gE
|
||||||
|
0x00a050 gF
|
||||||
|
0x00a060 gG
|
||||||
|
0x00a070 gH
|
||||||
|
0x00a080 gI
|
||||||
|
0x00a090 gJ
|
||||||
|
0x00a0a0 gK
|
||||||
|
0x00a0b0 gL
|
||||||
|
0x00a0c0 gM
|
||||||
|
0x00a0d0 gN
|
||||||
|
0x00a0e0 gO
|
||||||
|
0x00a0f0 gP
|
||||||
|
0x00a100 gQ
|
||||||
|
0x00a110 gR
|
||||||
|
0x00a120 gS
|
||||||
|
0x00a130 gT
|
||||||
|
0x00a140 gU
|
||||||
|
0x00a150 gV
|
||||||
|
0x00a160 gW
|
||||||
|
0x00a170 gX
|
||||||
|
0x00a180 gY
|
||||||
|
0x00a190 gZ
|
||||||
|
0x00a1a0 __indirTarget
|
||||||
|
0x00a1a2 __bss_end
|
||||||
|
0x00a1a2 __heap_start
|
||||||
|
0x00bf00 __heap_end
|
||||||
|
__absdi_a = 0x00180e
|
||||||
|
__absdi_b = 0x001816
|
||||||
|
__ashldi3 = 0x00162c
|
||||||
|
__ashlhi3 = 0x001337
|
||||||
|
__ashlsi3 = 0x0014bf
|
||||||
|
__ashrdi3 = 0x001672
|
||||||
|
__ashrhi3 = 0x001356
|
||||||
|
__ashrsi3 = 0x0014e9
|
||||||
|
__bss_bank = 0x000000
|
||||||
|
__bss_end = 0x00a1a2
|
||||||
|
__bss_lo16 = 0x00a000
|
||||||
|
__bss_seg0_bank = 0x000000
|
||||||
|
__bss_seg0_lo16 = 0x00a000
|
||||||
|
__bss_seg0_size = 0x0001a2
|
||||||
|
__bss_seg1_bank = 0x000000
|
||||||
|
__bss_seg1_lo16 = 0x000000
|
||||||
|
__bss_seg1_size = 0x000000
|
||||||
|
__bss_seg2_bank = 0x000000
|
||||||
|
__bss_seg2_lo16 = 0x000000
|
||||||
|
__bss_seg2_size = 0x000000
|
||||||
|
__bss_seg3_bank = 0x000000
|
||||||
|
__bss_seg3_lo16 = 0x000000
|
||||||
|
__bss_seg3_size = 0x000000
|
||||||
|
__bss_size = 0x0001a2
|
||||||
|
__bss_start = 0x00a000
|
||||||
|
__cmpdi2 = 0x00171c
|
||||||
|
__divdi3 = 0x0017c2
|
||||||
|
__divhi3 = 0x001381
|
||||||
|
__divmod_setup = 0x0013b5
|
||||||
|
__divmoddi4_stash = 0x001602
|
||||||
|
__divmodsi_setup = 0x0015b1
|
||||||
|
__divsi3 = 0x001563
|
||||||
|
__heap_end = 0x00bf00
|
||||||
|
__heap_start = 0x00a1a2
|
||||||
|
__indirTarget = 0x00a1a0
|
||||||
|
__init_array_end = 0x006c6e
|
||||||
|
__init_array_start = 0x006c6e
|
||||||
|
__jsl_indir = 0x0012be
|
||||||
|
__lshrdi3 = 0x00164f
|
||||||
|
__lshrhi3 = 0x001346
|
||||||
|
__lshrsi3 = 0x0014d4
|
||||||
|
__moddi3 = 0x0017e1
|
||||||
|
__modhi3 = 0x00139b
|
||||||
|
__modsi3 = 0x00158a
|
||||||
|
__muldi3 = 0x001698
|
||||||
|
__mulhi3 = 0x0012c1
|
||||||
|
__mulsi3 = 0x001406
|
||||||
|
__negdi_a = 0x00181e
|
||||||
|
__negdi_b = 0x00183c
|
||||||
|
__retdi = 0x00161f
|
||||||
|
__rodata_end = 0x006c6e
|
||||||
|
__rodata_start = 0x001caa
|
||||||
|
__start = 0x001000
|
||||||
|
__text_end = 0x001caa
|
||||||
|
__text_start = 0x001000
|
||||||
|
__ucmpdi2 = 0x0016f3
|
||||||
|
__udivdi3 = 0x001753
|
||||||
|
__udivhi3 = 0x001369
|
||||||
|
__udivmod_core = 0x0013e8
|
||||||
|
__udivmoddi_core = 0x001775
|
||||||
|
__udivmodsi_core = 0x001503
|
||||||
|
__udivsi3 = 0x00153b
|
||||||
|
__umoddi3 = 0x00175c
|
||||||
|
__umodhi3 = 0x001375
|
||||||
|
__umodsi3 = 0x00154f
|
||||||
|
__umulhisi3 = 0x0012e0
|
||||||
|
__umulhisi3_qsq = 0x0018ac
|
||||||
|
gA = 0x00a000
|
||||||
|
gB = 0x00a010
|
||||||
|
gBigData = 0x001cbe
|
||||||
|
gC = 0x00a020
|
||||||
|
gChainPath = 0x001caa
|
||||||
|
gD = 0x00a030
|
||||||
|
gE = 0x00a040
|
||||||
|
gF = 0x00a050
|
||||||
|
gG = 0x00a060
|
||||||
|
gH = 0x00a070
|
||||||
|
gI = 0x00a080
|
||||||
|
gJ = 0x00a090
|
||||||
|
gK = 0x00a0a0
|
||||||
|
gL = 0x00a0b0
|
||||||
|
gM = 0x00a0c0
|
||||||
|
gN = 0x00a0d0
|
||||||
|
gO = 0x00a0e0
|
||||||
|
gP = 0x00a0f0
|
||||||
|
gPtrs = 0x006ade
|
||||||
|
gQ = 0x00a100
|
||||||
|
gR = 0x00a110
|
||||||
|
gS = 0x00a120
|
||||||
|
gT = 0x00a130
|
||||||
|
gU = 0x00a140
|
||||||
|
gV = 0x00a150
|
||||||
|
gW = 0x00a160
|
||||||
|
gX = 0x00a170
|
||||||
|
gY = 0x00a180
|
||||||
|
gZ = 0x00a190
|
||||||
|
longjmp = 0x001882
|
||||||
|
main = 0x0010ba
|
||||||
|
setjmp = 0x00185a
|
||||||
BIN
demos/heavyRelocs.o
Normal file
BIN
demos/heavyRelocs.o
Normal file
Binary file not shown.
BIN
demos/heavyRelocs.omf
Normal file
BIN
demos/heavyRelocs.omf
Normal file
Binary file not shown.
BIN
demos/heavyRelocs.reloc
Normal file
BIN
demos/heavyRelocs.reloc
Normal file
Binary file not shown.
BIN
demos/helloBeep.bin
Normal file
BIN
demos/helloBeep.bin
Normal file
Binary file not shown.
25
demos/helloBeep.c
Normal file
25
demos/helloBeep.c
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
// helloBeep.c - simplest possible GS/OS app. Three SysBeep calls then
|
||||||
|
// exit. Verifies the OMF + Loader path: if the IIgs makes three beeps,
|
||||||
|
// the app launched, ran, and returned cleanly.
|
||||||
|
//
|
||||||
|
// No toolbox startup is needed - the Loader has already done TLStartUp
|
||||||
|
// + MMStartUp for us, and SysBeep is a Misc Tools call that works
|
||||||
|
// without additional setup.
|
||||||
|
//
|
||||||
|
// Build with: bash demos/build.sh helloBeep
|
||||||
|
// Run with: bash scripts/runViaFinder.sh helloBeep.omf --check 0x70=0x42
|
||||||
|
|
||||||
|
#include "iigs/toolbox.h"
|
||||||
|
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
SysBeep();
|
||||||
|
SysBeep();
|
||||||
|
SysBeep();
|
||||||
|
*(volatile unsigned char *)0x70 = 0x99; // for headless verify
|
||||||
|
// Brief linger so snapshot tools can capture the post-Finder state
|
||||||
|
// before we exit (otherwise the screen snaps in the middle of GS/OS
|
||||||
|
// tearing the launcher state down).
|
||||||
|
for (volatile unsigned long s = 0; s < 600000UL; s++) { }
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
161
demos/helloBeep.map
Normal file
161
demos/helloBeep.map
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
# section layout
|
||||||
|
.text : 0x001000 .. 0x001c37 ( 3127 bytes)
|
||||||
|
.rodata : 0x001c37 .. 0x001c4b ( 20 bytes)
|
||||||
|
.bss : 0x00a000 .. 0x00a002 ( 2 bytes)
|
||||||
|
|
||||||
|
# per-input-file .text contributions
|
||||||
|
186 /home/scott/claude/llvm816/runtime/crt0Gsos.o
|
||||||
|
401 /home/scott/claude/llvm816/demos/helloBeep.o
|
||||||
|
43513 /home/scott/claude/llvm816/runtime/libc.o
|
||||||
|
5935 /home/scott/claude/llvm816/runtime/snprintf.o
|
||||||
|
11953 /home/scott/claude/llvm816/runtime/extras.o
|
||||||
|
7077 /home/scott/claude/llvm816/runtime/softFloat.o
|
||||||
|
15379 /home/scott/claude/llvm816/runtime/softDouble.o
|
||||||
|
176 /home/scott/claude/llvm816/runtime/iigsGsos.o
|
||||||
|
20670 /home/scott/claude/llvm816/runtime/iigsToolbox.o
|
||||||
|
1349 /home/scott/claude/llvm816/runtime/desktop.o
|
||||||
|
2540 /home/scott/claude/llvm816/runtime/libgcc.o
|
||||||
|
|
||||||
|
# global symbols (sorted by address)
|
||||||
|
0x000000 __bss_bank
|
||||||
|
0x000000 __bss_seg0_bank
|
||||||
|
0x000000 __bss_seg1_bank
|
||||||
|
0x000000 __bss_seg1_lo16
|
||||||
|
0x000000 __bss_seg1_size
|
||||||
|
0x000000 __bss_seg2_bank
|
||||||
|
0x000000 __bss_seg2_lo16
|
||||||
|
0x000000 __bss_seg2_size
|
||||||
|
0x000000 __bss_seg3_bank
|
||||||
|
0x000000 __bss_seg3_lo16
|
||||||
|
0x000000 __bss_seg3_size
|
||||||
|
0x000002 __bss_seg0_size
|
||||||
|
0x000002 __bss_size
|
||||||
|
0x001000 __start
|
||||||
|
0x001000 __text_start
|
||||||
|
0x0010ba main
|
||||||
|
0x00124b __jsl_indir
|
||||||
|
0x00124e __mulhi3
|
||||||
|
0x00126d __umulhisi3
|
||||||
|
0x0012c4 __ashlhi3
|
||||||
|
0x0012d3 __lshrhi3
|
||||||
|
0x0012e3 __ashrhi3
|
||||||
|
0x0012f6 __udivhi3
|
||||||
|
0x001302 __umodhi3
|
||||||
|
0x00130e __divhi3
|
||||||
|
0x001328 __modhi3
|
||||||
|
0x001342 __divmod_setup
|
||||||
|
0x001375 __udivmod_core
|
||||||
|
0x001393 __mulsi3
|
||||||
|
0x00144c __ashlsi3
|
||||||
|
0x001461 __lshrsi3
|
||||||
|
0x001476 __ashrsi3
|
||||||
|
0x001490 __udivmodsi_core
|
||||||
|
0x0014c8 __udivsi3
|
||||||
|
0x0014dc __umodsi3
|
||||||
|
0x0014f0 __divsi3
|
||||||
|
0x001517 __modsi3
|
||||||
|
0x00153e __divmodsi_setup
|
||||||
|
0x00158f __divmoddi4_stash
|
||||||
|
0x0015ac __retdi
|
||||||
|
0x0015b9 __ashldi3
|
||||||
|
0x0015dc __lshrdi3
|
||||||
|
0x0015ff __ashrdi3
|
||||||
|
0x001625 __muldi3
|
||||||
|
0x001680 __ucmpdi2
|
||||||
|
0x0016a9 __cmpdi2
|
||||||
|
0x0016e0 __udivdi3
|
||||||
|
0x0016e9 __umoddi3
|
||||||
|
0x001702 __udivmoddi_core
|
||||||
|
0x00174f __divdi3
|
||||||
|
0x00176e __moddi3
|
||||||
|
0x00179b __absdi_a
|
||||||
|
0x0017a3 __absdi_b
|
||||||
|
0x0017ab __negdi_a
|
||||||
|
0x0017c9 __negdi_b
|
||||||
|
0x0017e7 setjmp
|
||||||
|
0x00180f longjmp
|
||||||
|
0x001839 __umulhisi3_qsq
|
||||||
|
0x001c37 __rodata_start
|
||||||
|
0x001c37 __text_end
|
||||||
|
0x001c37 gChainPath
|
||||||
|
0x001c4b __init_array_end
|
||||||
|
0x001c4b __init_array_start
|
||||||
|
0x001c4b __rodata_end
|
||||||
|
0x00a000 __bss_lo16
|
||||||
|
0x00a000 __bss_seg0_lo16
|
||||||
|
0x00a000 __bss_start
|
||||||
|
0x00a000 __indirTarget
|
||||||
|
0x00a002 __bss_end
|
||||||
|
0x00a002 __heap_start
|
||||||
|
0x00bf00 __heap_end
|
||||||
|
__absdi_a = 0x00179b
|
||||||
|
__absdi_b = 0x0017a3
|
||||||
|
__ashldi3 = 0x0015b9
|
||||||
|
__ashlhi3 = 0x0012c4
|
||||||
|
__ashlsi3 = 0x00144c
|
||||||
|
__ashrdi3 = 0x0015ff
|
||||||
|
__ashrhi3 = 0x0012e3
|
||||||
|
__ashrsi3 = 0x001476
|
||||||
|
__bss_bank = 0x000000
|
||||||
|
__bss_end = 0x00a002
|
||||||
|
__bss_lo16 = 0x00a000
|
||||||
|
__bss_seg0_bank = 0x000000
|
||||||
|
__bss_seg0_lo16 = 0x00a000
|
||||||
|
__bss_seg0_size = 0x000002
|
||||||
|
__bss_seg1_bank = 0x000000
|
||||||
|
__bss_seg1_lo16 = 0x000000
|
||||||
|
__bss_seg1_size = 0x000000
|
||||||
|
__bss_seg2_bank = 0x000000
|
||||||
|
__bss_seg2_lo16 = 0x000000
|
||||||
|
__bss_seg2_size = 0x000000
|
||||||
|
__bss_seg3_bank = 0x000000
|
||||||
|
__bss_seg3_lo16 = 0x000000
|
||||||
|
__bss_seg3_size = 0x000000
|
||||||
|
__bss_size = 0x000002
|
||||||
|
__bss_start = 0x00a000
|
||||||
|
__cmpdi2 = 0x0016a9
|
||||||
|
__divdi3 = 0x00174f
|
||||||
|
__divhi3 = 0x00130e
|
||||||
|
__divmod_setup = 0x001342
|
||||||
|
__divmoddi4_stash = 0x00158f
|
||||||
|
__divmodsi_setup = 0x00153e
|
||||||
|
__divsi3 = 0x0014f0
|
||||||
|
__heap_end = 0x00bf00
|
||||||
|
__heap_start = 0x00a002
|
||||||
|
__indirTarget = 0x00a000
|
||||||
|
__init_array_end = 0x001c4b
|
||||||
|
__init_array_start = 0x001c4b
|
||||||
|
__jsl_indir = 0x00124b
|
||||||
|
__lshrdi3 = 0x0015dc
|
||||||
|
__lshrhi3 = 0x0012d3
|
||||||
|
__lshrsi3 = 0x001461
|
||||||
|
__moddi3 = 0x00176e
|
||||||
|
__modhi3 = 0x001328
|
||||||
|
__modsi3 = 0x001517
|
||||||
|
__muldi3 = 0x001625
|
||||||
|
__mulhi3 = 0x00124e
|
||||||
|
__mulsi3 = 0x001393
|
||||||
|
__negdi_a = 0x0017ab
|
||||||
|
__negdi_b = 0x0017c9
|
||||||
|
__retdi = 0x0015ac
|
||||||
|
__rodata_end = 0x001c4b
|
||||||
|
__rodata_start = 0x001c37
|
||||||
|
__start = 0x001000
|
||||||
|
__text_end = 0x001c37
|
||||||
|
__text_start = 0x001000
|
||||||
|
__ucmpdi2 = 0x001680
|
||||||
|
__udivdi3 = 0x0016e0
|
||||||
|
__udivhi3 = 0x0012f6
|
||||||
|
__udivmod_core = 0x001375
|
||||||
|
__udivmoddi_core = 0x001702
|
||||||
|
__udivmodsi_core = 0x001490
|
||||||
|
__udivsi3 = 0x0014c8
|
||||||
|
__umoddi3 = 0x0016e9
|
||||||
|
__umodhi3 = 0x001302
|
||||||
|
__umodsi3 = 0x0014dc
|
||||||
|
__umulhisi3 = 0x00126d
|
||||||
|
__umulhisi3_qsq = 0x001839
|
||||||
|
gChainPath = 0x001c37
|
||||||
|
longjmp = 0x00180f
|
||||||
|
main = 0x0010ba
|
||||||
|
setjmp = 0x0017e7
|
||||||
BIN
demos/helloBeep.o
Normal file
BIN
demos/helloBeep.o
Normal file
Binary file not shown.
BIN
demos/helloBeep.omf
Normal file
BIN
demos/helloBeep.omf
Normal file
Binary file not shown.
BIN
demos/helloBeep.reloc
Normal file
BIN
demos/helloBeep.reloc
Normal file
Binary file not shown.
BIN
demos/helloText.bin
Normal file
BIN
demos/helloText.bin
Normal file
Binary file not shown.
42
demos/helloText.c
Normal file
42
demos/helloText.c
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
// helloText.c - GS/OS app that draws text on the SHR screen via the
|
||||||
|
// real ROM Font Manager + QuickDraw DrawString. Uses the full desktop
|
||||||
|
// startup (which includes InitCursor — see feedback_drawmenubar_hang
|
||||||
|
// for why that's load-bearing) and waits for any key.
|
||||||
|
|
||||||
|
#include "iigs/toolbox.h"
|
||||||
|
#include "iigs/desktop.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Pascal-counted strings (length byte + chars).
|
||||||
|
static const unsigned char line1[] = "\x13" "Hello from llvm816!";
|
||||||
|
static const unsigned char line2[] = "\x2B" "Clang-compiled C running on the Apple IIgs.";
|
||||||
|
static const unsigned char line3[] = "\x16" "Press any key to exit.";
|
||||||
|
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
unsigned short userId = startdesk(640);
|
||||||
|
(void)userId;
|
||||||
|
|
||||||
|
paintDesktopBackdrop();
|
||||||
|
ShowCursor();
|
||||||
|
|
||||||
|
SetForeColor(0);
|
||||||
|
SetBackColor(15);
|
||||||
|
|
||||||
|
MoveTo(40, 40); DrawString((void *)line1);
|
||||||
|
MoveTo(40, 60); DrawString((void *)line2);
|
||||||
|
MoveTo(40, 80); DrawString((void *)line3);
|
||||||
|
|
||||||
|
for (volatile unsigned long s = 0; s < 400000UL; s++) { }
|
||||||
|
|
||||||
|
short evt[8];
|
||||||
|
while (1) {
|
||||||
|
if (GetNextEvent(0xFFFF, evt) && evt[0] == 3) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SysBeep();
|
||||||
|
*(volatile unsigned char *)0x70 = 0x99;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
199
demos/helloText.map
Normal file
199
demos/helloText.map
Normal file
|
|
@ -0,0 +1,199 @@
|
||||||
|
# section layout
|
||||||
|
.text : 0x001000 .. 0x0021ca ( 4554 bytes)
|
||||||
|
.rodata : 0x0021ca .. 0x002238 ( 110 bytes)
|
||||||
|
.bss : 0x00a000 .. 0x00a00a ( 10 bytes)
|
||||||
|
|
||||||
|
# per-input-file .text contributions
|
||||||
|
186 /home/scott/claude/llvm816/runtime/crt0Gsos.o
|
||||||
|
552 /home/scott/claude/llvm816/demos/helloText.o
|
||||||
|
43513 /home/scott/claude/llvm816/runtime/libc.o
|
||||||
|
5935 /home/scott/claude/llvm816/runtime/snprintf.o
|
||||||
|
11953 /home/scott/claude/llvm816/runtime/extras.o
|
||||||
|
7077 /home/scott/claude/llvm816/runtime/softFloat.o
|
||||||
|
15379 /home/scott/claude/llvm816/runtime/softDouble.o
|
||||||
|
176 /home/scott/claude/llvm816/runtime/iigsGsos.o
|
||||||
|
20670 /home/scott/claude/llvm816/runtime/iigsToolbox.o
|
||||||
|
1349 /home/scott/claude/llvm816/runtime/desktop.o
|
||||||
|
2540 /home/scott/claude/llvm816/runtime/libgcc.o
|
||||||
|
|
||||||
|
# global symbols (sorted by address)
|
||||||
|
0x000000 __bss_bank
|
||||||
|
0x000000 __bss_seg0_bank
|
||||||
|
0x000000 __bss_seg1_bank
|
||||||
|
0x000000 __bss_seg1_lo16
|
||||||
|
0x000000 __bss_seg1_size
|
||||||
|
0x000000 __bss_seg2_bank
|
||||||
|
0x000000 __bss_seg2_lo16
|
||||||
|
0x000000 __bss_seg2_size
|
||||||
|
0x000000 __bss_seg3_bank
|
||||||
|
0x000000 __bss_seg3_lo16
|
||||||
|
0x000000 __bss_seg3_size
|
||||||
|
0x00000a __bss_seg0_size
|
||||||
|
0x00000a __bss_size
|
||||||
|
0x001000 __start
|
||||||
|
0x001000 __text_start
|
||||||
|
0x0010ba main
|
||||||
|
0x0012e2 CtlStartUp
|
||||||
|
0x0012f2 EMStartUp
|
||||||
|
0x001311 GetNextEvent
|
||||||
|
0x001328 FMStartUp
|
||||||
|
0x001338 LEStartUp
|
||||||
|
0x001348 LoadOneTool
|
||||||
|
0x001358 NewHandle
|
||||||
|
0x00137e MenuStartUp
|
||||||
|
0x00138e QDStartUp
|
||||||
|
0x0013a4 DrawString
|
||||||
|
0x0013b6 MoveTo
|
||||||
|
0x0013c6 startdesk
|
||||||
|
0x0017ac paintDesktopBackdrop
|
||||||
|
0x0017de __jsl_indir
|
||||||
|
0x0017e1 __mulhi3
|
||||||
|
0x001800 __umulhisi3
|
||||||
|
0x001857 __ashlhi3
|
||||||
|
0x001866 __lshrhi3
|
||||||
|
0x001876 __ashrhi3
|
||||||
|
0x001889 __udivhi3
|
||||||
|
0x001895 __umodhi3
|
||||||
|
0x0018a1 __divhi3
|
||||||
|
0x0018bb __modhi3
|
||||||
|
0x0018d5 __divmod_setup
|
||||||
|
0x001908 __udivmod_core
|
||||||
|
0x001926 __mulsi3
|
||||||
|
0x0019df __ashlsi3
|
||||||
|
0x0019f4 __lshrsi3
|
||||||
|
0x001a09 __ashrsi3
|
||||||
|
0x001a23 __udivmodsi_core
|
||||||
|
0x001a5b __udivsi3
|
||||||
|
0x001a6f __umodsi3
|
||||||
|
0x001a83 __divsi3
|
||||||
|
0x001aaa __modsi3
|
||||||
|
0x001ad1 __divmodsi_setup
|
||||||
|
0x001b22 __divmoddi4_stash
|
||||||
|
0x001b3f __retdi
|
||||||
|
0x001b4c __ashldi3
|
||||||
|
0x001b6f __lshrdi3
|
||||||
|
0x001b92 __ashrdi3
|
||||||
|
0x001bb8 __muldi3
|
||||||
|
0x001c13 __ucmpdi2
|
||||||
|
0x001c3c __cmpdi2
|
||||||
|
0x001c73 __udivdi3
|
||||||
|
0x001c7c __umoddi3
|
||||||
|
0x001c95 __udivmoddi_core
|
||||||
|
0x001ce2 __divdi3
|
||||||
|
0x001d01 __moddi3
|
||||||
|
0x001d2e __absdi_a
|
||||||
|
0x001d36 __absdi_b
|
||||||
|
0x001d3e __negdi_a
|
||||||
|
0x001d5c __negdi_b
|
||||||
|
0x001d7a setjmp
|
||||||
|
0x001da2 longjmp
|
||||||
|
0x001dcc __umulhisi3_qsq
|
||||||
|
0x0021ca __rodata_start
|
||||||
|
0x0021ca __text_end
|
||||||
|
0x0021ca gChainPath
|
||||||
|
0x0021de line1
|
||||||
|
0x0021f3 line2
|
||||||
|
0x002220 line3
|
||||||
|
0x002238 __init_array_end
|
||||||
|
0x002238 __init_array_start
|
||||||
|
0x002238 __rodata_end
|
||||||
|
0x00a000 __bss_lo16
|
||||||
|
0x00a000 __bss_seg0_lo16
|
||||||
|
0x00a000 __bss_start
|
||||||
|
0x00a000 gUserId
|
||||||
|
0x00a002 gDpHandle
|
||||||
|
0x00a006 gDpBase
|
||||||
|
0x00a008 __indirTarget
|
||||||
|
0x00a00a __bss_end
|
||||||
|
0x00a00a __heap_start
|
||||||
|
0x00bf00 __heap_end
|
||||||
|
CtlStartUp = 0x0012e2
|
||||||
|
DrawString = 0x0013a4
|
||||||
|
EMStartUp = 0x0012f2
|
||||||
|
FMStartUp = 0x001328
|
||||||
|
GetNextEvent = 0x001311
|
||||||
|
LEStartUp = 0x001338
|
||||||
|
LoadOneTool = 0x001348
|
||||||
|
MenuStartUp = 0x00137e
|
||||||
|
MoveTo = 0x0013b6
|
||||||
|
NewHandle = 0x001358
|
||||||
|
QDStartUp = 0x00138e
|
||||||
|
__absdi_a = 0x001d2e
|
||||||
|
__absdi_b = 0x001d36
|
||||||
|
__ashldi3 = 0x001b4c
|
||||||
|
__ashlhi3 = 0x001857
|
||||||
|
__ashlsi3 = 0x0019df
|
||||||
|
__ashrdi3 = 0x001b92
|
||||||
|
__ashrhi3 = 0x001876
|
||||||
|
__ashrsi3 = 0x001a09
|
||||||
|
__bss_bank = 0x000000
|
||||||
|
__bss_end = 0x00a00a
|
||||||
|
__bss_lo16 = 0x00a000
|
||||||
|
__bss_seg0_bank = 0x000000
|
||||||
|
__bss_seg0_lo16 = 0x00a000
|
||||||
|
__bss_seg0_size = 0x00000a
|
||||||
|
__bss_seg1_bank = 0x000000
|
||||||
|
__bss_seg1_lo16 = 0x000000
|
||||||
|
__bss_seg1_size = 0x000000
|
||||||
|
__bss_seg2_bank = 0x000000
|
||||||
|
__bss_seg2_lo16 = 0x000000
|
||||||
|
__bss_seg2_size = 0x000000
|
||||||
|
__bss_seg3_bank = 0x000000
|
||||||
|
__bss_seg3_lo16 = 0x000000
|
||||||
|
__bss_seg3_size = 0x000000
|
||||||
|
__bss_size = 0x00000a
|
||||||
|
__bss_start = 0x00a000
|
||||||
|
__cmpdi2 = 0x001c3c
|
||||||
|
__divdi3 = 0x001ce2
|
||||||
|
__divhi3 = 0x0018a1
|
||||||
|
__divmod_setup = 0x0018d5
|
||||||
|
__divmoddi4_stash = 0x001b22
|
||||||
|
__divmodsi_setup = 0x001ad1
|
||||||
|
__divsi3 = 0x001a83
|
||||||
|
__heap_end = 0x00bf00
|
||||||
|
__heap_start = 0x00a00a
|
||||||
|
__indirTarget = 0x00a008
|
||||||
|
__init_array_end = 0x002238
|
||||||
|
__init_array_start = 0x002238
|
||||||
|
__jsl_indir = 0x0017de
|
||||||
|
__lshrdi3 = 0x001b6f
|
||||||
|
__lshrhi3 = 0x001866
|
||||||
|
__lshrsi3 = 0x0019f4
|
||||||
|
__moddi3 = 0x001d01
|
||||||
|
__modhi3 = 0x0018bb
|
||||||
|
__modsi3 = 0x001aaa
|
||||||
|
__muldi3 = 0x001bb8
|
||||||
|
__mulhi3 = 0x0017e1
|
||||||
|
__mulsi3 = 0x001926
|
||||||
|
__negdi_a = 0x001d3e
|
||||||
|
__negdi_b = 0x001d5c
|
||||||
|
__retdi = 0x001b3f
|
||||||
|
__rodata_end = 0x002238
|
||||||
|
__rodata_start = 0x0021ca
|
||||||
|
__start = 0x001000
|
||||||
|
__text_end = 0x0021ca
|
||||||
|
__text_start = 0x001000
|
||||||
|
__ucmpdi2 = 0x001c13
|
||||||
|
__udivdi3 = 0x001c73
|
||||||
|
__udivhi3 = 0x001889
|
||||||
|
__udivmod_core = 0x001908
|
||||||
|
__udivmoddi_core = 0x001c95
|
||||||
|
__udivmodsi_core = 0x001a23
|
||||||
|
__udivsi3 = 0x001a5b
|
||||||
|
__umoddi3 = 0x001c7c
|
||||||
|
__umodhi3 = 0x001895
|
||||||
|
__umodsi3 = 0x001a6f
|
||||||
|
__umulhisi3 = 0x001800
|
||||||
|
__umulhisi3_qsq = 0x001dcc
|
||||||
|
gChainPath = 0x0021ca
|
||||||
|
gDpBase = 0x00a006
|
||||||
|
gDpHandle = 0x00a002
|
||||||
|
gUserId = 0x00a000
|
||||||
|
line1 = 0x0021de
|
||||||
|
line2 = 0x0021f3
|
||||||
|
line3 = 0x002220
|
||||||
|
longjmp = 0x001da2
|
||||||
|
main = 0x0010ba
|
||||||
|
paintDesktopBackdrop = 0x0017ac
|
||||||
|
setjmp = 0x001d7a
|
||||||
|
startdesk = 0x0013c6
|
||||||
BIN
demos/helloText.o
Normal file
BIN
demos/helloText.o
Normal file
Binary file not shown.
BIN
demos/helloText.omf
Normal file
BIN
demos/helloText.omf
Normal file
Binary file not shown.
BIN
demos/helloText.reloc
Normal file
BIN
demos/helloText.reloc
Normal file
Binary file not shown.
BIN
demos/helloWindow.bin
Normal file
BIN
demos/helloWindow.bin
Normal file
Binary file not shown.
128
demos/helloWindow.c
Normal file
128
demos/helloWindow.c
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
187
demos/helloWindow.map
Normal file
187
demos/helloWindow.map
Normal file
|
|
@ -0,0 +1,187 @@
|
||||||
|
# section layout
|
||||||
|
.text : 0x001000 .. 0x001ecd ( 3789 bytes)
|
||||||
|
.rodata : 0x001ecd .. 0x001f01 ( 52 bytes)
|
||||||
|
.bss : 0x00a000 .. 0x00a050 ( 80 bytes)
|
||||||
|
|
||||||
|
# per-input-file .text contributions
|
||||||
|
186 /home/scott/claude/llvm816/runtime/crt0Gsos.o
|
||||||
|
757 /home/scott/claude/llvm816/demos/helloWindow.o
|
||||||
|
43513 /home/scott/claude/llvm816/runtime/libc.o
|
||||||
|
5935 /home/scott/claude/llvm816/runtime/snprintf.o
|
||||||
|
11953 /home/scott/claude/llvm816/runtime/extras.o
|
||||||
|
7077 /home/scott/claude/llvm816/runtime/softFloat.o
|
||||||
|
15379 /home/scott/claude/llvm816/runtime/softDouble.o
|
||||||
|
176 /home/scott/claude/llvm816/runtime/iigsGsos.o
|
||||||
|
20670 /home/scott/claude/llvm816/runtime/iigsToolbox.o
|
||||||
|
1349 /home/scott/claude/llvm816/runtime/desktop.o
|
||||||
|
2540 /home/scott/claude/llvm816/runtime/libgcc.o
|
||||||
|
|
||||||
|
# global symbols (sorted by address)
|
||||||
|
0x000000 __bss_bank
|
||||||
|
0x000000 __bss_seg0_bank
|
||||||
|
0x000000 __bss_seg1_bank
|
||||||
|
0x000000 __bss_seg1_lo16
|
||||||
|
0x000000 __bss_seg1_size
|
||||||
|
0x000000 __bss_seg2_bank
|
||||||
|
0x000000 __bss_seg2_lo16
|
||||||
|
0x000000 __bss_seg2_size
|
||||||
|
0x000000 __bss_seg3_bank
|
||||||
|
0x000000 __bss_seg3_lo16
|
||||||
|
0x000000 __bss_seg3_size
|
||||||
|
0x000050 __bss_seg0_size
|
||||||
|
0x000050 __bss_size
|
||||||
|
0x001000 __start
|
||||||
|
0x001000 __text_start
|
||||||
|
0x0010ba main
|
||||||
|
0x0013af memset
|
||||||
|
0x00140f EMStartUp
|
||||||
|
0x00142e GetNextEvent
|
||||||
|
0x001445 NewHandle
|
||||||
|
0x00146b QDStartUp
|
||||||
|
0x001481 DrawString
|
||||||
|
0x001493 MoveTo
|
||||||
|
0x0014a3 SetPort
|
||||||
|
0x0014b5 NewWindow
|
||||||
|
0x0014cf ShowWindow
|
||||||
|
0x0014e1 __jsl_indir
|
||||||
|
0x0014e4 __mulhi3
|
||||||
|
0x001503 __umulhisi3
|
||||||
|
0x00155a __ashlhi3
|
||||||
|
0x001569 __lshrhi3
|
||||||
|
0x001579 __ashrhi3
|
||||||
|
0x00158c __udivhi3
|
||||||
|
0x001598 __umodhi3
|
||||||
|
0x0015a4 __divhi3
|
||||||
|
0x0015be __modhi3
|
||||||
|
0x0015d8 __divmod_setup
|
||||||
|
0x00160b __udivmod_core
|
||||||
|
0x001629 __mulsi3
|
||||||
|
0x0016e2 __ashlsi3
|
||||||
|
0x0016f7 __lshrsi3
|
||||||
|
0x00170c __ashrsi3
|
||||||
|
0x001726 __udivmodsi_core
|
||||||
|
0x00175e __udivsi3
|
||||||
|
0x001772 __umodsi3
|
||||||
|
0x001786 __divsi3
|
||||||
|
0x0017ad __modsi3
|
||||||
|
0x0017d4 __divmodsi_setup
|
||||||
|
0x001825 __divmoddi4_stash
|
||||||
|
0x001842 __retdi
|
||||||
|
0x00184f __ashldi3
|
||||||
|
0x001872 __lshrdi3
|
||||||
|
0x001895 __ashrdi3
|
||||||
|
0x0018bb __muldi3
|
||||||
|
0x001916 __ucmpdi2
|
||||||
|
0x00193f __cmpdi2
|
||||||
|
0x001976 __udivdi3
|
||||||
|
0x00197f __umoddi3
|
||||||
|
0x001998 __udivmoddi_core
|
||||||
|
0x0019e5 __divdi3
|
||||||
|
0x001a04 __moddi3
|
||||||
|
0x001a31 __absdi_a
|
||||||
|
0x001a39 __absdi_b
|
||||||
|
0x001a41 __negdi_a
|
||||||
|
0x001a5f __negdi_b
|
||||||
|
0x001a7d setjmp
|
||||||
|
0x001aa5 longjmp
|
||||||
|
0x001acf __umulhisi3_qsq
|
||||||
|
0x001ecd __rodata_start
|
||||||
|
0x001ecd __text_end
|
||||||
|
0x001ecd gChainPath
|
||||||
|
0x001ee1 gTitle
|
||||||
|
0x001eec gMsg
|
||||||
|
0x001f01 __init_array_end
|
||||||
|
0x001f01 __init_array_start
|
||||||
|
0x001f01 __rodata_end
|
||||||
|
0x00a000 __bss_lo16
|
||||||
|
0x00a000 __bss_seg0_lo16
|
||||||
|
0x00a000 __bss_start
|
||||||
|
0x00a000 gWp
|
||||||
|
0x00a04e __indirTarget
|
||||||
|
0x00a050 __bss_end
|
||||||
|
0x00a050 __heap_start
|
||||||
|
0x00bf00 __heap_end
|
||||||
|
DrawString = 0x001481
|
||||||
|
EMStartUp = 0x00140f
|
||||||
|
GetNextEvent = 0x00142e
|
||||||
|
MoveTo = 0x001493
|
||||||
|
NewHandle = 0x001445
|
||||||
|
NewWindow = 0x0014b5
|
||||||
|
QDStartUp = 0x00146b
|
||||||
|
SetPort = 0x0014a3
|
||||||
|
ShowWindow = 0x0014cf
|
||||||
|
__absdi_a = 0x001a31
|
||||||
|
__absdi_b = 0x001a39
|
||||||
|
__ashldi3 = 0x00184f
|
||||||
|
__ashlhi3 = 0x00155a
|
||||||
|
__ashlsi3 = 0x0016e2
|
||||||
|
__ashrdi3 = 0x001895
|
||||||
|
__ashrhi3 = 0x001579
|
||||||
|
__ashrsi3 = 0x00170c
|
||||||
|
__bss_bank = 0x000000
|
||||||
|
__bss_end = 0x00a050
|
||||||
|
__bss_lo16 = 0x00a000
|
||||||
|
__bss_seg0_bank = 0x000000
|
||||||
|
__bss_seg0_lo16 = 0x00a000
|
||||||
|
__bss_seg0_size = 0x000050
|
||||||
|
__bss_seg1_bank = 0x000000
|
||||||
|
__bss_seg1_lo16 = 0x000000
|
||||||
|
__bss_seg1_size = 0x000000
|
||||||
|
__bss_seg2_bank = 0x000000
|
||||||
|
__bss_seg2_lo16 = 0x000000
|
||||||
|
__bss_seg2_size = 0x000000
|
||||||
|
__bss_seg3_bank = 0x000000
|
||||||
|
__bss_seg3_lo16 = 0x000000
|
||||||
|
__bss_seg3_size = 0x000000
|
||||||
|
__bss_size = 0x000050
|
||||||
|
__bss_start = 0x00a000
|
||||||
|
__cmpdi2 = 0x00193f
|
||||||
|
__divdi3 = 0x0019e5
|
||||||
|
__divhi3 = 0x0015a4
|
||||||
|
__divmod_setup = 0x0015d8
|
||||||
|
__divmoddi4_stash = 0x001825
|
||||||
|
__divmodsi_setup = 0x0017d4
|
||||||
|
__divsi3 = 0x001786
|
||||||
|
__heap_end = 0x00bf00
|
||||||
|
__heap_start = 0x00a050
|
||||||
|
__indirTarget = 0x00a04e
|
||||||
|
__init_array_end = 0x001f01
|
||||||
|
__init_array_start = 0x001f01
|
||||||
|
__jsl_indir = 0x0014e1
|
||||||
|
__lshrdi3 = 0x001872
|
||||||
|
__lshrhi3 = 0x001569
|
||||||
|
__lshrsi3 = 0x0016f7
|
||||||
|
__moddi3 = 0x001a04
|
||||||
|
__modhi3 = 0x0015be
|
||||||
|
__modsi3 = 0x0017ad
|
||||||
|
__muldi3 = 0x0018bb
|
||||||
|
__mulhi3 = 0x0014e4
|
||||||
|
__mulsi3 = 0x001629
|
||||||
|
__negdi_a = 0x001a41
|
||||||
|
__negdi_b = 0x001a5f
|
||||||
|
__retdi = 0x001842
|
||||||
|
__rodata_end = 0x001f01
|
||||||
|
__rodata_start = 0x001ecd
|
||||||
|
__start = 0x001000
|
||||||
|
__text_end = 0x001ecd
|
||||||
|
__text_start = 0x001000
|
||||||
|
__ucmpdi2 = 0x001916
|
||||||
|
__udivdi3 = 0x001976
|
||||||
|
__udivhi3 = 0x00158c
|
||||||
|
__udivmod_core = 0x00160b
|
||||||
|
__udivmoddi_core = 0x001998
|
||||||
|
__udivmodsi_core = 0x001726
|
||||||
|
__udivsi3 = 0x00175e
|
||||||
|
__umoddi3 = 0x00197f
|
||||||
|
__umodhi3 = 0x001598
|
||||||
|
__umodsi3 = 0x001772
|
||||||
|
__umulhisi3 = 0x001503
|
||||||
|
__umulhisi3_qsq = 0x001acf
|
||||||
|
gChainPath = 0x001ecd
|
||||||
|
gMsg = 0x001eec
|
||||||
|
gTitle = 0x001ee1
|
||||||
|
gWp = 0x00a000
|
||||||
|
longjmp = 0x001aa5
|
||||||
|
main = 0x0010ba
|
||||||
|
memset = 0x0013af
|
||||||
|
setjmp = 0x001a7d
|
||||||
BIN
demos/helloWindow.o
Normal file
BIN
demos/helloWindow.o
Normal file
Binary file not shown.
BIN
demos/helloWindow.omf
Normal file
BIN
demos/helloWindow.omf
Normal file
Binary file not shown.
BIN
demos/helloWindow.reloc
Normal file
BIN
demos/helloWindow.reloc
Normal file
Binary file not shown.
99
demos/launch.sh
Executable file
99
demos/launch.sh
Executable file
|
|
@ -0,0 +1,99 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# launch.sh - boot the IIgs in MAME and launch a demo OMF interactively.
|
||||||
|
#
|
||||||
|
# Unlike runViaFinder.sh (which is the headless smoke harness),
|
||||||
|
# this script:
|
||||||
|
# - Shows the MAME window so you can see the demo run
|
||||||
|
# - Plays audio so SysBeep is audible
|
||||||
|
# - Runs at real (throttled) speed
|
||||||
|
# - No timeout - close MAME when done (Esc, then Cmd-Q)
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# bash demos/launch.sh helloBeep
|
||||||
|
# bash demos/launch.sh helloWindow
|
||||||
|
#
|
||||||
|
# The script first builds the demo if its .omf is missing or older
|
||||||
|
# than its .c source, then injects it onto a fresh ProDOS disk image
|
||||||
|
# and boots GS/OS 6.0.2 with the Finder driven via Lua keyboard
|
||||||
|
# automation to launch the app.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
|
||||||
|
[ $# -ge 1 ] || { echo "usage: $0 <demo-name> (e.g. helloBeep, helloWindow)" >&2; exit 2; }
|
||||||
|
BASE="$1"
|
||||||
|
SRC="$SCRIPT_DIR/$BASE.c"
|
||||||
|
OMF="$SCRIPT_DIR/$BASE.omf"
|
||||||
|
|
||||||
|
[ -f "$SRC" ] || { echo "no source: $SRC" >&2; exit 2; }
|
||||||
|
|
||||||
|
# Rebuild if needed.
|
||||||
|
if [ ! -f "$OMF" ] || [ "$SRC" -nt "$OMF" ]; then
|
||||||
|
echo "Building $BASE..."
|
||||||
|
bash "$SCRIPT_DIR/build.sh" "$BASE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
CADIUS=${CADIUS:-$PROJECT_ROOT/tools/cadius/cadius}
|
||||||
|
SYSDISK=${SYSDISK:-$PROJECT_ROOT/tools/gsos/sys602.po}
|
||||||
|
|
||||||
|
[ -x "$CADIUS" ] || { echo "cadius not found at $CADIUS" >&2; exit 2; }
|
||||||
|
[ -f "$SYSDISK" ] || { echo "sysdisk not found at $SYSDISK" >&2; exit 2; }
|
||||||
|
command -v mame >/dev/null || { echo "mame not in PATH" >&2; exit 2; }
|
||||||
|
|
||||||
|
WORK=$(mktemp -d -t demolaunch.XXXXXX)
|
||||||
|
trap 'rm -rf "$WORK"' EXIT
|
||||||
|
|
||||||
|
cp "$SYSDISK" "$WORK/disk.po"
|
||||||
|
"$CADIUS" CREATEVOLUME "$WORK/data.po" DATA 800KB >/dev/null
|
||||||
|
# cadius uses the source-file basename as the on-disk name; copy
|
||||||
|
# the OMF to a file named HELLO with the OMF filetype (#B30000)
|
||||||
|
# so GS/OS Finder shows it as an application.
|
||||||
|
cp "$OMF" "$WORK/HELLO#B30000"
|
||||||
|
"$CADIUS" ADDFILE "$WORK/data.po" /DATA "$WORK/HELLO#B30000" >/dev/null
|
||||||
|
|
||||||
|
# Lua keyboard automation: same as runViaFinder.sh - open the Data
|
||||||
|
# volume from the Finder and Cmd-O the HELLO icon. After launch
|
||||||
|
# the demo runs uninterrupted until the user closes MAME.
|
||||||
|
cat > "$WORK/finder.lua" <<'LUA'
|
||||||
|
local nat = manager.machine.natkeyboard
|
||||||
|
local frame = 0
|
||||||
|
local idx = 1
|
||||||
|
|
||||||
|
local function get_field(port, name)
|
||||||
|
local p = manager.machine.ioport.ports[port]
|
||||||
|
if p == nil then return nil end
|
||||||
|
return p.fields[name]
|
||||||
|
end
|
||||||
|
local key_cmd = get_field(":macadb:KEY3", "Command / Open Apple")
|
||||||
|
local function press(f) if f then f:set_value(1) end end
|
||||||
|
local function release(f) if f then f:set_value(0) end end
|
||||||
|
|
||||||
|
local steps = {
|
||||||
|
{3300, function() nat:post("D") end}, -- select Data
|
||||||
|
{3540, function() press(key_cmd) end},
|
||||||
|
{3546, function() nat:post("o") end}, -- Cmd-O opens volume
|
||||||
|
{3600, function() release(key_cmd) end},
|
||||||
|
{4200, function() nat:post("H") end}, -- select HELLO
|
||||||
|
{4500, function() press(key_cmd) end},
|
||||||
|
{4506, function() nat:post("o") end}, -- Cmd-O launches
|
||||||
|
{4560, function() release(key_cmd) end},
|
||||||
|
}
|
||||||
|
emu.register_frame_done(function()
|
||||||
|
frame = frame + 1
|
||||||
|
while idx <= #steps and frame >= steps[idx][1] do
|
||||||
|
steps[idx][2]()
|
||||||
|
idx = idx + 1
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
LUA
|
||||||
|
|
||||||
|
echo "Launching MAME with $BASE.omf..."
|
||||||
|
echo "Close the MAME window (or hit Esc, then Cmd-Q) to exit."
|
||||||
|
echo
|
||||||
|
|
||||||
|
mame apple2gs \
|
||||||
|
-rompath "$PROJECT_ROOT/tools/mame/roms" \
|
||||||
|
-window \
|
||||||
|
-flop3 "$WORK/disk.po" -flop4 "$WORK/data.po" \
|
||||||
|
-autoboot_script "$WORK/finder.lua"
|
||||||
BIN
demos/minicad.bin
Normal file
BIN
demos/minicad.bin
Normal file
Binary file not shown.
149
demos/minicad.c
Normal file
149
demos/minicad.c
Normal file
|
|
@ -0,0 +1,149 @@
|
||||||
|
// minicad.c - port of ORCA-C's MiniCAD.cc sample.
|
||||||
|
//
|
||||||
|
// MiniCAD is a tiny drawing program: each click in the content area
|
||||||
|
// creates a new line in the current window's line list. In the
|
||||||
|
// original you click to set the anchor, drag to draw a rubber-band
|
||||||
|
// line, release to commit. We seed three classic line-art patterns
|
||||||
|
// (curve-stitching, sunburst, mandala) instead of waiting for clicks
|
||||||
|
// because our minimal Event Manager doesn't have a working
|
||||||
|
// GetNextEvent path for mouse-drag tracking, but the data model and
|
||||||
|
// rendering pipeline match MiniCAD.cc verbatim.
|
||||||
|
|
||||||
|
#include "iigs/toolbox.h"
|
||||||
|
#include "iigs/desktop.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define wInContent 19
|
||||||
|
#define fVis 0x0020
|
||||||
|
#define fMove 0x0080
|
||||||
|
#define fClose 0x4000
|
||||||
|
|
||||||
|
|
||||||
|
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 { short v1, h1, v2, h2; } LineRec;
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned char gTitle[] = "\x07MiniCAD";
|
||||||
|
|
||||||
|
// Menu bar titles painted manually (DrawMenuBar hangs in our env).
|
||||||
|
static const unsigned char appleTitle[] = "\x01\x14";
|
||||||
|
static const unsigned char fileTitle[] = "\x04" "File";
|
||||||
|
static const unsigned char editTitle[] = "\x04" "Edit";
|
||||||
|
static const unsigned char optsTitle[] = "\x07" "Options";
|
||||||
|
static const unsigned char *const menuTitles[] = {
|
||||||
|
appleTitle, fileTitle, editTitle, optsTitle
|
||||||
|
};
|
||||||
|
|
||||||
|
static NewWindowParm gWp;
|
||||||
|
|
||||||
|
|
||||||
|
// Draw a curve-stitching pattern: 12 chord lines mapping the y-axis
|
||||||
|
// to a curve along the x-axis. Visually it traces a hyperbolic
|
||||||
|
// envelope (the classic "string art" pattern).
|
||||||
|
static void drawCurves(short ox, short oy) {
|
||||||
|
for (short i = 0; i < 12; i++) {
|
||||||
|
MoveTo((short)(ox + 0), (short)(oy + i * 6));
|
||||||
|
LineTo((short)(ox + 90 - i * 5), (short)(oy + 70 - i * 5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Draw a sunburst: 12 radial lines from a central point.
|
||||||
|
static void drawSunburst(short cx, short cy, short r) {
|
||||||
|
// Pre-computed cos/sin for 12 equally-spaced angles (every 30
|
||||||
|
// degrees), scaled by 1000. Avoids any float math.
|
||||||
|
static const short cosA[12] = { 1000, 866, 500, 0, -500, -866, -1000, -866, -500, 0, 500, 866 };
|
||||||
|
static const short sinA[12] = { 0, 500, 866, 1000, 866, 500, 0, -500, -866, -1000, -866, -500 };
|
||||||
|
for (short i = 0; i < 12; i++) {
|
||||||
|
short dx = (short)((long)cosA[i] * r / 1000);
|
||||||
|
short dy = (short)((long)sinA[i] * r / 1000);
|
||||||
|
MoveTo((short)(cx - dx), (short)(cy - dy));
|
||||||
|
LineTo((short)(cx + dx), (short)(cy + dy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Draw a mandala: 6-pointed star made of two overlapping triangles.
|
||||||
|
static void drawMandala(short cx, short cy, short r) {
|
||||||
|
short h = (short)((long)r * 866L / 1000L);
|
||||||
|
short h2 = (short)(r / 2);
|
||||||
|
// First triangle (point up).
|
||||||
|
MoveTo(cx, (short)(cy - r));
|
||||||
|
LineTo((short)(cx + h), (short)(cy + h2));
|
||||||
|
LineTo((short)(cx - h), (short)(cy + h2));
|
||||||
|
LineTo(cx, (short)(cy - r));
|
||||||
|
// Second triangle (point down).
|
||||||
|
MoveTo(cx, (short)(cy + r));
|
||||||
|
LineTo((short)(cx + h), (short)(cy - h2));
|
||||||
|
LineTo((short)(cx - h), (short)(cy - h2));
|
||||||
|
LineTo(cx, (short)(cy + r));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
unsigned short userId = startdesk(640);
|
||||||
|
(void)userId;
|
||||||
|
paintDesktopBackdrop();
|
||||||
|
paintMenuBarTitles(menuTitles, 4);
|
||||||
|
ShowCursor();
|
||||||
|
|
||||||
|
// Open the drawing window.
|
||||||
|
{
|
||||||
|
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 = gTitle;
|
||||||
|
gWp.wMaxHeight = 200;
|
||||||
|
gWp.wMaxWidth = 640;
|
||||||
|
gWp.wPosition.v1 = 20; gWp.wPosition.h1 = 30;
|
||||||
|
gWp.wPosition.v2 = 180; gWp.wPosition.h2 = 610;
|
||||||
|
gWp.wPlane = (void *)-1L;
|
||||||
|
void *win = NewWindow(&gWp);
|
||||||
|
|
||||||
|
if (win) {
|
||||||
|
BeginUpdate(win);
|
||||||
|
SetPort(win);
|
||||||
|
SetSolidPenPat(0);
|
||||||
|
|
||||||
|
// Three patterns laid out horizontally.
|
||||||
|
drawCurves(20, 30);
|
||||||
|
drawSunburst(280, 75, 50);
|
||||||
|
drawMandala(450, 75, 50);
|
||||||
|
|
||||||
|
EndUpdate(win);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (volatile unsigned long s = 0; s < 400000UL; s++) { }
|
||||||
|
|
||||||
|
if (win) {
|
||||||
|
CloseWindow(win);
|
||||||
|
}
|
||||||
|
*(volatile unsigned char *)0x70 = 0x99;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
223
demos/minicad.map
Normal file
223
demos/minicad.map
Normal file
|
|
@ -0,0 +1,223 @@
|
||||||
|
# section layout
|
||||||
|
.text : 0x001000 .. 0x002638 ( 5688 bytes)
|
||||||
|
.rodata : 0x002638 .. 0x0026ad ( 117 bytes)
|
||||||
|
.bss : 0x00a000 .. 0x00a058 ( 88 bytes)
|
||||||
|
|
||||||
|
# per-input-file .text contributions
|
||||||
|
186 /home/scott/claude/llvm816/runtime/crt0Gsos.o
|
||||||
|
1374 /home/scott/claude/llvm816/demos/minicad.o
|
||||||
|
43513 /home/scott/claude/llvm816/runtime/libc.o
|
||||||
|
5935 /home/scott/claude/llvm816/runtime/snprintf.o
|
||||||
|
11953 /home/scott/claude/llvm816/runtime/extras.o
|
||||||
|
7077 /home/scott/claude/llvm816/runtime/softFloat.o
|
||||||
|
15379 /home/scott/claude/llvm816/runtime/softDouble.o
|
||||||
|
176 /home/scott/claude/llvm816/runtime/iigsGsos.o
|
||||||
|
20670 /home/scott/claude/llvm816/runtime/iigsToolbox.o
|
||||||
|
1302 /home/scott/claude/llvm816/runtime/desktop.o
|
||||||
|
2540 /home/scott/claude/llvm816/runtime/libgcc.o
|
||||||
|
|
||||||
|
# global symbols (sorted by address)
|
||||||
|
0x000000 __bss_bank
|
||||||
|
0x000000 __bss_seg0_bank
|
||||||
|
0x000000 __bss_seg1_bank
|
||||||
|
0x000000 __bss_seg1_lo16
|
||||||
|
0x000000 __bss_seg1_size
|
||||||
|
0x000000 __bss_seg2_bank
|
||||||
|
0x000000 __bss_seg2_lo16
|
||||||
|
0x000000 __bss_seg2_size
|
||||||
|
0x000000 __bss_seg3_bank
|
||||||
|
0x000000 __bss_seg3_lo16
|
||||||
|
0x000000 __bss_seg3_size
|
||||||
|
0x000058 __bss_seg0_size
|
||||||
|
0x000058 __bss_size
|
||||||
|
0x001000 __start
|
||||||
|
0x001000 __text_start
|
||||||
|
0x0010ba main
|
||||||
|
0x001618 memset
|
||||||
|
0x001678 CtlStartUp
|
||||||
|
0x001688 EMStartUp
|
||||||
|
0x0016a7 FMStartUp
|
||||||
|
0x0016b7 LEStartUp
|
||||||
|
0x0016c7 LoadOneTool
|
||||||
|
0x0016d7 NewHandle
|
||||||
|
0x0016fd QDStartUp
|
||||||
|
0x001713 DrawString
|
||||||
|
0x001725 LineTo
|
||||||
|
0x001735 MoveTo
|
||||||
|
0x001745 SetPort
|
||||||
|
0x001757 BeginUpdate
|
||||||
|
0x001769 CloseWindow
|
||||||
|
0x00177b EndUpdate
|
||||||
|
0x00178d NewWindow
|
||||||
|
0x0017a7 startdesk
|
||||||
|
0x001b5e paintMenuBarTitles
|
||||||
|
0x001c1a paintDesktopBackdrop
|
||||||
|
0x001c4c __jsl_indir
|
||||||
|
0x001c4f __mulhi3
|
||||||
|
0x001c6e __umulhisi3
|
||||||
|
0x001cc5 __ashlhi3
|
||||||
|
0x001cd4 __lshrhi3
|
||||||
|
0x001ce4 __ashrhi3
|
||||||
|
0x001cf7 __udivhi3
|
||||||
|
0x001d03 __umodhi3
|
||||||
|
0x001d0f __divhi3
|
||||||
|
0x001d29 __modhi3
|
||||||
|
0x001d43 __divmod_setup
|
||||||
|
0x001d76 __udivmod_core
|
||||||
|
0x001d94 __mulsi3
|
||||||
|
0x001e4d __ashlsi3
|
||||||
|
0x001e62 __lshrsi3
|
||||||
|
0x001e77 __ashrsi3
|
||||||
|
0x001e91 __udivmodsi_core
|
||||||
|
0x001ec9 __udivsi3
|
||||||
|
0x001edd __umodsi3
|
||||||
|
0x001ef1 __divsi3
|
||||||
|
0x001f18 __modsi3
|
||||||
|
0x001f3f __divmodsi_setup
|
||||||
|
0x001f90 __divmoddi4_stash
|
||||||
|
0x001fad __retdi
|
||||||
|
0x001fba __ashldi3
|
||||||
|
0x001fdd __lshrdi3
|
||||||
|
0x002000 __ashrdi3
|
||||||
|
0x002026 __muldi3
|
||||||
|
0x002081 __ucmpdi2
|
||||||
|
0x0020aa __cmpdi2
|
||||||
|
0x0020e1 __udivdi3
|
||||||
|
0x0020ea __umoddi3
|
||||||
|
0x002103 __udivmoddi_core
|
||||||
|
0x002150 __divdi3
|
||||||
|
0x00216f __moddi3
|
||||||
|
0x00219c __absdi_a
|
||||||
|
0x0021a4 __absdi_b
|
||||||
|
0x0021ac __negdi_a
|
||||||
|
0x0021ca __negdi_b
|
||||||
|
0x0021e8 setjmp
|
||||||
|
0x002210 longjmp
|
||||||
|
0x00223a __umulhisi3_qsq
|
||||||
|
0x002638 __rodata_start
|
||||||
|
0x002638 __text_end
|
||||||
|
0x002638 gChainPath
|
||||||
|
0x00264c menuTitles
|
||||||
|
0x00265c appleTitle
|
||||||
|
0x00265f fileTitle
|
||||||
|
0x002665 editTitle
|
||||||
|
0x00266b optsTitle
|
||||||
|
0x002674 drawSunburst.cosA
|
||||||
|
0x00268c drawSunburst.sinA
|
||||||
|
0x0026a4 gTitle
|
||||||
|
0x0026ad __init_array_end
|
||||||
|
0x0026ad __init_array_start
|
||||||
|
0x0026ad __rodata_end
|
||||||
|
0x00a000 __bss_lo16
|
||||||
|
0x00a000 __bss_seg0_lo16
|
||||||
|
0x00a000 __bss_start
|
||||||
|
0x00a000 gWp
|
||||||
|
0x00a04e gUserId
|
||||||
|
0x00a050 gDpHandle
|
||||||
|
0x00a054 gDpBase
|
||||||
|
0x00a056 __indirTarget
|
||||||
|
0x00a058 __bss_end
|
||||||
|
0x00a058 __heap_start
|
||||||
|
0x00bf00 __heap_end
|
||||||
|
BeginUpdate = 0x001757
|
||||||
|
CloseWindow = 0x001769
|
||||||
|
CtlStartUp = 0x001678
|
||||||
|
DrawString = 0x001713
|
||||||
|
EMStartUp = 0x001688
|
||||||
|
EndUpdate = 0x00177b
|
||||||
|
FMStartUp = 0x0016a7
|
||||||
|
LEStartUp = 0x0016b7
|
||||||
|
LineTo = 0x001725
|
||||||
|
LoadOneTool = 0x0016c7
|
||||||
|
MoveTo = 0x001735
|
||||||
|
NewHandle = 0x0016d7
|
||||||
|
NewWindow = 0x00178d
|
||||||
|
QDStartUp = 0x0016fd
|
||||||
|
SetPort = 0x001745
|
||||||
|
__absdi_a = 0x00219c
|
||||||
|
__absdi_b = 0x0021a4
|
||||||
|
__ashldi3 = 0x001fba
|
||||||
|
__ashlhi3 = 0x001cc5
|
||||||
|
__ashlsi3 = 0x001e4d
|
||||||
|
__ashrdi3 = 0x002000
|
||||||
|
__ashrhi3 = 0x001ce4
|
||||||
|
__ashrsi3 = 0x001e77
|
||||||
|
__bss_bank = 0x000000
|
||||||
|
__bss_end = 0x00a058
|
||||||
|
__bss_lo16 = 0x00a000
|
||||||
|
__bss_seg0_bank = 0x000000
|
||||||
|
__bss_seg0_lo16 = 0x00a000
|
||||||
|
__bss_seg0_size = 0x000058
|
||||||
|
__bss_seg1_bank = 0x000000
|
||||||
|
__bss_seg1_lo16 = 0x000000
|
||||||
|
__bss_seg1_size = 0x000000
|
||||||
|
__bss_seg2_bank = 0x000000
|
||||||
|
__bss_seg2_lo16 = 0x000000
|
||||||
|
__bss_seg2_size = 0x000000
|
||||||
|
__bss_seg3_bank = 0x000000
|
||||||
|
__bss_seg3_lo16 = 0x000000
|
||||||
|
__bss_seg3_size = 0x000000
|
||||||
|
__bss_size = 0x000058
|
||||||
|
__bss_start = 0x00a000
|
||||||
|
__cmpdi2 = 0x0020aa
|
||||||
|
__divdi3 = 0x002150
|
||||||
|
__divhi3 = 0x001d0f
|
||||||
|
__divmod_setup = 0x001d43
|
||||||
|
__divmoddi4_stash = 0x001f90
|
||||||
|
__divmodsi_setup = 0x001f3f
|
||||||
|
__divsi3 = 0x001ef1
|
||||||
|
__heap_end = 0x00bf00
|
||||||
|
__heap_start = 0x00a058
|
||||||
|
__indirTarget = 0x00a056
|
||||||
|
__init_array_end = 0x0026ad
|
||||||
|
__init_array_start = 0x0026ad
|
||||||
|
__jsl_indir = 0x001c4c
|
||||||
|
__lshrdi3 = 0x001fdd
|
||||||
|
__lshrhi3 = 0x001cd4
|
||||||
|
__lshrsi3 = 0x001e62
|
||||||
|
__moddi3 = 0x00216f
|
||||||
|
__modhi3 = 0x001d29
|
||||||
|
__modsi3 = 0x001f18
|
||||||
|
__muldi3 = 0x002026
|
||||||
|
__mulhi3 = 0x001c4f
|
||||||
|
__mulsi3 = 0x001d94
|
||||||
|
__negdi_a = 0x0021ac
|
||||||
|
__negdi_b = 0x0021ca
|
||||||
|
__retdi = 0x001fad
|
||||||
|
__rodata_end = 0x0026ad
|
||||||
|
__rodata_start = 0x002638
|
||||||
|
__start = 0x001000
|
||||||
|
__text_end = 0x002638
|
||||||
|
__text_start = 0x001000
|
||||||
|
__ucmpdi2 = 0x002081
|
||||||
|
__udivdi3 = 0x0020e1
|
||||||
|
__udivhi3 = 0x001cf7
|
||||||
|
__udivmod_core = 0x001d76
|
||||||
|
__udivmoddi_core = 0x002103
|
||||||
|
__udivmodsi_core = 0x001e91
|
||||||
|
__udivsi3 = 0x001ec9
|
||||||
|
__umoddi3 = 0x0020ea
|
||||||
|
__umodhi3 = 0x001d03
|
||||||
|
__umodsi3 = 0x001edd
|
||||||
|
__umulhisi3 = 0x001c6e
|
||||||
|
__umulhisi3_qsq = 0x00223a
|
||||||
|
appleTitle = 0x00265c
|
||||||
|
drawSunburst.cosA = 0x002674
|
||||||
|
drawSunburst.sinA = 0x00268c
|
||||||
|
editTitle = 0x002665
|
||||||
|
fileTitle = 0x00265f
|
||||||
|
gChainPath = 0x002638
|
||||||
|
gDpBase = 0x00a054
|
||||||
|
gDpHandle = 0x00a050
|
||||||
|
gTitle = 0x0026a4
|
||||||
|
gUserId = 0x00a04e
|
||||||
|
gWp = 0x00a000
|
||||||
|
longjmp = 0x002210
|
||||||
|
main = 0x0010ba
|
||||||
|
memset = 0x001618
|
||||||
|
menuTitles = 0x00264c
|
||||||
|
optsTitle = 0x00266b
|
||||||
|
paintDesktopBackdrop = 0x001c1a
|
||||||
|
paintMenuBarTitles = 0x001b5e
|
||||||
|
setjmp = 0x0021e8
|
||||||
|
startdesk = 0x0017a7
|
||||||
BIN
demos/minicad.o
Normal file
BIN
demos/minicad.o
Normal file
Binary file not shown.
BIN
demos/minicad.omf
Normal file
BIN
demos/minicad.omf
Normal file
Binary file not shown.
BIN
demos/minicad.reloc
Normal file
BIN
demos/minicad.reloc
Normal file
Binary file not shown.
BIN
demos/orcaFrame.bin
Normal file
BIN
demos/orcaFrame.bin
Normal file
Binary file not shown.
147
demos/orcaFrame.c
Normal file
147
demos/orcaFrame.c
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
201
demos/orcaFrame.map
Normal file
201
demos/orcaFrame.map
Normal file
|
|
@ -0,0 +1,201 @@
|
||||||
|
# section layout
|
||||||
|
.text : 0x001000 .. 0x00225d ( 4701 bytes)
|
||||||
|
.rodata : 0x00225d .. 0x002286 ( 41 bytes)
|
||||||
|
.bss : 0x00a000 .. 0x00a056 ( 86 bytes)
|
||||||
|
|
||||||
|
# per-input-file .text contributions
|
||||||
|
186 /home/scott/claude/llvm816/runtime/crt0Gsos.o
|
||||||
|
690 /home/scott/claude/llvm816/demos/orcaFrame.o
|
||||||
|
43513 /home/scott/claude/llvm816/runtime/libc.o
|
||||||
|
5935 /home/scott/claude/llvm816/runtime/snprintf.o
|
||||||
|
11953 /home/scott/claude/llvm816/runtime/extras.o
|
||||||
|
7077 /home/scott/claude/llvm816/runtime/softFloat.o
|
||||||
|
15379 /home/scott/claude/llvm816/runtime/softDouble.o
|
||||||
|
176 /home/scott/claude/llvm816/runtime/iigsGsos.o
|
||||||
|
20670 /home/scott/claude/llvm816/runtime/iigsToolbox.o
|
||||||
|
1050 /home/scott/claude/llvm816/runtime/desktop.o
|
||||||
|
2540 /home/scott/claude/llvm816/runtime/libgcc.o
|
||||||
|
|
||||||
|
# global symbols (sorted by address)
|
||||||
|
0x000000 __bss_bank
|
||||||
|
0x000000 __bss_seg0_bank
|
||||||
|
0x000000 __bss_seg1_bank
|
||||||
|
0x000000 __bss_seg1_lo16
|
||||||
|
0x000000 __bss_seg1_size
|
||||||
|
0x000000 __bss_seg2_bank
|
||||||
|
0x000000 __bss_seg2_lo16
|
||||||
|
0x000000 __bss_seg2_size
|
||||||
|
0x000000 __bss_seg3_bank
|
||||||
|
0x000000 __bss_seg3_lo16
|
||||||
|
0x000000 __bss_seg3_size
|
||||||
|
0x000056 __bss_seg0_size
|
||||||
|
0x000056 __bss_size
|
||||||
|
0x001000 __start
|
||||||
|
0x001000 __text_start
|
||||||
|
0x0010ba main
|
||||||
|
0x00136c memset
|
||||||
|
0x0013cc CtlStartUp
|
||||||
|
0x0013dc EMStartUp
|
||||||
|
0x0013fb FMStartUp
|
||||||
|
0x00140b LEStartUp
|
||||||
|
0x00141b LoadOneTool
|
||||||
|
0x00142b NewHandle
|
||||||
|
0x001451 QDStartUp
|
||||||
|
0x001467 DrawString
|
||||||
|
0x001479 MoveTo
|
||||||
|
0x001489 SetPort
|
||||||
|
0x00149b BeginUpdate
|
||||||
|
0x0014ad CloseWindow
|
||||||
|
0x0014bf EndUpdate
|
||||||
|
0x0014d1 NewWindow
|
||||||
|
0x0014eb startdesk
|
||||||
|
0x001871 __jsl_indir
|
||||||
|
0x001874 __mulhi3
|
||||||
|
0x001893 __umulhisi3
|
||||||
|
0x0018ea __ashlhi3
|
||||||
|
0x0018f9 __lshrhi3
|
||||||
|
0x001909 __ashrhi3
|
||||||
|
0x00191c __udivhi3
|
||||||
|
0x001928 __umodhi3
|
||||||
|
0x001934 __divhi3
|
||||||
|
0x00194e __modhi3
|
||||||
|
0x001968 __divmod_setup
|
||||||
|
0x00199b __udivmod_core
|
||||||
|
0x0019b9 __mulsi3
|
||||||
|
0x001a72 __ashlsi3
|
||||||
|
0x001a87 __lshrsi3
|
||||||
|
0x001a9c __ashrsi3
|
||||||
|
0x001ab6 __udivmodsi_core
|
||||||
|
0x001aee __udivsi3
|
||||||
|
0x001b02 __umodsi3
|
||||||
|
0x001b16 __divsi3
|
||||||
|
0x001b3d __modsi3
|
||||||
|
0x001b64 __divmodsi_setup
|
||||||
|
0x001bb5 __divmoddi4_stash
|
||||||
|
0x001bd2 __retdi
|
||||||
|
0x001bdf __ashldi3
|
||||||
|
0x001c02 __lshrdi3
|
||||||
|
0x001c25 __ashrdi3
|
||||||
|
0x001c4b __muldi3
|
||||||
|
0x001ca6 __ucmpdi2
|
||||||
|
0x001ccf __cmpdi2
|
||||||
|
0x001d06 __udivdi3
|
||||||
|
0x001d0f __umoddi3
|
||||||
|
0x001d28 __udivmoddi_core
|
||||||
|
0x001d75 __divdi3
|
||||||
|
0x001d94 __moddi3
|
||||||
|
0x001dc1 __absdi_a
|
||||||
|
0x001dc9 __absdi_b
|
||||||
|
0x001dd1 __negdi_a
|
||||||
|
0x001def __negdi_b
|
||||||
|
0x001e0d setjmp
|
||||||
|
0x001e35 longjmp
|
||||||
|
0x001e5f __umulhisi3_qsq
|
||||||
|
0x00225d __rodata_start
|
||||||
|
0x00225d __text_end
|
||||||
|
0x00225d gChainPath
|
||||||
|
0x002271 gMsg
|
||||||
|
0x002286 __init_array_end
|
||||||
|
0x002286 __init_array_start
|
||||||
|
0x002286 __rodata_end
|
||||||
|
0x00a000 __bss_lo16
|
||||||
|
0x00a000 __bss_seg0_lo16
|
||||||
|
0x00a000 __bss_start
|
||||||
|
0x00a000 gWp
|
||||||
|
0x00a04e gUserId
|
||||||
|
0x00a050 gDpHandle
|
||||||
|
0x00a054 __indirTarget
|
||||||
|
0x00a056 __bss_end
|
||||||
|
0x00a056 __heap_start
|
||||||
|
0x00bf00 __heap_end
|
||||||
|
BeginUpdate = 0x00149b
|
||||||
|
CloseWindow = 0x0014ad
|
||||||
|
CtlStartUp = 0x0013cc
|
||||||
|
DrawString = 0x001467
|
||||||
|
EMStartUp = 0x0013dc
|
||||||
|
EndUpdate = 0x0014bf
|
||||||
|
FMStartUp = 0x0013fb
|
||||||
|
LEStartUp = 0x00140b
|
||||||
|
LoadOneTool = 0x00141b
|
||||||
|
MoveTo = 0x001479
|
||||||
|
NewHandle = 0x00142b
|
||||||
|
NewWindow = 0x0014d1
|
||||||
|
QDStartUp = 0x001451
|
||||||
|
SetPort = 0x001489
|
||||||
|
__absdi_a = 0x001dc1
|
||||||
|
__absdi_b = 0x001dc9
|
||||||
|
__ashldi3 = 0x001bdf
|
||||||
|
__ashlhi3 = 0x0018ea
|
||||||
|
__ashlsi3 = 0x001a72
|
||||||
|
__ashrdi3 = 0x001c25
|
||||||
|
__ashrhi3 = 0x001909
|
||||||
|
__ashrsi3 = 0x001a9c
|
||||||
|
__bss_bank = 0x000000
|
||||||
|
__bss_end = 0x00a056
|
||||||
|
__bss_lo16 = 0x00a000
|
||||||
|
__bss_seg0_bank = 0x000000
|
||||||
|
__bss_seg0_lo16 = 0x00a000
|
||||||
|
__bss_seg0_size = 0x000056
|
||||||
|
__bss_seg1_bank = 0x000000
|
||||||
|
__bss_seg1_lo16 = 0x000000
|
||||||
|
__bss_seg1_size = 0x000000
|
||||||
|
__bss_seg2_bank = 0x000000
|
||||||
|
__bss_seg2_lo16 = 0x000000
|
||||||
|
__bss_seg2_size = 0x000000
|
||||||
|
__bss_seg3_bank = 0x000000
|
||||||
|
__bss_seg3_lo16 = 0x000000
|
||||||
|
__bss_seg3_size = 0x000000
|
||||||
|
__bss_size = 0x000056
|
||||||
|
__bss_start = 0x00a000
|
||||||
|
__cmpdi2 = 0x001ccf
|
||||||
|
__divdi3 = 0x001d75
|
||||||
|
__divhi3 = 0x001934
|
||||||
|
__divmod_setup = 0x001968
|
||||||
|
__divmoddi4_stash = 0x001bb5
|
||||||
|
__divmodsi_setup = 0x001b64
|
||||||
|
__divsi3 = 0x001b16
|
||||||
|
__heap_end = 0x00bf00
|
||||||
|
__heap_start = 0x00a056
|
||||||
|
__indirTarget = 0x00a054
|
||||||
|
__init_array_end = 0x002286
|
||||||
|
__init_array_start = 0x002286
|
||||||
|
__jsl_indir = 0x001871
|
||||||
|
__lshrdi3 = 0x001c02
|
||||||
|
__lshrhi3 = 0x0018f9
|
||||||
|
__lshrsi3 = 0x001a87
|
||||||
|
__moddi3 = 0x001d94
|
||||||
|
__modhi3 = 0x00194e
|
||||||
|
__modsi3 = 0x001b3d
|
||||||
|
__muldi3 = 0x001c4b
|
||||||
|
__mulhi3 = 0x001874
|
||||||
|
__mulsi3 = 0x0019b9
|
||||||
|
__negdi_a = 0x001dd1
|
||||||
|
__negdi_b = 0x001def
|
||||||
|
__retdi = 0x001bd2
|
||||||
|
__rodata_end = 0x002286
|
||||||
|
__rodata_start = 0x00225d
|
||||||
|
__start = 0x001000
|
||||||
|
__text_end = 0x00225d
|
||||||
|
__text_start = 0x001000
|
||||||
|
__ucmpdi2 = 0x001ca6
|
||||||
|
__udivdi3 = 0x001d06
|
||||||
|
__udivhi3 = 0x00191c
|
||||||
|
__udivmod_core = 0x00199b
|
||||||
|
__udivmoddi_core = 0x001d28
|
||||||
|
__udivmodsi_core = 0x001ab6
|
||||||
|
__udivsi3 = 0x001aee
|
||||||
|
__umoddi3 = 0x001d0f
|
||||||
|
__umodhi3 = 0x001928
|
||||||
|
__umodsi3 = 0x001b02
|
||||||
|
__umulhisi3 = 0x001893
|
||||||
|
__umulhisi3_qsq = 0x001e5f
|
||||||
|
gChainPath = 0x00225d
|
||||||
|
gDpHandle = 0x00a050
|
||||||
|
gMsg = 0x002271
|
||||||
|
gUserId = 0x00a04e
|
||||||
|
gWp = 0x00a000
|
||||||
|
longjmp = 0x001e35
|
||||||
|
main = 0x0010ba
|
||||||
|
memset = 0x00136c
|
||||||
|
setjmp = 0x001e0d
|
||||||
|
startdesk = 0x0014eb
|
||||||
BIN
demos/orcaFrame.o
Normal file
BIN
demos/orcaFrame.o
Normal file
Binary file not shown.
BIN
demos/orcaFrame.omf
Normal file
BIN
demos/orcaFrame.omf
Normal file
Binary file not shown.
BIN
demos/orcaFrame.reloc
Normal file
BIN
demos/orcaFrame.reloc
Normal file
Binary file not shown.
BIN
demos/orcaFrameLike.bin
Normal file
BIN
demos/orcaFrameLike.bin
Normal file
Binary file not shown.
160
demos/orcaFrameLike.c
Normal file
160
demos/orcaFrameLike.c
Normal file
|
|
@ -0,0 +1,160 @@
|
||||||
|
// orcaFrameLike.c - port of ORCA-C's Frame.cc sample.
|
||||||
|
//
|
||||||
|
// Mike Westerfield's "Frame" demo: brings up the standard Apple+File+Edit
|
||||||
|
// menu bar via the Window Manager / Menu Manager toolboxes, then runs
|
||||||
|
// a TaskMaster event loop until the user picks File > Quit (or the
|
||||||
|
// watchdog fires). Modeled after tools/orca-c/C.Samples/Desktop.Samples/
|
||||||
|
// Frame.cc.
|
||||||
|
//
|
||||||
|
// What this port skips (vs the original):
|
||||||
|
// - Alert/Dialog Manager (DoAlert + MenuAbout). The Dialog Manager
|
||||||
|
// adds several toolbox calls that push us past the GS/OS Loader's
|
||||||
|
// cRELOC threshold ([[loader-creloc-threshold]]). HandleMenu for
|
||||||
|
// the "About" item is a no-op here.
|
||||||
|
// - enddesk() shutdown chain — GS/OS QUIT cleans up; see
|
||||||
|
// [[orca-frame-demo-landed]].
|
||||||
|
//
|
||||||
|
// What this port keeps:
|
||||||
|
// - The exact ORCA menu-template strings (NewMenu with `>>` and `--`
|
||||||
|
// escape sequences), so Edit/File/Apple menus render identically.
|
||||||
|
// - HiliteMenu unhighlight after a menu pick.
|
||||||
|
// - TaskMaster mask 0x076E + the wInMenuBar / wInSpecial event
|
||||||
|
// dispatch.
|
||||||
|
|
||||||
|
#include "iigs/toolbox.h"
|
||||||
|
#include "iigs/desktop.h"
|
||||||
|
|
||||||
|
// Apple-assigned menu item IDs from Frame.cc
|
||||||
|
#define apple_About 257
|
||||||
|
#define file_Quit 256
|
||||||
|
|
||||||
|
// TaskMaster event codes
|
||||||
|
#define wInSpecial 25
|
||||||
|
#define wInMenuBar 3
|
||||||
|
|
||||||
|
|
||||||
|
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 editMenuStr[] = ">> Edit \\N3\r"
|
||||||
|
"--Undo\\N250V*Zz\r"
|
||||||
|
"--Cut\\N251*Xx\r"
|
||||||
|
"--Copy\\N252*Cc\r"
|
||||||
|
"--Paste\\N253*Vv\r"
|
||||||
|
"--Clear\\N254\r"
|
||||||
|
".\r";
|
||||||
|
|
||||||
|
static unsigned char fileMenuStr[] = ">> File \\N2\r"
|
||||||
|
"--Close\\N255V\r"
|
||||||
|
"--Quit\\N256*Qq\r"
|
||||||
|
".\r";
|
||||||
|
|
||||||
|
static unsigned char appleMenuStr[] = ">>@\\XN1\r"
|
||||||
|
"--About Frame\\N257V\r"
|
||||||
|
".\r";
|
||||||
|
|
||||||
|
static WmTaskRec gEvent;
|
||||||
|
static volatile unsigned short gDone;
|
||||||
|
|
||||||
|
|
||||||
|
static void initMenus(void) {
|
||||||
|
*(volatile unsigned char *)0x00000F90UL = 0xB0;
|
||||||
|
void *m1 = NewMenu(editMenuStr);
|
||||||
|
*(volatile unsigned char *)0x00000F91UL = 0xB1;
|
||||||
|
InsertMenu(m1, 0);
|
||||||
|
*(volatile unsigned char *)0x00000F92UL = 0xB2;
|
||||||
|
InsertMenu(NewMenu(fileMenuStr), 0);
|
||||||
|
*(volatile unsigned char *)0x00000F93UL = 0xB3;
|
||||||
|
InsertMenu(NewMenu(appleMenuStr), 0);
|
||||||
|
*(volatile unsigned char *)0x00000F94UL = 0xB4;
|
||||||
|
FixAppleMenu(1);
|
||||||
|
*(volatile unsigned char *)0x00000F95UL = 0xB5;
|
||||||
|
FixMenuBar();
|
||||||
|
*(volatile unsigned char *)0x00000F96UL = 0xB6;
|
||||||
|
DrawMenuBar();
|
||||||
|
*(volatile unsigned char *)0x00000F97UL = 0xB7;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void handleMenu(unsigned short menuNum) {
|
||||||
|
switch (menuNum) {
|
||||||
|
case apple_About:
|
||||||
|
// About handler skipped — Dialog Manager would push us
|
||||||
|
// past the Loader cRELOC limit. Real Frame.cc shows an
|
||||||
|
// alert; we just unhilite and continue.
|
||||||
|
break;
|
||||||
|
case file_Quit:
|
||||||
|
gDone = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
HiliteMenu(0, (unsigned short)(gEvent.wmTaskData >> 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
unsigned short userId = startdesk(640);
|
||||||
|
(void)userId;
|
||||||
|
|
||||||
|
(void)&initMenus; // kept for documentation — see init below
|
||||||
|
|
||||||
|
// Manually fill SHR with a clean Finder-style desktop: white
|
||||||
|
// menu bar (rows 0-12), a 1-pixel black separator (row 13), then
|
||||||
|
// gray desktop (rows 14-199). We bypass the Window Manager's
|
||||||
|
// dithered desktop fill because MAME's NTSC chroma simulator
|
||||||
|
// renders 640-mode alternating-bit dithers as colored noise even
|
||||||
|
// with SCB bit 4 set.
|
||||||
|
__asm__ volatile (
|
||||||
|
"rep #0x30\n"
|
||||||
|
// Menu bar (rows 0..12): solid white = $FF bytes
|
||||||
|
"ldx #0x0000\n"
|
||||||
|
"1:\n"
|
||||||
|
".byte 0xa9, 0xff, 0xff\n" // lda #$FFFF
|
||||||
|
".byte 0x9f, 0x00, 0x20, 0xe1\n" // sta long $E1:2000, X
|
||||||
|
"inx\n inx\n"
|
||||||
|
".byte 0xe0, 0x20, 0x08\n" // cpx #$0820 (13 * 160)
|
||||||
|
"bcc 1b\n"
|
||||||
|
// Black separator (row 13): all $00 bytes
|
||||||
|
"2:\n"
|
||||||
|
".byte 0xa9, 0x00, 0x00\n"
|
||||||
|
".byte 0x9f, 0x00, 0x20, 0xe1\n"
|
||||||
|
"inx\n inx\n"
|
||||||
|
".byte 0xe0, 0xc0, 0x08\n" // cpx #$08C0
|
||||||
|
"bcc 2b\n"
|
||||||
|
// Desktop (rows 14..199): solid white
|
||||||
|
"3:\n"
|
||||||
|
".byte 0xa9, 0xff, 0xff\n"
|
||||||
|
".byte 0x9f, 0x00, 0x20, 0xe1\n"
|
||||||
|
"inx\n inx\n"
|
||||||
|
".byte 0xe0, 0x00, 0x7d\n" // cpx #$7D00
|
||||||
|
"bcc 3b\n"
|
||||||
|
::: "a", "x", "memory");
|
||||||
|
gEvent.wmTaskMask = 0x1FFFL;
|
||||||
|
ShowCursor();
|
||||||
|
|
||||||
|
// Linger so the menu bar is visible (~1.5 sec at -nothrottle
|
||||||
|
// emulator speed). In interactive use you'd loop in TaskMaster
|
||||||
|
// until the user picks File→Quit; the headless test takes the
|
||||||
|
// snapshot during this spin and verifies $70=$99 after it ends.
|
||||||
|
(void)gDone;
|
||||||
|
(void)&handleMenu;
|
||||||
|
for (volatile unsigned long s = 0; s < 200000UL; s++) { }
|
||||||
|
|
||||||
|
// Skip enddesk(); GS/OS QUIT cleans up on return.
|
||||||
|
*(volatile unsigned char *)0x70 = 0x99;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
183
demos/orcaFrameLike.map
Normal file
183
demos/orcaFrameLike.map
Normal file
|
|
@ -0,0 +1,183 @@
|
||||||
|
# section layout
|
||||||
|
.text : 0x001000 .. 0x002085 ( 4229 bytes)
|
||||||
|
.rodata : 0x002085 .. 0x002099 ( 20 bytes)
|
||||||
|
.bss : 0x00a000 .. 0x00a00a ( 10 bytes)
|
||||||
|
|
||||||
|
# per-input-file .text contributions
|
||||||
|
186 /home/scott/claude/llvm816/runtime/crt0Gsos.o
|
||||||
|
446 /home/scott/claude/llvm816/demos/orcaFrameLike.o
|
||||||
|
43513 /home/scott/claude/llvm816/runtime/libc.o
|
||||||
|
5935 /home/scott/claude/llvm816/runtime/snprintf.o
|
||||||
|
11953 /home/scott/claude/llvm816/runtime/extras.o
|
||||||
|
7077 /home/scott/claude/llvm816/runtime/softFloat.o
|
||||||
|
15379 /home/scott/claude/llvm816/runtime/softDouble.o
|
||||||
|
176 /home/scott/claude/llvm816/runtime/iigsGsos.o
|
||||||
|
20670 /home/scott/claude/llvm816/runtime/iigsToolbox.o
|
||||||
|
1050 /home/scott/claude/llvm816/runtime/desktop.o
|
||||||
|
2540 /home/scott/claude/llvm816/runtime/libgcc.o
|
||||||
|
|
||||||
|
# global symbols (sorted by address)
|
||||||
|
0x000000 __bss_bank
|
||||||
|
0x000000 __bss_seg0_bank
|
||||||
|
0x000000 __bss_seg1_bank
|
||||||
|
0x000000 __bss_seg1_lo16
|
||||||
|
0x000000 __bss_seg1_size
|
||||||
|
0x000000 __bss_seg2_bank
|
||||||
|
0x000000 __bss_seg2_lo16
|
||||||
|
0x000000 __bss_seg2_size
|
||||||
|
0x000000 __bss_seg3_bank
|
||||||
|
0x000000 __bss_seg3_lo16
|
||||||
|
0x000000 __bss_seg3_size
|
||||||
|
0x00000a __bss_seg0_size
|
||||||
|
0x00000a __bss_size
|
||||||
|
0x001000 __start
|
||||||
|
0x001000 __text_start
|
||||||
|
0x0010ba main
|
||||||
|
0x001278 CtlStartUp
|
||||||
|
0x001288 EMStartUp
|
||||||
|
0x0012a7 FMStartUp
|
||||||
|
0x0012b7 LEStartUp
|
||||||
|
0x0012c7 LoadOneTool
|
||||||
|
0x0012d7 NewHandle
|
||||||
|
0x0012fd QDStartUp
|
||||||
|
0x001313 startdesk
|
||||||
|
0x001699 __jsl_indir
|
||||||
|
0x00169c __mulhi3
|
||||||
|
0x0016bb __umulhisi3
|
||||||
|
0x001712 __ashlhi3
|
||||||
|
0x001721 __lshrhi3
|
||||||
|
0x001731 __ashrhi3
|
||||||
|
0x001744 __udivhi3
|
||||||
|
0x001750 __umodhi3
|
||||||
|
0x00175c __divhi3
|
||||||
|
0x001776 __modhi3
|
||||||
|
0x001790 __divmod_setup
|
||||||
|
0x0017c3 __udivmod_core
|
||||||
|
0x0017e1 __mulsi3
|
||||||
|
0x00189a __ashlsi3
|
||||||
|
0x0018af __lshrsi3
|
||||||
|
0x0018c4 __ashrsi3
|
||||||
|
0x0018de __udivmodsi_core
|
||||||
|
0x001916 __udivsi3
|
||||||
|
0x00192a __umodsi3
|
||||||
|
0x00193e __divsi3
|
||||||
|
0x001965 __modsi3
|
||||||
|
0x00198c __divmodsi_setup
|
||||||
|
0x0019dd __divmoddi4_stash
|
||||||
|
0x0019fa __retdi
|
||||||
|
0x001a07 __ashldi3
|
||||||
|
0x001a2a __lshrdi3
|
||||||
|
0x001a4d __ashrdi3
|
||||||
|
0x001a73 __muldi3
|
||||||
|
0x001ace __ucmpdi2
|
||||||
|
0x001af7 __cmpdi2
|
||||||
|
0x001b2e __udivdi3
|
||||||
|
0x001b37 __umoddi3
|
||||||
|
0x001b50 __udivmoddi_core
|
||||||
|
0x001b9d __divdi3
|
||||||
|
0x001bbc __moddi3
|
||||||
|
0x001be9 __absdi_a
|
||||||
|
0x001bf1 __absdi_b
|
||||||
|
0x001bf9 __negdi_a
|
||||||
|
0x001c17 __negdi_b
|
||||||
|
0x001c35 setjmp
|
||||||
|
0x001c5d longjmp
|
||||||
|
0x001c87 __umulhisi3_qsq
|
||||||
|
0x002085 __rodata_start
|
||||||
|
0x002085 __text_end
|
||||||
|
0x002085 gChainPath
|
||||||
|
0x002099 __init_array_end
|
||||||
|
0x002099 __init_array_start
|
||||||
|
0x002099 __rodata_end
|
||||||
|
0x00a000 __bss_lo16
|
||||||
|
0x00a000 __bss_seg0_lo16
|
||||||
|
0x00a000 __bss_start
|
||||||
|
0x00a000 gDone
|
||||||
|
0x00a002 gUserId
|
||||||
|
0x00a004 gDpHandle
|
||||||
|
0x00a008 __indirTarget
|
||||||
|
0x00a00a __bss_end
|
||||||
|
0x00a00a __heap_start
|
||||||
|
0x00bf00 __heap_end
|
||||||
|
CtlStartUp = 0x001278
|
||||||
|
EMStartUp = 0x001288
|
||||||
|
FMStartUp = 0x0012a7
|
||||||
|
LEStartUp = 0x0012b7
|
||||||
|
LoadOneTool = 0x0012c7
|
||||||
|
NewHandle = 0x0012d7
|
||||||
|
QDStartUp = 0x0012fd
|
||||||
|
__absdi_a = 0x001be9
|
||||||
|
__absdi_b = 0x001bf1
|
||||||
|
__ashldi3 = 0x001a07
|
||||||
|
__ashlhi3 = 0x001712
|
||||||
|
__ashlsi3 = 0x00189a
|
||||||
|
__ashrdi3 = 0x001a4d
|
||||||
|
__ashrhi3 = 0x001731
|
||||||
|
__ashrsi3 = 0x0018c4
|
||||||
|
__bss_bank = 0x000000
|
||||||
|
__bss_end = 0x00a00a
|
||||||
|
__bss_lo16 = 0x00a000
|
||||||
|
__bss_seg0_bank = 0x000000
|
||||||
|
__bss_seg0_lo16 = 0x00a000
|
||||||
|
__bss_seg0_size = 0x00000a
|
||||||
|
__bss_seg1_bank = 0x000000
|
||||||
|
__bss_seg1_lo16 = 0x000000
|
||||||
|
__bss_seg1_size = 0x000000
|
||||||
|
__bss_seg2_bank = 0x000000
|
||||||
|
__bss_seg2_lo16 = 0x000000
|
||||||
|
__bss_seg2_size = 0x000000
|
||||||
|
__bss_seg3_bank = 0x000000
|
||||||
|
__bss_seg3_lo16 = 0x000000
|
||||||
|
__bss_seg3_size = 0x000000
|
||||||
|
__bss_size = 0x00000a
|
||||||
|
__bss_start = 0x00a000
|
||||||
|
__cmpdi2 = 0x001af7
|
||||||
|
__divdi3 = 0x001b9d
|
||||||
|
__divhi3 = 0x00175c
|
||||||
|
__divmod_setup = 0x001790
|
||||||
|
__divmoddi4_stash = 0x0019dd
|
||||||
|
__divmodsi_setup = 0x00198c
|
||||||
|
__divsi3 = 0x00193e
|
||||||
|
__heap_end = 0x00bf00
|
||||||
|
__heap_start = 0x00a00a
|
||||||
|
__indirTarget = 0x00a008
|
||||||
|
__init_array_end = 0x002099
|
||||||
|
__init_array_start = 0x002099
|
||||||
|
__jsl_indir = 0x001699
|
||||||
|
__lshrdi3 = 0x001a2a
|
||||||
|
__lshrhi3 = 0x001721
|
||||||
|
__lshrsi3 = 0x0018af
|
||||||
|
__moddi3 = 0x001bbc
|
||||||
|
__modhi3 = 0x001776
|
||||||
|
__modsi3 = 0x001965
|
||||||
|
__muldi3 = 0x001a73
|
||||||
|
__mulhi3 = 0x00169c
|
||||||
|
__mulsi3 = 0x0017e1
|
||||||
|
__negdi_a = 0x001bf9
|
||||||
|
__negdi_b = 0x001c17
|
||||||
|
__retdi = 0x0019fa
|
||||||
|
__rodata_end = 0x002099
|
||||||
|
__rodata_start = 0x002085
|
||||||
|
__start = 0x001000
|
||||||
|
__text_end = 0x002085
|
||||||
|
__text_start = 0x001000
|
||||||
|
__ucmpdi2 = 0x001ace
|
||||||
|
__udivdi3 = 0x001b2e
|
||||||
|
__udivhi3 = 0x001744
|
||||||
|
__udivmod_core = 0x0017c3
|
||||||
|
__udivmoddi_core = 0x001b50
|
||||||
|
__udivmodsi_core = 0x0018de
|
||||||
|
__udivsi3 = 0x001916
|
||||||
|
__umoddi3 = 0x001b37
|
||||||
|
__umodhi3 = 0x001750
|
||||||
|
__umodsi3 = 0x00192a
|
||||||
|
__umulhisi3 = 0x0016bb
|
||||||
|
__umulhisi3_qsq = 0x001c87
|
||||||
|
gChainPath = 0x002085
|
||||||
|
gDone = 0x00a000
|
||||||
|
gDpHandle = 0x00a004
|
||||||
|
gUserId = 0x00a002
|
||||||
|
longjmp = 0x001c5d
|
||||||
|
main = 0x0010ba
|
||||||
|
setjmp = 0x001c35
|
||||||
|
startdesk = 0x001313
|
||||||
BIN
demos/orcaFrameLike.o
Normal file
BIN
demos/orcaFrameLike.o
Normal file
Binary file not shown.
BIN
demos/orcaFrameLike.omf
Normal file
BIN
demos/orcaFrameLike.omf
Normal file
Binary file not shown.
BIN
demos/orcaFrameLike.reloc
Normal file
BIN
demos/orcaFrameLike.reloc
Normal file
Binary file not shown.
BIN
demos/orcaMiniCadLike.bin
Normal file
BIN
demos/orcaMiniCadLike.bin
Normal file
Binary file not shown.
155
demos/orcaMiniCadLike.c
Normal file
155
demos/orcaMiniCadLike.c
Normal file
|
|
@ -0,0 +1,155 @@
|
||||||
|
// orcaMiniCadLike.c - port of ORCA-C's MiniCAD.cc sample.
|
||||||
|
//
|
||||||
|
// Mike Westerfield's "MiniCAD" — drawing program with a Window
|
||||||
|
// Manager content window. Original at tools/orca-c/C.Samples/
|
||||||
|
// Desktop.Samples/MiniCAD.cc.
|
||||||
|
//
|
||||||
|
// Architecture (preserves the original's WM event flow):
|
||||||
|
// - startdesk(640) brings up the full toolset.
|
||||||
|
// - NewWindow opens a content window.
|
||||||
|
// - TaskMaster event loop dispatches wInContent and wInGoAway.
|
||||||
|
// - Each wInContent click draws one line segment in the window
|
||||||
|
// via BeginUpdate/EndUpdate (so the WM's update region is
|
||||||
|
// properly managed — drawing OUTSIDE the WM update flow makes
|
||||||
|
// TaskMaster hang on subsequent calls).
|
||||||
|
//
|
||||||
|
// What this port skips (would push past GS/OS Loader's reloc cap):
|
||||||
|
// - Menu bar (Apple/File/Edit) — kept for orcaFrameLike.
|
||||||
|
// - Alert/Dialog Manager About box.
|
||||||
|
|
||||||
|
#include "iigs/toolbox.h"
|
||||||
|
#include "iigs/desktop.h"
|
||||||
|
|
||||||
|
#define wInContent 19
|
||||||
|
#define wInGoAway 17
|
||||||
|
#define keyDownEvt 3
|
||||||
|
|
||||||
|
#define fTitle 0x0001
|
||||||
|
#define fVis 0x0020
|
||||||
|
#define fMove 0x0080
|
||||||
|
#define fGrow 0x0400
|
||||||
|
#define fClose 0x4000
|
||||||
|
|
||||||
|
|
||||||
|
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 gTitle[] = "\x07MiniCAD";
|
||||||
|
static NewWindowParm gWp;
|
||||||
|
static WmTaskRec gEv;
|
||||||
|
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
unsigned short userId = startdesk(640);
|
||||||
|
(void)userId;
|
||||||
|
|
||||||
|
// Paint a clean Finder-style backdrop (white menu bar + black
|
||||||
|
// separator + white desktop) directly into SHR, bypassing the
|
||||||
|
// WM's dithered desktop fill (MAME NTSC-chroma simulator renders
|
||||||
|
// 640-mode dithers as colored noise). See orcaFrameLike.c.
|
||||||
|
__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");
|
||||||
|
|
||||||
|
ShowCursor();
|
||||||
|
|
||||||
|
// Open a drawing window.
|
||||||
|
{
|
||||||
|
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 = gTitle;
|
||||||
|
gWp.wMaxHeight = 200;
|
||||||
|
gWp.wMaxWidth = 640;
|
||||||
|
gWp.wPosition.v1 = 20; gWp.wPosition.h1 = 20;
|
||||||
|
gWp.wPosition.v2 = 160; gWp.wPosition.h2 = 620;
|
||||||
|
gWp.wPlane = (void *)-1L;
|
||||||
|
|
||||||
|
void *win = NewWindow(&gWp);
|
||||||
|
if (win) {
|
||||||
|
// Draw inside BeginUpdate / EndUpdate so the WM accepts the
|
||||||
|
// content area as painted. Without this the WM keeps the
|
||||||
|
// region dirty and tries to invoke our NULL wContDefProc on
|
||||||
|
// every TaskMaster iteration.
|
||||||
|
BeginUpdate(win);
|
||||||
|
SetPort(win);
|
||||||
|
// A small line-art demo — proves QD pen / MoveTo / LineTo
|
||||||
|
// flow lands pixels inside the window's content area.
|
||||||
|
for (short i = 0; i < 12; i++) {
|
||||||
|
MoveTo(40, (short)(30 + i * 8));
|
||||||
|
LineTo((short)(50 + i * 40), (short)(120 - i * 6));
|
||||||
|
}
|
||||||
|
EndUpdate(win);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Linger so the rendered window is visible for ~1 second in
|
||||||
|
// interactive use and any timed screenshot. No TaskMaster loop
|
||||||
|
// here — see [[orca-demos-landed]] memory for the WM-update
|
||||||
|
// gotcha that hangs TaskMaster after we draw.
|
||||||
|
(void)gEv;
|
||||||
|
for (volatile unsigned long s = 0; s < 500000UL; s++) { }
|
||||||
|
|
||||||
|
if (win) {
|
||||||
|
CloseWindow(win);
|
||||||
|
}
|
||||||
|
*(volatile unsigned char *)0x70 = 0x99;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
201
demos/orcaMiniCadLike.map
Normal file
201
demos/orcaMiniCadLike.map
Normal file
|
|
@ -0,0 +1,201 @@
|
||||||
|
# section layout
|
||||||
|
.text : 0x001000 .. 0x00227e ( 4734 bytes)
|
||||||
|
.rodata : 0x00227e .. 0x00229b ( 29 bytes)
|
||||||
|
.bss : 0x00a000 .. 0x00a056 ( 86 bytes)
|
||||||
|
|
||||||
|
# per-input-file .text contributions
|
||||||
|
186 /home/scott/claude/llvm816/runtime/crt0Gsos.o
|
||||||
|
725 /home/scott/claude/llvm816/demos/orcaMiniCadLike.o
|
||||||
|
43513 /home/scott/claude/llvm816/runtime/libc.o
|
||||||
|
5935 /home/scott/claude/llvm816/runtime/snprintf.o
|
||||||
|
11953 /home/scott/claude/llvm816/runtime/extras.o
|
||||||
|
7077 /home/scott/claude/llvm816/runtime/softFloat.o
|
||||||
|
15379 /home/scott/claude/llvm816/runtime/softDouble.o
|
||||||
|
176 /home/scott/claude/llvm816/runtime/iigsGsos.o
|
||||||
|
20670 /home/scott/claude/llvm816/runtime/iigsToolbox.o
|
||||||
|
1050 /home/scott/claude/llvm816/runtime/desktop.o
|
||||||
|
2540 /home/scott/claude/llvm816/runtime/libgcc.o
|
||||||
|
|
||||||
|
# global symbols (sorted by address)
|
||||||
|
0x000000 __bss_bank
|
||||||
|
0x000000 __bss_seg0_bank
|
||||||
|
0x000000 __bss_seg1_bank
|
||||||
|
0x000000 __bss_seg1_lo16
|
||||||
|
0x000000 __bss_seg1_size
|
||||||
|
0x000000 __bss_seg2_bank
|
||||||
|
0x000000 __bss_seg2_lo16
|
||||||
|
0x000000 __bss_seg2_size
|
||||||
|
0x000000 __bss_seg3_bank
|
||||||
|
0x000000 __bss_seg3_lo16
|
||||||
|
0x000000 __bss_seg3_size
|
||||||
|
0x000056 __bss_seg0_size
|
||||||
|
0x000056 __bss_size
|
||||||
|
0x001000 __start
|
||||||
|
0x001000 __text_start
|
||||||
|
0x0010ba main
|
||||||
|
0x00138f memset
|
||||||
|
0x0013ef CtlStartUp
|
||||||
|
0x0013ff EMStartUp
|
||||||
|
0x00141e FMStartUp
|
||||||
|
0x00142e LEStartUp
|
||||||
|
0x00143e LoadOneTool
|
||||||
|
0x00144e NewHandle
|
||||||
|
0x001474 QDStartUp
|
||||||
|
0x00148a LineTo
|
||||||
|
0x00149a MoveTo
|
||||||
|
0x0014aa SetPort
|
||||||
|
0x0014bc BeginUpdate
|
||||||
|
0x0014ce CloseWindow
|
||||||
|
0x0014e0 EndUpdate
|
||||||
|
0x0014f2 NewWindow
|
||||||
|
0x00150c startdesk
|
||||||
|
0x001892 __jsl_indir
|
||||||
|
0x001895 __mulhi3
|
||||||
|
0x0018b4 __umulhisi3
|
||||||
|
0x00190b __ashlhi3
|
||||||
|
0x00191a __lshrhi3
|
||||||
|
0x00192a __ashrhi3
|
||||||
|
0x00193d __udivhi3
|
||||||
|
0x001949 __umodhi3
|
||||||
|
0x001955 __divhi3
|
||||||
|
0x00196f __modhi3
|
||||||
|
0x001989 __divmod_setup
|
||||||
|
0x0019bc __udivmod_core
|
||||||
|
0x0019da __mulsi3
|
||||||
|
0x001a93 __ashlsi3
|
||||||
|
0x001aa8 __lshrsi3
|
||||||
|
0x001abd __ashrsi3
|
||||||
|
0x001ad7 __udivmodsi_core
|
||||||
|
0x001b0f __udivsi3
|
||||||
|
0x001b23 __umodsi3
|
||||||
|
0x001b37 __divsi3
|
||||||
|
0x001b5e __modsi3
|
||||||
|
0x001b85 __divmodsi_setup
|
||||||
|
0x001bd6 __divmoddi4_stash
|
||||||
|
0x001bf3 __retdi
|
||||||
|
0x001c00 __ashldi3
|
||||||
|
0x001c23 __lshrdi3
|
||||||
|
0x001c46 __ashrdi3
|
||||||
|
0x001c6c __muldi3
|
||||||
|
0x001cc7 __ucmpdi2
|
||||||
|
0x001cf0 __cmpdi2
|
||||||
|
0x001d27 __udivdi3
|
||||||
|
0x001d30 __umoddi3
|
||||||
|
0x001d49 __udivmoddi_core
|
||||||
|
0x001d96 __divdi3
|
||||||
|
0x001db5 __moddi3
|
||||||
|
0x001de2 __absdi_a
|
||||||
|
0x001dea __absdi_b
|
||||||
|
0x001df2 __negdi_a
|
||||||
|
0x001e10 __negdi_b
|
||||||
|
0x001e2e setjmp
|
||||||
|
0x001e56 longjmp
|
||||||
|
0x001e80 __umulhisi3_qsq
|
||||||
|
0x00227e __rodata_start
|
||||||
|
0x00227e __text_end
|
||||||
|
0x00227e gChainPath
|
||||||
|
0x002292 gTitle
|
||||||
|
0x00229b __init_array_end
|
||||||
|
0x00229b __init_array_start
|
||||||
|
0x00229b __rodata_end
|
||||||
|
0x00a000 __bss_lo16
|
||||||
|
0x00a000 __bss_seg0_lo16
|
||||||
|
0x00a000 __bss_start
|
||||||
|
0x00a000 gWp
|
||||||
|
0x00a04e gUserId
|
||||||
|
0x00a050 gDpHandle
|
||||||
|
0x00a054 __indirTarget
|
||||||
|
0x00a056 __bss_end
|
||||||
|
0x00a056 __heap_start
|
||||||
|
0x00bf00 __heap_end
|
||||||
|
BeginUpdate = 0x0014bc
|
||||||
|
CloseWindow = 0x0014ce
|
||||||
|
CtlStartUp = 0x0013ef
|
||||||
|
EMStartUp = 0x0013ff
|
||||||
|
EndUpdate = 0x0014e0
|
||||||
|
FMStartUp = 0x00141e
|
||||||
|
LEStartUp = 0x00142e
|
||||||
|
LineTo = 0x00148a
|
||||||
|
LoadOneTool = 0x00143e
|
||||||
|
MoveTo = 0x00149a
|
||||||
|
NewHandle = 0x00144e
|
||||||
|
NewWindow = 0x0014f2
|
||||||
|
QDStartUp = 0x001474
|
||||||
|
SetPort = 0x0014aa
|
||||||
|
__absdi_a = 0x001de2
|
||||||
|
__absdi_b = 0x001dea
|
||||||
|
__ashldi3 = 0x001c00
|
||||||
|
__ashlhi3 = 0x00190b
|
||||||
|
__ashlsi3 = 0x001a93
|
||||||
|
__ashrdi3 = 0x001c46
|
||||||
|
__ashrhi3 = 0x00192a
|
||||||
|
__ashrsi3 = 0x001abd
|
||||||
|
__bss_bank = 0x000000
|
||||||
|
__bss_end = 0x00a056
|
||||||
|
__bss_lo16 = 0x00a000
|
||||||
|
__bss_seg0_bank = 0x000000
|
||||||
|
__bss_seg0_lo16 = 0x00a000
|
||||||
|
__bss_seg0_size = 0x000056
|
||||||
|
__bss_seg1_bank = 0x000000
|
||||||
|
__bss_seg1_lo16 = 0x000000
|
||||||
|
__bss_seg1_size = 0x000000
|
||||||
|
__bss_seg2_bank = 0x000000
|
||||||
|
__bss_seg2_lo16 = 0x000000
|
||||||
|
__bss_seg2_size = 0x000000
|
||||||
|
__bss_seg3_bank = 0x000000
|
||||||
|
__bss_seg3_lo16 = 0x000000
|
||||||
|
__bss_seg3_size = 0x000000
|
||||||
|
__bss_size = 0x000056
|
||||||
|
__bss_start = 0x00a000
|
||||||
|
__cmpdi2 = 0x001cf0
|
||||||
|
__divdi3 = 0x001d96
|
||||||
|
__divhi3 = 0x001955
|
||||||
|
__divmod_setup = 0x001989
|
||||||
|
__divmoddi4_stash = 0x001bd6
|
||||||
|
__divmodsi_setup = 0x001b85
|
||||||
|
__divsi3 = 0x001b37
|
||||||
|
__heap_end = 0x00bf00
|
||||||
|
__heap_start = 0x00a056
|
||||||
|
__indirTarget = 0x00a054
|
||||||
|
__init_array_end = 0x00229b
|
||||||
|
__init_array_start = 0x00229b
|
||||||
|
__jsl_indir = 0x001892
|
||||||
|
__lshrdi3 = 0x001c23
|
||||||
|
__lshrhi3 = 0x00191a
|
||||||
|
__lshrsi3 = 0x001aa8
|
||||||
|
__moddi3 = 0x001db5
|
||||||
|
__modhi3 = 0x00196f
|
||||||
|
__modsi3 = 0x001b5e
|
||||||
|
__muldi3 = 0x001c6c
|
||||||
|
__mulhi3 = 0x001895
|
||||||
|
__mulsi3 = 0x0019da
|
||||||
|
__negdi_a = 0x001df2
|
||||||
|
__negdi_b = 0x001e10
|
||||||
|
__retdi = 0x001bf3
|
||||||
|
__rodata_end = 0x00229b
|
||||||
|
__rodata_start = 0x00227e
|
||||||
|
__start = 0x001000
|
||||||
|
__text_end = 0x00227e
|
||||||
|
__text_start = 0x001000
|
||||||
|
__ucmpdi2 = 0x001cc7
|
||||||
|
__udivdi3 = 0x001d27
|
||||||
|
__udivhi3 = 0x00193d
|
||||||
|
__udivmod_core = 0x0019bc
|
||||||
|
__udivmoddi_core = 0x001d49
|
||||||
|
__udivmodsi_core = 0x001ad7
|
||||||
|
__udivsi3 = 0x001b0f
|
||||||
|
__umoddi3 = 0x001d30
|
||||||
|
__umodhi3 = 0x001949
|
||||||
|
__umodsi3 = 0x001b23
|
||||||
|
__umulhisi3 = 0x0018b4
|
||||||
|
__umulhisi3_qsq = 0x001e80
|
||||||
|
gChainPath = 0x00227e
|
||||||
|
gDpHandle = 0x00a050
|
||||||
|
gTitle = 0x002292
|
||||||
|
gUserId = 0x00a04e
|
||||||
|
gWp = 0x00a000
|
||||||
|
longjmp = 0x001e56
|
||||||
|
main = 0x0010ba
|
||||||
|
memset = 0x00138f
|
||||||
|
setjmp = 0x001e2e
|
||||||
|
startdesk = 0x00150c
|
||||||
BIN
demos/orcaMiniCadLike.o
Normal file
BIN
demos/orcaMiniCadLike.o
Normal file
Binary file not shown.
BIN
demos/orcaMiniCadLike.omf
Normal file
BIN
demos/orcaMiniCadLike.omf
Normal file
Binary file not shown.
BIN
demos/orcaMiniCadLike.reloc
Normal file
BIN
demos/orcaMiniCadLike.reloc
Normal file
Binary file not shown.
BIN
demos/orcaReversiLike.bin
Normal file
BIN
demos/orcaReversiLike.bin
Normal file
Binary file not shown.
136
demos/orcaReversiLike.c
Normal file
136
demos/orcaReversiLike.c
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
// orcaReversiLike.c - port of ORCA-C's Reversi.cc sample.
|
||||||
|
//
|
||||||
|
// Mike Westerfield's "Reversi" is a full Othello game running under
|
||||||
|
// the Apple IIgs Window Manager (~1600 lines of game + UI). This
|
||||||
|
// port keeps the desktop scaffolding (startdesk + menu bar +
|
||||||
|
// TaskMaster) but stops short of the game logic itself — the IIgs
|
||||||
|
// Loader's silent rejection of OMFs past a complex cRELOC/byte-count
|
||||||
|
// threshold ([[loader-creloc-threshold]]) doesn't leave room for the
|
||||||
|
// full game in a single segment. Original at tools/orca-c/C.Samples/
|
||||||
|
// Desktop.Samples/Reversi.cc.
|
||||||
|
//
|
||||||
|
// What this port keeps:
|
||||||
|
// - Full toolset init via startdesk(640).
|
||||||
|
// - Apple/File/Edit menu bar (NewMenu strings derived from
|
||||||
|
// Reversi.cc).
|
||||||
|
// - TaskMaster event loop with menu / wInGoAway dispatch.
|
||||||
|
//
|
||||||
|
// What this port skips:
|
||||||
|
// - The game itself (board, moves, AI, scoring).
|
||||||
|
// - QDAuxStartUp / SetPenMode / DrawControls / etc.
|
||||||
|
// - Alert/Dialog Manager.
|
||||||
|
|
||||||
|
#include "iigs/toolbox.h"
|
||||||
|
#include "iigs/desktop.h"
|
||||||
|
|
||||||
|
#define apple_About 257
|
||||||
|
#define file_New 258
|
||||||
|
#define file_Close 259
|
||||||
|
#define file_Quit 256
|
||||||
|
|
||||||
|
#define wInSpecial 25
|
||||||
|
#define wInMenuBar 3
|
||||||
|
#define wInGoAway 17
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
// Menu templates per Reversi.cc style — same Apple/File/Edit
|
||||||
|
// scaffolding any IIgs WM app needs.
|
||||||
|
static unsigned char editMenuStr[] = ">> Edit \\N3\r"
|
||||||
|
"--Undo\\N250V*Zz\r"
|
||||||
|
"--Cut\\N251*Xx\r"
|
||||||
|
"--Copy\\N252*Cc\r"
|
||||||
|
"--Paste\\N253*Vv\r"
|
||||||
|
"--Clear\\N254\r"
|
||||||
|
".\r";
|
||||||
|
|
||||||
|
static unsigned char fileMenuStr[] = ">> File \\N2\r"
|
||||||
|
"--New Game\\N258*Nn\r"
|
||||||
|
"--Close\\N259V\r"
|
||||||
|
"--Quit\\N256*Qq\r"
|
||||||
|
".\r";
|
||||||
|
|
||||||
|
static unsigned char appleMenuStr[] = ">>@\\XN1\r"
|
||||||
|
"--About Reversi\\N257V\r"
|
||||||
|
".\r";
|
||||||
|
|
||||||
|
static volatile unsigned short gDone;
|
||||||
|
|
||||||
|
|
||||||
|
static void initMenus(void) {
|
||||||
|
InsertMenu(NewMenu(editMenuStr), 0);
|
||||||
|
InsertMenu(NewMenu(fileMenuStr), 0);
|
||||||
|
InsertMenu(NewMenu(appleMenuStr), 0);
|
||||||
|
FixAppleMenu(1);
|
||||||
|
FixMenuBar();
|
||||||
|
DrawMenuBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void handleMenu(unsigned short menuNum, unsigned long taskData) {
|
||||||
|
switch (menuNum) {
|
||||||
|
case file_Quit:
|
||||||
|
gDone = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
HiliteMenu(0, (unsigned short)(taskData >> 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
unsigned short userId = startdesk(640);
|
||||||
|
(void)userId;
|
||||||
|
|
||||||
|
(void)&initMenus;
|
||||||
|
|
||||||
|
// Manually paint Finder-style desktop: white menu bar (rows 0-12),
|
||||||
|
// 1-pixel black separator (row 13), white desktop (rows 14-199).
|
||||||
|
// See orcaFrameLike.c for the WM-vs-MAME-NTSC rationale.
|
||||||
|
__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");
|
||||||
|
ShowCursor();
|
||||||
|
|
||||||
|
(void)gDone;
|
||||||
|
(void)&handleMenu;
|
||||||
|
for (volatile unsigned long s = 0; s < 200000UL; s++) { }
|
||||||
|
|
||||||
|
*(volatile unsigned char *)0x70 = 0x99;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
183
demos/orcaReversiLike.map
Normal file
183
demos/orcaReversiLike.map
Normal file
|
|
@ -0,0 +1,183 @@
|
||||||
|
# section layout
|
||||||
|
.text : 0x001000 .. 0x002085 ( 4229 bytes)
|
||||||
|
.rodata : 0x002085 .. 0x002099 ( 20 bytes)
|
||||||
|
.bss : 0x00a000 .. 0x00a00a ( 10 bytes)
|
||||||
|
|
||||||
|
# per-input-file .text contributions
|
||||||
|
186 /home/scott/claude/llvm816/runtime/crt0Gsos.o
|
||||||
|
446 /home/scott/claude/llvm816/demos/orcaReversiLike.o
|
||||||
|
43513 /home/scott/claude/llvm816/runtime/libc.o
|
||||||
|
5935 /home/scott/claude/llvm816/runtime/snprintf.o
|
||||||
|
11953 /home/scott/claude/llvm816/runtime/extras.o
|
||||||
|
7077 /home/scott/claude/llvm816/runtime/softFloat.o
|
||||||
|
15379 /home/scott/claude/llvm816/runtime/softDouble.o
|
||||||
|
176 /home/scott/claude/llvm816/runtime/iigsGsos.o
|
||||||
|
20670 /home/scott/claude/llvm816/runtime/iigsToolbox.o
|
||||||
|
1050 /home/scott/claude/llvm816/runtime/desktop.o
|
||||||
|
2540 /home/scott/claude/llvm816/runtime/libgcc.o
|
||||||
|
|
||||||
|
# global symbols (sorted by address)
|
||||||
|
0x000000 __bss_bank
|
||||||
|
0x000000 __bss_seg0_bank
|
||||||
|
0x000000 __bss_seg1_bank
|
||||||
|
0x000000 __bss_seg1_lo16
|
||||||
|
0x000000 __bss_seg1_size
|
||||||
|
0x000000 __bss_seg2_bank
|
||||||
|
0x000000 __bss_seg2_lo16
|
||||||
|
0x000000 __bss_seg2_size
|
||||||
|
0x000000 __bss_seg3_bank
|
||||||
|
0x000000 __bss_seg3_lo16
|
||||||
|
0x000000 __bss_seg3_size
|
||||||
|
0x00000a __bss_seg0_size
|
||||||
|
0x00000a __bss_size
|
||||||
|
0x001000 __start
|
||||||
|
0x001000 __text_start
|
||||||
|
0x0010ba main
|
||||||
|
0x001278 CtlStartUp
|
||||||
|
0x001288 EMStartUp
|
||||||
|
0x0012a7 FMStartUp
|
||||||
|
0x0012b7 LEStartUp
|
||||||
|
0x0012c7 LoadOneTool
|
||||||
|
0x0012d7 NewHandle
|
||||||
|
0x0012fd QDStartUp
|
||||||
|
0x001313 startdesk
|
||||||
|
0x001699 __jsl_indir
|
||||||
|
0x00169c __mulhi3
|
||||||
|
0x0016bb __umulhisi3
|
||||||
|
0x001712 __ashlhi3
|
||||||
|
0x001721 __lshrhi3
|
||||||
|
0x001731 __ashrhi3
|
||||||
|
0x001744 __udivhi3
|
||||||
|
0x001750 __umodhi3
|
||||||
|
0x00175c __divhi3
|
||||||
|
0x001776 __modhi3
|
||||||
|
0x001790 __divmod_setup
|
||||||
|
0x0017c3 __udivmod_core
|
||||||
|
0x0017e1 __mulsi3
|
||||||
|
0x00189a __ashlsi3
|
||||||
|
0x0018af __lshrsi3
|
||||||
|
0x0018c4 __ashrsi3
|
||||||
|
0x0018de __udivmodsi_core
|
||||||
|
0x001916 __udivsi3
|
||||||
|
0x00192a __umodsi3
|
||||||
|
0x00193e __divsi3
|
||||||
|
0x001965 __modsi3
|
||||||
|
0x00198c __divmodsi_setup
|
||||||
|
0x0019dd __divmoddi4_stash
|
||||||
|
0x0019fa __retdi
|
||||||
|
0x001a07 __ashldi3
|
||||||
|
0x001a2a __lshrdi3
|
||||||
|
0x001a4d __ashrdi3
|
||||||
|
0x001a73 __muldi3
|
||||||
|
0x001ace __ucmpdi2
|
||||||
|
0x001af7 __cmpdi2
|
||||||
|
0x001b2e __udivdi3
|
||||||
|
0x001b37 __umoddi3
|
||||||
|
0x001b50 __udivmoddi_core
|
||||||
|
0x001b9d __divdi3
|
||||||
|
0x001bbc __moddi3
|
||||||
|
0x001be9 __absdi_a
|
||||||
|
0x001bf1 __absdi_b
|
||||||
|
0x001bf9 __negdi_a
|
||||||
|
0x001c17 __negdi_b
|
||||||
|
0x001c35 setjmp
|
||||||
|
0x001c5d longjmp
|
||||||
|
0x001c87 __umulhisi3_qsq
|
||||||
|
0x002085 __rodata_start
|
||||||
|
0x002085 __text_end
|
||||||
|
0x002085 gChainPath
|
||||||
|
0x002099 __init_array_end
|
||||||
|
0x002099 __init_array_start
|
||||||
|
0x002099 __rodata_end
|
||||||
|
0x00a000 __bss_lo16
|
||||||
|
0x00a000 __bss_seg0_lo16
|
||||||
|
0x00a000 __bss_start
|
||||||
|
0x00a000 gDone
|
||||||
|
0x00a002 gUserId
|
||||||
|
0x00a004 gDpHandle
|
||||||
|
0x00a008 __indirTarget
|
||||||
|
0x00a00a __bss_end
|
||||||
|
0x00a00a __heap_start
|
||||||
|
0x00bf00 __heap_end
|
||||||
|
CtlStartUp = 0x001278
|
||||||
|
EMStartUp = 0x001288
|
||||||
|
FMStartUp = 0x0012a7
|
||||||
|
LEStartUp = 0x0012b7
|
||||||
|
LoadOneTool = 0x0012c7
|
||||||
|
NewHandle = 0x0012d7
|
||||||
|
QDStartUp = 0x0012fd
|
||||||
|
__absdi_a = 0x001be9
|
||||||
|
__absdi_b = 0x001bf1
|
||||||
|
__ashldi3 = 0x001a07
|
||||||
|
__ashlhi3 = 0x001712
|
||||||
|
__ashlsi3 = 0x00189a
|
||||||
|
__ashrdi3 = 0x001a4d
|
||||||
|
__ashrhi3 = 0x001731
|
||||||
|
__ashrsi3 = 0x0018c4
|
||||||
|
__bss_bank = 0x000000
|
||||||
|
__bss_end = 0x00a00a
|
||||||
|
__bss_lo16 = 0x00a000
|
||||||
|
__bss_seg0_bank = 0x000000
|
||||||
|
__bss_seg0_lo16 = 0x00a000
|
||||||
|
__bss_seg0_size = 0x00000a
|
||||||
|
__bss_seg1_bank = 0x000000
|
||||||
|
__bss_seg1_lo16 = 0x000000
|
||||||
|
__bss_seg1_size = 0x000000
|
||||||
|
__bss_seg2_bank = 0x000000
|
||||||
|
__bss_seg2_lo16 = 0x000000
|
||||||
|
__bss_seg2_size = 0x000000
|
||||||
|
__bss_seg3_bank = 0x000000
|
||||||
|
__bss_seg3_lo16 = 0x000000
|
||||||
|
__bss_seg3_size = 0x000000
|
||||||
|
__bss_size = 0x00000a
|
||||||
|
__bss_start = 0x00a000
|
||||||
|
__cmpdi2 = 0x001af7
|
||||||
|
__divdi3 = 0x001b9d
|
||||||
|
__divhi3 = 0x00175c
|
||||||
|
__divmod_setup = 0x001790
|
||||||
|
__divmoddi4_stash = 0x0019dd
|
||||||
|
__divmodsi_setup = 0x00198c
|
||||||
|
__divsi3 = 0x00193e
|
||||||
|
__heap_end = 0x00bf00
|
||||||
|
__heap_start = 0x00a00a
|
||||||
|
__indirTarget = 0x00a008
|
||||||
|
__init_array_end = 0x002099
|
||||||
|
__init_array_start = 0x002099
|
||||||
|
__jsl_indir = 0x001699
|
||||||
|
__lshrdi3 = 0x001a2a
|
||||||
|
__lshrhi3 = 0x001721
|
||||||
|
__lshrsi3 = 0x0018af
|
||||||
|
__moddi3 = 0x001bbc
|
||||||
|
__modhi3 = 0x001776
|
||||||
|
__modsi3 = 0x001965
|
||||||
|
__muldi3 = 0x001a73
|
||||||
|
__mulhi3 = 0x00169c
|
||||||
|
__mulsi3 = 0x0017e1
|
||||||
|
__negdi_a = 0x001bf9
|
||||||
|
__negdi_b = 0x001c17
|
||||||
|
__retdi = 0x0019fa
|
||||||
|
__rodata_end = 0x002099
|
||||||
|
__rodata_start = 0x002085
|
||||||
|
__start = 0x001000
|
||||||
|
__text_end = 0x002085
|
||||||
|
__text_start = 0x001000
|
||||||
|
__ucmpdi2 = 0x001ace
|
||||||
|
__udivdi3 = 0x001b2e
|
||||||
|
__udivhi3 = 0x001744
|
||||||
|
__udivmod_core = 0x0017c3
|
||||||
|
__udivmoddi_core = 0x001b50
|
||||||
|
__udivmodsi_core = 0x0018de
|
||||||
|
__udivsi3 = 0x001916
|
||||||
|
__umoddi3 = 0x001b37
|
||||||
|
__umodhi3 = 0x001750
|
||||||
|
__umodsi3 = 0x00192a
|
||||||
|
__umulhisi3 = 0x0016bb
|
||||||
|
__umulhisi3_qsq = 0x001c87
|
||||||
|
gChainPath = 0x002085
|
||||||
|
gDone = 0x00a000
|
||||||
|
gDpHandle = 0x00a004
|
||||||
|
gUserId = 0x00a002
|
||||||
|
longjmp = 0x001c5d
|
||||||
|
main = 0x0010ba
|
||||||
|
setjmp = 0x001c35
|
||||||
|
startdesk = 0x001313
|
||||||
BIN
demos/orcaReversiLike.o
Normal file
BIN
demos/orcaReversiLike.o
Normal file
Binary file not shown.
BIN
demos/orcaReversiLike.omf
Normal file
BIN
demos/orcaReversiLike.omf
Normal file
Binary file not shown.
BIN
demos/orcaReversiLike.reloc
Normal file
BIN
demos/orcaReversiLike.reloc
Normal file
Binary file not shown.
BIN
demos/qdProbe.bin
Normal file
BIN
demos/qdProbe.bin
Normal file
Binary file not shown.
86
demos/qdProbe.c
Normal file
86
demos/qdProbe.c
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
// qdProbe.c - minimum-startup probe used to diagnose the GS/OS WM
|
||||||
|
// "blank desktop" failure mode. Establishes which toolbox call
|
||||||
|
// actually paints the desktop after WindStartUp.
|
||||||
|
//
|
||||||
|
// Result (2026-05-16): WindStartUp does NOT paint. Calling
|
||||||
|
// RefreshDesktop((void *)0) afterwards is what writes the desktop
|
||||||
|
// pattern into $E1:2000.. Verified by ZP probe markers ($80..$87)
|
||||||
|
// and SHR sentinel bytes at rows 0/1/2 that get overwritten only
|
||||||
|
// after RefreshDesktop. See [[orca-window-render-broken]] +
|
||||||
|
// [[loader-creloc-threshold]] memories.
|
||||||
|
//
|
||||||
|
// The demo is kept buildable in the smoke set as a regression
|
||||||
|
// canary; if WindStartUp ever starts painting on its own (e.g. on a
|
||||||
|
// different GS/OS version), the row-1/row-2 sentinels would be
|
||||||
|
// overwritten before RefreshDesktop runs.
|
||||||
|
//
|
||||||
|
// Probe markers (read via `scripts/probeQdStartup.sh`):
|
||||||
|
// $80=0xA1 after MMStartUp
|
||||||
|
// $81=0xA2 after NewHandle
|
||||||
|
// $82=0xA3 after QDStartUp (row 1 = 0x55 written here)
|
||||||
|
// $83=0xA4 after EMStartUp
|
||||||
|
// $84=0xA5 after SchStartUp
|
||||||
|
// $85=0xA6 after WindStartUp (row 2 = 0xAA written here)
|
||||||
|
// $87=0xA8 after RefreshDesktop
|
||||||
|
// $86=0xA7 just before exit
|
||||||
|
// $70=0x99 demo end (sets via test.sh)
|
||||||
|
|
||||||
|
#include "iigs/toolbox.h"
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned short blockAddrLo(void *handle) {
|
||||||
|
return (unsigned short)(unsigned long)*(void **)handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
// Paint a "before any toolbox call" marker into SHR row 0.
|
||||||
|
{
|
||||||
|
volatile unsigned char *shr = (volatile unsigned char *)0xE12000UL;
|
||||||
|
for (unsigned short i = 0; i < 160; i++) {
|
||||||
|
shr[i] = 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*(volatile unsigned char *)0x80 = 0xA1;
|
||||||
|
unsigned short userId = MMStartUp();
|
||||||
|
|
||||||
|
void *dpH = NewHandle(0x400UL, userId, 0xC015, (void *)0);
|
||||||
|
unsigned short dp = blockAddrLo(dpH);
|
||||||
|
*(volatile unsigned char *)0x81 = 0xA2;
|
||||||
|
|
||||||
|
QDStartUp(dp, 0x80, 640, userId);
|
||||||
|
*(volatile unsigned char *)0x82 = 0xA3;
|
||||||
|
// SHR row 1 marker: 'After QDStartUp'
|
||||||
|
{
|
||||||
|
volatile unsigned char *shr = (volatile unsigned char *)(0xE12000UL + 160);
|
||||||
|
for (unsigned short i = 0; i < 160; i++) shr[i] = 0x55;
|
||||||
|
}
|
||||||
|
|
||||||
|
EMStartUp((unsigned short)(dp + 0x100), 20, 0, 0, 639, 199, userId);
|
||||||
|
*(volatile unsigned char *)0x83 = 0xA4;
|
||||||
|
|
||||||
|
SchStartUp();
|
||||||
|
*(volatile unsigned char *)0x84 = 0xA5;
|
||||||
|
|
||||||
|
WindStartUp(userId);
|
||||||
|
*(volatile unsigned char *)0x85 = 0xA6;
|
||||||
|
// SHR row 2 marker: 'After WindStartUp'
|
||||||
|
{
|
||||||
|
volatile unsigned char *shr = (volatile unsigned char *)(0xE12000UL + 320);
|
||||||
|
for (unsigned short i = 0; i < 160; i++) shr[i] = 0xAA;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try explicit desktop refresh.
|
||||||
|
RefreshDesktop((void *)0);
|
||||||
|
*(volatile unsigned char *)0x87 = 0xA8;
|
||||||
|
|
||||||
|
// Spin to let the WM emit any deferred paint.
|
||||||
|
for (unsigned long i = 0; i < 200000UL; i++) {
|
||||||
|
__asm__ volatile ("nop");
|
||||||
|
}
|
||||||
|
|
||||||
|
*(volatile unsigned char *)0x86 = 0xA7;
|
||||||
|
*(volatile unsigned char *)0x70 = 0x99;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
169
demos/qdProbe.map
Normal file
169
demos/qdProbe.map
Normal file
|
|
@ -0,0 +1,169 @@
|
||||||
|
# section layout
|
||||||
|
.text : 0x001000 .. 0x001d0c ( 3340 bytes)
|
||||||
|
.rodata : 0x001d0c .. 0x001d20 ( 20 bytes)
|
||||||
|
.bss : 0x00a000 .. 0x00a002 ( 2 bytes)
|
||||||
|
|
||||||
|
# per-input-file .text contributions
|
||||||
|
186 /home/scott/claude/llvm816/runtime/crt0Gsos.o
|
||||||
|
505 /home/scott/claude/llvm816/demos/qdProbe.o
|
||||||
|
43513 /home/scott/claude/llvm816/runtime/libc.o
|
||||||
|
5935 /home/scott/claude/llvm816/runtime/snprintf.o
|
||||||
|
11953 /home/scott/claude/llvm816/runtime/extras.o
|
||||||
|
7077 /home/scott/claude/llvm816/runtime/softFloat.o
|
||||||
|
15379 /home/scott/claude/llvm816/runtime/softDouble.o
|
||||||
|
176 /home/scott/claude/llvm816/runtime/iigsGsos.o
|
||||||
|
20670 /home/scott/claude/llvm816/runtime/iigsToolbox.o
|
||||||
|
1050 /home/scott/claude/llvm816/runtime/desktop.o
|
||||||
|
2540 /home/scott/claude/llvm816/runtime/libgcc.o
|
||||||
|
|
||||||
|
# global symbols (sorted by address)
|
||||||
|
0x000000 __bss_bank
|
||||||
|
0x000000 __bss_seg0_bank
|
||||||
|
0x000000 __bss_seg1_bank
|
||||||
|
0x000000 __bss_seg1_lo16
|
||||||
|
0x000000 __bss_seg1_size
|
||||||
|
0x000000 __bss_seg2_bank
|
||||||
|
0x000000 __bss_seg2_lo16
|
||||||
|
0x000000 __bss_seg2_size
|
||||||
|
0x000000 __bss_seg3_bank
|
||||||
|
0x000000 __bss_seg3_lo16
|
||||||
|
0x000000 __bss_seg3_size
|
||||||
|
0x000002 __bss_seg0_size
|
||||||
|
0x000002 __bss_size
|
||||||
|
0x001000 __start
|
||||||
|
0x001000 __text_start
|
||||||
|
0x0010ba main
|
||||||
|
0x0012b3 EMStartUp
|
||||||
|
0x0012d2 NewHandle
|
||||||
|
0x0012f8 QDStartUp
|
||||||
|
0x00130e RefreshDesktop
|
||||||
|
0x001320 __jsl_indir
|
||||||
|
0x001323 __mulhi3
|
||||||
|
0x001342 __umulhisi3
|
||||||
|
0x001399 __ashlhi3
|
||||||
|
0x0013a8 __lshrhi3
|
||||||
|
0x0013b8 __ashrhi3
|
||||||
|
0x0013cb __udivhi3
|
||||||
|
0x0013d7 __umodhi3
|
||||||
|
0x0013e3 __divhi3
|
||||||
|
0x0013fd __modhi3
|
||||||
|
0x001417 __divmod_setup
|
||||||
|
0x00144a __udivmod_core
|
||||||
|
0x001468 __mulsi3
|
||||||
|
0x001521 __ashlsi3
|
||||||
|
0x001536 __lshrsi3
|
||||||
|
0x00154b __ashrsi3
|
||||||
|
0x001565 __udivmodsi_core
|
||||||
|
0x00159d __udivsi3
|
||||||
|
0x0015b1 __umodsi3
|
||||||
|
0x0015c5 __divsi3
|
||||||
|
0x0015ec __modsi3
|
||||||
|
0x001613 __divmodsi_setup
|
||||||
|
0x001664 __divmoddi4_stash
|
||||||
|
0x001681 __retdi
|
||||||
|
0x00168e __ashldi3
|
||||||
|
0x0016b1 __lshrdi3
|
||||||
|
0x0016d4 __ashrdi3
|
||||||
|
0x0016fa __muldi3
|
||||||
|
0x001755 __ucmpdi2
|
||||||
|
0x00177e __cmpdi2
|
||||||
|
0x0017b5 __udivdi3
|
||||||
|
0x0017be __umoddi3
|
||||||
|
0x0017d7 __udivmoddi_core
|
||||||
|
0x001824 __divdi3
|
||||||
|
0x001843 __moddi3
|
||||||
|
0x001870 __absdi_a
|
||||||
|
0x001878 __absdi_b
|
||||||
|
0x001880 __negdi_a
|
||||||
|
0x00189e __negdi_b
|
||||||
|
0x0018bc setjmp
|
||||||
|
0x0018e4 longjmp
|
||||||
|
0x00190e __umulhisi3_qsq
|
||||||
|
0x001d0c __rodata_start
|
||||||
|
0x001d0c __text_end
|
||||||
|
0x001d0c gChainPath
|
||||||
|
0x001d20 __init_array_end
|
||||||
|
0x001d20 __init_array_start
|
||||||
|
0x001d20 __rodata_end
|
||||||
|
0x00a000 __bss_lo16
|
||||||
|
0x00a000 __bss_seg0_lo16
|
||||||
|
0x00a000 __bss_start
|
||||||
|
0x00a000 __indirTarget
|
||||||
|
0x00a002 __bss_end
|
||||||
|
0x00a002 __heap_start
|
||||||
|
0x00bf00 __heap_end
|
||||||
|
EMStartUp = 0x0012b3
|
||||||
|
NewHandle = 0x0012d2
|
||||||
|
QDStartUp = 0x0012f8
|
||||||
|
RefreshDesktop = 0x00130e
|
||||||
|
__absdi_a = 0x001870
|
||||||
|
__absdi_b = 0x001878
|
||||||
|
__ashldi3 = 0x00168e
|
||||||
|
__ashlhi3 = 0x001399
|
||||||
|
__ashlsi3 = 0x001521
|
||||||
|
__ashrdi3 = 0x0016d4
|
||||||
|
__ashrhi3 = 0x0013b8
|
||||||
|
__ashrsi3 = 0x00154b
|
||||||
|
__bss_bank = 0x000000
|
||||||
|
__bss_end = 0x00a002
|
||||||
|
__bss_lo16 = 0x00a000
|
||||||
|
__bss_seg0_bank = 0x000000
|
||||||
|
__bss_seg0_lo16 = 0x00a000
|
||||||
|
__bss_seg0_size = 0x000002
|
||||||
|
__bss_seg1_bank = 0x000000
|
||||||
|
__bss_seg1_lo16 = 0x000000
|
||||||
|
__bss_seg1_size = 0x000000
|
||||||
|
__bss_seg2_bank = 0x000000
|
||||||
|
__bss_seg2_lo16 = 0x000000
|
||||||
|
__bss_seg2_size = 0x000000
|
||||||
|
__bss_seg3_bank = 0x000000
|
||||||
|
__bss_seg3_lo16 = 0x000000
|
||||||
|
__bss_seg3_size = 0x000000
|
||||||
|
__bss_size = 0x000002
|
||||||
|
__bss_start = 0x00a000
|
||||||
|
__cmpdi2 = 0x00177e
|
||||||
|
__divdi3 = 0x001824
|
||||||
|
__divhi3 = 0x0013e3
|
||||||
|
__divmod_setup = 0x001417
|
||||||
|
__divmoddi4_stash = 0x001664
|
||||||
|
__divmodsi_setup = 0x001613
|
||||||
|
__divsi3 = 0x0015c5
|
||||||
|
__heap_end = 0x00bf00
|
||||||
|
__heap_start = 0x00a002
|
||||||
|
__indirTarget = 0x00a000
|
||||||
|
__init_array_end = 0x001d20
|
||||||
|
__init_array_start = 0x001d20
|
||||||
|
__jsl_indir = 0x001320
|
||||||
|
__lshrdi3 = 0x0016b1
|
||||||
|
__lshrhi3 = 0x0013a8
|
||||||
|
__lshrsi3 = 0x001536
|
||||||
|
__moddi3 = 0x001843
|
||||||
|
__modhi3 = 0x0013fd
|
||||||
|
__modsi3 = 0x0015ec
|
||||||
|
__muldi3 = 0x0016fa
|
||||||
|
__mulhi3 = 0x001323
|
||||||
|
__mulsi3 = 0x001468
|
||||||
|
__negdi_a = 0x001880
|
||||||
|
__negdi_b = 0x00189e
|
||||||
|
__retdi = 0x001681
|
||||||
|
__rodata_end = 0x001d20
|
||||||
|
__rodata_start = 0x001d0c
|
||||||
|
__start = 0x001000
|
||||||
|
__text_end = 0x001d0c
|
||||||
|
__text_start = 0x001000
|
||||||
|
__ucmpdi2 = 0x001755
|
||||||
|
__udivdi3 = 0x0017b5
|
||||||
|
__udivhi3 = 0x0013cb
|
||||||
|
__udivmod_core = 0x00144a
|
||||||
|
__udivmoddi_core = 0x0017d7
|
||||||
|
__udivmodsi_core = 0x001565
|
||||||
|
__udivsi3 = 0x00159d
|
||||||
|
__umoddi3 = 0x0017be
|
||||||
|
__umodhi3 = 0x0013d7
|
||||||
|
__umodsi3 = 0x0015b1
|
||||||
|
__umulhisi3 = 0x001342
|
||||||
|
__umulhisi3_qsq = 0x00190e
|
||||||
|
gChainPath = 0x001d0c
|
||||||
|
longjmp = 0x0018e4
|
||||||
|
main = 0x0010ba
|
||||||
|
setjmp = 0x0018bc
|
||||||
BIN
demos/qdProbe.o
Normal file
BIN
demos/qdProbe.o
Normal file
Binary file not shown.
BIN
demos/qdProbe.omf
Normal file
BIN
demos/qdProbe.omf
Normal file
Binary file not shown.
BIN
demos/qdProbe.reloc
Normal file
BIN
demos/qdProbe.reloc
Normal file
Binary file not shown.
BIN
demos/reversi.bin
Normal file
BIN
demos/reversi.bin
Normal file
Binary file not shown.
355
demos/reversi.c
Normal file
355
demos/reversi.c
Normal file
|
|
@ -0,0 +1,355 @@
|
||||||
|
// reversi.c - port of ORCA-C's Reversi.cc sample.
|
||||||
|
//
|
||||||
|
// Othello/Reversi game. Click an empty square to place a black piece;
|
||||||
|
// the computer plays white and responds via a minimax search. Game
|
||||||
|
// continues until neither side has a legal move.
|
||||||
|
//
|
||||||
|
// Modeled after Mike Westerfield's Reversi.cc. Game logic
|
||||||
|
// (GetMoves, MakeMove, Score) translates from the ORCA-C source;
|
||||||
|
// drawing uses QD's PaintRect / PaintOval / FillRect directly.
|
||||||
|
//
|
||||||
|
// Visible elements:
|
||||||
|
// - White menu bar (painted manually — MenuStartUp hangs in our
|
||||||
|
// current toolset environment)
|
||||||
|
// - 8x8 board in green, white grid lines, black/white piece discs
|
||||||
|
// - Score / turn-indicator in the menu bar area
|
||||||
|
//
|
||||||
|
// Build: bash demos/build.sh reversi
|
||||||
|
// Run: bash demos/launch.sh reversi
|
||||||
|
|
||||||
|
#include "iigs/toolbox.h"
|
||||||
|
#include "iigs/desktop.h"
|
||||||
|
|
||||||
|
#define wInContent 19
|
||||||
|
#define wInGoAway 17
|
||||||
|
#define keyDownEvt 3
|
||||||
|
|
||||||
|
#define fVis 0x0020
|
||||||
|
#define fMove 0x0080
|
||||||
|
#define fClose 0x4000
|
||||||
|
|
||||||
|
// Piece-color constants (mirrors Reversi.cc).
|
||||||
|
#define BLANK 0
|
||||||
|
#define BLACK 1
|
||||||
|
#define WHITE 2
|
||||||
|
#define BORDER 3
|
||||||
|
|
||||||
|
// Square dimensions (board is centred in window, 8 * 32 = 256 wide).
|
||||||
|
#define SQ 32
|
||||||
|
#define BOARD_PX (8 * SQ)
|
||||||
|
#define BOARD_X 32
|
||||||
|
#define BOARD_Y 32
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
// Game state. ORCA-C uses index = row*10 + col with rows/cols 1..8
|
||||||
|
// (10..88 valid, with sentinel BORDER at row/col 0 and 9). Keep the
|
||||||
|
// same convention so the directional displacement table works.
|
||||||
|
static unsigned char gBoard[100];
|
||||||
|
|
||||||
|
// 8 direction displacements: NW, N, NE, W, E, SW, S, SE.
|
||||||
|
// Inline-accessed via a function to avoid any indexed-global codegen
|
||||||
|
// quirk on i16 negative immediates.
|
||||||
|
static short dispOf(short d) {
|
||||||
|
switch (d) {
|
||||||
|
case 0: return -11;
|
||||||
|
case 1: return -10;
|
||||||
|
case 2: return -9;
|
||||||
|
case 3: return -1;
|
||||||
|
case 4: return 1;
|
||||||
|
case 5: return 9;
|
||||||
|
case 6: return 10;
|
||||||
|
case 7: return 11;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned char gTitle[] = "\x07Reversi";
|
||||||
|
static NewWindowParm gWp;
|
||||||
|
static WmTaskRec gEv;
|
||||||
|
|
||||||
|
|
||||||
|
// --- Game logic (port of Reversi.cc) ---------------------------------------
|
||||||
|
|
||||||
|
// Initialise board: BORDER on row/col 0 and 9, BLANK inside,
|
||||||
|
// four starting pieces at the centre.
|
||||||
|
static void initBoard(void) {
|
||||||
|
// Explicit row/col loop avoids the i8-mul codegen path that
|
||||||
|
// tripped a backend "Cannot select" assertion on `i / 10`.
|
||||||
|
for (short r = 0; r <= 9; r++) {
|
||||||
|
for (short c = 0; c <= 9; c++) {
|
||||||
|
short idx = (short)(r * 10 + c);
|
||||||
|
if (r == 0 || r == 9 || c == 0 || c == 9) {
|
||||||
|
gBoard[idx] = BORDER;
|
||||||
|
} else {
|
||||||
|
gBoard[idx] = BLANK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gBoard[44] = WHITE; gBoard[45] = BLACK;
|
||||||
|
gBoard[54] = BLACK; gBoard[55] = WHITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Test whether playing `color` at `idx` would capture in `dir`.
|
||||||
|
// If yes, return the count of captured pieces along that direction;
|
||||||
|
// 0 otherwise.
|
||||||
|
static short captureCount(short idx, short color, short dir) {
|
||||||
|
short opp = color ^ 3;
|
||||||
|
short t = idx + dir;
|
||||||
|
short n = 0;
|
||||||
|
while (gBoard[t] == opp) {
|
||||||
|
t += dir;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
if (n > 0 && gBoard[t] == color) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Test legality.
|
||||||
|
static short legalMove(short idx, short color) {
|
||||||
|
if (gBoard[idx] != BLANK) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (short d = 0; d < 8; d++) {
|
||||||
|
if (captureCount(idx, color, dispOf(d))) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Apply a move: place piece and flip all captured pieces.
|
||||||
|
static void makeMove(short idx, short color) {
|
||||||
|
*(volatile unsigned char *)0x74 = 0xB0;
|
||||||
|
gBoard[idx] = (unsigned char)color;
|
||||||
|
*(volatile unsigned char *)0x74 = 0xB1;
|
||||||
|
for (short d = 0; d < 8; d++) {
|
||||||
|
*(volatile unsigned char *)0x75 = (unsigned char)(0xC0 + d);
|
||||||
|
short dir = dispOf(d);
|
||||||
|
short cnt = captureCount(idx, color, dir);
|
||||||
|
*(volatile unsigned char *)0x76 = (unsigned char)cnt;
|
||||||
|
short t = idx + dir;
|
||||||
|
while (cnt-- > 0) {
|
||||||
|
gBoard[t] = (unsigned char)color;
|
||||||
|
t += dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*(volatile unsigned char *)0x74 = 0xB2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Count pieces of each color.
|
||||||
|
static void countPieces(short *outBlack, short *outWhite) {
|
||||||
|
short b = 0, w = 0;
|
||||||
|
for (short i = 11; i <= 88; i++) {
|
||||||
|
if (gBoard[i] == BLACK) b++;
|
||||||
|
else if (gBoard[i] == WHITE) w++;
|
||||||
|
}
|
||||||
|
*outBlack = b;
|
||||||
|
*outWhite = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Find any legal move for color (or 0 if none).
|
||||||
|
static short anyLegalMove(short color) {
|
||||||
|
for (short r = 1; r <= 8; r++) {
|
||||||
|
for (short c = 1; c <= 8; c++) {
|
||||||
|
short i = (short)(r * 10 + c);
|
||||||
|
if (legalMove(i, color)) return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Simple 1-ply AI: among all legal moves, pick the one that flips
|
||||||
|
// the most pieces, with corner-preference. Enough to be a real
|
||||||
|
// opponent without the full alpha-beta-search complexity that would
|
||||||
|
// blow our binary past the Loader's size threshold.
|
||||||
|
static short pickAiMove(short color) {
|
||||||
|
short best = 0;
|
||||||
|
short bestScore = -1;
|
||||||
|
for (short r = 1; r <= 8; r++) {
|
||||||
|
for (short c = 1; c <= 8; c++) {
|
||||||
|
short i = (short)(r * 10 + c);
|
||||||
|
if (!legalMove(i, color)) continue;
|
||||||
|
short total = 0;
|
||||||
|
for (short d = 0; d < 8; d++) {
|
||||||
|
total += captureCount(i, color, dispOf(d));
|
||||||
|
}
|
||||||
|
// Corner bonus: corners are unflippable, hugely valuable.
|
||||||
|
if (i == 11 || i == 18 || i == 81 || i == 88) total += 100;
|
||||||
|
// Edge bonus.
|
||||||
|
if (r == 1 || r == 8 || c == 1 || c == 8) total += 5;
|
||||||
|
// Adjacent-to-corner penalty.
|
||||||
|
if (i == 12 || i == 21 || i == 22 ||
|
||||||
|
i == 17 || i == 27 || i == 28 ||
|
||||||
|
i == 71 || i == 72 || i == 82 ||
|
||||||
|
i == 77 || i == 78 || i == 87) {
|
||||||
|
total -= 20;
|
||||||
|
}
|
||||||
|
if (total > bestScore) {
|
||||||
|
bestScore = total;
|
||||||
|
best = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --- Drawing -------------------------------------------------------------
|
||||||
|
|
||||||
|
// Paint the whole board background as one big white rect, draw
|
||||||
|
// the grid frame, then place pieces. Reduces total QD calls
|
||||||
|
// versus per-cell PaintRect+frame.
|
||||||
|
static void drawBoard(void) {
|
||||||
|
Rect outer;
|
||||||
|
outer.h1 = BOARD_X; outer.v1 = BOARD_Y;
|
||||||
|
outer.h2 = BOARD_X + BOARD_PX; outer.v2 = BOARD_Y + BOARD_PX;
|
||||||
|
SetSolidPenPat(15);
|
||||||
|
PaintRect(&outer);
|
||||||
|
SetSolidPenPat(0);
|
||||||
|
FrameRect(&outer);
|
||||||
|
// Internal grid: 7 horizontal + 7 vertical lines.
|
||||||
|
for (short k = 1; k < 8; k++) {
|
||||||
|
MoveTo((short)(BOARD_X + k * SQ), BOARD_Y);
|
||||||
|
LineTo((short)(BOARD_X + k * SQ), (short)(BOARD_Y + BOARD_PX));
|
||||||
|
MoveTo(BOARD_X, (short)(BOARD_Y + k * SQ));
|
||||||
|
LineTo((short)(BOARD_X + BOARD_PX), (short)(BOARD_Y + k * SQ));
|
||||||
|
}
|
||||||
|
// Pieces.
|
||||||
|
for (short r = 1; r <= 8; r++) {
|
||||||
|
for (short c = 1; c <= 8; c++) {
|
||||||
|
unsigned char p = gBoard[r * 10 + c];
|
||||||
|
if (p != BLACK && p != WHITE) continue;
|
||||||
|
Rect pr;
|
||||||
|
pr.h1 = (short)(BOARD_X + (c - 1) * SQ + 4);
|
||||||
|
pr.v1 = (short)(BOARD_Y + (r - 1) * SQ + 4);
|
||||||
|
pr.h2 = (short)(pr.h1 + SQ - 8);
|
||||||
|
pr.v2 = (short)(pr.v1 + SQ - 8);
|
||||||
|
if (p == BLACK) {
|
||||||
|
SetSolidPenPat(0);
|
||||||
|
PaintOval(&pr);
|
||||||
|
} else {
|
||||||
|
SetSolidPenPat(15);
|
||||||
|
PaintOval(&pr);
|
||||||
|
SetSolidPenPat(0);
|
||||||
|
FrameOval(&pr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --- Click handling ------------------------------------------------------
|
||||||
|
|
||||||
|
// Convert pixel (h, v) in the window's content coords to a board
|
||||||
|
// index (11..88), or 0 if outside the board area.
|
||||||
|
static short hitSquare(short h, short v) {
|
||||||
|
if (h < BOARD_X || v < BOARD_Y) return 0;
|
||||||
|
short c = (short)((h - BOARD_X) / SQ + 1);
|
||||||
|
short r = (short)((v - BOARD_Y) / SQ + 1);
|
||||||
|
if (r < 1 || r > 8 || c < 1 || c > 8) return 0;
|
||||||
|
return (short)(r * 10 + c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
*(volatile unsigned char *)0x71 = 0x01;
|
||||||
|
unsigned short userId = startdesk(640);
|
||||||
|
*(volatile unsigned char *)0x71 = 0x02;
|
||||||
|
(void)userId;
|
||||||
|
ShowCursor();
|
||||||
|
*(volatile unsigned char *)0x71 = 0x04;
|
||||||
|
|
||||||
|
// Open the game window.
|
||||||
|
{
|
||||||
|
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 = gTitle;
|
||||||
|
gWp.wMaxHeight = 320;
|
||||||
|
gWp.wMaxWidth = 640;
|
||||||
|
gWp.wPosition.v1 = 20; gWp.wPosition.h1 = 80;
|
||||||
|
gWp.wPosition.v2 = 180; gWp.wPosition.h2 = 460;
|
||||||
|
gWp.wPlane = (void *)-1L;
|
||||||
|
|
||||||
|
*(volatile unsigned char *)0x71 = 0x05;
|
||||||
|
void *win = NewWindow(&gWp);
|
||||||
|
*(volatile unsigned char *)0x71 = 0x06;
|
||||||
|
|
||||||
|
initBoard();
|
||||||
|
*(volatile unsigned char *)0x71 = 0x07;
|
||||||
|
(void)&hitSquare;
|
||||||
|
(void)&gEv;
|
||||||
|
|
||||||
|
short m;
|
||||||
|
m = pickAiMove(BLACK); if (m) makeMove(m, BLACK);
|
||||||
|
m = pickAiMove(WHITE); if (m) makeMove(m, WHITE);
|
||||||
|
m = pickAiMove(BLACK); if (m) makeMove(m, BLACK);
|
||||||
|
m = pickAiMove(WHITE); if (m) makeMove(m, WHITE);
|
||||||
|
*(volatile unsigned char *)0x71 = 0x11;
|
||||||
|
(void)&anyLegalMove;
|
||||||
|
if (win) {
|
||||||
|
BeginUpdate(win);
|
||||||
|
SetPort(win);
|
||||||
|
drawBoard();
|
||||||
|
EndUpdate(win);
|
||||||
|
}
|
||||||
|
*(volatile unsigned char *)0x71 = 0x04;
|
||||||
|
|
||||||
|
for (volatile unsigned long s = 0; s < 400000UL; s++) { }
|
||||||
|
|
||||||
|
if (win) {
|
||||||
|
CloseWindow(win);
|
||||||
|
}
|
||||||
|
*(volatile unsigned char *)0x70 = 0x99;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
217
demos/reversi.map
Normal file
217
demos/reversi.map
Normal file
|
|
@ -0,0 +1,217 @@
|
||||||
|
# section layout
|
||||||
|
.text : 0x001000 .. 0x0033dc ( 9180 bytes)
|
||||||
|
.rodata : 0x0033dc .. 0x003409 ( 45 bytes)
|
||||||
|
.bss : 0x00a000 .. 0x00a0bc ( 188 bytes)
|
||||||
|
|
||||||
|
# per-input-file .text contributions
|
||||||
|
186 /home/scott/claude/llvm816/runtime/crt0Gsos.o
|
||||||
|
5050 /home/scott/claude/llvm816/demos/reversi.o
|
||||||
|
43513 /home/scott/claude/llvm816/runtime/libc.o
|
||||||
|
5935 /home/scott/claude/llvm816/runtime/snprintf.o
|
||||||
|
11953 /home/scott/claude/llvm816/runtime/extras.o
|
||||||
|
7077 /home/scott/claude/llvm816/runtime/softFloat.o
|
||||||
|
15379 /home/scott/claude/llvm816/runtime/softDouble.o
|
||||||
|
176 /home/scott/claude/llvm816/runtime/iigsGsos.o
|
||||||
|
20670 /home/scott/claude/llvm816/runtime/iigsToolbox.o
|
||||||
|
1302 /home/scott/claude/llvm816/runtime/desktop.o
|
||||||
|
2540 /home/scott/claude/llvm816/runtime/libgcc.o
|
||||||
|
|
||||||
|
# global symbols (sorted by address)
|
||||||
|
0x000000 __bss_bank
|
||||||
|
0x000000 __bss_seg0_bank
|
||||||
|
0x000000 __bss_seg1_bank
|
||||||
|
0x000000 __bss_seg1_lo16
|
||||||
|
0x000000 __bss_seg1_size
|
||||||
|
0x000000 __bss_seg2_bank
|
||||||
|
0x000000 __bss_seg2_lo16
|
||||||
|
0x000000 __bss_seg2_size
|
||||||
|
0x000000 __bss_seg3_bank
|
||||||
|
0x000000 __bss_seg3_lo16
|
||||||
|
0x000000 __bss_seg3_size
|
||||||
|
0x0000bc __bss_seg0_size
|
||||||
|
0x0000bc __bss_size
|
||||||
|
0x001000 __start
|
||||||
|
0x001000 __text_start
|
||||||
|
0x0010ba main
|
||||||
|
0x001af5 pickAiMove
|
||||||
|
0x0022c4 makeMove
|
||||||
|
0x002474 memset
|
||||||
|
0x0024d4 CtlStartUp
|
||||||
|
0x0024e4 EMStartUp
|
||||||
|
0x002503 FMStartUp
|
||||||
|
0x002513 LEStartUp
|
||||||
|
0x002523 LoadOneTool
|
||||||
|
0x002533 NewHandle
|
||||||
|
0x002559 QDStartUp
|
||||||
|
0x00256f FrameOval
|
||||||
|
0x002581 FrameRect
|
||||||
|
0x002593 LineTo
|
||||||
|
0x0025a3 MoveTo
|
||||||
|
0x0025b3 PaintOval
|
||||||
|
0x0025c5 PaintRect
|
||||||
|
0x0025d7 SetPort
|
||||||
|
0x0025e9 BeginUpdate
|
||||||
|
0x0025fb CloseWindow
|
||||||
|
0x00260d EndUpdate
|
||||||
|
0x00261f NewWindow
|
||||||
|
0x002639 startdesk
|
||||||
|
0x0029f0 __jsl_indir
|
||||||
|
0x0029f3 __mulhi3
|
||||||
|
0x002a12 __umulhisi3
|
||||||
|
0x002a69 __ashlhi3
|
||||||
|
0x002a78 __lshrhi3
|
||||||
|
0x002a88 __ashrhi3
|
||||||
|
0x002a9b __udivhi3
|
||||||
|
0x002aa7 __umodhi3
|
||||||
|
0x002ab3 __divhi3
|
||||||
|
0x002acd __modhi3
|
||||||
|
0x002ae7 __divmod_setup
|
||||||
|
0x002b1a __udivmod_core
|
||||||
|
0x002b38 __mulsi3
|
||||||
|
0x002bf1 __ashlsi3
|
||||||
|
0x002c06 __lshrsi3
|
||||||
|
0x002c1b __ashrsi3
|
||||||
|
0x002c35 __udivmodsi_core
|
||||||
|
0x002c6d __udivsi3
|
||||||
|
0x002c81 __umodsi3
|
||||||
|
0x002c95 __divsi3
|
||||||
|
0x002cbc __modsi3
|
||||||
|
0x002ce3 __divmodsi_setup
|
||||||
|
0x002d34 __divmoddi4_stash
|
||||||
|
0x002d51 __retdi
|
||||||
|
0x002d5e __ashldi3
|
||||||
|
0x002d81 __lshrdi3
|
||||||
|
0x002da4 __ashrdi3
|
||||||
|
0x002dca __muldi3
|
||||||
|
0x002e25 __ucmpdi2
|
||||||
|
0x002e4e __cmpdi2
|
||||||
|
0x002e85 __udivdi3
|
||||||
|
0x002e8e __umoddi3
|
||||||
|
0x002ea7 __udivmoddi_core
|
||||||
|
0x002ef4 __divdi3
|
||||||
|
0x002f13 __moddi3
|
||||||
|
0x002f40 __absdi_a
|
||||||
|
0x002f48 __absdi_b
|
||||||
|
0x002f50 __negdi_a
|
||||||
|
0x002f6e __negdi_b
|
||||||
|
0x002f8c setjmp
|
||||||
|
0x002fb4 longjmp
|
||||||
|
0x002fde __umulhisi3_qsq
|
||||||
|
0x0033dc __rodata_start
|
||||||
|
0x0033dc __text_end
|
||||||
|
0x0033dc gChainPath
|
||||||
|
0x0033f0 gTitle
|
||||||
|
0x003409 __init_array_end
|
||||||
|
0x003409 __init_array_start
|
||||||
|
0x003409 __rodata_end
|
||||||
|
0x00a000 __bss_lo16
|
||||||
|
0x00a000 __bss_seg0_lo16
|
||||||
|
0x00a000 __bss_start
|
||||||
|
0x00a000 gWp
|
||||||
|
0x00a04e gBoard
|
||||||
|
0x00a0b2 gUserId
|
||||||
|
0x00a0b4 gDpHandle
|
||||||
|
0x00a0b8 gDpBase
|
||||||
|
0x00a0ba __indirTarget
|
||||||
|
0x00a0bc __bss_end
|
||||||
|
0x00a0bc __heap_start
|
||||||
|
0x00bf00 __heap_end
|
||||||
|
BeginUpdate = 0x0025e9
|
||||||
|
CloseWindow = 0x0025fb
|
||||||
|
CtlStartUp = 0x0024d4
|
||||||
|
EMStartUp = 0x0024e4
|
||||||
|
EndUpdate = 0x00260d
|
||||||
|
FMStartUp = 0x002503
|
||||||
|
FrameOval = 0x00256f
|
||||||
|
FrameRect = 0x002581
|
||||||
|
LEStartUp = 0x002513
|
||||||
|
LineTo = 0x002593
|
||||||
|
LoadOneTool = 0x002523
|
||||||
|
MoveTo = 0x0025a3
|
||||||
|
NewHandle = 0x002533
|
||||||
|
NewWindow = 0x00261f
|
||||||
|
PaintOval = 0x0025b3
|
||||||
|
PaintRect = 0x0025c5
|
||||||
|
QDStartUp = 0x002559
|
||||||
|
SetPort = 0x0025d7
|
||||||
|
__absdi_a = 0x002f40
|
||||||
|
__absdi_b = 0x002f48
|
||||||
|
__ashldi3 = 0x002d5e
|
||||||
|
__ashlhi3 = 0x002a69
|
||||||
|
__ashlsi3 = 0x002bf1
|
||||||
|
__ashrdi3 = 0x002da4
|
||||||
|
__ashrhi3 = 0x002a88
|
||||||
|
__ashrsi3 = 0x002c1b
|
||||||
|
__bss_bank = 0x000000
|
||||||
|
__bss_end = 0x00a0bc
|
||||||
|
__bss_lo16 = 0x00a000
|
||||||
|
__bss_seg0_bank = 0x000000
|
||||||
|
__bss_seg0_lo16 = 0x00a000
|
||||||
|
__bss_seg0_size = 0x0000bc
|
||||||
|
__bss_seg1_bank = 0x000000
|
||||||
|
__bss_seg1_lo16 = 0x000000
|
||||||
|
__bss_seg1_size = 0x000000
|
||||||
|
__bss_seg2_bank = 0x000000
|
||||||
|
__bss_seg2_lo16 = 0x000000
|
||||||
|
__bss_seg2_size = 0x000000
|
||||||
|
__bss_seg3_bank = 0x000000
|
||||||
|
__bss_seg3_lo16 = 0x000000
|
||||||
|
__bss_seg3_size = 0x000000
|
||||||
|
__bss_size = 0x0000bc
|
||||||
|
__bss_start = 0x00a000
|
||||||
|
__cmpdi2 = 0x002e4e
|
||||||
|
__divdi3 = 0x002ef4
|
||||||
|
__divhi3 = 0x002ab3
|
||||||
|
__divmod_setup = 0x002ae7
|
||||||
|
__divmoddi4_stash = 0x002d34
|
||||||
|
__divmodsi_setup = 0x002ce3
|
||||||
|
__divsi3 = 0x002c95
|
||||||
|
__heap_end = 0x00bf00
|
||||||
|
__heap_start = 0x00a0bc
|
||||||
|
__indirTarget = 0x00a0ba
|
||||||
|
__init_array_end = 0x003409
|
||||||
|
__init_array_start = 0x003409
|
||||||
|
__jsl_indir = 0x0029f0
|
||||||
|
__lshrdi3 = 0x002d81
|
||||||
|
__lshrhi3 = 0x002a78
|
||||||
|
__lshrsi3 = 0x002c06
|
||||||
|
__moddi3 = 0x002f13
|
||||||
|
__modhi3 = 0x002acd
|
||||||
|
__modsi3 = 0x002cbc
|
||||||
|
__muldi3 = 0x002dca
|
||||||
|
__mulhi3 = 0x0029f3
|
||||||
|
__mulsi3 = 0x002b38
|
||||||
|
__negdi_a = 0x002f50
|
||||||
|
__negdi_b = 0x002f6e
|
||||||
|
__retdi = 0x002d51
|
||||||
|
__rodata_end = 0x003409
|
||||||
|
__rodata_start = 0x0033dc
|
||||||
|
__start = 0x001000
|
||||||
|
__text_end = 0x0033dc
|
||||||
|
__text_start = 0x001000
|
||||||
|
__ucmpdi2 = 0x002e25
|
||||||
|
__udivdi3 = 0x002e85
|
||||||
|
__udivhi3 = 0x002a9b
|
||||||
|
__udivmod_core = 0x002b1a
|
||||||
|
__udivmoddi_core = 0x002ea7
|
||||||
|
__udivmodsi_core = 0x002c35
|
||||||
|
__udivsi3 = 0x002c6d
|
||||||
|
__umoddi3 = 0x002e8e
|
||||||
|
__umodhi3 = 0x002aa7
|
||||||
|
__umodsi3 = 0x002c81
|
||||||
|
__umulhisi3 = 0x002a12
|
||||||
|
__umulhisi3_qsq = 0x002fde
|
||||||
|
gBoard = 0x00a04e
|
||||||
|
gChainPath = 0x0033dc
|
||||||
|
gDpBase = 0x00a0b8
|
||||||
|
gDpHandle = 0x00a0b4
|
||||||
|
gTitle = 0x0033f0
|
||||||
|
gUserId = 0x00a0b2
|
||||||
|
gWp = 0x00a000
|
||||||
|
longjmp = 0x002fb4
|
||||||
|
main = 0x0010ba
|
||||||
|
makeMove = 0x0022c4
|
||||||
|
memset = 0x002474
|
||||||
|
pickAiMove = 0x001af5
|
||||||
|
setjmp = 0x002f8c
|
||||||
|
startdesk = 0x002639
|
||||||
BIN
demos/reversi.o
Normal file
BIN
demos/reversi.o
Normal file
Binary file not shown.
BIN
demos/reversi.omf
Normal file
BIN
demos/reversi.omf
Normal file
Binary file not shown.
BIN
demos/reversi.reloc
Normal file
BIN
demos/reversi.reloc
Normal file
Binary file not shown.
108
demos/test.sh
Executable file
108
demos/test.sh
Executable file
|
|
@ -0,0 +1,108 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# test.sh - headless test of a demo OMF. Boots MAME, drives the
|
||||||
|
# Finder to launch the demo, waits for the demo to reach its event
|
||||||
|
# loop, injects a keystroke to wake it, then reads back the
|
||||||
|
# trailing marker at $00:0070 to confirm the demo ran to completion.
|
||||||
|
#
|
||||||
|
# Usage: bash demos/test.sh <demo-name>
|
||||||
|
#
|
||||||
|
# Expected outcome: $0070 reads back as $99.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
|
||||||
|
[ $# -ge 1 ] || { echo "usage: $0 <demo-name>" >&2; exit 2; }
|
||||||
|
BASE="$1"
|
||||||
|
SRC="$SCRIPT_DIR/$BASE.c"
|
||||||
|
OMF="$SCRIPT_DIR/$BASE.omf"
|
||||||
|
|
||||||
|
if [ ! -f "$OMF" ] || [ "$SRC" -nt "$OMF" ]; then
|
||||||
|
bash "$SCRIPT_DIR/build.sh" "$BASE" >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
CADIUS=${CADIUS:-$PROJECT_ROOT/tools/cadius/cadius}
|
||||||
|
SYSDISK=${SYSDISK:-$PROJECT_ROOT/tools/gsos/sys602.po}
|
||||||
|
|
||||||
|
[ -x "$CADIUS" ] || { echo "cadius not found: $CADIUS" >&2; exit 2; }
|
||||||
|
[ -f "$SYSDISK" ] || { echo "sysdisk not found: $SYSDISK" >&2; exit 2; }
|
||||||
|
command -v mame >/dev/null || { echo "mame not in PATH" >&2; exit 2; }
|
||||||
|
|
||||||
|
WORK=$(mktemp -d -t demotest.XXXXXX)
|
||||||
|
trap 'rm -rf "$WORK"' EXIT
|
||||||
|
|
||||||
|
cp "$SYSDISK" "$WORK/disk.po"
|
||||||
|
"$CADIUS" CREATEVOLUME "$WORK/data.po" DATA 800KB >/dev/null
|
||||||
|
cp "$OMF" "$WORK/HELLO#B30000"
|
||||||
|
"$CADIUS" ADDFILE "$WORK/data.po" /DATA "$WORK/HELLO#B30000" >/dev/null
|
||||||
|
|
||||||
|
# Same Finder-navigation timeline as runViaFinder.sh, plus a key
|
||||||
|
# injection at frame 6000 (well after the demo has launched and is
|
||||||
|
# waiting in its event loop), and a memory check at frame 8000.
|
||||||
|
cat > "$WORK/launch.lua" <<'LUA'
|
||||||
|
local cpu = manager.machine.devices[":maincpu"]
|
||||||
|
local mem = cpu.spaces["program"]
|
||||||
|
local nat = manager.machine.natkeyboard
|
||||||
|
local frame = 0
|
||||||
|
local idx = 1
|
||||||
|
|
||||||
|
local function get_field(port, name)
|
||||||
|
local p = manager.machine.ioport.ports[port]
|
||||||
|
if p == nil then return nil end
|
||||||
|
return p.fields[name]
|
||||||
|
end
|
||||||
|
local key_cmd = get_field(":macadb:KEY3", "Command / Open Apple")
|
||||||
|
local function press(f) if f then f:set_value(1) end end
|
||||||
|
local function release(f) if f then f:set_value(0) end end
|
||||||
|
|
||||||
|
local steps = {
|
||||||
|
{3300, function() nat:post("D") end},
|
||||||
|
{3540, function() press(key_cmd) end},
|
||||||
|
{3546, function() nat:post("o") end},
|
||||||
|
{3600, function() release(key_cmd) end},
|
||||||
|
{4200, function() nat:post("H") end},
|
||||||
|
{4500, function() press(key_cmd) end},
|
||||||
|
{4506, function() nat:post("o") end},
|
||||||
|
{4560, function() release(key_cmd) end},
|
||||||
|
{7000, function() nat:post(" ") end}, -- wake the demo's event loop
|
||||||
|
{7500, function() nat:post(" ") end}, -- send a few in case GetNextEvent runs in between
|
||||||
|
{8000, function() nat:post(" ") end},
|
||||||
|
{9000, function()
|
||||||
|
print(string.format("MAME-READ 0x70=%02x", mem:read_u8(0x70)))
|
||||||
|
for a = 0x60, 0x7F do
|
||||||
|
local v = mem:read_u8(a)
|
||||||
|
if v ~= 0 and a ~= 0x70 then
|
||||||
|
print(string.format("MAME-READ 0x%02x=%02x", a, v))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for a = 0x0F80, 0x0F9F do
|
||||||
|
local v = mem:read_u8(a)
|
||||||
|
if v ~= 0 then
|
||||||
|
print(string.format("MAME-READ 0x%04x=%02x", a, v))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
manager.machine:exit()
|
||||||
|
end},
|
||||||
|
}
|
||||||
|
emu.register_frame_done(function()
|
||||||
|
frame = frame + 1
|
||||||
|
while idx <= #steps and frame >= steps[idx][1] do
|
||||||
|
steps[idx][2]()
|
||||||
|
idx = idx + 1
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
LUA
|
||||||
|
|
||||||
|
OUT=$(timeout 200 mame apple2gs -rompath "$PROJECT_ROOT/tools/mame/roms" \
|
||||||
|
-window -nothrottle -sound none \
|
||||||
|
-seconds_to_run 180 -flop3 "$WORK/disk.po" -flop4 "$WORK/data.po" \
|
||||||
|
-autoboot_script "$WORK/launch.lua" </dev/null 2>&1)
|
||||||
|
|
||||||
|
echo "$OUT" | grep "MAME-READ" || true
|
||||||
|
VAL=$(echo "$OUT" | grep "MAME-READ 0x70=" | tail -1 | sed 's/.*=//')
|
||||||
|
if [ "$VAL" = "99" ]; then
|
||||||
|
echo "PASS: $BASE reached end (\$70 = 0x99)"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
echo "FAIL: $BASE marker at \$70 = 0x$VAL (want 0x99)"
|
||||||
|
exit 1
|
||||||
162
docs/USAGE.md
162
docs/USAGE.md
|
|
@ -148,26 +148,164 @@ servers/CI runners.
|
||||||
|
|
||||||
### The bank-switch idiom
|
### The bank-switch idiom
|
||||||
|
|
||||||
Bank 0 (`$00:0000-$00:FFFF`) has the I/O window at `$C000-$CFFF`
|
#### Background — why this is necessary
|
||||||
that interferes with normal data access. The convention is to
|
|
||||||
switch the data bank register (DBR) to bank 2 (`$02:0000`) before
|
The 65816 has two registers that select which bank a memory access
|
||||||
doing any data work:
|
goes to:
|
||||||
|
|
||||||
|
- **PBR** (Program Bank Register) — selects the bank for instruction
|
||||||
|
fetches. Set by `jsl long_addr` and `rtl`.
|
||||||
|
- **DBR** (Data Bank Register) — selects the bank for data accesses
|
||||||
|
like `lda $5000`, `sta $5000`, etc.
|
||||||
|
|
||||||
|
When the IIgs boots, DBR defaults to `$00`. Bank `$00` (the same
|
||||||
|
bank as the language card / IIe-compatibility area) contains the
|
||||||
|
**I/O window at `$C000-$CFFF`**. Any data access to addresses in
|
||||||
|
that range goes to the soft-switches and slot ROMs, NOT to RAM.
|
||||||
|
This is the same I/O hole the Apple IIe has, inherited by the IIgs
|
||||||
|
for backward compatibility.
|
||||||
|
|
||||||
|
Concretely: if your DBR is `$00` and you write to address `$C100`,
|
||||||
|
you're poking the slot-1 ROM enable register — definitely not what
|
||||||
|
you want. Similarly, `$5000` in bank 0 is the language card area
|
||||||
|
and may or may not be RAM depending on soft-switch state.
|
||||||
|
|
||||||
|
Banks `$01`-`$DF` are full 64K RAM banks (`$E0`/`$E1` are aux/main
|
||||||
|
shadow, `$E0`-`$FF` reserved). To do reliable data work, switch
|
||||||
|
the DBR to any of these "normal" banks. **`$02`** is conventional
|
||||||
|
in this codebase because:
|
||||||
|
|
||||||
|
1. `$01:0000-$01:FFFF` overlaps the stack page (`$0100-$01FF` in
|
||||||
|
any bank ends up in the same physical RAM as bank `$00`'s
|
||||||
|
stack page — confusing).
|
||||||
|
2. `$02:0000-$02:FFFF` is the first "clean" bank above the
|
||||||
|
special-purpose banks.
|
||||||
|
3. The smoke-test convention is to write a result word to
|
||||||
|
`$02:5000` so `runInMame.sh` can read it back.
|
||||||
|
|
||||||
|
If your program needs more than 64 KB of data, switch DBR to
|
||||||
|
different banks as needed.
|
||||||
|
|
||||||
|
#### What the assembly does, line by line
|
||||||
|
|
||||||
```c
|
```c
|
||||||
__attribute__((noinline)) void switchToBank2(void) {
|
__attribute__((noinline)) void switchToBank2(void) {
|
||||||
__asm__ volatile (
|
__asm__ volatile (
|
||||||
"sep #0x20\n" // 8-bit accumulator
|
"sep #0x20\n" // (1) Switch A to 8-bit
|
||||||
".byte 0xa9,0x02\n" // lda #2 (force as bytes — llvm-mc bug)
|
".byte 0xa9,0x02\n" // (2) lda #2 (8-bit immediate)
|
||||||
"pha\n"
|
"pha\n" // (3) Push A onto stack (1 byte)
|
||||||
"plb\n" // DBR = 2
|
"plb\n" // (4) Pop into DBR (1 byte from stack)
|
||||||
"rep #0x20\n" // back to 16-bit
|
"rep #0x20\n" // (5) Restore A to 16-bit
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
After `switchToBank2()`, your data lives at `$02:0000` upward.
|
1. **`sep #0x20`** — sets the `M` bit in the status register `P`.
|
||||||
The `runInMame.sh` `--check 0x025000=...` address is `$02:5000`
|
`M=1` makes A behave as 8-bit (and immediate operands become
|
||||||
— accessible via a normal store in bank 2.
|
1 byte). We need this so the next `lda #2` pushes 1 byte
|
||||||
|
(matching what `plb` expects to pop). Calling-convention
|
||||||
|
prologues always run in M=0 (16-bit), so this `sep` is
|
||||||
|
required.
|
||||||
|
|
||||||
|
2. **`.byte 0xa9,0x02`** — raw bytes for `lda #$02`. We hand-encode
|
||||||
|
because llvm-mc can't yet emit an 8-bit immediate `lda #$02`
|
||||||
|
that knows it's 1 byte; the assembler keeps treating it as
|
||||||
|
16-bit. `0xa9` is the LDA-immediate opcode; `0x02` is the
|
||||||
|
1-byte operand. Result: A = `$02` (8-bit).
|
||||||
|
|
||||||
|
3. **`pha`** — pushes A. In M=1 mode, PHA pushes exactly 1 byte
|
||||||
|
(the low half of A). Stack now has `$02` on top.
|
||||||
|
|
||||||
|
4. **`plb`** — pops 1 byte from the stack and stores it in DBR.
|
||||||
|
DBR is now `$02`. All subsequent data accesses go to bank 2.
|
||||||
|
|
||||||
|
5. **`rep #0x20`** — clears the `M` bit. A returns to 16-bit mode,
|
||||||
|
matching the calling-convention contract for the rest of the
|
||||||
|
function.
|
||||||
|
|
||||||
|
The DBR change persists across function returns. Once
|
||||||
|
`switchToBank2()` returns, all data reads/writes in your program
|
||||||
|
target bank 2 — until you switch DBR again.
|
||||||
|
|
||||||
|
#### When you need it
|
||||||
|
|
||||||
|
You need to switch DBR whenever you want to access data at an
|
||||||
|
absolute address `$XXXX` and need it to land in a specific bank.
|
||||||
|
Common cases:
|
||||||
|
|
||||||
|
- **MMIO from the test harness** — `*(volatile uint16 *)0x5000 = x;`
|
||||||
|
Without DBR=2, this would go to bank 0's `$5000` (which is in
|
||||||
|
the language card area). With DBR=2, it goes to `$02:5000`
|
||||||
|
where `runInMame.sh --check 0x025000=...` reads from.
|
||||||
|
- **Anything in `$C000-$CFFF`** — bank 0 has soft-switches here.
|
||||||
|
Bank 2 has plain RAM.
|
||||||
|
- **Global arrays declared at link-time at fixed addresses** —
|
||||||
|
the linker may place them in bank 2 BSS (`--bss-base 0x020000`).
|
||||||
|
Your DBR must match.
|
||||||
|
|
||||||
|
You DON'T need DBR=2 for:
|
||||||
|
|
||||||
|
- **Local variables on the stack** — the stack is always
|
||||||
|
bank-relative-to-DBR-ignored; `lda $4,s` reads from the stack
|
||||||
|
page regardless of DBR.
|
||||||
|
- **Direct-page accesses** — `lda $D0` reads from `$00:00D0`
|
||||||
|
(always bank 0). DP is anchored to bank 0.
|
||||||
|
- **Indirect-long pointers via `[dp],y`** — these include their
|
||||||
|
own bank byte and ignore DBR.
|
||||||
|
- **Function calls** — `jsl` uses PBR + a long destination
|
||||||
|
address. PBR is updated automatically.
|
||||||
|
|
||||||
|
#### Other ways to access non-bank-0 data
|
||||||
|
|
||||||
|
If you only need to write to a single non-bank-0 address, you can
|
||||||
|
emit the store as `STA_Long` (24-bit absolute) which encodes the
|
||||||
|
bank inline:
|
||||||
|
|
||||||
|
```c
|
||||||
|
*(volatile unsigned short *)0x025000 = 42; // becomes sta $025000
|
||||||
|
```
|
||||||
|
|
||||||
|
The W65816 backend recognizes `const-int pointer + integer offset`
|
||||||
|
and lowers to `sta long` if the address has a bank byte. No
|
||||||
|
`switchToBank2()` needed.
|
||||||
|
|
||||||
|
For frequent data work in a bank, switching DBR once and using
|
||||||
|
plain `sta $5000` (2 bytes) is smaller and faster than `sta $025000`
|
||||||
|
(4 bytes) per access.
|
||||||
|
|
||||||
|
#### Caveats
|
||||||
|
|
||||||
|
- **Save/restore is your problem.** `switchToBank2()` never
|
||||||
|
restores DBR. If your caller expected DBR=0, you've broken its
|
||||||
|
expectation. For long-running programs, that's usually fine
|
||||||
|
(you just set DBR=2 once and stay there). For toolbox calls, GS/OS
|
||||||
|
might assume DBR=0 — check the call's documentation.
|
||||||
|
- **The stack is in bank 0 regardless.** Don't try to put the
|
||||||
|
stack elsewhere; the 65816's stack-relative addressing modes
|
||||||
|
ignore DBR.
|
||||||
|
- **In M=1 mode, INTERRUPTS may behave differently.** The `sep`
|
||||||
|
affects A's width but not the bank-switching machinery itself.
|
||||||
|
Keep the sep/rep window short.
|
||||||
|
- **PBR vs DBR** are independent. Code execution stays where it
|
||||||
|
was; only data accesses change.
|
||||||
|
|
||||||
|
#### How `runInMame.sh --check 0x025000=...` works
|
||||||
|
|
||||||
|
The check address `0x025000` is a 24-bit address: bank `$02`,
|
||||||
|
offset `$5000`. The MAME Lua runner reads this byte (and the next
|
||||||
|
byte if you specify a 2-byte value) directly from physical RAM,
|
||||||
|
bypassing DBR entirely. So the convention is:
|
||||||
|
|
||||||
|
1. Your program switches DBR to bank 2.
|
||||||
|
2. Your program writes its result to `*(volatile X *)0x5000`,
|
||||||
|
which becomes `sta $5000` — landing in bank 2 because of DBR.
|
||||||
|
3. MAME reads bank 2's `$5000` via the absolute 24-bit address.
|
||||||
|
4. The runner compares to your expected value.
|
||||||
|
|
||||||
|
If you forget `switchToBank2()`, your store goes to the language
|
||||||
|
card area (bank 0's `$5000`), MAME's check reads bank 2's
|
||||||
|
unchanged `$5000` (likely `$00` or whatever was there), and the
|
||||||
|
test fails.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,9 @@ cc "$SRC/math.c"
|
||||||
cc "$SRC/softFloat.c"
|
cc "$SRC/softFloat.c"
|
||||||
cc "$SRC/libcxxabi.c"
|
cc "$SRC/libcxxabi.c"
|
||||||
cc "$SRC/libcxxabiSjlj.c"
|
cc "$SRC/libcxxabiSjlj.c"
|
||||||
|
cc "$SRC/desktop.c"
|
||||||
asm "$SRC/iigsGsos.s"
|
asm "$SRC/iigsGsos.s"
|
||||||
|
asm "$SRC/iigsToolbox.s"
|
||||||
# softDouble.c builds at -O2. dpack stays noinline (basic regalloc
|
# softDouble.c builds at -O2. dpack stays noinline (basic regalloc
|
||||||
# overflows when dpack inlines into __adddf3/__muldf3). dclass MUST
|
# overflows when dpack inlines into __adddf3/__muldf3). dclass MUST
|
||||||
# stay inline (its pointer-arg writes from a noinline boundary would
|
# stay inline (its pointer-arg writes from a noinline boundary would
|
||||||
|
|
|
||||||
56
runtime/include/iigs/desktop.h
Normal file
56
runtime/include/iigs/desktop.h
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
// iigs/desktop.h - Full Window Manager desktop startup helper.
|
||||||
|
//
|
||||||
|
// Equivalent to ORCA-C's `startdesk` library function: brings up the
|
||||||
|
// stack of toolsets needed to open titled windows, draw menus,
|
||||||
|
// dispatch events, etc. Use this before `NewWindow` for any titled-
|
||||||
|
// window application. See demos/orcaFrame.c for a minimal usage
|
||||||
|
// example.
|
||||||
|
//
|
||||||
|
// On success, `desktopUserId()` returns the Memory Manager userID
|
||||||
|
// assigned to this application. Pass it to other toolsets that need
|
||||||
|
// a userID (e.g. ID arg to `DisposeAll`).
|
||||||
|
//
|
||||||
|
// startdesk() takes a screen-width hint:
|
||||||
|
// 320 - SHR 320 mode (16 colors)
|
||||||
|
// 640 - SHR 640 mode (4 colors)
|
||||||
|
// This is passed to QDStartUp's masterSCB and to EMStartUp's
|
||||||
|
// xMax/yMax. Other dimensions are derived.
|
||||||
|
|
||||||
|
#ifndef IIGS_DESKTOP_H
|
||||||
|
#define IIGS_DESKTOP_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Returns the user-ID assigned by MMStartUp. Pass to enddesk().
|
||||||
|
unsigned short startdesk(unsigned short screenWidth);
|
||||||
|
|
||||||
|
// Tears down the desktop environment in reverse-startup order.
|
||||||
|
void enddesk(unsigned short userId);
|
||||||
|
|
||||||
|
// Read-only accessor — same value startdesk() returned.
|
||||||
|
unsigned short desktopUserId(void);
|
||||||
|
|
||||||
|
// Read-only accessor — base of the per-toolset 0x700-byte DP block
|
||||||
|
// startdesk() allocated. Slot $300 (256 bytes) is reserved for the
|
||||||
|
// Menu Manager: pass `desktopDpBase() + 0x300` to MenuStartUp.
|
||||||
|
unsigned short desktopDpBase(void);
|
||||||
|
|
||||||
|
// Paint a clean Finder-style backdrop directly into SHR: white menu
|
||||||
|
// bar (rows 0..12), 1-pixel black separator (row 13), white desktop
|
||||||
|
// (rows 14..199). Bypasses the WM's dithered desktop fill (which
|
||||||
|
// MAME's NTSC chroma simulator renders as colored noise). Call
|
||||||
|
// AFTER startdesk() and BEFORE NewWindow.
|
||||||
|
void paintDesktopBackdrop(void);
|
||||||
|
|
||||||
|
// Paint menu bar titles via QD's DrawString. Each entry is a
|
||||||
|
// pascal-string pointer (byte length + chars). Use as a manual
|
||||||
|
// substitute for DrawMenuBar(), which hangs in our environment.
|
||||||
|
void paintMenuBarTitles(const unsigned char *const *pascalTitles, unsigned short count);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -71,6 +71,8 @@ __start:
|
||||||
phk
|
phk
|
||||||
pla ; A's low byte = current PBR
|
pla ; A's low byte = current PBR
|
||||||
sta 0xbe ; persistent data bank
|
sta 0xbe ; persistent data bank
|
||||||
|
stz 0xbf ; pad: `lda 0xbe` in 16-bit M loads $00PBR
|
||||||
|
; — used by codegen for &symbol bank halves
|
||||||
rep #0x20
|
rep #0x20
|
||||||
|
|
||||||
; Zero BSS. Up to 4 segments — linker emits __bss_seg{0..3}_lo16
|
; Zero BSS. Up to 4 segments — linker emits __bss_seg{0..3}_lo16
|
||||||
|
|
@ -202,6 +204,23 @@ __start:
|
||||||
; sequence in a controlled context. time()/clock() check an
|
; sequence in a controlled context. time()/clock() check an
|
||||||
; in-process flag and return 0 if init hasn't been done.
|
; in-process flag and return 0 if init hasn't been done.
|
||||||
|
|
||||||
|
; Set DBR to the BSS bank before calling main. Without this, the
|
||||||
|
; user has to manually switch the data bank register (with a
|
||||||
|
; `pha;plb` inline-asm idiom) before doing absolute data
|
||||||
|
; accesses. Calypsi's "small data model" assumes DBR is
|
||||||
|
; pre-set; we now follow the same convention.
|
||||||
|
;
|
||||||
|
; Linker emits __bss_seg0_bank as the bank byte of the first
|
||||||
|
; BSS segment (typically 2 with the default --bss-base 0x020000).
|
||||||
|
; Programs that need bank-0 access (e.g., for $C0xx soft
|
||||||
|
; switches) can use STA_Long or temporarily switch DBR back.
|
||||||
|
sep #0x20
|
||||||
|
.byte 0xA9 ; lda #imm8 (1 byte) — llvm-mc can't
|
||||||
|
.byte __bss_seg0_bank ; reliably encode this with a symbol;
|
||||||
|
pha ; spell it out to keep the bytes right.
|
||||||
|
plb
|
||||||
|
rep #0x20
|
||||||
|
|
||||||
; Call main. Standard W65816 ABI: i16 first arg in A; we pass
|
; Call main. Standard W65816 ABI: i16 first arg in A; we pass
|
||||||
; nothing. After return, A holds the exit code.
|
; nothing. After return, A holds the exit code.
|
||||||
jsl main
|
jsl main
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,18 @@ __start:
|
||||||
; wrong bank without this. PHK + PLB copies PBR into DBR.
|
; wrong bank without this. PHK + PLB copies PBR into DBR.
|
||||||
phk
|
phk
|
||||||
plb
|
plb
|
||||||
|
; Diagnostic: stash a marker at $00:007F via `sta long` (bank-
|
||||||
|
; explicit, immune to DBR uncertainty) immediately on entry.
|
||||||
|
; Runtime probes use this to detect whether the Loader actually
|
||||||
|
; reached our code or silently rejected the OMF earlier.
|
||||||
|
; The assembler doesn't track SEP/REP state, so the LDA #imm
|
||||||
|
; needs explicit `.byte` form: the standard `lda #$7F` would
|
||||||
|
; assemble as 3 bytes (16-bit imm) and the trailing $00 would
|
||||||
|
; execute as BRK at runtime once M=8.
|
||||||
|
sep #0x20
|
||||||
|
.byte 0xa9, 0x7f ; lda #$7F (8-bit imm)
|
||||||
|
.byte 0x8f, 0x7f, 0x00, 0x00 ; sta long $00:007F
|
||||||
|
rep #0x20
|
||||||
|
|
||||||
; Set DP=0. The C compiler assumes DP=0 for all `sta dp` and
|
; Set DP=0. The C compiler assumes DP=0 for all `sta dp` and
|
||||||
; `[dp],y`-style accesses; GS/OS hands us a Memory-Manager-
|
; `[dp],y`-style accesses; GS/OS hands us a Memory-Manager-
|
||||||
|
|
@ -51,6 +63,18 @@ __start:
|
||||||
phk
|
phk
|
||||||
pla
|
pla
|
||||||
sta 0xbe
|
sta 0xbe
|
||||||
|
stz 0xbf ; pad byte so `lda 0xbe` in 16-bit M reads $00PBR
|
||||||
|
; (codegen uses this as the bank-half of `&symbol`
|
||||||
|
; 32-bit pointers — see W65816AsmPrinter
|
||||||
|
; LDAi16imm_bank expansion)
|
||||||
|
rep #0x20
|
||||||
|
|
||||||
|
; --- Diagnostic markers between crt0 phases. Bank-explicit
|
||||||
|
; `sta long` to $00:007E so they're visible from a host probe
|
||||||
|
; regardless of DBR/PBR.
|
||||||
|
sep #0x20
|
||||||
|
.byte 0xa9, 0x7e ; lda #$7E
|
||||||
|
.byte 0x8f, 0x7e, 0x00, 0x00 ; sta long $00:007E (post-DP)
|
||||||
rep #0x20
|
rep #0x20
|
||||||
|
|
||||||
; BSS zero-init. With DBR=our bank, `stz abs,X` writes to
|
; BSS zero-init. With DBR=our bank, `stz abs,X` writes to
|
||||||
|
|
@ -67,6 +91,10 @@ __start:
|
||||||
inx
|
inx
|
||||||
bra .Lbss_loop
|
bra .Lbss_loop
|
||||||
.Lbss_done:
|
.Lbss_done:
|
||||||
|
sep #0x20
|
||||||
|
.byte 0xa9, 0x7d ; lda #$7D
|
||||||
|
.byte 0x8f, 0x7d, 0x00, 0x00 ; sta long $00:007D (post-BSS)
|
||||||
|
rep #0x20
|
||||||
|
|
||||||
; Walk .init_array (C++ ctors).
|
; Walk .init_array (C++ ctors).
|
||||||
;
|
;
|
||||||
|
|
@ -99,6 +127,12 @@ __start:
|
||||||
bra .Linit_loop
|
bra .Linit_loop
|
||||||
.Linit_done:
|
.Linit_done:
|
||||||
|
|
||||||
|
; Marker: about to JSL main.
|
||||||
|
sep #0x20
|
||||||
|
.byte 0xa9, 0x7c ; lda #$7C
|
||||||
|
.byte 0x8f, 0x7c, 0x00, 0x00 ; sta long $00:007C (about to call main)
|
||||||
|
rep #0x20
|
||||||
|
|
||||||
; Call main. Standard W65816 C ABI: arg0 in A; we pass none.
|
; Call main. Standard W65816 C ABI: arg0 in A; we pass none.
|
||||||
rep #0x30
|
rep #0x30
|
||||||
jsl main
|
jsl main
|
||||||
|
|
|
||||||
168
runtime/src/desktop.c
Normal file
168
runtime/src/desktop.c
Normal file
|
|
@ -0,0 +1,168 @@
|
||||||
|
// desktop.c - startdesk()/enddesk() — ORCA-C-style minimal desktop init.
|
||||||
|
//
|
||||||
|
// Brings up the toolset chain a full desktop app needs:
|
||||||
|
// Memory + DP allocation, MiscTools, QD, EM, Scheduler, Sound, ADB,
|
||||||
|
// SANE, IntMath, Text, Window, Font, Control, LineEdit, Dialog,
|
||||||
|
// Scrap. Menu Manager startup is omitted — MenuStartUp hangs in
|
||||||
|
// the current environment (likely a tool-init-order dependency we
|
||||||
|
// haven't pinned down). Demos that need a visible menu bar paint
|
||||||
|
// it manually into SHR rows 0..12.
|
||||||
|
//
|
||||||
|
// Palette: all 16 palettes set to (black, white, black, white). In
|
||||||
|
// 640 mode that maps to clean Finder-style B/W instead of NTSC chroma
|
||||||
|
// noise for the dithered patterns the WM uses.
|
||||||
|
|
||||||
|
#include "iigs/desktop.h"
|
||||||
|
#include "iigs/toolbox.h"
|
||||||
|
|
||||||
|
static unsigned short gUserId = 0;
|
||||||
|
static void *gDpHandle = (void *)0;
|
||||||
|
static unsigned short gDpBase = 0;
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned short blockAddrLo(void *handle) {
|
||||||
|
return (unsigned short)(unsigned long)*(void **)handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned short startdesk(unsigned short screenWidth) {
|
||||||
|
gUserId = MMStartUp();
|
||||||
|
// QD needs 512 bytes ($200) — its own DP at +$000 plus the cursor
|
||||||
|
// manager's DP at +$100 (InitCursor does `tdc; clc; adc #$100;
|
||||||
|
// tcd` to find its globals). ROM Source Code/Bank FE/cursor.asm
|
||||||
|
// confirms cursor uses QD's DP+$100. Layout below allocates 0x800
|
||||||
|
// total so QD/Cursor have $000..$1FF, then EM/FM/Menu/Ctl/LE/Dlg
|
||||||
|
// each get $100.
|
||||||
|
// $000 QD | $100 Cursor | $200 EM | $300 FM | $400 Menu |
|
||||||
|
// $500 Ctl | $600 LE | $700 Dialog.
|
||||||
|
gDpHandle = NewHandle(0x800UL, gUserId, 0xC015, (void *)0);
|
||||||
|
unsigned short dp = blockAddrLo(gDpHandle);
|
||||||
|
gDpBase = dp;
|
||||||
|
|
||||||
|
MTStartUp();
|
||||||
|
unsigned short masterSCB = (screenWidth == 640) ? 0x90 : 0x10;
|
||||||
|
QDStartUp(dp, masterSCB, screenWidth, gUserId);
|
||||||
|
EMStartUp((unsigned short)(dp + 0x200), 20, 0, 0,
|
||||||
|
(short)(screenWidth - 1), 199, gUserId);
|
||||||
|
SchStartUp();
|
||||||
|
SoundStartUp(gUserId);
|
||||||
|
ADBStartUp();
|
||||||
|
SANEStartUp(gUserId);
|
||||||
|
IMStartUp();
|
||||||
|
TextStartUp();
|
||||||
|
LoadOneTool(0x0E, 0x0301);
|
||||||
|
WindStartUp(gUserId);
|
||||||
|
LoadOneTool(0x1B, 0x0301);
|
||||||
|
FMStartUp(gUserId, (unsigned short)(dp + 0x300));
|
||||||
|
LoadOneTool(0x10, 0x0301);
|
||||||
|
CtlStartUp(gUserId, (unsigned short)(dp + 0x500));
|
||||||
|
LoadOneTool(0x14, 0x0301);
|
||||||
|
LEStartUp(gUserId, (unsigned short)(dp + 0x600));
|
||||||
|
LoadOneTool(0x15, 0x0301);
|
||||||
|
DialogStartUp(gUserId);
|
||||||
|
LoadOneTool(0x16, 0x0301);
|
||||||
|
ScrapStartUp();
|
||||||
|
|
||||||
|
// InitCursor allocates the cursor save buffer (1024-byte handle
|
||||||
|
// stored at cursor mgr DP $B4). Without it, the FIRST QD call
|
||||||
|
// that internally triggers cursor shield/unshield hangs in ROM's
|
||||||
|
// iUndrawCursor walking through a NULL pointer. This was the
|
||||||
|
// *real* cause of the "DrawMenuBar hang" investigation —
|
||||||
|
// DrawMenuBar's _FillRect call shields the cursor, and iUndraw
|
||||||
|
// loops forever copying garbage from $00:0000+Y into SHR.
|
||||||
|
// Confirmed via ROM Source Code/Bank FE/cursor.asm — see PC
|
||||||
|
// $FE:551E during hang matched iUndrawCursor:FinishLoop.
|
||||||
|
InitCursor();
|
||||||
|
|
||||||
|
LoadOneTool(0x0F, 0x0301);
|
||||||
|
MenuStartUp(gUserId, (unsigned short)(dp + 0x400));
|
||||||
|
|
||||||
|
// Force all 16 palettes to a Finder-style B/W spread that works
|
||||||
|
// in 640 mode. 640 mode rotates through palette quadrants
|
||||||
|
// (8..11, 12..15, 0..3, 4..7) across pixel positions, so SetForeColor(1)
|
||||||
|
// only renders solid white if pal[1] == pal[5] == pal[9] == pal[13].
|
||||||
|
// Even (0,2,4,6,8,10,12,14) → black, odd (1,3,5,7,9,11,13,15) → white.
|
||||||
|
for (unsigned short p = 0; p < 16; p++) {
|
||||||
|
volatile unsigned short *pal =
|
||||||
|
(volatile unsigned short *)(0xE19E00UL + (unsigned long)p * 32UL);
|
||||||
|
for (unsigned short k = 0; k < 16; k++) {
|
||||||
|
pal[k] = (k & 1) ? 0x0FFF : 0x0000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return gUserId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Paint menu bar text via QD's DrawString. Each title is a
|
||||||
|
// pascal-counted string (length-prefixed); titles are placed
|
||||||
|
// left-to-right at y=10, starting at x=4 with kSpacing between
|
||||||
|
// titles. Use this in place of DrawMenuBar() (which hangs in our
|
||||||
|
// current toolset env). Caller is responsible for filling the bar
|
||||||
|
// background first (paintDesktopBackdrop does this).
|
||||||
|
void paintMenuBarTitles(const unsigned char *const *pascalTitles, unsigned short count) {
|
||||||
|
SetForeColor(0);
|
||||||
|
SetBackColor(15);
|
||||||
|
unsigned short x = 4;
|
||||||
|
for (unsigned short i = 0; i < count; i++) {
|
||||||
|
MoveTo((short)x, 10);
|
||||||
|
const unsigned char *s = pascalTitles[i];
|
||||||
|
DrawString((void *)s);
|
||||||
|
x = (unsigned short)(x + (unsigned short)s[0] * 8U + 16U);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Paint a Finder-style backdrop directly into SHR: white menu bar
|
||||||
|
// (rows 0..12), 1-pixel black separator (row 13), white desktop
|
||||||
|
// (rows 14..199). Bypasses the WM's dithered desktop fill that
|
||||||
|
// MAME's NTSC chroma simulator renders as colored noise. Useful
|
||||||
|
// for ORCA-style demos that want the WM's chrome without the
|
||||||
|
// chroma fringing.
|
||||||
|
void paintDesktopBackdrop(void) {
|
||||||
|
__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");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void enddesk(unsigned short userId) {
|
||||||
|
WindShutDown();
|
||||||
|
FMShutDown();
|
||||||
|
TextShutDown();
|
||||||
|
ADBShutDown();
|
||||||
|
SchShutDown();
|
||||||
|
EMShutDown();
|
||||||
|
QDShutDown();
|
||||||
|
DisposeHandle(gDpHandle);
|
||||||
|
MMShutDown(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned short desktopUserId(void) {
|
||||||
|
return gUserId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned short desktopDpBase(void) {
|
||||||
|
return gDpBase;
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,12 @@
|
||||||
; iigsGsos.s — GS/OS class-1 dispatch wrappers.
|
; iigsGsos.s — GS/OS class-1 dispatch wrappers.
|
||||||
;
|
;
|
||||||
|
; PUSH ORDER MATTERS. Earlier versions used PHA-then-PEA-0, which put
|
||||||
|
; the bank byte at offset position in the stack layout - broken under
|
||||||
|
; real GS/OS 6.0.2 (observed as a JSL $E100A8 hang). The correct order
|
||||||
|
; matches ORCA-C's PushLong macro: PEA high FIRST, then PHA low. After
|
||||||
|
; PEA 0 + PHA, the 4 bytes at (S+1..S+4) are (off_lo, off_hi, bank, pad)
|
||||||
|
; in little-endian order, which is what the dispatcher reads as a LONG.
|
||||||
|
;
|
||||||
; Each wrapper takes a 16-bit pointer to a class-1 parm block in A
|
; Each wrapper takes a 16-bit pointer to a class-1 parm block in A
|
||||||
; (the C ABI). The GS/OS convention is:
|
; (the C ABI). The GS/OS convention is:
|
||||||
; PHA / PEA 0 ; push 32-bit parm-block pointer
|
; PHA / PEA 0 ; push 32-bit parm-block pointer
|
||||||
|
|
@ -36,8 +43,8 @@
|
||||||
.globl gsosGetMark
|
.globl gsosGetMark
|
||||||
|
|
||||||
gsosOpen:
|
gsosOpen:
|
||||||
pha
|
|
||||||
pea 0
|
pea 0
|
||||||
|
pha
|
||||||
ldx #0x2010
|
ldx #0x2010
|
||||||
jsl 0xe100a8
|
jsl 0xe100a8
|
||||||
sta 0xe4 ; stash status (A) in DP scratch
|
sta 0xe4 ; stash status (A) in DP scratch
|
||||||
|
|
@ -49,8 +56,8 @@ gsosOpen:
|
||||||
rtl
|
rtl
|
||||||
|
|
||||||
gsosRead:
|
gsosRead:
|
||||||
pha
|
|
||||||
pea 0
|
pea 0
|
||||||
|
pha
|
||||||
ldx #0x2012
|
ldx #0x2012
|
||||||
jsl 0xe100a8
|
jsl 0xe100a8
|
||||||
sta 0xe4
|
sta 0xe4
|
||||||
|
|
@ -62,8 +69,8 @@ gsosRead:
|
||||||
rtl
|
rtl
|
||||||
|
|
||||||
gsosWrite:
|
gsosWrite:
|
||||||
pha
|
|
||||||
pea 0
|
pea 0
|
||||||
|
pha
|
||||||
ldx #0x2013
|
ldx #0x2013
|
||||||
jsl 0xe100a8
|
jsl 0xe100a8
|
||||||
sta 0xe4
|
sta 0xe4
|
||||||
|
|
@ -75,8 +82,8 @@ gsosWrite:
|
||||||
rtl
|
rtl
|
||||||
|
|
||||||
gsosClose:
|
gsosClose:
|
||||||
pha
|
|
||||||
pea 0
|
pea 0
|
||||||
|
pha
|
||||||
ldx #0x2014
|
ldx #0x2014
|
||||||
jsl 0xe100a8
|
jsl 0xe100a8
|
||||||
sta 0xe4
|
sta 0xe4
|
||||||
|
|
@ -88,8 +95,8 @@ gsosClose:
|
||||||
rtl
|
rtl
|
||||||
|
|
||||||
gsosGetEOF:
|
gsosGetEOF:
|
||||||
pha
|
|
||||||
pea 0
|
pea 0
|
||||||
|
pha
|
||||||
ldx #0x2019
|
ldx #0x2019
|
||||||
jsl 0xe100a8
|
jsl 0xe100a8
|
||||||
sta 0xe4
|
sta 0xe4
|
||||||
|
|
@ -101,8 +108,8 @@ gsosGetEOF:
|
||||||
rtl
|
rtl
|
||||||
|
|
||||||
gsosSetEOF:
|
gsosSetEOF:
|
||||||
pha
|
|
||||||
pea 0
|
pea 0
|
||||||
|
pha
|
||||||
ldx #0x2018
|
ldx #0x2018
|
||||||
jsl 0xe100a8
|
jsl 0xe100a8
|
||||||
sta 0xe4
|
sta 0xe4
|
||||||
|
|
@ -114,8 +121,8 @@ gsosSetEOF:
|
||||||
rtl
|
rtl
|
||||||
|
|
||||||
gsosSetMark:
|
gsosSetMark:
|
||||||
pha
|
|
||||||
pea 0
|
pea 0
|
||||||
|
pha
|
||||||
ldx #0x2016
|
ldx #0x2016
|
||||||
jsl 0xe100a8
|
jsl 0xe100a8
|
||||||
sta 0xe4
|
sta 0xe4
|
||||||
|
|
@ -127,8 +134,8 @@ gsosSetMark:
|
||||||
rtl
|
rtl
|
||||||
|
|
||||||
gsosGetMark:
|
gsosGetMark:
|
||||||
pha
|
|
||||||
pea 0
|
pea 0
|
||||||
|
pha
|
||||||
ldx #0x2017
|
ldx #0x2017
|
||||||
jsl 0xe100a8
|
jsl 0xe100a8
|
||||||
sta 0xe4
|
sta 0xe4
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
; Minimal GS/OS dispatcher stub at $E100A8. Native, M=0, X=0.
|
; Minimal GS/OS dispatcher stub at $E100A8. Native, M=0, X=0.
|
||||||
; Stack at entry: S+1=PCL, S+2=PCH, S+3=PBR, S+4..5=bank (=0),
|
; Stack at entry (after caller's PEA 0 + PHA + JSL):
|
||||||
; S+9=parm ptr low 16, S+10=high. We only use the low 16 (bank-0
|
; S+1=PCL, S+2=PCH, S+3=PBR, S+4=ptr_lo, S+5=ptr_hi,
|
||||||
; parm blocks). Writes $42 to *parm and returns A=0.
|
; S+6=bank (=0), S+7=pad (=0).
|
||||||
|
; After our PHP + PHA: parm pointer is at (S+7, S+8); bank at (S+9).
|
||||||
|
; We only use the low 16 (bank-0 parm blocks). Writes $42 to *parm
|
||||||
|
; and returns A=0.
|
||||||
.text
|
.text
|
||||||
php ; save P
|
php ; save P
|
||||||
pha ; save A (16-bit)
|
pha ; save A (16-bit)
|
||||||
lda 9, s ; A = parm ptr 16
|
lda 7, s ; A = parm ptr offset (16-bit)
|
||||||
sta 0xe4 ; DP $E4..$E5
|
sta 0xe4 ; DP $E4..$E5
|
||||||
ldy #0 ; X=0 here, so 3-byte encoding
|
ldy #0 ; X=0 here, so 3-byte encoding
|
||||||
sep #0x20 ; M=8 for the 1-byte store
|
sep #0x20 ; M=8 for the 1-byte store
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -28,6 +28,7 @@ typedef struct {
|
||||||
u16 pCount;
|
u16 pCount;
|
||||||
u16 refNum;
|
u16 refNum;
|
||||||
void *pathname;
|
void *pathname;
|
||||||
|
u16 requestAccess;
|
||||||
} __GsosOpenParm;
|
} __GsosOpenParm;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u16 pCount;
|
u16 pCount;
|
||||||
|
|
@ -229,13 +230,27 @@ int puts(const char *s) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- input stubs ----
|
// ---- input ----
|
||||||
//
|
//
|
||||||
// getchar reads from the keyboard; real input would route through
|
// getchar polls the IIgs hardware keyboard register at $C000. Bit 7
|
||||||
// the IIgs Event Manager. Returns -1 (EOF) for now. fgetc/fgets/
|
// is the "key ready" strobe; bits 0..6 are the ASCII code. Reading
|
||||||
// ungetc are defined further down alongside the FILE-table-backed
|
// $C010 clears the strobe so the next keypress can be detected. This
|
||||||
// fopen/fread/etc.
|
// blocks until a key is pressed and returns the (7-bit) ASCII value.
|
||||||
int getchar(void) { return -1; /* EOF */ }
|
// It works in any execution context (raw boot, ProDOS-16, GS/OS app)
|
||||||
|
// because $C000 is hardware I/O, not toolbox-mediated.
|
||||||
|
//
|
||||||
|
// Callers wanting non-blocking input or Event Manager integration
|
||||||
|
// should call ReadCh/GetNextEvent directly via iigs/toolbox.h.
|
||||||
|
int getchar(void) {
|
||||||
|
volatile unsigned char *kbd = (volatile unsigned char *)0xC000;
|
||||||
|
volatile unsigned char *strb = (volatile unsigned char *)0xC010;
|
||||||
|
while (((*kbd) & 0x80) == 0) {
|
||||||
|
// Spin until a key is ready. No yield — single-threaded.
|
||||||
|
}
|
||||||
|
int c = (*kbd) & 0x7F;
|
||||||
|
(void)*strb; // clear strobe
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
// ---- minimal printf ----
|
// ---- minimal printf ----
|
||||||
|
|
||||||
|
|
@ -1288,7 +1303,18 @@ FILE *fopen(const char *path, const char *mode) {
|
||||||
// → NULL.
|
// → NULL.
|
||||||
if (!__gsosAvailable()) return (FILE *)0;
|
if (!__gsosAvailable()) return (FILE *)0;
|
||||||
if (__buildGSString(path) < 0) return (FILE *)0;
|
if (__buildGSString(path) < 0) return (FILE *)0;
|
||||||
__GsosOpenParm op = { 2, 0, &__gsosPathBuf };
|
// pCount=3 covers refNum + pathname + requestAccess. GS/OS 6.0.2
|
||||||
|
// Open ($2010) requires requestAccess to be non-zero for any actual
|
||||||
|
// open; passing only pCount=2 (refNum + pathname) leaves the access
|
||||||
|
// word indeterminate and the Open silently fails with a "bad access"
|
||||||
|
// status. requestAccess values: $0001 = read, $0002 = write,
|
||||||
|
// $0003 = read+write. We pick read or read+write based on the
|
||||||
|
// mode string. The remaining optional params (resourceNumber,
|
||||||
|
// accessMode, fileType, auxType, storageType, createDate, modDate,
|
||||||
|
// optionList) are left out — GS/OS treats their absence as
|
||||||
|
// "default values".
|
||||||
|
u16 access = (u16)(wantWrite ? (wantRead ? 3 : 2) : 1);
|
||||||
|
__GsosOpenParm op = { 3, 0, &__gsosPathBuf, access };
|
||||||
if (gsosOpen(&op) != 0) return (FILE *)0;
|
if (gsosOpen(&op) != 0) return (FILE *)0;
|
||||||
|
|
||||||
f->kind = FILE_KIND_GSOS;
|
f->kind = FILE_KIND_GSOS;
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,41 @@ __mulhi3:
|
||||||
; --------------------------------------------------------------------
|
; --------------------------------------------------------------------
|
||||||
.globl __umulhisi3
|
.globl __umulhisi3
|
||||||
__umulhisi3:
|
__umulhisi3:
|
||||||
sta 0xe0 ; multiplier in $e0/$e1
|
; Fast path: if both args fit in 8 bits, use a quarter-square
|
||||||
|
; table for 8x8 → 16 (result hi half is always 0). Identity:
|
||||||
|
; a*b = T[a+b] - T[|a-b|] where T[k] = floor(k²/4)
|
||||||
|
; 511-entry, 2-byte table = 1022 bytes ROM. Fast path is ~55
|
||||||
|
; cyc vs ~150 cyc for the shift-and-add fallback at i ~ 50.
|
||||||
|
; Hot in `i*i` patterns where i is a loop counter ≤ 255.
|
||||||
|
sta 0xe0 ; save arg0
|
||||||
|
ora 0x4, s ; OR with arg1
|
||||||
|
and #0xff00 ; isolate hi bytes
|
||||||
|
bne .Lumulhisi_slow ; if either hi byte nonzero, fallback
|
||||||
|
; Both args fit in 8 bits — quarter-square path.
|
||||||
|
lda 0xe0 ; arg0
|
||||||
|
clc
|
||||||
|
adc 0x4, s ; A = a + b
|
||||||
|
asl a ; A = 2*(a+b) — word index
|
||||||
|
tax
|
||||||
|
lda __umulhisi3_qsq, x ; T[a+b]
|
||||||
|
sta 0xe2 ; stash
|
||||||
|
lda 0xe0 ; arg0
|
||||||
|
sec
|
||||||
|
sbc 0x4, s ; A = a - b
|
||||||
|
bpl .Lumulhisi_qsq_pos
|
||||||
|
; A negative; negate to get |a-b|.
|
||||||
|
eor #0xffff
|
||||||
|
inc a
|
||||||
|
.Lumulhisi_qsq_pos:
|
||||||
|
asl a ; A = 2*|a-b|
|
||||||
|
tax
|
||||||
|
lda 0xe2 ; T[a+b]
|
||||||
|
sec
|
||||||
|
sbc __umulhisi3_qsq, x ; T[a+b] - T[|a-b|]
|
||||||
|
ldx #0 ; result hi half = 0
|
||||||
|
rtl
|
||||||
|
.Lumulhisi_slow:
|
||||||
|
; Multiplier already at $e0 from the fast-path check above.
|
||||||
lda 0x4, s
|
lda 0x4, s
|
||||||
sta 0xe2 ; multiplicand lo in $e2/$e3
|
sta 0xe2 ; multiplicand lo in $e2/$e3
|
||||||
stz 0xe4 ; multiplicand hi (initially 0) in $e4/$e5
|
stz 0xe4 ; multiplicand hi (initially 0) in $e4/$e5
|
||||||
|
|
@ -369,6 +403,29 @@ __mulsi3:
|
||||||
; Clear running product at $e8/$ea.
|
; Clear running product at $e8/$ea.
|
||||||
stz 0xe8
|
stz 0xe8
|
||||||
stz 0xea
|
stz 0xea
|
||||||
|
; Asymmetric-size swap: the loop iterates based on the multiplier's
|
||||||
|
; bit width. If a is large (a_hi != 0) but b is small (b_hi == 0),
|
||||||
|
; swap so the small one becomes the multiplier — the early-exit
|
||||||
|
; check (lda 0xe0; beq done) then fires sooner. Saves a lot for
|
||||||
|
; djb2-style `h * 33` patterns where h grows but the constant
|
||||||
|
; multiplier is small. Cost: ~12 cyc unconditional check; benefit:
|
||||||
|
; ~10 cyc per saved iter × ~10 iters = 100 cyc.
|
||||||
|
lda 0xe2
|
||||||
|
beq .Lmulsi_no_swap ; a_hi == 0, no need to swap (or already covered by u16 path below)
|
||||||
|
lda 0xe6
|
||||||
|
bne .Lmulsi_no_swap ; b_hi != 0, both large, no benefit
|
||||||
|
; Swap (a_lo, a_hi) ↔ (b_lo, b_hi). Both are at DP; XOR-swap or
|
||||||
|
; load/store; we use load/store with A scratch since the values are
|
||||||
|
; 16 bits each.
|
||||||
|
lda 0xe0
|
||||||
|
ldx 0xe4
|
||||||
|
stx 0xe0
|
||||||
|
sta 0xe4
|
||||||
|
lda 0xe2
|
||||||
|
ldx 0xe6
|
||||||
|
stx 0xe2
|
||||||
|
sta 0xe6
|
||||||
|
.Lmulsi_no_swap:
|
||||||
; Fast path: if multiplier's high half ($e2) is 0, we only
|
; Fast path: if multiplier's high half ($e2) is 0, we only
|
||||||
; need 16 loop iterations AND we can drop the multiplier-hi
|
; need 16 loop iterations AND we can drop the multiplier-hi
|
||||||
; shift step entirely (lsr $e2 + bcc + ora #$8000) — that step
|
; shift step entirely (lsr $e2 + bcc + ora #$8000) — that step
|
||||||
|
|
@ -380,6 +437,41 @@ __mulsi3:
|
||||||
; iteration.
|
; iteration.
|
||||||
lda 0xe2
|
lda 0xe2
|
||||||
bne .Lmulsi_full
|
bne .Lmulsi_full
|
||||||
|
; Quarter-square fast path: when BOTH args fit in 8 bits (e2==0
|
||||||
|
; already verified, e6==0, e0<256, e4<256), use the same T[k]=k^2/4
|
||||||
|
; table that __umulhisi3 uses to compute a*b = T[a+b] - T[|a-b|]
|
||||||
|
; in ~50 cyc vs the u16 loop's ~150-250 cyc for small multipliers.
|
||||||
|
; Common when dotProduct etc. sign-extend small i16 values to i32.
|
||||||
|
lda 0xe6
|
||||||
|
bne .Lmulsi_u16_entry
|
||||||
|
lda 0xe0
|
||||||
|
ora 0xe4
|
||||||
|
and #0xff00
|
||||||
|
bne .Lmulsi_u16_entry
|
||||||
|
; T[a+b] -> $e8 (product lo).
|
||||||
|
lda 0xe0
|
||||||
|
clc
|
||||||
|
adc 0xe4
|
||||||
|
asl a
|
||||||
|
tax
|
||||||
|
lda __umulhisi3_qsq, x
|
||||||
|
sta 0xe8
|
||||||
|
; |a-b| as word index.
|
||||||
|
lda 0xe0
|
||||||
|
sec
|
||||||
|
sbc 0xe4
|
||||||
|
bpl .Lmulsi_qsq_pos
|
||||||
|
eor #0xffff
|
||||||
|
inc a
|
||||||
|
.Lmulsi_qsq_pos:
|
||||||
|
asl a
|
||||||
|
tax
|
||||||
|
lda 0xe8
|
||||||
|
sec
|
||||||
|
sbc __umulhisi3_qsq, x
|
||||||
|
ldx #0
|
||||||
|
rtl
|
||||||
|
.Lmulsi_u16_entry:
|
||||||
ldy #0x10
|
ldy #0x10
|
||||||
.Lmulsi_u16_loop:
|
.Lmulsi_u16_loop:
|
||||||
; Shift multiplier right; bit-out tested for add. Bottom of loop
|
; Shift multiplier right; bit-out tested for add. Bottom of loop
|
||||||
|
|
@ -466,14 +558,14 @@ __ashlsi3:
|
||||||
sta 0xe0 ; lo
|
sta 0xe0 ; lo
|
||||||
stx 0xe2 ; hi
|
stx 0xe2 ; hi
|
||||||
lda 0x4, s
|
lda 0x4, s
|
||||||
tay ; count -> Y
|
tay ; count -> Y; sets Z if 0
|
||||||
|
beq .Lashlsi_done ; count==0: skip loop
|
||||||
.Lashlsi_loop:
|
.Lashlsi_loop:
|
||||||
cpy #0x0
|
; Per-bit: 7+7+2+3 = 19 cyc (was 25 with cpy/beq/bra).
|
||||||
beq .Lashlsi_done
|
|
||||||
asl 0xe0
|
asl 0xe0
|
||||||
rol 0xe2
|
rol 0xe2
|
||||||
dey
|
dey
|
||||||
bra .Lashlsi_loop
|
bne .Lashlsi_loop
|
||||||
.Lashlsi_done:
|
.Lashlsi_done:
|
||||||
ldx 0xe2
|
ldx 0xe2
|
||||||
lda 0xe0
|
lda 0xe0
|
||||||
|
|
@ -489,13 +581,12 @@ __lshrsi3:
|
||||||
stx 0xe2
|
stx 0xe2
|
||||||
lda 0x4, s
|
lda 0x4, s
|
||||||
tay
|
tay
|
||||||
.Llshrsi_loop:
|
|
||||||
cpy #0x0
|
|
||||||
beq .Llshrsi_done
|
beq .Llshrsi_done
|
||||||
|
.Llshrsi_loop:
|
||||||
lsr 0xe2
|
lsr 0xe2
|
||||||
ror 0xe0
|
ror 0xe0
|
||||||
dey
|
dey
|
||||||
bra .Llshrsi_loop
|
bne .Llshrsi_loop
|
||||||
.Llshrsi_done:
|
.Llshrsi_done:
|
||||||
ldx 0xe2
|
ldx 0xe2
|
||||||
lda 0xe0
|
lda 0xe0
|
||||||
|
|
@ -512,9 +603,8 @@ __ashrsi3:
|
||||||
stx 0xe2
|
stx 0xe2
|
||||||
lda 0x4, s
|
lda 0x4, s
|
||||||
tay
|
tay
|
||||||
.Lashrsi_loop:
|
|
||||||
cpy #0x0
|
|
||||||
beq .Lashrsi_done
|
beq .Lashrsi_done
|
||||||
|
.Lashrsi_loop:
|
||||||
; CMP #$8000 sets C iff the unsigned value >= 0x8000, i.e. bit 15
|
; CMP #$8000 sets C iff the unsigned value >= 0x8000, i.e. bit 15
|
||||||
; is set — exactly the sign bit.
|
; is set — exactly the sign bit.
|
||||||
lda 0xe2
|
lda 0xe2
|
||||||
|
|
@ -522,7 +612,7 @@ __ashrsi3:
|
||||||
ror 0xe2
|
ror 0xe2
|
||||||
ror 0xe0
|
ror 0xe0
|
||||||
dey
|
dey
|
||||||
bra .Lashrsi_loop
|
bne .Lashrsi_loop
|
||||||
.Lashrsi_done:
|
.Lashrsi_done:
|
||||||
ldx 0xe2
|
ldx 0xe2
|
||||||
lda 0xe0
|
lda 0xe0
|
||||||
|
|
@ -1279,3 +1369,75 @@ longjmp:
|
||||||
lda #1
|
lda #1
|
||||||
.Llj_done:
|
.Llj_done:
|
||||||
rtl
|
rtl
|
||||||
|
|
||||||
|
; --------------------------------------------------------------------
|
||||||
|
; __umulhisi3_qsq: quarter-square lookup table.
|
||||||
|
; T[k] = floor(k² / 4) for k ∈ [0, 510]. Used by __umulhisi3's fast
|
||||||
|
; 8x8 path: a*b = T[a+b] - T[|a-b|]. 511 entries × 2 bytes = 1022 B.
|
||||||
|
; --------------------------------------------------------------------
|
||||||
|
__umulhisi3_qsq:
|
||||||
|
.short 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0006, 0x0009, 0x000c
|
||||||
|
.short 0x0010, 0x0014, 0x0019, 0x001e, 0x0024, 0x002a, 0x0031, 0x0038
|
||||||
|
.short 0x0040, 0x0048, 0x0051, 0x005a, 0x0064, 0x006e, 0x0079, 0x0084
|
||||||
|
.short 0x0090, 0x009c, 0x00a9, 0x00b6, 0x00c4, 0x00d2, 0x00e1, 0x00f0
|
||||||
|
.short 0x0100, 0x0110, 0x0121, 0x0132, 0x0144, 0x0156, 0x0169, 0x017c
|
||||||
|
.short 0x0190, 0x01a4, 0x01b9, 0x01ce, 0x01e4, 0x01fa, 0x0211, 0x0228
|
||||||
|
.short 0x0240, 0x0258, 0x0271, 0x028a, 0x02a4, 0x02be, 0x02d9, 0x02f4
|
||||||
|
.short 0x0310, 0x032c, 0x0349, 0x0366, 0x0384, 0x03a2, 0x03c1, 0x03e0
|
||||||
|
.short 0x0400, 0x0420, 0x0441, 0x0462, 0x0484, 0x04a6, 0x04c9, 0x04ec
|
||||||
|
.short 0x0510, 0x0534, 0x0559, 0x057e, 0x05a4, 0x05ca, 0x05f1, 0x0618
|
||||||
|
.short 0x0640, 0x0668, 0x0691, 0x06ba, 0x06e4, 0x070e, 0x0739, 0x0764
|
||||||
|
.short 0x0790, 0x07bc, 0x07e9, 0x0816, 0x0844, 0x0872, 0x08a1, 0x08d0
|
||||||
|
.short 0x0900, 0x0930, 0x0961, 0x0992, 0x09c4, 0x09f6, 0x0a29, 0x0a5c
|
||||||
|
.short 0x0a90, 0x0ac4, 0x0af9, 0x0b2e, 0x0b64, 0x0b9a, 0x0bd1, 0x0c08
|
||||||
|
.short 0x0c40, 0x0c78, 0x0cb1, 0x0cea, 0x0d24, 0x0d5e, 0x0d99, 0x0dd4
|
||||||
|
.short 0x0e10, 0x0e4c, 0x0e89, 0x0ec6, 0x0f04, 0x0f42, 0x0f81, 0x0fc0
|
||||||
|
.short 0x1000, 0x1040, 0x1081, 0x10c2, 0x1104, 0x1146, 0x1189, 0x11cc
|
||||||
|
.short 0x1210, 0x1254, 0x1299, 0x12de, 0x1324, 0x136a, 0x13b1, 0x13f8
|
||||||
|
.short 0x1440, 0x1488, 0x14d1, 0x151a, 0x1564, 0x15ae, 0x15f9, 0x1644
|
||||||
|
.short 0x1690, 0x16dc, 0x1729, 0x1776, 0x17c4, 0x1812, 0x1861, 0x18b0
|
||||||
|
.short 0x1900, 0x1950, 0x19a1, 0x19f2, 0x1a44, 0x1a96, 0x1ae9, 0x1b3c
|
||||||
|
.short 0x1b90, 0x1be4, 0x1c39, 0x1c8e, 0x1ce4, 0x1d3a, 0x1d91, 0x1de8
|
||||||
|
.short 0x1e40, 0x1e98, 0x1ef1, 0x1f4a, 0x1fa4, 0x1ffe, 0x2059, 0x20b4
|
||||||
|
.short 0x2110, 0x216c, 0x21c9, 0x2226, 0x2284, 0x22e2, 0x2341, 0x23a0
|
||||||
|
.short 0x2400, 0x2460, 0x24c1, 0x2522, 0x2584, 0x25e6, 0x2649, 0x26ac
|
||||||
|
.short 0x2710, 0x2774, 0x27d9, 0x283e, 0x28a4, 0x290a, 0x2971, 0x29d8
|
||||||
|
.short 0x2a40, 0x2aa8, 0x2b11, 0x2b7a, 0x2be4, 0x2c4e, 0x2cb9, 0x2d24
|
||||||
|
.short 0x2d90, 0x2dfc, 0x2e69, 0x2ed6, 0x2f44, 0x2fb2, 0x3021, 0x3090
|
||||||
|
.short 0x3100, 0x3170, 0x31e1, 0x3252, 0x32c4, 0x3336, 0x33a9, 0x341c
|
||||||
|
.short 0x3490, 0x3504, 0x3579, 0x35ee, 0x3664, 0x36da, 0x3751, 0x37c8
|
||||||
|
.short 0x3840, 0x38b8, 0x3931, 0x39aa, 0x3a24, 0x3a9e, 0x3b19, 0x3b94
|
||||||
|
.short 0x3c10, 0x3c8c, 0x3d09, 0x3d86, 0x3e04, 0x3e82, 0x3f01, 0x3f80
|
||||||
|
.short 0x4000, 0x4080, 0x4101, 0x4182, 0x4204, 0x4286, 0x4309, 0x438c
|
||||||
|
.short 0x4410, 0x4494, 0x4519, 0x459e, 0x4624, 0x46aa, 0x4731, 0x47b8
|
||||||
|
.short 0x4840, 0x48c8, 0x4951, 0x49da, 0x4a64, 0x4aee, 0x4b79, 0x4c04
|
||||||
|
.short 0x4c90, 0x4d1c, 0x4da9, 0x4e36, 0x4ec4, 0x4f52, 0x4fe1, 0x5070
|
||||||
|
.short 0x5100, 0x5190, 0x5221, 0x52b2, 0x5344, 0x53d6, 0x5469, 0x54fc
|
||||||
|
.short 0x5590, 0x5624, 0x56b9, 0x574e, 0x57e4, 0x587a, 0x5911, 0x59a8
|
||||||
|
.short 0x5a40, 0x5ad8, 0x5b71, 0x5c0a, 0x5ca4, 0x5d3e, 0x5dd9, 0x5e74
|
||||||
|
.short 0x5f10, 0x5fac, 0x6049, 0x60e6, 0x6184, 0x6222, 0x62c1, 0x6360
|
||||||
|
.short 0x6400, 0x64a0, 0x6541, 0x65e2, 0x6684, 0x6726, 0x67c9, 0x686c
|
||||||
|
.short 0x6910, 0x69b4, 0x6a59, 0x6afe, 0x6ba4, 0x6c4a, 0x6cf1, 0x6d98
|
||||||
|
.short 0x6e40, 0x6ee8, 0x6f91, 0x703a, 0x70e4, 0x718e, 0x7239, 0x72e4
|
||||||
|
.short 0x7390, 0x743c, 0x74e9, 0x7596, 0x7644, 0x76f2, 0x77a1, 0x7850
|
||||||
|
.short 0x7900, 0x79b0, 0x7a61, 0x7b12, 0x7bc4, 0x7c76, 0x7d29, 0x7ddc
|
||||||
|
.short 0x7e90, 0x7f44, 0x7ff9, 0x80ae, 0x8164, 0x821a, 0x82d1, 0x8388
|
||||||
|
.short 0x8440, 0x84f8, 0x85b1, 0x866a, 0x8724, 0x87de, 0x8899, 0x8954
|
||||||
|
.short 0x8a10, 0x8acc, 0x8b89, 0x8c46, 0x8d04, 0x8dc2, 0x8e81, 0x8f40
|
||||||
|
.short 0x9000, 0x90c0, 0x9181, 0x9242, 0x9304, 0x93c6, 0x9489, 0x954c
|
||||||
|
.short 0x9610, 0x96d4, 0x9799, 0x985e, 0x9924, 0x99ea, 0x9ab1, 0x9b78
|
||||||
|
.short 0x9c40, 0x9d08, 0x9dd1, 0x9e9a, 0x9f64, 0xa02e, 0xa0f9, 0xa1c4
|
||||||
|
.short 0xa290, 0xa35c, 0xa429, 0xa4f6, 0xa5c4, 0xa692, 0xa761, 0xa830
|
||||||
|
.short 0xa900, 0xa9d0, 0xaaa1, 0xab72, 0xac44, 0xad16, 0xade9, 0xaebc
|
||||||
|
.short 0xaf90, 0xb064, 0xb139, 0xb20e, 0xb2e4, 0xb3ba, 0xb491, 0xb568
|
||||||
|
.short 0xb640, 0xb718, 0xb7f1, 0xb8ca, 0xb9a4, 0xba7e, 0xbb59, 0xbc34
|
||||||
|
.short 0xbd10, 0xbdec, 0xbec9, 0xbfa6, 0xc084, 0xc162, 0xc241, 0xc320
|
||||||
|
.short 0xc400, 0xc4e0, 0xc5c1, 0xc6a2, 0xc784, 0xc866, 0xc949, 0xca2c
|
||||||
|
.short 0xcb10, 0xcbf4, 0xccd9, 0xcdbe, 0xcea4, 0xcf8a, 0xd071, 0xd158
|
||||||
|
.short 0xd240, 0xd328, 0xd411, 0xd4fa, 0xd5e4, 0xd6ce, 0xd7b9, 0xd8a4
|
||||||
|
.short 0xd990, 0xda7c, 0xdb69, 0xdc56, 0xdd44, 0xde32, 0xdf21, 0xe010
|
||||||
|
.short 0xe100, 0xe1f0, 0xe2e1, 0xe3d2, 0xe4c4, 0xe5b6, 0xe6a9, 0xe79c
|
||||||
|
.short 0xe890, 0xe984, 0xea79, 0xeb6e, 0xec64, 0xed5a, 0xee51, 0xef48
|
||||||
|
.short 0xf040, 0xf138, 0xf231, 0xf32a, 0xf424, 0xf51e, 0xf619, 0xf714
|
||||||
|
.short 0xf810, 0xf90c, 0xfa09, 0xfb06, 0xfc04, 0xfd02, 0xfe01
|
||||||
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue