]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
4400b1
authorToni Wilen <twilen@winuae.net>
Sun, 19 Apr 2020 15:18:01 +0000 (18:18 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 19 Apr 2020 15:18:01 +0000 (18:18 +0300)
blkdev_cdimage.cpp
cfgfile.cpp
gfxboard.cpp
od-win32/resources/winuae.rc
od-win32/win32.cpp
od-win32/win32.h
od-win32/win32gfx.cpp
od-win32/win32gui_extra.cpp
scsiemul.cpp
sndboard.cpp

index 80974327f05fc73e1be452ddf4b886ee82e701bf..17735eee2cd81371fb6e678334f34985324305f8 100644 (file)
@@ -200,6 +200,8 @@ static void flac_metadata_callback (const FLAC__StreamDecoder *decoder, const FL
                return;
        if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
                t->filesize = metadata->data.stream_info.total_samples * (metadata->data.stream_info.bits_per_sample / 8) * metadata->data.stream_info.channels;
+       } else if (metadata->type == FLAC__METADATA_TYPE_CUESHEET) {
+               write_log("!");
        }
 }
 static void flac_error_callback (const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
@@ -253,6 +255,7 @@ static void flac_get_size (struct cdtoc *t)
        FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new ();
        if (decoder) {
                FLAC__stream_decoder_set_md5_checking (decoder, false);
+               FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_CUESHEET);
                int init_status = FLAC__stream_decoder_init_stream (decoder,
                        &file_read_callback, &file_seek_callback, &file_tell_callback,
                        &file_len_callback, &file_eof_callback,
@@ -1659,15 +1662,19 @@ static int parsecue (struct cdunit *cdu, struct zfile *zcue, const TCHAR *img, c
                        fname = my_strdup (nextstring (&p));
                        fnametype = nextstring (&p);
                        fnametypeid = AUDENC_NONE;
+                       TCHAR *ext = _tcsrchr(fname, '.');
+                       if (ext) {
+                               ext++;
+                       }
                        if (!fnametype)
                                break;
                        if (_tcsicmp (fnametype, _T("BINARY")) && _tcsicmp (fnametype, _T("WAVE")) && _tcsicmp (fnametype, _T("MP3")) && _tcsicmp (fnametype, _T("FLAC"))) {
                                write_log (_T("CUE: unknown file type '%s' ('%s')\n"), fnametype, fname);
                        }
                        fnametypeid = AUDENC_PCM;
-                       if (!_tcsicmp (fnametype, _T("MP3")))
+                       if (!_tcsicmp (fnametype, _T("MP3")) || (ext && !_tcsicmp(ext, _T("MP3"))))
                                fnametypeid = AUDENC_MP3;
-                       else if (!_tcsicmp (fnametype, _T("FLAC")))
+                       else if (!_tcsicmp (fnametype, _T("FLAC")) || (ext && !_tcsicmp(ext, _T("FLAC"))))
                                fnametypeid = AUDENC_FLAC;
                        fileoffset = 0;
                        newfile = 1;
@@ -1969,12 +1976,15 @@ static int parsenrg(struct cdunit *cdu, struct zfile *znrg, const TCHAR *img, co
                                } else {
                                        tracknum = frombcd(trk);
                                        int index = frombcd(buf[2]);
-                                       if (index == 0 && tracknum >= 1 && tracknum <= 99) {
+                                       uae_u32 address = get_long_host(buf + 4);
+                                       if (tracknum >= 1 && tracknum <= 99) {
                                                struct cdtoc *t = &cdu->toc[tracknum - 1];
-                                               t->address = get_long_host(buf + 4);
-                                               t->ctrl = buf[0] >> 4;
-                                               t->adr = buf[0] & 15;
-                                               t->track = tracknum;
+                                               if (index == 0) {
+                                                       t->address = address;
+                                                       t->ctrl = buf[0] >> 4;
+                                                       t->adr = buf[0] & 15;
+                                                       t->track = tracknum;
+                                               }
                                        }
                                }
                                size -= 8;
index 5e76abb8713c7d61e03d8f4fba39836e4e84ff22..9db9526a9388155f27bbde71ab6130519d07f94f 100644 (file)
@@ -6712,6 +6712,10 @@ bool cfgfile_detect_art_path(const TCHAR *path, TCHAR *outpath)
        const TCHAR *p;
        if (!path[0])
                return false;
+#if 0
+       if (path[0] == '\\')
+               return false;
+#endif
        write_log(_T("Possible boxart path: '%s'\n"), path);
        _tcscpy(tmp, path);
        p = _tcsrchr(tmp, '\\');
index 254dc55f5961cfa265f98352734f1e0b0f74e9ce..e41dd15c4c5b93b9d6c35ec3f328f2a13548c42e 100644 (file)
@@ -513,8 +513,11 @@ static bool gfxboard_setmode(struct rtggfxboard *gb, struct gfxboard_mode *mode)
 
        state->Width = mode->width;
        state->Height = mode->height;
+       state->VirtualWidth = state->Width;
+       state->VirtualHeight = state->Height;
        int bpp = GetBytesPerPixel(mode->mode);
        state->BytesPerPixel = bpp;
+       state->BytesPerRow = mode->width * bpp;
        state->RGBFormat = mode->mode;
        write_log(_T("GFXBOARD %dx%dx%d\n"), mode->width, mode->height, bpp);
        if (!ad->picasso_requested_on && !ad->picasso_on) {
@@ -834,10 +837,11 @@ DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
                                                 int linesize, uint8_t *data,
                                                 bool byteswap)
 {
-       struct rtggfxboard *gb;
        for (int i = 0; i < MAX_RTG_BOARDS; i++) {
-               gb = &rtggfxboards[i];
+               struct rtggfxboard *gb = &rtggfxboards[i];
                if (data >= gb->vram && data < gb->vramend) {
+                       struct picasso96_state_struct *state = &picasso96_state[gb->monitor_id];
+                       state->XYOffset = (gb->vram - data) + gfxmem_banks[gb->rtg_index]->start;
                        gb->modechanged = true;
                        return &gb->fakesurface;
                }
index 50a22b993e785f0062c2d33add0cc471276666e0..cb596916667b1459836dc804522cd82bac9699f0 100644 (file)
@@ -1396,8 +1396,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 4,3,0,0
- PRODUCTVERSION 4,3,0,0
+ FILEVERSION 4,3,1,0
+ PRODUCTVERSION 4,3,1,0
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -1413,12 +1413,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "WinUAE"
-            VALUE "FileVersion", "4.3.0.0"
+            VALUE "FileVersion", "4.3.1.0"
             VALUE "InternalName", "WinUAE"
-            VALUE "LegalCopyright", "© 1996-2019 under the GNU Public License (GPL)"
+            VALUE "LegalCopyright", "© 1996-2020 under the GNU Public License (GPL)"
             VALUE "OriginalFilename", "WinUAE.exe"
             VALUE "ProductName", "WinUAE"
-            VALUE "ProductVersion", "4.3.0.0"
+            VALUE "ProductVersion", "4.3.1.0"
         END
     END
     BLOCK "VarFileInfo"
index c097375681f399488e6269a0f3767467bc3d2386..96271aba9d6298b7908bf0f55de30f8bc08d2bbe 100644 (file)
@@ -3599,7 +3599,7 @@ void logging_init (void)
                SystemInfo.wProcessorArchitecture, SystemInfo.wProcessorLevel, SystemInfo.wProcessorRevision,
                SystemInfo.dwNumberOfProcessors, filedate, os_touch);
        write_log (_T("\n(c) 1995-2001 Bernd Schmidt   - Core UAE concept and implementation.")
-               _T("\n(c) 1998-2019 Toni Wilen      - Win32 port, core code updates.")
+               _T("\n(c) 1998-2020 Toni Wilen      - Win32 port, core code updates.")
                _T("\n(c) 1996-2001 Brian King      - Win32 port, Picasso96 RTG, and GUI.")
                _T("\n(c) 1996-1999 Mathias Ortmann - Win32 port and bsdsocket support.")
                _T("\n(c) 2000-2001 Bernd Meyer     - JIT engine.")
@@ -4133,9 +4133,9 @@ void target_quit (void)
 void target_fixup_options (struct uae_prefs *p)
 {
        if (p->win32_automount_cddrives && !p->scsi)
-               p->scsi = UAESCSI_SPTI;
-       if (p->scsi > UAESCSI_LAST)
-               p->scsi = UAESCSI_SPTI;
+               p->scsi = 1;
+       if (p->win32_uaescsimode > UAESCSI_LAST)
+               p->win32_uaescsimode = UAESCSI_SPTI;
        bool paused = false;
        bool nosound = false;
        bool nojoy = true;
@@ -7376,7 +7376,7 @@ LONG WINAPI WIN32_ExceptionFilter (struct _EXCEPTION_POINTERS *pExceptionPointer
                                                        prevpc = (uae_u8*)ppc;
                                                }
                                                m68k_setpc ((uaecptr)p);
-                                               exception2(opc, er->ExceptionInformation[0] == 0, 4, regs.s ? 4 : 0);
+                                               hardware_exception2(opc, 0, er->ExceptionInformation[0] == 0, true, 4);
                                                lRet = EXCEPTION_CONTINUE_EXECUTION;
                                        }
                        }
index 5a574642e4f3e266736a5a62f005578cb72ccb0d..0ae34322644c9c7a72ea087e6de085e084065891 100644 (file)
 #define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100)
 #define GETBDD(x) ((x) % 100)
 
-#define WINUAEPUBLICBETA 0
+#define WINUAEPUBLICBETA 1
 #define LANG_DLL 1
 #define LANG_DLL_FULL_VERSION_MATCH 1
 
 #if WINUAEPUBLICBETA
-#define WINUAEBETA _T("10")
+#define WINUAEBETA _T("1")
 #else
 #define WINUAEBETA _T("")
 #endif
 
-#define WINUAEDATE MAKEBD(2019, 12, 19)
+#define WINUAEDATE MAKEBD(2020, 4, 19)
 
 //#define WINUAEEXTRA _T("AmiKit Preview")
 //#define WINUAEEXTRA _T("Amiga Forever Edition")
index 2667bd61a8fdafd2fb8c21d61a8d695fbf432d5a..f6edb2550e2705d47e8f574fc9f7438bf2d0d095 100644 (file)
@@ -4165,7 +4165,7 @@ retry:
                }
                const TCHAR *err = D3D_init(mon->hAmigaWnd, mon->monitor_id, mon->currentmode.native_width, mon->currentmode.native_height,
                        mon->currentmode.current_depth, &mon->currentmode.freq, fmh, fmv);
-                       if (err) {
+               if (err) {
                        if (currprefs.gfx_api == 2) {
                                D3D_free(0, true);
                                if (err[0] == 0 && currprefs.color_mode != 5) {
index 74eb5cc7f60faa3e57fc932ccd5ed7af39ebdc9c..4ceb9a475b1e012c672978e5f7f1f2bdaaecbd35 100644 (file)
@@ -1236,8 +1236,14 @@ int scaleresource_choosefont (HWND hDlg, int fonttype)
 #include <gdiplus.h> 
 
 #define MAX_BOX_ART_IMAGES 20
-#define MAX_BOX_ART_TYPES 4
-#define MAX_VISIBLE_IMAGES 2
+#define MAX_BOX_ART_TYPES 5
+#define MAX_VISIBLE_IMAGES 10
+
+struct imagedata
+{
+       Gdiplus::Image *image;
+       TCHAR *metafile;
+};
 
 static bool boxart_inited;
 static ULONG_PTR gdiplusToken;
@@ -1246,7 +1252,7 @@ static int boxart_window_width;
 static int boxart_window_height;
 static const int hgap = 8;
 static const int wgap = 8;
-static Gdiplus::Image *images[MAX_BOX_ART_IMAGES];
+static struct imagedata *images[MAX_BOX_ART_IMAGES];
 static int total_height;
 static int max_width;
 static int total_images;
@@ -1256,7 +1262,7 @@ static int lastimage;
 static TCHAR image_path[MAX_DPATH], config_path[MAX_DPATH];
 static int image_coords[MAX_VISIBLE_IMAGES + 1];
 
-int max_visible_boxart_images = MAX_VISIBLE_IMAGES;
+int max_visible_boxart_images = 2;
 int stored_boxart_window_width = 400;
 int stored_boxart_window_width_fsgui = 33;
 int calculated_boxart_window_width;
@@ -1273,6 +1279,7 @@ static const TCHAR *boxartnames[MAX_BOX_ART_TYPES] = {
        _T("Title"),
        _T("SShot"),
        _T("Misc"),
+       _T("Data"),
 };
 
 typedef HRESULT(CALLBACK* DWMGETWINDOWATTRIBUTE)(HWND hwnd, DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute);
@@ -1340,7 +1347,10 @@ void close_box_art_window(void)
 {
        for (int i = 0; i < MAX_BOX_ART_IMAGES; i++) {
                if (images[i]) {
-                       delete images[i];
+                       struct imagedata *im = images[i];
+                       delete im->image;
+                       xfree(im->metafile);
+                       xfree(im);
                        images[i] = NULL;
                }
        }
@@ -1419,7 +1429,8 @@ static void boxartpaint(HDC hdc, HWND hwnd)
                }
                while (imagemode) {
                        if (images[imagemode - 1]) {
-                               Gdiplus::Image *img = images[imagemode - 1];
+                               struct imagedata *im = images[imagemode - 1];
+                               Gdiplus::Image *img = im->image;
                                image_count = 1;
                                image_total_height = img->GetHeight();
                                max_width = img->GetWidth();
@@ -1454,7 +1465,8 @@ static void boxartpaint(HDC hdc, HWND hwnd)
                scale = scaley;
 
        Gdiplus::Graphics graphics(hdc);
-       Gdiplus::Pen pen(Gdiplus::Color(170, 170, 0, 0), 1);
+       Gdiplus::Pen pen1(Gdiplus::Color(170, 170, 0, 0), 2);
+       Gdiplus::Pen pen2(Gdiplus::Color(170, 0, 0, 170), 2);
 
        float y = 0;
        cnt = 0;
@@ -1462,7 +1474,8 @@ static void boxartpaint(HDC hdc, HWND hwnd)
                if (!imagemode && cnt >= max_visible_boxart_images)
                        break;
                if (images[i]) {
-                       Gdiplus::Image *img = images[i];
+                       struct imagedata *im = images[i];
+                       Gdiplus::Image *img = im->image;
                        int h = img->GetHeight();
                        y += h;
                        cnt++;
@@ -1478,7 +1491,8 @@ static void boxartpaint(HDC hdc, HWND hwnd)
                if (!imagemode && cnt >= max_visible_boxart_images)
                        break;
                if (images[i]) {
-                       Gdiplus::Image *img = images[i];
+                       struct imagedata *im = images[i];
+                       Gdiplus::Image *img = im->image;
                        int w = img->GetWidth();
                        int h = img->GetHeight();
 
@@ -1498,7 +1512,11 @@ static void boxartpaint(HDC hdc, HWND hwnd)
                        graphics.DrawImage(img, d);
 
                        Gdiplus::Rect d2(x1 - 1, y1 - 1, x2 + 1, y2 + 1);
-                       graphics.DrawRectangle(&pen, d2);
+                       if (im->metafile) {
+                               graphics.DrawRectangle(&pen2, d2);
+                       } else {
+                               graphics.DrawRectangle(&pen1, d2);
+                       }
 
                        image_coords[cnt] = y1 + y2 + hgap / 2;
 
@@ -1509,7 +1527,7 @@ static void boxartpaint(HDC hdc, HWND hwnd)
        }
 }
 
-extern int full_property_sheet;
+extern int full_property_sheet;  
 
 bool show_box_art(const TCHAR *path, const TCHAR *configpath)
 {
@@ -1551,8 +1569,12 @@ bool show_box_art(const TCHAR *path, const TCHAR *configpath)
        if (_tcslen(config_path) > 0)
                SetWindowText(boxarthwnd, config_path);
 
-       if (max_visible_boxart_images < 1 || max_visible_boxart_images > 3)
-               max_visible_boxart_images = 2;
+       if (max_visible_boxart_images < 1) {
+               max_visible_boxart_images = 1;
+       }
+       if (max_visible_boxart_images > MAX_VISIBLE_IMAGES) {
+               max_visible_boxart_images = MAX_VISIBLE_IMAGES;
+       }
 
        total_height = 0;
        max_width = 0;
@@ -1562,19 +1584,62 @@ bool show_box_art(const TCHAR *path, const TCHAR *configpath)
        write_log(_T("Box art path '%s'\n"), path);
        int cnt = 0;
        for (int arttype = 0; arttype < MAX_BOX_ART_TYPES; arttype++) {
+
                for (int j = 0; j < 10; j++) {
 
                        if (total_images >= MAX_BOX_ART_IMAGES)
                                break;
                        images[cnt] = NULL;
-
                        Gdiplus::Image *image;
-                       _tcscpy(tmp1, path);
-                       _tcscat(tmp1, _T("___"));
-                       _tcscat(tmp1, boxartnames[arttype]);
-                       if (j > 0)
-                               _stprintf(tmp1 + _tcslen(tmp1), _T("%d"), j + 1);
-                       _tcscat(tmp1, _T(".png"));
+                       TCHAR metafile[MAX_DPATH];
+                       metafile[0] = 0;
+
+                       if (arttype == MAX_BOX_ART_TYPES - 1) {
+                               WIN32_FIND_DATA ffd;
+                               if (j > 0) {
+                                       _stprintf(tmp1, _T("%s___%s%d_*"), path, boxartnames[arttype], j + 1);
+                               } else {
+                                       _stprintf(tmp1, _T("%s___%s_*"), path, boxartnames[arttype]);
+                               }
+                               HANDLE ffHandle = FindFirstFile(tmp1, &ffd);
+                               if (ffHandle == INVALID_HANDLE_VALUE) {
+                                       break;
+                               }
+                               int found = 0;
+                               for (;;) {
+                                       if (_tcslen(ffd.cFileName) >= 4 && !_tcsicmp(ffd.cFileName + _tcslen(ffd.cFileName) - 4, _T(".png"))) {
+                                               found |= 1;
+                                               _tcscpy(tmp1, path);
+                                               _tcscat(tmp1, ffd.cFileName);
+                                       } else if (!(found & 2)) {
+                                               _tcscpy(metafile, path);
+                                               _tcscat(metafile, ffd.cFileName);
+                                               found |= 2;
+                                       }
+                                       if (!FindNextFile(ffHandle, &ffd))
+                                               break;
+                               }
+                               FindClose(ffHandle);
+                               if (!(found & 1))
+                                       break;
+                               if (!(found & 2)) {
+                                       _tcscpy(metafile, path);
+                                       _tcscat(metafile, tmp1 + _tcslen(path) + 3 + _tcslen(boxartnames[arttype]) + (j > 0) + 1);
+                                       if (_tcslen(metafile) > 4) {
+                                               metafile[_tcslen(metafile) - 4] = 0;
+                                       }
+                                       if (!zfile_exists(metafile))
+                                               break;
+                               }
+                       } else {
+                               _tcscpy(tmp1, path);
+                               _tcscat(tmp1, _T("___"));
+                               _tcscat(tmp1, boxartnames[arttype]);
+                               if (j > 0) {
+                                       _stprintf(tmp1 + _tcslen(tmp1), _T("%d"), j + 1);
+                               }
+                               _tcscat(tmp1, _T(".png"));
+                       }
 
                        image = Gdiplus::Image::FromFile(tmp1);
                        // above returns out of memory if file does not exist!
@@ -1586,7 +1651,12 @@ bool show_box_art(const TCHAR *path, const TCHAR *configpath)
                                int w = image->GetWidth();
                                int h = image->GetHeight();
                                write_log(_T("Image '%s' loaded %d*%d\n"), tmp1, w, h);
-                               images[cnt++] = image;
+                               struct imagedata *img = xcalloc(struct imagedata, 1);
+                               img->image = image;
+                               if (metafile[0]) {
+                                       img->metafile = my_strdup(metafile);
+                               }
+                               images[cnt++] = img;
                                if (total_images < max_visible_boxart_images) {
                                        if (w > max_width)
                                                max_width = w;
@@ -1633,29 +1703,50 @@ LRESULT CALLBACK BoxArtWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
        switch (message)
        {
                case WM_LBUTTONDOWN:
+               case WM_LBUTTONDBLCLK:
+               {
+                       bool exec = false;
                        if (imagemode) {
                                lastimage = imagemode - 1;
-                               imagemode = 0;
+                               struct imagedata *im = images[lastimage];
+                               if (im->metafile) {
+                                       ShellExecute(NULL, _T("open"), im->metafile, NULL, NULL, SW_SHOWNORMAL);
+                                       exec = true;
+                               } else {
+                                       imagemode = 0;
+                               }
                        } else {
                                int y = (short)(lParam >> 16);
-                               imagemode = 0;
+                               int imagenum = 0;
                                for (int i = 1; i < max_visible_boxart_images; i++) {
                                        if (y >= image_coords[i - 1])
-                                               imagemode = i;
+                                               imagenum = i;
                                }
-                               while (imagemode > 0) {
-                                       if (images[imagemode])
+                               while (imagenum > 0) {
+                                       if (images[imagenum])
                                                break;
-                                       imagemode--;
+                                       imagenum--;
+                               }
+                               imagenum++;
+                               struct imagedata *im = images[imagenum - 1];
+                               if (im->metafile) {
+                                       ShellExecute(NULL, _T("open"), im->metafile, NULL, NULL, SW_SHOWNORMAL);
+                                       exec = true;
+                               } else {
+                                       imagemode = imagenum;
                                }
-                               imagemode++;
                        }
-                       lastimage = imagemode - 1;
-                       imagemodereset = true;
-                       if (oldmode != imagemode)
-                               InvalidateRect(hWnd, NULL, TRUE);
+                       if (!exec) {
+                               lastimage = imagemode - 1;
+                               imagemodereset = true;
+                               if (oldmode != imagemode) {
+                                       InvalidateRect(hWnd, NULL, TRUE);
+                               }
+                       }
+               }
                break;
                case WM_RBUTTONDOWN:
+               case WM_RBUTTONDBLCLK:
                        if (imagemode) {
                                imagemode++;
                                lastimage = imagemode - 1;
@@ -1665,8 +1756,9 @@ LRESULT CALLBACK BoxArtWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
                                        imagemode = 1;
                        }
                        imagemodereset = false;
-                       if (oldmode != imagemode)
+                       if (oldmode != imagemode) {
                                InvalidateRect(hWnd, NULL, TRUE);
+                       }
                break;
                case WM_PAINT:
                {
index 1ef57240c82d8bc953f132daf534e559dc1563a2..996c873d3239ddd4c22e6bdb0fe5856e3cd7919c 100644 (file)
@@ -1281,7 +1281,7 @@ static void dev_reset (void)
                                dev->aunit = unitnum;
                                unitnum++;
                        }
-                       write_log (_T("%s:%d = %s:'%s'\n"), UAEDEV_SCSI, dev->aunit, dev->di.backend, dev->di.label);
+                       write_log (_T("%s:%d = %s:'%s',%d\n"), UAEDEV_SCSI, dev->aunit, dev->di.backend, dev->di.label, dev->di.type);
                }
                dev->di.label[0] = 0;
        }
index ed197bc30a51593f40f1b16b65c38285e1b44ffa..7492940b0baf9e85dd41bae41e89f4ef5d3808c9 100644 (file)
@@ -25,7 +25,9 @@
 #include "rommgr.h"
 #include "devices.h"
 
-#define DEBUG_SNDDEV 0
+#define DEBUG_SNDDEV 1
+#define DEBUG_SNDDEV_READ 0
+#define DEBUG_SNDDEV_WRITE 1
 #define DEBUG_SNDDEV_FIFO 0
 
 static void snd_init(void);
@@ -69,7 +71,7 @@ struct uaesndboard_stream
        int len, original_len;
        int replen;
        int repcnt;
-       bool first;
+       int first;
        bool repeating;
        uae_u8 chmode;
        uae_s16 panx, pany;
@@ -170,14 +172,14 @@ static struct uaesndboard_data uaesndboard[MAX_DUPLICATE_SOUND_BOARDS];
        $0094.L size of RAM (or zero if no RAM)
 
        $00E0.L allocated streams, bit mask. Hardware level stream allocation feature, use single test and set/clear instruction or
-               disable interrupts before allocating/freeing streams. If stream bit is not set, stream's address range is inactive.
-               byte access to $00E3 is also allowed.
+                       disable interrupts before allocating/freeing streams. If stream bit is not set, stream's address range is inactive.
+                       byte access to $00E3 is also allowed.
 
        $00E4.L Stream latch bit. Write-only. Bit set = latch stream, bit not set = does nothing. ($00E6.W and $00E7.B also allowed)
        $00E8.L Stream unlatch bit. Same behavior as $00E4.L. ($00EA.W and $00EB.B also allowed)
 
        $00F0.L stream enable bit mask. RW. Can be used to start or stop multiple streams simultaneously. $00F3.B is also allowed.
-       Changing stream mask always clears stream's interrupt status register.
+                       Changing stream mask always clears stream's interrupt status register.
        $00F4.L stream master interrupt enable bit mask. RW.
        $00F8.L stream master interrupt request bit mask. RO.
 
@@ -190,9 +192,8 @@ static struct uaesndboard_data uaesndboard[MAX_DUPLICATE_SOUND_BOARDS];
        $0185.B Reserved
        $0186.B Reserved
        $0187.B Interrupt status. 7: set when interrupt active. 0,1,2,3: same as 34.B bit, always set when condition matches,
-               even if 34.B bit is not set. If also 34.B bit is set: bit 7 set and interrupt is activated.
-               bit 4 = timer interrupt.
-               Reading clears interrupt. RO.
+                       even if 34.B bit is not set. If also 34.B bit is set: bit 7 set and interrupt is activated.
+                       bit 4 = timer interrupt. Reading clears interrupt. RO.
        $0188.B Reserved
        $0189.B Reserved
        $018A.B Reserved
@@ -206,6 +207,9 @@ static struct uaesndboard_data uaesndboard[MAX_DUPLICATE_SOUND_BOARDS];
        $0192.B Reserved
        $0193.B Status (Read: bit 0 = play active, bit 1 = output stream allocated, bit 2 = repeating, Write: reload sample set if not playing or repeating)
        $0194.L Timer frequency (same format as 12.L), sets interrupt bit 4. Zero = disabled. WO.
+       $0198.L
+       $019C.L
+       $01a0.L Sample set pointer, force load. WO.
 
        $0200 stream 2
 
@@ -292,10 +296,11 @@ static void uaesndboard_stop(struct uaesndboard_data *data, struct uaesndboard_s
                return;
 
 #if DEBUG_SNDDEV
-       write_log("uaesnd %d: stop\n", s - data->stream);
+       write_log("UAESND %d: STOP\n", s - data->stream);
 #endif
 
        s->play = 0;
+       s->next = 0;
        data->streammask &= ~(1 << (s - data->stream));
        audio_enable_stream(false, s->streamid, 0, NULL, NULL);
        s->streamid = 0;
@@ -316,7 +321,7 @@ static void uaesndboard_maybe_alloc_stream(struct uaesndboard_data *data, struct
                s->streamid = audio_enable_stream(true, -1, MAX_UAE_CHANNELS, audio_state_sndboard_uae, NULL);
 
 #if DEBUG_SNDDEV
-               write_log("uaesnd %d: stream start %d\n", s - data->stream, s->streamid);
+               write_log("UAESND %d: Stream allocated %d\n", s - data->stream, s->streamid);
 #endif
 
                if (!s->streamid) {
@@ -394,7 +399,7 @@ static void uaesndboard_start(struct uaesndboard_data *data, struct uaesndboard_
                return;
 
 #if DEBUG_SNDDEV
-       write_log("uaesnd %d: start\n", s - data->stream);
+       write_log("UAESND %d: PLAY\n", s - data->stream);
 #endif
 
        s->play = 1;
@@ -429,11 +434,11 @@ static bool uaesnd_validate(struct uaesndboard_data *data, struct uaesndboard_st
        s->framesize = samplebits * s->ch / 8;
 
        if (s->flags != 0) {
-               write_log(_T("UAESND: Flags must be zero\n"));
+               write_log(_T("UAESND: Flags must be zero (%08x)\n"), s->flags);
                return false;
        }
        if (s->format != 0) {
-               write_log(_T("UAESND: Only format=0 supported\n"));
+               write_log(_T("UAESND: Only format=0 supported (%04x)\n"), s->format);
                return false;
        }
        if (s->ch < 0 || s->ch > MAX_UAE_CHANNELS || s->ch == 3 || s->ch == 5 || s->ch == 7) {
@@ -519,6 +524,7 @@ static void uaesnd_load(struct uaesndboard_stream *s, uaecptr addr)
        put_long_host(s->io + 44, s->original_len);
 
 #if DEBUG_SNDDEV
+       write_log(_T("PTR = %08x\n"), addr);
        write_log(_T("Flags = %04x\n"), s->flags);
        write_log(_T("Format = %04x\n"), s->format);
        write_log(_T("Address = %08x\n"), s->address);
@@ -562,28 +568,33 @@ static bool uaesnd_directload(struct uaesndboard_data *data, struct uaesndboard_
 
 static bool uaesnd_next(struct uaesndboard_data *data, struct uaesndboard_stream *s, uaecptr addr)
 {
-       if ((addr & 3) || !valid_address(addr, STREAM_STRUCT_SIZE)) {
+       if ((addr & 3) || !valid_address(addr, STREAM_STRUCT_SIZE) || addr < 0x100) {
                write_log(_T("UAESND: invalid sample set pointer %08x\n"), addr);
                return false;
        }
 
        s->setaddr = addr;
        uaesnd_load(s, addr);
-       s->first = true;
+       s->first = 10;
        s->repeating = false;
 
        return uaesnd_validate(data, s);
 }
 
-static void uaesnd_stream_start(struct uaesndboard_data *data, struct uaesndboard_stream *s)
+static void uaesnd_stream_start(struct uaesndboard_data *data, struct uaesndboard_stream *s, bool always)
 {
-       if (!s->play && s->next) {
+       if ((!s->play || always) && s->next) {
                if (data->streammask & (1 << (s - data->stream))) {
+#if DEBUG_SNDDEV
+                       write_log(_T("UAESND %d start (old=%d,forced=%d,next=%08x)\n"), s - data->stream, s->play, always, s->next);
+#endif
                        if (uaesnd_next(data, s, s->next)) {
                                uaesndboard_start(data, s);
+                               return;
                        }
                }
-       } else if (s->play && !s->next) {
+       }
+       if (s->play && !s->next) {
                uaesndboard_stop(data, s);
        }
 }
@@ -609,7 +620,7 @@ static void uaesnd_streammask(struct uaesndboard_data *data, uae_u32 m)
                        struct uaesndboard_stream *s = &data->stream[i];
                        s->intreqmask = 0;
                        if (data->streammask & (1 << i)) {
-                               uaesnd_stream_start(data, s);
+                               uaesnd_stream_start(data, s, false);
                        } else {
                                uaesndboard_stop(data, s);
                        }
@@ -705,9 +716,11 @@ static bool audio_state_sndboard_uae(int streamid, void *params)
                        }
                        uaesnd_irq(s, 8);
                }
-               if (s->first) {
-                       uaesnd_irq(s, 1);
-                       s->first = false;
+               if (s->first > 0) {
+                       s->first--;
+                       if (!s->first) {
+                               uaesnd_irq(s, 1);
+                       }
                }
                // if len was zero when called: do nothing.
                if (len == 0 && len_nonzero) {
@@ -717,11 +730,15 @@ static bool audio_state_sndboard_uae(int streamid, void *params)
                                if (s->repcnt != 0xffff)
                                        s->repcnt--;
                                s->repeat = get_long(s->setaddr + 16);
-                               s->replen = get_long(s->setaddr + 20);
-                               if (s->replen == 0) {
-                                       s->replen = s->lastlen;
+                               if (s->repeat) {
+                                       s->replen = get_long(s->setaddr + 20);
+                                       if (s->replen == 0) {
+                                               s->replen = s->lastlen;
+                                       } else {
+                                               s->lastlen = s->replen;
+                                       }
                                } else {
-                                       s->lastlen = s->replen;
+                                       s->repeat = 0;
                                }
                                s->repeating = true;
                                uaesnd_irq(s, 4);
@@ -845,7 +862,11 @@ static void uaesnd_put(struct uaesndboard_data *data, struct uaesndboard_stream
        if (reg == 0x80) { // set pointer write?
                uaecptr setaddr = get_long_host(s->io + 0x80);
                s->next = setaddr;
-               uaesnd_stream_start(data, s);
+               uaesnd_stream_start(data, s, false);
+       } else if (reg == 0xa0) { // force set pointer write?
+               uaecptr setaddr = get_long_host(s->io + 0xa0);
+               s->next = setaddr;
+               uaesnd_stream_start(data, s, true);
        } else if (reg >= 0x8c && reg <= 0x8f) {
                s->masterintenamask = get_long_host(s->io + 0x8c);
        } else if (reg == 0x94) { // timer
@@ -864,9 +885,13 @@ static void uaesnd_put(struct uaesndboard_data *data, struct uaesndboard_stream
                        }
                }
        } else if (reg == 0x93) { // status strobe
-               s->repcnt = 0;
-               if (!s->play || s->repeating) {
-                       uaesnd_next(data, s, s->next);
+               uae_u8 b = get_byte_host(s->io + 0x93);
+               if (b & 1) {
+                       // new sample queued, do not repeat or if already repeating: start immediately
+                       s->repcnt = 0;
+                       if (s->repeating) {
+                               s->replen = 1;
+                       }
                }
        } else if (reg < 0x40) {
                if (!uaesnd_directload(data, s, reg)) {
@@ -910,7 +935,7 @@ static uae_u32 REGPARAM2 uaesndboard_bget(uaecptr addr)
                        v = data->streamintreqmask >> ((3 - (addr - 0xf0)) * 8);
                }
        }
-#if DEBUG_SNDDEV
+#if DEBUG_SNDDEV_READ
        write_log(_T("uaesnd_bget %08x = %02x\n"), addr, v);
 #endif
        return v;
@@ -960,7 +985,7 @@ static uae_u32 REGPARAM2 uaesndboard_wget(uaecptr addr)
                        v = data->streamintreqmask;
                }
        }
-#if DEBUG_SNDDEV
+#if DEBUG_SNDDEV_READ
        write_log(_T("uaesnd_wget %08x = %04x\n"), addr, v);
 #endif
        return v;
@@ -993,7 +1018,7 @@ static uae_u32 REGPARAM2 uaesndboard_lget(uaecptr addr)
                        v = data->streamintreqmask;
                }
        }
-#if DEBUG_SNDDEV
+#if DEBUG_SNDDEV_READ
        write_log(_T("uaesnd_lget %08x = %08x\n"), addr, v);
 #endif
        return v;
@@ -1025,7 +1050,7 @@ static void REGPARAM2 uaesndboard_bput(uaecptr addr, uae_u32 b)
                return;
        } else {
                struct uaesndboard_stream *s = uaesnd_addr(addr);
-#if DEBUG_SNDDEV
+#if DEBUG_SNDDEV_WRITE
                write_log(_T("uaesnd_bput %08x = %02x\n"), addr, b);
 #endif
                if (s) {
@@ -1072,7 +1097,7 @@ static void REGPARAM2 uaesndboard_wput(uaecptr addr, uae_u32 b)
        } else {
                if (addr & 1)
                        return;
-#if DEBUG_SNDDEV
+#if DEBUG_SNDDEV_WRITE
                write_log(_T("uaesnd_wput %08x = %04x\n"), addr, b);
 #endif
                struct uaesndboard_stream *s = uaesnd_addr(addr);
@@ -1098,7 +1123,7 @@ static void REGPARAM2 uaesndboard_lput(uaecptr addr, uae_u32 b)
        if (data->configured) {
                if (addr & 3)
                        return;
-#if DEBUG_SNDDEV
+#if DEBUG_SNDDEV_WRITE
                write_log(_T("uaesnd_lput %08x = %08x\n"), addr, b);
 #endif
                struct uaesndboard_stream *s = uaesnd_addr(addr);