]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
imported winuaesrc1450b8.zip
authorToni Wilen <twilen@winuae.net>
Thu, 8 Nov 2007 16:42:58 +0000 (18:42 +0200)
committerToni Wilen <twilen@winuae.net>
Mon, 22 Feb 2010 19:36:44 +0000 (21:36 +0200)
36 files changed:
cdtv.c
cfgfile.c
custom.c
expansion.c
filesys.asm
filesys.c
hardfile.c
include/custom.h
include/options.h
include/scsi.h
inputdevice.c
main.c
newcpu.c
od-win32/cloanto/RetroPlatformGuestIPC.c [new file with mode: 0644]
od-win32/cloanto/RetroPlatformGuestIPC.h [new file with mode: 0644]
od-win32/cloanto/RetroPlatformIPC.h [new file with mode: 0644]
od-win32/hardfile_win32.c
od-win32/mman.c
od-win32/rp.c [new file with mode: 0644]
od-win32/rp.h [new file with mode: 0644]
od-win32/serial_win32.c
od-win32/sounddep/sound.c
od-win32/sounddep/sound.h
od-win32/sysconfig.h
od-win32/tun.c
od-win32/win32.c
od-win32/win32.h
od-win32/win32_uaenet.c [new file with mode: 0644]
od-win32/win32_uaenet.h [new file with mode: 0644]
od-win32/win32gfx.c
od-win32/win32gui.c
od-win32/winuae_msvc/winuae_msvc.8.vcproj
od-win32/winuae_msvc/winuae_msvc.vcproj
od-win32/winuaechangelog.txt
sana2.c
scsi.c

diff --git a/cdtv.c b/cdtv.c
index 4f04f80e55944a5378126b724b84693df63b00bd..9760e694ce9ae97199cf6cbb5b2b16883fad8d22 100644 (file)
--- 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)
index 93384eaf4a88325ebdfbcd2afc2c98ce008a71e0..d90209570c543245acb9aa52e21e409f9e51dd64 100644 (file)
--- 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);
index f4103d9f80b05cf0a07adc8847ea7c9f28db2f0f..9b5a79f2539c8c2b3b895020f8afc238840decf1 100644 (file)
--- 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);
index 48b67f1975769cf3160f231191a80f98f0bf2e5c..da113c6a486dae00496e02601ba85cdf15faaf07 100644 (file)
@@ -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]) ();
 }
 
index 3021fe2c5818f2436ada5fe470b83e62572bec97..7997acd46f1eb69e03e58eac309e803c01732101 100644 (file)
@@ -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
index b3c1dfdb280fd6d14a400ce0192dd4d5f7bb804f..8a040ff052fcd5a8736ae1d6683f535f74c7d81f 100644 (file)
--- 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 */
index 4b406c2888b404c104044c36453e9f5906e0d1e3..93d53cfbd2b5ab413d8d44aec8ce3e74c4208c34 100644 (file)
@@ -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) {
index a47b76c7ff9246eac0be9a64177bb58646540ed8..01d489959d2166be855c1c05a3171894207cc791 100644 (file)
@@ -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;
index 1751034d5bb9708589546e5c71a28c32b3018e95..a984e87133689d06e379314ce30499ff11db702b 100644 (file)
@@ -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. */
index b23ef6dbcc8178215cb92cb8353f8d9e5db55150..db47e179e86a6a0a43edbdb0287efa95c11d7e65 100644 (file)
@@ -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;
 };
index 6da3569493ed40ef71dc7175ce77bc2a37bd0880..d6e02b90e37980c0a7c27d720503a8891c597232 100644 (file)
@@ -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 1d752ac18b483c277ff4a9814118ab45637b6da9..64c730d414011c12f46c96fb6917fd25796e6e7f 100644 (file)
--- 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");
index 81db3cb16b38491bf2ffe361817db089d7cff1d5..719feece16bdebd21fb2799ce97dc7c3d573c4e3 100644 (file)
--- 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 (&regs, SPCFLAG_INT);
        }
        if (regs.spcflags) {
diff --git a/od-win32/cloanto/RetroPlatformGuestIPC.c b/od-win32/cloanto/RetroPlatformGuestIPC.c
new file mode 100644 (file)
index 0000000..18fb4d3
--- /dev/null
@@ -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 (file)
index 0000000..5477882
--- /dev/null
@@ -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 <windows.h>
+#include <tchar.h>
+
+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 (file)
index 0000000..0ef3073
--- /dev/null
@@ -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 <windows.h>
+
+#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,
+//             <millisecond delay> 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__
index 751902bd777a0271acca362441d26f2c3662e42a..45068e416e29c5777fb7074951d251447ed8d09a 100644 (file)
@@ -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;
 }
 
