From: Toni Wilen Date: Wed, 26 Aug 2009 15:03:08 +0000 (+0300) Subject: imported winuaesrc1620b11.zip X-Git-Tag: 2100~62 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=76e4bdb6b116f77a4ee1ae3f7eeb9ed458a26526;p=francis%2Fwinuae.git imported winuaesrc1620b11.zip --- diff --git a/blitter.c b/blitter.c index b3f2b13f..b2111e08 100644 --- a/blitter.c +++ b/blitter.c @@ -245,9 +245,10 @@ STATIC_INLINE const int *get_ch (void) 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]; @@ -256,9 +257,10 @@ STATIC_INLINE int channel_state (int cycles) } 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]; @@ -271,8 +273,6 @@ STATIC_INLINE int canblit (int hpos) { if (is_bitplane_dma (hpos)) return 0; - if (cycle_line[hpos] == CYCLE_CPU) - return -1; if (cycle_line[hpos]) return 0; return 1; @@ -657,7 +657,6 @@ static void decide_blitter_line (int hsync, int hpos) // final 2 idle cycles? if (blit_final) { if (blit_cyclecounter > get_ch ()[0]) { - bltdpt = bltcpt; blitter_done (last_blitter_hpos); return; } @@ -667,6 +666,7 @@ static void decide_blitter_line (int hsync, int hpos) /* 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; } @@ -695,6 +695,7 @@ static void decide_blitter_line (int hsync, int hpos) 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; @@ -839,7 +840,6 @@ STATIC_INLINE int blitter_doddma (int hpos) if (blit_ch == 1) blitter_hcounter1 = blitter_hcounter2; } - blit_final = 0; return wd; } @@ -989,6 +989,8 @@ void decide_blitter (int hpos) 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) { diff --git a/cpummu.c b/cpummu.c index 69dd7c77..aca34410 100644 --- a/cpummu.c +++ b/cpummu.c @@ -23,7 +23,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define DEBUG 0 +#define DEBUG 1 #include "sysconfig.h" #include "sysdeps.h" @@ -304,13 +304,15 @@ static void mmu_bus_error(uaecptr addr, int fc, int write, int size) 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); } @@ -460,6 +462,9 @@ static uaecptr REGPARAM2 mmu_lookup_pagetable(uaecptr addr, int super, int write 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; diff --git a/custom.c b/custom.c index e1473eaa..b67150e9 100644 --- a/custom.c +++ b/custom.c @@ -237,7 +237,7 @@ static unsigned int bplcon0d, bplcon0_res, bplcon0_planes, bplcon0_planes_limit; 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; @@ -260,6 +260,7 @@ static int diwfirstword, diwlastword; 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; @@ -2798,6 +2799,7 @@ static void calcdiw (void) plfstop = 0xff; plfstrt_start = HARD_DDF_START - 2; } + diw_change = 2; } /* display mode changed (lores, doubling etc..), recalculate everything */ @@ -4216,12 +4218,18 @@ static void update_copper (int until_hpos) /* 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 @@ -4297,8 +4305,9 @@ static void compute_spcflag_copper (int hpos) /* 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) { @@ -4307,7 +4316,7 @@ void blitter_done_notify (int hpos) if (cop_state.state != COP_bltwait) return; - hpos += 4; + hpos += 3; hpos &= ~1; if (hpos >= maxhpos) { hpos -= maxhpos; @@ -4316,6 +4325,8 @@ void blitter_done_notify (int hpos) 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; @@ -4651,6 +4662,8 @@ static void init_hardware_frame (void) last_planes_vpos = 0; diwfirstword_total = max_diwlastword; diwlastword_total = 0; + ddffirstword_total = max_diwlastword; + ddflastword_total = 0; plflastline_total = 0; plffirstline_total = maxvpos; } @@ -5250,23 +5263,34 @@ static void hsync_handler (void) 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 @@ -6614,18 +6638,21 @@ STATIC_INLINE int dma_cycle (void) 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; } @@ -6685,7 +6712,14 @@ void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v) 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); diff --git a/debug.c b/debug.c index 2612a23c..8e77f65d 100644 --- a/debug.c +++ b/debug.c @@ -811,6 +811,8 @@ static void decode_dma_record (int hpos, int vpos, int toggle) 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; diff --git a/disk.c b/disk.c index 949e0d51..945bb01b 100644 --- a/disk.c +++ b/disk.c @@ -2502,7 +2502,7 @@ static void disk_dmafinished (void) 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"); } } @@ -3079,12 +3079,12 @@ void DSKLEN (uae_u16 v, int hpos) } 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 (); } diff --git a/drawing.c b/drawing.c index f7008c73..c527846a 100644 --- a/drawing.c +++ b/drawing.c @@ -319,6 +319,7 @@ void notice_screen_contents_lost (void) 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 @@ -355,6 +356,18 @@ int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy) 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; diff --git a/gencpu.c b/gencpu.c index 7f8a58e8..f420af7c 100644 --- a/gencpu.c +++ b/gencpu.c @@ -49,6 +49,7 @@ static int cpulengths[65536]; #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 @@ -670,11 +671,20 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g 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) { @@ -722,7 +732,7 @@ static void genamode_e3 (amodes mode, char *reg, wordsizes size, char *name, int 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: @@ -810,19 +820,28 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha 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 (); @@ -867,11 +886,15 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha 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); } @@ -942,20 +965,20 @@ static void genmovemel_ce (uae_u16 opcode) 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; @@ -2855,23 +2878,20 @@ static void gen_opcode (unsigned long int opcode) 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; @@ -3117,64 +3137,57 @@ static void gen_opcode (unsigned long int opcode) 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: diff --git a/include/cpummu.h b/include/cpummu.h index c2b7e2d6..8c349e5c 100644 --- a/include/cpummu.h +++ b/include/cpummu.h @@ -164,7 +164,10 @@ extern void mmu_dump_tables(void); #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 diff --git a/include/custom.h b/include/custom.h index 7367581f..d86b2283 100644 --- a/include/custom.h +++ b/include/custom.h @@ -122,10 +122,10 @@ extern frame_time_t syncbase; #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; diff --git a/include/debug.h b/include/debug.h index 93d73ae5..2e0c0821 100644 --- a/include/debug.h +++ b/include/debug.h @@ -83,6 +83,7 @@ struct dma_rec #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); diff --git a/include/newcpu.h b/include/newcpu.h index 4519ab95..4b65308d 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -93,13 +93,25 @@ typedef double fptype; #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 { diff --git a/newcpu.c b/newcpu.c index 2bfc4378..1730da62 100644 --- a/newcpu.c +++ b/newcpu.c @@ -79,8 +79,8 @@ static uae_u64 srp_030, crp_030; 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]; @@ -134,16 +134,16 @@ void dump_counts (void) 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); @@ -157,8 +157,14 @@ static void set_cpu_caches (void) 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; } } @@ -1212,7 +1218,7 @@ static void Exception_normal (int nr, uaecptr oldpc) 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 { @@ -2587,6 +2593,9 @@ static void m68k_run_mmu040 (void) } #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]); @@ -3645,23 +3654,30 @@ int getDivs68kCycles (uae_s32 dividend, uae_s16 divisor) 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); @@ -3673,6 +3689,7 @@ STATIC_INLINE void fill_cache040 (uae_u32 addr) regs.prefetch020addr = addr; regs.prefetch020data = data; } +#endif STATIC_INLINE void fill_cache020 (uae_u32 addr) { @@ -3684,7 +3701,7 @@ 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; @@ -3704,9 +3721,11 @@ STATIC_INLINE void fill_cache020 (uae_u32 addr) void fill_cache0x0 (uae_u32 addr) { +#if 0 if (currprefs.cpu_model >= 68040) fill_cache040 (addr); else +#endif fill_cache020 (addr); } diff --git a/od-win32/sounddep/sound.c b/od-win32/sounddep/sound.c index 1cd7a936..12530a0e 100644 --- a/od-win32/sounddep/sound.c +++ b/od-win32/sounddep/sound.c @@ -694,7 +694,7 @@ static int open_audio_wasapi (struct sound_data *sd, int index, int exclusive) { HRESULT hr; struct sound_dp *s = sd->data; - WAVEFORMATEX *pwfx; + WAVEFORMATEX *pwfx, *pwfx_saved; WAVEFORMATEXTENSIBLE wavfmt; int final; LPWSTR name = NULL; @@ -753,6 +753,7 @@ static int open_audio_wasapi (struct sound_data *sd, int index, int exclusive) final = 0; rncnt = 0; + pwfx_saved = NULL; for (;;) { if (sd->channels == 6) { @@ -788,9 +789,18 @@ static int open_audio_wasapi (struct sound_data *sd, int index, int exclusive) 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; @@ -810,10 +820,10 @@ static int open_audio_wasapi (struct sound_data *sd, int index, int exclusive) 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; @@ -915,12 +925,14 @@ static int open_audio_wasapi (struct sound_data *sd, int index, int exclusive) 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; diff --git a/od-win32/win32.h b/od-win32/win32.h index dffc8353..3502854a 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -17,8 +17,8 @@ #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"" diff --git a/od-win32/win32gfx.c b/od-win32/win32gfx.c index 7e94ab8e..373e9e81 100644 --- a/od-win32/win32gfx.c +++ b/od-win32/win32gfx.c @@ -1709,9 +1709,9 @@ int vsync_switchmode (int hz, int oldhz) return tempvsync; if (currprefs.ntscmode) - newh = h * 50 / 60; - else newh = h * 60 / 50; + else + newh = h * 50 / 60; hz = hz * dbl; found = NULL; diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index f3d06cf9..4bd9bf35 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,16 @@ +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