|
|
1.1 root 1: /*
1.1.1.3 root 2: Hatari - stMemory.c
1.1 root 3:
1.1.1.3 root 4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
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.5 root 40: 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:
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
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.