]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
imported winuaesrc2020b4.zip
authorToni Wilen <twilen@winuae.net>
Sat, 16 Jan 2010 10:21:18 +0000 (12:21 +0200)
committerToni Wilen <twilen@winuae.net>
Mon, 22 Feb 2010 19:50:37 +0000 (21:50 +0200)
29 files changed:
akiko.c
blitter.c
blkdev.c
blkdev_cdimage.c [new file with mode: 0644]
cdtv.c
cfgfile.c
cia.c
custom.c
disk.c
filesys.c
gencpu.c
hardfile.c
include/akiko.h
include/blkdev.h
include/cpu_prefetch.h
include/newcpu.h
include/options.h
main.c
newcpu.c
od-win32/blkdev_win32_aspi.c
od-win32/blkdev_win32_ioctl.c
od-win32/blkdev_win32_spti.c
od-win32/win32.c
od-win32/win32.h
od-win32/win32gfx.c
od-win32/win32gui.c
od-win32/winuae_msvc/winuae_msvc.vcproj
od-win32/winuaechangelog.txt
zfile.c

diff --git a/akiko.c b/akiko.c
index 5e780193c9807f2099076bb04ecc12130de53692..77d553375e18069276c697aa0e4ca653f1528c46 100644 (file)
--- a/akiko.c
+++ b/akiko.c
@@ -411,6 +411,7 @@ static int cdrom_audiotimeout;
 static int cdrom_led;
 static int cdrom_dosomething;
 static int cdrom_receive_started;
+static int cdrom_muted;
 static int cd_initialized;
 
 static uae_u8 *sector_buffer_1, *sector_buffer_2;
@@ -650,9 +651,13 @@ static int sys_cddev_open (void)
        struct device_info di1, *di2;
        int cd32unit = -1;
        int audiounit = -1;
+       int opened[MAX_TOTAL_DEVICES];
+       int i;
 
        for (unitnum = 0; unitnum < MAX_TOTAL_DEVICES; unitnum++) {
+               opened[unitnum] = 0;
                if (sys_command_open (DF_IOCTL, unitnum)) {
+                       opened[unitnum] = 1;
                        di2 = sys_command_info (DF_IOCTL, unitnum, &di1);
                        if (di2 && di2->type == INQ_ROMD) {
                                write_log (L"%s: ", di2->label);
@@ -687,7 +692,6 @@ static int sys_cddev_open (void)
                                        write_log (L"can't read TOC\n");
                                }
                        }
-                       sys_command_close (DF_IOCTL, unitnum);
                }
        }
        unitnum = audiounit;
@@ -695,10 +699,14 @@ static int sys_cddev_open (void)
                unitnum = cd32unit;
        if (unitnum < 0)
                unitnum = first;
+       if (unitnum >= 0)
+               opened[unitnum] = 0;
+       for (i = 0; i < MAX_TOTAL_DEVICES; i++) {
+               if (opened[i])
+                       sys_command_close (DF_IOCTL, i);
+       }
        if (unitnum < 0)
                return 1;
-       if (!sys_command_open (DF_IOCTL, unitnum))
-               write_log (L"re-opening unit %d failed!\n", unitnum);
        di2 = sys_command_info (DF_IOCTL, unitnum, &di1);
        if (!di2) {
                write_log (L"unit %d info failed\n", unitnum);
@@ -1238,7 +1246,11 @@ static void *akiko_thread (void *null)
                        case 0x0104: // stop
                                cdaudiostop_do ();
                                break;
+                       case 0x0105: // mute change
+                               sys_command_cd_volume (DF_IOCTL, unitnum, cdrom_muted ? 0 : 0xffff);
+                               break;
                        case 0x0110: // do_play!
+                               sys_command_cd_volume (DF_IOCTL, unitnum, cdrom_muted ? 0 : 0xffff);
                                cdaudioplay_do ();
                                break;
                        }
@@ -1829,12 +1841,12 @@ void restore_akiko_finish (void)
        if (!currprefs.cs_cd32cd)
                return;
        akiko_c2p_do ();
-       write_comm_pipe_u32 (&requests, 0x102, 1); // pause
-       write_comm_pipe_u32 (&requests, 0x104, 1); // stop
-       write_comm_pipe_u32 (&requests, 0x103, 1); // unpause
+       write_comm_pipe_u32 (&requests, 0x0102, 1); // pause
+       write_comm_pipe_u32 (&requests, 0x0104, 1); // stop
+       write_comm_pipe_u32 (&requests, 0x0103, 1); // unpause
        if (cdrom_playing) {
-               write_comm_pipe_u32 (&requests, 0x103, 1); // unpause
-               write_comm_pipe_u32 (&requests, 0x110, 0); // play
+               write_comm_pipe_u32 (&requests, 0x0103, 1); // unpause
+               write_comm_pipe_u32 (&requests, 0x0110, 0); // play
                write_comm_pipe_u32 (&requests, last_play_pos, 0);
                write_comm_pipe_u32 (&requests, last_play_end, 0);
                write_comm_pipe_u32 (&requests, 0, 1);
@@ -1846,11 +1858,18 @@ void restore_akiko_finish (void)
 void akiko_entergui (void)
 {
        if (cdrom_playing)
-               write_comm_pipe_u32 (&requests, 0x102, 1);
+               write_comm_pipe_u32 (&requests, 0x0102, 1);
 }
 void akiko_exitgui (void)
 {
        if (cdrom_playing)
-               write_comm_pipe_u32 (&requests, 0x103, 1);
+               write_comm_pipe_u32 (&requests, 0x0103, 1);
+}
+
+void akiko_mute (int muted)
+{
+       cdrom_muted = muted;
+       if (unitnum >= 0)
+               write_comm_pipe_u32 (&requests, 0x0105, 1);
 }
 
index 6749e338707c6544fa0283cbbcc3ca88d9723fca..ebfac6864a07f93a416db6a612e635814c00c98b 100644 (file)
--- a/blitter.c
+++ b/blitter.c
@@ -824,7 +824,7 @@ STATIC_INLINE uae_u16 blitter_doblit (void)
 }
 
 
-STATIC_INLINE int blitter_doddma (int hpos)
+STATIC_INLINE void blitter_doddma (int hpos)
 {
        int wd;
        uae_u16 d;
@@ -841,25 +841,25 @@ STATIC_INLINE int blitter_doddma (int hpos)
                d = ddat1;
                ddat1use = 0;
                wd = 1;
+       } else {
+               write_log (L"BLITTER: D-channel without nothing to do?\n");
+               return;
        }
-       if (wd) {
-               alloc_cycle_ext (hpos, CYCLE_BLITTER);
-               record_dma_blit (0x00, d, bltdpt, hpos);
-               last_custom_value1 = d;
-               chipmem_agnus_wput2 (bltdpt, d);
-               bltdpt += blit_add;
-               blitter_hcounter2++;
-               if (blitter_hcounter2 == hblitsize) {
-                       blitter_hcounter2 = 0;
-                       bltdpt += blit_modaddd;
-                       blitter_vcounter2++;
-                       if (blitter_vcounter2 > blitter_vcounter1)
-                               blitter_vcounter1 = blitter_vcounter2;
-               }
-               if (blit_ch == 1)
-                       blitter_hcounter1 = blitter_hcounter2;
+       alloc_cycle_ext (hpos, CYCLE_BLITTER);
+       record_dma_blit (0x00, d, bltdpt, hpos);
+       last_custom_value1 = d;
+       chipmem_agnus_wput2 (bltdpt, d);
+       bltdpt += blit_add;
+       blitter_hcounter2++;
+       if (blitter_hcounter2 == hblitsize) {
+               blitter_hcounter2 = 0;
+               bltdpt += blit_modaddd;
+               blitter_vcounter2++;
+               if (blitter_vcounter2 > blitter_vcounter1)
+                       blitter_vcounter1 = blitter_vcounter2;
        }
-       return wd;
+       if (blit_ch == 1)
+               blitter_hcounter1 = blitter_hcounter2;
 }
 
 STATIC_INLINE void blitter_dodma (int ch, int hpos)
