|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * AutoConfig devices
5: *
1.1.1.2 ! root 6: * Copyright 1995, 1996 Bernd Schmidt
! 7: * Copyright 1996 Ed Hanway
1.1 root 8: */
9:
10: #include "sysconfig.h"
11: #include "sysdeps.h"
12:
13: #include "config.h"
14: #include "options.h"
1.1.1.2 ! root 15: #include "machdep/m68k.h"
1.1 root 16: #include "memory.h"
17: #include "custom.h"
1.1.1.2 ! root 18: #include "readcpu.h"
1.1 root 19: #include "newcpu.h"
20: #include "disk.h"
21: #include "xwin.h"
22: #include "autoconf.h"
23:
1.1.1.2 ! root 24: /* We'll need a lot of these. */
! 25: #define MAX_TRAPS 4096
! 26: static TrapFunction traps[MAX_TRAPS];
! 27: static char trapmode[MAX_TRAPS];
! 28: static const char *trapstr[MAX_TRAPS];
! 29: static CPTR trapoldfunc[MAX_TRAPS];
! 30:
! 31: static int max_trap = 0;
! 32: static int trace_traps = 0;
! 33: int lasttrap;
! 34:
1.1 root 35: static struct {
36: CPTR libbase;
37: TrapFunction functions[300]; /* I don't think any library has more than 300 functions */
38: } libpatches[20];
39: static int n_libpatches = 0;
40:
41: ULONG Call68k_retaddr(CPTR address, int saveregs, CPTR retaddr)
42: {
43: ULONG retval;
44: CPTR oldpc = m68k_getpc();
45:
46: struct regstruct backup_regs;
1.1.1.2 ! root 47: struct flag_struct backup_flags;
! 48:
! 49: if (saveregs) {
1.1 root 50: backup_regs = regs;
1.1.1.2 ! root 51: backup_flags = regflags;
! 52: }
! 53: m68k_areg(regs, 7) -= 4;
! 54: put_long (m68k_areg(regs, 7), retaddr);
1.1 root 55: m68k_setpc(address);
56: m68k_go(0);
1.1.1.2 ! root 57: retval = m68k_dreg(regs, 0);
! 58: if (saveregs) {
1.1 root 59: regs = backup_regs;
1.1.1.2 ! root 60: regflags = backup_flags;
! 61: }
1.1 root 62: m68k_setpc(oldpc);
63: return retval;
64: }
65:
66: ULONG Call68k(CPTR address, int saveregs)
67: {
68: return Call68k_retaddr(address, saveregs, 0xF0FFF0);
69: }
70:
71: ULONG CallLib(CPTR base, WORD offset)
72: {
73: int i;
1.1.1.2 ! root 74: CPTR olda6 = m68k_areg(regs, 6);
1.1 root 75: ULONG retval;
76:
77: for (i = 0; i < n_libpatches; i++) {
78: if (libpatches[i].libbase == base && libpatches[i].functions[-offset/6] != NULL)
79: return (*libpatches[i].functions[-offset/6])();
80: }
81:
1.1.1.2 ! root 82: m68k_areg(regs, 6) = base;
1.1 root 83: retval = Call68k(base + offset, 1);
1.1.1.2 ! root 84: m68k_areg(regs, 6) = olda6;
1.1 root 85: return retval;
86: }
87:
88: /* @$%&� compiler bugs */
89: static volatile int four = 4;
90:
91: CPTR libemu_InstallFunctionFlags(TrapFunction f, CPTR libbase, int offset,
1.1.1.2 ! root 92: int flags, const char *tracename)
1.1 root 93: {
94: int i;
95: CPTR retval;
96: CPTR execbase = get_long(four);
1.1.1.2 ! root 97: int trnum;
1.1 root 98: ULONG addr = here();
1.1.1.2 ! root 99: calltrap2(trnum = deftrap2(f, flags, tracename));
1.1 root 100: dw(RTS);
101:
1.1.1.2 ! root 102: m68k_areg(regs, 1) = libbase;
! 103: m68k_areg(regs, 0) = offset;
! 104: m68k_dreg(regs, 0) = addr;
1.1 root 105: retval = CallLib(execbase, -420);
1.1.1.2 ! root 106:
! 107: trapoldfunc[trnum] = retval;
! 108:
1.1 root 109: for (i = 0; i < n_libpatches; i++) {
110: if (libpatches[i].libbase == libbase)
111: break;
112: }
113: if (i == n_libpatches) {
114: int j;
115: libpatches[i].libbase = libbase;
116: for (j = 0; j < 300; j++)
117: libpatches[i].functions[j] = NULL;
118: n_libpatches++;
119: }
120: libpatches[i].functions[-offset/6] = f;
121: return retval;
122: }
123:
1.1.1.2 ! root 124: CPTR libemu_InstallFunction(TrapFunction f, CPTR libbase, int offset,
! 125: const char *tracename)
1.1 root 126: {
1.1.1.2 ! root 127: return libemu_InstallFunctionFlags(f, libbase, offset, 0, tracename);
1.1 root 128: }
129:
130: /* Commonly used autoconfig strings */
131:
132: CPTR EXPANSION_explibname, EXPANSION_doslibname, EXPANSION_uaeversion;
133: CPTR EXPANSION_uaedevname, EXPANSION_explibbase = 0, EXPANSION_haveV36;
1.1.1.2 ! root 134: CPTR EXPANSION_bootcode, EXPANSION_nullfunc;
1.1 root 135:
136: static int current_deviceno = 0;
137:
138: int get_new_device(char **devname, CPTR *devname_amiga)
139: {
140: char buffer[80];
141:
142: sprintf(buffer,"UAE%d", current_deviceno);
143:
1.1.1.2 ! root 144: *devname_amiga = ds(*devname = my_strdup(buffer));
1.1 root 145: return current_deviceno++;
146: }
147:
148: /* ROM tag area memory access */
149:
150: static UBYTE rtarea[65536];
151:
152: static ULONG rtarea_lget(CPTR) REGPARAM;
1.1.1.2 ! root 153: static ULONG rtarea_wget(CPTR) REGPARAM;
! 154: static ULONG rtarea_bget(CPTR) REGPARAM;
1.1 root 155: static void rtarea_lput(CPTR, ULONG) REGPARAM;
1.1.1.2 ! root 156: static void rtarea_wput(CPTR, ULONG) REGPARAM;
! 157: static void rtarea_bput(CPTR, ULONG) REGPARAM;
1.1 root 158: static UBYTE *rtarea_xlate(CPTR) REGPARAM;
159:
160: addrbank rtarea_bank = {
161: rtarea_lget, rtarea_wget,
162: rtarea_lget, rtarea_wget, rtarea_bget,
163: rtarea_lput, rtarea_wput, rtarea_bput,
164: rtarea_xlate, default_check
165: };
166:
1.1.1.2 ! root 167: UBYTE REGPARAM2 *rtarea_xlate(CPTR addr)
1.1 root 168: {
169: addr &= 0xFFFF;
170: return rtarea + addr;
171: }
172:
1.1.1.2 ! root 173: ULONG REGPARAM2 rtarea_lget(CPTR addr)
1.1 root 174: {
175: addr &= 0xFFFF;
176: return (ULONG)(rtarea_wget(addr) << 16) + rtarea_wget(addr+2);
177: }
178:
1.1.1.2 ! root 179: ULONG REGPARAM2 rtarea_wget(CPTR addr)
1.1 root 180: {
181: addr &= 0xFFFF;
182: return (rtarea[addr]<<8) + rtarea[addr+1];
183: }
184:
1.1.1.2 ! root 185: ULONG REGPARAM2 rtarea_bget(CPTR addr)
1.1 root 186: {
187: UWORD data;
188: addr &= 0xFFFF;
189: return rtarea[addr];
190: }
191:
1.1.1.2 ! root 192: void REGPARAM2 rtarea_lput(CPTR addr, ULONG value) { }
! 193: void REGPARAM2 rtarea_bput(CPTR addr, ULONG value) { }
1.1 root 194:
195: /* Don't start at 0 -- can get bogus writes there. */
196: static ULONG trap_base_addr = 0x00F00180;
197:
198: void do_emultrap(int tr)
199: {
200: struct regstruct backup_regs;
201: ULONG retval;
202:
1.1.1.2 ! root 203: if (*trapstr[tr] != 0 && trace_traps)
! 204: fprintf(stderr, "TRAP: %s\n", trapstr[tr]);
! 205:
! 206: /* For monitoring only? */
! 207: if (traps[tr] == NULL) {
! 208: Call68k(trapoldfunc[tr], 0);
! 209: if (*trapstr[tr] != 0 && trace_traps)
! 210: fprintf(stderr, "RET : %s\n", trapstr[tr]);
! 211: return;
! 212: }
! 213:
! 214: if ((trapmode[tr] & TRAPFLAG_NOREGSAVE) == 0)
1.1 root 215: backup_regs = regs;
1.1.1.2 ! root 216:
1.1 root 217: retval = (*traps[tr])();
1.1.1.2 ! root 218:
! 219: if ((trapmode[tr] & TRAPFLAG_NOREGSAVE) == 0)
1.1 root 220: regs = backup_regs;
1.1.1.2 ! root 221: if ((trapmode[tr] & TRAPFLAG_NORETVAL) == 0) {
! 222: m68k_dreg(regs, 0) = retval;
! 223: }
1.1 root 224: }
225:
1.1.1.2 ! root 226: void REGPARAM2 rtarea_wput(CPTR addr, ULONG value)
1.1 root 227: {
228: /* Save all registers */
229: struct regstruct backup_regs;
230: ULONG retval = 0;
231: ULONG func = ((addr - trap_base_addr) & 0xFFFF) >> 1;
232:
233: if (func == 0) {
1.1.1.2 ! root 234: lasttrap = get_long(m68k_areg(regs, 7));
! 235: m68k_areg(regs, 7) += 4;
1.1 root 236: regs.spcflags |= SPCFLAG_EMULTRAP;
237: return;
238: }
239:
240: backup_regs = regs;
241: if(func < max_trap) {
242: retval = (*traps[func])();
243: } else {
244: fprintf(stderr, "illegal emulator trap\n");
245: }
246: regs = backup_regs;
1.1.1.2 ! root 247: m68k_dreg(regs, 0) = retval;
1.1 root 248: }
249:
250: /* some quick & dirty code to fill in the rt area and save me a lot of
251: * scratch paper
252: */
253:
254: static int rt_addr = 0;
255: static int rt_straddr = 0xFF00 - 2;
256:
257: ULONG addr(int ptr)
258: {
259: return (ULONG)ptr + 0x00F00000;
260: }
261:
262: void dw(UWORD data)
263: {
264: rtarea[rt_addr++] = data >> 8;
265: rtarea[rt_addr++] = data;
266: }
267:
268: void dl(ULONG data)
269: {
270: rtarea[rt_addr++] = data >> 24;
271: rtarea[rt_addr++] = data >> 16;
272: rtarea[rt_addr++] = data >> 8;
273: rtarea[rt_addr++] = data;
274: }
275:
276: /* store strings starting at the end of the rt area and working
277: * backward. store pointer at current address
278: */
279:
280: ULONG ds(char *str)
281: {
282: int len = strlen(str) + 1;
283:
284: rt_straddr -= len;
1.1.1.2 ! root 285: strcpy((char *)rtarea + rt_straddr, str);
1.1 root 286:
287: return addr(rt_straddr);
288: }
289:
290: void calltrap2(ULONG n)
291: {
292: dw(0x4878); /* PEA.L n.w */
293: dw(n);
294: /* Call trap #0 is reserved for this */
295: dw(0x33C0); /* MOVE.W D0,abs32 */
296: dl(trap_base_addr);
297: }
298:
299: void calltrap(ULONG n)
300: {
301: #if 1
302: dw(0x33C0); /* MOVE.W D0,abs32 */
303: dl(n*2 + trap_base_addr);
304: #else
305: calltrap2(n);
306: #endif
307: }
308:
309: void org(ULONG a)
310: {
311: rt_addr = a - 0x00F00000;
312: }
313:
314: ULONG here(void)
315: {
316: return addr(rt_addr);
317: }
318:
319: int deftrap(TrapFunction func)
320: {
321: int num = max_trap++;
322: traps[num] = func;
323: trapmode[num] = 0;
1.1.1.2 ! root 324: trapstr[num] = "";
1.1 root 325: return num;
326: }
327:
1.1.1.2 ! root 328: int deftrap2(TrapFunction func, int mode, const char *str)
1.1 root 329: {
330: int num = max_trap++;
331: traps[num] = func;
332: trapmode[num] = mode;
1.1.1.2 ! root 333: trapstr[num] = str;
1.1 root 334: return num;
335: }
336:
337: void align(int b)
338: {
339: rt_addr = (rt_addr + (b-1)) & ~(b-1);
340: }
341:
342: static ULONG bootcode(void)
343: {
1.1.1.2 ! root 344: m68k_areg(regs, 1) = EXPANSION_doslibname;
! 345: m68k_dreg(regs, 0) = CallLib (m68k_areg(regs, 6), -96); /* FindResident() */
! 346: m68k_areg(regs, 0) = get_long(m68k_dreg(regs, 0) + 22); /* get dos.library rt_init */
! 347: return m68k_areg(regs, 0);
! 348: }
! 349:
! 350: static ULONG nullfunc(void)
! 351: {
! 352: fprintf(stderr, "Null function called\n");
! 353: return 0;
1.1 root 354: }
355:
356: void rtarea_init()
357: {
358: ULONG a;
359: char uaever[100];
360: sprintf(uaever, "uae-%d.%d.%d", (version / 100) % 10, (version / 10) % 10, (version / 1) % 10);
361:
362: EXPANSION_uaeversion = ds(uaever);
363: EXPANSION_explibname = ds("expansion.library");
364: EXPANSION_doslibname = ds("dos.library");
365: EXPANSION_uaedevname = ds("uae.device");
366:
367: deftrap(NULL); /* Generic emulator trap */
368: lasttrap = 0;
369:
370: align(4);
371: EXPANSION_bootcode = here();
1.1.1.2 ! root 372: calltrap2(deftrap2(bootcode, 1, ""));
1.1 root 373: dw(0x2040); /* move.l d0,a0 */
374: dw(0x4e90); /* jsr (a0) */
375: dw(RTS);
376:
1.1.1.2 ! root 377: EXPANSION_nullfunc = here();
! 378: calltrap(deftrap(nullfunc));
! 379: dw(RTS);
1.1 root 380:
1.1.1.2 ! root 381: a = here();
1.1 root 382: /* Standard "return from 68k mode" trap */
1.1.1.2 ! root 383: org(0xF0FFF0);
1.1 root 384: calltrap2(0);
385: dw(RTS);
386: org(a);
387: }
1.1.1.2 ! root 388:
! 389: static ULONG hyperchip_init(void)
! 390: {
! 391: #if 0 /* This doesn't work either. Arrrgh!! */
! 392: CPTR execbase = get_long(4);
! 393: CPTR memlist = execbase + 322;
! 394: CPTR memh;
! 395:
! 396: for (;;) {
! 397: memh = get_long(memlist);
! 398: if (get_long(memh) == 0) {
! 399: fprintf(stderr, "No chip memory !?!??\n");
! 400: return 0;
! 401: }
! 402:
! 403: if (get_word(memh + 14) == 3)
! 404: break;
! 405:
! 406: memlist = memh;
! 407: }
! 408: put_long(memh + 24, get_long(memh + 24) + chipmem_size - 0x200000);
! 409: put_long(memh + 28, get_long(memh + 28) + chipmem_size - 0x200000);
! 410: memlist = memh + 16;
! 411: for (;;) {
! 412: memh = get_long(memlist);
! 413: if (memh == 0)
! 414: break;
! 415: memlist = memh;
! 416: }
! 417: put_long(memlist, 0x200000);
! 418: put_long(0x200000, 0);
! 419: put_long(0x200004, chipmem_size - 0x200000);
! 420: #endif
! 421: return 0;
! 422: }
! 423:
! 424: void rtarea_setup(void)
! 425: {
! 426: #if 0
! 427: if (chipmem_size > 0x200000) {
! 428: CPTR a = here();
! 429: /* Build a struct Resident for the 8MB chipmem support */
! 430: dw(0x4AFC);
! 431: dl(a);
! 432: dl(a + 0x1A); /* Continue scan here */
! 433: dw(0x0101); /* RTF_COLDSTART; Version 1 */
! 434: dw(0x0305); /* NT_DEVICE; pri 05 */
! 435: a = ds("UAE HyperChip (tm)");
! 436: dl(a); dl(a); /* Identification */
! 437: dl(here() + 4); /* Init code */
! 438:
! 439: calltrap(deftrap(hyperchip_init));
! 440: #if 0 /* This doesn't work for some reason */
! 441: dw(0x2c78); dw(4); /* move.l $4,a6 */
! 442: dw(0x203c); dl(chipmem_size - 0x200000);
! 443: dw(0x7203); dw(0x74f6);
! 444: dw(0x207c); dl(0x200000);
! 445: dw(0x227c); dl(ds("Chip RAM"));
! 446: dw(0x4eee); dw(0xfd96); /* jmp AddMemList(a6) */
! 447: #endif
! 448: }
! 449: #endif
! 450: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.