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];
#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. */
/* 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);
}
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;
}
}
}
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;
extrasamples++;
}
}
- (*sample_handler) ();
+#endif
+ (*sample_handler) ();
+#if 0
if (outputsample == 0)
outputsample = -1;
else if (outputsample < 0)
outputsample = 1;
+#endif
}
}
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
}
if (!dmaen (DMA_BLITTER))
return;
blt_info.bltcdat = chipmem_bank.wget (bltcpt);
+ last_custom_value = blt_info.bltcdat;
}
bltstate = BLT_work;
}
if (bltcon0 & 0x200) {
if (!dmaen (DMA_BLITTER))
return;
+ last_custom_value = blt_info.bltddat;
chipmem_bank.wput (bltdpt, blt_info.bltddat);
}
bltstate = BLT_next;
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++;
{
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)
break;
case 3:
blt_info.bltcdat = dat = chipmem_agnus_wget (bltcpt);
+ last_custom_value = blt_info.bltcdat;
addr = bltcpt;
bltcpt += blit_add;
reg = 0x70;
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
}
}
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);
}
}
-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);
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. */
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
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;
}
}
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;
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;
return currprefs.cpu_cycle_exact != 0;
}
-static void INTENA_f (uae_u32 data)
-{
- doint();
-}
STATIC_INLINE void INTENA (uae_u16 v)
{
setclr (&intena,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);
doint ();
}
-void INTREQ_f (uae_u32 data)
+void INTREQ (uae_u16 data)
{
INTREQ_0 (data);
serial_check_irq ();
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)
}
#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);
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;
#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;
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)
{
}
}
-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)
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) {
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)
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;
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;
handle_events ();
- INTREQ_d (0x8000 | 0x0020, 3);
+ INTREQ (0x8000 | 0x0020);
if (bplcon0 & 4)
lof ^= 1;
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) {
diwhigh = 0;
diwhigh_written = 0;
- FMODE (0);
+ FMODE (0, 0);
CLXCON (0);
+ setup_fmodes (0);
+ sprite_width = GET_SPRITEWIDTH (fmode);
}
gayle_reset (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];
}
}
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 */
/* 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
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;
#endif
#ifdef AGA
- case 0x1FC: FMODE (value); break;
+ case 0x1FC: FMODE (hpos, value); break;
#endif
case 0x1FE: FNULL (value); break;
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);
}
checknasty (hpos, vpos);
}
#endif
- do_cycles_ce (1 * CYCLE_UNIT);
if (mode > 0)
v = get_word (addr);
else if (mode == 0)
if (debug_dma)
dr->dat = v;
#endif
- do_cycles_ce (1 * CYCLE_UNIT);
+ do_cycles_ce (2 * CYCLE_UNIT);
return 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)
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;
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;
pos += 16;
pos %= drv->tracklen;
}
- INTREQ_f (0x8000 | 0x1000);
+ INTREQ (0x8000 | 0x1000);
done = 1;
} else if (dskdmaen == 3) { /* TURBO write */
}
dskpt += 2;
}
- INTREQ_f (0x8000 | 0x1000);
+ INTREQ (0x8000 | 0x1000);
done = 1;
}
#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);
extern uae_u8 *gfxmemory;
extern uae_u32 gfxmem_mask;
extern int address_space_24;
+extern uae_u16 last_custom_value;
/* Default memory access functions */
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 *);
/* 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)
{
m = (uae_u16 *)(chipmemory + addr);
ce2_timeout ();
v = do_get_mem_word (m);
- last_custom_value = v;
+ //last_custom_value = v;
return v;
}
addr &= chipmem_mask;
m = (uae_u16 *)(chipmemory + addr);
ce2_timeout ();
- last_custom_value = w;
+ //last_custom_value = w;
do_put_mem_word (m, w);
}
addr &= chipmem_mask;
m = (uae_u16 *)(chipmemory + addr);
v = do_get_mem_word (m);
- last_custom_value = v;
+ //last_custom_value = v;
return v;
}
uae_u8 v;
addr &= chipmem_mask;
v = chipmemory[addr];
- last_custom_value = (v << 8) | v;
+ //last_custom_value = (v << 8) | v;
return v;
}
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;
}
{
if (ncrregs[SIEN_REG] == 0)
return;
- INTREQ_f(0x8000 | 0x0008);
+ INTREQ (0x8000 | 0x0008);
write_log (L"IRQ\n");
}
}
}
+
+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)
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);
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);
return 0;
}
+void prepare_interrupt (void)
+{
+ interrupt_cycles = get_cycles () + 6 * CYCLE_UNIT;
+ interrupt_cycles_active = 1;
+}
+
void doint (void)
{
if (currprefs.cpu_compatible)
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);
if (force == 1) {
if (oldpos != pos) {
intcount = 1;
- INTREQ_f (0x8000 | 0x2000);
+ INTREQ (0x8000 | 0x2000);
return; //to generate amiga ints every amigablksize
} else {
return;
oldpos -= ahisndbufsize;
if (oldpos != pos) {
intcount = 1;
- INTREQ_f (0x8000 | 0x2000);
+ INTREQ (0x8000 | 0x2000);
}
}
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..
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)
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");
}
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
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
} else {
int numFramesPadding, avail;
+ int stuck = 2000;
+ int oldpadding = 0;
for (;;) {
hr = s->pAudioClient->lpVtbl->GetCurrentPadding (s->pAudioClient, &numFramesPadding);
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;
counter--;
if (counter < 0) {
write_log (L"DSSOUND: stuck?!?!\n");
+ disable_sound ();
break;
}
}
if (counter < 0) {
write_log (L"DSSOUND: sound system got stuck!?\n");
restore_ds (sd, DSERR_BUFFERLOST);
+ disable_sound ();
return;
}
continue;
#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""
>
</File>
<File
- RelativePath=".\configfile.ico"
+ RelativePath="..\resources\configfile.ico"
>
</File>
<File
- RelativePath="..\resources\configfile.ico"
+ RelativePath=".\configfile.ico"
>
</File>
<File
>
</File>
<File
- RelativePath=".\file.ico"
+ RelativePath="..\resources\file.ico"
>
</File>
<File
- RelativePath="..\resources\file.ico"
+ RelativePath=".\file.ico"
>
</File>
<File
>
</File>
<File
- RelativePath="..\resources\port.ico"
+ RelativePath=".\port.ico"
>
</File>
<File
- RelativePath=".\port.ico"
+ RelativePath="..\resources\port.ico"
>
</File>
<File
+Beta 5:
+
+Biggest A500 cycle-exact updates should be done now.
+
+- interrupt delay rewritten and corrected, fixes Gleat Stuff #01/BRB
+- blitter/CPU timing tweak, fixes 1010 bobs/Celtic
+- disable sound if sound driver buffer position gets stuck (driver bug)
+- final partition read/write fix..
+- try to emulate reading of non-existing/write-only custom registers
+ more accurately
+- Brian the Lion "dialog screen" seems to be something AGA specific
+ after all.. 1 extra cycle needed after write to BPLCON0 before BPL
+ cycle diagram changes (or at least in Brian the Lion's situation..)
+ so add one cycle in AGA and hope it isn't totally incorrect fix..
+
Beta 4:
- 0x76/0x30 partition types are marked as "PART" in GUI and read/write