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;
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++;
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)) {
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;
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) {
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]);
return;
}
if (!wd_selected) {
+ scsi->message[0] = 0x80;
wd_selected = true;
wdregs[WD_COMMAND_PHASE] = 0x10;
}
}
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);
* (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;
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
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)
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 ());
}
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;
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);
}
}
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)
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;
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;
}
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) {
blitter_handler (0);
end:;
-#ifdef BLITTER_DEBUG
- blitter_delayed_debug = 1;
-#endif
+ if (log_blitter)
+ blitter_delayed_debug = 1;
}
int blitnasty (void)
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;
#endif
}
+void mmu_tt_modified (void)
+{
+ mmu_ttr_enabled = ((regs.dtt0 | regs.dtt1 | regs.itt0 | regs.itt1) & MMU_TTR_BIT_ENABLED) != 0;
+}
#if 0
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:
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;
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;
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;
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);
}
} 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) {
{
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;
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;
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;
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;
}
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) {
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) {
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) {
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;
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;
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;
}
} 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) {
}
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);
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) {
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)))
}
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)))
}
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);
regs.wb3_data = val;
THROW_AGAIN(prb);
} ENDTRY
+ ismoves = false;
}
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);
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);
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;
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)
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 {
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);
}
}
}
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);
}
}
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;
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);
}
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
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"));
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);
* 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) &&
/* 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) {
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;
}
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 */
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 */
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);
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)
}
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)) {
}
-/* 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) {
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) {
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;
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];
plf_active,
plf_passed_stop,
plf_passed_stop2,
- plf_end
+ plf_end,
+ plf_finished
} plf_state;
enum fetchstate {
#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)
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) {
}
if (until >= maxhpos) {
- finish_final_fetch (pos, fm);
+ finish_last_fetch (pos, fm);
return;
}
for (; ; pos++) {
if (pos == until) {
if (until >= maxhpos) {
- finish_final_fetch (pos, fm);
+ finish_last_fetch (pos, fm);
return;
}
flush_display (fm);
return;
}
if (until >= maxhpos) {
- finish_final_fetch (pos, fm);
+ finish_last_fetch (pos, fm);
return;
}
flush_display (fm);
}
}
- 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) {
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 */
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) {
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) {
bpldmasetuphpos = -1;
bpldmasetupphase = 0;
ddfstrt_old_hpos = -1;
+ bpldmawasactive = false;
if (plf_state > plf_active)
plf_state = plf_idle;
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;
}
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;
{
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)
uae_u32 vv = v;
if (!memwatch_enabled)
return v;
+ if (!currprefs.z3chipmem_size)
+ addr &= chipmem_mask;
memwatch_func (addr, 1, 2, &vv);
return vv;
}
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;
}
#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;
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)
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);
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) {
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)
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)
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
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
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. */
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
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
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
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;
{
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. */
{
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--) {
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) {
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);
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;
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;
}
#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
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
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;
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);
} 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)
{
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
{
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) {
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)
}
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)
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:
}
} 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 ();
}
}
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) {
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;
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;
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 ();
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)
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;
}
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.
}
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)
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)
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;
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
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";
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";
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";
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;
{
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) {
{
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;
{
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;
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);
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");
{
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;
{
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;
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);
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");
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);
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);
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 ();
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);
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
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;
}
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;
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;
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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");
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");
case i_BFINS:
{
char *getb, *putb;
+ int flags = 0;
if (using_mmu || using_ce020) {
getb = "x_get_bitfield";
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);
s[0] = 0x70;
s[2] = 5; /* ILLEGAL REQUEST */
s[12] = 0x25; /* INVALID LUN */
- ls = 12;
+ ls = 0x12;
goto err;
}
switch (cmdbuf[0])
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;
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)
}
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);
#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;
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)
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)
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)
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)
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)
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)
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)
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);
}
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)
{
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)
{
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);
{
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)
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)
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);
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;
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)))
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)))
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);
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)))
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)))
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);
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)
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)
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
}
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;
}
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;
}
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;
}
#define MMU_COMMON_H
#define MMUDEBUG 1
+#define MMUINSDEBUG 0
#ifdef _MSC_VER
#define unlikely(x) x
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;
uae_u8 cmd[16];
int reply_len;
int direction;
+ uae_u8 message[1];
int offset;
uae_u8 buffer[SCSI_DATA_BUFFER_SIZE];
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);
| 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;
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;
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;
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;
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;
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;
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
}
#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;
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);
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;
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;
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;
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;
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 ();
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 ();
}
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();
{
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))
} 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;
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;
}
} 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);
{
uae_u16 opcode;
uaecptr pc;
+ flag_struct f;
mmu030_opcode_stageb = -1;
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 ();
}
}
} 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;
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)
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
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);
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;
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;
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;
#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("")
- 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)
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)
{
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 */