From eda4d7b0c81e9d2381b6c7e9b26e9c343b1a5b7d Mon Sep 17 00:00:00 2001 From: Richard Burgess <> Date: Sun, 20 Nov 1994 11:01:08 +0000 Subject: [PATCH] autocommit for file dated 1994-11-20 11:01:08 --- ossource/dmacode.asm | 443 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 443 insertions(+) create mode 100644 ossource/dmacode.asm diff --git a/ossource/dmacode.asm b/ossource/dmacode.asm new file mode 100644 index 0000000..b62e3d3 --- /dev/null +++ b/ossource/dmacode.asm @@ -0,0 +1,443 @@ +; MMURTL Operating System Source Code +; Copyright 1991,1992,1993,1994 Richard A. Burgess +; ALL RIGHTS RESERVED Version 1.0 +.DATA + +.INCLUDE MOSEDF.INC + +.CODE +;========== DMA Equates for DMA amd PAGE registers ========= +;NOTES: With 8 bit DMA, the lower WORD (bits 15-0) are placed into +; the address registers of the DMA, and the Page register is the next +; most significant byte (bits 23-16). With WORD DMA moves (channels 5-7), +; address bits 16-1 are placed in the address registers, while 23-17 are +; put in the page register. Bit 16 is ignored by the page register. +; +; +; DMA 1 Port addresses and page registers + +DMA10Add EQU 00h ;Ch 0 Address +DMA10Cnt EQU 01h ;Ch 0 Word Count +DMA11Add EQU 02h ;Ch 1 Address +DMA11Cnt EQU 03h ;Ch 1 Word Count +DMA12Add EQU 04h ;Ch 2 Address +DMA12Cnt EQU 05h ;Ch 2 Word Count +DMA13Add EQU 06h ;Ch 3 Address +DMA13Cnt EQU 07h ;Ch 3 Word Count +DMA1StatCmd EQU 08h ;Read Status/Write Command +DMA1RqReg EQU 09h ;Read/Write DMA Rq Register +DMA1RCmdWbm EQU 0Ah ;Read Command/Write Single bit mask +DMA1Mode EQU 0Bh ;Read/Write Mode register +DMA1FF EQU 0Ch ;Writing this address clears byte ptr flip flop +DMA1Clear EQU 0Dh ;Write causes MASTER Clear (Read from Temp Reg) +DMA1ClrMode EQU 0Eh ;Rd clears mode reg count/Wr Clr ALL mask bits +DMA1MskBts EQU 0Fh ;Read/Write DMA Rq Mask Register + +; DMA 2 Port addresses + +DMA20Add EQU 0C0h ;Ch 0 Address +DMA20Cnt EQU 0C2h ;Ch 0 Word Count +DMA21Add EQU 0C4h ;Ch 1 Address +DMA21Cnt EQU 0C6h ;Ch 1 Word Count +DMA22Add EQU 0C8h ;Ch 2 Address +DMA22Cnt EQU 0CAh ;Ch 2 Word Count +DMA23Add EQU 0CCh ;Ch 3 Address +DMA23Cnt EQU 0CEh ;Ch 3 Word Count +DMA2StatCmd EQU 0D0h ;Read Status/Write Command +DMA2RqReg EQU 0D2h ;Read/Write DMA Rq Register +DMA2RCmdWbm EQU 0D4h ;Read Command/Write Single bit mask +DMA2Mode EQU 0D6h ;Read/Write Mode register +DMA2FF EQU 0D8h ;Writing this address clears byte ptr flip flop +DMA2Clear EQU 0DAh ;Write causes MASTER Clear (Read from Temp Reg) +DMA2ClrMode EQU 0DCh ;Rd clears mode reg count/Wr Clr ALL mask bits +DMA2MskBts EQU 0DEh ;Read/Write DMA Rq Mask Register + +;DMA Page register by DRQ/DACK number + +DMAPage0 EQU 87h ;DMA DACK0 Page register +DMAPage1 EQU 83h ; DACK1 (etc. etc. etc.) +DMAPage2 EQU 81h +DMAPage3 EQU 82h +DMAPage5 EQU 8Bh +DMAPage6 EQU 89h +DMAPage7 EQU 8Ah +; +; The following code sets up the initial DMA channel values for +; both chips to most probable use. Includes cascade mode for CH4 +; which is DMA channel 0 on chip 2 +; +PUBLIC InitDMA: + MOV AL, 04 ;Master disable + OUT DMA1StatCmd, AL + OUT DMA2StatCmd, AL + + XOR AL, AL ;MASTER CLEAR (same as hardware reset) + OUT DMA1Clear, AL + OUT DMA2Clear, AL + + XOR AL, AL ;All commands set to default (0) + OUT DMA1StatCmd, AL + OUT DMA2StatCmd, AL + + MOV AL, 40h ;CH 0 DMA 1 + OUT DMA1Mode, AL ; + MOV AL, 0C0h ;CH 0 DMA 2 (Cascade Mode) + OUT DMA2Mode, AL ; + + MOV AL, 41h ;CH 1 DMA 1 & 2 + OUT DMA1Mode, AL ; + OUT DMA2Mode, AL ; + + MOV AL, 42h ;CH 2 DMA 1 & 2 + OUT DMA1Mode, AL ; + OUT DMA2Mode, AL ; + + MOV AL, 43h ;CH 3 DMA 1 & 2 + OUT DMA1Mode, AL ; + OUT DMA2Mode, AL ; + + XOR AL,AL + OUT DMA1ClrMode, AL ;Enable ALL DMA 1 Channels + OUT DMA2ClrMode, AL ;Enable ALL DMA 2 Channels + RETN + +; +;----------------------------------------------------------- +; The following code sets up a single DMA channel for the caller. +; DMA is crippled because it can't move across 64K physical +; boundries. It's the caller's responsibility to know if he is +; crossing a boundry! If he does, this will wrap around over the segment!!! +; This code is completely reentrant. +; There is only one call for DMA set up. + +; The caller sets the type of DMA operation (In, Out, Verify). +; For channels 5,6 & 7, the address & count must be divided by +; two for the DMA hardware. This routine does this for you! +; Algorythm - Put mode byte bits (except channel bits) in BL, then jump to +; correct routine for that channel. The call will allow set up of +; all the differnet types of DMA modes for read and write with this +; single call. The call: +; +; DmaSetUp(dPhyMem, sdMem, dChannel, dType, dMode) +; EBP+ 28 24 20 16 12 +; +; dPhyMem is physical memory address +; sdMem is nBytes to move (STILL bytes for word xfers, we do math) +; dChannel (0,1,2,3,5,6,7) +; dType - 0 = Verify, 1 = In (Write Mem), 2 = Out (Read memory) +; dMode - 0 Demand Mode, 1 Single Cycle, (Disk I/O uses 1) +; 2 Block, 3 Cascade +; +; +PUBLIC __DMASetUp: + PUSH EBP ; + MOV EBP,ESP ; + MOV EAX, [EBP+12] ; dMode + CMP EAX, 04 ; Mode must be < 4 + JB DMAModeOK + MOV EAX, ErcDMAMode + JMP DMAEnd +DMAModeOK: + SHL EAX, 6 ; Move Mode bits to 6 and 7 + MOV BL, AL ; Put it in BL + MOV EAX, [EBP+16] ; get dType + AND BL, 0C0h ; Set to Verify by default (low bits 0) + CMP EAX, 0 ; Check fType (Verify?) + JE DMASelect ; Yes + CMP EAX, 1 ; In? (Write) + JE DMAWrite ; Yes (if no then fall thru to Read) +DMARead: + OR BL, 00001000b ; OR read command to BL (OUT) + JMP DMASelect +DMAWrite: + OR BL, 00000100b ; OR write command to BL (IN) + +DMASelect: + MOV EAX, [EBP+20] ;Jump table for channel selection + CMP EAX, 0 ; + JE DMA0 + CMP EAX, 1 + JE DMA1 + CMP EAX, 2 + JE DMA2 + CMP EAX, 3 + JE DMA3 + CMP EAX, 5 + JE DMA5 + CMP EAX, 6 + JE DMA6 + CMP EAX, 7 + JE DMA7 + MOV EAX, ErcDMAChannel + JMP DMAEnd + +DMA0: + CLI + MOV AL, 00000100b ; channel 0 Set Mask for DRQ + OUT DMA1RCmdWbm, AL ; + MOV AL, 00000000b ; CH0 (CH is last 2 bits) + OR AL, BL ; OR with MODE + OUT DMA1Mode, AL + OUT DMA1FF, AL ; Clear FlipFLop (Val in AL irrelevent) + MOV EAX, [EBP+28] ; dPhyMem + OUT DMA10Add, AL ; Lo byte address + SHR EAX, 8 + OUT DMA10Add, AL ; Hi Byte + SHR EAX, 8 + OUT DMAPage0, AL ; Highest byte (to page register) + MOV EAX, [EBP+24] + DEC EAX + OUT DMA10Cnt, AL + SHR EAX, 8 + OUT DMA10Cnt, AL + MOV AL, 00000000b ; channel 0 Clear Mask for DRQ + OUT DMA1RcmdWbm, AL + STI + XOR EAX, EAX + JMP DMAEnd + +DMA1: + CLI + MOV AL, 00000101b ; channel 1 Set Mask for DRQ + OUT DMA1RCmdWbm, AL + MOV AL, 00000001b ; CH1 + OR AL, BL ; OR with MODE/TYPE + OUT DMA1Mode, AL + OUT DMA1FF, AL ; Clear FlipFLop (Val in AL irrelevent) + MOV EAX, [EBP+28] ; dPhyMem + OUT DMA11Add, AL ; Lo byte address + SHR EAX, 8 + OUT DMA11Add, AL ; Hi Byte + SHR EAX, 8 + OUT DMAPage1, AL ; Highest byte (to page register) + MOV EAX, [EBP+24] ; sdMem + DEC EAX + OUT DMA11Cnt, AL + SHR EAX, 8 + OUT DMA11Cnt, AL + MOV AL, 00000001b ; channel 1 Clear Mask for DRQ + OUT DMA1RcmdWbm, AL + STI + XOR EAX, EAX + JMP DMAEnd + +DMA2: + CLI + MOV AL, 00000110b ; channel 2 Set Mask for DRQ + OUT DMA1RCmdWbm, AL + MOV AL, 00000010b ; CH2 + OR AL, BL ; OR with MODE + OUT DMA1Mode, AL + OUT DMA1FF, AL ; Clear FlipFLop (Val in AL irrelevent) + MOV EAX, [EBP+28] ; dPhyMem + OUT DMA12Add, AL ; Lo byte address + SHR EAX, 8 + OUT DMA12Add, AL ; Hi Byte + SHR EAX, 8 + OUT DMAPage2, AL ; Highest byte (to page register) + MOV EAX, [EBP+24] ; sdMem + DEC EAX + OUT DMA12Cnt, AL + SHR EAX, 8 + OUT DMA12Cnt, AL + MOV AL, 00000010b ; channel 2 Clear Mask for DRQ + OUT DMA1RcmdWbm, AL + STI + XOR EAX, EAX + JMP DMAEnd + +DMA3: + CLI + MOV AL, 00000111b ; channel 3 Set Mask for DRQ + OUT DMA1RCmdWbm, AL + MOV AL, 00000011b ; CH3 + OR AL, BL ; OR with MODE + OUT DMA1Mode, AL + OUT DMA1FF, AL ; Clear FlipFLop (Val in AL irrelevent) + MOV EAX, [EBP+28] ; dPhyMem + OUT DMA13Add, AL ; Lo byte address + SHR EAX, 8 + OUT DMA13Add, AL ; Hi Byte + SHR EAX, 8 + OUT DMAPage3, AL ; Highest byte (to page register) + MOV EAX, [EBP+24] ; sdMem + DEC EAX + OUT DMA13Cnt, AL + SHR EAX, 8 + OUT DMA13Cnt, AL + MOV AL, 00000011b ; channel 3 Clear Mask for DRQ + OUT DMA1RcmdWbm, AL + STI + XOR EAX, EAX + JMP DMAEnd + +;NOTE: DMA channels 5-7 are on DMA2 and numbered 1-3 for chip select purposes + +DMA5: + CLI + MOV AL, 00000101b ; channel 1 DMA2 Set Mask for DRQ + OUT DMA2RCmdWbm, AL + MOV AL, 00000001b ; CH1 on DMA 2 + OR AL, BL ; OR with MODE + OUT DMA2Mode, AL + OUT DMA2FF, AL ; Clear FlipFLop (Val in AL irrelevent) + MOV EAX, [EBP+28] ; dPhyMem + MOV EBX, EAX ; Save EBX for page + AND EAX, 0FFFFh ; Rid of all but lower 16 + SHR EAX, 1 ; DIV by 2 for WORD Xfer (bits 16-1) + OUT DMA21Add, AL ; Lo byte address + SHR EAX, 8 + OUT DMA21Add, AL ; Hi Byte + MOV EAX, EBX + SHR EAX, 15 ; We only need 23-17 for the page + OUT DMAPage5, AL ; Highest byte (to page register) + MOV EAX, [EBP+24] ; sdMem + SHR EAX, 1 ; DIV by 2 for WORD Xfer + DEC EAX ; One less word + OUT DMA21Cnt, AL + SHR EAX, 8 + OUT DMA21Cnt, AL + MOV AL, 00000001b ; channel 1 Clear Mask for DRQ + OUT DMA2RcmdWbm, AL + STI + XOR EAX, EAX + JMP DMAEnd +; +DMA6: + CLI + MOV AL, 00000110b ; channel 2 Set Mask for DRQ + OUT DMA2RCmdWbm, AL + MOV AL, 00000010b ; CH2 on DMA 2 + OR AL, BL ; OR with MODE + OUT DMA2Mode, AL + OUT DMA2FF, AL ; Clear FlipFLop (Val in AL irrelevent) + MOV EAX, [EBP+28] ; dPhyMem + MOV EBX, EAX + AND EAX, 0FFFFh ; Rid of all but lower 16 + SHR EAX, 1 ; DIV by 2 for WORD Xfer + OUT DMA22Add, AL ; Lo byte address + SHR EAX, 8 + OUT DMA22Add, AL ; Hi Byte + MOV EAX, EBX + SHR EAX, 15 + OUT DMAPage6, AL ; Highest byte (to page register) + MOV EAX, [EBP+24] ; sdMem + SHR EAX, 1 ; DIV by 2 for WORD Xfer + DEC EAX + OUT DMA22Cnt, AL + SHR EAX, 8 + OUT DMA22Cnt, AL + MOV AL, 00000010b ; channel 2 Clear Mask for DRQ + OUT DMA2RcmdWbm, AL + STI + XOR EAX, EAX + JMP DMAEnd +; +DMA7: + CLI + MOV AL, 00000111b ; channel 3 Set Mask for DRQ + OUT DMA2RCmdWbm, AL + MOV AL, 00000011b ; CH3 on DMA 2 + OR AL, BL ; OR with MODE + OUT DMA2Mode, AL + OUT DMA2FF, AL ; Clear FlipFLop (Val in AL irrelevent) + MOV EAX, [EBP+28] ; dPhyMem + MOV EBX, EAX + AND EAX, 0FFFFh ; Rid of all but lower 16 + SHR EAX, 1 ; DIV by 2 for WORD Xfer + OUT DMA23Add, AL ; Lo byte address + SHR EAX, 8 + OUT DMA23Add, AL ; Hi Byte + MOV EAX, EBX + SHR EAX, 15 + OUT DMAPage6, AL ; Highest byte (to page register) + MOV EAX, [EBP+24] ; sdMem + SHR EAX, 1 ; DIV by 2 for WORD Xfer + DEC EAX + OUT DMA23Cnt, AL + SHR EAX, 8 + OUT DMA23Cnt, AL + MOV AL, 00000011b ; channel 3 Clear Mask for DRQ + OUT DMA2RcmdWbm, AL + STI + XOR EAX, EAX +DMAEnd: + MOV ESP,EBP ; + POP EBP ; + RETF 20 ; 20 bytes of crap to dump + +;------------------------------------------------------------ +; GetDMACount returns the number of bytes or words left in the +; DMA count register for the channel specified. For channels +; 5-7 this will be the number of WORDS. For 0-3 this will be BYTES! +; Programmers should note (I should tell them) this value will read +; one less byte/word than is really in the channel. This is because +; 0 = 1 for set purposes. to move 64K, you actually set the +; channel 65,535. +; +; GetDMACount(dChannel, pwCountRet) +; EBP+ 16 12 +; +; dChannel (0,1,2,3,5,6,7) +; pwCountRet is a pointer to a Word (2 byte unsigned value) where +; the count will be returned. The count is number of WORDS-1 +; for channels 5-7 and BYTES-1 for channels 0-3. + +PUBLIC __GetDMACount: + PUSH EBP ; + MOV EBP,ESP ; + MOV EAX, [EBP+16] ;Channel + MOV ESI, [EBP+12] ;Return address for count +DMACSelect: + CMP EAX, 0 ; + JNE SHORT DMAC1 + MOV DX, DMA10Cnt ; + JMP SHORT DMACDoIt +DMAC1: + CMP EAX, 1 + JNE SHORT DMAC2 + MOV DX, DMA11Cnt ; + JMP SHORT DMACDoIt +DMAC2: + CMP EAX, 2 + JNE SHORT DMAC3 + MOV DX, DMA12Cnt ; + JMP SHORT DMACDoIt +DMAC3: + CMP EAX, 3 + JNE SHORT DMAC5 + MOV DX, DMA13Cnt ; + JMP SHORT DMACDoIt +DMAC5: + CMP EAX, 5 + JNE SHORT DMAC6 + MOV DX, DMA21Cnt ; + JMP SHORT DMACDoIt +DMAC6: + CMP EAX, 6 + JNE SHORT DMAC7 + MOV DX, DMA22Cnt ; + JMP SHORT DMACDoIt +DMAC7: + MOV DX, DMA23Cnt ; + CMP EAX, 7 + JE SHORT DMACDoIt + MOV EAX, ErcDMAChannel ;No such channel! + MOV ESP,EBP ; + POP EBP ; + RETF 8 ; 20 bytes of junk to dump + +DMACDoIt: + CLI + IN AL,DX ; + MOV CL,AL ; + IN AL,DX ; + MOV CH,AL ;CX has words/bytes left in DMA + STI ; + MOV WORD PTR [ESI], CX ; + XOR EAX, EAX ; No Error + MOV ESP,EBP ; + POP EBP ; + RETF 8 ; 8 bytes to dump from the stack + +;=========== module end ============== -- 2.40.0