From 07f04fc7343bd12714d32d6af64a321db4107c59 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Thu, 6 Aug 2009 18:59:22 +0300 Subject: [PATCH] imported winuaesrc1620b5.zip --- audio.c | 16 +- blitter.c | 9 +- custom.c | 281 +++++++++++++++--------- debug.c | 6 +- disk.c | 4 +- include/debug.h | 1 + include/memory.h | 1 + include/newcpu.h | 1 + memory.c | 13 +- ncr_scsi.c | 2 +- newcpu.c | 41 +++- od-win32/ahidsound_dsonly.c | 6 +- od-win32/hardfile_win32.c | 2 +- od-win32/picasso96_win.c | 2 +- od-win32/serial_win32.c | 4 +- od-win32/sounddep/sound.c | 18 ++ od-win32/win32.h | 4 +- od-win32/winuae_msvc/winuae_msvc.vcproj | 12 +- od-win32/winuaechangelog.txt | 15 ++ 19 files changed, 288 insertions(+), 150 deletions(-) diff --git a/audio.c b/audio.c index aa0eb5d6..10f0107b 100644 --- a/audio.c +++ b/audio.c @@ -1276,7 +1276,7 @@ void audio_reset (void) free_ahi_v2 (); #endif reset_sound (); - memset(sound_filter_state, 0, sizeof sound_filter_state); + memset (sound_filter_state, 0, sizeof sound_filter_state); if (savestate_state != STATE_RESTORE) { for (i = 0; i < 4; i++) { cdp = &audio_channel[i]; @@ -1326,7 +1326,7 @@ STATIC_INLINE int sound_prefs_changed (void) #ifndef M_PI #define M_PI 3.14159265358979323846 #endif -static float rc_calculate_a0(int sample_rate, int cutoff_freq) +static float rc_calculate_a0 (int sample_rate, int cutoff_freq) { float omega; /* The BLT correction formula below blows up if the cutoff is above nyquist. */ @@ -1337,7 +1337,7 @@ static float rc_calculate_a0(int sample_rate, int cutoff_freq) /* Compensate for the bilinear transformation. This allows us to specify the * stop frequency more exactly, but the filter becomes less steep further * from stopband. */ - omega = tan(omega / 2) * 2; + omega = tan (omega / 2) * 2; return 1 / (1 + 1 / omega); } @@ -1398,9 +1398,9 @@ void set_audio (void) write_log (L"Sound is not supported.\n"); } else { write_log (L"Sorry, can't initialize sound.\n"); - currprefs.produce_sound = 0; + currprefs.produce_sound = 1; /* So we don't do this every frame */ - changed_prefs.produce_sound = 0; + changed_prefs.produce_sound = 1; } } } @@ -1545,6 +1545,7 @@ void update_audio (void) if (rounded == best_evtime) { /* Before the following addition, next_sample_evtime is in range [-0.5, 0.5) */ next_sample_evtime += scaled_sample_evtime; +#if 0 doublesample = 0; if (--samplecounter <= 0) { samplecounter = currprefs.sound_freq / 1000; @@ -1558,11 +1559,14 @@ void update_audio (void) extrasamples++; } } - (*sample_handler) (); +#endif + (*sample_handler) (); +#if 0 if (outputsample == 0) outputsample = -1; else if (outputsample < 0) outputsample = 1; +#endif } } diff --git a/blitter.c b/blitter.c index 19961cab..61800a7c 100644 --- a/blitter.c +++ b/blitter.c @@ -310,6 +310,7 @@ static void blitter_done (int hpos) STATIC_INLINE chipmem_agnus_wput2 (uaecptr addr, uae_u32 w) { #ifndef BLITTER_DEBUG_NO_D + last_custom_value = w; chipmem_agnus_wput (addr, w); #endif } @@ -520,6 +521,7 @@ STATIC_INLINE void blitter_read (void) if (!dmaen (DMA_BLITTER)) return; blt_info.bltcdat = chipmem_bank.wget (bltcpt); + last_custom_value = blt_info.bltcdat; } bltstate = BLT_work; } @@ -532,6 +534,7 @@ STATIC_INLINE void blitter_write (void) if (bltcon0 & 0x200) { if (!dmaen (DMA_BLITTER)) return; + last_custom_value = blt_info.bltddat; chipmem_bank.wput (bltdpt, blt_info.bltddat); } bltstate = BLT_next; @@ -816,6 +819,7 @@ STATIC_INLINE int blitter_doddma (int hpos) if (wd) { alloc_cycle_ext (hpos, CYCLE_BLITTER); record_dma_blit (0x00, d, bltdpt, hpos); + last_custom_value = d; chipmem_agnus_wput2 (bltdpt, d); bltdpt += blit_add; blitter_hcounter2++; @@ -842,12 +846,14 @@ STATIC_INLINE void blitter_dodma (int ch, int hpos) { case 1: blt_info.bltadat = dat = chipmem_agnus_wget (bltapt); + last_custom_value = blt_info.bltadat; addr = bltapt; bltapt += blit_add; reg = 0x74; break; case 2: blt_info.bltbdat = dat = chipmem_agnus_wget (bltbpt); + last_custom_value = blt_info.bltbdat; addr = bltbpt; bltbpt += blit_add; if (blitdesc) @@ -859,6 +865,7 @@ STATIC_INLINE void blitter_dodma (int ch, int hpos) break; case 3: blt_info.bltcdat = dat = chipmem_agnus_wget (bltcpt); + last_custom_value = blt_info.bltcdat; addr = bltcpt; bltcpt += blit_add; reg = 0x70; @@ -1118,7 +1125,7 @@ static void blit_bltset (int con) blit_frozen = 1; } else if (!iseo && isen) { #ifdef BLITTER_DEBUG_NOWAIT - write_log (L"BLITTER: on the fly %d (%d) -> %d (%d) switch\n", oldch, iseo, blit_ch, isen); + write_log (L"BLITTER: on the fly %d (%d) -> %d (%d) switch\n", original_ch, iseo, blit_ch, isen); #endif } } diff --git a/custom.c b/custom.c index 9b9a2630..ea8c2ad4 100644 --- a/custom.c +++ b/custom.c @@ -848,6 +848,26 @@ STATIC_INLINE int isocs7planes (void) return !(currprefs.chipset_mask & CSMASK_AGA) && bplcon0_res == 0 && bplcon0_planes == 7; } +int is_bitplane_dma (int hpos) +{ + if (fetch_state == fetch_not_started || hpos < plfstrt) + return 0; + if ((plf_state == plf_end && hpos >= thisline_decision.plfright) + || hpos >= estimated_last_fetch_cycle) + return 0; + return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask]; +} + +STATIC_INLINE int is_bitplane_dma_inline (int hpos) +{ + if (fetch_state == fetch_not_started || hpos < plfstrt) + return 0; + if ((plf_state == plf_end && hpos >= thisline_decision.plfright) + || hpos >= estimated_last_fetch_cycle) + return 0; + return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask]; +} + static void update_denise (int hpos) { toscr_res = GET_RES_DENISE (bplcon0d); @@ -861,8 +881,26 @@ static void update_denise (int hpos) } } -static void expand_fmodes (void) +static int bpldmasetuphpos; +static int bpldmasetupphase; + +/* set currently active Agnus bitplane DMA sequence */ +static void setup_fmodes (int hpos) { + switch (fmode & 3) + { + case 0: + fetchmode = 0; + break; + case 1: + case 2: + fetchmode = 1; + break; + case 3: + fetchmode = 2; + break; + } + badmode = GET_RES_AGNUS (bplcon0) != GET_RES_DENISE (bplcon0); bplcon0_res = GET_RES_AGNUS (bplcon0); bplcon0_planes = GET_PLANES (bplcon0); bplcon0_planes_limit = GET_PLANES_LIMIT (bplcon0); @@ -874,7 +912,67 @@ static void expand_fmodes (void) fm_maxplane_shift = fm_maxplanes[fetchmode * 4 + bplcon0_res]; fm_maxplane = 1 << fm_maxplane_shift; fetch_modulo_cycle = fetchunit - fetchstart; + if (is_bitplane_dma (hpos - 1)) + cycle_line[hpos - 1] = 1; curr_diagram = cycle_diagram_table[fetchmode][bplcon0_res][bplcon0_planes_limit]; + estimate_last_fetch_cycle (hpos); + if (bpldmasetuphpos >= 0 && debug_dma) + record_dma_event (DMA_EVENT_BPLFETCHUPDATE, hpos, vpos); + bpldmasetuphpos = -1; + bpldmasetupphase = 0; + ddf_change = vpos; +} + +static void BPLCON0_Denise (int hpos, uae_u16 v); + +// writing to BPLCON0 adds 4 cycle delay before Agnus bitplane DMA sequence changes +// (Note that Denise sees the change after 1 cycle) +// AGA either needs 1 extra cycle or only in specific situations (perhaps only +// when first plane in block is active, which is not possible in OCS/ECS) +#define BPLCON_AGNUS_DELAY (4 + ((currprefs.chipset_mask & CSMASK_AGA) ? 1 : 0)) +#define BPLCON_DENISE_DELAY 1 + +static void maybe_setup_fmodes (int hpos) +{ + switch (bpldmasetupphase) + { + case 0: + BPLCON0_Denise (hpos, bplcon0); + bpldmasetupphase++; + bpldmasetuphpos += BPLCON_AGNUS_DELAY - BPLCON_DENISE_DELAY; + break; + case 1: + setup_fmodes (hpos); + break; + } +} + +STATIC_INLINE maybe_check (int hpos) +{ + if (bpldmasetuphpos > 0 && hpos >= bpldmasetuphpos) + maybe_setup_fmodes (hpos); +} + +static void bpldmainitdelay (int hpos) +{ + int needdelay = 1; + int hposa; + + hposa = hpos + BPLCON_AGNUS_DELAY; + ddf_change = vpos; + if (hposa >= maxhpos - 1) + needdelay = 0; + if (hposa < 0x14) + needdelay = 0; + if (!needdelay) { + BPLCON0_Denise (hposa, bplcon0); + setup_fmodes (hposa); + return; + } + if (bpldmasetuphpos < 0) { + bpldmasetupphase = 0; + bpldmasetuphpos = hpos + BPLCON_DENISE_DELAY; + } } /* Expand bplcon0/bplcon1 into the toscr_xxx variables. */ @@ -1439,6 +1537,8 @@ STATIC_INLINE int one_fetch_cycle_0 (int pos, int ddfstop_to_test, int dma, int plf_state++; } + maybe_check (pos); + if (dma) { /* fetchstart_mask can be larger than fm_maxplane if FMODE > 0. This means that the remaining cycles are idle; we'll fall through the whole switch @@ -1629,15 +1729,18 @@ static void update_fetch_2 (int hpos) { update_fetch (hpos, 2); } STATIC_INLINE void decide_fetch (int hpos) { - if (fetch_state != fetch_not_started && hpos > last_fetch_hpos) { - switch (fetchmode) { - case 0: update_fetch_0 (hpos); break; -#ifdef AGA - case 1: update_fetch_1 (hpos); break; - case 2: update_fetch_2 (hpos); break; -#endif - default: uae_abort (L"fetchmode corrupt"); + if (hpos > last_fetch_hpos) { + if (fetch_state != fetch_not_started) { + switch (fetchmode) { + case 0: update_fetch_0 (hpos); break; + #ifdef AGA + case 1: update_fetch_1 (hpos); break; + case 2: update_fetch_2 (hpos); break; + #endif + default: uae_abort (L"fetchmode corrupt"); + } } + maybe_check (hpos); last_fetch_hpos = hpos; } } @@ -2441,6 +2544,8 @@ static void reset_decisions (void) last_sprite_point = 0; fetch_state = fetch_not_started; bplcon1_hpos = -1; + bpldmasetuphpos = -1; + bpldmasetupphase = 0; if (plf_state > plf_active) plf_state = plf_idle; @@ -2807,14 +2912,14 @@ STATIC_INLINE uae_u16 VHPOSR (void) uae_u16 vp = GETVPOS (); uae_u16 hp = GETHPOS (); - hp += 2; + hp += 3; if (hp >= maxhpos) { hp -= maxhpos; vp++; if (vp >= maxvpos) vp = 0; } - hp += 2; + hp += 1; if (hp >= maxhpos) hp -= maxhpos; @@ -3030,10 +3135,6 @@ STATIC_INLINE int use_eventmode (void) return currprefs.cpu_cycle_exact != 0; } -static void INTENA_f (uae_u32 data) -{ - doint(); -} STATIC_INLINE void INTENA (uae_u16 v) { setclr (&intena,v); @@ -3042,15 +3143,20 @@ STATIC_INLINE void INTENA (uae_u16 v) write_log (L"INTENA %04X (%04X) %p\n", intena, v, M68K_GETPC); #endif if (v & 0x8000) { - if (!use_eventmode ()) - INTENA_f (0); - else - event2_newevent2 (6, 0, INTENA_f); + if (use_eventmode ()) + prepare_interrupt (); + doint (); } } void INTREQ_0 (uae_u16 v) { + intreqr = intreq; + /* data in intreq is immediately available (vsync only currently because there is something unknown..) */ + setclr (&intreqr, v & (0x8000 | 0x20)); + + if (use_eventmode ()) + prepare_interrupt (); if (v & (0x80|0x100|0x200|0x400)) audio_update_irq (v); setclr (&intreq, v); @@ -3058,7 +3164,7 @@ void INTREQ_0 (uae_u16 v) doint (); } -void INTREQ_f (uae_u32 data) +void INTREQ (uae_u16 data) { INTREQ_0 (data); serial_check_irq (); @@ -3075,25 +3181,6 @@ void INTREQ_f (uae_u32 data) rethink_gayle (); } -static void INTREQ_d (uae_u16 v, int d) -{ - intreqr = intreq; - /* data in intreq is immediately available (vsync only currently because there is something unknown..) */ - setclr (&intreqr, v & (0x8000 | 0x20)); - if (!use_eventmode () || v == 0) - INTREQ_f (v); - else - event2_newevent2 (d, v, INTREQ_f); -} - -void INTREQ (uae_u16 v) -{ - if (!use_eventmode ()) - INTREQ_f (v); - else - INTREQ_d (v, 6); -} - static void ADKCON (int hpos, uae_u16 v) { if (currprefs.produce_sound > 0) @@ -3144,26 +3231,6 @@ static void varsync (void) } #endif -int is_bitplane_dma (int hpos) -{ - if (fetch_state == fetch_not_started || hpos < plfstrt) - return 0; - if ((plf_state == plf_end && hpos >= thisline_decision.plfright) - || hpos >= estimated_last_fetch_cycle) - return 0; - return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask]; -} - -STATIC_INLINE int is_bitplane_dma_inline (int hpos) -{ - if (fetch_state == fetch_not_started || hpos < plfstrt) - return 0; - if ((plf_state == plf_end && hpos >= thisline_decision.plfright) - || hpos >= estimated_last_fetch_cycle) - return 0; - return curr_diagram[(hpos - cycle_diagram_shift) & fetchstart_mask]; -} - static void BPLxPTH (int hpos, uae_u16 v, int num) { decide_line (hpos); @@ -3199,9 +3266,7 @@ static void BPLCON0_Denise (int hpos, uae_u16 v) if (isehb (bplcon0d, bplcon2)) v |= 0x80; - // Denise reacts to HAM/EHB/DPF changes instantly - if ((bplcon0d & (0x800 | 0x400 | 0x80)) != (v & (0x800 | 0x400 | 0x80))) - record_register_change (hpos, 0x100, (bplcon0d & ~(0x800 | 0x400 | 0x80)) | (v & (0x0800 | 0x400 | 0x80))); + record_register_change (hpos, 0x100, (bplcon0d & ~(0x800 | 0x400 | 0x80)) | (v & (0x0800 | 0x400 | 0x80))); bplcon0d = v & ~0x80; @@ -3228,7 +3293,16 @@ static void BPLCON0 (int hpos, uae_u16 v) #endif if (bplcon0 == v) return; - + + bplcon0 = v; + + bpldmainitdelay (hpos); + + if (thisline_decision.plfleft == -1) + BPLCON0_Denise (hpos, v); +} + +#if 0 if ((bplcon0 & 2) && !(v & 2)) { vpos_previous = vpos; hpos_previous = hpos; @@ -3257,11 +3331,7 @@ static void BPLCON0 (int hpos, uae_u16 v) estimate_last_fetch_cycle (hpos); } - -static void BPLCON0_f (uae_u32 d) -{ - BPLCON0 (d >> 16, d & 0xffff); -} +#endif STATIC_INLINE void BPLCON1 (int hpos, uae_u16 v) { @@ -3431,27 +3501,17 @@ static void DDFSTOP (int hpos, uae_u16 v) } } -static void FMODE (uae_u16 v) +static void FMODE (int hpos, uae_u16 v) { if (! (currprefs.chipset_mask & CSMASK_AGA)) v = 0; + v &= 0xC00F; + if (fmode == v) + return; ddf_change = vpos; fmode = v; sprite_width = GET_SPRITEWIDTH (fmode); - switch (fmode & 3) { - case 0: - fetchmode = 0; - break; - case 1: - case 2: - fetchmode = 1; - break; - case 3: - fetchmode = 2; - break; - } - expand_fmodes (); - calcdiw (); + bpldmainitdelay (hpos); } static void FNULL (uae_u16 v) @@ -3934,7 +3994,7 @@ static void update_copper (int until_hpos) custom_wput_copper (c_hpos, cop_state.moveaddr, cop_state.movedata, 0); } } -#if 1 +#if 0 if (cop_state.movedelay100 > 0) { cop_state.movedelay100--; if (cop_state.movedelay100 == 1) { @@ -4002,7 +4062,7 @@ static void update_copper (int until_hpos) case COP_read1: if (copper_cant_read (old_hpos)) continue; - cop_state.i1 = chipmem_agnus_wget (cop_state.ip); + cop_state.i1 = last_custom_value = chipmem_agnus_wget (cop_state.ip); alloc_cycle (old_hpos, CYCLE_COPPER); #ifdef DEBUGGER if (debug_dma) @@ -4015,7 +4075,7 @@ static void update_copper (int until_hpos) case COP_read2: if (copper_cant_read (old_hpos)) continue; - cop_state.i2 = chipmem_agnus_wget (cop_state.ip); + cop_state.i2 = last_custom_value = chipmem_agnus_wget (cop_state.ip); alloc_cycle (old_hpos, CYCLE_COPPER); cop_state.ip += 2; cop_state.saved_i1 = cop_state.i1; @@ -4058,7 +4118,7 @@ static void update_copper (int until_hpos) cop_state.state = COP_strobe_delay1; } else { // FIX: all copper writes happen 1 cycle later than CPU writes - if (reg == 0x100) { + if (0 && reg == 0x100) { // special case BPLCON0 BPL DMA sequence delay // dma sequence does not change until 1+4 cycles after the write cop_state.movedelay100 = 2; @@ -4729,7 +4789,7 @@ static void vsync_handler (void) handle_events (); - INTREQ_d (0x8000 | 0x0020, 3); + INTREQ (0x8000 | 0x0020); if (bplcon0 & 4) lof ^= 1; @@ -4991,10 +5051,7 @@ static void hsync_handler (void) ahi_hsync (); } - if (currprefs.chipset_mask & CSMASK_AGA) - last_custom_value = 0xfff; - else - last_custom_value = uaerand (); + last_custom_value = 0xffff; // refresh slots should set this to 0xffff if (!nocustom()) { if (!currprefs.blitter_cycle_exact && bltstate != BLT_done && dmaen (DMA_BITPLANE) && diwstate == DIW_waiting_stop) { @@ -5362,8 +5419,10 @@ void customreset (int hardreset) diwhigh = 0; diwhigh_written = 0; - FMODE (0); + FMODE (0, 0); CLXCON (0); + setup_fmodes (0); + sprite_width = GET_SPRITEWIDTH (fmode); } gayle_reset (hardreset); @@ -5432,13 +5491,13 @@ void customreset (int hardreset) uae_u32 vv; audio_update_adkmasks (); - INTENA_f (0); - INTREQ_f (0); + INTENA (0); + INTREQ (0); COPJMP (1, 1); v = bplcon0; BPLCON0 (0, 0); BPLCON0 (0, v); - FMODE (fmode); + FMODE (0, fmode); if (!(currprefs.chipset_mask & CSMASK_AGA)) { for(i = 0 ; i < 32 ; i++) { vv = current_colors.color_regs_ecs[i]; @@ -5472,6 +5531,8 @@ void customreset (int hardreset) } } sprres = expand_sprres (bplcon0, bplcon3); + sprite_width = GET_SPRITEWIDTH (fmode); + setup_fmodes (0); #ifdef ACTION_REPLAY /* Doing this here ensures we can use the 'reset' command from within AR */ @@ -5680,7 +5741,9 @@ STATIC_INLINE uae_u32 REGPARAM2 custom_wget_1 (int hpos, uaecptr addr, int noput /* OCS/ECS: * reading write-only register causes write with last value in chip * bus (custom registers, chipram, slowram) - * and finally returns all ones + * and finally returns either all ones or something weird if DMA happens + * in next (or previous) cycle.. FIXME. + * * AGA: * only writes to custom registers change last value, read returns * last value which then changes to all ones (following read will return @@ -5689,19 +5752,21 @@ STATIC_INLINE uae_u32 REGPARAM2 custom_wget_1 (int hpos, uaecptr addr, int noput v = last_custom_value; if (!noput) { int r; + uae_u16 old = last_custom_value; + uae_u16 l = currprefs.cpu_compatible && currprefs.cpu_model == 68000 ? regs.irc : 0xffff;//last_custom_value; decide_line (hpos); decide_fetch (hpos); decide_blitter (hpos); -#if CUSTOM_DEBUG > 0 - write_log (L"%04X read!\n", addr); -#endif - r = custom_wput_copper (hpos, addr, last_custom_value, 1); + r = custom_wput_copper (hpos, addr, l, 1); if (currprefs.chipset_mask & CSMASK_AGA) { - v = last_custom_value; + v = l; last_custom_value = 0xffff; } else { - v = 0xffff; + v = old; } +#if CUSTOM_DEBUG > 0 + write_log (L"%08X read = %04X. Value written=%04X PC=%08x\n", 0xdff000 | addr, v, l, M68K_GETPC); +#endif } return v; @@ -5954,7 +6019,7 @@ static int REGPARAM2 custom_wput_1 (int hpos, uaecptr addr, uae_u32 value, int n #endif #ifdef AGA - case 0x1FC: FMODE (value); break; + case 0x1FC: FMODE (hpos, value); break; #endif case 0x1FE: FNULL (value); break; @@ -5962,7 +6027,7 @@ static int REGPARAM2 custom_wput_1 (int hpos, uaecptr addr, uae_u32 value, int n default: if (!noget) { #if CUSTOM_DEBUG > 0 - write_log (L"%04X written!\n", addr); + write_log (L"%04X written %08x\n", addr, M68K_GETPC); #endif custom_wget_1 (hpos, addr, 1); } @@ -6558,7 +6623,6 @@ uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode) checknasty (hpos, vpos); } #endif - do_cycles_ce (1 * CYCLE_UNIT); if (mode > 0) v = get_word (addr); else if (mode == 0) @@ -6567,7 +6631,7 @@ uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode) if (debug_dma) dr->dat = v; #endif - do_cycles_ce (1 * CYCLE_UNIT); + do_cycles_ce (2 * CYCLE_UNIT); return v; } @@ -6596,12 +6660,11 @@ void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v) checknasty (hpos, vpos); } #endif - do_cycles_ce (1 * CYCLE_UNIT); if (mode > 0) put_word (addr, v); else if (mode == 0) put_byte (addr, v); - do_cycles_ce (1 * CYCLE_UNIT); + do_cycles_ce (2 * CYCLE_UNIT); } void do_cycles_ce (long cycles) diff --git a/debug.c b/debug.c index 65e801d9..6d1834ae 100644 --- a/debug.c +++ b/debug.c @@ -752,8 +752,10 @@ struct dma_rec *record_dma (uae_u16 reg, uae_u16 dat, uae_u32 addr, int hpos, in if (hpos >= NR_DMA_REC_HPOS || vpos >= NR_DMA_REC_VPOS) return NULL; dr = &dma_record[dma_record_toggle][vpos * NR_DMA_REC_HPOS + hpos]; - if (dr->reg != 0xffff) + if (dr->reg != 0xffff) { write_log (L"DMA conflict: v=%d h=%d OREG=%04X NREG=%04X\n", vpos, hpos, dr->reg, reg); + return dr; + } dr->reg = reg; dr->dat = dat; dr->addr = addr; @@ -807,6 +809,8 @@ static void decode_dma_record (int hpos, int vpos, int toggle) l2[cl2++] = 'B'; if (dr->evt & DMA_EVENT_BLITIRQ) l2[cl2++] = 'b'; + if (dr->evt & DMA_EVENT_BPLFETCHUPDATE) + l2[cl2++] = 'p'; if (i < cols - 1 && h < maxh - 1) { l1[cl + col - 1] = 32; l2[cl + col - 1] = 32; diff --git a/disk.c b/disk.c index 4ba5b7ca..8033e96f 100644 --- a/disk.c +++ b/disk.c @@ -3144,7 +3144,7 @@ void DSKLEN (uae_u16 v, int hpos) pos += 16; pos %= drv->tracklen; } - INTREQ_f (0x8000 | 0x1000); + INTREQ (0x8000 | 0x1000); done = 1; } else if (dskdmaen == 3) { /* TURBO write */ @@ -3176,7 +3176,7 @@ void DSKLEN (uae_u16 v, int hpos) } dskpt += 2; } - INTREQ_f (0x8000 | 0x1000); + INTREQ (0x8000 | 0x1000); done = 1; } diff --git a/include/debug.h b/include/debug.h index e5cf79c0..93d73ae5 100644 --- a/include/debug.h +++ b/include/debug.h @@ -82,6 +82,7 @@ struct dma_rec #define DMA_EVENT_BLITIRQ 1 #define DMA_EVENT_BLITNASTY 2 #define DMA_EVENT_BLITFINISHED 4 +#define DMA_EVENT_BPLFETCHUPDATE 8 extern struct dma_rec *record_dma (uae_u16 reg, uae_u16 dat, uae_u32 addr, int hpos, int vpos); extern void record_dma_reset (void); diff --git a/include/memory.h b/include/memory.h index 9bdfe993..2c9c060c 100644 --- a/include/memory.h +++ b/include/memory.h @@ -132,6 +132,7 @@ extern uae_u32 gfxmem_start; extern uae_u8 *gfxmemory; extern uae_u32 gfxmem_mask; extern int address_space_24; +extern uae_u16 last_custom_value; /* Default memory access functions */ diff --git a/include/newcpu.h b/include/newcpu.h index a9b9c9cf..a8b8fd39 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -283,6 +283,7 @@ extern void REGPARAM3 MakeFromSR (struct regstruct *regs) REGPARAM; extern void REGPARAM3 Exception (int, struct regstruct *regs, uaecptr) REGPARAM; extern void NMI (void); extern void NMI_delayed (void); +extern void prepare_interrupt (void); extern void doint (void); extern void dump_counts (void); extern int m68k_move2c (int, uae_u32 *); diff --git a/memory.c b/memory.c index 4f358e60..f874e744 100644 --- a/memory.c +++ b/memory.c @@ -36,7 +36,6 @@ int candirect = -1; /* Set by each memory handler that does not simply access real memory. */ int special_mem; #endif -extern uae_u16 last_custom_value; static int isdirectjit (void) { @@ -1263,7 +1262,7 @@ static uae_u32 REGPARAM2 chipmem_wget_ce2 (uaecptr addr) m = (uae_u16 *)(chipmemory + addr); ce2_timeout (); v = do_get_mem_word (m); - last_custom_value = v; + //last_custom_value = v; return v; } @@ -1300,7 +1299,7 @@ static void REGPARAM2 chipmem_wput_ce2 (uaecptr addr, uae_u32 w) addr &= chipmem_mask; m = (uae_u16 *)(chipmemory + addr); ce2_timeout (); - last_custom_value = w; + //last_custom_value = w; do_put_mem_word (m, w); } @@ -1332,7 +1331,7 @@ static uae_u32 REGPARAM2 chipmem_wget (uaecptr addr) addr &= chipmem_mask; m = (uae_u16 *)(chipmemory + addr); v = do_get_mem_word (m); - last_custom_value = v; + //last_custom_value = v; return v; } @@ -1341,7 +1340,7 @@ static uae_u32 REGPARAM2 chipmem_bget (uaecptr addr) uae_u8 v; addr &= chipmem_mask; v = chipmemory[addr]; - last_custom_value = (v << 8) | v; + //last_custom_value = (v << 8) | v; return v; } @@ -1360,14 +1359,14 @@ void REGPARAM2 chipmem_wput (uaecptr addr, uae_u32 w) addr &= chipmem_mask; m = (uae_u16 *)(chipmemory + addr); - last_custom_value = w; + //last_custom_value = w; do_put_mem_word (m, w); } void REGPARAM2 chipmem_bput (uaecptr addr, uae_u32 b) { addr &= chipmem_mask; - last_custom_value = (b << 8) | b; + //last_custom_value = (b << 8) | b; chipmemory[addr] = b; } diff --git a/ncr_scsi.c b/ncr_scsi.c index 1afdbd29..37969c29 100644 --- a/ncr_scsi.c +++ b/ncr_scsi.c @@ -251,7 +251,7 @@ static void INT2(void) { if (ncrregs[SIEN_REG] == 0) return; - INTREQ_f(0x8000 | 0x0008); + INTREQ (0x8000 | 0x0008); write_log (L"IRQ\n"); } diff --git a/newcpu.c b/newcpu.c index 39ff49d6..5c9e7d95 100644 --- a/newcpu.c +++ b/newcpu.c @@ -1998,6 +1998,21 @@ static void do_trace (void) } } + +static int interrupt_cycles_active; +static unsigned long interrupt_cycles; + +// handle interrupt delay (few cycles) +STATIC_INLINE int time_for_interrupt (void) +{ + if (!interrupt_cycles_active) + return 1; + if ((int)get_cycles () - (int)interrupt_cycles < 0) + return 0; + interrupt_cycles_active = 0; + return 1; +} + #define IDLETIME (currprefs.cpu_idle * sleep_resolution / 700) STATIC_INLINE int do_specialties (int cycles, struct regstruct *regs) @@ -2071,10 +2086,12 @@ STATIC_INLINE int do_specialties (int cycles, struct regstruct *regs) if (regs->spcflags & SPCFLAG_COPPER) do_copper (); if (regs->spcflags & (SPCFLAG_INT | SPCFLAG_DOINT)) { - int intr = intlev (); - unset_special (regs, SPCFLAG_INT | SPCFLAG_DOINT); - if (intr != -1 && intr > regs->intmask) - do_interrupt (intr, regs); + if (time_for_interrupt ()) { + int intr = intlev (); + unset_special (regs, SPCFLAG_INT | SPCFLAG_DOINT); + if (intr != -1 && intr > regs->intmask) + do_interrupt (intr, regs); + } } if ((regs->spcflags & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE))) { unset_special (regs, SPCFLAG_BRK | SPCFLAG_MODE_CHANGE); @@ -2109,10 +2126,12 @@ STATIC_INLINE int do_specialties (int cycles, struct regstruct *regs) do_trace (); if (regs->spcflags & SPCFLAG_INT) { - int intr = intlev (); - unset_special (regs, SPCFLAG_INT | SPCFLAG_DOINT); - if (intr != -1 && (intr > regs->intmask || intr == 7)) - do_interrupt (intr, regs); + if (time_for_interrupt ()) { + int intr = intlev (); + unset_special (regs, SPCFLAG_INT | SPCFLAG_DOINT); + if (intr != -1 && (intr > regs->intmask || intr == 7)) + do_interrupt (intr, regs); + } } if (regs->spcflags & SPCFLAG_DOINT) { unset_special (regs, SPCFLAG_DOINT); @@ -2126,6 +2145,12 @@ STATIC_INLINE int do_specialties (int cycles, struct regstruct *regs) return 0; } +void prepare_interrupt (void) +{ + interrupt_cycles = get_cycles () + 6 * CYCLE_UNIT; + interrupt_cycles_active = 1; +} + void doint (void) { if (currprefs.cpu_compatible) diff --git a/od-win32/ahidsound_dsonly.c b/od-win32/ahidsound_dsonly.c index b3a2a8d8..27c050a6 100644 --- a/od-win32/ahidsound_dsonly.c +++ b/od-win32/ahidsound_dsonly.c @@ -191,7 +191,7 @@ void ahi_updatesound(int force) if (sound_flushes2 == 1) { oldpos = 0; intcount = 1; - INTREQ_f (0x8000 | 0x2000); + INTREQ (0x8000 | 0x2000); hr = IDirectSoundBuffer_Play (lpDSB2, 0, 0, DSBPLAY_LOOPING); if(hr == DSERR_BUFFERLOST) { IDirectSoundBuffer_Restore (lpDSB2); @@ -210,7 +210,7 @@ void ahi_updatesound(int force) if (force == 1) { if (oldpos != pos) { intcount = 1; - INTREQ_f (0x8000 | 0x2000); + INTREQ (0x8000 | 0x2000); return; //to generate amiga ints every amigablksize } else { return; @@ -252,7 +252,7 @@ void ahi_updatesound(int force) oldpos -= ahisndbufsize; if (oldpos != pos) { intcount = 1; - INTREQ_f (0x8000 | 0x2000); + INTREQ (0x8000 | 0x2000); } } diff --git a/od-win32/hardfile_win32.c b/od-win32/hardfile_win32.c index f8371aa0..491eafe8 100644 --- a/od-win32/hardfile_win32.c +++ b/od-win32/hardfile_win32.c @@ -203,7 +203,7 @@ static int safetycheck (HANDLE *h, const TCHAR *name, uae_u64 offset, uae_u8 *bu write_log (L"hd ignored, read error %d!\n", GetLastError ()); return 2; } - if (offset > 0) + if (j == 0 && offset > 0) return -5; if (j == 0 && buf[0] == 0x39 && buf[1] == 0x10 && buf[2] == 0xd3 && buf[3] == 0x12) { // ADIDE "CPRM" hidden block.. diff --git a/od-win32/picasso96_win.c b/od-win32/picasso96_win.c index d211bf6d..13ef0836 100644 --- a/od-win32/picasso96_win.c +++ b/od-win32/picasso96_win.c @@ -679,7 +679,7 @@ static void picasso_trigger_vblank (void) put_long (uaegfx_base + CARD_IRQPTR, boardinfo + PSSO_BoardInfo_SoftInterrupt); put_byte (uaegfx_base + CARD_IRQFLAG, 1); if (currprefs.win32_rtgvblankrate != 0) - INTREQ_f (0x8000 | 0x0008); + INTREQ (0x8000 | 0x0008); } static int isvsync (void) diff --git a/od-win32/serial_win32.c b/od-win32/serial_win32.c index 1cdb9b7e..818c1830 100644 --- a/od-win32/serial_win32.c +++ b/od-win32/serial_win32.c @@ -116,7 +116,7 @@ static void checkreceive (int mode) gettimeofday (&tv, NULL); if (tv.tv_sec > lastchartime) { ovrun = 1; - INTREQ_f (0x8000 | 0x0800); + INTREQ (0x8000 | 0x0800); while (readser (&recdata)); write_log (L"SERIAL: overrun\n"); } @@ -181,7 +181,7 @@ static void checksend (int mode) writeser (serdatshift); #endif data_in_serdat = 0; - INTREQ_f (0x8000 | 0x0001); + INTREQ (0x8000 | 0x0001); #if SERIALDEBUG > 2 write_log (L"SERIAL: send %04X (%c)\n", serdatshift, doTCHAR (serdatshift)); #endif diff --git a/od-win32/sounddep/sound.c b/od-win32/sounddep/sound.c index 21e3c47d..c1cd412b 100644 --- a/od-win32/sounddep/sound.c +++ b/od-win32/sounddep/sound.c @@ -1261,6 +1261,12 @@ void reset_sound (void) clearbuffer (sdp); } +static void disable_sound (void) +{ + close_sound (); + currprefs.produce_sound = changed_prefs.produce_sound = 1; +} + #ifdef JIT extern uae_u8* compiled_code; #else @@ -1622,6 +1628,8 @@ static void finish_sound_buffer_wasapi (struct sound_data *sd, uae_u16 *sndbuffe } else { int numFramesPadding, avail; + int stuck = 2000; + int oldpadding = 0; for (;;) { hr = s->pAudioClient->lpVtbl->GetCurrentPadding (s->pAudioClient, &numFramesPadding); @@ -1635,6 +1643,14 @@ static void finish_sound_buffer_wasapi (struct sound_data *sd, uae_u16 *sndbuffe gui_data.sndbuf_status = 1; statuscnt = SND_STATUSCNT; sleep_millis (1); + if (oldpadding == numFramesPadding) { + if (stuck-- < 0) { + write_log (L"WASAPI: sound stuck %d %d %d !?\n", s->bufferFrameCount, numFramesPadding, s->sndbufframes); + disable_sound (); + return; + } + } + oldpadding = numFramesPadding; } s->sndbuf += (s->wasapigoodsize - avail) * 1000 / s->wasapigoodsize; gui_data.sndbuf = s->sndbuf / s->framecounter; @@ -1691,6 +1707,7 @@ static void finish_sound_buffer_ds (struct sound_data *sd, uae_u16 *sndbuffer) counter--; if (counter < 0) { write_log (L"DSSOUND: stuck?!?!\n"); + disable_sound (); break; } } @@ -1786,6 +1803,7 @@ static void finish_sound_buffer_ds (struct sound_data *sd, uae_u16 *sndbuffer) if (counter < 0) { write_log (L"DSSOUND: sound system got stuck!?\n"); restore_ds (sd, DSERR_BUFFERLOST); + disable_sound (); return; } continue; diff --git a/od-win32/win32.h b/od-win32/win32.h index 8613ed3a..d674d7d6 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -17,8 +17,8 @@ #define WINUAEPUBLICBETA 1 -#define WINUAEBETA L"Beta 4" -#define WINUAEDATE MAKEBD(2009, 8, 3) +#define WINUAEBETA L"5" +#define WINUAEDATE MAKEBD(2009, 8, 6) #define WINUAEEXTRA L"" #define WINUAEREV L"" diff --git a/od-win32/winuae_msvc/winuae_msvc.vcproj b/od-win32/winuae_msvc/winuae_msvc.vcproj index cebc8744..39485de7 100644 --- a/od-win32/winuae_msvc/winuae_msvc.vcproj +++ b/od-win32/winuae_msvc/winuae_msvc.vcproj @@ -1446,11 +1446,11 @@ >