]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
2600b4
authorToni Wilen <twilen@winuae.net>
Sat, 26 Jan 2013 16:22:38 +0000 (18:22 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 26 Jan 2013 16:22:38 +0000 (18:22 +0200)
23 files changed:
a2065.cpp
a2091.cpp
blitter.cpp
cpummu.cpp
cpummu30.cpp
custom.cpp
debug.cpp
filesys.cpp
fpp.cpp
gayle.cpp
gencpu.cpp
hardfile.cpp
include/cpummu.h
include/cpummu030.h
include/mmu_common.h
include/newcpu.h
include/scsi.h
newcpu.cpp
od-win32/hardfile_win32.cpp
od-win32/win32.cpp
od-win32/win32.h
od-win32/winuaechangelog.txt
scsi.cpp

index 91ea0be34ffc78f519dd568ae68d5c19232cb6c4..fe6e57cf851f7687f53b0a80e65af296acc61fc4 100644 (file)
--- 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) {
index e9b1c3b68db422ccdf4a5ac025bc4254e5594698..be0108d408121d249e5a4188f43596f6adf56830 100644 (file)
--- 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);
index d5275cc0e13fcb6eb1a5180381956b447fb19e2d..38ef1017a2e9f7bda7038856a8977bc664d051f1 100644 (file)
@@ -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"
 #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)
index 64b52a94040ed55dcf06cacddcdcdbfec3e90e86..9ed001e3de59b767a5e82778ef8b4d28589e0c03 100644 (file)
@@ -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);
        }
index a056e6a7235455341f029ddaa4f9325aee3cd3cf..31a955908707abc1af5b83ab284d62df5fec093d 100644 (file)
@@ -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++) {
         if (((fc_base&fc_mask)==(mmu030.atc[i].logical.fc&fc_mask)) &&
             (mmu030.atc[i].logical.addr == logical_addr) &&
@@ -446,6 +447,7 @@ void mmu030_flush_atc_page_fc(uaecptr logical_addr, uae_u32 fc_base, uae_u32 fc_
 /* This function flushes ATC entries depending on their logical address */
 void mmu030_flush_atc_page(uaecptr logical_addr) {
     int i;
+       logical_addr &= mmu030.translation.page.imask;
     for (i=0; i<ATC030_NUM_ENTRIES; i++) {
         if ((mmu030.atc[i].logical.addr == logical_addr) &&
             mmu030.atc[i].logical.valid) {
@@ -584,15 +586,15 @@ int mmu030_match_ttr_access(uaecptr addr, uae_u32 fc, bool write)
     return (tt0|tt1) & TT_OK_MATCH;
 }
 
-/* Read-Modify-Write */
-int mmu030_match_rmw_ttr_access(uaecptr addr, uae_u32 fc)
+/* Locked Read-Modify-Write */
+int mmu030_match_lrmw_ttr_access(uaecptr addr, uae_u32 fc)
 {
     int tt0, tt1;
 
        if (!tt_enabled)
                return 0;
-    tt0 = mmu030_do_match_rmw_ttr(tt0_030, mmu030.transparent.tt0, addr, fc);
-    tt1 = mmu030_do_match_rmw_ttr(tt1_030, mmu030.transparent.tt1, addr, fc);
+    tt0 = mmu030_do_match_lrmw_ttr(tt0_030, mmu030.transparent.tt0, addr, fc);
+    tt1 = mmu030_do_match_lrmw_ttr(tt1_030, mmu030.transparent.tt1, addr, fc);
     return (tt0|tt1) & TT_OK_MATCH;
 }
 
@@ -628,7 +630,7 @@ int mmu030_do_match_ttr(uae_u32 tt, TT_info comp, uaecptr addr, uae_u32 fc, bool
        return TT_NO_MATCH;
 }
 
-int mmu030_do_match_rmw_ttr(uae_u32 tt, TT_info comp, uaecptr addr, uae_u32 fc)
+int mmu030_do_match_lrmw_ttr(uae_u32 tt, TT_info comp, uaecptr addr, uae_u32 fc)
 {
        if ((tt & TT_ENABLE) && (tt & TT_RWM))  {       /* transparent translation enabled */
         
@@ -1425,6 +1427,11 @@ uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level) {
         write_log(_T("ATC is full. Replacing entry %i\n"), i);
 #endif
        }
+       if (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;
index ff6b225328d2531952dddb071f3bf23690e7dc15..e96186be8f6af22fd3dc5cf6e9d51e582af739ef 100644 (file)
@@ -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;
index 04d3eb5f2dbb2c0625d7f60a5dc6d29ff82c2dd3..a04d75dfdea9f22c74148a7b6b8a63652177c065 100644 (file)
--- 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;
                                        }
index 73f099da239f934e61aaedd3720ce815a99c210b..bd0fa131772efc868bc32e87a6bb4b32da6fcc1a 100644 (file)
@@ -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 edb66e68fa50324e8ca76a7dad361bcdbbb43b52..8ec86cf25dccd1d14e48a97495d2a7f248ffb61e 100644 (file)
--- 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;
index 1ab5c783a76d122bdec28345c60a487f9c00d6a7..5e00956d63c2110b84ea1aa7252aebc16fcc014d 100644 (file)
--- 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;
        }
 
index d58a05a94661c2629340060916bc95c06b6a8c97..e0e359d9bd0ab158e0cb4ac501ee4fc743d2f7d7 100644 (file)
@@ -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);
index ddbe7a71b6df2fbff4e53e6f9aa269ce0a6e726b..209c614ab11b4d78ed53d2a6a5dea61b5db7ac62 100644 (file)
@@ -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])
index 7c8fe43b55340d9f1de571b118e481c5aea68332..ea674289016c45b92cebe8ffa6bc32fec82dacd9 100644 (file)
 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)
index 13ce038ab731c8fb90e0613a8e479a8cf4478f51..9e72860ff6eeae7cd2f0f543fe8d58e91f738a72 100644 (file)
@@ -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;
 }
