xdma.lst
来自「DOS下的dma读写驱动」· LST 代码 · 共 807 行 · 第 1/5 页
LST
807 行
649 00000323 026F06 add ch,[bx+Timer-@] ;Get ending output timer value +1.
650 00000326 8A4707 mov al,[bx+IDEAd-@] ;Set IDE status address in DI-reg.
651 00000329 B401 mov ah,001h
652 0000032B 97 xchg ax,di
653 0000032C 8B5708 mov dx,[bx+DMAAd-@] ;Get DMA command-register address.
654 0000032F E866FF call Await ;Await end of all DMA output.
655 00000332 7340 jnc OCExit ;If no output errors, exit below.
656 00000334 90 nop ;(Unused alignment "filler").
657 00000335 50 push ax ;BAAAD News! Save return code.
658 00000336 BE[C103] mov si,OEMsg ;Point to start of message "text".
659 00000339 E8D1FF call DsplyM ;Display beginning message text.
660 0000033C 58 pop ax ;Display error return code.
661 0000033D 86C4 xchg al,ah
662 0000033F E8B0FF call Dsply2
663 00000342 E8C8FF call DsplyM ;Display "Disk=" message text.
664 00000345 8A6707 mov ah,[bx+IDEAd-@] ;Get low-order IDE channel number.
665 00000348 C0EC02 shr ah,2 ;Align channel & disk-select bits.
666 0000034B 326720 xor ah,[bx+DSCmd-@] ;"XOR" with LBA command disk-select.
667 0000034E 80F4D0 xor ah,0D0h ;Zero upper bits & re-invert select.
668 00000351 E89FFF call Dsply1 ;Display disk number (0 to 3).
669 00000354 E8B6FF call DsplyM ;Display "LBA=" message text.
670 00000357 8B471A mov ax,[bx+LBA2+1-@] ;Display LBA bits 32-47.
671 0000035A E893FF call Dsply4
672 0000035D 8B471F mov ax,[bx+LBA+2-@] ;Get LBA bits 16-23 and LBA command.
673 00000360 80E40F and ah,00Fh ;Anything in "LBA28" bits 24-27?
674 00000363 7503 jnz OCMsg1 ;Yes, set bits 16-31 in message.
675 00000365 8A6719 mov ah,[bx+LBA2-@] ;Get "LBA48" bits 24-31.
676 00000368 E885FF OCMsg1 call Dsply4 ;Display LBA bits 16-31.
677 0000036B 8B471D mov ax,[bx+LBA-@] ;Display LBA bits 0-15.
678 0000036E E87FFF call Dsply4
679 00000371 E899FF call DsplyM ;Display ending message text.
680 00000374 FA OCExit cli ;Disable CPU interrupts.
681 00000375 80671267 and byte [bx+Flags-@],067h ;Reset I-O & overlap "busy".
682 00000379 07 pop es ;Reload all CPU registers and exit.
683 0000037A 1F pop ds
684 0000037B 61 popa
685 0000037C CB retf
686 ;
687 ; Subroutine to display a message byte using a BIOS "Int 010h" call.
688 ;
689 0000037D 53 DsplyB push bx ;Save all needed registers.
690 0000037E 56 push si
691 0000037F 50 push ax ;Save output byte.
692 00000380 B40F mov ah,00Fh ;Get BIOS video "page" in BH-reg.
693 00000382 CD10 int 010h
694 00000384 58 pop ax ;Reload output byte.
695 00000385 B40E mov ah,00Eh ;Have BIOS display next message byte.
696 00000387 CD10 int 010h
697 00000389 FB sti ;RESTORE all critical driver settings!
698 0000038A FC cld ;(Never-NEVER "trust" external code!).
699 0000038B 0E push cs
700 0000038C 1F pop ds
701 0000038D 5E pop si ;Reload registers and exit.
702 0000038E 5B pop bx
703 0000038F C3 ret
704 ;
705 ; Timer-interrupt routine, called every 55-msec by IRQ8 timer "ticks".
706 ;
707 00000390 9C TmInt pushf ;Entry -- save CPU flags and call
708 00000391 9A db 09Ah ; all other timer routines first!
709 00000392 00000000 @PrvTmr dd 0 ;(Prior timer vector, saved by Init).
710 00000396 FA cli ;Disable CPU interrupts.
711 00000397 1E push ds ;Save and set our DS-register.
712 00000398 0E push cs
713 00000399 1F pop ds
714 0000039A 53 push bx ;Save and zero our BX-register.
715 0000039B 31DB xor bx,bx
716 0000039D FE4F06 dec byte [bx+Timer-@] ;Decrement 400-msec timer.
717 000003A0 7F1C jg TmRet ;If it has not expired, exit!
718 000003A2 885F06 mov [bx+Timer-@],bl ;If zero BEFORE, reset it!
719 000003A5 F6471298 test byte [bx+Flags-@],098h ;Doing I-O, or NO overlap?
720 000003A9 7E13 jle TmRet ;If either, exit immediately.
721 000003AB 896744 mov [bx+CStack-@],sp ;Save caller's stack pointer.
722 000003AE 8C5746 mov [bx+CStack+2-@],ss
723 000003B1 0E push cs ;Switch to driver's stack.
724 000003B2 17 pop ss
725 000003B3 BC[4005] mov sp,ResEnd
726 000003B6 0E push cs ;Await end of output overlap.
727 000003B7 E85AFF call OCheck
728 000003BA 0FB26744 lss sp,[bx+CStack-@] ;Switch back to caller stack.
729 000003BE 5B TmRet pop bx ;Reload BX- and DS-registers.
730 000003BF 1F pop ds
731 000003C0 CF iret ;Exit.
732 ;
733 ; Output-Overlap Error Message "Text".
734 ;
735 000003C1 0D0A58444D41204572- OEMsg db CR,LF,'XDMA Error ',0
736 000003CA 726F722000
737 000003CF 682C204469736B3D00 db 'h, Disk=',0
738 000003D8 204C42413D00 db ' LBA=',0
739 000003DE 68210D0A db 'h!',CR,LF
740 000003E2 0700 @Beep db 007h,0
741 ResLmt equ $ ;End of resident overlap logic.
742 ResEnd equ $+OSTACK ;End of resident overlap driver.
743 ;
744 ; Subroutine to "validate" an UltraDMA hard-disk.
745 ;
746 000003E4 31DB I_ValD xor bx,bx ;Point ES-reg. to low memory.
747 000003E6 8EC3 mov es,bx
748 000003E8 B0EC mov al,0ECh ;Issue "Identify Device" command.
749 000003EA BAF701 mov dx,CCMD
750 000003ED 325707 xor dl,[bx+IDEAd-@]
751 000003F0 EE out dx,al
752 000003F1 BB6C04 mov bx,BIOSTMR ;Point to low-memory BIOS timer.
753 000003F4 B108 mov cl,RDYTO ;Set I-O timeout limit in CL-reg.
754 000003F6 26020F add cl,[es:bx]
755 000003F9 BE[8109] mov si,IEMsg ;Point to "Identify error" message.
756 000003FC 263A0F I_IDDly cmp cl,[es:bx] ;Has our command timed out?
757 000003FF 7409 je I_SErr ;Yes, set CPU carry flag & exit.
758 00000401 EC in al,dx ;Get IDE controller status.
759 00000402 A8C0 test al,BSY+RDY ;Controller or disk still busy?
760 00000404 7EF6 jle I_IDDly ;Yes, loop back and check again.
761 00000406 A801 test al,ERR ;Did command cause any errors?
762 00000408 7402 jz I_PIO ;No, read I.D. data using PIO mode.
763 0000040A F9 I_SErr stc ;Set carry flag (error!) and exit.
764 0000040B C3 ret
765 0000040C 83C2F9 I_PIO add dx,byte (CDATA-CCMD) ;Point to PIO data register.
766 0000040F ED in ax,dx ;Read I.D. bytes 0 and 1.
767 00000410 D1E0 shl ax,1 ;Save "ATA/ATAPI" flag in carry bit.
768 00000412 B91B00 mov cx,27 ;Skip I.D. bytes 2-53 and
769 00000415 ED I_Skp1 in ax,dx ; read I.D. bytes 54-55.
770 00000416 E2FD loop I_Skp1
771 00000418 0E push cs ;Point to disk-name message.
772 00000419 07 pop es
773 0000041A BF[D108] mov di,DName
774 0000041D B11A mov cl,26 ;Read & swap disk name into message.
775 0000041F 86E0 I_RdNm xchg ah,al ;(I.D. bytes 54-93. Bytes 94-105 are
776 00000421 AB stosw ; also read but are ignored. Bytes
777 00000422 ED in ax,dx ; 106-107 are left in the AX-reg.).
778 00000423 E2FA loop I_RdNm
779 00000425 93 xchg ax,bx ;Save "UltraDMA valid" flag in BL-reg.
780 00000426 B123 mov cl,35 ;Skip I.D. bytes 108-175 &
781 00000428 ED I_Skp2 in ax,dx ; read I.D. bytes 176-177.
782 00000429 E2FD loop I_Skp2
783 0000042B 88E7 mov bh,ah ;Save "UltraDMA mode" flags in BH-reg.
784 0000042D B1A7 mov cl,167 ;Skip remaining I.D. data.
785 0000042F ED I_Skp3 in ax,dx
786 00000430 E2FD loop I_Skp3
787 00000432 BE[9009] mov si,UEMsg ;Point to "is not UltraDMA" message.
788 00000435 D0DB rcr bl,1 ;Shift "ATA/ATAPI" flag into BL-reg.
789 00000437 80E382 and bl,082h ;ATAPI disk, or UltraDMA bits invalid?
790 0000043A 7ECE jle I_SErr ;Yes? Exit & display error message.
791 0000043C BF[5E08] mov di,Modes ;Point to UltraDMA mode table.
792 0000043F 08FF or bh,bh ;Will disk do UltraDMA mode 0?
793 00000441 74C7 jz I_SErr ;No? Exit & display message!
794 00000443 38DF I_NxtM cmp bh,bl ;Will disk do next UltraDMA mode?
795 00000445 7207 jb I_GotM ;No, use current mode.
796 00000447 47 inc di ;Point to next mode table value.
797 00000448 47 inc di
798 00000449 41 inc cx ;Get next UltraDMA mode number.
799 0000044A D0E3 shl bl,1 ;More UltraDMA modes to check?
800 0000044C 75F5 jnz I_NxtM ;Yes, loop back.
801 0000044E FF35 I_GotM push word [di] ;Save disk mode value.
802 00000450 BB[F908] mov bx,DNEnd ;Point to end of disk name.
803 00000453 81FB[D108] I_NxtN cmp bx,DName ;Are we at the disk-name start?
804 00000457 740D je I_Name ;Yes, disk name is all spaces!
805 00000459 4B dec bx ;Decrement disk name pointer.
806 0000045A 803F20 cmp byte [bx],' ' ;Is this name byte a space?
807 0000045D 74F4 j
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?