mirror of
https://github.com/elliotnunn/tbxi-patches.git
synced 2025-03-03 19:29:20 +00:00
Patch ATALoad to boot from driver-less disks
Unreliable: currently this only works on QEMU
This commit is contained in:
parent
a05f8638d7
commit
9351898fb5
281
ATALoad.a
Normal file
281
ATALoad.a
Normal file
@ -0,0 +1,281 @@
|
||||
; 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
|
||||
|
||||
lea $10(sp),a0 ; re-push the 12 bytes of arguments onto the stack
|
||||
move.l -(a0),-(sp)
|
||||
move.l -(a0),-(sp)
|
||||
move.l -(a0),-(sp)
|
||||
bsr.s OriginalFunc ; ... and call the function
|
||||
add.l #$C,sp ; pop those copied arguments, we don't need them
|
||||
|
||||
cmp.l #$FFFFDB93,d0 ; ATANoDriverErr -> try our method
|
||||
beq.s NewFunc
|
||||
cmp.l #$FFFFDB92,d0 ; ATANoDDMErr -> try our method
|
||||
beq.s NewFunc
|
||||
rts ; don't try our method
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
NewFunc
|
||||
link a6,#-$4DA
|
||||
movem.l d3-d7/a2-a4,-(sp)
|
||||
|
||||
|
||||
; 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
|
||||
|
||||
|
||||
string c
|
||||
mystring dc.b 'log from ATALoad ^n'
|
||||
PrintHex ; A0 is already set to a number...
|
||||
MOVE.L #4, D1 ; r4 arg (1: byte, 2: 2byte, else: 4byte)
|
||||
MOVE.L #97, D0 ; call NKPrintHex
|
||||
DC.W $FE1F
|
||||
|
||||
LEA mystring,A0
|
||||
MOVE.L #96, D0 ; call NKXprintf
|
||||
DC.W $FE1F
|
||||
|
||||
RTS ; stack is safe!
|
||||
|
||||
|
||||
END
|
194
ATALoad.dmp
Normal file
194
ATALoad.dmp
Normal file
@ -0,0 +1,194 @@
|
||||
|
||||
First: Flags=0 Version=2
|
||||
|
||||
Dictionary: Flags $00 FirstId 1
|
||||
1: #0001
|
||||
2: Main
|
||||
Pad
|
||||
|
||||
|
||||
|
||||
Module: Flags=$10=(Main Local Code) Module="#0001"(1) Segment="Main"(2)
|
||||
|
||||
Content: Flags $08
|
||||
Contents offset $0000 size $0236
|
||||
00000000: 41EF 0010 'A...' LEA $0010(A7),A0
|
||||
00000004: 2F20 '/ ' MOVE.L -(A0),-(A7)
|
||||
00000006: 2F20 '/ ' MOVE.L -(A0),-(A7)
|
||||
00000008: 2F20 '/ ' MOVE.L -(A0),-(A7)
|
||||
0000000A: 6116 'a.' BSR.S *+$0018 ; 00000022
|
||||
0000000C: DEFC 000C '....' ADDA.W #$000C,A7
|
||||
00000010: 0C80 FFFF DB93 '......' CMPI.L #$FFFFDB93,D0
|
||||
00000016: 6712 'g.' BEQ.S *+$0014 ; 0000002A
|
||||
00000018: 0C80 FFFF DB92 '......' CMPI.L #$FFFFDB92,D0
|
||||
0000001E: 670A 'g.' BEQ.S *+$000C ; 0000002A
|
||||
00000020: 4E75 'Nu' RTS
|
||||
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
|
||||
|
||||
Size: Flags $00 ModuleSize 566
|
||||
|
||||
Last
|
||||
Record Summary
|
||||
Type Count
|
||||
0 Pad 1
|
||||
1 First 1
|
||||
2 Last 1
|
||||
4 Dictionary 1
|
||||
5 Module 1
|
||||
7 ModSize 1
|
||||
8 Content 1
|
BIN
DRVR_53_ATADisk
Normal file
BIN
DRVR_53_ATADisk
Normal file
Binary file not shown.
100
ataboot.py
Executable file
100
ataboot.py
Executable file
@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import patch_common
|
||||
|
||||
from os import path
|
||||
import os
|
||||
import struct
|
||||
import shutil
|
||||
import re
|
||||
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.
|
||||
''')
|
||||
|
||||
|
||||
# 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)
|
||||
if code[i:i+2] == b'ER':
|
||||
for j in reversed(range(0, i, 2)):
|
||||
if code[j:j+2] == b'NV': # LINK A6,#$xxxx
|
||||
return j
|
||||
|
||||
raise ValueError('Function InitDevice not found')
|
||||
|
||||
|
||||
def patch_ataload(code):
|
||||
code = bytearray(code)
|
||||
new = len(code) # boundary between old and new code
|
||||
|
||||
# Parse the DumpObj'd file
|
||||
with open(path.join(path.dirname(__file__), 'ATALoad.dmp')) as f:
|
||||
for l in f:
|
||||
m = re.match(r'^[0-9A-F]{8}: ([0-9A-F ]+)', l) or re.match('^ {13}([0-9A-F][0-9A-F ]*)', l)
|
||||
if m:
|
||||
code.extend(binascii.unhexlify(m.group(1).replace(' ', '')))
|
||||
|
||||
InitDevice = find_InitDevice(code[:new])
|
||||
BOOT = find_BOOT(code[:new])
|
||||
|
||||
print('ATALoad patch: InitDevice=0x%X, NewInitDevice=0x%X, BOOT=0x%X' % (InitDevice, new, BOOT))
|
||||
|
||||
# "Link" the new code into the old
|
||||
for i in range(new, 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
|
||||
|
||||
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)
|
||||
|
||||
|
||||
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 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)
|
||||
|
||||
|
||||
cleanup()
|
Loading…
x
Reference in New Issue
Block a user