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