@@ -1045,10 +1045,9 @@ void decide_blitter (int hpos)
 
                        blt_info.got_cycle = 1;
                        if (c == 4) {
-                               if (blitter_doddma (last_blitter_hpos)) {
-                                       blit_cyclecounter++;
-                                       blit_totalcyclecounter++;
-                               }
+                               blitter_doddma (last_blitter_hpos);
+                               blit_cyclecounter++;
+                               blit_totalcyclecounter++;
                        } else {
                                if (blitter_vcounter1 < vblitsize) {
                                        blitter_dodma (c, last_blitter_hpos);
@@ -1169,6 +1168,7 @@ static void blit_bltset (int con)
                        blit_frozen = 0; // switched back to original fill mode? unfreeze
                } else if (iseo && !isen) {
                        blit_frozen = 1;
+                       write_log (L"BLITTER: frozen! %d (%d) -> %d (%d) %08X\n", original_ch, iseo, blit_ch, isen, M68K_GETPC);
                } else if (!iseo && isen) {
 #ifdef BLITTER_DEBUG_NOWAIT
                        write_log (L"BLITTER: on the fly %d (%d) -> %d (%d) switch\n", original_ch, iseo, blit_ch, isen);
index f0e284bd15cde347ae291544f725f07f07ccca63..1c6fe48732268f1087e2cadcf0bd9cfc3932dfc5 100644 (file)
--- a/blkdev.c
+++ b/blkdev.c
@@ -25,14 +25,19 @@ static int initialized;
 extern struct device_functions devicefunc_win32_aspi;
 extern struct device_functions devicefunc_win32_spti;
 extern struct device_functions devicefunc_win32_ioctl;
+extern struct device_functions devicefunc_cdimage;
 
 static void install_driver (int flags)
 {
        int installed = 0;
 
        device_func[DF_SCSI] = &devicefunc_win32_aspi;
+       if (devicefunc_cdimage.openbus (0)) {
+               device_func[DF_IOCTL] = &devicefunc_cdimage;
+       }
 #ifdef WINDDK
-       device_func[DF_IOCTL] = &devicefunc_win32_ioctl;
+       if (!device_func[DF_IOCTL])
+               device_func[DF_IOCTL] = &devicefunc_win32_ioctl;
        device_func[DF_SCSI] = &devicefunc_win32_spti;
        installed = 1;
        if (currprefs.win32_uaescsimode == UAESCSI_ADAPTECASPI ||
@@ -155,6 +160,14 @@ int sys_command_cd_play (int mode, int unitnum,uae_u32 startmsf, uae_u32 endmsf,
        return device_func[DF_IOCTL]->play (unitnum, startmsf, endmsf, scan);
 }
 
+/* set CD audio volume */
+void sys_command_cd_volume (int mode, int unitnum, uae_u16 volume)
+{
+       if (mode == DF_SCSI || !have_ioctl)
+               return;
+       device_func[DF_IOCTL]->volume (unitnum, volume);
+}
+
 /* read qcode */
 uae_u8 *sys_command_cd_qcode (int mode, int unitnum)
 {
diff --git a/blkdev_cdimage.c b/blkdev_cdimage.c
new file mode 100644 (file)
index 0000000..7be044e
--- /dev/null
@@ -0,0 +1,901 @@
+/*
+* UAE
+*
+* CD32/CDTV image file support
+*
+* Copyright 2010 Toni Wilen
+*
+*/
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+#include "options.h"
+#include "blkdev.h"
+#include "zfile.h"
+#include "gui.h"
+#include "fsdb.h"
+#include "threaddep/thread.h"
+
+#define USE 1
+
+#define CDDA_BUFFERS 6
+
+#define AUDIO_STATUS_NOT_SUPPORTED  0x00
+#define AUDIO_STATUS_IN_PROGRESS    0x11
+#define AUDIO_STATUS_PAUSED         0x12
+#define AUDIO_STATUS_PLAY_COMPLETE  0x13
+#define AUDIO_STATUS_PLAY_ERROR     0x14
+#define AUDIO_STATUS_NO_STATUS      0x15
+
+struct cdtoc
+{
+       struct zfile *handle;
+       int offset;
+       int filesize;
+       uae_u8 *data;
+       TCHAR *fname;
+       int address;
+       uae_u8 adr, ctrl;
+       int track;
+       int size;
+};
+
+static uae_u8 buffer[2352];
+static struct cdtoc toc[102];
+static int tracks;
+
+static int cdda_play_finished;
+static int cdda_play;
+static int cdda_paused;
+static int cdda_volume;
+static int cdda_volume_main;
+static uae_u32 cd_last_pos;
+static int cdda_start, cdda_end;
+
+/* convert minutes, seconds and frames -> logical sector number */
+static int msf2lsn (int        msf)
+{
+       int sector = (((msf >> 16) & 0xff) * 60 * 75 + ((msf >> 8) & 0xff) * 75 + ((msf >> 0) & 0xff));
+       return sector - 150;
+}
+
+/* convert logical sector number -> minutes, seconds and frames */
+static int lsn2msf (int        sectors)
+{
+       int msf;
+       sectors += 150;
+       msf = (sectors / (75 * 60)) << 16;
+       msf |= ((sectors / 75) % 60) << 8;
+       msf |= (sectors % 75) << 0;
+       return msf;
+}
+
+static struct cdtoc *findtoc (int *sectorp)
+{
+       int i;
+       int sector;
+
+       sector = *sectorp;
+       for (i = 0; i <= tracks; i++) {
+               struct cdtoc *t = &toc[i];
+               if (t->address > sector) {
+                       if (i == 0)
+                               return NULL;
+                       t--;
+                       sector -= t->address;
+                       *sectorp = sector;
+                       return t;
+               }
+       }
+       return NULL;
+}
+
+#ifdef _WIN32
+
+#include <windows.h>
+#include <mmreg.h>
+#include <msacm.h>
+
+#define MP3_BLOCK_SIZE 522
+
+static HACMSTREAM g_mp3stream = NULL;
+
+static void mp3decoder_close (void)
+{
+       if (g_mp3stream)
+               acmStreamClose (g_mp3stream, 0);
+       g_mp3stream = NULL;
+}
+
+static int mp3decoder_open (void)
+{
+       MMRESULT mmr;
+       LPWAVEFORMATEX waveFormat;
+       LPMPEGLAYER3WAVEFORMAT mp3format;
+       DWORD maxFormatSize;
+
+       if (g_mp3stream)
+               return 1;
+       
+       // find the biggest format size
+       maxFormatSize = 0;
+       mmr = acmMetrics (NULL, ACM_METRIC_MAX_SIZE_FORMAT, &maxFormatSize);
+  
+       // define desired output format
+       waveFormat = (LPWAVEFORMATEX) LocalAlloc( LPTR, maxFormatSize );
+       waveFormat->wFormatTag = WAVE_FORMAT_PCM;
+       waveFormat->nChannels = 2; // stereo
+       waveFormat->nSamplesPerSec = 44100; // 44.1kHz
+       waveFormat->wBitsPerSample = 16; // 16 bits
+       waveFormat->nBlockAlign = 4; // 4 bytes of data at a time are useful (1 sample)
+       waveFormat->nAvgBytesPerSec = 4 * 44100; // byte-rate
+       waveFormat->cbSize = 0; // no more data to follow
+  
+       // define MP3 input format
+       mp3format = (LPMPEGLAYER3WAVEFORMAT) LocalAlloc( LPTR, maxFormatSize );
+       mp3format->wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
+       mp3format->wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
+       mp3format->wfx.nChannels = 2;
+       mp3format->wfx.nAvgBytesPerSec = 128 * (1024 / 8);  // not really used but must be one of 64, 96, 112, 128, 160kbps
+       mp3format->wfx.wBitsPerSample = 0;                  // MUST BE ZERO
+       mp3format->wfx.nBlockAlign = 1;                     // MUST BE ONE
+       mp3format->wfx.nSamplesPerSec = 44100;              // 44.1kHz
+       mp3format->fdwFlags = MPEGLAYER3_FLAG_PADDING_OFF;
+       mp3format->nBlockSize = MP3_BLOCK_SIZE;             // voodoo value #1
+       mp3format->nFramesPerBlock = 1;                     // MUST BE ONE
+       mp3format->nCodecDelay = 1393;                      // voodoo value #2
+       mp3format->wID = MPEGLAYER3_ID_MPEG;
+  
+       mmr = acmStreamOpen( &g_mp3stream,               // open an ACM conversion stream
+                    NULL,                       // querying all ACM drivers
+                    (LPWAVEFORMATEX) mp3format, // converting from MP3
+                    waveFormat,                 // to WAV
+                    NULL,                       // with no filter
+                    0,                          // or async callbacks
+                    0,                          // (and no data for the callback)
+                    0                           // and no flags
+                    );
+  
+       LocalFree (mp3format);
+       LocalFree (waveFormat);
+       if (mmr == MMSYSERR_NOERROR)
+               return 1;
+       write_log (L"CUEMP3: couldn't open ACM mp3 decoder, %d\n", mmr);
+       return 0;
+}
+
+static uae_u8 *mp3decoder_get (struct zfile *zf, int *size)
+{
+       MMRESULT mmr;
+       unsigned long rawbufsize = 0;
+       LPBYTE mp3buf;
+       LPBYTE rawbuf;
+       uae_u8 *outbuf = NULL;
+       int outsize = 0;
+       int outsizer = 10000000;
+       int outoffset = 0;
+       ACMSTREAMHEADER mp3streamHead;
+
+       write_log (L"CUEMP3: decoding '%s'..\n", zfile_getname (zf));
+       mmr = acmStreamSize (g_mp3stream, MP3_BLOCK_SIZE, &rawbufsize, ACM_STREAMSIZEF_SOURCE);
+       if (mmr != MMSYSERR_NOERROR) {
+               write_log (L"CUEMP3: acmStreamSize, %d\n", mmr);
+               return NULL;
+       }
+       // allocate our I/O buffers
+       mp3buf = (LPBYTE) LocalAlloc (LPTR, MP3_BLOCK_SIZE);
+       rawbuf = (LPBYTE) LocalAlloc (LPTR, rawbufsize);
+  
+       // prepare the decoder
+       ZeroMemory (&mp3streamHead, sizeof (ACMSTREAMHEADER));
+       mp3streamHead.cbStruct = sizeof (ACMSTREAMHEADER);
+       mp3streamHead.pbSrc = mp3buf;
+       mp3streamHead.cbSrcLength = MP3_BLOCK_SIZE;
+       mp3streamHead.pbDst = rawbuf;
+       mp3streamHead.cbDstLength = rawbufsize;
+       mmr = acmStreamPrepareHeader (g_mp3stream, &mp3streamHead, 0);
+       if (mmr != MMSYSERR_NOERROR) {
+               write_log (L"CUEMP3: acmStreamPrepareHeader, %d\n", mmr);
+               return NULL;
+       }
+       for (;;) {
+               int count = zfile_fread (mp3buf, 1, MP3_BLOCK_SIZE, zf);
+               if (count != MP3_BLOCK_SIZE)
+                       break;
+               // convert the data
+               mmr = acmStreamConvert (g_mp3stream, &mp3streamHead, ACM_STREAMCONVERTF_BLOCKALIGN);
+               if (mmr != MMSYSERR_NOERROR) {
+                       write_log (L"CUEMP3: acmStreamConvert, %d\n", mmr);
+                       return NULL;
+               }
+               if (outoffset + mp3streamHead.cbDstLengthUsed > outsize) {
+                       outsize += outsizer;
+                       outbuf = realloc (outbuf, outsize);
+                       if (!outbuf)
+                               break;
+               }
+               memcpy (outbuf + outoffset, rawbuf, mp3streamHead.cbDstLengthUsed);
+               outoffset += mp3streamHead.cbDstLengthUsed;
+       }
+       acmStreamUnprepareHeader (g_mp3stream, &mp3streamHead, 0);
+       LocalFree (rawbuf);
+       LocalFree (mp3buf);
+       write_log (L"CUEMP3: destination size %d bytes\n", outoffset);
+       *size = outoffset;
+       return outbuf;
+}
+
+static HWAVEOUT cdda_wavehandle;
+
+static void cdda_closewav (void)
+{
+       if (cdda_wavehandle != NULL)
+               waveOutClose (cdda_wavehandle);
+       cdda_wavehandle = NULL;
+}
+
+// DAE CDDA based on Larry Osterman's "Playing Audio CDs" blog series
+
+static int cdda_openwav (void)
+{
+       WAVEFORMATEX wav = { 0 };
+       MMRESULT mmr;
+
+       wav.cbSize = 0;
+       wav.nChannels = 2;
+       wav.nSamplesPerSec = 44100;
+       wav.wBitsPerSample = 16;
+       wav.nBlockAlign = wav.wBitsPerSample / 8 * wav.nChannels;
+       wav.nAvgBytesPerSec = wav.nBlockAlign * wav.nSamplesPerSec;
+       wav.wFormatTag = WAVE_FORMAT_PCM;
+       mmr = waveOutOpen (&cdda_wavehandle, WAVE_MAPPER, &wav, 0, 0, WAVE_ALLOWSYNC | WAVE_FORMAT_DIRECT);
+       if (mmr != MMSYSERR_NOERROR) {
+               write_log (L"CDDA: wave open %d\n", mmr);
+               cdda_closewav ();
+               return 0;
+       }
+       return 1;
+}
+
+static void *cdda_play_func (void *v)
+{
+       int cdda_pos;
+       int num_sectors = CDDA_BUFFERS;
+       int quit = 0;
+       int bufnum;
+       int buffered;
+       uae_u8 *px[2], *p;
+       int bufon[2];
+       int i;
+       WAVEHDR whdr[2];
+       MMRESULT mmr;
+       int volume, volume_main;
+       int oldplay;
+
+       for (i = 0; i < 2; i++) {
+               memset (&whdr[i], 0, sizeof (WAVEHDR));
+               whdr[i].dwFlags = WHDR_DONE;
+       }
+
+       while (cdda_play == 0)
+               Sleep (10);
+       oldplay = -1;
+
+       p = xmalloc (2 * num_sectors * 4096);
+       px[0] = p;
+       px[1] = p + num_sectors * 4096;
+       bufon[0] = bufon[1] = 0;
+       bufnum = 0;
+       buffered = 0;
+       volume = -1;
+       volume_main = -1;
+
+       if (cdda_openwav ()) {
+
+               for (i = 0; i < 2; i++) {
+                       memset (&whdr[i], 0, sizeof (WAVEHDR));
+                       whdr[i].dwBufferLength = 2352 * num_sectors;
+                       whdr[i].lpData = px[i];
+                       mmr = waveOutPrepareHeader (cdda_wavehandle, &whdr[i], sizeof (WAVEHDR));
+                       if (mmr != MMSYSERR_NOERROR) {
+                               write_log (L"CDDA: waveOutPrepareHeader %d:%d\n", i, mmr);
+                               goto end;
+                       }
+                       whdr[i].dwFlags |= WHDR_DONE;
+               }
+
+               while (cdda_play > 0) {
+
+                       if (oldplay != cdda_play) {
+                               struct cdtoc *t;
+                               int sector;
+                               sector = cdda_start;
+                               t = findtoc (&sector);
+                               if (!t)
+                                       write_log (L"CDDA: illegal sector number %d\n", cdda_start);
+                               else
+                                       write_log (L"CDDA: playing track %d (file '%s', offset %d, secoffset %d)\n",
+                                               t->track, t->fname, t->offset, sector);
+                               cdda_pos = cdda_start;
+                               oldplay = cdda_play;
+                       }
+
+                       while (!(whdr[bufnum].dwFlags & WHDR_DONE)) {
+                               Sleep (10);
+                               if (!cdda_play)
+                                       goto end;
+                       }
+                       bufon[bufnum] = 0;
+
+                       if ((cdda_pos < cdda_end || cdda_end == 0xffffffff) && !cdda_paused && cdda_play) {
+                               struct cdtoc *t;
+                               int sector;
+
+                               sector = cdda_pos;
+                               t = findtoc (&sector);
+                               if (t && t->handle) {
+                                       if (t->data) {
+                                               memcpy (px[bufnum], t->data + sector * t->size + t->offset, t->size * num_sectors);
+                                       } else {
+                                               zfile_fseek (t->handle, sector * t->size + t->offset, SEEK_SET);
+                                               if (zfile_fread (px[bufnum], t->size, num_sectors, t->handle) < num_sectors) {
+                                                       int i = num_sectors - 1;
+                                                       memset (px[bufnum], 0, t->size * num_sectors);
+                                                       while (i > 0) {
+                                                               if (zfile_fread (px[bufnum], t->size, i, t->handle) == i)
+                                                                       break;
+                                                               i--;
+                                                       }
+                                                       if (i == 0)
+                                                               write_log (L"CDDA: read error, track %d (file '%s' offset %d secoffset %d)\n",
+                                                                       t->track, t->fname, t->offset, sector);
+                                               }
+                                       }
+                               }
+       
+                               bufon[bufnum] = 1;
+                               if (volume != cdda_volume || volume_main != currprefs.sound_volume) {
+                                       int vol;
+                                       volume = cdda_volume;
+                                       volume_main = currprefs.sound_volume;
+                                       vol = (100 - volume_main) * volume / 100;
+                                       if (vol >= 0xffff)
+                                               vol = 0xffff;
+                                       waveOutSetVolume (cdda_wavehandle, vol | (vol << 16));
+                               }
+                               mmr = waveOutWrite (cdda_wavehandle, &whdr[bufnum], sizeof (WAVEHDR));
+                               if (mmr != MMSYSERR_NOERROR) {
+                                       write_log (L"CDDA: waveOutWrite %d\n", mmr);
+                                       break;
+                               }
+
+                               cdda_pos += num_sectors;
+                               if (cdda_pos >= cdda_end)
+                                       cdda_play_finished = 1;
+                               cd_last_pos = cdda_pos;
+
+                       }
+
+
+                       if (bufon[0] == 0 && bufon[1] == 0) {
+                               while (!(whdr[0].dwFlags & WHDR_DONE) || !(whdr[1].dwFlags & WHDR_DONE))
+                                       Sleep (10);
+                               while (cdda_paused && cdda_play > 0)
+                                       Sleep (10);
+                       }
+
+                       bufnum = 1 - bufnum;
+
+               }
+       }
+
+end:
+       while (!(whdr[0].dwFlags & WHDR_DONE) || !(whdr[1].dwFlags & WHDR_DONE))
+               Sleep (10);
+       for (i = 0; i < 2; i++)
+               waveOutUnprepareHeader  (cdda_wavehandle, &whdr[i], sizeof (WAVEHDR));
+
+       cdda_closewav ();
+       xfree (p);
+       cdda_play = 0;
+       write_log (L"CDDA: thread killed\n");
+       return NULL;
+}
+
+#endif
+
+static void cdda_stop (void)
+{
+       if (cdda_play > 0) {
+               cdda_play = -1;
+               while (cdda_play) {
+                       Sleep (10);
+               }
+       }
+       cdda_play_finished = 0;
+       cdda_paused = 0;
+}
+
+
+static int command_pause (int unitnum, int paused)
+{
+       cdda_paused = paused;
+       return 1;
+}
+
+static int command_stop (int unitnum)
+{
+       cdda_stop ();
+       return 1;
+}
+
+static int command_play (int unitnum, uae_u32 start, uae_u32 end, int scan)
+{
+       cdda_paused = 0;
+       cdda_play_finished = 0;
+       cdda_start = msf2lsn (start);
+       cdda_end = msf2lsn (end);
+       if (!cdda_play)
+               uae_start_thread (L"cdda_play", cdda_play_func, NULL, NULL);
+       cdda_play++;
+       return 1;
+}
+
+static uae_u8 *command_qcode (int unitnum)
+{
+       static uae_u8 buf[4 + 12];
+       uae_u8 *p;
+       int trk;
+       int pos;
+       int msf;
+       int start, end;
+       int status;
+
+       memset (buf, 0, sizeof buf);
+       p = buf;
+
+       status = AUDIO_STATUS_NO_STATUS;
+       if (cdda_play) {
+               status = AUDIO_STATUS_IN_PROGRESS;
+               if (cdda_paused)
+                       status = AUDIO_STATUS_PAUSED;
+       } else if (cdda_play_finished) {
+               status = AUDIO_STATUS_PLAY_COMPLETE;
+       }
+       pos = cd_last_pos;
+
+       p[1] = status;
+       p[3] = 12;
+
+       p = buf + 4;
+
+       if (pos >= 150)
+               trk = 0;
+       start = end = 0;
+       for (trk = 0; trk <= tracks; trk++) {
+               struct cdtoc *td = &toc[trk];
+               if (pos < td->address)
+                       break;
+               if (pos >= td->address && pos < td[1].address) {
+                       start = td->address;
+                       break;
+               }
+       }
+       p[1] = (toc[trk].ctrl << 0) | (toc[trk].adr << 4);
+       p[2] = trk + 1;
+       p[3] = 1;
+       msf = lsn2msf (pos);
+       p[5] = (msf >> 16) & 0xff;
+       p[6] = (msf >> 8) & 0xff;
+       p[7] = (msf >> 0) & 0xff;
+       pos -= start;
+       if (pos < 0)
+               pos = 0;
+       msf = lsn2msf (pos);
+       p[9] = (pos >> 16) & 0xff;
+       p[10] = (pos >> 8) & 0xff;
+       p[11] = (pos >> 0) & 0xff;
+
+       return buf;
+}
+
+static void command_volume (int unitnum, uae_u16 volume)
+{
+       cdda_volume = volume;
+}
+
+uae_u8 *command_rawread (int unitnum, int sector, int sectorsize)
+{
+       cdda_stop ();
+       return NULL;
+}
+static uae_u8 *command_read (int unitnum, int sector)
+{
+       struct cdtoc *t = findtoc (&sector);
+       int offset;
+       if (!t || t->handle == NULL)
+               return NULL;
+       cdda_stop ();
+       offset = 0;
+       if (t->size > 2048)
+               offset = 16;
+       zfile_fseek (t->handle, t->offset + sector * t->size + offset, SEEK_SET);
+       zfile_fread (buffer, 2048, 1, t->handle);
+       return buffer;
+}
+
+static uae_u8 *command_toc (int unitnum)
+{
+       static uae_u8 statictoc[11 * 102];
+       uae_u8 *p = statictoc;
+       int i;
+       uae_u32 msf;
+
+       cdda_stop ();
+       if (!tracks)
+               return NULL;
+       p[0] = ((tracks + 4) * 11) >> 8;
+       p[1] = ((tracks + 4) * 11) & 0xff;
+       p[2] = 1;
+       p[3] = tracks;
+       p += 4;
+       memset (p, 0, 11);
+       p[0] = 1;
+       p[1] = (toc[0].ctrl << 0) | (toc[0].adr << 4);
+       p[3] = 0xa0;
+       p[8] = 1;
+       p += 11;
+       memset (p, 0, 11);
+       p[0] = 1;
+       p[1] = 0x10;
+       p[3] = 0xa1;
+       p[8] = tracks;
+       p += 11;
+       memset (p, 0, 11);
+       p[0] = 1;
+       p[1] = 0x10;
+       p[3] = 0xa2;
+       msf = lsn2msf (toc[tracks].address);
+       p[8] = msf >> 16;
+       p[9] = msf >> 8;
+       p[10] = msf >> 0;
+       p += 11;
+       for (i = 0; i < tracks; i++) {
+               memset (p, 0, 11);
+               p[0] = 1;
+               p[1] = (toc[i].ctrl << 0) | (toc[i].adr << 4);
+               p[2] = 0;
+               p[3] = i + 1;
+               msf = lsn2msf (toc[i].address);
+               p[8] = msf >> 16;
+               p[9] = msf >> 8;
+               p[10] = msf >> 0;
+               p += 11;
+       }
+       gui_flicker_led (LED_CD, unitnum, 1);
+       return statictoc;
+}
+
+static void skipspace (TCHAR **s)
+{
+       while (_istspace (**s))
+               (*s)++;
+}
+static void skipnspace (TCHAR **s)
+{
+       while (!_istspace (**s))
+               (*s)++;
+}
+
+static TCHAR *nextstring (TCHAR **sp)
+{
+       TCHAR *s;
+       TCHAR *out = NULL;
+
+       skipspace (sp);
+       s = *sp;
+       if (*s == '\"') {
+               s++;
+               out = s;
+               while (*s && *s != '\"')
+                       s++;
+               *s++ = 0;
+       } else if (*s) {
+               out = s;
+               skipnspace (&s);
+               *s++ = 0;
+       }
+       *sp = s;
+       return out;
+}
+
+static int open_device (int unitnum)
+{
+       struct zfile *zcue;
+       TCHAR *fname, *fnametype;
+       int tracknum;
+       int offset, secoffset, newfile;
+       int i;
+       TCHAR *p;
+       TCHAR curdir[MAX_DPATH], oldcurdir[MAX_DPATH];
+       uae_u64 siz;
+       TCHAR *img = currprefs.cdimagefile;
+       int ctrl;
+
+       if (unitnum || !img)
+               return 0;
+       zcue = zfile_fopen (img, L"rb", 0);
+       if (!zcue)
+               return 0;
+
+       fname = NULL;
+       fnametype = NULL;
+       tracknum = 0;
+       offset = 0;
+       secoffset = 0;
+       newfile = 0;
+       ctrl = 0;
+
+       zfile_fseek (zcue, 0, SEEK_END);
+       siz = zfile_ftell (zcue);
+       zfile_fseek (zcue, 0, SEEK_SET);
+       if (siz >= 16384) {
+               if ((siz % 2048) == 0 || (siz % 2352) == 0) {
+                       struct cdtoc *t = &toc[0];
+                       tracks = 1;
+                       t->ctrl = 4;
+                       t->adr = 1;
+                       t->fname = my_strdup (img);
+                       t->handle = zcue;
+                       t->size = (siz % 2048) == 0 ? 2048 : 2352;
+                       write_log (L"CUE: plain CD image mounted!\n");
+                       zcue = NULL;
+                       goto isodone;
+               }
+               zfile_fclose (zcue);
+               return 0;
+       }
+
+       write_log (L"CUE TOC: '%s'\n", img);
+       _tcscpy (curdir, img);
+       oldcurdir[0] = 0;
+       p = curdir + _tcslen (curdir);
+       while (p > curdir) {
+               if (*p == '/' || *p == '\\')
+                       break;
+               p--;
+       }
+       *p = 0;
+       if (p > curdir)
+               my_setcurrentdir (curdir, oldcurdir);
+       for (;;) {
+               TCHAR buf[MAX_DPATH];
+               if (!zfile_fgets (buf, sizeof buf / sizeof (TCHAR), zcue))
+                       break;
+
+               p = buf;
+               skipspace (&p);
+
+               if (!_tcsnicmp (p, L"FILE", 4)) {
+                       p += 4;
+                       xfree (fname);
+                       fname = my_strdup (nextstring (&p));
+                       fnametype = nextstring (&p);
+                       if (_tcsicmp (fnametype, L"BINARY") && _tcsicmp (fnametype, L"WAVE") && _tcsicmp (fnametype, L"MP3")) {
+                               write_log (L"CUE: unknown file type '%s' ('%s')\n", fnametype, fname);
+                       }
+                       offset = 0;
+                       newfile = 1;
+                       ctrl = 0;
+               } else if (!_tcsnicmp (p, L"FLAGS", 5)) {
+                       ctrl &= ~(1 | 2 | 8);
+                       for (;;) {
+                               TCHAR *f = nextstring (&p);
+                               if (!f)
+                                       break;
+                               if (!_tcsicmp (f, L"PRE"))
+                                       ctrl |= 1;
+                               if (!_tcsicmp (f, L"DCP"))
+                                       ctrl |= 2;
+                               if (!_tcsicmp (f, L"4CH"))
+                                       ctrl |= 8;
+                       }
+               } else if (!_tcsnicmp (p, L"TRACK", 5)) {
+                       int size;
+                       TCHAR *tracktype;
+                       
+                       p += 5;
+                       tracknum = _tstoi (nextstring (&p));
+                       tracktype = nextstring (&p);
+                       size = 2352;
+                       if (!_tcsicmp (tracktype, L"AUDIO")) {
+                               ctrl &= ~4;
+                       } else {
+                               ctrl |= 4;
+                               if (!_tcsicmp (tracktype, L"MODE1/2048"))
+                                       size = 2048;
+                               else if (!_tcsicmp (tracktype, L"MODE1/2352"))
+                                       size = 2352;
+                               else if (!_tcsicmp (tracktype, L"MODE2/2336"))
+                                       size = 2336;
+                               else if (!_tcsicmp (tracktype, L"MODE2/2352"))
+                                       size = 2352;
+                               else {
+                                       write_log (L"CUE: unknown tracktype '%s' ('%s')\n", tracktype, fname);
+                               }
+                       }
+                       if (tracknum >= 1 && tracknum <= 99) {
+                               struct cdtoc *t = &toc[tracknum - 1];
+                               struct zfile *ztrack;
+
+                               if (tracknum > 1 && newfile) {
+                                       t--;
+                                       secoffset += t->filesize / t->size;
+                                       t++;
+                               }
+
+                               newfile = 0;
+                               ztrack = zfile_fopen (fname, L"rb", 0);
+                               if (!ztrack) {
+                                       TCHAR tmp[MAX_DPATH];
+                                       _tcscpy (tmp, fname);
+                                       p = tmp + _tcslen (tmp);
+                                       while (p > tmp) {
+                                               if (*p == '/' || *p == '\\') {
+                                                       ztrack = zfile_fopen (p + 1, L"rb", 0);
+                                                       if (ztrack) {
+                                                               xfree (fname);
+                                                               fname = my_strdup (p + 1);
+                                                       }
+                                                       break;
+                                               }
+                                               p--;
+                                       }
+                               }
+                               t->track = tracknum;
+                               t->ctrl = ctrl;
+                               t->adr = 1;
+                               t->handle = ztrack;
+                               t->size = size;
+                               t->fname = my_strdup (fname);
+                               if (tracknum > tracks)
+                                       tracks = tracknum;
+                               zfile_fseek (t->handle, 0, SEEK_END);
+                               t->filesize = zfile_ftell (t->handle);
+                               zfile_fseek (t->handle, 0, SEEK_SET);
+                       }
+               } else if (!_tcsnicmp (p, L"INDEX", 5)) {
+                       int idxnum;
+                       int tn = 0;
+                       TCHAR *tt;
+                       p += 5;
+                       idxnum = _tstoi (nextstring (&p));
+                       tt = nextstring (&p);
+                       tn = _tstoi (tt) * 60 * 75;
+                       tn += _tstoi (tt + 3) * 75;
+                       tn += _tstoi (tt + 6);
+                       if (tracknum >= 1 && tracknum <= 99) {
+                               struct cdtoc *t = &toc[tracknum - 1];
+                               if (!t->address) {
+                                       t->address = tn + secoffset;
+                                       if (tracknum > 1) {
+                                               offset += t->address - t[-1].address;
+                                       } else {
+                                               offset += t->address;
+                                       }
+                                       if (!secoffset)
+                                               t->offset = offset * t->size;
+                                       if (!_tcsicmp (fnametype, L"WAVE") && t->handle) {
+                                               struct zfile *zf = t->handle;
+                                               uae_u8 buf[16] = { 0 };
+                                               zfile_fread (buf, 12, 1, zf);
+                                               if (!memcmp (buf, "RIFF", 4) && !memcmp (buf + 8, "WAVE", 4)) {
+                                                       int size;
+                                                       for (;;) {
+                                                               memset (buf, 0, sizeof buf);
+                                                               if (zfile_fread (buf, 8, 1, zf) != 1)
+                                                                       break;
+                                                               size = (buf[4] << 0) | (buf[5] << 8) | (buf[6] << 16) | (buf[7] << 24);
+                                                               if (!memcmp (buf, "data", 4))
+                                                                       break;
+                                                               if (size <= 0)
+                                                                       break;
+                                                               zfile_fseek (zf, size, SEEK_CUR);
+                                                       }
+                                                       t->offset += zfile_ftell (zf);
+                                                       t->filesize = size;
+                                               }
+                                       } else if (!_tcsicmp (fnametype, L"MP3") && t->handle) {
+                                               t->offset = 0;
+                                               // bleh
+                                               if (mp3decoder_open ()) {
+                                                       t->data = mp3decoder_get (t->handle, &t->filesize);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+isodone:
+       if (tracks && toc[tracks - 1].handle) {
+               struct cdtoc *t = &toc[tracks - 1];
+               int size = t->filesize - offset * t->size;
+               if (size < 0)
+                       size = 0;
+               toc[tracks].address = toc[tracks - 1].address + size / t->size;
+       }
+       xfree (fname);
+       if (oldcurdir[0])
+               my_setcurrentdir (oldcurdir, NULL);
+       for (i = 0; i <= tracks; i++) {
+               struct cdtoc *t = &toc[i];
+               uae_u32 msf = lsn2msf (t->address);
+               if (i < tracks)
+                       write_log (L"%2d: ", i + 1);
+               else
+                       write_log (L"    ");
+               write_log (L"%7d %02d:%02d:%02d",
+                       t->address, (msf >> 16) & 0xff, (msf >> 8) & 0xff, (msf >> 0) & 0xff);
+               if (i < tracks)
+                       write_log (L" %s %x %10d %s", (t->ctrl & 4) ? L"DATA" : L"CDA ", t->ctrl, t->offset, t->handle == NULL ? L"FILE ERROR" : L"");
+               write_log (L"\n");
+               if (i < tracks)
+                       write_log (L" - %s\n", t->fname);
+       }
+       zfile_fclose (zcue);
+       mp3decoder_close ();
+       return 1;
+}
+static void close_device (int unitnum)
+{
+       int i;
+
+       for (i = 0; i < tracks; i++) {
+               struct cdtoc *t = &toc[i];
+               zfile_fclose (t->handle);
+               xfree (t->fname);
+               xfree (t->data);
+       }
+       memset (toc, 0, sizeof toc);
+       tracks = 0;
+}
+
+static int ismedia (int unitnum, int quick)
+{
+       return currprefs.cdimagefile[0] ? 1 : 0;
+}
+
+static int open_bus (int flags)
+{
+       return ismedia (0, 1);
+}
+
+static void close_bus (void)
+{
+}
+
+static struct device_info *info_device (int unitnum, struct device_info *di)
+{
+       if (unitnum)
+               return 0;
+       di->bus = unitnum;
+       di->target = 0;
+       di->lun = 0;
+       di->media_inserted = 0;
+       di->bytespersector = 2048;
+       if (ismedia (unitnum, 1))
+               di->media_inserted = 1;
+       di->write_protected = 1;
+       di->type = INQ_ROMD;
+       di->id = 1;
+       _tcscpy (di->label, L"IMG");
+       return di;
+}
+
+struct device_functions devicefunc_cdimage = {
+       open_bus, close_bus, open_device, close_device, info_device,
+       0, 0, 0,
+       command_pause, command_stop, command_play, command_volume, command_qcode,
+       command_toc, command_read, command_rawread, 0,
+       0, 0, ismedia
+};
diff --git a/cdtv.c b/cdtv.c
index e51542055c1aedc0c5cd73698e0353da24f1579d..887620cca5fb5af9c3f1bc342219450839303ad3 100644 (file)
--- a/cdtv.c
+++ b/cdtv.c
@@ -786,6 +786,10 @@ static void tp_bput (int addr, uae_u8 v)
 #ifdef CDTV_DEBUG_CMD
                write_log (L"CDTV CD volume = %d\n", cd_volume);
 #endif
+               if (cd_volume > 1023)
+                       cd_volume = 1023;
+               if (unitnum >= 0)
+                       sys_command_cd_volume (DF_IOCTL, unitnum, (cd_volume << 6) | (cd_volume >> 4));
                cd_volume = 0;
                volstrobe2 = 1;
        } else if (volstrobe2 && !((tp_b >> 7) & 1)) {
@@ -1310,6 +1314,8 @@ static void open_unit (void)
        struct device_info di1, *di2;
        int first = -1;
        int cdtvunit = -1, audiounit = -1;
+       int opened[MAX_TOTAL_DEVICES];
+       int i;
 
        if (unitnum >= 0)
                sys_command_close (DF_IOCTL, unitnum);
@@ -1320,7 +1326,9 @@ static void open_unit (void)
                return;
        }
        for (unitnum = 0; unitnum < MAX_TOTAL_DEVICES; unitnum++) {
+               opened[unitnum] = 0;
                if (sys_command_open (DF_IOCTL, unitnum)) {
+                       opened[unitnum] = 1;
                        di2 = sys_command_info (DF_IOCTL, unitnum, &di1);
                        if (di2 && di2->type == INQ_ROMD) {
                                write_log (L"%s: ", di2->label);
@@ -1345,7 +1353,6 @@ static void open_unit (void)
                                        write_log (L"TOC read failed\n");
                                }
                        }
-                       sys_command_close (DF_IOCTL, unitnum);
                }
        }
        unitnum = audiounit;
@@ -1353,9 +1360,14 @@ static void open_unit (void)
                unitnum = cdtvunit;
        if (unitnum < 0)
                unitnum = first;
+       if (unitnum >= 0)
+               opened[unitnum] = 0;
+       for (i = 0; i < MAX_TOTAL_DEVICES; i++) {
+               if (opened[i])
+                       sys_command_close (DF_IOCTL, i);
+       }
        cd_media = 0;
        if (unitnum >= 0) {
-               sys_command_open (DF_IOCTL, unitnum);
                cd_media = ismedia () ? -1 : 0;
                if (!cd_media)
                        cd_hunt = 1;
index 64cf1d09c2723299cfb76d4ccacf0b674e2164d7..42fa6bb5e68f7ec425478474b56b3952401f9abc 100644 (file)
--- a/cfgfile.c
+++ b/cfgfile.c
@@ -525,6 +525,9 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
                }
        }
 
+       if (p->cdimagefile[0])
+               cfgfile_write_str (f, L"cdimage0", p->cdimagefile);
+
        cfgfile_write (f, L"nr_floppies", L"%d", p->nr_floppies);
        cfgfile_write (f, L"floppy_speed", L"%d", p->floppy_speed);
        cfgfile_write (f, L"floppy_volume", L"%d", p->dfxclickvolume);
@@ -993,6 +996,9 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
                }
        }
 
+       if (cfgfile_string (option, value, L"cdimage0", p->cdimagefile, sizeof p->cdimagefile / sizeof (TCHAR)))
+               return 1;
+
        if (cfgfile_intval (option, value, L"sound_frequency", &p->sound_freq, 1)) {
                /* backwards compatibility */
                p->sound_latency = 1000 * (p->sound_maxbsiz >> 1) / p->sound_freq;
@@ -3475,7 +3481,7 @@ static void buildin_default_prefs (struct uae_prefs *p)
        target_default_options (p, 1);
 }
 
-static void set_68020_compa (struct uae_prefs *p, int compa)
+static void set_68020_compa (struct uae_prefs *p, int compa, int cd32)
 {
        if (compa == 0) {
                p->blitter_cycle_exact = 1;
@@ -3485,15 +3491,11 @@ static void set_68020_compa (struct uae_prefs *p, int compa)
                        p->cpu_clock_multiplier = 4 << 8;
                }
        }
-       if (compa > 0) {
+       if (compa > 1) {
                p->cpu_compatible = 0;
                p->address_space_24 = 0;
                p->cachesize = 8192;
        }
-       if (compa > 1) {
-               p->immediate_blits = 1;
-               p->produce_sound = 2;
-       }
 }
 
 /* 0: cycle-exact
@@ -3701,7 +3703,7 @@ static int bip_cd32 (struct uae_prefs *p, int config, int compa, int romcheck)
        p->nr_floppies = 0;
        p->dfxtype[0] = DRV_NONE;
        p->dfxtype[1] = DRV_NONE;
-       set_68020_compa (p, compa);
+       set_68020_compa (p, compa, 1);
        p->cs_compatible = CP_CD32;
        built_in_chipset_prefs (p);
        fetch_datapath (p->flashfile, sizeof (p->flashfile) / sizeof (TCHAR));
@@ -3723,7 +3725,7 @@ static int bip_a1200 (struct uae_prefs *p, int config, int compa, int romcheck)
                p->fastmem_size = 0x400000;
                p->cs_rtc = 2;
        }
-       set_68020_compa (p, compa);
+       set_68020_compa (p, compa, 0);
        p->cs_compatible = CP_A1200;
        built_in_chipset_prefs (p);
        return configure_rom (p, roms, romcheck);
diff --git a/cia.c b/cia.c
index 24c8e55844e0bb7738ba96eec38a73cfd79a9368..f7476ac84ba144c12e81e199025983f901ef4e47 100644 (file)
--- a/cia.c
+++ b/cia.c
@@ -58,7 +58,7 @@ static unsigned long ciaata_passed, ciaatb_passed, ciabta_passed, ciabtb_passed;
 
 static unsigned long ciaatod, ciabtod, ciaatol, ciabtol, ciaaalarm, ciabalarm;
 static int ciaatlatch, ciabtlatch;
-static int oldled, oldovl, led_changed;
+static int oldled, oldovl, oldcd32mute, led_changed;
 
 unsigned int ciabpra;
 
@@ -593,6 +593,9 @@ static void bfe001_change (void)
                        //activate_debugger ();
                        map_overlay (0);
                }
+       } else if (currprefs.cs_cd32cd && (v & 1) != oldcd32mute) {
+               oldcd32mute = v & 1;
+               akiko_mute (oldcd32mute ? 0 : 1);
        }
 }
 
@@ -1150,6 +1153,7 @@ void CIA_reset (void)
        ciaasdr_unread = 0;
        serbits = 0;
        oldovl = 1;
+       oldcd32mute = 1;
        oldled = -1;
        resetwarning_phase = resetwarning_timer = 0;
 
index 2ee9ac65ebd58e58e52fa5bc088e44238a5f4686..c2f534981db6b5431f765e42f7ba700a3e3e6ae0 100644 (file)
--- a/custom.c
+++ b/custom.c
@@ -3265,6 +3265,91 @@ static void DMACON (int hpos, uae_u16 v)
        events_schedule();
 }
 
+
+static void MISC_handler (void)
+{
+       int i, recheck;
+       evt mintime;
+       evt ct = get_cycles ();
+       static int recursive;
+
+       if (recursive)
+               return;
+       recursive++;
+       eventtab[ev_misc].active = 0;
+       recheck = 1;
+       while (recheck) {
+               recheck = 0;
+               mintime = ~0L;
+               for (i = 0; i < ev2_max; i++) {
+                       if (eventtab2[i].active) {
+                               if (eventtab2[i].evtime == ct) {
+                                       eventtab2[i].active = 0;
+                                       eventtab2[i].handler (eventtab2[i].data);
+                                       if (eventtab2[i].active)
+                                               recheck = 1;
+                               } else {
+                                       evt eventtime = eventtab2[i].evtime - ct;
+                                       if (eventtime < mintime)
+                                               mintime = eventtime;
+                               }
+                       }
+               }
+       }
+       if (mintime != ~0L) {
+               eventtab[ev_misc].active = 1;
+               eventtab[ev_misc].oldcycles = ct;
+               eventtab[ev_misc].evtime = ct + mintime;
+               events_schedule ();
+       }
+       recursive--;
+}
+
+STATIC_INLINE void event2_newevent_xx (int no, evt t, uae_u32 data, evfunc2 func)
+{
+       evt et;
+
+       et = t + get_cycles ();
+       if (no < 0) {
+               for (no = ev2_misc; no < ev2_max; no++) {
+                       if (!eventtab2[no].active)
+                               break;
+                       if (eventtab2[no].evtime == et && eventtab2[no].handler == func) {
+                               eventtab2[no].handler (eventtab2[no].data);
+                               break;
+                       }
+               }
+               if (no == ev2_max) {
+                       write_log (L"out of event2's! PC=%x\n", M68K_GETPC);
+                       return;
+               }
+       }
+       eventtab2[no].active = 1;
+       eventtab2[no].evtime = et;
+       eventtab2[no].handler = func;
+       eventtab2[no].data = data;
+       MISC_handler ();
+}
+
+STATIC_INLINE void event2_newevent_x (int no, evt t, uae_u32 data, evfunc2 func)
+{
+       if (((int)t) <= 0) {
+               func (data);
+               return;
+       }
+
+       event2_newevent_xx (no, t * CYCLE_UNIT, data, func);
+}
+
+void event2_newevent (int no, evt t)
+{
+       event2_newevent_x (no, t, 0, eventtab2[no].handler);
+}
+void event2_newevent2 (evt t, uae_u32 data, evfunc2 func)
+{
+       event2_newevent_x (-1, t, data, func);
+}
+
 static int irq_nmi;
 
 void NMI_delayed (void)
@@ -3301,6 +3386,15 @@ STATIC_INLINE int use_eventmode (void)
        return currprefs.cpu_cycle_exact != 0;
 }
 
+static void send_interrupt (void)
+{
+       int lev = intlev ();
+       if (lev < 0)
+               lev = 0;
+       if (lev != regs.ipl)
+               event2_newevent_xx (-1, 5 * CYCLE_UNIT, lev, prepare_interrupt);
+}
+
 STATIC_INLINE void INTENA (uae_u16 v)
 {
        setclr (&intena,v);
@@ -3308,9 +3402,9 @@ STATIC_INLINE void INTENA (uae_u16 v)
        if (v & 0x40)
                write_log (L"INTENA %04X (%04X) %p\n", intena, v, M68K_GETPC);
 #endif
-       if (v & 0x8000) {
-               if (use_eventmode ())
-                       prepare_interrupt ();
+       if (use_eventmode ()) {
+               send_interrupt ();
+       } else if (v & 0x8000) {
                doint ();
        }
 }
@@ -3321,21 +3415,21 @@ void INTREQ_0 (uae_u16 v)
        intreqr = intreq;
        /* data in intreq is immediately available (vsync only currently because there is something unknown..) */
        setclr (&intreqr, v & (0x8000 | 0x20));
-       setclr (&tmp, v);
+       setclr (&intreq, v);
 
+       if (v & (0x80 | 0x100 | 0x200 | 0x400))
+               audio_update_irq (v);
+       intreqr = intreq;
        if (use_eventmode ()) {
                if (tmp != intreq)
-                       prepare_interrupt ();
+                       send_interrupt ();
                if (tmp > intreq) {
                        if (debug_dma)
                                record_dma_event (DMA_EVENT_INTREQ, current_hpos (), vpos);
                }
+       } else {
+               doint ();
        }
-       if (v & (0x80 | 0x100 | 0x200 | 0x400))
-               audio_update_irq (v);
-       intreq = tmp;
-       intreqr = intreq;
-       doint ();
 }
 
 void INTREQ (uae_u16 data)
@@ -5499,90 +5593,6 @@ static void hsync_handler (void)
 #endif
 }
 
-static void MISC_handler (void)
-{
-       int i, recheck;
-       evt mintime;
-       evt ct = get_cycles ();
-       static int recursive;
-
-       if (recursive)
-               return;
-       recursive++;
-       eventtab[ev_misc].active = 0;
-       recheck = 1;
-       while (recheck) {
-               recheck = 0;
-               mintime = ~0L;
-               for (i = 0; i < ev2_max; i++) {
-                       if (eventtab2[i].active) {
-                               if (eventtab2[i].evtime == ct) {
-                                       eventtab2[i].active = 0;
-                                       eventtab2[i].handler (eventtab2[i].data);
-                                       if (eventtab2[i].active)
-                                               recheck = 1;
-                               } else {
-                                       evt eventtime = eventtab2[i].evtime - ct;
-                                       if (eventtime < mintime)
-                                               mintime = eventtime;
-                               }
-                       }
-               }
-       }
-       if (mintime != ~0L) {
-               eventtab[ev_misc].active = 1;
-               eventtab[ev_misc].oldcycles = ct;
-               eventtab[ev_misc].evtime = ct + mintime;
-               events_schedule ();
-       }
-       recursive--;
-}
-
-STATIC_INLINE void event2_newevent_xx (int no, evt t, uae_u32 data, evfunc2 func)
-{
-       evt et;
-
-       et = t + get_cycles ();
-       if (no < 0) {
-               for (no = ev2_misc; no < ev2_max; no++) {
-                       if (!eventtab2[no].active)
-                               break;
-                       if (eventtab2[no].evtime == et && eventtab2[no].handler == func) {
-                               eventtab2[no].handler (eventtab2[no].data);
-                               break;
-                       }
-               }
-               if (no == ev2_max) {
-                       write_log (L"out of event2's! PC=%x\n", M68K_GETPC);
-                       return;
-               }
-       }
-       eventtab2[no].active = 1;
-       eventtab2[no].evtime = et;
-       eventtab2[no].handler = func;
-       eventtab2[no].data = data;
-       MISC_handler ();
-}
-
-STATIC_INLINE void event2_newevent_x (int no, evt t, uae_u32 data, evfunc2 func)
-{
-       if (((int)t) <= 0) {
-               func (data);
-               return;
-       }
-
-       event2_newevent_xx (no, t * CYCLE_UNIT, data, func);
-}
-
-void event2_newevent (int no, evt t)
-{
-       event2_newevent_x (no, t, 0, eventtab2[no].handler);
-}
-void event2_newevent2 (evt t, uae_u32 data, evfunc2 func)
-{
-       event2_newevent_x (-1, t, data, func);
-}
-
 void event2_remevent (int no)
 {
        eventtab2[no].active = 0;
@@ -6319,10 +6329,14 @@ static void REGPARAM2 custom_bput (uaecptr addr, uae_u32 value)
        static int warned;
        uae_u16 rval;
 
-       if (addr & 1) {
-               rval = value & 0xff;
+       if (currprefs.chipset_mask & CSMASK_AGA) {
+               if (addr & 1) {
+                       rval = value & 0xff;
+               } else {
+                       rval = (value << 8) | (value & 0xFF);
+               }
        } else {
-               rval = (value << 8) | (value & 0xFF);
+               rval = (value << 8) | (value & 0xff);
        }
 
 #ifdef JIT
@@ -6979,6 +6993,7 @@ void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v)
        else if (mode == 0)
                put_byte (addr, v);
        do_cycles_ce (CYCLE_UNIT);
+
 }
 
 void wait_cpu_cycle_write_ce020 (uaecptr addr, int mode, uae_u32 v)
diff --git a/disk.c b/disk.c
index 8728930a3b05dc9f627aaa4b3ea1485b2837ac74..f3e1318a331d90db61153c4a7ba7f01237e7154b 100644 (file)
--- a/disk.c
+++ b/disk.c
@@ -2766,7 +2766,7 @@ static void disk_doupdate_predict (drive * drv, int startcycle)
                updatetrackspeed (drv, drv->mfmpos);
        if (diskevent_flag) {
                disk_sync_cycle = startcycle >> 8;
-               event2_newevent(ev2_disk, (startcycle - firstcycle) / CYCLE_UNIT);
+               event2_newevent (ev2_disk, (startcycle - firstcycle) / CYCLE_UNIT);
        }
 }
 
index 3d0541f7a53cd5da9e1f36be1c50d4c16faec5f1..2534360560d022ddf44b22b0196d1b92f7d4f3e4 100644 (file)
--- a/filesys.c
+++ b/filesys.c
@@ -5327,11 +5327,16 @@ static void dump_partinfo (uae_char *name, int num, uaecptr pp, int partblock)
 {
        TCHAR *s = au (name);
        uae_u32 dostype = get_long (pp + 80);
+       uae_u64 size;
+
+       size = ((uae_u64)get_long (pp + 20)) * 4 * get_long (pp + 28) * get_long (pp + 36) * (get_long (pp + 56) - get_long (pp + 52) + 1);
+
        write_log (L"RDB: '%s' dostype=%08X. PartBlock=%d\n", s, dostype, partblock);
        write_log (L"BlockSize: %d, Surfaces: %d, SectorsPerBlock %d\n",
                get_long (pp + 20) * 4, get_long (pp + 28), get_long (pp + 32));
-       write_log (L"SectorsPerTrack: %d, Reserved: %d, LowCyl %d, HighCyl %d\n",
-               get_long (pp + 36), get_long (pp + 40), get_long (pp + 52), get_long (pp + 56));
+       write_log (L"SectorsPerTrack: %d, Reserved: %d, LowCyl %d, HighCyl %d, Size %dM\n",
+               get_long (pp + 36), get_long (pp + 40), get_long (pp + 52), get_long (pp + 56), (uae_u32)(size >> 20));
+               
        write_log (L"Buffers: %d, BufMemType: %08x, MaxTransfer: %08x, BootPri: %d\n",
                get_long (pp + 60), get_long (pp + 64), get_long (pp + 68), get_long (pp + 76));
        xfree (s);
index 55548cf3d8acde948e01eaaaf763b077b6ade5d4..76e77f9ad450131ec25f4ce568a5fcec4eec66bd 100644 (file)
--- a/gencpu.c
+++ b/gencpu.c
@@ -404,6 +404,20 @@ static void fill_prefetch_0 (void)
        insn_n_cycles += 4;
 }
 
+static void dummy_prefetch (void)
+{
+       int o = m68k_pc_offset + 2;
+       if (!using_prefetch)
+               return;
+       if (using_ce) {
+               printf ("\tget_wordi_ce (m68k_getpc () + %d);\n", o);
+       } else {
+               printf ("\tget_wordi (m68k_getpc () + %d);\n", o);
+       }
+       count_read++;
+       insn_n_cycles += 4;
+}
+
 static void fill_prefetch_next_1 (void)
 {
        irc2ir ();
@@ -1046,8 +1060,8 @@ static void genmovemel (uae_u16 opcode)
                printf ("\tm68k_areg (regs, dstreg) = srca;\n");
                count_read++;
        }
-       fill_prefetch_next ();
        count_ncycles++;
+       fill_prefetch_next ();
 }
 
 static void genmovemel_ce (uae_u16 opcode)
@@ -1075,8 +1089,8 @@ static void genmovemel_ce (uae_u16 opcode)
        count_read++;
        if (table68k[opcode].dmode == Aipi)
                printf ("\tm68k_areg (regs, dstreg) = srca;\n");
-       fill_prefetch_next ();
        count_ncycles++;
+       fill_prefetch_next ();
 }
 
 static void genmovemle (uae_u16 opcode)
@@ -1123,11 +1137,8 @@ static void genmovemle (uae_u16 opcode)
                printf ("\twhile (amask) { %s, m68k_areg (regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n",
                        putcode, size);
        }
