source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDmaBlock.asm @ 589

Last change on this file since 589 was 589, checked in by krille_n_, 8 years ago

Changes:

  • BIOS: Fixed a purely cosmetic bug from r542 where, in builds containing MODULE_EBIOS, the boot menu would display an incorrect drive size (0.4 kB with MODULE_STRINGS_COMPRESSED or 0.5 kB without) for old drives with no support for LBA.
  • Fixed a bug from r392 where Vision_DetectAndReturnIDinAXandPortInDXifControllerPresent would return the ID in AL instead of AH (if DANGEROUS_DETECTION had been defined).
  • Fixed a bug from r587 in AdvAtaInit.asm that would prevent detection of QDI Vision controllers.
  • Also changed how the QDI Vision IDs are defined (removed the need for shifting) to avoid confusion. This fixed a potential bug from r587 in AdvAtaInit.asm where some IDs were not being shifted.
  • Fixed a bug in PDC20x30.asm from r587 where GetPdcIDtoAX would not return with the IDE base port in DX so DisablePdcProgrammingMode would fail.
  • Made some changes to ModuleDependency.inc and other files so that MODULE_ADVANCED_ATA now requires USE_386. Consequently it is no longer included in the regular AT-builds, only in the 386_8k-build.
  • Moved the UNROLL_SECTORS_IN_CX_TO_xWORDS macros from IDE_8bit.inc to IdeIO.inc which means it's now possible to build a BIOS without MODULE_8BIT_IDE.
  • XTIDECFG: Added a minimum DOS version check (since it needs DOS version 2+) to allow the program to quit gracefully in the unlikely scenario where someone tries to run it under DOS version 1.
  • Made some changes to Drive.asm to improve drive enumeration. The old method using GET_DOS_DRIVE_PARAMETER_BLOCK_FOR_SPECIFIC_DRIVE worked well in Windows XP but not in Windows 98 SE (in Windows or in DOS mode). The two problems were; 1) The function call would access the drives which on single floppy drive systems would cause Windows to swap between A: and B: (throwing a blue screen asking the user to insert a disk etc). 2) Only floppy drives and FAT16 drives would be available in the list of drives, no FAT32/optical/network drives.
  • Improved code in IdeControllerMenu.asm so that the default port addresses for all IDE interfaces are now restored when (re-)selecting the (same) type of IDE device.
  • Also made it impossible to select a device type unless the required module is included in the loaded BIOS.
  • The version check done when loading a BIOS now uses the FLASH_SIGNATURE definition from Version.inc. Any changes affecting RomVars now only requires updating that definition. This means that changes to RomVars must be implemented in both the BIOS and XTIDECFG before being committed to the repository.
  • Added a compatibility fix for 3Com 3C503 cards to the ROM checksumming code in Buffers.asm (Buffers_GenerateChecksum).
  • SerDrive: Made some minor changes to file names and paths to improve compatibility with case sensitive environments.
  • BIOSDRVS: Made a minor size optimization which as a side effect also makes it compatible with all DOS versions including DOS version 1.
  • Library: Renamed the WAIT_RETRACE_IF_NECESSARY_THEN macro to CALL_WAIT_FOR_RETRACE_IF_NECESSARY_THEN and made a tail-call-optimized version of it (JMP_WAIT_FOR_RETRACE_IF_NECESSARY_THEN).
  • A speed optimization to the eRCL_IM macro for 386 and higher. This change breaks emulation in the sense that the macro will fail when given a memory operand as the first parameter.
  • Other minor optimizations and fixes.
