mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-26 16:49:18 +00:00
296 lines
8.7 KiB
Plaintext
296 lines
8.7 KiB
Plaintext
;__________________________________________________________________________________________________
|
|
;
|
|
; File: NewProto.a
|
|
;
|
|
; Contains: This is the socket listener for the new boot protocol. It handles packet reception.
|
|
; This works as follows:
|
|
;
|
|
; Call readrest to get packet, check size.
|
|
; Push parameters and call C routine to handle the world
|
|
;
|
|
; The whole listener works at interrupt time under tight time constraints. We want
|
|
; to assure that the workstation is not the gating factor in image throughput.
|
|
;
|
|
; This listener assumes that it has been initialized before being called for the first
|
|
; time. This includes setting up the buffers, reception bitmaps, and our pointer to them.
|
|
;
|
|
; Written by: Patrick Dyson
|
|
;
|
|
; Copyright © 1989, 1992 by Apple Computer, Inc. All rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM2> 11/5/92 SWC Changed ATalkEqu.a->AppleTalk.a.
|
|
; <3> 12/28/89 SWC Fixed the header and set tabs to 4.
|
|
; <2> 12/19/89 PD Adding to bbs
|
|
; <1.0> 10/30/89 PWD Adding to EASE
|
|
;__________________________________________________________________________________________________
|
|
|
|
PRINT OFF
|
|
INCLUDE 'AppleTalk.a' ; AppleTalk equates
|
|
INCLUDE 'Traps.a'
|
|
INCLUDE 'ATBootEqu.a' ; boot driver equates
|
|
PRINT ON
|
|
|
|
;
|
|
; void BootStorage(Ptr a)
|
|
;
|
|
BootStorage PROC EXPORT
|
|
|
|
MOVE.L (SP)+, A0 ; return address
|
|
MOVE.L (SP)+, BootStore ; save passed pointer there
|
|
JMP (A0)
|
|
ENDP
|
|
|
|
BootListen PROC EXPORT
|
|
IMPORT CheckBitmap
|
|
IMPORT SetBitmap
|
|
IMPORT getImageBuffer
|
|
IMPORT BufferPtr
|
|
IMPORT GoListener
|
|
IMPORT CLISTENER
|
|
|
|
MOVEM.L D4-D7, -(SP) ; save some work registers
|
|
CMP.B #BootDDPType,DDPType-DDPHSzLong(A3) ; make sure this is our ddp type
|
|
BNE.S @trash ; nope, just ignore pkt!
|
|
|
|
CMP.W #minPktSize, D1 ; make sure that we have at least enough
|
|
BMI.S @trash ; punt if not
|
|
;
|
|
; Pick up our globals pointer
|
|
;
|
|
MOVE.L BootStore, A5 ; should point to our globals
|
|
;
|
|
; Pick up the source address (net)(node)(socket) in D2.L
|
|
;
|
|
CMP.B #shortDDP,ToRHA+LAPType(A2) ; is this a short DDP hdr?
|
|
BNE.S @long ; branch for long header
|
|
|
|
MOVE.B ToRHA+LAPSrcAdr(A2),D2 ; stuff source node ID
|
|
SWAP D2
|
|
MOVE sysNetNum(A2),D2 ; use our built in net num for shorts
|
|
|
|
BRA.S @10 ; all done - go clean up
|
|
|
|
@long MOVE.B DDPSrcNode-DDPHSzLong(A3),D2 ; 'from' node ID
|
|
SWAP D2
|
|
MOVE DDPSrcNet-DDPHSzLong(A3),D2 ; 'from' xtend net ID
|
|
|
|
@10 SWAP D2 ; should be net<xx><node>
|
|
LSL.W #8, D2 ; up a byte net<node><xx>
|
|
MOVE.B DDPSrcSkt-DDPHSzLong(A3),D2 ; 'from' skt num net<node><skt>
|
|
;
|
|
; Get next couple of bytes of the packet...
|
|
;
|
|
MOVEQ.L #minPktSize,D3 ; count to read
|
|
SUB.L D3, SP ; make space for header
|
|
MOVE.L SP, A3 ; point for readpacket
|
|
JSR (A4) ; readpacket
|
|
;
|
|
MOVE (SP)+, D0 ; pop type and version
|
|
MOVE.L (SP)+, D5 ; (either OSID or imageID) and
|
|
; the block number or first two bytes of user data
|
|
SWAP D5
|
|
; now we have:
|
|
; D0.W <type><version>
|
|
; if it is an image data packet
|
|
; D5.L <Block #><imageID.W>
|
|
; -or-
|
|
; if it is a user record reply
|
|
; D5.L <UserData.W><imageID.W>
|
|
; -or-
|
|
; if it is a user record update reply
|
|
; D5.L <UserData.W><result>
|
|
|
|
TST D3 ; was there an error
|
|
BNE @gohome ; punt iff so
|
|
MOVE.B D0,D3 ; pick up version
|
|
CMP.B #packetVersion,D3 ; is it one we can deal with?
|
|
BGT.S @trash ; nope
|
|
LSR.W #8, D0 ; the type into the low byte
|
|
CMP.B #rbImageData, D0 ; is this one image data (most often.. )
|
|
BNE.S @doUserReply ; nope
|
|
;
|
|
; We have an image data packet
|
|
;
|
|
CMP.L server_addr(A5), D2 ; is this from a reasonable place?
|
|
BNE.S @trash
|
|
CMP.W bootImageID(A5), D5 ; is this for us?
|
|
BNE.S @trash
|
|
SWAP D5 ; get block number in low word
|
|
CMP.W lastBlockNo(A5), D5 ; is the block number in range?
|
|
BGT.S @trash
|
|
|
|
MOVE.L bitmapBase(A5),A3 ; get the image bitmap
|
|
MOVE.L A3,D6 ; save for setbitmap (being hopeful)
|
|
MOVE.W D5,D0 ; make D0 block number
|
|
BSR CheckBitmap ; have we received this one already?
|
|
BEQ.S @wantit ; branch if not
|
|
MOVE.L #-1,D0 ; indicate we didn't want this one
|
|
MOVE.L A5, D7 ; set up to pass globals pointer
|
|
JSR GoListener ; tell the C Glue
|
|
|
|
@trash MOVEM.L (SP)+, D4-D7 ; restore work registers
|
|
MOVEQ #0,D3 ; indicate we don't want this one
|
|
JMP 2(A4) ; let MPP do the work
|
|
|
|
@wantit MOVE.L imageBuffer(A5),D0 ; pick up image buffer area
|
|
BEQ.S @trash ; punt iff nil
|
|
MOVE.L D0,A3
|
|
MOVE.W D5,D0 ; D5.W block ID from above
|
|
BSR getImageBuffer ; returns buffer base address in A3
|
|
|
|
MOVE blockSize(A5),D3 ; pick up blocksize
|
|
MOVE.L A5, D7 ; save across readrest
|
|
|
|
JSR 2(A4) ; call readrest (puts image data directly in buffer )
|
|
BNE.S @gohome ; punt if error.
|
|
|
|
TST D3 ; > 0 if short packet
|
|
BGT.S @gohome
|
|
;
|
|
; We have read in the packet, now we do the protocol stuff (clear timers, set bitmap)
|
|
;
|
|
MOVE.L D6,A0 ; base address saved from above
|
|
MOVE.W D5, D0 ; D5 is the block number
|
|
JSR SetBitmap
|
|
|
|
CLR.L D0 ; 0 if a good packet & we kept it
|
|
JSR GoListener
|
|
BRA.S @gohome
|
|
|
|
@doUserReply
|
|
; D0.W ; type
|
|
; D3.B ; the version
|
|
; if it is a user record reply
|
|
; D5.L <UserData.W><imageID.W>
|
|
; -or-
|
|
; if it is a user record update reply
|
|
; D5.L <UserData.W><result>
|
|
; D2 ; the source address
|
|
; A5 ; our globals
|
|
;
|
|
; At this point, we have read the first six bytes of the packet and partially digested them.
|
|
CMP.B #rbUserRecordAck, D0 ; is this a user record update ack?
|
|
BEQ.S @doRecordAck ; deal with it
|
|
|
|
CMP #-1, bootImageID(A5) ; do we already have a user record?
|
|
BNE.S @trash ; then ignore this one
|
|
|
|
CMP.B #rbUserReply, D0 ; is this a cool packet?
|
|
BNE.S @trash ; nope
|
|
LEA readPacketArea(A5), A3 ; point to read area
|
|
;
|
|
; restore the packet that we have already read, then read the rest in
|
|
;
|
|
MOVE.B D0, (A3)+ ; pop the command
|
|
MOVE.B D3, (A3)+ ; and the version
|
|
SWAP D5 ; make it <imageID.W><UserData.W>
|
|
MOVE.L D5, (A3)+ ; the osID (machine ID)
|
|
; and the first two bytes of userdata
|
|
|
|
MOVE.L #ddpMaxData, D3 ; get whole packet
|
|
MOVE.L A5, D7 ; save A5 across readrest
|
|
|
|
JSR 2(A4) ; call readrest (count in D3)
|
|
BNE.S @gohome ; punt if error
|
|
|
|
MOVE.L D7, -(SP) ; push globals pointer
|
|
MOVE.L D2, -(SP) ; push source address
|
|
JSR CLISTENER
|
|
LEA 8(SP),SP ; clean up stack
|
|
|
|
@doRecordAck
|
|
@gohome MOVEM.L (SP)+, D4-D7 ; restore work registers
|
|
RTS ; cruise...
|
|
|
|
|
|
ENDP
|
|
|
|
GoListener PROC EXPORT
|
|
IMPORT DOIMAGEDATA
|
|
MOVE.L D0, -(SP) ; push good/bad packet flag
|
|
MOVE.L D7, -(SP) ; push globals
|
|
; MOVE.L D4, -(SP) ; block number (already long extended)
|
|
JSR DOIMAGEDATA ; do that protocol thing
|
|
LEA 8(SP),SP ; clean up stack
|
|
RTS
|
|
ENDP
|
|
|
|
;-----------------------------------------------------------------------------------
|
|
; procedure CheckBitmap
|
|
;
|
|
; On entry :
|
|
; A3 -> bitmap base address
|
|
; D0.W -> bit number to check (true if zero), corresponds to block number
|
|
;
|
|
; A5 -> globals
|
|
;
|
|
; On Exit
|
|
; Z bit set if bitmap bit set (already received packet)
|
|
;
|
|
; ALL REGISTERS PRESERVED
|
|
;
|
|
|
|
CheckBitmap PROC EXPORT
|
|
MOVEM.L D1, -(SP) ; save those registers
|
|
MOVE.W D0,D1 ; copy bit number for index
|
|
LSR.W #3,D0 ; make a byte index
|
|
BTST.B D1,($0,A3,D0.W) ; check that bit! (D1 modulo 8)
|
|
MOVEM.L (SP)+,D1 ; restore that D1 (ccr's NOT set)
|
|
RTS
|
|
ENDP
|
|
|
|
;-----------------------------------------------------------------------------------
|
|
; procedure SetBitmap
|
|
;
|
|
; On entry :
|
|
; A0 -> bitmap base address
|
|
; D0 -> bit number to set, corresponds to block number
|
|
;
|
|
; On Exit
|
|
;
|
|
; Trashes D0, D1
|
|
;
|
|
|
|
SetBitmap PROC EXPORT
|
|
MOVE.W D0,D1 ; copy bit number for index
|
|
LSR.W #3,D0 ; make a byte index
|
|
BSET.B D1,($0,A0,D0.W) ; check that bit! (D1 modulo 8)
|
|
RTS
|
|
ENDP
|
|
|
|
;-----------------------------------------------------------------------------------
|
|
; procedure getImageBuffer
|
|
;
|
|
; On Entry:
|
|
; A3 -> image buffer base address
|
|
; D0.W -> block number to return base address of
|
|
;
|
|
; A5 -> globals
|
|
;
|
|
; On Exit
|
|
; A3 -> base address of buffer
|
|
;
|
|
; ALL REGISTERS PRESERVED except A3
|
|
;
|
|
|
|
getImageBuffer PROC EXPORT
|
|
MOVE.L D0, -(SP)
|
|
MULU blockSize(A5), D0 ; pick up blocksize, make offset
|
|
|
|
ADD.L D0, A3 ; make into an address
|
|
|
|
MOVE.L (SP)+, D0 ; restore D0
|
|
RTS
|
|
ENDP
|
|
|
|
BufferPtr PROC EXPORT
|
|
|
|
dude DC.L 0 ; to store our globals off of
|
|
|
|
ENDP
|
|
|
|
|
|
END
|