#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;
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;
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;
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++)
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;
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)
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;
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)
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 ();
for (i = 0; i < 4; i++) {
if (audio_channel[i].evtime == 0)
- audio_handler (i);
+ audio_state_channel (i, true);
}
}
end:
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)
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;
events_schedule ();
}
}
-
+#ifdef TEST_AUDIO
+ cdp->per_original = v;
+#endif
cdp->per = per;
#ifdef DEBUG_AUDIO
if (debugchannel (nr))
{
struct audio_channel_data *cdp = audio_channel + nr;
int v2 = v & 64 ? 63 : v & 63;
-
audio_activate ();
update_audio ();
cdp->vol = v2;
#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;
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 ();
acd->lc = restore_u32 ();
acd->pt = restore_u32 ();
acd->evtime = restore_u32 ();
+ last_cycles = get_cycles () - 1;
return src;
}
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;
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. */
}
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;
}
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)
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);
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;
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);
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);
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;
unset_special (SPCFLAG_BLTNASTY);
if (changed & (DMA_MASTER | 0x0f))
- audio_hsync (hpos);
+ audio_state_machine ();
if (changed & (DMA_MASTER | DMA_BITPLANE)) {
ddf_change = vpos;
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;
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)
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)
{
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 {
}
}
+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 ();
CDTV_hsync_handler ();
#endif
decide_blitter (-1);
- DISK_hsync (maxhpos);
+ DISK_hsync ();
#ifdef CPUEMU_12
if (currprefs.cpu_cycle_exact || currprefs.blitter_cycle_exact) {
if (currprefs.produce_sound)
- audio_hsync (-1);
+ audio_hsync ();
+
+ events_dmal_hsync ();
#ifdef JIT
if (currprefs.cachesize) {
set_cycles (0);
vpos_count = vpos_count_prev = 0;
+ dmal = 0;
init_hz ();
vpos_lpen = -1;
} 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)
#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];
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;
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;
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]);
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;
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;
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);
}
}
}
}
}
-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;
}
}
-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;
{
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))) {
static int linecounter;
-void DISK_hsync (int tohpos)
+void DISK_hsync (void)
{
int dr;
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];
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)
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)
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)
{
init_aspect_maps ();
- init_row_map();
+ init_row_map ();
last_redraw_point = 0;
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]);
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);
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);
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;
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
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;
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;
}
#include "statusline.h"
#include "hq2x_d3d.h"
#include "zfile.h"
+#include "uae.h"
extern int D3DEX, d3ddebug;
#include <d3d9.h>
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) {
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;
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);
DWORD CreationDisposition = OPEN_EXISTING;
DWORD FlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
DWORD attr;
+ wstring fname;
mos = xmalloc (struct my_openfile_s, 1);
if (!mos)
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)) {
#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
#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
COMBOBOX IDC_SOUNDCARDLIST,5,3,291,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
GROUPBOX "Sound Emulation",IDC_SOUNDSETTINGS,5,20,120,85\r
CONTROL "Disabled",IDC_SOUND0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,13,35,101,10\r
- CONTROL "Disabled, but emulated",IDC_SOUND1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,48,102,10\r
- CONTROL "Enabled",IDC_SOUND2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,61,102,10\r
- CONTROL "Enabled, 100% accurate",IDC_SOUND3,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,74,101,10\r
+ CONTROL "Disabled, but emulated",IDC_SOUND1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,53,102,10\r
+ CONTROL "Enabled",IDC_SOUND2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,71,102,10\r
GROUPBOX "Volume",IDC_STATIC,132,36,164,31\r
CONTROL "",IDC_SOUNDVOLUME,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,137,44,105,20\r
EDITTEXT IDC_SOUNDVOLUME2,247,47,40,12,ES_CENTER | ES_READONLY\r
PUSHBUTTON "Cancel",IDCANCEL,175,65,48,15\r
END\r
\r
-IDD_CHIPSET DIALOGEX 0, 65490, 300, 229\r
+IDD_CHIPSET DIALOGEX 0, 65490, 300, 165\r
STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD\r
FONT 8, "MS Sans Serif", 0, 0, 0x0\r
BEGIN\r
"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,100,121,161,10\r
CONTROL "Full [] 100% collision hardware emulation. Only very few games need this option. Slowest.",IDC_COLLISION3,\r
"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,100,137,119,10\r
- GROUPBOX "Sound Emulation",IDC_STATIC,13,159,268,65\r
- CONTROL "Disabled",IDC_CS_SOUND0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,37,175,102,10\r
- CONTROL "Emulated",IDC_CS_SOUND1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,37,190,91,10\r
- CONTROL "Emulated, 100% accurate",IDC_CS_SOUND2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,37,205,95,10\r
CONTROL "Genlock connected [] Allow boot sequence to detect genlock. Genlock is not emulated.",IDC_GENLOCK,\r
"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,179,59,100,10\r
COMBOBOX IDC_CS_EXT,100,80,49,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
BEGIN\r
END\r
\r
+ IDD_SOUND, DIALOG\r
+ BEGIN\r
+ END\r
+\r
IDD_LOADSAVE, DIALOG\r
BEGIN\r
END\r
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;
}
}
+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;
_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);
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)
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)
#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
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);
{
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 {
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;
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) {
TCHAR Nth[MAX_NTH_LENGTH];
TCHAR *blah[1] = { Nth };
TCHAR *string = NULL;
- int which_button;
switch(workprefs.chipset_mask)
{
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");
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);
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;
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;
{
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);
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);
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);
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);
}
}
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] != '_') {
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) {
{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
+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=<drive letter>:\ 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