File size: 7.9 KB
Line 
1; Project name  :   XTIDE Universal BIOS
2; Description   :   IDE Read/Write functions for transferring block using DMA.
3;                   These functions should only be called from IdeTransfer.asm.
4
5;
6; XTIDE Universal BIOS and Associated Tools
7; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
8;
9; This program is free software; you can redistribute it and/or modify
10; it under the terms of the GNU General Public License as published by
11; the Free Software Foundation; either version 2 of the License, or
12; (at your option) any later version.
13;
14; This program is distributed in the hope that it will be useful,
15; but WITHOUT ANY WARRANTY; without even the implied warranty of
16; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17; GNU General Public License for more details.
18; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19;
20
21; Section containing code
22SECTION .text
23
24;--------------------------------------------------------------------
25; IdeDmaBlock_WriteToXTCF
26;   Parameters:
27;       CX:     Block size in 512 byte sectors
28;       DX:     XTCF Base Port Address
29;       ES:SI:  Physical address to buffer to receive data
30;   Returns:
31;       Nothing
32;   Corrupts registers:
33;       AX, BX, CX, DX
34;--------------------------------------------------------------------
35ALIGN JUMP_ALIGN
36IdeDmaBlock_WriteToXTCF:
37    xchg    si, di
38    mov     bl, CHANNEL_3 | READ | AUTOINIT_DISABLE | ADDRESS_INCREMENT | DEMAND_MODE
39    call    TransferBlockToOrFromXTCF
40    xchg    di, si
41    ret
42
43
44;--------------------------------------------------------------------
45; IdeDmaBlock_ReadFromXTCF
46;   Parameters:
47;       CX:     Block size in 512 byte sectors
48;       DX:     XTCF Base Port Address
49;       ES:DI:  Physical address to buffer to receive data
50;   Returns:
51;       Nothing
52;   Corrupts registers:
53;       AX, BX, CX, DX
54;--------------------------------------------------------------------
55ALIGN JUMP_ALIGN
56IdeDmaBlock_ReadFromXTCF:
57    mov     bl, CHANNEL_3 | WRITE | AUTOINIT_DISABLE | ADDRESS_INCREMENT | DEMAND_MODE
58    ; Fall to TransferBlockToOrFromXTCF
59
60
61;--------------------------------------------------------------------
62; TransferBlockToOrFromXTCF
63;   Parameters:
64;       BL:     Mode byte for DMA Mode Register
65;       CX:     Block size in 512 byte sectors
66;       DX:     XTCF Base Port Address
67;       ES:DI:  Physical address to buffer to receive data
68;   Returns:
69;       Nothing
70;   Corrupts registers:
71;       AX, BX, CX, DX
72;--------------------------------------------------------------------
73TransferBlockToOrFromXTCF:
74    ; 8-bit DMA transfers must be done within 64k physical page.
75    ; XT-CF support maximum of 64 sector (32768 bytes) blocks in DMA mode
76    ; so we never need to separate transfer to more than 2 separate DMA operations.
77
78    ; Load XT-CFv3 Control Register port to DX
79    add     dl, XTCF_CONTROL_REGISTER
80
81    ; convert sectors in CX to BYTES
82%ifdef USE_186
83    shl     cx, 9                                   ; CX = Block size in BYTEs
84%else
85    xchg    cl, ch
86    shl     cx, 1
87%endif
88
89    ; Calculate bytes for first page
90    mov     ax, di
91    neg     ax          ; 2s complement
92
93    ; If DI was zero carry flag will be cleared (and set otherwise)
94    ; When DI is zero only one transfer is required since we've limited the
95    ; XT-CFv3 block size to 32k
96    jnc     SHORT StartDMAtransferForXTCFwithDmaModeInBL
97
98    ; CF was set, so DI != 0 and we might need one or two transfers
99    cmp     cx, ax                                          ; if we won't cross a physical page boundary...
100    jbe     SHORT StartDMAtransferForXTCFwithDmaModeInBL    ; ...perform the transfer in one operation
101
102    ; Calculate how much we can transfer on first and second rounds
103    xchg    cx, ax      ; CX = BYTEs for first page
104    sub     ax, cx      ; AX = BYTEs for second page
105    push    ax          ; Save bytes for second transfer on stack
106
107    ; Transfer first DMA page
108    call    StartDMAtransferForXTCFwithDmaModeInBL
109    pop     cx                                      ; Pop size for second DMA page
110    ; Fall to StartDMAtransferForXTCFwithDmaModeInBL
111
112
113;--------------------------------------------------------------------
114; StartDMAtransferForXTCFwithDmaModeInBL
115;   Parameters:
116;       BL:     Byte for DMA Mode Register
117;       CX:     Number of BYTEs to transfer (1...32768 since max block size is limited to 64)
118;       DX:     XT-CFv3 Control Register
119;       ES:     Bits 3..0 have physical address bits 19..16
120;       DI:     Physical address bits 15..0
121;   Returns:
122;       ES:DI updated (CX is added)
123;   Corrupts registers:
124;       AX, CX
125;--------------------------------------------------------------------
126ALIGN JUMP_ALIGN
127StartDMAtransferForXTCFwithDmaModeInBL:
128    ; Program 8-bit DMA Controller
129    ; Disable Interrupts and DMA Channel 3 during DMA setup
130    mov     al, SET_CH3_MASK_BIT
131    cli                                 ; Disable interrupts - programming must be atomic
132    out     MASK_REGISTER_DMA8_out, al  ; Disable DMA Channel 3
133
134    ; Set DMA Mode (read or write using channel 3)
135    mov     al, bl
136    out     MODE_REGISTER_DMA8_out, al
137
138    ; Send start address to DMA controller
139    mov     ax, es
140    out     PAGE_DMA8_CH_3, al
141    mov     ax, di
142    out     CLEAR_FLIPFLOP_DMA8_out, al                         ; Reset flip-flop to low byte
143    out     BASE_AND_CURRENT_ADDRESS_REGISTER_DMA8_CH3_out, al  ; Low byte
144    mov     al, ah
145    out     BASE_AND_CURRENT_ADDRESS_REGISTER_DMA8_CH3_out, al  ; High byte
146
147    ; Set number of bytes to transfer (DMA controller must be programmed number of bytes - 1)
148    mov     ax, cx
149    dec     ax                                                  ; DMA controller is programmed for one byte less
150    out     BASE_AND_CURRENT_COUNT_REGISTER_DMA8_CH3_out, al    ; Low byte
151    mov     al, ah
152    out     BASE_AND_CURRENT_COUNT_REGISTER_DMA8_CH3_out, al    ; High byte
153
154    ; Enable DMA Channel 3
155    mov     al, CLEAR_CH3_MASK_BIT
156    out     MASK_REGISTER_DMA8_out, al                          ; Enable DMA Channel 3
157    sti                                                         ; Enable interrupts
158
159    ; Update physical address in ES:DI - since IO might need several calls through this function either from here
160    ; if crossing a physical page boundary, or from IdeTransfer.asm if requested sectors was > PIOVARS.wSectorsInBlock
161    ; We update the pointer here (before the actual transfer) to avoid having to save the byte count on the stack
162    mov     ax, es                      ; copy physical page address to ax
163    add     di, cx                      ; add requested bytes to di
164    adc     al, 0                       ; and increment physical page address, if required
165    mov     es, ax                      ; and save it back in es
166
167    ; XT-CF transfers 16 bytes at a time. We need to manually start transfer for every block by writing (anything)
168    ; to the XT-CFv3 Control Register, which raises DRQ thereby passing system control to the 8237 DMA controller.
169    ; The XT-CFv3 logic releases DRQ after 16 transfers, thereby handing control back to the CPU and allowing any other IRQs or
170    ; DRQs to be serviced (which, on the PC and PC/XT will include DRAM refresh via DMA channel 0).  The 16-byte transfers can
171    ; also be interrupted by the DMA controller raising TC (i.e. when done).  Each transfer cannot be otherwise interrupted
172    ; and is therefore atomic (and hence fast).
173
174%if 0   ; Slow DMA code - works by checking 8237 status register after each 16-byte transfer, until it reports TC has been raised.
175ALIGN JUMP_ALIGN
176.TransferNextBlock:
177    cli                                 ; We want no ISR to read DMA Status Register before we do
178    out     dx, al                      ; Transfer up to 16 bytes to/from XT-CF card
179    in      al, STATUS_REGISTER_DMA8_in
180    sti
181    test    al, FLG_CH3_HAS_REACHED_TERMINAL_COUNT
182    jz      SHORT .TransferNextBlock    ; All bytes transferred?
183%else   ; Fast DMA code - perform computed number of transfers, then check DMA status register to be sure
184    ; We'll divide transfers in 16-byte atomic transfers, so include any partial block, which will be terminated by the DMA controller raising T/C
185    add     cx, BYTE 15
186
187%ifdef USE_186
188    shr     cx, 4
189%else
190    xchg    cx, ax
191    mov     cl, 4
192    shr     ax, cl
193    xchg    cx, ax
194%endif
195
196ALIGN JUMP_ALIGN
197.TransferNextDmaBlock:
198    out     dx, al                      ; Transfer up to 16 bytes to/from XT-CF card
199    loop    .TransferNextDmaBlock       ; dec CX and loop if CX > 0, also adds required wait-state
200    inc     cx                          ; set up CX, in case we need to do an extra iteration
201    in      al, STATUS_REGISTER_DMA8_in ; check 8237 DMA controller status flags...
202    test    al, FLG_CH3_HAS_REACHED_TERMINAL_COUNT  ; ... for channel 3 terminal count
203    jz      SHORT .TransferNextDmaBlock ; If not set, get more bytes
204%endif
205
206    ret
Note: See TracBrowser for help on using the repository browser.