|
|
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.