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

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

unix.superglobalmegacorp.com

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