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