-       if (using_prefetch) {
-               sync_m68k_pc ();
-               fill_prefetch_next ();
-       }
        count_ncycles++;
+       fill_prefetch_next ();
 }
 
 static void genmovemle_ce (uae_u16 opcode)
@@ -1171,8 +1182,8 @@ static void genmovemle_ce (uae_u16 opcode)
                                size);
                }
        }
-       fill_prefetch_next ();
        count_ncycles++;
+       fill_prefetch_next ();
 }
 
 static void duplicate_carry (int n)
@@ -1568,14 +1579,16 @@ static void gen_opcode (unsigned long int opcode)
                genastore_rev ("src", curi->dmode, "dstreg", curi->size, "dst");
                break;
        }
+       // all SR/CCR modifications have dummy read access
        case i_ORSR:
        case i_EORSR:
                printf ("\tMakeSR ();\n");
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               dummy_prefetch ();
                if (curi->size == sz_byte) {
                        printf ("\tsrc &= 0xFF;\n");
                }
-               addcycles000 (4);
+               addcycles000 (8);
                fill_prefetch_next ();
                printf ("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|');
                printf ("\tMakeFromSR ();\n");
@@ -1583,10 +1596,11 @@ static void gen_opcode (unsigned long int opcode)
        case i_ANDSR:
                printf ("\tMakeSR ();\n");
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               dummy_prefetch ();
                if (curi->size == sz_byte) {
                        printf ("\tsrc |= 0xFF00;\n");
                }
-               addcycles000 (4);
+               addcycles000 (8);
                fill_prefetch_next ();
                printf ("\tregs.sr &= src;\n");
                printf ("\tMakeFromSR ();\n");
@@ -1632,14 +1646,14 @@ static void gen_opcode (unsigned long int opcode)
                break;
        }
        case i_SUBX:
