|
|
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.11! root 18: char TOS_rcsid[] = "Hatari $Id: tos.c,v 1.33 2005/10/04 15:31:52 thothy Exp $";
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"
25: #include "floppy.h"
1.1.1.4 root 26: #include "gemdos.h"
27: #include "hdc.h"
1.1.1.10 root 28: #include "ioMem.h"
29: #include "log.h"
1.1 root 30: #include "m68000.h"
31: #include "memorySnapShot.h"
32: #include "stMemory.h"
33: #include "tos.h"
34: #include "vdi.h"
35:
36:
1.1.1.10 root 37: Uint16 TosVersion; /* eg, 0x0100, 0x0102 */
38: Uint32 TosAddress, TosSize; /* Address in ST memory and size of TOS image */
39: BOOL bTosImageLoaded = FALSE; /* Successfully loaded a TOS image? */
40: BOOL bRamTosImage; /* TRUE if we loaded a RAM TOS image */
41: unsigned int ConnectedDriveMask = 0x03; /* Bit mask of connected drives, eg 0x7 is A,B,C */
1.1.1.11! root 42: int nNumDrives = 2; /* Number of drives, default is 2 for A: and B: */
1.1.1.10 root 43:
44:
1.1 root 45: /* Possible TOS file extensions to scan for */
1.1.1.10 root 46: static const char *pszTosNameExts[] =
1.1.1.6 root 47: {
1.1 root 48: ".img",
49: ".rom",
50: ".tos",
51: NULL
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.6 root 58: TP_ALWAYS, /* Patch should alway be applied */
1.1.1.11! root 59: TP_ACSI_OFF, /* Apply patch only if ACSI HD emulation is off */
! 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.6 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. */
1.1.1.10 root 68: const char *pszName; /* Name of the patch */
1.1.1.7 root 69: int Flags; /* When should the patch be applied? (see enum above) */
1.1.1.6 root 70: Uint32 Address; /* Where the patch should be applied */
71: Uint32 OldData; /* Expected first 4 old bytes */
72: Uint32 Size; /* Length of the patch */
1.1.1.10 root 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";
77: static const char pszMouse[] = "working mouse in big screen resolutions";
78: static const char pszRomCheck[] = "ROM checksum";
79: static const char pszNoSteHw[] = "disable STE hardware access";
1.1.1.6 root 80:
1.1.1.9 root 81: //static Uint8 pRtsOpcode[] = { 0x4E, 0x75 }; /* 0x4E75 = RTS */
1.1.1.10 root 82: static const Uint8 pNopOpcodes[] = { 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71,
1.1.1.6 root 83: 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71,
84: 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71 }; /* 0x4E71 = NOP */
1.1.1.10 root 85: static const Uint8 pMouseOpcode[] = { 0xD3, 0xC1 }; /* "ADDA.L D1,A1" (instead of "ADDA.W D1,A1") */
86: static const Uint8 pRomCheckOpcode[] = { 0x60, 0x00, 0x00, 0x98 }; /* BRA $e00894 */
87: static const Uint8 pBraOpcode[] = { 0x60 }; /* 0x60XX = BRA */
1.1 root 88:
1.1.1.6 root 89: /* The patches for the TOS: */
1.1.1.10 root 90: static const TOS_PATCH TosPatches[] =
1.1.1.6 root 91: {
1.1.1.11! root 92: { 0x100, -1, pszDmaBoot, TP_ACSI_OFF, 0xFC03D6, 0x610000D0, 4, pNopOpcodes }, /* BSR $FC04A8 */
1.1.1.6 root 93:
1.1.1.11! root 94: { 0x102, -1, pszDmaBoot, TP_ACSI_OFF, 0xFC0472, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $FC0558 */
1.1.1.6 root 95: { 0x102, 0, pszMouse, TP_ALWAYS, 0xFD0030, 0xD2C147F9, 2, pMouseOpcode },
96: { 0x102, 1, pszMouse, TP_ALWAYS, 0xFD008A, 0xD2C147F9, 2, pMouseOpcode },
97: { 0x102, 2, pszMouse, TP_ALWAYS, 0xFD00A8, 0xD2C147F9, 2, pMouseOpcode },
98: { 0x102, 3, pszMouse, TP_ALWAYS, 0xFD0030, 0xD2C147F9, 2, pMouseOpcode },
99: { 0x102, 6, pszMouse, TP_ALWAYS, 0xFCFEF0, 0xD2C147F9, 2, pMouseOpcode },
100: { 0x102, 8, pszMouse, TP_ALWAYS, 0xFCFEFE, 0xD2C147F9, 2, pMouseOpcode },
101:
1.1.1.11! root 102: { 0x104, -1, pszDmaBoot, TP_ACSI_OFF, 0xFC0466, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $FC054C */
1.1.1.6 root 103:
1.1.1.11! root 104: { 0x106, -1, pszDmaBoot, TP_ACSI_OFF, 0xE00576, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $E0065C */
1.1.1.10 root 105:
1.1.1.11! root 106: { 0x162, -1, pszDmaBoot, TP_ACSI_OFF, 0xE00576, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $E0065C */
1.1.1.10 root 107:
1.1.1.11! root 108: { 0x205, -1, pszDmaBoot, TP_ACSI_OFF, 0xE006AE, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $E00794 */
1.1.1.6 root 109: /* An unpatched TOS 2.05 only works on STEs, so apply some anti-STE patches... */
1.1.1.11! root 110: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00096, 0x42788900, 4, pNopOpcodes }, /* CLR.W $FFFF8900 */
! 111: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE0009E, 0x31D88924, 4, pNopOpcodes }, /* MOVE.W (A0)+,$FFFF8924 */
! 112: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE000A6, 0x09D10AA9, 28, pNopOpcodes },
! 113: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE003A0, 0x30389200, 4, pNopOpcodes }, /* MOVE.W $ffff9200,D0 */
! 114: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE004EA, 0x61000CBC, 4, pNopOpcodes },
! 115: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00508, 0x61000C9E, 4, pNopOpcodes },
! 116: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE007A0, 0x631E2F3C, 1, pBraOpcode },
! 117: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00928, 0x10388901, 4, pNopOpcodes }, /* MOVE.B $FFFF8901,D0 */
! 118: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00944, 0xB0388901, 4, pNopOpcodes }, /* CMP.B $FFFF8901,D0 */
! 119: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00950, 0x67024601, 1, pBraOpcode },
! 120: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00968, 0x61000722, 4, pNopOpcodes },
! 121: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00CF2, 0x1038820D, 4, pNopOpcodes }, /* MOVE.B $FFFF820D,D0 */
! 122: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00E00, 0x1038820D, 4, pNopOpcodes }, /* MOVE.B $FFFF820D,D0 */
! 123: { 0x205, 0, pszNoSteHw, TP_ANTI_STE, 0xE03038, 0x31C0860E, 4, pNopOpcodes },
! 124: { 0x205, 0, pszNoSteHw, TP_ANTI_STE, 0xE034A8, 0x31C0860E, 4, pNopOpcodes },
! 125: { 0x205, 0, pszNoSteHw, TP_ANTI_STE, 0xE034F6, 0x31E90002, 6, pNopOpcodes },
1.1.1.6 root 126:
127: /* E007FA MOVE.L #$1FFFE,D7 Run checksums on 2xROMs (skip) */
128: /* Checksum is total of TOS ROM image, but get incorrect results */
129: /* as we've changed bytes in the ROM! So, just skip anyway! */
130: { 0x206, -1, pszRomCheck, TP_ALWAYS, 0xE007FA, 0x2E3C0001, 4, pRomCheckOpcode },
1.1.1.11! root 131: { 0x206, -1, pszDmaBoot, TP_ACSI_OFF, 0xE00898, 0x610000E0, 4, pNopOpcodes }, /* BSR.W $E0097A */
1.1 root 132:
1.1.1.6 root 133: { 0, 0, NULL, 0, 0, 0, 0, NULL }
134: };
1.1 root 135:
136:
137:
1.1.1.6 root 138: /*-----------------------------------------------------------------------*/
139: /*
140: Save/Restore snapshot of local variables ('MemorySnapShot_Store' handles type)
141: */
142: void TOS_MemorySnapShot_Capture(BOOL bSave)
143: {
144: /* Save/Restore details */
145: MemorySnapShot_Store(&TosVersion, sizeof(TosVersion));
146: MemorySnapShot_Store(&TosAddress, sizeof(TosAddress));
147: MemorySnapShot_Store(&TosSize, sizeof(TosSize));
148: MemorySnapShot_Store(&ConnectedDriveMask, sizeof(ConnectedDriveMask));
1.1.1.11! root 149: MemorySnapShot_Store(&nNumDrives, sizeof(nNumDrives));
1.1 root 150: }
151:
1.1.1.3 root 152:
153: /*-----------------------------------------------------------------------*/
1.1 root 154: /*
1.1.1.4 root 155: Patch TOS to skip some TOS setup code which we don't support/need.
1.1 root 156:
157: So, how do we find these addresses when we have no commented source code?
1.1.1.10 root 158: - For the "Boot from DMA bus" patch:
159: Scan at start of rom for tst.w $482, boot call will be just above it.
1.1 root 160: */
1.1.1.6 root 161: static void TOS_FixRom(void)
1.1 root 162: {
1.1.1.6 root 163: int nGoodPatches, nBadPatches;
164: short TosCountry;
1.1.1.10 root 165: const TOS_PATCH *pPatch;
1.1 root 166:
1.1.1.6 root 167: /* Check for EmuTOS first since we can not patch it */
168: if(STMemory_ReadLong(TosAddress+0x2c) == 0x45544F53) /* 0x45544F53 = 'ETOS' */
169: {
1.1.1.10 root 170: Log_Printf(LOG_DEBUG, "Detected EmuTOS, skipping TOS patches.\n");
1.1.1.6 root 171: return;
172: }
1.1 root 173:
1.1.1.7 root 174: /* We also can't patch RAM TOS images (yet) */
175: if(bRamTosImage)
176: {
1.1.1.10 root 177: Log_Printf(LOG_DEBUG, "Detected RAM TOS image, skipping TOS patches.\n");
1.1.1.7 root 178: return;
179: }
180:
1.1.1.6 root 181: nGoodPatches = nBadPatches = 0;
182: TosCountry = STMemory_ReadWord(TosAddress+28)>>1; /* TOS country code */
183: pPatch = TosPatches;
1.1 root 184:
1.1.1.6 root 185: /* Apply TOS patches: */
186: while(pPatch->Version)
187: {
1.1.1.7 root 188: /* Only apply patches that suit to the actual TOS version: */
1.1.1.6 root 189: if(pPatch->Version == TosVersion
190: && (pPatch->Country == TosCountry || pPatch->Country == -1))
191: {
192: /* Make sure that we really patch the right place by comparing data: */
193: if(STMemory_ReadLong(pPatch->Address) == pPatch->OldData)
1.1.1.5 root 194: {
1.1.1.6 root 195: /* Only apply the patch if it is really needed: */
1.1.1.11! root 196: if (pPatch->Flags == TP_ALWAYS || (pPatch->Flags == TP_ACSI_OFF && !ACSI_EMU_ON)
! 197: || (pPatch->Flags == TP_ANTI_STE && ConfigureParams.System.nMachineType == MACHINE_ST))
1.1.1.5 root 198: {
1.1.1.6 root 199: /* Now we can really apply the patch! */
200: /*fprintf(stderr, "Applying TOS patch '%s'.\n", pPatch->pszName);*/
201: memcpy(&STRam[pPatch->Address], pPatch->pNewData, pPatch->Size);
1.1.1.11! root 202: nGoodPatches += 1;
1.1.1.5 root 203: }
1.1.1.6 root 204: else
1.1.1.5 root 205: {
1.1.1.6 root 206: /*fprintf(stderr, "Skipped patch '%s'.\n", pPatch->pszName);*/
1.1.1.5 root 207: }
208: }
209: else
210: {
1.1.1.10 root 211: Log_Printf(LOG_DEBUG, "Failed to apply TOS patch '%s' at %x (expected %x, found %x).\n",
212: pPatch->pszName, pPatch->Address, pPatch->OldData, STMemory_ReadLong(pPatch->Address));
1.1.1.6 root 213: nBadPatches += 1;
1.1.1.5 root 214: }
1.1.1.6 root 215: }
216: pPatch += 1;
217: }
1.1 root 218:
1.1.1.10 root 219: Log_Printf(LOG_DEBUG, "Applied %i TOS patches, %i patches failed.\n",
220: nGoodPatches, nBadPatches);
1.1 root 221: }
222:
1.1.1.3 root 223:
224: /*-----------------------------------------------------------------------*/
1.1 root 225: /*
226: Set default memory configuration, connected floppies and memory size
227: */
1.1.1.6 root 228: static void TOS_SetDefaultMemoryConfig(void)
1.1 root 229: {
1.1.1.11! root 230: int i;
! 231: Uint8 nMemControllerByte;
! 232: static const int MemControllerTable[] =
! 233: {
! 234: 0x01, /* 512 KiB */
! 235: 0x05, /* 1 MiB */
! 236: 0x02, /* 2 MiB */
! 237: 0x06, /* 2.5 MiB */
! 238: 0x0A /* 4 MiB */
! 239: };
! 240:
1.1.1.3 root 241: /* As TOS checks hardware for memory size + connected devices on boot-up */
242: /* we set these values ourselves and fill in the magic numbers so TOS */
243: /* skips these tests which would crash the emulator as the reference the MMU */
244:
245: /* Fill in magic numbers, so TOS does not try to reference MMU */
1.1.1.11! root 246: STMemory_WriteLong(0x420, 0x752019f3); /* memvalid - configuration is valid */
! 247: STMemory_WriteLong(0x43a, 0x237698aa); /* another magic # */
! 248: STMemory_WriteLong(0x51a, 0x5555aaaa); /* and another */
! 249:
! 250: /* Calculate end of RAM */
! 251: if (ConfigureParams.Memory.nMemorySize > 0 && ConfigureParams.Memory.nMemorySize <= 14)
! 252: STRamEnd = ConfigureParams.Memory.nMemorySize * 0x100000;
! 253: else
! 254: STRamEnd = 0x80000; /* 512 KiB */
1.1 root 255:
1.1.1.3 root 256: /* Set memory size, adjust for extra VDI screens if needed */
1.1.1.5 root 257: if (bUseVDIRes)
258: {
1.1.1.11! root 259: /* This is enough for 1024x768x16colors (0x60000) */
! 260: STMemory_WriteLong(0x436, STRamEnd-0x60000); /* mem top - upper end of user memory (before 32k screen) */
! 261: STMemory_WriteLong(0x42e, STRamEnd-0x58000); /* phys top */
1.1 root 262: }
1.1.1.5 root 263: else
264: {
1.1.1.11! root 265: STMemory_WriteLong(0x436, STRamEnd-0x8000); /* mem top - upper end of user memory (before 32k screen) */
! 266: STMemory_WriteLong(0x42e, STRamEnd); /* phys top */
1.1 root 267: }
268:
1.1.1.11! root 269: /* Set memory controller byte according to different memory sizes */
! 270: /* Setting per bank: %00=128k %01=512k %10=2Mb %11=reserved. - e.g. %1010 means 4Mb */
! 271: if (ConfigureParams.Memory.nMemorySize <= 4)
! 272: nMemControllerByte = MemControllerTable[ConfigureParams.Memory.nMemorySize];
! 273: else
! 274: nMemControllerByte = 0x0f;
! 275: STMemory_WriteByte(0x424, nMemControllerByte);
! 276: STMemory_WriteByte(0xff8001, nMemControllerByte);
1.1.1.3 root 277:
278: /* Set TOS floppies */
1.1.1.6 root 279: STMemory_WriteWord(0x446, nBootDrive); /* Boot up on A(0) or C(2) */
1.1.1.9 root 280: //STMemory_WriteWord(0x4a6, 0x2); /* Connected floppies A,B (0 or 2) */
1.1.1.4 root 281:
1.1.1.11! root 282: /* Create connected drives mask: */
! 283: ConnectedDriveMask = 0;
! 284: for (i = 0; i < nNumDrives; i++)
! 285: {
! 286: ConnectedDriveMask |= (1 << i);
! 287: }
! 288: /* Set connected drives system variable.
! 289: * NOTE: some TOS images overwrite this value, see 'OpCode_SysInit', too */
! 290: STMemory_WriteLong(0x4c2, ConnectedDriveMask);
1.1 root 291:
1.1.1.3 root 292: /* Mirror ROM boot vectors */
1.1.1.6 root 293: STMemory_WriteLong(0x00, STMemory_ReadLong(TosAddress));
294: STMemory_WriteLong(0x04, STMemory_ReadLong(TosAddress+4));
1.1.1.7 root 295:
296: /* Initialize the memory banks: */
297: memory_uninit();
298: memory_init(STRamEnd, 0, TosAddress);
1.1.1.6 root 299: }
300:
301:
302: /*-----------------------------------------------------------------------*/
303: /*
304: Load TOS Rom image file into ST memory space and fix image so can emulate correctly
305: Pre TOS 1.06 are loaded at 0xFC0000 with later ones at 0xE00000
306: */
307: int TOS_LoadImage(void)
308: {
1.1.1.10 root 309: Uint8 *pTosFile = NULL;
1.1.1.6 root 310:
311: bTosImageLoaded = FALSE;
312:
313: /* Load TOS image into memory so we can check it's vesion */
314: TosVersion = 0;
1.1.1.9 root 315: pTosFile = File_Read(ConfigureParams.Rom.szTosImageFileName, NULL, NULL, pszTosNameExts);
316: TosSize = File_Length(ConfigureParams.Rom.szTosImageFileName);
1.1.1.6 root 317:
318: if(pTosFile && TosSize>0)
319: {
1.1.1.7 root 320: /* Check for RAM TOS images first: */
1.1.1.8 root 321: if(SDL_SwapBE32(*(Uint32 *)pTosFile) == 0x46FC2700)
1.1.1.7 root 322: {
1.1.1.10 root 323: Log_Printf(LOG_WARN, "Detected a RAM TOS - this will probably not work very well!\n");
1.1.1.7 root 324: /* RAM TOS images have a 256 bytes loader function before the real image
325: * starts, so we simply skip the first 256 bytes here: */
326: TosSize -= 0x100;
327: memmove(pTosFile, pTosFile + 0x100, TosSize);
328: bRamTosImage = TRUE;
329: }
330: else
331: {
332: bRamTosImage = FALSE;
333: }
334:
1.1.1.6 root 335: /* Now, look at start of image to find Version number and address */
1.1.1.10 root 336: TosVersion = SDL_SwapBE16(*(Uint16 *)&pTosFile[2]);
337: TosAddress = SDL_SwapBE32(*(Uint32 *)&pTosFile[8]);
1.1.1.6 root 338:
339: /* Check for reasonable TOS version: */
340: if(TosVersion<0x100 || TosVersion>0x500 || TosSize>1024*1024L
1.1.1.7 root 341: || (!bRamTosImage && TosAddress!=0xe00000 && TosAddress!=0xfc0000))
1.1.1.6 root 342: {
1.1.1.10 root 343: Log_AlertDlg(LOG_FATAL, "Your TOS image seems not to be a valid TOS ROM file!\n"
344: "(TOS version %x, address $%x)", TosVersion, TosAddress);
1.1.1.6 root 345: return -2;
346: }
347:
1.1.1.10 root 348: /* TOSes 1.06 and 1.62 are for the STE ONLY and so don't run on a real ST. */
1.1.1.6 root 349: /* They access illegal memory addresses which don't exist on a real machine and cause the OS */
1.1.1.10 root 350: /* to lock up. So, if user selects one of these, switch to STE mode. */
351: if ((TosVersion == 0x0106 || TosVersion == 0x0162) && ConfigureParams.System.nMachineType != MACHINE_STE)
1.1.1.6 root 352: {
1.1.1.10 root 353: Log_AlertDlg(LOG_INFO, "TOS versions 1.06 and 1.62\nare NOT valid ST ROM images.\n"
354: " => Switching to STE mode now.\n");
355: IoMem_UnInit();
356: ConfigureParams.System.nMachineType = MACHINE_STE;
357: IoMem_Init();
1.1.1.6 root 358: }
359:
360: /* Copy loaded image into ST memory */
1.1.1.10 root 361: memcpy(STRam+TosAddress, pTosFile, TosSize);
1.1.1.6 root 362: }
363: else
364: {
1.1.1.10 root 365: Log_AlertDlg(LOG_FATAL, "Can not load TOS file:\n'%s'", ConfigureParams.Rom.szTosImageFileName);
1.1.1.6 root 366: return -1;
367: }
368:
1.1.1.10 root 369: Log_Printf(LOG_DEBUG, "Loaded TOS version %i.%c%c, starting at $%x, "
1.1.1.6 root 370: "country code = %i, %s\n", TosVersion>>8, '0'+((TosVersion>>4)&0x0f),
371: '0'+(TosVersion&0x0f), TosAddress, STMemory_ReadWord(TosAddress+28)>>1,
372: (STMemory_ReadWord(TosAddress+28)&1)?"PAL":"NTSC");
373:
374: /* Are we allowed VDI under this TOS? */
1.1.1.10 root 375: if (TosVersion == 0x0100 && bUseVDIRes)
1.1.1.6 root 376: {
1.1.1.10 root 377: /* Warn user */
378: Log_AlertDlg(LOG_WARN, "To use GEM extended resolutions, you must select a TOS >= 1.02.");
1.1.1.6 root 379: /* And select non VDI */
1.1.1.9 root 380: bUseVDIRes = ConfigureParams.Screen.bUseExtVdiResolutions = FALSE;
1.1.1.6 root 381: }
382:
383: /* Fix TOS image, modify code for emulation */
384: TOS_FixRom();
385:
386: /* Set connected devices, memory configuration */
387: TOS_SetDefaultMemoryConfig();
388:
389: /* and free loaded image */
1.1.1.10 root 390: free(pTosFile);
1.1.1.6 root 391:
392: bTosImageLoaded = TRUE;
393: return 0;
1.1 root 394: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.