From 732fdfd5fec3e90c451149b72711c5940eaee993 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 22 Apr 2017 20:46:28 +0300 Subject: [PATCH] fakeuaebootrom, internal winlaunch. --- memory.cpp | 85 +++++++++++++- od-win32/ahidsound_dsonly.cpp | 207 +++++++++++++++++++++++++++------- 2 files changed, 249 insertions(+), 43 deletions(-) diff --git a/memory.cpp b/memory.cpp index fd2d2d27..7f67e917 100644 --- a/memory.cpp +++ b/memory.cpp @@ -154,10 +154,65 @@ static void REGPARAM3 dummy_wput (uaecptr, uae_u32) REGPARAM; static void REGPARAM3 dummy_bput (uaecptr, uae_u32) REGPARAM; static int REGPARAM3 dummy_check (uaecptr addr, uae_u32 size) REGPARAM; +/* fake UAE ROM */ + +extern addrbank fakeuaebootrom_bank; +MEMORY_FUNCTIONS(fakeuaebootrom); + #define MAX_ILG 1000 #define NONEXISTINGDATA 0 //#define NONEXISTINGDATA 0xffffffff +static bool map_uae_boot_rom_direct(void) +{ + if (!fakeuaebootrom_bank.allocated_size) { + fakeuaebootrom_bank.start = 0xf00000; + fakeuaebootrom_bank.reserved_size = 65536; + fakeuaebootrom_bank.mask = fakeuaebootrom_bank.reserved_size - 1; + if (!mapped_malloc (&fakeuaebootrom_bank)) + return false; + // create jump table to real uae boot rom + for (int i = 0xff00; i < 0xfff8; i += 8) { + uae_u8 *p = fakeuaebootrom_bank.baseaddr + i; + p[0] = 0x4e; + p[1] = 0xf9; + uaecptr p2 = rtarea_base + i; + p[2] = p2 >> 24; + p[3] = p2 >> 16; + p[4] = p2 >> 8; + p[5] = p2 >> 0; + } + } + map_banks(&fakeuaebootrom_bank, 0xf0, 1, 1); + write_log(_T("Mapped fake UAE Boot ROM jump table.\n")); + return true; +} + +// if access looks like old style hook call and f00000 space is unused, redirect to UAE boot ROM. +static bool maybe_map_boot_rom(uaecptr addr) +{ + if (currprefs.uaeboard >= 2 && get_mem_bank_real(0xf00000) == &dummy_bank) { + uae_u32 pc = M68K_GETPC; + if (addr >= 0xf0ff00 && addr <= 0xf0fff8 && (((valid_address(pc, 2) && (pc < 0xf00000 || pc >= 0x01000000) && !currprefs.cpu_compatible) || (pc == addr && currprefs.cpu_compatible)))) { + bool check2 = currprefs.cpu_compatible; + if (!check2) { + uae_u32 w = get_word(pc); + // JSR xxxxxxxx or JSR (an) + if (w == 0x4eb9 || w == 0x4eb9) + check2 = true; + } + if (check2) { + if (map_uae_boot_rom_direct()) { + if (get_mem_bank_real(0xf00000) == &fakeuaebootrom_bank) { + return true; + } + } + } + } + } + return false; +} + static void dummylog (int rw, uaecptr addr, int size, uae_u32 val, int ins) { if (illegal_count >= MAX_ILG && MAX_ILG > 0) @@ -303,6 +358,14 @@ uae_u32 dummy_get (uaecptr addr, int size, bool inst, uae_u32 defvalue) return isideint() ? 0xffff : 0x0000; } #endif + + if ((size == 2 || size == 4) && inst && maybe_map_boot_rom(addr)) { + if (size == 2) + return get_word(addr); + return get_long(addr); + } + + if (gary_nonrange(addr) || (size > 1 && gary_nonrange(addr + size - 1))) { if (gary_timeout) gary_wait (addr, size, false); @@ -762,7 +825,6 @@ MEMORY_FUNCTIONS(a3000hmem); MEMORY_FUNCTIONS(mem25bit); - /* Kick memory */ uae_u16 kickstart_version; @@ -974,7 +1036,10 @@ uae_u8 *REGPARAM2 default_xlate (uaecptr addr) cpu_halt(CPU_HALT_OPCODE_FETCH_FROM_NON_EXISTING_ADDRESS); return kickmem_xlate(2); } - recursive++; + + if (maybe_map_boot_rom(addr)) + return get_real_address(addr); + int size = currprefs.cpu_model >= 68020 ? 4 : 2; if (quit_program == 0) { /* do this only in 68010+ mode, there are some tricky A500 programs.. */ @@ -1127,6 +1192,13 @@ addrbank extendedkickmem2_bank = { extendedkickmem2_lget, extendedkickmem2_wget, ABFLAG_ROM | ABFLAG_THREADSAFE, 0, S_WRITE }; +addrbank fakeuaebootrom_bank = { + fakeuaebootrom_lget, fakeuaebootrom_wget, mem25bit_bget, + fakeuaebootrom_lput, fakeuaebootrom_wput, mem25bit_bput, + fakeuaebootrom_xlate, fakeuaebootrom_check, NULL, _T("*"), _T("fakeuaerom"), + fakeuaebootrom_lget, fakeuaebootrom_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 +}; MEMORY_FUNCTIONS(custmem1); MEMORY_FUNCTIONS(custmem2); @@ -1192,7 +1264,7 @@ static bool is_alg_rom(const TCHAR *name) struct romdata *rd = getromdatabypath(name); if (!rd) return false; - return (rd->type & ROMTYPE_ALG) != 0; + return (rd->type & ROMTYPE_ALG) != 0; } static void descramble_alg(uae_u8 *data, int size) @@ -1900,6 +1972,8 @@ static void allocate_memory (void) bool bogoreset = (bogomem_bank.flags & ABFLAG_NOALLOC) != 0 && (chipmem_bank.reserved_size != currprefs.chipmem_size || bogomem_bank.reserved_size != currprefs.bogomem_size); + mapped_free(&fakeuaebootrom_bank); + if (bogoreset) { mapped_free(&chipmem_bank); mapped_free(&bogomem_bank); @@ -2681,8 +2755,9 @@ void memory_cleanup (void) mapped_free (&cardmem_bank); } #endif - mapped_free (&custmem1_bank); - mapped_free (&custmem2_bank); + mapped_free(&custmem1_bank); + mapped_free(&custmem2_bank); + mapped_free(&fakeuaebootrom_bank); bogomem_bank.baseaddr = NULL; kickmem_bank.baseaddr = NULL; diff --git a/od-win32/ahidsound_dsonly.cpp b/od-win32/ahidsound_dsonly.cpp index 10ba3696..c2daa669 100644 --- a/od-win32/ahidsound_dsonly.cpp +++ b/od-win32/ahidsound_dsonly.cpp @@ -415,6 +415,115 @@ static void *bswap_buffer = NULL; static uae_u32 bswap_buffer_size = 0; static double syncdivisor; +#define FAKE_HANDLE_WINLAUNCH 0xfffffffe + +typedef uae_u32 (*fake_func_get)(struct fake_handle_struct*, const char*); +typedef uae_u32 (*fake_func_exec)(struct fake_handle_struct*, TrapContext*); + +struct fake_handle_struct +{ + uae_u32 handle; + uae_u32 func_start; + uae_u32 func_end; + fake_func_get get; + fake_func_exec exec; +}; + +// "Emulate" winlaunch + +static uae_u32 fake_winlaunch_get(struct fake_handle_struct *me, const char *name) +{ + if (!stricmp(name, "_launch")) + return me->func_start; + return 0; +} +static const int fake_winlaunch_cmdval[] = +{ + SW_HIDE, SW_MAXIMIZE, SW_MINIMIZE, SW_RESTORE, SW_SHOW, SW_SHOWDEFAULT, SW_SHOWMAXIMIZED, + SW_SHOWMINIMIZED, SW_SHOWMINNOACTIVE, SW_SHOWNA, SW_SHOWNOACTIVATE, SW_SHOWNORMAL +}; +static uae_u32 fake_winlaunch_exec(struct fake_handle_struct *me, TrapContext *ctx) +{ + uae_u32 file = m68k_dreg(regs, 1); + if (!valid_address(file, 2)) + return 0; + uae_u32 parms = m68k_dreg(regs, 2); + uae_u8 *fileptr = get_real_address(file); + uae_u8 *parmsptr = NULL; + if (parms) + parmsptr = get_real_address(parms); + uae_u32 showcmdval = m68k_dreg(regs, 3); + if (showcmdval > 11) + return 0; + uae_u32 ret = (uae_u32)ShellExecuteA(NULL, NULL, (char*)fileptr, (char*)parmsptr, "", fake_winlaunch_cmdval[showcmdval]); + uae_u32 aret = 0; + switch (ret) { + case 0: + aret = 1; + break; + case ERROR_FILE_NOT_FOUND: + aret = 2; + break; + case ERROR_PATH_NOT_FOUND: + aret = 3; + break; + case ERROR_BAD_FORMAT: + aret = 4; + break; + case SE_ERR_ACCESSDENIED: + aret = 5; + break; + case SE_ERR_ASSOCINCOMPLETE: + aret = 6; + break; + case SE_ERR_DDEBUSY: + aret = 7; + break; + case SE_ERR_DDEFAIL: + aret = 8; + break; + case SE_ERR_DDETIMEOUT: + aret = 9; + break; + case SE_ERR_DLLNOTFOUND: + aret = 10; + break; + case SE_ERR_NOASSOC: + aret = 11; + break; + case SE_ERR_OOM: + aret = 12; + break; + case SE_ERR_SHARE: + aret = 13; + break; + } + return aret; +} + +static struct fake_handle_struct fake_handles[] = +{ + { FAKE_HANDLE_WINLAUNCH, 4, 4, fake_winlaunch_get, fake_winlaunch_exec, }, + { 0 } +}; + + +static HMODULE native_override(const TCHAR *dllname, TrapContext *ctx) +{ + const TCHAR *s = _tcsrchr(dllname, '/'); + if (!s) + s = _tcsrchr(dllname, '\\'); + if (!s) { + s = dllname; + } else if (s) { + s++; + } + if (!_tcsicmp(s, _T("winlaunch.alib"))) { + return (HMODULE)FAKE_HANDLE_WINLAUNCH; + } + return 0; +} + uae_u32 REGPARAM2 ahi_demux (TrapContext *context) { //use the extern int (6 #13) @@ -636,8 +745,6 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context) flushprinter (); return 0; -#if defined(X86_MSVC_ASSEMBLY) - case 100: // open dll { if (!currprefs.native_code) @@ -650,42 +757,43 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context) TCHAR newdllpath[MAX_DPATH]; int ok = 0; TCHAR *filepart; + DWORD err = 0; dllptr = m68k_areg (regs, 0); + if (!valid_address(dllptr, 2)) + return 0; dllname = au ((uae_char*)get_real_address (dllptr)); - dpath[0] = 0; - GetFullPathName (dllname, sizeof dpath / sizeof (TCHAR), dpath, &filepart); - if (_tcslen (dpath) > _tcslen (start_path_data) && !_tcsncmp (dpath, start_path_data, _tcslen (start_path_data))) { - /* path really is relative to winuae directory */ - ok = 1; - _tcscpy (newdllpath, dpath + _tcslen (start_path_data)); - if (!_tcsncmp (newdllpath, dlldir, _tcslen (dlldir))) /* remove "winuae_dll" */ - _tcscpy (newdllpath, dpath + _tcslen (start_path_data) + 1 + _tcslen (dlldir)); - _stprintf (dpath, _T("%s%s%s"), start_path_data, WIN32_PLUGINDIR, newdllpath); - h = LoadLibrary (dpath); - if (h == NULL) - write_log (_T("native open: '%s' = %d\n"), dpath, GetLastError ()); - if (h == NULL) { - _stprintf (dpath, _T("%s%s\\%s"), start_path_data, dlldir, newdllpath); - h = LoadLibrary (dllname); - if (h == NULL) - write_log (_T("fallback native open: '%s' = %d\n"), dpath, GetLastError ()); - } - } else { - write_log (_T("native open outside of installation dir '%s'!\n"), dpath); - } - xfree (dllname); -#if 0 - if (h == NULL) { - h = LoadLibrary (filepart); - write_log (_T("native file open: '%s' = %p\n"), filepart, h); - if (h == NULL) { - _stprintf (dpath, "%s%s%s", start_path_data, WIN32_PLUGINDIR, filepart); + h = native_override(dllname, context); +#if defined(X86_MSVC_ASSEMBLY) + if (h == 0) { + dpath[0] = 0; + GetFullPathName (dllname, sizeof dpath / sizeof (TCHAR), dpath, &filepart); + if (_tcslen (dpath) > _tcslen (start_path_data) && !_tcsncmp (dpath, start_path_data, _tcslen (start_path_data))) { + /* path really is relative to winuae directory */ + ok = 1; + _tcscpy (newdllpath, dpath + _tcslen (start_path_data)); + if (!_tcsncmp (newdllpath, dlldir, _tcslen (dlldir))) /* remove "winuae_dll" */ + _tcscpy (newdllpath, dpath + _tcslen (start_path_data) + 1 + _tcslen (dlldir)); + _stprintf (dpath, _T("%s%s%s"), start_path_data, WIN32_PLUGINDIR, newdllpath); h = LoadLibrary (dpath); - write_log (_T("native path open: '%s' = %p\n"), dpath, h); + if (h == NULL) + err = GetLastError(); + if (h == NULL) { + _stprintf (dpath, _T("%s%s\\%s"), start_path_data, dlldir, newdllpath); + h = LoadLibrary (dllname); + if (h == NULL) { + DWORD err2 = GetLastError(); + if (h == NULL) { + write_log (_T("fallback native open: '%s' = %d, %d\n"), dpath, err2, err); + } + } + } + } else { + write_log (_T("native open outside of installation dir '%s'!\n"), dpath); } } #endif + xfree (dllname); syncdivisor = (3580000.0 * CYCLE_UNIT) / (double)syncbase; return (uae_u32)h; } @@ -693,13 +801,19 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context) case 101: //get dll label { if (currprefs.native_code) { - HMODULE m; uaecptr funcaddr; char *funcname; - m = (HMODULE) m68k_dreg (regs, 1); + uae_u32 m = m68k_dreg (regs, 1); funcaddr = m68k_areg (regs, 0); funcname = (char*)get_real_address (funcaddr); - return (uae_u32) GetProcAddress (m, funcname); + for (int i = 0; fake_handles[i].handle; i++) { + if (fake_handles[i].handle == m) { + return fake_handles[i].get(&fake_handles[i], funcname); + } + } +#if defined(X86_MSVC_ASSEMBLY) + return (uae_u32) GetProcAddress ((HMODULE)m, funcname); +#endif } return 0; } @@ -708,6 +822,13 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context) { uae_u32 ret = 0; if (currprefs.native_code) { + uaecptr funcptr = m68k_areg(regs, 0); + for (int i = 0; fake_handles[i].handle; i++) { + if (fake_handles[i].func_start >= funcptr && fake_handles[i].func_end <= funcptr) { + return fake_handles[i].exec(&fake_handles[i], context); + } + } +#if defined(X86_MSVC_ASSEMBLY) unsigned long rate1; double v; rate1 = read_processor_time (); @@ -719,6 +840,7 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context) v = 1000000 * CYCLE_UNIT; do_extra_cycles ((unsigned long)(syncdivisor * rate1)); //compensate the time stay in native func } +#endif } return ret; } @@ -726,13 +848,22 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context) case 103: //close dll { if (currprefs.native_code) { - HMODULE libaddr; - libaddr = (HMODULE) m68k_dreg (regs, 1); - FreeLibrary (libaddr); + uae_u32 addr = m68k_dreg (regs, 1); + for (int i = 0; fake_handles[i].handle; i++) { + if (addr == fake_handles[i].handle) { + addr = 0; + break; + } + } +#if defined(X86_MSVC_ASSEMBLY) + if (addr) { + HMODULE libaddr = (HMODULE)addr; + FreeLibrary (libaddr); + } +#endif } return 0; } -#endif case 104: //screenlost { -- 2.47.3