arlaneenalra
Member
- Joined
- Mar 26, 2024
- Messages
- 46
So according to Wikipedia, Int 13h, function 10h is "is the drive ready?", 09h is "Initialize disk controller" and 11h is "Recalibrate drive".
Is this a situation where the XTA2SD simply doesn't support these calls because it doesn't need to?
While that could be the case, I suspect it's not that simple. https://forum.vcfed.org/index.php?threads/8-bit-ide-xta-replacement-project.1224016/post-1258145 mentions that the list of XTA commands ( 00, 01, 03, 08, 0C, E4 ) The int 13h calls equate to:
* AH=10h is XTA command 0h
* AH=09h is XTA command Ch
* AH=11h is XTA command 1h
All of which are in the mentioned list. My guess is that these commands are expected to behave in a manner that does not match what the XTA2SD is doing. I tried tracing it but got lost in the meat of BIOS function code. It does a very simple setup like:
Code:
hdd_int_10h
f000:d3dd c6 06 42 MOV byte ptr [0x42],0x0
00 00
f000:d3e2 ba 23 03 MOV DX,0x323
f000:d3e5 02 16 77 00 ADD DL,byte ptr [0x77]
f000:d3e9 b0 02 MOV AL,0x2
f000:d3eb ee OUT DX,AL
f000:d3ec eb 00 JMP LAB_f000_d3ee
LAB_f000_d3ee XREF[1]: f000:d3ec(j)
f000:d3ee e9 f2 00 JMP hdd_select_controller undefined hdd_select_controller(
-- Flow Override: CALL_RETURN (CALL_TERMINATOR)
and then jumps into that function I labeled hdd_select_controller which processes that actual command sequence.
The flow there seems to be:
* out 322h, 1h - select the controller
* wait for the controller to report ready for a command
* call a function to actually send the command (it looks like they build a command block at 0040:0042-0040:0048h and send 6(?) bytes to the drive every time:
Code:
**************************************************************
* Sends a command to the Hdd controller. *
* * The command to send pointed to by 0040:0042 (word) *
* *
**************************************************************
undefined __cdecl16near hdd_send_command(void)
undefined AL:1 <RETURN>
hdd_send_command XREF[2]: hdd_select_controller:f000:d506(
hdd_send_command_and_transfer_da
f000:d601 52 PUSH DX
f000:d602 8d 36 42 00 LEA SI,[0x42]
f000:d606 ba 20 03 MOV DX,0x320
f000:d609 02 16 77 00 ADD DL,byte ptr [0x77]
f000:d60d b9 06 00 MOV CX,0x6
LAB_f000_d610 XREF[1]: f000:d614(j)
f000:d610 ac LODSB SI
f000:d611 eb 00 JMP LAB_f000_d613
LAB_f000_d613 XREF[1]: f000:d611(j)
f000:d613 ee OUT DX,AL
f000:d614 e2 fa LOOP LAB_f000_d610
f000:d616 5a POP DX
f000:d617 c3 RET
Code:
hdd_ready_for_command XREF[1]: f000:d4f8(j)
f000:d506 e8 f8 00 CALL hdd_send_command = ??
undefined hdd_send_command(void)
f000:d509 b9 64 00 MOV CX,0x64
f000:d50c 80 3e 42 CMP byte ptr [0x42],0xc Check to see if we're sending co
00 0c
f000:d511 75 02 JNZ hdd_has_valid_command
f000:d513 f8 CLC
f000:d514 c3 RET
The code after that is where things get complicated and I lost track of what was going on. Since my hack works, I know that the read and write sector calls have to work. Now that I look at them, those calls do and ultimately fall through to hdd_select_controller :
Code:
hdd_int_02h
f000:d274 c6 06 42 MOV byte ptr [0x42],0x8 Setup read DCB
00 08
f000:d279 b4 04 MOV AH,0x4
f000:d27b e9 39 02 JMP hdd_check_io_preconditions
hdd_int_03h
f000:d27e c6 06 42 MOV byte ptr [0x42],0xa Setup write DCB
00 0a
f000:d283 b4 08 MOV AH,0x8
f000:d285 e9 2f 02 JMP hdd_check_io_preconditions
That look like:
Code:
hdd_check_io_preconditions XREF[6]: f000:d27b(j), f000:d285(j),
f000:d399(j), f000:d3a3(j),
f000:d3cb(j), f000:d3da(j)
f000:d4b7 e8 18 01 CALL hdd_check_for_buffer_overflow = ??
undefined hdd_check_for_buffer_o
f000:d4ba 73 06 JNC hdd_memory_ok Check to see if we need more mem
f000:d4bc c6 06 74 MOV byte ptr [0x74],0x9
00 09
f000:d4c1 c3 RET
hdd_memory_ok XREF[2]: f000:d28d(j), f000:d4ba(j)
f000:d4c2 f6 c1 3f TEST CL,0x3f
f000:d4c5 75 06 JNZ LAB_f000_d4cd
f000:d4c7 c6 06 74 MOV byte ptr [0x74],0x1
00 01
f000:d4cc c3 RET
LAB_f000_d4cd XREF[1]: f000:d4c5(j)
f000:d4cd 80 3e 42 CMP byte ptr [0x42],0x5
00 05
f000:d4d2 b0 02 MOV AL,0x2
f000:d4d4 74 05 JZ LAB_f000_d4db
f000:d4d6 e8 3f 01 CALL FUN_f000_d618 = ??
undefined FUN_f000_d618()
f000:d4d9 b0 03 MOV AL,0x3
LAB_f000_d4db XREF[1]: f000:d4d4(j)
f000:d4db ba 23 03 MOV DX,0x323
f000:d4de 02 16 77 00 ADD DL,byte ptr [0x77]
f000:d4e2 ee OUT DX,AL
The hdd_check_for_buffer_overflow appears to do math to figure out how much space in memory is needed or the operation, but otherwise have no external impact that I can see.
Everything get's called from a jump table lookup that ultimately returns to:
Code:
f000:d1e7 2e ff 96 CALL word ptr CS:[BP + 0xd0ee]=>DAT_0000_d1ec Uses the hdd_interrupt_function_
ee d0
f000:d1ec b0 07 MOV AL,0x7
f000:d1ee e6 0a OUT 0xa,AL
f000:d1f0 eb 00 JMP LAB_f000_d1f2
LAB_f000_d1f2 XREF[1]: f000:d1f0(j)
f000:d1f2 ba 23 03 MOV DX,0x323
f000:d1f5 02 16 77 00 ADD DL,byte ptr [offset hdd_unknown] = ??
f000:d1f9 b0 00 MOV AL,0x0
f000:d1fb ee OUT DX,AL
f000:d1fc 2e 8e 1e MOV DS,word ptr CS:[segment_bios_data] = 0040h
de e2
f000:d201 9d POPF
f000:d202 07 POP ES
f000:d203 5d POP BP
f000:d204 5f POP DI
f000:d205 5e POP SI
f000:d206 5a POP DX
f000:d207 59 POP CX
f000:d208 5b POP BX
f000:d209 58 POP AX
f000:d20a 32 e4 XOR AH,AH
f000:d20c 3a 26 74 00 CMP AH,byte ptr [offset hdd_1_status] = ??
f000:d210 8a 26 74 00 MOV AH,byte ptr [offset hdd_1_status] = ??
f000:d214 1f POP DS
f000:d215 ca 02 00 RETF 0x2
So, whatever is causing the failure is tripping something up in the hdd_select_controller logic (my name again) starting at f000:d4e3 in the rom. I haven't had a chance to dig into that and likely won't for a while. I'm also not an expert at 16bit assembly, just a bit of a dabbler.