Annotation of hatari/src/tos.c, revision 1.1.1.24

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       root       38: 
1.1.1.14  root       39: bool bIsEmuTOS;
                     40: Uint16 TosVersion;                      /* eg. 0x0100, 0x0102 */
1.1.1.10  root       41: Uint32 TosAddress, TosSize;             /* Address in ST memory and size of TOS image */
1.1.1.16  root       42: bool bTosImageLoaded = false;           /* Successfully loaded a TOS image? */
                     43: bool bRamTosImage;                      /* true if we loaded a RAM TOS image */
1.1.1.23  root       44: unsigned int ConnectedDriveMask = 0x00; /* Bit mask of connected drives, eg 0x7 is A,B,C */
1.1.1.16  root       45: 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       46: 
1.1       root       47: /* Possible TOS file extensions to scan for */
1.1.1.12  root       48: static const char * const pszTosNameExts[] =
1.1.1.6   root       49: {
1.1.1.12  root       50:        ".img",
                     51:        ".rom",
                     52:        ".tos",
                     53:        NULL
1.1       root       54: };
                     55: 
1.1.1.18  root       56: static struct {
                     57:        FILE *file;          /* file pointer to contents of INF file */
                     58:        char prgname[16];    /* TOS name of the program to auto start */
                     59:        const char *infname; /* name of the INF file TOS will try to match */
                     60:        int match_count;     /* how many times INF was matched after boot */
                     61:        int match_max;       /* how many times TOS needs it to be matched */
                     62: } TosAutoStart;
                     63: 
                     64: /* autostarted program name will be added after first '\' character */
                     65: static const char emudesk_inf[] =
                     66: "#E 9A 07\r\n"
                     67: "#Z 01 C:\\@\r\n"
                     68: "#W 00 00 02 06 26 0C 08 C:\\*.*@\r\n"
                     69: "#W 00 00 02 08 26 0C 00 @\r\n"
                     70: "#W 00 00 02 0A 26 0C 00 @\r\n"
                     71: "#W 00 00 02 0D 26 0C 00 @\r\n"
                     72: "#M 00 00 01 FF A DISK A@ @\r\n"
                     73: "#M 01 00 01 FF B DISK B@ @\r\n"
                     74: "#M 02 00 01 FF C DISK C@ @\r\n"
                     75: "#F FF 28 @ *.*@\r\n"
                     76: "#D FF 02 @ *.*@\r\n"
                     77: "#G 08 FF *.APP@ @\r\n"
                     78: "#G 08 FF *.PRG@ @\r\n"
                     79: "#P 08 FF *.TTP@ @\r\n"
                     80: "#F 08 FF *.TOS@ @\r\n"
                     81: "#T 00 03 03 FF   TRASH@ @\r\n";
                     82: 
                     83: static const char desktop_inf[] =
                     84: "#a000000\r\n"
                     85: "#b001000\r\n"
                     86: "#c7770007000600070055200505552220770557075055507703111302\r\n"
                     87: "#d\r\n"
                     88: "#Z 01 C:\\@\r\n"
                     89: "#E D8 11\r\n"
                     90: "#W 00 00 10 01 17 17 13 C:\\*.*@\r\n"
                     91: "#W 00 00 08 0B 1D 0D 00 @\r\n"
                     92: "#W 00 00 0A 0F 1A 09 00 @\r\n"
                     93: "#W 00 00 0E 01 1A 09 00 @\r\n"
                     94: "#M 00 00 05 FF A DISK A@ @\r\n"
                     95: "#M 00 01 05 FF B DISK B@ @\r\n"
                     96: "#M 00 02 05 FF C DISK C@ @\r\n"
                     97: "#T 00 03 02 FF   TRASH@ @\r\n"
                     98: "#F FF 04   @ *.*@\r\n"
                     99: "#D FF 01   @ *.*@\r\n"
                    100: "#P 03 04   @ *.*@\r\n"
                    101: "#G 03 FF   *.APP@ @\r\n"
                    102: "#G 03 FF   *.PRG@ @\r\n"
                    103: "#P 03 FF   *.TTP@ @\r\n"
                    104: "#F 03 04   *.TOS@ @\r\n";
1.1       root      105: 
1.1.1.6   root      106: /* Flags that define if a TOS patch should be applied */
                    107: enum
1.1       root      108: {
1.1.1.12  root      109:        TP_ALWAYS,            /* Patch should alway be applied */
1.1.1.13  root      110:        TP_HDIMAGE_OFF,       /* Apply patch only if HD emulation is off */
1.1.1.22  root      111:        TP_ANTI_STE,          /* Apply patch only if running on plain ST */
1.1.1.24! root      112:        TP_ANTI_PMMU,         /* Apply patch only if no PMMU is available */
        !           113:        TP_FIX_060,           /* Apply patch only if CPU is 68060 */
1.1.1.6   root      114: };
1.1.1.3   root      115: 
1.1.1.6   root      116: /* This structure is used for patching the TOS ROMs */
1.1.1.7   root      117: typedef struct
1.1       root      118: {
1.1.1.12  root      119:        Uint16 Version;       /* TOS version number */
                    120:        Sint16 Country;       /* TOS country code: -1 if it does not matter, 0=US, 1=Germany, 2=France, etc. */
                    121:        const char *pszName;  /* Name of the patch */
                    122:        int Flags;            /* When should the patch be applied? (see enum above) */
                    123:        Uint32 Address;       /* Where the patch should be applied */
                    124:        Uint32 OldData;       /* Expected first 4 old bytes */
                    125:        Uint32 Size;          /* Length of the patch */
                    126:        const void *pNewData; /* Pointer to the new bytes */
1.1.1.6   root      127: } TOS_PATCH;
                    128: 
1.1.1.10  root      129: static const char pszDmaBoot[] = "boot from DMA bus";
1.1.1.13  root      130: static const char pszMouse[] = "big resolutions mouse driver";
1.1.1.10  root      131: static const char pszRomCheck[] = "ROM checksum";
                    132: static const char pszNoSteHw[] = "disable STE hardware access";
1.1.1.12  root      133: static const char pszNoPmmu[] = "disable PMMU access";
1.1.1.13  root      134: static const char pszHwDisable[] = "disable hardware access";
1.1.1.24! root      135: static const char pszFix060[] = "replace code for 68060";
        !           136: static const char pszFalconExtraRAM[] = "enable extra TT RAM on Falcon";
