mirror of
https://github.com/elliotnunn/NetBoot.git
synced 2024-12-22 01:30:18 +00:00
Streaming write support seems to work
This commit is contained in:
parent
c338a53575
commit
a0617e17a1
30
ChainBoot.py
30
ChainBoot.py
@ -36,6 +36,8 @@ image += bytes(5)
|
|||||||
image += b'Elliot'*10000 # padding, too much!
|
image += b'Elliot'*10000 # padding, too much!
|
||||||
image = append_snefru(image)
|
image = append_snefru(image)
|
||||||
|
|
||||||
|
writable_image = bytearray(open('A608.dsk', 'rb').read())
|
||||||
|
|
||||||
open('/tmp/imgdebug', 'wb').write(image)
|
open('/tmp/imgdebug', 'wb').write(image)
|
||||||
|
|
||||||
# typedef short (*j_code)( short command, # SP+4 (sign-extend to long)
|
# typedef short (*j_code)( short command, # SP+4 (sign-extend to long)
|
||||||
@ -93,6 +95,10 @@ def pstring(x):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
buf_sequence = -1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
while 1:
|
while 1:
|
||||||
data, addr = sock.recvfrom(1024)
|
data, addr = sock.recvfrom(1024)
|
||||||
|
|
||||||
@ -178,6 +184,7 @@ while 1:
|
|||||||
|
|
||||||
if len(data) < 2: continue
|
if len(data) < 2: continue
|
||||||
boot_type, boot_vers = struct.unpack_from('>BB', data)
|
boot_type, boot_vers = struct.unpack_from('>BB', data)
|
||||||
|
whole_data = data
|
||||||
data = data[2:]
|
data = data[2:]
|
||||||
|
|
||||||
# rbNullCommand EQU 0 ; ignore this one
|
# rbNullCommand EQU 0 ; ignore this one
|
||||||
@ -283,7 +290,7 @@ while 1:
|
|||||||
boot_blkcnt = min(boot_blkcnt, 32)
|
boot_blkcnt = min(boot_blkcnt, 32)
|
||||||
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 = writable_image[blk*512:blk*512+512]
|
||||||
sock.sendto(mk_ddp(
|
sock.sendto(mk_ddp(
|
||||||
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,
|
||||||
@ -292,6 +299,27 @@ while 1:
|
|||||||
),
|
),
|
||||||
(MCAST_ADDR, MCAST_PORT))
|
(MCAST_ADDR, MCAST_PORT))
|
||||||
|
|
||||||
|
elif boot_type == 130:
|
||||||
|
boot_type, blk, seq, hunk_start = struct.unpack_from('>BBHL', whole_data)
|
||||||
|
if seq != buf_sequence:
|
||||||
|
buf_sequence = seq
|
||||||
|
buf = bytearray(32*512)
|
||||||
|
|
||||||
|
putdata = whole_data[8:]
|
||||||
|
buf[(blk % 32) * 512:(blk % 32) * 512 + len(putdata)] = putdata
|
||||||
|
|
||||||
|
if blk & 0x80:
|
||||||
|
del buf[(blk % 32) * 512 + 512:]
|
||||||
|
writable_image[hunk_start*512:hunk_start*512+len(buf)] = buf
|
||||||
|
|
||||||
|
sock.sendto(mk_ddp(
|
||||||
|
dest_node=llap_src_node, dest_socket=ddp_src_socket,
|
||||||
|
src_node=99, src_socket=99,
|
||||||
|
proto_type=10,
|
||||||
|
data=struct.pack('>BBH', 131, 0, seq)
|
||||||
|
),
|
||||||
|
(MCAST_ADDR, MCAST_PORT))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print(f'ATBOOT type={boot_type} vers={boot_vers} contents={repr(data)}')
|
print(f'ATBOOT type={boot_type} vers={boot_vers} contents={repr(data)}')
|
||||||
|
|
||||||
|
130
ChainLoader.a
130
ChainLoader.a
@ -96,7 +96,7 @@ getBootBlocks
|
|||||||
lsl.l #4,D0
|
lsl.l #4,D0
|
||||||
swap D0
|
swap D0
|
||||||
move.l D0,$C(A3) ; dQDrvSz/dQDrvSz2
|
move.l D0,$C(A3) ; dQDrvSz/dQDrvSz2
|
||||||
move.l #$80080000,-4(A3) ; secret flags, see http://mirror.informatimago.com/next/developer.apple.com/documentation/mac/Files/Files-112.html
|
move.l #$00080000,-4(A3) ; secret flags, see http://mirror.informatimago.com/next/developer.apple.com/documentation/mac/Files/Files-112.html
|
||||||
move.w #1,4(A3) ; qType
|
move.w #1,4(A3) ; qType
|
||||||
move.w #0,$A(A3) ; dQFSID should be for a native fs
|
move.w #0,$A(A3) ; dQFSID should be for a native fs
|
||||||
|
|
||||||
@ -323,7 +323,7 @@ DrvrPrime
|
|||||||
|
|
||||||
|
|
||||||
DrvrSendRead
|
DrvrSendRead
|
||||||
; Called from Prime routine: PB/DCE in A0/A1 must be preserved (but we only require A0)
|
; Called from Prime routine or socket listener: PB/DCE in A0/A1 must be preserved (but we only require A0)
|
||||||
lea gExpectHdr,A2
|
lea gExpectHdr,A2
|
||||||
clr.w (A2)+
|
clr.w (A2)+
|
||||||
addq.w #1,(A2) ; packet filter sequence word
|
addq.w #1,(A2) ; packet filter sequence word
|
||||||
@ -390,17 +390,100 @@ DrvrDidSendRead
|
|||||||
rts ; TODO: set up a timeout/retry task
|
rts ; TODO: set up a timeout/retry task
|
||||||
|
|
||||||
|
|
||||||
DrvrSendFirstWrite
|
|
||||||
; yech...
|
|
||||||
; fall through...
|
|
||||||
|
|
||||||
DrvrSendWrite
|
DrvrSendWrite
|
||||||
nop
|
; Called from Prime routine or socket listener: PB/DCE in A0/A1 must be preserved (but we only require A0)
|
||||||
|
|
||||||
|
; D1 = block index within chunk
|
||||||
|
move.l $28(A0),D1
|
||||||
|
lsr.l #5,D1
|
||||||
|
lsr.l #4,D1
|
||||||
|
move.l D1,D0
|
||||||
|
and.l #32-1,D1
|
||||||
|
|
||||||
|
move.l $28(A0),D2
|
||||||
|
add.l #512,D2
|
||||||
|
cmp.l $24(A0),D2
|
||||||
|
bne.s .notLastBlock
|
||||||
|
bset #7,D1
|
||||||
|
.notLastBlock
|
||||||
|
|
||||||
|
; D0 = first block of chunk
|
||||||
|
and.l #-32,D0
|
||||||
|
add.l $2E(A0),D0
|
||||||
|
|
||||||
|
tst.l D1
|
||||||
|
bne.s .notFirstBlockOfChunk
|
||||||
|
lea gExpectHdr,A2
|
||||||
|
clr.w (A2)+
|
||||||
|
addq.w #1,(A2) ; packet filter sequence word
|
||||||
|
.notFirstBlockOfChunk
|
||||||
|
|
||||||
|
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.b #$82,(A2)+ ; Means a polite request
|
||||||
|
move.b D1,(A2)+ ; nth block of this chunk follows
|
||||||
|
move.w gExpectHdr+2,(A2)+
|
||||||
|
move.l D0,(A2)+ ; first block of this chunk
|
||||||
|
|
||||||
|
lea gWDS,A2
|
||||||
|
clr.w (A2)+ ; WDS+0: reserved field
|
||||||
|
pea gAddr
|
||||||
|
move.l (SP)+,(A2)+ ; WDS+2: pointer to address struct
|
||||||
|
|
||||||
|
move.w #8,(A2)+ ; WDS: push length/ptr of header
|
||||||
|
pea gQuery
|
||||||
|
move.l (SP)+,(A2)+
|
||||||
|
|
||||||
|
move.w #512,(A2)+ ; WDS: push length/ptr of body
|
||||||
|
move.l $20(A0),D0 ; ptr = ioBuffer
|
||||||
|
add.l $28(A0),D0 ; + ioActCount
|
||||||
|
move.l D0,(A2)+
|
||||||
|
|
||||||
|
clr.w (A2)+ ; WDS: end with zero
|
||||||
|
|
||||||
|
move.l A0,-(SP)
|
||||||
|
lea gMyPB,A0
|
||||||
|
bsr DrvrClearBlock
|
||||||
|
pea DrvrDidSendWrite
|
||||||
|
move.l (SP)+,$C(A0) ; ioCompletion
|
||||||
|
move.w #-10,$18(A0) ; ioRefNum = .MPP
|
||||||
|
move.w #246,$1A(A0) ; csCode = writeDDP
|
||||||
|
move.b #10,$1C(A0) ; socket = 10 (hardcoded)
|
||||||
|
move.b #1,$1D(A0) ; set checksumFlag
|
||||||
|
pea gWDS
|
||||||
|
move.l (SP)+,$1E(A0) ; wdsPointer to our WriteDataStructure
|
||||||
|
dc.w $A404 ; _Control ,async
|
||||||
|
move.l (SP)+,A0
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
DrvrDidSendWrite
|
DrvrDidSendWrite ; completion routine for the above control call..
|
||||||
nop
|
; need to test whether to send another, or switch to wait mode...
|
||||||
|
|
||||||
|
move.l gMyDCE,A0
|
||||||
|
move.l 6+2(A0),A0 ; A3 = dCtlQHdr.qHead = ParamBlk
|
||||||
|
|
||||||
|
movem.l $24(A0),D0/D1 ; D0=ioReqCount, D1=ioActCount
|
||||||
|
add.l #512,D1
|
||||||
|
move.l D1,$28(A0)
|
||||||
|
|
||||||
|
cmp.l D0,D1
|
||||||
|
beq.s .sentAllOfChunk
|
||||||
|
and.l #32-1,D0
|
||||||
|
beq.s .sentAllOfChunk
|
||||||
|
bra DrvrSendWrite
|
||||||
|
|
||||||
|
.sentAllOfChunk
|
||||||
|
rts ; TODO: set up a timeout/retry task
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -520,7 +603,7 @@ DrvrDidReceiveRead
|
|||||||
add.l #512,D0
|
add.l #512,D0
|
||||||
move.l D0,$28(A0)
|
move.l D0,$28(A0)
|
||||||
cmp.l $24(A0),D0
|
cmp.l $24(A0),D0
|
||||||
beq.s .ioDone
|
beq.s DrvrIODone
|
||||||
|
|
||||||
addq.l #1,D1 ; If bitmap=$FFFFFFFF then get the next chunk of 32
|
addq.l #1,D1 ; If bitmap=$FFFFFFFF then get the next chunk of 32
|
||||||
beq DrvrSendRead ; A0 must be the PB
|
beq DrvrSendRead ; A0 must be the PB
|
||||||
@ -528,7 +611,26 @@ DrvrDidReceiveRead
|
|||||||
rts ; Just return to await more packets.
|
rts ; Just return to await more packets.
|
||||||
|
|
||||||
|
|
||||||
.ioDone lea gExpectHdr,A1 ; Disable this socket listener
|
DrvrDidReceiveWrite
|
||||||
|
moveq.l #0,D3
|
||||||
|
jsr 2(A4) ; ReadRest (D3=0 i.e. discard)
|
||||||
|
|
||||||
|
move.l gMyDCE,A0
|
||||||
|
move.l 6+2(A0),A0 ; A3 = dCtlQHdr.qHead = ParamBlk
|
||||||
|
|
||||||
|
movem.l $24(A0),D0/D1 ; D0=ioReqCount, D1=ioActCount
|
||||||
|
cmp.l D0,D1
|
||||||
|
blo DrvrSendWrite
|
||||||
|
|
||||||
|
bra.s DrvrIODone
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DrvrIODone
|
||||||
|
lea gExpectHdr,A1 ; Disable this socket listener
|
||||||
clr.w (A1)
|
clr.w (A1)
|
||||||
|
|
||||||
move.l gMyDCE,A1
|
move.l gMyDCE,A1
|
||||||
@ -538,10 +640,6 @@ DrvrDidReceiveRead
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
DrvrDidReceiveWrite
|
|
||||||
move.w #$5555,D0
|
|
||||||
dc.w $A9C9
|
|
||||||
|
|
||||||
DrvrTrashPacket
|
DrvrTrashPacket
|
||||||
moveq.l #0,D3
|
moveq.l #0,D3
|
||||||
jmp 2(A4) ; ReadRest nothing
|
jmp 2(A4) ; ReadRest nothing
|
||||||
@ -581,7 +679,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 #$00080000,$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
|
||||||
|
Loading…
Reference in New Issue
Block a user