+               if (!isreg (curi->smode))
+                       addcycles000 (2);
                genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
                genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
+               fill_prefetch_next ();
                if (curi->size == sz_long && isreg (curi->smode))
                        addcycles000 (4);
-               if (!isreg (curi->smode))
-                       addcycles000 (2);
-               fill_prefetch_next ();
                start_brace ();
                printf ("\tuae_u32 newv = dst - src - (GET_XFLG () ? 1 : 0);\n");
                genflags (flag_subx, curi->size, "newv", "src", "dst");
@@ -1647,6 +1661,8 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
                break;
        case i_SBCD:
+               if (!isreg (curi->smode))
+                       addcycles000 (2);
                genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
                genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
@@ -1670,7 +1686,8 @@ static void gen_opcode (unsigned long int opcode)
                        genflags (flag_zn, curi->size, "newv", "", "");
                        printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n");
                }
-               addcycles000 (2);
+               if (isreg (curi->smode))
+                       addcycles000 (2);
                genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
                break;
        case i_ADD:
@@ -1714,14 +1731,14 @@ static void gen_opcode (unsigned long int opcode)
                break;
        }
        case i_ADDX:
+               if (!isreg (curi->smode))
+                       addcycles000 (2);
                genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
                genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
+               fill_prefetch_next ();
                if (curi->size == sz_long && isreg (curi->smode))
                        addcycles000 (4);
