|
|
1.1.1.3 root 1: /*
1.1 root 2: * UAE - The Un*x Amiga Emulator
1.1.1.3 root 3: *
1.1 root 4: * A "replacement" for a missing Kickstart
5: * Warning! Q&D
6: *
7: * (c) 1995 Bernd Schmidt
8: */
9:
10: #include "sysconfig.h"
11: #include "sysdeps.h"
12:
13: #include "options.h"
1.1.1.4 root 14: #include "uae.h"
1.1 root 15: #include "memory.h"
16: #include "custom.h"
17: #include "newcpu.h"
18: #include "cia.h"
19: #include "disk.h"
20: #include "ersatz.h"
21:
22: #define EOP_INIT 0
23: #define EOP_NIMP 1
24: #define EOP_SERVEINT 2
25: #define EOP_DOIO 3
26: #define EOP_OPENLIB 4
27: #define EOP_AVAILMEM 5
28: #define EOP_ALLOCMEM 6
29: #define EOP_ALLOCABS 7
1.1.1.4 root 30: #define EOP_LOOP 8
1.1 root 31:
1.1.1.9 root 32: static int already_failed = 0;
33:
1.1.1.3 root 34: void init_ersatz_rom (uae_u8 *data)
1.1 root 35: {
1.1.1.7 root 36: write_log ("Trying to use Kickstart replacement.\n");
1.1 root 37: *data++ = 0x00; *data++ = 0x08; /* initial SP */
38: *data++ = 0x00; *data++ = 0x00;
39: *data++ = 0x00; *data++ = 0xF8; /* initial PC */
40: *data++ = 0x00; *data++ = 0x08;
41:
42: *data++ = 0xFF; *data++ = 0x0D;
43: *data++ = 0x00; *data++ = EOP_INIT;
44: *data++ = 0xFF; *data++ = 0x0D;
45: *data++ = 0x00; *data++ = EOP_NIMP;
1.1.1.3 root 46:
1.1 root 47: *data++ = 0xFF; *data++ = 0x0D;
1.1.1.4 root 48: *data++ = 0x00; *data++ = EOP_LOOP;
49: *data++ = 0xFF; *data++ = 0x0D;
1.1 root 50: *data++ = 0x00; *data++ = EOP_DOIO;
1.1.1.4 root 51:
1.1 root 52: *data++ = 0x4E; *data++ = 0x75;
53: *data++ = 0xFF; *data++ = 0x0D;
54: *data++ = 0x00; *data++ = EOP_SERVEINT;
55: *data++ = 0x4E; *data++ = 0x73;
1.1.1.4 root 56:
1.1 root 57: *data++ = 0xFF; *data++ = 0x0D;
58: *data++ = 0x00; *data++ = EOP_AVAILMEM;
59: *data++ = 0x4E; *data++ = 0x75;
60: *data++ = 0xFF; *data++ = 0x0D;
1.1.1.4 root 61:
1.1.1.3 root 62: *data++ = 0x00; *data++ = EOP_ALLOCMEM;
1.1 root 63: *data++ = 0x4E; *data++ = 0x75;
64: *data++ = 0xFF; *data++ = 0x0D;
65: *data++ = 0x00; *data++ = EOP_ALLOCABS;
1.1.1.4 root 66:
1.1 root 67: *data++ = 0x4E; *data++ = 0x75;
68: }
69:
1.1.1.9 root 70: static void ersatz_failed (void)
71: {
72: if (already_failed)
73: return;
74: already_failed = 1;
75: #if 0
76: notify_user (NUMSG_KICKREPNO);
77: uae_restart (-1, NULL);
78: #endif
79: uae_quit ();
80: }
81:
1.1 root 82: static void ersatz_doio (void)
83: {
1.1.1.3 root 84: uaecptr request = m68k_areg(regs, 1);
1.1 root 85: switch (get_word (request + 0x1C)) {
86: case 9: /* TD_MOTOR is harmless */
87: case 2: case 0x8002: /* READ commands */
88: break;
1.1.1.3 root 89:
1.1 root 90: default:
1.1.1.7 root 91: write_log ("Only CMD_READ supported in DoIO()\n");
1.1.1.9 root 92: ersatz_failed ();
1.1 root 93: }
94: {
1.1.1.3 root 95: uaecptr dest = get_long (request + 0x28);
1.1 root 96: int start = get_long (request + 0x2C) / 512;
97: int nsecs = get_long (request + 0x24) / 512;
98: int tr = start / 11;
99: int sec = start % 11;
100: while (nsecs--) {
101: DISK_ersatz_read (tr, sec, dest);
102: dest += 512;
103: if (++sec == 11)
104: sec = 0, tr++;
105: }
106: }
107: }
108:
109: static void ersatz_init (void)
110: {
111: int f;
1.1.1.3 root 112: uaecptr request;
113: uaecptr a;
114:
1.1.1.4 root 115: if (disk_empty (0)) {
1.1.1.7 root 116: write_log ("You need to have a diskfile in DF0 to use the Kickstart replacement!\n");
1.1.1.4 root 117: uae_quit ();
118: m68k_setpc (0xF80010);
119: return;
120: }
121:
1.1 root 122: regs.s = 0;
123: /* Set some interrupt vectors */
124: for (a = 8; a < 0xC0; a += 4) {
1.1.1.4 root 125: put_long (a, 0xF8001A);
1.1 root 126: }
127: regs.isp = regs.msp = regs.usp = 0x800;
1.1.1.2 root 128: m68k_areg(regs, 7) = 0x80000;
1.1 root 129: regs.intmask = 0;
1.1.1.3 root 130:
1.1 root 131: /* Build a dummy execbase */
1.1.1.2 root 132: put_long (4, m68k_areg(regs, 6) = 0x676);
1.1.1.3 root 133: put_byte (0x676 + 0x129, 0);
134: for (f = 1; f < 105; f++) {
135: put_word (0x676 - 6*f, 0x4EF9);
1.1 root 136: put_long (0x676 - 6*f + 2, 0xF8000C);
137: }
138: /* Some "supported" functions */
1.1.1.4 root 139: put_long (0x676 - 456 + 2, 0xF80014);
140: put_long (0x676 - 216 + 2, 0xF80020);
141: put_long (0x676 - 198 + 2, 0xF80026);
142: put_long (0x676 - 204 + 2, 0xF8002c);
143: put_long (0x676 - 210 + 2, 0xF8002a);
1.1.1.3 root 144:
1.1 root 145: /* Build an IORequest */
146: request = 0x800;
147: put_word (request + 0x1C, 2);
148: put_long (request + 0x28, 0x4000);
149: put_long (request + 0x2C, 0);
150: put_long (request + 0x24, 0x200 * 4);
1.1.1.2 root 151: m68k_areg(regs, 1) = request;
1.1 root 152: ersatz_doio ();
1.1.1.6 root 153: /* kickstart disk loader */
154: if (get_long(0x4000) == 0x4b49434b) {
155: /* a kickstart disk was found in drive 0! */
1.1.1.7 root 156: write_log ("Loading Kickstart rom image from Kickstart disk\n");
1.1.1.6 root 157: /* print some notes... */
1.1.1.7 root 158: write_log ("NOTE: if UAE crashes set CPU to 68000 and/or chipmem size to 512KB!\n");
1.1.1.6 root 159:
160: /* read rom image from kickstart disk */
161: put_word (request + 0x1C, 2);
162: put_long (request + 0x28, 0xF80000);
163: put_long (request + 0x2C, 0x200);
164: put_long (request + 0x24, 0x200 * 512);
165: m68k_areg(regs, 1) = request;
166: ersatz_doio ();
167:
168: /* read rom image once again to mirror address space.
169: not elegant, but it works... */
170: put_word (request + 0x1C, 2);
171: put_long (request + 0x28, 0xFC0000);
172: put_long (request + 0x2C, 0x200);
173: put_long (request + 0x24, 0x200 * 512);
174: m68k_areg(regs, 1) = request;
175: ersatz_doio ();
176:
177: disk_eject (0);
178:
179: m68k_setpc (0xFC0002);
1.1.1.8 root 180: fill_prefetch_slow ();
1.1.1.10 root 181: uae_reset (0);
1.1.1.6 root 182: ersatzkickfile = 0;
183: return;
184: }
185:
1.1 root 186: m68k_setpc (0x400C);
1.1.1.8 root 187: fill_prefetch_slow ();
1.1 root 188:
189: /* Init the hardware */
1.1.1.2 root 190: put_long (0x3000, 0xFFFFFFFEul);
1.1 root 191: put_long (0xDFF080, 0x3000);
192: put_word (0xDFF088, 0);
193: put_word (0xDFF096, 0xE390);
194: put_word (0xDFF09A, 0xE02C);
195: put_word (0xDFF09E, 0x0000);
196: put_word (0xDFF092, 0x0038);
197: put_word (0xDFF094, 0x00D0);
198: put_word (0xDFF08E, 0x2C81);
199: put_word (0xDFF090, 0xF4C1);
200: put_word (0xDFF02A, 0x8000);
1.1.1.3 root 201:
1.1 root 202: put_byte (0xBFD100, 0xF7);
203: put_byte (0xBFEE01, 0);
204: put_byte (0xBFEF01, 0x08);
205: put_byte (0xBFDE00, 0x04);
206: put_byte (0xBFDF00, 0x84);
207: put_byte (0xBFDD00, 0x9F);
208: put_byte (0xBFED01, 0x9F);
209: }
210:
1.1.1.3 root 211: void ersatz_perform (uae_u16 what)
1.1 root 212: {
213: switch (what) {
214: case EOP_INIT:
215: ersatz_init ();
216: break;
1.1.1.3 root 217:
1.1 root 218: case EOP_SERVEINT:
219: /* Just reset all the interrupt request bits */
220: put_word (0xDFF09C, get_word (0xDFF01E) & 0x3FFF);
221: break;
1.1.1.3 root 222:
1.1 root 223: case EOP_DOIO:
224: ersatz_doio ();
225: break;
1.1.1.3 root 226:
1.1 root 227: case EOP_AVAILMEM:
1.1.1.2 root 228: m68k_dreg(regs, 0) = m68k_dreg(regs, 1) & 4 ? 0 : 0x70000;
1.1 root 229: break;
1.1.1.3 root 230:
1.1 root 231: case EOP_ALLOCMEM:
1.1.1.2 root 232: m68k_dreg(regs, 0) = m68k_dreg(regs, 1) & 4 ? 0 : 0x0F000;
1.1 root 233: break;
234:
235: case EOP_ALLOCABS:
1.1.1.2 root 236: m68k_dreg(regs, 0) = m68k_areg(regs, 1);
1.1 root 237: break;
238:
239: case EOP_NIMP:
1.1.1.7 root 240: write_log ("Unimplemented Kickstart function called\n");
1.1.1.9 root 241: ersatz_failed ();
242: break;
243:
1.1.1.4 root 244: /* fall through */
245: case EOP_LOOP:
246: m68k_setpc (0xF80010);
247: break;
248:
1.1.1.3 root 249: case EOP_OPENLIB:
1.1 root 250: default:
1.1.1.7 root 251: write_log ("Internal error. Giving up.\n");
1.1.1.9 root 252: ersatz_failed ();
253: break;
1.1 root 254: }
255: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.