1.1.1.6   root      137: 
1.1.1.9   root      138: //static Uint8 pRtsOpcode[] = { 0x4E, 0x75 };  /* 0x4E75 = RTS */
1.1.1.10  root      139: static const Uint8 pNopOpcodes[] = { 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71,
1.1.1.6   root      140:         0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71,
1.1.1.12  root      141:         0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71, 0x4E, 0x71 };  /* 0x4E71 = NOP */
1.1.1.10  root      142: static const Uint8 pMouseOpcode[] = { 0xD3, 0xC1 };  /* "ADDA.L D1,A1" (instead of "ADDA.W D1,A1") */
1.1.1.13  root      143: static const Uint8 pRomCheckOpcode206[] = { 0x60, 0x00, 0x00, 0x98 };  /* BRA $e00894 */
                    144: static const Uint8 pRomCheckOpcode306[] = { 0x60, 0x00, 0x00, 0xB0 };  /* BRA $e00886 */
                    145: static const Uint8 pRomCheckOpcode404[] = { 0x60, 0x00, 0x00, 0x94 };  /* BRA $e00746 */
1.1.1.10  root      146: static const Uint8 pBraOpcode[] = { 0x60 };  /* 0x60XX = BRA */
1.1       root      147: 
1.1.1.24! root      148: static const Uint8 p060Pmove1[] = {    /* replace PMOVE */
        !           149:        0x70, 0x0c,                     /* moveq #12,d0 */
        !           150:        0x42, 0x30, 0x08, 0x00,         /* loop: clr.b 0,(d0,a0) */
        !           151:        0x55, 0x40,                     /* subq  #2,d0 */
        !           152:        0x4a, 0x40,                     /* tst.w d0 */
        !           153:        0x66, 0xf6,                     /* bne.s loop */
        !           154: };
        !           155: static const Uint8 p060Pmove2[] = {            /* replace PMOVE */
        !           156:        0x41, 0xf8, 0xfa, 0x26,                 /* lea    0xfffffa26.w,a0 */
        !           157:        0x20, 0xfc, 0x00, 0x00, 0x00, 0x88,     /* move.l #$00000088,(a0)+ */
        !           158:        0x20, 0xbc, 0x00, 0x01, 0x00, 0x05,     /* move.l #$00010005,(a0) */
        !           159:        0x4a, 0x38, 0x0a, 0x87                  /* tst.b  $a87.w */
        !           160: };
        !           161: static const Uint8 p060Pmove3_1[] = {          /* replace PMOVE */
        !           162:        0x4e, 0xb9, 0x00, 0xe7, 0xf0, 0x00,     /* jsr     $e7f000 */
        !           163:        0x4e, 0x71                              /* nop */
        !           164: };
        !           165: static const Uint8 p060Pmove3_2[] = {          /* replace PMOVE $28(a2),d7 */
        !           166: 
        !           167:        0x00, 0x7c, 0x07, 0x00,                 /* ori       #$700,sr */
        !           168:        0x1e, 0x2a, 0x00, 0x28,                 /* move.b    $28(a2),d7 */
        !           169:        0xe1, 0x4f,                             /* lsl.w     #8,d7 */
        !           170:        0x1e, 0x2a, 0x00, 0x2a,                 /* move.b    $2a(a2),d7 */
        !           171:        0x48, 0x47,                             /* swap      d7 */
        !           172:        0x1e, 0x2a, 0x00, 0x2c,                 /* move.b    $2c(a2),d7 */
        !           173:        0xe1, 0x4f,                             /* lsl.w     #8,d7 */
        !           174:        0x1e, 0x2a, 0x00, 0x2e,                 /* move.b    $2e(a2),d7 */
        !           175:        0x4e, 0x75                              /* rts */
        !           176: };
        !           177: 
        !           178: static const Uint8 pFalconExtraRAM_1[] = {
        !           179:        0x4e, 0xb9, 0x00, 0xe7, 0xf1, 0x00      /* jsr       $e7f100 */
        !           180: };
        !           181: static const Uint8 pFalconExtraRAM_2[] = {     /* call maddalt() to declare the extra RAM */
        !           182:        0x20, 0x38, 0x05, 0xa4,                 /* move.l    $05a4.w,d0 */
        !           183:        0x67, 0x18,                             /* beq.s     $ba2d2 */
        !           184:        0x04, 0x80, 0x01, 0x00, 0x00, 0x00,     /* subi.l    #$1000000,d0 */
        !           185:        0x2f, 0x00,                             /* move.l    d0,-(sp) */
        !           186:        0x2f, 0x3c, 0x01, 0x00, 0x00, 0x00,     /* move.l    #$1000000,-(sp) */
        !           187:        0x3f, 0x3c, 0x00, 0x14,                 /* move.w    #$14,-(sp) */
        !           188:        0x4e, 0x41,                             /* trap      #1 */
        !           189:        0x4f, 0xef, 0x00, 0x0a,                 /* lea       $a(sp),sp */
        !           190:        0x70, 0x03,                             /* moveq     #3,d0 */
        !           191:        0x4e, 0xf9, 0x00, 0xe0, 0x0b, 0xd2      /* jmp       $e00bd2 */
        !           192: };
        !           193: 
1.1.1.6   root      194: /* The patches for the TOS: */
1.1.1.10  root      195: static const TOS_PATCH TosPatches[] =
1.1.1.6   root      196: {
1.1.1.13  root      197:   { 0x100, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xFC03D6, 0x610000D0, 4, pNopOpcodes }, /* BSR $FC04A8 */
1.1.1.6   root      198: 
1.1.1.13  root      199:   { 0x102, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xFC0472, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $FC0558 */
1.1.1.6   root      200:   { 0x102, 0, pszMouse, TP_ALWAYS, 0xFD0030, 0xD2C147F9, 2, pMouseOpcode },
                    201:   { 0x102, 1, pszMouse, TP_ALWAYS, 0xFD008A, 0xD2C147F9, 2, pMouseOpcode },
                    202:   { 0x102, 2, pszMouse, TP_ALWAYS, 0xFD00A8, 0xD2C147F9, 2, pMouseOpcode },
                    203:   { 0x102, 3, pszMouse, TP_ALWAYS, 0xFD0030, 0xD2C147F9, 2, pMouseOpcode },
                    204:   { 0x102, 6, pszMouse, TP_ALWAYS, 0xFCFEF0, 0xD2C147F9, 2, pMouseOpcode },
                    205:   { 0x102, 8, pszMouse, TP_ALWAYS, 0xFCFEFE, 0xD2C147F9, 2, pMouseOpcode },
                    206: 
1.1.1.13  root      207:   { 0x104, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xFC0466, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $FC054C */
1.1.1.6   root      208: 
1.1.1.13  root      209:   { 0x106, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xE00576, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $E0065C */
1.1.1.10  root      210: 
1.1.1.13  root      211:   { 0x162, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xE00576, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $E0065C */
1.1.1.10  root      212: 
1.1.1.13  root      213:   { 0x205, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xE006AE, 0x610000E4, 4, pNopOpcodes }, /* BSR.W $E00794 */
1.1.1.6   root      214:   /* An unpatched TOS 2.05 only works on STEs, so apply some anti-STE patches... */
1.1.1.11  root      215:   { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00096, 0x42788900, 4, pNopOpcodes }, /* CLR.W $FFFF8900 */
                    216:   { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE0009E, 0x31D88924, 4, pNopOpcodes }, /* MOVE.W (A0)+,$FFFF8924 */
                    217:   { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE000A6, 0x09D10AA9, 28, pNopOpcodes },
                    218:   { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE003A0, 0x30389200, 4, pNopOpcodes }, /* MOVE.W $ffff9200,D0 */
                    219:   { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE004EA, 0x61000CBC, 4, pNopOpcodes },
                    220:   { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00508, 0x61000C9E, 4, pNopOpcodes },
                    221:   { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE007A0, 0x631E2F3C, 1, pBraOpcode },
                    222:   { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00928, 0x10388901, 4, pNopOpcodes }, /* MOVE.B $FFFF8901,D0 */
                    223:   { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00944, 0xB0388901, 4, pNopOpcodes }, /* CMP.B $FFFF8901,D0 */
                    224:   { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00950, 0x67024601, 1, pBraOpcode },
                    225:   { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00968, 0x61000722, 4, pNopOpcodes },
                    226:   { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00CF2, 0x1038820D, 4, pNopOpcodes }, /* MOVE.B $FFFF820D,D0 */
                    227:   { 0x205, -1, pszNoSteHw, TP_ANTI_STE, 0xE00E00, 0x1038820D, 4, pNopOpcodes }, /* MOVE.B $FFFF820D,D0 */
                    228:   { 0x205, 0, pszNoSteHw, TP_ANTI_STE, 0xE03038, 0x31C0860E, 4, pNopOpcodes },
                    229:   { 0x205, 0, pszNoSteHw, TP_ANTI_STE, 0xE034A8, 0x31C0860E, 4, pNopOpcodes },
                    230:   { 0x205, 0, pszNoSteHw, TP_ANTI_STE, 0xE034F6, 0x31E90002, 6, pNopOpcodes },
1.1.1.6   root      231: 
                    232:   /* E007FA  MOVE.L  #$1FFFE,D7  Run checksums on 2xROMs (skip) */
                    233:   /* Checksum is total of TOS ROM image, but get incorrect results */
                    234:   /* as we've changed bytes in the ROM! So, just skip anyway! */
1.1.1.13  root      235:   { 0x206, -1, pszRomCheck, TP_ALWAYS, 0xE007FA, 0x2E3C0001, 4, pRomCheckOpcode206 },
                    236:   { 0x206, -1, pszDmaBoot, TP_HDIMAGE_OFF, 0xE00898, 0x610000E0, 4, pNopOpcodes }, /* BSR.W $E0097A */
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.12  root      241: 
1.1.1.24! root      242:   { 0x400, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE00064, 0xF0394000, 24, pNopOpcodes }, /* pmove : TC=0 TT0=0 TT1=0 -> disable MMU */
1.1.1.22  root      243:   { 0x400, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE0148A, 0xF0394C00, 32, pNopOpcodes },
1.1.1.24! root      244:   { 0x400, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE03948, 0xF0394000, 24, pNopOpcodes }, /* pmove : TC=0 TT0=0 TT1=0 -> disable MMU */
1.1.1.13  root      245:   { 0x400, -1, pszRomCheck, TP_ALWAYS, 0xE00686, 0x2E3C0007, 4, pRomCheckOpcode404 },
                    246: 
1.1.1.24! root      247:   { 0x401, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE0006A, 0xF0394000, 24, pNopOpcodes }, /* pmove : TC=0 TT0=0 TT1=0 -> disable MMU */
1.1.1.22  root      248:   { 0x401, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE014A8, 0xF0394C00, 32, pNopOpcodes },
1.1.1.24! root      249:   { 0x401, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE03946, 0xF0394000, 24, pNopOpcodes }, /* pmove : TC=0 TT0=0 TT1=0 -> disable MMU */
1.1.1.13  root      250:   { 0x401, -1, pszRomCheck, TP_ALWAYS, 0xE006A6, 0x2E3C0007, 4, pRomCheckOpcode404 },
                    251: 
1.1.1.24! root      252:   { 0x402, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE0006A, 0xF0394000, 24, pNopOpcodes }, /* pmove : TC=0 TT0=0 TT1=0 -> disable MMU */
1.1.1.22  root      253:   { 0x402, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE014A8, 0xF0394C00, 32, pNopOpcodes },
1.1.1.24! root      254:   { 0x402, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE03946, 0xF0394000, 24, pNopOpcodes }, /* pmove : TC=0 TT0=0 TT1=0 -> disable MMU */
1.1.1.13  root      255:   { 0x402, -1, pszRomCheck, TP_ALWAYS, 0xE006A6, 0x2E3C0007, 4, pRomCheckOpcode404 },
                    256: 
1.1.1.24! root      257:   { 0x404, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE0006A, 0xF0394000, 24, pNopOpcodes }, /* pmove : TC=0 TT0=0 TT1=0 -> disable MMU */
        !           258:   { 0x404, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE014E6, 0xF0394C00, 32, pNopOpcodes }, /* pmove : CRP=80000002 00000700 TC=80f04445 TT0=017e8107 TT1=807e8507 -> */
        !           259:   { 0x404, -1, pszNoPmmu, TP_ANTI_PMMU, 0xE039A0, 0xF0394000, 24, pNopOpcodes }, /* pmove : TC=0 TT0=0 TT1=0 -> disable MMU */
1.1.1.13  root      260:   { 0x404, -1, pszRomCheck, TP_ALWAYS, 0xE006B0, 0x2E3C0007, 4, pRomCheckOpcode404 },
1.1.1.23  root      261:   { 0x404, -1, pszDmaBoot, TP_ALWAYS, 0xE01C9E, 0x62FC31FC, 2, pNopOpcodes },  /* Just a delay */
                    262:   { 0x404, -1, pszDmaBoot, TP_ALWAYS, 0xE01CB2, 0x62FC31FC, 2, pNopOpcodes },  /* Just a delay */
1.1.1.24! root      263:   { 0x404, -1, pszFix060, TP_FIX_060, 0xE025E2, 0x01C80000, 12, p060Pmove1 },
        !           264:   { 0x404, -1, pszFix060, TP_FIX_060, 0xE02632, 0x41F8FA01, 20, p060Pmove2 },
        !           265:   { 0x404, -1, pszFix060, TP_FIX_060, 0xE02B1E, 0x007c0700, 8, p060Pmove3_1 },
        !           266:   { 0x404, -1, pszFix060, TP_FIX_060, 0xE7F000, 0xFFFFFFFF, sizeof( p060Pmove3_2 ), p060Pmove3_2 },
        !           267:   { 0x404, -1, pszFalconExtraRAM, TP_ALWAYS, 0xE0096E, 0x70036100, 6, pFalconExtraRAM_1 },
        !           268:   { 0x404, -1, pszFalconExtraRAM, TP_ALWAYS, 0xE7F100, 0xFFFFFFFF, sizeof( pFalconExtraRAM_2 ), pFalconExtraRAM_2 },
1.1.1.13  root      269: 
1.1.1.22  root      270:   { 0x492, -1, pszNoPmmu, TP_ANTI_PMMU, 0x00F946, 0xF0394000, 24, pNopOpcodes },
                    271:   { 0x492, -1, pszNoPmmu, TP_ANTI_PMMU, 0x01097A, 0xF0394C00, 32, pNopOpcodes },
                    272:   { 0x492, -1, pszNoPmmu, TP_ANTI_PMMU, 0x012E04, 0xF0394000, 24, pNopOpcodes },
1.1.1.13  root      273: 
1.1.1.6   root      274:   { 0, 0, NULL, 0, 0, 0, 0, NULL }
                    275: };
1.1       root      276: 
                    277: 
                    278: 
1.1.1.6   root      279: /*-----------------------------------------------------------------------*/
1.1.1.13  root      280: /**
                    281:  * Save/Restore snapshot of local variables ('MemorySnapShot_Store' handles type)
                    282:  */
1.1.1.14  root      283: void TOS_MemorySnapShot_Capture(bool bSave)
1.1.1.6   root      284: {
1.1.1.12  root      285:        /* Save/Restore details */
                    286:        MemorySnapShot_Store(&TosVersion, sizeof(TosVersion));
                    287:        MemorySnapShot_Store(&TosAddress, sizeof(TosAddress));
                    288:        MemorySnapShot_Store(&TosSize, sizeof(TosSize));
                    289:        MemorySnapShot_Store(&ConnectedDriveMask, sizeof(ConnectedDriveMask));
                    290:        MemorySnapShot_Store(&nNumDrives, sizeof(nNumDrives));
1.1       root      291: }
                    292: 
1.1.1.3   root      293: 
                    294: /*-----------------------------------------------------------------------*/
1.1.1.13  root      295: /**
                    296:  * Patch TOS to skip some TOS setup code which we don't support/need.
                    297:  *
                    298:  * So, how do we find these addresses when we have no commented source code?
                    299:  * - For the "Boot from DMA bus" patch:
                    300:  *   Scan at start of rom for tst.w $482, boot call will be just above it.
                    301:  */
1.1.1.6   root      302: static void TOS_FixRom(void)
1.1       root      303: {
1.1.1.12  root      304:        int nGoodPatches, nBadPatches;
                    305:        short TosCountry;
                    306:        const TOS_PATCH *pPatch;
                    307: 
1.1.1.13  root      308:        /* We can't patch RAM TOS images (yet) */
                    309:        if (bRamTosImage && TosVersion != 0x0492)
1.1.1.12  root      310:        {
                    311:                Log_Printf(LOG_DEBUG, "Detected RAM TOS image, skipping TOS patches.\n");
                    312:                return;
                    313:        }
                    314: 
                    315:        nGoodPatches = nBadPatches = 0;
                    316:        TosCountry = STMemory_ReadWord(TosAddress+28)>>1;   /* TOS country code */
                    317:        pPatch = TosPatches;
                    318: 
                    319:        /* Apply TOS patches: */
                    320:        while (pPatch->Version)
                    321:        {
                    322:                /* Only apply patches that suit to the actual TOS  version: */
                    323:                if (pPatch->Version == TosVersion
                    324:                    && (pPatch->Country == TosCountry || pPatch->Country == -1))
                    325:                {
1.1.1.22  root      326: #if ENABLE_WINUAE_CPU
                    327:                        bool use_mmu = ConfigureParams.System.bMMU;
                    328: #else
                    329:                        bool use_mmu = false;
                    330: #endif
1.1.1.12  root      331:                        /* Make sure that we really patch the right place by comparing data: */
                    332:                        if(STMemory_ReadLong(pPatch->Address) == pPatch->OldData)
                    333:                        {
                    334:                                /* Only apply the patch if it is really needed: */
1.1.1.13  root      335:                                if (pPatch->Flags == TP_ALWAYS
1.1.1.19  root      336:                                    || (pPatch->Flags == TP_HDIMAGE_OFF && !ACSI_EMU_ON
                    337:                                        && !ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage
                    338:                                        && ConfigureParams.System.bFastBoot)
                    339:                                    || (pPatch->Flags == TP_ANTI_STE
1.1.1.22  root      340:                                        && ConfigureParams.System.nMachineType == MACHINE_ST)
                    341:                                    || (pPatch->Flags == TP_ANTI_PMMU && !use_mmu)
1.1.1.24! root      342:                                    || (pPatch->Flags == TP_FIX_060 && ConfigureParams.System.nCpuLevel > 4)
1.1.1.22  root      343:                                   )
1.1.1.12  root      344:                                {
                    345:                                        /* Now we can really apply the patch! */
1.1.1.13  root      346:                                        Log_Printf(LOG_DEBUG, "Applying TOS patch '%s'.\n", pPatch->pszName);
                    347:                                        memcpy(&RomMem[pPatch->Address], pPatch->pNewData, pPatch->Size);
1.1.1.12  root      348:                                        nGoodPatches += 1;
                    349:                                }
                    350:                                else
                    351:                                {
1.1.1.13  root      352:                                        Log_Printf(LOG_DEBUG, "Skipped patch '%s'.\n", pPatch->pszName);
1.1.1.12  root      353:                                }
                    354:                        }
                    355:                        else
                    356:                        {
                    357:                                Log_Printf(LOG_DEBUG, "Failed to apply TOS patch '%s' at %x (expected %x, found %x).\n",
                    358:                                           pPatch->pszName, pPatch->Address, pPatch->OldData, STMemory_ReadLong(pPatch->Address));
                    359:                                nBadPatches += 1;
                    360:                        }
                    361:                }
                    362:                pPatch += 1;
                    363:        }
1.1.1.3   root      364: 
1.1.1.12  root      365:        Log_Printf(LOG_DEBUG, "Applied %i TOS patches, %i patches failed.\n",
                    366:                   nGoodPatches, nBadPatches);
1.1.1.6   root      367: }
                    368: 
                    369: 
                    370: /*-----------------------------------------------------------------------*/
1.1.1.13  root      371: /**
1.1.1.18  root      372:  * Set name of program that will be auto started after TOS boots.
                    373:  * Supported only from TOS 1.04 forward.
                    374:  */
                    375: void TOS_AutoStart(const char *prgname)
                    376: {
                    377:        Str_Filename2TOSname(prgname, TosAutoStart.prgname);
                    378: }
                    379: 
                    380: /*-----------------------------------------------------------------------*/
                    381: /**
                    382:  * Create a temporary desktop.inf file which will start autostart program.
                    383:  * This needs to be re-created on each boot in case user changed TOS version.
                    384:  */
                    385: static void TOS_CreateAutoInf(void)
                    386: {
                    387:        const char *contents, *infname, *prgname;
                    388:        int offset, size, max;
                    389:        FILE *fp;
                    390: 
                    391:        /* in case TOS didn't for some reason close it on previous boot */
                    392:        TOS_AutoStartClose(TosAutoStart.file);
                    393: 
                    394:        prgname = TosAutoStart.prgname;
                    395:        /* autostart not enabled? */
                    396:        if (!*prgname)
                    397:                return;
                    398: 
                    399:        /* autostart not supported? */
                    400:        if (TosVersion < 0x0104)
                    401:        {
                    402:                Log_Printf(LOG_WARN, "Only TOS versions >= 1.04 support autostarting!\n");
                    403:                return;
                    404:        }
                    405: 
                    406:        if (bIsEmuTOS)
                    407:        {
                    408:                infname = "C:\\EMUDESK.INF";
                    409:                size = sizeof(emudesk_inf);
                    410:                contents = emudesk_inf;
                    411:                max = 1;
                    412:        } else {
                    413:                /* need to match file TOS searches first */
                    414:                if (TosVersion >= 0x0200)
                    415:                        infname = "NEWDESK.INF";
                    416:                else
                    417:                        infname = "DESKTOP.INF";
                    418:                size = sizeof(desktop_inf);
                    419:                contents = desktop_inf;
                    420:                max = 1;
                    421:        }
                    422:        /* infname needs to be exactly the same string that given
                    423:         * TOS version gives for GEMDOS to find.
                    424:         */
                    425:        TosAutoStart.infname = infname;
                    426:        TosAutoStart.match_max = max;
                    427:        TosAutoStart.match_count = 0;
                    428: 
                    429:        /* find where to insert the program name */
                    430:        for (offset = 0; offset < size; )
                    431:        {
                    432:                if (contents[offset++] == '\\')
                    433:                        break;
                    434:        }
                    435:        assert(offset < size);
                    436: 
                    437:        /* create the autostart file */
                    438:        fp = tmpfile();
                    439:        if (!(fp
                    440:              && fwrite(contents, offset, 1, fp) == 1
                    441:              && fwrite(prgname, strlen(prgname), 1, fp) == 1
                    442:              && fwrite(contents+offset, size-offset-1, 1, fp) == 1
                    443:              && fseek(fp, 0, SEEK_SET) == 0))
                    444:        {
                    445:                if (fp)
                    446:                        fclose(fp);
                    447:                Log_Printf(LOG_ERROR, "Failed to create autostart file for '%s'!\n", TosAutoStart.prgname);
                    448:                return;
                    449:        }
                    450:        TosAutoStart.file = fp;
                    451:        Log_Printf(LOG_WARN, "Virtual autostart file '%s' created for '%s'.\n", infname, prgname);
                    452: }
                    453: 
                    454: /*-----------------------------------------------------------------------*/
                    455: /**
                    456:  * If given name matches autostart file, return its handle, NULL otherwise
                    457:  */
                    458: FILE *TOS_AutoStartOpen(const char *filename)
                    459: {
                    460:        if (TosAutoStart.file && strcmp(filename, TosAutoStart.infname) == 0)
                    461:        {
1.1.1.23  root      462:                /* whether to "autostart" also exception debugging? */
                    463:                if (ConfigureParams.Log.nExceptionDebugMask & EXCEPT_AUTOSTART)
                    464:                {
                    465:                        ExceptionDebugMask = ConfigureParams.Log.nExceptionDebugMask & ~EXCEPT_AUTOSTART;
                    466:                        fprintf(stderr, "Exception debugging enabled (0x%x).\n", ExceptionDebugMask);
                    467:                }
1.1.1.18  root      468:                Log_Printf(LOG_WARN, "Autostart file '%s' for '%s' matched.\n", filename, TosAutoStart.prgname);
                    469:                return TosAutoStart.file;
                    470:        }
                    471:        return NULL;
                    472: }
                    473: 
                    474: /*-----------------------------------------------------------------------*/
                    475: /**
                    476:  * If given handle matches autostart file, close it and return true,
                    477:  * false otherwise.
                    478:  */
                    479: bool TOS_AutoStartClose(FILE *fp)
                    480: {
                    481:        if (fp && fp == TosAutoStart.file)
                    482:        {
                    483:                if (++TosAutoStart.match_count >= TosAutoStart.match_max)
                    484:                {
                    485:                        /* Remove autostart INF file after TOS has
                    486:                         * read it enough times to do autostarting.
                    487:                         * Otherwise user may try change desktop settings
                    488:                         * and save them, but they would be lost.
                    489:                         */
                    490:                        fclose(TosAutoStart.file);
                    491:                        TosAutoStart.file = NULL;
                    492:                        Log_Printf(LOG_WARN, "Autostart file removed.\n");
                    493:                }
                    494:                return true;
                    495:        }
                    496:        return false;
                    497: }
                    498: 
                    499: 
                    500: /*-----------------------------------------------------------------------*/
                    501: /**
1.1.1.13  root      502:  * Assert that TOS version matches the machine type and change the system
                    503:  * configuration if necessary.
                    504:  * For example TOSes 1.06 and 1.62 are for the STE ONLY and so don't run
                    505:  * on a real ST, TOS 3.0x is TT only and TOS 4.x is Falcon only.
                    506:  * These TOS version access illegal memory addresses on machine they were
                    507:  * not designed for and so cause the OS to lock up. So, if user selects one
                    508:  * of these, switch to the appropriate machine type.
                    509:  */
                    510: static void TOS_CheckSysConfig(void)
                    511: {
1.1.1.22  root      512:        int oldCpuLevel = ConfigureParams.System.nCpuLevel;
1.1.1.21  root      513:        MACHINETYPE oldMachineType = ConfigureParams.System.nMachineType;
1.1.1.22  root      514:        if (((TosVersion == 0x0106 || TosVersion == 0x0162) && ConfigureParams.System.nMachineType != MACHINE_STE)
                    515:            || (TosVersion == 0x0162 && ConfigureParams.System.nCpuLevel != 0))
1.1.1.13  root      516:        {
1.1.1.14  root      517:                Log_AlertDlg(LOG_ERROR, "TOS versions 1.06 and 1.62 are for Atari STE only.\n"
1.1.1.13  root      518:                             " ==> Switching to STE mode now.\n");
                    519:                IoMem_UnInit();
                    520:                ConfigureParams.System.nMachineType = MACHINE_STE;
1.1.1.18  root      521:                ClocksTimings_InitMachine ( ConfigureParams.System.nMachineType );
1.1.1.13  root      522:                IoMem_Init();
1.1.1.18  root      523:                ConfigureParams.System.nCpuFreq = 8;
1.1.1.17  root      524:                ConfigureParams.System.nCpuLevel = 0;
1.1.1.13  root      525:        }
                    526:        else if ((TosVersion & 0x0f00) == 0x0300 && ConfigureParams.System.nMachineType != MACHINE_TT)
                    527:        {
1.1.1.14  root      528:                Log_AlertDlg(LOG_ERROR, "TOS versions 3.0x are for Atari TT only.\n"
1.1.1.13  root      529:                             " ==> Switching to TT mode now.\n");
                    530:                IoMem_UnInit();
                    531:                ConfigureParams.System.nMachineType = MACHINE_TT;
1.1.1.18  root      532:                ClocksTimings_InitMachine ( ConfigureParams.System.nMachineType );
1.1.1.13  root      533:                IoMem_Init();
1.1.1.18  root      534:                ConfigureParams.System.nCpuFreq = 32;
1.1.1.13  root      535:                ConfigureParams.System.nCpuLevel = 3;
                    536:        }
                    537:        else if ((TosVersion & 0x0f00) == 0x0400 && ConfigureParams.System.nMachineType != MACHINE_FALCON)
                    538:        {
1.1.1.14  root      539:                Log_AlertDlg(LOG_ERROR, "TOS versions 4.x are for Atari Falcon only.\n"
1.1.1.13  root      540:                             " ==> Switching to Falcon mode now.\n");
                    541:                IoMem_UnInit();
                    542:                ConfigureParams.System.nMachineType = MACHINE_FALCON;
1.1.1.18  root      543:                ClocksTimings_InitMachine ( ConfigureParams.System.nMachineType );
                    544: #if ENABLE_DSP_EMU
                    545:                ConfigureParams.System.nDSPType = DSP_TYPE_EMU;
                    546:                DSP_Init();
                    547: #endif
1.1.1.13  root      548:                IoMem_Init();
1.1.1.18  root      549:                ConfigureParams.System.nCpuFreq = 16;
1.1.1.13  root      550:                ConfigureParams.System.nCpuLevel = 3;
                    551:        }
1.1.1.19  root      552:        else if (TosVersion <= 0x0104 &&
                    553:                 (ConfigureParams.System.nCpuLevel > 0 || ConfigureParams.System.nMachineType != MACHINE_ST))
1.1.1.17  root      554:        {
1.1.1.19  root      555:                Log_AlertDlg(LOG_ERROR, "TOS versions <= 1.4 work only in\n"
                    556:                             "ST mode and with a 68000 CPU.\n"
1.1.1.22  root      557:                             " ==> Switching to ST mode with 68000 now.\n");
1.1.1.17  root      558:                IoMem_UnInit();
                    559:                ConfigureParams.System.nMachineType = MACHINE_ST;
1.1.1.18  root      560:                ClocksTimings_InitMachine ( ConfigureParams.System.nMachineType );
1.1.1.17  root      561:                IoMem_Init();
1.1.1.18  root      562:                ConfigureParams.System.nCpuFreq = 8;
1.1.1.17  root      563:                ConfigureParams.System.nCpuLevel = 0;
                    564:        }
1.1.1.13  root      565:        else if ((TosVersion < 0x0300 && ConfigureParams.System.nMachineType == MACHINE_FALCON)
                    566:                 || (TosVersion < 0x0200 && ConfigureParams.System.nMachineType == MACHINE_TT))
                    567:        {
1.1.1.19  root      568:                Log_AlertDlg(LOG_ERROR, "This TOS version does not work in TT/Falcon mode.\n"
1.1.1.13  root      569:                             " ==> Switching to STE mode now.\n");
                    570:                IoMem_UnInit();
                    571:                ConfigureParams.System.nMachineType = MACHINE_STE;
1.1.1.18  root      572:                ClocksTimings_InitMachine ( ConfigureParams.System.nMachineType );
1.1.1.13  root      573:                IoMem_Init();
1.1.1.18  root      574:                ConfigureParams.System.nCpuFreq = 8;
1.1.1.17  root      575:                ConfigureParams.System.nCpuLevel = 0;
1.1.1.13  root      576:        }
1.1.1.22  root      577:        else if ((TosVersion & 0x0f00) == 0x0400 && ConfigureParams.System.nCpuLevel < 2)
1.1.1.14  root      578:        {
1.1.1.22  root      579:                Log_AlertDlg(LOG_ERROR, "TOS versions 4.x require a CPU >= 68020.\n"
1.1.1.14  root      580:                             " ==> Switching to 68020 mode now.\n");
                    581:                ConfigureParams.System.nCpuLevel = 2;
1.1.1.21  root      582:        }
1.1.1.22  root      583:        else if ((TosVersion & 0x0f00) == 0x0300 && ConfigureParams.System.nCpuLevel < 3)
                    584:        {
                    585:                Log_AlertDlg(LOG_ERROR, "TOS versions 3.0x require a CPU >= 68030.\n"
                    586:                             " ==> Switching to 68030 mode now.\n");
                    587:                ConfigureParams.System.nCpuLevel = 3;
                    588:        }
1.1.1.21  root      589:        /* TOS version triggered changes? */
                    590:        if (ConfigureParams.System.nMachineType != oldMachineType)
                    591:        {
                    592: #if ENABLE_WINUAE_CPU
                    593:                if (ConfigureParams.System.nMachineType == MACHINE_TT)
                    594:                {
                    595:                        ConfigureParams.System.bCompatibleFPU = true;
                    596:                        ConfigureParams.System.n_FPUType = FPU_68882;
                    597:                } else {
                    598:                        ConfigureParams.System.n_FPUType = FPU_NONE;    /* TODO: or leave it as-is? */
                    599:                }
1.1.1.22  root      600:                if (TosVersion < 0x200)
                    601:                {
                    602:                        ConfigureParams.System.bAddressSpace24 = true;
                    603:                        ConfigureParams.System.bMMU = false;
                    604:                }
1.1.1.21  root      605: #endif
1.1.1.18  root      606:                M68000_CheckCpuSettings();
1.1.1.14  root      607:        }
1.1.1.22  root      608:        else if (ConfigureParams.System.nCpuLevel != oldCpuLevel)
                    609:        {
                    610:                M68000_CheckCpuSettings();
                    611:        }
1.1.1.19  root      612:        if (TosVersion < 0x0104 && ConfigureParams.HardDisk.bUseHardDiskDirectories)
                    613:        {
                    614:                Log_AlertDlg(LOG_ERROR, "Please use at least TOS v1.04 for the HD directory emulation "
                    615:                             "(all required GEMDOS functionality isn't completely emulated for this TOS version).");
                    616:        }
1.1.1.13  root      617: }
                    618: 
                    619: 
                    620: /*-----------------------------------------------------------------------*/
                    621: /**
1.1.1.20  root      622:  * Load TOS Rom image file into ST memory space and fix image so it can be
                    623:  * emulated correctly.  Pre TOS 1.06 are loaded at 0xFC0000 and later ones
                    624:  * at 0xE00000.
1.1.1.13  root      625:  */
1.1.1.6   root      626: int TOS_LoadImage(void)
                    627: {
1.1.1.12  root      628:        Uint8 *pTosFile = NULL;
                    629:        long nFileSize;
1.1.1.6   root      630: 
1.1.1.16  root      631:        bTosImageLoaded = false;
1.1.1.6   root      632: 
1.1.1.24! root      633:        /* Calculate end of RAM */
        !           634:        if (ConfigureParams.Memory.nMemorySize > 0
        !           635:            && ConfigureParams.Memory.nMemorySize <= 14)
        !           636:                STRamEnd = ConfigureParams.Memory.nMemorySize * 0x100000;
        !           637:        else
        !           638:                STRamEnd = 0x80000;   /* 512 KiB */
        !           639: 
1.1.1.20  root      640:        /* Load TOS image into memory so that we can check its version */
1.1.1.12  root      641:        TosVersion = 0;
1.1.1.13  root      642:        pTosFile = File_Read(ConfigureParams.Rom.szTosImageFileName, &nFileSize, pszTosNameExts);
1.1.1.12  root      643: 
                    644:        if (!pTosFile || nFileSize <= 0)
                    645:        {
                    646:                Log_AlertDlg(LOG_FATAL, "Can not load TOS file:\n'%s'", ConfigureParams.Rom.szTosImageFileName);
1.1.1.24! root      647:                free(pTosFile);
1.1.1.12  root      648:                return -1;
                    649:        }
                    650: 
                    651:        TosSize = nFileSize;
                    652: 
                    653:        /* Check for RAM TOS images first: */
                    654:        if (SDL_SwapBE32(*(Uint32 *)pTosFile) == 0x46FC2700)
                    655:        {
1.1.1.13  root      656:                int nRamTosLoaderSize;
1.1.1.12  root      657:                Log_Printf(LOG_WARN, "Detected a RAM TOS - this will probably not work very well!\n");
                    658:                /* RAM TOS images have a 256 bytes loader function before the real image
1.1.1.13  root      659:                 * starts (34 bytes for TOS 4.92). Since we directly copy the image to the right
                    660:                 * location later, we simply skip this additional header here: */
                    661:                if (SDL_SwapBE32(*(Uint32 *)(pTosFile+34)) == 0x602E0492)
                    662:                        nRamTosLoaderSize = 0x22;
                    663:                else
                    664:                        nRamTosLoaderSize = 0x100;
                    665:                TosSize -= nRamTosLoaderSize;
                    666:                memmove(pTosFile, pTosFile + nRamTosLoaderSize, TosSize);
1.1.1.16  root      667:                bRamTosImage = true;
1.1.1.12  root      668:        }
                    669:        else
                    670:        {
1.1.1.16  root      671:                bRamTosImage = false;
1.1.1.12  root      672:        }
                    673: 
1.1.1.13  root      674:        /* Check for EmuTOS ... (0x45544F53 = 'ETOS') */
                    675:        bIsEmuTOS = (SDL_SwapBE32(*(Uint32 *)&pTosFile[0x2c]) == 0x45544F53);
                    676: 
1.1.1.12  root      677:        /* Now, look at start of image to find Version number and address */
                    678:        TosVersion = SDL_SwapBE16(*(Uint16 *)&pTosFile[2]);
                    679:        TosAddress = SDL_SwapBE32(*(Uint32 *)&pTosFile[8]);
                    680: 
                    681:        /* Check for reasonable TOS version: */
1.1.1.18  root      682:        if (TosVersion == 0x000 && TosSize == 16384)
                    683:        {
                    684:                /* TOS 0.00 was a very early boot loader ROM which could only
                    685:                 * execute a boot sector from floppy disk, which was used in
                    686:                 * the very early STs before a full TOS was available in ROM.
                    687:                 * It's not very useful nowadays, but we support it here, too,
                    688:                 * just for fun. */
                    689:                TosAddress = 0xfc0000;
                    690:        }
1.1.1.24! root      691:        else if (TosVersion < 0x100 || TosVersion >= 0x500 || TosSize > 1024*1024L
        !           692:                 || (TosAddress == 0xfc0000 && TosSize > 224*1024L)
        !           693:                 || (bRamTosImage && TosAddress + TosSize > STRamEnd)
        !           694:                 || (!bRamTosImage && TosAddress != 0xe00000 && TosAddress != 0xfc0000))
1.1.1.12  root      695:        {
                    696:                Log_AlertDlg(LOG_FATAL, "Your TOS image seems not to be a valid TOS ROM file!\n"
                    697:                             "(TOS version %x, address $%x)", TosVersion, TosAddress);
1.1.1.24! root      698:                free(pTosFile);
1.1.1.12  root      699:                return -2;
                    700:        }
                    701: 
1.1.1.13  root      702:        /* Assert that machine type matches the TOS version. Note that EmuTOS can
                    703:         * handle all machine types, so we don't do the system check there: */
                    704:        if (!bIsEmuTOS)
                    705:                TOS_CheckSysConfig();
                    706: 
1.1.1.24! root      707: #if ENABLE_WINUAE_CPU
        !           708:        /* 32-bit addressing is supported only by 680x0, TOS v3, TOS v4 and EmuTOS */
        !           709:        if (ConfigureParams.System.nCpuLevel == 0 || (TosVersion < 0x0300 && !bIsEmuTOS))
        !           710:                ConfigureParams.System.bAddressSpace24 = true;
        !           711: 
        !           712:        else if (ConfigureParams.Memory.nTTRamSize)
        !           713:        {
        !           714:                switch (ConfigureParams.System.nMachineType)
        !           715:                {
        !           716:                case MACHINE_TT:
        !           717:                        if (ConfigureParams.System.bAddressSpace24)
        !           718:                        {
        !           719:                                /* Print a message and force 32 bit addressing (keeping 24 bit with TT RAM would crash TOS) */
        !           720:                                Log_AlertDlg(LOG_ERROR, "Enabling 32-bit addressing for TT-RAM access.\nThis can cause issues in some programs!\n");
        !           721:                                ConfigureParams.System.bAddressSpace24 = false;
        !           722:                        }
        !           723:                        break;
        !           724:                case MACHINE_FALCON:
        !           725:                        if (ConfigureParams.System.bAddressSpace24)
        !           726:                        {
        !           727:                                /* Print a message, but don't force 32 bit addressing as 24 bit addressing is also possible under Falcon */
        !           728:                                /* So, if Falcon is in 24 bit mode, we just don't add TT RAM */
        !           729:                                Log_AlertDlg(LOG_ERROR, "You need to disable 24-bit addressing to use TT-RAM in Falcon mode.\n");
        !           730:                        }
        !           731:                        break;
        !           732:                default:
        !           733:                        break;
        !           734:                }
        !           735:        }
        !           736: #endif
1.1.1.13  root      737: 
                    738:        /* (Re-)Initialize the memory banks: */
                    739:        memory_uninit();
1.1.1.24! root      740:        memory_init(STRamEnd, ConfigureParams.Memory.nTTRamSize*1024*1024, TosAddress);
1.1.1.13  root      741: 
                    742:        /* Clear Upper memory (ROM and IO memory) */
                    743:        memset(&RomMem[0xe00000], 0, 0x200000);
1.1.1.12  root      744: 
1.1.1.24! root      745:        /* Copy loaded image into memory */
        !           746:        if (bRamTosImage)
        !           747:                memcpy(&STRam[TosAddress], pTosFile, TosSize);
        !           748:        else
        !           749:                memcpy(&RomMem[TosAddress], pTosFile, TosSize);
1.1.1.12  root      750: 
                    751:        Log_Printf(LOG_DEBUG, "Loaded TOS version %i.%c%c, starting at $%x, "
                    752:                   "country code = %i, %s\n", TosVersion>>8, '0'+((TosVersion>>4)&0x0f),
                    753:                   '0'+(TosVersion&0x0f), TosAddress, STMemory_ReadWord(TosAddress+28)>>1,
                    754:                   (STMemory_ReadWord(TosAddress+28)&1)?"PAL":"NTSC");
                    755: 
                    756:        /* Are we allowed VDI under this TOS? */
                    757:        if (TosVersion == 0x0100 && bUseVDIRes)
                    758:        {
                    759:                /* Warn user */
1.1.1.18  root      760:                Log_AlertDlg(LOG_ERROR, "To use extended VDI resolutions, you must select a TOS >= 1.02.");
1.1.1.12  root      761:                /* And select non VDI */
1.1.1.16  root      762:                bUseVDIRes = ConfigureParams.Screen.bUseExtVdiResolutions = false;
1.1.1.12  root      763:        }
                    764: 
                    765:        /* Fix TOS image, modify code for emulation */
1.1.1.19  root      766:        if (ConfigureParams.Rom.bPatchTos && !bIsEmuTOS)
                    767:        {
1.1.1.13  root      768:                TOS_FixRom();
1.1.1.19  root      769:        }
                    770:        else
                    771:        {
                    772:                Log_Printf(LOG_DEBUG, "Skipped TOS patches.\n");
                    773:        }
1.1.1.12  root      774: 
                    775:        /* Set connected devices, memory configuration, etc. */
                    776:        STMemory_SetDefaultConfig();
1.1.1.6   root      777: 
1.1.1.12  root      778:        /* and free loaded image */
                    779:        free(pTosFile);
1.1.1.6   root      780: 
1.1.1.16  root      781:        bTosImageLoaded = true;
1.1.1.18  root      782:        TOS_CreateAutoInf();
1.1.1.6   root      783: 
1.1.1.12  root      784:        return 0;
1.1       root      785: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.