-               if (!isreg (curi->smode))
-                       addcycles000 (2);
-               fill_prefetch_next ();
                start_brace ();
                printf ("\tuae_u32 newv = dst + src + (GET_XFLG () ? 1 : 0);\n");
                genflags (flag_addx, curi->size, "newv", "src", "dst");
@@ -1729,6 +1746,8 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
                break;
        case i_ABCD:
+               if (!isreg (curi->smode))
+                       addcycles000 (2);
                genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
                genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
@@ -1754,23 +1773,24 @@ static void gen_opcode (unsigned long int opcode)
                        genflags (flag_zn, curi->size, "newv", "", "");
                        printf ("\tSET_VFLG ((tmp_newv & 0x80) == 0 && (newv & 0x80) != 0);\n");
                }
-               addcycles000 (2);
+               if (isreg (curi->smode))
+                       addcycles000 (2);
                genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
                break;
        case i_NEG:
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               fill_prefetch_next ();
                if (isreg (curi->smode) && curi->size == sz_long)
                        addcycles000 (2);
-               fill_prefetch_next ();
                start_brace ();
                genflags (flag_sub, curi->size, "dst", "src", "0");
                genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src");
                break;
        case i_NEGX:
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               fill_prefetch_next ();
                if (isreg (curi->smode) && curi->size == sz_long)
                        addcycles000 (2);
-               fill_prefetch_next ();
                start_brace ();
                printf ("\tuae_u32 newv = 0 - src - (GET_XFLG () ? 1 : 0);\n");
                genflags (flag_subx, curi->size, "newv", "src", "0");
@@ -1806,17 +1826,17 @@ static void gen_opcode (unsigned long int opcode)
                break;
        case i_CLR:
                genamode (curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0);
+               fill_prefetch_next ();
                if (isreg (curi->smode) && curi->size == sz_long)
                        addcycles000 (2);
-               fill_prefetch_next ();
                genflags (flag_logical, curi->size, "0", "", "");
                genastore_rev ("0", curi->smode, "srcreg", curi->size, "src");
                break;
        case i_NOT:
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               fill_prefetch_next ();
                if (isreg (curi->smode) && curi->size == sz_long)
                        addcycles000 (2);
-               fill_prefetch_next ();
                start_brace ();
                printf ("\tuae_u32 dst = ~src;\n");
                genflags (flag_logical, curi->size, "dst", "", "");
@@ -1839,10 +1859,11 @@ static void gen_opcode (unsigned long int opcode)
        case i_BSET:
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
+               fill_prefetch_next ();
                bsetcycles (curi);
+               // bclr needs 1 extra cycle
                if (curi->mnemo == i_BCLR && curi->dmode == Dreg)
                        addcycles000 (2);
-               fill_prefetch_next ();
                if (curi->mnemo == i_BCHG) {
                        printf ("\tdst ^= (1 << src);\n");
                        printf ("\tSET_ZFLG (((uae_u32)dst & (1 << src)) >> src);\n");
@@ -1856,6 +1877,7 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
                break;
        case i_CMPM:
+               // confirmed
                genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
                genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
@@ -1919,13 +1941,12 @@ static void gen_opcode (unsigned long int opcode)
                        *
                        * - move.x xxx,[at least 1 extension word here] = fetch 1 extension word before (xxx)
                        *
-                       * - current theory: moves are build from 3 separate microcode subroutines, fetch, move and write
                        */
                        int prefetch_done = 0, flags;
                        int dualprefetch = curi->dmode == absl && (curi->smode != Dreg && curi->smode != Areg && curi->smode != imm);
                        genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_MOVE);
                        flags = 1 | (dualprefetch ? GF_NOREFILL : 0);
-                       genamode2 (curi->dmode, "dstreg", curi->size, "dst", 2, 0, flags, 0);
+                       genamode2 (curi->dmode, "dstreg", curi->size, "dst", 2, 0, flags | GF_MOVE, 0);
                        genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                        if (curi->mnemo == i_MOVEA && curi->size == sz_word)
                                printf ("\tsrc = (uae_s32)(uae_s16)src;\n");
@@ -1945,11 +1966,11 @@ static void gen_opcode (unsigned long int opcode)
                                fill_prefetch_next ();
                }
                break;
-       case i_MVSR2: // MOVE FROM SR (like CLR, does dummy read first on 68000)
-               genamode (curi->smode, "srcreg", sz_word, "src", cpu_level == 0 ? 1 : 2, 0, 0);
+       case i_MVSR2: // MOVE FROM SR
+               genamode (curi->smode, "srcreg", sz_word, "src", 2, 0, 0);
+               fill_prefetch_next ();
                if (isreg (curi->smode))
                        addcycles000 (2);
-               fill_prefetch_next ();
                printf ("\tMakeSR ();\n");
                if (curi->size == sz_byte)
                        genastore ("regs.sr & 0xff", curi->smode, "srcreg", sz_word, "src");
@@ -1959,14 +1980,18 @@ static void gen_opcode (unsigned long int opcode)
        case i_MV2SR: // MOVE TO SR
                genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
                if (curi->size == sz_byte) {
-                       addcycles000 (8);
+                       // MOVE TO CCR
+                       dummy_prefetch ();
+                       addcycles000 (4);
                        printf ("\tMakeSR ();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n");
                } else {
+                       // MOVE TO SR
+                       dummy_prefetch ();
                        addcycles000 (4);
                        printf ("\tregs.sr = src;\n");
                }
-               fill_prefetch_next ();
                printf ("\tMakeFromSR ();\n");
+               fill_prefetch_next ();
                break;
        case i_SWAP:
                genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, 0);
@@ -1977,14 +2002,16 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("dst", curi->smode, "srcreg", sz_long, "src");
                break;
        case i_EXG:
+               // confirmed
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
-               addcycles000 (2);
                fill_prefetch_next ();
+               addcycles000 (2);
                genastore ("dst", curi->smode, "srcreg", curi->size, "src");
                genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
                break;
        case i_EXT:
+               // confirmed
                genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, 0);
                fill_prefetch_next ();
                start_brace ();
@@ -2000,12 +2027,14 @@ static void gen_opcode (unsigned long int opcode)
                        curi->size == sz_word ? sz_word : sz_long, "src");
                break;
        case i_MVMEL:
+               // confirmed
                if (using_ce)
                        genmovemel_ce (opcode);
                else
                        genmovemel (opcode);
                break;
        case i_MVMLE:
+               // confirmed
                if (using_ce)
                        genmovemle_ce (opcode);
                else
@@ -2106,6 +2135,7 @@ static void gen_opcode (unsigned long int opcode)
                fill_prefetch_full ();
                break;
        case i_LINK:
+               // ce confirmed
                if (using_mmu) {
                        genamode (curi->dmode, "dstreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0);
                        genamode (Apdi, "7", sz_long, "old", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, 0);
@@ -2124,6 +2154,7 @@ static void gen_opcode (unsigned long int opcode)
                }
                break;
        case i_UNLK:
+               // ce confirmed
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                printf ("\tm68k_areg (regs, 7) = src;\n");
                genamode (Aipi, "7", sz_long, "old", 1, 0, 0);
@@ -2208,6 +2239,7 @@ static void gen_opcode (unsigned long int opcode)
                fill_prefetch_full ();
                break;
        case i_BSR:
+               // .b and .w confirmed
                printf ("\tuae_s32 s;\n");
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA|GF_NOREFILL);
                printf ("\ts = (uae_s32)src + 2;\n");
@@ -2233,6 +2265,7 @@ static void gen_opcode (unsigned long int opcode)
                fill_prefetch_full ();
                break;
        case i_Bcc:
