|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * DOS DMA interface. ! 5: * ! 6: * (c) 1996 Peter Remmers ! 7: */ ! 8: ! 9: #include <stdlib.h> ! 10: #include <pc.h> ! 11: #include <dpmi.h> ! 12: ! 13: #include "dos-dma.h" ! 14: ! 15: /* some useful macros */ ! 16: #define LOBYTE(x) ((unsigned char)(((unsigned short)(x)) & 0xFF)) ! 17: #define HIBYTE(x) ((unsigned char)(((unsigned short)(x)) >> 8)) ! 18: #define LOWORD(x) ((unsigned short)(((unsigned long)(x)) & 0xFFFF)) ! 19: #define HIWORD(x) ((unsigned short)(((unsigned long)(x)) >> 16)) ! 20: ! 21: const unsigned short DMA_Address [8] = {0x00,0x02,0x04,0x06,0xC0,0xC4,0xC8,0xCC}; ! 22: const unsigned short DMA_Count [8] = {0x01,0x03,0x05,0x07,0xC2,0xC6,0xCA,0xCE}; ! 23: ! 24: const unsigned short DMA_PageLo[8]= { 0x87, 0x83, 0x81, 0x82, 0x8F, 0x8B, 0x89, 0x8A}; ! 25: const unsigned short DMA_PageHi[8]= {0x487,0x483,0x481,0x482,0x48F,0x48B,0x489,0x48A}; ! 26: ! 27: #define DMA_Status(ch) ((ch)<4 ? 0x08 : 0xD0) /* Read */ ! 28: #define DMA_Command(ch) ((ch)<4 ? 0x08 : 0xD0) /* Write */ ! 29: #define DMA_Request(ch) ((ch)<4 ? 0x09 : 0xD2) ! 30: #define DMA_MaskSingle(ch) ((ch)<4 ? 0x0A : 0xD4) ! 31: #define DMA_Mode(ch) ((ch)<4 ? 0x0B : 0xD6) ! 32: #define DMA_ClearFF(ch) ((ch)<4 ? 0x0C : 0xD8) ! 33: #define DMA_Latch(ch) ((ch)<4 ? 0x0D : 0xDA) /* Read */ ! 34: #define DMA_MasterClear(ch) ((ch)<4 ? 0x0D : 0xDA) /* Write */ ! 35: #define DMA_ClearMask(ch) ((ch)<4 ? 0x0E : 0xDC) ! 36: #define DMA_MaskAll(ch) ((ch)<4 ? 0x0F : 0xDE) ! 37: ! 38: ! 39: /* allocate DOS memory that does not cross a physical 64k boundary */ ! 40: unsigned long DMA_AllocDMABuf (_go32_dpmi_seginfo *info) ! 41: { ! 42: unsigned long Phys; ! 43: unsigned long bytes; ! 44: ! 45: /* first allocate requested size */ ! 46: if (_go32_dpmi_allocate_dos_memory (info)) return (NULL); ! 47: ! 48: Phys = (info->rm_segment) << 4; ! 49: bytes = (info->size) << 4; ! 50: ! 51: /* if memory does not cross boundary we are lucky and that's it */ ! 52: if (HIWORD(Phys + bytes) == HIWORD (Phys)) return (Phys); ! 53: ! 54: /* if not, free memory */ ! 55: _go32_dpmi_free_dos_memory (info); ! 56: ! 57: /* and allocate twice the requested size */ ! 58: bytes <<= 1; ! 59: info->size <<= 1; ! 60: if (_go32_dpmi_allocate_dos_memory (info)) return (NULL); ! 61: ! 62: /* and take the half that does not cross a boundary */ ! 63: Phys = (info->rm_segment) << 4; ! 64: if (HIWORD(Phys + bytes) == HIWORD (Phys)) return (Phys); ! 65: ! 66: return (Phys + (bytes>>1)); ! 67: } ! 68: ! 69: void DMA_Mask (unsigned char channel) ! 70: { ! 71: outportb(DMA_MaskSingle(channel), 4 + (channel&3)); ! 72: } ! 73: ! 74: void DMA_UnMask (unsigned char channel) ! 75: { ! 76: outportb(DMA_MaskSingle(channel), channel&3); ! 77: } ! 78: ! 79: void DMA_InitTransfer (unsigned char channel, unsigned char Mode, ! 80: unsigned long PhysAddr, unsigned short Count) ! 81: { ! 82: unsigned short Page; ! 83: unsigned short Addr; ! 84: ! 85: if (channel & 4) Count >>= 1; ! 86: Count--; ! 87: ! 88: Page = HIWORD(PhysAddr); ! 89: if (channel & 4) PhysAddr >>= 1; ! 90: Addr = LOWORD (PhysAddr); ! 91: ! 92: outportb (DMA_MaskSingle(channel), (channel&3) + 0x04); ! 93: outportb (DMA_Mode (channel), (channel&3) | (Mode&0xFC)); ! 94: outportb (DMA_ClearFF (channel), 0); ! 95: outportb (DMA_Count [channel], LOBYTE(Count)); ! 96: outportb (DMA_Count [channel], HIBYTE(Count)); ! 97: outportb (DMA_Address [channel], LOBYTE(Addr)); ! 98: outportb (DMA_Address [channel], HIBYTE(Addr)); ! 99: outportb (DMA_PageLo [channel], LOBYTE(Page)); ! 100: outportb (DMA_PageHi [channel], HIBYTE(Page)); ! 101: outportb (DMA_MaskSingle(channel), channel&3); ! 102: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.