index d2c10a29aa4b54991bf656032260d5f0890d5153..9fe2cd6ca282cee1ecf0fa7ad3192f5b1d8c20bb 100644 (file)
@@ -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 (file)
index 0000000..5b46d3e
--- /dev/null
@@ -0,0 +1,292 @@
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <signal.h>
+
+#include <windows.h>
+
+#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 (file)
index 0000000..fd9a731
--- /dev/null
@@ -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;
index 7bfebe072d5f5f2307f2010f44fa4bfc496e5c68..5f95f501af32c3cb0dd246f810b78831df7c99f7 100644 (file)
@@ -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;
index a2fb51302ece272b95e1393052e1a1ef6e5feb62..20dd096c27466502edbaefef2f65008109b68948 100644 (file)
@@ -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)
 {
index bb604703e90b6a9d78aac578b37d025ae908f7c4..4ea9777e431cb5b8f08e14d473db510572acc349 100644 (file)
@@ -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)
index ff35aa8a410d933b98a4dd0e03e313b4a1e0bc2c..5701d2e4d682f23c8f9b49b0acbdd650684ea206 100644 (file)
@@ -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
 
index f39aba68b651b24b661ac46be9d4d89e6eb8c96d..c6256e735e004ffc7b8f0996efc100c95f3d51b1 100644 (file)
@@ -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);
index 87c6ffc7af0c18725cecbc2254e72c3ac3b37253..dbb16c35c9f1c22a82fffb668d2c82bc8e591165 100644 (file)
 #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;
 }
 
index d4302f8f0d4715fdbfbf51e73dffb775a81d4b69..bcf21193c6d5844c3bacf9782c0ecd3bb29c647d 100644 (file)
@@ -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 (file)
index 0000000..a7f83b3
--- /dev/null
@@ -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 <windows.h>
+#include <winspool.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <mmsystem.h>
+#include <ddraw.h>
+#include <commctrl.h>
+#include <commdlg.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <io.h>
+
+#include <setupapi.h>
+#include <windows.h>
+
+#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 (file)
index 0000000..09a8656
--- /dev/null
@@ -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*);
+
index 93f5d838a70b1b5e8c1f5b74e59e657557fa53d2..41c84ca57e6cf500308d01aeb997e71e81c86155 100644 (file)
@@ -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;
 }
 
index 15969a9a9d186b6ffb101fde2012c9e6f96d8d14..15cb6356738974e848b66c6f0838aeaf9b39ec15 100644 (file)
@@ -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;
index 3090904e0b7ec84851513f2acced5e853501e443..b9a8b5ac40ab8bb9496501d2df7a79ebfa394c70 100644 (file)
                                RelativePath="..\posixemu.c"
                                >
                        </File>
+                       <File
+                               RelativePath="..\cloanto\RetroPlatformGuestIPC.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\rp.c"
+                               >
+                       </File>
                        <File
                                RelativePath="..\scaler.c"
                                >
                                RelativePath="..\win32_scale2x.c"
                                >
                        </File>
+                       <File
+                               RelativePath="..\win32_uaenet.c"
+                               >
+                       </File>
                        <File
                                RelativePath="..\win32gfx.c"
                                >
index c2a7d023cd7a18bd2403f087b07a0d61ea435a0f..cd00373e02a415efbf7b5a1828dbf81a7f8e624b 100644 (file)
                                RelativePath="..\posixemu.c"
                                >
                        </File>
+                       <File
+                               RelativePath="..\cloanto\RetroPlatformGuestIPC.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\rp.c"
+                               >
+                       </File>
                        <File
                                RelativePath="..\scaler.c"
                                >
                                RelativePath="..\win32_scale2x.c"
                                >
                        </File>
+                       <File
+                               RelativePath="..\win32_uaenet.c"
+                               >
+                       </File>
                        <File
                                RelativePath="..\win32gfx.c"
                                >
index a6ebcc4c72bef1b8c1d4566689e49d6f06af320e..92315d2393a3ac38c4038483113e53253853d14a 100644 (file)
@@ -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 777fa63595a981725825b7226486fefbfb02c036..128ce30e9129c09486bed713c1ee171471cadff6 100644 (file)
--- 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"
 
 #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 af6d2a6f428120d5ab4d62d0dbbeafc1f1bcdd2b..211e1accbe86390d28dea67bf4e6c3973f3acd7a 100644 (file)
--- 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) {