index a681a1315d55680a463271e84f0a3649738ee7b5..37b63bd925c132f5d8ead900371f3c18c35af53a 100644 (file)
@@ -3,6 +3,7 @@
 #define MMU_COMMON_H
 
 #define MMUDEBUG 1
+#define MMUINSDEBUG 0
 
 #ifdef _MSC_VER
 #define unlikely(x) x
index d6a6fc6eaa57d3f6249bd2518a39572a343c8a52..c0f0a88464b094ed2a8499472b971bc7d2ec71a5 100644 (file)
@@ -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;
index b6152c040c045d4c0428a021526c9869a706d92a..29b61c0ed5cda92576be5bd579caf7dbd93643ae 100644 (file)
@@ -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);
index 276dd07af6f91fe7f84510cf4ac1a56d90ffff68..7e1285d75039d967de9afaea75039f5a629d1e53 100644 (file)
@@ -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);
index 834d94e048495e33381daf880774e1f1b93c1fea..d2c000b8e45df958246919bda3accab714fb73ca 100644 (file)
@@ -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;
index d3b376cbd1695cbb50bf8a1d2e1278476ec29b87..01b1abb9dfaf64176fd642728c46d31e8eed4220 100644 (file)
@@ -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;
index 354145e0de17fdd0c6dc7346cc13bd07d372d5ca..77e5e9fdb688d501071bc4685e001804027f4cce 100644 (file)
 #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("")
index 1585d8a3fa774ce9c675cea08b2c13f5e76d12ed..38c9042fbc48c425ea59727632a62cd86bd65723 100644 (file)
@@ -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)
index 0237e27ad99fe6a8c698712d9ace90354d14973f..9045ede052031f60ed82c87f707fa5fe76cf24ca 100644 (file)
--- 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 */