From 50172b3abcb1fe6ef3ea3a0d5e643a575583e586 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Tue, 6 Jul 2010 19:54:43 +0300 Subject: [PATCH] 2210b1 --- audio.cpp | 582 +++++++++++++------------ blitter.cpp | 6 +- blkdev.cpp | 6 + blkdev_cdimage.cpp | 70 +-- custom.cpp | 132 +++++- disk.cpp | 360 ++++++++------- drawing.cpp | 2 +- driveclick.cpp | 6 +- include/audio.h | 9 +- include/disk.h | 8 +- include/events.h | 6 +- include/uae.h | 1 + od-win32/dinput.cpp | 2 +- od-win32/direct3d.cpp | 15 +- od-win32/fsdb_mywin32.cpp | 5 +- od-win32/resources/resource | 4 - od-win32/resources/winuae.rc | 15 +- od-win32/win32.cpp | 104 ++++- od-win32/win32.h | 6 +- od-win32/win32gui.cpp | 90 ++-- od-win32/winuae_msvc10/winuae_msvc.sln | 2 - od-win32/winuaechangelog.txt | 35 +- 22 files changed, 878 insertions(+), 588 deletions(-) diff --git a/audio.cpp b/audio.cpp index 89d39a8a..38e38eda 100644 --- a/audio.cpp +++ b/audio.cpp @@ -45,7 +45,10 @@ #define MAX_EV ~0ul //#define DEBUG_AUDIO -#define DEBUG_CHANNEL_MASK 15 +#define DEBUG_CHANNEL_MASK 2 +//#define TEST_AUDIO + +#define PERIOD_MIN 4 int audio_channel_mask = 15; @@ -78,7 +81,13 @@ typedef struct { struct audio_channel_data { unsigned long adk_mask; unsigned long evtime; - uae_u8 dmaen, intreq2; + bool dmaenstore; + bool intreq2; + bool dr; + bool dsr; + bool pbufldl; + int drhpos; + bool dat_written; uaecptr lc, pt; int current_sample, last_sample; int state; @@ -86,12 +95,15 @@ struct audio_channel_data { int vol; int len, wlen; uae_u16 dat, dat2; - int request_word, request_word_skip; - int vpos; int sample_accum, sample_accum_time; int sinc_output_state; sinc_queue_t sinc_queue[SINC_QUEUE_LENGTH]; int sinc_queue_length; +#ifdef TEST_AUDIO + bool hisample, losample; + bool have_dat; + int per_original; +#endif }; static int samplecnt; @@ -143,7 +155,7 @@ void write_wavheader (struct zfile *wavfile, uae_u32 size, uae_u32 freq) zfile_fwrite (&tl, 1, 4, wavfile); } -static void convertsample(uae_u8 *sample, int len) +static void convertsample (uae_u8 *sample, int len) { int i; for (i = 0; i < len; i++) @@ -1019,23 +1031,45 @@ static void sample16si_rh_handler (void) static int audio_work_to_do; -static void zerostate (struct audio_channel_data *cdp) +static void zerostate (int nr) { + struct audio_channel_data *cdp = audio_channel + nr; cdp->state = 0; cdp->evtime = MAX_EV; - cdp->request_word = 0; + cdp->intreq2 = 0; + cdp->dsr = cdp->dr = false; +#ifdef TEST_AUDIO + cdp->have_dat = false; +#endif } -static void audio_event_reset (void) +static void schedule_audio (void) { + unsigned long best = MAX_EV; int i; - last_cycles = get_cycles () - 1; - next_sample_evtime = scaled_sample_evtime; + eventtab[ev_audio].active = 0; + eventtab[ev_audio].oldcycles = get_cycles (); for (i = 0; i < 4; i++) { struct audio_channel_data *cdp = audio_channel + i; - zerostate (cdp); + if (cdp->evtime != MAX_EV) { + if (best > cdp->evtime) { + best = cdp->evtime; + eventtab[ev_audio].active = 1; + } + } } + eventtab[ev_audio].evtime = get_cycles () + best; +} + +static void audio_event_reset (void) +{ + int i; + + last_cycles = get_cycles () - 1; + next_sample_evtime = scaled_sample_evtime; + for (i = 0; i < 4; i++) + zerostate (i); schedule_audio (); events_schedule (); samplecnt = 0; @@ -1073,23 +1107,23 @@ STATIC_INLINE int is_audio_active (void) return audio_work_to_do; } -void schedule_audio (void) +uae_u16 audio_dmal (void) { - unsigned long best = MAX_EV; - int i; - - eventtab[ev_audio].active = 0; - eventtab[ev_audio].oldcycles = get_cycles (); - for (i = 0; i < 4; i++) { - struct audio_channel_data *cdp = audio_channel + i; - if (cdp->evtime != MAX_EV) { - if (best > cdp->evtime) { - best = cdp->evtime; - eventtab[ev_audio].active = 1; - } + uae_u16 dmal = 0; + for (int nr = 0; nr < 4; nr++) { + struct audio_channel_data *cdp = audio_channel + nr; + // hpos offset hack, no need for expensive event + if (cdp->drhpos > 0 && cdp->drhpos < maxhpos - 4) { + if (cdp->dr) + dmal |= 1 << (nr * 2); + if (cdp->dsr) + dmal |= 1 << (nr * 2 + 1); + cdp->dr = cdp->dsr = false; + } else { + cdp->drhpos = 1; } } - eventtab[ev_audio].evtime = get_cycles () + best; + return dmal; } static int isirq (int nr) @@ -1099,18 +1133,20 @@ static int isirq (int nr) static void setirq (int nr, int which) { + struct audio_channel_data *cdp = audio_channel + nr; #ifdef DEBUG_AUDIO if (debugchannel (nr)) - write_log (L"SETIRQ %d (%d) %08X\n", nr, which, M68K_GETPC); + write_log (L"SETIRQ%d (%d,%d) PC=%08X\n", nr, which, isirq (nr) ? 1 : 0, M68K_GETPC); #endif - INTREQ (0x8000 | (0x80 << nr)); + INTREQ_0 (0x8000 | (0x80 << nr)); } static void newsample (int nr, sample8_t sample) { struct audio_channel_data *cdp = audio_channel + nr; #ifdef DEBUG_AUDIO - if (!debugchannel (nr)) sample = 0; + if (!debugchannel (nr)) + sample = 0; #endif if (!(audio_channel_mask & (1 << nr))) sample = 0; @@ -1118,164 +1154,237 @@ static void newsample (int nr, sample8_t sample) cdp->current_sample = sample; } -static void state23 (struct audio_channel_data *cdp) +STATIC_INLINE void setdr (int nr) { - if (!cdp->dmaen) - return; - if (cdp->request_word >= 0) - return; - cdp->request_word = 0; + struct audio_channel_data *cdp = audio_channel + nr; +#ifdef TEST_AUDIO + if (cdp->dr) + write_log (L"%d: DR already active (STATE=%d)\n", nr, cdp->state); +#endif + cdp->drhpos = current_hpos (); + cdp->dr = true; if (cdp->wlen == 1) { - cdp->wlen = cdp->len; - cdp->pt = cdp->lc; - cdp->intreq2 = 1; - if (sampleripper_enabled) - do_samplerip (cdp); + cdp->dsr = true; + cdp->drhpos++; #ifdef DEBUG_AUDIO - if (debugchannel (cdp - audio_channel)) - write_log (L"Channel %d looped, LC=%08X LEN=%d\n", cdp - audio_channel, cdp->pt, cdp->wlen); + if (debugchannel (nr)) + write_log (L"DSR%d PT=%08X PC=%08X\n", nr, cdp->pt, M68K_GETPC); #endif + } +} + +static void loaddat (int nr) +{ + struct audio_channel_data *cdp = audio_channel + nr; + int audav = adkcon & (0x01 << nr); + int audap = adkcon & (0x10 << nr); + if (audav || audap) { + if (nr > 3) + return; + if (audav) { + cdp[1].vol = cdp->dat; + } else if (audap) { + if (cdp->dat == 0) + cdp[1].per = PERIOD_MAX; + else if (cdp->dat > PERIOD_MIN) + cdp[1].per = cdp->dat * CYCLE_UNIT; + else + cdp[1].per = PERIOD_MIN * CYCLE_UNIT; + } } else { - cdp->wlen = (cdp->wlen - 1) & 0xFFFF; +#ifdef TEST_AUDIO + if (cdp->hisample || cdp->losample) + write_log (L"%d: high or low sample not used\n", nr); + cdp->hisample = cdp->losample = true; + if (!cdp->have_dat) + write_log (L"%d: dat not updated. STATE=%d\n", nr, cdp->state); + cdp->have_dat = false; +#endif + cdp->dat2 = cdp->dat; } } -static void audio_handler (int nr) +STATIC_INLINE void loadper (int nr) { struct audio_channel_data *cdp = audio_channel + nr; + cdp->evtime = cdp->per; + if (cdp->evtime < CYCLE_UNIT) + write_log (L"loadper%d bug %d\n", nr, cdp->evtime); +} + + +static void audio_state_channel2 (int nr, bool perfin) +{ + struct audio_channel_data *cdp = audio_channel + nr; + bool chan_ena = (dmacon & DMA_MASTER) && (dmacon & (1 << nr)); int audav = adkcon & (0x01 << nr); int audap = adkcon & (0x10 << nr); int napnav = (!audav && !audap) || audav; - int evtime = cdp->evtime; + int hpos = current_hpos (); - audio_activate (); - cdp->evtime = MAX_EV; +#ifdef DEBUG_AUDIO + if (debugchannel (nr)) { + if (cdp->dmaenstore != chan_ena) { + cdp->dmaenstore = chan_ena; + write_log (L"%d:DMA=%d IRQ=%d PC=%08x\n", nr, chan_ena, isirq (nr) ? 1 : 0, M68K_GETPC); + } + } +#endif + if (currprefs.produce_sound == 0) { + zerostate (nr); + return; + } switch (cdp->state) { case 0: - cdp->intreq2 = 0; - cdp->vpos = vpos; - if (cdp->dmaen) { + if (chan_ena) { + cdp->evtime = MAX_EV; cdp->state = 1; + cdp->dsr = true; + cdp->dr = true; + cdp->drhpos = hpos; cdp->wlen = cdp->len; - /* there are too many stupid sound routines that fail on "too" fast cpus.. */ - if (usehacks ()) - cdp->pt = cdp->lc; +#ifdef TEST_AUDIO + cdp->have_dat = false; +#endif #ifdef DEBUG_AUDIO if (debugchannel (nr)) - write_log (L"%d:0>1: LEN=%d\n", nr, cdp->wlen); + write_log (L"%d:0>1: LEN=%d PC=%08x\n", nr, cdp->wlen, M68K_GETPC); #endif - cdp->request_word = 0; - cdp->request_word_skip = 0; - audio_handler (nr); - return; - } else if (!cdp->dmaen && cdp->request_word < 0 && !isirq (nr)) { - cdp->evtime = 0; + } else if (cdp->dat_written && !isirq (nr)) { cdp->state = 2; setirq (nr, 0); - audio_handler (nr); - return; + loaddat (nr); + if (currprefs.cpu_model >= 68020 && !currprefs.cpu_cycle_exact && cdp->per < 10 * CYCLE_UNIT) { + // make sure audio.device AUDxDAT startup returns to idle state before DMA is enabled + newsample (nr, (cdp->dat2 >> 0) & 0xff); + zerostate (nr); + } else { + loadper (nr); + cdp->pbufldl = true; + audio_state_channel2 (nr, false); + } + } else { + zerostate (nr); } - cdp->request_word = 0; - cdp->request_word_skip = 0; - return; - + break; case 1: - if (!cdp->dmaen) { - cdp->state = 0; + if (!cdp->dat_written) return; - } - cdp->state = 5; +#ifdef TEST_AUDIO + if (!cdp->have_dat) + write_log (L"%d: state 1 but no have_dat\n", nr); + cdp->have_dat = false; + cdp->losample = cdp->hisample = false; +#endif + setirq (nr, 1); + setdr (nr); if (cdp->wlen != 1) - cdp->wlen = (cdp->wlen - 1) & 0xFFFF; - cdp->request_word = 2; - /* "mysterious" delay for Mission Elevator */ - //if (cdp->vpos == vpos) - if (current_hpos () > maxhpos - 20) - cdp->request_word_skip = 1; - return; - + cdp->wlen = (cdp->wlen - 1) & 0xffff; + cdp->state = 5; + break; case 5: - if (!cdp->request_word) { - cdp->request_word = 2; - return; - } - setirq (nr, 5); - if (!cdp->dmaen) { - cdp->state = 0; - cdp->request_word = 0; + if (!cdp->dat_written) return; - } - cdp->state = 2; - cdp->request_word = 3; +#ifdef DEBUG_AUDIO + if (debugchannel (nr)) + write_log (L"%d:>5: LEN=%d PT=%08X PC=%08X\n", nr, cdp->wlen, cdp->pt, M68K_GETPC); +#endif + loaddat (nr); if (napnav) - cdp->request_word = 2; - cdp->dat = cdp->dat2; - return; - + setdr (nr); + cdp->state = 2; + loadper (nr); + cdp->pbufldl = true; + cdp->intreq2 = 0; + audio_state_channel2 (nr, false); + break; case 2: - if (currprefs.produce_sound == 0) - cdp->per = PERIOD_MAX; - - if (!cdp->dmaen && isirq (nr) && (evtime == 0 || evtime == MAX_EV || evtime == cdp->per)) { - zerostate (cdp); + if (cdp->pbufldl) { +#ifdef TEST_AUDIO + if (cdp->hisample == false) + write_log (L"%d: high sample used twice\n", nr); + cdp->hisample = false; +#endif + newsample (nr, (cdp->dat2 >> 8) & 0xff); + cdp->pbufldl = false; + } + if (!perfin) return; + if (audap) + loaddat (nr); + if (chan_ena) { + if (audap) + setdr (nr); + if (cdp->intreq2 && audap) + setirq (nr, 21); + } else { + if (audap) + setirq (nr, 22); } - - state23 (cdp); + loadper (nr); + cdp->pbufldl = true; cdp->state = 3; - cdp->evtime = cdp->per; - newsample (nr, (cdp->dat >> 8) & 0xff); - cdp->dat <<= 8; - /* Period attachment? */ - if (audap) { - if (cdp->intreq2 && cdp->dmaen) - setirq (nr, 2); - cdp->intreq2 = 0; - cdp->request_word = 1; - cdp->dat = cdp->dat2; - if (nr < 3) { - if (cdp->dat == 0) - (cdp+1)->per = PERIOD_MAX; - else if (cdp->dat < maxhpos * CYCLE_UNIT / 2 && currprefs.produce_sound < 3) - (cdp+1)->per = maxhpos * CYCLE_UNIT / 2; - else - (cdp+1)->per = cdp->dat * CYCLE_UNIT; - } - } - return; - + audio_state_channel2 (nr, false); + break; case 3: - if (currprefs.produce_sound == 0) - cdp->per = PERIOD_MAX; - - state23 (cdp); - cdp->state = 2; - cdp->evtime = cdp->per; - newsample (nr, (cdp->dat >> 8) & 0xff); - cdp->dat <<= 8; - cdp->dat = cdp->dat2; - if (cdp->dmaen) { - if (napnav) - cdp->request_word = 1; + if (cdp->pbufldl) { +#ifdef TEST_AUDIO + if (cdp->losample == false) + write_log (L"%d: low sample used twice\n", nr); + cdp->losample = false; +#endif + newsample (nr, (cdp->dat2 >> 0) & 0xff); + cdp->pbufldl = false; + } + if (!perfin) + return; + if (chan_ena) { + loaddat (nr); if (cdp->intreq2 && napnav) - setirq (nr, 3); + setirq (nr, 31); + if (napnav) + setdr (nr); } else { - if (napnav) { - setirq (nr, 4); + if (isirq (nr)) { +#ifdef DEBUG_AUDIO + if (debugchannel (nr)) + write_log (L"%d: IDLE\n", nr); +#endif + zerostate (nr); + return; } + loaddat (nr); + if (napnav) + setirq (nr, 32); } cdp->intreq2 = 0; + loadper (nr); + cdp->pbufldl = true; + cdp->state = 2; + audio_state_channel2 (nr, false); + break; + } +} - /* Volume attachment? */ - if (audav) { - if (nr < 3) { - (cdp+1)->vol = cdp->dat; - } - } - return; +static void audio_state_channel (int nr, bool perfin) +{ + struct audio_channel_data *cdp = audio_channel + nr; + audio_state_channel2 (nr, perfin); + cdp->dat_written = 0; +} + +void audio_state_machine (void) +{ + update_audio (); + for (int nr = 0; nr < 4; nr++) { + struct audio_channel_data *cdp = audio_channel + nr; + audio_state_channel2 (nr, false); + cdp->dat_written = 0; } + schedule_audio (); + events_schedule (); } void audio_reset (void) @@ -1297,14 +1406,9 @@ void audio_reset (void) cdp->vol = 0; cdp->evtime = MAX_EV; } - } else { - for (i = 0; i < 4; i++) { - cdp = &audio_channel[i]; - cdp->dmaen = (dmacon & DMA_MASTER) && (dmacon & (1 << i)); - } } - last_cycles = get_cycles (); + last_cycles = get_cycles () - 1; next_sample_evtime = scaled_sample_evtime; schedule_audio (); events_schedule (); @@ -1588,7 +1692,7 @@ void update_audio (void) for (i = 0; i < 4; i++) { if (audio_channel[i].evtime == 0) - audio_handler (i); + audio_state_channel (i, true); } } end: @@ -1601,118 +1705,72 @@ void audio_evhandler (void) schedule_audio (); } -void audio_hsync (int hpos) +void audio_hsync (void) { - int nr, handle; - static int old_dma; - int dmaaction = hpos < 0; - if (!isaudio ()) return; - - if (old_dma != (dmacon & (DMA_MASTER | 15))) { - old_dma = dmacon & (DMA_MASTER | 15); - audio_activate (); - } - if (audio_work_to_do > 0 && currprefs.sound_auto) { audio_work_to_do--; if (audio_work_to_do == 0) audio_deactivate (); } - - if (!is_audio_active ()) - return; - update_audio (); - handle = 0; - /* Sound data is fetched at the beginning of each line */ - for (nr = 0; nr < 4; nr++) { - struct audio_channel_data *cdp = audio_channel + nr; - int chan_ena = (dmacon & DMA_MASTER) && (dmacon & (1 << nr)); - int handle2 = 0; - - if (dmaaction && cdp->request_word > 0) { +} - if (cdp->request_word_skip) { - cdp->request_word_skip = 0; - continue; - } +void AUDxDAT (int nr, uae_u16 v, uaecptr addr) +{ + struct audio_channel_data *cdp = audio_channel + nr; + int chan_ena = (dmacon & DMA_MASTER) && (dmacon & (1 << nr)); - if (cdp->state == 5) { - cdp->pt = cdp->lc; +#ifdef DEBUG_AUDIO + if (debugchannel (nr) && (!chan_ena || addr == 0xffffffff || (cdp->state != 2 && cdp->state != 3))) + write_log (L"AUD%dDAT: %04X ADDR=%08X LEN=%d/%d %d,%d,%d %06X\n", nr, + v, addr, cdp->wlen, cdp->len, cdp->state, chan_ena, isirq (nr) ? 1 : 0, M68K_GETPC); +#endif + cdp->dat = v; + cdp->dat_written = true; +#ifdef TEST_AUDIO + if (cdp->have_dat) + write_log (L"%d: audxdat but old dat not yet used\n", nr); + cdp->have_dat = true; +#endif + if (cdp->state == 2 || cdp->state == 3) { + if (chan_ena) { + if (cdp->wlen == 1) { + cdp->wlen = cdp->len; + cdp->intreq2 = true; if (sampleripper_enabled) do_samplerip (cdp); #ifdef DEBUG_AUDIO if (debugchannel (nr)) - write_log (L"%d:>5: LEN=%d PT=%08X\n", nr, cdp->wlen, cdp->pt); + write_log (L"AUD%d looped, IRQ=%d, LC=%08X LEN=%d\n", nr, isirq (nr), cdp->pt, cdp->wlen); #endif + } else { + cdp->wlen = (cdp->wlen - 1) & 0xffff; } - cdp->dat2 = last_custom_value1 = chipmem_wget_indirect (cdp->pt); - if (cdp->request_word >= 2) - handle2 = 1; - if (chan_ena) { - if (dmaaction) { - alloc_cycle_ext (13 + nr * 2, CYCLE_MISC); -#ifdef DEBUGGER - if (debug_dma) - record_dma (0xaa + nr * 16, cdp->dat2, cdp->pt, 13 + nr * 2, vpos, DMARECORD_AUDIO); -#endif - } - if (cdp->request_word == 1 || cdp->request_word == 2) - cdp->pt += 2; - } - cdp->request_word = -1; - - } - - if (cdp->dmaen != chan_ena) { -#ifdef DEBUG_AUDIO - if (debugchannel (nr)) - write_log (L"AUD%dDMA %d->%d (%d) LEN=%d/%d %08X\n", nr, cdp->dmaen, chan_ena, - cdp->state, cdp->wlen, cdp->len, M68K_GETPC); -#endif - cdp->dmaen = chan_ena; - if (cdp->dmaen) - handle2 = 1; } - if (handle2) - audio_handler (nr); - handle |= handle2; - } - if (handle) { + } else { + audio_activate (); + update_audio (); + audio_state_channel (nr, false); schedule_audio (); events_schedule (); } + cdp->dat_written = false; } - void AUDxDAT (int nr, uae_u16 v) { - struct audio_channel_data *cdp = audio_channel + nr; + AUDxDAT (nr, v, 0xffffffff); +} -#ifdef DEBUG_AUDIO - if (debugchannel (nr)) - write_log (L"AUD%dDAT: %04X STATE=%d IRQ=%d %08X\n", nr, - v, cdp->state, isirq(nr) ? 1 : 0, M68K_GETPC); -#endif - audio_activate (); - update_audio (); - cdp->dat2 = v; - if (cdp->request_word >= 2 && cdp->request_word_skip == 0) - audio_handler (nr); - cdp->request_word = -1; - cdp->request_word_skip = 0; - /* cpu >= 68020: another "too fast" memory/CPU hack */ - if (cdp->state == 0 || usehacks ()) { - cdp->state = 2; - cdp->wlen = cdp->len; +uaecptr audio_getpt (int nr, int reset) +{ + struct audio_channel_data *cdp = audio_channel + nr; + uaecptr p = cdp->pt; + cdp->pt += 2; + if (reset) cdp->pt = cdp->lc; - if (usehacks ()) - setirq (nr, -1); - audio_handler (nr); - schedule_audio (); - events_schedule (); - } + return p; } void AUDxLCH (int nr, uae_u16 v) @@ -1749,19 +1807,10 @@ void AUDxPER (int nr, uae_u16 v) if (per == 0) per = PERIOD_MAX - 1; -#if 0 - // too fast CPU compatibility hack. KS sets AUDxPER == 8 or 1 when ending the sound, this does not - // always work correctly in JIT modes if sound is immediately restarted. - if (usehacks () && per < 10 * CYCLE_UNIT && !cdp->dmaen) { - zerostate (cdp); - } -#endif - - if (per < maxhpos * CYCLE_UNIT / 2 && currprefs.produce_sound < 3) - per = maxhpos * CYCLE_UNIT / 2; - else if (per < 4 * CYCLE_UNIT) + if (per < PERIOD_MIN * CYCLE_UNIT) { /* smaller values would cause extremely high cpu usage */ - per = 4 * CYCLE_UNIT; + per = PERIOD_MIN * CYCLE_UNIT; + } if (cdp->per == PERIOD_MAX - 1 && per != PERIOD_MAX - 1) { cdp->evtime = CYCLE_UNIT; @@ -1770,7 +1819,9 @@ void AUDxPER (int nr, uae_u16 v) events_schedule (); } } - +#ifdef TEST_AUDIO + cdp->per_original = v; +#endif cdp->per = per; #ifdef DEBUG_AUDIO if (debugchannel (nr)) @@ -1794,7 +1845,6 @@ void AUDxVOL (int nr, uae_u16 v) { struct audio_channel_data *cdp = audio_channel + nr; int v2 = v & 64 ? 63 : v & 63; - audio_activate (); update_audio (); cdp->vol = v2; @@ -1804,27 +1854,6 @@ void AUDxVOL (int nr, uae_u16 v) #endif } -void audio_update_irq (uae_u16 v) -{ -#ifdef DEBUG_AUDIO - uae_u16 v2 = intreq, v3 = intreq; - int i; - if (v & 0x8000) - v2 |= v & 0x7FFF; - else - v2 &= ~v; - v2 &= (0x80 | 0x100 | 0x200 | 0x400); - v3 &= (0x80 | 0x100 | 0x200 | 0x400); - for (i = 0; i < 4; i++) { - if ((1 << i) & DEBUG_CHANNEL_MASK) { - uae_u16 mask = 0x80 << i; - if ((v2 & mask) != (v3 & mask)) - write_log (L"AUD%dINTREQ %d->%d %08X\n", i, !!(v3 & mask), !!(v2 & mask), M68K_GETPC); - } - } -#endif -} - void audio_update_adkmasks (void) { static int prevcon = -1; @@ -1864,8 +1893,14 @@ uae_u8 *restore_audio (int i, uae_u8 *src) acd = audio_channel + i; acd->state = restore_u8 (); acd->vol = restore_u8 (); - acd->intreq2 = restore_u8 (); - acd->request_word = restore_u8 (); + acd->intreq2 = restore_u8 () ? true : false; + p = restore_u8 (); + acd->dr = acd->dsr = false; + if (p & 1) + acd->dr = true; + if (p & 2) + acd->dsr = true; + acd->drhpos = 1; acd->len = restore_u16 (); acd->wlen = restore_u16 (); p = restore_u16 (); @@ -1874,6 +1909,7 @@ uae_u8 *restore_audio (int i, uae_u8 *src) acd->lc = restore_u32 (); acd->pt = restore_u32 (); acd->evtime = restore_u32 (); + last_cycles = get_cycles () - 1; return src; } @@ -1892,7 +1928,7 @@ uae_u8 *save_audio (int i, int *len, uae_u8 *dstptr) save_u8 ((uae_u8)acd->state); save_u8 (acd->vol); save_u8 (acd->intreq2); - save_u8 (acd->request_word); + save_u8 ((acd->dr ? 1 : 0) | (acd->dsr ? 2 : 0)); save_u16 (acd->len); save_u16 (acd->wlen); p = acd->per == PERIOD_MAX ? 0 : acd->per / CYCLE_UNIT; diff --git a/blitter.cpp b/blitter.cpp index b9da8f9d..3d4a7436 100644 --- a/blitter.cpp +++ b/blitter.cpp @@ -760,7 +760,7 @@ void blitter_handler (uae_u32 data) static int blitter_stuck; if (!dmaen (DMA_BLITTER)) { - event2_newevent (ev2_blitter, 10); + event2_newevent (ev2_blitter, 10, 0); blitter_stuck++; if (blitter_stuck < 20000 || !currprefs.immediate_blits) return; /* gotta come back later. */ @@ -771,7 +771,7 @@ void blitter_handler (uae_u32 data) } blitter_stuck = 0; if (blit_slowdown > 0 && !currprefs.immediate_blits) { - event2_newevent (ev2_blitter, blit_slowdown); + event2_newevent (ev2_blitter, blit_slowdown, 0); blit_slowdown = -1; return; } @@ -1365,7 +1365,7 @@ static void do_blitter2 (int hpos, int copper) blit_waitcyclecounter = 0; blit_cyclecounter = cycles * (blit_dmacount2 + (blit_nod ? 0 : 1)); - event2_newevent (ev2_blitter, blit_cyclecounter); + event2_newevent (ev2_blitter, blit_cyclecounter, 0); } void do_blitter (int hpos, int copper) diff --git a/blkdev.cpp b/blkdev.cpp index aaa1c204..f1638fed 100644 --- a/blkdev.cpp +++ b/blkdev.cpp @@ -68,6 +68,12 @@ void sys_command_setunit (int unitnum) int sys_command_open (int mode, int unitnum) { int ret = 0; + + if (forcedunit >= 0) { + if (unitnum != forcedunit) + return 0; + } + if (mode == DF_SCSI || !have_ioctl) { if (device_func[DF_SCSI] != NULL) ret = device_func[DF_SCSI]->opendev (unitnum); diff --git a/blkdev_cdimage.cpp b/blkdev_cdimage.cpp index 9889a57f..5e2e052d 100644 --- a/blkdev_cdimage.cpp +++ b/blkdev_cdimage.cpp @@ -1041,10 +1041,41 @@ static void close_device (int unitnum) unload_image (); } -void cdimage_vsync (void) +static bool mountme (void) { - int media = 0; + sys_command_setunit (-1); + bool sel = false; + donotmountme = true; + device_func_init (DEVICE_TYPE_ANY); + for (int i = 0; i < MAX_TOTAL_DEVICES && !sel; i++) { + int opened = sys_command_isopen (i); + struct device_info *discsi, discsi2; + discsi = 0; + if (sys_command_open (DF_IOCTL, i)) { + discsi = sys_command_info (DF_IOCTL, i, &discsi2); + if (discsi && discsi->type == INQ_ROMD) { + if (!_tcsicmp (currprefs.cdimagefile, discsi->label)) { + sys_command_setunit (i); + write_log (L"Drive '%s' (unit=%d) selected (media=%d)\n", discsi->label, i, discsi->media_inserted); + sel = true; + } + } + } + } + donotmountme = false; + if (!sel) { + sys_command_setunit (0); + device_func_init (DEVICE_TYPE_ANY); // activate us again + parse_image (); + int media = tracks > 0; + write_log (L"IMG_EMU (%s) selected (media=%d)\n", currprefs.cdimagefile, media); + return true; + } + return false; +} +void cdimage_vsync (void) +{ if (_tcscmp (changed_prefs.cdimagefile, currprefs.cdimagefile)) { _tcscpy (newfile, changed_prefs.cdimagefile); changed_prefs.cdimagefile[0] = currprefs.cdimagefile[0] = 0; @@ -1072,36 +1103,10 @@ void cdimage_vsync (void) if (un < 0) { device_func_init (DEVICE_TYPE_ANY); // activate us again parse_image (); - media = tracks > 0; scsi_do_disk_change (255, 1); } } else { - bool sel = false; - donotmountme = true; - device_func_init (DEVICE_TYPE_ANY); - for (int i = 0; i < MAX_TOTAL_DEVICES && !sel; i++) { - int opened = sys_command_isopen (i); - struct device_info *discsi, discsi2; - discsi = 0; - if (sys_command_open (DF_IOCTL, i)) { - discsi = sys_command_info (DF_IOCTL, i, &discsi2); - if (discsi && discsi->type == INQ_ROMD) { - if (!_tcsicmp (currprefs.cdimagefile, discsi->label)) { - sys_command_setunit (i); - write_log (L"Drive '%s' (unit=%d) selected (media=%d)\n", discsi->label, i, discsi->media_inserted); - sel = true; - } - } - } - } - donotmountme = false; - if (!sel) { - sys_command_setunit (0); - device_func_init (DEVICE_TYPE_ANY); // activate us again - parse_image (); - media = tracks > 0; - write_log (L"IMG_EMU (%s) selected (media=%d)\n", currprefs.cdimagefile, media); - } + mountme (); } #ifdef RETROPLATFORM rp_cd_image_change (0, currprefs.cdimagefile); @@ -1125,8 +1130,13 @@ static int open_bus (int flags) if (imagechange) return 1; v = currprefs.cdimagefile[0] ? 1 : 0; - if (currprefs.cdimagefileuse) + if (v) { + if (!mountme ()) + return 0; + } + if (currprefs.cdimagefileuse) { v = 1; + } #ifdef RETROPLATFORM rp_cd_change (0, 0); rp_cd_image_change (0, currprefs.cdimagefile); diff --git a/custom.cpp b/custom.cpp index 5eb4f3dc..20910d0f 100644 --- a/custom.cpp +++ b/custom.cpp @@ -3011,7 +3011,7 @@ STATIC_INLINE uae_u16 VPOSR (void) vp = (vp >> 8) & 7; if (currprefs.cs_agnusrev >= 0) { - csbit |= currprefs.cs_agnusrev << 8; + csbit |= currprefs.cs_agnusrev << 8; } else { #ifdef AGA csbit |= (currprefs.chipset_mask & CSMASK_AGA) ? 0x2300 : 0; @@ -3250,7 +3250,7 @@ static void DMACON (int hpos, uae_u16 v) unset_special (SPCFLAG_BLTNASTY); if (changed & (DMA_MASTER | 0x0f)) - audio_hsync (hpos); + audio_state_machine (); if (changed & (DMA_MASTER | DMA_BITPLANE)) { ddf_change = vpos; @@ -3264,13 +3264,16 @@ static void DMACON (int hpos, uae_u16 v) static void MISC_handler (void) { + static bool dorecheck; int i, recheck; evt mintime; evt ct = get_cycles (); static int recursive; - if (recursive) + if (recursive) { + dorecheck = true; return; + } recursive++; eventtab[ev_misc].active = 0; recheck = 1; @@ -3282,8 +3285,10 @@ static void MISC_handler (void) if (eventtab2[i].evtime == ct) { eventtab2[i].active = 0; eventtab2[i].handler (eventtab2[i].data); - if (eventtab2[i].active) + if (dorecheck || eventtab2[i].active) { recheck = 1; + dorecheck = false; + } } else { evt eventtime = eventtab2[i].evtime - ct; if (eventtime < mintime) @@ -3343,9 +3348,9 @@ STATIC_INLINE void event2_newevent_x (int no, evt t, uae_u32 data, evfunc2 func) event2_newevent_xx (no, t * CYCLE_UNIT, data, func); } -void event2_newevent (int no, evt t) +void event2_newevent (int no, evt t, uae_u32 data) { - event2_newevent_x (no, t, 0, eventtab2[no].handler); + event2_newevent_x (no, t, data, eventtab2[no].handler); } void event2_newevent2 (evt t, uae_u32 data, evfunc2 func) { @@ -3455,15 +3460,17 @@ void INTREQ_f (uae_u16 v) void INTREQ_0 (uae_u16 v) { +#if 0 + if (!(v & 0x8000) && (v & (0x80 | 0x100 | 0x200 | 0x400))) + write_log (L"audirq clear %d\n", v); +#endif + uae_u16 old = intreq; setclr (&intreq, v); if (!(v & 0x8000) && old == intreq) return; - if (v & (0x0080 | 0x0100 | 0x0200 | 0x0400)) - audio_update_irq (v); - if (use_eventmode (v)) { event2_newevent_xx (-1, INT_PROCESSING_DELAY, intreq, send_intreq_do); } else { @@ -5266,6 +5273,100 @@ static void hsync_scandoubler (void) } } +static void events_dmal (int); +static uae_u16 dmal, dmal_hpos; + +static void dmal_emu (uae_u32 v) +{ + int hpos = current_hpos (); + if (v >= 6) { + v -= 6; + int nr = v / 2; + uaecptr pt = audio_getpt (nr, v & 1); + uae_u16 dat = chipmem_wget_indirect (pt); +#ifdef DEBUGGER + if (debug_dma) + record_dma (0xaa + nr * 16, dat, pt, hpos, vpos, DMARECORD_AUDIO); +#endif + last_custom_value1 = dat; + AUDxDAT (nr, dat, pt); + } else { + uae_u16 dat; + int w = v & 1; + uaecptr pt = disk_getpt (); + // disk_fifostatus() needed in >100% disk speed modes + if (w) { + if (disk_fifostatus () <= 0) { + dat = chipmem_wget_indirect (pt); + last_custom_value1 = dat; + DSKDAT (dat); + } + } else { + if (disk_fifostatus () >= 0) { + dat = DSKDATR (); + chipmem_wput_indirect (pt, dat); + } + } +#ifdef DEBUGGER + if (debug_dma) + record_dma (w ? 0x26 : 0x08, dat, pt, hpos, vpos, DMARECORD_DISK); +#endif + } +} + +static void dmal_func (uae_u32 v) +{ + dmal_emu (v); + events_dmal (0); +} +static void dmal_func2 (uae_u32 v) +{ + for (int i = 0; i < 6 + 8; i += 2) { + if (dmal & 3) + dmal_emu (dmal_hpos + ((dmal & 2) ? 1 : 0)); + dmal_hpos += 2; + dmal >>= 2; + } +} + +static void events_dmal (int hp) +{ + int i; + if (!dmal) + return; + if (currprefs.cpu_cycle_exact) { + for (i = 0; i < 6 + 8; i += 2) { + if (dmal & 3) + break; + hp += 2; + dmal >>= 2; + dmal_hpos += 2; + } + event2_newevent2 (hp, dmal_hpos + ((dmal & 2) ? 1 : 0), dmal_func); + dmal &= ~3; + } else { + event2_newevent2 (hp, 17, dmal_func2); + } +} + +static void events_dmal_hsync (void) +{ + if (dmal) + write_log (L"DMAL error!? %04x\n", dmal); + dmal = audio_dmal (); + dmal <<= 6; + dmal |= disk_dmal (); + if (!dmal) + return; + dmal_hpos = 0; + for (int i = 0; i < 6 + 8; i += 2) { + if (dmal & (3 << i)) { + alloc_cycle_ext (i + 7, CYCLE_MISC); + } + } + events_dmal (7); +} + static void hsync_handler (void) { int hpos = current_hpos (); @@ -5302,7 +5403,7 @@ static void hsync_handler (void) CDTV_hsync_handler (); #endif decide_blitter (-1); - DISK_hsync (maxhpos); + DISK_hsync (); #ifdef CPUEMU_12 if (currprefs.cpu_cycle_exact || currprefs.blitter_cycle_exact) { @@ -5426,7 +5527,9 @@ static void hsync_handler (void) if (currprefs.produce_sound) - audio_hsync (-1); + audio_hsync (); + + events_dmal_hsync (); #ifdef JIT if (currprefs.cachesize) { @@ -5709,6 +5812,7 @@ void customreset (int hardreset) set_cycles (0); vpos_count = vpos_count_prev = 0; + dmal = 0; init_hz (); vpos_lpen = -1; @@ -6307,12 +6411,6 @@ static void REGPARAM2 custom_bput (uaecptr addr, uae_u32 value) } else { custom_wput (addr & ~1, rval); } - if (warned < 10) { - if (M68K_GETPC < 0xe00000 || M68K_GETPC >= 0x10000000) { - write_log (L"Byte put to custom register %04X PC=%08X\n", addr, M68K_GETPC); - warned++; - } - } } static void REGPARAM2 custom_lput(uaecptr addr, uae_u32 value) diff --git a/disk.cpp b/disk.cpp index 1a904127..f5616ad4 100644 --- a/disk.cpp +++ b/disk.cpp @@ -91,9 +91,6 @@ static uae_u8 writebuffer[544 * MAX_SECTORS]; #define DSKREADY_TIME 4 #define DSKREADY_DOWN_TIME 10 -static int diskevent_flag; -static int disk_sync_cycle; - #if 0 #define MAX_DISK_WORDS_PER_LINE 50 /* depends on floppy_speed */ static uae_u32 dma_tab[MAX_DISK_WORDS_PER_LINE + 1]; @@ -101,9 +98,13 @@ static uae_u32 dma_tab[MAX_DISK_WORDS_PER_LINE + 1]; static int dskdmaen, dsklength, dsklength2, dsklen; static uae_u16 dskbytr_val; static uae_u32 dskpt; +static bool fifo_filled; +static uae_u16 fifo[3]; +static int fifo_inuse[3]; static int dma_enable, bitoffset, syncoffset; static uae_u16 word, dsksync; static unsigned long dsksync_cycles; +static int cemode = 1; #define WORDSYNC_TIME 11 /* Always carried through to the next line. */ static int disk_hpos; @@ -220,7 +221,7 @@ static void writeimageblock (struct zfile *dst, uae_u8 *sector, int offset) zfile_fwrite (sector, FS_FLOPPY_BLOCKSIZE, 1, dst); } -static void disk_checksum(uae_u8 *p, uae_u8 *c) +static void disk_checksum (uae_u8 *p, uae_u8 *c) { uae_u32 cs = 0; int i; @@ -2603,9 +2604,13 @@ static void fetchnextrevolution (drive *drv) void DISK_handler (uae_u32 data) { - int flag = diskevent_flag; + int flag = data & 255; + int disk_sync_cycle = data >> 8; + int hpos = current_hpos (); - event2_remevent(ev2_disk); + event2_remevent (ev2_disk); + if (disk_sync_cycle >= maxhpos) + return; DISK_update (disk_sync_cycle); if (flag & (DISK_REVOLUTION << 0)) fetchnextrevolution (&floppy[0]); @@ -2619,48 +2624,8 @@ void DISK_handler (uae_u32 data) INTREQ (0x8000 | 0x1000); if (flag & DISK_INDEXSYNC) cia_diskindex (); -#if 0 - { - int i; - for (i = 0; i < MAX_FLOPPY_DRIVES; i++) { - drive *drv = &floppy[i]; - if (drv->dskready_time) { - drv->dskready_time--; - if (drv->dskready_time == 0) { - drv->dskready = 1; - if (disk_debug_logging > 0) - write_log (L"%d: %d\n", i, drv->mfmpos); - } - } - } - } -#endif } -#ifdef CPUEMU_12 -extern uae_u8 cycle_line[256]; - -static void diskdma (uae_u32 pt, uae_u16 w, int write) -{ - int i, got; - - got = 0; - for (i = 7; i <= 11; i += 2) { - if (!cycle_line[i]) { - cycle_line[i] = CYCLE_MISC; - if (debug_dma) - record_dma (write ? 0x26 : 0x08, w, pt, i, vpos, DMARECORD_DISK); - got = 1; - break; - } - // if (cycle_line[i] != CYCLE_MISC) - // write_log (L"%d!?\n", cycle_line[i]); - } - // if (!got) - // write_log (L"disk dma cycle overflow!?\n"); -} -#endif - static void disk_doupdate_write (drive * drv, int floppybits) { int dr; @@ -2683,16 +2648,21 @@ static void disk_doupdate_write (drive * drv, int floppybits) floppy[dr].mfmpos %= drv->tracklen; } } - if (dmaen (DMA_DISK) && dskdmaen == 3 && dsklength > 0 && (!(adkcon &0x400) || dma_enable)) { + if (dmaen (DMA_DISK) && dskdmaen == 3 && dsklength > 0 && (!(adkcon &0x400) || dma_enable) && fifo_filled) { bitoffset++; bitoffset &= 15; if (!bitoffset) { + // fast disk modes, fill the fifo instantly + if (currprefs.floppy_speed > 100 && !fifo_inuse[0] && !fifo_inuse[1] && !fifo_inuse[2]) { + while (!fifo_inuse[2]) { + uae_u16 w = chipmem_wget_indirect (dskpt); + DSKDAT (w); + dskpt += 2; + } + } + uae_u16 w = DSKDATR (); for (dr = 0; dr < MAX_FLOPPY_DRIVES ; dr++) { drive *drv2 = &floppy[dr]; - uae_u16 w = chipmem_wget_indirect (dskpt); -#ifdef CPUEMU_12 - diskdma (dskpt, w, 1); -#endif if (drives[dr]) { drv2->bigmfmbuf[drv2->mfmpos >> 4] = w; drv2->bigmfmbuf[(drv2->mfmpos >> 4) + 1] = 0x5555; @@ -2703,17 +2673,17 @@ static void disk_doupdate_write (drive * drv, int floppybits) amax_diskwrite (w); #endif } - dskpt += 2; dsklength--; - if (dsklength == 0) { + if (dsklength <= 0) { disk_dmafinished (); - for (dr = 0; dr < MAX_FLOPPY_DRIVES ; dr++) { - drive *drv2 = &floppy[dr]; - drv2->writtento = 0; - if (drives[dr]) { - drive_write_data (drv2); - //set_steplimit (drv2); - } + for (int dr = 0; dr < MAX_FLOPPY_DRIVES ; dr++) { + drive *drv = &floppy[dr]; + drv->writtento = 0; + if (drv->motoroff) + continue; + if (selected & (1 << dr)) + continue; + drive_write_data (drv); } } } @@ -2745,80 +2715,103 @@ static void updatetrackspeed (drive *drv, int mfmpos) } } -static void disk_doupdate_predict (drive * drv, int startcycle) +static void disk_doupdate_predict (int startcycle) { - int is_sync = 0; - int firstcycle = startcycle; - uae_u32 tword = word; - int mfmpos = drv->mfmpos; - int indexhack = drv->indexhack; + int finaleventcycle = maxhpos << 8; + int finaleventflag = 0; - diskevent_flag = 0; - while (startcycle < (maxhpos << 8) && !diskevent_flag) { - int cycle = startcycle >> 8; - if (drv->tracktiming[0]) - updatetrackspeed (drv, mfmpos); - if (dskdmaen != 3) { - tword <<= 1; - if (!drive_empty (drv)) { - if (unformatted (drv)) - tword |= (uaerand() & 0x1000) ? 1 : 0; - else - tword |= getonebit (drv->bigmfmbuf, mfmpos); + for (int dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { + drive *drv = &floppy[dr]; + if (drv->motoroff) + continue; + if (drv->motoroff || !drv->trackspeed) + continue; + if (selected & (1 << dr)) + continue; + int diskevent_flag = 0; + uae_u32 tword = word; + int countcycle = startcycle; + int mfmpos = drv->mfmpos; + int indexhack = drv->indexhack; + while (countcycle < (maxhpos << 8)) { + if (drv->tracktiming[0]) + updatetrackspeed (drv, mfmpos); + if (dskdmaen != 3) { + tword <<= 1; + if (!drive_empty (drv)) { + if (unformatted (drv)) + tword |= (uaerand() & 0x1000) ? 1 : 0; + else + tword |= getonebit (drv->bigmfmbuf, mfmpos); + } + if ((tword & 0xffff) == dsksync && dsksync != 0) + diskevent_flag |= DISK_WORDSYNC; } - if ((tword & 0xffff) == dsksync && dsksync != 0) - diskevent_flag |= DISK_WORDSYNC; - } - mfmpos++; - mfmpos %= drv->tracklen; - if (mfmpos == 0) - diskevent_flag |= DISK_REVOLUTION << (drv - floppy); - if (mfmpos == drv->indexoffset) { - diskevent_flag |= DISK_INDEXSYNC; - indexhack = 0; - } - if (dskdmaen != 3 && mfmpos == drv->skipoffset) { - update_jitter (); - int skipcnt = disk_jitter; - while (skipcnt-- > 0) { - mfmpos++; - mfmpos %= drv->tracklen; - if (mfmpos == 0) - diskevent_flag |= DISK_REVOLUTION << (drv - floppy); - if (mfmpos == drv->indexoffset) { - diskevent_flag |= DISK_INDEXSYNC; - indexhack = 0; + mfmpos++; + mfmpos %= drv->tracklen; + if (mfmpos == 0) + diskevent_flag |= DISK_REVOLUTION << (drv - floppy); + if (mfmpos == drv->indexoffset) { + diskevent_flag |= DISK_INDEXSYNC; + indexhack = 0; + } + if (dskdmaen != 3 && mfmpos == drv->skipoffset) { + update_jitter (); + int skipcnt = disk_jitter; + while (skipcnt-- > 0) { + mfmpos++; + mfmpos %= drv->tracklen; + if (mfmpos == 0) + diskevent_flag |= DISK_REVOLUTION << (drv - floppy); + if (mfmpos == drv->indexoffset) { + diskevent_flag |= DISK_INDEXSYNC; + indexhack = 0; + } } } + if (diskevent_flag) + break; + countcycle += drv->trackspeed; + } + if (drv->tracktiming[0]) + updatetrackspeed (drv, drv->mfmpos); + if (diskevent_flag && countcycle < finaleventcycle) { + finaleventcycle = countcycle; + finaleventflag = diskevent_flag; } - startcycle += drv->trackspeed; } - if (drv->tracktiming[0]) - updatetrackspeed (drv, drv->mfmpos); - if (diskevent_flag) { - disk_sync_cycle = startcycle >> 8; - event2_newevent (ev2_disk, (startcycle - firstcycle) / CYCLE_UNIT); + if (finaleventflag && (finaleventcycle >> 8) < maxhpos) { + event2_newevent (ev2_disk, (finaleventcycle - startcycle) >> 8, ((finaleventcycle >> 8) << 8) | finaleventflag); } } +static bool doreaddma (void) +{ + if (dmaen (DMA_DISK) && bitoffset == 15 && dma_enable && dskdmaen == 2 && dsklength >= 0) { + if (dsklength > 0) { + // fast disk modes, just flush the fifo + if (currprefs.floppy_speed > 100 && fifo_inuse[0] && fifo_inuse[1] && fifo_inuse[2]) { + while (fifo_inuse[0]) { + uae_u16 w = DSKDATR (); + chipmem_wput_indirect (dskpt, w); + dskpt += 2; + } + } + DSKDAT (word); + dsklength--; + } + return true; + } + return false; +} + static void disk_doupdate_read_nothing (int floppybits) { int j = 0, k = 1, l = 0; while (floppybits >= get_floppy_speed()) { word <<= 1; - if (dmaen (DMA_DISK) && bitoffset == 15 && dma_enable && dskdmaen == 2 && dsklength >= 0) { - if (dsklength > 0) { - chipmem_wput_indirect (dskpt, word); -#ifdef CPUEMU_12 - diskdma (dskpt, word, 0); -#endif - dskpt += 2; - } - dsklength--; - if (dsklength <= 0) - disk_dmafinished (); - } + doreaddma (); if ((bitoffset & 7) == 7) { dskbytr_val = word & 0xff; dskbytr_val |= 0x8000; @@ -2829,31 +2822,6 @@ static void disk_doupdate_read_nothing (int floppybits) } } -static bool doreaddma (void) -{ - if (dmaen (DMA_DISK) && bitoffset == 15 && dma_enable && dskdmaen == 2 && dsklength >= 0) { - if (dsklength > 0) { - chipmem_wput_indirect (dskpt, word); -#ifdef CPUEMU_12 - diskdma (dskpt, word, 0); -#endif - dskpt += 2; - } -#if 0 - dma_tab[j++] = word; - if (j == MAX_DISK_WORDS_PER_LINE - 1) { - write_log (L"Bug: Disk DMA buffer overflow!\n"); - j--; - } -#endif - dsklength--; - if (dsklength <= 0) - disk_dmafinished (); - return true; - } - return false; -} - static void disk_doupdate_read (drive * drv, int floppybits) { int j = 0, k = 1, l = 0; @@ -2987,6 +2955,9 @@ static void DISK_start (void) { int dr; + for (int i = 0; i < 3; i++) + fifo_inuse[0] = 0; + fifo_filled = 0; for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { drive *drv = &floppy[dr]; if (!(selected & (1 << dr))) { @@ -3012,7 +2983,7 @@ static void DISK_start (void) static int linecounter; -void DISK_hsync (int tohpos) +void DISK_hsync (void) { int dr; @@ -3027,25 +2998,27 @@ void DISK_hsync (int tohpos) disk_dmafinished (); return; } - DISK_update (tohpos); + DISK_update (maxhpos); } void DISK_update (int tohpos) { int dr; - int cycles = (tohpos << 8) - disk_hpos; + int cycles; int startcycle = disk_hpos; - int didread; + cycles = (tohpos << 8) - disk_hpos; +#if 0 + if (tohpos == 228) + write_log (L"x"); + if (tohpos != maxhpos || cycles / 256 != maxhpos) + write_log (L"%d %d %d\n", tohpos, cycles / 256, disk_hpos / 256); +#endif if (cycles <= 0) return; disk_hpos += cycles; if (disk_hpos >= (maxhpos << 8)) - disk_hpos -= maxhpos << 8; - -#if 0 - dodmafetch (); -#endif + disk_hpos %= 1 << 8; for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { drive *drv = &floppy[dr]; @@ -3063,7 +3036,7 @@ void DISK_update (int tohpos) drive_fill_bigbuf (drv, 0); drv->mfmpos %= drv->tracklen; } - didread = 0; + int didaccess = 0; for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) { drive *drv = &floppy[dr]; if (drv->motoroff || !drv->trackspeed) @@ -3074,16 +3047,15 @@ void DISK_update (int tohpos) disk_doupdate_write (drv, drv->floppybitcounter); else disk_doupdate_read (drv, drv->floppybitcounter); - disk_doupdate_predict (drv, disk_hpos); drv->floppybitcounter %= drv->trackspeed; - didread = 1; - break; + didaccess = 1; } /* no floppy selected but read dma */ - if (!didread && dskdmaen == 2) { + if (!didaccess && dskdmaen == 2) { disk_doupdate_read_nothing (cycles); } + disk_doupdate_predict (disk_hpos); } void DSKLEN (uae_u16 v, int hpos) @@ -3296,24 +3268,74 @@ void DSKSYNC (int hpos, uae_u16 v) dsksync = v; } +STATIC_INLINE bool iswrite (void) +{ + return dskdmaen == 3; +} + void DSKDAT (uae_u16 v) { - static int count = 0; -#if 0 - if (dsklen == 0x8000) { - if (v == 1) - longwritemode = 1; + if (fifo_inuse[2]) { + write_log (L"DSKDAT: FIFO overflow!\n"); return; } -#endif - if (count < 5) { - count++; - write_log (L"%04X written to DSKDAT. Not good. PC=%08X", v, M68K_GETPC); - if (count == 5) - write_log (L"(further messages suppressed)"); + fifo_inuse[2] = fifo_inuse[1]; + fifo[2] = fifo[1]; + fifo_inuse[1] = fifo_inuse[0]; + fifo[1] = fifo[0]; + fifo_inuse[0] = iswrite () ? 2 : 1; + fifo[0] = v; + fifo_filled = 1; +} +uae_u16 DSKDATR (void) +{ + int i; + uae_u16 v = 0; + for (i = 2; i >= 0; i--) { + if (fifo_inuse[i]) { + fifo_inuse[i] = 0; + v = fifo[i]; + break; + } + } + if (i < 0) { + write_log (L"DSKDATR: FIFO underflow!\n"); + } else if (dskdmaen > 0 && dskdmaen < 3 && dsklength <= 0 && disk_fifostatus () < 0) { + disk_dmafinished (); + } + return v; +} +int disk_fifostatus (void) +{ + if (fifo_inuse[0] && fifo_inuse[1] && fifo_inuse[2]) + return 1; + if (!fifo_inuse[0] && !fifo_inuse[1] && !fifo_inuse[2]) + return -1; + return 0; +} - write_log (L"\n"); +uae_u16 disk_dmal (void) +{ + uae_u16 dmal = 0; + if (dskdmaen) { + if (dskdmaen == 3) { + dmal = (1 + 2) * (fifo_inuse[0] ? 1 : 0) + (4 + 8) * (fifo_inuse[1] ? 1 : 0) + (16 + 32) * (fifo_inuse[2] ? 1 : 0); + dmal ^= 63; + if (dsklength == 2) + dmal &= ~(16 + 32); + if (dsklength == 1) + dmal &= ~(16 + 32 + 4 + 8); + } else { + dmal = 16 * (fifo_inuse[0] ? 1 : 0) + 4 * (fifo_inuse[1] ? 1 : 0) + 1 * (fifo_inuse[2] ? 1 : 0); + } } + return dmal; +} +uaecptr disk_getpt (void) +{ + uaecptr pt = dskpt; + dskpt += 2; + return pt; } void DSKPTH (uae_u16 v) { diff --git a/drawing.cpp b/drawing.cpp index 266516fc..8aa77b39 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -3035,7 +3035,7 @@ void reset_drawing (void) init_aspect_maps (); - init_row_map(); + init_row_map (); last_redraw_point = 0; diff --git a/driveclick.cpp b/driveclick.cpp index 2560295b..4b177ab9 100644 --- a/driveclick.cpp +++ b/driveclick.cpp @@ -167,11 +167,7 @@ void driveclick_init (void) wave_initialized = 1; for (j = 0; j < CLICK_TRACKS; j++) drvs[i][DS_CLICK].lengths[j] = drvs[i][DS_CLICK].len; - _stprintf (tmp, L"%splugins%cfloppysounds%c", start_path_plugins, FSDB_DIR_SEPARATOR, FSDB_DIR_SEPARATOR, FSDB_DIR_SEPARATOR); - if (my_existsdir (tmp)) - _tcscpy (path2, tmp); - else - _stprintf (path2, L"%suae_data%c", start_path_data, FSDB_DIR_SEPARATOR); + get_plugin_path (path2, sizeof path2 / sizeof (TCHAR), L"floppysounds"); _stprintf (tmp, L"%sdrive_click_%s", path2, currprefs.dfxclickexternal[i]); v = loadsample (tmp, &drvs[i][DS_CLICK]); diff --git a/include/audio.h b/include/audio.h index a987a7cf..c1cd3b67 100644 --- a/include/audio.h +++ b/include/audio.h @@ -14,21 +14,24 @@ extern void aud2_handler (void); extern void aud3_handler (void); extern void AUDxDAT (int nr, uae_u16 value); +extern void AUDxDAT (int nr, uae_u16 value, uaecptr addr); extern void AUDxVOL (int nr, uae_u16 value); extern void AUDxPER (int nr, uae_u16 value); extern void AUDxLCH (int nr, uae_u16 value); extern void AUDxLCL (int nr, uae_u16 value); extern void AUDxLEN (int nr, uae_u16 value); +extern uae_u16 audio_dmal (void); +extern void audio_state_machine (void); +extern uaecptr audio_getpt (int nr, int reset); + extern int init_audio (void); extern void ahi_install (void); extern void audio_reset (void); extern void update_audio (void); -extern void schedule_audio (void); extern void audio_evhandler (void); -extern void audio_hsync (int); +extern void audio_hsync (void); extern void audio_update_adkmasks (void); -extern void audio_update_irq (uae_u16); extern void update_sound (int freq, int longframe, int linetoggle); extern void led_filter_audio (void); extern void set_audio (void); diff --git a/include/disk.h b/include/disk.h index dd4dbcb5..a6a38f9b 100644 --- a/include/disk.h +++ b/include/disk.h @@ -24,7 +24,7 @@ extern int DISK_validate_filename (const TCHAR *fname, int leave_open, bool *wrp extern void DISK_handler (uae_u32); extern void DISK_update (int hpos); extern void DISK_update_adkcon (int hpos, uae_u16 v); -extern void DISK_hsync (int hpos); +extern void DISK_hsync (void); extern void DISK_reset (void); extern int disk_getwriteprotect (const TCHAR *name); extern int disk_setwriteprotect (int num, const TCHAR *name, int protect); @@ -40,10 +40,14 @@ extern int disk_prevnext_name (TCHAR *img, int dir); extern void DSKLEN (uae_u16 v, int hpos); extern uae_u16 DSKBYTR (int hpos); -extern void DSKDAT (uae_u16); extern void DSKSYNC (int, uae_u16); extern void DSKPTL (uae_u16); extern void DSKPTH (uae_u16); +extern void DSKDAT (uae_u16); +extern uae_u16 DSKDATR (void); +extern uae_u16 disk_dmal (void); +extern uaecptr disk_getpt (void); +extern int disk_fifostatus (void); extern int disk_debug_logging; extern int disk_debug_mode; diff --git a/include/events.h b/include/events.h index 49a917e5..944980df 100644 --- a/include/events.h +++ b/include/events.h @@ -63,9 +63,9 @@ enum { extern struct ev eventtab[ev_max]; extern struct ev2 eventtab2[ev2_max]; -extern void event2_newevent(int, evt); -extern void event2_newevent2(evt, uae_u32, evfunc2); -extern void event2_remevent(int); +extern void event2_newevent (int, evt, uae_u32); +extern void event2_newevent2 (evt, uae_u32, evfunc2); +extern void event2_remevent (int); #if 0 #ifdef JIT diff --git a/include/uae.h b/include/uae.h index c6b72646..5a54aa59 100644 --- a/include/uae.h +++ b/include/uae.h @@ -25,6 +25,7 @@ extern void target_reset (void); extern void target_addtorecent (const TCHAR*, int); extern void target_run (void); extern void target_quit (void); +extern bool get_plugin_path (TCHAR *out, int size, const TCHAR *path); extern int quit_program; extern bool console_emulation; diff --git a/od-win32/dinput.cpp b/od-win32/dinput.cpp index 4b69b674..bd09f2d7 100644 --- a/od-win32/dinput.cpp +++ b/od-win32/dinput.cpp @@ -1111,7 +1111,7 @@ static void handle_rawinput_2 (RAWINPUT *raw) break; } if (num == num_keyboard) { - if (!istest && scancode == DIK_F12 && pressed) + if (!istest && scancode == DIK_F12 && pressed && isfocus ()) inputdevice_add_inputcode (AKS_ENTERGUI, 1); return; } diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index f36c1dd4..43a3e753 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -21,6 +21,7 @@ #include "statusline.h" #include "hq2x_d3d.h" #include "zfile.h" +#include "uae.h" extern int D3DEX, d3ddebug; #include @@ -685,7 +686,8 @@ static LPD3DXEFFECT psEffect_LoadEffect (const TCHAR *shaderfile, int full) DWORD compileflags = psEnabled ? 0 : D3DXSHADER_USE_LEGACY_D3DX9_31_DLL; int canusefile = 0, existsfile = 0; - _stprintf (tmp, L"%s%sfiltershaders\\direct3d\\%s", start_path_plugins, WIN32_PLUGINDIR, shaderfile); + get_plugin_path (tmp, sizeof tmp / sizeof (TCHAR), L"filtershaders\\direct3d"); + _tcscpy (tmp, shaderfile); if (!full) { struct zfile *z = zfile_fopen (tmp, L"r", 0); if (z) { @@ -1176,10 +1178,12 @@ static int createmask2texture (const TCHAR *filename) return 0; zf = NULL; for (int i = 0; i < 2; i++) { - if (i == 0) - _stprintf (tmp, L"%s%soverlays\\%s", start_path_exe, WIN32_PLUGINDIR, filename); - else + if (i == 0) { + get_plugin_path (tmp, sizeof tmp / sizeof (TCHAR), L"overlays"); _tcscpy (tmp, filename); + } else { + _tcscpy (tmp, filename); + } zf = zfile_fopen (tmp, L"rb", ZFD_NORMAL); if (zf) break; @@ -1236,7 +1240,8 @@ static int createmasktexture (const TCHAR *filename) if (filename[0] == 0) return 0; tx = NULL; - _stprintf (tmp, L"%s%smasks\\%s", start_path_exe, WIN32_PLUGINDIR, filename); + get_plugin_path (tmp, sizeof tmp / sizeof (TCHAR), L"masks"); + _tcscpy (tmp, filename); zf = zfile_fopen (tmp, L"rb", ZFD_NORMAL); if (!zf) { zf = zfile_fopen (filename, L"rb", ZFD_NORMAL); diff --git a/od-win32/fsdb_mywin32.cpp b/od-win32/fsdb_mywin32.cpp index be2c8e65..1f560756 100644 --- a/od-win32/fsdb_mywin32.cpp +++ b/od-win32/fsdb_mywin32.cpp @@ -246,6 +246,7 @@ struct my_openfile_s *my_open (const TCHAR *name, int flags) DWORD CreationDisposition = OPEN_EXISTING; DWORD FlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; DWORD attr; + wstring fname; mos = xmalloc (struct my_openfile_s, 1); if (!mos) @@ -266,7 +267,9 @@ struct my_openfile_s *my_open (const TCHAR *name, int flags) if (CreationDisposition == CREATE_ALWAYS && attr != INVALID_FILE_ATTRIBUTES && (attr & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) SetFileAttributes (name, FILE_ATTRIBUTE_NORMAL); - h = CreateFile (name, DesiredAccess, ShareMode, NULL, CreationDisposition, FlagsAndAttributes, NULL); + fname = L"\\\\?\\"; + fname += name; + h = CreateFile (fname.c_str(), DesiredAccess, ShareMode, NULL, CreationDisposition, FlagsAndAttributes, NULL); if (h == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); if (err == ERROR_ACCESS_DENIED && (DesiredAccess & GENERIC_WRITE)) { diff --git a/od-win32/resources/resource b/od-win32/resources/resource index c41a07aa..15ab7126 100644 --- a/od-win32/resources/resource +++ b/od-win32/resources/resource @@ -478,7 +478,6 @@ #define IDC_SOUND0 1238 #define IDC_SOUND1 1239 #define IDC_SOUND2 1240 -#define IDC_SOUND3 1241 #define IDC_SOUNDSTYLE 1242 #define IDC_SOUNDSTYLE0 1243 #define IDC_STEREO 1244 @@ -821,16 +820,13 @@ #define IDC_DF0QENABLE 1649 #define IDC_AVIOUTPUT_ORIGINALSIZE 1649 #define IDC_SOUNDCARD 1650 -#define IDC_CS_SOUND0 1650 #define IDC_UPBM 1650 #define IDC_DISKLISTINSERT 1650 #define IDC_DF1QENABLE 1650 #define IDC_AVIOUTPUT_ORIGINALSIZE2 1650 #define IDC_SCREENSHOT_ORIGINALSIZE 1650 #define IDC_SOUNDCARDLIST 1651 -#define IDC_CS_SOUND1 1651 #define IDC_SOUNDFREQ 1652 -#define IDC_CS_SOUND2 1652 #define IDC_SOUNDFREQTXT 1653 #define IDC_PANEL_FRAME 1653 #define IDC_SOUNDFILTERTXT 1654 diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index 5ce172cd..bcda2335 100644 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -310,9 +310,8 @@ BEGIN COMBOBOX IDC_SOUNDCARDLIST,5,3,291,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP GROUPBOX "Sound Emulation",IDC_SOUNDSETTINGS,5,20,120,85 CONTROL "Disabled",IDC_SOUND0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,13,35,101,10 - CONTROL "Disabled, but emulated",IDC_SOUND1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,48,102,10 - CONTROL "Enabled",IDC_SOUND2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,61,102,10 - CONTROL "Enabled, 100% accurate",IDC_SOUND3,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,74,101,10 + CONTROL "Disabled, but emulated",IDC_SOUND1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,53,102,10 + CONTROL "Enabled",IDC_SOUND2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,71,102,10 GROUPBOX "Volume",IDC_STATIC,132,36,164,31 CONTROL "",IDC_SOUNDVOLUME,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,137,44,105,20 EDITTEXT IDC_SOUNDVOLUME2,247,47,40,12,ES_CENTER | ES_READONLY @@ -591,7 +590,7 @@ BEGIN PUSHBUTTON "Cancel",IDCANCEL,175,65,48,15 END -IDD_CHIPSET DIALOGEX 0, 65490, 300, 229 +IDD_CHIPSET DIALOGEX 0, 65490, 300, 165 STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN @@ -622,10 +621,6 @@ BEGIN "Button",BS_AUTORADIOBUTTON | WS_TABSTOP,100,121,161,10 CONTROL "Full [] 100% collision hardware emulation. Only very few games need this option. Slowest.",IDC_COLLISION3, "Button",BS_AUTORADIOBUTTON | WS_TABSTOP,100,137,119,10 - GROUPBOX "Sound Emulation",IDC_STATIC,13,159,268,65 - CONTROL "Disabled",IDC_CS_SOUND0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,37,175,102,10 - CONTROL "Emulated",IDC_CS_SOUND1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,37,190,91,10 - CONTROL "Emulated, 100% accurate",IDC_CS_SOUND2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,37,205,95,10 CONTROL "Genlock connected [] Allow boot sequence to detect genlock. Genlock is not emulated.",IDC_GENLOCK, "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,179,59,100,10 COMBOBOX IDC_CS_EXT,100,80,49,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP @@ -1205,6 +1200,10 @@ BEGIN BEGIN END + IDD_SOUND, DIALOG + BEGIN + END + IDD_LOADSAVE, DIALOG BEGIN END diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 2b8db82a..84927a84 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -2074,7 +2074,7 @@ static void strip_slashes (TCHAR *p) while (_tcslen (p) > 0 && (p[_tcslen (p) - 1] == '\\' || p[_tcslen (p) - 1] == '/')) p[_tcslen (p) - 1] = 0; } -static void fixtrailing(TCHAR *p) +static void fixtrailing (TCHAR *p) { if (_tcslen(p) == 0) return; @@ -3783,6 +3783,68 @@ void create_afnewdir (int remove) } } +static bool isdir (const TCHAR *path) +{ + DWORD a = GetFileAttributes (path); + if (a == INVALID_FILE_ATTRIBUTES) + return false; + if (a & FILE_ATTRIBUTE_DIRECTORY) + return true; + return false; +} + +bool get_plugin_path (TCHAR *out, int len, const TCHAR *path) +{ + TCHAR tmp[MAX_DPATH]; + _tcscpy (tmp, start_path_plugins); + if (path != NULL) + _tcscat (tmp, path); + if (isdir (tmp)) { + _tcscpy (out, tmp); + fixtrailing (out); + return true; + } + if (!_tcsicmp (path, L"floppysounds")) { + _tcscpy (tmp, start_path_data); + _tcscpy (tmp, L"uae_data"); + if (isdir (tmp)) { + _tcscpy (out, tmp); + fixtrailing (out); + return true; + } + _tcscpy (tmp, start_path_exe); + _tcscpy (tmp, L"uae_data"); + if (isdir (tmp)) { + _tcscpy (out, tmp); + fixtrailing (out); + return true; + } + } + _tcscpy (tmp, start_path_data); + _tcscpy (tmp, WIN32_PLUGINDIR); + if (path != NULL) + _tcscat (tmp, path); + if (isdir (tmp)) { + _tcscpy (out, tmp); + fixtrailing (out); + return true; + } + _tcscpy (tmp, start_path_exe); + _tcscpy (tmp, WIN32_PLUGINDIR); + if (path != NULL) + _tcscat (tmp, path); + if (isdir (tmp)) { + _tcscpy (out, tmp); + fixtrailing (out); + return true; + } + _tcscpy (out, start_path_plugins); + if (path != NULL) + _tcscat (tmp, path); + fixtrailing (out); + return false; +} + static void getstartpaths (void) { TCHAR *posn, *p; @@ -3977,9 +4039,17 @@ static void getstartpaths (void) _tcscpy (start_path_data, tmp); SetCurrentDirectory (start_path_data); - v = GetFileAttributes (start_path_plugins); - if (v == INVALID_FILE_ATTRIBUTES || !(v & FILE_ATTRIBUTE_DIRECTORY) || start_data == 0 || start_data == -2) { - _tcscpy (start_path_plugins, start_path_exe); + if (!start_path_plugins[0]) { + _tcscpy (start_path_plugins, start_path_data); + _tcscat (start_path_plugins, WIN32_PLUGINDIR); + v = GetFileAttributes (start_path_plugins); + if (v == INVALID_FILE_ATTRIBUTES || !(v & FILE_ATTRIBUTE_DIRECTORY)) + _tcscpy (start_path_plugins, start_path_data); + } else { + v = GetFileAttributes (start_path_plugins); + if (v == INVALID_FILE_ATTRIBUTES || !(v & FILE_ATTRIBUTE_DIRECTORY) || start_data == 0 || start_data == -2) { + _tcscpy (start_path_plugins, start_path_exe); + } } fixtrailing (start_path_plugins); GetFullPathName (start_path_plugins, sizeof tmp / sizeof (TCHAR), tmp, NULL); @@ -4889,7 +4959,7 @@ HMODULE WIN32_LoadLibrary_2 (const TCHAR *name, int expand) if (!newname) return NULL; for (round = 0; round < 6; round++) { - TCHAR *s; + TCHAR s[MAX_DPATH]; _tcscpy (newname, name); #ifdef CPU_64_BIT switch(round) @@ -4923,24 +4993,12 @@ HMODULE WIN32_LoadLibrary_2 (const TCHAR *name, int expand) break; } #endif - s = xmalloc (TCHAR, _tcslen (start_path_plugins) + _tcslen (WIN32_PLUGINDIR) + _tcslen (newname) + 1); - if (s) { - _stprintf (s, L"%s%s%s", start_path_plugins, WIN32_PLUGINDIR, newname); - m = LoadLibrary (s); - LLError (m, s); - if (m) { - xfree (s); - goto end; - } - _stprintf (s, L"%s%s", start_path_plugins, newname); - m = LoadLibrary (s); - LLError (m ,s); - if (m) { - xfree (s); - goto end; - } - xfree (s); - } + get_plugin_path (s, sizeof s / sizeof (TCHAR), NULL); + _tcscat (s, newname); + m = LoadLibrary (s); + LLError (m ,s); + if (m) + goto end; m = LoadLibrary (newname); LLError (m, newname); if (m) diff --git a/od-win32/win32.h b/od-win32/win32.h index 0f9e2e07..40c877b2 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -18,9 +18,9 @@ #define WINUAEPUBLICBETA 1 #define LANG_DLL 1 -#define WINUAEBETA L"0" -#define WINUAEDATE MAKEBD(2010, 7, 1) -#define WINUAEEXTRA L"TEST" +#define WINUAEBETA L"1" +#define WINUAEDATE MAKEBD(2010, 7, 6) +#define WINUAEEXTRA L"" #define WINUAEREV L"" #define IHF_WINDOWHIDDEN 6 diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 00e2446b..03ff29e5 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -147,6 +147,7 @@ void WIN32GUI_LoadUIString (DWORD id, TCHAR *string, DWORD dwStringLen) static int quickstart_model = 0, quickstart_conf = 0, quickstart_compa = 1; static int quickstart_floppy = 1, quickstart_cd = 0, quickstart_ntsc = 0; static int quickstart_cdtype = 0; +static TCHAR quickstart_cddrive[16]; static int quickstart_ok, quickstart_ok_floppy; static void addfloppytype (HWND hDlg, int n); static void addfloppyhistory (HWND hDlg); @@ -1920,6 +1921,10 @@ static void selectdisk (struct uae_prefs *prefs, HWND hDlg, int num, int id, TCH { SetDlgItemText (hDlg, id, full_path); if (iscd (num)) { + if (quickstart_cddrive[0]) { + quickstart_cdtype = 0; + quickstart_cddrive[0] = 0; + } _tcscpy (prefs->cdimagefile, full_path); DISK_history_add (full_path, -1, HISTORY_CD, 0); } else { @@ -4763,6 +4768,8 @@ static void init_quickstartdlg (HWND hDlg) regqueryint (NULL, L"QuickStartCompatibility", &quickstart_compa); regqueryint (NULL, L"QuickStartFloppies", &quickstart_floppy); regqueryint (NULL, L"QuickStartCDType", &quickstart_cdtype); + int size = sizeof quickstart_cddrive / sizeof (TCHAR); + regquerystr (NULL, L"QuickStartCDDrive", quickstart_cddrive, &size); regqueryint (NULL, L"QuickStartNTSC", &quickstart_ntsc); if (quickstart) { workprefs.df[0][0] = 0; @@ -5004,6 +5011,23 @@ static INT_PTR CALLBACK QuickstartDlgProc (HWND hDlg, UINT msg, WPARAM wParam, L if (HIWORD (wParam) == CBN_SELCHANGE || HIWORD (wParam) == CBN_KILLFOCUS) { switch (LOWORD (wParam)) { + case IDC_CD0Q_TYPE: + val = SendDlgItemMessage (hDlg, IDC_CD0Q_TYPE, CB_GETCURSEL, 0, 0); + if (val != CB_ERR) { + quickstart_cdtype = val; + if (quickstart_cdtype >= 2) { + int len = sizeof quickstart_cddrive / sizeof (TCHAR); + quickstart_cdtype = 2; + SendDlgItemMessage (hDlg, IDC_CD0Q_TYPE, WM_GETTEXT, (WPARAM)len, (LPARAM)quickstart_cddrive); + _tcscpy (workprefs.cdimagefile, quickstart_cddrive); + } else { + workprefs.cdimagefile[0] = 0; + quickstart_cddrive[0] = 0; + } + addfloppytype (hDlg, 1); + addfloppyhistory (hDlg); + } + break; case IDC_QUICKSTART_MODEL: val = SendDlgItemMessage (hDlg, IDC_QUICKSTART_MODEL, CB_GETCURSEL, 0, 0L); if (val != CB_ERR) { @@ -5849,7 +5873,6 @@ static void values_to_chipsetdlg (HWND hDlg) TCHAR Nth[MAX_NTH_LENGTH]; TCHAR *blah[1] = { Nth }; TCHAR *string = NULL; - int which_button; switch(workprefs.chipset_mask) { @@ -5875,12 +5898,6 @@ static void values_to_chipsetdlg (HWND hDlg) CheckDlgButton (hDlg, IDC_BLITIMM, workprefs.immediate_blits); CheckRadioButton (hDlg, IDC_COLLISION0, IDC_COLLISION3, IDC_COLLISION0 + workprefs.collision_level); CheckDlgButton (hDlg, IDC_CYCLEEXACT, workprefs.cpu_cycle_exact); - switch (workprefs.produce_sound) { - case 0: which_button = IDC_CS_SOUND0; break; - case 1: case 2: which_button = IDC_CS_SOUND1; break; - default: which_button = IDC_CS_SOUND2; break; - } - CheckRadioButton (hDlg, IDC_CS_SOUND0, IDC_CS_SOUND2, which_button); SendDlgItemMessage (hDlg, IDC_CS_EXT, CB_RESETCONTENT, 0, 0); SendDlgItemMessage (hDlg, IDC_CS_EXT, CB_ADDSTRING, 0, (LPARAM)L""); SendDlgItemMessage (hDlg, IDC_CS_EXT, CB_ADDSTRING, 0, (LPARAM)L"Generic"); @@ -5902,7 +5919,7 @@ static void values_to_chipsetdlg (HWND hDlg) static void values_from_chipsetdlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { BOOL success = FALSE; - int nn, snd; + int nn; bool n; workprefs.genlock = ischecked (hDlg, IDC_GENLOCK); @@ -5932,16 +5949,6 @@ static void values_from_chipsetdlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l if (workprefs.ntscmode != n) { workprefs.ntscmode = n; } - snd = ischecked (hDlg, IDC_CS_SOUND0) ? 0 - : ischecked (hDlg, IDC_CS_SOUND1) ? 2 : 3; - if (snd == 0 || snd == 3) { - workprefs.produce_sound = snd; - } else if (snd == 2) { - if (workprefs.produce_sound == 0) - workprefs.produce_sound = 2; - else if (workprefs.produce_sound >= 2) - workprefs.produce_sound = 2; - } nn = SendDlgItemMessage (hDlg, IDC_CS_EXT, CB_GETCURSEL, 0, 0); if (nn != CB_ERR) { workprefs.cs_compatible = nn; @@ -7910,14 +7917,12 @@ static void sound_loaddrivesamples (void) free (drivesounds); p = drivesounds = 0; - _stprintf (dirname, L"%s\\%sfloppysounds\\*.wav", start_path_plugins, WIN32_PLUGINDIR); + + get_plugin_path (dirname, sizeof dirname / sizeof (TCHAR), L"floppysounds"); + _tcscat (dirname, L"*.wav"); h = FindFirstFile (dirname, &fd); - if (h == INVALID_HANDLE_VALUE) { - _stprintf (dirname, L"%s\\uae_data\\*.wav", start_path_plugins); - h = FindFirstFile (dirname, &fd); - if (h == INVALID_HANDLE_VALUE) - return; - } + if (h == INVALID_HANDLE_VALUE) + return; for (;;) { if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { TCHAR *name = fd.cFileName; @@ -8080,10 +8085,9 @@ static void values_to_sounddlg (HWND hDlg) { case 0: which_button = IDC_SOUND0; break; case 1: which_button = IDC_SOUND1; break; - case 2: which_button = IDC_SOUND2; break; - case 3: which_button = IDC_SOUND3; break; + case 2: case 3: which_button = IDC_SOUND2; break; } - CheckRadioButton (hDlg, IDC_SOUND0, IDC_SOUND3, which_button); + CheckRadioButton (hDlg, IDC_SOUND0, IDC_SOUND2, which_button); CheckDlgButton (hDlg, IDC_SOUND_AUTO, workprefs.sound_auto); @@ -8165,8 +8169,7 @@ static void values_from_sounddlg (HWND hDlg) workprefs.sound_freq = 96000; workprefs.produce_sound = (ischecked (hDlg, IDC_SOUND0) ? 0 - : ischecked (hDlg, IDC_SOUND1) ? 1 - : ischecked (hDlg, IDC_SOUND2) ? 2 : 3); + : ischecked (hDlg, IDC_SOUND1) ? 1 : 3); workprefs.sound_auto = ischecked (hDlg, IDC_SOUND_AUTO); @@ -9439,11 +9442,28 @@ static void addfloppytype (HWND hDlg, int n) SendDlgItemMessage (hDlg, IDC_CD0Q_TYPE, CB_ADDSTRING, 0, (LPARAM)tmp); WIN32GUI_LoadUIString (IDS_QS_CD_IMAGE, tmp, sizeof tmp / sizeof (TCHAR)); SendDlgItemMessage (hDlg, IDC_CD0Q_TYPE, CB_ADDSTRING, 0, (LPARAM)tmp); + quickstart_cdtype = 0; if (workprefs.cdimagefile[0]) quickstart_cdtype = 1; + int cnt = 2; + for (int drive = 'C'; drive <= 'Z'; ++drive) { + TCHAR vol[100]; + _stprintf (vol, L"%c:\\", drive); + int drivetype = GetDriveType (vol); + if (drivetype == DRIVE_CDROM) { + SendDlgItemMessage (hDlg, IDC_CD0Q_TYPE, CB_ADDSTRING, 0, (LPARAM)vol); + if (!_tcsicmp (vol, quickstart_cddrive)) { + quickstart_cdtype = cnt; + _tcscpy (workprefs.cdimagefile, vol); + } + cnt++; + } + } SendDlgItemMessage (hDlg, IDC_CD0Q_TYPE, CB_SETCURSEL, quickstart_cdtype, 0); hide (hDlg, IDC_CD0Q_TYPE, 0); text = workprefs.cdimagefile; + regsetstr (NULL, L"QuickStartCDDrive", quickstart_cdtype >= 2 ? quickstart_cddrive : L""); + regsetint (NULL, L"QuickStartCDType", quickstart_cdtype >= 2 ? 2 : quickstart_cdtype); } else { hide (hDlg, f_wp, 0); hide (hDlg, f_wptext, 0); @@ -9571,6 +9591,10 @@ static void getfloppyname (HWND hDlg, int n) disk_insert (n, tmp); _tcscpy (workprefs.df[n], tmp); } else { + if (quickstart_cddrive[0]) { + quickstart_cdtype = 0; + quickstart_cddrive[0] = 0; + } _tcscpy (workprefs.cdimagefile, tmp); } } @@ -12060,7 +12084,8 @@ static void values_to_hw3ddlg (HWND hDlg) HANDLE h; WIN32_FIND_DATA wfd; TCHAR tmp[MAX_DPATH]; - _stprintf (tmp, L"%s%sfiltershaders\\direct3d\\*.fx", start_path_plugins, WIN32_PLUGINDIR); + get_plugin_path (tmp, sizeof tmp / sizeof (TCHAR), L"filtershaders\\direct3d"); + _tcscat (tmp, L"*.fx"); h = FindFirstFile (tmp, &wfd); while (h != INVALID_HANDLE_VALUE) { if (wfd.cFileName[0] != '_') { @@ -12087,7 +12112,8 @@ static void values_to_hw3ddlg (HWND hDlg) HANDLE h; WIN32_FIND_DATA wfd; TCHAR tmp[MAX_DPATH]; - _stprintf (tmp, L"%s%s%s\\*.*", start_path_plugins, WIN32_PLUGINDIR, overlaytype == 0 ? L"overlays" : L"masks"); + get_plugin_path (tmp, sizeof tmp / sizeof (TCHAR), overlaytype == 0 ? L"overlays" : L"masks"); + _tcscat (tmp, L"*.*"); h = FindFirstFile (tmp, &wfd); i = 0; j = 1; while (h != INVALID_HANDLE_VALUE) { diff --git a/od-win32/winuae_msvc10/winuae_msvc.sln b/od-win32/winuae_msvc10/winuae_msvc.sln index 3a6e7f0e..d00f879a 100644 --- a/od-win32/winuae_msvc10/winuae_msvc.sln +++ b/od-win32/winuae_msvc10/winuae_msvc.sln @@ -133,10 +133,8 @@ Global {8627DA33-98D1-4F60-B404-ECCEE0EE7BF9}.Release|Win32.ActiveCfg = Release|Win32 {8627DA33-98D1-4F60-B404-ECCEE0EE7BF9}.Release|x64.ActiveCfg = Release|x64 {98BA115B-829F-4085-9729-ABD0D779A60A}.Debug|Win32.ActiveCfg = Debug|Win32 - {98BA115B-829F-4085-9729-ABD0D779A60A}.Debug|Win32.Build.0 = Debug|Win32 {98BA115B-829F-4085-9729-ABD0D779A60A}.Debug|x64.ActiveCfg = Debug|Win32 {98BA115B-829F-4085-9729-ABD0D779A60A}.FullRelease|Win32.ActiveCfg = Release|Win32 - {98BA115B-829F-4085-9729-ABD0D779A60A}.FullRelease|Win32.Build.0 = Release|Win32 {98BA115B-829F-4085-9729-ABD0D779A60A}.FullRelease|x64.ActiveCfg = Release|Win32 {98BA115B-829F-4085-9729-ABD0D779A60A}.Release|Win32.ActiveCfg = Release|Win32 {98BA115B-829F-4085-9729-ABD0D779A60A}.Release|x64.ActiveCfg = Release|x64 diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 4bc31862..472c5aae 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,18 +1,47 @@ +Beta 1: + - fixed Z3/RTG RAM leaking when restarting - D3D scanlines can be (finally) enabled on the fly -- blank right border after hsync position instead of filling it with border color that goes - far outside of displayable area +- blank right border after approximate hsync position instead of filling it with border + color that extends far outside of displayable area - ECS Agnus bitplane DMA state machine update, state machine advances on OCS when DDFSTRT matches hpos and display window is open. ECS only requires DDFSTRT match. (yaqube) - triple/double/single buffer option was never saved to configuration file - autovsync was broken -- "old" overlays are now masks (plugins\masks), "new" overlays are in plugins\overlays. +- "old" overlays are now masks in plugins\masks, "new" overlays are in plugins\overlays. (rename overlays -> masks and create new overlays directory) - both overlays and masks can be selected using GUI (overlay position can be only modified by editing configuration file) - added Automatic center option to autoscale select menu, centers image using autoscale parameters +- audio state machine emulation rewrite, now it is fully cycle-exact, including + correct DMAL DMA request line delays. (DMAL logic examined by yaqube, I was too slow and lazy..) +- disk emulation DMA accesses are now fully cycle-exact, emulates DMAL and Paula 3-word FIFO +- fixed ancient bug in disk emulation that emulated remaining cycles in current line twice + when disk event triggered (index, word sync), basically made disk rotate twice the speed + for about 20 or so bits of data from disk +- above disk events didn't work correctly if multiple drives were selected at the same time + (very rare situation) +- added CDROM drives to quickstart CD32/CDTV "autodetect" select menu (works on the fly too) +- cdimage0=:\ at startup didn't work (only worked if changed on the fly) +- rawkeyboard hardcoded F12 check ignored focus +- drive sound emulation crashed if specific sound files were missing +- non-accurate sound enabled -option removed, difference compared to 100% accurate was + practically non-existing, also now totally useless chipset sound options removed, + disabled but emulated is now also 100% accurate +- files inside plugins-directory will be checked from 3 locations (until found): + plugin_path, data_path and exe_path. (fixes some path issues introduced in 2.2) + +In cycle-exact mode DMA fetches happen in exactly correct positions (need more CPU power), +in non-cycle-exact modes all DMA fetches use audio channel 0 position (faster, less timing +events needed). Complete custom chipset should be fully cycle exact now (in theory at least) + +All "too fast cpu" audio hacks removed except audio.device AUDxDAT write with AUDxPER=8 +and then waiting for interrupt, in JIT modes interrupt code may run fast enough to enable +DMA before audio state machine has returned back to idle state. This hack forces AUDxDAT +writes with AUDxPER less than 10 to finish immediately. + 2.2.0 Final -- 2.47.3