|
|
1.1 ! root 1: TITLE Sample 16 Bits DOS application ! 2: ;---------------------------------------------------------------; ! 3: ; ! 4: include 16bits.inc ! 5: ! 6: DOSSEG ! 7: .MODEL SMALL ! 8: ! 9: .STACK 100h ! 10: ! 11: .DATA ! 12: ! 13: ! 14: DMAWriteBuffer label byte ! 15: db 64 dup (?) ! 16: DMA_BUFFER_SIZE equ $ - DMAWriteBuffer ! 17: ! 18: DMAReadBuffer label byte ! 19: db DMA_BUFFER_SIZE dup (?) ! 20: ! 21: MIOPattern label byte ! 22: db 00, 0FFh, 0AAh, 055h ! 23: MIOPATTERN_SIZE equ $ - MIOPattern ! 24: ! 25: public start ! 26: ! 27: .CODE ! 28: start: ! 29: jmp short RealStart ! 30: OldVector label dword ! 31: dd ? ! 32: DMACompleted db ? ! 33: ! 34: RealStart: ! 35: mov ax,@DATA ! 36: mov ds,ax ! 37: mov es,ax ! 38: assume ds:@DATA, es:@DATA ! 39: ! 40: ;Hook interrupt(DMA terminate count notification) ! 41: push ds ! 42: mov al, DMA_INTERRUPT ! 43: mov ah, 35h ! 44: int 21h ! 45: mov word ptr cs:OldVector, bx ! 46: mov word ptr cs:OldVector + 2, es ! 47: mov dx, offset ISRDMACompleted ! 48: mov ax, cs ! 49: mov ds, ax ! 50: mov al, DMA_INTERRUPT ! 51: mov ah, 25h ! 52: int 21h ! 53: pop ds ! 54: ! 55: ! 56: ;VDD operation. ! 57: ;(1). Hook the I/O port. ! 58: ;(2). Keep the port status up-to-date if a write operation is performed ! 59: ; by 16 bits application(this program). ! 60: ;(3). Simulate DMA operation and generate a fake interrupt for 16bits ! 61: ; applicatiion if the DMA operation reaches its TC. ! 62: ; ! 63: ; ! 64: ;16bits application ! 65: ;(1). Output one byte to the port and then request DMA operation. ! 66: ;(2). Wait for DMA operation completed. ! 67: ;(3). goto step (1) if there are more data to be transferred. ! 68: ;Note that the given I/O must be a R/W port. ! 69: ! 70: ;Here we do a DMA write operation upon I/O mapped I/O ! 71: mov cx, DMA_BUFFER_SIZE ! 72: mov si, offset DMAWriteBuffer ! 73: DMATransferLoop_Fast: ! 74: mov dx, IO_PORT_DMA ! 75: mov al, cl ! 76: out dx, al ;write I/O the current count ! 77: cli ! 78: mov cs:DMACompleted, FALSE ;reset TC flag ! 79: sti ! 80: ;channel #1, write op, no auto init, addr inc, single transfer ! 81: mov al, 01000101B ! 82: call SetupDMAOperation ! 83: ;Fire the DMA WRITE operation, this will cause VDD to gain control ! 84: ;and start DMA operation. ! 85: mov dx, IO_PORT_FIRE_DMA_FAST ! 86: out dx, al ! 87: ;In real world(there is a real hardware adapter), we won't do this ! 88: ;idle loop, rather, we can do something useful(like, read the DMA current ! 89: ;count and display the progress and so forth)provided that we can regain ! 90: ;control while DMA operation is in progress(VDD spawns a new thread to ! 91: ;handle DMA operation and returns to us immediately) ! 92: ; ! 93: ;Since we are simulating DMA operation without hardware, we always ! 94: ;start the DMA operation with transfer count set to 1 byte. In reality ! 95: ;this is should not be the case because it will slow down the data transfer. ! 96: ! 97: WaitForDMA_Fast: ! 98: cmp cs:DMACompleted, TRUE ! 99: jnz WaitForDMA_Fast ! 100: inc si ! 101: loop DMATransferLoop_Fast ! 102: ; ! 103: ;Now do a DMA read operation ! 104: mov cx, DMA_BUFFER_SIZE ! 105: mov si, offset DMAWriteBuffer ! 106: mov di, offset DMAReadBuffer ! 107: DMATransferLoop_Slow: ! 108: ;channel #1, read op, no auto init, addr inc, single transfer ! 109: mov al, 01001001B ! 110: cli ! 111: mov cs:DMACompleted, FALSE ! 112: sti ! 113: call SetupDMAOperation ! 114: ;Fire the DMA READ operation ! 115: mov dx, IO_PORT_FIRE_DMA_SLOW ! 116: out dx, al ! 117: WaitForDMA_Slow: ! 118: cmp cs:DMACompleted, TRUE ! 119: jne WaitForDMA_Slow ! 120: mov dx, IO_PORT_DMA ! 121: in al, dx ! 122: mov [di], al ! 123: inc di ;advance our buffer ! 124: inc si ;and the DMA buffer ! 125: loop DMATransferLoop_Slow ! 126: ; ! 127: ;The DMAWriteBuffer and DMAReadBuffer should have the same contents. ! 128: ;If they don't, it failed. .... ! 129: ! 130: ! 131: ;Memory mapped I/O ! 132: mov ax, MIO_SEGMENT ! 133: mov es, ax ! 134: mov bx, MIOPATTERN_SIZE ! 135: mov si, offset MIOPattern ! 136: ! 137: MIO_Loop: ! 138: cld ! 139: lodsb ;get next pattern ! 140: mov cx, MIO_PORT_RANGE ! 141: mov di, MIO_PORT_FIRST ! 142: rep stosb ;fill all I/O with the pattern ! 143: mov cx, MIO_PORT_RANGE ! 144: dec di ! 145: std ! 146: repe scasb ; ! 147: je @F ! 148: ; call ErrorMIO ;if any i/o failed, ! 149: @@: ! 150: dec bx ;next pattern ! 151: jnz MIO_Loop ! 152: ! 153: ;Before terminate, retsore everything we have touched ! 154: push ds ! 155: lds dx, cs:OldVector ! 156: mov al, DMA_INTERRUPT ! 157: mov ah, 25h ! 158: int 21h ! 159: pop ds ! 160: mov ah, 04Ch ! 161: int 21h ! 162: ! 163: ;-------------------------------------------------------; ! 164: ;Setup DMA operation ! 165: ;Input: ds:si = seg:offset of memeory address ! 166: ; al = DMA mode ! 167: ;output: NONE ! 168: ;Modified: AX, DX ! 169: ;-------------------------------------------------------; ! 170: SetupDMAOperation proc ! 171: push cx ! 172: mov dx, DMA_PORT_FLIPFLOP ! 173: out dx, al ! 174: mov dx, DMA_PORT_MODE ;more register ! 175: out dx, al ! 176: mov ax, ds ;transfer address -> page:offset ! 177: mov cl, 4 ;page: A16 ~ A19, offset A0 ~ A15 ! 178: rol ax, cl ! 179: mov ch, al ! 180: and al, 0F0h ! 181: add ax, si ! 182: jnc @F ! 183: inc ch ! 184: @@: ! 185: mov dx, DMA_PORT_ADDR ! 186: out dx, al ;offset lower byte ! 187: mov al, ah ! 188: out dx, al ;and higher byte ! 189: mov dx, DMA_PORT_PAGE ;page register ! 190: mov al, ch ! 191: and al, 0Fh ;only 4 bits allowed ! 192: out dx, al ! 193: mov al, 1 ;single transfer, one byte ! 194: mov dx, DMA_PORT_COUNT ! 195: out dx, al ! 196: dec al ! 197: out dx, al ;higher byte set to 0 ! 198: mov dx, DMA_PORT_REQUEST ;request channel #1 ! 199: mov al, 00000101B ! 200: out dx, al ! 201: mov dx, DMA_PORT_SNGLE_MASK ;start DMA transfer ! 202: mov al, 00000001B ! 203: out dx, al ! 204: pop cx ! 205: ret ! 206: SetupDMAOperation endp ! 207: ! 208: ! 209: ISRDMACompleted proc far ! 210: mov byte ptr DMACompleted, TRUE ! 211: mov al, 20h ! 212: out 20h, al ! 213: out 0A0h, al ! 214: iret ! 215: ISRDMACompleted endp ! 216: ! 217: END start
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.