mirror of
https://github.com/elliotnunn/tbxi-patches.git
synced 2025-03-03 04:29:41 +00:00
Definitive ATABoot patch
Key realisations: 1. The driver entry point only needs to be called once per disk, not once per bootable partition. Bootability is decided elsewhere. 2. As a result, my shim code does not need to access the disk at all. 3. None of the ROM-based ATADisk drivers support "slave" drives. 4. Apple drivers (contrary to the Monster Disk Driver Technote) only care about D5 (the drive ID and some flags) on entry.
This commit is contained in:
parent
9351898fb5
commit
a8c1a4de1c
299
ATALoad.a
299
ATALoad.a
@ -1,6 +1,5 @@
|
||||
; Asm ATALoad.a -o ATALoad.a.o; DumpObj ATALoad.a.o > ATALoad.dmp
|
||||
; The python script does the rest.
|
||||
; This is messy and brittle. I got very, very sick of it!
|
||||
|
||||
MAIN
|
||||
MACHINE MC68030
|
||||
@ -12,6 +11,11 @@
|
||||
bsr.s OriginalFunc ; ... and call the function
|
||||
add.l #$C,sp ; pop those copied arguments, we don't need them
|
||||
|
||||
; move.l d0,-(sp)
|
||||
; move.l d0,a0
|
||||
; bsr PrintHex
|
||||
; move.l (sp)+,d0
|
||||
|
||||
cmp.l #$FFFFDB93,d0 ; ATANoDriverErr -> try our method
|
||||
beq.s NewFunc
|
||||
cmp.l #$FFFFDB92,d0 ; ATANoDDMErr -> try our method
|
||||
@ -21,247 +25,68 @@
|
||||
|
||||
OriginalFunc
|
||||
string asis
|
||||
dc.b 'Nsrt' ; placeholder for script to insert the clobbered LINK instruction
|
||||
bra *+2+'ID' ; placeholder for script to jump to remainder of original function
|
||||
|
||||
|
||||
|
||||
var_regs equ -$4FA
|
||||
|
||||
ataPB equ -$4DA ; to
|
||||
ataPBQType equ -$4D6
|
||||
ataPBVers equ -$4D4
|
||||
ataPBReserved2 equ -$4CE
|
||||
ataPBFunctionCode equ -$4C8
|
||||
ataPBIOSpeed equ -$4C7
|
||||
ataPBFlags equ -$4C6
|
||||
ataPBDeviceID equ -$4C2
|
||||
ataPBTimeOut equ -$4BE
|
||||
ataPBState equ -$4B2
|
||||
|
||||
; common part of PB ends at offset $30 = -$4AA
|
||||
; this part below is a bit tricky...
|
||||
|
||||
ataPB34 equ -$4A6 ; 34
|
||||
ataPB38 equ -$4A2 ; 38
|
||||
ataPB3C equ -$49E ; 3c
|
||||
ataPB40 equ -$49A ; 40
|
||||
|
||||
; -492...-48A = "task file"
|
||||
|
||||
ataPBTaskFile_ataTFCount equ -$491
|
||||
ataPBTaskFile_ataTFSDH equ -$48C
|
||||
ataPBTaskFile_ataTFCommand equ -$48B
|
||||
|
||||
; entire PB ends at offset $30 = -$4AA
|
||||
|
||||
; max possible PB size ends at $B8 = -$422
|
||||
|
||||
var_bstruct_0 equ -$422
|
||||
var_bstruct_2 equ -$420
|
||||
var_bstruct_4 equ -$41E
|
||||
var_bstruct_6 equ -$41C
|
||||
|
||||
var_ddmidx equ -$41A
|
||||
var_drvrcnt equ -$418
|
||||
var_arg2 equ -$40E
|
||||
var_ddmptr equ -$40C
|
||||
|
||||
var_buf1 equ -$408
|
||||
var_buf2 equ -$208
|
||||
|
||||
var_flags equ -8
|
||||
var_4 equ -4
|
||||
|
||||
arg_dev equ 8
|
||||
arg_ddtype equ $C ; a long
|
||||
arg_romdrvr equ $10
|
||||
dc.b 'Nsrt' ; LINKER SCRIPT
|
||||
bra *+2+'ID' ; LINKER SCRIPT
|
||||
|
||||
|
||||
NewFunc
|
||||
link a6,#-$4DA
|
||||
movem.l d3-d7/a2-a4,-(sp)
|
||||
link a6,#-4
|
||||
movem.l d5,-4(a6)
|
||||
|
||||
; 16(a6).L = !AfterSystemStartupTime
|
||||
; 12(a6).L = $0701, the DDMap ID for a Mac driver
|
||||
; 8(a6).L = device ID (i.e. devNum<<8 | busNum)
|
||||
|
||||
; move.l 16(a6),a0
|
||||
; bsr PrintHex
|
||||
; move.l 12(a6),a0
|
||||
; bsr PrintHex
|
||||
; move.l 8(a6),a0
|
||||
; bsr PrintHex
|
||||
|
||||
cmp.w #$0701,12+2(a6)
|
||||
bne.s @fail
|
||||
|
||||
move.l #'Size',d0 ; LINKER SCRIPT
|
||||
dc.w $A51E ; _NewPtrSys
|
||||
tst.l A0
|
||||
beq.s @fail
|
||||
|
||||
move.l a0,a1
|
||||
lea *+2+'At',a0 ; LINKER SCRIPT
|
||||
move.l #'Size',d0 ; LINKER SCRIPT
|
||||
dc.w $A02E ; _BlockMove
|
||||
|
||||
move.l 8(a6),d5 ; put device number in this byte
|
||||
and.l #$0000FF00,d5
|
||||
|
||||
move.l 8(a6),d0 ; put bus number in this byte
|
||||
swap d0
|
||||
and.l #$00FF0000,d0
|
||||
or.l d0,d5
|
||||
|
||||
tst.b 16+3(a6)
|
||||
bne.s @rom
|
||||
bset.l #31,d5 ; kAfterSystemStartupTime
|
||||
@rom
|
||||
|
||||
jsr 8(a0) ; ATAMgr v2 entry point
|
||||
; never mind the spec, only set d5
|
||||
|
||||
; move.l d0,a0
|
||||
; bsr PrintHex
|
||||
|
||||
bra.s @return
|
||||
|
||||
@fail
|
||||
move.l #$FFFFDB93,d0
|
||||
@return
|
||||
movem.l -4(a6),d5
|
||||
unlk a6
|
||||
rts
|
||||
|
||||
|
||||
; Wipe the stack frame to be safe
|
||||
lea -$4DA(A6),A0
|
||||
@lup clr.w (A0)+
|
||||
cmp.l A0,A6
|
||||
bne.s @lup
|
||||
|
||||
; Check that we are asked for an ATA driver
|
||||
cmp.l #$00000701,arg_ddtype(a6) ; kDriverTypeMacATA
|
||||
bne itr_fail
|
||||
|
||||
; Load the actual working driver
|
||||
move.w #$FFFF,$B9E ; temp ROMMapInsert
|
||||
move.l #'DRVR',-(SP)
|
||||
move.w #53,-(SP) ; .ATADisk
|
||||
dc.w $A9A0
|
||||
movea.l (SP)+,A2
|
||||
tst.l A2
|
||||
beq itr_fail
|
||||
movea.l (A2),A2
|
||||
|
||||
; Set pointers to the 512-byte scratch buffer and the param block
|
||||
lea var_buf1(a6),a3
|
||||
lea ataPB(a6),a4
|
||||
|
||||
; Set bit 31 ("RAM based driver at run time") in the d5 passed to DRVR
|
||||
move.l #0,var_flags(a6)
|
||||
tst.b arg_romdrvr+3(a6)
|
||||
bne.s is_romdrvr
|
||||
ori.b #$80,var_flags(a6) ; set the flag
|
||||
is_romdrvr:
|
||||
|
||||
; Get the "IDENTIFY DEVICE" block with CHS information
|
||||
move.l #0, $00(a4) ; ataPBLink
|
||||
move.w #0, $04(a4) ; ataPBQType
|
||||
move.b #2, $06(a4) ; --> ataPBVers
|
||||
move.b #0, $13(a4) ; --> ataPBIOSpeed
|
||||
move.w arg_dev+2(a6),d1
|
||||
ext.l d1
|
||||
move.l d1, $18(a4) ; --> ataPBDeviceID
|
||||
move.l #0, $08(a4) ; ? ataPBReserved2
|
||||
move.l #20000,$1C(a4) ; --> ataPBTimeOut
|
||||
move.b #$13, $12(a4) ; --> ataPBFunctionCode = kATAMgrDriveIdentify
|
||||
move.w #$2000,$14(a4) ; --> ataPBFlags = mATAFlagIORead
|
||||
move.w #0, $28(a4) ; ? ataPBState
|
||||
move.l a3, $38(a4) ; ataPBBuffer
|
||||
|
||||
sub.l #2,sp
|
||||
move.l a4,-(sp)
|
||||
dc.w $AAF1 ; ATAManager
|
||||
move.w (sp)+,d0
|
||||
ext.l d0
|
||||
bne itr_return
|
||||
|
||||
; Parse the "IDENTIFY DEVICE" block
|
||||
move.w 2(a3),var_bstruct_0(a6) ; typically 1041
|
||||
move.w 6(a3),var_bstruct_2(a6) ; typically 0010
|
||||
move.w $C(a3),var_bstruct_4(a6) ; typically 003f
|
||||
move.w var_bstruct_2(a6),d0 ; can't safely get rid of these for some reason!
|
||||
mulu.w var_bstruct_4(a6),d0
|
||||
move.w d0,var_bstruct_6(a6)
|
||||
|
||||
; Send "Init drive parameters"
|
||||
move.b #$1, $12(a4) ; --> ataPBFunctionCode = IO (not in headers)
|
||||
move.w #0, $14(a4) ; --> ataPBFlags
|
||||
move.w #0, $28(a4) ; ? ataPBState
|
||||
move.b #$91, $48+$7(a4) ; ataPBTaskFile.ataTFCommand = kATAcmdInitDrive
|
||||
move.l arg_dev(a6),d0 ; (leaving bit $40 as zero for CHS)
|
||||
lsr.l #4,d0
|
||||
and.l #$10,d0 ; master/slave bit
|
||||
or.l #$A0,d0 ; sector size ? 512
|
||||
move.w var_bstruct_2(a6),d1
|
||||
sub.w #1,d1
|
||||
or.w d1,d0 ; head number
|
||||
move.b d0, $48+$6(a4) ; ataPBTaskFile.ataTFSDH
|
||||
move.b var_bstruct_4+1(a6),$48+$1(a4); ataPBTaskFile.ataTFCount
|
||||
|
||||
sub.l #2,sp
|
||||
move.l a4,-(sp)
|
||||
dc.w $AAF1 ; ATAManager
|
||||
move.w (sp)+,d0
|
||||
|
||||
; Loop over all partitions, ask the driver to pick a bootable one
|
||||
move.w #$2000,ataPBFlags(a6)
|
||||
move.l #$200,ataPB34(a6)
|
||||
move.b #$20,ataPBTaskFile_ataTFCommand(a6)
|
||||
move.l #1,d5 ; Initially check only one partition, increase this number later
|
||||
moveq #0,d6 ; Partition index counter
|
||||
tellDriverAboutPartitionLoop:
|
||||
|
||||
move.l d6,d0
|
||||
addq.l #1,d6
|
||||
cmp.l d0,d5
|
||||
bcs.s itr_fail
|
||||
move.l a3,ataPB38(a6)
|
||||
move.l #$200,ataPB3C(a6)
|
||||
move.b #1,ataPBTaskFile_ataTFCount(a6)
|
||||
pea var_bstruct_0(a6)
|
||||
move.l d6,-(sp)
|
||||
pea ataPB(a6)
|
||||
bsr paramblk_helper_function
|
||||
subq.l #2,sp
|
||||
pea ataPB(a6)
|
||||
dc.w $AAF1 ;;;;;;;;;;;;;;;;;;;;;;;;; kATAcmdRead again (get next PM entry)
|
||||
move.w (sp)+,d7
|
||||
lea $C(sp),sp
|
||||
moveq #0,d0
|
||||
move.w (a3),d0
|
||||
cmpi.l #'PM',d0
|
||||
bne.s tellDriverAboutPartitionLoop
|
||||
move.l 4(a3),d5 ; update the *real* number of partitions, so we don't end early
|
||||
move.l var_flags(a6),-(sp) ; var_flags, obviously
|
||||
move.w var_arg2(a6),d0
|
||||
ext.l d0
|
||||
move.l d0,-(sp) ; arg_dev+2 extended to a long, pretty much always zero
|
||||
move.l a3,-(sp) ; pointer to this partition map entry
|
||||
move.l a2,-(sp) ; pointer to driver
|
||||
bsr *+2+'BT' ; BOOT function
|
||||
move.l d0,d4
|
||||
|
||||
lea $10(sp),sp
|
||||
move.w d4,d7 ; -1 means try a different partition, 0 means succes, otherwise error
|
||||
cmpi.w #$FFFF,d7
|
||||
beq.s tellDriverAboutPartitionLoop
|
||||
|
||||
tst.w d7
|
||||
bne.s itr_fail
|
||||
|
||||
move.l d4,d0 ; the final pathway for success
|
||||
bra.s itr_return
|
||||
|
||||
itr_fail:
|
||||
move.l #$FFFFDB93,d0 ; ATANoDriverErr
|
||||
|
||||
itr_return:
|
||||
movem.l var_regs(a6),d3-d7/a2-a4
|
||||
unlk a6
|
||||
rts
|
||||
|
||||
|
||||
paramblk_helper_function:
|
||||
link a6,#0
|
||||
movem.l d6-d7/a3-a4,-(sp)
|
||||
move.l $C(a6),d7
|
||||
movea.l $10(a6),a3
|
||||
movea.l $8(a6),a4
|
||||
move.l $18(a4),d0
|
||||
lsr.l #8,d0
|
||||
moveq #1,d6
|
||||
and.l d0,d6
|
||||
clr.w $28(a4)
|
||||
moveq #0,d0
|
||||
move.w 6(a3),d0
|
||||
move.l d7,d1
|
||||
divu.l d0,d1
|
||||
move.w d1,$4C(a4)
|
||||
moveq #0,d0
|
||||
move.w 4(a3),d0
|
||||
move.l d7,d1
|
||||
divu.l d0,d1
|
||||
moveq #0,d0
|
||||
move.w 2(a3),d0
|
||||
tst.l d0
|
||||
tdivs.l d0,d2:d1
|
||||
moveq #$F,d0
|
||||
and.l d2,d0
|
||||
move.b d0,$4E(a4)
|
||||
move.l d6,d0
|
||||
lsl.l #4,d0
|
||||
or.b d0,$4E(a4)
|
||||
ori.b #$A0,$4E(a4)
|
||||
moveq #0,d0
|
||||
move.w 4(a3),d0
|
||||
move.l d7,d1
|
||||
tdivu.l d0,d2:d1
|
||||
addq.b #1,d2
|
||||
move.b d2,$4A(a4)
|
||||
movem.l -$10(a6),d6-d7/a3-a4
|
||||
unlk a6
|
||||
rts
|
||||
END
|
||||
|
||||
|
||||
string c
|
||||
|
184
ATALoad.dmp
184
ATALoad.dmp
@ -11,7 +11,7 @@ Pad
|
||||
Module: Flags=$10=(Main Local Code) Module="#0001"(1) Segment="Main"(2)
|
||||
|
||||
Content: Flags $08
|
||||
Contents offset $0000 size $0236
|
||||
Contents offset $0000 size $008E
|
||||
00000000: 41EF 0010 'A...' LEA $0010(A7),A0
|
||||
00000004: 2F20 '/ ' MOVE.L -(A0),-(A7)
|
||||
00000006: 2F20 '/ ' MOVE.L -(A0),-(A7)
|
||||
@ -26,161 +26,35 @@ Contents offset $0000 size $0236
|
||||
00000022: 4E73 'Ns' RTE
|
||||
00000024: 7274 'rt' MOVEQ #$74,D1 ; 't'
|
||||
00000026: 6000 4944 '`.ID' BRA *+$4946 ; 0000496C
|
||||
0000002A: 4E56 FB26 'NV.&' LINK A6,#$FB26
|
||||
0000002E: 48E7 1F38 'H..8' MOVEM.L D3-D7/A2-A4,-(A7)
|
||||
00000032: 41EE FB26 'A..&' LEA -$04DA(A6),A0
|
||||
00000036: 4258 'BX' CLR.W (A0)+
|
||||
00000038: BDC8 '..' CMPA.L A0,A6
|
||||
0000003A: 66FA 'f.' BNE.S *-$0004 ; 00000036
|
||||
0000003C: 0CAE 0000 0701 '......' CMPI.L #$00000701,$000C(A6)
|
||||
000C
|
||||
00000044: 6600 0164 'f..d' BNE *+$0166 ; 000001AA
|
||||
00000048: 31FC FFFF 0B9E '1.....' MOVE.W #$FFFF,$0B9E
|
||||
0000004E: 2F3C 4452 5652 '/<DRVR' MOVE.L #$44525652,-(A7) ; 'DRVR'
|
||||
00000054: 3F3C 0035 '?<.5' MOVE.W #$0035,-(A7)
|
||||
00000058: A9A0 '..' _GetResource ; A9A0
|
||||
0000005A: 245F '$_' MOVEA.L (A7)+,A2
|
||||
0000005C: 4A8A 'J.' TST.L A2
|
||||
0000005E: 6700 014A 'g..J' BEQ *+$014C ; 000001AA
|
||||
00000062: 2452 '$R' MOVEA.L (A2),A2
|
||||
00000064: 47EE FBF8 'G...' LEA -$0408(A6),A3
|
||||
00000068: 49EE FB26 'I..&' LEA -$04DA(A6),A4
|
||||
0000006C: 42AE FFF8 'B...' CLR.L -$0008(A6)
|
||||
00000070: 4A2E 0013 'J...' TST.B $0013(A6)
|
||||
00000074: 6606 'f.' BNE.S *+$0008 ; 0000007C
|
||||
00000076: 002E 0080 FFF8 '......' ORI.B #$80,-$0008(A6)
|
||||
0000007C: 4294 'B.' CLR.L (A4)
|
||||
0000007E: 426C 0004 'Bl..' CLR.W $0004(A4)
|
||||
00000082: 197C 0002 0006 '.|....' MOVE.B #$02,$0006(A4)
|
||||
00000088: 422C 0013 'B,..' CLR.B $0013(A4)
|
||||
0000008C: 322E 000A '2...' MOVE.W $000A(A6),D1
|
||||
00000090: 48C1 'H.' EXT.L D1
|
||||
00000092: 2941 0018 ')A..' MOVE.L D1,$0018(A4)
|
||||
00000096: 42AC 0008 'B...' CLR.L $0008(A4)
|
||||
0000009A: 297C 0000 4E20 ')|..N ' MOVE.L #$00004E20,$001C(A4)
|
||||
001C
|
||||
000000A2: 197C 0013 0012 '.|....' MOVE.B #$13,$0012(A4)
|
||||
000000A8: 397C 2000 0014 '9| ...' MOVE.W #$2000,$0014(A4)
|
||||
000000AE: 426C 0028 'Bl.(' CLR.W $0028(A4)
|
||||
000000B2: 294B 0038 ')K.8' MOVE.L A3,$0038(A4)
|
||||
000000B6: 558F 'U.' SUBQ.L #$2,A7
|
||||
000000B8: 2F0C '/.' MOVE.L A4,-(A7)
|
||||
000000BA: AAF1 '..' DC.W $AAF1 ; TB 02F1
|
||||
000000BC: 301F '0.' MOVE.W (A7)+,D0
|
||||
000000BE: 48C0 'H.' EXT.L D0
|
||||
000000C0: 6600 00EE 'f...' BNE *+$00F0 ; 000001B0
|
||||
000000C4: 3D6B 0002 FBDE '=k....' MOVE.W $0002(A3),-$0422(A6)
|
||||
000000CA: 3D6B 0006 FBE0 '=k....' MOVE.W $0006(A3),-$0420(A6)
|
||||
000000D0: 3D6B 000C FBE2 '=k....' MOVE.W $000C(A3),-$041E(A6)
|
||||
000000D6: 302E FBE0 '0...' MOVE.W -$0420(A6),D0
|
||||
000000DA: C0EE FBE2 '....' MULU.W -$041E(A6),D0
|
||||
000000DE: 3D40 FBE4 '=@..' MOVE.W D0,-$041C(A6)
|
||||
000000E2: 197C 0001 0012 '.|....' MOVE.B #$01,$0012(A4)
|
||||
000000E8: 426C 0014 'Bl..' CLR.W $0014(A4)
|
||||
000000EC: 426C 0028 'Bl.(' CLR.W $0028(A4)
|
||||
000000F0: 197C 0091 004F '.|...O' MOVE.B #$91,$004F(A4)
|
||||
000000F6: 202E 0008 ' ...' MOVE.L $0008(A6),D0
|
||||
000000FA: E888 '..' LSR.L #$4,D0
|
||||
000000FC: 0280 0000 0010 '......' ANDI.L #$00000010,D0
|
||||
00000102: 0080 0000 00A0 '......' ORI.L #$000000A0,D0
|
||||
00000108: 322E FBE0 '2...' MOVE.W -$0420(A6),D1
|
||||
0000010C: 5341 'SA' SUBQ.W #$1,D1
|
||||
0000010E: 8041 '.A' OR.W D1,D0
|
||||
00000110: 1940 004E '.@.N' MOVE.B D0,$004E(A4)
|
||||
00000114: 196E FBE3 0049 '.n...I' MOVE.B -$041D(A6),$0049(A4)
|
||||
0000011A: 558F 'U.' SUBQ.L #$2,A7
|
||||
0000011C: 2F0C '/.' MOVE.L A4,-(A7)
|
||||
0000011E: AAF1 '..' DC.W $AAF1 ; TB 02F1
|
||||
00000120: 301F '0.' MOVE.W (A7)+,D0
|
||||
00000122: 3D7C 2000 FB3A '=| ..:' MOVE.W #$2000,-$04C6(A6)
|
||||
00000128: 2D7C 0000 0200 '-|....' MOVE.L #$00000200,-$04A6(A6)
|
||||
FB5A
|
||||
00000130: 1D7C 0020 FB75 '.|. .u' MOVE.B #$20,-$048B(A6) ; ' '
|
||||
00000136: 7A01 'z.' MOVEQ #$01,D5
|
||||
00000138: 7C00 '|.' MOVEQ #$00,D6
|
||||
0000013A: 2006 ' .' MOVE.L D6,D0
|
||||
0000013C: 5286 'R.' ADDQ.L #$1,D6
|
||||
0000013E: BA80 '..' CMP.L D0,D5
|
||||
00000140: 6568 'eh' BCS.S *+$006A ; 000001AA
|
||||
00000142: 2D4B FB5E '-K.^' MOVE.L A3,-$04A2(A6)
|
||||
00000146: 2D7C 0000 0200 '-|....' MOVE.L #$00000200,-$049E(A6)
|
||||
FB62
|
||||
0000014E: 1D7C 0001 FB6F '.|...o' MOVE.B #$01,-$0491(A6)
|
||||
00000154: 486E FBDE 'Hn..' PEA -$0422(A6)
|
||||
00000158: 2F06 '/.' MOVE.L D6,-(A7)
|
||||
0000015A: 486E FB26 'Hn.&' PEA -$04DA(A6)
|
||||
0000015E: 6100 005A 'a..Z' BSR *+$005C ; 000001BA
|
||||
00000162: 558F 'U.' SUBQ.L #$2,A7
|
||||
00000164: 486E FB26 'Hn.&' PEA -$04DA(A6)
|
||||
00000168: AAF1 '..' DC.W $AAF1 ; TB 02F1
|
||||
0000016A: 3E1F '>.' MOVE.W (A7)+,D7
|
||||
0000016C: 4FEF 000C 'O...' LEA $000C(A7),A7
|
||||
00000170: 7000 'p.' MOVEQ #$00,D0
|
||||
00000172: 3013 '0.' MOVE.W (A3),D0
|
||||
00000174: 0C80 0000 504D '....PM' CMPI.L #$0000504D,D0
|
||||
0000017A: 66BE 'f.' BNE.S *-$0040 ; 0000013A
|
||||
0000017C: 2A2B 0004 '*+..' MOVE.L $0004(A3),D5
|
||||
00000180: 2F2E FFF8 '/...' MOVE.L -$0008(A6),-(A7)
|
||||
00000184: 302E FBF2 '0...' MOVE.W -$040E(A6),D0
|
||||
00000188: 48C0 'H.' EXT.L D0
|
||||
0000018A: 2F00 '/.' MOVE.L D0,-(A7)
|
||||
0000018C: 2F0B '/.' MOVE.L A3,-(A7)
|
||||
0000018E: 2F0A '/.' MOVE.L A2,-(A7)
|
||||
00000190: 6100 4254 'a.BT' BSR *+$4256 ; 000043E6
|
||||
00000194: 2800 '(.' MOVE.L D0,D4
|
||||
00000196: 4FEF 0010 'O...' LEA $0010(A7),A7
|
||||
0000019A: 3E04 '>.' MOVE.W D4,D7
|
||||
0000019C: 0C47 FFFF '.G..' CMPI.W #$FFFF,D7
|
||||
000001A0: 6798 'g.' BEQ.S *-$0066 ; 0000013A
|
||||
000001A2: 4A47 'JG' TST.W D7
|
||||
000001A4: 6604 'f.' BNE.S *+$0006 ; 000001AA
|
||||
000001A6: 2004 ' .' MOVE.L D4,D0
|
||||
000001A8: 6006 '`.' BRA.S *+$0008 ; 000001B0
|
||||
000001AA: 203C FFFF DB93 ' <....' MOVE.L #$FFFFDB93,D0
|
||||
000001B0: 4CEE 1CF8 FB06 'L.....' MOVEM.L -$04FA(A6),D3-D7/A2-A4
|
||||
000001B6: 4E5E 'N^' UNLK A6
|
||||
000001B8: 4E75 'Nu' RTS
|
||||
000001BA: 4E56 0000 'NV..' LINK A6,#$0000
|
||||
000001BE: 48E7 0318 'H...' MOVEM.L D6/D7/A3/A4,-(A7)
|
||||
000001C2: 2E2E 000C '....' MOVE.L $000C(A6),D7
|
||||
000001C6: 266E 0010 '&n..' MOVEA.L $0010(A6),A3
|
||||
000001CA: 286E 0008 '(n..' MOVEA.L $0008(A6),A4
|
||||
000001CE: 202C 0018 ' ,..' MOVE.L $0018(A4),D0
|
||||
000001D2: E088 '..' LSR.L #$8,D0
|
||||
000001D4: 7C01 '|.' MOVEQ #$01,D6
|
||||
000001D6: CC80 '..' AND.L D0,D6
|
||||
000001D8: 426C 0028 'Bl.(' CLR.W $0028(A4)
|
||||
000001DC: 7000 'p.' MOVEQ #$00,D0
|
||||
000001DE: 302B 0006 '0+..' MOVE.W $0006(A3),D0
|
||||
000001E2: 2207 '".' MOVE.L D7,D1
|
||||
000001E4: 4C40 1001 'L@..' DIVU.L D0,D1
|
||||
000001E8: 3941 004C '9A.L' MOVE.W D1,$004C(A4)
|
||||
000001EC: 7000 'p.' MOVEQ #$00,D0
|
||||
000001EE: 302B 0004 '0+..' MOVE.W $0004(A3),D0
|
||||
000001F2: 2207 '".' MOVE.L D7,D1
|
||||
000001F4: 4C40 1001 'L@..' DIVU.L D0,D1
|
||||
000001F8: 7000 'p.' MOVEQ #$00,D0
|
||||
000001FA: 302B 0002 '0+..' MOVE.W $0002(A3),D0
|
||||
000001FE: 4A80 'J.' TST.L D0
|
||||
00000200: 4C40 1802 'L@..' TDIVS.L D0,D2:D1
|
||||
00000204: 700F 'p.' MOVEQ #$0F,D0
|
||||
00000206: C082 '..' AND.L D2,D0
|
||||
00000208: 1940 004E '.@.N' MOVE.B D0,$004E(A4)
|
||||
0000020C: 2006 ' .' MOVE.L D6,D0
|
||||
0000020E: E988 '..' LSL.L #$4,D0
|
||||
00000210: 812C 004E '.,.N' OR.B D0,$004E(A4)
|
||||
00000214: 002C 00A0 004E '.,...N' ORI.B #$A0,$004E(A4)
|
||||
0000021A: 7000 'p.' MOVEQ #$00,D0
|
||||
0000021C: 302B 0004 '0+..' MOVE.W $0004(A3),D0
|
||||
00000220: 2207 '".' MOVE.L D7,D1
|
||||
00000222: 4C40 1002 'L@..' TDIVU.L D0,D2:D1
|
||||
00000226: 5202 'R.' ADDQ.B #$1,D2
|
||||
00000228: 1942 004A '.B.J' MOVE.B D2,$004A(A4)
|
||||
0000022C: 4CEE 18C0 FFF0 'L.....' MOVEM.L -$0010(A6),D6/D7/A3/A4
|
||||
00000232: 4E5E 'N^' UNLK A6
|
||||
00000234: 4E75 'Nu' RTS
|
||||
0000002A: 4E56 FFFC 'NV..' LINK A6,#$FFFC
|
||||
0000002E: 48EE 0020 FFFC 'H.. ..' MOVEM.L D5,-$0004(A6)
|
||||
00000034: 0C6E 0701 000E '.n....' CMPI.W #$0701,$000E(A6)
|
||||
0000003A: 6642 'fB' BNE.S *+$0044 ; 0000007E
|
||||
0000003C: 203C 5369 7A65 ' <Size' MOVE.L #$53697A65,D0 ; 'Size'
|
||||
00000042: A51E '..' _NewPtr ,Sys ; A51E
|
||||
00000044: 4A88 'J.' TST.L A0
|
||||
00000046: 6736 'g6' BEQ.S *+$0038 ; 0000007E
|
||||
00000048: 2248 '"H' MOVEA.L A0,A1
|
||||
0000004A: 41FA 4174 'A.At' LEA *+$4176,A0 ; 000041C0
|
||||
0000004E: 203C 5369 7A65 ' <Size' MOVE.L #$53697A65,D0 ; 'Size'
|
||||
00000054: A02E '..' _BlockMove ; A02E
|
||||
00000056: 2A2E 0008 '*...' MOVE.L $0008(A6),D5
|
||||
0000005A: 0285 0000 FF00 '......' ANDI.L #$0000FF00,D5
|
||||
00000060: 202E 0008 ' ...' MOVE.L $0008(A6),D0
|
||||
00000064: 4840 'H@' SWAP D0
|
||||
00000066: 0280 00FF 0000 '......' ANDI.L #$00FF0000,D0
|
||||
0000006C: 8A80 '..' OR.L D0,D5
|
||||
0000006E: 4A2E 0013 'J...' TST.B $0013(A6)
|
||||
00000072: 6604 'f.' BNE.S *+$0006 ; 00000078
|
||||
00000074: 08C5 001F '....' BSET #$1F,D5
|
||||
00000078: 4EA8 0008 'N...' JSR $0008(A0)
|
||||
0000007C: 6006 '`.' BRA.S *+$0008 ; 00000084
|
||||
0000007E: 203C FFFF DB93 ' <....' MOVE.L #$FFFFDB93,D0
|
||||
00000084: 4CEE 0020 FFFC 'L.. ..' MOVEM.L -$0004(A6),D5
|
||||
0000008A: 4E5E 'N^' UNLK A6
|
||||
0000008C: 4E75 'Nu' RTS
|
||||
|
||||
Size: Flags $00 ModuleSize 566
|
||||
Size: Flags $00 ModuleSize 142
|
||||
|
||||
Last
|
||||
Record Summary
|
||||
|
69
ataboot.py
69
ataboot.py
@ -11,28 +11,13 @@ import binascii
|
||||
|
||||
|
||||
src, cleanup = patch_common.get_src(desc='''
|
||||
Enable booting from ATA disks without an Apple_Driver_ATA partition. This is
|
||||
done by patching the ROM-based .ATALoad DRVR to fall back on the ROM-based
|
||||
.ATADisk DRVR when initially scanning a disk. The .ATADisk is added to the ROM
|
||||
if missing. The disk still needs an Apple Partition Map.
|
||||
Support ATA startup disks without an Apple_Driver_ATA partition. This allows Mac
|
||||
OS to be installed on a disk without repartitioning it. Accomplished by
|
||||
shoehorning the Drive Setup 2.1 ATA driver into the ROM ATALoad driver, to
|
||||
replace missing driver partitions.
|
||||
''')
|
||||
|
||||
|
||||
# long BOOT(void *DRVR, void *PartMapEntry, long flags)
|
||||
# C calling convention: args pushed in reverse order and not popped by function, return value in d0
|
||||
def find_BOOT(code):
|
||||
for i in range(0, len(code), 2):
|
||||
if code[i:i+4] == b'BOOT': # MOVE.L 'BOOT',D0 --or-- MOVE.L 'BOOT',-(SP)
|
||||
for j in reversed(range(0, i, 2)):
|
||||
# Count backwards and look for the target of *any* JSR, which is the start of the func
|
||||
for k in range(0, len(code), 2):
|
||||
if code[k:k+2] == b'\x4E\xBA': # JSR opcode
|
||||
if k+2 + struct.unpack('>h', code[k+2:k+4])[0] == j:
|
||||
return j
|
||||
|
||||
raise ValueError('Function BOOT not found')
|
||||
|
||||
|
||||
def find_InitDevice(code):
|
||||
for i in range(0, len(code), 2):
|
||||
# checking Driver Descriptor Map magic number (there are two but this one always first)
|
||||
@ -46,7 +31,7 @@ def find_InitDevice(code):
|
||||
|
||||
def patch_ataload(code):
|
||||
code = bytearray(code)
|
||||
new = len(code) # boundary between old and new code
|
||||
cut1 = len(code) # boundary between original and glue
|
||||
|
||||
# Parse the DumpObj'd file
|
||||
with open(path.join(path.dirname(__file__), 'ATALoad.dmp')) as f:
|
||||
@ -55,46 +40,50 @@ def patch_ataload(code):
|
||||
if m:
|
||||
code.extend(binascii.unhexlify(m.group(1).replace(' ', '')))
|
||||
|
||||
InitDevice = find_InitDevice(code[:new])
|
||||
BOOT = find_BOOT(code[:new])
|
||||
cut2 = len(code) # boundary between glue and driver
|
||||
|
||||
print('ATALoad patch: InitDevice=0x%X, NewInitDevice=0x%X, BOOT=0x%X' % (InitDevice, new, BOOT))
|
||||
with open(path.join(path.dirname(__file__), 'AppleATADisk'), 'rb') as f:
|
||||
code.extend(f.read())
|
||||
|
||||
InitDevice = find_InitDevice(code[:cut1])
|
||||
|
||||
print('ATALoad patch: InitDevice=0x%X, glue=0x%X, driver=0x%X' % (InitDevice, cut1, cut2))
|
||||
|
||||
# "Link" the new code into the old
|
||||
for i in range(new, len(code), 2):
|
||||
for i in range(cut1, len(code), 2):
|
||||
if code[i:i+4] == b'Nsrt':
|
||||
code[i:i+4] = code[InitDevice:InitDevice+4] # copy the first LINK from the original function
|
||||
code[InitDevice:InitDevice+2] = b'\x60\x00' # BRA.W opcode, to...
|
||||
code[InitDevice+2:InitDevice+4] = struct.pack('>h', new - (InitDevice+2)) # ...the start of the new code
|
||||
code[InitDevice+2:InitDevice+4] = struct.pack('>h', cut1 - (InitDevice+2)) # ...the start of the new code
|
||||
|
||||
if code[i:i+2] == b'At':
|
||||
code[i:i+2] = struct.pack('>h', cut2 - i)
|
||||
|
||||
if code[i:i+4] == b'Size':
|
||||
code[i:i+4] = struct.pack('>l', cut2 - cut1)
|
||||
|
||||
if code[i:i+2] == b'ID': # reference to original InitDevice, skipping the mangled 4-byte LINK
|
||||
code[i:i+2] = struct.pack('>h', (InitDevice+4) - i)
|
||||
|
||||
if code[i:i+2] == b'BT': # reference to BOOT function
|
||||
code[i:i+2] = struct.pack('>h', BOOT - i)
|
||||
|
||||
return bytes(code)
|
||||
|
||||
|
||||
found_drvr = False
|
||||
|
||||
for (parent, folders, files) in os.walk(src):
|
||||
folders.sort(); files.sort() # make it kinda deterministic
|
||||
for filename in files:
|
||||
full = path.join(src, parent, filename)
|
||||
|
||||
if filename == 'Romfile':
|
||||
ataload = path.join(src, parent, 'Rsrc', 'DRVR_-20175_ATALoad')
|
||||
atadisk = path.join(src, parent, 'Rsrc', 'DRVR_53_ATADisk')
|
||||
if filename == 'DRVR_-20175_ATALoad':
|
||||
code = open(full, 'rb').read()
|
||||
code = patch_ataload(code)
|
||||
open(full, 'wb').write(code)
|
||||
found_drvr = True
|
||||
|
||||
if path.exists(ataload):
|
||||
code = open(ataload, 'rb').read()
|
||||
code = patch_ataload(code)
|
||||
open(ataload, 'wb').write(code)
|
||||
|
||||
if not path.exists(atadisk):
|
||||
with open(full, 'a') as f: # append to Romfile
|
||||
f.write('\ntype=DRVR id=53 name=.ATADisk src=Rsrc/DRVR_53_ATADisk # inserted by ataboot.py\n')
|
||||
print('ATALoad patch: using .ATADisk DRVR from Drive Setup 2.1')
|
||||
shutil.copy(path.join(path.dirname(__file__), 'DRVR_53_ATADisk'), atadisk)
|
||||
if not found_drvr:
|
||||
raise ValueError('ATALoad DRVR not found')
|
||||
|
||||
|
||||
cleanup()
|
||||
|
Loading…
x
Reference in New Issue
Block a user