/* * UAE - The U*nix Amiga Emulator * * UAE Library v0.1 * * (c) 1996 Tauno Taipaleenmaki * * Change UAE parameters and other stuff from inside the emulation. */ #include "sysconfig.h" #include "sysdeps.h" #include #include #include "options.h" #include "uae.h" #include "memory.h" #include "custom.h" #include "newcpu.h" #include "xwin.h" #include "autoconf.h" #include "traps.h" #include "disk.h" #include "debug.h" #include "gensound.h" #include "picasso96.h" #include "filesys.h" /* * Returns UAE Version */ static uae_u32 emulib_GetVersion (void) { return version; } /* * Resets your amiga */ static uae_u32 emulib_HardReset (void) { uae_reset(1, 1); return 0; } static uae_u32 emulib_Reset (void) { uae_reset(0, 0); return 0; } /* * Enables SOUND */ static uae_u32 emulib_EnableSound (uae_u32 val) { if (!sound_available || currprefs.produce_sound >= 2) return 0; currprefs.produce_sound = val; return 1; } /* * Enables FAKE JOYSTICK */ static uae_u32 emulib_EnableJoystick (uae_u32 val) { currprefs.jports[0].jd[0].id = val & 255; currprefs.jports[1].jd[0].id = (val >> 8) & 255; return 1; } /* * Sets the framerate */ static uae_u32 emulib_SetFrameRate (uae_u32 val) { if (val == 0) return 0; else if (val > 20) return 0; else { currprefs.gfx_framerate = val; return 1; } } /* * Changes keyboard language settings */ static uae_u32 emulib_ChangeLanguage (uae_u32 which) { if (which > 6) return 0; else { switch (which) { case 0: currprefs.keyboard_lang = KBD_LANG_US; break; case 1: currprefs.keyboard_lang = KBD_LANG_DK; break; case 2: currprefs.keyboard_lang = KBD_LANG_DE; break; case 3: currprefs.keyboard_lang = KBD_LANG_SE; break; case 4: currprefs.keyboard_lang = KBD_LANG_FR; break; case 5: currprefs.keyboard_lang = KBD_LANG_IT; break; case 6: currprefs.keyboard_lang = KBD_LANG_ES; break; default: break; } return 1; } } /* The following ones don't work as we never realloc the arrays... */ /* * Changes chip memory size * (reboots) */ static uae_u32 REGPARAM2 emulib_ChgCMemSize(TrapContext *ctx, uae_u32 memsize) { if (memsize != 0x80000 && memsize != 0x100000 && memsize != 0x200000) { memsize = 0x200000; write_log (_T("Unsupported chipmem size!\n")); } trap_set_dreg(ctx, 0, 0); changed_prefs.chipmem.size = memsize; uae_reset(1, 1); return 1; } /* * Changes slow memory size * (reboots) */ static uae_u32 REGPARAM2 emulib_ChgSMemSize(TrapContext *ctx, uae_u32 memsize) { if (memsize != 0x80000 && memsize != 0x100000 && memsize != 0x180000 && memsize != 0x1C0000) { memsize = 0; write_log (_T("Unsupported bogomem size!\n")); } trap_set_dreg(ctx, 0, 0); changed_prefs.bogomem.size = memsize; uae_reset (1, 1); return 1; } /* * Changes fast memory size * (reboots) */ static uae_u32 REGPARAM2 emulib_ChgFMemSize(TrapContext *ctx, uae_u32 memsize) { if (memsize != 0x100000 && memsize != 0x200000 && memsize != 0x400000 && memsize != 0x800000) { memsize = 0; write_log (_T("Unsupported fastmem size!\n")); } trap_set_dreg(ctx, 0, 0); changed_prefs.fastmem[0].size = memsize; uae_reset (1, 1); return 0; } /* * Inserts a disk */ static uae_u32 emulib_InsertDisk(TrapContext *ctx, uaecptr name, uae_u32 drive) { char real_name[256]; TCHAR *s; if (drive > 3) return 0; if (trap_get_string(ctx, real_name, name, sizeof real_name) >= sizeof real_name) return 0; /* ENAMETOOLONG */ s = au (real_name); _tcscpy (changed_prefs.floppyslots[drive].df, s); xfree (s); return 1; } /* * Exits the emulator */ static uae_u32 emulib_ExitEmu(void) { uae_quit (); return 1; } /* * Gets UAE Configuration */ static uae_u32 emulib_GetUaeConfig(TrapContext *ctx, uaecptr place) { trap_put_long(ctx, place, version); trap_put_long(ctx, place + 4, chipmem_bank.allocated_size); trap_put_long(ctx, place + 8, bogomem_bank.allocated_size); trap_put_long(ctx, place + 12, fastmem_bank[0].allocated_size); trap_put_long(ctx, place + 16, currprefs.gfx_framerate); trap_put_long(ctx, place + 20, currprefs.produce_sound); trap_put_long(ctx, place + 24, currprefs.jports[0].jd[0].id | (currprefs.jports[1].jd[0].id << 8)); trap_put_long(ctx, place + 28, currprefs.keyboard_lang); if (disk_empty (0)) trap_put_byte(ctx, place + 32, 0); else trap_put_byte(ctx, place + 32, 1); if (disk_empty (1)) trap_put_byte(ctx, place + 33, 0); else trap_put_byte(ctx, place + 33, 1); if (disk_empty(2)) trap_put_byte(ctx, place + 34, 0); else trap_put_byte(ctx, place + 34, 1); if (disk_empty(3)) trap_put_byte(ctx, place + 35, 0); else trap_put_byte(ctx, place + 35, 1); for (int i = 0; i < 4; i++) { char *s = ua (currprefs.floppyslots[i].df); trap_put_string(ctx, s, place + 36 + i * 256, 256); xfree (s); } return 1; } /* * Sets UAE Configuration * * NOT IMPLEMENTED YET */ static uae_u32 emulib_SetUaeConfig(uaecptr place) { return 1; } /* * Gets the name of the disk in the given drive */ static uae_u32 emulib_GetDisk(TrapContext *ctx, uae_u32 drive, uaecptr name) { if (drive > 3) return 0; char *n = ua(currprefs.floppyslots[drive].df); trap_put_string(ctx, (uae_u8*)n, name, 256); xfree(n); return 1; } /* * Enter debugging state */ static uae_u32 emulib_Debug(void) { #ifdef DEBUGGER activate_debugger (); return 1; #else return 0; #endif } #define CREATE_NATIVE_FUNC_PTR uae_u32 (* native_func) (uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, \ uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32) #define SET_NATIVE_FUNC(x) native_func = (uae_u32 (*)(uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32, uae_u32))(x) #define CALL_NATIVE_FUNC( d1,d2,d3,d4,d5,d6,d7,a1,a2,a3,a4,a5,a6 ) if(native_func) native_func( d1,d2,d3,d4,d5,d6,d7,a1,a2,a3,a4,a5,a6 ) /* A0 - Contains a ptr to the native .obj data. This ptr is Amiga-based. */ /* We simply find the first function in this .obj data, and execute it. */ static uae_u32 REGPARAM2 emulib_ExecuteNativeCode (void) { #if 0 uaecptr object_AAM = m68k_areg (regs, 0); uae_u32 d1 = m68k_dreg (regs, 1); uae_u32 d2 = m68k_dreg (regs, 2); uae_u32 d3 = m68k_dreg (regs, 3); uae_u32 d4 = m68k_dreg (regs, 4); uae_u32 d5 = m68k_dreg (regs, 5); uae_u32 d6 = m68k_dreg (regs, 6); uae_u32 d7 = m68k_dreg (regs, 7); uae_u32 a1 = m68k_areg (regs, 1); uae_u32 a2 = m68k_areg (regs, 2); uae_u32 a3 = m68k_areg (regs, 3); uae_u32 a4 = m68k_areg (regs, 4); uae_u32 a5 = m68k_areg (regs, 5); uae_u32 a6 = m68k_areg (regs, 6); uae_u8* object_UAM = NULL; CREATE_NATIVE_FUNC_PTR; if (get_mem_bank(object_AAM).check (object_AAM, 1)) object_UAM = get_mem_bank (object_AAM).xlateaddr (object_AAM); if (object_UAM) { SET_NATIVE_FUNC (FindFunctionInObject (object_UAM)); CALL_NATIVE_FUNC (d1, d2, d3, d4, d5, d6, d7, a1, a2, a3, a4, a5, a6); } return 1; #endif return 0; } static uae_u32 emulib_Minimize (void) { return 0; // OSDEP_minimize_uae(); } static int native_dos_op(TrapContext *ctx, uae_u32 mode, uae_u32 p1, uae_u32 p2, uae_u32 p3) { TCHAR tmp[MAX_DPATH]; char *s; int v; if (mode) return -1; /* receive native path from lock * p1 = dos.library:Lock, p2 = buffer, p3 = max buffer size */ v = get_native_path(ctx, p1, tmp); if (v) return v; s = ua (tmp); trap_put_string(ctx, (uae_u8*)s, p2, p3); xfree (s); return 0; } static uae_u32 uaelib_demux_common(TrapContext *ctx, uae_u32 ARG0, uae_u32 ARG1, uae_u32 ARG2, uae_u32 ARG3, uae_u32 ARG4, uae_u32 ARG5) { switch (ARG0) { case 0: return emulib_GetVersion(); case 1: return emulib_GetUaeConfig(ctx, ARG1); case 2: return emulib_SetUaeConfig(ARG1); case 3: return emulib_HardReset(); case 4: return emulib_Reset(); case 5: return emulib_InsertDisk(ctx, ARG1, ARG2); case 6: return emulib_EnableSound(ARG1); case 7: return emulib_EnableJoystick(ARG1); case 8: return emulib_SetFrameRate(ARG1); case 9: return emulib_ChgCMemSize(ctx, ARG1); case 10: return emulib_ChgSMemSize(ctx, ARG1); case 11: return emulib_ChgFMemSize(ctx, ARG1); case 12: return emulib_ChangeLanguage(ARG1); /* The next call brings bad luck */ case 13: return emulib_ExitEmu(); case 14: return emulib_GetDisk(ctx, ARG1, ARG2); case 15: return emulib_Debug(); case 68: return emulib_Minimize(); case 69: return emulib_ExecuteNativeCode(); case 70: return 0; /* RESERVED. Something uses this.. */ case 80: if (!currprefs.maprom) return 0xffffffff; /* Disable possible ROM protection */ unprotect_maprom(); return currprefs.maprom; case 81: return cfgfile_uaelib(ctx, ARG1, ARG2, ARG3, ARG4); case 82: return cfgfile_uaelib_modify(ctx, ARG1, ARG2, ARG3, ARG4, ARG5); case 83: currprefs.mmkeyboard = ARG1 ? 1 : 0; return currprefs.mmkeyboard; #ifdef DEBUGGER case 84: return mmu_init(ARG1, ARG2, ARG3); #endif case 85: return native_dos_op(ctx, ARG1, ARG2, ARG3, ARG4); case 86: if (valid_address(ARG1, 1)) { uae_char tmp[MAX_DPATH]; trap_get_string(ctx, tmp, ARG1, sizeof tmp); TCHAR *s = au(tmp); write_log(_T("DBG: %s\n"), s); xfree(s); return 1; } return 0; case 87: { uae_u32 d0, d1; d0 = emulib_target_getcpurate(ARG1, &d1); trap_set_dreg(ctx, 1, d1); return d0; } } return 0; } uae_u32 uaeboard_demux(uae_u32 *board) { uae_u32 arg0, arg1, arg2, arg3, arg4, arg5; arg0 = do_get_mem_word((uae_u16*)&board[0]); arg1 = do_get_mem_long(&board[2]); arg2 = do_get_mem_long(&board[3]); arg3 = do_get_mem_long(&board[4]); arg4 = do_get_mem_long(&board[5]); arg5 = do_get_mem_long(&board[6]); return uaelib_demux_common(NULL, arg0, arg1, arg2, arg3, arg4, arg5); } static uae_u32 REGPARAM2 uaelib_demux2 (TrapContext *ctx) { #define ARG0 (trap_get_long(ctx, trap_get_areg(ctx, 7) + 4)) #define ARG1 (trap_get_long(ctx, trap_get_areg(ctx, 7) + 8)) #define ARG2 (trap_get_long(ctx, trap_get_areg(ctx, 7) + 12)) #define ARG3 (trap_get_long(ctx, trap_get_areg(ctx, 7) + 16)) #define ARG4 (trap_get_long(ctx, trap_get_areg(ctx, 7) + 20)) #define ARG5 (trap_get_long(ctx, trap_get_areg(ctx, 7) + 24)) #ifdef PICASSO96 if (ARG0 >= 16 && ARG0 <= 39) return picasso_demux(ARG0, ctx); #endif return uaelib_demux_common(ctx, ARG0, ARG1, ARG2, ARG3, ARG4, ARG5); } extern int uaelib_debug; static uae_u32 REGPARAM2 uaelib_demux (TrapContext *ctx) { uae_u32 v; struct regstruct *r = ®s; if (uaelib_debug) write_log (_T("%d: %08x %08x %08x %08x %08x %08x %08x %08x, %08x %08x %08x %08x %08x %08x %08x %08x\n"), ARG0, r->regs[0],r->regs[1],r->regs[2],r->regs[3],r->regs[4],r->regs[5],r->regs[6],r->regs[7], r->regs[8],r->regs[9],r->regs[10],r->regs[11],r->regs[12],r->regs[13],r->regs[14],r->regs[15]); v = uaelib_demux2 (ctx); if (uaelib_debug) write_log (_T("=%08x\n"), v); return v; } /* * Installs the UAE LIBRARY */ void emulib_install (void) { uaecptr a; if (!uae_boot_rom_type && !currprefs.uaeboard) return; a = here (); currprefs.mmkeyboard = 0; org (rtarea_base + 0xFF60); calltrap (deftrapres (uaelib_demux, 0, _T("uaelib_demux"))); dw (RTS); org (a); }