From 90e585fcad965fed7cefc47d82f92e0cd0343a3c Mon Sep 17 00:00:00 2001 From: Elliot Nunn Date: Mon, 29 Mar 2021 11:50:02 +0800 Subject: [PATCH] Stub backend to desk accessory --- Makefile | 7 ++- ServerDA.a | 67 ++++++++++++++++++++++++ ServerDRVR.a | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 ServerDRVR.a diff --git a/Makefile b/Makefile index 63e973f..9dfbaa2 100644 --- a/Makefile +++ b/Makefile @@ -85,11 +85,16 @@ testchain: ChainLoader.bin FORCE ServerDA.bin: ServerDA.a vasm-1/vasmm68k_mot -quiet -Fbin -pic -o $@ $< -ServerDA ServerDA.idump ServerDA.rdump: ServerDA.bin +ServerDRVR.bin: ServerDRVR.a + vasm-1/vasmm68k_mot -quiet -Fbin -pic -o $@ $< + +ServerDA ServerDA.idump ServerDA.rdump: ServerDA.bin ServerDRVR.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 + echo data "'DRVR'" '(-16000, sysheap, locked) {};' >>ServerDA.rdump + rfx cp ServerDRVR.bin ServerDA.rdump//DRVR/-16000 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/ diff --git a/ServerDA.a b/ServerDA.a index 8749fc1..29bdff6 100644 --- a/ServerDA.a +++ b/ServerDA.a @@ -51,6 +51,19 @@ DAOpen MOVEM.L A1-A4,-(SP) ; preserve A1-A4 MOVE.L A1,A4 ; MOVE DCE pointer to a reg +; Install the backend driver (anywhere in the unit table) + move.w $18(A1),D0 ; dCtlRefNum, so we need A0 to be intact + not.w D0 + asl.w #5,D0 + or.w #$C000,D0 ; "owned resource" ID + subq #4,SP + move.l #'DRVR',-(SP) + move.w D0,-(SP) + dc.w $A9A0 ; _GetResource (will be locked in sysheap) + move.l (SP)+,A0 + move.l (A0),A0 + bsr InstallAndOpenDriver + ; Create a fake queue to use until the backend driver is written lea gBackendQHdr,A0 lea HackQueueHeader,A1 @@ -730,6 +743,60 @@ GetFile ; push a 74 byte SFReply structure to the stack rts +InstallAndOpenDriver ; driver pointer is in A0, returns err code in D0 + movem.l A3-A4/D7,-(SP) + move.l A0,A4 ; keep the driver pointer in A4 + + ; slightly unorthodox approach... + move.l $11C,A3 ; unit table base + clr.l D7 + move.w $1D2,D7 ; unit table length in bytes + add.l D7,D7 + add.l D7,D7 + + tst.l -4(A3,D7) ; Extend unit table by 1 slot if needed + beq.s .lastEntryIsFree + addq.l #4,D7 + move.l D7,D0 + dc.w $A71E ; _NewPtrSysClear (new one) + move.l A0,A1 + move.l A3,A0 + move.l D7,D0 + subq.l #4,D0 + dc.w $A22E ; _BlockMoveData (old to new) + move.l A1,A3 + move.l A1,$11C + add.w #1,$1D2 + dc.w $A01F ; _DisposPtr (old) +.lastEntryIsFree + + move.l A4,A0 + move.w $1D2,D0 + neg.w D0 ; -(lenUT) = refnum highest slot + dc.w $A43D ; _DrvrInstall ReserveMem + + move.l -4(A3,D7),A0 ; We need to populate this ourselves + move.l (A0),A0 + move.l A4,(A0) ; set dCtlDriver pointer + move.w (A4),4(A0) ; drvrFlags to dCtlFlags + move.w 2(A4),$22(A0) ; drvrDelay to dCtlDelay + move.w 4(A4),$24(A0) ; drvrEMask to dCtlEMask + move.w 6(A4),$26(A0) ; drvrMenu to dCtlMenu + + ; Open the driver + sub #$32,SP + move.l SP,A0 + clr.b $1B(A0) ; IOPermssn = whatever is allowed + pea $12(A4) ; IOFileName = directly from the DRVR + move.l (SP)+,$12(A0) + dc.w $A000 ; _Open + move.w $10(A0),D0 ; return result + add #$32,SP + + movem.l (SP)+,A3-A4/D7 + rts + + Poof ; animation, takes D0, ONLY WORKS WITH BASIC QD! link A6,#-0 diff --git a/ServerDRVR.a b/ServerDRVR.a new file mode 100644 index 0000000..4e7af69 --- /dev/null +++ b/ServerDRVR.a @@ -0,0 +1,143 @@ +; I implement a "BootServer" on the AppleTalk network +; The Server Desk Accessory installs me in the system heap and opens me + +ServerHeader + dc.w $4000 ; dNeedLock + dc.w 0 ; delay + dc.w 0 ; evt mask + dc.w 0 ; menu + + dc.w ServerOpen-ServerHeader + dc.w 0 ; no Prime + dc.w 0 ; no Control + dc.w 0 ; no Status + dc.w ServerClose-ServerHeader + dc.b 14, '.NetBootServer', 0 + dc.b 0, 0, $20, 1 ; version + +ServerOpen + dc.w $A9FF + movem.l A0/A1,-(SP) + +; Try *once*. AT might come up later but not because of us. + bsr TryOpenMPP + bne.s .couldNotOpenAppleTalk + bsr Listen +.couldNotOpenAppleTalk + +; Be ready for the LAP Manager to open/close .MPP + bsr RegisterForTransitions + + movem.l (SP)+,A0/A1 + clr.w $10(A0) ; return noErr + rts + +ServerClose + movem.l A0/A1,-(SP) + bsr StopListening + movem.l (SP)+,A0/A1 + clr.w D0 ; return noErr + rts + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +TryOpenMPP +; Checking whether the "B" printer port is configured for AppleTalk is an +; application responsibility on 64K ROM machines (as documented in IM), +; but 128K ROM and later machines move this check to AppleTalk itself, +; for example to allow other AppleTalk interfaces. + tst.w $28E ; ROM85 positive? + bgt.s .returnYes ; it is always safe to try on 128K machines + + move.b $1FB,D0 ; SPConfig & 0xF == useFree (0) or useATalk (1)? + and.b #$F,D0 + sub.b #1,D0 + ble.s .returnYes + + move.b $291,D0 ; PortBUse negative or useATalk (1)? + blt.s .returnYes + cmp.b #1,D0 + beq.s .returnYes + +.returnNo moveq #1,D0 + rts + +.returnYes + sub #$32,SP + lea .MPP,A0 + move.l A0,$12(SP) ; IOFileName + clr.b $1B(SP) ; IOPermssn + move.l SP,A0 + dc.w $A000 ; _Open + tst.w $10(A0) ; IOResult: check it + add #$32,SP + rts + +.MPP dc.b 4, '.MPP', 0 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +RegisterForTransitions rts ; register for the LAP Manager queue if possible + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +Listen + sub #$32,SP ; OPEN DDP SOCKET + move.w #-10,$18(SP) ; ioRefNum = MPP + move.w #248,$1A(SP) ; csCode = openSkt + clr.b $1C(SP) ; socket = auto-assign + pea SocketListener + move.l (SP)+,$1E(SP) ; listener + move.l SP,A0 + dc.w $A004 ; _Control + lea NameTableEntry+7,A0 ; lowest byte of AddrBlock + move.b $1C(SP),(A0) ; save socket number there + add #$32,SP + + sub #$32,SP ; ADVERTISE NBP SERVICE + move.w #-10,$18(SP) ; ioRefNum = MPP + move.w #253,$1A(SP) ; csCode = registerName + move.b #7,$1C(SP) ; interval = 7*8 ticks = 1sec + move.b #5,$1D(SP) ; count = 5 + pea NameTableEntry + move.l (SP)+,$1E(SP) ; entityPtr = our NTE + move.b #1,$22(SP) ; verifyFlag = do + move.l SP,A0 + dc.w $A004 ; _Control + add #$32,SP + + rts + +NameTableEntry + dc.l 0 ; qLink + dc.l 0 ; addrblock + dc.b 0 ; odd address + dc.b 4, '0000' ; object + dc.b 10, 'BootServer' ; type + dc.b 1, '*' ; zone + even + +StopListening + sub #$32,SP ; REMOVE NBP SERVICE + move.w #-10,$18(SP) ; ioRefNum = MPP + move.w #252,$1A(SP) ; csCode = removeName + pea NameTableEntry + move.l (SP)+,$1E(SP) ; entityPtr = our NTE + move.l SP,A0 + dc.w $A004 ; _Control + add #$32,SP + + sub #$32,SP ; CLOSE DDP SOCKET + move.w #-10,$18(SP) ; ioRefNum = MPP + move.w 257,$1A(SP) ; csCode = closeSkt + move.b NameTableEntry+7,$1C(SP); socket = auto-assign + move.l SP,A0 + dc.w $A004 ; _Control + add #$32,SP + + rts + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +SocketListener ; DDP socket listener, very tricky piece of code! + dc.w $A9FF