mirror of
https://github.com/elliotnunn/NetBoot.git
synced 2025-04-28 11:37:31 +00:00
New state-machine-based boot somewhat works
(For requests under 32b)
This commit is contained in:
parent
286ca935bf
commit
4a44f288c0
@ -200,7 +200,7 @@ while 1:
|
|||||||
# // while others are stored on disk by the boot server
|
# // while others are stored on disk by the boot server
|
||||||
# typedef struct
|
# typedef struct
|
||||||
# {
|
# {
|
||||||
# char serverName[serverNameLength]; // server name to boot off of
|
# char serverName[serverNameLength]; // server name to boot off of
|
||||||
# char serverZone[zoneNameLength]; // and the zone it lives in
|
# char serverZone[zoneNameLength]; // and the zone it lives in
|
||||||
# char serverVol[volNameLength]; // the volume name
|
# char serverVol[volNameLength]; // the volume name
|
||||||
# short serverAuthMeth; // authentication method to use (none, clear txt, rand)
|
# short serverAuthMeth; // authentication method to use (none, clear txt, rand)
|
||||||
@ -279,7 +279,7 @@ while 1:
|
|||||||
# break # wait for another request, you mofo!
|
# break # wait for another request, you mofo!
|
||||||
|
|
||||||
elif boot_type == 128:
|
elif boot_type == 128:
|
||||||
boot_seq, boot_blkoffset, boot_blkcnt, boot_imgname = struct.unpack_from('>HLL32p', data)
|
boot_seq, boot_blkoffset, boot_blkcnt = struct.unpack_from('>HLL', data); boot_imgname = b'A608.dsk'
|
||||||
boot_imgname = boot_imgname.decode('mac_roman')
|
boot_imgname = boot_imgname.decode('mac_roman')
|
||||||
for blk in range(boot_blkoffset, boot_blkoffset + boot_blkcnt):
|
for blk in range(boot_blkoffset, boot_blkoffset + boot_blkcnt):
|
||||||
thisblk = image2dict[boot_imgname][blk*512:blk*512+512]
|
thisblk = image2dict[boot_imgname][blk*512:blk*512+512]
|
||||||
@ -287,7 +287,7 @@ while 1:
|
|||||||
dest_node=llap_src_node, dest_socket=ddp_src_socket,
|
dest_node=llap_src_node, dest_socket=ddp_src_socket,
|
||||||
src_node=99, src_socket=99,
|
src_node=99, src_socket=99,
|
||||||
proto_type=10,
|
proto_type=10,
|
||||||
data=struct.pack('>BBHL', 129, 1, boot_seq, blk-boot_blkoffset) + thisblk
|
data=struct.pack('>BBH', 129, blk-boot_blkoffset, boot_seq) + thisblk
|
||||||
),
|
),
|
||||||
(MCAST_ADDR, MCAST_PORT))
|
(MCAST_ADDR, MCAST_PORT))
|
||||||
|
|
||||||
|
314
ChainLoader.a
314
ChainLoader.a
@ -1,6 +1,8 @@
|
|||||||
myUnitNum equ 52
|
myUnitNum equ 52
|
||||||
myDRefNum equ ~myUnitNum
|
myDRefNum equ ~myUnitNum
|
||||||
|
|
||||||
|
serverBufSize equ 32
|
||||||
|
|
||||||
|
|
||||||
Code
|
Code
|
||||||
cmp.l #1,4(SP)
|
cmp.l #1,4(SP)
|
||||||
@ -41,14 +43,14 @@ getBootBlocks
|
|||||||
move.w D0,7(A0) ; network
|
move.w D0,7(A0) ; network
|
||||||
|
|
||||||
; Patch the disk image name and size into the DRVR code
|
; Patch the disk image name and size into the DRVR code
|
||||||
bsr BootPicker ; A0 = pstring ptr
|
; bsr BootPicker ; A0 = pstring ptr
|
||||||
lea gNumBlks-DrvrBase(A2),A1
|
; lea gNumBlks-DrvrBase(A2),A1
|
||||||
move.l -4(A0),(A1) ; the size is underneath the pstring ptr
|
; move.l -4(A0),(A1) ; the size is underneath the pstring ptr
|
||||||
move.l -4(A0),D6 ; D6 = block count, needed for DQE
|
; move.l -4(A0),D6 ; D6 = block count, needed for DQE
|
||||||
lea gQFilename-DrvrBase(A2),A1 ; A1 = dest
|
; lea gQFilename-DrvrBase(A2),A1 ; A1 = dest
|
||||||
moveq.l #1,D0
|
; moveq.l #1,D0
|
||||||
add.b (A0),D0
|
; add.b (A0),D0
|
||||||
dc.w $A22E ; _BlockMoveData
|
; dc.w $A22E ; _BlockMoveData
|
||||||
|
|
||||||
; Install the driver in the unit table
|
; Install the driver in the unit table
|
||||||
move.l #myDRefNum,D0
|
move.l #myDRefNum,D0
|
||||||
@ -262,14 +264,10 @@ DrvrBase
|
|||||||
g
|
g
|
||||||
gNumBlks dc.l 0 ; the source of all truth
|
gNumBlks dc.l 0 ; the source of all truth
|
||||||
gMyDCE dc.l 0
|
gMyDCE dc.l 0
|
||||||
gQuery
|
gExpectHdr dc.l 0
|
||||||
gQTypeVer dc.w 0 ; part of gQuery
|
gProgress dc.l 0
|
||||||
gQSeqNum dc.w 0 ; part of gQuery
|
gQuery dcb.b 20 ; really need to consider the length of this!
|
||||||
gQOffset dc.l 0 ; part of gQuery: block offset
|
gWDS dcb.b 2+4+2+4+2+4+2 ; room for an address and two data chunks
|
||||||
gQLen dc.l 0 ; part of gQuery: block count
|
|
||||||
gQFilename dcb.b 32 ; part of gQuery ; set by the init code
|
|
||||||
gQueryEnd
|
|
||||||
gWDS dcb.b 2+4+2+4+2
|
|
||||||
gMyPB dcb.b $32+2 ; allow us to clear it with move.l's
|
gMyPB dcb.b $32+2 ; allow us to clear it with move.l's
|
||||||
odd
|
odd
|
||||||
gSaveAddr dcb.b 16
|
gSaveAddr dcb.b 16
|
||||||
@ -304,55 +302,72 @@ DrvrPrime
|
|||||||
ror.l #5,D0
|
ror.l #5,D0
|
||||||
move.l D0,$2E(A0) ; ioPosOffset = D0 = byte_offset/512
|
move.l D0,$2E(A0) ; ioPosOffset = D0 = byte_offset/512
|
||||||
|
|
||||||
; Increment the protocol sequence counter.
|
|
||||||
lea gQSeqNum,A2
|
|
||||||
addq.w #1,(A2)
|
|
||||||
|
|
||||||
; Kick the state machine.
|
|
||||||
movem.l A0-A1,-(SP)
|
|
||||||
bsr.s DrvrTransmitRequest ; takes A0 as PB argument
|
|
||||||
movem.l (SP)+,A0-A1
|
|
||||||
|
|
||||||
; Return with a "pending" ioResult.
|
; Return with a "pending" ioResult.
|
||||||
move.w #1,$10(A0) ; ioResult = pending. We will return without an answer.
|
move.w #1,$10(A0) ; ioResult = pending. We will return without an answer.
|
||||||
rts
|
|
||||||
|
; Wang the state machine!
|
||||||
|
cmp.b #2,7(A0) ; ioTrap == _Read?
|
||||||
|
bne DrvrSendWrite ; transition from "Idle" to "Await Comp Send Write Packet"
|
||||||
|
bra DrvrSendRead ; transition from "Idle" to "Await Comp Send Read Packet"
|
||||||
|
|
||||||
|
|
||||||
DrvrTransmitRequest ; On entry, A0=pb. Trashes A0-A4/D0 so be careful. Uses our globals extensively.
|
|
||||||
lea g,A2
|
|
||||||
|
|
||||||
move.b gSaveAddr-g(A2),gAddr-g(A2) ; reasonable way to copy the address struct, I guess
|
|
||||||
move.l gSaveAddr-g+1(A2),gAddr-g+1(A2)
|
|
||||||
move.l gSaveAddr-g+5(A2),gAddr-g+5(A2)
|
|
||||||
move.l gSaveAddr-g+9(A2),gAddr-g+9(A2)
|
|
||||||
move.w gSaveAddr-g+13(A2),gAddr-g+13(A2)
|
|
||||||
move.b gSaveAddr-g+15(A2),gAddr-g+15(A2)
|
|
||||||
|
|
||||||
move.w #$8001,gQTypeVer-g(A2) ; Means a polite request, v1
|
|
||||||
|
; Some wrappers for the routines below...
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DrvrSendRead
|
||||||
|
; Called from Prime routine: PB/DCE in A0/A1 must be preserved
|
||||||
|
lea gExpectHdr+2,A2
|
||||||
|
addq.w #1,(A2) ; packet filter sequence word
|
||||||
|
lea gProgress,A2
|
||||||
|
clr.l (A2)
|
||||||
|
|
||||||
|
lea gSaveAddr,A2
|
||||||
|
lea gAddr,A3
|
||||||
|
move.b (A2)+,(A3)+ ; copy the address struct, dang it!
|
||||||
|
move.l (A2)+,(A3)+
|
||||||
|
move.l (A2)+,(A3)+
|
||||||
|
move.l (A2)+,(A3)+
|
||||||
|
move.w (A2)+,(A3)+
|
||||||
|
move.b (A2)+,(A3)+
|
||||||
|
|
||||||
|
lea gQuery,A2
|
||||||
|
move.w #$8000,(A2)+ ; Means a polite request
|
||||||
|
move.w gExpectHdr+2,(A2)+
|
||||||
|
|
||||||
move.l $28(A0),D0 ; [ioActCount (in bytes)
|
move.l $28(A0),D0 ; [ioActCount (in bytes)
|
||||||
lsr.l #4,D0
|
lsr.l #4,D0
|
||||||
lsr.l #5,D0 ; / 512]
|
lsr.l #5,D0 ; / 512]
|
||||||
add.l $2E(A0),D0 ; + ioPosOffset (in blocks)
|
add.l $2E(A0),D0 ; + ioPosOffset (in blocks)
|
||||||
move.l D0,gQOffset-g(A2) ; -> "offset" field of request
|
move.l D0,(A2)+ ; -> "offset" field of request
|
||||||
|
|
||||||
move.l $24(A0),D0 ; [ioReqCount (in bytes)
|
move.l $24(A0),D0 ; [ioReqCount (in bytes)
|
||||||
sub.l $28(A0),D0 ; - ioActCount (in bytes)]
|
sub.l $28(A0),D0 ; - ioActCount (in bytes)]
|
||||||
lsr.l #4,D0
|
lsr.l #4,D0
|
||||||
lsr.l #5,D0 ; / 512
|
lsr.l #5,D0 ; / 512
|
||||||
move.l D0,gQLen-g(A2) ; -> "length" field of request
|
move.l D0,(A2)+ ; -> "length" field of request
|
||||||
|
|
||||||
lea gAddr,A3
|
lea gWDS,A2
|
||||||
clr.w gWDS-g(A2) ; WDS+0 reserved field
|
clr.w (A2)+ ; WDS+0: reserved field
|
||||||
move.l A3,gWDS-g+2(A2) ; WDS+2 pointer to address struct
|
pea gAddr
|
||||||
lea gQuery,A3
|
move.l (SP)+,(A2)+ ; WDS+2: pointer to address struct
|
||||||
move.w #gQueryEnd-gQuery,gWDS-g+6(A2) ; WDS+6 length of second entry
|
move.w #12,(A2)+ ; WDS: push pointer/length
|
||||||
move.l A3,gWDS-g+8(A2) ; WDS+8 pointer to second entry
|
pea gQuery
|
||||||
clr.w gWDS-g+12(A2) ; WDS+10 zero to end the list
|
move.l (SP)+,(A2)+
|
||||||
|
clr.w (A2)+ ; WDS: end with zero
|
||||||
|
|
||||||
|
move.l A0,-(SP)
|
||||||
lea gMyPB,A0
|
lea gMyPB,A0
|
||||||
.retry
|
|
||||||
bsr DrvrClearBlock
|
bsr DrvrClearBlock
|
||||||
|
pea DrvrDidSendRead
|
||||||
|
move.l (SP)+,$C(A0) ; ioCompletion
|
||||||
move.w #-10,$18(A0) ; ioRefNum = .MPP
|
move.w #-10,$18(A0) ; ioRefNum = .MPP
|
||||||
move.w #246,$1A(A0) ; csCode = writeDDP
|
move.w #246,$1A(A0) ; csCode = writeDDP
|
||||||
move.b #10,$1C(A0) ; socket = 10 (hardcoded)
|
move.b #10,$1C(A0) ; socket = 10 (hardcoded)
|
||||||
@ -360,25 +375,40 @@ DrvrTransmitRequest ; On entry, A0=pb. Trashes A0-A4/D0 so be careful. Uses our
|
|||||||
pea gWDS
|
pea gWDS
|
||||||
move.l (SP)+,$1E(A0) ; wdsPointer to our WriteDataStructure
|
move.l (SP)+,$1E(A0) ; wdsPointer to our WriteDataStructure
|
||||||
dc.w $A404 ; _Control ,async
|
dc.w $A404 ; _Control ,async
|
||||||
|
move.l (SP)+,A0
|
||||||
cmp.w #-91,$10(A0) ; This happens when the RAM MPP replaces the ROM one
|
|
||||||
bne.s .noNeedToRetry ; so we need to reopen socket #10, then retry...
|
|
||||||
|
|
||||||
bsr DrvrClearBlock
|
|
||||||
move.w #-10,$18(A0) ; ioRefNum = .MPP
|
|
||||||
move.w #248,$1A(A0) ; csCode = openSkt
|
|
||||||
move.b #10,$1C(A0) ; socket = 10 (hardcoded)
|
|
||||||
pea DrvrSockListener
|
|
||||||
move.l (SP)+,$1E(A0) ; listener
|
|
||||||
dc.w $A004 ; _Control (synchronous, better hope it doesn't deadlock!)
|
|
||||||
|
|
||||||
bra.s .retry
|
|
||||||
|
|
||||||
.noNeedToRetry
|
|
||||||
move.w $10(A0),D0 ; for our caller to figure out what went wrong
|
|
||||||
|
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
DrvrDidSendRead
|
||||||
|
; Called as completion routine: PB/result in A0/D0, must preserve all registers other than A0/A1/D0-D2
|
||||||
|
|
||||||
|
lea gExpectHdr,A2
|
||||||
|
move.w #$8100,(A2) ; Enable packet reception
|
||||||
|
|
||||||
|
rts ; TODO: set up a timeout/retry task
|
||||||
|
|
||||||
|
|
||||||
|
DrvrSendFirstWrite
|
||||||
|
; yech...
|
||||||
|
; fall through...
|
||||||
|
|
||||||
|
DrvrSendWrite
|
||||||
|
nop
|
||||||
|
|
||||||
|
|
||||||
|
DrvrDidSendWrite
|
||||||
|
nop
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DrvrClearBlock
|
DrvrClearBlock
|
||||||
move.w #$32/2-1,D0
|
move.w #$32/2-1,D0
|
||||||
.loop clr.w (A0)+
|
.loop clr.w (A0)+
|
||||||
@ -386,87 +416,123 @@ DrvrClearBlock
|
|||||||
lea -$32(A0),A0
|
lea -$32(A0),A0
|
||||||
rts
|
rts
|
||||||
|
|
||||||
DrvrSockListener ; works closely with the Prime routine
|
DrvrSockListener
|
||||||
; A0 Reserved for internal use by the .MPP driver. You must preserve this register until after the ReadRest routine has completed execution.
|
; Registers on call to DDP socket listener:
|
||||||
; A1 Reserved for internal use by the .MPP driver. You must preserve this register until after the ReadRest routine has completed execution.
|
; A0 Reserved for internal use by the .MPP driver. You must preserve this register
|
||||||
; A2 Pointer to the .MPP driver's local variables. Elliot says: the frame and packet header ("RHA") are at offset 1 from A2 (keeps the 2-byte fields aligned)
|
; until after the ReadRest routine has completed execution.
|
||||||
; A3 Pointer to the first byte in the RHA past the DDP header bytes (the first byte after the DDP protocol type field).
|
; A1 Reserved for internal use by the .MPP driver. You must preserve this register
|
||||||
; A4 Pointer to the ReadPacket routine. The ReadRest routine starts 2 bytes after the start of the ReadPacket routine.
|
; until after the ReadRest routine has completed execution.
|
||||||
; A5 Free for your use before and until your socket listener calls the ReadRest routine.
|
; A2 Pointer to the .MPP driver's local variables. Elliot says: the frame and packet
|
||||||
; D0 Lower byte is the destination socket number of the packet.
|
; header ("RHA") are at offset 1 from A2 (keeps the 2-byte fields aligned)
|
||||||
; D1 Word indicating the number of bytes in the DDP packet left to be read (that is, the number of bytes following the DDP header).
|
; A3 Pointer to the first byte in the RHA past the DDP header bytes (the first byte
|
||||||
; D2 Free for your use.
|
; after the DDP protocol type field).
|
||||||
; D3 Free for your use.
|
; A4 Pointer to the ReadPacket routine. The ReadRest routine starts 2 bytes after the
|
||||||
|
; start of the ReadPacket routine.
|
||||||
|
; A5 Free for your use before and until your socket listener calls the ReadRest routine.
|
||||||
|
; D0 Lower byte is the destination socket number of the packet.
|
||||||
|
; D1 Word indicating the number of bytes in the DDP packet left to be read (that is,
|
||||||
|
; the number of bytes following the DDP header).
|
||||||
|
; D2 Free for your use.
|
||||||
|
; D3 Free for your use.
|
||||||
|
|
||||||
|
; Registers on entry to the ReadPacket routine
|
||||||
|
; A3 Pointer to a buffer to hold the data you want to read
|
||||||
|
; D3 Number of bytes to read; must be nonzero
|
||||||
|
|
||||||
|
; Registers on exit from the ReadPacket routine
|
||||||
|
; A0 Unchanged
|
||||||
|
; A1 Unchanged
|
||||||
|
; A2 Unchanged
|
||||||
|
; A3 Address of the first byte after the last byte read into buffer
|
||||||
|
; A4 Unchanged
|
||||||
|
; D0 Changed
|
||||||
|
; D1 Number of bytes left to be read
|
||||||
|
; D2 Unchanged
|
||||||
|
; D3 Equals 0 if requested number of bytes were read, nonzero if error
|
||||||
|
|
||||||
|
; Registers on entry to the ReadRest routine
|
||||||
|
; A3 Pointer to a buffer to hold the data you want to read
|
||||||
|
; D3 Size of the buffer (word length); may be 0
|
||||||
|
|
||||||
|
; Registers on exit from the ReadRest routine
|
||||||
|
; A0 Unchanged
|
||||||
|
; A1 Unchanged
|
||||||
|
; A2 Unchanged
|
||||||
|
; A3 Pointer to first byte after the last byte read into buffer
|
||||||
|
; D0 Changed
|
||||||
|
; D1 Changed
|
||||||
|
; D2 Unchanged
|
||||||
|
; D3 Equals 0 if requested number of bytes exactly equaled the size of the buffer;
|
||||||
|
; less than 0 if more data was left than would fit in buffer (extra data equals
|
||||||
|
; -D3 bytes); greater than 0 if less data was left than the size of the buffer
|
||||||
|
; (extra buffer space equals D3 bytes)
|
||||||
|
|
||||||
|
; cmp.b #10,-1(A3) ; DDP protocol type better be ATBOOT
|
||||||
|
; bne.s DrvrTrashPacket
|
||||||
|
|
||||||
|
moveq.l #4,D3
|
||||||
|
jsr (A4) ; Read the nice short packet header
|
||||||
|
move.l -4(A3),D0
|
||||||
|
|
||||||
|
if 0
|
||||||
|
lea gExpectHdr,A5 ; Check the packet header
|
||||||
|
move.l (A5),D1
|
||||||
|
eor.l D0,D1
|
||||||
|
swap D1
|
||||||
|
clr.b D1
|
||||||
|
bne.s DrvrTrashPacket
|
||||||
|
endif
|
||||||
|
|
||||||
|
btst #25,D0
|
||||||
|
bne.s DrvrDidReceiveWrite
|
||||||
|
|
||||||
|
|
||||||
|
DrvrDidReceiveRead
|
||||||
|
swap D0 ; Confirm that this packet is not a dupe
|
||||||
|
and.w #32-1,D0
|
||||||
|
|
||||||
|
lea gProgress,A5
|
||||||
|
move.l (A5),D2
|
||||||
|
bset.l D0,D2
|
||||||
|
bne.s DrvrTrashPacket
|
||||||
|
move.l D2,(A5)
|
||||||
|
|
||||||
move.l gMyDCE,A5
|
move.l gMyDCE,A5
|
||||||
btst.b #7,5(A5) ; Check drvrActive flag (is there an outstanding request?)
|
|
||||||
beq .trashpacket
|
|
||||||
|
|
||||||
cmp.b #10,-1(A3) ; DDP protocol type better be ATBOOT
|
|
||||||
bne.s .trashpacket
|
|
||||||
|
|
||||||
moveq.l #8,D3
|
|
||||||
jsr (A4) ; Read 8 bytes
|
|
||||||
|
|
||||||
cmp.w #$8101,-8(A3) ; Check protocol and version
|
|
||||||
bne.s .trashpacket
|
|
||||||
|
|
||||||
lea gQSeqNum,A5 ; Check packet sequence number
|
|
||||||
move.w (A5),D2
|
|
||||||
cmp.w -6(A3),D2
|
|
||||||
bne.s .trashpacket
|
|
||||||
|
|
||||||
move.l gMyDCE,A5 ; Get current param block
|
|
||||||
move.l 6+2(A5),A5 ; dCtlQHdr.qHead
|
move.l 6+2(A5),A5 ; dCtlQHdr.qHead
|
||||||
|
|
||||||
move.l $28(A5),D2 ; keep this in D2 because we will use it in a sec
|
move.l $28(A5),D2 ; increment ioActCount, check ioReqCount
|
||||||
move.l -4(A3),D3
|
add.l #512,D2
|
||||||
lsl.l #4,D3
|
move.l D2,$28(A5)
|
||||||
lsl.l #5,D3
|
sub.l $24(A5),D2 ; D2 gets saved across the coming ReadRest call
|
||||||
cmp.l D3,D2 ; ioActCount = this offset?
|
|
||||||
bne.s .outoforder
|
|
||||||
|
|
||||||
move.l $20(A5),A3 ; ioBuffer
|
move.l $20(A5),A3 ; ioBuffer
|
||||||
add.l D2,A3 ; A3 = ioBuffer + ioReqDone
|
asl.w #5,D0
|
||||||
move.l #512,D3 ; D3 = bytes to read = 512
|
asl.w #4,D0
|
||||||
add.l D3,D2 ; D2 = new ioReqDone = old ioReqDone + 512
|
add.w D0,A3 ; A3 = ioBuffer + thisPackOffset
|
||||||
jsr 2(A4) ; ReadRest
|
move.l #512,D3 ; D3 = size
|
||||||
; From this point on, use A1 instead of A5
|
jsr 2(A4) ; ReadRest!
|
||||||
|
|
||||||
move.l gMyDCE,A1 ; Get current param block
|
tst.l D2
|
||||||
move.l 6+2(A1),A1 ; dCtlQHdr.qHead
|
beq.s .ioDone
|
||||||
|
rts
|
||||||
|
|
||||||
move.l D2,$28(A1) ; update ioActCount
|
.ioDone lea gExpectHdr,A1
|
||||||
cmp.l $24(A1),D2 ; does it equal ioReqCount?
|
clr.w (A1)
|
||||||
bne.s .rts
|
|
||||||
|
|
||||||
lea gMyDCE,A1
|
|
||||||
move.l (A1),A1
|
|
||||||
|
|
||||||
|
move.l gMyDCE,A1
|
||||||
moveq.l #0,D0
|
moveq.l #0,D0
|
||||||
move.l $8FC,A0 ; jIODone (D0 = result, A1 = DCE)
|
move.l $8FC,A0 ; jIODone (D0 = result, A1 = DCE)
|
||||||
jmp (A0)
|
jmp (A0)
|
||||||
|
|
||||||
|
|
||||||
.outoforder ; apparent dropped packet, so please resend
|
|
||||||
moveq.l #0,D3
|
|
||||||
jsr 2(A4) ; ReadRest nothing
|
|
||||||
|
|
||||||
movem.l A0-A4,-(SP)
|
DrvrDidReceiveWrite
|
||||||
move.l gMyDCE,A0 ; Get current param block
|
bsr DrvrDidReceiveWrite
|
||||||
move.l 6+2(A0),A0 ; dCtlQHdr.qHead
|
|
||||||
bsr DrvrTransmitRequest
|
|
||||||
movem.l (SP)+,A0-A4
|
|
||||||
|
|
||||||
rts
|
DrvrTrashPacket
|
||||||
|
|
||||||
.trashpacket
|
|
||||||
moveq.l #0,D3
|
moveq.l #0,D3
|
||||||
jmp 2(A4) ; ReadRest nothing
|
jmp 2(A4) ; ReadRest nothing
|
||||||
|
|
||||||
.rts
|
|
||||||
rts
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
DrvrControl
|
DrvrControl
|
||||||
@ -503,7 +569,7 @@ status_fmtLstCode ; tell them about our size
|
|||||||
status_drvStsCode ; tell them about some of our flags
|
status_drvStsCode ; tell them about some of our flags
|
||||||
move.w #0,$1C(A0) ; csParam[0..1] = track no (0)
|
move.w #0,$1C(A0) ; csParam[0..1] = track no (0)
|
||||||
move.l #$80080000,$1C+2(A0) ; csParam[2..5] = same flags as dqe
|
move.l #$80080000,$1C+2(A0) ; csParam[2..5] = same flags as dqe
|
||||||
|
|
||||||
move.w #0,$10(A0) ; ioResult = noErr
|
move.w #0,$10(A0) ; ioResult = noErr
|
||||||
bra DrvrFinish
|
bra DrvrFinish
|
||||||
|
|
||||||
|
@ -90,26 +90,20 @@ while 1:
|
|||||||
print('malformed short packet %r' % data.hex())
|
print('malformed short packet %r' % data.hex())
|
||||||
continue
|
continue
|
||||||
boot_type, boot_vers = struct.unpack_from('>BB', data)
|
boot_type, boot_vers = struct.unpack_from('>BB', data)
|
||||||
data = data[2:]
|
|
||||||
|
|
||||||
if boot_type == 1:
|
if boot_type == 1:
|
||||||
print(' ATBOOT "syn"', data.hex())
|
print(' ATBOOT "syn"', data[2:].hex())
|
||||||
elif boot_type == 2:
|
elif boot_type == 2:
|
||||||
print(' ATBOOT "ack"', data.hex())
|
print(' ATBOOT "ack"', data[2:].hex())
|
||||||
elif boot_type == 3:
|
elif boot_type == 3:
|
||||||
print(' ATBOOT image request', data.hex())
|
print(' ATBOOT image request', data[2:].hex())
|
||||||
elif boot_type == 4:
|
elif boot_type == 4:
|
||||||
print(' ATBOOT image reply', data.hex())
|
print(' ATBOOT image reply', data[2:].hex())
|
||||||
elif boot_type == 128:
|
elif boot_type >= 0x80:
|
||||||
a, b, c, d = struct.unpack_from('>HLL32p', data)
|
print(' ATBOOT Elliot', data.hex())
|
||||||
d = d.decode('mac_roman')
|
|
||||||
print(f' ATBOOT Elliot block seq={hex(a)} blkIdx={hex(b)} byteLen={hex(c)} img={repr(d)}')
|
|
||||||
elif boot_type == 129:
|
|
||||||
a, b = struct.unpack_from('>HL', data)
|
|
||||||
print(f' ATBOOT Elliot reply seq={hex(a)} relByteIdx={hex(b)}')
|
|
||||||
else:
|
else:
|
||||||
print(' ATBOOT', boot_type, boot_vers, data.hex())
|
print(' ATBOOT ???', boot_type, boot_vers, data[2:].hex())
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print('Totally unknown DDP type', ddp_proto_type)
|
print('Totally unknown DDP type', ddp_proto_type)
|
||||||
print(' ' + data.hex())
|
print(' ' + data.hex())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user