From 2c6e8ba0b6975ce58f2b4c9e18cf6617d55d5d50 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Thu, 8 Nov 2007 18:42:58 +0200 Subject: [PATCH] imported winuaesrc1450b8.zip --- cdtv.c | 24 +- cfgfile.c | 2 +- custom.c | 39 +- expansion.c | 9 +- filesys.asm | 5 +- filesys.c | 19 +- hardfile.c | 4 +- include/custom.h | 2 +- include/options.h | 3 +- include/scsi.h | 3 +- inputdevice.c | 4 + main.c | 6 +- newcpu.c | 1 + od-win32/cloanto/RetroPlatformGuestIPC.c | 250 ++++++++++ od-win32/cloanto/RetroPlatformGuestIPC.h | 53 +++ od-win32/cloanto/RetroPlatformIPC.h | 538 ++++++++++++++++++++++ od-win32/hardfile_win32.c | 19 +- od-win32/mman.c | 3 +- od-win32/rp.c | 292 ++++++++++++ od-win32/rp.h | 13 + od-win32/serial_win32.c | 17 +- od-win32/sounddep/sound.c | 10 +- od-win32/sounddep/sound.h | 1 + od-win32/sysconfig.h | 1 + od-win32/tun.c | 4 +- od-win32/win32.c | 50 +- od-win32/win32.h | 4 +- od-win32/win32_uaenet.c | 186 ++++++++ od-win32/win32_uaenet.h | 9 + od-win32/win32gfx.c | 18 +- od-win32/win32gui.c | 15 +- od-win32/winuae_msvc/winuae_msvc.8.vcproj | 12 + od-win32/winuae_msvc/winuae_msvc.vcproj | 12 + od-win32/winuaechangelog.txt | 21 + sana2.c | 246 +++++----- scsi.c | 4 + 36 files changed, 1708 insertions(+), 191 deletions(-) create mode 100644 od-win32/cloanto/RetroPlatformGuestIPC.c create mode 100644 od-win32/cloanto/RetroPlatformGuestIPC.h create mode 100644 od-win32/cloanto/RetroPlatformIPC.h create mode 100644 od-win32/rp.c create mode 100644 od-win32/rp.h create mode 100644 od-win32/win32_uaenet.c create mode 100644 od-win32/win32_uaenet.h diff --git a/cdtv.c b/cdtv.c index 4f04f80e..9760e694 100644 --- a/cdtv.c +++ b/cdtv.c @@ -487,9 +487,8 @@ static void cdrom_command_thread(uae_u8 b) cdrom_command_output[0] = flag; cdrom_command_accepted(1, s, &cdrom_command_cnt_in); cd_finished = 0; - if (first) - do_stch(); - first = 0; + if (first == -1) + first = 1; } break; case 0x82: @@ -692,15 +691,17 @@ static uae_u8 tp_imr, tp_cr, tp_air; static void tp_check_interrupts(void) { + /* MC = 1 ? */ if ((tp_cr & 1) != 1) return; if (sten == 1) { - if (tp_cd & (1 << 3)) { + sten = -1; + if (tp_cd & (1 << 3)) tp_air |= 1 << 3; - INT2(); - } } + if ((tp_air & tp_cd) & 0x1f) + INT2 (); } @@ -719,7 +720,8 @@ static void tp_bput (int addr, uae_u8 v) tp_b = v; break; case 2: - tp_c = v; + if (!(tp_cr & 1)) + tp_c = v; break; case 3: tp_ad = v; @@ -901,6 +903,12 @@ void CDTV_hsync_handler(void) return; cdtv_hsync = 0; + if (first > 0) { + first--; + if (first == 0) + do_stch(); + } + if (play_state == 1) { play_state = 2; cd_playing = 1; @@ -968,7 +976,7 @@ static void cdtv_reset (void) cd_error = 0; cd_finished = 0; stch = 0; - first = 1; + first = -1; } static uae_u32 dmac_bget2 (uaecptr addr) diff --git a/cfgfile.c b/cfgfile.c index 93384eaf..d9020957 100644 --- a/cfgfile.c +++ b/cfgfile.c @@ -414,7 +414,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_write (f, "serial_direct=%s\n", p->serial_direct ? "true" : "false"); cfgfile_write (f, "scsi=%s\n", scsimode[p->scsi]); cfgfile_write (f, "uaeserial=%s\n", p->uaeserial ? "true" : "false"); - cfgfile_write (f, "sana2=%s\n", p->sana2[0] ? p->sana2 : "none"); + cfgfile_write (f, "sana2=%s\n", p->sana2[0] ? p->sana2 : ""); cfgfile_write (f, "sound_output=%s\n", soundmode1[p->produce_sound]); cfgfile_write (f, "sound_bits=%d\n", p->sound_bits); diff --git a/custom.c b/custom.c index f4103d9f..9b5a79f2 100644 --- a/custom.c +++ b/custom.c @@ -356,6 +356,11 @@ enum fetchstate { * helper functions */ +STATIC_INLINE int ecsshres(void) +{ + return GET_RES (bplcon0) == RES_SUPERHIRES && (currprefs.chipset_mask & CSMASK_ECS_DENISE) && !(currprefs.chipset_mask & CSMASK_AGA); +} + STATIC_INLINE int nodraw (void) { return !currprefs.cpu_cycle_exact && framecnt != 0; @@ -1665,7 +1670,8 @@ static int expand_sprres (uae_u16 con0, uae_u16 con3) { int res; - switch ((con3 >> 6) & 3) { + switch ((con3 >> 6) & 3) + { default: res = RES_LORES; break; @@ -1687,8 +1693,8 @@ static int expand_sprres (uae_u16 con0, uae_u16 con3) case 3: res = RES_SUPERHIRES; break; - } #endif + } return res; } @@ -1859,14 +1865,15 @@ static void do_sprite_collisions (void) } STATIC_INLINE void record_sprite_1 (uae_u16 *buf, uae_u32 datab, int num, int dbl, - int do_collisions, uae_u32 collision_mask) + unsigned int mask, int do_collisions, uae_u32 collision_mask) { int j = 0; while (datab) { unsigned int tmp = *buf; unsigned int col = (datab & 3) << (2 * num); tmp |= col; - *buf++ = tmp; + if ((j & mask) == 0) + *buf++ = tmp; if (dbl > 0) *buf++ = tmp; if (dbl > 1) { @@ -1891,7 +1898,7 @@ STATIC_INLINE void record_sprite_1 (uae_u16 *buf, uae_u32 datab, int num, int db This function assumes that for all sprites in a given line, SPRXP either stays equal or increases between successive calls. - The data is recorded either in lores pixels (if ECS), or in superhires + The data is recorded either in lores pixels (if OCS/ECS), or in superhires pixels (if AGA). */ static void record_sprite (int line, int num, int sprxp, uae_u16 *data, uae_u16 *datb, unsigned int ctl) @@ -1902,12 +1909,15 @@ static void record_sprite (int line, int num, int sprxp, uae_u16 *data, uae_u16 uae_u16 *buf; uae_u32 collision_mask; int width, dbl, half; + unsigned int mask = 0; half = 0; dbl = sprite_buffer_res - sprres; if (dbl < 0) { half = -dbl; dbl = 0; + if (ecsshres()) + mask = 1; } width = (sprite_width << sprite_buffer_res) >> sprres; @@ -1938,9 +1948,9 @@ static void record_sprite (int line, int num, int sprxp, uae_u16 *data, uae_u16 buf = spixels + word_offs + ((i << dbl) >> half); if (currprefs.collision_level > 0 && collision_mask) - record_sprite_1 (buf, datab, num, dbl, 1, collision_mask); + record_sprite_1 (buf, datab, num, dbl, mask, 1, collision_mask); else - record_sprite_1 (buf, datab, num, dbl, 0, collision_mask); + record_sprite_1 (buf, datab, num, dbl, mask, 0, collision_mask); data++; datb++; } @@ -2325,7 +2335,7 @@ void init_hz (void) minfirstline = maxvpos - 1; sprite_vblank_endline = minfirstline - 2; maxvpos_max = maxvpos; - doublescan = htotal <= 140; + doublescan = htotal <= 150; dumpsync(); hzc = 1; } @@ -2350,8 +2360,7 @@ void init_hz (void) #endif write_log ("%s mode, V=%dHz H=%dHz (%dx%d)\n", isntsc ? "NTSC" : "PAL", - vblank_hz, - vblank_hz * maxvpos, + vblank_hz, vblank_hz * maxvpos, maxhpos, maxvpos); } @@ -3181,16 +3190,18 @@ STATIC_INLINE void SPRxCTLPOS (int num) sprxp = (sprpos[num] & 0xFF) * 2 + (sprctl[num] & 1); sprxp <<= sprite_buffer_res; /* Quite a bit salad in this register... */ -#ifdef ECS_DENISE - if (currprefs.chipset_mask & CSMASK_ECS_DENISE) { - sprxp |= ((sprctl[num] >> 3) & 2) >> (2 - sprite_buffer_res); + if (0) { } -#endif #ifdef AGA else if (currprefs.chipset_mask & CSMASK_AGA) { sprxp |= ((sprctl[num] >> 3) & 3) >> (2 - sprite_buffer_res); s->dblscan = sprpos[num] & 0x80; } +#endif +#ifdef ECS_DENISE + else if (currprefs.chipset_mask & CSMASK_ECS_DENISE) { + sprxp |= ((sprctl[num] >> 3) & 2) >> (2 - sprite_buffer_res); + } #endif s->xpos = sprxp; s->vstart = (sprpos[num] >> 8) | ((sprctl[num] << 6) & 0x100); diff --git a/expansion.c b/expansion.c index 48b67f19..da113c6a 100644 --- a/expansion.c +++ b/expansion.c @@ -1108,6 +1108,13 @@ static void expamem_init_a4091 (void) ncr_init(); } +void p96memstart(void) +{ + p96ram_start = currprefs.z3fastmem_start + ((currprefs.z3fastmem_size + 0xffffff) & ~0xffffff); + if (p96ram_start == currprefs.z3fastmem_start + currprefs.z3fastmem_size) + p96ram_start += 0x1000000; +} + void expamem_reset (void) { int do_mount = 1; @@ -1187,7 +1194,7 @@ void expamem_reset (void) z3fastmem_start = currprefs.z3fastmem_start; if (!p96mode) - p96ram_start = currprefs.z3fastmem_start + ((currprefs.z3fastmem_size + 0xffffff) & ~0xffffff); + p96memstart(); (*card_init[0]) (); } diff --git a/filesys.asm b/filesys.asm index 3021fe2c..7997acd4 100644 --- a/filesys.asm +++ b/filesys.asm @@ -815,14 +815,13 @@ make_dev: ; IN: A0 param_packet, D6: unit_no, D7: b0=autoboot,b1=onthefly,b2=v36 btst #2,d7 bne.s mountalways ; >= 36 btst #1,d7 - bne.s mountalways - tst.l PP_FSSIZE(a0) - beq.w general_ret ; no filesystem -> don't mount + bne.w mountalways mountalways ; allocate memory for loaded filesystem move.l PP_FSSIZE(a0),d0 beq.s nordbfs1 + bmi.s nordbfs1 move.l a0,-(sp) moveq #1,d1 move.l 4.w,a6 diff --git a/filesys.c b/filesys.c index b3c1dfdb..8a040ff0 100644 --- a/filesys.c +++ b/filesys.c @@ -4094,9 +4094,10 @@ action_set_date (Unit *unit, dpacket packet) if (err != 0) { PUT_PCK_RES1 (packet, DOS_FALSE); PUT_PCK_RES2 (packet, err); - } else + } else { + notify_check (unit, a); PUT_PCK_RES1 (packet, DOS_TRUE); - notify_check (unit, a); + } gui_hd_led (2); } @@ -5784,10 +5785,10 @@ static uae_u8 *restore_filesys_virtual (UnitInfo *ui, uae_u8 *src, int num) static char *getfullaname(a_inode *a) { - char *p = (char*)xmalloc (2000); + char *p; int first = 1; - memset(p, 0, 2000); + p = (char*)xcalloc (2000, 1); while (a) { int len = strlen(a->aname); memmove (p + len + 1, p, strlen(p) + 1); @@ -5812,10 +5813,13 @@ static int recurse_aino (UnitInfo *ui, a_inode *a, int cnt, uae_u8 **dstp) if (dstp) dst = *dstp; while (a) { + //write_log("recurse '%s' '%s' %d %08x\n", a->aname, a->nname, a->uniq, a->parent); if (a->elock || a->shlock || a->uniq == 0) { if (dst) { - char *fn = getfullaname(a); - write_log ("%04x '%s' s=%d e=%d d=%d\n", a->uniq, fn, a->shlock, a->elock, a->dir); + char *fn; + write_log ("%04x s=%d e=%d d=%d '%s' '%s'\n", a->uniq, a->shlock, a->elock, a->dir, a->aname, a->nname); + fn = getfullaname(a); + write_log ("->'%s'\n", fn); save_u64 (a->uniq); save_u32 (a->locked_children); save_u32 (a->exnext_count); @@ -5973,6 +5977,9 @@ uae_u8 *save_filesys (int num, int *len) ui = &mountinfo.ui[num]; if (!ui->open) return NULL; + /* not initialized yet, do not save */ + if (type == FILESYS_VIRTUAL && (ui->self == NULL || ui->volname == NULL)) + return NULL; write_log ("FS_FILESYS: '%s' '%s'\n", ui->devname, ui->volname); dstbak = dst = (uae_u8*)xmalloc (100000); save_u32 (2); /* version */ diff --git a/hardfile.c b/hardfile.c index 4b406c28..93d53cfb 100644 --- a/hardfile.c +++ b/hardfile.c @@ -746,10 +746,10 @@ void hardfile_do_disk_change (int fsid, int insert) hfd = get_hardfile_data (fsid); if (!hfd) return; - write_log("uaehf.device:%d media status=%d\n", fsid, insert); - hfd->drive_empty = newstate; uae_sem_wait (&change_sem); hardfpd[fsid].changenum++; + write_log("uaehf.device:%d media status=%d changenum=%d\n", fsid, insert, hardfpd[fsid].changenum); + hfd->drive_empty = newstate; j = 0; while (j < MAX_ASYNC_REQUESTS) { if (hardfpd[fsid].d_request_type[j] == ASYNC_REQUEST_CHANGEINT) { diff --git a/include/custom.h b/include/custom.h index a47b76c7..01d48995 100644 --- a/include/custom.h +++ b/include/custom.h @@ -43,7 +43,7 @@ extern int bogusframe; extern unsigned long int hsync_counter; extern uae_u16 dmacon; -extern uae_u16 intena,intreq; +extern uae_u16 intena, intreq, intreqr; extern int current_hpos (void); extern int vpos; diff --git a/include/options.h b/include/options.h index 1751034d..a984e871 100644 --- a/include/options.h +++ b/include/options.h @@ -352,6 +352,7 @@ extern char *cfgfile_subst_path (const char *path, const char *subst, const char extern int target_parse_option (struct uae_prefs *, char *option, char *value); extern void target_save_options (struct zfile*, struct uae_prefs *); extern void target_default_options (struct uae_prefs *, int type); +extern void target_fixup_options (struct uae_prefs *); extern int target_cfgfile_load (struct uae_prefs *, char *filename, int type, int isdefault); extern void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type); @@ -380,7 +381,7 @@ extern int check_prefs_changed_gfx (void); extern struct uae_prefs currprefs, changed_prefs; -extern void machdep_init (void); +extern int machdep_init (void); extern void machdep_free (void); /* AIX doesn't think it is Unix. Neither do I. */ diff --git a/include/scsi.h b/include/scsi.h index b23ef6db..db47e179 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -1,4 +1,5 @@ +#define SCSI_DATA_BUFFER_SIZE (512 * 512) struct scsi_data { int id; @@ -14,7 +15,7 @@ struct scsi_data int direction; int offset; - uae_u8 buffer[256 * 512]; + uae_u8 buffer[SCSI_DATA_BUFFER_SIZE]; struct hd_hardfiledata *hfd; int nativescsiunit; }; diff --git a/inputdevice.c b/inputdevice.c index 6da35694..d6e02b90 100644 --- a/inputdevice.c +++ b/inputdevice.c @@ -45,6 +45,7 @@ #include "zfile.h" #include "cia.h" #include "autoconf.h" +#include "rp.h" int inputdevice_logging = 0; @@ -2980,6 +2981,9 @@ void warpmode (int mode) } else { turbo_emulation = currprefs.gfx_framerate; } +#ifdef RETROPLATFORM + rp_turbo (turbo_emulation); +#endif } else if (mode == 0 && turbo_emulation > 0) { changed_prefs.gfx_framerate = currprefs.gfx_framerate = turbo_emulation; turbo_emulation = 0; diff --git a/main.c b/main.c index 1d752ac1..64c730d4 100644 --- a/main.c +++ b/main.c @@ -378,6 +378,7 @@ void fixup_prefs (struct uae_prefs *p) if (p->cpu_cycle_exact) p->gfx_framerate = 1; #endif + target_fixup_options (p); } int quit_program = 0; @@ -676,7 +677,10 @@ static void real_main2 (int argc, char **argv) else currprefs = changed_prefs; - machdep_init (); + if (!machdep_init ()) { + restart_program = 0; + return; + } if (! setup_sound ()) { write_log ("Sound driver unavailable: Sound output disabled\n"); diff --git a/newcpu.c b/newcpu.c index 81db3cb1..719feece 100644 --- a/newcpu.c +++ b/newcpu.c @@ -2294,6 +2294,7 @@ static void m68k_run_2a (void) /* Whenever we return from that, we should check spcflags */ if (uae_int_requested) { intreq |= 0x0008; + intreqr = intreq; set_special (®s, SPCFLAG_INT); } if (regs.spcflags) { diff --git a/od-win32/cloanto/RetroPlatformGuestIPC.c b/od-win32/cloanto/RetroPlatformGuestIPC.c new file mode 100644 index 00000000..18fb4d3f --- /dev/null +++ b/od-win32/cloanto/RetroPlatformGuestIPC.c @@ -0,0 +1,250 @@ +/***************************************************************************** + Name : RetroPlatformGuestIPC.c + Project : RetroPlatform Player + Client : Cloanto Italia srl + Legal : Copyright © 2007 Cloanto Italia srl - All rights reserved. This + : file is made available under the terms of the GNU General Public + : License version 2 as published by the Free Software Foundation. + Authors : os, mcb + Created : 2007-08-24 15:28:48 + Comment : RP Player interprocess communication functions (guest side) + Note : Can be compiled both in Unicode and Multibyte projects + *****************************************************************************/ + +#include "RetroPlatformGuestIPC.h" +#include "RetroPlatformIPC.h" + +// private functions +static BOOL RegisterWndClass(LPCTSTR pszClassName, HINSTANCE hInstance); +static LRESULT CALLBACK RPGuestWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +static const _TCHAR g_szHostWndClass[] = _T(RPIPC_HostWndClass); +static const _TCHAR g_szGuestWndClass[] = _T(RPIPC_GuestWndClass); +static const WCHAR g_szRegistration[] = L"Cloanto(R) RetroPlatform(TM)"; + + + +/***************************************************************************** + Name : RPInitializeGuest + Arguments : RPGUESTINFO *pInfo - structure receiving IPC context info + : HINSTANCE hInstance - current module instance + : LPCTSTR pszHostInfo - host information + : RPGUESTMSGFN pfnMsgFunction - message function to be called with incoming host messages + : LPARAM lMsgFunctionParam - application-defined value to be passed to the message function + Return : HRESULT - S_OK (successful initialization), S_FALSE (not started as guest), or error code + Authors : os + Created : 2007-08-24 16:45:32 + Comment : the guest calls this function (typically at startup time) + to initialize the IPC context with the host + *****************************************************************************/ + +HRESULT RPInitializeGuest(RPGUESTINFO *pInfo, HINSTANCE hInstance, LPCTSTR pszHostInfo, + RPGUESTMSGFN pfnMsgFunction, LPARAM lMsgFunctionParam) +{ + _TCHAR szGuestClass[(sizeof(g_szGuestWndClass)/sizeof(_TCHAR))+20]; + _TCHAR *pszHostClass; + LRESULT lr; + + if (!pInfo || !pszHostInfo) + return E_POINTER; + + pInfo->hInstance = hInstance; + pInfo->hHostMessageWindow = NULL; + pInfo->hGuestMessageWindow = NULL; + pInfo->bGuestClassRegistered = FALSE; + pInfo->pfnMsgFunction = pfnMsgFunction; + pInfo->lMsgFunctionParam = lMsgFunctionParam; + + // find the host message window + // + pszHostClass = (_TCHAR *)LocalAlloc(LMEM_FIXED, _tcslen(g_szHostWndClass) + _tcslen(pszHostInfo) + 1); + if (!pszHostClass) + return E_OUTOFMEMORY; + wsprintf(pszHostClass, g_szHostWndClass, pszHostInfo); + pInfo->hHostMessageWindow = FindWindow(pszHostClass, NULL); + LocalFree(pszHostClass); + if (!pInfo->hHostMessageWindow) + return HRESULT_FROM_WIN32(ERROR_HOST_UNREACHABLE); + + // create the guest message window + // + wsprintf(szGuestClass, g_szGuestWndClass, GetCurrentProcessId()); + if (!RegisterWndClass(szGuestClass, hInstance)) + return HRESULT_FROM_WIN32(GetLastError()); + pInfo->bGuestClassRegistered = TRUE; + // + pInfo->hGuestMessageWindow = CreateWindow(szGuestClass, NULL, 0, 0,0, 1,1, NULL, NULL, hInstance, (LPVOID)pInfo); + if (!pInfo->hGuestMessageWindow) + { + RPUninitializeGuest(pInfo); + return HRESULT_FROM_WIN32(GetLastError()); + } + + // register with the host + // + if (!RPSendMessage(RPIPCGM_REGISTER, 0, 0, g_szRegistration, sizeof(g_szRegistration), pInfo, &lr)) + { + RPUninitializeGuest(pInfo); + return HRESULT_FROM_WIN32(ERROR_HOST_UNREACHABLE); + } + if (!lr) + { + RPUninitializeGuest(pInfo); + return HRESULT_FROM_WIN32(ERROR_INVALID_ACCESS); + } + return S_OK; +} + +/***************************************************************************** + Name : RPUninitializeGuest + Arguments : RPGUESTINFO *pInfo - + Return : void + Authors : os + Created : 2007-08-27 16:16:21 + Comment : the guest calls this function (typically at uninitialization time) + to free the IPC context resources + allocated by a successfull call to RPInitializeGuest() + *****************************************************************************/ + +void RPUninitializeGuest(RPGUESTINFO *pInfo) +{ + _TCHAR szGuestClass[(sizeof(g_szGuestWndClass)/sizeof(_TCHAR))+20]; + + if (!pInfo) + return; + + if (pInfo->hGuestMessageWindow) + { + DestroyWindow(pInfo->hGuestMessageWindow); + pInfo->hGuestMessageWindow = NULL; + } + if (pInfo->bGuestClassRegistered) + { + wsprintf(szGuestClass, g_szGuestWndClass, GetCurrentProcessId()); + UnregisterClass(szGuestClass, pInfo->hInstance); + pInfo->bGuestClassRegistered = FALSE; + } +} + +/***************************************************************************** + Name : RPSendMessage + Arguments : UINT uMessage - message ID + : WPARAM wParam - message information (ignored if pData is not NULL) + : LPARAM lParam - message information (ignored if pData is not NULL) + : LPCVOID pData - message large-size information + : DWORD dwDataSize - size of the data pointed to by pData + : const RPGUESTINFO *pInfo - IPC context information + : LRESULT *plResult - optional pointer to get the response returned by the host + Return : BOOL - TRUE, if the message was successfully sent + Authors : os + Created : 2007-08-27 17:17:31 + Comment : the guest calls this function to send messages to the host; + if pData is NULL then the information sent along the message + is held by the wParam/lParam pair + *****************************************************************************/ + +BOOL RPSendMessage(UINT uMessage, WPARAM wParam, LPARAM lParam, + LPCVOID pData, DWORD dwDataSize, const RPGUESTINFO *pInfo, LRESULT *plResult) +{ + #define SRPMSG_TIMEOUT 5000 + DWORD_PTR dwResult; + + if (!pInfo) + return FALSE; + if (!pInfo->hHostMessageWindow) + return FALSE; + + if (pData) + { + COPYDATASTRUCT cds; + cds.dwData = (ULONG_PTR)uMessage; + cds.cbData = dwDataSize; + cds.lpData = (LPVOID)pData; + if (!SendMessageTimeout(pInfo->hHostMessageWindow, WM_COPYDATA, (WPARAM)pInfo->hGuestMessageWindow, (LPARAM)&cds, SMTO_NORMAL, SRPMSG_TIMEOUT, &dwResult)) + return FALSE; + } + else + { + if (!SendMessageTimeout(pInfo->hHostMessageWindow, uMessage, wParam, lParam, SMTO_NORMAL, SRPMSG_TIMEOUT, &dwResult)) + return FALSE; + } + if (plResult) + *plResult = dwResult; + + return TRUE; +} + +/***************************************************************************** + Name : RegisterWndClass + Arguments : LPCTSTR pszClassName - + : HINSTANCE hInstance - + Return : BOOL - + Authors : os + Created : 2007-08-27 16:09:12 + Comment : registers the guest window message class + *****************************************************************************/ + +static BOOL RegisterWndClass(LPCTSTR pszClassName, HINSTANCE hInstance) +{ + WNDCLASSEX wcex; + + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.style = 0; + wcex.lpfnWndProc = RPGuestWndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = NULL; + wcex.hCursor = NULL; + wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wcex.lpszMenuName = NULL; + wcex.lpszClassName = pszClassName; + wcex.hIconSm = NULL; + + return RegisterClassEx(&wcex); +} + +/***************************************************************************** + Name : RPGuestWndProc + Arguments : HWND hWnd - + : UINT uMessage - + : WPARAM wParam - + : LPARAM lParam - + Return : LRESULT - response returned to the host + Authors : os + Created : 2007-08-27 15:24:37 + Comment : window procedure (dispatches host messages to the guest callback function) + *****************************************************************************/ + +static LRESULT CALLBACK RPGuestWndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam) +{ + RPGUESTINFO *pInfo = (RPGUESTINFO *)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_USERDATA); + + if (uMessage == WM_CREATE) + { + LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam; + if (!lpcs) + return -1; + pInfo = (RPGUESTINFO *)lpcs->lpCreateParams; + if (!pInfo) + return -1; + #pragma warning (push) + #pragma warning (disable : 4244) // ignore LONG_PTR cast warning in 32-bit compilation + SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pInfo); + #pragma warning (pop) + return 0; + } + else if (uMessage == WM_COPYDATA && pInfo && lParam) + { + COPYDATASTRUCT *pcds = (COPYDATASTRUCT *)lParam; + return pInfo->pfnMsgFunction((UINT)pcds->dwData, 0, 0, pcds->lpData, pcds->cbData, pInfo->lMsgFunctionParam); + } + else if (uMessage >= WM_APP && uMessage <= 0xBFFF && pInfo) + { + return pInfo->pfnMsgFunction(uMessage, wParam, lParam, NULL, 0, pInfo->lMsgFunctionParam); + } + else + { + return DefWindowProc(hWnd, uMessage, wParam, lParam); + } +} diff --git a/od-win32/cloanto/RetroPlatformGuestIPC.h b/od-win32/cloanto/RetroPlatformGuestIPC.h new file mode 100644 index 00000000..54778820 --- /dev/null +++ b/od-win32/cloanto/RetroPlatformGuestIPC.h @@ -0,0 +1,53 @@ +/***************************************************************************** + Name : RetroPlatformGuestIPC.h + Project : RetroPlatform Player + Client : Cloanto Italia srl + Legal : Copyright © 2007 Cloanto Italia srl - All rights reserved. This + : file is made available under the terms of the GNU General Public + : License version 2 as published by the Free Software Foundation. + Authors : os + Created : 2007-08-24 15:29:26 + Comment : RP Player interprocess communication include file (guest side) + *****************************************************************************/ + +#ifndef __CLOANTO_RETROPLATFORMGUESTIPC_H__ +#define __CLOANTO_RETROPLATFORMGUESTIPC_H__ + +#include +#include + +typedef LRESULT (CALLBACK *RPGUESTMSGFN)(UINT uMessage, WPARAM wParam, LPARAM lParam, LPCVOID pData, DWORD dwDataSize, LPARAM lMsgFunctionParam); + +// the RPGuestInfo fields should be considered private, +// since future implementations of RetroPlatform interprocess communication +// might use a different IPC mechanism; +// the guest (emulator engine) is just supposed to call +// the RetroPlatform IPC public functions (see below) +// to communicate with the host +// +typedef struct RPGuestInfo +{ + HINSTANCE hInstance; + HWND hHostMessageWindow; + HWND hGuestMessageWindow; + BOOL bGuestClassRegistered; + RPGUESTMSGFN pfnMsgFunction; + LPARAM lMsgFunctionParam; +} RPGUESTINFO; + +#ifdef __cplusplus +extern "C" { +#endif + +// RetroPlatform IPC public functions +// (see instructions in RetroPlatformGuestIPC.c) +// +HRESULT RPInitializeGuest(RPGUESTINFO *pInfo, HINSTANCE hInstance, LPCTSTR pszHostInfo, RPGUESTMSGFN pfnMsgFunction, LPARAM lMsgFunctionParam); +void RPUninitializeGuest(RPGUESTINFO *pInfo); +BOOL RPSendMessage(UINT uMessage, WPARAM wParam, LPARAM lParam, LPCVOID pData, DWORD dwDataSize, const RPGUESTINFO *pInfo, LRESULT *plResult); + +#ifdef __cplusplus +} // ... extern "C" +#endif + +#endif // __CLOANTO_RETROPLATFORMGUESTIPC_H__ diff --git a/od-win32/cloanto/RetroPlatformIPC.h b/od-win32/cloanto/RetroPlatformIPC.h new file mode 100644 index 00000000..0ef30735 --- /dev/null +++ b/od-win32/cloanto/RetroPlatformIPC.h @@ -0,0 +1,538 @@ +/***************************************************************************** + Name : RetroPlatformIPC.h + Project : RetroPlatform Player + Client : Cloanto Italia srl + Legal : Copyright © 2007 Cloanto Italia srl - All rights reserved. This + : file is made available under the terms of the GNU General Public + : License version 2 as published by the Free Software Foundation. + Authors : os, mcb + Created : 2007-08-27 13:55:49 + Comment : RP Player interprocess communication include file + *****************************************************************************/ + +#ifndef __CLOANTO_RETROPLATFORMIPC_H__ +#define __CLOANTO_RETROPLATFORMIPC_H__ + +#include + +#define RPLATFORM_API_VER "1.0" +#define RPLATFORM_API_VER_MAJOR 1 +#define RPLATFORM_API_VER_MINOR 0 + +#define RPIPC_HostWndClass "RetroPlatformHost%s" +#define RPIPC_GuestWndClass "RetroPlatformGuest%d" + + +// **************************************************************************** +// Guest-to-Host Messages +// **************************************************************************** + +// Message: +// RPIPCGM_REGISTER +// Description: +// this is a private message and is automatically sent +// by the RPInitializeGuest() function +// to register the caller as a RetroPlatform guest +// +#define RPIPCGM_REGISTER (WM_APP + 0) + +// Message: +// RPIPCGM_FEATURES +// Description: +// the guest uses this message to tell the host +// about the features it supports; +// at startup time, the guest sends initialization messages +// so that the host can adapt the GUI based on the reported features; +// these messages include: +// RPIPCGM_FEATURES (describes guest features), +// RPIPCGM_POWERLED (turns on the power LED in the GUI), +// RPIPCGM_DEVICES (one for each device category: tells the number of emulated devices), +// RPIPCGM_DEVICEIMAGE (one for each device with an image file loaded), +// RPIPCGM_TURBO (tells if some of the turbo modes are activated from the start), +// RPIPCGM_INPUTMODE (tells if keyboard mode or joystick mode is active), +// RPIPCGM_VOLUME (reports about starting volume level), +// RPIPCGM_SCREENMODE (communicates the screen mode and the guest window handle); +// note that at startup time the guest should create a borderless and hidden window +// and send its handle using a RPIPCGM_SCREENMODE message, which must be the last +// of the initialization messages, since it displays the guest window +// and the host "frame window" (the part of the player user interface +// with command and status icons which can be used to drag the guest window, etc.) +// Data sent: +// WPARAM = RP_FEATURE_* flags +// Response: +// none +// +#define RPIPCGM_FEATURES (WM_APP + 1) + +// Message: +// RPIPCGM_CLOSED +// Description: +// this message is sent to the host when the guest is terminating +// Data sent: +// none +// Response: +// none +// +#define RPIPCGM_CLOSED (WM_APP + 2) + +// Message: +// RPIPCGM_ACTIVATED +// Description: +// the guest sends this message to the host +// when its window is being activated +// Data sent: +// LPARAM = identifier of the thread that owns the window being deactivated +// Response: +// none +// +#define RPIPCGM_ACTIVATED (WM_APP + 3) + +// Message: +// RPIPCGM_DEACTIVATED +// Description: +// the guest sends this message to the host +// when its window is being deactivated +// Data sent: +// LPARAM = identifier of the thread that owns the window being activated +// Response: +// none +// +#define RPIPCGM_DEACTIVATED (WM_APP + 4) + +// Message: +// RPIPCGM_ZORDER +// Description: +// the guest sends this message to notify the host about a change +// in the Z order (front-to-back position) of its window +// (e.g. the user clicked the window icon in the application bar +// to bring the window to the front) +// Data sent: +// none +// Response: +// none +// +#define RPIPCGM_ZORDER (WM_APP + 5) + +// Message: +// RPIPCGM_MINIMIZED +// Description: +// the guest sends this message to the host when its window +// has been minimized +// (e.g. using the Minimize menu command in the application bar) +// Data sent: +// none +// Response: +// none +// +#define RPIPCGM_MINIMIZED (WM_APP + 6) + +// Message: +// RPIPCGM_RESTORED +// Description: +// the guest sends this message to the host when its window +// has been restored from the minimized status +// (e.g. using the Restore menu command in the application bar) +// Data sent: +// none +// Response: +// none +// +#define RPIPCGM_RESTORED (WM_APP + 7) + +// Message: +// RPIPCGM_MOVED +// Description: +// the guest sends this message to the host when its window position +// has been changed +// (e.g. using the Move menu command in the application bar) +// Data sent: +// none +// Response: +// none +// +#define RPIPCGM_MOVED (WM_APP + 8) + +// Message: +// RPIPCGM_SCREENMODE +// Description: +// the guest sends a RPIPCGM_SCREENMODE message to notify the host +// about a change in its "screen mode" (1x/2x/4x/full screen, etc.); +// screen mode changes requested by the host +// (see the RPIPCHM_SCREENMODE message) must not be notified, +// unless this is an asynchronous screen mode change +// (i.e. the guest returned the INVALID_HANDLE_VALUE +// response to a RPIPCHM_SCREENMODE host request); +// this message can also be sent when the guest has to close +// and reopen its window for other reasons; +// at startup-time, the guest must create +// a borderless and hidden window and send its handle +// using this message; the host will then take care +// of preparing, positioning and showing the guest window +// Data sent: +// WPARAM = new screen mode (RP_SCREENMODE_* value) +// LPARAM = handle of the (new) guest window +// Response: +// none +// +#define RPIPCGM_SCREENMODE (WM_APP + 9) + +// Message: +// RPIPCGM_POWERLED +// Description: +// sent to the host to change the power LED state +// Data sent: +// WPARAM = power LED intensity (min/off 0, max 100) +// Response: +// none +// +#define RPIPCGM_POWERLED (WM_APP + 10) + +// Message: +// RPIPCGM_DEVICES +// Description: +// this message is used to notify the host about a change +// in the number of emulated devices (floppy drives, hard disks, etc.) +// Data sent: +// WPARAM = device category (RP_DEVICE_* value) +// LPARAM = 32-bit bitfield representing the devices +// emulated in the specified category +// (every bit set to 1 corresponds to a mounted drive +// e.g. 0x00000005 = drive 0 and drive 2 are emulated) +// Response: +// none +// +#define RPIPCGM_DEVICES (WM_APP + 11) + +// Message: +// RPIPCGM_DEVICEACTIVITY +// Description: +// this message can be used to turn on or off the activity indicator +// of a specified device (like a LED on the original hardware); +// the indicator can also be "blinked", i.e. the host will turn the +// LED on and then off again after the specified amount of time +// Data sent: +// WPARAM = device category (RP_DEVICE_* value) and device number +// combined with the MAKEWORD macro; +// e.g. MAKEWORD(RP_DEVICE_FLOPPY, 0) +// LPARAM = 0 turns off the activity LED, +// (LPARAM)-1 turns on the activity LED, +// turns on the activity LED +// for the specified amount of time (blink) +// Response: +// none +// +#define RPIPCGM_DEVICEACTIVITY (WM_APP + 12) + +// Message: +// RPIPCGM_MOUSECAPTURE +// Description: +// the guest sends this message when the mouse is captured/released +// (the mouse is "captured" when its movements are restricted to the guest window area +// and the system cursor is not visible); +// for consistency across different guests, a guest which sends RPIPCGM_MOUSECAPTURE +// messages should also implement a keyboard-actuated mouse release functionality +// (the preferred key for this purpose is included in the parameters sent from the +// host at startup time - see RPLaunchGuest() in RetroPlatformPlugin.h); +// note that in order not to interfere with the window dragging functionality, +// the mouse should not be captured when the guest window gets the focus, +// but when a mouse button event is received +// Data sent: +// WPARAM = non-zero if the mouse has been captured, +// zero if the mouse has been released +// Response: +// none +// +#define RPIPCGM_MOUSECAPTURE (WM_APP + 13) + +// Message: +// RPIPCGM_HOSTAPIVERSION +// Description: +// the guest can send a RPIPCGM_HOSTAPIVERSION to query the host +// about the RetroPlatform API version it implements; +// since the guest plugin already asks for a minimim version of the API +// on the host side, this message can be used to check the host API version +// and enable optional functionality +// Data sent: +// none +// Response: +// LRESULT = major and minor version combined with the MAKELONG macro +// (e.g. LOWORD(lr) = major version; HIWORD(lr) = minor version) +// +#define RPIPCGM_HOSTAPIVERSION (WM_APP + 14) + +// Message: +// RPIPCGM_PAUSE +// Description: +// the guest sends this message to the host +// when it enters or exits pause mode; +// pause mode changes requested by the host +// (see the RPIPCHM_PAUSE message) must not be notified; +// note: when paused, the guest should release the mouse (if captured) +// Data sent: +// WPARAM = non-zero when the guest enters pause mode +// or zero when the guest exits from pause mode +// Response: +// none +// +#define RPIPCGM_PAUSE (WM_APP + 15) + +// Message: +// RPIPCGM_DEVICEIMAGE +// Description: +// the guest sends a RPIPCGM_DEVICEIMAGE message +// to notify the host that an image file has been loaded into +// (or ejected from) an emulated device; +// this notification must not be sent when the event +// has been requested by the host (see the RPIPCHM_DEVICEIMAGE message) +// Data sent: +// pData = a RPDEVICEIMAGE structure (see below); +// the szImageFile field of the structure +// contains an empty string when the guest +// is ejecting an image file from the device +// Response: +// none +// +#define RPIPCGM_DEVICEIMAGE (WM_APP + 16) + +// Message: +// RPIPCGM_TURBO +// Description: +// the guest sends a RPIPCGM_TURBO message +// to notify the host about activation of "turbo" (maximum speed) mode +// of some of its functionalities (e.g. floppy, CPU); +// turbo mode activations/deactivations requested by the host +// (see the RPIPCHM_TURBO message) must not be notified; +// Data sent: +// WPARAM = mask of functionalities affected (RP_TURBO_* flags) +// LPARAM = bits corresponding to those set in WPARAM +// (1 = turbo mode activated for the guest functionality +// 0 = guest functionality reverted to normal speed) +// Response: +// none +// +#define RPIPCGM_TURBO (WM_APP + 17) + +// Message: +// RPIPCGM_INPUTMODE +// Description: +// the RPIPCGM_INPUTMODE message can be used +// to notify the host about activation +// of the specified input mode (e.g. keyboard vs. game controller) +// of the guest; input mode changes requested by the host +// (see the RPIPCHM_INPUTMODE message) must not be notified +// Data sent: +// WPARAM = input mode activated (RP_INPUTMODE_* value) +// Response: +// none +// +#define RPIPCGM_INPUTMODE (WM_APP + 18) + +// Message: +// RPIPCGM_VOLUME +// Description: +// the guest uses the RPIPCGM_VOLUME message +// to notify the host about a change of its audio level; +// audio level changes requested by the host +// (see the RPIPCHM_VOLUME message) must not be notified +// Data sent: +// WPARAM = volume level (min/off 0, max 100) +// Response: +// none +// +#define RPIPCGM_VOLUME (WM_APP + 19) + + + + +// **************************************************************************** +// Host-to-Guest Messages +// **************************************************************************** + +// Message: +// RPIPCHM_CLOSE +// Description: +// sent from the host when the emulation must be terminated +// (e.g. the user has hit the close button in the host window); +// the guest should destroy its window and terminate (see Response below) +// Data sent: +// none +// Response: +// LRESULT = non-zero if the guest can safely terminate or 0 otherwise +// +#define RPIPCHM_CLOSE (WM_APP + 200) + +// Message: +// RPIPCHM_MINIMIZE +// Description: +// sent from the host when the emulation window must be minimized +// Data sent: +// none +// Response: +// LRESULT = non-zero if the guest can minimized its window or 0 otherwise +// +#define RPIPCHM_MINIMIZE (WM_APP + 201) + +// Message: +// RPIPCHM_SCREENMODE +// Description: +// this message is sent to ask the guest to activate a specified screen mode; +// when switching to the new screen mode, the guest can resize (reuse) its window +// or close its window and open a new one +// Data sent: +// WPARAM = RP_SCREENMODE_* value +// Response: +// LRESULT = handle of the (new) guest window +// or NULL (the screen mode couldn't be changed) +// or INVALID_HANDLE_VALUE (the screen mode will be changed asynchronously +// and the host will soon get a RPIPCGM_SCREENMODE notification) +// +#define RPIPCHM_SCREENMODE (WM_APP + 202) + +// Message: +// RPIPCHM_SCREENCAPTURE +// Description: +// with this message the host asks the guest to save its screen +// to the the specified file in BMP format +// Data sent: +// pData = (Unicode) full path and name of the file to save +// (note: the file may exist and can be overwritten) +// Response: +// LRESULT = non-zero if the guest saved its screen to the file +// +#define RPIPCHM_SCREENCAPTURE (WM_APP + 203) + +// Message: +// RPIPCHM_PAUSE +// Description: +// the RPIPCHM_PAUSE message sets the guest into pause mode +// or resumes the guest from pause mode; +// note: when paused, the guest should release the mouse (if captured) +// Data sent: +// WPARAM = non-zero to set the guest into pause mode +// or zero to resume the guest from pause mode +// Response: +// LRESULT = non-zero if the guest executed the command +// +#define RPIPCHM_PAUSE (WM_APP + 204) + +// Message: +// RPIPCHM_DEVICEIMAGE +// Description: +// the host sends a RPIPCHM_DEVICEIMAGE message +// to load an image file into an emulated device +// (e.g. an ADF floppy file into a floppy drive) +// or to unload the currently loaded image from the device +// Data sent: +// pData = a RPDEVICEIMAGE structure (see below); +// if the szImageFile field of the structure +// contains an empty string, the guest should +// unload the current image file from the device +// Response: +// LRESULT = non-zero if the guest executed the command +// +#define RPIPCHM_DEVICEIMAGE (WM_APP + 205) + +// Message: +// RPIPCHM_RESET +// Description: +// the host sends this message to reset the guest +// Data sent: +// WPARAM = a RP_RESET_* value +// Response: +// LRESULT = non-zero if the guest executed the command +// +#define RPIPCHM_RESET (WM_APP + 206) + +// Message: +// RPIPCHM_TURBO +// Description: +// the host sends this message to activate or deactivate +// the turbo mode of selected guest functionalities +// Data sent: +// WPARAM = mask of functionalities to change (RP_TURBO_* flags) +// LPARAM = bits corresponding to those set in WPARAM +// (1 = speedup the guest functionality +// 0 = revert to normal speed emulation) +// Response: +// LRESULT = non-zero if the guest executed the command +// +#define RPIPCHM_TURBO (WM_APP + 207) + +// Message: +// RPIPCHM_INPUTMODE +// Description: +// the RPIPCHM_INPUTMODE message activates +// the specified input mode of the guest +// Data sent: +// WPARAM = input mode (RP_INPUTMODE_* value) +// Response: +// LRESULT = non-zero if the guest executed the command +// +#define RPIPCHM_INPUTMODE (WM_APP + 208) + +// Message: +// RPIPCHM_VOLUME +// Description: +// the host uses the RPIPCHM_VOLUME message to set +// the audio level of the guest +// Data sent: +// WPARAM = volume level (min 0, max 100) +// Response: +// LRESULT = non-zero if the guest set the volume as requested +// +#define RPIPCHM_VOLUME (WM_APP + 209) + + + +// **************************************************************************** +// Message Data Structures and Defines +// **************************************************************************** + +// Guest Features +#define RP_FEATURE_POWERLED 0x00000001 // a power LED is emulated +#define RP_FEATURE_SCREEN1X 0x00000002 // 1x windowed mode is available +#define RP_FEATURE_SCREEN2X 0x00000004 // 2x windowed mode is available +#define RP_FEATURE_SCREEN4X 0x00000008 // 4x windowed mode is available +#define RP_FEATURE_FULLSCREEN 0x00000010 // full screen display is available +#define RP_FEATURE_SCREENCAPTURE 0x00000020 // screen capture functionality is available (see RPIPCHM_SCREENCAPTURE message) +#define RP_FEATURE_PAUSE 0x00000040 // pause functionality is available (see RPIPCHM_PAUSE message) +#define RP_FEATURE_TURBO 0x00000080 // turbo mode functionality is available (see RPIPCHM_TURBO message) +#define RP_FEATURE_INPUTMODE 0x00000100 // input mode switching is supported (see RPIPCHM_INPUTMODE message) +#define RP_FEATURE_VOLUME 0x00000200 // volume adjustment is possible (see RPIPCHM_VOLUME message) + +// Screen Modes +#define RP_SCREENMODE_1X 0 // 1x windowed mode +#define RP_SCREENMODE_2X 1 // 2x windowed mode +#define RP_SCREENMODE_4X 2 // 4x windowed mode +#define RP_SCREENMODE_FULLSCREEN 3 // full screen + +// Device Categories +#define RP_DEVICE_FLOPPY 0 // floppy disk drive +#define RP_DEVICE_HD 1 // hard disk drive +#define RP_DEVICE_CD 2 // CD/DVD drive +#define RP_DEVICE_NET 3 // network card +#define RP_DEVICE_TAPE 4 // cassette tape drive +#define RP_DEVICE_CARTRIDGE 5 // expansion cartridge + +typedef struct RPDeviceImage +{ + BYTE btDeviceCategory; // RP_DEVICE_* value + BYTE btDeviceNumber; // device number (range 0..31) + WCHAR szImageFile[1]; // full path and name of the image file to load (Unicode, variable-sized field) +} RPDEVICEIMAGE; + +// Turbo Mode Functionalities +#define RP_TURBO_CPU 0x00000001 // CPU +#define RP_TURBO_FLOPPY 0x00000002 // floppy disk drive +#define RP_TURBO_TAPE 0x00000004 // cassette tape drive + +// Input Modes +#define RP_INPUTMODE_KEYBOARD 0 // the keyboard is used to simulate a joystick +#define RP_INPUTMODE_JOYSTICK 1 // use the joystick connected to the system + +// Reset Type +#define RP_RESET_SOFT 0 // soft reset +#define RP_RESET_HARD 1 // hard reset + + +#endif // __CLOANTO_RETROPLATFORMIPC_H__ diff --git a/od-win32/hardfile_win32.c b/od-win32/hardfile_win32.c index 751902bd..45068e41 100644 --- a/od-win32/hardfile_win32.c +++ b/od-win32/hardfile_win32.c @@ -1079,15 +1079,25 @@ static int hmc (struct hardfiledata *hfd, int nr) int first = 1; while (hfd->handle_valid) { +// write_log ("testing if %s:%d has media inserted\n", hfd->emptyname, nr); status = 0; SetFilePointer (hfd->handle, 0, NULL, FILE_BEGIN); ret = ReadFile (hfd->handle, buf, hfd->blocksize, &got, NULL); err = GetLastError (); +// if (ret) +// write_log ("read ok\n"); +// else +// write_log ("=%d\n", err); if (!ret && err == ERROR_DEV_NOT_EXIST) { if (!first) break; first = 0; hdf_open (hfd, hfd->emptyname); + if (!hfd->handle_valid) { + /* whole device has disappeared */ + status = -1; + goto end; + } continue; } break; @@ -1096,7 +1106,9 @@ static int hmc (struct hardfiledata *hfd, int nr) status = 1; if (!ret && !hfd->drive_empty && isnomediaerr (err)) status = -1; +end: xfree (buf); + //write_log("hmc returned %d\n", status); return status; } @@ -1120,7 +1132,11 @@ int win32_hardfile_media_change (void) } if (hfd->drive_empty < 0 || !hfd->handle_valid) { int empty = hfd->drive_empty; - if (!hdf_open (hfd, hfd->emptyname)) + int r; + //write_log ("trying to open '%s' de=%d hv=%d\n", hfd->emptyname, hfd->drive_empty, hfd->handle_valid); + r = hdf_open (hfd, hfd->emptyname); + //write_log ("=%d\n", r); + if (!r) continue; reopen = 1; if (hfd->drive_empty < 0) @@ -1141,6 +1157,7 @@ int win32_hardfile_media_change (void) } hardfile_do_disk_change (i, ret < 0 ? 0 : 1); } + //write_log ("win32_hardfile_media_change returned %d\n", gotinsert); return gotinsert; } diff --git a/od-win32/mman.c b/od-win32/mman.c index d2c10a29..9fe2cd6c 100644 --- a/od-win32/mman.c +++ b/od-win32/mman.c @@ -301,7 +301,8 @@ void *shmat(int shmid, void *shmaddr, int shmflg) p96ram_start = p96mem_offset - natmem_offset; shmaddr = natmem_offset + p96ram_start; } else { - p96ram_start = currprefs.z3fastmem_start + ((currprefs.z3fastmem_size + 0xffffff) & ~0xffffff); + extern void p96memstart(void); + p96memstart(); shmaddr = natmem_offset + p96ram_start; virtualfreewithlock(shmaddr, os_winnt ? size : 0, os_winnt ? MEM_DECOMMIT : MEM_RELEASE); xfree(p96fakeram); diff --git a/od-win32/rp.c b/od-win32/rp.c new file mode 100644 index 00000000..5b46d3e9 --- /dev/null +++ b/od-win32/rp.c @@ -0,0 +1,292 @@ + +#include +#include +#include + +#include + +#include "cloanto/RetroPlatformGuestIPC.h" +#include "cloanto/RetroPlatformIPC.h" +#include "rp.h" + +#include "sysconfig.h" +#include "sysdeps.h" +#include "options.h" +#include "uae.h" +#include "inputdevice.h" +#include "audio.h" +#include "sound.h" +#include "disk.h" +#include "xwin.h" +#include "picasso96_win.h" +#include "win32.h" +#include "win32gfx.h" + +static int initialized; +static RPGUESTINFO guestinfo; +char *rp_param; +static int default_width, default_height; +static int hwndset; +static int minimized; + + +const char *getmsg (int msg) +{ + switch (msg) + { + case RPIPCGM_REGISTER: return "RPIPCGM_REGISTER"; + case RPIPCGM_FEATURES: return "RPIPCGM_FEATURES"; + case RPIPCGM_CLOSED: return "RPIPCGM_CLOSED"; + case RPIPCGM_ACTIVATED: return "RPIPCGM_ACTIVATED"; + case RPIPCGM_DEACTIVATED: return "RPIPCGM_DEACTIVATED"; + case RPIPCGM_ZORDER: return "RPIPCGM_ZORDER"; + case RPIPCGM_MINIMIZED: return "RPIPCGM_MINIMIZED"; + case RPIPCGM_RESTORED: return "RPIPCGM_RESTORED"; + case RPIPCGM_MOVED: return "RPIPCGM_MOVED"; + case RPIPCGM_SCREENMODE: return "RPIPCGM_SCREENMODE"; + case RPIPCGM_POWERLED: return "RPIPCGM_POWERLED"; + case RPIPCGM_DEVICES: return "RPIPCGM_DEVICES"; + case RPIPCGM_DEVICEACTIVITY: return "RPIPCGM_DEVICEACTIVITY"; + case RPIPCGM_MOUSECAPTURE: return "RPIPCGM_MOUSECAPTURE"; + case RPIPCGM_HOSTAPIVERSION: return "RPIPCGM_HOSTAPIVERSION"; + case RPIPCGM_PAUSE: return "RPIPCGM_PAUSE"; + case RPIPCGM_DEVICEIMAGE: return "RPIPCGM_DEVICEIMAGE"; + case RPIPCGM_TURBO: return "RPIPCGM_TURBO"; + case RPIPCGM_INPUTMODE: return "RPIPCGM_INPUTMODE"; + case RPIPCGM_VOLUME: return "RPIPCGM_VOLUME"; + + case RPIPCHM_CLOSE: return "RPIPCHM_CLOSE"; + case RPIPCHM_MINIMIZE: return "RPIPCHM_MINIMIZE"; + case RPIPCHM_SCREENMODE: return "RPIPCHM_SCREENMODE"; + case RPIPCHM_SCREENCAPTURE: return "RPIPCHM_SCREENCAPTURE"; + case RPIPCHM_PAUSE: return "RPIPCHM_PAUSE"; + case RPIPCHM_DEVICEIMAGE: return "RPIPCHM_DEVICEIMAGE"; + case RPIPCHM_RESET: return "RPIPCHM_RESET"; + case RPIPCHM_TURBO: return "RPIPCHM_TURBO"; + case RPIPCHM_INPUTMODE: return "RPIPCHM_INPUTMODE"; + case RPIPCHM_VOLUME: return "RPIPCHM_VOLUME"; + + default: return "UNKNOWN"; + } +} + +BOOL RPSendMessagex(UINT uMessage, WPARAM wParam, LPARAM lParam, + LPCVOID pData, DWORD dwDataSize, const RPGUESTINFO *pInfo, LRESULT *plResult) +{ + BOOL v = RPSendMessage (uMessage, wParam, lParam, pData, dwDataSize, pInfo, plResult); + write_log ("RPSEND(%s [%d], %08x, %08x, %08x, %d\n", + getmsg (uMessage), uMessage - WM_APP, wParam, lParam, pData, dwDataSize); + return v; +} + +static char *ua (WCHAR *s) +{ + char *d; + int len = WideCharToMultiByte (CP_ACP, 0, s, -1, NULL, 0, 0, FALSE); + if (!len) + return ""; + d = xmalloc (len + 1); + WideCharToMultiByte (CP_ACP, 0, s, -1, d, len, 0, FALSE); + return d; +} + +static int winok(void) +{ + if (!initialized) + return 0; + if (!hwndset) + return 0; + if (minimized) + return 0; + return 1; +} + +static int get_x (void) +{ + int res = currprefs.gfx_resolution; + + if (res == 0) + return RP_SCREENMODE_1X; + if (res == 1) + return RP_SCREENMODE_2X; + return RP_SCREENMODE_4X; +} + +static LRESULT CALLBACK RPHostMsgFunction(UINT uMessage, WPARAM wParam, LPARAM lParam, + LPCVOID pData, DWORD dwDataSize, LPARAM lMsgFunctionParam) +{ + write_log ("RPFUNC(%s [%d], %08x, %08x, %08x, %d, %08x)\n", + getmsg (uMessage), uMessage - WM_APP, wParam, lParam, pData, dwDataSize, lMsgFunctionParam); + + switch (uMessage) + { + default: + write_log ("Unknown or unsupported command\n"); + break; + case RPIPCHM_CLOSE: + uae_quit (); + return TRUE; + case RPIPCHM_RESET: + uae_reset (wParam == RP_RESET_SOFT ? 0 : -1); + return TRUE; + case RPIPCHM_TURBO: + warpmode (lParam); + return TRUE; + case RPIPCHM_PAUSE: + pausemode (lParam); + return TRUE; + case RPIPCHM_VOLUME: + currprefs.sound_volume = changed_prefs.sound_volume = wParam; + set_volume (currprefs.sound_volume, 0); + return TRUE; + case RPIPCHM_SCREENCAPTURE: + screenshot (1, 1); + return TRUE; + case RPIPCHM_MINIMIZE: + minimized = 1; + if (ShowWindow (hAmigaWnd, SW_MINIMIZE)) + return TRUE; + break; + case RPIPCHM_DEVICEIMAGE: + { + RPDEVICEIMAGE *di = (RPDEVICEIMAGE*)pData; + if (di->btDeviceCategory == RP_DEVICE_FLOPPY) { + char *fn = ua (di->szImageFile); + disk_insert (di->btDeviceNumber, fn); + xfree (fn); + } + return TRUE; + } + case RPIPCHM_SCREENMODE: + { + BYTE mode = (BYTE)wParam; + int res = (mode == RP_SCREENMODE_1X) ? 0 : ((mode == RP_SCREENMODE_2X) ? 1 : 2); + minimized = 0; + changed_prefs.gfx_resolution = res; + if (res == 0) + changed_prefs.gfx_linedbl = 0; + else + changed_prefs.gfx_linedbl = 1; + res = 1 << res; + changed_prefs.gfx_size_win.width = default_width * res; + changed_prefs.gfx_size_win.height = default_height * res; + WIN32GFX_DisplayChangeRequested(); + hwndset = 0; + return (LRESULT)INVALID_HANDLE_VALUE; + } + } + return FALSE; +} + +HRESULT rp_init (void) +{ + HRESULT hr; + + hr = RPInitializeGuest(&guestinfo, hInst, rp_param, RPHostMsgFunction, 0); + if (SUCCEEDED (hr)) { + initialized = TRUE; + write_log ("rp_init('%s') succeeded\n", rp_param); + } else { + write_log ("rp_init('%s') failed, error code %08x\n", rp_param, hr); + } + return hr; +} + +void rp_free (void) +{ + if (!initialized) + return; + initialized = 0; + RPSendMessagex(RPIPCGM_CLOSED, 0, 0, NULL, 0, &guestinfo, NULL); + RPUninitializeGuest (&guestinfo); +} + +void rp_fixup_options (struct uae_prefs *p) +{ + int i, v; + int res; + + if (!initialized) + return; + p->win32_borderless = 1; + RPSendMessagex(RPIPCGM_FEATURES, + RP_FEATURE_POWERLED | RP_FEATURE_SCREEN1X | RP_FEATURE_SCREEN2X | + RP_FEATURE_PAUSE | RP_FEATURE_TURBO | RP_FEATURE_INPUTMODE | RP_FEATURE_VOLUME, + 0, NULL, 0, &guestinfo, NULL); + /* floppy drives */ + v = 0; + for (i = 0; i < 4; i++) { + if (p->dfxtype[i] >= 0) + v |= 1 << i; + } + RPSendMessagex(RPIPCGM_DEVICES, RP_DEVICE_FLOPPY, v, NULL, 0, &guestinfo, NULL); + res = 1 << currprefs.gfx_resolution; + default_width = currprefs.gfx_size_win.width / res; + default_height = currprefs.gfx_size_win.height / res; +} + +void rp_update_leds (int led, int onoff) +{ + if (!initialized) + return; + if (led < 0 || led > 4) + return; + switch (led) + { + case 0: + RPSendMessage(RPIPCGM_POWERLED, onoff ? 100 : 0, 0, NULL, 0, &guestinfo, NULL); + break; + case 1: + case 2: + case 3: + case 4: + RPSendMessage(RPIPCGM_DEVICEACTIVITY, MAKEWORD (RP_DEVICE_FLOPPY, led - 1), onoff ? -1 : 0, NULL, 0, &guestinfo, NULL); + break; + } +} + +void rp_update_status (struct uae_prefs *p) +{ + if (!initialized) + return; + RPSendMessagex(RPIPCGM_VOLUME, (WPARAM)p->sound_volume, 0, NULL, 0, &guestinfo, NULL); +} + +void rp_mousecapture (int captured) +{ + if (!winok()) + return; + RPSendMessagex(RPIPCGM_MOUSECAPTURE, captured, 0, NULL, 0, &guestinfo, NULL); +} + +void rp_activate (int active) +{ + if (!winok()) + return; + RPSendMessagex(active ? RPIPCGM_ACTIVATED : RPIPCGM_DEACTIVATED, 0, 0, NULL, 0, &guestinfo, NULL); +} + +void rp_turbo (int active) +{ + if (!initialized) + return; + RPSendMessagex(RPIPCGM_TURBO, RP_TURBO_CPU, active, NULL, 0, &guestinfo, NULL); +} + +void rp_set_hwnd (void) +{ + int rx; + if (!initialized) + return; + rx = get_x (); + hwndset = 1; + RPSendMessagex(RPIPCGM_SCREENMODE, rx, (LPARAM)hAmigaWnd, NULL, 0, &guestinfo, NULL); + rp_mousecapture (1); +} + +void rp_moved (int zorder) +{ + if (!winok()) + return; + RPSendMessagex(zorder ? RPIPCGM_ZORDER : RPIPCGM_MOVED, 0, 0, NULL, 0, &guestinfo, NULL); +} \ No newline at end of file diff --git a/od-win32/rp.h b/od-win32/rp.h new file mode 100644 index 00000000..fd9a7319 --- /dev/null +++ b/od-win32/rp.h @@ -0,0 +1,13 @@ + +extern HRESULT rp_init (void); +extern void rp_free (void); +extern void rp_fixup_options (struct uae_prefs*); +extern void rp_update_status (struct uae_prefs*); +extern void rp_update_leds (int, int); +extern void rp_activate (int); +extern void rp_mousecapture (int); +extern void rp_turbo (int); +extern void rp_set_hwnd (void); +extern void rp_moved (int); + +extern char *rp_param; diff --git a/od-win32/serial_win32.c b/od-win32/serial_win32.c index 7bfebe07..5f95f501 100644 --- a/od-win32/serial_win32.c +++ b/od-win32/serial_win32.c @@ -53,25 +53,22 @@ void SERPER (uae_u16 w) if (serper == w) /* don't set baudrate if it's already ok */ return; + ninebit = 0; serper = w; - - if (w & 0x8000) { - if (!warned) { - write_log ("SERIAL: program uses 9bit mode PC=%x\n", M68K_GETPC); - warned++; - } + if (w & 0x8000) ninebit = 1; - } w &= 0x7fff; if (w < 13) w = 13; per = w; - if (per == 0) per = 1; + if (per == 0) + per = 1; per = 3546895 / (per + 1); - if (per <= 0) per = 1; + if (per <= 0) + per = 1; i = 0; while (allowed_baudrates[i] >= 0 && per > allowed_baudrates[i] * 100 / 97) i++; @@ -82,7 +79,7 @@ void SERPER (uae_u16 w) serial_period_hsyncs = 1; serial_period_hsync_counter = 0; - write_log ("SERIAL: period=%d, baud=%d, hsyncs=%d PC=%x\n", w, baud, serial_period_hsyncs, M68K_GETPC); + write_log ("SERIAL: period=%d, baud=%d, hsyncs=%d, bits=%d, PC=%x\n", w, baud, serial_period_hsyncs, ninebit ? 9 : 8, M68K_GETPC); if (ninebit) baud *= 2; diff --git a/od-win32/sounddep/sound.c b/od-win32/sounddep/sound.c index a2fb5130..20dd096c 100644 --- a/od-win32/sounddep/sound.c +++ b/od-win32/sounddep/sound.c @@ -192,13 +192,13 @@ static void close_audio_ds (void) extern HWND hMainWnd; extern void setvolume_ahi(LONG); -static void setvolume (void) +void set_volume (int volume, int mute) { HRESULT hr; LONG vol = DSBVOLUME_MIN; - if (currprefs.sound_volume < 100 && !mute) - vol = (LONG)((DSBVOLUME_MIN / 2) + (-DSBVOLUME_MIN / 2) * log (1 + (2.718281828 - 1) * (1 - currprefs.sound_volume / 100.0))); + if (volume < 100 && !mute) + vol = (LONG)((DSBVOLUME_MIN / 2) + (-DSBVOLUME_MIN / 2) * log (1 + (2.718281828 - 1) * (1 - volume / 100.0))); hr = IDirectSoundBuffer_SetVolume (lpDSBsecondary, vol); if (FAILED(hr)) write_log ("SOUND: SetVolume(%d) failed: %s\n", vol, DXError (hr)); @@ -424,7 +424,7 @@ static int open_audio_ds (int size) } IDirectSound_Release(pdsb); - setvolume (); + set_volume (currprefs.sound_volume, mute); cleardsbuffer (); init_sound_table16 (); if (get_audio_amigachannels() == 4) @@ -1014,7 +1014,7 @@ void sound_volume (int dir) if (currprefs.sound_volume > 100) currprefs.sound_volume = 100; changed_prefs.sound_volume = currprefs.sound_volume; - setvolume (); + set_volume (currprefs.sound_volume, mute); } void master_sound_volume (int dir) { diff --git a/od-win32/sounddep/sound.h b/od-win32/sounddep/sound.h index bb604703..4ea9777e 100644 --- a/od-win32/sounddep/sound.h +++ b/od-win32/sounddep/sound.h @@ -23,6 +23,7 @@ extern char **enumerate_sound_devices (int *total); extern int drivesound_init (void); extern void drivesound_free (void); extern void sound_volume (int); +extern void set_volume (int, int); extern void master_sound_volume (int); STATIC_INLINE void check_sound_buffers (void) diff --git a/od-win32/sysconfig.h b/od-win32/sysconfig.h index ff35aa8a..5701d2e4 100644 --- a/od-win32/sysconfig.h +++ b/od-win32/sysconfig.h @@ -57,6 +57,7 @@ #define NCR /* A4000T/A4091 SCSI */ #define SANA2 /* SANA2 network driver */ #define AMAX /* A-Max ROM adapater emulation */ +#define RETROPLATFORM /* Cloanto RetroPlayer support */ #else diff --git a/od-win32/tun.c b/od-win32/tun.c index f39aba68..c6256e73 100644 --- a/od-win32/tun.c +++ b/od-win32/tun.c @@ -83,8 +83,8 @@ const struct tap_reg *get_tap_reg (void) &len); if (status != ERROR_SUCCESS || data_type != REG_SZ) - write_log ("Error opening registry key: %s\\%s\n", - unit_string, component_id_string); + ;//write_log ("Error opening registry key: %s\\%s\n", + // unit_string, component_id_string); else { len = sizeof (net_cfg_instance_id); diff --git a/od-win32/win32.c b/od-win32/win32.c index 87c6ffc7..dbb16c35 100644 --- a/od-win32/win32.c +++ b/od-win32/win32.c @@ -68,9 +68,12 @@ #include "ar.h" #include "akiko.h" #include "cdtv.h" +#ifdef RETROPLATFORM +#include "rp.h" +#endif extern FILE *debugfile; -extern int console_logging; +extern int console_logging = 0; static OSVERSIONINFO osVersion; static SYSTEM_INFO SystemInfo; @@ -554,6 +557,9 @@ void setmouseactive (int active) } if (!active) checkpause (); +#ifdef RETROPLATFORM + rp_mousecapture (active); +#endif } #ifndef AVIOUTPUT @@ -615,6 +621,9 @@ static void winuae_active (HWND hWnd, int minimized) if (isfullscreen() > 0 && !gui_active) setmouseactive (1); manual_palette_refresh_needed = 1; +#ifdef RETROPLATFORM + rp_activate (1); +#endif } @@ -656,10 +665,14 @@ static void winuae_inactive (HWND hWnd, int minimized) #ifdef FILESYS filesys_flush_cache (); #endif +#ifdef RETROPLATFORM + rp_activate (0); +#endif } void minimizewindow (void) { + write_log("minimize\n"); ShowWindow (hMainWnd, SW_MINIMIZE); } @@ -942,11 +955,17 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, return 0; case WM_WINDOWPOSCHANGED: + { + WINDOWPOS *wp = (WINDOWPOS *)lParam; GetWindowRect (hWnd, &amigawin_rect); if (isfullscreen() == 0) { changed_prefs.gfx_size_win.x = amigawin_rect.left; changed_prefs.gfx_size_win.y = amigawin_rect.top; } +#ifdef RETROPLATFORM + rp_moved (!(wp->flags & SWP_NOZORDER)); +#endif + } break; case WM_MOUSEMOVE: @@ -1060,6 +1079,7 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, win32_aspi_media_change (drive, inserted); } if (type == DRIVE_REMOVABLE || type == DRIVE_CDROM || !inserted) { + write_log("WM_DEVICECHANGE '%s' type=%d inserted=%d\n", drvname, type, inserted); if (!win32_hardfile_media_change ()) { if ((inserted && CheckRM (drvname)) || !inserted) filesys_media_change (drvname, inserted, NULL); @@ -1826,6 +1846,13 @@ static get_aspi(int old) return UAESCSI_ADAPTECASPI; } +void target_fixup_options (struct uae_prefs *p) +{ +#ifdef RETROPLATFORM + rp_fixup_options (p); +#endif +} + void target_default_options (struct uae_prefs *p, int type) { if (type == 2 || type == 0) { @@ -1859,6 +1886,10 @@ void target_default_options (struct uae_prefs *p, int type) p->win32_uaescsimode = get_aspi(p->win32_uaescsimode); p->win32_midioutdev = -2; p->win32_midiindev = 0; + p->win32_automount_removable = 0; + p->win32_automount_drives = 0; + p->win32_automount_cddrives = 0; + p->win32_automount_netdrives = 0; } } @@ -2950,6 +2981,12 @@ static int process_arg(char **xargv) force_direct_catweasel = getval (argv[++i]); continue; } +#ifdef RETROPLATFORM + if (!_strnicmp (arg, "/rphost:", 8) || !_strnicmp (arg, "-rphost:", 8)) { + rp_param = arg + 8; + continue; + } +#endif if (i + 1 < argc) { char *np = argv[i + 1]; @@ -3081,6 +3118,9 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR } } +#ifdef RETROPLATFORM + rp_free (); +#endif closeIPC(); write_disk_history (); if (mm_timerres && timermode == 0) @@ -3468,17 +3508,17 @@ int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin SETPROCESSDPIAWARE pSetProcessDPIAware; DWORD_PTR sys_aff; HANDLE thread; - CHANGEWINDOWMESSAGEFILTER pChangeWindowMessageFilter; original_affinity = 1; GetProcessAffinityMask (GetCurrentProcess(), &original_affinity, &sys_aff); thread = GetCurrentThread(); original_affinity = SetThreadAffinityMask(thread, 1); - pChangeWindowMessageFilter = (CHANGEWINDOWMESSAGEFILTER)GetProcAddress( - GetModuleHandle("user32.dll"), "ChangeWindowMessageFilter"); #if 0 #define MSGFLT_ADD 1 + CHANGEWINDOWMESSAGEFILTER pChangeWindowMessageFilter; + pChangeWindowMessageFilter = (CHANGEWINDOWMESSAGEFILTER)GetProcAddress( + GetModuleHandle("user32.dll"), "ChangeWindowMessageFilter"); if (pChangeWindowMessageFilter) pChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD); #endif @@ -3492,9 +3532,7 @@ int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin WinMain2 (hInstance, hPrevInstance, lpCmdLine, nCmdShow); } __except(WIN32_ExceptionFilter(GetExceptionInformation(), GetExceptionCode())) { } -#if 0 SetThreadAffinityMask(thread, original_affinity); -#endif return FALSE; } diff --git a/od-win32/win32.h b/od-win32/win32.h index d4302f8f..bcf21193 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -15,9 +15,9 @@ #define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100) #define GETBDD(x) ((x) % 100) -#define WINUAEBETA 7 +#define WINUAEBETA 8 #define WINUAEPUBLICBETA 1 -#define WINUAEDATE MAKEBD(2007, 10, 31) +#define WINUAEDATE MAKEBD(2007, 11, 8) #define WINUAEEXTRA "" #define WINUAEREV "" diff --git a/od-win32/win32_uaenet.c b/od-win32/win32_uaenet.c new file mode 100644 index 00000000..a7f83b3f --- /dev/null +++ b/od-win32/win32_uaenet.c @@ -0,0 +1,186 @@ +/* + * UAE - The Un*x Amiga Emulator + * + * Win32 uaenet emulation + * + * Copyright 1997 Mathias Ortmann + * Copyright 1998-1999 Brian King - added MIDI output support + */ + +#include "sysconfig.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "sysdeps.h" +#include "options.h" + +#include "threaddep/thread.h" +#include "win32_uaenet.h" + +struct uaenetdatawin32 +{ + HANDLE hCom; + HANDLE evtr, evtw, evtt, evtwce; + OVERLAPPED olr, olw, olwce; + int writeactive; + void *readdata, *writedata; + volatile int threadactive; + uae_thread_id tid; + uae_sem_t change_sem, sync_sem; + void *user; +}; + +int uaenet_getdatalenght (void) +{ + return sizeof (struct uaenetdatawin32); +} + +static void uaeser_initdata (struct uaenetdatawin32 *sd, void *user) +{ + memset (sd, 0, sizeof (struct uaenetdatawin32)); + sd->hCom = INVALID_HANDLE_VALUE; + sd->evtr = sd->evtw = sd->evtt = sd->evtwce = 0; + sd->user = user; +} + +static void *uaenet_trap_thread (void *arg) +{ + struct uaenetdatawin32 *sd = arg; + HANDLE handles[4]; + int cnt, actual; + DWORD evtmask; + + uae_set_thread_priority (2); + sd->threadactive = 1; + uae_sem_post (&sd->sync_sem); + while (sd->threadactive == 1) { + int sigmask = 0; + uae_sem_wait (&sd->change_sem); + if (WaitForSingleObject(sd->evtwce, 0) == WAIT_OBJECT_0) { + if (evtmask & EV_RXCHAR) + sigmask |= 1; + if ((evtmask & EV_TXEMPTY) && !sd->writeactive) + sigmask |= 2; + //startwce(sd, &evtmask); + } + cnt = 0; + handles[cnt++] = sd->evtt; + handles[cnt++] = sd->evtwce; + if (sd->writeactive) { + if (GetOverlappedResult (sd->hCom, &sd->olw, &actual, FALSE)) { + sd->writeactive = 0; + sigmask |= 2; + } else { + handles[cnt++] = sd->evtw; + } + } + if (!sd->writeactive) + sigmask |= 2; + uaenet_signal (sd->user, sigmask | 1); + uae_sem_post (&sd->change_sem); + WaitForMultipleObjects(cnt, handles, FALSE, INFINITE); + } + sd->threadactive = 0; + uae_sem_post (&sd->sync_sem); + return 0; +} + +void uaenet_trigger (struct uaenetdatawin32 *sd) +{ + SetEvent (sd->evtt); +} + +int uaenet_write (struct uaenetdatawin32 *sd, uae_u8 *data, uae_u32 len) +{ + int ret = 1; + if (!WriteFile (sd->hCom, data, len, NULL, &sd->olw)) { + sd->writeactive = 1; + if (GetLastError() != ERROR_IO_PENDING) { + ret = 0; + sd->writeactive = 0; + } + } + SetEvent (sd->evtt); + return ret; +} + +int uaenet_read (struct uaenetdatawin32 *sd, uae_u8 *data, uae_u32 len) +{ + int ret = 1; + DWORD err; + + if (!ReadFile (sd->hCom, data, len, NULL, &sd->olr)) { + if (GetLastError() == ERROR_IO_PENDING) + WaitForSingleObject(sd->evtr, INFINITE); + else + ret = 0; + } + SetEvent (sd->evtt); + return ret; +} + +int uaenet_open (struct uaenetdatawin32 *sd, void *user, int unit) +{ + char buf[256]; + + sd->user = user; + sprintf (buf, "\\.\\\\COM%d", unit); + sd->evtr = CreateEvent (NULL, TRUE, FALSE, NULL); + sd->evtw = CreateEvent (NULL, TRUE, FALSE, NULL); + sd->evtt = CreateEvent (NULL, FALSE, FALSE, NULL); + sd->evtwce = CreateEvent (NULL, TRUE, FALSE, NULL); + if (!sd->evtt || !sd->evtw || !sd->evtt || !sd->evtwce) + goto end; + sd->olr.hEvent = sd->evtr; + sd->olw.hEvent = sd->evtw; + sd->olwce.hEvent = sd->evtwce; + sd->hCom = CreateFile (buf, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); + if (sd->hCom == INVALID_HANDLE_VALUE) { + write_log ("UAENET: '%s' failed to open, err=%d\n", buf, GetLastError()); + goto end; + } + uae_sem_init (&sd->sync_sem, 0, 0); + uae_sem_init (&sd->change_sem, 0, 1); + uae_start_thread ("uaenet_win32", uaenet_trap_thread, sd, &sd->tid); + uae_sem_wait (&sd->sync_sem); + + return 1; + +end: + uaenet_close (sd); + return 0; +} + +void uaenet_close (struct uaenetdatawin32 *sd) +{ + if (sd->threadactive) { + sd->threadactive = -1; + SetEvent (sd->evtt); + while (sd->threadactive) + Sleep(10); + CloseHandle (sd->evtt); + } + if (sd->hCom != INVALID_HANDLE_VALUE) + CloseHandle(sd->hCom); + if (sd->evtr) + CloseHandle(sd->evtr); + if (sd->evtw) + CloseHandle(sd->evtw); + if (sd->evtwce) + CloseHandle(sd->evtwce); + uaeser_initdata (sd, sd->user); +} diff --git a/od-win32/win32_uaenet.h b/od-win32/win32_uaenet.h new file mode 100644 index 00000000..09a86560 --- /dev/null +++ b/od-win32/win32_uaenet.h @@ -0,0 +1,9 @@ +extern int uaenet_getdatalenght (void); +extern int uaenet_getbytespending (void*); +extern int uaenet_open (void*, void*, int); +extern void uaenet_close (void*); +extern int uaenet_read (void*, uae_u8 *data, uae_u32 len); +extern int uaenet_write (void*, uae_u8 *data, uae_u32 len); +extern void uaenet_signal (void*, int source); +extern void uaenet_trigger (void*); + diff --git a/od-win32/win32gfx.c b/od-win32/win32gfx.c index 93f5d838..41c84ca5 100644 --- a/od-win32/win32gfx.c +++ b/od-win32/win32gfx.c @@ -46,6 +46,9 @@ #include "gfxfilter.h" #include "parser.h" #include "lcd.h" +#ifdef RETROPLATFORM +#include "rp.h" +#endif #define AMIGA_WIDTH_MAX 752 #define AMIGA_HEIGHT_MAX 568 @@ -218,18 +221,18 @@ int WIN32GFX_IsPicassoScreen(void) return screen_is_picasso; } -void WIN32GFX_DisablePicasso( void ) +void WIN32GFX_DisablePicasso(void) { picasso_requested_on = 0; picasso_on = 0; } -void WIN32GFX_EnablePicasso( void ) +void WIN32GFX_EnablePicasso(void) { picasso_requested_on = 1; } -void WIN32GFX_DisplayChangeRequested( void ) +void WIN32GFX_DisplayChangeRequested(void) { display_change_requested = 1; } @@ -1813,7 +1816,7 @@ static void gfxmode_reset (void) #endif } -void machdep_init (void) +int machdep_init (void) { picasso_requested_on = 0; picasso_on = 0; @@ -1822,6 +1825,7 @@ void machdep_init (void) #ifdef LOGITECHLCD lcd_open(); #endif + return 1; } void machdep_free (void) @@ -2063,7 +2067,7 @@ static int create_windows (void) hAmigaWnd = CreateWindowEx (dxfs ? WS_EX_ACCEPTFILES | WS_EX_TOPMOST : WS_EX_ACCEPTFILES | exstyle | (currprefs.win32_alwaysontop ? WS_EX_TOPMOST : 0), "AmigaPowah", "WinUAE", - WS_CLIPCHILDREN | WS_CLIPSIBLINGS | (hMainWnd ? WS_VISIBLE | WS_CHILD : WS_VISIBLE | WS_POPUP), + WS_CLIPCHILDREN | WS_CLIPSIBLINGS | (hMainWnd ? WS_VISIBLE | WS_CHILD : WS_VISIBLE | WS_POPUP | WS_SYSMENU | WS_MINIMIZEBOX), x, y, currentmode->native_width, currentmode->native_height, hMainWnd ? hMainWnd : hhWnd, NULL, 0, NULL); @@ -2082,7 +2086,9 @@ static int create_windows (void) } UpdateWindow (hAmigaWnd); ShowWindow (hAmigaWnd, SW_SHOWNORMAL); - +#ifdef RETROPLATFORM + rp_set_hwnd (); +#endif return 1; } diff --git a/od-win32/win32gui.c b/od-win32/win32gui.c index 15969a9a..15cb6356 100644 --- a/od-win32/win32gui.c +++ b/od-win32/win32gui.c @@ -77,6 +77,7 @@ #include "lcd.h" #include "uaeipc.h" #include "crc32.h" +#include "rp.h" #define ARCHIVE_STRING "*.zip;*.7z;*.rar;*.lha;*.lzh;*.lzx" @@ -10180,8 +10181,17 @@ static int GetSettings (int all_options, HWND hwnd) dialogreturn = -1; hAccelTable = NULL; DragAcceptFiles(hwnd, TRUE); - if (first) + if (first) { +#ifdef RETROPLATFORM + if (rp_param != NULL) { + if (FAILED (rp_init ())) + return -2; + return 0; + } +#endif write_log ("Entering GUI idle loop\n"); + } + scaleresource_setmaxsize(800, 600); tres = scaleresource(panelresource, hwnd); dhwnd = CreateDialogIndirect (tres->inst, tres->resource, hwnd, DialogProc); @@ -10339,6 +10349,9 @@ void gui_led (int led, int on) indicator_leds (led, on); #ifdef LOGITECHLCD lcd_update (led, on); +#endif +#ifdef RETROPLATFORM + rp_update_leds (led, on); #endif if (!hStatusWnd) return; diff --git a/od-win32/winuae_msvc/winuae_msvc.8.vcproj b/od-win32/winuae_msvc/winuae_msvc.8.vcproj index 3090904e..b9a8b5ac 100644 --- a/od-win32/winuae_msvc/winuae_msvc.8.vcproj +++ b/od-win32/winuae_msvc/winuae_msvc.8.vcproj @@ -1349,6 +1349,14 @@ RelativePath="..\posixemu.c" > + + + + @@ -1381,6 +1389,10 @@ RelativePath="..\win32_scale2x.c" > + + diff --git a/od-win32/winuae_msvc/winuae_msvc.vcproj b/od-win32/winuae_msvc/winuae_msvc.vcproj index c2a7d023..cd00373e 100644 --- a/od-win32/winuae_msvc/winuae_msvc.vcproj +++ b/od-win32/winuae_msvc/winuae_msvc.vcproj @@ -1343,6 +1343,14 @@ RelativePath="..\posixemu.c" > + + + + @@ -1375,6 +1383,10 @@ RelativePath="..\win32_scale2x.c" > + + diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index a6ebcc4c..92315d23 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,25 @@ +Beta 8: + +- AGA sprite doublescan fixed (b7) +- some more doublescan tweaks (Super72 modes are now detected as + doublescanned. Other "weird" modes also work more or less, note that + some require horizontal centering) +- sana2 configuration save fixed (but note that sana2 emulation still + isn't really doing much) +- CDTV "Snoopy" fix corrected. Fixes random CDTV boot freeze. +- increased A590/A2091 SCSI data buffer size (crash while formatting + if sectors per track size was large enough) +- default hardware config (used by QS) clears pc drive mount checkboxes +- harddrive removal signal was not always send to uaehf.device if drive + was removed with disk still in drive (for example USB ZIP drive) +- ACTION_SET_DATE notification check crashed if file didn't exist +- directory filesystem and hardfile slowdown fixed (b2) +- state save crashed if directory harddrives were configured but state + was saved before drive initialization, for example when booting + non-dos adf +- always have empty memory space between Z3Fast and RTG RAM + Beta 7: - added information text to hardfile panel. diff --git a/sana2.c b/sana2.c index 777fa635..128ce30e 100644 --- a/sana2.c +++ b/sana2.c @@ -26,6 +26,7 @@ #include "uae.h" #include "sana2.h" #include "tun_uae.h" +#include "win32_uaenet.h" #define SANA2NAME "uaenet.device" @@ -107,20 +108,32 @@ #define DRIVE_NEWSTYLE 0x4E535459L /* 'NSTY' */ #define NSCMD_DEVICEQUERY 0x4000 -#define ASYNC_REQUEST_NONE 0 -#define ASYNC_REQUEST_TEMP 1 +static char *getdevname (void) +{ + return "uaenet.device"; +} + +struct sanapacket +{ + uae_u8 *data; + int len; + uae_u8 srcaddr[ADDR_SIZE], dstaddr[ADDR_SIZE]; +}; + +struct asyncreq { + struct asyncreq *next; + uaecptr request; + int ready; +}; struct devstruct { - int unitnum, aunit; - int opencnt; - int changenum; - volatile uaecptr d_request[MAX_ASYNC_REQUESTS]; - volatile int d_request_type[MAX_ASYNC_REQUESTS]; - volatile uae_u32 d_request_data[MAX_ASYNC_REQUESTS]; + int unitnum, unit, opencnt; + struct asyncreq *ar; smp_comm_pipe requests; uae_thread_id tid; int thread_running; uae_sem_t sync_sem; + void *sysdata; }; struct priv_devstruct { @@ -148,7 +161,7 @@ static struct tapdata td; static struct devstruct devst[MAX_TOTAL_DEVICES]; static struct priv_devstruct pdevst[MAX_OPEN_DEVICES]; static uae_u32 nscmd_cmd; -static uae_sem_t change_sem; +static uae_sem_t change_sem, async_sem; static struct device_info *devinfo (int mode, int unitnum, struct device_info *di) { @@ -182,16 +195,6 @@ static int start_thread (struct devstruct *dev) return dev->thread_running; } -static void dev_close_3 (struct devstruct *dev, struct priv_devstruct *pdev) -{ - if (!dev->opencnt) return; - dev->opencnt--; - if (!dev->opencnt) { - pdev->inuse = 0; - write_comm_pipe_u32 (&dev->requests, 0, 1); - } -} - static uae_u32 REGPARAM2 dev_close_2 (TrapContext *context) { uae_u32 request = m68k_areg (&context->regs, 1); @@ -205,8 +208,13 @@ static uae_u32 REGPARAM2 dev_close_2 (TrapContext *context) write_log ("%s:%d close, req=%08.8X\n", SANA2NAME, pdev->unit, request); if (!dev) return 0; - dev_close_3 (dev, pdev); put_long (request + 24, 0); + dev->opencnt--; + if (!dev->opencnt) { + pdev->inuse = 0; + write_comm_pipe_u32 (&dev->requests, 0, 1); + uaenet_close (dev->sysdata); + } put_word (m68k_areg (&context->regs, 6) + 32, get_word (m68k_areg (&context->regs, 6) + 32) - 1); return 0; } @@ -240,10 +248,16 @@ static uae_u32 REGPARAM2 dev_open_2 (TrapContext *context) write_log ("opening %s:%d ioreq=%08.8X\n", SANA2NAME, unit, ioreq); if (!dev) return openfail (ioreq, 32); /* badunitnum */ - if (!dev->opencnt) { + dev->sysdata = xcalloc (uaenet_getdatalenght(), 1); + if (!uaenet_open (dev->sysdata, dev, unit)) { + xfree (dev->sysdata); + return openfail (ioreq, 32); /* badunitnum */ + } + if (get_word (m68k_areg (&context->regs, 6) + 32) == 0) { for (i = 0; i < MAX_OPEN_DEVICES; i++) { pdev = &pdevst[i]; - if (pdev->inuse == 0) break; + if (pdev->inuse == 0) + break; } pdev->unit = unit; pdev->flags = flags; @@ -261,9 +275,9 @@ static uae_u32 REGPARAM2 dev_open_2 (TrapContext *context) return openfail (ioreq, -1); put_long (ioreq + 24, pdev - pdevst); } - dev->opencnt++; - put_word (m68k_areg (&context->regs, 6) + 32, get_word (m68k_areg (&context->regs, 6) + 32) + 1); + dev->opencnt = get_word (m68k_areg (&context->regs, 6) + 32) + 1; + put_word (m68k_areg (&context->regs, 6) + 32, dev->opencnt); put_byte (ioreq + 31, 0); put_byte (ioreq + 8, 7); return 0; @@ -282,87 +296,92 @@ static uae_u32 REGPARAM2 diskdev_expunge (TrapContext *context) return 0; } -static int is_async_request (struct devstruct *dev, uaecptr request) +static struct asyncreq *get_async_request (struct devstruct *dev, uaecptr request, int ready) { - int i = 0; - while (i < MAX_ASYNC_REQUESTS) { - if (dev->d_request[i] == request) return 1; - i++; + struct asyncreq *ar; + int ret = 0; + + uae_sem_wait (&async_sem); + ar = dev->ar; + while (ar) { + if (ar->request == request) { + if (ready) + ar->ready = 1; + break; + } + ar = ar->next; } - return 0; + uae_sem_post (&async_sem); + return ar; } -static int add_async_request (struct devstruct *dev, uaecptr request, int type, uae_u32 data) +static int add_async_request (struct devstruct *dev, uaecptr request) { - int i; + struct asyncreq *ar, *ar2; -// if (log_net) -// write_log ("%s: async request %08x (%d) added\n", SANA2NAME, request, type); - i = 0; - while (i < MAX_ASYNC_REQUESTS) { - if (dev->d_request[i] == request) { - dev->d_request_type[i] = type; - dev->d_request_data[i] = data; - return 0; - } - i++; - } - i = 0; - while (i < MAX_ASYNC_REQUESTS) { - if (dev->d_request[i] == 0) { - dev->d_request[i] = request; - dev->d_request_type[i] = type; - dev->d_request_data[i] = data; - return 0; - } - i++; + if (log_net) + write_log ("%s:%d async request %x added\n", getdevname(), dev->unit, request); + + uae_sem_wait (&async_sem); + ar = (struct asyncreq*)xcalloc (sizeof (struct asyncreq), 1); + ar->request = request; + if (!dev->ar) { + dev->ar = ar; + } else { + ar2 = dev->ar; + while (ar2->next) + ar2 = ar2->next; + ar2->next = ar; } - return -1; + uae_sem_post (&async_sem); + return 1; } static int release_async_request (struct devstruct *dev, uaecptr request) { - int i = 0; - -// if (log_net) -// write_log ("async request %p removed\n", request); - while (i < MAX_ASYNC_REQUESTS) { - if (dev->d_request[i] == request) { - int type = dev->d_request_type[i]; - dev->d_request[i] = 0; - dev->d_request_data[i] = 0; - dev->d_request_type[i] = 0; - return type; + struct asyncreq *ar, *prevar; + + uae_sem_wait (&async_sem); + ar = dev->ar; + prevar = NULL; + while (ar) { + if (ar->request == request) { + if (prevar == NULL) + dev->ar = ar->next; + else + prevar->next = ar->next; + uae_sem_post (&async_sem); + xfree (ar); + if (log_net) + write_log ("%s:%d async request %x removed\n", getdevname(), dev->unit, request); + return 1; } - i++; + prevar = ar; + ar = ar->next; } - return -1; + uae_sem_post (&async_sem); + write_log ("%s:%d async request %x not found for removal!\n", getdevname(), dev->unit, request); + return 0; } -static void abort_async (struct devstruct *dev, uaecptr request, int errcode, int type) +static void abort_async (struct devstruct *dev, uaecptr request) { - int i; - i = 0; - while (i < MAX_ASYNC_REQUESTS) { - if (dev->d_request[i] == request && dev->d_request_type[i] == ASYNC_REQUEST_TEMP) { - /* ASYNC_REQUEST_TEMP = request is processing */ - sleep_millis (10); - i = 0; - continue; - } - i++; + struct asyncreq *ar = get_async_request (dev, request, 1); + if (!ar) { + write_log ("%s:%d: abort sync but no request %x found!\n", getdevname(), dev->unit, request); + return; } - i = release_async_request (dev, request); - if (i >= 0 && log_net) - write_log ("%s: asyncronous request=%08.8X aborted, error=%d\n", SANA2NAME, request, errcode); + if (log_net) + write_log ("%s:%d asyncronous request=%08.8X aborted\n", getdevname(), dev->unit, request); + put_byte (request + 31, -2); + put_byte (request + 30, get_byte (request + 30) | 0x20); + write_comm_pipe_u32 (&dev->requests, request, 1); } -struct sanapacket +void uaenet_signal (struct devstruct *dev, int sigmask) { - uae_u8 *data; - int len; - uae_u8 srcaddr[ADDR_SIZE], dstaddr[ADDR_SIZE]; -}; + return; +} static void frees2packet (struct sanapacket *sp) { @@ -390,7 +409,7 @@ err: return S2ERR_NO_RESOURCES; } -static int dev_do_io (struct devstruct *dev, uaecptr request) +static int dev_do_io (struct devstruct *dev, uaecptr request, int quick) { uae_u32 command = get_word (request + 28); uae_u32 packettype = get_long (request + 32 + 4); @@ -428,12 +447,13 @@ static int dev_do_io (struct devstruct *dev, uaecptr request) case CMD_READ: if (!pdev->online) goto offline; - io_error = S2ERR_NO_RESOURCES; + async = 1; break; case S2_READORPHAN: if (!pdev->online) goto offline; + async = 1; break; case S2_BROADCAST: @@ -449,7 +469,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request) case CMD_WRITE: if (!pdev->online) goto offline; - io_error = writes2packet (data, datalength, srcaddr, dstaddr); + async = 1; break; case S2_MULTICAST: @@ -460,7 +480,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request) wire_error = S2WERR_BAD_MULTICAST; goto end; } - io_error = S2WERR_BAD_MULTICAST; + async = 1; break; case CMD_FLUSH: @@ -630,12 +650,11 @@ static uae_u32 REGPARAM2 dev_beginio (TrapContext *context) } put_byte (request+31, 0); if ((flags & 1) && dev_canquick (dev, request)) { - if (dev_do_io (dev, request)) + if (dev_do_io (dev, request, 1)) write_log ("%s: command %d bug with IO_QUICK\n", SANA2NAME, command); return get_byte (request + 31); } else { - add_async_request (dev, request, ASYNC_REQUEST_TEMP, 0); - put_byte (request+30, get_byte (request + 30) & ~1); + put_byte (request + 30, get_byte (request + 30) & ~1); write_comm_pipe_u32 (&dev->requests, request, 1); return 0; } @@ -656,13 +675,14 @@ static void *dev_thread (void *devs) uae_sem_post (&dev->sync_sem); uae_sem_post (&change_sem); return 0; - } else if (dev_do_io (dev, request) == 0) { - put_byte (request + 30, get_byte (request + 30) & ~1); + } else if (get_async_request (dev, request, 1)) { + uae_ReplyMsg (request); release_async_request (dev, request); + } else if (dev_do_io (dev, request, 0) == 0) { uae_ReplyMsg (request); } else { - if (log_net) - write_log ("%s:%d async request %08.8X\n", SANA2NAME, dev->unitnum, request); + add_async_request (dev, request); + uaenet_trigger (dev->sysdata); } uae_sem_post (&change_sem); } @@ -685,49 +705,38 @@ static uae_u32 REGPARAM2 dev_init (TrapContext *context) static uae_u32 REGPARAM2 dev_abortio (TrapContext *context) { uae_u32 request = m68k_areg (&context->regs, 1); - struct priv_devstruct *pdev = getpdevstruct (request); - struct devstruct *dev; + struct devstruct *dev = getdevstruct (get_long (request + 24)); - if (!pdev) { - put_byte (request + 31, 32); - return get_byte (request + 31); - } - dev = getdevstruct (pdev->unit); if (!dev) { put_byte (request + 31, 32); return get_byte (request + 31); } - put_byte (request + 31, -2); - if (log_net) - write_log ("%s abortio: unit=%d, request=%08.8X\n", SANA2NAME, pdev->unit, request); - abort_async (dev, request, -2, 0); + abort_async (dev, request); return 0; } + static void dev_reset (void) { - int i, j; + int i; struct devstruct *dev; int unitnum = 0; for (i = 0; i < MAX_TOTAL_DEVICES; i++) { dev = &devst[i]; - if (dev->opencnt > 0) { - for (j = 0; j < MAX_ASYNC_REQUESTS; j++) { - uaecptr request; - if (request = dev->d_request[i]) - abort_async (dev, request, 0, 0); - } - dev->opencnt = 1; + if (dev->opencnt) { + while (dev->ar) + abort_async (dev, dev->ar->request); + write_comm_pipe_u32 (&dev->requests, 0, 1); + uae_sem_wait (&dev->sync_sem); } memset (dev, 0, sizeof (struct devstruct)); - dev->unitnum = dev->aunit = -1; + dev->unitnum = -1; } for (i = 0; i < MAX_OPEN_DEVICES; i++) memset (&pdevst[i], 0, sizeof (struct priv_devstruct)); } - static uaecptr ROM_netdev_resname = 0, ROM_netdev_resid = 0, ROM_netdev_init = 0; @@ -765,7 +774,7 @@ void netdev_install (void) tap_open_driver (&td, currprefs.sana2); - ROM_netdev_resname = ds ("uaenet.device"); + ROM_netdev_resname = ds (getdevname()); ROM_netdev_resid = ds ("UAE net.device 0.1"); /* initcode */ @@ -863,6 +872,7 @@ void netdev_start_threads (void) if (log_net) write_log ("netdev_start_threads()\n"); uae_sem_init (&change_sem, 0, 1); + uae_sem_init (&async_sem, 0, 1); } void netdev_reset (void) diff --git a/scsi.c b/scsi.c index af6d2a6f..211e1acc 100644 --- a/scsi.c +++ b/scsi.c @@ -132,6 +132,10 @@ void scsi_start_transfer(struct scsi_data *sd, int len) int scsi_send_data(struct scsi_data *sd, uae_u8 b) { if (sd->direction) { + if (sd->offset >= SCSI_DATA_BUFFER_SIZE) { + write_log ("SCSI data buffer overflow!\n"); + return 0; + } sd->buffer[sd->offset++] = b; } else { if (sd->offset >= 16) { -- 2.47.3