source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm @ 346

Last change on this file since 346 was 346, checked in by aitotat@…, 12 years ago

Changes to XTIDE Universal BIOS:

  • Added some comments.
File size: 10.0 KB
RevLine 
[99]1; Project name  :   XTIDE Universal BIOS
[3]2; Description   :   Functions for creating Disk Parameter Table.
3
4; Section containing code
5SECTION .text
6
7;--------------------------------------------------------------------
8; Creates new Disk Parameter Table for detected hard disk.
9; Drive is then fully accessible using any BIOS function.
10;
11; CreateDPT_FromAtaInformation
12;   Parameters:
13;       BH:     Drive Select byte for Drive and Head Register
14;       ES:SI:  Ptr to 512-byte ATA information read from the drive
15;       CS:BP:  Ptr to IDEVARS for the controller
16;       DS:     RAMVARS segment
17;       ES:     BDA Segment
18;   Returns:
19;       DL:     Drive number for new drive
[294]20;       DS:DI:  Ptr to Disk Parameter Table (if successful)
[3]21;       CF:     Cleared if DPT created successfully
22;               Set if any error
23;   Corrupts registers:
[99]24;       AX, BX, CX, DH
[3]25;--------------------------------------------------------------------
26CreateDPT_FromAtaInformation:
[150]27    call    FindDPT_ForNewDriveToDSDI
[99]28    ; Fall to .InitializeDPT
[3]29
30;--------------------------------------------------------------------
[99]31; .InitializeDPT
[3]32;   Parameters:
33;       BH:     Drive Select byte for Drive and Head Register
34;       DS:DI:  Ptr to Disk Parameter Table
35;       CS:BP:  Ptr to IDEVARS for the controller
36;   Returns:
[150]37;       Nothing
[3]38;   Corrupts registers:
[150]39;       AX
[3]40;--------------------------------------------------------------------
[99]41.InitializeDPT:
[150]42    mov     [di+DPT.bIdevarsOffset], bp ; IDEVARS must start in first 256 bytes of ROM
43    ; Fall to .StoreDriveSelectAndDriveControlByte
[3]44
45;--------------------------------------------------------------------
[150]46; .StoreDriveSelectAndDriveControlByte
[3]47;   Parameters:
48;       BH:     Drive Select byte for Drive and Head Register
49;       DS:DI:  Ptr to Disk Parameter Table
50;       ES:SI:  Ptr to 512-byte ATA information read from the drive
51;       CS:BP:  Ptr to IDEVARS for the controller
52;   Returns:
[99]53;       Nothing
[3]54;   Corrupts registers:
55;       AX
56;--------------------------------------------------------------------
[150]57.StoreDriveSelectAndDriveControlByte:
58    mov     al, bh
59    and     ax, BYTE FLG_DRVNHEAD_DRV       ; AL now has Master/Slave bit
60    cmp     [cs:bp+IDEVARS.bIRQ], ah        ; Interrupts enabled?
61    jz      SHORT .StoreFlags               ;  If not, do not set interrupt flag
[158]62    or      al, FLGL_DPT_ENABLE_IRQ
[150]63.StoreFlags:
64    mov     [di+DPT.wFlags], ax
[173]65    ; Fall to .StoreAddressing
[3]66
67;--------------------------------------------------------------------
[173]68; .StoreAddressing
[3]69;   Parameters:
70;       DS:DI:  Ptr to Disk Parameter Table
71;       ES:SI:  Ptr to 512-byte ATA information read from the drive
72;       CS:BP:  Ptr to IDEVARS for the controller
73;   Returns:
[227]74;       Nothing
[3]75;   Corrupts registers:
[227]76;       AX, BX, CX, DX
[3]77;--------------------------------------------------------------------
[173]78.StoreAddressing:
79    ; Check if CHS defined in ROMVARS
[193]80    call    AccessDPT_GetPointerToDRVPARAMStoCSBX
81    test    byte [cs:bx+DRVPARAMS.wFlags], FLG_DRVPARAMS_USERCHS    ; User specified CHS?
[227]82    jnz     SHORT .StoreUserDefinedPCHS
[173]83
84    ; Check if LBA supported
[169]85    call    AtaID_GetPCHStoAXBLBHfromAtaInfoInESSI
[173]86    test    BYTE [es:si+ATA1.wCaps+1], A1_wCaps_LBA>>8
[227]87    jz      SHORT .StoreCHSfromAXBHBL       ; Small old drive with CHS addressing only
[3]88
[324]89    ; Store LBA 28/48 addressing and total sector count
[173]90    call    AtaID_GetTotalSectorCountToBXDXAXfromAtaInfoInESSI
[324]91    call    StoreLbaAddressingAndTotalSectorCountFromBXDXAX
92
93    ; Replace sector count with user defined if necessary
94    call    AccessDPT_GetPointerToDRVPARAMStoCSBX
95    test    BYTE [cs:bx+DRVPARAMS.wFlags], FLG_DRVPARAMS_USERLBA
96    jz      SHORT .KeepTotalSectorsFromAtaID
97    mov     ax, [cs:bx+DRVPARAMS.dwMaximumLBA]
98    mov     dx, [cs:bx+DRVPARAMS.dwMaximumLBA+2]
99    xor     bx, bx
100
101    ; Compare user defined and ATA-ID sector count and select smaller
102    cmp     bx, [di+DPT.twLbaSectors+4]
103    jb      SHORT .StoreUserDefinedSectorCountToDPT
104    cmp     dx, [di+DPT.twLbaSectors+2]
105    jb      SHORT .StoreUserDefinedSectorCountToDPT
106    ja      SHORT .KeepTotalSectorsFromAtaID
107    cmp     ax, [di+DPT.twLbaSectors]
108    jae     SHORT .KeepTotalSectorsFromAtaID
109.StoreUserDefinedSectorCountToDPT:
110    call    StoreLbaAddressingAndTotalSectorCountFromBXDXAX
111
112    ; Calculate L-CHS for old INT 13h
113.KeepTotalSectorsFromAtaID:
114    mov     bx, [di+DPT.twLbaSectors+4]     ; Restore BX
115    call    AccessDPT_ConvertSectorCountFromBXDXAXtoLbaAssistedCHSinDXAXBLBH
[227]116    mov     [di+DPT.bLbaHeads], bl
117    jmp     SHORT .StoreBlockMode
[173]118
[227]119;--------------------------------------------------------------------
120; .StoreUserDefinedPCHS
121;   Parameters:
122;       DS:DI:  Ptr to Disk Parameter Table
123;       ES:SI:  Ptr to 512-byte ATA information read from the drive
124;       CS:BP:  Ptr to IDEVARS for the controller
125;   Returns:
126;       AX:     Number of P-CHS cylinders
127;       BH:     Number of P-CHS sectors per track
128;       BL:     Number of P-CHS heads
129;   Corrupts registers:
130;       Nothing
131;--------------------------------------------------------------------
132.StoreUserDefinedPCHS:
[3]133    call    AccessDPT_GetPointerToDRVPARAMStoCSBX
134    mov     ax, [cs:bx+DRVPARAMS.wCylinders]
[99]135    mov     bx, [cs:bx+DRVPARAMS.wHeadsAndSectors]
[227]136    ; Fall to .StoreCHSfromAXBHBL
[3]137
[227]138;--------------------------------------------------------------------
139; .StoreCHSfromAXBHBL
140;   Parameters:
141;       AX:     Number of P-CHS cylinders
142;       BH:     Number of P-CHS sectors per track
143;       BL:     Number of P-CHS heads
144;       DS:DI:  Ptr to Disk Parameter Table
145;       ES:SI:  Ptr to 512-byte ATA information read from the drive
146;       CS:BP:  Ptr to IDEVARS for the controller
147;   Returns:
148;       AX:     Number of P-CHS cylinders
149;       BH:     Number of P-CHS sectors per track
150;       BL:     Number of P-CHS heads
151;   Corrupts registers:
152;       CX
153;--------------------------------------------------------------------
154.StoreCHSfromAXBHBL:
[173]155    push    ax
[227]156    push    bx
157    call    AccessDPT_ShiftPCHinAXBLtoLCH   ; Get number of bits to shift
158    pop     bx
[173]159    pop     ax
[227]160    jcxz    .StorePCHSfromAXDX              ; Small drive so use L-CHS addressing
[3]161
[227]162    ; Store P-CHS addressing mode and number of bits to shift in L-CHS to P-CHS translation
163    or      cl, ADDRESSING_MODE_PCHS<<ADDRESSING_MODE_FIELD_POSITION
164    or      [di+DPT.bFlagsLow], cl
165    ; Fall to .StoreChsFromAXBLBH
166
[3]167;--------------------------------------------------------------------
[227]168; .StoreChsFromAXBLBH
[3]169;   Parameters:
[227]170;       AX:     Number of P-CHS cylinders
171;       BH:     Number of P-CHS sectors per track
172;       BL:     Number of P-CHS heads
[3]173;       DS:DI:  Ptr to Disk Parameter Table
174;       ES:SI:  Ptr to 512-byte ATA information read from the drive
[160]175;       CS:BP:  Ptr to IDEVARS for the controller
[3]176;   Returns:
[99]177;       Nothing
[3]178;   Corrupts registers:
[227]179;       Nothing
[3]180;--------------------------------------------------------------------
[227]181.StorePCHSfromAXDX:
182    mov     [di+DPT.wPchsCylinders], ax
183    mov     [di+DPT.wPchsHeadsAndSectors], bx
[99]184    ; Fall to .StoreBlockMode
[3]185
186;--------------------------------------------------------------------
[99]187; .StoreBlockMode
[3]188;   Parameters:
189;       DS:DI:  Ptr to Disk Parameter Table
190;       ES:SI:  Ptr to 512-byte ATA information read from the drive
[160]191;       CS:BP:  Ptr to IDEVARS for the controller
[3]192;   Returns:
[99]193;       Nothing
[3]194;   Corrupts registers:
[150]195;       Nothing
[3]196;--------------------------------------------------------------------
[99]197.StoreBlockMode:
[150]198    cmp     BYTE [es:si+ATA1.bBlckSize], 1  ; Max block size in sectors
199    jbe     SHORT .BlockModeTransfersNotSupported
[158]200    or      BYTE [di+DPT.bFlagsHigh], FLGH_DPT_BLOCK_MODE_SUPPORTED
[150]201.BlockModeTransfersNotSupported:
202    ; Fall to .StoreDeviceSpecificParameters
[3]203
204;--------------------------------------------------------------------
[150]205; .StoreDeviceSpecificParameters
[3]206;   Parameters:
207;       DS:DI:  Ptr to Disk Parameter Table
208;       ES:SI:  Ptr to 512-byte ATA information read from the drive
[160]209;       CS:BP:  Ptr to IDEVARS for the controller
[3]210;   Returns:
[99]211;       Nothing
[3]212;   Corrupts registers:
[150]213;       AX, BX, CX, DX
[3]214;--------------------------------------------------------------------
[150]215.StoreDeviceSpecificParameters:
216    call    Device_FinalizeDPT
[258]217
[262]218;----------------------------------------------------------------------
219; Update drive counts (hard and floppy)
[294]220;----------------------------------------------------------------------
221
[258]222%ifdef MODULE_SERIAL_FLOPPY
223;
224; These two instructions serve two purposes:
225; 1. If the drive is a floppy drive (CF set), then we effectively increment the counter.
[294]226; 2. If this is a hard disk, and there have been any floppy drives previously added, then the hard disk is
[258]227;    effectively discarded.  This is more of a safety check then code that should ever normally be hit (see below).
[294]228;    Since the floppy DPT's come after the hard disk DPT's, without expensive (code size) code to relocate a DPT,
[258]229;    this was necessary.  Now, this situation shouldn't happen in normal operation, for a couple of reasons:
[294]230;       A. xtidecfg always puts configured serial ports at the end of the IDEVARS list
[258]231;       B. the auto serial code is always executed last
232;       C. the serial server always returns floppy drives last
233;
234    adc     byte [RAMVARS.xlateVars+XLATEVARS.bFlopCreateCnt], 0
[294]235    jnz     .AllDone
[258]236%else
237;
238; Even without floppy support enabled, we shouldn't try to mount a floppy image as a hard disk, which
[294]239; could lead to unpredictable results since no MBR will be present, etc.  The server doesn't know that
[258]240; floppies are supported, so it is important to still fail here if a floppy is seen during the drive scan.
241;
242    jc      .AllDone
243%endif
244
[150]245    inc     BYTE [RAMVARS.bDrvCnt]      ; Increment drive count to RAMVARS
[294]246
247.AllDone:
[162]248    clc
[3]249    ret
[258]250
[324]251
252;--------------------------------------------------------------------
253; StoreLbaAddressingAndTotalSectorCountFromBXDXAX
254;   Parameters:
255;       BX:DX:AX:   Total Sector Count
256;       DS:DI:      Ptr to Disk Parameter Table
257;   Returns:
258;       Nothing
259;   Corrupts registers:
260;       CX
261;--------------------------------------------------------------------
262StoreLbaAddressingAndTotalSectorCountFromBXDXAX:
263    mov     [di+DPT.twLbaSectors], ax
264    mov     [di+DPT.twLbaSectors+2], dx
265    mov     [di+DPT.twLbaSectors+4], bx
266
267    and     BYTE [di+DPT.bFlagsLow], ~MASKL_DPT_ADDRESSING_MODE
268    test    bx, bx
[346]269    jnz     SHORT .SetLba48AddressingToDPT  ; Must be LBA48
270
271    ; Drives can report at most 0FFF FFFFh LBA28 sectors according to ATA specification.
272    ; That is (2^28)-1 so we can simply check if DH is zero or not.
273    test    dh, dh
[324]274    jz      SHORT .SetLba28AddressingToDPT
275.SetLba48AddressingToDPT:
276    or      BYTE [di+DPT.bFlagsLow], ADDRESSING_MODE_LBA48<<ADDRESSING_MODE_FIELD_POSITION
277.SetLba28AddressingToDPT:
278    or      BYTE [di+DPT.bFlagsLow], ADDRESSING_MODE_LBA28<<ADDRESSING_MODE_FIELD_POSITION
279    ret
Note: See TracBrowser for help on using the repository browser.