Changeset 545 in xtideuniversalbios for trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDmaBlock.asm
- Timestamp:
- Apr 19, 2013, 11:44:35 AM (12 years ago)
- google:author:
- aitotat@gmail.com
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDmaBlock.asm
r526 r545 78 78 ; so we never need to separate transfer to more than 2 separate DMA operations. 79 79 80 ; Load XT-CF Control Register port to DX80 ; Load XT-CFv3 Control Register port to DX 81 81 add dl, XTCF_CONTROL_REGISTER 82 82 … … 90 90 shl cx, 1 91 91 %endif 92 cmp cx, ax 93 jbe SHORT .TransferLastDmaPageWithSizeInCX 92 cmp cx, ax ; if we won't cross a physical page boundary... 93 jbe SHORT .TransferLastDmaPageWithSizeInCX ; ...perform the transfer in one operation 94 94 95 ; Push size for second DMA page95 ; Calculate how much we can transfer on first and second rounds 96 96 xchg cx, ax ; CX = BYTEs for first page 97 97 sub ax, cx ; AX = BYTEs for second page 98 push ax 98 push ax ; Save bytes for second transfer on stack 99 99 100 100 ; Transfer first DMA page … … 108 108 ;-------------------------------------------------------------------- 109 109 ; StartDMAtransferForXTCFwithDmaModeInBL 110 ; Updated for XT-CFv3, 11-Apr-13 110 111 ; Parameters: 111 112 ; BL: Byte for DMA Mode Register 112 ; CX: Number of BYTEs to transfer (1...32768 since max block size is limited to 64) 113 ; DX: XTCF Control Register 113 ; CX: Number of BYTEs to transfer (512...32768 since max block size is limited to 64) 114 ; DX: XT-CFv3 Control Register 115 ; ES: Bits 3..0 have physical address bits 19..16 116 ; DI: Physical address bits 15..0 114 117 ; Returns: 115 ; Nothing118 ; ES:DI updated (CX is added) 116 119 ; Corrupts registers: 117 120 ; AX … … 122 125 ; Disable Interrupts and DMA Channel 3 during DMA setup 123 126 mov al, SET_CH3_MASK_BIT 124 cli ; Disable interrupts125 out MASK_REGISTER_DMA8_out, al 127 cli ; Disable interrupts - programming must be atomic 128 out MASK_REGISTER_DMA8_out, al ; Disable DMA Channel 3 126 129 127 130 ; Set DMA Mode (read or write using channel 3) … … 129 132 out MODE_REGISTER_DMA8_out, al 130 133 131 ; Set address to DMA controller 132 out CLEAR_FLIPFLOP_DMA8_out, al ; Reset flip-flop to low byte 134 ; Send start address to DMA controller 133 135 mov ax, es 134 136 out PAGE_DMA8_CH_3, al 135 137 mov ax, di 138 out CLEAR_FLIPFLOP_DMA8_out, al ; Reset flip-flop to low byte 136 139 out BASE_AND_CURRENT_ADDRESS_REGISTER_DMA8_CH3_out, al ; Low byte 137 140 mov al, ah … … 140 143 ; Set number of bytes to transfer (DMA controller must be programmed number of bytes - 1) 141 144 mov ax, cx 142 dec ax ; DMA controller is programmed for one byte less145 dec ax ; DMA controller is programmed for one byte less 143 146 out BASE_AND_CURRENT_COUNT_REGISTER_DMA8_CH3_out, al ; Low byte 144 147 mov al, ah … … 147 150 ; Enable DMA Channel 3 148 151 mov al, CLEAR_CH3_MASK_BIT 149 out MASK_REGISTER_DMA8_out, al ; Enable DMA Channel 3150 sti ; Enable interrupts152 out MASK_REGISTER_DMA8_out, al ; Enable DMA Channel 3 153 sti ; Enable interrupts 151 154 155 ; XT-CF transfers 16 bytes at a time. We need to manually start transfer for every block by writing (anything) 156 ; to the XT-CFv3 Control Register, which raises DRQ thereby passing system control to the 8237 DMA controller. 157 ; The XT-CFv3 logic releases DRQ after 16 transfers, thereby handing control back to the CPU and allowing any other IRQs or 158 ; DRQs to be serviced (which, on the PC and PC/XT will include DRAM refresh via DMA channel 0). The 16-byte transfers can 159 ; also be interrupted by the DMA controller raising TC (i.e. when done). Each transfer cannot be otherwise interrupted 160 ; and is therefore atomic (and hence fast). 152 161 153 %if 0 ; Slow DMA code 154 ; XT-CF transfers 16 bytes at a time. We need to manually 155 ; start transfer for every block. 156 ALIGN JUMP_ALIGN 157 .TransferNextBlock: 158 mov al, RAISE_DRQ_AND_CLEAR_XTCF_XFER_COUNTER 159 cli ; We want no ISR to read DMA Status Register before we do 160 out dx, al ; Transfer up to 16 bytes to/from XT-CF card 161 ; * Here XT-CF sets CPU to wait states during transfer * 162 in al, STATUS_REGISTER_DMA8_in 163 sti 164 test al, FLG_CH3_HAS_REACHED_TERMINAL_COUNT 165 jz SHORT .TransferNextBlock ; All bytes transferred? 162 %if 0 ; Slow DMA code - works by checking 8237 status register after each 16-byte transfer, until it reports TC has been raised. 163 ;ALIGN JUMP_ALIGN 164 ;.TransferNextBlock: 165 ; cli ; We want no ISR to read DMA Status Register before we do 166 ; out dx, al ; Transfer up to 16 bytes to/from XT-CF card 167 ; in al, STATUS_REGISTER_DMA8_in 168 ; sti 169 ; test al, FLG_CH3_HAS_REACHED_TERMINAL_COUNT 170 ; jz SHORT .TransferNextBlock ; All bytes transferred? 166 171 %endif ; Slow DMA code 167 172 168 169 %if 1 ; Fast DMA code 170 push cx 171 add cx, BYTE 15 ; Include any partial DMA block (since we had to divide transfer to 64k physical pages) 172 eSHR_IM cx, 4 ; Drive Block size to 16 Byte DMA Block Size 173 174 .JustOneMoreDmaBlock: 175 mov al, RAISE_DRQ_AND_CLEAR_XTCF_XFER_COUNTER 176 ALIGN JUMP_ALIGN 173 %if 1 ; Fast DMA code - perform computed number of transfers, then check DMA status register to be sure 174 push cx ; need byte count to update pointer at the end 175 add cx, BYTE 15 ; We'll divide transfers in 16-byte atomic transfers, 176 eSHR_IM cx, 4 ; so include any partial block, which will be terminated 177 ALIGN JUMP_ALIGN ; by the DMA controller raising T/C 177 178 .TransferNextDmaBlock: 178 out dx, al ; Transfer 16 bytes to/from XT-CF card 179 loop .TransferNextDmaBlock 180 179 out dx, al ; Transfer up to 16 bytes to/from XT-CF card 180 loop .TransferNextDmaBlock ; dec CX and loop if CX > 0, also adds required wait-state 181 181 inc cx ; set up CX, in case we need to do an extra iteration 182 in al, STATUS_REGISTER_DMA8_in 183 test al, FLG_CH3_HAS_REACHED_TERMINAL_COUNT 184 jz SHORT . JustOneMoreDmaBlock ; it wasn't set soget more bytes185 pop cx 182 in al, STATUS_REGISTER_DMA8_in ; check 8237 DMA controller status flags... 183 test al, FLG_CH3_HAS_REACHED_TERMINAL_COUNT ; ... for channel 3 terminal count 184 jz SHORT .TransferNextDmaBlock ; If not set, get more bytes 185 pop cx ; get back requested bytes 186 186 %endif ; Fast DMA code 187 187 188 ; Update physical address in ES:DI - since IO might need several calls through this function either from here 189 ; if crossing a physical page boundary, and from IdeTransfer.asm if requested sectors was > PIOVARS.wSectorsInBlock 190 mov ax, es ; copy physical page address to ax 191 add di, cx ; add requested bytes to di 192 adc al, 0 ; and increment physical page address, if required 193 mov es, ax ; and save it back in es 188 194 189 ; Restore XT-CF to normal operation190 mov al, XTCF_DMA_MODE191 out dx, al192 193 ; Increment physical address in ES:DI194 mov ax, es195 add di, cx196 adc al, ah197 mov es, ax198 195 ret
Note:
See TracChangeset
for help on using the changeset viewer.