/* * Get a pointer to the base of physical video memory. This can be used for DMA transfer. * In DOS, the physical and the logical address most likely are the same. * Return: A pointer to base of physical video memory. * NULL pointer if fail. */ void *getPhysicalMemoryBase( unsigned short vendorId, /* PCI vendor ID */ unsigned short deviceId, /* PCI device ID */ unsigned short deviceNum /* If more than one device in system, device number are ordered as 0, 1, 2,... */ ) { uint32_t physicalAddr; if (enableDevice(vendorId, deviceId, deviceNum) == -1) return (void *)0; #ifdef USE_A0000 /* * Access frame buffer through the 0xA0000 address. */ physicalAddr = 0xA0000; /* Set to Write Mode 0 */ pokeIO(GRAPHICS_REGISTER, 0x05, 0x00); /* Enable address 0xA0000 to 0xAFFFF */ #ifdef BANK_SIZE_128K pokeIO(GRAPHICS_REGISTER, 0x06, 0x00); setBankSize(128*1024); #else pokeIO(GRAPHICS_REGISTER, 0x06, 0x04); setBankSize(64*1024); #endif /* Enable writing to corresponding plane. Set it ot 0x0f or 0x04. BIOS set this IO port to 0x04 during font loading */ pokeIO(SEQUENCER_REGISTER, 0x04, 0x04); #else /* * Access frame buffer through the PCI linear address. */ /* Get frame buffer physical address */ physicalAddr = readPCIDword(vendorId, deviceId, deviceNum, 0x10); /* * In a memory bar (Frame buffer), bit 3 to bit 0 are used as the base * address information, therefore, we should mask this out and set them * to zero. */ physicalAddr &= ~0x0000000F; #endif DDKDEBUGPRINT((INIT_LEVEL, "Memory Physical Addr: %08x\n", physicalAddr)); if (physicalAddr == (-1)) return (void *)0; return ((void *)physicalAddr); }
/* * Get the logical address of an offset location in frame buffer. * Return: A valid address if success. * NULL address if fail. */ void *getAddress(uint32_t offset /*Offset from base of frame buffer*/) { if (frameBufBase[gwCurDev] == (unsigned char *)0) { frameBufBase[gwCurDev] = (unsigned char *)getMemoryBase(SMI_PCI_VENDOR_ID, gwDeviceId, gwCurDev); DDKDEBUGPRINT((INIT_LEVEL, "Device: %x, Memory Base Addr: %08x\n", gwCurDev, frameBufBase[gwCurDev])); if (frameBufBase[gwCurDev] == 0) { return((void *)0); } } #ifdef USE_A0000 { unsigned short bankValue; /* Calculate the Memory Address high (bank register) and the new offset */ bankValue = (unsigned short)(offset / gBankSize); offset = offset % gBankSize; /* Set the Page Selection Register and also */ pokeIO(CRT_REGISTER, 0x89, (unsigned char) bankValue); pokeIO(CRT_REGISTER, 0x8A, (unsigned char) (bankValue >> 8)); } #endif return(frameBufBase[gwCurDev] + offset); }
void DELAY(short wait) { for(; wait--;) pokeIO(0x600005,0b11111); /* low power mode, wake up CPU only on AI 1 (grayscale), 2 (Keypress), 3 (AMS clock), 4 (Link), 5 (AMS timer base, needed for APD) and 6 (ON, always wakes up the CPU) -- Saves Battery Power -- */ }
void ioWriteMMIOData(uint32_t data) { unsigned char index; pokeIO(CRT_REGISTER, 0x87, (unsigned char) (data >> 24)); pokeIO(CRT_REGISTER, 0x86, (unsigned char) (data >> 16)); pokeIO(CRT_REGISTER, 0x85, (unsigned char) (data >> 8)); pokeIO(CRT_REGISTER, 0x84, (unsigned char) data); }
void ioWriteMMIOAddress(uint32_t address) { unsigned char index; for (index = 0x80; index <= 0x82; index++) { pokeIO(CRT_REGISTER, index, (unsigned char) address); address >>= 8; } }
void Memory::pokeTo(uint16_t addr, uint8_t value, MemoryType dest) { switch (dest) { case MEM_RAM: pokeRam(addr, value); break; case MEM_ROM: pokeRom(addr, value); break; case MEM_IO: pokeIO(addr, value); break; default: assert(false); } }