|
|
1.1 root 1: /*
1.1.1.6 root 2: Hatari - tos.c
1.1 root 3:
1.1.1.6 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.
1.1 root 6:
1.1.1.6 root 7: Load TOS image file into ST memory, fix/setup for emulator.
8:
9: The Atari ST TOS needs to be patched to help with emulation. Eg, it references
10: the MMU chip to set memory size. This is patched to the sizes we need without
11: the complicated emulation of hardware which is not needed (as yet). We also
12: patch DMA devices and Hard Drives.
13: NOTE: TOS versions 1.06 and 1.62 were not designed for use on a real STfm.
14: These were for the STe machine ONLY. They access the DMA/Microwire addresses
15: on boot-up which (correctly) cause a bus-error on Hatari as they would in a
16: real STfm. If a user tries to select any of these images we bring up an error.
1.1 root 17: */
1.1.1.16! root 18: const char TOS_fileid[] = "Hatari tos.c : " __DATE__ " " __TIME__;
1.1 root 19:
1.1.1.8 root 20: #include <SDL_endian.h>
1.1.1.4 root 21:
1.1 root 22: #include "main.h"
1.1.1.9 root 23: #include "configuration.h"
1.1 root 24: #include "file.h"
1.1.1.4 root 25: #include "gemdos.h"
26: #include "hdc.h"
1.1.1.10 root 27: #include "ioMem.h"
28: #include "log.h"
1.1 root 29: #include "m68000.h"
30: #include "memorySnapShot.h"
31: #include "stMemory.h"
32: #include "tos.h"
33: #include "vdi.h"
34:
35:
1.1.1.14 root 36: bool bIsEmuTOS;
37: Uint16 TosVersion; /* eg. 0x0100, 0x0102 */
1.1.1.10 root 38: Uint32 TosAddress, TosSize; /* Address in ST memory and size of TOS image */
1.1.1.16! root 39: bool bTosImageLoaded = false; /* Successfully loaded a TOS image? */
! 40: bool bRamTosImage; /* true if we loaded a RAM TOS image */
1.1.1.10 root 41: unsigned int ConnectedDriveMask = 0x03; /* Bit mask of connected drives, eg 0x7 is A,B,C */
1.1.1.16! root 42: int nNumDrives = 2; /* Number of drives, default is 2 for A: and B: - Strictly, this is the highest mapped drive letter, in-between drives may not be allocated */
1.1.1.10 root 43:
44:
1.1 root 45: /* Possible TOS file extensions to scan for */
1.1.1.12 root 46: static const char * const pszTosNameExts[] =
1.1.1.6 root 47: {
1.1.1.12 root 48: ".img",
49: ".rom",
50: ".tos",
51: NULL
1.1 root 52: };
53:
54:
1.1.1.6 root 55: /* Flags that define if a TOS patch should be applied */
56: enum
1.1 root 57: {
1.1.1.12 root 58: TP_ALWAYS, /* Patch should alway be applied */
1.1.1.13 root 59: TP_HDIMAGE_OFF, /* Apply patch only if HD emulation is off */
1.1.1.12 root 60: TP_ANTI_STE /* Apply patch only if running on plain ST */
1.1.1.6 root 61: };
1.1.1.3 root 62:
1.1.1.6 root 63: /* This structure is used for patching the TOS ROMs */
1.1.1.7 root 64: typedef struct
1.1 root 65: {
1.1.1.12 root 66: Uint16 Version; /* TOS version number */
67: Sint16 Country; /* TOS country code: -1 if it does not matter, 0=US, 1=Germany, 2=France, etc. */
68: const char *pszName; /* Name of the patch */
69: int Flags; /* When should the patch be applied? (see enum above) */
70: Uint32 Address; /* Where the patch should be applied */
71: Uint32 OldData; /* Expected first 4 old bytes */
72: Uint32 Size; /* Length of the patch */
73: const void *pNewData; /* Pointer to the new bytes */
1.1.1.6 root 74: } TOS_PATCH;
75:
1.1.1.10 root 76: static const char pszDmaBoot[] = "boot from DMA bus";
1.1.1.13 root 77: static const char pszMouse[] = "big resolutions mouse driver";
1.1.1.10 root 78: static const char pszRomCheck[] = "ROM checksum";
79: static const char pszNoSteHw[] = "disable STE hardware access";
1.1.1.12 root 80: static const char pszNoPmmu[] = "disable PMMU access";
1.1.1.13 root 81: static const char pszHwDisable[] = "disable hardware access";
1.1.1.6 root 82:
1.1.1.9 root 83: //static Uint8 pRtsOpcode[] = { 0x4E, 0x75 }; /* 0x4E75 = RTS */
1.1.1.10 root 84: static const Uint8 pNopOpcodes[] = { 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71,
1.1.1.6 root 85: 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71,
1.1.1.12 root 86: 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71 }; /* 0x4E71 = NOP */
1.1.1.10 root 87: static const Uint8 pMouseOpcode[] = { 0xD3, 0xC1 }; /* "ADDA.L D1,A1" (instead of "ADDA.W D1,A1") */
1.1.1.13 root 88: static const Uint8 pRomCheckOpcode206[] = { 0x60, 0x00, 0x00, 0x98 }; /* BRA $e00894 */
89: static const Uint8 pRomCheckOpcode306[] = { 0x60, 0x00, 0x00, 0xB0 }; /* BRA $e00886 */
90: static const Uint8 pRomCheckOpcode404[] = { 0x60, 0x00, 0x00, 0x94 }; /* BRA $e00746 */
1.1.1.10 root 91: static const Uint8 pBraOpcode[] = { 0x60 }; /* 0x60XX = BRA */
1.1 root 92:
1.1.1.6 root 93: /* The patches for the TOS: */
1.1.1.10 root 94: static const TOS_PATCH TosPatches[] =
1.1.1.6 root 95: {
1.1.1.13 root 96: { 0x100, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xFC03D6, 0x610000D0, 4, pNopOpcodes }, /* BSR $FC04A8 */
1.1.1.6 root 97:
1.1.1.13 root 98: { 0x102, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xFC0472, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $FC0558 */
1.1.1.6 root 99: { 0x102, 0, pszMouse, TP_ALWAYS, 0xFD0030, 0xD2C147F9, 2, pMouseOpcode },
100: { 0x102, 1, pszMouse, TP_ALWAYS, 0xFD008A, 0xD2C147F9, 2, pMouseOpcode },
101: { 0x102, 2, pszMouse, TP_ALWAYS, 0xFD00A8, 0xD2C147F9, 2, pMouseOpcode },
102: { 0x102, 3, pszMouse, TP_ALWAYS, 0xFD0030, 0xD2C147F9, 2, pMouseOpcode },
103: { 0x102, 6, pszMouse, TP_ALWAYS, 0xFCFEF0, 0xD2C147F9, 2, pMouseOpcode },
104: { 0x102, 8, pszMouse, TP_ALWAYS, 0xFCFEFE, 0xD2C147F9, 2, pMouseOpcode },
105:
1.1.1.13 root 106: { 0x104, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xFC0466, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $FC054C */
1.1.1.6 root 107:
1.1.1.13 root 108: { 0x106, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xE00576, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $E0065C */
1.1.1.10 root 109:
1.1.1.13 root 110: { 0x162, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xE00576, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $E0065C */
1.1.1.10 root 111:
1.1.1.13 root 112: { 0x205, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xE006AE, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $E00794 */
1.1.1.6 root 113: /* An unpatched TOS 2.05 only works on STEs, so apply some anti-STE patches... */
1.1.1.11 root 114: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00096, 0x42788900, 4, pNopOpcodes }, /* CLR.W $FFFF8900 */
115: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE0009E, 0x31D88924, 4, pNopOpcodes }, /* MOVE.W (A0)+,$FFFF8924 */
116: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE000A6, 0x09D10AA9, 28, pNopOpcodes },
117: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE003A0, 0x30389200, 4, pNopOpcodes }, /* MOVE.W $ffff9200,D0 */
118: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE004EA, 0x61000CBC, 4, pNopOpcodes },
119: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00508, 0x61000C9E, 4, pNopOpcodes },
120: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE007A0, 0x631E2F3C, 1, pBraOpcode },
121: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00928, 0x10388901, 4, pNopOpcodes }, /* MOVE.B $FFFF8901,D0 */
122: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00944, 0xB0388901, 4, pNopOpcodes }, /* CMP.B $FFFF8901,D0 */
123: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00950, 0x67024601, 1, pBraOpcode },
124: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00968, 0x61000722, 4, pNopOpcodes },
125: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00CF2, 0x1038820D, 4, pNopOpcodes }, /* MOVE.B $FFFF820D,D0 */
126: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00E00, 0x1038820D, 4, pNopOpcodes }, /* MOVE.B $FFFF820D,D0 */
127: { 0x205, 0, pszNoSteHw, TP_ANTI_STE, 0xE03038, 0x31C0860E, 4, pNopOpcodes },
128: { 0x205, 0, pszNoSteHw, TP_ANTI_STE, 0xE034A8, 0x31C0860E, 4, pNopOpcodes },
129: { 0x205, 0, pszNoSteHw, TP_ANTI_STE, 0xE034F6, 0x31E90002, 6, pNopOpcodes },
1.1.1.6 root 130:
131: /* E007FA MOVE.L #$1FFFE,D7 Run checksums on 2xROMs (skip) */
132: /* Checksum is total of TOS ROM image, but get incorrect results */
133: /* as we've changed bytes in the ROM! So, just skip anyway! */
1.1.1.13 root 134: { 0x206, -1, pszRomCheck, TP_ALWAYS, 0xE007FA, 0x2E3C0001, 4, pRomCheckOpcode206 },
135: { 0x206, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xE00898, 0x610000E0, 4, pNopOpcodes }, /* BSR.W $E0097A */
1.1 root 136:
1.1.1.13 root 137: { 0x306, -1, pszRomCheck, TP_ALWAYS, 0xE007D4, 0x2E3C0001, 4, pRomCheckOpcode306 },
1.1.1.12 root 138: { 0x306, -1, pszNoPmmu, TP_ALWAYS, 0xE00068, 0xF0394000, 24, pNopOpcodes },
139: { 0x306, -1, pszNoPmmu, TP_ALWAYS, 0xE01702, 0xF0394C00, 32, pNopOpcodes },
140:
1.1.1.13 root 141: { 0x400, -1, pszNoPmmu, TP_ALWAYS, 0xE00064, 0xF0394000, 24, pNopOpcodes },
142: { 0x400, -1, pszNoPmmu, TP_ALWAYS, 0xE0148A, 0xF0394C00, 32, pNopOpcodes },
143: { 0x400, -1, pszNoPmmu, TP_ALWAYS, 0xE03948, 0xF0394000, 24, pNopOpcodes },
144: { 0x400, -1, pszRomCheck, TP_ALWAYS, 0xE00686, 0x2E3C0007, 4, pRomCheckOpcode404 },
145:
146: { 0x401, -1, pszNoPmmu, TP_ALWAYS, 0xE0006A, 0xF0394000, 24, pNopOpcodes },
147: { 0x401, -1, pszNoPmmu, TP_ALWAYS, 0xE014A8, 0xF0394C00, 32, pNopOpcodes },
148: { 0x401, -1, pszNoPmmu, TP_ALWAYS, 0xE03946, 0xF0394000, 24, pNopOpcodes },
149: { 0x401, -1, pszRomCheck, TP_ALWAYS, 0xE006A6, 0x2E3C0007, 4, pRomCheckOpcode404 },
150:
151: { 0x402, -1, pszNoPmmu, TP_ALWAYS, 0xE0006A, 0xF0394000, 24, pNopOpcodes },
152: { 0x402, -1, pszNoPmmu, TP_ALWAYS, 0xE014A8, 0xF0394C00, 32, pNopOpcodes },
153: { 0x402, -1, pszNoPmmu, TP_ALWAYS, 0xE03946, 0xF0394000, 24, pNopOpcodes },
154: { 0x402, -1, pszRomCheck, TP_ALWAYS, 0xE006A6, 0x2E3C0007, 4, pRomCheckOpcode404 },
155:
156: { 0x404, -1, pszNoPmmu, TP_ALWAYS, 0xE0006A, 0xF0394000, 24, pNopOpcodes },
157: { 0x404, -1, pszNoPmmu, TP_ALWAYS, 0xE014E6, 0xF0394C00, 32, pNopOpcodes },
158: { 0x404, -1, pszNoPmmu, TP_ALWAYS, 0xE039A0, 0xF0394000, 24, pNopOpcodes },
159: { 0x404, -1, pszRomCheck, TP_ALWAYS, 0xE006B0, 0x2E3C0007, 4, pRomCheckOpcode404 },
160:
161: { 0x492, -1, pszNoPmmu, TP_ALWAYS, 0x00F946, 0xF0394000, 24, pNopOpcodes },
162: { 0x492, -1, pszNoPmmu, TP_ALWAYS, 0x01097A, 0xF0394C00, 32, pNopOpcodes },
163: { 0x492, -1, pszNoPmmu, TP_ALWAYS, 0x012E04, 0xF0394000, 24, pNopOpcodes },
164:
1.1.1.6 root 165: { 0, 0, NULL, 0, 0, 0, 0, NULL }
166: };
1.1 root 167:
168:
169:
1.1.1.6 root 170: /*-----------------------------------------------------------------------*/
1.1.1.13 root 171: /**
172: * Save/Restore snapshot of local variables ('MemorySnapShot_Store' handles type)
173: */
1.1.1.14 root 174: void TOS_MemorySnapShot_Capture(bool bSave)
1.1.1.6 root 175: {
1.1.1.12 root 176: /* Save/Restore details */
177: MemorySnapShot_Store(&TosVersion, sizeof(TosVersion));
178: MemorySnapShot_Store(&TosAddress, sizeof(TosAddress));
179: MemorySnapShot_Store(&TosSize, sizeof(TosSize));
180: MemorySnapShot_Store(&ConnectedDriveMask, sizeof(ConnectedDriveMask));
181: MemorySnapShot_Store(&nNumDrives, sizeof(nNumDrives));
1.1 root 182: }
183:
1.1.1.3 root 184:
185: /*-----------------------------------------------------------------------*/
1.1.1.13 root 186: /**
187: * Patch TOS to skip some TOS setup code which we don't support/need.
188: *
189: * So, how do we find these addresses when we have no commented source code?
190: * - For the "Boot from DMA bus" patch:
191: * Scan at start of rom for tst.w $482, boot call will be just above it.
192: */
1.1.1.6 root 193: static void TOS_FixRom(void)
1.1 root 194: {
1.1.1.12 root 195: int nGoodPatches, nBadPatches;
196: short TosCountry;
197: const TOS_PATCH *pPatch;
198:
1.1.1.13 root 199: /* We can't patch RAM TOS images (yet) */
200: if (bRamTosImage && TosVersion != 0x0492)
1.1.1.12 root 201: {
202: Log_Printf(LOG_DEBUG, "Detected RAM TOS image, skipping TOS patches.\n");
203: return;
204: }
205:
206: nGoodPatches = nBadPatches = 0;
207: TosCountry = STMemory_ReadWord(TosAddress+28)>>1; /* TOS country code */
208: pPatch = TosPatches;
209:
210: /* Apply TOS patches: */
211: while (pPatch->Version)
212: {
213: /* Only apply patches that suit to the actual TOS version: */
214: if (pPatch->Version == TosVersion
215: && (pPatch->Country == TosCountry || pPatch->Country == -1))
216: {
217: /* Make sure that we really patch the right place by comparing data: */
218: if(STMemory_ReadLong(pPatch->Address) == pPatch->OldData)
219: {
220: /* Only apply the patch if it is really needed: */
1.1.1.13 root 221: if (pPatch->Flags == TP_ALWAYS
222: || (pPatch->Flags == TP_HDIMAGE_OFF && !ACSI_EMU_ON && !ConfigureParams.HardDisk.bUseIdeHardDiskImage)
1.1.1.12 root 223: || (pPatch->Flags == TP_ANTI_STE && ConfigureParams.System.nMachineType == MACHINE_ST))
224: {
225: /* Now we can really apply the patch! */
1.1.1.13 root 226: Log_Printf(LOG_DEBUG, "Applying TOS patch '%s'.\n", pPatch->pszName);
227: memcpy(&RomMem[pPatch->Address], pPatch->pNewData, pPatch->Size);
1.1.1.12 root 228: nGoodPatches += 1;
229: }
230: else
231: {
1.1.1.13 root 232: Log_Printf(LOG_DEBUG, "Skipped patch '%s'.\n", pPatch->pszName);
1.1.1.12 root 233: }
234: }
235: else
236: {
237: Log_Printf(LOG_DEBUG, "Failed to apply TOS patch '%s' at %x (expected %x, found %x).\n",
238: pPatch->pszName, pPatch->Address, pPatch->OldData, STMemory_ReadLong(pPatch->Address));
239: nBadPatches += 1;
240: }
241: }
242: pPatch += 1;
243: }
1.1.1.3 root 244:
1.1.1.12 root 245: Log_Printf(LOG_DEBUG, "Applied %i TOS patches, %i patches failed.\n",
246: nGoodPatches, nBadPatches);
1.1.1.6 root 247: }
248:
249:
250: /*-----------------------------------------------------------------------*/
1.1.1.13 root 251: /**
252: * Assert that TOS version matches the machine type and change the system
253: * configuration if necessary.
254: * For example TOSes 1.06 and 1.62 are for the STE ONLY and so don't run
255: * on a real ST, TOS 3.0x is TT only and TOS 4.x is Falcon only.
256: * These TOS version access illegal memory addresses on machine they were
257: * not designed for and so cause the OS to lock up. So, if user selects one
258: * of these, switch to the appropriate machine type.
259: */
260: static void TOS_CheckSysConfig(void)
261: {
262: if ((TosVersion == 0x0106 || TosVersion == 0x0162) && ConfigureParams.System.nMachineType != MACHINE_STE)
263: {
1.1.1.14 root 264: Log_AlertDlg(LOG_ERROR, "TOS versions 1.06 and 1.62 are for Atari STE only.\n"
1.1.1.13 root 265: " ==> Switching to STE mode now.\n");
266: IoMem_UnInit();
267: ConfigureParams.System.nMachineType = MACHINE_STE;
268: IoMem_Init();
269: }
270: else if ((TosVersion & 0x0f00) == 0x0300 && ConfigureParams.System.nMachineType != MACHINE_TT)
271: {
1.1.1.14 root 272: Log_AlertDlg(LOG_ERROR, "TOS versions 3.0x are for Atari TT only.\n"
1.1.1.13 root 273: " ==> Switching to TT mode now.\n");
274: IoMem_UnInit();
275: ConfigureParams.System.nMachineType = MACHINE_TT;
276: IoMem_Init();
277: ConfigureParams.System.nCpuLevel = 3;
278: M68000_CheckCpuLevel();
279: }
280: else if ((TosVersion & 0x0f00) == 0x0400 && ConfigureParams.System.nMachineType != MACHINE_FALCON)
281: {
1.1.1.14 root 282: Log_AlertDlg(LOG_ERROR, "TOS versions 4.x are for Atari Falcon only.\n"
1.1.1.13 root 283: " ==> Switching to Falcon mode now.\n");
284: IoMem_UnInit();
285: ConfigureParams.System.nMachineType = MACHINE_FALCON;
286: IoMem_Init();
287: ConfigureParams.System.nCpuLevel = 3;
288: M68000_CheckCpuLevel();
289: }
290: else if ((TosVersion < 0x0300 && ConfigureParams.System.nMachineType == MACHINE_FALCON)
291: || (TosVersion < 0x0200 && ConfigureParams.System.nMachineType == MACHINE_TT))
292: {
1.1.1.14 root 293: Log_AlertDlg(LOG_ERROR, "This TOS versions does not work in TT/Falcon mode.\n"
1.1.1.13 root 294: " ==> Switching to STE mode now.\n");
295: IoMem_UnInit();
296: ConfigureParams.System.nMachineType = MACHINE_STE;
297: IoMem_Init();
298: if (TosVersion <= 0x0104)
299: {
300: ConfigureParams.System.nCpuLevel = 0;
301: M68000_CheckCpuLevel();
302: }
303: }
1.1.1.14 root 304: else if (TosVersion >= 0x0300 && ConfigureParams.System.nCpuLevel < 2)
305: {
306: Log_AlertDlg(LOG_ERROR, "This TOS versions requires a CPU >= 68020.\n"
307: " ==> Switching to 68020 mode now.\n");
308: ConfigureParams.System.nCpuLevel = 2;
309: M68000_CheckCpuLevel();
310: }
1.1.1.13 root 311: }
312:
313:
314: /*-----------------------------------------------------------------------*/
315: /**
316: * Load TOS Rom image file into ST memory space and fix image so can emulate correctly
317: * Pre TOS 1.06 are loaded at 0xFC0000 with later ones at 0xE00000
318: */
1.1.1.6 root 319: int TOS_LoadImage(void)
320: {
1.1.1.12 root 321: Uint8 *pTosFile = NULL;
322: long nFileSize;
1.1.1.6 root 323:
1.1.1.16! root 324: bTosImageLoaded = false;
1.1.1.6 root 325:
1.1.1.12 root 326: /* Load TOS image into memory so we can check it's vesion */
327: TosVersion = 0;
1.1.1.13 root 328: pTosFile = File_Read(ConfigureParams.Rom.szTosImageFileName, &nFileSize, pszTosNameExts);
1.1.1.12 root 329:
330: if (!pTosFile || nFileSize <= 0)
331: {
332: Log_AlertDlg(LOG_FATAL, "Can not load TOS file:\n'%s'", ConfigureParams.Rom.szTosImageFileName);
333: return -1;
334: }
335:
336: TosSize = nFileSize;
337:
338: /* Check for RAM TOS images first: */
339: if (SDL_SwapBE32(*(Uint32 *)pTosFile) == 0x46FC2700)
340: {
1.1.1.13 root 341: int nRamTosLoaderSize;
1.1.1.12 root 342: Log_Printf(LOG_WARN, "Detected a RAM TOS - this will probably not work very well!\n");
343: /* RAM TOS images have a 256 bytes loader function before the real image
1.1.1.13 root 344: * starts (34 bytes for TOS 4.92). Since we directly copy the image to the right
345: * location later, we simply skip this additional header here: */
346: if (SDL_SwapBE32(*(Uint32 *)(pTosFile+34)) == 0x602E0492)
347: nRamTosLoaderSize = 0x22;
348: else
349: nRamTosLoaderSize = 0x100;
350: TosSize -= nRamTosLoaderSize;
351: memmove(pTosFile, pTosFile + nRamTosLoaderSize, TosSize);
1.1.1.16! root 352: bRamTosImage = true;
1.1.1.12 root 353: }
354: else
355: {
1.1.1.16! root 356: bRamTosImage = false;
1.1.1.12 root 357: }
358:
1.1.1.13 root 359: /* Check for EmuTOS ... (0x45544F53 = 'ETOS') */
360: bIsEmuTOS = (SDL_SwapBE32(*(Uint32 *)&pTosFile[0x2c]) == 0x45544F53);
361:
1.1.1.12 root 362: /* Now, look at start of image to find Version number and address */
363: TosVersion = SDL_SwapBE16(*(Uint16 *)&pTosFile[2]);
364: TosAddress = SDL_SwapBE32(*(Uint32 *)&pTosFile[8]);
365:
366: /* Check for reasonable TOS version: */
1.1.1.13 root 367: if (TosVersion<0x100 || TosVersion>=0x500 || TosSize>1024*1024L
1.1.1.12 root 368: || (!bRamTosImage && TosAddress!=0xe00000 && TosAddress!=0xfc0000))
369: {
370: Log_AlertDlg(LOG_FATAL, "Your TOS image seems not to be a valid TOS ROM file!\n"
371: "(TOS version %x, address $%x)", TosVersion, TosAddress);
372: return -2;
373: }
374:
1.1.1.13 root 375: /* Assert that machine type matches the TOS version. Note that EmuTOS can
376: * handle all machine types, so we don't do the system check there: */
377: if (!bIsEmuTOS)
378: TOS_CheckSysConfig();
379:
380: /* Calculate end of RAM */
381: if (ConfigureParams.Memory.nMemorySize > 0
382: && ConfigureParams.Memory.nMemorySize <= 14)
383: STRamEnd = ConfigureParams.Memory.nMemorySize * 0x100000;
384: else
385: STRamEnd = 0x80000; /* 512 KiB */
386:
387: /* (Re-)Initialize the memory banks: */
388: memory_uninit();
389: memory_init(STRamEnd, 0, TosAddress);
390:
391: /* Clear Upper memory (ROM and IO memory) */
392: memset(&RomMem[0xe00000], 0, 0x200000);
1.1.1.12 root 393:
394: /* Copy loaded image into ST memory */
1.1.1.13 root 395: memcpy(&RomMem[TosAddress], pTosFile, TosSize);
1.1.1.12 root 396:
397: Log_Printf(LOG_DEBUG, "Loaded TOS version %i.%c%c, starting at $%x, "
398: "country code = %i, %s\n", TosVersion>>8, '0'+((TosVersion>>4)&0x0f),
399: '0'+(TosVersion&0x0f), TosAddress, STMemory_ReadWord(TosAddress+28)>>1,
400: (STMemory_ReadWord(TosAddress+28)&1)?"PAL":"NTSC");
401:
402: /* Are we allowed VDI under this TOS? */
403: if (TosVersion == 0x0100 && bUseVDIRes)
404: {
405: /* Warn user */
1.1.1.14 root 406: Log_AlertDlg(LOG_ERROR, "To use GEM extended resolutions, you must select a TOS >= 1.02.");
1.1.1.12 root 407: /* And select non VDI */
1.1.1.16! root 408: bUseVDIRes = ConfigureParams.Screen.bUseExtVdiResolutions = false;
1.1.1.12 root 409: }
410:
411: /* Fix TOS image, modify code for emulation */
1.1.1.13 root 412: if (!bIsEmuTOS)
413: TOS_FixRom();
1.1.1.12 root 414:
415: /* Set connected devices, memory configuration, etc. */
416: STMemory_SetDefaultConfig();
1.1.1.6 root 417:
1.1.1.12 root 418: /* and free loaded image */
419: free(pTosFile);
1.1.1.6 root 420:
1.1.1.16! root 421: bTosImageLoaded = true;
1.1.1.6 root 422:
1.1.1.12 root 423: return 0;
1.1 root 424: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.