From: Toni Wilen Date: Sat, 26 Jan 2013 16:22:38 +0000 (+0200) Subject: 2600b4 X-Git-Tag: 2600~17 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=94e50e87ab6703e506ca5d58d53c48bc90298f9e;p=francis%2Fwinuae.git 2600b4 --- diff --git a/a2065.cpp b/a2065.cpp index 91ea0be3..fe6e57cf 100644 --- a/a2065.cpp +++ b/a2065.cpp @@ -427,7 +427,7 @@ static void do_transmit (void) int i; int size, outsize; int err, add_fcs; - uae_u32 addr; + uae_u32 addr, bufaddr; uae_u8 *p; uae_u16 tmd0, tmd1, tmd2, tmd3; @@ -436,7 +436,8 @@ static void do_transmit (void) outsize = 0; tdr_offset %= am_tdr_tlen; - p = boardram + ((am_tdr_tdra + tdr_offset * 8) & RAM_MASK); + bufaddr = am_tdr_tdra + tdr_offset * 8; + p = boardram + (bufaddr & RAM_MASK); tmd1 = (p[3] << 8) | (p[2] << 0); if (!(tmd1 & TX_OWN) || !(tmd1 & TX_STP)) { tdr_offset++; @@ -496,10 +497,10 @@ static void do_transmit (void) if ((am_mode & MODE_DTCR) && !add_fcs) outsize -= 4; // do not include checksum bytes if (log_a2065 && log_transmit) { - write_log (_T("A2065->DST:%02X.%02X.%02X.%02X.%02X.%02X SRC:%02X.%02X.%02X.%02X.%02X.%02X E=%04X S=%d\n"), + write_log (_T("A2065->DST:%02X.%02X.%02X.%02X.%02X.%02X SRC:%02X.%02X.%02X.%02X.%02X.%02X E=%04X S=%d ADDR=%04X\n"), d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], - (d[12] << 8) | d[13], outsize); + (d[12] << 8) | d[13], outsize, bufaddr); } transmitlen = outsize; if (mungepacket (d, transmitlen)) { @@ -642,12 +643,16 @@ static void chip_wput (uaecptr addr, uae_u16 v) csr[0] &= ~t; csr[0] &= ~CSR0_ERR; - if ((csr[0] & (CSR0_STOP | CSR0_STRT | CSR0_INIT)) == (CSR0_STOP | CSR0_STRT | CSR0_INIT)) - csr[0] &= ~(CSR0_STRT | CSR0_INIT); - if (csr[0] & CSR0_INIT) - csr[0] &= ~CSR0_STOP; + if ((csr[0] & CSR0_STOP) && !(oreg & CSR0_STOP)) { + + csr[0] = CSR0_STOP; + if (log_a2065) + write_log (_T("A2065: STOP.\n")); + csr[3] = 0; + am_initialized = 0; + + } else if ((csr[0] & CSR0_STRT) && !(oreg & CSR0_STRT) && (oreg & CSR0_STOP)) { - if ((csr[0] & CSR0_STRT) && !(oreg & CSR0_STRT)) { csr[0] &= ~CSR0_STOP; if (!(am_mode & MODE_DTX)) csr[0] |= CSR0_TXON; @@ -655,22 +660,16 @@ static void chip_wput (uaecptr addr, uae_u16 v) csr[0] |= CSR0_RXON; if (log_a2065) write_log (_T("A2065: START.\n")); - } - - if ((csr[0] & CSR0_STOP) && !(oreg & CSR0_STOP)) { - csr[0] = CSR0_STOP; - if (log_a2065) - write_log (_T("A2065: STOP.\n")); - csr[3] = 0; - am_initialized = 0; - } + + } else if ((csr[0] & CSR0_INIT) && (oreg & CSR0_STOP) && !(oreg & CSR0_INIT)) { - if ((csr[0] & CSR0_INIT) && am_initialized == 0) { if (log_a2065) write_log (_T("A2065: INIT.\n")); chip_init (); csr[0] |= CSR0_IDON; + csr[0] &= ~(CSR0_RXON | CSR0_TXON | CSR0_STOP); am_initialized = 1; + } if ((csr[0] & CSR0_STRT) && am_initialized) { diff --git a/a2091.cpp b/a2091.cpp index e9b1c3b6..be0108d4 100644 --- a/a2091.cpp +++ b/a2091.cpp @@ -421,14 +421,16 @@ static bool wd_do_transfer_out (void) write_log (_T("%s SCSI O [%02X] %d/%d TC=%d %s\n"), WD33C93, wdregs[WD_COMMAND_PHASE], scsi->offset, scsi->data_len, gettc (), scsitostring ()); #endif if (wdregs[WD_COMMAND_PHASE] < 0x20) { + int msg = wd_data[0]; /* message was sent */ setphase (0x20); wd_phase = CSR_XFER_DONE | PHS_COMMAND; scsi->status = 0; scsi_start_transfer (scsi); #if WD33C93_DEBUG > 0 - write_log (_T("%s SCSI got MESSAGE %02X\n"), WD33C93, wd_data[0]); + write_log (_T("%s SCSI got MESSAGE %02X\n"), WD33C93, msg); #endif + scsi->message[0] = msg; } else if (wdregs[WD_COMMAND_PHASE] == 0x30) { #if WD33C93_DEBUG > 0 write_log (_T("%s SCSI got COMMAND %02X\n"), WD33C93, wd_data[0]); @@ -536,6 +538,7 @@ static void wd_cmd_sel_xfer (bool atn) return; } if (!wd_selected) { + scsi->message[0] = 0x80; wd_selected = true; wdregs[WD_COMMAND_PHASE] = 0x10; } @@ -750,6 +753,7 @@ static void wd_cmd_sel (bool atn) } scsi_start_transfer (scsi); wd_selected = true; + scsi->message[0] = 0x80; set_status (CSR_SELECT, 2); if (atn) { set_status (CSR_SRV_REQ | PHS_MESS_OUT, 4); diff --git a/blitter.cpp b/blitter.cpp index d5275cc0..38ef1017 100644 --- a/blitter.cpp +++ b/blitter.cpp @@ -7,11 +7,6 @@ * (c) 2002 - 2005 Toni Wilen */ -//#define BLITTER_DEBUG_NOWAIT -//#define BLITTER_DEBUG -//#define BLITTER_DEBUG_NO_D -//#define BLITTER_INSTANT - #define SPEEDUP #include "sysconfig.h" @@ -28,6 +23,17 @@ #include "savestate.h" #include "debug.h" +// 1 = logging +// 2 = no wait detection +// 4 = no D +// 8 = instant + +#ifdef BLITTER_DEBUG +int log_blitter = 1; +#else +int log_blitter = 0; +#endif + /* we must not change ce-mode while blitter is running.. */ static int blitter_cycle_exact; static int blt_statefile_type; @@ -46,10 +52,8 @@ static int blit_add; static int blit_modadda, blit_modaddb, blit_modaddc, blit_modaddd; static int blit_ch; -#ifdef BLITTER_DEBUG static int blitter_dontdo; static int blitter_delayed_debug; -#endif #ifdef BLITTER_SLOWDOWNDEBUG static int blitter_slowdowndebug; #endif @@ -347,19 +351,18 @@ static void blitter_done (int hpos) record_dma_event (DMA_EVENT_BLITFINISHED, hpos, vpos); event2_remevent (ev2_blitter); unset_special (SPCFLAG_BLTNASTY); -#ifdef BLITTER_DEBUG - write_log (_T("cycles %d, missed %d, total %d\n"), - blit_totalcyclecounter, blit_misscyclecounter, blit_totalcyclecounter + blit_misscyclecounter); -#endif + if (log_blitter) + write_log (_T("cycles %d, missed %d, total %d\n"), + blit_totalcyclecounter, blit_misscyclecounter, blit_totalcyclecounter + blit_misscyclecounter); } STATIC_INLINE void chipmem_agnus_wput2 (uaecptr addr, uae_u32 w) { last_custom_value1 = w; -#ifndef BLITTER_DEBUG_NO_D - chipmem_wput_indirect (addr, w); - debug_wputpeekdma (addr, w); -#endif + if (!(log_blitter & 4)) { + chipmem_wput_indirect (addr, w); + debug_wputpeekdma (addr, w); + } } static void blitter_dofast (void) @@ -791,14 +794,14 @@ static void actually_do_blit (void) static void blitter_doit (void) { - #ifdef BLITTER_DEBUG - if (!blitter_dontdo) + if (log_blitter) { + if (!blitter_dontdo) + actually_do_blit (); + else + bltstate = BLT_done; + } else { actually_do_blit (); - else - bltstate = BLT_done; -#else - actually_do_blit (); -#endif + } blitter_done (current_hpos ()); } @@ -1022,12 +1025,12 @@ void decide_blitter (int hpos) if (bltstate == BLT_done) return; -#ifdef BLITTER_DEBUG - if (blitter_delayed_debug) { + + if (log_blitter && blitter_delayed_debug) { blitter_delayed_debug = 0; blitter_dump (); } -#endif + if (!blitter_cycle_exact) return; @@ -1224,9 +1227,8 @@ static void blit_bltset (int con) blit_frozen = 1; write_log (_T("BLITTER: frozen! %d (%d) -> %d (%d) %08X\n"), original_ch, iseo, blit_ch, isen, M68K_GETPC); } else if (!iseo && isen) { -#ifdef BLITTER_DEBUG_NOWAIT - write_log (_T("BLITTER: on the fly %d (%d) -> %d (%d) switch\n"), original_ch, iseo, blit_ch, isen); -#endif + if (log_blitter & 2) + write_log (_T("BLITTER: on the fly %d (%d) -> %d (%d) switch\n"), original_ch, iseo, blit_ch, isen); } } @@ -1314,14 +1316,15 @@ static void do_blitter2 (int hpos, int copper) int cycles; int cleanstart; -#ifdef BLITTER_DEBUG_NOWAIT - if (bltstate != BLT_done) { - if (blit_final) { - write_log (_T("blitter was already active! PC=%08x\n"), M68K_GETPC); - //activate_debugger(); + if ((log_blitter & 2)) { + if (bltstate != BLT_done) { + if (blit_final) { + write_log (_T("blitter was already active! PC=%08x\n"), M68K_GETPC); + //activate_debugger(); + } } } -#endif + cleanstart = 0; if (bltstate == BLT_done) { if (blit_faulty > 0) @@ -1369,25 +1372,25 @@ static void do_blitter2 (int hpos, int copper) original_line = blitline; } -#ifdef BLITTER_DEBUG - blitter_dontdo = 0; - if (1) { - int ch = 0; - if (blit_ch & 1) - ch++; - if (blit_ch & 2) - ch++; - if (blit_ch & 4) - ch++; - if (blit_ch & 8) - ch++; - write_log (_T("blitstart: %dx%d ch=%d %d*%d=%d d=%d f=%02X n=%d pc=%p l=%d dma=%04X %s\n"), - blt_info.hblitsize, blt_info.vblitsize, ch, blit_diag[0], cycles, blit_diag[0] * cycles, - blitdesc ? 1 : 0, blitfill, dmaen (DMA_BLITPRI) ? 1 : 0, M68K_GETPC, blitline, - dmacon, ((dmacon & (DMA_MASTER | DMA_BLITTER)) == (DMA_MASTER | DMA_BLITTER)) ? _T("") : _T(" off!")); - blitter_dump (); + if (log_blitter) { + blitter_dontdo = 0; + if (1) { + int ch = 0; + if (blit_ch & 1) + ch++; + if (blit_ch & 2) + ch++; + if (blit_ch & 4) + ch++; + if (blit_ch & 8) + ch++; + write_log (_T("blitstart: %dx%d ch=%d %d*%d=%d d=%d f=%02X n=%d pc=%p l=%d dma=%04X %s\n"), + blt_info.hblitsize, blt_info.vblitsize, ch, blit_diag[0], cycles, blit_diag[0] * cycles, + blitdesc ? 1 : 0, blitfill, dmaen (DMA_BLITPRI) ? 1 : 0, M68K_GETPC, blitline, + dmacon, ((dmacon & (DMA_MASTER | DMA_BLITTER)) == (DMA_MASTER | DMA_BLITTER)) ? _T("") : _T(" off!")); + blitter_dump (); + } } -#endif bltstate = BLT_init; blit_slowdown = 0; @@ -1412,18 +1415,18 @@ static void do_blitter2 (int hpos, int copper) blit_maxcyclecounter = 0x7fffffff; if (blitter_cycle_exact) { -#ifdef BLITTER_INSTANT - blitter_handler (0); -#else - blitter_hcounter1 = blitter_hcounter2 = 0; - blitter_vcounter1 = blitter_vcounter2 = 0; - if (blit_nod) - blitter_vcounter2 = blt_info.vblitsize; - blit_cyclecounter = -BLITTER_STARTUP_CYCLES; - blit_waitcyclecounter = copper; - blit_startcycles = 0; - blit_maxcyclecounter = blt_info.hblitsize * blt_info.vblitsize + 2; -#endif + if (log_blitter & 8) { + blitter_handler (0); + } else { + blitter_hcounter1 = blitter_hcounter2 = 0; + blitter_vcounter1 = blitter_vcounter2 = 0; + if (blit_nod) + blitter_vcounter2 = blt_info.vblitsize; + blit_cyclecounter = -BLITTER_STARTUP_CYCLES; + blit_waitcyclecounter = copper; + blit_startcycles = 0; + blit_maxcyclecounter = blt_info.hblitsize * blt_info.vblitsize + 2; + } return; } @@ -1512,15 +1515,14 @@ void maybe_blit (int hpos, int hack) warned--; debugtest (DEBUGTEST_BLITTER, _T("program does not wait for blitter tc=%d\n"), blit_cyclecounter); -#ifdef BLITTER_DEBUG - warned = 0; -#endif -#ifdef BLITTER_DEBUG_NOWAIT - warned = 10; - write_log (_T("program does not wait for blitter PC=%08x\n"), M68K_GETPC); - //activate_debugger (); - //blitter_done (hpos); -#endif + if (log_blitter) + warned = 0; + if (log_blitter & 2) { + warned = 10; + write_log (_T("program does not wait for blitter PC=%08x\n"), M68K_GETPC); + //activate_debugger (); + //blitter_done (hpos); + } } if (blitter_cycle_exact) { @@ -1533,9 +1535,8 @@ void maybe_blit (int hpos, int hack) blitter_handler (0); end:; -#ifdef BLITTER_DEBUG - blitter_delayed_debug = 1; -#endif + if (log_blitter) + blitter_delayed_debug = 1; } int blitnasty (void) diff --git a/cpummu.cpp b/cpummu.cpp index 64b52a94..9ed001e3 100644 --- a/cpummu.cpp +++ b/cpummu.cpp @@ -47,8 +47,11 @@ struct mmu_atc_line mmu_atc_array[ATC_TYPE][ATC_WAYS][ATC_SLOTS]; bool mmu_pagesize_8k; int mmu060_state; -uae_u16 mmu060_opcode; +uae_u16 mmu_opcode; +bool mmu_restart; static bool locked_rmw_cycle; +static bool ismoves; +bool mmu_ttr_enabled; int mmu040_movem; uaecptr mmu040_movem_ea; @@ -96,6 +99,10 @@ void mmu_make_transparent_region(uaecptr baseaddr, uae_u32 size, int datamode) #endif } +void mmu_tt_modified (void) +{ + mmu_ttr_enabled = ((regs.dtt0 | regs.dtt1 | regs.itt0 | regs.itt1) & MMU_TTR_BIT_ENABLED) != 0; +} #if 0 @@ -248,11 +255,24 @@ static ALWAYS_INLINE int mmu_get_fc(bool super, bool data) return (super ? 4 : 0) | (data ? 1 : 2); } -static void mmu_bus_error(uaecptr addr, int fc, bool write, int size, uae_u32 status) +static void mmu_bus_error(uaecptr addr, int fc, bool write, int size, bool rmw, uae_u32 status) { if (currprefs.mmu_model == 68040) { uae_u16 ssw = 0; + if (ismoves) { + // MOVES special behavior + int fc2 = write ? regs.dfc : regs.sfc; + if (fc2 == 0 || fc2 == 3 || fc2 == 4 || fc2 == 7) + ssw |= MMU_SSW_TT1; + if ((fc2 & 3) != 3) + fc2 &= ~2; +#if MMUDEBUG > 0 + write_log (_T("040 MMU MOVES fc=%d -> %d\n"), fc, fc2); +#endif + fc = fc2; + } + ssw |= fc & MMU_SSW_TM; /* TM = FC */ switch (size) { case sz_byte: @@ -267,29 +287,33 @@ static void mmu_bus_error(uaecptr addr, int fc, bool write, int size, uae_u32 st case 16: // MOVE16 ssw |= MMU_SSW_SIZE_L; // ?? ssw |= MMU_SSW_TT0; + write_log (_T("040 MMU MOVE16 FAULT!\n")); break; } - regs.wb3_status = write ? 0x80 | ssw : 0; + regs.wb3_status = write ? 0x80 | (ssw & 0x7f) : 0; if (!write) ssw |= MMU_SSW_RW; if (mmu040_movem) { ssw |= MMU_SSW_CM; - addr = mmu040_movem_ea; + regs.mmu_effective_addr = mmu040_movem_ea; mmu040_movem = 0; - write_log (_T("040 MMU_SSW_CM!\n")); + write_log (_T("040 MMU_SSW_CM EA=%08X\n"), mmu040_movem_ea); } if (locked_rmw_cycle) { - ssw |= MMU_SSW_LK; + ssw |= MMU_SSW_LK | MMU_SSW_RW; locked_rmw_cycle = false; +#if MMUDEBUG > 0 write_log (_T("040 MMU_SSW_LK!\n")); +#endif } - regs.mmu_ssw = ssw | MMU_SSW_ATC; + ssw |= MMU_SSW_ATC; + regs.mmu_ssw = ssw; #if MMUDEBUG > 0 - write_log(_T("040 BUS ERROR: fc=%d w=%d logical=%08x ssw=%04x PC=%08x\n"), fc, write, addr, ssw, m68k_getpc()); + write_log(_T("BF: fc=%d w=%d logical=%08x ssw=%04x PC=%08x INS=%04X\n"), fc, write, addr, ssw, m68k_getpc(), mmu_opcode); #endif } else { uae_u32 fslw = 0; @@ -320,12 +344,17 @@ static void mmu_bus_error(uaecptr addr, int fc, bool write, int size, uae_u32 st break; } if ((fc & 3) == 2) { + // instruction faults always point to opcode address + addr = regs.instruction_pc; if (mmu060_state == 0) { fslw |= MMU_FSLW_IO; // opword fetch } else { fslw |= MMU_FSLW_IO | MMU_FSLW_MA; // extension word } } + if (rmw) { + fslw |= MMU_FSLW_W | MMU_FSLW_R; + } if (locked_rmw_cycle) { fslw |= MMU_FSLW_LK; locked_rmw_cycle = false; @@ -335,24 +364,26 @@ static void mmu_bus_error(uaecptr addr, int fc, bool write, int size, uae_u32 st regs.mmu_fslw = fslw; #if MMUDEBUG > 0 - write_log(_T("060 BUS ERROR: fc=%d w=%d logical=%08x ssw=%08x PC=%08x\n"), fc, write, addr, fslw, m68k_getpc()); + write_log(_T("BF: fc=%d w=%d logical=%08x ssw=%08x rmw=%d PC=%08x INS=%04X\n"), fc, write, addr, fslw, rmw, m68k_getpc(), mmu_opcode); #endif } regs.mmu_fault_addr = addr; + #if 0 - if (addr == 0x00002180) { + if (m68k_getpc () == 0x0004B0AC) { write_log (_T("*")); - - extern void activate_debugger(void); - activate_debugger (); +#if 0 + extern void activate_debugger(void); + activate_debugger (); +#endif } #endif THROW(2); } -void mmu_bus_error_ttr_write_fault(uaecptr addr, bool super, bool data, uae_u32 val, int size) +void mmu_bus_error_ttr_write_fault(uaecptr addr, bool super, bool data, uae_u32 val, int size, bool rmw) { uae_u32 status = 0; @@ -360,7 +391,7 @@ void mmu_bus_error_ttr_write_fault(uaecptr addr, bool super, bool data, uae_u32 status |= MMU_FSLW_TTR; } regs.wb3_data = val; - mmu_bus_error(addr, mmu_get_fc (super, data), true, size, status); + mmu_bus_error(addr, mmu_get_fc (super, data), true, size, false, status); } @@ -389,6 +420,9 @@ static uaecptr mmu_fill_atc(uaecptr addr, bool super, bool data, bool write, str } ENDTRY if ((desc & 1) && (!super && desc & MMU_MMUSR_S)) { *status |= MMU_FSLW_SP; +#if MMUDEBUG > 1 + write_log (_T("MMU: supervisor protected %x\n"), addr); +#endif l->valid = 0; l->global = 0; } else if ((desc & 1) == 0) { @@ -409,7 +443,7 @@ static ALWAYS_INLINE bool mmu_fill_atc_try(uaecptr addr, bool super, bool data, { mmu_fill_atc(addr,super,data,write,l1, status); if (!(l1->valid)) { -#if MMUDEBUG > 1 +#if MMUDEBUG > 2 write_log(_T("MMU: non-resident page (%x,%x)!\n"), addr, regs.pc); #endif goto fail; @@ -470,8 +504,8 @@ static uaecptr REGPARAM2 mmu_lookup_pagetable(uaecptr addr, bool super, bool wri desc = phys_get_long(desc_addr); if ((desc & 2) == 0) { #if MMUDEBUG > 1 - write_log(_T("MMU: invalid root descriptor %s for %x desc at %x desc=%x %s at %d\n"), super ? _T("srp"):_T("urp"), - addr,desc_addr,desc,__FILE__,__LINE__); + write_log(_T("MMU: invalid root descriptor %s for %x desc at %x desc=%x\n"), super ? _T("srp"):_T("urp"), + addr, desc_addr, desc); #endif *status |= MMU_FSLW_PTA; return 0; @@ -487,8 +521,8 @@ static uaecptr REGPARAM2 mmu_lookup_pagetable(uaecptr addr, bool super, bool wri desc = phys_get_long(desc_addr); if ((desc & 2) == 0) { #if MMUDEBUG > 1 - write_log(_T("MMU: invalid ptr descriptor %s for %x desc at %x desc=%x %s at %d\n"), super ? _T("srp"):_T("urp"), - addr,desc_addr,desc,__FILE__,__LINE__); + write_log(_T("MMU: invalid ptr descriptor %s for %x desc at %x desc=%x\n"), super ? _T("srp"):_T("urp"), + addr, desc_addr, desc); #endif *status |= MMU_FSLW_PTB; return 0; @@ -513,13 +547,17 @@ static uaecptr REGPARAM2 mmu_lookup_pagetable(uaecptr addr, bool super, bool wri desc = phys_get_long(desc_addr); } if ((desc & 1) == 0) { -#if MMUDEBUG > 1 - write_log(_T("MMU: invalid page descriptor log=%0lx desc=%08x @%08x %s at %d\n"), addr, desc, desc_addr,__FILE__,__LINE__); +#if MMUDEBUG > 2 + write_log(_T("MMU: invalid page descriptor log=%0lx desc=%08x @%08x\n"), addr, desc, desc_addr); #endif - if ((desc & 3) == 2) + if ((desc & 3) == 2) { *status |= MMU_FSLW_IL; - else +#if MMUDEBUG > 1 + write_log(_T("MMU: double indirect descriptor log=%0lx desc=%08x @%08x\n"), addr, desc, desc_addr); +#endif + } else { *status |= MMU_FSLW_PF; + } return desc; } @@ -544,14 +582,14 @@ static uaecptr REGPARAM2 mmu_lookup_pagetable(uaecptr addr, bool super, bool wri return desc; } -uae_u16 REGPARAM2 mmu_get_word_unaligned(uaecptr addr, bool data) +uae_u16 REGPARAM2 mmu_get_word_unaligned(uaecptr addr, bool data, bool rmw) { uae_u16 res; - res = (uae_u16)mmu_get_byte(addr, data, sz_word) << 8; + res = (uae_u16)mmu_get_byte(addr, data, sz_word, rmw) << 8; SAVE_EXCEPTION; TRY(prb) { - res |= mmu_get_byte(addr + 1, data, sz_word); + res |= mmu_get_byte(addr + 1, data, sz_word, rmw); RESTORE_EXCEPTION; } CATCH(prb) { @@ -564,15 +602,15 @@ uae_u16 REGPARAM2 mmu_get_word_unaligned(uaecptr addr, bool data) return res; } -uae_u32 REGPARAM2 mmu_get_long_unaligned(uaecptr addr, bool data) +uae_u32 REGPARAM2 mmu_get_long_unaligned(uaecptr addr, bool data, bool rmw) { uae_u32 res; if (likely(!(addr & 1))) { - res = (uae_u32)mmu_get_word(addr, data, sz_long) << 16; + res = (uae_u32)mmu_get_word(addr, data, sz_long, rmw) << 16; SAVE_EXCEPTION; TRY(prb) { - res |= mmu_get_word(addr + 2, data, sz_long); + res |= mmu_get_word(addr + 2, data, sz_long, rmw); RESTORE_EXCEPTION; } CATCH(prb) { @@ -583,12 +621,12 @@ uae_u32 REGPARAM2 mmu_get_long_unaligned(uaecptr addr, bool data) THROW_AGAIN(prb); } ENDTRY } else { - res = (uae_u32)mmu_get_byte(addr, data, sz_long) << 8; + res = (uae_u32)mmu_get_byte(addr, data, sz_long, rmw) << 8; SAVE_EXCEPTION; TRY(prb) { - res = (res | mmu_get_byte(addr + 1, data, sz_long)) << 8; - res = (res | mmu_get_byte(addr + 2, data, sz_long)) << 8; - res |= mmu_get_byte(addr + 3, data, sz_long); + res = (res | mmu_get_byte(addr + 1, data, sz_long, rmw)) << 8; + res = (res | mmu_get_byte(addr + 2, data, sz_long, rmw)) << 8; + res |= mmu_get_byte(addr + 3, data, sz_long, rmw); RESTORE_EXCEPTION; } CATCH(prb) { @@ -602,7 +640,7 @@ uae_u32 REGPARAM2 mmu_get_long_unaligned(uaecptr addr, bool data) return res; } -uae_u16 REGPARAM2 mmu_get_rmw_word_unaligned(uaecptr addr) +uae_u16 REGPARAM2 mmu_get_lrmw_word_unaligned(uaecptr addr) { uae_u16 res; @@ -622,7 +660,7 @@ uae_u16 REGPARAM2 mmu_get_rmw_word_unaligned(uaecptr addr) return res; } -uae_u32 REGPARAM2 mmu_get_rmw_long_unaligned(uaecptr addr) +uae_u32 REGPARAM2 mmu_get_lrmw_long_unaligned(uaecptr addr) { uae_u32 res; @@ -660,50 +698,50 @@ uae_u32 REGPARAM2 mmu_get_rmw_long_unaligned(uaecptr addr) return res; } uae_u8 REGPARAM2 mmu_get_byte_slow(uaecptr addr, bool super, bool data, - int size, struct mmu_atc_line *cl) + int size, bool rmw, struct mmu_atc_line *cl) { uae_u32 status; if (!mmu_fill_atc_try(addr, super, data, 0, cl, &status)) { - mmu_bus_error(addr, mmu_get_fc(super, data), 0, size, status); + mmu_bus_error(addr, mmu_get_fc(super, data), 0, size, rmw, status); return 0; } return phys_get_byte(mmu_get_real_address(addr, cl)); } uae_u16 REGPARAM2 mmu_get_word_slow(uaecptr addr, bool super, bool data, - int size, struct mmu_atc_line *cl) + int size, bool rmw, struct mmu_atc_line *cl) { uae_u32 status; if (!mmu_fill_atc_try(addr, super, data, 0, cl, &status)) { - mmu_bus_error(addr, mmu_get_fc(super, data), 0, size, status); + mmu_bus_error(addr, mmu_get_fc(super, data), 0, size, rmw, status); return 0; } return phys_get_word(mmu_get_real_address(addr, cl)); } uae_u32 REGPARAM2 mmu_get_long_slow(uaecptr addr, bool super, bool data, - int size, struct mmu_atc_line *cl) + int size, bool rmw, struct mmu_atc_line *cl) { uae_u32 status; if (!mmu_fill_atc_try(addr, super, data, 0, cl, &status)) { - mmu_bus_error(addr, mmu_get_fc(super, data), 0, size, status); + mmu_bus_error(addr, mmu_get_fc(super, data), 0, size, rmw, status); return 0; } return phys_get_long(mmu_get_real_address(addr, cl)); } -void REGPARAM2 mmu_put_long_unaligned(uaecptr addr, uae_u32 val, bool data) +void REGPARAM2 mmu_put_long_unaligned(uaecptr addr, uae_u32 val, bool data, bool rmw) { SAVE_EXCEPTION; TRY(prb) { if (likely(!(addr & 1))) { - mmu_put_word(addr, val >> 16, data, sz_long); - mmu_put_word(addr + 2, val, data, sz_long); + mmu_put_word(addr, val >> 16, data, sz_long, rmw); + mmu_put_word(addr + 2, val, data, sz_long, rmw); } else { - mmu_put_byte(addr, val >> 24, data, sz_long); - mmu_put_byte(addr + 1, val >> 16, data, sz_long); - mmu_put_byte(addr + 2, val >> 8, data, sz_long); - mmu_put_byte(addr + 3, val, data, sz_long); + mmu_put_byte(addr, val >> 24, data, sz_long, rmw); + mmu_put_byte(addr + 1, val >> 16, data, sz_long, rmw); + mmu_put_byte(addr + 2, val >> 8, data, sz_long, rmw); + mmu_put_byte(addr + 3, val, data, sz_long, rmw); } RESTORE_EXCEPTION; } @@ -719,12 +757,12 @@ void REGPARAM2 mmu_put_long_unaligned(uaecptr addr, uae_u32 val, bool data) } ENDTRY } -void REGPARAM2 mmu_put_word_unaligned(uaecptr addr, uae_u16 val, bool data) +void REGPARAM2 mmu_put_word_unaligned(uaecptr addr, uae_u16 val, bool data, bool rmw) { SAVE_EXCEPTION; TRY(prb) { - mmu_put_byte(addr, val >> 8, data, sz_word); - mmu_put_byte(addr + 1, val, data, sz_word); + mmu_put_byte(addr, val >> 8, data, sz_word, rmw); + mmu_put_byte(addr + 1, val, data, sz_word, rmw); RESTORE_EXCEPTION; } CATCH(prb) { @@ -740,36 +778,36 @@ void REGPARAM2 mmu_put_word_unaligned(uaecptr addr, uae_u16 val, bool data) } void REGPARAM2 mmu_put_byte_slow(uaecptr addr, uae_u8 val, bool super, bool data, - int size, struct mmu_atc_line *cl) + int size, bool rmw, struct mmu_atc_line *cl) { uae_u32 status; if (!mmu_fill_atc_try(addr, super, data, 1, cl, &status)) { regs.wb3_data = val; - mmu_bus_error(addr, mmu_get_fc(super, data), 1, size, status); + mmu_bus_error(addr, mmu_get_fc(super, data), 1, size, rmw, status); return; } phys_put_byte(mmu_get_real_address(addr, cl), val); } void REGPARAM2 mmu_put_word_slow(uaecptr addr, uae_u16 val, bool super, bool data, - int size, struct mmu_atc_line *cl) + int size, bool rmw, struct mmu_atc_line *cl) { uae_u32 status; if (!mmu_fill_atc_try(addr, super, data, 1, cl, &status)) { regs.wb3_data = val; - mmu_bus_error(addr, mmu_get_fc(super, data), 1, size, status); + mmu_bus_error(addr, mmu_get_fc(super, data), 1, size, rmw, status); return; } phys_put_word(mmu_get_real_address(addr, cl), val); } void REGPARAM2 mmu_put_long_slow(uaecptr addr, uae_u32 val, bool super, bool data, - int size, struct mmu_atc_line *cl) + int size, bool rmw, struct mmu_atc_line *cl) { uae_u32 status; if (!mmu_fill_atc_try(addr, super, data, 1, cl, &status)) { regs.wb3_data = val; - mmu_bus_error(addr, mmu_get_fc(super, data), 1, size, status); + mmu_bus_error(addr, mmu_get_fc(super, data), 1, size, rmw, status); return; } phys_put_long(mmu_get_real_address(addr, cl), val); @@ -778,33 +816,64 @@ void REGPARAM2 mmu_put_long_slow(uaecptr addr, uae_u32 val, bool super, bool dat uae_u32 REGPARAM2 sfc_get_long(uaecptr addr) { bool super = (regs.sfc & 4) != 0; - bool data = (regs.sfc & 3) != 2; + bool data = true; uae_u32 res; - if (likely(!is_unaligned(addr, 4))) - return mmu_get_user_long(addr, super, data, false, sz_long); - - if (likely(!(addr & 1))) { - res = (uae_u32)mmu_get_user_word(addr, super, data, false, sz_long) << 16; - SAVE_EXCEPTION; - TRY(prb) { - res |= mmu_get_user_word(addr + 2, super, data, false, sz_long); - RESTORE_EXCEPTION; + ismoves = true; + if (likely(!is_unaligned(addr, 4))) { + res = mmu_get_user_long(addr, super, data, false, sz_long); + } else { + if (likely(!(addr & 1))) { + res = (uae_u32)mmu_get_user_word(addr, super, data, false, sz_long) << 16; + SAVE_EXCEPTION; + TRY(prb) { + res |= mmu_get_user_word(addr + 2, super, data, false, sz_long); + RESTORE_EXCEPTION; + } + CATCH(prb) { + RESTORE_EXCEPTION; + regs.mmu_fault_addr = addr; + regs.mmu_fslw |= MMU_FSLW_MA; + regs.mmu_ssw |= MMU_SSW_MA; + THROW_AGAIN(prb); + } ENDTRY + } else { + res = (uae_u32)mmu_get_user_byte(addr, super, data, false, sz_long) << 8; + SAVE_EXCEPTION; + TRY(prb) { + res = (res | mmu_get_user_byte(addr + 1, super, data, false, sz_long)) << 8; + res = (res | mmu_get_user_byte(addr + 2, super, data, false, sz_long)) << 8; + res |= mmu_get_user_byte(addr + 3, super, data, false, sz_long); + RESTORE_EXCEPTION; + } + CATCH(prb) { + RESTORE_EXCEPTION; + regs.mmu_fault_addr = addr; + regs.mmu_fslw |= MMU_FSLW_MA; + regs.mmu_ssw |= MMU_SSW_MA; + THROW_AGAIN(prb); + } ENDTRY } - CATCH(prb) { - RESTORE_EXCEPTION; - regs.mmu_fault_addr = addr; - regs.mmu_fslw |= MMU_FSLW_MA; - regs.mmu_ssw |= MMU_SSW_MA; - THROW_AGAIN(prb); - } ENDTRY + } + + ismoves = false; + return res; +} + +uae_u16 REGPARAM2 sfc_get_word(uaecptr addr) +{ + bool super = (regs.sfc & 4) != 0; + bool data = true; + uae_u16 res; + + ismoves = true; + if (likely(!is_unaligned(addr, 2))) { + res = mmu_get_user_word(addr, super, data, false, sz_word); } else { - res = (uae_u32)mmu_get_user_byte(addr, super, data, false, sz_long) << 8; + res = (uae_u16)mmu_get_user_byte(addr, super, data, false, sz_word) << 8; SAVE_EXCEPTION; TRY(prb) { - res = (res | mmu_get_user_byte(addr + 1, super, data, false, sz_long)) << 8; - res = (res | mmu_get_user_byte(addr + 2, super, data, false, sz_long)) << 8; - res |= mmu_get_user_byte(addr + 3, super, data, false, sz_long); + res |= mmu_get_user_byte(addr + 1, super, data, false, sz_word); RESTORE_EXCEPTION; } CATCH(prb) { @@ -815,47 +884,28 @@ uae_u32 REGPARAM2 sfc_get_long(uaecptr addr) THROW_AGAIN(prb); } ENDTRY } - return res; -} - -uae_u16 REGPARAM2 sfc_get_word(uaecptr addr) -{ - bool super = (regs.sfc & 4) != 0; - bool data = (regs.sfc & 3) != 2; - uae_u16 res; - - if (likely(!is_unaligned(addr, 2))) - return mmu_get_user_word(addr, super, data, false, sz_word); - - res = (uae_u16)mmu_get_user_byte(addr, super, data, false, sz_word) << 8; - SAVE_EXCEPTION; - TRY(prb) { - res |= mmu_get_user_byte(addr + 1, super, data, false, sz_word); - RESTORE_EXCEPTION; - } - CATCH(prb) { - RESTORE_EXCEPTION; - regs.mmu_fault_addr = addr; - regs.mmu_fslw |= MMU_FSLW_MA; - regs.mmu_ssw |= MMU_SSW_MA; - THROW_AGAIN(prb); - } ENDTRY + ismoves = false; return res; } uae_u8 REGPARAM2 sfc_get_byte(uaecptr addr) { bool super = (regs.sfc & 4) != 0; - bool data = (regs.sfc & 3) != 2; - - return mmu_get_user_byte(addr, super, data, false, sz_byte); + bool data = true; + uae_u8 res; + + ismoves = true; + res = mmu_get_user_byte(addr, super, data, false, sz_byte); + ismoves = false; + return res; } void REGPARAM2 dfc_put_long(uaecptr addr, uae_u32 val) { bool super = (regs.dfc & 4) != 0; - bool data = (regs.dfc & 3) != 2; + bool data = true; + ismoves = true; SAVE_EXCEPTION; TRY(prb) { if (likely(!is_unaligned(addr, 4))) @@ -881,13 +931,15 @@ void REGPARAM2 dfc_put_long(uaecptr addr, uae_u32 val) } THROW_AGAIN(prb); } ENDTRY + ismoves = false; } void REGPARAM2 dfc_put_word(uaecptr addr, uae_u16 val) { bool super = (regs.dfc & 4) != 0; - bool data = (regs.dfc & 3) != 2; + bool data = true; + ismoves = true; SAVE_EXCEPTION; TRY(prb) { if (likely(!is_unaligned(addr, 2))) @@ -908,13 +960,15 @@ void REGPARAM2 dfc_put_word(uaecptr addr, uae_u16 val) } THROW_AGAIN(prb); } ENDTRY + ismoves = false; } void REGPARAM2 dfc_put_byte(uaecptr addr, uae_u8 val) { bool super = (regs.dfc & 4) != 0; - bool data = (regs.dfc & 3) != 2; + bool data = true; + ismoves = true; SAVE_EXCEPTION; TRY(prb) { mmu_put_user_byte(addr, val, super, data, sz_byte); @@ -925,6 +979,7 @@ void REGPARAM2 dfc_put_byte(uaecptr addr, uae_u8 val) regs.wb3_data = val; THROW_AGAIN(prb); } ENDTRY + ismoves = false; } void REGPARAM2 mmu_op_real(uae_u32 opcode, uae_u16 extra) @@ -941,13 +996,13 @@ void REGPARAM2 mmu_op_real(uae_u32 opcode, uae_u16 extra) glob = (opcode & 8) != 0; if (opcode & 16) { -#if MMUDEBUG > 1 +#if MMUINSDEBUG > 1 write_log(_T("pflusha(%u,%u) PC=%08x\n"), glob, regs.dfc, m68k_getpc ()); #endif mmu_flush_atc_all(glob); } else { addr = m68k_areg(regs, regno); -#if MMUDEBUG > 1 +#if MMUINSDEBUG > 1 write_log(_T("pflush(%u,%u,%x) PC=%08x\n"), glob, regs.dfc, addr, m68k_getpc ()); #endif mmu_flush_atc(addr, super, glob); @@ -964,7 +1019,7 @@ void REGPARAM2 mmu_op_real(uae_u32 opcode, uae_u16 extra) regno = opcode & 7; write = (opcode & 32) == 0; addr = m68k_areg(regs, regno); -#if MMUDEBUG > 1 +#if MMUINSDEBUG > 0 write_log(_T("PTEST%c (A%d) %08x DFC=%d\n"), write ? 'W' : 'R', regno, addr, regs.dfc); #endif mmu_flush_atc(addr, super, true); @@ -974,7 +1029,7 @@ void REGPARAM2 mmu_op_real(uae_u32 opcode, uae_u16 extra) uae_u32 desc; bool data = (regs.dfc & 3) != 2; - if (mmu_match_ttr(addr,super,data)!=TTR_NO_MATCH) + if (mmu_match_ttr(addr,super,data, false)!=TTR_NO_MATCH) regs.mmusr = MMU_MMUSR_T | MMU_MMUSR_R; else { uae_u32 status; @@ -993,7 +1048,7 @@ void REGPARAM2 mmu_op_real(uae_u32 opcode, uae_u16 extra) regs.mmusr = MMU_MMUSR_B; } ENDTRY RESTORE_EXCEPTION; -#if MMUDEBUG > 1 +#if MMUINSDEBUG > 0 write_log(_T("PTEST result: mmusr %08x\n"), regs.mmusr); #endif } else if ((opcode & 0xFFB8) == 0xF588) { // PLPA (68060) @@ -1002,13 +1057,13 @@ void REGPARAM2 mmu_op_real(uae_u32 opcode, uae_u16 extra) uae_u32 addr = m68k_areg (regs, regno); bool data = (regs.dfc & 3) != 2; -#if MMUDEBUG > 1 +#if MMUINSDEBUG > 0 write_log(_T("PLPA%c param: %08x\n"), write ? 'W' : 'R', addr); #endif - if (mmu_match_ttr(addr,super,data)==TTR_NO_MATCH) { + if (mmu_match_ttr(addr,super,data,false)==TTR_NO_MATCH) { m68k_areg (regs, regno) = mmu_translate (addr, super, data, write != 0); } -#if MMUDEBUG > 1 +#if MMUINSDEBUG > 0 write_log(_T("PLPA%c result: %08x\n"), write ? 'W' : 'R', m68k_areg (regs, regno)); #endif } else { @@ -1088,6 +1143,7 @@ void m68k_do_rte_mmu040 (uaecptr a7) if (ssr & MMU_SSW_CM) { mmu040_movem = 1; mmu040_movem_ea = get_long_mmu040 (a7 + 8); + write_log (_T("MMU restarted MOVEM EA=%08X\n"), mmu040_movem_ea); } } @@ -1096,12 +1152,15 @@ void flush_mmu040 (uaecptr addr, int n) } void m68k_do_rts_mmu040 (void) { - m68k_setpc (get_long_mmu040 (m68k_areg (regs, 7))); + uaecptr stack = m68k_areg (regs, 7); + uaecptr newpc = get_long_mmu040 (stack); m68k_areg (regs, 7) += 4; + m68k_setpc (newpc); } void m68k_do_bsr_mmu040 (uaecptr oldpc, uae_s32 offset) { - put_long_mmu040 (m68k_areg (regs, 7) - 4, oldpc); + uaecptr newstack = m68k_areg (regs, 7) - 4; + put_long_mmu040 (newstack, oldpc); m68k_areg (regs, 7) -= 4; m68k_incpci (offset); } @@ -1111,36 +1170,39 @@ void flush_mmu060 (uaecptr addr, int n) } void m68k_do_rts_mmu060 (void) { - m68k_setpc (get_long_mmu060 (m68k_areg (regs, 7))); + uaecptr stack = m68k_areg (regs, 7); + uaecptr newpc = get_long_mmu060 (stack); m68k_areg (regs, 7) += 4; + m68k_setpc (newpc); } void m68k_do_bsr_mmu060 (uaecptr oldpc, uae_s32 offset) { - put_long_mmu060 (m68k_areg (regs, 7) - 4, oldpc); + uaecptr newstack = m68k_areg (regs, 7) - 4; + put_long_mmu060 (newstack, oldpc); m68k_areg (regs, 7) -= 4; m68k_incpci (offset); } -void uae_mmu_put_rmw (uaecptr addr, uae_u32 v, int size, int type) +void uae_mmu_put_lrmw (uaecptr addr, uae_u32 v, int size, int type) { locked_rmw_cycle = true; if (size == sz_byte) { - mmu_put_byte(addr, v, true, sz_byte); + mmu_put_byte(addr, v, true, sz_byte, true); } else if (size == sz_word) { if (unlikely(is_unaligned(addr, 2))) { - mmu_put_word_unaligned(addr, v, true); + mmu_put_word_unaligned(addr, v, true, true); } else { - mmu_put_word(addr, v, true, sz_word); + mmu_put_word(addr, v, true, sz_word, true); } } else { if (unlikely(is_unaligned(addr, 4))) - mmu_put_long_unaligned(addr, v, true); + mmu_put_long_unaligned(addr, v, true, true); else - mmu_put_long(addr, v, true, sz_long); + mmu_put_long(addr, v, true, sz_long, true); } locked_rmw_cycle = false; } -uae_u32 uae_mmu_get_rmw (uaecptr addr, int size, int type) +uae_u32 uae_mmu_get_lrmw (uaecptr addr, int size, int type) { uae_u32 v; locked_rmw_cycle = true; @@ -1148,13 +1210,13 @@ uae_u32 uae_mmu_get_rmw (uaecptr addr, int size, int type) v = mmu_get_user_byte(addr, regs.s != 0, true, true, sz_byte); } else if (size == sz_word) { if (unlikely(is_unaligned(addr, 2))) { - v = mmu_get_rmw_word_unaligned(addr); + v = mmu_get_lrmw_word_unaligned(addr); } else { v = mmu_get_user_word(addr, regs.s != 0, true, true, sz_word); } } else { if (unlikely(is_unaligned(addr, 4))) - v = mmu_get_rmw_long_unaligned(addr); + v = mmu_get_lrmw_long_unaligned(addr); else v = mmu_get_user_long(addr, regs.s != 0, true, true, sz_long); } diff --git a/cpummu30.cpp b/cpummu30.cpp index a056e6a7..31a95590 100644 --- a/cpummu30.cpp +++ b/cpummu30.cpp @@ -341,7 +341,7 @@ void mmu_op30_pload (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra) bool write = rw ? false : true; -#if MMU030_OP_DBG_MSG +#if 0 write_log (_T("PLOAD%c: Create ATC entry for %08X, FC = %i\n"), write?'W':'R', extra, fc); #endif @@ -355,7 +355,7 @@ void mmu_op30_pflush (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra) uae_u32 fc_mask = (uae_u32)(next&0x00E0)>>5; uae_u32 fc_base = mmu_op30_helper_get_fc(next); -#if MMU030_OP_DBG_MSG +#if 0 switch (mode) { case 0x1: write_log(_T("PFLUSH: Flush all entries\n")); @@ -400,9 +400,9 @@ uae_u32 mmu_op30_helper_get_fc(uae_u16 next) { return (m68k_dreg(regs, next&0x7)&0x7); case 0x0000: if (next&1) { - return (regs.dfc&0x7); + return (regs.dfc); } else { - return (regs.sfc&0x7); + return (regs.sfc); } default: write_log(_T("MMU_OP30 ERROR: bad fc source! (%04X)\n"),next&0x0018); @@ -431,6 +431,7 @@ void mmu030_flush_atc_fc(uae_u32 fc_base, uae_u32 fc_mask) { * and their function code */ void mmu030_flush_atc_page_fc(uaecptr logical_addr, uae_u32 fc_base, uae_u32 fc_mask) { int i; + logical_addr &= mmu030.translation.page.imask; for (i=0; i= ATC030_NUM_ENTRIES) { + i = 0; + write_log (_T("ATC entry not found!!!\n")); + } + mmu030_atc_handle_history_bit(i); /* Create ATC entry */ @@ -1560,8 +1567,9 @@ static void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc) { bBusErrorReadWrite = read; mm030_stageb_address = addr; #if 1 - write_log(_T("MMU: page fault (logical addr=%08X SSW=%04x read=%d size=%d fc=%d pc=%08x)\n"), - addr, regs.mmu_ssw, read, (flags & MMU030_SSW_SIZE_B) ? 1 : (flags & MMU030_SSW_SIZE_W) ? 2 : 4, fc, regs.instruction_pc); + write_log(_T("MMU: page fault (logical addr=%08X SSW=%04x read=%d size=%d fc=%d pc=%08x ob=%08x ins=%04X)\n"), + addr, regs.mmu_ssw, read, (flags & MMU030_SSW_SIZE_B) ? 1 : (flags & MMU030_SSW_SIZE_W) ? 2 : 4, fc, + regs.instruction_pc, (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) ? mmu030_data_buffer : mmu030_ad[mmu030_idx].val, mmu030_opcode & 0xffff); #endif // extern void activate_debugger(void); @@ -1929,10 +1937,10 @@ void mmu030_put_generic(uaecptr addr, uae_u32 val, uae_u32 fc, int size, int acc mmu030_put_atc_generic(addr, val, atc_line_num, fc, size, flags); } } -static uae_u32 mmu030_get_generic_rmw(uaecptr addr, uae_u32 fc, int size, int accesssize, int flags) { +static uae_u32 mmu030_get_generic_lrmw(uaecptr addr, uae_u32 fc, int size, int accesssize, int flags) { // addr,super,write - if ((!mmu030.enabled) || (mmu030_match_rmw_ttr_access(addr,fc)) || (fc==7)) { + if ((!mmu030.enabled) || (mmu030_match_lrmw_ttr_access(addr,fc)) || (fc==7)) { if (size == sz_byte) return phys_get_byte(addr); else if (size == sz_word) @@ -1955,7 +1963,7 @@ static uae_u32 mmu030_get_generic_rmw(uaecptr addr, uae_u32 fc, int size, int ac } uae_u32 mmu030_get_generic(uaecptr addr, uae_u32 fc, int size, int accesssize, int flags) { if (flags & MMU030_SSW_RM) { - return mmu030_get_generic_rmw(addr, fc, size, accesssize, flags); + return mmu030_get_generic_lrmw(addr, fc, size, accesssize, flags); } // addr,super,write if ((!mmu030.enabled) || (mmu030_match_ttr_access(addr,fc,false)) || (fc==7)) { @@ -1981,8 +1989,8 @@ uae_u32 mmu030_get_generic(uaecptr addr, uae_u32 fc, int size, int accesssize, i } -/* RMW is rarely used */ -uae_u32 uae_mmu030_get_rmw(uaecptr addr, int size) +/* Locked RMW is rarely used */ +uae_u32 uae_mmu030_get_lrmw(uaecptr addr, int size) { uae_u32 fc = (regs.s ? 4 : 0) | 1; if (size == sz_byte) { @@ -1999,7 +2007,7 @@ uae_u32 uae_mmu030_get_rmw(uaecptr addr, int size) return mmu030_get_generic(addr, fc, size, size, MMU030_SSW_RM); } } -void uae_mmu030_put_rmw(uaecptr addr, uae_u32 val, int size) +void uae_mmu030_put_lrmw(uaecptr addr, uae_u32 val, int size) { uae_u32 fc = (regs.s ? 4 : 0) | 1; if (size == sz_byte) { @@ -2189,6 +2197,7 @@ void m68k_do_rte_mmu030 (uaecptr a7) mmu030_retry = false; } else if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) { // if movem, skip next move + mmu030_data_buffer = get_long_mmu030 (a7 + 0x2c); mmu030_state[1] |= MMU030_STATEFLAG1_MOVEM2; } else { mmu030_ad[idxsize].done = true; diff --git a/custom.cpp b/custom.cpp index ff6b2253..e96186be 100644 --- a/custom.cpp +++ b/custom.cpp @@ -249,6 +249,7 @@ uae_u8 cycle_line[256]; static uae_u16 bplxdat[8]; static bool bpl1dat_written, bpl1dat_early, bpl1dat_written_at_least_once; +static bool bpldmawasactive; static uae_s16 bpl1mod, bpl2mod; static uaecptr prevbpl[2][MAXVPOS][8]; static uaecptr bplpt[8], bplptx[8]; @@ -384,7 +385,8 @@ enum plfstate plf_active, plf_passed_stop, plf_passed_stop2, - plf_end + plf_end, + plf_finished } plf_state; enum fetchstate { @@ -1578,18 +1580,27 @@ static void do_long_fetch (int hpos, int nwords, int dma, int fm) #endif /* make sure fetch that goes beyond maxhpos is finished */ -static void finish_final_fetch (int pos, int fm) +static void finish_final_fetch (int fm) +{ + int pos = maxhpos; + if (plf_state != plf_end) + return; + pos += flush_plane_data (fm); + thisline_decision.plfright = pos; + thisline_decision.plflinelen = out_offs; + finish_playfield_line (); +} + +static void finish_last_fetch (int pos, int fm) { if (thisline_decision.plfleft < 0) return; if (plf_state == plf_end) return; + pos += flush_plane_data (fm); plf_state = plf_end; ddfstate = DIW_waiting_start; - pos += flush_plane_data (fm); - thisline_decision.plfright = pos; - thisline_decision.plflinelen = out_offs; - finish_playfield_line (); + fetch_state = fetch_not_started; } STATIC_INLINE int one_fetch_cycle_0 (int pos, int ddfstop_to_test, int dma, int fm) @@ -1599,7 +1610,7 @@ STATIC_INLINE int one_fetch_cycle_0 (int pos, int ddfstop_to_test, int dma, int if ((fetch_cycle & fetchunit_mask) == 0) { if (plf_state == plf_passed_stop2) { - finish_final_fetch (pos, fm); + finish_last_fetch (pos, fm); return 1; } if (plf_state == plf_passed_stop) { @@ -1722,7 +1733,7 @@ static void update_fetch_x (int until, int fm) } if (until >= maxhpos) { - finish_final_fetch (pos, fm); + finish_last_fetch (pos, fm); return; } @@ -1757,7 +1768,7 @@ STATIC_INLINE void update_fetch (int until, int fm) for (; ; pos++) { if (pos == until) { if (until >= maxhpos) { - finish_final_fetch (pos, fm); + finish_last_fetch (pos, fm); return; } flush_display (fm); @@ -1834,7 +1845,7 @@ STATIC_INLINE void update_fetch (int until, int fm) return; } if (until >= maxhpos) { - finish_final_fetch (pos, fm); + finish_last_fetch (pos, fm); return; } flush_display (fm); @@ -1890,21 +1901,30 @@ static void start_bpl_dma (int hpos, int hstart) } } - plfstrt_sprite = plfstrt; fetch_start (hpos); - fetch_cycle = 0; - ddfstate = DIW_waiting_stop; - compute_toscr_delay (last_fetch_hpos, bplcon1); - /* If someone already wrote BPL1DAT, clear the area between that point and - the real fetch start. */ - if (bpl1dat_written_at_least_once && hstart > last_fetch_hpos) { - update_fetch_x (hstart, fetchmode); - bpl1dat_written_at_least_once = false; - } else { - reset_bpl_vars (); + if (!bpldmawasactive) { + + plfstrt_sprite = plfstrt; + fetch_cycle = 0; + compute_toscr_delay (last_fetch_hpos, bplcon1); + /* If someone already wrote BPL1DAT, clear the area between that point and + the real fetch start. */ + if (bpl1dat_written_at_least_once && hstart > last_fetch_hpos) { + update_fetch_x (hstart, fetchmode); + bpl1dat_written_at_least_once = false; + } else { + reset_bpl_vars (); + } + cycle_diagram_shift = hstart; + + bpldmawasactive = true; } + + last_fetch_hpos = hstart; + + #if 0 if (!nodraw ()) { if (thisline_decision.plfleft >= 0) { @@ -1915,8 +1935,6 @@ static void start_bpl_dma (int hpos, int hstart) update_toscr_planes (); } #endif - last_fetch_hpos = hstart; - cycle_diagram_shift = hstart; } /* this may turn on datafetch if program turns dma on during the ddf */ @@ -1960,7 +1978,7 @@ STATIC_INLINE void decide_line (int hpos) if (fetch_state == fetch_not_started && (diwstate == DIW_waiting_stop || (currprefs.chipset_mask & CSMASK_ECS_AGNUS))) { int ok = 0; if (last_decide_line_hpos < plfstrt_start && hpos >= plfstrt_start) { - if (plf_state == plf_idle) + if (plf_state == plf_idle || plf_state == plf_end) plf_state = plf_start; } if (last_decide_line_hpos < plfstrt && hpos >= plfstrt) { @@ -2605,6 +2623,7 @@ static void finish_decisions (void) decide_diw (hpos); decide_line (hpos); decide_fetch (hpos); + finish_final_fetch (fetchmode); record_color_change2 (hsyncstartpos, 0xffff, 0); if (thisline_decision.plfleft >= 0 && thisline_decision.plflinelen < 0) { @@ -2739,6 +2758,7 @@ static void reset_decisions (void) bpldmasetuphpos = -1; bpldmasetupphase = 0; ddfstrt_old_hpos = -1; + bpldmawasactive = false; if (plf_state > plf_active) plf_state = plf_idle; @@ -3227,17 +3247,25 @@ static void calcdiw (void) plfstop = ddfstop; /* probably not the correct place.. should use plf_state instead */ if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { - /* ECS/AGA and ddfstop > maxhpos == always-on display */ - if (plfstop > maxhpos) - plfstrt = 0; - if (plfstrt < HARD_DDF_START) - plfstrt = HARD_DDF_START; - plfstrt_start = plfstrt - 4; + if (!bpldmawasactive) { + /* ECS/AGA and ddfstop > maxhpos == always-on display */ + if (plfstop > maxhpos) + plfstrt = 0; + if (plfstrt < HARD_DDF_START) + plfstrt = HARD_DDF_START; + plfstrt_start = plfstrt - 4; + } else { + plfstrt_start = plfstrt - 4; + } } else { - /* OCS and ddfstrt >= ddfstop == ddfstop = max */ - if (plfstrt >= plfstop && plfstrt >= HARD_DDF_START) - plfstop = 0xff; - plfstrt_start = HARD_DDF_START - 2; + if (!bpldmawasactive) { + /* OCS and ddfstrt >= ddfstop == ddfstop = max */ + if (plfstrt >= plfstop && plfstrt >= HARD_DDF_START) + plfstop = 0xff; + plfstrt_start = HARD_DDF_START_REAL - 2; + } else { + plfstrt_start = plfstrt - 4; + } } diw_change = 2; } @@ -3490,7 +3518,7 @@ static void immediate_copper (int num) pos = oldpos; if (!dmaen(DMA_COPPER)) break; - if (cop_state.ip >= currprefs.chipmem_size) + if (cop_state.ip >= currprefs.chipmem_size && cop_state.ip < currprefs.z3chipmem_start && cop_state.ip >= currprefs.z3chipmem_start + currprefs.z3chipmem_size) break; pos++; oldpos = pos; diff --git a/debug.cpp b/debug.cpp index 04d3eb5f..a04d75df 100644 --- a/debug.cpp +++ b/debug.cpp @@ -2228,7 +2228,9 @@ uae_u16 debug_wputpeekdma (uaecptr addr, uae_u32 v) { if (!memwatch_enabled) return v; - memwatch_func (addr, 2, 2, &v); + if (!currprefs.z3chipmem_size) + addr &= chipmem_mask; + memwatch_func (addr & chipmem_mask, 2, 2, &v); return v; } uae_u16 debug_wgetpeekdma (uaecptr addr, uae_u32 v) @@ -2236,6 +2238,8 @@ uae_u16 debug_wgetpeekdma (uaecptr addr, uae_u32 v) uae_u32 vv = v; if (!memwatch_enabled) return v; + if (!currprefs.z3chipmem_size) + addr &= chipmem_mask; memwatch_func (addr, 1, 2, &vv); return vv; } @@ -3681,10 +3685,12 @@ static BOOL debug_line (TCHAR *input) regs = history[temp]; if (history[temp].pc == addr || addr == 0) { m68k_setpc (history[temp].pc); - if (badly) + if (badly) { m68k_dumpstate (NULL); - else + } else { + console_out_f(_T("%d "), history[temp].s); m68k_disasm (history[temp].pc, NULL, 1); + } if (addr && history[temp].pc == addr) break; } diff --git a/filesys.cpp b/filesys.cpp index 73f099da..bd0fa131 100644 --- a/filesys.cpp +++ b/filesys.cpp @@ -78,6 +78,8 @@ int log_filesys = 0; #define TRACE3(x) #endif +#define UNIT_LED(unit) ((unit)->ui.unit_type == UNIT_CDFS ? LED_CD : LED_HD) + #define RTAREA_HEARTBEAT 0xFFFC static uae_sem_t test_sem; @@ -4118,7 +4120,7 @@ static void action_examine_next (Unit *unit, dpacket packet) uae_u32 uniq; TRACE((_T("ACTION_EXAMINE_NEXT(0x%lx,0x%lx)\n"), lock, info)); - gui_flicker_led (LED_HD, unit->unit, 1); + gui_flicker_led (UNIT_LED(unit), unit->unit, 1); DUMPLOCK(unit, lock); if (lock != 0) @@ -4431,7 +4433,7 @@ static void return; } TRACE((_T("ACTION_READ(%s,0x%lx,%ld)\n"), k->aino->nname, addr, size)); - gui_flicker_led (LED_HD, unit->unit, 1); + gui_flicker_led (UNIT_LED(unit), unit->unit, 1); if (size == 0) { PUT_PCK_RES1 (packet, 0); @@ -4529,7 +4531,7 @@ static void return; } - gui_flicker_led (LED_HD, unit->unit, 2); + gui_flicker_led (UNIT_LED(unit), unit->unit, 2); TRACE((_T("ACTION_WRITE(%s,0x%lx,%ld)\n"), k->aino->nname, addr, size)); if (unit->ui.readonly || unit->ui.locked) { @@ -4610,7 +4612,7 @@ static void cur = k->file_pos; TRACE((_T("ACTION_SEEK(%s,%d,%d)=%d\n"), k->aino->nname, pos, mode, cur)); - gui_flicker_led (LED_HD, unit->unit, 1); + gui_flicker_led (UNIT_LED(unit), unit->unit, 1); filesize = fs_fsize64 (k->fd); if (whence == SEEK_CUR) @@ -4671,7 +4673,7 @@ static void PUT_PCK_RES1 (packet, DOS_TRUE); } notify_check (unit, a); - gui_flicker_led (LED_HD, unit->unit, 2); + gui_flicker_led (UNIT_LED(unit), unit->unit, 2); } static void action_set_comment (Unit * unit, dpacket packet) @@ -4728,7 +4730,7 @@ maybe_free_and_out: a->comment = commented; fsdb_set_file_attrs (a); notify_check (unit, a); - gui_flicker_led (LED_HD, unit->unit, 2); + gui_flicker_led (UNIT_LED(unit), unit->unit, 2); } static void @@ -4910,7 +4912,7 @@ static void notify_check (unit, aino); updatedirtime (aino, 0); PUT_PCK_RES1 (packet, make_lock (unit, aino->uniq, -2) >> 2); - gui_flicker_led (LED_HD, unit->unit, 2); + gui_flicker_led (UNIT_LED(unit), unit->unit, 2); } static void @@ -4962,7 +4964,7 @@ static void return; } - gui_flicker_led (LED_HD, unit->unit, 1); + gui_flicker_led (UNIT_LED(unit), unit->unit, 1); k->notifyactive = 1; /* If any open files have file pointers beyond this size, truncate only * so far that these pointers do not become invalid. */ @@ -5101,7 +5103,7 @@ static void delete_aino (unit, a); } PUT_PCK_RES1 (packet, DOS_TRUE); - gui_flicker_led (LED_HD, unit->unit, 2); + gui_flicker_led (UNIT_LED(unit), unit->unit, 2); } static void @@ -5134,7 +5136,7 @@ static void notify_check (unit, a); PUT_PCK_RES1 (packet, DOS_TRUE); } - gui_flicker_led (LED_HD, unit->unit, 2); + gui_flicker_led (UNIT_LED(unit), unit->unit, 2); } static void @@ -5240,7 +5242,7 @@ static void if (a2->elock > 0 || a2->shlock > 0 || wehavekeys > 0) de_recycle_aino (unit, a2); PUT_PCK_RES1 (packet, DOS_TRUE); - gui_flicker_led (LED_HD, unit->unit, 2); + gui_flicker_led (UNIT_LED(unit), unit->unit, 2); } static void @@ -5350,7 +5352,7 @@ static void action_change_file_position64 (Unit *unit, dpacket packet) whence = SEEK_SET; TRACE((_T("ACTION_CHANGE_FILE_POSITION64(%s,%lld,%d)\n"), k->aino->nname, pos, mode)); - gui_flicker_led (LED_HD, unit->unit, 1); + gui_flicker_led (UNIT_LED(unit), unit->unit, 1); cur = k->file_pos; { @@ -5423,7 +5425,7 @@ static void action_change_file_size64 (Unit *unit, dpacket packet) return; } - gui_flicker_led (LED_HD, unit->unit, 1); + gui_flicker_led (UNIT_LED(unit), unit->unit, 1); k->notifyactive = 1; /* If any open files have file pointers beyond this size, truncate only * so far that these pointers do not become invalid. */ diff --git a/fpp.cpp b/fpp.cpp index edb66e68..8ec86cf2 100644 --- a/fpp.cpp +++ b/fpp.cpp @@ -1119,7 +1119,7 @@ static uaecptr fmovem2mem (uaecptr ad, uae_u32 list, int incr) { int reg; // 68030 MMU state saving is annoying! - if (currprefs.mmu_model) { + if (currprefs.mmu_model == 68030) { int idx = 0; if (incr < 0) { for (reg = 7; reg >= 0; reg--) { @@ -1207,11 +1207,11 @@ static uaecptr fmovem2mem (uaecptr ad, uae_u32 list, int incr) static uaecptr fmovem2fpp (uaecptr ad, uae_u32 list, int incr) { int reg; - if (currprefs.mmu_model) { + if (currprefs.mmu_model == 68030) { + static uae_u32 wrd1, wrd2, wrd3; int idx = 0; if (incr < 0) { for (reg = 7; reg >= 0; reg--) { - uae_u32 wrd1, wrd2, wrd3; if (list & 0x80) { ad -= 4; if (mmu030_state[0] == idx * 3 + 0) { @@ -1227,15 +1227,14 @@ static uaecptr fmovem2fpp (uaecptr ad, uae_u32 list, int incr) if (mmu030_state[0] == idx * 3 + 2) { wrd1 = x_get_long (ad); mmu030_state[0]++; + regs.fp[reg] = to_exten(wrd1, wrd2, wrd3); } - regs.fp[reg] = to_exten(wrd1, wrd2, wrd3); idx++; } list <<= 1; } } else { for (reg = 0; reg <= 7; reg++) { - uae_u32 wrd1, wrd2, wrd3; if (list & 0x80) { if (mmu030_state[0] == idx * 3 + 0) { wrd1 = x_get_long (ad); @@ -1250,9 +1249,9 @@ static uaecptr fmovem2fpp (uaecptr ad, uae_u32 list, int incr) if (mmu030_state[0] == idx * 3 + 2) { wrd3 = x_get_long (ad); mmu030_state[0]++; + regs.fp[reg] = to_exten(wrd1, wrd2, wrd3); } ad += 4; - regs.fp[reg] = to_exten(wrd1, wrd2, wrd3); idx++; } list <<= 1; diff --git a/gayle.cpp b/gayle.cpp index 1ab5c783..5e00956d 100644 --- a/gayle.cpp +++ b/gayle.cpp @@ -1094,7 +1094,12 @@ static uae_u32 ide_read_reg (int ide_reg) if (ide->regs.ide_status & IDE_STATUS_BSY) ide_reg = IDE_STATUS; if (!isdrive (ide)) { - v = 0xff; + if (ide_reg == IDE_STATUS && ide->pair->irq) + ide->pair->irq = 0; + if (isdrive (ide->pair)) + v = 0x00; + else + v = 0xff; goto end; } diff --git a/gencpu.cpp b/gencpu.cpp index d58a05a9..e0e359d9 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -54,6 +54,7 @@ static int optimized_flags; #define GF_IR2IRC 128 #define GF_LRMW 256 #define GF_NOFAULTPC 512 +#define GF_RMW 1024 /* 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 @@ -68,7 +69,8 @@ static int generate_stbl; static int mmufixupcnt; static int mmufixupstate; static int mmudisp020cnt; - +static bool candormw; +static char rmw_varname[100]; #define GENA_GETV_NO_FETCH 0 #define GENA_GETV_FETCH 1 @@ -80,6 +82,8 @@ static int mmudisp020cnt; static char *srcl, *dstl; static char *srcw, *dstw; static char *srcb, *dstb; +static char *srcblrmw, *srcwlrmw, *srcllrmw; +static char *dstblrmw, *dstwlrmw, *dstllrmw; static char *srcbrmw, *srcwrmw, *srclrmw; static char *dstbrmw, *dstwrmw, *dstlrmw; static char *prefetch_long, *prefetch_word; @@ -241,16 +245,27 @@ static const char *bit_mask (int size) return 0; } -static void gen_nextilong (char *type, char *name, int flags) +static void add_mmu040_movem (int movem) +{ + if (movem != 3) + return; + printf ("\tif (mmu040_movem) {\n"); + printf ("\t\tsrca = mmu040_movem_ea;\n"); + printf ("\t} else\n"); + start_brace (); +} + +static void gen_nextilong2 (char *type, char *name, int flags, int movem) { int r = m68k_pc_offset; m68k_pc_offset += 4; + printf ("\t%s %s;\n", type, name); + add_mmu040_movem (movem); if (using_ce020) { - printf ("\t%s %s = %s (%d);\n", type, name, prefetch_long, r); + printf ("\t%s = %s (%d);\n", name, prefetch_long, r); count_read += 2; } else if (using_ce) { - printf ("\t%s %s;\n", type, name); /* we must do this because execution order of (something | something2) is not defined */ if (flags & GF_NOREFILL) { printf ("\t%s = %s (%d) << 16;\n", name, prefetch_word, r + 2); @@ -265,23 +280,26 @@ static void gen_nextilong (char *type, char *name, int flags) } else { if (using_prefetch) { if (flags & GF_NOREFILL) { - printf ("\t%s %s;\n", type, name); printf ("\t%s = %s (%d) << 16;\n", name, prefetch_word, r + 2); count_read++; printf ("\t%s |= regs.irc;\n", name); insn_n_cycles += 4; } else { - printf ("\t%s %s = %s (%d);\n", type, name, prefetch_long, r + 2); + printf ("\t%s = %s (%d);\n", name, prefetch_long, r + 2); count_read++; count_read++; insn_n_cycles += 8; } } else { insn_n_cycles += 8; - printf ("\t%s %s = %s (%d);\n", type, name, prefetch_long, r); + printf ("\t%s = %s (%d);\n", name, prefetch_long, r); } } } +static void gen_nextilong (char *type, char *name, int flags) +{ + gen_nextilong2 (type, name, flags, 0); +} static const char *gen_nextiword (int flags) { @@ -502,21 +520,11 @@ static void gen_set_fault_pc (void) return; sync_m68k_pc (); printf ("\tregs.instruction_pc = m68k_getpci ();\n"); + printf ("\tmmu_restart = false;\n"); m68k_pc_offset = 0; clearmmufixup (0); } -static void add_mmu040_movem (int movem) -{ - if (movem != 3) - return; - printf ("\tif (mmu040_movem) {\n"); - printf ("\t\tsrca = mmu040_movem_ea;\n"); - printf ("\t} else\n"); - start_brace (); -} - - static void syncmovepc (int getv, int flags) { #if 0 @@ -545,8 +553,14 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g { char namea[100]; int m68k_pc_offset_last = m68k_pc_offset; + bool rmw = false; sprintf (namea, "%sa", name); + if ((flags & GF_RMW) && using_mmu == 68060) { + strcpy (rmw_varname, name); + candormw = true; + rmw = true; + } start_brace (); switch (mode) { @@ -595,13 +609,18 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g syncmovepc (getv, flags); return; case Aind: // (An) - printf ("\tuaecptr %sa = m68k_areg (regs, %s);\n", name, reg); + printf ("\tuaecptr %sa;\n", name); + add_mmu040_movem (movem); + printf ("\t%sa = m68k_areg (regs, %s);\n", name, reg); break; case Aipi: // (An)+ - printf ("\tuaecptr %sa = m68k_areg (regs, %s);\n", name, reg); + printf ("\tuaecptr %sa;\n", name); + add_mmu040_movem (movem); + printf ("\t%sa = m68k_areg (regs, %s);\n", name, reg); break; case Apdi: // -(An) printf ("\tuaecptr %sa;\n", name); + add_mmu040_movem (movem); switch (size) { case sz_byte: if (movem) @@ -625,7 +644,9 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g } break; case Ad16: // (d16,An) - printf ("\tuaecptr %sa = m68k_areg (regs, %s) + (uae_s32)(uae_s16)%s;\n", name, reg, gen_nextiword (flags)); + printf ("\tuaecptr %sa;\n", name); + add_mmu040_movem (movem); + printf ("\t%sa = m68k_areg (regs, %s) + (uae_s32)(uae_s16)%s;\n", name, reg, gen_nextiword (flags)); count_read_ea++; break; case Ad8r: // (d8,An,Xn) @@ -680,10 +701,12 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g break; case absw: - printf ("\tuaecptr %sa = (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags)); + printf ("\tuaecptr %sa;\n", name); + add_mmu040_movem (movem); + printf ("\t%sa = (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags)); break; case absl: - gen_nextilong ("uaecptr", namea, flags); + gen_nextilong2 ("uaecptr", namea, flags, movem); count_read_ea += 2; break; case imm: @@ -794,9 +817,9 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g } } else { switch (size) { - case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = %s (%sa);\n", name, (flags & GF_LRMW) ? srcbrmw : srcb, name); break; - case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = %s (%sa);\n", name, (flags & GF_LRMW) ? srcwrmw : srcw, name); break; - case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = %s (%sa);\n", name, (flags & GF_LRMW) ? srclrmw : srcl, name); break; + case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = %s (%sa);\n", name, (flags & GF_LRMW) ? srcblrmw : (rmw ? srcbrmw : srcb), name); break; + case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = %s (%sa);\n", name, (flags & GF_LRMW) ? srcwlrmw : (rmw ? srcwrmw : srcw), name); break; + case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = %s (%sa);\n", name, (flags & GF_LRMW) ? srcllrmw : (rmw ? srclrmw : srcl), name); break; default: abort (); } } @@ -856,6 +879,11 @@ static void genamode (amodes mode, char *reg, wordsizes size, char *name, int ge static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, char *to, int store_dir, int flags) { + if (candormw) { + if (strcmp (rmw_varname, to) != 0) + candormw = false; + } + switch (mode) { case Dreg: switch (size) { @@ -947,7 +975,7 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha if (flags & GF_FC) printf ("\tdfc%s_put_byte (%sa, %s);\n", mmu_postfix, to, from); else - printf ("\t%s (%sa, %s);\n", (flags & GF_LRMW) ? dstbrmw : dstb, to, from); + printf ("\t%s (%sa, %s);\n", (flags & GF_LRMW) ? dstblrmw : (candormw ? dstbrmw : dstb), to, from); break; case sz_word: insn_n_cycles += 4; @@ -956,7 +984,7 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha if (flags & GF_FC) printf ("\tdfc%s_put_word (%sa, %s);\n", mmu_postfix, to, from); else - printf ("\t%s (%sa, %s);\n", (flags & GF_LRMW) ? dstwrmw :dstw, to, from); + printf ("\t%s (%sa, %s);\n", (flags & GF_LRMW) ? dstwlrmw : (candormw ? dstwrmw : dstw), to, from); break; case sz_long: insn_n_cycles += 8; @@ -965,7 +993,7 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha if (flags & GF_FC) printf ("\tdfc%s_put_long (%sa, %s);\n", mmu_postfix, to, from); else - printf ("\t%s (%sa, %s);\n", (flags & GF_LRMW) ? dstlrmw : dstl, to, from); + printf ("\t%s (%sa, %s);\n", (flags & GF_LRMW) ? dstllrmw : (candormw ? dstlrmw : dstl), to, from); break; default: abort (); @@ -1041,34 +1069,62 @@ static void movem_mmu060 (const char *code, int size, bool put, bool aipi, bool index = "movem_index1"; } - for (int i = 0; i < 2; i++) { - char reg; - if (i == dphase) - reg = 'd'; - else - reg = 'a'; - printf ("\twhile (%cmask) {\n", reg); - if (apdi) - printf ("\t\tsrca -= %d;\n", size); - if (put) { - printf ("\t\t%s, m68k_%creg (regs, %s[%cmask]));\n", code, reg, index, reg); - } else { - printf ("\t\tm68k_%creg (regs, %s[%cmask]) = %s;\n", reg, index, reg, code); + if (!put) { + printf("\tuae_u32 tmp[16];\n"); + printf("\tint tmpreg[16];\n"); + printf("\tint idx = 0;\n"); + for (int i = 0; i < 2; i++) { + char reg; + if (i == dphase) + reg = 'd'; + else + reg = 'a'; + printf ("\twhile (%cmask) {\n", reg); + if (apdi) + printf ("\t\tsrca -= %d;\n", size); + printf ("\t\ttmpreg[idx] = %s[%cmask] + %d;\n", index, reg, i == dphase ? 0 : 8); + printf ("\t\ttmp[idx++] = %s;\n", code); + if (!apdi) + printf ("\t\tsrca += %d;\n", size); + printf ("\t\t%cmask = movem_next[%cmask];\n", reg, reg); + printf ("\t}\n"); } - if (!apdi) - printf ("\t\tsrca += %d;\n", size); - printf ("\t\t%cmask = movem_next[%cmask];\n", reg, reg); + if (aipi || apdi) + printf ("\tm68k_areg (regs, dstreg) = srca;\n"); + printf ("\twhile (--idx >= 0) {\n"); + printf ("\t\tregs.regs[tmpreg[idx]] = tmp[idx];\n"); printf ("\t}\n"); + } else { + for (int i = 0; i < 2; i++) { + char reg; + if (i == dphase) + reg = 'd'; + else + reg = 'a'; + printf ("\twhile (%cmask) {\n", reg); + if (apdi) + printf ("\t\tsrca -= %d;\n", size); + if (put) { + printf ("\t\t%s, m68k_%creg (regs, %s[%cmask]));\n", code, reg, index, reg); + } else { + printf ("\t\tm68k_%creg (regs, %s[%cmask]) = %s;\n", reg, index, reg, code); + } + if (!apdi) + printf ("\t\tsrca += %d;\n", size); + printf ("\t\t%cmask = movem_next[%cmask];\n", reg, reg); + printf ("\t}\n"); + } + if (aipi || apdi) + printf ("\tm68k_areg (regs, dstreg) = srca;\n"); } - if (aipi || apdi) - printf ("\tm68k_areg (regs, dstreg) = srca;\n"); } static bool mmu040_special_movem (uae_u16 opcode) { if (using_mmu != 68040) return false; - return (((((opcode >> 3) & 7) == 7) && ((opcode & 7) == 2 || (opcode & 7) == 3)) || ((opcode >> 3) & 7) == 6); + return true; +// return (((((opcode >> 3) & 7) == 7) && ((opcode & 7) == 2 || (opcode & 7) == 3)) || ((opcode >> 3) & 7) == 6); } static void movem_mmu040 (const char *code, int size, bool put, bool aipi, bool apdi, uae_u16 opcode) @@ -1085,11 +1141,9 @@ static void movem_mmu040 (const char *code, int size, bool put, bool aipi, bool index = "movem_index1"; } - if (mmu040_special_movem (opcode)) { - printf ("\tmmu040_movem = 1;\n"); - printf ("\tmmu040_movem_ea = srca;\n"); - mvm = true; - } + printf ("\tmmu040_movem = 1;\n"); + printf ("\tmmu040_movem_ea = srca;\n"); + mvm = true; for (int i = 0; i < 2; i++) { char reg; @@ -1112,8 +1166,7 @@ static void movem_mmu040 (const char *code, int size, bool put, bool aipi, bool } if (aipi || apdi) printf ("\tm68k_areg (regs, dstreg) = srca;\n"); - if (mvm) - printf ("\tmmu040_movem = 0;\n"); + printf ("\tmmu040_movem = 0;\n"); } /* 68030 MMU does not restore register state if it bus faults. @@ -1132,6 +1185,13 @@ static void movem_mmu030 (const char *code, int size, bool put, bool aipi, bool } printf ("\tmmu030_state[1] |= MMU030_STATEFLAG1_MOVEM1;\n"); printf ("\tint movem_cnt = 0;\n"); + if (!put) { + printf ("\tuae_u32 val;\n"); + printf ("\tif (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM2)\n"); + printf ("\t\tsrca = mmu030_ad[mmu030_idx].val;\n"); + printf ("\telse\n"); + printf ("\t\tmmu030_ad[mmu030_idx].val = srca;\n"); + } for (int i = 0; i < 2; i++) { char reg; if (i == dphase) @@ -1145,13 +1205,16 @@ static void movem_mmu030 (const char *code, int size, bool put, bool aipi, bool printf ("\t\t\tif (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM2) {\n"); printf ("\t\t\t\tmmu030_state[1] &= ~MMU030_STATEFLAG1_MOVEM2;\n"); if (!put) - printf ("\t\t\t\tm68k_%creg (regs, %s[%cmask]) = %smmu030_data_buffer;\n", reg, index, reg, size == 2 ? "(uae_s32)(uae_s16)" : ""); + printf ("\t\t\t\tval = %smmu030_data_buffer;\n", size == 2 ? "(uae_s32)(uae_s16)" : ""); printf ("\t\t\t} else {\n"); if (put) - printf ("\t\t\t\t%s, m68k_%creg (regs, %s[%cmask]));\n", code, reg, index, reg); + printf ("\t\t\t\t%s, (mmu030_data_buffer = m68k_%creg (regs, %s[%cmask])));\n", code, reg, index, reg); else - printf ("\t\t\t\tm68k_%creg (regs, %s[%cmask]) = %s;\n", reg, index, reg, code); + printf ("\t\t\t\tval = %s;\n", code); printf ("\t\t\t}\n"); + if (!put) { + printf ("\t\t\tm68k_%creg (regs, %s[%cmask]) = val;\n", reg, index, reg); + } printf ("\t\t\tmmu030_state[0]++;\n"); printf ("\t\t}\n"); if (!apdi) @@ -1635,15 +1698,17 @@ static int islongimm (struct instr *curi) return (curi->size == sz_long && (curi->smode == Dreg || curi->smode == imm)); } -static void gen_opcode (unsigned long int opcode) -{ - struct instr *curi = table68k + opcode; +static void resetvars (void) +{ insn_n_cycles = using_prefetch ? 0 : 4; + insn_n_cycles020 = 0; ir2irc = 0; mmufixupcnt = 0; mmufixupstate = 0; mmudisp020cnt = 0; + candormw = false; + rmw_varname[0] = 0; prefetch_long = NULL; srcli = NULL; @@ -1655,12 +1720,12 @@ static void gen_opcode (unsigned long int opcode) do_cycles = "do_cycles"; srcwd = srcld = NULL; dstwd = dstld = NULL; - srcbrmw = NULL; - srcwrmw = NULL; - srclrmw = NULL; - dstbrmw = NULL; - dstwrmw = NULL; - dstlrmw = NULL; + srcblrmw = NULL; + srcwlrmw = NULL; + srcllrmw = NULL; + dstblrmw = NULL; + dstwlrmw = NULL; + dstllrmw = NULL; if (using_indirect) { // tracer @@ -1759,12 +1824,12 @@ static void gen_opcode (unsigned long int opcode) dstw = "put_word_mmu030_state"; srcb = "get_byte_mmu030_state"; dstb = "put_byte_mmu030_state"; - srcbrmw = "get_rmw_byte_mmu030_state"; - srcwrmw = "get_rmw_word_mmu030_state"; - srclrmw = "get_rmw_long_mmu030_state"; - dstbrmw = "put_rmw_byte_mmu030_state"; - dstwrmw = "put_rmw_word_mmu030_state"; - dstlrmw = "put_rmw_long_mmu030_state"; + srcblrmw = "get_lrmw_byte_mmu030_state"; + srcwlrmw = "get_lrmw_word_mmu030_state"; + srcllrmw = "get_lrmw_long_mmu030_state"; + dstblrmw = "put_lrmw_byte_mmu030_state"; + dstwlrmw = "put_lrmw_word_mmu030_state"; + dstllrmw = "put_lrmw_long_mmu030_state"; srcld = "get_long_mmu030"; srcwd = "get_word_mmu030"; dstld = "put_long_mmu030"; @@ -1785,12 +1850,12 @@ static void gen_opcode (unsigned long int opcode) dstw = "put_word_mmu040"; srcb = "get_byte_mmu040"; dstb = "put_byte_mmu040"; - srcbrmw = "get_rmw_byte_mmu040"; - srcwrmw = "get_rmw_word_mmu040"; - srclrmw = "get_rmw_long_mmu040"; - dstbrmw = "put_rmw_byte_mmu040"; - dstwrmw = "put_rmw_word_mmu040"; - dstlrmw = "put_rmw_long_mmu040"; + srcblrmw = "get_lrmw_byte_mmu040"; + srcwlrmw = "get_lrmw_word_mmu040"; + srcllrmw = "get_lrmw_long_mmu040"; + dstblrmw = "put_lrmw_byte_mmu040"; + dstwlrmw = "put_lrmw_word_mmu040"; + dstllrmw = "put_lrmw_long_mmu040"; } else if (using_mmu) { // 68060 MMU disp020 = "x_get_disp_ea_020"; @@ -1807,6 +1872,13 @@ static void gen_opcode (unsigned long int opcode) dstw = "put_word_mmu060"; srcb = "get_byte_mmu060"; dstb = "put_byte_mmu060"; + srcblrmw = "get_lrmw_byte_mmu060"; + srcwlrmw = "get_lrmw_word_mmu060"; + srcllrmw = "get_lrmw_long_mmu060"; + dstblrmw = "put_lrmw_byte_mmu060"; + dstwlrmw = "put_lrmw_word_mmu060"; + dstllrmw = "put_lrmw_long_mmu060"; + // 68060 only: also non-locked read-modify-write accesses are reported srcbrmw = "get_rmw_byte_mmu060"; srcwrmw = "get_rmw_word_mmu060"; srclrmw = "get_rmw_long_mmu060"; @@ -1858,16 +1930,22 @@ static void gen_opcode (unsigned long int opcode) srcld = srcl; if (!srcwd) srcwd = srcw; - if (!srcbrmw) { - srcbrmw = srcb; - srcwrmw = srcw; - srclrmw = srcl; - dstbrmw = dstb; - dstwrmw = dstw; - dstlrmw = dstl; + if (!srcblrmw) { + srcblrmw = srcb; + srcwlrmw = srcw; + srcllrmw = srcl; + dstblrmw = dstb; + dstwlrmw = dstw; + dstllrmw = dstl; } - insn_n_cycles020 = 0; +} + +static void gen_opcode (unsigned long int opcode) +{ + struct instr *curi = table68k + opcode; + + resetvars (); start_brace (); m68k_pc_offset = 2; @@ -1901,7 +1979,7 @@ static void gen_opcode (unsigned long int opcode) { int c = 0; genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_RMW); printf ("\tsrc %c= dst;\n", curi->mnemo == i_OR ? '|' : curi->mnemo == i_AND ? '&' : '^'); genflags (flag_logical, curi->size, "src", "", ""); if (curi->dmode == Dreg && curi->size == sz_long) { @@ -1945,7 +2023,7 @@ static void gen_opcode (unsigned long int opcode) { int c = 0; genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_RMW); if (curi->dmode == Dreg) { if (curi->size == sz_long) { c += 2; @@ -1965,7 +2043,7 @@ static void gen_opcode (unsigned long int opcode) { int c = 0; genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); - genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); + genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, GF_RMW); if (curi->smode == immi) { // SUBAQ.x is always 8 cycles c += 4; @@ -1986,7 +2064,7 @@ static void gen_opcode (unsigned long int opcode) if (!isreg (curi->smode)) addcycles000 (2); genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA | GF_RMW); fill_prefetch_next (); if (curi->size == sz_long && isreg (curi->smode)) addcycles000 (4); @@ -2000,7 +2078,7 @@ static void gen_opcode (unsigned long int opcode) if (!isreg (curi->smode)) addcycles000 (2); genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA | GF_RMW); fill_prefetch_next (); start_brace (); printf ("\tuae_u16 newv_lo = (dst & 0xF) - (src & 0xF) - (GET_XFLG () ? 1 : 0);\n"); @@ -2029,7 +2107,7 @@ static void gen_opcode (unsigned long int opcode) { int c = 0; genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_RMW); if (curi->dmode == Dreg) { if (curi->size == sz_long) { c += 2; @@ -2049,7 +2127,7 @@ static void gen_opcode (unsigned long int opcode) { int c = 0; genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); - genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); + genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, GF_RMW); if (curi->smode == immi) { // ADDAQ.x is always 8 cycles c += 4; @@ -2070,7 +2148,7 @@ static void gen_opcode (unsigned long int opcode) if (!isreg (curi->smode)) addcycles000 (2); genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA | GF_RMW); fill_prefetch_next (); if (curi->size == sz_long && isreg (curi->smode)) addcycles000 (4); @@ -2084,7 +2162,7 @@ static void gen_opcode (unsigned long int opcode) if (!isreg (curi->smode)) addcycles000 (2); genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA | GF_RMW); fill_prefetch_next (); start_brace (); printf ("\tuae_u16 newv_lo = (src & 0xF) + (dst & 0xF) + (GET_XFLG () ? 1 : 0);\n"); @@ -2112,7 +2190,7 @@ static void gen_opcode (unsigned long int opcode) genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); break; case i_NEG: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW); fill_prefetch_next (); if (isreg (curi->smode) && curi->size == sz_long) addcycles000 (2); @@ -2121,7 +2199,7 @@ static void gen_opcode (unsigned long int opcode) genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src"); break; case i_NEGX: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW); fill_prefetch_next (); if (isreg (curi->smode) && curi->size == sz_long) addcycles000 (2); @@ -2132,7 +2210,7 @@ static void gen_opcode (unsigned long int opcode) genastore_rev ("newv", curi->smode, "srcreg", curi->size, "src"); break; case i_NBCD: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW); if (isreg (curi->smode)) addcycles000 (2); fill_prefetch_next (); @@ -2167,7 +2245,7 @@ static void gen_opcode (unsigned long int opcode) genastore_rev ("0", curi->smode, "srcreg", curi->size, "src"); break; case i_NOT: - genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); + genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW); fill_prefetch_next (); if (isreg (curi->smode) && curi->size == sz_long) addcycles000 (2); @@ -2192,7 +2270,7 @@ static void gen_opcode (unsigned long int opcode) case i_BCLR: case i_BSET: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); - genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_IR2IRC); + genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_IR2IRC | GF_RMW); fill_prefetch_next (); bsetcycles (curi); // bclr needs 1 extra cycle @@ -2478,7 +2556,7 @@ static void gen_opcode (unsigned long int opcode) printf ("\t\texception3i (0x%04X, newpc);\n", opcode); printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t}\n"); - printf ("\t\tm68k_setpc (newpc);\n"); + setpc ("newpc"); printf ("\tipl_fetch ();\n"); need_endlabel = 1; } @@ -2559,7 +2637,7 @@ static void gen_opcode (unsigned long int opcode) printf ("\tm68k_do_rts ();\n"); printf ("\tif (m68k_getpc () & 1) {\n"); printf ("\t\tuaecptr faultpc = m68k_getpc ();\n"); - printf ("\t\tm68k_setpc (pc);\n"); + setpc ("pc"); printf ("\t\texception3i (0x%04X, faultpc);\n", opcode); printf ("\t}\n"); count_read += 2; @@ -2586,7 +2664,7 @@ static void gen_opcode (unsigned long int opcode) printf ("\tMakeFromSR ();\n"); printf ("\tif (m68k_getpc () & 1) {\n"); printf ("\t\tuaecptr faultpc = m68k_getpc ();\n"); - printf ("\t\tm68k_setpc (oldpc);\n"); + setpc ("oldpc"); printf ("\t\texception3i (0x%04X, faultpc);\n", opcode); printf ("\t}\n"); m68k_pc_offset = 0; @@ -2994,7 +3072,7 @@ static void gen_opcode (unsigned long int opcode) case i_ASR: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW); fill_prefetch_next(); start_brace (); switch (curi->size) { @@ -3030,7 +3108,7 @@ static void gen_opcode (unsigned long int opcode) break; case i_ASL: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW); fill_prefetch_next(); start_brace (); switch (curi->size) { @@ -3069,7 +3147,7 @@ static void gen_opcode (unsigned long int opcode) break; case i_LSR: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW); fill_prefetch_next(); start_brace (); switch (curi->size) { @@ -3101,7 +3179,7 @@ static void gen_opcode (unsigned long int opcode) break; case i_LSL: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW); fill_prefetch_next(); start_brace (); switch (curi->size) { @@ -3133,7 +3211,7 @@ static void gen_opcode (unsigned long int opcode) break; case i_ROL: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW); fill_prefetch_next (); start_brace (); switch (curi->size) { @@ -3163,7 +3241,7 @@ static void gen_opcode (unsigned long int opcode) break; case i_ROR: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW); fill_prefetch_next (); start_brace (); switch (curi->size) { @@ -3193,7 +3271,7 @@ static void gen_opcode (unsigned long int opcode) break; case i_ROXL: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW); fill_prefetch_next (); start_brace (); switch (curi->size) { @@ -3226,7 +3304,7 @@ static void gen_opcode (unsigned long int opcode) break; case i_ROXR: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); - genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); + genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW); fill_prefetch_next (); start_brace (); switch (curi->size) { @@ -3261,7 +3339,7 @@ static void gen_opcode (unsigned long int opcode) genastore ("val", curi->dmode, "dstreg", curi->size, "data"); break; case i_ASRW: - genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); + genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW); fill_prefetch_next (); start_brace (); switch (curi->size) { @@ -3279,7 +3357,7 @@ static void gen_opcode (unsigned long int opcode) genastore ("val", curi->smode, "srcreg", curi->size, "data"); break; case i_ASLW: - genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); + genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW); fill_prefetch_next (); start_brace (); switch (curi->size) { @@ -3300,7 +3378,7 @@ static void gen_opcode (unsigned long int opcode) genastore ("val", curi->smode, "srcreg", curi->size, "data"); break; case i_LSRW: - genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); + genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW); fill_prefetch_next (); start_brace (); switch (curi->size) { @@ -3317,7 +3395,7 @@ static void gen_opcode (unsigned long int opcode) genastore ("val", curi->smode, "srcreg", curi->size, "data"); break; case i_LSLW: - genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); + genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW); fill_prefetch_next (); start_brace (); switch (curi->size) { @@ -3334,7 +3412,7 @@ static void gen_opcode (unsigned long int opcode) genastore ("val", curi->smode, "srcreg", curi->size, "data"); break; case i_ROLW: - genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); + genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW); fill_prefetch_next (); start_brace (); switch (curi->size) { @@ -3351,7 +3429,7 @@ static void gen_opcode (unsigned long int opcode) genastore ("val", curi->smode, "srcreg", curi->size, "data"); break; case i_RORW: - genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); + genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW); fill_prefetch_next (); start_brace (); switch (curi->size) { @@ -3368,7 +3446,7 @@ static void gen_opcode (unsigned long int opcode) genastore ("val", curi->smode, "srcreg", curi->size, "data"); break; case i_ROXLW: - genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); + genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW); fill_prefetch_next (); start_brace (); switch (curi->size) { @@ -3386,7 +3464,7 @@ static void gen_opcode (unsigned long int opcode) genastore ("val", curi->smode, "srcreg", curi->size, "data"); break; case i_ROXRW: - genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); + genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW); fill_prefetch_next (); start_brace (); switch (curi->size) { @@ -3479,13 +3557,13 @@ static void gen_opcode (unsigned long int opcode) printf ("\tuae_u32 rn2 = regs.regs[(extra >> 12) & 15];\n"); if (curi->size == sz_word) { int old_brace_level = n_braces; - printf ("\tuae_u16 dst1 = %s (rn1), dst2 = %s (rn2);\n", srcwrmw, srcwrmw); + printf ("\tuae_u16 dst1 = %s (rn1), dst2 = %s (rn2);\n", srcwlrmw, srcwlrmw); genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, (extra >> 16) & 7)", "dst1"); printf ("\tif (GET_ZFLG ()) {\n"); genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, extra & 7)", "dst2"); printf ("\tif (GET_ZFLG ()) {\n"); - printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 22) & 7));\n", dstwrmw); - printf ("\t%s (rn2, m68k_dreg (regs, (extra >> 6) & 7));\n", dstwrmw); + printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 22) & 7));\n", dstwlrmw); + printf ("\t%s (rn2, m68k_dreg (regs, (extra >> 6) & 7));\n", dstwlrmw); printf ("\t}}\n"); pop_braces (old_brace_level); printf ("\tif (! GET_ZFLG ()) {\n"); @@ -3494,13 +3572,13 @@ static void gen_opcode (unsigned long int opcode) printf ("\t}\n"); } else { int old_brace_level = n_braces; - printf ("\tuae_u32 dst1 = %s (rn1), dst2 = %s (rn2);\n", srclrmw, srclrmw); + printf ("\tuae_u32 dst1 = %s (rn1), dst2 = %s (rn2);\n", srcllrmw, srcllrmw); genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, (extra >> 16) & 7)", "dst1"); printf ("\tif (GET_ZFLG ()) {\n"); genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, extra & 7)", "dst2"); printf ("\tif (GET_ZFLG ()) {\n"); - printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 22) & 7));\n", dstlrmw); - printf ("\t%s (rn2, m68k_dreg (regs, (extra >> 6) & 7));\n", dstlrmw); + printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 22) & 7));\n", dstllrmw); + printf ("\t%s (rn2, m68k_dreg (regs, (extra >> 6) & 7));\n", dstllrmw); printf ("\t}}\n"); pop_braces (old_brace_level); printf ("\tif (! GET_ZFLG ()) {\n"); @@ -3593,6 +3671,7 @@ static void gen_opcode (unsigned long int opcode) case i_BFINS: { char *getb, *putb; + int flags = 0; if (using_mmu || using_ce020) { getb = "x_get_bitfield"; @@ -3601,6 +3680,8 @@ static void gen_opcode (unsigned long int opcode) getb = "get_bitfield"; putb = "put_bitfield"; } + if (curi->mnemo == i_BFCHG || curi->mnemo == i_BFCLR || curi->mnemo == i_BFSET || curi->mnemo == i_BFINS) + flags = GF_RMW; genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); genamode (curi->dmode, "dstreg", sz_long, "dst", 2, 0, 0); diff --git a/hardfile.cpp b/hardfile.cpp index ddbe7a71..209c614a 100644 --- a/hardfile.cpp +++ b/hardfile.cpp @@ -1129,7 +1129,7 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua s[0] = 0x70; s[2] = 5; /* ILLEGAL REQUEST */ s[12] = 0x25; /* INVALID LUN */ - ls = 12; + ls = 0x12; goto err; } switch (cmdbuf[0]) diff --git a/include/cpummu.h b/include/cpummu.h index 7c8fe43b..ea674289 100644 --- a/include/cpummu.h +++ b/include/cpummu.h @@ -44,12 +44,14 @@ static __inline void flush_internals (void) { } extern int mmu060_state; -extern uae_u16 mmu060_opcode; extern int mmu040_movem; extern uaecptr mmu040_movem_ea; extern bool mmu_pagesize_8k; +extern uae_u16 mmu_opcode; +extern bool mmu_restart; +extern bool mmu_ttr_enabled; //typedef uae_u8 flagtype; @@ -275,10 +277,12 @@ STATIC_INLINE int mmu_do_match_ttr(uae_u32 ttr, uaecptr addr, bool super) return TTR_NO_MATCH; } -STATIC_INLINE int mmu_match_ttr(uaecptr addr, bool super, bool data) +STATIC_INLINE int mmu_match_ttr(uaecptr addr, bool super, bool data, bool rmw) { int res; + if (!mmu_ttr_enabled) + return TTR_NO_MATCH; if (data) { res = mmu_do_match_ttr(regs.dtt0, addr, super); if (res == TTR_NO_MATCH) @@ -290,34 +294,38 @@ STATIC_INLINE int mmu_match_ttr(uaecptr addr, bool super, bool data) } return res; } -extern void mmu_bus_error_ttr_write_fault(uaecptr addr, bool super, bool data, uae_u32 val, int size); -STATIC_INLINE int mmu_match_ttr_write(uaecptr addr, bool super, bool data, uae_u32 val,int size) +extern void mmu_bus_error_ttr_write_fault(uaecptr addr, bool super, bool data, uae_u32 val, int size, bool rmw); +STATIC_INLINE int mmu_match_ttr_write(uaecptr addr, bool super, bool data, uae_u32 val, int size, bool rmw) { - int res = mmu_match_ttr(addr, super, data); + if (!mmu_ttr_enabled) + return TTR_NO_MATCH; + int res = mmu_match_ttr(addr, super, data, rmw); if (res == TTR_NO_WRITE) - mmu_bus_error_ttr_write_fault(addr, super, data, val, size); + mmu_bus_error_ttr_write_fault(addr, super, data, val, size, rmw); return res; } -extern uae_u16 REGPARAM3 mmu_get_word_unaligned(uaecptr addr, bool data) REGPARAM; -extern uae_u32 REGPARAM3 mmu_get_long_unaligned(uaecptr addr, bool data) REGPARAM; +extern void mmu_tt_modified (void); + +extern uae_u16 REGPARAM3 mmu_get_word_unaligned(uaecptr addr, bool data, bool rmw) REGPARAM; +extern uae_u32 REGPARAM3 mmu_get_long_unaligned(uaecptr addr, bool data, bool rmw) REGPARAM; extern uae_u8 REGPARAM3 mmu_get_byte_slow(uaecptr addr, bool super, bool data, - int size, struct mmu_atc_line *cl) REGPARAM; + int size, bool rmw, struct mmu_atc_line *cl) REGPARAM; extern uae_u16 REGPARAM3 mmu_get_word_slow(uaecptr addr, bool super, bool data, - int size, struct mmu_atc_line *cl) REGPARAM; + int size, bool rmw, struct mmu_atc_line *cl) REGPARAM; extern uae_u32 REGPARAM3 mmu_get_long_slow(uaecptr addr, bool super, bool data, - int size, struct mmu_atc_line *cl) REGPARAM; + int size, bool rmw, struct mmu_atc_line *cl) REGPARAM; -extern void REGPARAM3 mmu_put_word_unaligned(uaecptr addr, uae_u16 val, bool data) REGPARAM; -extern void REGPARAM3 mmu_put_long_unaligned(uaecptr addr, uae_u32 val, bool data) REGPARAM; +extern void REGPARAM3 mmu_put_word_unaligned(uaecptr addr, uae_u16 val, bool data, bool rmw) REGPARAM; +extern void REGPARAM3 mmu_put_long_unaligned(uaecptr addr, uae_u32 val, bool data, bool rmw) REGPARAM; extern void REGPARAM3 mmu_put_byte_slow(uaecptr addr, uae_u8 val, bool super, bool data, - int size, struct mmu_atc_line *cl) REGPARAM; + int size, bool rmw, struct mmu_atc_line *cl) REGPARAM; extern void REGPARAM3 mmu_put_word_slow(uaecptr addr, uae_u16 val, bool super, bool data, - int size, struct mmu_atc_line *cl) REGPARAM; + int size, bool rmw, struct mmu_atc_line *cl) REGPARAM; extern void REGPARAM3 mmu_put_long_slow(uaecptr addr, uae_u32 val, bool super, bool data, - int size, struct mmu_atc_line *cl) REGPARAM; + int size, bool rmw, struct mmu_atc_line *cl) REGPARAM; extern void mmu_make_transparent_region(uaecptr baseaddr, uae_u32 size, int datamode); @@ -347,8 +355,8 @@ extern void REGPARAM3 dfc_put_byte(uaecptr addr, uae_u8 val) REGPARAM; #define dfc060_put_word dfc_put_word #define dfc060_put_byte dfc_put_byte -extern void uae_mmu_put_rmw (uaecptr addr, uae_u32 v, int size, int type); -extern uae_u32 uae_mmu_get_rmw (uaecptr addr, int size, int type); +extern void uae_mmu_put_lrmw (uaecptr addr, uae_u32 v, int size, int type); +extern uae_u32 uae_mmu_get_lrmw (uaecptr addr, int size, int type); extern void REGPARAM3 mmu_flush_atc(uaecptr addr, bool super, bool global) REGPARAM; extern void REGPARAM3 mmu_flush_atc_all(bool global) REGPARAM; @@ -369,64 +377,64 @@ static ALWAYS_INLINE void mmu_get_move16(uaecptr addr, uae_u32 *v, bool data, in for (int i = 0; i < 4; i++) { uaecptr addr2 = addr + i * 4; // addr,super,data - if ((!regs.mmu_enabled) || (mmu_match_ttr(addr2,regs.s != 0,data)!=TTR_NO_MATCH)) + if ((!regs.mmu_enabled) || (mmu_match_ttr(addr2,regs.s != 0,data,false)!=TTR_NO_MATCH)) v[i] = phys_get_long(addr2); else if (likely(mmu_lookup(addr2, data, false, &cl))) v[i] = phys_get_long(mmu_get_real_address(addr2, cl)); else - v[i] = mmu_get_long_slow(addr2, regs.s != 0, data, size, cl); + v[i] = mmu_get_long_slow(addr2, regs.s != 0, data, size, false, cl); } } -static ALWAYS_INLINE uae_u32 mmu_get_long(uaecptr addr, bool data, int size) +static ALWAYS_INLINE uae_u32 mmu_get_long(uaecptr addr, bool data, int size, bool rmw) { struct mmu_atc_line *cl; // addr,super,data - if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data)!=TTR_NO_MATCH)) + if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data,rmw)!=TTR_NO_MATCH)) return phys_get_long(addr); if (likely(mmu_lookup(addr, data, false, &cl))) return phys_get_long(mmu_get_real_address(addr, cl)); - return mmu_get_long_slow(addr, regs.s != 0, data, size, cl); + return mmu_get_long_slow(addr, regs.s != 0, data, size, rmw, cl); } -static ALWAYS_INLINE uae_u16 mmu_get_word(uaecptr addr, bool data, int size) +static ALWAYS_INLINE uae_u16 mmu_get_word(uaecptr addr, bool data, int size, bool rmw) { struct mmu_atc_line *cl; // addr,super,data - if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data)!=TTR_NO_MATCH)) + if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data,rmw)!=TTR_NO_MATCH)) return phys_get_word(addr); if (likely(mmu_lookup(addr, data, false, &cl))) return phys_get_word(mmu_get_real_address(addr, cl)); - return mmu_get_word_slow(addr, regs.s != 0, data, size, cl); + return mmu_get_word_slow(addr, regs.s != 0, data, size, rmw, cl); } -static ALWAYS_INLINE uae_u8 mmu_get_byte(uaecptr addr, bool data, int size) +static ALWAYS_INLINE uae_u8 mmu_get_byte(uaecptr addr, bool data, int size, bool rmw) { struct mmu_atc_line *cl; // addr,super,data - if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data)!=TTR_NO_MATCH)) + if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,regs.s != 0,data,rmw)!=TTR_NO_MATCH)) return phys_get_byte(addr); if (likely(mmu_lookup(addr, data, false, &cl))) return phys_get_byte(mmu_get_real_address(addr, cl)); - return mmu_get_byte_slow(addr, regs.s != 0, data, size, cl); + return mmu_get_byte_slow(addr, regs.s != 0, data, size, rmw, cl); } -static ALWAYS_INLINE void mmu_put_long(uaecptr addr, uae_u32 val, bool data, int size) +static ALWAYS_INLINE void mmu_put_long(uaecptr addr, uae_u32 val, bool data, int size, bool rmw) { struct mmu_atc_line *cl; // addr,super,data - if ((!regs.mmu_enabled) || mmu_match_ttr_write(addr,regs.s != 0,data,val,size)==TTR_OK_MATCH) { + if ((!regs.mmu_enabled) || mmu_match_ttr_write(addr,regs.s != 0,data,val,size,rmw)==TTR_OK_MATCH) { phys_put_long(addr,val); return; } if (likely(mmu_lookup(addr, data, true, &cl))) phys_put_long(mmu_get_real_address(addr, cl), val); else - mmu_put_long_slow(addr, val, regs.s != 0, data, size, cl); + mmu_put_long_slow(addr, val, regs.s != 0, data, size, rmw, cl); } static ALWAYS_INLINE void mmu_put_move16(uaecptr addr, uae_u32 *val, bool data, int size) @@ -435,43 +443,43 @@ static ALWAYS_INLINE void mmu_put_move16(uaecptr addr, uae_u32 *val, bool data, for (int i = 0; i < 4; i++) { uaecptr addr2 = addr + i * 4; // addr,super,data - if ((!regs.mmu_enabled) || (mmu_match_ttr_write(addr2,regs.s != 0,data,val[i],size)==TTR_OK_MATCH)) + if ((!regs.mmu_enabled) || (mmu_match_ttr_write(addr2,regs.s != 0,data,val[i],size,false)==TTR_OK_MATCH)) phys_put_long(addr2,val[i]); else if (likely(mmu_lookup(addr2, data, true, &cl))) phys_put_long(mmu_get_real_address(addr2, cl), val[i]); else - mmu_put_long_slow(addr2, val[i], regs.s != 0, data, size, cl); + mmu_put_long_slow(addr2, val[i], regs.s != 0, data, size, false, cl); } } -static ALWAYS_INLINE void mmu_put_word(uaecptr addr, uae_u16 val, bool data, int size) +static ALWAYS_INLINE void mmu_put_word(uaecptr addr, uae_u16 val, bool data, int size, bool rmw) { struct mmu_atc_line *cl; // addr,super,data - if ((!regs.mmu_enabled) || (mmu_match_ttr_write(addr,regs.s != 0,data,val,size)==TTR_OK_MATCH)) { + if ((!regs.mmu_enabled) || (mmu_match_ttr_write(addr,regs.s != 0,data,val,size,rmw)==TTR_OK_MATCH)) { phys_put_word(addr,val); return; } if (likely(mmu_lookup(addr, data, true, &cl))) phys_put_word(mmu_get_real_address(addr, cl), val); else - mmu_put_word_slow(addr, val, regs.s != 0, data, size, cl); + mmu_put_word_slow(addr, val, regs.s != 0, data, size, rmw, cl); } -static ALWAYS_INLINE void mmu_put_byte(uaecptr addr, uae_u8 val, bool data, int size) +static ALWAYS_INLINE void mmu_put_byte(uaecptr addr, uae_u8 val, bool data, int size, bool rmw) { struct mmu_atc_line *cl; // addr,super,data - if ((!regs.mmu_enabled) || (mmu_match_ttr_write(addr,regs.s != 0,data,val,size)==TTR_OK_MATCH)) { + if ((!regs.mmu_enabled) || (mmu_match_ttr_write(addr,regs.s != 0,data,val,size,rmw)==TTR_OK_MATCH)) { phys_put_byte(addr,val); return; } if (likely(mmu_lookup(addr, data, true, &cl))) phys_put_byte(mmu_get_real_address(addr, cl), val); else - mmu_put_byte_slow(addr, val, regs.s != 0, data, size, cl); + mmu_put_byte_slow(addr, val, regs.s != 0, data, size, rmw, cl); } static ALWAYS_INLINE uae_u32 mmu_get_user_long(uaecptr addr, bool super, bool data, bool write, int size) @@ -479,11 +487,11 @@ static ALWAYS_INLINE uae_u32 mmu_get_user_long(uaecptr addr, bool super, bool da struct mmu_atc_line *cl; // addr,super,data - if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)!=TTR_NO_MATCH)) + if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data,false)!=TTR_NO_MATCH)) return phys_get_long(addr); if (likely(mmu_user_lookup(addr, super, data, write, &cl))) return phys_get_long(mmu_get_real_address(addr, cl)); - return mmu_get_long_slow(addr, super, data, size, cl); + return mmu_get_long_slow(addr, super, data, size, false, cl); } static ALWAYS_INLINE uae_u16 mmu_get_user_word(uaecptr addr, bool super, bool data, bool write, int size) @@ -491,11 +499,11 @@ static ALWAYS_INLINE uae_u16 mmu_get_user_word(uaecptr addr, bool super, bool da struct mmu_atc_line *cl; // addr,super,data - if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)!=TTR_NO_MATCH)) + if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data,false)!=TTR_NO_MATCH)) return phys_get_word(addr); if (likely(mmu_user_lookup(addr, super, data, write, &cl))) return phys_get_word(mmu_get_real_address(addr, cl)); - return mmu_get_word_slow(addr, super, data, size, cl); + return mmu_get_word_slow(addr, super, data, size, false, cl); } static ALWAYS_INLINE uae_u8 mmu_get_user_byte(uaecptr addr, bool super, bool data, bool write, int size) @@ -503,11 +511,11 @@ static ALWAYS_INLINE uae_u8 mmu_get_user_byte(uaecptr addr, bool super, bool dat struct mmu_atc_line *cl; // addr,super,data - if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)!=TTR_NO_MATCH)) + if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data,false)!=TTR_NO_MATCH)) return phys_get_byte(addr); if (likely(mmu_user_lookup(addr, super, data, write, &cl))) return phys_get_byte(mmu_get_real_address(addr, cl)); - return mmu_get_byte_slow(addr, super, data, size, cl); + return mmu_get_byte_slow(addr, super, data, size, false, cl); } static ALWAYS_INLINE void mmu_put_user_long(uaecptr addr, uae_u32 val, bool super, bool data, int size) @@ -515,14 +523,14 @@ static ALWAYS_INLINE void mmu_put_user_long(uaecptr addr, uae_u32 val, bool supe struct mmu_atc_line *cl; // addr,super,data - if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)==TTR_OK_MATCH)) { + if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data,false)==TTR_OK_MATCH)) { phys_put_long(addr,val); return; } if (likely(mmu_user_lookup(addr, super, data, true, &cl))) phys_put_long(mmu_get_real_address(addr, cl), val); else - mmu_put_long_slow(addr, val, super, data, size, cl); + mmu_put_long_slow(addr, val, super, data, size, false, cl); } static ALWAYS_INLINE void mmu_put_user_word(uaecptr addr, uae_u16 val, bool super, bool data, int size) @@ -530,14 +538,14 @@ static ALWAYS_INLINE void mmu_put_user_word(uaecptr addr, uae_u16 val, bool supe struct mmu_atc_line *cl; // addr,super,data - if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)==TTR_OK_MATCH)) { + if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data,false)==TTR_OK_MATCH)) { phys_put_word(addr,val); return; } if (likely(mmu_user_lookup(addr, super, data, true, &cl))) phys_put_word(mmu_get_real_address(addr, cl), val); else - mmu_put_word_slow(addr, val, super, data, size, cl); + mmu_put_word_slow(addr, val, super, data, size, false, cl); } static ALWAYS_INLINE void mmu_put_user_byte(uaecptr addr, uae_u8 val, bool super, bool data, int size) @@ -545,14 +553,14 @@ static ALWAYS_INLINE void mmu_put_user_byte(uaecptr addr, uae_u8 val, bool super struct mmu_atc_line *cl; // addr,super,data - if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data)==TTR_OK_MATCH)) { + if ((!regs.mmu_enabled) || (mmu_match_ttr(addr,super,data,false)==TTR_OK_MATCH)) { phys_put_byte(addr,val); return; } if (likely(mmu_user_lookup(addr, super, data, true, &cl))) phys_put_byte(mmu_get_real_address(addr, cl), val); else - mmu_put_byte_slow(addr, val, super, data, size, cl); + mmu_put_byte_slow(addr, val, super, data, size, false, cl); } @@ -584,87 +592,87 @@ static ALWAYS_INLINE uae_u32 HWget_b(uaecptr addr) static ALWAYS_INLINE uae_u32 uae_mmu040_get_ilong(uaecptr addr) { if (unlikely(is_unaligned(addr, 4))) - return mmu_get_long_unaligned(addr, false); - return mmu_get_long(addr, false, sz_long); + return mmu_get_long_unaligned(addr, false, false); + return mmu_get_long(addr, false, sz_long, false); } static ALWAYS_INLINE uae_u16 uae_mmu040_get_iword(uaecptr addr) { if (unlikely(is_unaligned(addr, 2))) - return mmu_get_word_unaligned(addr, false); - return mmu_get_word(addr, false, sz_word); + return mmu_get_word_unaligned(addr, false, false); + return mmu_get_word(addr, false, sz_word, false); } static ALWAYS_INLINE uae_u16 uae_mmu040_get_ibyte(uaecptr addr) { - return mmu_get_byte(addr, false, sz_byte); + return mmu_get_byte(addr, false, sz_byte, false); } static ALWAYS_INLINE uae_u32 uae_mmu040_get_long(uaecptr addr) { if (unlikely(is_unaligned(addr, 4))) - return mmu_get_long_unaligned(addr, true); - return mmu_get_long(addr, true, sz_long); + return mmu_get_long_unaligned(addr, true, false); + return mmu_get_long(addr, true, sz_long, false); } static ALWAYS_INLINE uae_u16 uae_mmu040_get_word(uaecptr addr) { if (unlikely(is_unaligned(addr, 2))) - return mmu_get_word_unaligned(addr, true); - return mmu_get_word(addr, true, sz_word); + return mmu_get_word_unaligned(addr, true, false); + return mmu_get_word(addr, true, sz_word, false); } static ALWAYS_INLINE uae_u8 uae_mmu040_get_byte(uaecptr addr) { - return mmu_get_byte(addr, true, sz_byte); + return mmu_get_byte(addr, true, sz_byte, false); } static ALWAYS_INLINE void uae_mmu040_put_word(uaecptr addr, uae_u16 val) { if (unlikely(is_unaligned(addr, 2))) - mmu_put_word_unaligned(addr, val, true); + mmu_put_word_unaligned(addr, val, true, false); else - mmu_put_word(addr, val, true, sz_word); + mmu_put_word(addr, val, true, sz_word, false); } static ALWAYS_INLINE void uae_mmu040_put_byte(uaecptr addr, uae_u8 val) { - mmu_put_byte(addr, val, true, sz_byte); + mmu_put_byte(addr, val, true, sz_byte, false); } static ALWAYS_INLINE void uae_mmu040_put_long(uaecptr addr, uae_u32 val) { if (unlikely(is_unaligned(addr, 4))) - mmu_put_long_unaligned(addr, val, true); + mmu_put_long_unaligned(addr, val, true, false); else - mmu_put_long(addr, val, true, sz_long); + mmu_put_long(addr, val, true, sz_long, false); } static ALWAYS_INLINE uae_u32 uae_mmu060_get_ilong(uaecptr addr) { if (unlikely(is_unaligned(addr, 4))) - return mmu_get_long_unaligned(addr, false); - return mmu_get_long(addr, false, sz_long); + return mmu_get_long_unaligned(addr, false, false); + return mmu_get_long(addr, false, sz_long, false); } static ALWAYS_INLINE uae_u16 uae_mmu060_get_iword(uaecptr addr) { if (unlikely(is_unaligned(addr, 2))) - return mmu_get_word_unaligned(addr, false); - return mmu_get_word(addr, false, sz_word); + return mmu_get_word_unaligned(addr, false, false); + return mmu_get_word(addr, false, sz_word, false); } static ALWAYS_INLINE uae_u16 uae_mmu060_get_ibyte(uaecptr addr) { - return mmu_get_byte(addr, false, sz_byte); + return mmu_get_byte(addr, false, sz_byte, false); } -static ALWAYS_INLINE uae_u32 uae_mmu060_get_long(uaecptr addr) +static ALWAYS_INLINE uae_u32 uae_mmu060_get_long(uaecptr addr, bool rmw) { if (unlikely(is_unaligned(addr, 4))) - return mmu_get_long_unaligned(addr, true); - return mmu_get_long(addr, true, sz_long); + return mmu_get_long_unaligned(addr, true, rmw); + return mmu_get_long(addr, true, sz_long, rmw); } -static ALWAYS_INLINE uae_u16 uae_mmu060_get_word(uaecptr addr) +static ALWAYS_INLINE uae_u16 uae_mmu060_get_word(uaecptr addr, bool rmw) { if (unlikely(is_unaligned(addr, 2))) - return mmu_get_word_unaligned(addr, true); - return mmu_get_word(addr, true, sz_word); + return mmu_get_word_unaligned(addr, true, rmw); + return mmu_get_word(addr, true, sz_word, rmw); } -static ALWAYS_INLINE uae_u8 uae_mmu060_get_byte(uaecptr addr) +static ALWAYS_INLINE uae_u8 uae_mmu060_get_byte(uaecptr addr, bool rmw) { - return mmu_get_byte(addr, true, sz_byte); + return mmu_get_byte(addr, true, sz_byte, rmw); } static ALWAYS_INLINE void uae_mmu_get_move16(uaecptr addr, uae_u32 *val) { @@ -672,23 +680,23 @@ static ALWAYS_INLINE void uae_mmu_get_move16(uaecptr addr, uae_u32 *val) mmu_get_move16(addr, val, true, 16); } -static ALWAYS_INLINE void uae_mmu060_put_long(uaecptr addr, uae_u32 val) +static ALWAYS_INLINE void uae_mmu060_put_long(uaecptr addr, uae_u32 val, bool rmw) { if (unlikely(is_unaligned(addr, 4))) - mmu_put_long_unaligned(addr, val, true); + mmu_put_long_unaligned(addr, val, true, rmw); else - mmu_put_long(addr, val, true, sz_long); + mmu_put_long(addr, val, true, sz_long, rmw); } -static ALWAYS_INLINE void uae_mmu060_put_word(uaecptr addr, uae_u16 val) +static ALWAYS_INLINE void uae_mmu060_put_word(uaecptr addr, uae_u16 val, bool rmw) { if (unlikely(is_unaligned(addr, 2))) - mmu_put_word_unaligned(addr, val, true); + mmu_put_word_unaligned(addr, val, true, rmw); else - mmu_put_word(addr, val, true, sz_word); + mmu_put_word(addr, val, true, sz_word, rmw); } -static ALWAYS_INLINE void uae_mmu060_put_byte(uaecptr addr, uae_u8 val) +static ALWAYS_INLINE void uae_mmu060_put_byte(uaecptr addr, uae_u8 val, bool rmw) { - mmu_put_byte(addr, val, true, sz_byte); + mmu_put_byte(addr, val, true, sz_byte, rmw); } static ALWAYS_INLINE void uae_mmu_put_move16(uaecptr addr, uae_u32 *val) { @@ -696,7 +704,7 @@ static ALWAYS_INLINE void uae_mmu_put_move16(uaecptr addr, uae_u32 *val) mmu_put_move16(addr, val, true, 16); } - +// normal 040 STATIC_INLINE void put_byte_mmu040 (uaecptr addr, uae_u32 v) { uae_mmu040_put_byte (addr, v); @@ -721,30 +729,30 @@ STATIC_INLINE uae_u32 get_long_mmu040 (uaecptr addr) { return uae_mmu040_get_long (addr); } - +// normal 060 STATIC_INLINE void put_byte_mmu060 (uaecptr addr, uae_u32 v) { - uae_mmu060_put_byte (addr, v); + uae_mmu060_put_byte (addr, v, false); } STATIC_INLINE void put_word_mmu060 (uaecptr addr, uae_u32 v) { - uae_mmu060_put_word (addr, v); + uae_mmu060_put_word (addr, v, false); } STATIC_INLINE void put_long_mmu060 (uaecptr addr, uae_u32 v) { - uae_mmu060_put_long (addr, v); + uae_mmu060_put_long (addr, v, false); } STATIC_INLINE uae_u32 get_byte_mmu060 (uaecptr addr) { - return uae_mmu060_get_byte (addr); + return uae_mmu060_get_byte (addr, false); } STATIC_INLINE uae_u32 get_word_mmu060 (uaecptr addr) { - return uae_mmu060_get_word (addr); + return uae_mmu060_get_word (addr, false); } STATIC_INLINE uae_u32 get_long_mmu060 (uaecptr addr) { - return uae_mmu060_get_long (addr); + return uae_mmu060_get_long (addr, false); } STATIC_INLINE void get_move16_mmu (uaecptr addr, uae_u32 *v) @@ -756,54 +764,80 @@ STATIC_INLINE void put_move16_mmu (uaecptr addr, uae_u32 *v) return uae_mmu_put_move16 (addr, v); } +// locked rmw 060 +STATIC_INLINE void put_lrmw_byte_mmu060 (uaecptr addr, uae_u32 v) +{ + uae_mmu_put_lrmw (addr, v, sz_byte, 1); +} +STATIC_INLINE void put_lrmw_word_mmu060 (uaecptr addr, uae_u32 v) +{ + uae_mmu_put_lrmw (addr, v, sz_word, 1); +} +STATIC_INLINE void put_lrmw_long_mmu060 (uaecptr addr, uae_u32 v) +{ + uae_mmu_put_lrmw (addr, v, sz_long, 1); +} +STATIC_INLINE uae_u32 get_lrmw_byte_mmu060 (uaecptr addr) +{ + return uae_mmu_get_lrmw (addr, sz_byte, 1); +} +STATIC_INLINE uae_u32 get_lrmw_word_mmu060 (uaecptr addr) +{ + return uae_mmu_get_lrmw (addr, sz_word, 1); +} +STATIC_INLINE uae_u32 get_lrmw_long_mmu060 (uaecptr addr) +{ + return uae_mmu_get_lrmw (addr, sz_long, 1); +} +// normal rmw 060 STATIC_INLINE void put_rmw_byte_mmu060 (uaecptr addr, uae_u32 v) { - uae_mmu_put_rmw (addr, v, sz_byte, 1); + uae_mmu060_put_byte (addr, v, true); } STATIC_INLINE void put_rmw_word_mmu060 (uaecptr addr, uae_u32 v) { - uae_mmu_put_rmw (addr, v, sz_word, 1); + uae_mmu060_put_word (addr, v, true); } STATIC_INLINE void put_rmw_long_mmu060 (uaecptr addr, uae_u32 v) { - uae_mmu_put_rmw (addr, v, sz_long, 1); + uae_mmu060_put_long (addr, v, true); } STATIC_INLINE uae_u32 get_rmw_byte_mmu060 (uaecptr addr) { - return uae_mmu_get_rmw (addr, sz_byte, 1); + return uae_mmu060_get_byte (addr, true); } STATIC_INLINE uae_u32 get_rmw_word_mmu060 (uaecptr addr) { - return uae_mmu_get_rmw (addr, sz_word, 1); + return uae_mmu060_get_word (addr, true); } STATIC_INLINE uae_u32 get_rmw_long_mmu060 (uaecptr addr) { - return uae_mmu_get_rmw (addr, sz_long, 1); + return uae_mmu060_get_long (addr, true); } - -STATIC_INLINE void put_rmw_byte_mmu040 (uaecptr addr, uae_u32 v) +// locked rmw 040 +STATIC_INLINE void put_lrmw_byte_mmu040 (uaecptr addr, uae_u32 v) { - uae_mmu_put_rmw (addr, v, sz_byte, 0); + uae_mmu_put_lrmw (addr, v, sz_byte, 0); } -STATIC_INLINE void put_rmw_word_mmu040 (uaecptr addr, uae_u32 v) +STATIC_INLINE void put_lrmw_word_mmu040 (uaecptr addr, uae_u32 v) { - uae_mmu_put_rmw (addr, v, sz_word, 0); + uae_mmu_put_lrmw (addr, v, sz_word, 0); } -STATIC_INLINE void put_rmw_long_mmu040 (uaecptr addr, uae_u32 v) +STATIC_INLINE void put_lrmw_long_mmu040 (uaecptr addr, uae_u32 v) { - uae_mmu_put_rmw (addr, v, sz_long, 0); + uae_mmu_put_lrmw (addr, v, sz_long, 0); } -STATIC_INLINE uae_u32 get_rmw_byte_mmu040 (uaecptr addr) +STATIC_INLINE uae_u32 get_lrmw_byte_mmu040 (uaecptr addr) { - return uae_mmu_get_rmw (addr, sz_byte, 0); + return uae_mmu_get_lrmw (addr, sz_byte, 0); } -STATIC_INLINE uae_u32 get_rmw_word_mmu040 (uaecptr addr) +STATIC_INLINE uae_u32 get_lrmw_word_mmu040 (uaecptr addr) { - return uae_mmu_get_rmw (addr, sz_word, 0); + return uae_mmu_get_lrmw (addr, sz_word, 0); } -STATIC_INLINE uae_u32 get_rmw_long_mmu040 (uaecptr addr) +STATIC_INLINE uae_u32 get_lrmw_long_mmu040 (uaecptr addr) { - return uae_mmu_get_rmw (addr, sz_long, 0); + return uae_mmu_get_lrmw (addr, sz_long, 0); } STATIC_INLINE uae_u32 get_ibyte_mmu040 (int o) diff --git a/include/cpummu030.h b/include/cpummu030.h index 13ce038a..9e72860f 100644 --- a/include/cpummu030.h +++ b/include/cpummu030.h @@ -72,9 +72,9 @@ uaecptr mmu030_translate(uaecptr addr, bool super, bool data, bool write); int mmu030_match_ttr(uaecptr addr, uae_u32 fc, bool write); int mmu030_match_ttr_access(uaecptr addr, uae_u32 fc, bool write); -int mmu030_match_rmw_ttr(uaecptr addr, uae_u32 fc); +int mmu030_match_lrmw_ttr(uaecptr addr, uae_u32 fc); int mmu030_do_match_ttr(uae_u32 tt, TT_info masks, uaecptr addr, uae_u32 fc, bool write); -int mmu030_do_match_rmw_ttr(uae_u32 tt, TT_info masks, uaecptr addr, uae_u32 fc); +int mmu030_do_match_lrmw_ttr(uae_u32 tt, TT_info masks, uaecptr addr, uae_u32 fc); void mmu030_put_long(uaecptr addr, uae_u32 val, uae_u32 fc); void mmu030_put_word(uaecptr addr, uae_u16 val, uae_u32 fc); @@ -83,15 +83,15 @@ uae_u32 mmu030_get_long(uaecptr addr, uae_u32 fc); uae_u16 mmu030_get_word(uaecptr addr, uae_u32 fc); uae_u8 mmu030_get_byte(uaecptr addr, uae_u32 fc); -uae_u32 uae_mmu030_get_rmw(uaecptr addr, int size); -void uae_mmu030_put_rmw(uaecptr addr, uae_u32 val, int size); +uae_u32 uae_mmu030_get_lrmw(uaecptr addr, int size); +void uae_mmu030_put_lrmw(uaecptr addr, uae_u32 val, int size); uae_u32 mmu030_get_generic(uaecptr addr, uae_u32 fc, int size, int accesssize, int flags); extern uae_u16 REGPARAM3 mmu030_get_word_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM; extern uae_u32 REGPARAM3 mmu030_get_long_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM; -extern uae_u16 REGPARAM3 mmu030_get_rmw_word_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM; -extern uae_u32 REGPARAM3 mmu030_get_rmw_long_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM; +extern uae_u16 REGPARAM3 mmu030_get_lrmw_word_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM; +extern uae_u32 REGPARAM3 mmu030_get_lrmw_long_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM; extern void REGPARAM3 mmu030_put_word_unaligned(uaecptr addr, uae_u16 val, uae_u32 fc, int flags) REGPARAM; extern void REGPARAM3 mmu030_put_long_unaligned(uaecptr addr, uae_u32 val, uae_u32 fc, int flags) REGPARAM; @@ -166,8 +166,8 @@ static ALWAYS_INLINE void uae_mmu030_put_byte(uaecptr addr, uae_u8 val) static ALWAYS_INLINE uae_u32 sfc030_get_long(uaecptr addr) { - uae_u32 fc = regs.sfc&7; -#if MMUDEBUG > 1 + uae_u32 fc = regs.sfc; +#if MMUDEBUG > 2 write_log(_T("sfc030_get_long: FC = %i\n"),fc); #endif if (unlikely(is_unaligned(addr, 4))) @@ -177,8 +177,8 @@ static ALWAYS_INLINE uae_u32 sfc030_get_long(uaecptr addr) static ALWAYS_INLINE uae_u16 sfc030_get_word(uaecptr addr) { - uae_u32 fc = regs.sfc&7; -#if MMUDEBUG > 1 + uae_u32 fc = regs.sfc; +#if MMUDEBUG > 2 write_log(_T("sfc030_get_word: FC = %i\n"),fc); #endif if (unlikely(is_unaligned(addr, 2))) @@ -188,8 +188,8 @@ static ALWAYS_INLINE uae_u16 sfc030_get_word(uaecptr addr) static ALWAYS_INLINE uae_u8 sfc030_get_byte(uaecptr addr) { - uae_u32 fc = regs.sfc&7; -#if MMUDEBUG > 1 + uae_u32 fc = regs.sfc; +#if MMUDEBUG > 2 write_log(_T("sfc030_get_byte: FC = %i\n"),fc); #endif return mmu030_get_byte(addr, fc); @@ -197,8 +197,8 @@ static ALWAYS_INLINE uae_u8 sfc030_get_byte(uaecptr addr) static ALWAYS_INLINE void dfc030_put_long(uaecptr addr, uae_u32 val) { - uae_u32 fc = regs.dfc&7; -#if MMUDEBUG > 1 + uae_u32 fc = regs.dfc; +#if MMUDEBUG > 2 write_log(_T("dfc030_put_long: FC = %i\n"),fc); #endif if (unlikely(is_unaligned(addr, 4))) @@ -209,8 +209,8 @@ static ALWAYS_INLINE void dfc030_put_long(uaecptr addr, uae_u32 val) static ALWAYS_INLINE void dfc030_put_word(uaecptr addr, uae_u16 val) { - uae_u32 fc = regs.dfc&7; -#if MMUDEBUG > 1 + uae_u32 fc = regs.dfc; +#if MMUDEBUG > 2 write_log(_T("dfc030_put_word: FC = %i\n"),fc); #endif if (unlikely(is_unaligned(addr, 2))) @@ -221,8 +221,8 @@ static ALWAYS_INLINE void dfc030_put_word(uaecptr addr, uae_u16 val) static ALWAYS_INLINE void dfc030_put_byte(uaecptr addr, uae_u8 val) { - uae_u32 fc = regs.dfc&7; -#if MMUDEBUG > 1 + uae_u32 fc = regs.dfc; +#if MMUDEBUG > 2 write_log(_T("dfc030_put_byte: FC = %i\n"),fc); #endif mmu030_put_byte(addr, val, fc); @@ -268,10 +268,10 @@ STATIC_INLINE void put_byte_mmu030_state (uaecptr addr, uae_u32 v) uae_mmu030_put_byte (addr, v); ACCESS_EXIT_PUT } -STATIC_INLINE void put_rmw_byte_mmu030_state (uaecptr addr, uae_u32 v) +STATIC_INLINE void put_lrmw_byte_mmu030_state (uaecptr addr, uae_u32 v) { ACCESS_CHECK_PUT - uae_mmu030_put_rmw (addr, v, sz_byte); + uae_mmu030_put_lrmw (addr, v, sz_byte); ACCESS_EXIT_PUT } STATIC_INLINE void put_word_mmu030_state (uaecptr addr, uae_u32 v) @@ -280,10 +280,10 @@ STATIC_INLINE void put_word_mmu030_state (uaecptr addr, uae_u32 v) uae_mmu030_put_word (addr, v); ACCESS_EXIT_PUT } -STATIC_INLINE void put_rmw_word_mmu030_state (uaecptr addr, uae_u32 v) +STATIC_INLINE void put_lrmw_word_mmu030_state (uaecptr addr, uae_u32 v) { ACCESS_CHECK_PUT - uae_mmu030_put_rmw (addr, v, sz_word); + uae_mmu030_put_lrmw (addr, v, sz_word); ACCESS_EXIT_PUT } STATIC_INLINE void put_long_mmu030_state (uaecptr addr, uae_u32 v) @@ -292,10 +292,10 @@ STATIC_INLINE void put_long_mmu030_state (uaecptr addr, uae_u32 v) uae_mmu030_put_long (addr, v); ACCESS_EXIT_PUT } -STATIC_INLINE void put_rmw_long_mmu030_state (uaecptr addr, uae_u32 v) +STATIC_INLINE void put_lrmw_long_mmu030_state (uaecptr addr, uae_u32 v) { ACCESS_CHECK_PUT - uae_mmu030_put_rmw (addr, v, sz_long); + uae_mmu030_put_lrmw (addr, v, sz_long); ACCESS_EXIT_PUT } @@ -307,11 +307,11 @@ STATIC_INLINE uae_u32 get_byte_mmu030_state (uaecptr addr) ACCESS_EXIT_GET return v; } -STATIC_INLINE uae_u32 get_rmw_byte_mmu030_state (uaecptr addr) +STATIC_INLINE uae_u32 get_lrmw_byte_mmu030_state (uaecptr addr) { uae_u32 v; ACCESS_CHECK_GET - v = uae_mmu030_get_rmw (addr, sz_byte); + v = uae_mmu030_get_lrmw (addr, sz_byte); ACCESS_EXIT_GET return v; } @@ -324,11 +324,11 @@ STATIC_INLINE uae_u32 get_word_mmu030_state (uaecptr addr) ACCESS_EXIT_GET return v; } -STATIC_INLINE uae_u32 get_rmw_word_mmu030_state (uaecptr addr) +STATIC_INLINE uae_u32 get_lrmw_word_mmu030_state (uaecptr addr) { uae_u32 v; ACCESS_CHECK_GET - v = uae_mmu030_get_rmw (addr, sz_word); + v = uae_mmu030_get_lrmw (addr, sz_word); ACCESS_EXIT_GET return v; } @@ -340,11 +340,11 @@ STATIC_INLINE uae_u32 get_long_mmu030_state (uaecptr addr) ACCESS_EXIT_GET return v; } -STATIC_INLINE uae_u32 get_rmw_long_mmu030_state (uaecptr addr) +STATIC_INLINE uae_u32 get_lrmw_long_mmu030_state (uaecptr addr) { uae_u32 v; ACCESS_CHECK_GET - v = uae_mmu030_get_rmw (addr, sz_long); + v = uae_mmu030_get_lrmw (addr, sz_long); ACCESS_EXIT_GET return v; } diff --git a/include/mmu_common.h b/include/mmu_common.h index a681a131..37b63bd9 100644 --- a/include/mmu_common.h +++ b/include/mmu_common.h @@ -3,6 +3,7 @@ #define MMU_COMMON_H #define MMUDEBUG 1 +#define MMUINSDEBUG 0 #ifdef _MSC_VER #define unlikely(x) x diff --git a/include/newcpu.h b/include/newcpu.h index d6a6fc6e..c0f0a884 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -163,7 +163,8 @@ struct regstruct uae_u32 cacr, caar; uae_u32 itt0, itt1, dtt0, dtt1; uae_u32 tcr, mmusr, urp, srp, buscr; - uae_u32 mmu_fslw, mmu_fault_addr; + uae_u32 mmu_fslw; + uae_u32 mmu_fault_addr, mmu_effective_addr; uae_u16 mmu_ssw; uae_u32 wb3_data; uae_u16 wb3_status; diff --git a/include/scsi.h b/include/scsi.h index b6152c04..29b61c0e 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -13,6 +13,7 @@ struct scsi_data uae_u8 cmd[16]; int reply_len; int direction; + uae_u8 message[1]; int offset; uae_u8 buffer[SCSI_DATA_BUFFER_SIZE]; @@ -31,6 +32,7 @@ extern void scsi_start_transfer(struct scsi_data*); extern int scsi_send_data(struct scsi_data*, uae_u8); extern int scsi_receive_data(struct scsi_data*, uae_u8*); extern void scsi_emulate_cmd(struct scsi_data *sd); +extern void scsi_illegal_lun(struct scsi_data *sd); extern int scsi_hd_emulate(struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, uae_u8 *cmdbuf, int scsi_cmd_len, uae_u8 *scsi_data, int *data_len, uae_u8 *r, int *reply_len, uae_u8 *s, int *sense_len); diff --git a/newcpu.cpp b/newcpu.cpp index 276dd07a..7e1285d7 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -2010,6 +2010,18 @@ void REGPARAM2 MakeSR (void) | GET_CFLG ()); } +void SetSR (uae_u16 sr) +{ + regs.sr &= 0xff00; + regs.sr |= sr; + + SET_XFLG ((regs.sr >> 4) & 1); + SET_NFLG ((regs.sr >> 3) & 1); + SET_ZFLG ((regs.sr >> 2) & 1); + SET_VFLG ((regs.sr >> 1) & 1); + SET_CFLG (regs.sr & 1); +} + void REGPARAM2 MakeFromSR (void) { int oldm = regs.m; @@ -2262,7 +2274,7 @@ kludge_me_do: newpc |= x_get_word (4 * nr + 2); // read low address if (newpc & 1) { if (nr == 2 || nr == 3) - uae_reset (1, 0); /* there is nothing else we can do.. */ + cpu_halt (2); else exception3 (regs.ir, newpc); return; @@ -2326,7 +2338,7 @@ static void Exception_build_stack_frame (uae_u32 oldpc, uae_u32 currpc, uae_u32 m68k_areg (regs, 7) -= 2; x_put_word (m68k_areg (regs, 7), ssw); m68k_areg (regs, 7) -= 4; - x_put_long (m68k_areg (regs, 7), regs.mmu_fault_addr); + x_put_long (m68k_areg (regs, 7), regs.mmu_effective_addr); break; case 0x9: // coprocessor mid-instruction stack frame (68020, 68030) m68k_areg (regs, 7) -= 4; @@ -2347,7 +2359,7 @@ static void Exception_build_stack_frame (uae_u32 oldpc, uae_u32 currpc, uae_u32 write_log(_T("Exception stack frame format %X not implemented\n"), format); return; } - // 68060 bus fault + // 68060 bus access fault m68k_areg (regs, 7) -= 4; x_put_long (m68k_areg (regs, 7), regs.mmu_fslw); m68k_areg (regs, 7) -= 4; @@ -2393,11 +2405,12 @@ static void Exception_build_stack_frame (uae_u32 oldpc, uae_u32 currpc, uae_u32 m68k_areg (regs, 7) -= 4; x_put_long (m68k_areg (regs, 7), mmu030_disp_store[0]); m68k_areg (regs, 7) -= 4; - x_put_long (m68k_areg (regs, 7), mmu030_ad[mmu030_idx].val); // Data output buffer = value that was going to be written + // Data output buffer = value that was going to be written + x_put_long (m68k_areg (regs, 7), (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) ? mmu030_data_buffer : mmu030_ad[mmu030_idx].val); m68k_areg (regs, 7) -= 4; x_put_long (m68k_areg (regs, 7), mmu030_opcode); // Internal register (opcode storage) m68k_areg (regs, 7) -= 4; - x_put_long (m68k_areg (regs, 7), regs.mmu_fault_addr); + x_put_long (m68k_areg (regs, 7), regs.mmu_fault_addr); // data cycle fault address m68k_areg (regs, 7) -= 2; x_put_word (m68k_areg (regs, 7), 0); // Instr. pipe stage B m68k_areg (regs, 7) -= 2; @@ -2412,7 +2425,7 @@ static void Exception_build_stack_frame (uae_u32 oldpc, uae_u32 currpc, uae_u32 return; } m68k_areg (regs, 7) -= 2; - x_put_word (m68k_areg (regs, 7), (format<<12) | (nr * 4)); + x_put_word (m68k_areg (regs, 7), (format << 12) | (nr * 4)); m68k_areg (regs, 7) -= 4; x_put_long (m68k_areg (regs, 7), currpc); m68k_areg (regs, 7) -= 2; @@ -2430,10 +2443,10 @@ static void Exception_mmu030 (int nr, uaecptr oldpc) MakeSR(); if (!regs.s) { - regs.usp = m68k_areg(regs, 7); + regs.usp = m68k_areg (regs, 7); m68k_areg(regs, 7) = regs.m ? regs.msp : regs.isp; regs.s = 1; - mmu_set_super(1); + mmu_set_super (1); } #if 0 @@ -2443,20 +2456,26 @@ static void Exception_mmu030 (int nr, uaecptr oldpc) } #endif - if (regs.m && nr >= 24 && nr < 32) { /* M + Interrupt */ - Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x1); +#if 0 + write_log (_T("Exception %d -> %08x\n", nr, newpc)); +#endif + + + newpc = x_get_long (regs.vbr + 4 * nr); + + if (regs.m && nr >= 24 && nr < 32) { /* M + Interrupt */ + Exception_build_stack_frame (oldpc, currpc, regs.mmu_ssw, nr, 0x1); } else if (nr ==5 || nr == 6 || nr == 7 || nr == 9 || nr == 56) { - Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x2); + Exception_build_stack_frame (oldpc, currpc, regs.mmu_ssw, nr, 0x2); } else if (nr == 2 || nr == 3) { - Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0xB); + Exception_build_stack_frame (oldpc, currpc, regs.mmu_ssw, nr, 0xB); } else { - Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x0); + Exception_build_stack_frame (oldpc, currpc, regs.mmu_ssw, nr, 0x0); } - newpc = x_get_long (regs.vbr + 4 * nr); if (newpc & 1) { if (nr == 2 || nr == 3) - uae_reset (1, 0); /* there is nothing else we can do.. */ + cpu_halt (2); else exception3 (regs.ir, newpc); return; @@ -2493,7 +2512,12 @@ static void Exception_mmu (int nr, uaecptr oldpc) mmu_set_super (1); } - if (nr == 2) { // bus error + newpc = x_get_long (regs.vbr + 4 * nr); +#if 0 + write_log (_T("Exception %d: %08x -> %08x\n"), nr, currpc, newpc); +#endif + + if (nr == 2) { // bus error //write_log (_T("Exception_mmu %08x %08x %08x\n"), currpc, oldpc, regs.mmu_fault_addr); if (currprefs.mmu_model == 68040) Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x7); @@ -2513,10 +2537,9 @@ static void Exception_mmu (int nr, uaecptr oldpc) Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x0); } - newpc = x_get_long (regs.vbr + 4 * nr); if (newpc & 1) { if (nr == 2 || nr == 3) - uae_reset (1, 0); /* there is nothing else we can do.. */ + cpu_halt (2); else exception3 (regs.ir, newpc); return; @@ -2595,7 +2618,7 @@ static void Exception_normal (int nr) newpc = x_get_long (regs.vbr + 4 * nr); if (newpc & 1) { if (nr == 2 || nr == 3) - uae_reset (1, 0); /* there is nothing else we can do.. */ + cpu_halt (2); else exception3 (regs.ir, newpc); return; @@ -2711,7 +2734,7 @@ kludge_me_do: newpc = x_get_long (regs.vbr + 4 * nr); if (newpc & 1) { if (nr == 2 || nr == 3) - uae_reset (1, 0); /* there is nothing else we can do.. */ + cpu_halt (2); else exception3 (regs.ir, newpc); return; @@ -2861,10 +2884,10 @@ int m68k_move2c (int regno, uae_u32 *regp) break; /* no differences between 68040 and 68060 */ - case 4: regs.itt0 = *regp & 0xffffe364; break; - case 5: regs.itt1 = *regp & 0xffffe364; break; - case 6: regs.dtt0 = *regp & 0xffffe364; break; - case 7: regs.dtt1 = *regp & 0xffffe364; break; + case 4: regs.itt0 = *regp & 0xffffe364; mmu_tt_modified (); break; + case 5: regs.itt1 = *regp & 0xffffe364; mmu_tt_modified (); break; + case 6: regs.dtt0 = *regp & 0xffffe364; mmu_tt_modified (); break; + case 7: regs.dtt1 = *regp & 0xffffe364; mmu_tt_modified (); break; /* 68060 only */ case 8: regs.buscr = *regp & 0xf0000000; break; @@ -3256,6 +3279,7 @@ void m68k_reset (int hardreset) regs.caar = regs.cacr = 0; regs.itt0 = regs.itt1 = regs.dtt0 = regs.dtt1 = 0; regs.tcr = regs.mmusr = regs.urp = regs.srp = regs.buscr = 0; + mmu_tt_modified (); if (currprefs.cpu_model == 68020) { regs.cacr |= 8; set_cpu_caches (); @@ -3343,8 +3367,8 @@ uae_u32 REGPARAM2 op_illg (uae_u32 opcode) if ((opcode & 0xF000) == 0xF000) { if (warned < 20) { - //write_log (_T("B-Trap %x at %x (%p)\n"), opcode, pc, regs.pc_p); - //warned++; + write_log (_T("B-Trap %x at %x (%p)\n"), opcode, pc, regs.pc_p); + warned++; } Exception (0xB); //activate_debugger (); @@ -3352,8 +3376,8 @@ uae_u32 REGPARAM2 op_illg (uae_u32 opcode) } if ((opcode & 0xF000) == 0xA000) { if (warned < 20) { - //write_log (_T("A-Trap %x at %x (%p)\n"), opcode, pc, regs.pc_p); - //warned++; + write_log (_T("A-Trap %x at %x (%p)\n"), opcode, pc, regs.pc_p); + warned++; } Exception (0xA); //activate_debugger(); @@ -4262,16 +4286,24 @@ static void m68k_run_mmu060 (void) { uae_u16 opcode; uaecptr pc; + flag_struct f; + retry: TRY (prb) { for (;;) { + f.cznv = regflags.cznv; + f.x = regflags.x; pc = regs.instruction_pc = m68k_getpc (); + + mmu_opcode = -1; mmu060_state = 0; - mmu060_opcode = opcode = x_prefetch (0); + mmu_opcode = opcode = x_prefetch (0); mmu060_state = 1; + count_instr (opcode); do_cycles (cpu_cycles); cpu_cycles = (*cpufunctbl[opcode])(opcode); + cpu_cycles = adjust_cycles (cpu_cycles); if (regs.spcflags) { if (do_specialties (cpu_cycles)) @@ -4281,6 +4313,8 @@ retry: } CATCH (prb) { m68k_setpc (regs.instruction_pc); + regflags.cznv = f.cznv; + regflags.x = f.x; if (mmufixup[0].reg >= 0) { m68k_areg (regs, mmufixup[0].reg) = mmufixup[0].value; @@ -4311,25 +4345,32 @@ retry: static void m68k_run_mmu040 (void) { uae_u16 opcode; + flag_struct f; uaecptr pc; retry: TRY (prb) { for (;;) { + f.cznv = regflags.cznv; + f.x = regflags.x; + mmu_restart = true; pc = regs.instruction_pc = m68k_getpc (); + #if 0 - if (pc == 0x000fa01c) { - write_log (_T("*")); - //activate_debugger (); + if (pc == 0x0004B0A6) { + //write_log (_T("*")); + activate_debugger (); } #endif - opcode = x_prefetch (0); + mmu_opcode = -1; + mmu_opcode = opcode = x_prefetch (0); count_instr (opcode); do_cycles (cpu_cycles); cpu_cycles = (*cpufunctbl[opcode])(opcode); cpu_cycles = adjust_cycles (cpu_cycles); + if (regs.spcflags) { if (do_specialties (cpu_cycles)) return; @@ -4337,21 +4378,18 @@ retry: } } CATCH (prb) { -#if 0 - if (regs.wb3_status & 0x80) { - // movem to memory? - if ((opcode & 0xff80) == 0x4880) { - regs.mmu_ssw |= MMU_SSW_CM; - //write_log (_T("MMU_SSW_CM\n")); - } -#endif - - //opcodedebug (pc, opcode, false); + if (mmu_restart) { + /* restore state if instruction restart */ + regflags.cznv = f.cznv; + regflags.x = f.x; + m68k_setpc (regs.instruction_pc); + } if (mmufixup[0].reg >= 0) { m68k_areg (regs, mmufixup[0].reg) = mmufixup[0].value; mmufixup[0].reg = -1; } + //activate_debugger (); TRY (prb2) { Exception (prb); @@ -4373,6 +4411,7 @@ static void m68k_run_mmu030 (void) { uae_u16 opcode; uaecptr pc; + flag_struct f; mmu030_opcode_stageb = -1; retry: @@ -4381,10 +4420,12 @@ retry: int cnt; insretry: pc = regs.instruction_pc = m68k_getpc (); + f.cznv = regflags.cznv; + f.x = regflags.x; mmu030_state[0] = mmu030_state[1] = mmu030_state[2] = 0; #if 0 - if (pc == 0x00109FFC) { + if (pc == 0xC0075432) { write_log (_T("*")); //activate_debugger (); } @@ -4427,7 +4468,11 @@ insretry: } } CATCH (prb) { + regflags.cznv = f.cznv; + regflags.x = f.x; + m68k_setpc (regs.instruction_pc); + if (mmufixup[0].reg >= 0) { m68k_areg (regs, mmufixup[0].reg) = mmufixup[0].value; mmufixup[0].reg = -1; @@ -4820,7 +4865,7 @@ void m68k_go (int may_quit) if (regs.panic) { regs.panic = 0; /* program jumped to non-existing memory and cpu was >= 68020 */ - get_real_address (regs.isp); /* stack in no one's land? -> reboot */ + get_real_address (regs.isp); /* stack in no one's land? -> halt */ if (regs.isp & 1) regs.panic = 5; if (!regs.panic) @@ -4851,9 +4896,11 @@ void m68k_go (int may_quit) cpu_halt (regs.halted); continue; } +#if 0 if (mmu_enabled && !currprefs.cachesize) { run_func = m68k_run_mmu; } else { +#endif run_func = currprefs.cpu_cycle_exact && currprefs.cpu_model == 68000 ? m68k_run_1_ce : currprefs.cpu_compatible && currprefs.cpu_model == 68000 ? m68k_run_1 : #ifdef JIT @@ -4864,7 +4911,9 @@ void m68k_go (int may_quit) currprefs.cpu_model == 68060 && currprefs.mmu_model ? m68k_run_mmu060 : currprefs.cpu_model >= 68020 && currprefs.cpu_cycle_exact ? m68k_run_2ce : currprefs.cpu_compatible ? (currprefs.cpu_model <= 68020 ? m68k_run_2p : m68k_run_2pf) : m68k_run_2; +#if 0 } +#endif run_func (); } protect_roms (false); diff --git a/od-win32/hardfile_win32.cpp b/od-win32/hardfile_win32.cpp index 834d94e0..d2c000b8 100644 --- a/od-win32/hardfile_win32.cpp +++ b/od-win32/hardfile_win32.cpp @@ -517,13 +517,13 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname) i = _tcslen (name) - 1; while (i >= 0) { if ((i > 0 && (name[i - 1] == '/' || name[i - 1] == '\\')) || i == 0) { - _tcscpy (hfd->vendor_id, _T("UAE")); _tcsncpy (hfd->product_id, name + i, 15); - _tcscpy (hfd->product_rev, _T("0.3")); break; } i--; } + _tcscpy (hfd->vendor_id, _T("UAE")); + _tcscpy (hfd->product_rev, _T("0.4")); if (h != INVALID_HANDLE_VALUE) { DWORD ret, low; LONG high = 0; diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index d3b376cb..01b1abb9 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -4722,6 +4722,7 @@ extern int inputdevice_logging; extern int vsync_modechangetimeout; extern int forcedframelatency; extern int tablet_log; +extern int log_blitter; extern DWORD_PTR cpu_affinity, cpu_paffinity; static DWORD_PTR original_affinity = -1; @@ -5032,6 +5033,10 @@ static int parseargs (const TCHAR *argx, const TCHAR *np, const TCHAR *np2) tablet_log = getval (np); return 2; } + if (!_tcscmp (arg, _T("blitterdebug"))) { + log_blitter = getval (np); + return 2; + } if (!_tcscmp (arg, _T("inputlog"))) { rawinput_log = getval (np); return 2; diff --git a/od-win32/win32.h b/od-win32/win32.h index 354145e0..77e5e9fd 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -19,11 +19,11 @@ #define LANG_DLL 1 #if WINUAEPUBLICBETA -#define WINUAEBETA _T("3") +#define WINUAEBETA _T("4") #else #define WINUAEBETA _T("") #endif -#define WINUAEDATE MAKEBD(2013, 1, 21) +#define WINUAEDATE MAKEBD(2013, 1, 26) #define WINUAEEXTRA _T("") //#define WINUAEEXTRA _T("AmiKit Preview") #define WINUAEREV _T("") diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 1585d8a3..38c9042f 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,6 +1,21 @@ - restore only single input target to default. +Beta 4: + +- Fixed 68030 MMU MOVEM to memory wrong bus error data output buffer value. +- 68030 MMU FMOVEM didn't work if it caused bus fault. +- 68060 MMU non-locked Read-Modify-Write bus error bits emulated. +- SCSI emulation: reject >0 LUNs also when LUN is included with SCSI Identify Message. +- IDE single drive setup should return zero when accessing non-existing slave drive's status register. +- A2065 emulation initialization tweak, fixes NetBSD 1.0 hang. +- CDFS didn't use CD led (FS) +- Blitter logging/debugging command line option added (was compile time previously) -blitterdebug x + (1 = logging, 2 = writes to blitter register while already active logging, 4 = disable D channel, 8 = immediate blitter even in cycle-exact mode) +- Support display setups that have two (or more) horizontal DDFSTRT/DDFSTOP regions. Fixes Subtle Shades / Nuance "face" part. + (There is still some small glitches on left side of text part, later..) +- Some remaining instant reset conditions replaced with halted state. + Beta 3: - Programmed display modes disable normal DMA start/end display limits. (NetBSD AGA console screen) diff --git a/scsi.cpp b/scsi.cpp index 0237e27a..9045ede0 100644 --- a/scsi.cpp +++ b/scsi.cpp @@ -18,6 +18,7 @@ static int outcmd[] = { 0x0a, 0x2a, 0x2f, 0xaa, -1 }; static int incmd[] = { 0x03, 0x08, 0x12, 0x1a, 0x25, 0x28, 0x37, 0x42, 0x43, 0xa8, 0x51, 0x52, -1 }; static int nonecmd[] = { 0x00, 0x1b, 0x1e, 0x35, -1 }; +static int scsicmdsizes[] = { 6, 10, 10, 12, 16, 12, 10, 10 }; static int scsi_data_dir(struct scsi_data *sd) { @@ -49,44 +50,46 @@ void scsi_emulate_analyze (struct scsi_data *sd) int cmd_len, data_len; data_len = sd->data_len; + cmd_len = scsicmdsizes[sd->cmd[0] >> 5]; switch (sd->cmd[0]) { case 0x0a: - cmd_len = 6; data_len = sd->cmd[4] * sd->hfd->hfd.ci.blocksize; break; case 0x2a: - cmd_len = 10; data_len = ((sd->cmd[7] << 8) | (sd->cmd[8] << 0)) * (uae_s64)sd->hfd->hfd.ci.blocksize; break; case 0xaa: - cmd_len = 12; data_len = ((sd->cmd[6] << 24) | (sd->cmd[7] << 16) | (sd->cmd[8] << 8) | (sd->cmd[9] << 0)) * (uae_s64)sd->hfd->hfd.ci.blocksize; break; - - case 0x25: - case 0x28: - case 0x35: - case 0x51: - case 0x52: - case 0x43: - cmd_len = 10; - break; - case 0xa8: - cmd_len = 12; - break; - default: - cmd_len = 6; - break; } sd->cmd_len = cmd_len; sd->data_len = data_len; sd->direction = scsi_data_dir (sd); } +void scsi_illegal_lun(struct scsi_data *sd) +{ + uae_u8 *s = sd->sense; + + memset (s, 0, sizeof (sd->sense)); + sd->status = 2; /* CHECK CONDITION */ + s[0] = 0x70; + s[2] = 5; /* ILLEGAL REQUEST */ + s[12] = 0x25; /* INVALID LUN */ + sd->sense_len = 0x12; +} + void scsi_emulate_cmd(struct scsi_data *sd) { sd->status = 0; + if ((sd->message[0] & 0xc0) == 0x80 && (sd->message[0] & 0x1f)) { + uae_u8 lun = sd->message[0] & 0x1f; + if (lun > 7) + lun = 7; + sd->cmd[1] &= ~(7 << 5); + sd->cmd[1] |= lun << 5; + } //write_log (_T("CMD=%02x\n"), sd->cmd[0]); if (sd->cd_emu_unit >= 0) { if (sd->cmd[0] == 0x03) { /* REQUEST SENSE */