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

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

Added floppy drive emulation over the serial connection (MODULE_SERIAL_FLOPPY). Along the way, various optimizations were made to stay within the 8K ROM size target. Also, serial code now returns the number of sectors transferred.

File size: 9.1 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
20;       DS:DI:  Ptr to Disk Parameter Table (if succesfull)
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
[173]89    ; Check if 48-bit LBA supported
90    test    BYTE [es:si+ATA6.wSetSup83+1], A6_wSetSup83_LBA48>>8
91    jz      SHORT .StoreLBA28addressing
92    or      BYTE [di+DPT.bFlagsLow], ADDRESSING_MODE_LBA48<<ADDRESSING_MODE_FIELD_POSITION
93.StoreLBA28addressing:
94    or      BYTE [di+DPT.bFlagsLow], ADDRESSING_MODE_LBA28<<ADDRESSING_MODE_FIELD_POSITION
95    call    AtaID_GetTotalSectorCountToBXDXAXfromAtaInfoInESSI
[227]96    mov     [di+DPT.twLbaSectors], ax
97    mov     [di+DPT.twLbaSectors+2], dx
98    mov     [di+DPT.twLbaSectors+4], bx
[173]99    call    AtaID_GetLbaAssistedCHStoDXAXBLBH
[227]100    mov     [di+DPT.bLbaHeads], bl
101    jmp     SHORT .StoreBlockMode
[173]102
[227]103;--------------------------------------------------------------------
104; .StoreUserDefinedPCHS
105;   Parameters:
106;       DS:DI:  Ptr to Disk Parameter Table
107;       ES:SI:  Ptr to 512-byte ATA information read from the drive
108;       CS:BP:  Ptr to IDEVARS for the controller
109;   Returns:
110;       AX:     Number of P-CHS cylinders
111;       BH:     Number of P-CHS sectors per track
112;       BL:     Number of P-CHS heads
113;   Corrupts registers:
114;       Nothing
115;--------------------------------------------------------------------
116.StoreUserDefinedPCHS:
[3]117    call    AccessDPT_GetPointerToDRVPARAMStoCSBX
118    mov     ax, [cs:bx+DRVPARAMS.wCylinders]
[99]119    mov     bx, [cs:bx+DRVPARAMS.wHeadsAndSectors]
[227]120    ; Fall to .StoreCHSfromAXBHBL
[3]121
[227]122;--------------------------------------------------------------------
123; .StoreCHSfromAXBHBL
124;   Parameters:
125;       AX:     Number of P-CHS cylinders
126;       BH:     Number of P-CHS sectors per track
127;       BL:     Number of P-CHS heads
128;       DS:DI:  Ptr to Disk Parameter Table
129;       ES:SI:  Ptr to 512-byte ATA information read from the drive
130;       CS:BP:  Ptr to IDEVARS for the controller
131;   Returns:
132;       AX:     Number of P-CHS cylinders
133;       BH:     Number of P-CHS sectors per track
134;       BL:     Number of P-CHS heads
135;   Corrupts registers:
136;       CX
137;--------------------------------------------------------------------
138.StoreCHSfromAXBHBL:
[173]139    push    ax
[227]140    push    bx
141    call    AccessDPT_ShiftPCHinAXBLtoLCH   ; Get number of bits to shift
142    pop     bx
[173]143    pop     ax
[227]144    jcxz    .StorePCHSfromAXDX              ; Small drive so use L-CHS addressing
[3]145
[227]146    ; Store P-CHS addressing mode and number of bits to shift in L-CHS to P-CHS translation
147    or      cl, ADDRESSING_MODE_PCHS<<ADDRESSING_MODE_FIELD_POSITION
148    or      [di+DPT.bFlagsLow], cl
149    ; Fall to .StoreChsFromAXBLBH
150
[3]151;--------------------------------------------------------------------
[227]152; .StoreChsFromAXBLBH
[3]153;   Parameters:
[227]154;       AX:     Number of P-CHS cylinders
155;       BH:     Number of P-CHS sectors per track
156;       BL:     Number of P-CHS heads
[3]157;       DS:DI:  Ptr to Disk Parameter Table
158;       ES:SI:  Ptr to 512-byte ATA information read from the drive
[160]159;       CS:BP:  Ptr to IDEVARS for the controller
[3]160;   Returns:
[99]161;       Nothing
[3]162;   Corrupts registers:
[227]163;       Nothing
[3]164;--------------------------------------------------------------------
[227]165.StorePCHSfromAXDX:
166    mov     [di+DPT.wPchsCylinders], ax
167    mov     [di+DPT.wPchsHeadsAndSectors], bx
[99]168    ; Fall to .StoreBlockMode
[3]169
170;--------------------------------------------------------------------
[99]171; .StoreBlockMode
[3]172;   Parameters:
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:
[150]179;       Nothing
[3]180;--------------------------------------------------------------------
[99]181.StoreBlockMode:
[150]182    cmp     BYTE [es:si+ATA1.bBlckSize], 1  ; Max block size in sectors
183    jbe     SHORT .BlockModeTransfersNotSupported
[158]184    or      BYTE [di+DPT.bFlagsHigh], FLGH_DPT_BLOCK_MODE_SUPPORTED
[150]185.BlockModeTransfersNotSupported:
186    ; Fall to .StoreDeviceSpecificParameters
[3]187
188;--------------------------------------------------------------------
[150]189; .StoreDeviceSpecificParameters
[3]190;   Parameters:
191;       DS:DI:  Ptr to Disk Parameter Table
192;       ES:SI:  Ptr to 512-byte ATA information read from the drive
[160]193;       CS:BP:  Ptr to IDEVARS for the controller
[3]194;   Returns:
[99]195;       Nothing
[3]196;   Corrupts registers:
[150]197;       AX, BX, CX, DX
[3]198;--------------------------------------------------------------------
[150]199.StoreDeviceSpecificParameters:
200    call    Device_FinalizeDPT
[258]201
202%ifdef MODULE_SERIAL_FLOPPY
203;
204; These two instructions serve two purposes:
205; 1. If the drive is a floppy drive (CF set), then we effectively increment the counter.
206; 2. If this is a hard disk, and there have been any floppy drives previously added, then the hard disk is 
207;    effectively discarded.  This is more of a safety check then code that should ever normally be hit (see below).
208;    Since the floppy DPT's come after the hard disk DPT's, without expensive (code size) code to relocate a DPT, 
209;    this was necessary.  Now, this situation shouldn't happen in normal operation, for a couple of reasons:
210;       A. xtidecfg always puts configured serial ports at the end fo the IDEVARS list
211;       B. the auto serial code is always executed last
212;       C. the serial server always returns floppy drives last
213;
214    adc     byte [RAMVARS.xlateVars+XLATEVARS.bFlopCreateCnt], 0
215    jnz     .AllDone   
216%else
217;
218; Even without floppy support enabled, we shouldn't try to mount a floppy image as a hard disk, which
219; could lead to unpredictable results since no MBR will be present, etc.  The server doesn't know that 
220; floppies are supported, so it is important to still fail here if a floppy is seen during the drive scan.
221;
222    jc      .AllDone
223%endif
224
[99]225    ; Fall to .StoreDriveNumberAndUpdateDriveCount
[3]226
227;--------------------------------------------------------------------
[99]228; .StoreDriveNumberAndUpdateDriveCount
[3]229;   Parameters:
230;       DS:DI:  Ptr to Disk Parameter Table
231;       ES:SI:  Ptr to 512-byte ATA information read from the drive
[160]232;       CS:BP:  Ptr to IDEVARS for the controller
[3]233;       ES:     BDA Segment
234;   Returns:
235;       DL:     Drive number for new drive
[162]236;       CF:     Always cleared
[3]237;   Corrupts registers:
238;       Nothing
239;--------------------------------------------------------------------
[99]240.StoreDriveNumberAndUpdateDriveCount:
[150]241    mov     dl, [es:BDA.bHDCount]
242    or      dl, 80h                     ; Set bit 7 since hard disk
[3]243
[150]244    inc     BYTE [RAMVARS.bDrvCnt]      ; Increment drive count to RAMVARS
245    inc     BYTE [es:BDA.bHDCount]      ; Increment drive count to BDA
[3]246
[150]247    cmp     BYTE [RAMVARS.bFirstDrv], 0 ; First drive set?
248    ja      SHORT .AllDone              ;  If so, return
249    mov     [RAMVARS.bFirstDrv], dl     ; Store first drive number
[258]250
251.AllDone:
[162]252    clc
[3]253    ret
[258]254
Note: See TracBrowser for help on using the repository browser.