Rudimentary desk accessory

Cribbed from the "MPW-GM" disk
This commit is contained in:
Elliot Nunn 2021-03-14 17:45:59 +08:00
parent 8d68e8c3a0
commit c8efb91c62
3 changed files with 284 additions and 0 deletions

4
.gitignore vendored
View File

@ -17,3 +17,7 @@ payload
packbits
*.pb
ServerDA
ServerDA.idump
ServerDA.rdump

View File

@ -82,4 +82,22 @@ testchain: ChainLoader.bin FORCE
ServerDA.bin: ServerDA.a
vasm-1/vasmm68k_mot -quiet -Fbin -pic -o $@ $<
ServerDA ServerDA.idump ServerDA.rdump: ServerDA.bin
touch ServerDA ServerDA.idump
/bin/echo -n dfilmovr >ServerDA.idump
echo data "'DRVR'" '(12, "", purgeable) {};' >ServerDA.rdump
rfx cp ServerDA.bin ServerDA.rdump//DRVR/12
testda: FORCE ServerDA ServerDA.idump ServerDA.rdump
rm -rf /tmp/testda; mkdir -p /tmp/testda/Desktop\ Folder; cp ServerDA ServerDA.idump ServerDA.rdump /tmp/testda/Desktop\ Folder/
MakeHFS -s 400k -n TestDA -d now -i /tmp/testda /tmp/testda.dsk
rsync Big.dsk /tmp/Big.dsk
Mini\ vMac\ Classic.app/Co*/Ma*/* /tmp/Big.dsk /tmp/testda.dsk
FORCE:

262
ServerDA.a Normal file
View File

@ -0,0 +1,262 @@
***************************************************************************
****
**** MEMORY DESK ACCESSORY - A sample DA written in MPW 68000 Assembly
****
**** Copyright Apple Computer, Inc. 1985-1987, 1993, 1998
**** All rights reserved.
****
***************************************************************************
; Desk accessories (drivers) cannot use global variables in the normal sense.
; Usually, a handle is allocated and stuffed into dCtlStorage and global
; variables are stored in this handle. However, in this example, the globals
; are allocated at the end of the desk accessory's window record. Since the
; window record is always nonrelocatable storage, the variables will never move.
; This record structure below defines the layout of our "global variables."
**************************** DESK ACCESSORY ENTRY **************************
DAEntry ; See Device Manager IM:2
DC.B $24 ; (1<<dCtlEnable) + (1<<dNeedTime) ; periodic,control flags set
DC.B 0 ; Lower byte is unused
DC.W 5*60 ; 5 sec periodic update
DC.W $40 ; (1<<updateEvt) ; Handle only update events
DC.W 0 ; No menu for this accessory
DC.W DAOpen-DAEntry ; Open routine
DC.W DADone-DAEntry ; Prime - unused
DC.W DACtl-DAEntry ; Control
DC.W DADone-DAEntry ; Status - unused
DC.W DAClose-DAEntry ; Close
DATitle
DC.B 17, 'Free Mem (#Bytes)' ; DA Name (& Window Title)
ALIGN 2 ; Word align
************************ DESK ACCESSORY OPEN ROUTINE ***********************
DAOpen
MOVEM.L A1-A4,-(SP) ; preserve A1-A4
MOVE.L A1,A4 ; MOVE DCE pointer to a reg
SUBQ.L #4,SP ; FUNCTION = GrafPtr
MOVE.L SP,-(SP) ; push a pointer to it
DC.W $A874 ; _GetPort ; push it on top of stack
TST.L $1E(A4) ; DCtlEntry.dCtlWindow do we have a window?
BNE.S StdReturn ; If so, return, Else
******************************* NEW WINDOW ROUTINE *************************
MOVE.L #156,D0 ; WindowRecord size
DC.W $A11E ; _NewPtr ; allocate space for record
SUBQ #4,SP ; FUNCTION = WindowRef
MOVE.L A0,-(SP) ; address of storage
PEA theWindow ; boundsRect
PEA DATitle ; title
CLR.W -(SP) ; visible flag FALSE
MOVE.W #16,-(SP) ; window proc = rDocProc, 16px rounding
MOVE.L #-1,-(SP) ; window in front
MOVE.B #1,-(SP) ; goAway box TRUE
CLR.L -(SP) ; refCon is 0
DC.W $A913 ; __NewWindow
MOVE.L (SP)+,A0
MOVE.L A0,$1E(A4) ; DCtlEntry.DCtlWindow save windowPtr
MOVE.W $18(A4),$6C(A0) ; DCtlEntry.DCtlRefNum system window
DC.W $A11D ; __MaxMem
StdReturn
DC.W $A873 ; __SetPort ; old port on stack
MOVEM.L (SP)+,A1-A4 ; restore regs
************************ DESK ACCESSORY DONE ROUTINE ***********************
DADone
MOVEQ #0,D0 ; return no error
RTS ; all done, exit
************************ DESK ACCESSORY CLOSE ROUTINE **********************
DAClose
MOVEM.L A1-A4,-(SP) ; preserve A1-A4
MOVE.L A1,A4 ; MOVE DCE ptr to A4
SUBQ.L #4,SP ; FUNCTION = GrafPtr
MOVE.L SP,-(SP) ; push a pointer to it
DC.W $A874 ; __GetPort ; get it, now it's on TOS
MOVE.L $1E(A4),-(SP) ; DCtlEntry.DCtlWindow push the window
DC.W $A914 ; __DisposeWindow ; dispose of the window
CLR.L $1E(A4) ; DCtlEntry.DCtlWindow mark DCE properly
BRA.S StdReturn ; all done with close, exit
********************** DESK ACCESSORY CONTROL ROUTINE **********************
DACtl
MOVE.L A4,-(SP) ; preserve reg
MOVE.L A1,A4 ; move DCE ptr to A4
MOVE.W $1A(A0),D0 ; get the control opCode
SUB.W #64,D0 ; = 64? (event)
BEQ.S DoCtlEvent
SUB.W #1,D0 ; = 65? (periodic)
BEQ.S DoPeriodic
CtlDone
MOVE.L A4,A1 ; put DCE ptr back in A1
MOVE.L (SP)+,A4 ; restore reg
MOVEQ #0,D0 ; return no error
MOVE.L $8FC,-(SP) ; jump to IODone
RTS
************************** EVENT HANDLING ROUTINE **************************
DoCtlEvent
MOVE.L A3,-(SP) ; save reg
MOVE.L $1C(A0),A3 ; CntrlParam.CSParamget the event pointer
MOVE.W 0(A3),D0 ; EventRecord.what get the event number
SUBQ #6,D0 ; updateEvt is it an update?
BNE.S CtlEvtDone ; If not, exit
MOVE.L 2(A3),-(SP) ; EventRecord.message push windowPtr
DC.W $A922 ; __BeginUpdate ; begin the update operation
MOVE.L 2(A3),-(SP) ; EventRecord.message push windowPtr again
DC.W $A873 ; __SetPort
BSR.S DrawWindow ; draw our items
MOVE.L 2(A3),-(SP) ; EventRecord.message one more time
DC.W $A923 ; __EndUpdate ; end of update
CtlEvtDone
MOVE.L (SP)+,A3 ; restore reg
BRA.S CtlDone ; exit
**************************** PERIODIC ROUTINE *****************************
DoPeriodic
MOVE.L $1E(A4),-(SP) ; DCtlEntry.DCtlWindow set the port
DC.W $A873 ; __SetPort
BSR.S DrawWindow ; draw our window every 5s
BRA.S CtlDone
****************************** FONT METRICS *******************************
DrawWindow
MOVE.W #0,-(SP) ; SrcCopy source mode
DC.W $A889 ; __TextMode
MOVE.W #4,-(SP) ; Monaco Monaco
DC.W $A887 ; __TextFont
MOVE.W #9,-(SP) ; 9 point
DC.W $A88A ; __TextSize
MOVE.W #1,-(SP) ; bold
DC.W $A888 ; __TextFace
********************** WRITE APPLICATION HEAP FREEMEM *********************
MOVE.W #6,-(SP)
MOVE.W #10,-(SP)
DC.W $A893 ; __MoveTo
PEA s1 ; #'AppHeap: '
DC.W $A884 ; __DrawString
DC.W $A01C ; __FreeMem ; free memory -> D0
JSR PrintNum ; draw our free mem
************************* WRITE SYSTEM HEAP FREEMEM ***********************
PEA s2 ; #' SysHeap: '
DC.W $A884 ; __DrawString
DC.W $A41C ; __FreeMem SYS ; free memory -> D0
JSR PrintNum ; draw our free sys mem
***************************** WRITELN VOL INFO ****************************
PEA s3 ; #' Disk: '
DC.W $A884 ; __DrawString
MOVE.L #122,D0 ; HVolumeParam.sizeof size of HFS ParamBlock
DC.W $A31E ; __NewPtr CLEAR ; NewPtr -> A0
BNE.S Exit ; IF Error THEN Exit
MOVE.L A0,D7 ; save PBPtr in D7
MOVE.L $1A(A4),A1 ; DCtlEntry.DCtlWindow get window rec pointer
LEA aString,A1 ; address of string buffer
MOVE.L A1,$12(A0) ; ioNamePtr = Volume Name
DC.W $A207 ; __PBHGetVInfoSync ; _GetVolInfo info -> A0^
MOVE.L D7,A0
MOVE.L $30(A0),D1 ; HVolumeParam.ioVAlBlkSiz block size in D1
MOVE.W $3E(A0),D2 ; HVolumeParam.ioVFrBlk free blocks in D2
MOVE.W D1,D0 ; 32 bit * 16 bit multiply
MULU.W D2,D0 ; right half of size
SWAP D1
MOVE.W D1,D3
MULU.W D2,D3 ; left half of size
SWAP D3
ADD.L D3,D0 ; total bytes free on vol
JSR PrintNum ; write # bytes free
PEA s4 ; #' free on '
DC.W $A884 ; __DrawString
MOVE.W #4,-(SP) ; underlined
DC.W $A888 ; __TextFace
MOVE.L D7,A0
MOVE.L $12(A0),-(SP) ; HVolumeParam.ioNamePtr offset for volName
DC.W $A884 ; __DrawString
MOVE.L D7,A0 ; free the memory
DC.W $A01F ; __DisposePtr
Exit
RTS
***************************** SUBROUTINES ****************************
PrintNum
; Binary integer to be drawn at CurPenPos in D0 on entry
; number drawn in plain text, bolding restored afterwords
MOVE.L D0,D6 ; for safe keeping
CLR.W -(SP) ; plain text
DC.W $A888 ; __TextFace
MOVE.L D6,D0 ; and back again
MOVE.L $1A(A4),A0 ; DCtlEntry.DCtlWindow get window rec pointer
LEA aNumStr,A0 ; get buffer address
move.w #$0000,-(sp)
dc.w $A9EE ; __NumToString ; Binary-Decimal Package
MOVE.L A0,-(SP) ; push the pointer to the str
DC.W $A884 ; __DrawString
MOVE.W #1,-(SP) ; bold text restored
DC.W $A888 ; __TextFace
RTS
******************************* DATA AREA **********************************
s1 dc.b 9, 'AppHeap: '
s2 dc.b 11, ' SysHeap: '
s3 dc.b 8, ' Disk: ', 0
s4 dc.b 9, ' free on '
theWindow DC.W 322,10,338,500 ; window top,left,bottom,right
; Desk accessories (drivers) cannot use global variables in the normal sense.
; Usually, a handle is allocated and stuffed into dCtlStorage and global
; variables are stored in this handle. However, in this example, the globals
; are allocated at the end of the desk accessory's window record. Since the
; window record is always nonrelocatable storage, the variables will never move.
; This record structure below defines the layout of our "global variables."
;GlobalVars RECORD WindowRecord.sizeof ; Put variables at end of window rec
aString DCB.B 28 ; vol names must be < 28 char
aNumStr DCB.B 10 ; sufficient for 10 GB of space
;GlobalSize EQU *-GlobalVars ; size of my globals
; ENDR