+               // bcc.s and bcc.w cycles confirmed
                if (curi->size == sz_long) {
                        if (cpu_level < 2) {
                                addcycles000 (2);
@@ -2346,6 +2379,7 @@ static void gen_opcode (unsigned long int opcode)
                need_endlabel = 1;
                break;
        case i_Scc:
+               // confirmed
                genamode (curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0);
                start_brace ();
                fill_prefetch_next();
index 37ff641716a49fcab4b55abfdd7a5d37b5481533..516fc9daeefbabd5e3626c4e3d42906c06e8a420 100644 (file)
 #include "execio.h"
 #include "zfile.h"
 
-#undef DEBUGME
+//#undef DEBUGME
 #define hf_log
 #define hf_log2
 #define scsi_log
 #define hf_log3
 
-//#define DEBUGME
+#define DEBUGME
 #ifdef DEBUGME
 #undef hf_log
 #define hf_log write_log
@@ -137,7 +137,7 @@ static void getchs2 (struct hardfiledata *hfd, int *cyl, int *cylsec, int *head,
 static void getchs (struct hardfiledata *hfd, int *cyl, int *cylsec, int *head, int *tracksec)
 {
        getchs2 (hfd, cyl, cylsec, head, tracksec);
-       hf_log ("CHS: %08X-%08X %d %d %d %d %d\n",
+       hf_log (L"CHS: %08X-%08X %d %d %d %d %d\n",
                (uae_u32)(hfd->virtsize >> 32),(uae_u32)hfd->virtsize,
                *cyl, *cylsec, *head, *tracksec);
 }
@@ -904,7 +904,7 @@ int hdf_write (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len)
 static uae_u64 cmd_readx (struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len)
 {
        gui_flicker_led (LED_HD, hfd->unitnum, 1);
-       hf_log3 ("cmd_read: %p %04x-%08x (%d) %08x (%d)\n",
+       hf_log3 (L"cmd_read: %p %04x-%08x (%d) %08x (%d)\n",
                dataptr, (uae_u32)(offset >> 32), (uae_u32)offset, (uae_u32)(offset / hfd->blocksize), (uae_u32)len, (uae_u32)(len / hfd->blocksize));
        return hdf_read (hfd, dataptr, offset, len);
 }
@@ -918,7 +918,7 @@ static uae_u64 cmd_read (struct hardfiledata *hfd, uaecptr dataptr, uae_u64 offs
 static uae_u64 cmd_writex (struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 offset, uae_u64 len)
 {
        gui_flicker_led (LED_HD, hfd->unitnum, 2);
-       hf_log3 ("cmd_write: %p %04x-%08x (%d) %08x (%d)\n",
+       hf_log3 (L"cmd_write: %p %04x-%08x (%d) %08x (%d)\n",
                dataptr, (uae_u32)(offset >> 32), (uae_u32)offset, (uae_u32)(offset / hfd->blocksize), (uae_u32)len, (uae_u32)(len / hfd->blocksize));
        return hdf_write (hfd, dataptr, offset, len);
 }
@@ -1288,28 +1288,28 @@ static int handle_scsi (uaecptr request, struct hardfiledata *hfd)
        status = 0;
        memset (reply, 0, sizeof reply);
        reply_len = 0; sense_len = 0;
-       scsi_log ("hdf scsiemu: cmd=%02X,%d flags=%02X sense=%p,%d data=%p,%d\n",
+       scsi_log (L"hdf scsiemu: cmd=%02X,%d flags=%02X sense=%p,%d data=%p,%d\n",
                cmd, scsi_cmd_len, scsi_flags, scsi_sense, scsi_sense_len, scsi_data, scsi_len);
        for (i = 0; i < scsi_cmd_len; i++) {
                cmdbuf[i] = get_byte (scsi_cmd + i);
-               scsi_log ("%02X%c", get_byte (scsi_cmd + i), i < scsi_cmd_len - 1 ? '.' : ' ');
+               scsi_log (L"%02X%c", get_byte (scsi_cmd + i), i < scsi_cmd_len - 1 ? '.' : ' ');
        }
-       scsi_log ("\n");
+       scsi_log (L"\n");
 
        status = scsi_emulate (hfd, NULL, cmdbuf, scsi_cmd_len, scsi_data_ptr, &scsi_len, reply, &reply_len, sense, &sense_len);
 
        put_word (acmd + 18, status != 0 ? 0 : scsi_cmd_len); /* fake scsi_CmdActual */
        put_byte (acmd + 21, status); /* scsi_Status */
        if (reply_len > 0) {
-               scsi_log ("RD:");
+               scsi_log (L"RD:");
                i = 0;
                while (i < reply_len) {
                        if (i < 24)
-                               scsi_log ("%02X%c", reply[i], i < reply_len - 1 ? '.' : ' ');
+                               scsi_log (L"%02X%c", reply[i], i < reply_len - 1 ? '.' : ' ');
                        put_byte (scsi_data + i, reply[i]);
                        i++;
                }
-               scsi_log ("\n");
+               scsi_log (L"\n");
        }
        i = 0;
        if (scsi_sense) {
@@ -1371,7 +1371,7 @@ static int add_async_request (struct hardfileprivdata *hfpd, uaecptr request, in
                if (hfpd->d_request[i] == request) {
                        hfpd->d_request_type[i] = type;
                        hfpd->d_request_data[i] = data;
-                       hf_log ("old async request %p (%d) added\n", request, type);
+                       hf_log (L"old async request %p (%d) added\n", request, type);
                        return 0;
                }
                i++;
@@ -1382,12 +1382,12 @@ static int add_async_request (struct hardfileprivdata *hfpd, uaecptr request, in
                        hfpd->d_request[i] = request;
                        hfpd->d_request_type[i] = type;
                        hfpd->d_request_data[i] = data;
-                       hf_log ("async request %p (%d) added (total=%d)\n", request, type, i);
+                       hf_log (L"async request %p (%d) added (total=%d)\n", request, type, i);
                        return 0;
                }
                i++;
        }
-       hf_log ("async request overflow %p!\n", request);
+       hf_log (L"async request overflow %p!\n", request);
        return -1;
 }
 
@@ -1401,19 +1401,19 @@ static int release_async_request (struct hardfileprivdata *hfpd, uaecptr request
                        hfpd->d_request[i] = 0;
                        hfpd->d_request_data[i] = 0;
                        hfpd->d_request_type[i] = 0;
-                       hf_log ("async request %p removed\n", request);
+                       hf_log (L"async request %p removed\n", request);
                        return type;
                }
                i++;
        }
-       hf_log ("tried to remove non-existing request %p\n", request);
+       hf_log (L"tried to remove non-existing request %p\n", request);
        return -1;
 }
 
 static void abort_async (struct hardfileprivdata *hfpd, uaecptr request, int errcode, int type)
 {
        int i;
-       hf_log ("aborting async request %p\n", request);
+       hf_log (L"aborting async request %p\n", request);
        i = 0;
        while (i < MAX_ASYNC_REQUESTS) {
                if (hfpd->d_request[i] == request && hfpd->d_request_type[i] == ASYNC_REQUEST_TEMP) {
@@ -1426,7 +1426,7 @@ static void abort_async (struct hardfileprivdata *hfpd, uaecptr request, int err
        }
        i = release_async_request (hfpd, request);
        if (i >= 0)
-               hf_log ("asyncronous request=%08X aborted, error=%d\n", request, errcode);
+               hf_log (L"asyncronous request=%08X aborted, error=%d\n", request, errcode);
 }
 
 static void *hardfile_thread (void *devs);
@@ -1731,7 +1731,7 @@ no_disk:
        put_long (request + 32, actual);
        put_byte (request + 31, error);
 
-       hf_log2 ("hf: unit=%d, request=%p, cmd=%d offset=%u len=%d, actual=%d error%=%d\n", unit, request,
+       hf_log2 (L"hf: unit=%d, request=%p, cmd=%d offset=%u len=%d, actual=%d error%=%d\n", unit, request,
                get_word (request + 28), get_long (request + 44), get_long (request + 36), actual, error);
 
        return async;
@@ -1744,15 +1744,15 @@ static uae_u32 REGPARAM2 hardfile_abortio (TrapContext *context)
        struct hardfiledata *hfd = get_hardfile_data (unit);
        struct hardfileprivdata *hfpd = &hardfpd[unit];
 
-       hf_log2 ("uaehf.device abortio ");
+       hf_log2 (L"uaehf.device abortio ");
        start_thread (context, unit);
        if (!hfd || !hfpd || !hfpd->thread_running) {
                put_byte (request + 31, 32);
-               hf_log2 ("error\n");
+               hf_log2 (L"error\n");
                return get_byte (request + 31);
        }
        put_byte (request + 31, -2);
-       hf_log2 ("unit=%d, request=%08X\n",  unit, request);
+       hf_log2 (L"unit=%d, request=%08X\n",  unit, request);
        abort_async (hfpd, request, -2, 0);
        return 0;
 }
@@ -1799,12 +1799,12 @@ static uae_u32 REGPARAM2 hardfile_beginio (TrapContext *context)
        }
        put_byte (request + 31, 0);
        if ((flags & 1) && hardfile_canquick (hfd, request)) {
-               hf_log ("hf quickio unit=%d request=%p cmd=%d\n", unit, request, cmd);
+               hf_log (L"hf quickio unit=%d request=%p cmd=%d\n", unit, request, cmd);
                if (hardfile_do_io (hfd, hfpd, request))
-                       hf_log2 ("uaehf.device cmd %d bug with IO_QUICK\n", cmd);
+                       hf_log2 (L"uaehf.device cmd %d bug with IO_QUICK\n", cmd);
                return get_byte (request + 31);
        } else {
-               hf_log2 ("hf asyncio unit=%d request=%p cmd=%d\n", unit, request, cmd);
+               hf_log2 (L"hf asyncio unit=%d request=%p cmd=%d\n", unit, request, cmd);
                add_async_request (hfpd, request, ASYNC_REQUEST_TEMP, 0);
                put_byte (request + 30, get_byte (request + 30) & ~1);
                write_comm_pipe_u32 (&hfpd->requests, request, 1);
@@ -1832,7 +1832,7 @@ static void *hardfile_thread (void *devs)
                        release_async_request (hfpd, request);
                        uae_ReplyMsg (request);
                } else {
-                       hf_log2 ("async request %08X\n", request);
+                       hf_log2 (L"async request %08X\n", request);
                }
                uae_sem_post (&change_sem);
        }
index a4a6d78c74a7b05ef9efdb3db3b187039f9d598a..06ae5447543054ac7a7d68510e1708d8af99f10e 100644 (file)
@@ -10,6 +10,7 @@ extern void akiko_free (void);
 extern void akiko_entergui (void);
 extern void akiko_exitgui (void);
 extern void AKIKO_hsync_handler (void);
+extern void akiko_mute (int);
 
 extern uae_u8 *extendedkickmemory;
 
index 0c9c05fa429debb8cd1137ab94a1698b1cc61bbd..e91f5880d6a10002c808920ac561a5965c3c98e1 100644 (file)
@@ -76,6 +76,7 @@ typedef int (*execscsicmd_direct_func)(int, struct amigascsi*);
 typedef int (*pause_func)(int, int);
 typedef int (*stop_func)(int);
 typedef int (*play_func)(int, uae_u32, uae_u32, int);
+typedef void (*volume_func)(int, uae_u16);
 typedef uae_u8* (*qcode_func)(int);
 typedef uae_u8* (*toc_func)(int);
 typedef uae_u8* (*read_func)(int, int);
@@ -97,6 +98,7 @@ struct device_functions {
     pause_func pause;
     stop_func stop;
     play_func play;
+       volume_func volume;
     qcode_func qcode;
     toc_func toc;
     read_func read;
@@ -122,6 +124,7 @@ extern struct device_scsi_info *sys_command_scsi_info (int mode, int unitnum, st
 extern void sys_command_cd_pause (int mode, int unitnum, int paused);
 extern void sys_command_cd_stop (int mode, int unitnum);
 extern int sys_command_cd_play (int mode, int unitnum, uae_u32 startmsf, uae_u32 endmsf, int);
+extern void sys_command_cd_volume (int mode, int unitnum, uae_u16 volume);
 extern uae_u8 *sys_command_cd_qcode (int mode, int unitnum);
 extern uae_u8 *sys_command_cd_toc (int mode, int unitnum);
 extern uae_u8 *sys_command_cd_read (int mode, int unitnum, int offset);
index cd402ee1e1e1366168955828ab817e2b57f73102..d378bc41d9743b747f63cc92f901325c8f7d7e5a 100644 (file)
@@ -12,6 +12,11 @@ STATIC_INLINE uae_u32 get_long_prefetch (int o)
        return v;
 }
 
+STATIC_INLINE void prefetch_common_ce000 (void)
+{
+       regs.lastfetch = get_cycles () + CYCLE_UNIT;
+}
+
 #ifdef CPUEMU_20
 
 STATIC_INLINE void checkcycles_ce020 (void)
@@ -271,6 +276,7 @@ STATIC_INLINE uae_u32 next_ilong_020ce (void)
 
 STATIC_INLINE uae_u32 mem_access_delay_word_read (uaecptr addr)
 {
+       prefetch_common_ce000 ();
        switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
@@ -284,6 +290,7 @@ STATIC_INLINE uae_u32 mem_access_delay_word_read (uaecptr addr)
 }
 STATIC_INLINE uae_u32 mem_access_delay_wordi_read (uaecptr addr)
 {
+       prefetch_common_ce000 ();
        switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
@@ -297,6 +304,7 @@ STATIC_INLINE uae_u32 mem_access_delay_wordi_read (uaecptr addr)
 
 STATIC_INLINE uae_u32 mem_access_delay_byte_read (uaecptr addr)
 {
+       prefetch_common_ce000 ();
        switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
@@ -310,6 +318,7 @@ STATIC_INLINE uae_u32 mem_access_delay_byte_read (uaecptr addr)
 }
 STATIC_INLINE void mem_access_delay_byte_write (uaecptr addr, uae_u32 v)
 {
+       prefetch_common_ce000 ();
        switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
@@ -323,6 +332,7 @@ STATIC_INLINE void mem_access_delay_byte_write (uaecptr addr, uae_u32 v)
 }
 STATIC_INLINE void mem_access_delay_word_write (uaecptr addr, uae_u32 v)
 {
+       prefetch_common_ce000 ();
        switch (ce_banktype[addr >> 16])
        {
        case CE_MEMBANK_CHIP:
index 3f250d086b394e777bab4a7b014a74bdf9413946..e0cab40481b905a8b8ffb11b288d6a3945b1f7d0 100644 (file)
@@ -133,6 +133,7 @@ extern struct regstruct
        flagtype x;
        flagtype stopped;
        int intmask;
+       int ipl;
 
        uae_u32 vbr, sfc, dfc;
 
@@ -165,6 +166,7 @@ extern struct regstruct
        uae_u32 prefetch020data;
        uae_u32 prefetch020addr;
        int ce020memcycles;
+       evt lastfetch;
 
 } regs, lastint_regs, mmu_backup_regs;
 
@@ -316,7 +318,7 @@ extern void REGPARAM3 MakeFromSR (void) REGPARAM;
 extern void REGPARAM3 Exception (int, uaecptr) REGPARAM;
 extern void NMI (void);
 extern void NMI_delayed (void);
-extern void prepare_interrupt (void);
+extern void prepare_interrupt (uae_u32);
 extern void doint (void);
 extern void dump_counts (void);
 extern int m68k_move2c (int, uae_u32 *);
index a993061655caed8e9ea042b7893d79c50b5000ac..31dc91d423e25f2e327a19a3ffa8aa1f616b600e 100644 (file)
@@ -267,6 +267,7 @@ struct uae_prefs {
     TCHAR sername[256];
     TCHAR amaxromfile[MAX_DPATH];
     TCHAR a2065name[MAX_DPATH];
+       TCHAR cdimagefile[MAX_DPATH];
 
     TCHAR path_floppy[256];
     TCHAR path_hardfile[256];
diff --git a/main.c b/main.c
index ca850bd67417b756c1c60dca0f98692b706f9b58..7cb3bcd693024c2074af17eea4cb8343f8781f4c 100644 (file)
--- a/main.c
+++ b/main.c
@@ -532,6 +532,10 @@ static void parse_cmdline (int argc, TCHAR **argv)
                } else if (_tcscmp (argv[i], L"-h") == 0 || _tcscmp (argv[i], L"-help") == 0) {
                        usage ();
                        exit (0);
+               } else if (_tcsncmp (argv[i], L"-cdimage=", 9) == 0) {
+                       TCHAR *txt = parsetext (argv[i] + 9);
+                       cfgfile_parse_option (&currprefs, L"cdimage0", txt, 0);
+                       xfree (txt);
                } else {
                        if (argv[i][0] == '-' && argv[i][1] != '\0') {
                                const TCHAR *arg = argv[i] + 2;
index ee27ae39ee0a46f1dcf9db187f2a52214668c567..f4ff92c2c1e303d52078d29d52cbf1f988df1b28 100644 (file)
--- a/newcpu.c
+++ b/newcpu.c
@@ -2569,19 +2569,49 @@ static void do_trace (void)
 
 
 static int interrupt_cycles_active;
-static unsigned long interrupt_cycles;
+static evt interrupt_cycle;
 
 // handle interrupt delay (few cycles)
 STATIC_INLINE int time_for_interrupt (void)
 {
-       if (!interrupt_cycles_active)
-               return 1;
-       if ((int)get_cycles () - (int)interrupt_cycles < 0)
-               return 0;
-       interrupt_cycles_active = 0;
+       if (interrupt_cycles_active) {
+               if (interrupt_cycle != regs.lastfetch) {
+                       interrupt_cycles_active = 0;
+                       return 1;
+               } else {
+                       return 0;
+               }
+       }
        return 1;
 }
 
+void prepare_interrupt (uae_u32 lev)
+{
+       // CPU IPLx lines change state now
+       // but we may need to wait for next S4 state
+       // before CPU sees it
+       regs.ipl = lev;
+       if (currprefs.cpu_model == 68000) {
+               interrupt_cycle = get_cycles ();
+               if ((regs.lastfetch - interrupt_cycle) >= 0) {
+                       // interrupt arrived too late
+                       // wait for next memory cycle
+                       interrupt_cycles_active = 1;
+               }
+       }
+       set_special (SPCFLAG_INT);
+}
+
+void doint (void)
+{
+       if (currprefs.cpu_cycle_exact)
+               return;
+       if (currprefs.cpu_compatible)
+               set_special (SPCFLAG_INT);
+       else
+               set_special (SPCFLAG_DOINT);
+}
+
 #define IDLETIME (currprefs.cpu_idle * sleep_resolution / 700)
 
 STATIC_INLINE int do_specialties (int cycles)
@@ -2654,14 +2684,22 @@ STATIC_INLINE int do_specialties (int cycles)
                do_cycles (4 * CYCLE_UNIT);
                if (regs.spcflags & SPCFLAG_COPPER)
                        do_copper ();
-               if (regs.spcflags & (SPCFLAG_INT | SPCFLAG_DOINT)) {
+
+               if (currprefs.cpu_cycle_exact) {
                        if (time_for_interrupt ()) {
+                               int intr = regs.ipl;
+                               if (intr > 0 && intr > regs.intmask)
+                                       do_interrupt (intr);
+                       }
+               } else {
+                       if (regs.spcflags & (SPCFLAG_INT | SPCFLAG_DOINT)) {
                                int intr = intlev ();
                                unset_special (SPCFLAG_INT | SPCFLAG_DOINT);
-                               if (intr != -1 && intr > regs.intmask)
+                               if (intr > 0 && intr > regs.intmask)
                                        do_interrupt (intr);
                        }
                }
+
                if ((regs.spcflags & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE))) {
                        unset_special (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE);
                        // SPCFLAG_BRK breaks STOP condition, need to prefetch
@@ -2694,14 +2732,21 @@ STATIC_INLINE int do_specialties (int cycles)
        if (regs.spcflags & SPCFLAG_TRACE)
                do_trace ();
 
-       if (regs.spcflags & SPCFLAG_INT) {
+       if (currprefs.cpu_cycle_exact) {
                if (time_for_interrupt ()) {
+                       int intr = regs.ipl;
+                       if (intr > 0 && intr > regs.intmask)
+                               do_interrupt (intr);
+               }
+       } else {
+               if (regs.spcflags & SPCFLAG_INT) {
                        int intr = intlev ();
                        unset_special (SPCFLAG_INT | SPCFLAG_DOINT);
-                       if (intr != -1 && (intr > regs.intmask || intr == 7))
+                       if (intr > 0 && (intr > regs.intmask || intr == 7))
                                do_interrupt (intr);
                }
        }
+
        if (regs.spcflags & SPCFLAG_DOINT) {
                unset_special (SPCFLAG_DOINT);
                set_special (SPCFLAG_INT);
@@ -2714,21 +2759,6 @@ STATIC_INLINE int do_specialties (int cycles)
        return 0;
 }
 
-void prepare_interrupt (void)
-{
-       interrupt_cycles = get_cycles () + 5 * CYCLE_UNIT + CYCLE_UNIT / 2;
-       if (vpos == 0 && current_hpos () == 0)
-               interrupt_cycles -= CYCLE_UNIT; // vblank int hpos=-1
-       interrupt_cycles_active = 1;
-}
-
-void doint (void)
-{
-       if (currprefs.cpu_compatible)
-               set_special (SPCFLAG_INT);
-       else
-               set_special (SPCFLAG_DOINT);
-}
 //static uae_u32 pcs[1000];
 
 //#define DEBUG_CD32IO
index 20d526b2330faf2a20b131688d1834b414f049a3..210e54ce42662029bf5eb0032d5b7380720cc001 100644 (file)
@@ -1017,5 +1017,5 @@ static struct device_scsi_info *scsi_info (int unitnum, struct device_scsi_info
 struct device_functions devicefunc_win32_aspi = {
        open_scsi_bus, close_scsi_bus, open_scsi_device, close_scsi_device, info_device,
        execscsicmd_out, execscsicmd_in, execscsicmd_direct,
-       0, 0, 0, 0, 0, 0, 0, 0, check_isatapi, scsi_info, 0
+       0, 0, 0, 0, 0, 0, 0, 0, 0, check_isatapi, scsi_info, 0
 };
index ec69e798af4181cb39a68a61ebd2fbdb4602bb82..1a6593da366aa6f569bc46d04c7c77a3e3573aa7 100644 (file)
@@ -12,6 +12,7 @@
 
 #ifdef WINDDK
 
+#include "options.h"
 #include "uae.h"
 #include "threaddep/thread.h"
 #include "blkdev.h"
@@ -38,13 +39,23 @@ struct dev_info_ioctl {
        int type;
        int blocksize;
        int mciid;
+       int cdda;
        CDROM_TOC toc;
        UINT errormode;
        int playend;
        int fullaccess;
+       int cdda_play_finished;
+       int cdda_play;
+       int cdda_paused;
+       int cdda_volume;
+       int cdda_volume_main;
+       uae_u32 cd_last_pos;
+       HWAVEOUT cdda_wavehandle;
+       int cdda_start, cdda_end;
 };
 
-#define IOCTL_DATA_BUFFER 4096
+#define IOCTL_DATA_BUFFER 8192
+#define CDDA_BUFFERS 6
 
 static int MCICDA;
 
@@ -97,6 +108,23 @@ static int win32_error (int unitnum, const TCHAR *format,...)
        return err;
 }
 
+/* convert minutes, seconds and frames -> logical sector number */
+static int msf2lsn (int        msf)
+{
+       int sector = (((msf >> 16) & 0xff) * 60 * 75 + ((msf >> 8) & 0xff) * 75 + ((msf >> 0) & 0xff));
+       return sector;
+}
+
+/* convert logical sector number -> minutes, seconds and frames */
+static int lsn2msf (int        sectors)
+{
+       int msf;
+       msf = (sectors / (75 * 60)) << 16;
+       msf |= ((sectors / 75) % 60) << 8;
+       msf |= (sectors % 75) << 0;
+       return msf;
+}
+
 static int close_createfile (int unitnum)
 {
        struct dev_info_ioctl *ciw = &ciw32[unitnum];
@@ -222,6 +250,180 @@ static int open_mci (int unitnum)
        return 1;
 }
 
+static void cdda_closewav (struct dev_info_ioctl *ciw)
+{
+       if (ciw->cdda_wavehandle != NULL)
+               waveOutClose (ciw->cdda_wavehandle);
+       ciw->cdda_wavehandle = NULL;
+}
+
+// DAE CDDA based on Larry Osterman's "Playing Audio CDs" blog series
+
+static int cdda_openwav (struct dev_info_ioctl *ciw)
+{
+       WAVEFORMATEX wav = { 0 };
+       MMRESULT mmr;
+
+       wav.cbSize = 0;
+       wav.nChannels = 2;
+       wav.nSamplesPerSec = 44100;
+       wav.wBitsPerSample = 16;
+       wav.nBlockAlign = wav.wBitsPerSample / 8 * wav.nChannels;
+       wav.nAvgBytesPerSec = wav.nBlockAlign * wav.nSamplesPerSec;
+       wav.wFormatTag = WAVE_FORMAT_PCM;
+       mmr = waveOutOpen (&ciw->cdda_wavehandle, WAVE_MAPPER, &wav, 0, 0, WAVE_ALLOWSYNC | WAVE_FORMAT_DIRECT);
+       if (mmr != MMSYSERR_NOERROR) {
+               write_log (L"CDDA: wave open %d\n", mmr);
+               cdda_closewav (ciw);
+               return 0;
+       }
+       return 1;
+}
+
+static void *cdda_play (void *v)
+{
+       DWORD len;
+       struct dev_info_ioctl *ciw = v;
+       int unitnum = ciw32 - ciw;
+       int cdda_pos;
+       int num_sectors = CDDA_BUFFERS;
+       int quit = 0;
+       int bufnum;
+       int buffered;
+       uae_u8 *px[2], *p;
+       int bufon[2];
+       int i;
+       WAVEHDR whdr[2];
+       MMRESULT mmr;
+       int volume, volume_main;
+       int oldplay;
+
+
+       for (i = 0; i < 2; i++) {
+               memset (&whdr[i], 0, sizeof (WAVEHDR));
+               whdr[i].dwFlags = WHDR_DONE;
+       }
+
+       while (ciw->cdda_play == 0)
+               Sleep (10);
+       oldplay = -1;
+
+       p = VirtualAlloc (NULL, 2 * num_sectors * 4096, MEM_COMMIT, PAGE_READWRITE);
+       px[0] = p;
+       px[1] = p + num_sectors * 4096;
+       bufon[0] = bufon[1] = 0;
+       bufnum = 0;
+       buffered = 0;
+       volume = -1;
+       volume_main = -1;
+
+       if (cdda_openwav (ciw)) {
+
+               for (i = 0; i < 2; i++) {
+                       memset (&whdr[i], 0, sizeof (WAVEHDR));
+                       whdr[i].dwBufferLength = 2352 * num_sectors;
+                       whdr[i].lpData = px[i];
+                       mmr = waveOutPrepareHeader (ciw->cdda_wavehandle, &whdr[i], sizeof (WAVEHDR));
+                       if (mmr != MMSYSERR_NOERROR) {
+                               write_log (L"CDDA: waveOutPrepareHeader %d:%d\n", i, mmr);
+                               goto end;
+                       }
+                       whdr[i].dwFlags |= WHDR_DONE;
+               }
+
+               while (ciw->cdda_play > 0) {
+
+                       if (oldplay != ciw->cdda_play) {
+                               cdda_pos = ciw->cdda_start;
+                               oldplay = ciw->cdda_play;
+                       }
+
+                       while (!(whdr[bufnum].dwFlags & WHDR_DONE)) {
+                               Sleep (10);
+                               if (!ciw->cdda_play)
+                                       goto end;
+                       }
+                       bufon[bufnum] = 0;
+
+                       if ((cdda_pos < ciw->cdda_end || ciw->cdda_end == 0xffffffff) && !ciw->cdda_paused && ciw->cdda_play) {
+                               RAW_READ_INFO rri;
+
+                               seterrormode (unitnum);
+                               rri.DiskOffset.QuadPart = 2048 * (cdda_pos - 150);
+                               rri.SectorCount = num_sectors;
+                               rri.TrackMode = CDDA;
+                               if (!DeviceIoControl (ciw->h, IOCTL_CDROM_RAW_READ, &rri, sizeof rri, px[bufnum], num_sectors * 2352, &len, NULL)) {
+                                       DWORD err = GetLastError ();
+                                       write_log (L"IOCTL_CDROM_RAW_READ CDDA returned %d\n", err);
+                                       quit = 1;
+                               }
+                               reseterrormode (unitnum);
+                               if (quit)
+                                       break;
+               
+                               bufon[bufnum] = 1;
+                               if (volume != ciw->cdda_volume || volume_main != currprefs.sound_volume) {
+                                       int vol;
+                                       volume = ciw->cdda_volume;
+                                       volume_main = currprefs.sound_volume;
+                                       vol = (100 - volume_main) * volume / 100;
+                                       if (vol >= 0xffff)
+                                               vol = 0xffff;
+                                       waveOutSetVolume (ciw->cdda_wavehandle, vol | (vol << 16));
+                               }
+                               mmr = waveOutWrite (ciw->cdda_wavehandle, &whdr[bufnum], sizeof (WAVEHDR));
+                               if (mmr != MMSYSERR_NOERROR) {
+                                       write_log (L"CDDA: waveOutWrite %d\n", mmr);
+                                       break;
+                               }
+
+                               cdda_pos += num_sectors;
+                               if (cdda_pos >= ciw->cdda_end)
+                                       ciw->cdda_play_finished = 1;
+                               ciw->cd_last_pos = cdda_pos;
+
+                       }
+
+
+                       if (bufon[0] == 0 && bufon[1] == 0) {
+                               while (!(whdr[0].dwFlags & WHDR_DONE) || !(whdr[1].dwFlags & WHDR_DONE))
+                                       Sleep (10);
+                               while (ciw->cdda_paused && ciw->cdda_play > 0)
+                                       Sleep (10);
+                       }
+
+                       bufnum = 1 - bufnum;
+
+               }
+       }
+
+end:
+       while (!(whdr[0].dwFlags & WHDR_DONE) || !(whdr[1].dwFlags & WHDR_DONE))
+               Sleep (10);
+       for (i = 0; i < 2; i++)
+               waveOutUnprepareHeader  (ciw->cdda_wavehandle, &whdr[i], sizeof (WAVEHDR));
+
+       cdda_closewav (ciw);
+       VirtualFree (p, 0, MEM_RELEASE);
+       ciw->cdda_play = 0;
+       write_log (L"CDDA: thread killed\n");
+       return NULL;
+}
+
+static void cdda_stop (int unitnum)
+{
+       struct dev_info_ioctl *ciw = &ciw32[unitnum];
+
+       if (ciw->cdda_play > 0) {
+               ciw->cdda_play = -1;
+               while (ciw->cdda_play) {
+                       Sleep (10);
+               }
+       }
+       ciw->cdda_play_finished = 0;
+       ciw->cdda_paused = 0;
+}
+
 /* pause/unpause CD audio */
 static int ioctl_command_pause (int unitnum, int paused)
 {
@@ -235,6 +437,10 @@ static int ioctl_command_pause (int unitnum, int paused)
                else
                        mcierr(L"MCI_RESUME", mciSendCommand (ciw->mciid, MCI_RESUME, MCI_WAIT, (DWORD_PTR)&gp));
 
+       } else if (ciw->cdda) {
+
+               ciw->cdda_paused = paused;
+               
        } else {
 
                DWORD len;
@@ -256,6 +462,7 @@ static int ioctl_command_pause (int unitnum, int paused)
        return 1;
 }
 
+
 /* stop CD audio */
 static int ioctl_command_stop (int unitnum)
 {
@@ -267,6 +474,10 @@ static int ioctl_command_stop (int unitnum)
                mcierr (L"MCI_STOP", mciSendCommand (ciw->mciid, MCI_STOP, MCI_WAIT, (DWORD_PTR)&gp));
                ciw->playend = -1;
 
+       } else if (ciw->cdda) {
+
+               cdda_stop (unitnum);
+               
        } else {
 
                DWORD len;
@@ -287,12 +498,20 @@ static int ioctl_command_stop (int unitnum)
        return 1;
 }
 
+static void ioctl_command_volume (int unitnum, uae_u16 volume)
+{
+       struct dev_info_ioctl *ciw = &ciw32[unitnum];
+
+       ciw->cdda_volume = volume;
+}
+
 /* play CD audio */
 static int ioctl_command_play (int unitnum, uae_u32 start, uae_u32 end, int scan)
 {
        struct dev_info_ioctl *ciw = &ciw32[unitnum];
 
-       open_mci (unitnum);
+       if (!ciw->cdda)
+               open_mci (unitnum);
 
        if (ciw->mciid > 0) {
 
@@ -306,6 +525,20 @@ static int ioctl_command_play (int unitnum, uae_u32 start, uae_u32 end, int scan
                mcierr (L"MCI_PLAY", mciSendCommand (ciw->mciid, MCI_PLAY, MCI_FROM | MCI_TO, (DWORD_PTR)&playParms));
                ciw->playend = end;
 
+       } else if (ciw->cdda) {
+
+               if (!open_createfile (unitnum, 1))
+                       return 0;
+               ciw->cdda_paused = 0;
+               ciw->cdda_play_finished = 0;
+               if (!ciw->cdda_play) {
+                       uae_start_thread (L"cdda_play", cdda_play, ciw, NULL);
+               }
+               ciw->cdda_start = msf2lsn (start);
+               ciw->cdda_end = msf2lsn (end);
+               ciw->cd_last_pos = ciw->cdda_start;
+               ciw->cdda_play++;
+
        } else {
 
                DWORD len;
@@ -348,23 +581,6 @@ static int ioctl_command_play (int unitnum, uae_u32 start, uae_u32 end, int scan
        return 1;
 }
 
-/* convert minutes, seconds and frames -> logical sector number */
-static int msf2lsn (int        msf)
-{
-       int sector = (((msf >> 16) & 0xff) * 60 * 75 + ((msf >> 8) & 0xff) * 75 + ((msf >> 0) & 0xff));
-       return sector;
-}
-
-/* convert logical sector number -> minutes, seconds and frames */
-static int lsn2msf (int        sectors)
-{
-       int msf;
-       msf = (sectors / (75 * 60)) << 16;
-       msf |= ((sectors / 75) % 60) << 8;
-       msf |= (sectors % 75) << 0;
-       return msf;
-}
-
 /* read qcode */
 static uae_u8 *ioctl_command_qcode (int unitnum)
 {
@@ -429,12 +645,76 @@ static uae_u8 *ioctl_command_qcode (int unitnum)
 
                return buf;
 
+       } else if (ciw->cdda) {
+
+               static uae_u8 buf[4 + 12];
+               uae_u8 *p;
+               int trk;
+               CDROM_TOC *toc = &ciw->toc;
+               int pos;
+               int msf;
+               int start, end;
+               int status;
+
+               memset (buf, 0, sizeof buf);
+               p = buf;
+
+               status = AUDIO_STATUS_NO_STATUS;
+               if (ciw->cdda_play) {
+                       status = AUDIO_STATUS_IN_PROGRESS;
+                       if (ciw->cdda_paused)
+                               status = AUDIO_STATUS_PAUSED;
+               } else if (ciw->cdda_play_finished) {
+                       status = AUDIO_STATUS_PLAY_COMPLETE;
+               }
+               pos = ciw->cd_last_pos;
+#if 0
+               pos -= CDDA_BUFFERS * 2;
+               if (ciw->cdda_play && pos < ciw->cdda_start) {
+                       pos = ciw->cdda_start;
+                       status = AUDIO_STATUS_NO_STATUS;
+               }
+#endif
+               p[1] = status;
+               p[3] = 12;
+
+               p = buf + 4;
+
+               if (pos >= 150)
+                       trk = 0;
+               start = end = 0;
+               for (trk = 0; trk <= toc->LastTrack; trk++) {
+                       TRACK_DATA *td = &toc->TrackData[trk];
+                       start = msf2lsn ((td->Address[1] << 16) | (td->Address[2] << 8) | td->Address[3]);
+                       end = msf2lsn ((td[1].Address[1] << 16) | (td[1].Address[2] << 8) | td[1].Address[3]);
+                       if (pos < start)
+                               break;
+                       if (pos >= start && pos < end)
+                               break;
+               }
+               p[1] = (toc->TrackData[trk].Control << 0) | (toc->TrackData[trk].Adr << 4);
+               p[2] = trk + 1;
+               p[3] = 1;
+               msf = lsn2msf (pos);
+               p[5] = (msf >> 16) & 0xff;
+               p[6] = (msf >> 8) & 0xff;
+               p[7] = (msf >> 0) & 0xff;
+               pos -= start;
+               if (pos < 0)
+                       pos = 0;
+               msf = lsn2msf (pos);
+               p[9] = (pos >> 16) & 0xff;
+               p[10] = (pos >> 8) & 0xff;
+               p[11] = (pos >> 0) & 0xff;
+
+               return buf;
+
        } else {
 
                SUB_Q_CHANNEL_DATA qcd;
                DWORD len;
                ULONG in = 1;
-               uae_u8 *p = ciw32[unitnum].tempbuffer;
+               uae_u8 *p = ciw->tempbuffer;
                int cnt = 3;
 
                memset (p, 0, 4 + 12);
@@ -442,7 +722,7 @@ static uae_u8 *ioctl_command_qcode (int unitnum)
                p[3] = 12;
                while (cnt-- > 0) {
                        reseterrormode (unitnum);
-                       if(!DeviceIoControl (ciw32[unitnum].h, IOCTL_CDROM_READ_Q_CHANNEL, &in, sizeof(in), &qcd, sizeof (qcd), &len, NULL)) {
+                       if(!DeviceIoControl (ciw->h, IOCTL_CDROM_READ_Q_CHANNEL, &in, sizeof(in), &qcd, sizeof (qcd), &len, NULL)) {
                                reseterrormode (unitnum);
                                if (win32_error (unitnum, L"IOCTL_CDROM_READ_Q_CHANNEL") < 0)
                                        continue;
@@ -462,7 +742,7 @@ static uae_u8 *ioctl_command_qcode (int unitnum)
                p[9] = qcd.CurrentPosition.TrackRelativeAddress[1];
                p[10] = qcd.CurrentPosition.TrackRelativeAddress[2];
                p[11] = qcd.CurrentPosition.TrackRelativeAddress[3];
-               return ciw32[unitnum].tempbuffer;
+               return ciw->tempbuffer;
        }
 }
 
@@ -489,6 +769,7 @@ static uae_u8 *spti_read (int unitnum, int sector, int sectorsize)
 
        if (!open_createfile (unitnum, 1))
                return 0;
+       ciw32[unitnum].cd_last_pos = sector + sectorsize;
        cmd[3] = (uae_u8)(sector >> 16);
        cmd[4] = (uae_u8)(sector >> 8);
        cmd[5] = (uae_u8)(sector >> 0);
@@ -532,6 +813,7 @@ uae_u8 *ioctl_command_rawread (int unitnum, int sector, int sectorsize)
                return spti_read (unitnum, sector, sectorsize);
        if (!open_createfile (unitnum, 1))
                return 0;
+       cdda_stop (unitnum);
        if (sectorsize != 2336 && sectorsize != 2352 && sectorsize != 2048)
                return 0;
        while (cnt-- > 0) {
@@ -547,6 +829,7 @@ uae_u8 *ioctl_command_rawread (int unitnum, int sector, int sectorsize)
                                DWORD err = GetLastError ();
                }
                reseterrormode (unitnum);
+               ciw32[unitnum].cd_last_pos = sector + sectorsize;
                break;
        }
        if (sectorsize == 2352)
@@ -563,6 +846,7 @@ static int ioctl_command_readwrite (int unitnum, int sector, int write, int bloc
        *ptr = NULL;
        if (!open_createfile (unitnum, 0))
                return 0;
+       cdda_stop (unitnum);
        while (cnt-- > 0) {
                gui_flicker_led (LED_CD, unitnum, 1);
                seterrormode (unitnum);
@@ -701,14 +985,17 @@ static int ismedia (int unitnum)
 /* read toc */
 static uae_u8 *ioctl_command_toc (int unitnum)
 {
+       struct dev_info_ioctl *ciw = &ciw32[unitnum];
        DWORD len;
        int i;
-       uae_u8 *p = ciw32[unitnum].tempbuffer;
+       uae_u8 *p = ciw->tempbuffer;
        int cnt = 3;
-       CDROM_TOC *toc = &ciw32[unitnum].toc;
+       CDROM_TOC *toc = &ciw->toc;
 
        if (!open_createfile (unitnum, 0))
                return 0;
+       cdda_stop (unitnum);
+       ciw32[unitnum].cd_last_pos = 0;
        gui_flicker_led (LED_CD, unitnum, 1);
        while (cnt-- > 0) {
                seterrormode (unitnum);
@@ -767,6 +1054,9 @@ static int sys_cddev_open (int unitnum)
 {
        struct dev_info_ioctl *ciw = &ciw32[unitnum];
 
+       ciw->cdda = 1;
+       ciw->cdda_volume = 0xffff;
+       ciw->cdda_volume_main = currprefs.sound_volume;
        /* buffer must be page aligned for device access */
        ciw->tempbuffer = VirtualAlloc (NULL, IOCTL_DATA_BUFFER, MEM_COMMIT, PAGE_READWRITE);
        if (!ciw->tempbuffer) {
@@ -809,6 +1099,7 @@ void sys_cddev_close (int unitnum)
 
        if (!unitcheck (unitnum))
                return;
+       cdda_stop (unitnum);
        close_createfile (unitnum);
        close_mci (unitnum);
        VirtualFree (ciw->tempbuffer, 0, MEM_RELEASE);
@@ -928,7 +1219,7 @@ static struct device_scsi_info *ioctl_scsi_info (int unitnum, struct device_scsi
 struct device_functions devicefunc_win32_ioctl = {
        open_bus, close_bus, open_device, close_device, info_device,
        0, 0, 0,
-       ioctl_command_pause, ioctl_command_stop, ioctl_command_play, ioctl_command_qcode,
+       ioctl_command_pause, ioctl_command_stop, ioctl_command_play, ioctl_command_volume, ioctl_command_qcode,
        ioctl_command_toc, ioctl_command_read, ioctl_command_rawread, ioctl_command_write,
        0, ioctl_scsi_info, ioctl_ismedia
 };
index 193d63aba6fb28f942e0467c35d23c26cff82430..eb2a20c83855875d530d14f33b1ddf4a19b21c1c 100644 (file)
@@ -528,7 +528,7 @@ static struct device_scsi_info *scsi_info (int unitnum, struct device_scsi_info
 struct device_functions devicefunc_win32_spti = {
        open_scsi_bus, close_scsi_bus, open_scsi_device, close_scsi_device, info_device,
        execscsicmd_out, execscsicmd_in, execscsicmd_direct,
-       0, 0, 0, 0, 0, 0, 0, 0, check_isatapi, scsi_info, 0
+       0, 0, 0, 0, 0, 0, 0, 0, 0, check_isatapi, scsi_info, 0
 };
 
 static int getCDROMProperty (int idx, HDEVINFO DevInfo, const GUID *guid)
index 7754e1bccbe105c74332de8a5e5569b6e891b4c8..3ac8ca1784940c024e0e6ac58001b15589007a0e 100644 (file)
@@ -112,7 +112,7 @@ HINSTANCE hInst = NULL;
 HMODULE hUIDLL = NULL;
 HWND (WINAPI *pHtmlHelp)(HWND, LPCWSTR, UINT, LPDWORD) = NULL;
 HWND hAmigaWnd, hMainWnd, hHiddenWnd, hGUIWnd;
-RECT amigawin_rect;
+RECT amigawin_rect, mainwin_rect;
 static int mouseposx, mouseposy;
 static UINT TaskbarRestart;
 static HWND TaskbarRestartHWND;
@@ -1322,6 +1322,7 @@ static int canstretch (void)
 
 static LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
+       static RECT myrect;
        PAINTSTRUCT ps;
        RECT rc;
        HDC hDC;
@@ -1417,24 +1418,21 @@ static LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT message, WPARAM wParam,
                                        DWORD top = rc2.top - win_y_diff;
                                        DWORD width = rc2.right - rc2.left;
                                        DWORD height = rc2.bottom - rc2.top;
-                                       if (amigawin_rect.left & 3) {
-                                               MoveWindow (hMainWnd, rc2.left + 4 - amigawin_rect.left % 4, rc2.top,
-                                                       rc2.right - rc2.left, rc2.bottom - rc2.top, TRUE);
-
-                                       }
                                        if (store_xy++) {
                                                regsetint (NULL, L"MainPosX", left);
                                                regsetint (NULL, L"MainPosY", top);
                                        }
                                        changed_prefs.gfx_size_win.x = left;
                                        changed_prefs.gfx_size_win.y = top;
-                                       if (canstretch ()) {
+                                       if (canstretch () && mainwin_rect.right - mainwin_rect.left != width && mainwin_rect.bottom - mainwin_rect.top != height) {
                                                changed_prefs.gfx_size_win.width = width - window_extra_width;
                                                changed_prefs.gfx_size_win.height = height - window_extra_height;
                                        }
                                }
+                               GetWindowRect (hMainWnd, &mainwin_rect);
                                return 0;
                        }
+                       GetWindowRect (hMainWnd, &mainwin_rect);
                }
                break;
 
index 69bac1fc3a023d20152b6d8dfea96cef50e54c57..47aeea342dfc14c288769dab47f9a99f2471a933 100644 (file)
@@ -18,8 +18,8 @@
 #define WINUAEPUBLICBETA 1
 #define LANG_DLL 1
 
-#define WINUAEBETA L"Beta 3"
-#define WINUAEDATE MAKEBD(2010, 1, 10)
+#define WINUAEBETA L"Beta 4"
+#define WINUAEDATE MAKEBD(2010, 1, 16)
 #define WINUAEEXTRA L""
 #define WINUAEREV L""
 
@@ -29,7 +29,7 @@
 #define WINUAEAPPNAME L"Arabuusimiehet.WinUAE"
 extern HMODULE hUIDLL;
 extern HWND hAmigaWnd, hMainWnd, hHiddenWnd, hGUIWnd;
-extern RECT amigawin_rect;
+extern RECT amigawin_rect, mainwin_rect;
 extern int in_sizemove;
 extern int manual_painting_needed;
 extern int manual_palette_refresh_needed;
index 20c3b1c236e5d39fbd5fd128389edfb705ec472b..7bbe33b9b8696b267a28ffd666a6cf90ff7ce97a 100644 (file)
@@ -2153,6 +2153,7 @@ static int create_windows_2 (void)
                        y = ny;
                }
                GetWindowRect (hAmigaWnd, &amigawin_rect);
+               GetWindowRect (hMainWnd, &mainwin_rect);
                if (d3dfs || dxfs)
                        SetCursorPos (x + w / 2, y + h / 2);
                write_log (L"window already open\n");
@@ -2288,6 +2289,7 @@ WS_EX_TOPMOST :
        if (hMainWnd == NULL)
                hMainWnd = hAmigaWnd;
        GetWindowRect (hAmigaWnd, &amigawin_rect);
+       GetWindowRect (hMainWnd, &mainwin_rect);
        if (dxfs || d3dfs)
                SetCursorPos (x + w / 2, y + h / 2);
        addnotifications (hAmigaWnd, FALSE, FALSE);
index d3de097de86bf6fe63cab5f658da2ba2996cd5ac..97b02be885fa18351f2c7582c3fb526b703e9be6 100644 (file)
@@ -1521,8 +1521,6 @@ static UINT_PTR CALLBACK ofnhook (HWND hDlg, UINT message, WPARAM wParam, LPARAM
                nmhdr = (LPNMHDR)lParam;
                if (nmhdr->code == CDN_INITDONE)
                        doit = TRUE;
-       } else if (message == WM_INITDIALOG) {
-               doit = TRUE;
        }
        if (!doit)
                return FALSE;
@@ -1540,14 +1538,16 @@ static UINT_PTR CALLBACK ofnhook (HWND hDlg, UINT message, WPARAM wParam, LPARAM
        prevheight = h2;
        write_log (L"MOVEWINDOW %dx%d %dx%d (%dx%d)\n", md->rect.left, md->rect.top, md->rect.right, md->rect.bottom, w2, h2);
        hWnd = GetParent (hDlg);
+       windowRect.left = windowRect.right = windowRect.top = windowRect.bottom = -1;
        GetWindowRect (hWnd, &windowRect);
        width = windowRect.right - windowRect.left;
        height = windowRect.bottom - windowRect.top;
+       write_log (L"%dx%d %dx%d\n", windowRect.left, windowRect.top, windowRect.right, windowRect.bottom);
        if (width > w2)
                width = w2;
        if (height > h2)
                height = h2;
-       MoveWindow (hWnd, md->rect.left + (w2 - width) / 2, md->rect.top + (h2 - height) / 2, width, height, FALSE);
+       SetWindowPos (hWnd, NULL, md->rect.left + (w2 - width) / 2, md->rect.top + (h2 - height) / 2, width, height, SWP_NOZORDER | SWP_NOACTIVATE);
        return FALSE;
 }
 
index b343ca3e10aa9b410876fcd07b6350739010d758..177d12f360bd2c6ffba2318805715f645d9a158f 100644 (file)
                                        >
                                </File>
                                <File
-                                       RelativePath=".\configfile.ico"
+                                       RelativePath="..\resources\configfile.ico"
                                        >
                                </File>
                                <File
-                                       RelativePath="..\resources\configfile.ico"
+                                       RelativePath=".\configfile.ico"
                                        >
                                </File>
                                <File
                                        >
                                </File>
                                <File
-                                       RelativePath=".\expansion.ico"
+                                       RelativePath="..\resources\expansion.ico"
                                        >
                                </File>
                                <File
-                                       RelativePath="..\resources\expansion.ico"
+                                       RelativePath=".\expansion.ico"
                                        >
                                </File>
                                <File
-                                       RelativePath=".\file.ico"
+                                       RelativePath="..\resources\file.ico"
                                        >
                                </File>
                                <File
-                                       RelativePath="..\resources\file.ico"
+                                       RelativePath=".\file.ico"
                                        >
                                </File>
                                <File
                                RelativePath="..\..\blkdev.c"
                                >
                        </File>
+                       <File
+                               RelativePath="..\..\blkdev_cdimage.c"
+                               >
+                       </File>
                        <File
                                RelativePath="..\..\bsdsocket.c"
                                >
index 18007c58933c34b361b1bba2c5364e4be7c1d8c6..b18f7e492a7943714626cc7417bf62316ef25d22 100644 (file)
@@ -1,4 +1,42 @@
 
+Beta 4:
+
+- ADDX and SUBX timing updates
+- ABCD and SBCD idle cycle position in -(An),-(An) mode fixed
+- EXG idle cycle and prefetch swapped
+- BCLR/BSET/BCHG/BTST idle cycle and prefetch swapped
+- writing to blitter registers while active could have confused
+  blitter emulation logic, stopping the blitter mid blit (stopping
+  because emulation got confused, not because emulation detected
+  situation when it should really stop)
+- plain A500 OCS/ECS byte writes to custom registers fixed (I think
+  this was using 68020/AGA behavior for all modes accidentally)
+- interrupt delay and 68000 IPL sampling timing improved
+- windowed mode window was sometimes incorrectly detected as resized
+  when it only lost focus (native mode size was changed to current
+  window size)
+
+  Big CD32/CDTV CD handling update:
+
+- stupid MCI CD32/CDTV CD audio replaced with simple "audio ripper"
+  that reads the digital CD audio data and sends it to audio device
+  NOTE: no jitter correction yet (possibly bad sound if your drive
+  is old enough to not have accurate streaming support)
+- CDTV CD hardware volume control now supported
+- CD32 CD mute on/off "volume" control supported (no real volume..)
+- Sound-panel volume also adjusts CD32/CDTV CD audio volume
+- CD32/CDTV Q sub channel data virtualized (does not need real drive
+  anymore, makes new things possible, see below)
+- Built-in CUE CD image support, including CD audio track support!
+  .CUE + single big .BIN and .CUE + .BIN + .WAVs supported (MP3 audio
+  is also supported if you have mp3 codec installed but all tracks will
+  be decoded before emulation starts..) Most common data tracks
+  supported. Plain iso images also supported.
+  Problems = logs AND .cue file required.
+  cdimage0=<path to .cue/.iso> in config file, command line parameter
+  -cdimage=<path to .cue/.iso> can also be used.
+  No GUI support yet.
+
 Beta 3:
 
 - Shadow Fighter AGA graphics priority issue really fixed now
diff --git a/zfile.c b/zfile.c
index 52c174f6b3647dbe4a38b4dc189919c3a442631b..ac4d3fd8a0d72204d4d92beadceaa6456f141aef 100644 (file)
--- a/zfile.c
+++ b/zfile.c
@@ -2044,8 +2044,8 @@ int zfile_zuncompress (void *dst, int dstsize, struct zfile *src, int srcsize)
        uae_u8 inbuf[4096];
        int incnt;
 
-       memset (&zs, 0, sizeof(zs));
-       if (inflateInit_ (&zs, ZLIB_VERSION, sizeof(z_stream)) != Z_OK)
+       memset (&zs, 0, sizeof (zs));
+       if (inflateInit_ (&zs, ZLIB_VERSION, sizeof (z_stream)) != Z_OK)
                return 0;
        zs.next_out = (Bytef*)dst;
        zs.avail_out = dstsize;