📄 xdma.lst
字号:
487 0000021E 1F pop ds
488 0000021F C3 VDExit ret ;Exit.
489 ;
490 ; Subroutine to execute read and write commands.
491 ;
492 00000220 66C7473000000000 BufDMA mov dword [bx+IOAdr-@],0 ;Buffered -- set XMS buffer addr.
493 @XBufAd equ $-4 ;(XMS 32-bit buffer address, Init set).
494 00000228 8B5708 DoDMA mov dx,[bx+DMAAd-@] ;Ensure any previous DMA is stopped!
495 0000022B EC in al,dx ;(On some older chipsets, if DMA is
496 0000022C 24FE and al,0FEh ; running, reading an IDE register
497 0000022E EE out dx,al ; causes the chipset to "HANG"!!).
498 0000022F 8A4720 mov al,[bx+DSCmd-@] ;Select our desired disk.
499 00000232 24F0 and al,0F0h
500 00000234 8A5707 mov dl,[bx+IDEAd-@]
501 00000237 B601 mov dh,001h
502 00000239 EE out dx,al
503 0000023A 89D7 mov di,dx ;Save IDE drive-select address.
504 0000023C B94008 mov cx,(RDYTO*256)+(FLT*2) ;Get timeout & "fault" mask.
505 0000023F E85600 call Await ;Await controller- and disk-ready.
506 00000242 72DB jc VDExit ;If any errors, exit above!
507 00000244 56 push si ;Save BIOS timer pointer.
508 00000245 BE[1400] mov si,PRDAd ;Point to parameters we will output.
509 00000248 F6440D12 test byte [si+IOCmd-PRDAd],012h ;Is this a write request?
510 0000024C 7502 jnz SetDMA ;Yes, reset DMA command register.
511 0000024E B008 mov al,008h ;Get "DMA read" command bit.
512 00000250 8B5708 SetDMA mov dx,[bx+DMAAd-@] ;Reset DMA commands and set DMA mode.
513 00000253 EE out dx,al
514 00000254 42 inc dx ;Point to DMA status register.
515 00000255 42 inc dx
516 00000256 EC in al,dx ;Reset DMA status register.
517 00000257 0C06 or al,006h ;(Done this way so we do NOT alter
518 00000259 EE out dx,al ; the "DMA capable" status flags!).
519 0000025A 42 inc dx ;Set PRD pointer to our DMA address.
520 0000025B 42 inc dx
521 0000025C 666F outsd
522 0000025E B8F701 mov ax,001F7h ;Set IDE parameter-output flags.
523 00000261 8D55FB NxtPar lea dx,[di+CSECCT-CDSEL-1] ;Point to IDE sector count -1.
524 00000264 42 IDEPar inc dx ;Output all ten LBA48 parameter bytes.
525 00000265 6E outsb ;(1st 4 overlayed by 2nd 4 if LBA28!).
526 00000266 D1E8 shr ax,1 ;More parameters to go in this group?
527 00000268 72FA jc IDEPar ;Yes, loop back and output next one.
528 0000026A 75F5 jnz NxtPar ;If first 4 done, go output last 6.
529 0000026C 5E pop si ;Reload BIOS timer pointer.
530 0000026D B603 mov dh,003h ;Get IDE alternate-status address.
531 0000026F 4A dec dx ;(Primary-status address | 300h - 1).
532 00000270 263A2C ChkDRQ cmp ch,[es:si] ;Too long without 1st data-request?
533 00000273 7476 je DMAEnd ;Yes? Return carry and DMA timeout!
534 00000275 EC in al,dx ;Read IDE alternate status.
535 00000276 2408 and al,DRQ ;Has 1st data-request arrived?
536 00000278 74F6 jz ChkDRQ ;No, loop back and check again.
537 0000027A 8B5708 mov dx,[bx+DMAAd-@] ;Point to DMA command register.
538 0000027D EC in al,dx ;Set DMA Start/Stop bit (starts DMA).
539 0000027E 40 inc ax
540 0000027F EE out dx,al
541 00000280 F6472100 test byte [bx+IOCmd-@],0 ;Overlap output request?
542 @Ovlp2 equ $-1 ;(012h if overlap enabled).
543 00000284 741E jz ChkDMA ;No, go await input end.
544 00000286 8A4713 mov al,[bx+ReqBF-@] ;Post channel "overlap" flag,
545 00000289 2460 and al,060h ; so other IDE drivers WAIT!
546 0000028B C0E802 shr al,2
547 0000028E 084712 or [bx+Flags-@],al
548 00000291 C6470608 mov byte [bx+Timer-@],RDYTO ;Set 400-msec timeout count.
549 00000295 31C0 xor ax,ax ;Return success & zero carry.
550 00000297 C3 ret ;Exit back to "BufOut" logic.
551 ;
552 ; Subroutine to await end of I-O.
553 ;
554 00000298 8EC3 Await mov es,bx ;Point to low-memory BIOS timer.
555 0000029A BE6C04 mov si,BIOSTMR
556 0000029D 26022C add ch,[es:si] ;Set timeout limit in CH-reg.
557 000002A0 D0E9 shr cl,1 ;Are we only checking drive "ready"?
558 000002A2 7320 jnc ChkRdy ;Yes, use logic below.
559 000002A4 42 ChkDMA inc dx ;Point to DMA status register.
560 000002A5 42 inc dx
561 000002A6 EC in al,dx ;Read DMA controller status.
562 000002A7 4A dec dx ;Point back to DMA command register.
563 000002A8 4A dec dx
564 000002A9 2406 and al,DMI+DME ;DMA interrupt or DMA error?
565 000002AB 7505 jnz HltDMA ;Yes, halt DMA and check results.
566 000002AD 263A2C cmp ch,[es:si] ;Has our DMA transfer timed out?
567 000002B0 75F2 jne ChkDMA ;No, loop back and check again.
568 000002B2 50 HltDMA push ax ;Save ending DMA status.
569 000002B3 EC in al,dx ;Reset DMA Start/Stop bit.
570 000002B4 24FE and al,0FEh
571 000002B6 EE out dx,al
572 000002B7 58 pop ax ;Reload ending DMA status.
573 000002B8 3C04 cmp al,DMI ;Did DMA end with only an interrupt?
574 000002BA 752D jne ErrDMA ;No? Go see what went wrong.
575 000002BC 42 inc dx ;Reread DMA controller status.
576 000002BD 42 inc dx
577 000002BE EC in al,dx
578 000002BF A802 test al,DME ;Any "late" DMA error after DMA end?
579 000002C1 7528 jnz DMAEnd ;Yes? Return carry and DMA error!
580 000002C3 41 inc cx ;Check "fault" and hard-error at end.
581 000002C4 8D5501 ChkRdy lea dx,[di+CSTAT-CDSEL] ;Read IDE primary status.
582 000002C7 EC in al,dx
583 000002C8 A8C0 test al,BSY+RDY ;Controller or disk still busy?
584 000002CA 7F0C jg ChkErr ;No, go check for "fault" or error.
585 000002CC 263A2C cmp ch,[es:si] ;Too long without becoming ready?
586 000002CF 75F3 jne ChkRdy ;No, loop back and check again.
587 000002D1 A880 test al,BSY ;BAAAD News! Did controller go ready?
588 000002D3 B88A00 mov ax,(256*CTLRERR)+DISKERR ;(Get not-ready error codes).
589 000002D6 EB09 jmp short WhichE ;Go see which error code to return.
590 000002D8 20C8 ChkErr and al,cl ;Disk "fault" or hard-error?
591 000002DA 740C jz ChkExit ;No, all is well -- go exit below.
592 000002DC A820 test al,FLT ;BAAAD News! Is the disk "faulted"?
593 000002DE B8BFAC mov ax,(256*FAULTED)+HARDERR ;(Get hardware error codes).
594 000002E1 7402 WhichE jz EndErr ;If "zero", use AL-reg. return code.
595 000002E3 88E0 mov al,ah ;Use AH-reg. return code of this pair.
596 000002E5 00C8 EndErr add al,cl ;Add 1 if error occurred at I-O end.
597 000002E7 F9 Kaput stc ;Set carry flag to denote "error"!
598 000002E8 C3 ChkExit ret ;Exit.
599 000002E9 A802 ErrDMA test al,DME ;BAAAD News! Did DMA end with error?
600 000002EB B8E8EF DMAEnd mov ax,(256*DMAERR)+DMATIMO ;(Get DMA error codes).
601 000002EE EBF1 jmp short WhichE ;Go see which error code to return.
602 BaseLmt equ $ ;End of resident "basic" logic.
603 BaseEnd equ $+BSTACK ;End of resident "basic" driver.
604 ;
605 ; Subroutine to display an error-message number. At entry, the BL-
606 ; register has the digits count, and the AX-register has the data.
607 ;
608 000002F0 43 Dsply4 inc bx ;Set 4-digit display count.
609 000002F1 43 inc bx
610 000002F2 43 Dsply2 inc bx ;Set 2-digit display count.
611 000002F3 43 Dsply1 inc bx ;Set 1-digit display count.
612 000002F4 C1C004 DsplyN rol ax,4 ;Get next hex digit in low-order.
613 000002F7 50 push ax ;Save remaining digits.
614 000002F8 240F and al,00Fh ;Mask off next hex digit.
615 000002FA 3C09 cmp al,009h ;Is digit 0-9?
616 000002FC 7602 jbe DspNmA ;Yes, convert to ASCII.
617 000002FE 0407 add al,007h ;Add A-F offset.
618 00000300 0430 DspNmA add al,030h ;Convert digit to ASCII.
619 00000302 E87800 call DsplyB ;Display digit using the BIOS.
620 00000305 58 pop ax ;Reload remaining digits.
621 00000306 4B dec bx ;More digits to go?
622 00000307 75EB jnz DsplyN ;Yes, loop back.
623 00000309 C3 ret ;Exit.
624 ;
625 ; Subroutine to display an error-message "text" element.
626 ; At entry, the "text" pointer is in the SI-register.
627 ;
628 0000030A E87000 DspNxt call DsplyB ;Display byte using the BIOS.
629 0000030D FC DsplyM cld ;Ensure FORWARD "string" commands!
630 0000030E AC lodsb ;Get next output byte.
631 0000030F 08C0 or al,al ;Are we at the terminating "null"?
632 00000311 75F7 jnz DspNxt ;No, loop back & display next byte.
633 00000313 C3 ret ;Exit.
634 ;
635 ; Subroutine to await overlap end and display any output-error message.
636 ; NOTE: Starting in V3.1 XDMA, "OCheck" is FIXED to address 00314h, so
637 ; XCDROM or other IDE drivers can call "OCheck" and have it wait
638 ; for overlap-end, before doing their own I-O on an IDE channel.
639 ;
640 00000314 60 OCheck pusha ;Save all CPU registers.
641 00000315 1E push ds
642 00000316 06 push es
643 00000317 0E push cs ;Set our DS-register.
644 00000318 1F pop ds
645 00000319 31DB xor bx,bx ;Zero BX-reg. for relative commands.
646 0000031B 804F1280 or byte [bx+Flags-@],080h ;Set driver I-O "busy" flag.
647 0000031F FB sti ;Re-enable CPU interrupts.
648 00000320 B94101 mov cx,257+(FLT*2) ;Set 1 extra count & "fault" mask.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -