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

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

unix.superglobalmegacorp.com

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