Ignore:
Timestamp:
Apr 19, 2013, 11:44:35 AM (9 years ago)
Author:
aitotat@…
google:author:
aitotat@gmail.com
Message:

Changes to XTIDE Universal BIOS:

  • Integrated XT-CFv3 support by James Pearce.
  • XT-CFv2 memory mapped I/O and DMA modes are no longer supported (but PIO mode is).
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDmaBlock.asm

    r526 r545  
    7878    ; so we never need to separate transfer to more than 2 separate DMA operations.
    7979
    80     ; Load XT-CF Control Register port to DX
     80    ; Load XT-CFv3 Control Register port to DX
    8181    add     dl, XTCF_CONTROL_REGISTER
    8282
     
    9090    shl     cx, 1
    9191%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
    9494
    95     ; Push size for second DMA page
     95    ; Calculate how much we can transfer on first and second rounds
    9696    xchg    cx, ax                                  ; CX = BYTEs for first page
    9797    sub     ax, cx                                  ; AX = BYTEs for second page
    98     push    ax
     98    push    ax                                      ; Save bytes for second transfer on stack
    9999
    100100    ; Transfer first DMA page
     
    108108;--------------------------------------------------------------------
    109109; StartDMAtransferForXTCFwithDmaModeInBL
     110; Updated for XT-CFv3, 11-Apr-13
    110111;   Parameters:
    111112;       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
    114117;   Returns:
    115 ;       Nothing
     118;       ES:DI updated (CX is added)
    116119;   Corrupts registers:
    117120;       AX
     
    122125    ; Disable Interrupts and DMA Channel 3 during DMA setup
    123126    mov     al, SET_CH3_MASK_BIT
    124     cli                                     ; Disable interrupts
    125     out     MASK_REGISTER_DMA8_out, al      ; Disable DMA Channel 3
     127    cli                                 ; Disable interrupts - programming must be atomic
     128    out     MASK_REGISTER_DMA8_out, al  ; Disable DMA Channel 3
    126129
    127130    ; Set DMA Mode (read or write using channel 3)
     
    129132    out     MODE_REGISTER_DMA8_out, al
    130133
    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
    133135    mov     ax, es
    134136    out     PAGE_DMA8_CH_3, al
    135137    mov     ax, di
     138    out     CLEAR_FLIPFLOP_DMA8_out, al                         ; Reset flip-flop to low byte
    136139    out     BASE_AND_CURRENT_ADDRESS_REGISTER_DMA8_CH3_out, al  ; Low byte
    137140    mov     al, ah
     
    140143    ; Set number of bytes to transfer (DMA controller must be programmed number of bytes - 1)
    141144    mov     ax, cx
    142     dec     ax                              ; DMA controller is programmed for one byte less
     145    dec     ax                                                  ; DMA controller is programmed for one byte less
    143146    out     BASE_AND_CURRENT_COUNT_REGISTER_DMA8_CH3_out, al    ; Low byte
    144147    mov     al, ah
     
    147150    ; Enable DMA Channel 3
    148151    mov     al, CLEAR_CH3_MASK_BIT
    149     out     MASK_REGISTER_DMA8_out, al      ; Enable DMA Channel 3
    150     sti                                     ; Enable interrupts
     152    out     MASK_REGISTER_DMA8_out, al                          ; Enable DMA Channel 3
     153    sti                                                         ; Enable interrupts
    151154
     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).
    152161
    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?
    166171%endif ; Slow DMA code
    167172
    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
     177ALIGN JUMP_ALIGN                        ; by the DMA controller raising T/C
    177178.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
    181181    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 so get more bytes
    185     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
    186186%endif ; Fast DMA code
    187187
     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
    188194
    189     ; Restore XT-CF to normal operation
    190     mov     al, XTCF_DMA_MODE
    191     out     dx, al
    192 
    193     ; Increment physical address in ES:DI
    194     mov     ax, es
    195     add     di, cx
    196     adc     al, ah
    197     mov     es, ax
    198195    ret
Note: See TracChangeset for help on using the changeset viewer.