STATIC_INLINE int channel_state (int cycles)
{
- const int *diag = get_ch ();
+ const int *diag;
if (cycles < 0)
return 0;
+ diag = get_ch ();
if (cycles < diag[0])
return diag[1 + cycles];
cycles -= diag[0];
}
STATIC_INLINE int channel_pos (int cycles)
{
- const int *diag = get_ch ();
+ const int *diag;
if (cycles < 0)
return 0;
+ diag = get_ch ();
if (cycles < diag[0])
return cycles;
cycles -= diag[0];
{
if (is_bitplane_dma (hpos))
return 0;
- if (cycle_line[hpos] == CYCLE_CPU)
- return -1;
if (cycle_line[hpos])
return 0;
return 1;
// final 2 idle cycles?
if (blit_final) {
if (blit_cyclecounter > get_ch ()[0]) {
- bltdpt = bltcpt;
blitter_done (last_blitter_hpos);
return;
}
/* onedot mode and no pixel = bus write access is skipped */
if (c == 4 && blitsing && blitonedot > 1) {
if (vblitsize == 0) {
+ bltdpt = bltcpt;
blit_final = 1;
blit_cyclecounter = 0;
}
alloc_cycle_ext (last_blitter_hpos, CYCLE_BLITTER);
record_dma_blit (0x00, blt_info.bltddat, bltdpt, last_blitter_hpos);
if (vblitsize == 0) {
+ bltdpt = bltcpt;
blit_final = 1;
blit_cyclecounter = 0;
break;
if (blit_ch == 1)
blitter_hcounter1 = blitter_hcounter2;
}
- blit_final = 0;
return wd;
}
if (c == 0) {
blt_info.got_cycle = 1;
blit_cyclecounter++;
+ if (blit_cyclecounter == 0)
+ blit_final = 0;
blit_totalcyclecounter++;
/* check if blit with zero channels has ended */
if (blit_ch == 0 && blit_cyclecounter >= blit_maxcyclecounter) {
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define DEBUG 0
+#define DEBUG 1
#include "sysconfig.h"
#include "sysdeps.h"
regs.wb3_status = write ? 0x80 | ssw : 0;
if (!write)
ssw |= MMU_SSW_RW;
+
if (regs.t0 || regs.t1)
ssw |= MMU_SSW_CT;
regs.mmu_fault_addr = addr;
regs.mmu_ssw = ssw | MMU_SSW_ATC;
- //write_log (L"BUS ERROR: fc=%d w=%d log=%08x ssw=%04x\n", fc, write, addr, ssw);
+ write_log (L"BUS ERROR: fc=%d w=%d log=%08x ssw=%04x\n", fc, write, addr, ssw);
+ activate_debugger ();
THROW(2);
}
uae_u32 desc, desc_addr, wp;
int i, indirect;
+ if (addr == 0xb000)
+ write_log (L"x");
+
indirect = 0;
wp = 0;
desc = super ? regs.srp : regs.urp;
static unsigned int diwstrt, diwstop, diwhigh;
static int diwhigh_written;
static unsigned int ddfstrt, ddfstop, ddfstrt_old_hpos, ddfstrt_old_vpos;
-static int ddf_change, badmode;
+static int ddf_change, badmode, diw_change;
static int fmode;
static int bplcon1_hpos;
static enum diw_states diwstate, hdiwstate, ddfstate;
int first_planes_vpos, last_planes_vpos;
int diwfirstword_total, diwlastword_total;
+int ddffirstword_total, ddflastword_total;
int firstword_bplcon1;
static int last_copper_hpos;
plfstop = 0xff;
plfstrt_start = HARD_DDF_START - 2;
}
+ diw_change = 2;
}
/* display mode changed (lores, doubling etc..), recalculate everything */
/* Now we know that the comparisons were successful. We might still
have to wait for the blitter though. */
- if ((cop_state.saved_i2 & 0x8000) == 0 && (DMACONR (old_hpos) & 0x4000)) {
- /* We need to wait for the blitter. */
- cop_state.state = COP_bltwait;
- copper_enabled_thisline = 0;
- unset_special (SPCFLAG_COPPER);
- goto out;
+ if ((cop_state.saved_i2 & 0x8000) == 0) {
+ decide_blitter (old_hpos);
+ if (bltstate != BLT_done) {
+ /* We need to wait for the blitter. */
+ cop_state.state = COP_bltwait;
+ copper_enabled_thisline = 0;
+ unset_special (SPCFLAG_COPPER);
+ goto out;
+ } else {
+ if (debug_dma)
+ record_dma_event (DMA_EVENT_COPPERWAKE, old_hpos, vp);
+ }
}
#ifdef DEBUGGER
/*
Copper writes to BLTSIZE: 3 blitter idle cycles, blitter normal cycle starts
- BFD=0 wait: blitter interrupt, 4 cycles, copper fetches next word
(CPU write to BLTSIZE only have 2 idle cycles at start)
+
+ BFD=0 wait: 1 cycle (or 2 if hpos is not aligned) delay before wait ends
*/
void blitter_done_notify (int hpos)
{
if (cop_state.state != COP_bltwait)
return;
- hpos += 4;
+ hpos += 3;
hpos &= ~1;
if (hpos >= maxhpos) {
hpos -= maxhpos;
cop_state.hpos = hpos;
cop_state.vpos = vp;
cop_state.state = COP_read1;
+ if (debug_dma)
+ record_dma_event (DMA_EVENT_COPPERWAKE, hpos, vp);
if (dmaen (DMA_COPPER) && vp == vpos) {
copper_enabled_thisline = 1;
last_planes_vpos = 0;
diwfirstword_total = max_diwlastword;
diwlastword_total = 0;
+ ddffirstword_total = max_diwlastword;
+ ddflastword_total = 0;
plflastline_total = 0;
plffirstline_total = maxvpos;
}
last_planes_vpos = vpos - 1;
}
}
- if (vpos >= first_planes_vpos && vpos <= last_planes_vpos) {
- if (diwlastword > diwlastword_total)
- diwlastword_total = diwlastword;
- if (diwfirstword < diwfirstword_total) {
- diwfirstword_total = diwfirstword;
+ if (diw_change == 0) {
+ if (vpos >= first_planes_vpos && vpos <= last_planes_vpos) {
+ if (diwlastword > diwlastword_total)
+ diwlastword_total = diwlastword;
+ if (diwfirstword < diwfirstword_total) {
+ diwfirstword_total = diwfirstword;
+ firstword_bplcon1 = bplcon1;
+ }
+ }
+ if (diwstate == DIW_waiting_stop) {
+ int f = 8 << fetchmode;
+ if (plfstrt + f < ddffirstword_total + f)
+ ddffirstword_total = plfstrt + f;
+ if (plfstop + 2 * f > ddflastword_total + 2 * f)
+ ddflastword_total = plfstop + 2 * f;
+ }
+ if ((plffirstline < plffirstline_total || (plffirstline_total == minfirstline && vpos > minfirstline)) && plffirstline < vpos / 2) {
firstword_bplcon1 = bplcon1;
+ if (plffirstline < minfirstline)
+ plffirstline_total = minfirstline;
+ else
+ plffirstline_total = plffirstline;
}
+ if (plflastline > plflastline_total && plflastline > plffirstline_total && plflastline > maxvpos / 2)
+ plflastline_total = plflastline;
}
- if ((plffirstline < plffirstline_total || (plffirstline_total == minfirstline && vpos > minfirstline)) && plffirstline < vpos / 2) {
- firstword_bplcon1 = bplcon1;
- if (plffirstline < minfirstline)
- plffirstline_total = minfirstline;
- else
- plffirstline_total = plffirstline;
- }
- if (plflastline > plflastline_total && plflastline > plffirstline_total && plflastline > vpos / 2)
- plflastline_total = plflastline;
+ if (diw_change > 0)
+ diw_change--;
#if 0
decide_fetch_ce (hpos);
bpldma = is_bitplane_dma (hpos_old);
if (bltstate != BLT_done) {
- if (!blitpri && blitter_nasty >= BLIT_NASTY && cycle_line[hpos_old] == 0 && !bpldma)
+ if (!blitpri && blitter_nasty >= BLIT_NASTY && cycle_line[hpos_old] == 0 && !bpldma) {
+ alloc_cycle (hpos_old, CYCLE_CPUNASTY);
break;
+ }
decide_blitter (hpos);
// copper may have been waiting for the blitter
sync_copper (hpos);
}
- if (cycle_line[hpos_old] == 0 && !bpldma)
+ if (cycle_line[hpos_old] == 0 && !bpldma) {
+ alloc_cycle (hpos_old, CYCLE_CPU);
break;
+ }
do_cycles (1 * CYCLE_UNIT);
/* bus was allocated to dma channel, wait for next cycle.. */
}
- alloc_cycle (hpos_old, CYCLE_CPU);
return hpos_old;
}
void do_cycles_ce (long cycles)
{
int hpos;
- while (cycles > 0) {
+ int mask = CYCLE_UNIT - 1;
+ static int extra;
+
+ extra += cycles & mask;
+ cycles &= ~mask;
+ cycles += extra & ~mask;
+ extra &= mask;
+ while (cycles >= CYCLE_UNIT) {
hpos = current_hpos () + 1;
sync_copper (hpos);
decide_line (hpos);
l2[cl2++] = 'b';
if (dr->evt & DMA_EVENT_BPLFETCHUPDATE)
l2[cl2++] = 'p';
+ if (dr->evt & DMA_EVENT_COPPERWAKE)
+ l2[cl2++] = 'W';
if (i < cols - 1 && h < maxh - 1) {
l1[cl + col - 1] = 32;
l2[cl + col - 1] = 32;
int dr, mfmpos = -1;
write_log (L"disk dma finished %08X MFMpos=", dskpt);
for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++)
- write_log (L"%d%s", floppy[dr].mfmpos, dr < MAX_FLOPPY_DRIVES - 1 ? "," : "");
+ write_log (L"%d%s", floppy[dr].mfmpos, dr < MAX_FLOPPY_DRIVES - 1 ? L"," : L"");
write_log (L"\n");
}
}
}
if (dr == 4) {
write_log (L"disk %s DMA started, drvmask=%x motormask=%x\n",
- dskdmaen == 3 ? "write" : "read", selected ^ 15, motormask);
+ dskdmaen == 3 ? L"write" : L"read", selected ^ 15, motormask);
noselected = 1;
} else {
if (disk_debug_logging > 0) {
write_log (L"disk %s DMA started, drvmask=%x track %d mfmpos %d dmaen=%d\n",
- dskdmaen == 3 ? "write" : "read", selected ^ 15,
+ dskdmaen == 3 ? L"write" : L"read", selected ^ 15,
floppy[dr].cyl * 2 + side, floppy[dr].mfmpos, dma_enable);
disk_dma_debugmsg ();
}
extern int plffirstline_total, plflastline_total;
extern int first_planes_vpos, last_planes_vpos;
extern int diwfirstword_total, diwlastword_total;
+extern int ddffirstword_total, ddflastword_total;
extern int firstword_bplcon1;
#define MIN_DISPLAY_W 256
diwfirstword_total = 48 << currprefs.gfx_resolution;
if (diwlastword_total > (448 << currprefs.gfx_resolution))
diwlastword_total = 448 << currprefs.gfx_resolution;
+ ddffirstword_total = coord_hw_to_window_x (ddffirstword_total * 2 + DIW_DDF_OFFSET);
+ ddflastword_total = coord_hw_to_window_x (ddflastword_total * 2 + DIW_DDF_OFFSET);
+ if (ddffirstword_total < (48 << currprefs.gfx_resolution))
+ ddffirstword_total = 48 << currprefs.gfx_resolution;
+ if (ddflastword_total > (448 << currprefs.gfx_resolution))
+ ddflastword_total = 448 << currprefs.gfx_resolution;
+ if (0 && !(currprefs.chipset_mask & CSMASK_AGA)) {
+ if (ddffirstword_total > diwfirstword_total)
+ diwfirstword_total = ddffirstword_total;
+ if (ddflastword_total < diwlastword_total)
+ diwlastword_total = ddflastword_total;
+ }
}
w = diwlastword_total - diwfirstword_total;
#define GF_AA 7
#define GF_NOREFILL 8
#define GF_PREFETCH 16
+#define GF_FC 32
/* For the current opcode, the next lower level that will have different code.
* Initialized to -1 for each opcode. If it remains unchanged, indicates we
default: abort ();
}
} else if (using_mmu) {
- switch (size) {
- case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = get_byte_mmu (%sa);\n", name, name); break;
- case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = get_word_mmu (%sa);\n", name, name); break;
- case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = get_long_mmu (%sa);\n", name, name); break;
- default: abort ();
+ if (flags & GF_FC) {
+ switch (size) {
+ case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = sfc_get_byte (%sa);\n", name, name); break;
+ case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = sfc_get_word (%sa);\n", name, name); break;
+ case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = sfc_get_long (%sa);\n", name, name); break;
+ default: abort ();
+ }
+ } else {
+ switch (size) {
+ case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = get_byte_mmu (%sa);\n", name, name); break;
+ case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = get_word_mmu (%sa);\n", name, name); break;
+ case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = get_long_mmu (%sa);\n", name, name); break;
+ default: abort ();
+ }
}
} else {
switch (size) {
genamode2 (mode, reg, size, name, getv, movem, flags, e3fudge);
}
-static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, char *to, int store_dir)
+static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, char *to, int store_dir, int flags)
{
switch (mode) {
case Dreg:
switch (size) {
case sz_byte:
insn_n_cycles += 4;
- printf ("\tput_byte_mmu (%sa,%s);\n", to, from);
+ if (flags & GF_FC)
+ printf ("\tdfc_put_byte (%sa,%s);\n", to, from);
+ else
+ printf ("\tput_byte_mmu (%sa,%s);\n", to, from);
break;
case sz_word:
insn_n_cycles += 4;
if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
abort ();
- printf ("\tput_word_mmu (%sa,%s);\n", to, from);
+ if (flags & GF_FC)
+ printf ("\tdfc_put_word (%sa,%s);\n", to, from);
+ else
+ printf ("\tput_word_mmu (%sa,%s);\n", to, from);
break;
case sz_long:
insn_n_cycles += 8;
if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
abort ();
- printf ("\tput_long_mmu (%sa,%s);\n", to, from);
+ if (flags & GF_FC)
+ printf ("\tdfc_put_long (%sa,%s);\n", to, from);
+ else
+ printf ("\tput_long_mmu (%sa,%s);\n", to, from);
break;
default:
abort ();
static void genastore (char *from, amodes mode, char *reg, wordsizes size, char *to)
{
- genastore_2 (from, mode, reg, size, to, 0);
+ genastore_2 (from, mode, reg, size, to, 0, 0);
}
static void genastore_rev (char *from, amodes mode, char *reg, wordsizes size, char *to)
{
- genastore_2 (from, mode, reg, size, to, 1);
+ genastore_2 (from, mode, reg, size, to, 1, 0);
+}
+static void genastore_dfc (char *from, amodes mode, char *reg, wordsizes size, char *to)
+{
+ genastore_2 (from, mode, reg, size, to, 1, GF_FC);
}
static void genmovemle (uae_u16 opcode)
{
- char putcode[100];
+ char *putcode;
int size = table68k[opcode].size == sz_long ? 4 : 2;
if (using_mmu) {
if (table68k[opcode].size == sz_long) {
- strcpy (putcode, "put_long_mmu (srca");
+ putcode = "put_long_mmu (srca";
} else {
- strcpy (putcode, "put_word_mmu (srca");
+ putcode = "put_word_mmu (srca";
}
} else {
if (table68k[opcode].size == sz_long) {
- strcpy (putcode, "put_long (srca");
+ putcode = "put_long (srca";
} else {
- strcpy (putcode, "put_word (srca");
+ putcode = "put_word (srca";
}
}
count_write += table68k[opcode].size == sz_long ? 2 : 1;
printf ("\t}\n");
}
break;
- case i_MOVES: /* ignore DFC and SFC because we have no MMU */
+ case i_MOVES: /* ignore DFC and SFC when using_mmu == false */
{
int old_brace_level;
- if (using_mmu) {
- printf ("write_log(L\"WARNING: MOVES currently ignores MMU!\");\n");
- }
genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
printf ("\tif (extra & 0x800)\n");
old_brace_level = n_braces;
start_brace ();
printf ("\tuae_u32 src = regs.regs[(extra >> 12) & 15];\n");
genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
- genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
+ genastore_dfc ("src", curi->dmode, "dstreg", curi->size, "dst");
pop_braces (old_brace_level);
- printf ("else");
+ printf ("\telse");
start_brace ();
- genamode (curi->dmode, "dstreg", curi->size, "src", 1, 0, 0);
+ genamode (curi->dmode, "dstreg", curi->size, "src", 1, 0, GF_FC);
printf ("\tif (extra & 0x8000) {\n");
switch (curi->size) {
case sz_byte: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = (uae_s32)(uae_s8)src;\n"); break;
break;
case i_MOVE16:
- if (using_ce020) {
- if ((opcode & 0xfff8) == 0xf620) {
- /* MOVE16 (Ax)+,(Ay)+ */
- printf ("\tuaecptr mems = m68k_areg (regs, srcreg) & ~15, memd;\n");
- printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword (0));
- printf ("\tmemd = m68k_areg (regs, dstreg) & ~15;\n");
- printf ("\tput_long_ce020 (memd, get_long_ce020 (mems));\n");
- printf ("\tput_long_ce020 (memd+4, get_long_ce020 (mems+4));\n");
- printf ("\tput_long_ce020 (memd+8, get_long_ce020 (mems+8));\n");
- printf ("\tput_long_ce020 (memd+12, get_long_ce020 (mems+12));\n");
- printf ("\tif (srcreg != dstreg)\n");
- printf ("\tm68k_areg (regs, srcreg) += 16;\n");
- printf ("\tm68k_areg (regs, dstreg) += 16;\n");
- } else {
- /* Other variants */
- genamode (curi->smode, "srcreg", curi->size, "mems", 0, 2, 0);
- genamode (curi->dmode, "dstreg", curi->size, "memd", 0, 2, 0);
- printf ("\tmemsa &= ~15;\n");
- printf ("\tmemda &= ~15;\n");
- printf ("\tput_long_ce020 (memda, get_long_ce020 (memsa));\n");
- printf ("\tput_long_ce020 (memda+4, get_long_ce020 (memsa+4));\n");
- printf ("\tput_long_ce020 (memda+8, get_long_ce020 (memsa+8));\n");
- printf ("\tput_long_ce020 (memda+12, get_long_ce020 (memsa+12));\n");
- if ((opcode & 0xfff8) == 0xf600)
- printf ("\tm68k_areg (regs, srcreg) += 16;\n");
- else if ((opcode & 0xfff8) == 0xf608)
- printf ("\tm68k_areg (regs, dstreg) += 16;\n");
- }
- } else {
- if ((opcode & 0xfff8) == 0xf620) {
- /* MOVE16 (Ax)+,(Ay)+ */
- printf ("\tuaecptr mems = m68k_areg (regs, srcreg) & ~15, memd;\n");
- printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword (0));
- printf ("\tmemd = m68k_areg (regs, dstreg) & ~15;\n");
- printf ("\tput_long (memd, get_long (mems));\n");
- printf ("\tput_long (memd+4, get_long (mems+4));\n");
- printf ("\tput_long (memd+8, get_long (mems+8));\n");
- printf ("\tput_long (memd+12, get_long (mems+12));\n");
- printf ("\tif (srcreg != dstreg)\n");
- printf ("\tm68k_areg (regs, srcreg) += 16;\n");
- printf ("\tm68k_areg (regs, dstreg) += 16;\n");
- } else {
- /* Other variants */
- genamode (curi->smode, "srcreg", curi->size, "mems", 0, 2, 0);
- genamode (curi->dmode, "dstreg", curi->size, "memd", 0, 2, 0);
- printf ("\tmemsa &= ~15;\n");
- printf ("\tmemda &= ~15;\n");
- printf ("\tput_long (memda, get_long (memsa));\n");
- printf ("\tput_long (memda+4, get_long (memsa+4));\n");
- printf ("\tput_long (memda+8, get_long (memsa+8));\n");
- printf ("\tput_long (memda+12, get_long (memsa+12));\n");
- if ((opcode & 0xfff8) == 0xf600)
- printf ("\tm68k_areg (regs, srcreg) += 16;\n");
- else if ((opcode & 0xfff8) == 0xf608)
- printf ("\tm68k_areg (regs, dstreg) += 16;\n");
- }
- }
- break;
+ {
+ char *src, *dst;
+ if (using_ce020) {
+ src = "get_long_ce020";
+ dst = "put_long_ce020";
+ } else if (using_mmu) {
+ src = "get_long_mmu";
+ dst = "put_long_mmu";
+ } else {
+ src = "get_long";
+ dst = "put_long";
+ }
+ if ((opcode & 0xfff8) == 0xf620) {
+ /* MOVE16 (Ax)+,(Ay)+ */
+ printf ("\tuae_u32 v1, v2, v3, v4;\n");
+ printf ("\tuaecptr mems = m68k_areg (regs, srcreg) & ~15, memd;\n");
+ printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword (0));
+ printf ("\tmemd = m68k_areg (regs, dstreg) & ~15;\n");
+ printf ("\tv1 = %s (mems);\n", src);
+ printf ("\tv2 = %s (mems + 4);\n", src);
+ printf ("\tv3 = %s (mems + 8);\n", src);
+ printf ("\tv4 = %s (mems + 12);\n", src);
+ printf ("\t%s (memd , v1);\n", dst);
+ printf ("\t%s (memd + 4, v2);\n", dst);
+ printf ("\t%s (memd + 8, v3);\n", dst);
+ printf ("\t%s (memd + 12, v4);\n", dst);
+ printf ("\tif (srcreg != dstreg)\n");
+ printf ("\t\tm68k_areg (regs, srcreg) += 16;\n");
+ printf ("\tm68k_areg (regs, dstreg) += 16;\n");
+ } else {
+ /* Other variants */
+ printf ("\tuae_u32 v1, v2, v3, v4;\n");
+ genamode (curi->smode, "srcreg", curi->size, "mems", 0, 2, 0);
+ genamode (curi->dmode, "dstreg", curi->size, "memd", 0, 2, 0);
+ printf ("\tmemsa &= ~15;\n");
+ printf ("\tmemda &= ~15;\n");
+ printf ("\tv1 = %s (memsa);\n", src);
+ printf ("\tv2 = %s (memsa + 4);\n", src);
+ printf ("\tv3 = %s (memsa + 8);\n", src);
+ printf ("\tv4 = %s (memsa + 12);\n", src);
+ printf ("\t%s (memda , v1);\n", dst);
+ printf ("\t%s (memda + 4, v2);\n", dst);
+ printf ("\t%s (memda + 8, v3);\n", dst);
+ printf ("\t%s (memda + 12, v4);\n", dst);
+ if ((opcode & 0xfff8) == 0xf600)
+ printf ("\tm68k_areg (regs, srcreg) += 16;\n");
+ else if ((opcode & 0xfff8) == 0xf608)
+ printf ("\tm68k_areg (regs, dstreg) += 16;\n");
+ }
+ }
+ break;
case i_PFLUSHN:
case i_PFLUSH:
#define MMU_SSW_LK 0x0200
#define MMU_SSW_ATC 0x0400
#define MMU_SSW_MA 0x0800
+#define MMU_SSW_CM 0x1000
#define MMU_SSW_CT 0x2000
+#define MMU_SSW_CU 0x4000
+#define MMU_SSW_CP 0x8000
#define TTR_I0 4
#define TTR_I1 5
#define CYCLE_STROBE 0x02
#define CYCLE_MISC 0x04
#define CYCLE_SPRITE 0x08
-#define CYCLE_BITPLANE 0x10
-#define CYCLE_COPPER 0x20
-#define CYCLE_BLITTER 0x40
-#define CYCLE_CPU 0x80
+#define CYCLE_COPPER 0x10
+#define CYCLE_BLITTER 0x20
+#define CYCLE_CPU 0x40
+#define CYCLE_CPUNASTY 0x80
extern unsigned long frametime, timeframes;
extern int plfstrt, plfstop, plffirstline, plflastline;
#define DMA_EVENT_BLITNASTY 2
#define DMA_EVENT_BLITFINISHED 4
#define DMA_EVENT_BPLFETCHUPDATE 8
+#define DMA_EVENT_COPPERWAKE 16
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);
#define CPU020_CLOCK_MULT 4
#define CACHELINES020 64
-#define CACHELINES040 1024 // 040 cache really isn't like this..
struct cache020
{
uae_u32 data;
uae_u32 tag;
uae_u32 valid:1;
};
+#define CACHESETS040 64
+struct cache040set
+{
+ uae_u32 data[4];
+ int valid[4];
+ uae_u32 tag;
+};
+#define CACHELINES040 4
+struct cache040
+{
+ struct cache040set cs[4];
+ int count;
+};
extern struct regstruct
{
static uae_u32 tt0_030, tt1_030, tc_030;
static uae_u16 mmusr_030;
-static struct cache020 cacheline020[CACHELINES020];
-static struct cache020 cacheline040[CACHELINES040];
+static struct cache020 caches020[CACHELINES020];
+static struct cache040 caches040[CACHELINES040];
#if COUNT_INSTRS
static unsigned long int instrcount[65536];
static void set_cpu_caches (void)
{
- int i;
+ int i, j;
if (currprefs.cpu_model < 68040) {
if (regs.cacr & 0x08) { // Clear Cache
for (i = 0; i < CACHELINES020; i++)
- cacheline020[i].valid = 0;
+ caches020[i].valid = 0;
regs.prefetch020addr = 0xff000000;
}
if (regs.cacr & 0x04) { // Clear Entry
- cacheline020[(regs.caar >> 2) & 0x3f].valid = 0;
+ caches020[(regs.caar >> 2) & 0x3f].valid = 0;
}
#ifdef JIT
set_cache_state (regs.cacr & 1);
set_cache_state ((regs.cacr & 0x8000) ? 1 : 0);
#endif
if (!(regs.cacr & 0x8000)) {
- for (i = 0; i < CACHELINES040; i++)
- cacheline040[i].valid = 0;
+ for (i = 0; i < CACHESETS040; i++) {
+ for (j = 0; j < CACHELINES040; j++) {
+ caches040[i].cs[j].valid[0] = 0;
+ caches040[i].cs[j].valid[1] = 0;
+ caches040[i].cs[j].valid[2] = 0;
+ caches040[i].cs[j].valid[3] = 0;
+ }
+ }
regs.prefetch020addr = 0xff000000;
}
}
m68k_areg (regs, 7) -= 2;
put_word (m68k_areg (regs, 7), regs.mmu_ssw);
m68k_areg (regs, 7) -= 4;
- put_word (m68k_areg (regs, 7), regs.mmu_fault_addr);
+ put_long (m68k_areg (regs, 7), regs.mmu_fault_addr);
} else {
}
#ifdef _WIN32
} __except (GetExceptionCode () == MMUEX) {
+ // movem to memory?
+ if ((opcode & 0xff80) == 0x4880)
+ regs.mmu_ssw |= MMU_SSW_CM;
// write bus errors restart at next instruction
if (regs.wb3_status & 0x80) {
// write_log (L"%08x %04x %d\n", regs.fault_pc, opcode, cpufunclen[opcode]);
return mcycles * 2;
}
-
+#if 0
STATIC_INLINE void fill_cache040 (uae_u32 addr)
{
- int index;
+ int index, i, j;
uae_u32 tag;
uae_u32 data;
- struct cache020 *c;
-
- addr &= ~3;
- index = (addr >> 2) & (CACHELINES040 - 1);
- tag = regs.s | (addr & ~((CACHELINES040 << 2) - 1));
- c = &cacheline040[index];
- if (c->valid && c->tag == tag) {
- // cache hit
- regs.prefetch020addr = addr;
- regs.prefetch020data = c->data;
- return;
+ struct cache040 *c;
+
+ addr &= ~15;
+ index = (addr >> 4) & (CACHESETS040 - 1);
+ tag = regs.s | (addr & ~((CACHESETS040 << 4) - 1));
+ c = &caches040[index];
+ for (i = 0; i < CACHELINES040; i++) {
+ struct cache040set *cs = &c->cs;
+ for (j = 0; j < 4; j++) {
+ if (cs->valid[j] && c->tag == tag[j]) {
+ // cache hit
+ regs.prefetch020addr = addr;
+ regs.prefetch020data = c->data[j];
+ return;
+ } if (cs->valid[j] == 0) {
+ inv = &cs->valid[j];
+ }
+ }
}
// cache miss
data = mem_access_delay_longi_read_020 (addr);
regs.prefetch020addr = addr;
regs.prefetch020data = data;
}
+#endif
STATIC_INLINE void fill_cache020 (uae_u32 addr)
{
addr &= ~3;
index = (addr >> 2) & (CACHELINES020 - 1);
tag = regs.s | (addr & ~((CACHELINES020 << 2) - 1));
- c = &cacheline020[index];
+ c = &caches020[index];
if (c->valid && c->tag == tag) {
// cache hit
regs.prefetch020addr = addr;
void fill_cache0x0 (uae_u32 addr)
{
+#if 0
if (currprefs.cpu_model >= 68040)
fill_cache040 (addr);
else
+#endif
fill_cache020 (addr);
}
{
HRESULT hr;
struct sound_dp *s = sd->data;
- WAVEFORMATEX *pwfx;
+ WAVEFORMATEX *pwfx, *pwfx_saved;
WAVEFORMATEXTENSIBLE wavfmt;
int final;
LPWSTR name = NULL;
final = 0;
rncnt = 0;
+ pwfx_saved = NULL;
for (;;) {
if (sd->channels == 6) {
hr = s->pAudioClient->lpVtbl->IsFormatSupported (s->pAudioClient, sharemode, &wavfmt.Format, &pwfx);
if (SUCCEEDED (hr) && hr != S_FALSE)
break;
- write_log (L"WASAPI: IsFormatSupported(%d,%08X,%d) %08X\n", sd->channels, rn[rncnt], sd->freq, hr);
+ write_log (L"WASAPI: IsFormatSupported(%d,%08X,%d) (%d,%d) %08X\n",
+ sd->channels, rn[rncnt], sd->freq,
+ pwfx ? pwfx->nChannels : -1, pwfx ? pwfx->nSamplesPerSec : -1,
+ hr);
+ if (final && SUCCEEDED (hr))
+ break;
if (hr != AUDCLNT_E_UNSUPPORTED_FORMAT && hr != S_FALSE)
goto error;
+ if (hr == S_FALSE && pwfx_saved == NULL) {
+ pwfx_saved = pwfx;
+ pwfx = NULL;
+ }
rncnt++;
if (rn[rncnt])
continue;
continue;
}
final = 1;
- if (pwfx == NULL)
+ if (pwfx_saved == NULL)
goto error;
- sd->channels = pwfx->nChannels;
- sd->freq = pwfx->nSamplesPerSec;
+ sd->channels = pwfx_saved->nChannels;
+ sd->freq = pwfx_saved->nSamplesPerSec;
}
size = sd->sndbufsize * sd->channels * 16 / 8;
name, s->wasapiexclusive, sd->channels, sd->freq, sd->sndbufsize, s->bufferFrameCount);
CoTaskMemFree (pwfx);
+ CoTaskMemFree (pwfx_saved);
CoTaskMemFree (name);
return 1;
error:
CoTaskMemFree (pwfx);
+ CoTaskMemFree (pwfx_saved);
CoTaskMemFree (name);
close_audio_wasapi (sd);
return 0;
#define WINUAEPUBLICBETA 1
-#define WINUAEBETA L"10"
-#define WINUAEDATE MAKEBD(2009, 8, 23)
+#define WINUAEBETA L"11"
+#define WINUAEDATE MAKEBD(2009, 8, 26)
#define WINUAEEXTRA L""
#define WINUAEREV L""
return tempvsync;
if (currprefs.ntscmode)
- newh = h * 50 / 60;
- else
newh = h * 60 / 50;
+ else
+ newh = h * 50 / 60;
hz = hz * dbl;
found = NULL;
+Beta 11:
+
+- fixed 68020 CE-mode cycle counting bug (too slow memory accesses)
+- MOVE16 MMU support update (fetch all data before writing), MOVES MMU
+ support update, MOVEM to memory MMU special handling support
+ (still not working with mmulib, reason unknown)
+- b10 blitter cycles given to CPU update was very wrong..
+- copper BFD=0 wait woke up too early in some cases (and real fix here)
+- calculate autoscale settings only when display window registers have
+ been stable at least 1 full scanline (also fixes NTSC "jumping")
+- WASAPI shared mode closest match update
+
Beta 10:
- and more reading of write-only register fixes, original Cardiaxx