; Project name : XTIDE Universal BIOS ; Description : Functions for finding Disk Parameter Table. ; Section containing code SECTION .text ;-------------------------------------------------------------------- ; Finds pointer to first unused Disk Parameter Table. ; ; FindDPT_ForNewDriveToDSDI ; Parameters: ; DS: RAMVARS segment ; Returns: ; DS:DI: Ptr to first unused DPT ; Corrupts registers: ; DL ;-------------------------------------------------------------------- ALIGN JUMP_ALIGN FindDPT_ForNewDriveToDSDI: mov dl, [RAMVARS.bFirstDrv] add dl, [RAMVARS.bDrvCnt] ; Fall to FindDPT_ForDriveNumber ;-------------------------------------------------------------------- ; Finds Disk Parameter Table for drive number. ; IDE Base Port address will be stored to RAMVARS if correct DPT is found. ; ; FindDPT_ForDriveNumber ; Parameters: ; DL: Drive number ; DS: RAMVARS segment ; Returns: ; DS:DI: Ptr to DPT ; Corrupts registers: ; Nothing ;-------------------------------------------------------------------- ALIGN JUMP_ALIGN FindDPT_ForDriveNumber: push dx xchg di, ax ; Save the contents of AX in DI mov al, LARGEST_DPT_SIZE sub dl, [RAMVARS.bFirstDrv] mul dl add ax, BYTE RAMVARS_size xchg di, ax ; Restore AX and put result in DI pop dx ret ;-------------------------------------------------------------------- ; Finds Disk Parameter Table for ; Master or Slave drive at wanted port. ; ; FindDPT_ToDSDIForIdeMasterAtPortDX ; FindDPT_ToDSDIForIdeSlaveAtPortDX ; Parameters: ; DX: IDE Base Port address ; DS: RAMVARS segment ; Returns: ; DL: Drive number (if DPT found) ; DS:DI: Ptr to DPT ; CF: Set if wanted DPT found ; Cleared if DPT not found ; Corrupts registers: ; SI ; ; Converted to macros since there is only once call site for each of these ; ;-------------------------------------------------------------------- %macro FindDPT_ToDSDIForIdeMasterAtPortDX 0 mov si, IterateToMasterAtPortCallback call IterateAllDPTs %endmacro %macro FindDPT_ToDSDIForIdeSlaveAtPortDX 0 mov si, IterateToSlaveAtPortCallback call IterateAllDPTs %endmacro ;-------------------------------------------------------------------- ; Iteration callback for finding DPT using ; IDE base port for Master or Slave drive. ; ; IterateToSlaveAtPortCallback ; IterateToMasterAtPortCallback ; Parameters: ; CH: Drive number ; DX: IDE Base Port address ; DS:DI: Ptr to DPT to examine ; Returns: ; DL: Drive number if correct DPT ; CF: Set if wanted DPT found ; Cleared if wrong DPT ; Corrupts registers: ; Nothing ;-------------------------------------------------------------------- ALIGN JUMP_ALIGN IterateToSlaveAtPortCallback: test BYTE [di+DPT.bFlagsLow], FLGL_DPT_SLAVE ; Clears CF jnz SHORT CompareBasePortAddress ret ; Wrong DPT ALIGN JUMP_ALIGN IterateToMasterAtPortCallback: test BYTE [di+DPT.bFlagsLow], FLGL_DPT_SLAVE jnz SHORT ReturnWrongDPT ; Return if slave drive CompareBasePortAddress: push bx eMOVZX bx, BYTE [di+DPT.bIdevarsOffset] ; CS:BX now points to IDEVARS cmp dx, [cs:bx+IDEVARS.wPort] ; Wanted port? pop bx jne SHORT ReturnWrongDPT mov dl, ch ; Return drive number in DL ReturnRightDPT: stc ; Set CF since wanted DPT ret ;-------------------------------------------------------------------- ; IterateToDptWithFlagsHighSet: ; Parameters: ; DS:DI: Ptr to DPT to examine ; AL: Bit in bFlagsHigh to test ; Returns: ; CF: Set if wanted DPT found ; Cleared if wrong DPT ; Corrupts registers: ; Nothing ;-------------------------------------------------------------------- ALIGN JUMP_ALIGN IterateToDptWithFlagsHighSet: test BYTE [di+DPT.bFlagsHigh], al ; Clears CF (but we need the clc below anyway callers above) jnz SHORT ReturnRightDPT ReturnWrongDPT: clc ; Clear CF since wrong DPT ret ;-------------------------------------------------------------------- ; FindDPT_ToDSDIforInterruptInService ; FindDPT_ToDSDIforSerialDevice ; Parameters: ; DS: RAMVARS segment ; Returns: ; DS:DI: Ptr to DPT ; CF: Set if wanted DPT found ; Cleared if DPT not found ; Corrupts registers: ; SI, AX, BX (for SerialDevice only) ;-------------------------------------------------------------------- ALIGN JUMP_ALIGN %ifdef MODULE_SERIAL FindDPT_ToDSDIforSerialDevice: mov al, FLGH_DPT_SERIAL_DEVICE SKIP2B bx %endif ; do not align due to SKIP2B above FindDPT_ToDSDIforInterruptInService: mov al, FLGH_DPT_INTERRUPT_IN_SERVICE mov si, IterateToDptWithFlagsHighSet ; Fall to IterateAllDPTs ;-------------------------------------------------------------------- ; Iterates all Disk Parameter Tables. ; ; IterateAllDPTs ; Parameters: ; AX,BX,DX: Parameters to callback function ; CS:SI: Ptr to callback function ; DS: RAMVARS segment ; Returns: ; DS:DI: Ptr to wanted DPT (if found) ; CF: Set if wanted DPT found ; Cleared if DPT not found, or no DPTs present ; Corrupts registers: ; Nothing unless corrupted by callback function ;-------------------------------------------------------------------- ALIGN JUMP_ALIGN IterateAllDPTs: push cx mov cx, [RAMVARS.wDrvCntAndFirst] jcxz .NotFound ; Return if no drives mov di, RAMVARS_size ; Point DS:DI to first DPT ALIGN JUMP_ALIGN .LoopWhileDPTsLeft: call si ; Is wanted DPT? jc SHORT .AllDptsIterated ; If so, return inc ch ; Increment drive number add di, BYTE LARGEST_DPT_SIZE ; Point to next DPT dec cl ; Decrement drives left jnz SHORT .LoopWhileDPTsLeft .NotFound: clc ; Clear CF since DPT not found ALIGN JUMP_ALIGN .AllDptsIterated: pop cx ret