|
|
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.7 ! root 18: static char rcsid[] = "Hatari $Id: tos.c,v 1.17 2003/04/02 20:53:35 emanne Exp $";
1.1 root 19:
1.1.1.4 root 20: #include <SDL_types.h>
21:
1.1 root 22: #include "main.h"
23: #include "cart.h"
24: #include "debug.h"
25: #include "decode.h"
26: #include "dialog.h"
27: #include "errlog.h"
28: #include "file.h"
29: #include "floppy.h"
1.1.1.4 root 30: #include "gemdos.h"
31: #include "hdc.h"
1.1 root 32: #include "m68000.h"
33: #include "memAlloc.h"
34: #include "memorySnapShot.h"
35: #include "stMemory.h"
36: #include "tos.h"
37: #include "vdi.h"
38:
39:
40: /* Settings for differnt memory sizes */
1.1.1.6 root 41: static MEMORY_INFO MemoryInfo[] =
42: {
43: { 0x80000, 0x01, 0x00080000 }, /* MEMORYSIZE_512 */
44: { 0x100000, 0x05, 0x00100000 }, /* MEMORYSIZE_1024 */
45: { 0x200000, 0x02, 0x00200000 }, /* MEMORYSIZE_2MB */
46: { 0x400000, 0x0A, 0x00400000 } /* MEMORYSIZE_4MB */
1.1 root 47: };
48:
1.1.1.4 root 49: /* Bit masks of connected drives(we support up to C,D,E,F,G,H) */
1.1.1.6 root 50: unsigned int ConnectedDriveMaskList[] =
51: {
1.1 root 52: 0x03, /* DRIVELIST_NONE A,B */
53: 0x07, /* DRIVELIST_C A,B,C */
54: 0x0F, /* DRIVELIST_CD A,B,C,D */
55: 0x1F, /* DRIVELIST_CDE A,B,C,D,E */
56: 0x3F, /* DRIVELIST_CDEF A,B,C,D,E,F */
1.1.1.4 root 57: 0x7F, /* DRIVELIST_CDEFG A,B,C,D,E,F,G */
58: 0xFF, /* DRIVELIST_CDEFGH A,B,C,D,E,F,G,H */
1.1 root 59: };
60:
1.1.1.6 root 61: unsigned short int TosVersion; /* eg, 0x0100, 0x0102 */
62: unsigned long TosAddress, TosSize; /* Address in ST memory and size of TOS image */
63: BOOL bTosImageLoaded = FALSE; /* Successfully loaded a TOS image? */
1.1.1.7 ! root 64: BOOL bRamTosImage; /* TRUE if we loaded a RAM TOS image */
1.1 root 65: unsigned int ConnectedDriveMask=0x03; /* Bit mask of connected drives, eg 0x7 is A,B,C */
1.1.1.7 ! root 66: unsigned long STRamEnd; /* End of ST Ram, above this address is no-mans-land and hardware vectors */
1.1 root 67:
68: /* Possible TOS file extensions to scan for */
1.1.1.6 root 69: char *pszTosNameExts[] =
70: {
1.1 root 71: ".img",
72: ".rom",
73: ".tos",
74: NULL
75: };
76:
77:
1.1.1.6 root 78: /* Flags that define if a TOS patch should be applied */
79: enum
1.1 root 80: {
1.1.1.6 root 81: TP_ALWAYS, /* Patch should alway be applied */
82: TP_HD_ON, /* Apply patch only if HD emulation is on */
83: TP_HD_OFF /* Apply patch only if HD emulation is off */
84: };
1.1.1.3 root 85:
1.1.1.6 root 86: /* This structure is used for patching the TOS ROMs */
1.1.1.7 ! root 87: typedef struct
1.1 root 88: {
1.1.1.6 root 89: Uint16 Version; /* TOS version number */
90: Sint16 Country; /* TOS country code: -1 if it does not matter, 0=US, 1=Germany, 2=France, etc. */
91: char *pszName; /* Name of the patch */
1.1.1.7 ! root 92: int Flags; /* When should the patch be applied? (see enum above) */
1.1.1.6 root 93: Uint32 Address; /* Where the patch should be applied */
94: Uint32 OldData; /* Expected first 4 old bytes */
95: Uint32 Size; /* Length of the patch */
1.1.1.7 ! root 96: void *pNewData; /* Pointer to the new bytes */
1.1.1.6 root 97: } TOS_PATCH;
98:
99: static char pszHdvInit[] = "hdv_init - initialize drives";
100: static char pszHdvBoot[] = "hdv_boot - load boot sector";
101: static char pszDmaBoot[] = "boot from DMA bus";
102: static char pszSetConDrv[] = "set connected drives mask";
103: static char pszClrConDrv[] = "clear connected drives mask";
104: static char pszMouse[] = "working mouse in big screen resolutions";
105: static char pszRomCheck[] = "ROM checksum";
106: static char pszNoSteHw[] = "disable STE hardware access";
107:
108: static Uint8 pRtsOpcode[] = { 0x4E, 0x75 }; /* 0x4E75 = RTS */
109: static Uint8 pNopOpcodes[] = { 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71,
110: 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71,
111: 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71 }; /* 0x4E71 = NOP */
112: static Uint8 pMouseOpcode[] = { 0xD3, 0xC1 }; /* "ADDA.L D1,A1" (instead of "ADDA.W D1,A1") */
113: static Uint8 pRomCheckOpcode[] = { 0x60, 0x00, 0x00, 0x98 }; /* BRA $e00894 */
114: static Uint8 pBraOpcode[] = { 0x60 }; /* 0x60XX = BRA */
1.1 root 115:
1.1.1.6 root 116: /* The patches for the TOS: */
117: static TOS_PATCH TosPatches[] =
118: {
119: { 0x100, -1, pszHdvInit, TP_ALWAYS, 0xFC0D60, 0x4E56FFF0, 2, pRtsOpcode },
120: { 0x100, -1, pszHdvBoot, TP_ALWAYS, 0xFC1384, 0x4EB900FC, 6, pNopOpcodes }, /* JSR $FC0AF8 */
121: { 0x100, -1, pszDmaBoot, TP_HD_OFF, 0xFC03D6, 0x610000D0, 4, pNopOpcodes }, /* BSR $FC04A8 */
122:
123: { 0x102, -1, pszHdvInit, TP_ALWAYS, 0xFC0F44, 0x4E56FFF0, 2, pRtsOpcode },
124: { 0x102, -1, pszHdvBoot, TP_ALWAYS, 0xFC1568, 0x4EB900FC, 6, pNopOpcodes }, /* JSR $FC0C2E */
1.1.1.7 ! root 125: //{ 0x102, -1, pszClrConDrv, TP_HD_OFF, 0xFC0302, 0x42B90000, 6, pNopOpcodes }, /* CLR.L $4C2 */
1.1.1.6 root 126: { 0x102, -1, pszDmaBoot, TP_HD_OFF, 0xFC0472, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $FC0558 */
127: { 0x102, 0, pszMouse, TP_ALWAYS, 0xFD0030, 0xD2C147F9, 2, pMouseOpcode },
128: { 0x102, 1, pszMouse, TP_ALWAYS, 0xFD008A, 0xD2C147F9, 2, pMouseOpcode },
129: { 0x102, 2, pszMouse, TP_ALWAYS, 0xFD00A8, 0xD2C147F9, 2, pMouseOpcode },
130: { 0x102, 3, pszMouse, TP_ALWAYS, 0xFD0030, 0xD2C147F9, 2, pMouseOpcode },
131: { 0x102, 6, pszMouse, TP_ALWAYS, 0xFCFEF0, 0xD2C147F9, 2, pMouseOpcode },
132: { 0x102, 8, pszMouse, TP_ALWAYS, 0xFCFEFE, 0xD2C147F9, 2, pMouseOpcode },
133:
134: { 0x104, -1, pszHdvInit, TP_ALWAYS, 0xFC16BA, 0x4E56FFF0, 2, pRtsOpcode },
135: { 0x104, -1, pszHdvBoot, TP_ALWAYS, 0xFC1CCE, 0x4EB900FC, 6, pNopOpcodes }, /* JSR $FC0BD8 */
1.1.1.7 ! root 136: //{ 0x104, -1, pszClrConDrv, TP_HD_OFF, 0xFC02E6, 0x42AD04C2, 4, pNopOpcodes }, /* CLR.L $4C2(A5) */
1.1.1.6 root 137: { 0x104, -1, pszDmaBoot, TP_HD_OFF, 0xFC0466, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $FC054C */
138:
1.1.1.7 ! root 139: //{ 0x205, -1, pszClrConDrv, TP_HD_OFF, 0xE002FC, 0x42B804C2, 4, pNopOpcodes }, /* CLR.L $4C2 */
1.1.1.6 root 140: { 0x205, -1, pszDmaBoot, TP_HD_OFF, 0xE006AE, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $E00794 */
141: { 0x205, 0, pszHdvInit, TP_ALWAYS, 0xE0468C, 0x4E56FFF0, 2, pRtsOpcode },
142: { 0x205, 1, pszHdvInit, TP_ALWAYS, 0xE046E6, 0x4E56FFF0, 2, pRtsOpcode },
143: { 0x205, 2, pszHdvInit, TP_ALWAYS, 0xE04704, 0x4E56FFF0, 2, pRtsOpcode },
144: { 0x205, 4, pszHdvInit, TP_ALWAYS, 0xE04712, 0x4E56FFF0, 2, pRtsOpcode },
145: { 0x205, 5, pszHdvInit, TP_ALWAYS, 0xE046F4, 0x4E56FFF0, 2, pRtsOpcode },
146: { 0x205, 6, pszHdvInit, TP_ALWAYS, 0xE04704, 0x4E56FFF0, 2, pRtsOpcode },
147: { 0x205, 0, pszHdvBoot, TP_ALWAYS, 0xE04CA0, 0x4EB900E0, 6, pNopOpcodes }, /* JSR $E00E8E */
148: { 0x205, 1, pszHdvBoot, TP_ALWAYS, 0xE04CFA, 0x4EB900E0, 6, pNopOpcodes },
149: { 0x205, 2, pszHdvBoot, TP_ALWAYS, 0xE04D18, 0x4EB900E0, 6, pNopOpcodes },
150: { 0x205, 4, pszHdvBoot, TP_ALWAYS, 0xE04D26, 0x4EB900E0, 6, pNopOpcodes },
151: { 0x205, 5, pszHdvBoot, TP_ALWAYS, 0xE04D08, 0x4EB900E0, 6, pNopOpcodes },
152: { 0x205, 6, pszHdvBoot, TP_ALWAYS, 0xE04D18, 0x4EB900E0, 6, pNopOpcodes },
153: /* An unpatched TOS 2.05 only works on STEs, so apply some anti-STE patches... */
154: { 0x205, -1, pszNoSteHw, TP_ALWAYS, 0xE00096, 0x42788900, 4, pNopOpcodes }, /* CLR.W $FFFF8900 */
155: { 0x205, -1, pszNoSteHw, TP_ALWAYS, 0xE0009E, 0x31D88924, 4, pNopOpcodes }, /* MOVE.W (A0)+,$FFFF8924 */
156: { 0x205, -1, pszNoSteHw, TP_ALWAYS, 0xE000A6, 0x09D10AA9, 28, pNopOpcodes },
157: { 0x205, -1, pszNoSteHw, TP_ALWAYS, 0xE003A0, 0x30389200, 4, pNopOpcodes }, /* MOVE.W $ffff9200,D0 */
158: { 0x205, -1, pszNoSteHw, TP_ALWAYS, 0xE004EA, 0x61000CBC, 4, pNopOpcodes },
159: { 0x205, -1, pszNoSteHw, TP_ALWAYS, 0xE00508, 0x61000C9E, 4, pNopOpcodes },
160: { 0x205, -1, pszNoSteHw, TP_ALWAYS, 0xE007A0, 0x631E2F3C, 1, pBraOpcode },
161: { 0x205, -1, pszNoSteHw, TP_ALWAYS, 0xE00928, 0x10388901, 4, pNopOpcodes }, /* MOVE.B $FFFF8901,D0 */
162: { 0x205, -1, pszNoSteHw, TP_ALWAYS, 0xE00944, 0xB0388901, 4, pNopOpcodes }, /* CMP.B $FFFF8901,D0 */
163: { 0x205, -1, pszNoSteHw, TP_ALWAYS, 0xE00950, 0x67024601, 1, pBraOpcode },
164: { 0x205, -1, pszNoSteHw, TP_ALWAYS, 0xE00968, 0x61000722, 4, pNopOpcodes },
165: { 0x205, -1, pszNoSteHw, TP_ALWAYS, 0xE00CF2, 0x1038820D, 4, pNopOpcodes }, /* MOVE.B $FFFF820D,D0 */
166: { 0x205, -1, pszNoSteHw, TP_ALWAYS, 0xE00E00, 0x1038820D, 4, pNopOpcodes }, /* MOVE.B $FFFF820D,D0 */
167: { 0x205, 0, pszNoSteHw, TP_ALWAYS, 0xE03038, 0x31C0860E, 4, pNopOpcodes },
168: { 0x205, 0, pszNoSteHw, TP_ALWAYS, 0xE034A8, 0x31C0860E, 4, pNopOpcodes },
169: { 0x205, 0, pszNoSteHw, TP_ALWAYS, 0xE034F6, 0x31E90002, 6, pNopOpcodes },
170:
171: /* E007FA MOVE.L #$1FFFE,D7 Run checksums on 2xROMs (skip) */
172: /* Checksum is total of TOS ROM image, but get incorrect results */
173: /* as we've changed bytes in the ROM! So, just skip anyway! */
174: { 0x206, -1, pszRomCheck, TP_ALWAYS, 0xE007FA, 0x2E3C0001, 4, pRomCheckOpcode },
1.1.1.7 ! root 175: // { 0x206, -1, pszClrConDrv, TP_HD_OFF, 0xE00362, 0x42B804C2, 4, pNopOpcodes }, /* CLR.L $4C2 */
1.1.1.6 root 176: { 0x206, -1, pszDmaBoot, TP_HD_OFF, 0xE00898, 0x610000E0, 4, pNopOpcodes }, /* BSR.W $E0097A */
177: { 0x206, 0, pszHdvInit, TP_ALWAYS, 0xE0518E, 0x4E56FFF0, 2, pRtsOpcode },
178: { 0x206, 1, pszHdvInit, TP_ALWAYS, 0xE051E8, 0x4E56FFF0, 2, pRtsOpcode },
179: { 0x206, 2, pszHdvInit, TP_ALWAYS, 0xE05206, 0x4E56FFF0, 2, pRtsOpcode },
180: { 0x206, 3, pszHdvInit, TP_ALWAYS, 0xE0518E, 0x4E56FFF0, 2, pRtsOpcode },
181: { 0x206, 6, pszHdvInit, TP_ALWAYS, 0xE05206, 0x4E56FFF0, 2, pRtsOpcode },
182: { 0x206, 8, pszHdvInit, TP_ALWAYS, 0xE05214, 0x4E56FFF0, 2, pRtsOpcode },
183: { 0x206, 0, pszHdvBoot, TP_ALWAYS, 0xE05944, 0x4EB900E0, 6, pNopOpcodes }, /* JSR $E011DC */
184: { 0x206, 1, pszHdvBoot, TP_ALWAYS, 0xE0599E, 0x4EB900E0, 6, pNopOpcodes },
185: { 0x206, 2, pszHdvBoot, TP_ALWAYS, 0xE059BC, 0x4EB900E0, 6, pNopOpcodes },
186: { 0x206, 3, pszHdvBoot, TP_ALWAYS, 0xE05944, 0x4EB900E0, 6, pNopOpcodes },
187: { 0x206, 6, pszHdvBoot, TP_ALWAYS, 0xE059BC, 0x4EB900E0, 6, pNopOpcodes },
188: { 0x206, 8, pszHdvBoot, TP_ALWAYS, 0xE059CA, 0x4EB900E0, 6, pNopOpcodes },
1.1 root 189:
1.1.1.6 root 190: { 0, 0, NULL, 0, 0, 0, 0, NULL }
191: };
1.1 root 192:
193:
194:
1.1.1.6 root 195: /*-----------------------------------------------------------------------*/
196: /*
197: Save/Restore snapshot of local variables ('MemorySnapShot_Store' handles type)
198: */
199: void TOS_MemorySnapShot_Capture(BOOL bSave)
200: {
201: /* Save/Restore details */
202: MemorySnapShot_Store(&TosVersion, sizeof(TosVersion));
203: MemorySnapShot_Store(&TosAddress, sizeof(TosAddress));
204: MemorySnapShot_Store(&TosSize, sizeof(TosSize));
205: MemorySnapShot_Store(&ConnectedDriveMask, sizeof(ConnectedDriveMask));
1.1 root 206: }
207:
1.1.1.3 root 208:
209: /*-----------------------------------------------------------------------*/
1.1 root 210: /*
1.1.1.4 root 211: Patch TOS to skip some TOS setup code which we don't support/need.
1.1 root 212:
213: So, how do we find these addresses when we have no commented source code?
1.1.1.6 root 214: - Hdv_init: Scan start of TOS for table of move.l <addr>,$46A(a5), around 0x224 bytes in
215: and look at the first entry - that's the hdv_init address.
216: - Hdv_boot: Scan start of TOS for table of move.l <addr>,$47A(a5), and look for 5th entry,
217: that's the hdv_boot address. The function starts with link,movem,jsr.
218: - Boot from DMA bus: again scan at start of rom for tst.w $482, boot call will be just above it.
219: - Clear connected drives: search for 'clr.w' and '$4c2' to find, may use (a5) in which case op-code
220: is only 4 bytes and also note this is only do on TOS > 1.00
221:
222: If we use hard disk emulation, we also need to force set condrv ($4c2),
223: because the ACSI driver (if any) will reset it. This is done after the DMA
224: bus boot (when the driver loads), replacing the RTS with our own routine which
225: sets condrv and then RTSes.
1.1 root 226: */
1.1.1.6 root 227: static void TOS_FixRom(void)
1.1 root 228: {
1.1.1.6 root 229: int nGoodPatches, nBadPatches;
230: short TosCountry;
231: BOOL bHdIsOn;
232: TOS_PATCH *pPatch;
1.1 root 233:
1.1.1.6 root 234: /* Check for EmuTOS first since we can not patch it */
235: if(STMemory_ReadLong(TosAddress+0x2c) == 0x45544F53) /* 0x45544F53 = 'ETOS' */
236: {
237: fprintf(stderr, "Detected EmuTOS, skipping TOS patches.\n");
238: return;
239: }
1.1 root 240:
1.1.1.7 ! root 241: /* We also can't patch RAM TOS images (yet) */
! 242: if(bRamTosImage)
! 243: {
! 244: fprintf(stderr, "RAM TOS image --> skipping TOS patches.\n");
! 245: return;
! 246: }
! 247:
1.1.1.6 root 248: nGoodPatches = nBadPatches = 0;
249: TosCountry = STMemory_ReadWord(TosAddress+28)>>1; /* TOS country code */
250: bHdIsOn = (ACSI_EMU_ON || GEMDOS_EMU_ON);
251: pPatch = TosPatches;
1.1 root 252:
1.1.1.6 root 253: /* Apply TOS patches: */
254: while(pPatch->Version)
255: {
1.1.1.7 ! root 256: /* Only apply patches that suit to the actual TOS version: */
1.1.1.6 root 257: if(pPatch->Version == TosVersion
258: && (pPatch->Country == TosCountry || pPatch->Country == -1))
259: {
260: /* Make sure that we really patch the right place by comparing data: */
261: if(STMemory_ReadLong(pPatch->Address) == pPatch->OldData)
1.1.1.5 root 262: {
1.1.1.6 root 263: /* Only apply the patch if it is really needed: */
264: if(pPatch->Flags == TP_ALWAYS || (pPatch->Flags == TP_HD_ON && bHdIsOn)
265: || (pPatch->Flags == TP_HD_OFF && !bHdIsOn))
1.1.1.5 root 266: {
1.1.1.6 root 267: /* Now we can really apply the patch! */
268: /*fprintf(stderr, "Applying TOS patch '%s'.\n", pPatch->pszName);*/
269: memcpy(&STRam[pPatch->Address], pPatch->pNewData, pPatch->Size);
1.1.1.5 root 270: }
1.1.1.6 root 271: else
1.1.1.5 root 272: {
1.1.1.6 root 273: /*fprintf(stderr, "Skipped patch '%s'.\n", pPatch->pszName);*/
1.1.1.5 root 274: }
1.1.1.6 root 275: nGoodPatches += 1;
1.1.1.5 root 276: }
277: else
278: {
1.1.1.7 ! root 279: fprintf(stderr, "Failed to apply TOS patch '%s' at %x (expected %x, found %lx).\n",
! 280: pPatch->pszName, pPatch->Address, pPatch->OldData, STMemory_ReadLong(pPatch->Address));
1.1.1.6 root 281: nBadPatches += 1;
1.1.1.5 root 282: }
1.1.1.6 root 283: }
284: pPatch += 1;
285: }
1.1 root 286:
1.1.1.6 root 287: fprintf(stderr, "Applied %i TOS patches, %i patches failed.\n",
288: nGoodPatches, nBadPatches);
1.1 root 289:
1.1.1.6 root 290: /* Modify assembler loaded into cartridge area */
291: switch(TosVersion)
292: {
293: case 0x0100: Cart_WriteHdvAddress(0x167A); break;
294: case 0x0102: Cart_WriteHdvAddress(0x16DA); break;
295: case 0x0104: Cart_WriteHdvAddress(0x181C); break;
296: case 0x0205: Cart_WriteHdvAddress(0x1410); break;
297: case 0x0206: Cart_WriteHdvAddress(0x1644); break;
1.1 root 298: }
1.1.1.6 root 299:
1.1 root 300: }
301:
1.1.1.3 root 302:
303: /*-----------------------------------------------------------------------*/
1.1 root 304: /*
305: Set default memory configuration, connected floppies and memory size
306: */
1.1.1.6 root 307: static void TOS_SetDefaultMemoryConfig(void)
1.1 root 308: {
1.1.1.3 root 309: /* As TOS checks hardware for memory size + connected devices on boot-up */
310: /* we set these values ourselves and fill in the magic numbers so TOS */
311: /* skips these tests which would crash the emulator as the reference the MMU */
312:
313: /* Fill in magic numbers, so TOS does not try to reference MMU */
1.1.1.6 root 314: STMemory_WriteLong(0x420, 0x752019f3); /* memvalid - configuration is valid */
315: STMemory_WriteLong(0x43a, 0x237698aa); /* another magic # */
316: STMemory_WriteLong(0x51a, 0x5555aaaa); /* and another */
1.1 root 317:
1.1.1.3 root 318: /* Set memory size, adjust for extra VDI screens if needed */
1.1.1.5 root 319: if (bUseVDIRes)
320: {
1.1.1.3 root 321: /* This is enough for 1024x768x16colour (0x60000) */
1.1.1.6 root 322: STMemory_WriteLong(0x436, MemoryInfo[ConfigureParams.Memory.nMemorySize].PhysTop-0x60000); /* mem top - upper end of user memory (before 32k screen) */
323: STMemory_WriteLong(0x42e, MemoryInfo[ConfigureParams.Memory.nMemorySize].PhysTop-0x58000); /* phys top */
1.1 root 324: }
1.1.1.5 root 325: else
326: {
1.1.1.6 root 327: STMemory_WriteLong(0x436, MemoryInfo[ConfigureParams.Memory.nMemorySize].PhysTop-0x8000); /* mem top - upper end of user memory(before 32k screen) */
328: STMemory_WriteLong(0x42e, MemoryInfo[ConfigureParams.Memory.nMemorySize].PhysTop); /* phys top */
1.1 root 329: }
1.1.1.6 root 330: STMemory_WriteByte(0x424, MemoryInfo[ConfigureParams.Memory.nMemorySize].MemoryConfig);
331: STMemory_WriteByte(0xff8001, MemoryInfo[ConfigureParams.Memory.nMemorySize].MemoryConfig);
1.1 root 332:
1.1.1.7 ! root 333: /* Set memory range */
1.1.1.3 root 334: STRamEnd = MemoryInfo[ConfigureParams.Memory.nMemorySize].MemoryEnd; /* Set end of RAM */
335:
336: /* Set TOS floppies */
1.1.1.6 root 337: STMemory_WriteWord(0x446, nBootDrive); /* Boot up on A(0) or C(2) */
338: STMemory_WriteWord(0x4a6, 0x2); /* Connected floppies A,B (0 or 2) */
1.1.1.4 root 339:
1.1.1.3 root 340: ConnectedDriveMask = ConnectedDriveMaskList[ConfigureParams.HardDisc.nDriveList];
1.1.1.4 root 341:
1.1.1.6 root 342: STMemory_WriteLong(0x4c2, ConnectedDriveMask); /* Drives A,B and C - NOTE some TOS images overwrite value, see 'TOS_ConnectedDrive_OpCode' */
1.1 root 343:
1.1.1.3 root 344: /* Mirror ROM boot vectors */
1.1.1.6 root 345: STMemory_WriteLong(0x00, STMemory_ReadLong(TosAddress));
346: STMemory_WriteLong(0x04, STMemory_ReadLong(TosAddress+4));
1.1.1.7 ! root 347:
! 348: /* Initialize the memory banks: */
! 349: memory_uninit();
! 350: memory_init(STRamEnd, 0, TosAddress);
1.1.1.6 root 351: }
352:
353:
354: /*-----------------------------------------------------------------------*/
355: /*
356: Load TOS Rom image file into ST memory space and fix image so can emulate correctly
357: Pre TOS 1.06 are loaded at 0xFC0000 with later ones at 0xE00000
358: */
359: int TOS_LoadImage(void)
360: {
361: void *pTosFile = NULL;
362:
363: bTosImageLoaded = FALSE;
364:
365: /* Load TOS image into memory so we can check it's vesion */
366: TosVersion = 0;
367: pTosFile = File_Read(ConfigureParams.TOSGEM.szTOSImageFileName, NULL, NULL, pszTosNameExts);
368: TosSize = File_Length(ConfigureParams.TOSGEM.szTOSImageFileName);
369:
370: if(pTosFile && TosSize>0)
371: {
1.1.1.7 ! root 372: /* Check for RAM TOS images first: */
! 373: if(STMemory_Swap68000Long(*(Uint32 *)pTosFile) == 0x46FC2700)
! 374: {
! 375: fprintf(stderr, "Warning: Detected a RAM TOS - this will probably not work very well!\n");
! 376: /* RAM TOS images have a 256 bytes loader function before the real image
! 377: * starts, so we simply skip the first 256 bytes here: */
! 378: TosSize -= 0x100;
! 379: memmove(pTosFile, pTosFile + 0x100, TosSize);
! 380: bRamTosImage = TRUE;
! 381: }
! 382: else
! 383: {
! 384: bRamTosImage = FALSE;
! 385: }
! 386:
1.1.1.6 root 387: /* Now, look at start of image to find Version number and address */
388: TosVersion = STMemory_Swap68000Int(*(Uint16 *)((Uint32)pTosFile+2));
389: TosAddress = STMemory_Swap68000Long(*(Uint32 *)((Uint32)pTosFile+8));
390:
391: /* Check for reasonable TOS version: */
392: if(TosVersion<0x100 || TosVersion>0x500 || TosSize>1024*1024L
1.1.1.7 ! root 393: || (!bRamTosImage && TosAddress!=0xe00000 && TosAddress!=0xfc0000))
1.1.1.6 root 394: {
395: Main_Message("Your TOS seems not to be a valid TOS ROM file!\n", PROG_NAME);
1.1.1.7 ! root 396: fprintf(stderr,"(TOS version %x, address %lx)\n", TosVersion, TosAddress);
1.1.1.6 root 397: return -2;
398: }
399:
400: /* TOSes 1.06 and 1.62 are for the STe ONLY and so don't run on a real STfm. */
401: /* They access illegal memory addresses which don't exist on a real machine and cause the OS */
402: /* to lock up. So, if user selects one of these, show an error */
403: if(TosVersion==0x0106 || TosVersion==0x0162)
404: {
405: Main_Message("TOS versions 1.06 and 1.62 are NOT valid STfm images.\n\n"
406: "These were only designed for use on the STe range of machines.\n", PROG_NAME /*,MB_OK|MB_ICONINFORMATION*/);
407: return -3;
408: }
409:
410: /* Copy loaded image into ST memory */
411: memcpy((void *)((unsigned long)STRam+TosAddress), pTosFile, TosSize);
412: }
413: else
414: {
415: char err_txt[256];
416: strcpy(err_txt, "Can not load TOS file:\n ");
417: strncat(err_txt, ConfigureParams.TOSGEM.szTOSImageFileName, 256-32);
418: strcat(err_txt, "\n");
419: Main_Message(err_txt, PROG_NAME);
420: return -1;
421: }
422:
423: fprintf(stderr, "Loaded TOS version %i.%c%c, starting at $%lx, "
424: "country code = %i, %s\n", TosVersion>>8, '0'+((TosVersion>>4)&0x0f),
425: '0'+(TosVersion&0x0f), TosAddress, STMemory_ReadWord(TosAddress+28)>>1,
426: (STMemory_ReadWord(TosAddress+28)&1)?"PAL":"NTSC");
427:
428: /* Are we allowed VDI under this TOS? */
429: if(TosVersion == 0x0100 && bUseVDIRes)
430: {
431: /* Warn user (exit if need to) */
432: Main_Message("To use GEM extended resolutions, you must select a TOS >= 1.02.",
433: PROG_NAME /*,MB_OK|MB_ICONINFORMATION*/);
434: /* And select non VDI */
435: bUseVDIRes = ConfigureParams.TOSGEM.bUseExtGEMResolutions = FALSE;
436: }
437:
438: /* Fix TOS image, modify code for emulation */
439: TOS_FixRom();
440:
441: /* Set connected devices, memory configuration */
442: TOS_SetDefaultMemoryConfig();
443:
444: /* and free loaded image */
445: Memory_Free(pTosFile);
446:
447: bTosImageLoaded = TRUE;
448: return 0;
1.1 root 449: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.