|
|
1.1 root 1: /* 1.1.1.3 root 2: Hatari - stMemory.c 1.1 root 3: 1.1.1.15! root 4: This file is distributed under the GNU General Public License, version 2 ! 5: or at your option any later version. Read the file gpl.txt for details. 1.1.1.3 root 6: 1.1.1.4 root 7: ST Memory access functions. 1.1 root 8: */ 1.1.1.10 root 9: const char STMemory_fileid[] = "Hatari stMemory.c : " __DATE__ " " __TIME__; 1.1 root 10: 1.1.1.4 root 11: #include "stMemory.h" 1.1.1.6 root 12: #include "configuration.h" 13: #include "floppy.h" 1.1.1.10 root 14: #include "gemdos.h" 1.1.1.12 root 15: #include "ioMem.h" 1.1.1.10 root 16: #include "log.h" 1.1.1.7 root 17: #include "memory.h" 1.1.1.12 root 18: #include "memorySnapShot.h" 19: #include "tos.h" 20: #include "vdi.h" 1.1.1.7 root 21: 1.1.1.2 root 22: 1.1.1.7 root 23: /* STRam points to our ST Ram. Unless the user enabled SMALL_MEM where we have 24: * to save memory, this includes all TOS ROM and IO hardware areas for ease 25: * and emulation speed - so we create a 16 MiB array directly here. 26: * But when the user turned on ENABLE_SMALL_MEM, this only points to a malloc'ed 27: * buffer with the ST RAM; the ROM and IO memory will be handled separately. */ 28: #if ENABLE_SMALL_MEM 29: Uint8 *STRam; 30: #else 31: Uint8 STRam[16*1024*1024]; 32: #endif 1.1.1.4 root 33: 1.1.1.7 root 34: Uint32 STRamEnd; /* End of ST Ram, above this address is no-mans-land and ROM/IO memory */ 1.1 root 35: 1.1.1.2 root 36: 1.1.1.7 root 37: /** 38: * Clear section of ST's memory space. 39: */ 1.1.1.15! root 40: static void STMemory_Clear(Uint32 StartAddress, Uint32 EndAddress) 1.1 root 41: { 1.1.1.5 root 42: memset(&STRam[StartAddress], 0, EndAddress-StartAddress); 1.1 root 43: } 44: 1.1.1.13 root 45: /** 46: * Copy given memory area safely to Atari RAM. 47: * If the memory area isn't fully within RAM, only the valid parts are written. 48: * Useful for all kinds of IO operations. 49: * 50: * addr - destination Atari RAM address 51: * src - source Hatari memory address 52: * len - number of bytes to copy 53: * name - name / description if this memory copy for error messages 54: * 55: * Return true if whole copy was safe / valid. 56: */ 57: bool STMemory_SafeCopy(Uint32 addr, Uint8 *src, unsigned int len, const char *name) 58: { 59: Uint32 end; 60: 61: if (STMemory_ValidArea(addr, len)) 62: { 63: memcpy(&STRam[addr], src, len); 64: return true; 65: } 66: Log_Printf(LOG_WARN, "Invalid '%s' RAM range 0x%x+%i!\n", name, addr, len); 67: 68: for (end = addr + len; addr < end; addr++, src++) 69: { 70: if (STMemory_ValidArea(addr, 1)) 71: STRam[addr] = *src; 72: } 73: return false; 74: } 1.1.1.6 root 75: 1.1.1.12 root 76: /** 77: * Save/Restore snapshot of RAM / ROM variables 78: * ('MemorySnapShot_Store' handles type) 79: */ 80: void STMemory_MemorySnapShot_Capture(bool bSave) 81: { 82: MemorySnapShot_Store(&STRamEnd, sizeof(STRamEnd)); 83: 84: /* Only save/restore area of memory machine is set to, eg 1Mb */ 85: MemorySnapShot_Store(STRam, STRamEnd); 86: 87: /* And Cart/TOS/Hardware area */ 88: MemorySnapShot_Store(&RomMem[0xE00000], 0x200000); 89: } 90: 91: 1.1.1.7 root 92: /** 93: * Set default memory configuration, connected floppies, memory size and 94: * clear the ST-RAM area. 95: * As TOS checks hardware for memory size + connected devices on boot-up 96: * we set these values ourselves and fill in the magic numbers so TOS 97: * skips these tests. 98: */ 1.1.1.6 root 99: void STMemory_SetDefaultConfig(void) 100: { 101: int i; 1.1.1.7 root 102: int screensize; 103: int memtop; 1.1.1.6 root 104: Uint8 nMemControllerByte; 1.1.1.13 root 105: Uint8 nFalcSysCntrl; 106: 1.1.1.6 root 107: static const int MemControllerTable[] = 108: { 109: 0x01, /* 512 KiB */ 110: 0x05, /* 1 MiB */ 111: 0x02, /* 2 MiB */ 112: 0x06, /* 2.5 MiB */ 113: 0x0A /* 4 MiB */ 114: }; 115: 1.1.1.7 root 116: if (bRamTosImage) 117: { 118: /* Clear ST-RAM, excluding the RAM TOS image */ 119: STMemory_Clear(0x00000000, TosAddress); 120: STMemory_Clear(TosAddress+TosSize, STRamEnd); 121: } 1.1.1.6 root 122: else 1.1.1.7 root 123: { 124: /* Clear whole ST-RAM */ 125: STMemory_Clear(0x00000000, STRamEnd); 126: } 1.1.1.6 root 127: 128: /* Mirror ROM boot vectors */ 129: STMemory_WriteLong(0x00, STMemory_ReadLong(TosAddress)); 130: STMemory_WriteLong(0x04, STMemory_ReadLong(TosAddress+4)); 131: 1.1.1.14 root 132: /* Fill in magic numbers to bypass TOS' memory tests for faster boot or 133: * if VDI resolution is enabled or if more than 4 MB of ram are used. 134: * (for highest compatibility, those tests should not be bypassed in 135: * the common STF/STE cases as some programs like "Yolanda" rely on 136: * the RAM content after those tests) */ 137: if (ConfigureParams.System.bFastBoot || bUseVDIRes 138: || (ConfigureParams.Memory.nMemorySize > 4 && !bIsEmuTOS)) 139: { 140: /* Write magic values to sysvars to signal valid config */ 141: STMemory_WriteLong(0x420, 0x752019f3); /* memvalid */ 142: STMemory_WriteLong(0x43a, 0x237698aa); /* memval2 */ 143: STMemory_WriteLong(0x51a, 0x5555aaaa); /* memval3 */ 144: } 1.1.1.6 root 145: 1.1.1.7 root 146: /* Set memory size, adjust for extra VDI screens if needed. 147: * Note: TOS seems to set phys_top-0x8000 as the screen base 148: * address - so we have to move phys_top down in VDI resolution 149: * mode, although there is more "physical" ST RAM available. */ 150: screensize = VDIWidth * VDIHeight / 8 * VDIPlanes; 1.1.1.14 root 151: /* Use 32 kiB in normal screen mode or when the screen size is smaller than 32 kiB */ 1.1.1.7 root 152: if (!bUseVDIRes || screensize < 0x8000) 153: screensize = 0x8000; 154: /* mem top - upper end of user memory (right before the screen memory). 155: * Note: memtop / phystop must be dividable by 512, or TOS crashes */ 156: memtop = (STRamEnd - screensize) & 0xfffffe00; 157: STMemory_WriteLong(0x436, memtop); 158: /* phys top - This must be memtop + 0x8000 to make TOS happy */ 159: STMemory_WriteLong(0x42e, memtop+0x8000); 1.1.1.6 root 160: 161: /* Set memory controller byte according to different memory sizes */ 162: /* Setting per bank: %00=128k %01=512k %10=2Mb %11=reserved. - e.g. %1010 means 4Mb */ 163: if (ConfigureParams.Memory.nMemorySize <= 4) 164: nMemControllerByte = MemControllerTable[ConfigureParams.Memory.nMemorySize]; 165: else 166: nMemControllerByte = 0x0f; 167: STMemory_WriteByte(0x424, nMemControllerByte); 168: IoMem_WriteByte(0xff8001, nMemControllerByte); 169: 1.1.1.7 root 170: if (ConfigureParams.System.nMachineType == MACHINE_FALCON) 171: { 1.1.1.13 root 172: /* Set the Falcon memory and monitor configuration register: 173: 1.1.1.15! root 174: $ffff8006.b [R] 76543210 Monitor-memory ! 175: |||||||| ! 176: |||||||+- RAM Wait Status ! 177: ||||||| 0 = 1 Wait (default) ! 178: ||||||| 1 = 0 Wait ! 179: ||||||+-- Video Bus size ??? ! 180: |||||| 0 = 16 Bit ! 181: |||||| 1 = 32 Bit (default) ! 182: ||||++--- ROM Wait Status ! 183: |||| 00 = Reserved ! 184: |||| 01 = 2 Wait (default) ! 185: |||| 10 = 1 Wait ! 186: |||| 11 = 0 Wait ! 187: ||++----- Falcon Memory ! 188: || 00 = 1 MB ! 189: || 01 = 4 MB ! 190: || 10 = 14 MB ! 191: || 11 = no boot ! ! 192: ++------- Monitor-Typ ! 193: 00 - Monochrome (SM124) ! 194: 01 - Color (SC1224) ! 195: 10 - VGA Color ! 196: 11 - Television 1.1.1.13 root 197: 198: Bit 1 seems not to be well documented. It's used by TOS at bootup to compute the memory size. 199: After some tests, I get the following RAM values (Bits 5, 4, 1 are involved) : 200: 201: 00 = 512 Ko 20 = 8192 Ko 202: 02 = 1024 Ko 22 = 14366 Ko 203: 10 = 2048 Ko 30 = Illegal 204: 12 = 4096 Ko 32 = Illegal 205: 206: I use these values for Hatari's emulation. 207: I also set the bit 3 and 2 at value 01 are mentioned in the register description. 208: */ 209: 210: if (ConfigureParams.Memory.nMemorySize == 14) /* 14 Meg */ 211: nFalcSysCntrl = 0x26; 212: else if (ConfigureParams.Memory.nMemorySize == 8) /* 8 Meg */ 213: nFalcSysCntrl = 0x24; 214: else if (ConfigureParams.Memory.nMemorySize == 4) /* 4 Meg */ 1.1.1.7 root 215: nFalcSysCntrl = 0x16; 1.1.1.13 root 216: else if (ConfigureParams.Memory.nMemorySize == 2) /* 2 Meg */ 1.1.1.7 root 217: nFalcSysCntrl = 0x14; 1.1.1.13 root 218: else if (ConfigureParams.Memory.nMemorySize == 1) /* 1 Meg */ 1.1.1.7 root 219: nFalcSysCntrl = 0x06; 220: else 1.1.1.13 root 221: nFalcSysCntrl = 0x04; /* 512 Ko */ 222: 1.1.1.8 root 223: switch(ConfigureParams.Screen.nMonitorType) { 1.1.1.13 root 224: case MONITOR_TYPE_TV: 225: nFalcSysCntrl |= FALCON_MONITOR_TV; 226: break; 227: case MONITOR_TYPE_VGA: 228: nFalcSysCntrl |= FALCON_MONITOR_VGA; 229: break; 230: case MONITOR_TYPE_RGB: 231: nFalcSysCntrl |= FALCON_MONITOR_RGB; 232: break; 233: case MONITOR_TYPE_MONO: 234: nFalcSysCntrl |= FALCON_MONITOR_MONO; 235: break; 1.1.1.7 root 236: } 237: STMemory_WriteByte(0xff8006, nFalcSysCntrl); 238: } 239: 1.1.1.6 root 240: /* Set TOS floppies */ 241: STMemory_WriteWord(0x446, nBootDrive); /* Boot up on A(0) or C(2) */ 242: 243: /* Create connected drives mask: */ 1.1.1.10 root 244: ConnectedDriveMask = STMemory_ReadLong(0x4c2); // Get initial drive mask (see what TOS thinks) 245: ConnectedDriveMask |= 0x03; // Always use A: and B: 246: if (GEMDOS_EMU_ON) 1.1.1.6 root 247: { 1.1.1.10 root 248: for (i = 0; i < MAX_HARDDRIVES; i++) 249: { 250: if (emudrives[i] != NULL) // Is this GEMDOS drive enabled? 1.1.1.12 root 251: ConnectedDriveMask |= (1 << emudrives[i]->drive_number); 1.1.1.10 root 252: } 1.1.1.6 root 253: } 254: /* Set connected drives system variable. 255: * NOTE: some TOS images overwrite this value, see 'OpCode_SysInit', too */ 256: STMemory_WriteLong(0x4c2, ConnectedDriveMask); 257: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.