|
|
1.1 root 1: /*
2: Hatari
3:
4: Load TOS image file into ST memory, fix/setup for emulator
5:
6: The Atari ST TOS needs to be patched to help with emulation. Eg, it references the MMU chip
7: to set memory size. This is patched to the sizes we need without the complicated emulation
8: of hardware which is not needed(as yet). We also patch DMA devices and Hard Drives.
9: NOTE: TOS versions 1.06 and 1.62 were not designed for use on a real STfm. These were for the
10: STe machine ONLY. They access the DMA/Microwire addresses on boot-up which(correctly) cause a
11: bus-error on Hatari as they would in a real STfm. If a user tries to select any of these images
12: we bring up an error and default back to the built-in TOS 1.00
13: */
14:
15: #include "main.h"
16: #include "cart.h"
17: #include "debug.h"
18: #include "decode.h"
19: #include "dialog.h"
20: #include "errlog.h"
21: #include "file.h"
22: #include "floppy.h"
23: #include "m68000.h"
24: #include "memAlloc.h"
25: #include "memorySnapShot.h"
26: #include "stMemory.h"
27: #include "tos.h"
28: #include "vdi.h"
29:
30:
31: /* Settings for differnt memory sizes */
32: static MEMORY_INFO MemoryInfo[] = {
33: 0x80000,0x0000,0x00080000, /* MEMORYSIZE_512 */
34: 0x100000,0x0101,0x00100000, /* MEMORYSIZE_1024 */
35: 0x200000,0x0001,0x00200000, /* MEMORYSIZE_2MB */
36: 0x400000,0x1010,0x00400000 /* MEMORYSIZE_4MB */
37: };
38:
39: /* Bit masks of connected drives(we support upto C,D,E,F) */
40: unsigned int ConnectedDriveMaskList[] = {
41: 0x03, /* DRIVELIST_NONE A,B */
42: 0x07, /* DRIVELIST_C A,B,C */
43: 0x0F, /* DRIVELIST_CD A,B,C,D */
44: 0x1F, /* DRIVELIST_CDE A,B,C,D,E */
45: 0x3F, /* DRIVELIST_CDEF A,B,C,D,E,F */
46: };
47:
48: unsigned short int TOSVersion; /* eg, 0x0100, 0x0102 */
49: unsigned long TOSAddress,TOSSize; /* Address in ST memory and size of TOS image */
50: unsigned int ConnectedDriveMask=0x03; /* Bit mask of connected drives, eg 0x7 is A,B,C */
51:
52: /* Possible TOS file extensions to scan for */
53: char *pszTOSNameExts[] = {
54: ".img",
55: ".rom",
56: ".tos",
57: NULL
58: };
59:
60: /* Taken from Decode.asm - Thothy */
61: unsigned long STRamEnd; /* End of ST Ram, above this address is no-mans-land and hardware vectors */
62: unsigned long STRamEnd_BusErr; /* as above, but start of BUS error exception */
63:
64:
65:
1.1.1.3 ! root 66: /*-----------------------------------------------------------------------*/
1.1 root 67: /*
68: Save/Restore snapshot of local variables('MemorySnapShot_Store' handles type)
69: */
70: void TOS_MemorySnapShot_Capture(BOOL bSave)
71: {
1.1.1.3 ! root 72: /* Save/Restore details */
1.1 root 73: MemorySnapShot_Store(&TOSVersion,sizeof(TOSVersion));
74: MemorySnapShot_Store(&TOSAddress,sizeof(TOSAddress));
75: MemorySnapShot_Store(&TOSSize,sizeof(TOSSize));
76: MemorySnapShot_Store(&ConnectedDriveMask,sizeof(ConnectedDriveMask));
77: }
78:
1.1.1.3 ! root 79:
! 80: /*-----------------------------------------------------------------------*/
1.1 root 81: /*
82: Load TOS Rom image file into ST memory space and fix image so can emulate correctly
83: Pre TOS 1.06 are loaded at 0xFC0000 with later ones at 0xE00000
84: If we cannot find the TOS image, or we detect an error we default to the built-in
85: TOS 1.00 image. This works great for new users who do not understand the idea of a TOS
86: Rom and are confused when presented with a 'select TOS image' dialog.
87: */
88: void TOS_LoadImage(void)
89: {
90: void *pTOSFile = NULL;
91: unsigned short int *pVersionPtr, *pTerritoryPtr;
92: BOOL bTOSImageLoaded = FALSE;
93:
94: /* Load TOS image into memory so we can check it's vesion */
95: TOSVersion = 0;
96: if (pTOSFile==NULL)
1.1.1.3 ! root 97: pTOSFile = File_Read(ConfigureParams.TOSGEM.szTOSImageFileName,NULL,NULL,pszTOSNameExts);
1.1 root 98:
99: if (pTOSFile) {
100: /* Now, look at start of image to find Version number and Territory */
101: pVersionPtr = (unsigned short int *)((unsigned long)pTOSFile+0x2);
102: pTerritoryPtr = (unsigned short int *)((unsigned long)pTOSFile+0x1c);
103: TOSVersion = STMemory_Swap68000Int(*pVersionPtr);
104:
105: /* Now see where to copy image */
106: switch(TOSVersion) {
107: case 0x0100: /* TOS 1.00 */
108: case 0x0102: /* TOS 1.02 */
109: case 0x0104: /* TOS 1.04 */
110: TOSAddress = 0xFC0000;
111: TOSSize = 192*1024; /* 192k */
112: bTOSImageLoaded = TRUE;
113: break;
114:
115: /* TOSes 1.06 and 1.62 are for the STe ONLY and so don't run on a real STfm. */
116: /* They access illegal memory addresses which don't exist on a real machine and cause the OS */
117: /* to lock up. So, if user selects one of these, show error and default to original TOS */
118: case 0x0106: /* TOS 1.06 */
119: case 0x0162: /* TOS 1.62 */
120: Main_Message("TOS versions 1.06 and 1.62 are NOT valid STfm images.\n\nThese were only designed for use on the STe range of machines.\n",PROG_NAME /*,MB_OK|MB_ICONINFORMATION*/);
121: bTOSImageLoaded = FALSE;
122: break;
123:
124: case 0x0205: /* TOS 2.05 */
125: case 0x0206: /* TOS 2.06 */
126: TOSAddress = 0xE00000;
127: TOSSize = 256*1024; /* 256k */
128: bTOSImageLoaded = TRUE;
129: break;
130: }
131:
132: /* Copy loaded image into ST memory, if found valid one*/
133: if (bTOSImageLoaded)
134: memcpy((void *)((unsigned long)STRam+TOSAddress),pTOSFile,TOSSize);
135: }
136:
137: /* Are we allowed VDI under this TOS? */
138: if ( (TOSVersion<0x0104) && (bUseVDIRes) ) {
139: /* Warn user (exit if need to) */
140: Main_Message("To use GEM Extended resolutions, you must select TOS 1.04 or higher.",PROG_NAME /*,MB_OK|MB_ICONINFORMATION*/);
141: /* And select non VDI */
142: bUseVDIRes = ConfigureParams.TOSGEM.bUseExtGEMResolutions = FALSE; /*FIXME*/
143: /* Default TOS 1.00 */
144: bTOSImageLoaded = FALSE;
145: }
146:
147: /* Did we load a TOS image correctly? */
148: if (!bTOSImageLoaded) {
149: fprintf(stderr, "Error: No tos.img loaded!\n");
150: exit(-1);
151: }
152:
153: /* Fix TOS image, modify code for emulation */
154: TOS_FixRom();
155:
156: /* Set connected devices, memory configuration */
157: TOS_SetDefaultMemoryConfig();
158:
159: /* and free loaded image */
160: Memory_Free(pTOSFile);
161: }
162:
1.1.1.3 ! root 163:
! 164: /*-----------------------------------------------------------------------*/
1.1 root 165: /*
166: Modify TOS Rom image to set default memory configuration, connected floppies and memory size
167: and skip some TOS setup code which we don't support/need.
168: As TOS Roms need to be modified we can only run images which are entered here.
169:
170: So, how do we find these addresses when we have no commented source code?
171: Easy,
172: Hdv_init: Scan start of TOS for table of move.l <addr>,$46A(a5), around 0x224 bytes in
173: and look at the first entry - that's the hdv_init address.
174: Hdv_boot: Scan start of TOS for table of move.l <addr>,$47A(a5), and look for 5th entry
175: - that's the hdv_boot address. The function starts with link,movem,jsr.
176: Boot from DMA bus: again scan at start of rom for tst.w $482, boot call will be just above it.
177: Set connected drives: search for 'clr.w' and '$4c2' to find, may use (a5) in which case op-code
178: is only 4 bytes and also note this is only do on TOS's after 1.00
179: */
180: void TOS_FixRom(void)
181: {
182: switch(TOSVersion) {
183: /*
184: TOS 1.00 settings
185: */
186: case 0x0100:
187: /* hdv_init, initialize drives */
1.1.1.3 ! root 188: STMemory_WriteWord(0xFC0D60,RTS_OPCODE); /* RTS */
1.1 root 189:
190: /* FC1384 JSR $FC0AF8 hdv_boot, load boot sector */
1.1.1.3 ! root 191: STMemory_WriteWord(0xFC1384,NOP_OPCODE); /* NOP */
! 192: STMemory_WriteWord(0xFC1384+2,NOP_OPCODE); /* NOP */
! 193: STMemory_WriteWord(0xFC1384+4,NOP_OPCODE); /* NOP */
1.1 root 194:
195: /* FC03d6 JSR $FC04A8 Boot from DMA bus */
196: if (bUseVDIRes) {
1.1.1.3 ! root 197: STMemory_WriteWord(0xFC03D6,0xa000); /* Init Line-A */
! 198: STMemory_WriteWord(0xFC03D6+2,0xa0ff); /* Trap Line-A (to get structure) */
1.1 root 199: }
200: else {
1.1.1.3 ! root 201: STMemory_WriteWord(0xFC03D6,NOP_OPCODE); /* NOP */
! 202: STMemory_WriteWord(0xFC03D6+2,NOP_OPCODE); /* NOP */
1.1 root 203: }
204:
205: /* Timer D(MFP init 0xFC21B4), set value before call Set Timer routine */
206: STMemory_WriteWord(0xFC21F6,TIMERD_OPCODE);
207:
208: /* Modify assembler loaded into cartridge area */
209: Cart_WriteHdvAddress(0x167A);
210: break;
211:
212: /*
213: TOS 1.02 settings
214: */
215: case 0x0102:
216: /* hdv_init, initialize drives */
1.1.1.3 ! root 217: STMemory_WriteWord(0xFC0F44,RTS_OPCODE); /* RTS */
1.1 root 218:
219: /* FC1568 JSR $FC0C2E hdv_boot, load boot sector */
1.1.1.3 ! root 220: STMemory_WriteWord(0xFC1568,NOP_OPCODE); /* NOP */
! 221: STMemory_WriteWord(0xFC1568+2,NOP_OPCODE); /* NOP */
! 222: STMemory_WriteWord(0xFC1568+4,NOP_OPCODE); /* NOP */
1.1 root 223:
224: /* FC0472 BSR.W $FC0558 Boot from DMA bus */
225: if (bUseVDIRes) {
1.1.1.3 ! root 226: STMemory_WriteWord(0xFC0472,0xa000); /* Init Line-A */
! 227: STMemory_WriteWord(0xFC0472+2,0xa0ff); /* Trap Line-A (to get structure) */
1.1 root 228: }
229: else {
1.1.1.3 ! root 230: STMemory_WriteWord(0xFC0472,NOP_OPCODE); /* NOP */
! 231: STMemory_WriteWord(0xFC0472+2,NOP_OPCODE); /* NOP */
1.1 root 232: }
233:
234: /* FC0302 CLR.L $4C2 Set connected drives */
235: STMemory_WriteWord(0xFC0302,CONDRV_OPCODE);
1.1.1.3 ! root 236: STMemory_WriteWord(0xFC0302+2,NOP_OPCODE); /* NOP */
! 237: STMemory_WriteWord(0xFC0302+4,NOP_OPCODE); /* NOP */
1.1 root 238:
1.1.1.3 ! root 239: /* Timer D (MFP init 0xFC2408) */
1.1 root 240: STMemory_WriteWord(0xFC2450,TIMERD_OPCODE);
241:
1.1.1.3 ! root 242: /* Modify assembler loaded into cartridge area */
1.1 root 243: Cart_WriteHdvAddress(0x16DA);
244: break;
245:
246: /*
247: TOS 1.04 settings
248: */
249: case 0x0104:
250: /* hdv_init, initialize drives */
1.1.1.3 ! root 251: STMemory_WriteWord(0xFC16BA,RTS_OPCODE); /* RTS */
1.1 root 252:
253: /* FC1CCE JSR $FC0BD8 hdv_boot, load boot sector */
1.1.1.3 ! root 254: STMemory_WriteWord(0xFC1CCE,NOP_OPCODE); /* NOP */
! 255: STMemory_WriteWord(0xFC1CCE + 2,NOP_OPCODE); /* NOP */
! 256: STMemory_WriteWord(0xFC1CCE + 4,NOP_OPCODE); /* NOP */
1.1 root 257:
258: /* FC0466 BSR.W $FC054C Boot from DMA bus */
259: if (bUseVDIRes) {
1.1.1.3 ! root 260: STMemory_WriteWord(0xFC0466,0xa000); /* Init Line-A */
! 261: STMemory_WriteWord(0xFC0466+2,0xa0ff); /* Trap Line-A (to get structure) */
1.1 root 262: }
263: else {
1.1.1.3 ! root 264: STMemory_WriteWord(0xFC0466,NOP_OPCODE); /* NOP */
! 265: STMemory_WriteWord(0xFC0466+2,NOP_OPCODE); /* NOP */
1.1 root 266: }
267:
268: /* FC02E6 CLR.L $4C2(A5) Set connected drives */
269: STMemory_WriteWord(0xFC02E6,CONDRV_OPCODE);
1.1.1.3 ! root 270: STMemory_WriteWord(0xFC02E6+2,NOP_OPCODE); /* NOP */
1.1 root 271:
272: /* Timer D(MFP init 0xFC34FC) */
273: STMemory_WriteWord(0xFC3544,TIMERD_OPCODE);
274:
275: /* Modify assembler loaded into cartridge area */
276: Cart_WriteHdvAddress(0x181C);
277: break;
278:
279: /*
280: TOS 1.06 settings
281: */
282: // case 0x0106:
283: // // hdv_init, initialize drives
284: // STMemory_WriteWord(0xE01892,RTS_OPCODE); //RTS
285: //
286: // // E01EA6 JSR $E00D74 hdv_boot, load boot sector
287: // STMemory_WriteWord(0xE01EA6,NOP_OPCODE); //NOP
288: // STMemory_WriteWord(0xE01EA6+2,NOP_OPCODE); //NOP
289: // STMemory_WriteWord(0xE01EA6+4,NOP_OPCODE); //NOP
290: //
291: // // E00576 BSR.W $E0065C Boot from DMA bus
292: // if (bUseVDIRes) {
293: // STMemory_WriteWord(0xE00576,0xa000); //Init Line-A
294: // STMemory_WriteWord(0xE00576+2,0xa0ff); //Trap Line-A(to get structure)
295: // }
296: // else {
297: // STMemory_WriteWord(0xE00576,NOP_OPCODE); //NOP
298: // STMemory_WriteWord(0xE00576+2,NOP_OPCODE); //NOP
299: // }
300: //
301: // // E002DC CLR.L $4C2(A5) Set connected drives
302: // STMemory_WriteWord(0xE002DC,CONDRV_OPCODE);
303: // STMemory_WriteWord(0xE002DC+2,NOP_OPCODE); //NOP
304: //
305: // // Timer D(MFP init 0xE036BC)
306: // STMemory_WriteWord(0xE03704,TIMERD_OPCODE);
307: //
308: // // Modify assembler loaded into cartridge area
309: // Cart_WriteHdvAddress(0x185C);
310: // break;
311:
312: /*
313: TOS 1.62 settings
314: */
315: // case 0x0162:
316: // // hdv_init, initialize drives
317: // STMemory_WriteWord(0xE01892,RTS_OPCODE); //RTS
318: //
319: // // E01EA6 JSR $E00D74 hdv_boot, load boot sector
320: // STMemory_WriteWord(0xE01EA6,NOP_OPCODE); //NOP
321: // STMemory_WriteWord(0xE01EA6+2,NOP_OPCODE); //NOP
322: // STMemory_WriteWord(0xE01EA6+4,NOP_OPCODE); //NOP
323: //
324: // // E00576 BSR.W $E0065C Boot from DMA bus
325: // if (bUseVDIRes) {
326: // STMemory_WriteWord(0xE00576,0xa000); //Init Line-A
327: // STMemory_WriteWord(0xE00576+2,0xa0ff); //Trap Line-A(to get structure)
328: // }
329: // else {
330: // STMemory_WriteWord(0xE00576,NOP_OPCODE); //NOP
331: // STMemory_WriteWord(0xE00576+2,NOP_OPCODE); //NOP
332: // }
333: //
334: // // E002DC CLR.L $4C2(A5) Set connected drives
335: // STMemory_WriteWord(0xE002DC,CONDRV_OPCODE);
336: // STMemory_WriteWord(0xE002DC+2,NOP_OPCODE); //NOP
337: //
338: // // Timer D(MFP init 0xE036BC)
339: // STMemory_WriteWord(0xE03704,TIMERD_OPCODE);
340: //
341: // // Modify assembler loaded into cartridge area
342: // Cart_WriteHdvAddress(0x185C);
343: // break;
344:
345: /*
346: TOS 2.05 settings
347: */
348: case 0x0205:
1.1.1.3 ! root 349: /* hdv_init, initialize drives */
! 350: STMemory_WriteWord(0xE0468C,RTS_OPCODE); /* RTS */
1.1 root 351:
1.1.1.3 ! root 352: /* E04CA0 JSR $E00E8E hdv_boot, load boot sector */
! 353: STMemory_WriteWord(0xE04CA0,NOP_OPCODE); /* NOP */
! 354: STMemory_WriteWord(0xE04CA0+2,NOP_OPCODE); /* NOP */
! 355: STMemory_WriteWord(0xE04CA0+4,NOP_OPCODE); /* NOP */
1.1 root 356:
1.1.1.3 ! root 357: /* E006AE BSR.W $E00794 Boot from DMA bus */
1.1 root 358: if (bUseVDIRes) {
1.1.1.3 ! root 359: STMemory_WriteWord(0xE006AE,0xa000); /* Init Line-A */
! 360: STMemory_WriteWord(0xE006AE + 2,0xa0ff); /* Trap Line-A (to get structure) */
1.1 root 361: }
362: else {
1.1.1.3 ! root 363: STMemory_WriteWord(0xE006AE,NOP_OPCODE); /* NOP */
! 364: STMemory_WriteWord(0xE006AE + 2,NOP_OPCODE); /* NOP */
1.1 root 365: }
366:
1.1.1.3 ! root 367: /* E002FC CLR.L $4C2 Set connected drives */
1.1 root 368: STMemory_WriteWord(0xE002FC,CONDRV_OPCODE);
1.1.1.3 ! root 369: STMemory_WriteWord(0xE002FC+2,NOP_OPCODE); /* NOP */
1.1 root 370:
1.1.1.3 ! root 371: /* Timer D(MFP init 0xE01928) */
1.1 root 372: STMemory_WriteWord(0xE01972,TIMERD_OPCODE);
373:
1.1.1.3 ! root 374: /* Modify assembler loaded into cartridge area */
1.1 root 375: Cart_WriteHdvAddress(0x1410);
376: break;
377:
378: /*
379: TOS 2.06 settings
380: */
381: case 0x0206:
382: /* hdv_init, initialize drives */
1.1.1.3 ! root 383: STMemory_WriteWord(0xE0518E,RTS_OPCODE); /* RTS */
1.1 root 384:
385: /* E05944 JSR $E011DC hdv_boot, load boot sector */
1.1.1.3 ! root 386: STMemory_WriteWord(0xE05944,NOP_OPCODE); /* NOP */
! 387: STMemory_WriteWord(0xE05944+2,NOP_OPCODE); /* NOP */
! 388: STMemory_WriteWord(0xE05944+4,NOP_OPCODE); /* NOP */
1.1 root 389:
390: /* E00898 BSR.W $E0097A Boot from DMA bus */
391: if (bUseVDIRes) {
1.1.1.3 ! root 392: STMemory_WriteWord(0xE00898,0xa000); /* Init Line-A */
! 393: STMemory_WriteWord(0xE00898+2,0xa0ff); /* Trap Line-A (to get structure) */
1.1 root 394: }
395: else {
1.1.1.3 ! root 396: STMemory_WriteWord(0xE00898,NOP_OPCODE); /* NOP */
! 397: STMemory_WriteWord(0xE00898+2,NOP_OPCODE); /* NOP */
1.1 root 398: }
399:
400: /* E00362 CLR.L $4C2 Set connected drives */
401: STMemory_WriteWord(0xE00362,CONDRV_OPCODE);
1.1.1.3 ! root 402: STMemory_WriteWord(0xE00362+2,NOP_OPCODE); /* NOP */
1.1 root 403:
404: /* E007FA MOVE.L #$1FFFE,D7 Run checksums on 2xROMs(skip) */
405: /* Checksum is total of TOS rom image, but get incorrect results as we've */
406: /* changed bytes in the ROM! So, just skip anyway! */
1.1.1.3 ! root 407: STMemory_WriteWord(0xE007FA,BRAW_OPCODE); /* BRA.W $E00894 */
1.1 root 408: STMemory_WriteWord(0xE007FA+2,0x98);
409:
410: /* Timer D(MFP init 0xE02206) */
411: STMemory_WriteWord(0xE02250,TIMERD_OPCODE);
412:
413: /* Modify assembler loaded into cartridge area */
414: Cart_WriteHdvAddress(0x1644);
415: break;
416: }
417: }
418:
1.1.1.3 ! root 419:
! 420: /*-----------------------------------------------------------------------*/
1.1 root 421: /*
422: Set default memory configuration, connected floppies and memory size
423: */
424: void TOS_SetDefaultMemoryConfig(void)
425: {
1.1.1.3 ! root 426: /* As TOS checks hardware for memory size + connected devices on boot-up */
! 427: /* we set these values ourselves and fill in the magic numbers so TOS */
! 428: /* skips these tests which would crash the emulator as the reference the MMU */
! 429:
! 430: /* Fill in magic numbers, so TOS does not try to reference MMU */
! 431: STMemory_WriteLong(0x420,0x752019f3); /* memvalid - configuration is valid */
! 432: STMemory_WriteLong(0x43a,0x237698aa); /* another magic # */
! 433: STMemory_WriteLong(0x51a,0x5555aaaa); /* and another */
1.1 root 434:
1.1.1.3 ! root 435: /* Set memory size, adjust for extra VDI screens if needed */
1.1 root 436: if (bUseVDIRes) {
1.1.1.3 ! root 437: /* This is enough for 1024x768x16colour (0x60000) */
! 438: STMemory_WriteLong(0x436,MemoryInfo[ConfigureParams.Memory.nMemorySize].PhysTop-0x60000); /* mem top - upper end of user memory (before 32k screen) */
! 439: STMemory_WriteLong(0x42e,MemoryInfo[ConfigureParams.Memory.nMemorySize].PhysTop-0x58000); /* phys top */
1.1 root 440: }
441: else {
1.1.1.3 ! root 442: STMemory_WriteLong(0x436,MemoryInfo[ConfigureParams.Memory.nMemorySize].PhysTop-0x8000); /* mem top - upper end of user memory(before 32k screen) */
! 443: STMemory_WriteLong(0x42e,MemoryInfo[ConfigureParams.Memory.nMemorySize].PhysTop); /* phys top */
1.1 root 444: }
1.1.1.3 ! root 445: STMemory_WriteLong(0x424,MemoryInfo[ConfigureParams.Memory.nMemorySize].MemoryConfig); /* 512k configure 0x00=128k 0x01=512k 0x10=2Mb 11=reserved eg 0x1010 = 4Mb */
! 446: STMemory_WriteLong(0xff8000,MemoryInfo[ConfigureParams.Memory.nMemorySize].MemoryConfig);
1.1 root 447:
1.1.1.3 ! root 448: /* Set memory range, and start of BUS error */
! 449: STRamEnd = MemoryInfo[ConfigureParams.Memory.nMemorySize].MemoryEnd; /* Set end of RAM */
! 450: STRamEnd_BusErr = 0x00420000; /* 4Mb */ /* Between RAM end and this is void space (0's), after is a BUS error */
! 451:
! 452: /* Set TOS floppies */
! 453: STMemory_WriteWord(0x446,nBootDrive); /* Boot up on A(0) or C(2) */
! 454: STMemory_WriteWord(0x4a6,0x2); /* Connected floppies A,B (0 or 2) */
! 455: ConnectedDriveMask = ConnectedDriveMaskList[ConfigureParams.HardDisc.nDriveList];
! 456: STMemory_WriteLong(0x4c2,ConnectedDriveMask); /* Drives A,B and C - NOTE some TOS images overwrite value, see 'TOS_ConnectedDrive_OpCode' */
1.1 root 457:
1.1.1.3 ! root 458: /* Mirror ROM boot vectors */
! 459: STMemory_WriteLong(0x00,STMemory_ReadLong(TOSAddress) );
1.1 root 460: STMemory_WriteLong(0x04,STMemory_ReadLong(TOSAddress+4) );
461: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.