mirror of
https://github.com/elliotnunn/NetBoot.git
synced 2024-12-21 10:30:03 +00:00
Add graphical boot-picker code
Not used for anything yet!
This commit is contained in:
parent
18d8e9e3da
commit
71d9ea9038
309
BootPicker.a
Normal file
309
BootPicker.a
Normal file
@ -0,0 +1,309 @@
|
||||
; Inputs: append 1 or more Pascal strings, followed by zero byte
|
||||
; Outputs: D0 = index of selected string, Ao = pointer to selected string
|
||||
|
||||
|
||||
; Aesthetic parameters
|
||||
kMinWid equ 70 ; min width to leave for button label
|
||||
kBtnHt equ 20 ; should always be 20 because text won't move
|
||||
kBtnGap equ 13
|
||||
kPadX equ 5+26 ; due to border, padding=6 would leave 1 white pixel
|
||||
kPadY equ 5+13
|
||||
|
||||
|
||||
; Save all the stuff that we whack
|
||||
movem.l A1-A5/D1-D7,-(SP)
|
||||
move.l $3F8,-(SP) ; Save DSAlertRect
|
||||
move.l $3F8+4,-(SP)
|
||||
move.l $9CE,-(SP) ; Save ToolScratch
|
||||
move.l $9CE+4,-(SP)
|
||||
move.l $2BA,-(SP) ; Save DSAlertTab
|
||||
link.w A6,#0 ; We use a lot of stack
|
||||
|
||||
|
||||
; Head-patch _PtInRect to account for our unusual window placement
|
||||
move.w #$A8AD,D0 ; _PtInRect
|
||||
dc.w $A146 ; _GetTrapAddress
|
||||
move.l A0,$9CE+4 ; Save in ToolScratch+4 to enable head-patch
|
||||
|
||||
move.w #$A8AD,D0 ; _PtInRect
|
||||
lea MyPtInRect,A0
|
||||
dc.w $A047 ; _SetTrapAddress
|
||||
|
||||
|
||||
; Do the usual "QuickDraw outside of application" setup
|
||||
clr.l -(SP)
|
||||
move.l SP,A5 ; tiny A5 world with QD globals ptr
|
||||
lea -206(SP),SP ; push the QD globals
|
||||
pea 202(SP)
|
||||
dc.w $A86E ; _InitGraf
|
||||
dc.w $A8FE ; _InitFonts (because we use _StringWidth)
|
||||
lea -108(SP),SP
|
||||
pea (SP)
|
||||
dc.w $A86F ; _OpenPort (don't save, we have our own globs)
|
||||
|
||||
|
||||
; Copy a stub alert table to the stack
|
||||
move.l #MyDSAlertTabEnd-MyDSAlertTabStart,D0
|
||||
sub.l D0,SP
|
||||
move.l SP,A1
|
||||
lea MyDSAlertTabStart,A0
|
||||
dc.w $A22E ; _BlockMoveData
|
||||
|
||||
|
||||
; First pass: calculate box width, putting shortest string width into D5
|
||||
moveq.l #kMinWid,D5
|
||||
lea TrailingList,A0 ; A0 = current pstring ptr
|
||||
dswLoop
|
||||
tst.b (A0)
|
||||
beq.s dswDone
|
||||
|
||||
move.l A0,-(SP)
|
||||
clr.w -(SP)
|
||||
move.l A0,-(SP)
|
||||
dc.w $A88C ; _StringWidth
|
||||
move.w (SP)+,D0
|
||||
addq.w #8,D0
|
||||
cmp.w D0,D5
|
||||
bgt.s .notlargest
|
||||
move.w D0,D5
|
||||
.notlargest
|
||||
move.l (SP)+,A0
|
||||
|
||||
moveq.l #1,D0 ; increment the pstring ptr
|
||||
add.b (A0),D0
|
||||
add.l D0,A0
|
||||
bra.s dswLoop
|
||||
dswDone
|
||||
|
||||
|
||||
; Second pass: create a button list object in the DS alert table
|
||||
move.w (SP)+,D7 ; pop NumEntries from DS table
|
||||
|
||||
move.l #((kPadY)<<16)|(kPadX),D2 ; D2 = current button's topleft
|
||||
move.l #((kPadY+kBtnHt)<<16)|(kPadX+4+4),D3; D3 = current button's botright
|
||||
add.w D5,D3 ; ...including width of the text
|
||||
moveq.l #0,D6 ; D6 = button counter
|
||||
lea TrailingList,A0 ; A0 = current pstring ptr
|
||||
dsbLoop
|
||||
tst.b (A0)
|
||||
beq.s dsbDone
|
||||
|
||||
move.w D6,-(SP) ; push procedure object ID (base $8000)
|
||||
add.w #$8000,(SP)
|
||||
move.l D3,-(SP) ; push botright
|
||||
move.l D2,-(SP) ; push topleft
|
||||
move.w D6,-(SP) ; push string object ID (base $C000)
|
||||
add.w #$C000,(SP)
|
||||
; increment...
|
||||
add.l #(kBtnHt+kBtnGap)<<16,D2 ; the button's top edge
|
||||
add.l #(kBtnHt+kBtnGap)<<16,D3 ; the button's bottom edge
|
||||
addq.w #1,D6 ; the button counter
|
||||
moveq.l #1,D0 ; the pstring ptr
|
||||
add.b (A0),D0
|
||||
add.l D0,A0
|
||||
bra.s dsbLoop
|
||||
|
||||
dsbDone ; done looping, push a header for this object...
|
||||
move.w D6,-(SP) ; the number of buttons
|
||||
mulu #12,D6 ; the size in bytes = 12n+2
|
||||
add.w #2,D6
|
||||
move.w D6,-(SP)
|
||||
move.w #$1993,-(SP) ; the unique ID for this button list
|
||||
|
||||
addq.w #1,D7
|
||||
move.w D7,-(SP) ; increment and re-push NumEntries
|
||||
|
||||
|
||||
; Third pass: calculate box height
|
||||
lea $3F8,A1 ; A0 = DSAlertRect
|
||||
move.l (A5),A0 ; From QD globals
|
||||
move.l -122+6+4(A0),D0 ; D0 = screenBits.bounds.botRight, so D0.W = screen width
|
||||
|
||||
add.w #kPadX,D3 ; D3 = box width
|
||||
sub.w D3,D0
|
||||
bgt.s .nottoowide
|
||||
clr.w D0
|
||||
.nottoowide
|
||||
asr.w #1,D0
|
||||
move.w D0,2(A1) ; set DSAlertRect left
|
||||
move.w D0,$9CE+2 ; & stash in ToolScratch for MyPtInRect
|
||||
add.w D3,D0
|
||||
move.w D0,6(A1) ; set DSAlertRect right
|
||||
|
||||
swap D0 ; D0 = screen height
|
||||
swap D2 ; D2 = box height ("top" of next button)
|
||||
add.w #kPadY-kBtnGap,D2 ; adjust box height
|
||||
sub.w D2,D0
|
||||
bgt.s .nottoohigh
|
||||
clr.w D0
|
||||
.nottoohigh
|
||||
asr.w #1,D0
|
||||
move.w D0,(A1) ; set DSAlertRect top
|
||||
move.w D0,$9CE ; & stash in ToolScratch for MyPtInRect
|
||||
add.w D2,D0
|
||||
move.w D0,4(A1) ; set DSAlertRect bottom
|
||||
|
||||
|
||||
; Fourth pass: create a string offset for each button
|
||||
moveq.l #0,D6 ; D6 = button counter
|
||||
lea TrailingList,A0 ; A0 = current pstring ptr
|
||||
dssLoop
|
||||
tst.b (A0)
|
||||
beq.s dssDone
|
||||
|
||||
move.w (SP)+,D7 ; pop NumEntries from DS table
|
||||
|
||||
; push the struct fields...
|
||||
bsr PushPaddedString ; even-length string with 2-byte length
|
||||
move.w D6,-(SP) ; the unique ID (C000+n)
|
||||
add.w #$C000,(SP)
|
||||
|
||||
addq.w #1,D7
|
||||
move.w D7,-(SP) ; increment and re-push NumEntries
|
||||
|
||||
; increment...
|
||||
addq.w #1,D6 ; the button counter
|
||||
moveq.l #1,D0 ; the pstring ptr
|
||||
add.b (A0),D0
|
||||
add.l D0,A0
|
||||
bra.s dssLoop
|
||||
dssDone
|
||||
|
||||
|
||||
; Fifth pass: generate code for each button
|
||||
moveq.l #0,D6 ; D6 = button counter
|
||||
lea TrailingList,A0 ; A0 = current pstring ptr
|
||||
dspLoop
|
||||
tst.b (A0)
|
||||
beq.s dspDone
|
||||
|
||||
move.w (SP)+,D7 ; pop NumEntries from DS table
|
||||
|
||||
pea ReturnToCaller ; craft the code for this button...
|
||||
move.w #$4EF9,-(SP) ; jmp ReturnToCaller (absolute addr)
|
||||
move.l A6,-(SP)
|
||||
move.w #$2C7C,-(SP) ; move.l #CorrectA6,A6 ; frame ptr
|
||||
move.l A0,-(SP)
|
||||
move.w #$207C,-(SP) ; move.l #CorrectA0,A0 ; return string ptr
|
||||
move.l D6,-(SP)
|
||||
move.w #$203C,-(SP) ; move.l #CorrectD0,D0 ; return string idx
|
||||
|
||||
; push a header...
|
||||
move.w #24,-(SP) ; the size in bytes of the above code
|
||||
move.w D6,-(SP) ; the unique ID (8000+n)
|
||||
add.w #$8000,(SP)
|
||||
|
||||
addq.w #1,D7
|
||||
move.w D7,-(SP) ; increment and re-push NumEntries
|
||||
|
||||
; increment...
|
||||
addq.w #1,D6 ; the button counter
|
||||
moveq.l #1,D0 ; the pstring ptr
|
||||
add.b (A0),D0
|
||||
add.l D0,A0
|
||||
bra.s dspLoop
|
||||
|
||||
dspDone ; Must clear the instruction cache on 030/040
|
||||
move.l A6,D0
|
||||
sub.l SP,D0
|
||||
move.l SP,A0
|
||||
move.l SP,A1
|
||||
dc.w $A02E ; using non-Data _BlockMove
|
||||
|
||||
|
||||
; Put up the DeepShit alert
|
||||
move.l SP,$2BA ; Set DSAlertTab
|
||||
clr.l $A8C ; Clear RestProc or our buttons get jumbled
|
||||
move.w #$2012,D0 ; Our error object number
|
||||
dc.w $A9C9 ; _SysError!
|
||||
bra.s * ; Should never return
|
||||
|
||||
|
||||
; The selected procedure will jump to here after setting A6,A0,D0
|
||||
ReturnToCaller
|
||||
move.w #$A8AD,D0 ; Unpatch _PtInRect
|
||||
move.l $9CE+4,A0 ; We saved it in ToolScratch
|
||||
dc.w $A047 ; _SetTrapAddress
|
||||
|
||||
unlk A6 ; See the saving code for details
|
||||
move.l (SP)+,$2BA
|
||||
move.l (SP)+,$9CE+4
|
||||
move.l (SP)+,$9CE
|
||||
move.l (SP)+,$3F8+4
|
||||
move.l (SP)+,$3F8
|
||||
movem.l (SP)+,A1-A5/D1-D7
|
||||
rts
|
||||
|
||||
|
||||
PushPaddedString ; trashes A1-A2,D0-D2, but must preserve A0
|
||||
move.l (SP)+,A2
|
||||
|
||||
move.l A0,-(SP) ; backup
|
||||
moveq.l #0,D0
|
||||
clr.w -(SP)
|
||||
move.l A0,-(SP)
|
||||
dc.w $A88C ; _StringWidth
|
||||
move.w D5,D0
|
||||
sub.w (SP)+,D0
|
||||
bgt.s .notzero
|
||||
moveq.l #0,D0
|
||||
.notzero
|
||||
asr.w #3,D0 ; divide the leftover by twice a Chicago space
|
||||
move.l (SP)+,A0 ; restore backup
|
||||
|
||||
clr.w D1
|
||||
move.b D0,D1
|
||||
add.b (A0),D1
|
||||
addq.b #1,D1
|
||||
bclr #0,D1 ; this is the spaced-out length in memory
|
||||
|
||||
clr.w D2
|
||||
.spaceloop
|
||||
cmp.w D2,D1
|
||||
beq.s .spacedone
|
||||
move.w #$2020,-(SP)
|
||||
addq.w #2,D2
|
||||
bra.s .spaceloop
|
||||
.spacedone
|
||||
move.w D1,-(SP)
|
||||
|
||||
|
||||
lea 2(SP),A1 ; bm dest
|
||||
add.w D0,A1
|
||||
|
||||
clr.l D0
|
||||
move.b (A0),D0
|
||||
move.l A0,-(SP)
|
||||
addq.l #1,A0 ; bm src
|
||||
dc.w $A22E ; _BlockMoveData
|
||||
move.l (SP)+,A0
|
||||
|
||||
|
||||
jmp (A2)
|
||||
|
||||
|
||||
MyPtInRect
|
||||
move.l $9CE,D0
|
||||
sub.w D0,10(SP)
|
||||
swap D0
|
||||
sub.w D0,8(SP)
|
||||
|
||||
move.l $9CE+4,A0
|
||||
jmp (A0)
|
||||
|
||||
|
||||
MyDSAlertTabStart
|
||||
dc.w 1 ; NumEntries
|
||||
|
||||
; Our only alert definition
|
||||
dc.w $2012 ; ID of this error
|
||||
dc.w 10 ; length of remaining items
|
||||
dc.w 0 ; primary text definition ID
|
||||
dc.w 0 ; secondary text definition ID
|
||||
dc.w 0 ; icon definition ID
|
||||
dc.w 0 ; procedure definition ID
|
||||
dc.w $1993 ; button definition ID
|
||||
MyDSAlertTabEnd
|
||||
|
||||
|
||||
TrailingList
|
12
Makefile
12
Makefile
@ -63,5 +63,17 @@ pyserver: payload FORCE
|
||||
|
||||
|
||||
|
||||
testpicker: BootPicker.bin FORCE
|
||||
cp sys701-144.img bootpick.tmp
|
||||
dd if=BootPicker.bin of=bootpick.tmp bs=138 seek=1 conv=notrunc
|
||||
Mini\ vMac\ Classic.app/Co*/Ma*/* xo.rom bootpick.tmp
|
||||
|
||||
BootPicker.bin: BootPicker.a
|
||||
vasm-1/vasmm68k_mot -quiet -Fbin -pic -o $@ $<
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
FORCE:
|
||||
|
Loading…
Reference in New Issue
Block a user