|
|
1.1 root 1: /*
1.1.1.6 root 2: Hatari - tos.c
1.1 root 3:
1.1.1.22 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 root 6:
1.1.1.6 root 7: Load TOS image file into ST memory, fix/setup for emulator.
8:
1.1.1.18 root 9: The Atari ST TOS needs to be patched to help with emulation. Eg, it
10: references the MMU chip to set memory size. This is patched to the
11: sizes we need without the complicated emulation of hardware which
12: is not needed (as yet). We also patch DMA devices and Hard Drives.
13:
14: NOTE: TOS versions 1.06 and 1.62 were not designed for use on a
15: real STfm. These were for the STe machine ONLY. They access the
16: DMA/Microwire addresses on boot-up which (correctly) cause a
17: bus-error on Hatari as they would in a real STfm. If a user tries
18: to select any of these images we bring up an error. */
1.1.1.16 root 19: const char TOS_fileid[] = "Hatari tos.c : " __DATE__ " " __TIME__;
1.1 root 20:
1.1.1.8 root 21: #include <SDL_endian.h>
1.1.1.4 root 22:
1.1 root 23: #include "main.h"
1.1.1.9 root 24: #include "configuration.h"
1.1 root 25: #include "file.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"
1.1.1.18 root 33: #include "str.h"
1.1 root 34: #include "tos.h"
35: #include "vdi.h"
1.1.1.18 root 36: #include "falcon/dsp.h"
37: #include "clocks_timings.h"
1.1.1.25 root 38: #include "screen.h"
39: #include "video.h"
1.1 root 40:
1.1.1.14 root 41: bool bIsEmuTOS;
42: Uint16 TosVersion; /* eg. 0x0100, 0x0102 */
1.1.1.10 root 43: Uint32 TosAddress, TosSize; /* Address in ST memory and size of TOS image */
1.1.1.16 root 44: bool bTosImageLoaded = false; /* Successfully loaded a TOS image? */
45: bool bRamTosImage; /* true if we loaded a RAM TOS image */
1.1.1.23 root 46: unsigned int ConnectedDriveMask = 0x00; /* Bit mask of connected drives, eg 0x7 is A,B,C */
1.1.1.16 root 47: 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 48:
1.1 root 49: /* Possible TOS file extensions to scan for */
1.1.1.12 root 50: static const char * const pszTosNameExts[] =
1.1.1.6 root 51: {
1.1.1.12 root 52: ".img",
53: ".rom",
54: ".tos",
55: NULL
1.1 root 56: };
57:
1.1.1.6 root 58: /* Flags that define if a TOS patch should be applied */
59: enum
1.1 root 60: {
1.1.1.12 root 61: TP_ALWAYS, /* Patch should alway be applied */
1.1.1.13 root 62: TP_HDIMAGE_OFF, /* Apply patch only if HD emulation is off */
1.1.1.22 root 63: TP_ANTI_STE, /* Apply patch only if running on plain ST */
1.1.1.24 root 64: TP_ANTI_PMMU, /* Apply patch only if no PMMU is available */
65: TP_FIX_060, /* Apply patch only if CPU is 68060 */
1.1.1.26! root 66: TP_VDIRES, /* Apply patch only if VDI is used */
1.1.1.6 root 67: };
1.1.1.3 root 68:
1.1.1.6 root 69: /* This structure is used for patching the TOS ROMs */
1.1.1.7 root 70: typedef struct
1.1 root 71: {
1.1.1.12 root 72: Uint16 Version; /* TOS version number */
73: Sint16 Country; /* TOS country code: -1 if it does not matter, 0=US, 1=Germany, 2=France, etc. */
74: const char *pszName; /* Name of the patch */
75: int Flags; /* When should the patch be applied? (see enum above) */
76: Uint32 Address; /* Where the patch should be applied */
77: Uint32 OldData; /* Expected first 4 old bytes */
78: Uint32 Size; /* Length of the patch */
79: const void *pNewData; /* Pointer to the new bytes */
1.1.1.6 root 80: } TOS_PATCH;
81:
1.1.1.10 root 82: static const char pszDmaBoot[] = "boot from DMA bus";
1.1.1.13 root 83: static const char pszMouse[] = "big resolutions mouse driver";
1.1.1.10 root 84: static const char pszRomCheck[] = "ROM checksum";
85: static const char pszNoSteHw[] = "disable STE hardware access";
1.1.1.12 root 86: static const char pszNoPmmu[] = "disable PMMU access";
1.1.1.24 root 87: static const char pszFix060[] = "replace code for 68060";
88: static const char pszFalconExtraRAM[] = "enable extra TT RAM on Falcon";
1.1.1.26! root 89: static const char pszAtariLogo[] = "draw Atari Logo";
! 90: static const char pszSTbook[] = "disable MCU access on ST-Book";
1.1.1.6 root 91:
1.1.1.9 root 92: //static Uint8 pRtsOpcode[] = { 0x4E, 0x75 }; /* 0x4E75 = RTS */
1.1.1.10 root 93: static const Uint8 pNopOpcodes[] = { 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71,
1.1.1.6 root 94: 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71,
1.1.1.12 root 95: 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71 }; /* 0x4E71 = NOP */
1.1.1.10 root 96: static const Uint8 pMouseOpcode[] = { 0xD3, 0xC1 }; /* "ADDA.L D1,A1" (instead of "ADDA.W D1,A1") */
1.1.1.13 root 97: static const Uint8 pRomCheckOpcode206[] = { 0x60, 0x00, 0x00, 0x98 }; /* BRA $e00894 */
98: static const Uint8 pRomCheckOpcode306[] = { 0x60, 0x00, 0x00, 0xB0 }; /* BRA $e00886 */
99: static const Uint8 pRomCheckOpcode404[] = { 0x60, 0x00, 0x00, 0x94 }; /* BRA $e00746 */
1.1.1.10 root 100: static const Uint8 pBraOpcode[] = { 0x60 }; /* 0x60XX = BRA */
1.1 root 101:
1.1.1.26! root 102: /*
! 103: * Routine for drawing the Atari logo.
! 104: * When this function is called, A0 contains a pointer to a 96x86x1 image.
! 105: * We cannot use the vdi yet (the screen workstation has not yet been opened),
! 106: * but we can take into account extended VDI modes.
! 107: */
! 108: static const Uint8 pAtariLogo[] = {
! 109: 0x3e, 0x3c, 0x00, 0x01, /* move.w #planes, d7; number will be patched below */
! 110: 0x2c, 0x3c, 0, 0, 1, 64, /* move.l #linewidth, d6; number will be patched below */
! 111: 0x22, 0x78, 0x04, 0x4e, /* movea.l (_v_bas_ad).w,a1 */
! 112: 0xd3, 0xc6, /* adda.l d6,a1 ; start drawing at 5th line */
! 113: 0xd3, 0xc6, /* adda.l d6,a1 */
! 114: 0xd3, 0xc6, /* adda.l d6,a1 */
! 115: 0xd3, 0xc6, /* adda.l d6,a1 */
! 116: 0xd3, 0xc6, /* adda.l d6,a1 */
! 117: 0x30, 0x3c, 0x00, 0x55, /* move.w #$0055,d0 ; 86 lines of data */
! 118: /* logocol1: */
! 119: 0x72, 0x05, /* moveq.l #5,d1 ; 6 words of data per line */
! 120: 0x24, 0x49, /* movea.l a1,a2 */
! 121: /* logocol2: */
! 122: 0x34, 0x18, /* move.w (a0)+,d2 */
! 123: 0x36, 0x07, /* move.w d7,d3 */
! 124: 0x53, 0x43, /* subq.w #1,d3 */
! 125: /* logocol3: */
! 126: 0x34, 0xc2, /* move.w d2,(a2)+ */
! 127: 0x51, 0xcb, 0xff, 0xfc, /* dbf d3,logocol3 */
! 128: 0x51, 0xc9, 0xff, 0xf2, /* dbf d1,logocol2 */
! 129: 0xd3, 0xc6, /* adda.l d6,a1 */
! 130: 0x51, 0xc8, 0xff, 0xe8, /* dbf d0,logocol1 */
! 131: 0x4e, 0x71, /* nops to end of original routine */
! 132: 0x4e, 0x71,
! 133: 0x4e, 0x71,
! 134: 0x4e, 0x71,
! 135: 0x4e, 0x71,
! 136: 0x4e, 0x71,
! 137: 0x4e, 0x71,
! 138: 0x4e, 0x71
! 139: };
! 140:
1.1.1.25 root 141: static const Uint8 p060movep1[] = { /* replace MOVEP */
1.1.1.24 root 142: 0x70, 0x0c, /* moveq #12,d0 */
143: 0x42, 0x30, 0x08, 0x00, /* loop: clr.b 0,(d0,a0) */
144: 0x55, 0x40, /* subq #2,d0 */
145: 0x4a, 0x40, /* tst.w d0 */
146: 0x66, 0xf6, /* bne.s loop */
147: };
1.1.1.25 root 148: static const Uint8 p060movep2[] = { /* replace MOVEP */
1.1.1.24 root 149: 0x41, 0xf8, 0xfa, 0x26, /* lea 0xfffffa26.w,a0 */
150: 0x20, 0xfc, 0x00, 0x00, 0x00, 0x88, /* move.l #$00000088,(a0)+ */
151: 0x20, 0xbc, 0x00, 0x01, 0x00, 0x05, /* move.l #$00010005,(a0) */
152: 0x4a, 0x38, 0x0a, 0x87 /* tst.b $a87.w */
153: };
1.1.1.25 root 154: static const Uint8 p060movep3_1[] = { /* replace MOVEP */
1.1.1.24 root 155: 0x4e, 0xb9, 0x00, 0xe7, 0xf0, 0x00, /* jsr $e7f000 */
156: 0x4e, 0x71 /* nop */
157: };
1.1.1.25 root 158: static const Uint8 p060movep3_2[] = { /* replace MOVEP $28(a2),d7 */
1.1.1.24 root 159:
160: 0x00, 0x7c, 0x07, 0x00, /* ori #$700,sr */
161: 0x1e, 0x2a, 0x00, 0x28, /* move.b $28(a2),d7 */
162: 0xe1, 0x4f, /* lsl.w #8,d7 */
163: 0x1e, 0x2a, 0x00, 0x2a, /* move.b $2a(a2),d7 */
164: 0x48, 0x47, /* swap d7 */
165: 0x1e, 0x2a, 0x00, 0x2c, /* move.b $2c(a2),d7 */
166: 0xe1, 0x4f, /* lsl.w #8,d7 */
167: 0x1e, 0x2a, 0x00, 0x2e, /* move.b $2e(a2),d7 */
168: 0x4e, 0x75 /* rts */
169: };
170:
171: static const Uint8 pFalconExtraRAM_1[] = {
172: 0x4e, 0xb9, 0x00, 0xe7, 0xf1, 0x00 /* jsr $e7f100 */
173: };
174: static const Uint8 pFalconExtraRAM_2[] = { /* call maddalt() to declare the extra RAM */
175: 0x20, 0x38, 0x05, 0xa4, /* move.l $05a4.w,d0 */
176: 0x67, 0x18, /* beq.s $ba2d2 */
177: 0x04, 0x80, 0x01, 0x00, 0x00, 0x00, /* subi.l #$1000000,d0 */
178: 0x2f, 0x00, /* move.l d0,-(sp) */
179: 0x2f, 0x3c, 0x01, 0x00, 0x00, 0x00, /* move.l #$1000000,-(sp) */
180: 0x3f, 0x3c, 0x00, 0x14, /* move.w #$14,-(sp) */
181: 0x4e, 0x41, /* trap #1 */
182: 0x4f, 0xef, 0x00, 0x0a, /* lea $a(sp),sp */
183: 0x70, 0x03, /* moveq #3,d0 */
184: 0x4e, 0xf9, 0x00, 0xe0, 0x0b, 0xd2 /* jmp $e00bd2 */
185: };
186:
1.1.1.6 root 187: /* The patches for the TOS: */
1.1.1.10 root 188: static const TOS_PATCH TosPatches[] =
1.1.1.6 root 189: {
1.1.1.13 root 190: { 0x100, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xFC03D6, 0x610000D0, 4, pNopOpcodes }, /* BSR $FC04A8 */
1.1.1.6 root 191:
1.1.1.13 root 192: { 0x102, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xFC0472, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $FC0558 */
1.1.1.6 root 193: { 0x102, 0, pszMouse, TP_ALWAYS, 0xFD0030, 0xD2C147F9, 2, pMouseOpcode },
194: { 0x102, 1, pszMouse, TP_ALWAYS, 0xFD008A, 0xD2C147F9, 2, pMouseOpcode },
195: { 0x102, 2, pszMouse, TP_ALWAYS, 0xFD00A8, 0xD2C147F9, 2, pMouseOpcode },
196: { 0x102, 3, pszMouse, TP_ALWAYS, 0xFD0030, 0xD2C147F9, 2, pMouseOpcode },
197: { 0x102, 6, pszMouse, TP_ALWAYS, 0xFCFEF0, 0xD2C147F9, 2, pMouseOpcode },
198: { 0x102, 8, pszMouse, TP_ALWAYS, 0xFCFEFE, 0xD2C147F9, 2, pMouseOpcode },
199:
1.1.1.13 root 200: { 0x104, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xFC0466, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $FC054C */
1.1.1.6 root 201:
1.1.1.13 root 202: { 0x106, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xE00576, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $E0065C */
1.1.1.10 root 203:
1.1.1.13 root 204: { 0x162, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xE00576, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $E0065C */
1.1.1.10 root 205:
1.1.1.13 root 206: { 0x205, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xE006AE, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $E00794 */
1.1.1.6 root 207: /* An unpatched TOS 2.05 only works on STEs, so apply some anti-STE patches... */
1.1.1.11 root 208: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00096, 0x42788900, 4, pNopOpcodes }, /* CLR.W $FFFF8900 */
209: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE0009E, 0x31D88924, 4, pNopOpcodes }, /* MOVE.W (A0)+,$FFFF8924 */
210: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE000A6, 0x09D10AA9, 28, pNopOpcodes },
211: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE003A0, 0x30389200, 4, pNopOpcodes }, /* MOVE.W $ffff9200,D0 */
212: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE004EA, 0x61000CBC, 4, pNopOpcodes },
213: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00508, 0x61000C9E, 4, pNopOpcodes },
214: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE007A0, 0x631E2F3C, 1, pBraOpcode },
215: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00928, 0x10388901, 4, pNopOpcodes }, /* MOVE.B $FFFF8901,D0 */
216: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00944, 0xB0388901, 4, pNopOpcodes }, /* CMP.B $FFFF8901,D0 */
217: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00950, 0x67024601, 1, pBraOpcode },
218: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00968, 0x61000722, 4, pNopOpcodes },
219: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00CF2, 0x1038820D, 4, pNopOpcodes }, /* MOVE.B $FFFF820D,D0 */
220: { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00E00, 0x1038820D, 4, pNopOpcodes }, /* MOVE.B $FFFF820D,D0 */
221: { 0x205, 0, pszNoSteHw, TP_ANTI_STE, 0xE03038, 0x31C0860E, 4, pNopOpcodes },
222: { 0x205, 0, pszNoSteHw, TP_ANTI_STE, 0xE034A8, 0x31C0860E, 4, pNopOpcodes },
223: { 0x205, 0, pszNoSteHw, TP_ANTI_STE, 0xE034F6, 0x31E90002, 6, pNopOpcodes },
1.1.1.6 root 224:
225: /* E007FA MOVE.L #$1FFFE,D7 Run checksums on 2xROMs (skip) */
226: /* Checksum is total of TOS ROM image, but get incorrect results */
227: /* as we've changed bytes in the ROM! So, just skip anyway! */
1.1.1.13 root 228: { 0x206, -1, pszRomCheck, TP_ALWAYS, 0xE007FA, 0x2E3C0001, 4, pRomCheckOpcode206 },
229: { 0x206, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xE00898, 0x610000E0, 4, pNopOpcodes }, /* BSR.W $E0097A */
1.1.1.26! root 230: { 0x206, -1, pszAtariLogo, TP_VDIRES, 0xE0076C, 0x1038044c, sizeof( pAtariLogo ), pAtariLogo },
! 231:
! 232: { 0x208, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xE00806, 0x610000E8, 4, pNopOpcodes }, /* BSR.W $E008F0 */
! 233: { 0x208, -1, pszAtariLogo, TP_VDIRES, 0xE006B4, 0x1038044c, sizeof( pAtariLogo ), pAtariLogo },
! 234: { 0x208, -1, pszSTbook, TP_ALWAYS, 0xE00066, 0x303900d0, 18, pNopOpcodes },
! 235: { 0x208, -1, pszSTbook, TP_ALWAYS, 0xE000D6, 0x4a7900d0, 6, pNopOpcodes },
! 236: { 0x208, -1, pszSTbook, TP_ALWAYS, 0xE009FE, 0x303900d0, 14, pNopOpcodes },
1.1 root 237:
1.1.1.13 root 238: { 0x306, -1, pszRomCheck, TP_ALWAYS, 0xE007D4, 0x2E3C0001, 4, pRomCheckOpcode306 },
1.1.1.24 root 239: { 0x306, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE00068, 0xF0394000, 24, pNopOpcodes }, /* pmove : TC=0 TT0=0 TT1=0 -> disable MMU */
240: { 0x306, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE01702, 0xF0394C00, 32, pNopOpcodes }, /* pmove : CRP=80000002 00000700 TC=80f04445 TT0=017e8107 TT1=807e8507 -> */
1.1.1.25 root 241: { 0x306, -1, pszFix060, TP_FIX_060, 0xe024dc, 0x01C80000, 12, p060movep1 },
242: { 0x306, -1, pszFix060, TP_FIX_060, 0xe024fa, 0x01C80000, 12, p060movep1 },
1.1.1.26! root 243: { 0x306, -1, pszAtariLogo, TP_VDIRES, 0xE00754, 0x1038044c, sizeof( pAtariLogo ), pAtariLogo },
1.1.1.12 root 244:
1.1.1.24 root 245: { 0x400, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE00064, 0xF0394000, 24, pNopOpcodes }, /* pmove : TC=0 TT0=0 TT1=0 -> disable MMU */
1.1.1.22 root 246: { 0x400, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE0148A, 0xF0394C00, 32, pNopOpcodes },
1.1.1.24 root 247: { 0x400, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE03948, 0xF0394000, 24, pNopOpcodes }, /* pmove : TC=0 TT0=0 TT1=0 -> disable MMU */
1.1.1.13 root 248: { 0x400, -1, pszRomCheck, TP_ALWAYS, 0xE00686, 0x2E3C0007, 4, pRomCheckOpcode404 },
1.1.1.25 root 249: { 0x400, -1, pszFix060, TP_FIX_060, 0xE0258A, 0x01C80000, 12, p060movep1 },
250: { 0x400, -1, pszFix060, TP_FIX_060, 0xE025DA, 0x41F8FA01, 20, p060movep2 },
1.1.1.13 root 251:
1.1.1.24 root 252: { 0x401, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE0006A, 0xF0394000, 24, pNopOpcodes }, /* pmove : TC=0 TT0=0 TT1=0 -> disable MMU */
1.1.1.22 root 253: { 0x401, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE014A8, 0xF0394C00, 32, pNopOpcodes },
1.1.1.24 root 254: { 0x401, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE03946, 0xF0394000, 24, pNopOpcodes }, /* pmove : TC=0 TT0=0 TT1=0 -> disable MMU */
1.1.1.13 root 255: { 0x401, -1, pszRomCheck, TP_ALWAYS, 0xE006A6, 0x2E3C0007, 4, pRomCheckOpcode404 },
1.1.1.25 root 256: { 0x401, -1, pszFix060, TP_FIX_060, 0xE02588, 0x01C80000, 12, p060movep1 },
257: { 0x401, -1, pszFix060, TP_FIX_060, 0xE025D8, 0x41F8FA01, 20, p060movep2 },
1.1.1.13 root 258:
1.1.1.24 root 259: { 0x402, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE0006A, 0xF0394000, 24, pNopOpcodes }, /* pmove : TC=0 TT0=0 TT1=0 -> disable MMU */
1.1.1.22 root 260: { 0x402, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE014A8, 0xF0394C00, 32, pNopOpcodes },
1.1.1.24 root 261: { 0x402, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE03946, 0xF0394000, 24, pNopOpcodes }, /* pmove : TC=0 TT0=0 TT1=0 -> disable MMU */
1.1.1.13 root 262: { 0x402, -1, pszRomCheck, TP_ALWAYS, 0xE006A6, 0x2E3C0007, 4, pRomCheckOpcode404 },
1.1.1.25 root 263: { 0x402, -1, pszFix060, TP_FIX_060, 0xE02588, 0x01C80000, 12, p060movep1 },
264: { 0x402, -1, pszFix060, TP_FIX_060, 0xE025D8, 0x41F8FA01, 20, p060movep2 },
1.1.1.13 root 265:
1.1.1.24 root 266: { 0x404, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE0006A, 0xF0394000, 24, pNopOpcodes }, /* pmove : TC=0 TT0=0 TT1=0 -> disable MMU */
267: { 0x404, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE014E6, 0xF0394C00, 32, pNopOpcodes }, /* pmove : CRP=80000002 00000700 TC=80f04445 TT0=017e8107 TT1=807e8507 -> */
268: { 0x404, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE039A0, 0xF0394000, 24, pNopOpcodes }, /* pmove : TC=0 TT0=0 TT1=0 -> disable MMU */
1.1.1.13 root 269: { 0x404, -1, pszRomCheck, TP_ALWAYS, 0xE006B0, 0x2E3C0007, 4, pRomCheckOpcode404 },
1.1.1.23 root 270: { 0x404, -1, pszDmaBoot, TP_ALWAYS, 0xE01C9E, 0x62FC31FC, 2, pNopOpcodes }, /* Just a delay */
271: { 0x404, -1, pszDmaBoot, TP_ALWAYS, 0xE01CB2, 0x62FC31FC, 2, pNopOpcodes }, /* Just a delay */
1.1.1.25 root 272: { 0x404, -1, pszFix060, TP_FIX_060, 0xE025E2, 0x01C80000, 12, p060movep1 },
273: { 0x404, -1, pszFix060, TP_FIX_060, 0xE02632, 0x41F8FA01, 20, p060movep2 },
274: { 0x404, -1, pszFix060, TP_FIX_060, 0xE02B1E, 0x007c0700, 8, p060movep3_1 },
275: { 0x404, -1, pszFix060, TP_FIX_060, 0xE7F000, 0xFFFFFFFF, sizeof( p060movep3_2 ), p060movep3_2 },
1.1.1.24 root 276: { 0x404, -1, pszFalconExtraRAM, TP_ALWAYS, 0xE0096E, 0x70036100, 6, pFalconExtraRAM_1 },
277: { 0x404, -1, pszFalconExtraRAM, TP_ALWAYS, 0xE7F100, 0xFFFFFFFF, sizeof( pFalconExtraRAM_2 ), pFalconExtraRAM_2 },
1.1.1.13 root 278:
1.1.1.22 root 279: { 0x492, -1, pszNoPmmu, TP_ANTI_PMMU, 0x00F946, 0xF0394000, 24, pNopOpcodes },
280: { 0x492, -1, pszNoPmmu, TP_ANTI_PMMU, 0x01097A, 0xF0394C00, 32, pNopOpcodes },
281: { 0x492, -1, pszNoPmmu, TP_ANTI_PMMU, 0x012E04, 0xF0394000, 24, pNopOpcodes },
1.1.1.13 root 282:
1.1.1.6 root 283: { 0, 0, NULL, 0, 0, 0, 0, NULL }
284: };
1.1 root 285:
286:
287:
1.1.1.6 root 288: /*-----------------------------------------------------------------------*/
1.1.1.13 root 289: /**
290: * Save/Restore snapshot of local variables ('MemorySnapShot_Store' handles type)
291: */
1.1.1.14 root 292: void TOS_MemorySnapShot_Capture(bool bSave)
1.1.1.6 root 293: {
1.1.1.12 root 294: /* Save/Restore details */
295: MemorySnapShot_Store(&TosVersion, sizeof(TosVersion));
296: MemorySnapShot_Store(&TosAddress, sizeof(TosAddress));
297: MemorySnapShot_Store(&TosSize, sizeof(TosSize));
298: MemorySnapShot_Store(&ConnectedDriveMask, sizeof(ConnectedDriveMask));
299: MemorySnapShot_Store(&nNumDrives, sizeof(nNumDrives));
1.1 root 300: }
301:
1.1.1.3 root 302:
303: /*-----------------------------------------------------------------------*/
1.1.1.13 root 304: /**
305: * Patch TOS to skip some TOS setup code which we don't support/need.
306: *
307: * So, how do we find these addresses when we have no commented source code?
308: * - For the "Boot from DMA bus" patch:
309: * Scan at start of rom for tst.w $482, boot call will be just above it.
310: */
1.1.1.6 root 311: static void TOS_FixRom(void)
1.1 root 312: {
1.1.1.12 root 313: int nGoodPatches, nBadPatches;
314: short TosCountry;
315: const TOS_PATCH *pPatch;
1.1.1.26! root 316: Uint32 logopatch_addr = 0;
1.1.1.12 root 317:
1.1.1.13 root 318: /* We can't patch RAM TOS images (yet) */
319: if (bRamTosImage && TosVersion != 0x0492)
1.1.1.12 root 320: {
321: Log_Printf(LOG_DEBUG, "Detected RAM TOS image, skipping TOS patches.\n");
322: return;
323: }
324:
325: nGoodPatches = nBadPatches = 0;
326: TosCountry = STMemory_ReadWord(TosAddress+28)>>1; /* TOS country code */
327: pPatch = TosPatches;
328:
329: /* Apply TOS patches: */
330: while (pPatch->Version)
331: {
332: /* Only apply patches that suit to the actual TOS version: */
333: if (pPatch->Version == TosVersion
334: && (pPatch->Country == TosCountry || pPatch->Country == -1))
335: {
1.1.1.22 root 336: #if ENABLE_WINUAE_CPU
1.1.1.25 root 337: bool use_mmu = ConfigureParams.System.bMMU &&
338: ConfigureParams.System.nCpuLevel == 3;
1.1.1.22 root 339: #else
340: bool use_mmu = false;
341: #endif
1.1.1.12 root 342: /* Make sure that we really patch the right place by comparing data: */
343: if(STMemory_ReadLong(pPatch->Address) == pPatch->OldData)
344: {
345: /* Only apply the patch if it is really needed: */
1.1.1.13 root 346: if (pPatch->Flags == TP_ALWAYS
1.1.1.19 root 347: || (pPatch->Flags == TP_HDIMAGE_OFF && !ACSI_EMU_ON
348: && !ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage
349: && ConfigureParams.System.bFastBoot)
1.1.1.25 root 350: || (pPatch->Flags == TP_ANTI_STE && Config_IsMachineST())
1.1.1.22 root 351: || (pPatch->Flags == TP_ANTI_PMMU && !use_mmu)
1.1.1.26! root 352: || (pPatch->Flags == TP_VDIRES && bUseVDIRes)
1.1.1.24 root 353: || (pPatch->Flags == TP_FIX_060 && ConfigureParams.System.nCpuLevel > 4)
1.1.1.22 root 354: )
1.1.1.12 root 355: {
356: /* Now we can really apply the patch! */
1.1.1.13 root 357: Log_Printf(LOG_DEBUG, "Applying TOS patch '%s'.\n", pPatch->pszName);
358: memcpy(&RomMem[pPatch->Address], pPatch->pNewData, pPatch->Size);
1.1.1.12 root 359: nGoodPatches += 1;
1.1.1.26! root 360: if (strcmp(pPatch->pszName, pszAtariLogo) == 0)
! 361: logopatch_addr = pPatch->Address;
1.1.1.12 root 362: }
363: else
364: {
1.1.1.13 root 365: Log_Printf(LOG_DEBUG, "Skipped patch '%s'.\n", pPatch->pszName);
1.1.1.12 root 366: }
367: }
368: else
369: {
370: Log_Printf(LOG_DEBUG, "Failed to apply TOS patch '%s' at %x (expected %x, found %x).\n",
371: pPatch->pszName, pPatch->Address, pPatch->OldData, STMemory_ReadLong(pPatch->Address));
372: nBadPatches += 1;
373: }
374: }
375: pPatch += 1;
376: }
1.1.1.3 root 377:
1.1.1.26! root 378: /* patch some values into the "Draw logo" patch */
! 379: if (logopatch_addr != 0)
1.1.1.18 root 380: {
1.1.1.26! root 381: STMemory_WriteWord(logopatch_addr + 2, VDIPlanes);
! 382: STMemory_WriteLong(logopatch_addr + 6, VDIWidth * VDIPlanes / 8);
1.1.1.18 root 383: }
384:
1.1.1.26! root 385: Log_Printf(LOG_DEBUG, "Applied %i TOS patches, %i patches failed.\n",
! 386: nGoodPatches, nBadPatches);
1.1.1.18 root 387: }
388:
389:
390: /*-----------------------------------------------------------------------*/
391: /**
1.1.1.13 root 392: * Assert that TOS version matches the machine type and change the system
393: * configuration if necessary.
394: * For example TOSes 1.06 and 1.62 are for the STE ONLY and so don't run
395: * on a real ST, TOS 3.0x is TT only and TOS 4.x is Falcon only.
396: * These TOS version access illegal memory addresses on machine they were
397: * not designed for and so cause the OS to lock up. So, if user selects one
398: * of these, switch to the appropriate machine type.
399: */
400: static void TOS_CheckSysConfig(void)
401: {
1.1.1.22 root 402: int oldCpuLevel = ConfigureParams.System.nCpuLevel;
1.1.1.21 root 403: MACHINETYPE oldMachineType = ConfigureParams.System.nMachineType;
1.1.1.25 root 404: #if ENABLE_WINUAE_CPU
405: FPUTYPE oldFpuType = ConfigureParams.System.n_FPUType;
406: #endif
407:
1.1.1.26! root 408: if (((TosVersion == 0x0106 || TosVersion == 0x0162) && ConfigureParams.System.nMachineType != MACHINE_STE)
1.1.1.22 root 409: || (TosVersion == 0x0162 && ConfigureParams.System.nCpuLevel != 0))
1.1.1.13 root 410: {
1.1.1.14 root 411: Log_AlertDlg(LOG_ERROR, "TOS versions 1.06 and 1.62 are for Atari STE only.\n"
1.1.1.13 root 412: " ==> Switching to STE mode now.\n");
413: IoMem_UnInit();
414: ConfigureParams.System.nMachineType = MACHINE_STE;
1.1.1.18 root 415: ClocksTimings_InitMachine ( ConfigureParams.System.nMachineType );
1.1.1.25 root 416: Video_SetTimings ( ConfigureParams.System.nMachineType , ConfigureParams.System.VideoTimingMode );
1.1.1.13 root 417: IoMem_Init();
1.1.1.26! root 418: Configuration_ChangeCpuFreq ( 8 );
1.1.1.17 root 419: ConfigureParams.System.nCpuLevel = 0;
1.1.1.13 root 420: }
1.1.1.25 root 421: else if ((TosVersion & 0x0f00) == 0x0300 && !Config_IsMachineTT())
1.1.1.13 root 422: {
1.1.1.14 root 423: Log_AlertDlg(LOG_ERROR, "TOS versions 3.0x are for Atari TT only.\n"
1.1.1.13 root 424: " ==> Switching to TT mode now.\n");
425: IoMem_UnInit();
426: ConfigureParams.System.nMachineType = MACHINE_TT;
1.1.1.18 root 427: ClocksTimings_InitMachine ( ConfigureParams.System.nMachineType );
1.1.1.25 root 428: Video_SetTimings ( ConfigureParams.System.nMachineType , ConfigureParams.System.VideoTimingMode );
1.1.1.13 root 429: IoMem_Init();
1.1.1.26! root 430: Configuration_ChangeCpuFreq ( 32 );
1.1.1.13 root 431: ConfigureParams.System.nCpuLevel = 3;
432: }
1.1.1.25 root 433: else if ((TosVersion & 0x0f00) == 0x0400 && !Config_IsMachineFalcon())
1.1.1.13 root 434: {
1.1.1.14 root 435: Log_AlertDlg(LOG_ERROR, "TOS versions 4.x are for Atari Falcon only.\n"
1.1.1.13 root 436: " ==> Switching to Falcon mode now.\n");
437: IoMem_UnInit();
438: ConfigureParams.System.nMachineType = MACHINE_FALCON;
1.1.1.18 root 439: ClocksTimings_InitMachine ( ConfigureParams.System.nMachineType );
1.1.1.25 root 440: Video_SetTimings ( ConfigureParams.System.nMachineType , ConfigureParams.System.VideoTimingMode );
1.1.1.18 root 441: #if ENABLE_DSP_EMU
442: ConfigureParams.System.nDSPType = DSP_TYPE_EMU;
1.1.1.25 root 443: DSP_Enable();
1.1.1.18 root 444: #endif
1.1.1.13 root 445: IoMem_Init();
1.1.1.26! root 446: Configuration_ChangeCpuFreq ( 16 );
1.1.1.13 root 447: ConfigureParams.System.nCpuLevel = 3;
448: }
1.1.1.19 root 449: else if (TosVersion <= 0x0104 &&
1.1.1.25 root 450: (ConfigureParams.System.nCpuLevel > 0 || !Config_IsMachineST()))
1.1.1.17 root 451: {
1.1.1.19 root 452: Log_AlertDlg(LOG_ERROR, "TOS versions <= 1.4 work only in\n"
453: "ST mode and with a 68000 CPU.\n"
1.1.1.22 root 454: " ==> Switching to ST mode with 68000 now.\n");
1.1.1.17 root 455: IoMem_UnInit();
456: ConfigureParams.System.nMachineType = MACHINE_ST;
1.1.1.18 root 457: ClocksTimings_InitMachine ( ConfigureParams.System.nMachineType );
1.1.1.25 root 458: Video_SetTimings ( ConfigureParams.System.nMachineType , ConfigureParams.System.VideoTimingMode );
1.1.1.17 root 459: IoMem_Init();
1.1.1.26! root 460: Configuration_ChangeCpuFreq ( 8 );
1.1.1.17 root 461: ConfigureParams.System.nCpuLevel = 0;
462: }
1.1.1.26! root 463: else if (TosVersion < 0x0300 &&
! 464: (Config_IsMachineTT() || Config_IsMachineFalcon()))
1.1.1.13 root 465: {
1.1.1.19 root 466: Log_AlertDlg(LOG_ERROR, "This TOS version does not work in TT/Falcon mode.\n"
1.1.1.13 root 467: " ==> Switching to STE mode now.\n");
468: IoMem_UnInit();
469: ConfigureParams.System.nMachineType = MACHINE_STE;
1.1.1.18 root 470: ClocksTimings_InitMachine ( ConfigureParams.System.nMachineType );
1.1.1.25 root 471: Video_SetTimings ( ConfigureParams.System.nMachineType , ConfigureParams.System.VideoTimingMode );
1.1.1.13 root 472: IoMem_Init();
1.1.1.26! root 473: Configuration_ChangeCpuFreq ( 8 );
1.1.1.17 root 474: ConfigureParams.System.nCpuLevel = 0;
1.1.1.13 root 475: }
1.1.1.22 root 476: else if ((TosVersion & 0x0f00) == 0x0400 && ConfigureParams.System.nCpuLevel < 2)
1.1.1.14 root 477: {
1.1.1.22 root 478: Log_AlertDlg(LOG_ERROR, "TOS versions 4.x require a CPU >= 68020.\n"
1.1.1.14 root 479: " ==> Switching to 68020 mode now.\n");
480: ConfigureParams.System.nCpuLevel = 2;
1.1.1.21 root 481: }
1.1.1.25 root 482: #if ENABLE_WINUAE_CPU
483: else if ((TosVersion & 0x0f00) == 0x0300 &&
484: (ConfigureParams.System.nCpuLevel < 2 || ConfigureParams.System.n_FPUType == FPU_NONE))
485: {
486: Log_AlertDlg(LOG_ERROR, "TOS versions 3.0x require a CPU >= 68020 with FPU.\n"
487: " ==> Switching to 68030 mode with FPU now.\n");
488: ConfigureParams.System.nCpuLevel = 3;
489: ConfigureParams.System.n_FPUType = FPU_68882;
490: }
491: #else
1.1.1.22 root 492: else if ((TosVersion & 0x0f00) == 0x0300 && ConfigureParams.System.nCpuLevel < 3)
493: {
1.1.1.25 root 494: Log_AlertDlg(LOG_ERROR, "TOS versions 3.0x require a CPU >= 68020 with FPU.\n"
495: " ==> Switching to 68030 mode with FPU now.\n");
1.1.1.22 root 496: ConfigureParams.System.nCpuLevel = 3;
497: }
1.1.1.25 root 498: #endif
499:
1.1.1.21 root 500: /* TOS version triggered changes? */
501: if (ConfigureParams.System.nMachineType != oldMachineType)
502: {
503: #if ENABLE_WINUAE_CPU
1.1.1.25 root 504: if (Config_IsMachineTT())
1.1.1.21 root 505: {
506: ConfigureParams.System.bCompatibleFPU = true;
507: ConfigureParams.System.n_FPUType = FPU_68882;
508: } else {
509: ConfigureParams.System.n_FPUType = FPU_NONE; /* TODO: or leave it as-is? */
510: }
1.1.1.22 root 511: if (TosVersion < 0x200)
512: {
513: ConfigureParams.System.bAddressSpace24 = true;
514: ConfigureParams.System.bMMU = false;
515: }
1.1.1.21 root 516: #endif
1.1.1.18 root 517: M68000_CheckCpuSettings();
1.1.1.14 root 518: }
1.1.1.25 root 519: else if (ConfigureParams.System.nCpuLevel != oldCpuLevel
520: #if ENABLE_WINUAE_CPU
521: || ConfigureParams.System.n_FPUType != oldFpuType
522: #endif
523: )
1.1.1.22 root 524: {
525: M68000_CheckCpuSettings();
526: }
1.1.1.19 root 527: if (TosVersion < 0x0104 && ConfigureParams.HardDisk.bUseHardDiskDirectories)
528: {
529: Log_AlertDlg(LOG_ERROR, "Please use at least TOS v1.04 for the HD directory emulation "
530: "(all required GEMDOS functionality isn't completely emulated for this TOS version).");
531: }
1.1.1.25 root 532: if (Config_IsMachineFalcon() && bUseVDIRes && !bIsEmuTOS)
533: {
534: Log_AlertDlg(LOG_ERROR, "Please use EmuTOS for proper VDI results in Falcon mode "
535: "(TOS 4 doesn't fully support VDI).");
536: }
1.1.1.13 root 537: }
538:
539:
540: /*-----------------------------------------------------------------------*/
541: /**
1.1.1.20 root 542: * Load TOS Rom image file into ST memory space and fix image so it can be
543: * emulated correctly. Pre TOS 1.06 are loaded at 0xFC0000 and later ones
544: * at 0xE00000.
1.1.1.26! root 545: *
! 546: * Return zero if all OK, non-zero value for error.
1.1.1.13 root 547: */
1.1.1.6 root 548: int TOS_LoadImage(void)
549: {
1.1.1.12 root 550: Uint8 *pTosFile = NULL;
551: long nFileSize;
1.1.1.6 root 552:
1.1.1.16 root 553: bTosImageLoaded = false;
1.1.1.6 root 554:
1.1.1.24 root 555: /* Calculate end of RAM */
1.1.1.26! root 556: STRamEnd = ConfigureParams.Memory.STRamSize_KB * 1024;
1.1.1.24 root 557:
1.1.1.20 root 558: /* Load TOS image into memory so that we can check its version */
1.1.1.12 root 559: TosVersion = 0;
1.1.1.13 root 560: pTosFile = File_Read(ConfigureParams.Rom.szTosImageFileName, &nFileSize, pszTosNameExts);
1.1.1.12 root 561:
562: if (!pTosFile || nFileSize <= 0)
563: {
564: Log_AlertDlg(LOG_FATAL, "Can not load TOS file:\n'%s'", ConfigureParams.Rom.szTosImageFileName);
1.1.1.24 root 565: free(pTosFile);
1.1.1.12 root 566: return -1;
567: }
568:
569: TosSize = nFileSize;
570:
571: /* Check for RAM TOS images first: */
572: if (SDL_SwapBE32(*(Uint32 *)pTosFile) == 0x46FC2700)
573: {
1.1.1.13 root 574: int nRamTosLoaderSize;
1.1.1.12 root 575: Log_Printf(LOG_WARN, "Detected a RAM TOS - this will probably not work very well!\n");
576: /* RAM TOS images have a 256 bytes loader function before the real image
1.1.1.13 root 577: * starts (34 bytes for TOS 4.92). Since we directly copy the image to the right
578: * location later, we simply skip this additional header here: */
579: if (SDL_SwapBE32(*(Uint32 *)(pTosFile+34)) == 0x602E0492)
580: nRamTosLoaderSize = 0x22;
581: else
582: nRamTosLoaderSize = 0x100;
583: TosSize -= nRamTosLoaderSize;
584: memmove(pTosFile, pTosFile + nRamTosLoaderSize, TosSize);
1.1.1.16 root 585: bRamTosImage = true;
1.1.1.12 root 586: }
587: else
588: {
1.1.1.16 root 589: bRamTosImage = false;
1.1.1.12 root 590: }
591:
1.1.1.13 root 592: /* Check for EmuTOS ... (0x45544F53 = 'ETOS') */
593: bIsEmuTOS = (SDL_SwapBE32(*(Uint32 *)&pTosFile[0x2c]) == 0x45544F53);
594:
1.1.1.12 root 595: /* Now, look at start of image to find Version number and address */
596: TosVersion = SDL_SwapBE16(*(Uint16 *)&pTosFile[2]);
597: TosAddress = SDL_SwapBE32(*(Uint32 *)&pTosFile[8]);
1.1.1.26! root 598: if (TosVersion == 0x206 && SDL_SwapBE16(*(Uint16 *)&pTosFile[30]) == 0x186A)
! 599: TosVersion = 0x208;
1.1.1.12 root 600:
601: /* Check for reasonable TOS version: */
1.1.1.18 root 602: if (TosVersion == 0x000 && TosSize == 16384)
603: {
604: /* TOS 0.00 was a very early boot loader ROM which could only
605: * execute a boot sector from floppy disk, which was used in
606: * the very early STs before a full TOS was available in ROM.
607: * It's not very useful nowadays, but we support it here, too,
608: * just for fun. */
609: TosAddress = 0xfc0000;
610: }
1.1.1.24 root 611: else if (TosVersion < 0x100 || TosVersion >= 0x500 || TosSize > 1024*1024L
612: || (TosAddress == 0xfc0000 && TosSize > 224*1024L)
613: || (bRamTosImage && TosAddress + TosSize > STRamEnd)
614: || (!bRamTosImage && TosAddress != 0xe00000 && TosAddress != 0xfc0000))
1.1.1.12 root 615: {
616: Log_AlertDlg(LOG_FATAL, "Your TOS image seems not to be a valid TOS ROM file!\n"
617: "(TOS version %x, address $%x)", TosVersion, TosAddress);
1.1.1.24 root 618: free(pTosFile);
1.1.1.12 root 619: return -2;
620: }
621:
1.1.1.13 root 622: /* Assert that machine type matches the TOS version. Note that EmuTOS can
623: * handle all machine types, so we don't do the system check there: */
624: if (!bIsEmuTOS)
625: TOS_CheckSysConfig();
626:
1.1.1.24 root 627: #if ENABLE_WINUAE_CPU
1.1.1.25 root 628: /* 32-bit addressing is supported only by CPU >= 68020, TOS v3, TOS v4 and EmuTOS */
629: if (ConfigureParams.System.nCpuLevel < 2 || (TosVersion < 0x0300 && !bIsEmuTOS))
630: {
1.1.1.24 root 631: ConfigureParams.System.bAddressSpace24 = true;
1.1.1.25 root 632: M68000_CheckCpuSettings();
633: }
1.1.1.26! root 634: else if (ConfigureParams.Memory.TTRamSize_KB)
1.1.1.24 root 635: {
636: switch (ConfigureParams.System.nMachineType)
637: {
638: case MACHINE_TT:
639: if (ConfigureParams.System.bAddressSpace24)
640: {
641: /* Print a message and force 32 bit addressing (keeping 24 bit with TT RAM would crash TOS) */
642: Log_AlertDlg(LOG_ERROR, "Enabling 32-bit addressing for TT-RAM access.\nThis can cause issues in some programs!\n");
643: ConfigureParams.System.bAddressSpace24 = false;
1.1.1.25 root 644: M68000_CheckCpuSettings();
1.1.1.24 root 645: }
646: break;
647: case MACHINE_FALCON:
648: if (ConfigureParams.System.bAddressSpace24)
649: {
650: /* Print a message, but don't force 32 bit addressing as 24 bit addressing is also possible under Falcon */
651: /* So, if Falcon is in 24 bit mode, we just don't add TT RAM */
652: Log_AlertDlg(LOG_ERROR, "You need to disable 24-bit addressing to use TT-RAM in Falcon mode.\n");
653: }
654: break;
655: default:
656: break;
657: }
658: }
659: #endif
1.1.1.13 root 660:
661: /* (Re-)Initialize the memory banks: */
662: memory_uninit();
1.1.1.26! root 663: memory_init(STRamEnd, ConfigureParams.Memory.TTRamSize_KB*1024, TosAddress);
1.1.1.13 root 664:
665: /* Clear Upper memory (ROM and IO memory) */
666: memset(&RomMem[0xe00000], 0, 0x200000);
1.1.1.12 root 667:
1.1.1.24 root 668: /* Copy loaded image into memory */
669: if (bRamTosImage)
670: memcpy(&STRam[TosAddress], pTosFile, TosSize);
671: else
672: memcpy(&RomMem[TosAddress], pTosFile, TosSize);
1.1.1.12 root 673:
674: Log_Printf(LOG_DEBUG, "Loaded TOS version %i.%c%c, starting at $%x, "
675: "country code = %i, %s\n", TosVersion>>8, '0'+((TosVersion>>4)&0x0f),
676: '0'+(TosVersion&0x0f), TosAddress, STMemory_ReadWord(TosAddress+28)>>1,
677: (STMemory_ReadWord(TosAddress+28)&1)?"PAL":"NTSC");
678:
679: /* Are we allowed VDI under this TOS? */
680: if (TosVersion == 0x0100 && bUseVDIRes)
681: {
682: /* Warn user */
1.1.1.18 root 683: Log_AlertDlg(LOG_ERROR, "To use extended VDI resolutions, you must select a TOS >= 1.02.");
1.1.1.12 root 684: /* And select non VDI */
1.1.1.16 root 685: bUseVDIRes = ConfigureParams.Screen.bUseExtVdiResolutions = false;
1.1.1.12 root 686: }
687:
688: /* Fix TOS image, modify code for emulation */
1.1.1.19 root 689: if (ConfigureParams.Rom.bPatchTos && !bIsEmuTOS)
690: {
1.1.1.13 root 691: TOS_FixRom();
1.1.1.19 root 692: }
693: else
694: {
695: Log_Printf(LOG_DEBUG, "Skipped TOS patches.\n");
696: }
1.1.1.12 root 697:
698: /* Set connected devices, memory configuration, etc. */
699: STMemory_SetDefaultConfig();
1.1.1.6 root 700:
1.1.1.12 root 701: /* and free loaded image */
702: free(pTosFile);
1.1.1.6 root 703:
1.1.1.16 root 704: bTosImageLoaded = true;
1.1.1.12 root 705: return 0;
1.1 root 706: }
1.1.1.26! root 707:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.