1 ; MMURTL Operating System Source Code
\r
2 ; Copyright 1991,1992,1993,1994 Richard A. Burgess
\r
3 ; ALL RIGHTS RESERVED Version 1.0
\r
9 ;========== DMA Equates for DMA amd PAGE registers =========
\r
10 ;NOTES: With 8 bit DMA, the lower WORD (bits 15-0) are placed into
\r
11 ; the address registers of the DMA, and the Page register is the next
\r
12 ; most significant byte (bits 23-16). With WORD DMA moves (channels 5-7),
\r
13 ; address bits 16-1 are placed in the address registers, while 23-17 are
\r
14 ; put in the page register. Bit 16 is ignored by the page register.
\r
17 ; DMA 1 Port addresses and page registers
\r
19 DMA10Add EQU 00h ;Ch 0 Address
\r
20 DMA10Cnt EQU 01h ;Ch 0 Word Count
\r
21 DMA11Add EQU 02h ;Ch 1 Address
\r
22 DMA11Cnt EQU 03h ;Ch 1 Word Count
\r
23 DMA12Add EQU 04h ;Ch 2 Address
\r
24 DMA12Cnt EQU 05h ;Ch 2 Word Count
\r
25 DMA13Add EQU 06h ;Ch 3 Address
\r
26 DMA13Cnt EQU 07h ;Ch 3 Word Count
\r
27 DMA1StatCmd EQU 08h ;Read Status/Write Command
\r
28 DMA1RqReg EQU 09h ;Read/Write DMA Rq Register
\r
29 DMA1RCmdWbm EQU 0Ah ;Read Command/Write Single bit mask
\r
30 DMA1Mode EQU 0Bh ;Read/Write Mode register
\r
31 DMA1FF EQU 0Ch ;Writing this address clears byte ptr flip flop
\r
32 DMA1Clear EQU 0Dh ;Write causes MASTER Clear (Read from Temp Reg)
\r
33 DMA1ClrMode EQU 0Eh ;Rd clears mode reg count/Wr Clr ALL mask bits
\r
34 DMA1MskBts EQU 0Fh ;Read/Write DMA Rq Mask Register
\r
36 ; DMA 2 Port addresses
\r
38 DMA20Add EQU 0C0h ;Ch 0 Address
\r
39 DMA20Cnt EQU 0C2h ;Ch 0 Word Count
\r
40 DMA21Add EQU 0C4h ;Ch 1 Address
\r
41 DMA21Cnt EQU 0C6h ;Ch 1 Word Count
\r
42 DMA22Add EQU 0C8h ;Ch 2 Address
\r
43 DMA22Cnt EQU 0CAh ;Ch 2 Word Count
\r
44 DMA23Add EQU 0CCh ;Ch 3 Address
\r
45 DMA23Cnt EQU 0CEh ;Ch 3 Word Count
\r
46 DMA2StatCmd EQU 0D0h ;Read Status/Write Command
\r
47 DMA2RqReg EQU 0D2h ;Read/Write DMA Rq Register
\r
48 DMA2RCmdWbm EQU 0D4h ;Read Command/Write Single bit mask
\r
49 DMA2Mode EQU 0D6h ;Read/Write Mode register
\r
50 DMA2FF EQU 0D8h ;Writing this address clears byte ptr flip flop
\r
51 DMA2Clear EQU 0DAh ;Write causes MASTER Clear (Read from Temp Reg)
\r
52 DMA2ClrMode EQU 0DCh ;Rd clears mode reg count/Wr Clr ALL mask bits
\r
53 DMA2MskBts EQU 0DEh ;Read/Write DMA Rq Mask Register
\r
55 ;DMA Page register by DRQ/DACK number
\r
57 DMAPage0 EQU 87h ;DMA DACK0 Page register
\r
58 DMAPage1 EQU 83h ; DACK1 (etc. etc. etc.)
\r
65 ; The following code sets up the initial DMA channel values for
\r
66 ; both chips to most probable use. Includes cascade mode for CH4
\r
67 ; which is DMA channel 0 on chip 2
\r
70 MOV AL, 04 ;Master disable
\r
74 XOR AL, AL ;MASTER CLEAR (same as hardware reset)
\r
78 XOR AL, AL ;All commands set to default (0)
\r
82 MOV AL, 40h ;CH 0 DMA 1
\r
84 MOV AL, 0C0h ;CH 0 DMA 2 (Cascade Mode)
\r
87 MOV AL, 41h ;CH 1 DMA 1 & 2
\r
91 MOV AL, 42h ;CH 2 DMA 1 & 2
\r
95 MOV AL, 43h ;CH 3 DMA 1 & 2
\r
100 OUT DMA1ClrMode, AL ;Enable ALL DMA 1 Channels
\r
101 OUT DMA2ClrMode, AL ;Enable ALL DMA 2 Channels
\r
105 ;-----------------------------------------------------------
\r
106 ; The following code sets up a single DMA channel for the caller.
\r
107 ; DMA is crippled because it can't move across 64K physical
\r
108 ; boundries. It's the caller's responsibility to know if he is
\r
109 ; crossing a boundry! If he does, this will wrap around over the segment!!!
\r
110 ; This code is completely reentrant.
\r
111 ; There is only one call for DMA set up.
\r
113 ; The caller sets the type of DMA operation (In, Out, Verify).
\r
114 ; For channels 5,6 & 7, the address & count must be divided by
\r
115 ; two for the DMA hardware. This routine does this for you!
\r
116 ; Algorythm - Put mode byte bits (except channel bits) in BL, then jump to
\r
117 ; correct routine for that channel. The call will allow set up of
\r
118 ; all the differnet types of DMA modes for read and write with this
\r
119 ; single call. The call:
\r
121 ; DmaSetUp(dPhyMem, sdMem, dChannel, dType, dMode)
\r
122 ; EBP+ 28 24 20 16 12
\r
124 ; dPhyMem is physical memory address
\r
125 ; sdMem is nBytes to move (STILL bytes for word xfers, we do math)
\r
126 ; dChannel (0,1,2,3,5,6,7)
\r
127 ; dType - 0 = Verify, 1 = In (Write Mem), 2 = Out (Read memory)
\r
128 ; dMode - 0 Demand Mode, 1 Single Cycle, (Disk I/O uses 1)
\r
129 ; 2 Block, 3 Cascade
\r
135 MOV EAX, [EBP+12] ; dMode
\r
136 CMP EAX, 04 ; Mode must be < 4
\r
138 MOV EAX, ErcDMAMode
\r
141 SHL EAX, 6 ; Move Mode bits to 6 and 7
\r
142 MOV BL, AL ; Put it in BL
\r
143 MOV EAX, [EBP+16] ; get dType
\r
144 AND BL, 0C0h ; Set to Verify by default (low bits 0)
\r
145 CMP EAX, 0 ; Check fType (Verify?)
\r
147 CMP EAX, 1 ; In? (Write)
\r
148 JE DMAWrite ; Yes (if no then fall thru to Read)
\r
150 OR BL, 00001000b ; OR read command to BL (OUT)
\r
153 OR BL, 00000100b ; OR write command to BL (IN)
\r
156 MOV EAX, [EBP+20] ;Jump table for channel selection
\r
171 MOV EAX, ErcDMAChannel
\r
176 MOV AL, 00000100b ; channel 0 Set Mask for DRQ
\r
177 OUT DMA1RCmdWbm, AL ;
\r
178 MOV AL, 00000000b ; CH0 (CH is last 2 bits)
\r
179 OR AL, BL ; OR with MODE
\r
181 OUT DMA1FF, AL ; Clear FlipFLop (Val in AL irrelevent)
\r
182 MOV EAX, [EBP+28] ; dPhyMem
\r
183 OUT DMA10Add, AL ; Lo byte address
\r
185 OUT DMA10Add, AL ; Hi Byte
\r
187 OUT DMAPage0, AL ; Highest byte (to page register)
\r
193 MOV AL, 00000000b ; channel 0 Clear Mask for DRQ
\r
194 OUT DMA1RcmdWbm, AL
\r
201 MOV AL, 00000101b ; channel 1 Set Mask for DRQ
\r
202 OUT DMA1RCmdWbm, AL
\r
203 MOV AL, 00000001b ; CH1
\r
204 OR AL, BL ; OR with MODE/TYPE
\r
206 OUT DMA1FF, AL ; Clear FlipFLop (Val in AL irrelevent)
\r
207 MOV EAX, [EBP+28] ; dPhyMem
\r
208 OUT DMA11Add, AL ; Lo byte address
\r
210 OUT DMA11Add, AL ; Hi Byte
\r
212 OUT DMAPage1, AL ; Highest byte (to page register)
\r
213 MOV EAX, [EBP+24] ; sdMem
\r
218 MOV AL, 00000001b ; channel 1 Clear Mask for DRQ
\r
219 OUT DMA1RcmdWbm, AL
\r
226 MOV AL, 00000110b ; channel 2 Set Mask for DRQ
\r
227 OUT DMA1RCmdWbm, AL
\r
228 MOV AL, 00000010b ; CH2
\r
229 OR AL, BL ; OR with MODE
\r
231 OUT DMA1FF, AL ; Clear FlipFLop (Val in AL irrelevent)
\r
232 MOV EAX, [EBP+28] ; dPhyMem
\r
233 OUT DMA12Add, AL ; Lo byte address
\r
235 OUT DMA12Add, AL ; Hi Byte
\r
237 OUT DMAPage2, AL ; Highest byte (to page register)
\r
238 MOV EAX, [EBP+24] ; sdMem
\r
243 MOV AL, 00000010b ; channel 2 Clear Mask for DRQ
\r
244 OUT DMA1RcmdWbm, AL
\r
251 MOV AL, 00000111b ; channel 3 Set Mask for DRQ
\r
252 OUT DMA1RCmdWbm, AL
\r
253 MOV AL, 00000011b ; CH3
\r
254 OR AL, BL ; OR with MODE
\r
256 OUT DMA1FF, AL ; Clear FlipFLop (Val in AL irrelevent)
\r
257 MOV EAX, [EBP+28] ; dPhyMem
\r
258 OUT DMA13Add, AL ; Lo byte address
\r
260 OUT DMA13Add, AL ; Hi Byte
\r
262 OUT DMAPage3, AL ; Highest byte (to page register)
\r
263 MOV EAX, [EBP+24] ; sdMem
\r
268 MOV AL, 00000011b ; channel 3 Clear Mask for DRQ
\r
269 OUT DMA1RcmdWbm, AL
\r
274 ;NOTE: DMA channels 5-7 are on DMA2 and numbered 1-3 for chip select purposes
\r
278 MOV AL, 00000101b ; channel 1 DMA2 Set Mask for DRQ
\r
279 OUT DMA2RCmdWbm, AL
\r
280 MOV AL, 00000001b ; CH1 on DMA 2
\r
281 OR AL, BL ; OR with MODE
\r
283 OUT DMA2FF, AL ; Clear FlipFLop (Val in AL irrelevent)
\r
284 MOV EAX, [EBP+28] ; dPhyMem
\r
285 MOV EBX, EAX ; Save EBX for page
\r
286 AND EAX, 0FFFFh ; Rid of all but lower 16
\r
287 SHR EAX, 1 ; DIV by 2 for WORD Xfer (bits 16-1)
\r
288 OUT DMA21Add, AL ; Lo byte address
\r
290 OUT DMA21Add, AL ; Hi Byte
\r
292 SHR EAX, 15 ; We only need 23-17 for the page
\r
293 OUT DMAPage5, AL ; Highest byte (to page register)
\r
294 MOV EAX, [EBP+24] ; sdMem
\r
295 SHR EAX, 1 ; DIV by 2 for WORD Xfer
\r
296 DEC EAX ; One less word
\r
300 MOV AL, 00000001b ; channel 1 Clear Mask for DRQ
\r
301 OUT DMA2RcmdWbm, AL
\r
308 MOV AL, 00000110b ; channel 2 Set Mask for DRQ
\r
309 OUT DMA2RCmdWbm, AL
\r
310 MOV AL, 00000010b ; CH2 on DMA 2
\r
311 OR AL, BL ; OR with MODE
\r
313 OUT DMA2FF, AL ; Clear FlipFLop (Val in AL irrelevent)
\r
314 MOV EAX, [EBP+28] ; dPhyMem
\r
316 AND EAX, 0FFFFh ; Rid of all but lower 16
\r
317 SHR EAX, 1 ; DIV by 2 for WORD Xfer
\r
318 OUT DMA22Add, AL ; Lo byte address
\r
320 OUT DMA22Add, AL ; Hi Byte
\r
323 OUT DMAPage6, AL ; Highest byte (to page register)
\r
324 MOV EAX, [EBP+24] ; sdMem
\r
325 SHR EAX, 1 ; DIV by 2 for WORD Xfer
\r
330 MOV AL, 00000010b ; channel 2 Clear Mask for DRQ
\r
331 OUT DMA2RcmdWbm, AL
\r
338 MOV AL, 00000111b ; channel 3 Set Mask for DRQ
\r
339 OUT DMA2RCmdWbm, AL
\r
340 MOV AL, 00000011b ; CH3 on DMA 2
\r
341 OR AL, BL ; OR with MODE
\r
343 OUT DMA2FF, AL ; Clear FlipFLop (Val in AL irrelevent)
\r
344 MOV EAX, [EBP+28] ; dPhyMem
\r
346 AND EAX, 0FFFFh ; Rid of all but lower 16
\r
347 SHR EAX, 1 ; DIV by 2 for WORD Xfer
\r
348 OUT DMA23Add, AL ; Lo byte address
\r
350 OUT DMA23Add, AL ; Hi Byte
\r
353 OUT DMAPage6, AL ; Highest byte (to page register)
\r
354 MOV EAX, [EBP+24] ; sdMem
\r
355 SHR EAX, 1 ; DIV by 2 for WORD Xfer
\r
360 MOV AL, 00000011b ; channel 3 Clear Mask for DRQ
\r
361 OUT DMA2RcmdWbm, AL
\r
367 RETF 20 ; 20 bytes of crap to dump
\r
369 ;------------------------------------------------------------
\r
370 ; GetDMACount returns the number of bytes or words left in the
\r
371 ; DMA count register for the channel specified. For channels
\r
372 ; 5-7 this will be the number of WORDS. For 0-3 this will be BYTES!
\r
373 ; Programmers should note (I should tell them) this value will read
\r
374 ; one less byte/word than is really in the channel. This is because
\r
375 ; 0 = 1 for set purposes. to move 64K, you actually set the
\r
378 ; GetDMACount(dChannel, pwCountRet)
\r
381 ; dChannel (0,1,2,3,5,6,7)
\r
382 ; pwCountRet is a pointer to a Word (2 byte unsigned value) where
\r
383 ; the count will be returned. The count is number of WORDS-1
\r
384 ; for channels 5-7 and BYTES-1 for channels 0-3.
\r
386 PUBLIC __GetDMACount:
\r
389 MOV EAX, [EBP+16] ;Channel
\r
390 MOV ESI, [EBP+12] ;Return address for count
\r
425 MOV EAX, ErcDMAChannel ;No such channel!
\r
428 RETF 8 ; 20 bytes of junk to dump
\r
435 MOV CH,AL ;CX has words/bytes left in DMA
\r
437 MOV WORD PTR [ESI], CX ;
\r
438 XOR EAX, EAX ; No Error
\r
441 RETF 8 ; 8 bytes to dump from the stack
\r
443 ;=========== module end ==============
\r