source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/Address.asm @ 568

Last change on this file since 568 was 568, checked in by krille_n_@…, 9 years ago

Changes:

  • SerDrive: Using named pipe mode (serdrive -p) now works under Windows XP/2000/Server 2003.
  • checksum.pl: Added a compatibility fix for 3Com 3C503 cards.
  • XTIDECFG will now scan every possible segment address to find and load the BIOS and/or its settings from EEPROM. This should simplify things for people using combined option ROMs.
  • Fixed a bug from r521 in BootSector.asm where the BIOS would not display a timeout error if it failed to load the boot sector from harddrive.
  • Fixed a bug from r541 in CompatibleDPT.asm where CompatibleDPT_CreateDeviceParameterTableExtensionToESBXfromDPTinDSSI would generate an invalid checksum in the DPTE.
  • Optimizations and other fixes.
File size: 6.9 KB
RevLine 
[165]1; Project name  :   XTIDE Universal BIOS
2; Description   :   Functions for address translations.
3
[376]4;
[526]5; XTIDE Universal BIOS and Associated Tools
6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
[376]7;
8; This program is free software; you can redistribute it and/or modify
9; it under the terms of the GNU General Public License as published by
10; the Free Software Foundation; either version 2 of the License, or
11; (at your option) any later version.
[526]12;
[376]13; This program is distributed in the hope that it will be useful,
14; but WITHOUT ANY WARRANTY; without even the implied warranty of
15; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16; GNU General Public License for more details.
[526]17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18;
[376]19
[165]20; Section containing code
21SECTION .text
22
23;---------------------------------------------------------------------
24; Address_ExtractLCHSparametersFromOldInt13hAddress
25;   Parameters:
26;       CH:     Cylinder number, bits 7...0
27;       CL:     Bits 7...6: Cylinder number bits 9 and 8
28;               Bits 5...0: Sector number
29;       DH:     Head number
30;   Returns:
31;       BL:     Sector number (1...63)
32;       BH:     Head number (0...255)
33;       CX:     Cylinder number (0...1023)
34;   Corrupts registers:
35;       Nothing
36;--------------------------------------------------------------------
[191]37ALIGN JUMP_ALIGN
[165]38Address_ExtractLCHSparametersFromOldInt13hAddress:
[568]39    mov     bl, 3Fh             ; Load sector number mask
40    and     bl, cl              ; Sector number now in BL
[165]41    sub     cl, bl              ; Remove from cylinder number high
42    eROL_IM cl, 2               ; High bits to beginning
43    mov     bh, dh              ; Copy Head number
44    xchg    cl, ch              ; Cylinder number now in CX
45    ret
46
47
48;---------------------------------------------------------------------
[421]49; Converts LARGE addressing mode LCHS parameters to IDE P-CHS parameters.
[165]50; PCylinder = (LCylinder << n) + (LHead / PHeadCount)
51; PHead     = LHead % PHeadCount
52; PSector   = LSector
53;
[421]54; ConvertLargeModeLCHStoPCHS:
[165]55;   Parameters:
56;       BL:     Sector number (1...63)
[421]57;       BH:     Head number (0...239)
[165]58;       CX:     Cylinder number (0...1023)
59;       DS:DI:  Ptr to Disk Parameter Table
60;   Returns:
61;       BL:     Sector number (1...63)
62;       BH:     Head number (0...15)
63;       CX:     Cylinder number (0...16382)
64;   Corrupts registers:
65;       AX, DX
66;--------------------------------------------------------------------
67ALIGN JUMP_ALIGN
[421]68ConvertLargeModeLCHStoPCHS:
[165]69    ; LHead / PHeadCount and LHead % PHeadCount
70    eMOVZX  ax, bh                  ; Copy L-CHS Head number to AX
[227]71    div     BYTE [di+DPT.bPchsHeads]; AL = LHead / PHeadCount, AH = LHead % PHeadCount
[165]72    mov     bh, ah                  ; Copy P-CHS Head number to BH
73    xor     ah, ah                  ; AX = LHead / PHeadCount
74
75    ; (LCylinder << n) + (LHead / PHeadCount)
76    mov     dx, cx                  ; Copy L-CHS Cylinder number to DX
[568]77    mov     cl, MASKL_DPT_CHS_SHIFT_COUNT   ; Load shift count mask
78    and     cl, [di+DPT.bFlagsLow]  ; Shift count now in CL
[165]79    shl     dx, cl                  ; DX = LCylinder << n
80    add     ax, dx                  ; AX = P-CHS Cylinder number
81    xchg    cx, ax                  ; Move P-CHS Cylinder number to CX
82DoNotConvertLCHS:
83    ret
84
[568]85; *FIXME* The above function description doesn't match the code.
86; If CX has a maximum value of 1023 on entry then there is no way CX can be 16382 on return.
87; 1023 SHL 3 (MASKL_DPT_CHS_SHIFT_COUNT) is 8184. With the addition of AX (at most 255?)
88; the result is 8439.
[421]89
[191]90;--------------------------------------------------------------------
91; Address_OldInt13hAddressToIdeAddress
92;   Parameters:
93;       CH:     Cylinder number, bits 7...0
94;       CL:     Bits 7...6: Cylinder number bits 9 and 8
95;               Bits 5...0: Starting sector number (1...63)
96;       DH:     Starting head number (0...255)
97;       DS:DI:  Ptr to DPT
98;   Returns:
99;       BL:     LBA Low Register / Sector Number Register (LBA 7...0)
100;       CL:     LBA Mid Register / Low Cylinder Register (LBA 15...8)
101;       CH:     LBA High Register / High Cylinder Register (LBA 23...16)
102;       BH:     Drive and Head Register (LBA 27...24)
103;   Corrupts registers:
104;       AX, DX
105;--------------------------------------------------------------------
106ALIGN JUMP_ALIGN
107Address_OldInt13hAddressToIdeAddress:
[568]108    call    Address_ExtractLCHSparametersFromOldInt13hAddress
109    mov     al, [di+DPT.bFlagsLow]
110    and     al, MASKL_DPT_TRANSLATEMODE
[230]111
[421]112;;; 0: ADDRESSING_MODE_NORMAL
[568]113    jz      SHORT DoNotConvertLCHS
[230]114
[421]115;;; 1: ADDRESSING_MODE_LARGE
[568]116    test    al, FLGL_DPT_ASSISTED_LBA
117    jz      SHORT ConvertLargeModeLCHStoPCHS
[230]118
[421]119;;; 2: ADDRESSING_MODE_ASSISTED_LBA
[568]120    ; Fall to ConvertAssistedLBAModeLCHStoLBARegisterValues
[194]121
[230]122
[165]123;---------------------------------------------------------------------
124; Converts LCHS parameters to 28-bit LBA address.
125; Only 24-bits are used since LHCS to LBA28 conversion has 8.4GB limit.
126; LBA = ((cylToSeek*headsPerCyl+headToSeek)*sectPerTrack)+sectToSeek-1
[542]127; headsPerCyl and sectPerTrack are the current translation values (L-CHS).
[165]128;
129; Returned address is in same registers that
[421]130; DoNotConvertLCHS and ConvertLargeModeLCHStoPCHS returns.
[165]131;
[421]132; ConvertAssistedLBAModeLCHStoLBARegisterValues:
[165]133;   Parameters:
134;       BL:     Sector number (1...63)
[421]135;       BH:     Head number (0...254)
[165]136;       CX:     Cylinder number (0...1023)
137;       DS:DI:  Ptr to Disk Parameter Table
138;   Returns:
139;       BL:     LBA Low Register / Sector Number Register (LBA 7...0)
140;       CL:     LBA Mid Register / Low Cylinder Register (LBA 15...8)
141;       CH:     LBA High Register / High Cylinder Register (LBA 23...16)
142;       BH:     Drive and Head Register (LBA 27...24)
143;   Corrupts registers:
144;       AX, DX
145;--------------------------------------------------------------------
[421]146ConvertAssistedLBAModeLCHStoLBARegisterValues:
[165]147    ; cylToSeek*headsPerCyl (18-bit result)
[421]148    ; Max = 1023 * 255 = 260,865 = 3FB01h
[294]149    mov     ax, LBA_ASSIST_SPT      ; Load Sectors per Track
150    xchg    cx, ax                  ; Cylinder number to AX, Sectors per Track to CX
151%ifdef USE_386
[421]152    movzx   dx, [di+DPT.bLchsHeads]
[294]153%else
154    cwd
[421]155    mov     dl, [di+DPT.bLchsHeads]
[294]156%endif
[165]157    mul     dx                      ; DX:AX = cylToSeek*headsPerCyl
158
159    ; +=headToSeek (18-bit result)
[421]160    ; Max = 260,865 + 254 = 261,119 = 3FBFFh
[165]161    add     al, bh                  ; Add Head number to DX:AX
162    adc     ah, dh                  ; DH = Zero after previous multiplication
163    adc     dl, dh
164
165    ; *=sectPerTrack (18-bit by 6-bit multiplication with 24-bit result)
[421]166    ; Max = 261,119 * 63 = 16,450,497 = FB03C1h
[165]167    xchg    ax, dx                  ; Hiword to AX, loword to DX
168    mul     cl                      ; AX = hiword * Sectors per Track
169    mov     bh, al                  ; Backup hiword * Sectors per Track
170    xchg    ax, dx                  ; Loword back to AX
171    mul     cx                      ; DX:AX = loword * Sectors per Track
172    add     dl, bh                  ; DX:AX = (cylToSeek*headsPerCyl+headToSeek)*sectPerTrack
173
174    ; +=sectToSeek-1 (24-bit result)
[421]175    ; Max = 16,450,497 + 63 - 1 = 16,450,559 = FB03FFh
[165]176    xor     bh, bh                  ; Sector number now in BX
177    dec     bx                      ; sectToSeek-=1
178    add     ax, bx                  ; Add to loword
179    adc     dl, bh                  ; Add possible carry to byte2, BH=zero
180
181    ; Copy DX:AX to proper return registers
182    xchg    bx, ax                  ; BL = Sector Number Register (LBA 7...0)
183    mov     cl, bh                  ; Low Cylinder Register (LBA 15...8)
184    mov     ch, dl                  ; High Cylinder Register (LBA 23...16)
185    mov     bh, dh                  ; Drive and Head Register (LBA 27...24)
186    ret
Note: See TracBrowser for help on using the repository browser.