📄 xdma.lst
字号:
325 000000CB 91 xchg ax,cx ;CHS -- save request code and sectors.
326 000000CC 31FF xor di,di ;Reset upper LBA address bits.
327 000000CE BE3F00 mov si,0003Fh ;Set SI-reg. to starting sector.
328 000000D1 21C6 and si,ax
329 000000D3 4E dec si
330 000000D4 C0E806 shr al,6 ;Set AX-reg. to starting cylinder.
331 000000D7 86C4 xchg al,ah
332 000000D9 92 xchg ax,dx ;Swap cylinder & head values.
333 000000DA 2E8A463C mov al,[cs:bp+CHSSec-@] ;Get disk CHS sectors/head value.
334 000000DE 08C0 or al,al ;Were disk CHS values legitimate?
335 000000E0 74CF jz Pass ;No? Let BIOS do this request!
336 000000E2 50 push ax ;Save CHS sectors/head value.
337 000000E3 F6E4 mul ah ;Convert head to sectors.
338 000000E5 01C6 add si,ax ;Add result to starting sector.
339 000000E7 58 pop ax ;Reload CHS sectors/head value.
340 000000E8 2EF66640 mul byte [cs:bp+CHSHd-@] ;Convert cylinder to sectors.
341 000000EC F7E2 mul dx
342 000000EE 01C6 add si,ax ;Add to head/sector value.
343 000000F0 11FA adc dx,di
344 000000F2 93 xchg ax,bx ;Get buffer offset in AX-register.
345 000000F3 91 xchg ax,cx ;Swap offset with request/sectors.
346 000000F4 1E SaveSeg push ds ;Save CPU segment registers.
347 000000F5 06 push es
348 000000F6 0E push cs ;Set this driver's DS-register.
349 000000F7 1F pop ds
350 000000F8 31DB xor bx,bx ;Zero BX-reg. for relative commands.
351 000000FA 88571F mov [bx+LBA+2-@],dl ;Save LBA bits 16-23, to free DL-reg.
352 000000FD 8A5713 mov dl,[bx+ReqBF-@] ;Set driver & channel "busy" flags
353 00000100 085712 or [bx+Flags-@],dl ; so other IDE drivers will WAIT!
354 00000103 FB sti ;Re-enable CPU interrupts.
355 00000104 89771D mov [bx+LBA-@],si ;Save LBA bits 0-15 and 24-47.
356 00000107 887719 mov [bx+LBA2-@],dh
357 0000010A 897F1A mov [bx+LBA2+1-@],di
358 0000010D 894F28 mov [bx+VDSOf-@],cx ;Save 32-bit user buffer address.
359 00000110 895F2A mov [bx+VDSOf+2-@],bx
360 00000113 8C472C mov [bx+VDSSg-@],es ;Save 16-bit user buffer segment.
361 00000116 C1EA0C shr dx,12 ;Shift out LBA bits 16-27.
362 00000119 09D7 or di,dx ;Anything in LBA bits 28-47?
363 0000011B 7508 jnz LBA48 ;Yes, use LBA48 read/write command.
364 0000011D 867719 xchg dh,[bx+LBA2-@] ;LBA28 -- reload & reset bits 24-27.
365 00000120 80CCC9 or ah,(DRCMD+1) ;Get LBA28 read/write command + 5.
366 00000123 EB03 jmp short GetAdr ;Go get IDE and LBA address bytes.
367 00000125 C0E403 LBA48 shl ah,3 ;LBA48 -- get command as 020h/030h.
368 00000128 B207 GetAdr mov dl,(LBABITS/32) ;Initialize LBA command bits.
369 0000012A BFF600 mov di,(CDSEL-100h) ;Get primary device-address bytes.
370 @DMALo1 equ $-1 ;(Lower DMA command address, Init set).
371 0000012D D1ED shr bp,1 ;Is this a primary-channel request?
372 0000012F 7403 jz DevAdr ;Yes, set IDE & PCI address bytes.
373 00000131 BF7608 mov di,(CDSEL+680h) ;Get secondary device-address bytes.
374 @DMALo2 equ $-1 ;(Lower DMA command address, Init set).
375 00000134 897F07 DevAdr mov [bx+IDEAd-@],di ;Set current IDE & PCI address bytes.
376 00000137 C0D205 rcl dl,5 ;Shift disk-select into LBA commands.
377 0000013A 08F2 or dl,dh ;"Or" in LBA28 bits 24-27 (if any).
378 0000013C B605 mov dh,005h ;Get final IDE command byte.
379 0000013E 30E6 xor dh,ah ;(LBA28 = C8h/CAh, LBA48 = 25h/35h).
380 00000140 895720 mov [bx+DSCmd-@],dx ;Set LBA and IDE command bytes.
381 00000143 88471C mov [bx+SecCt-@],al ;Set I-O sector count.
382 00000146 B400 mov ah,0 ;Set VDS/XMS and DMA buffer lengths.
383 00000148 D1E0 shl ax,1
384 0000014A 894725 mov [bx+VDSLn+1-@],ax
385 0000014D 894735 mov [bx+IOLen+1-@],ax
386 00000150 F6C600 test dh,0 ;Overlap output request?
387 @Ovlp1 equ $-1 ;(012h if overlap enabled).
388 00000153 7578 jnz BufIO ;Yes, do buffered output.
389 00000155 66834F30FF or dword [bx+IOAdr-@],byte -1 ;Invalidate VDS address.
390 0000015A B80381 mov ax,08103h ;VDS "lock" user buffer.
391 0000015D BA0C00 mov dx,0000Ch
392 00000160 E8AF00 call VDLock
393 00000163 7268 jc BufIO ;Error -- do buffered I-O.
394 00000165 8B4730 mov ax,[bx+IOAdr-@] ;Get lower VDS address.
395 00000168 66837F30FF cmp dword [bx+IOAdr-@],byte -1 ;Is VDS address valid?
396 0000016D 7211 jb SetVLF ;Yes, set VDS "lock" flag.
397 0000016F B81000 mov ax,16 ;No VDS -- get 20-bit buffer segment.
398 00000172 F7672C mul word [bx+VDSSg-@]
399 00000175 034728 add ax,[bx+VDSOf-@] ;Add in buffer offset value.
400 00000178 11DA adc dx,bx
401 0000017A 894730 mov [bx+IOAdr-@],ax ;Set 20-bit user buffer address.
402 0000017D 895732 mov [bx+IOAdr+2-@],dx
403 00000180 105F11 SetVLF adc [bx+VLF-@],bl ;Set VDS "lock" flag from carry bit.
404 00000183 A803 test al,003h ;Is user I-O buffer 32-bit aligned?
405 00000185 7543 jnz NoLock ;No, use buffered I-O routines below.
406 00000187 8B4F34 mov cx,[bx+IOLen-@] ;Get lower ending DMA address.
407 0000018A 49 dec cx ;(IOLen - 1 + IOAdr).
408 0000018B 01C8 add ax,cx ;Would this I-O cross a 64K boundary?
409 0000018D 723B jc NoLock ;Yes, use buffered I-O routines below.
410 0000018F 837F32FF cmp word [bx+IOAdr+2-@],byte -1 ;DMA I-O above our limit?
411 @DMALmt equ $-1 ;(If 640K limit, set to 009h by Init).
412 00000193 7735 ja NoLock ;Yes, use buffered I-O routines below.
413 00000195 E89000 call DoDMA ;Do direct DMA I-O with user's buffer.
414 00000198 89E5 Done mov bp,sp ;Done -- point to saved registers.
415 0000019A 884613 mov [bp+19],al ;Set error code in exiting AH-reg.
416 0000019D 9C pushf ;Save error flag (carry bit).
417 0000019E E86700 call VDUnlk ;If needed, "unlock" user I-O buffer.
418 000001A1 FA cli ;Disable CPU interrupts.
419 000001A2 8A4713 mov al,[bx+ReqBF-@] ;Reset driver & channel "busy" flags
420 000001A5 F6D0 not al ; so other IDE drivers may proceed!
421 000001A7 204712 and [bx+Flags-@],al
422 000001AA 58 pop ax ;Reload error flag into carry bit.
423 000001AB D1E8 shr ax,1
424 000001AD 07 pop es ;Reload all CPU registers.
425 000001AE 1F pop ds
426 000001AF 61 popa
427 000001B0 2E0FB226[4400] lss sp,[cs:CStack] ;Switch back to caller's stack.
428 000001B6 89E5 GetOut mov bp,sp ;Point to caller's saved BP-reg.
429 000001B8 D05E06 rcr byte [bp+6],1 ;Set error flag in exiting carry
430 000001BB D04606 rol byte [bp+6],1 ; bit, in flags saved by Int 13h.
431 000001BE 5D pop bp ;Reload BP-register and exit.
432 000001BF CF iret
433 000001C0 E81F00 BufOut call XMSMov ;Buffered output -- move data to XMS.
434 000001C3 72D3 jc Done ;If error, post return code & exit!
435 000001C5 E85800 call BufDMA ;Output all data from XMS buffer.
436 000001C8 EBCE jmp short Done ;Done -- post any return code & exit.
437 000001CA E83B00 NoLock call VDUnlk ;Buffered I-O -- "unlock" user buffer.
438 000001CD 66C1672810 BufIO shl dword [bx+VDSOf-@],16 ;Convert to XMS handle & offset.
439 000001D2 F6472112 test byte [bx+IOCmd-@],012h ;Is this a write request?
440 000001D6 75E8 jnz BufOut ;Yes, use output routine above.
441 000001D8 E84500 call BufDMA ;Input all data to driver XMS buffer.
442 000001DB 72BB jc Done ;If error, post return code & exit!
443 000001DD E80200 call XMSMov ;Move XMS data to user input buffer.
444 000001E0 EBB6 jmp short Done ;Done -- post any return code & exit.
445 ;
446 ; Subroutine to move data to or from the driver's XMS buffer.
447 ;
448 000001E2 0E XMSMov push cs ;Point ES-reg. to our data.
449 000001E3 07 pop es
450 000001E4 BF[2E00] mov di,XMSDH ;Point to XMS destination field.
451 000001E7 7508 jnz XMSet ;If output, just set XMS destination!
452 000001E9 BE[2800] mov si,XMSSH ;Point to XMS user-buffer address.
453 000001EC 56 push si
454 000001ED A5 movsw ;Move user-buffer address from
455 000001EE A5 movsw ; XMS source to XMS destination.
456 000001EF A5 movsw
457 000001F0 5F pop di ;Point to XMS source field.
458 000001F1 BE[2200] XMSet mov si,XMOfs ;Set XMS handle and buffer offset as
459 000001F4 B80000 mov ax,0 ; input source or output destination.
460 @XMHdl equ $-2 ;(XMS memory "handle", set by Init).
461 000001F7 AB stosw
462 000001F8 A5 movsw
463 000001F9 891D mov [di],bx
464 000001FB B40B mov ah,00Bh ;Get XMS "move data" request code.
465 000001FD 53 push bx ;Save BX-reg. and execute XMS request.
466 000001FE 9A db 09Ah ;(SI-reg. points to IOLen after move).
467 000001FF 00000000 @XEntry dd 0 ;(XMS "entry" address, set by Init).
468 00000203 48 dec ax ;Return 0 if success, -1 if error.
469 00000204 D1F8 sar ax,1 ;If error, set carry flag on.
470 00000206 EB12 jmp short VDDone ;Go restore driver settings and exit.
471 ;
472 ; Subroutine to do a VDS "lock" or "unlock".
473 ;
474 00000208 D06F11 VDUnlk shr byte [bx+VLF-@],1 ;Was I-O buffer "locked" by VDS?
475 0000020B 7312 jnc VDExit ;No, just exit below.
476 0000020D B80481 VDUnlX mov ax,08104h ;Get VDS "unlock" parameters.
477 00000210 31D2 xor dx,dx
478 00000212 BF[2400] VDLock mov di,VDSLn ;Point to VDS parameter block.
479 00000215 0E push cs
480 00000216 07 pop es
481 00000217 53 push bx ;Save BX-reg. and execute VDS request.
482 00000218 CD4B int 04Bh
483 0000021A 5B VDDone pop bx ;Reload our BX-register.
484 0000021B FB sti ;RESTORE all critical driver settings!
485 0000021C FC cld ;(Never-NEVER "trust" external code!).
486 0000021D 0E push cs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -