{
if (blit_interrupt)
return;
- if (!done && !currprefs.blitter_cycle_exact)
+ if (!done && (!currprefs.blitter_cycle_exact || (currprefs.chipset_mask & CSMASK_AGA)))
return;
blit_interrupt = 1;
INTREQ (0x8040);
#ifdef BLITTER_DEBUG_NOWAIT
warned = 10;
write_log (L"program does not wait for blitter PC=%08x\n", M68K_GETPC);
- //activate_debugger ();
+ activate_debugger ();
//blitter_done (hpos);
#endif
}
#define DBG_MMU_VERBOSE 1
#define DBG_MMU_SANITY 1
-#ifdef FULLMMU
-
static mmu_atc_l1_array atc_l1[2];
static struct mmu_atc_line atc_l2[2][ATC_L2_SIZE];
mmu_atc_l1_array *current_atc;
if ((root_des & 2) == 0)
continue; /* invalid */
- D(bug(L"ROOT: %03d U=%d W=%d UDT=%02d\n", root_idx,
+ D(bug(L" ROOT: %03d U=%d W=%d UDT=%02d\n", root_idx,
root_des & 8 ? 1 : 0,
root_des & 4 ? 1 : 0,
root_des & 3
if (n_pages_used == -1)
continue;
- D(bug(L" PTR: %03d U=%d W=%d UDT=%02d\n", ptr_idx,
+ D(bug(L" PTR: %08X %03d U=%d W=%d UDT=%02d\n", page_addr, ptr_idx,
ptr_des & 8 ? 1 : 0,
ptr_des & 4 ? 1 : 0,
ptr_des & 3
page_des = page_info[page_idx].match;
if ((page_des & MMU_PDT_MASK) == 2) {
- D(bug(L" PAGE: %03d-%03d log=%08lx INDIRECT --> addr=%08lx\n",
+ D(bug(L" PAGE: %03d-%03d log=%08lx INDIRECT --> addr=%08lx (%08lx)\n",
page_info[page_idx].start_idx,
page_info[page_idx].start_idx + page_info[page_idx].n_pages - 1,
page_info[page_idx].log,
- page_des & MMU_PAGE_INDIRECT_MASK
+ page_des & MMU_PAGE_INDIRECT_MASK,
+ phys_get_long (page_des & MMU_PAGE_INDIRECT_MASK)
));
} else {
mmu_dump_ttr(L"DTT1", regs.dtt1);
mmu_dump_ttr(L"ITT0", regs.itt0);
mmu_dump_ttr(L"ITT1", regs.itt1);
- mmu_dump_atc();
+// mmu_dump_atc();
#if DEBUG
+ mmu_dump_table(L"URP", regs.urp);
mmu_dump_table(L"SRP", regs.srp);
#endif
}
//write_log (L"BUS ERROR: fc=%d w=%d log=%08x ssw=%04x\n", fc, write, addr, ssw);
//activate_debugger ();
+ //mmu_dump_tables ();
THROW(2);
}
uae_u32 desc, desc_addr, wp;
int i, indirect;
- if (addr == 0xb000)
- write_log (L"x");
-
indirect = 0;
wp = 0;
desc = super ? regs.srp : regs.urp;
desc_addr = (desc & MMU_ROOT_PTR_ADDR_MASK) | i;
desc = phys_get_long(desc_addr);
if ((desc & 2) == 0) {
- D(bug(L"MMU: invalid root descriptor for %lx\n", addr));
+ D(bug(L"MMU: invalid %s root (%08x) descriptor for %08x,%08x = %08x\n",
+ super ? L"S" : L"U", super ? regs.srp : regs.urp, addr, desc_addr, desc));
return 0;
}
regno = opcode & 7;
write = (opcode & 32) == 0;
addr = m68k_areg(regs, regno);
- //bug("ptest(%u,%u,%x)", write, regs.dfc, addr);
D(bug(L"PTEST%c (A%d) %08x DFC=%d\n", write ? 'W' : 'R', regno, addr, regs.dfc));
mmu_flush_atc(addr, super, true);
SAVE_EXCEPTION;
{
// if (regs.tcr == tc)
// return;
-
// regs.tcr = tc;
+
regs.mmu_enabled = tc & 0x8000 ? 1 : 0;
regs.mmu_pagesize_8k = tc & 0x4000 ? 1 : 0;
mmu_flush_atc_all(true);
- D(bug(L"MMU: enabled=%d page8k=%d\n", regs.mmu_enabled, regs.mmu_pagesize_8k));
+ //D(bug(L"MMU: enabled=%d page8k=%d\n", regs.mmu_enabled, regs.mmu_pagesize_8k));
write_log (L"MMU: enabled=%d page8k=%d\n", regs.mmu_enabled, regs.mmu_pagesize_8k);
}
current_atc = &atc_l1[super];
}
-#else
-
-void mmu_op(uae_u32 opcode, uae_u16 /*extra*/)
-{
- if ((opcode & 0xFE0) == 0x0500) {
- /* PFLUSH instruction */
- flush_internals();
- } else if ((opcode & 0x0FD8) == 0x548) {
- /* PTEST instruction */
- } else
- op_illg(opcode);
-}
-
-#endif
-
-/*
-vim:ts=4:sw=4:
-*/
if (currprefs.chipset_mask & CSMASK_ECS_AGNUS)
vp |= lol ? 0x80 : 0;
#if 0
- write_log (L"VPOSR %04x at %08x\n", vp, M68K_GETPC);
+ if (M68K_GETPC < 0xf00000)
+ write_log (L"VPOSR %04x at %08x\n", vp, M68K_GETPC);
#endif
if (currprefs.cpu_model >= 68020)
hsyncdelay ();
static void VPOSW (uae_u16 v)
{
#if 0
- write_log (L"VPOSW %04X PC=%08x\n", v, M68K_GETPC);
+ if (M68K_GETPC < 0xf00000)
+ write_log (L"VPOSW %04X PC=%08x\n", v, M68K_GETPC);
#endif
if (lof != ((v & 0x8000) ? 1 : 0))
lof_changed = 1;
if (currprefs.cpu_model >= 68020)
hsyncdelay ();
#if 0
- write_log (L"VPOS %04x %04x at %08x\n", VPOSR (), vp, M68K_GETPC);
- if (M68K_GETPC == 0x40e6) {
- activate_debugger();
- }
+ if (M68K_GETPC < 0xf00000)
+ write_log (L"VPOS %04x %04x at %08x\n", VPOSR (), vp, M68K_GETPC);
#endif
return vp;
}
if (using_ce020)
printf ("\t%sa = get_disp_ea_020ce (m68k_areg (regs, %s), next_iword_020ce ());\n", name, reg);
else if (using_mmu)
- printf ("\t%sa = get_disp_ea_020 (m68k_areg (regs, %s), next_iword_mmu ());\n", name, reg);
+ printf ("\t%sa = get_disp_ea_040mmu (m68k_areg (regs, %s), next_iword_mmu ());\n", name, reg);
else
printf ("\t%sa = get_disp_ea_020 (m68k_areg (regs, %s), next_iword ());\n", name, reg);
} else {
if (using_ce020)
printf ("\t%sa = get_disp_ea_020ce (tmppc, next_iword_020ce ());\n", name);
else if (using_mmu)
- printf ("\t%sa = get_disp_ea_020 (tmppc, next_iword_mmu ());\n", name);
+ printf ("\t%sa = get_disp_ea_040mmu (tmppc, next_iword_mmu ());\n", name);
else
printf ("\t%sa = get_disp_ea_020 (tmppc, next_iword ());\n", name);
} else {
static void gen_opcode (unsigned long int opcode)
{
struct instr *curi = table68k + opcode;
+ char *srcl, *dstl;
+ char *srcw, *dstw;
+ char *srcb, *dstb;
insn_n_cycles = using_prefetch ? 0 : 4;
+ if (using_ce020) {
+ srcl = "get_long_ce020";
+ dstl = "put_long_ce020";
+ srcw = "get_word_ce020";
+ dstw = "put_word_ce020";
+ srcb = "get_byte_ce020";
+ dstb = "put_byte_ce020";
+ } else if (using_mmu) {
+ srcl = "get_long_mmu";
+ dstl = "put_long_mmu";
+ srcw = "get_word_mmu";
+ dstw = "put_word_mmu";
+ srcb = "get_byte_mmu";
+ dstb = "put_byte_mmu";
+ } else {
+ srcl = "get_long";
+ dstl = "put_long";
+ srcw = "get_word";
+ dstw = "put_word";
+ srcb = "get_byte";
+ dstb = "put_byte";
+ }
+
if (using_ce020) {
addcycles_ce020 (1); // better than nothing...
}
printf ("\tm68k_do_rts_ce ();\n");
else if (using_indirect)
printf ("\tm68k_do_rtsi ();\n");
+ else if (using_mmu)
+ printf ("\tm68k_do_rts_mmu ();\n");
else
printf ("\tm68k_do_rts ();\n");
count_read += 2;
fill_prefetch_1 (0);
if (curi->smode == Ad8r || curi->smode == PC8r)
addcycles000 (6);
- printf("\tm68k_areg (regs, 7) -= 4;\n");
+ printf ("\tm68k_areg (regs, 7) -= 4;\n");
if (using_ce) {
- printf("\tput_word_ce (m68k_areg (regs, 7), oldpc >> 16);\n");
- printf("\tput_word_ce (m68k_areg (regs, 7) + 2, oldpc);\n");
+ printf ("\tput_word_ce (m68k_areg (regs, 7), oldpc >> 16);\n");
+ printf ("\tput_word_ce (m68k_areg (regs, 7) + 2, oldpc);\n");
+ } else if (using_mmu) {
+ printf ("\tput_long_mmu (m68k_areg (regs, 7), oldpc);\n");
} else {
- printf("\tput_long (m68k_areg (regs, 7), oldpc);\n");
+ printf ("\tput_long (m68k_areg (regs, 7), oldpc);\n");
}
count_write += 2;
fill_prefetch_next ();
need_endlabel = 1;
}
addcycles000 (2);
- if (using_ce)
+ if (using_ce) {
printf ("\tm68k_do_bsr_ce (m68k_getpc () + %d, s);\n", m68k_pc_offset);
- else if (using_indirect)
+ } else if (using_indirect) {
printf ("\tm68k_do_bsri (m68k_getpc () + %d, s);\n", m68k_pc_offset);
- else
+ } else if (using_mmu) {
+ printf ("\tm68k_do_bsr_mmu (m68k_getpc () + %d, s);\n", m68k_pc_offset);
+ } else {
printf ("\tm68k_do_bsr (m68k_getpc () + %d, s);\n", m68k_pc_offset);
+ }
count_write += 2;
m68k_pc_offset = 0;
fill_prefetch_full ();
} else {
printf ("\tuae_u32 tmp,bf0,bf1;\n");
printf ("\tdsta += (offset >> 3) | (offset & 0x80000000 ? ~0x1fffffff : 0);\n");
- printf ("\tbf0 = get_long (dsta);bf1 = get_byte (dsta+4) & 0xff;\n");
+ printf ("\tbf0 = %s (dsta);bf1 = %s (dsta+4) & 0xff;\n", srcl, srcb);
printf ("\ttmp = (bf0 << (offset & 7)) | (bf1 >> (8 - (offset & 7)));\n");
}
printf ("\ttmp >>= (32 - width);\n");
printf ("\t\t(tmp >> (offset & 7)) |\n");
printf ("\t\t(((offset & 7) + width) >= 32 ? 0 :\n");
printf ("\t\t (bf0 & ((uae_u32)0xffffffff >> ((offset & 7) + width))));\n");
- printf ("\tput_long (dsta,bf0 );\n");
+ printf ("\t%s (dsta, bf0 );\n", dstl);
printf ("\tif (((offset & 7) + width) > 32) {\n");
printf ("\t\tbf1 = (bf1 & (0xff >> (width - 32 + (offset & 7)))) |\n");
printf ("\t\t\t(tmp << (8 - (offset & 7)));\n");
- printf ("\t\tput_byte (dsta+4,bf1);\n");
+ printf ("\t\t%s (dsta + 4,bf1);\n", dstb);
printf ("\t}\n");
}
}
printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n");
printf ("\tval = (uae_u16)get_byte (m68k_areg (regs, srcreg));\n");
printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n");
- printf ("\tval = (val | ((uae_u16)get_byte (m68k_areg (regs, srcreg)) << 8)) + %s;\n", gen_nextiword (0));
+ printf ("\tval = (val | ((uae_u16)%s (m68k_areg (regs, srcreg)) << 8)) + %s;\n", srcb, gen_nextiword (0));
printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n");
- printf ("\tput_byte (m68k_areg (regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n");
+ printf ("\t%s (m68k_areg (regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n", dstb);
}
break;
case i_UNPK:
printf ("\tval = (uae_u16)get_byte (m68k_areg (regs, srcreg));\n");
printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword (0));
printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n");
- printf ("\tput_byte (m68k_areg (regs, dstreg),val);\n");
+ printf ("\t%s (m68k_areg (regs, dstreg),val);\n", dstb);
printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n");
- printf ("\tput_byte (m68k_areg (regs, dstreg),val >> 8);\n");
+ printf ("\t%s (m68k_areg (regs, dstreg),val >> 8);\n", dstb);
}
break;
case i_TAS:
case i_MOVE16:
{
- char *src, *dst;
- if (using_ce020) {
- src = "get_long_ce020";
- dst = "put_long_ce020";
- } else if (using_mmu) {
- src = "get_long_mmu";
- dst = "put_long_mmu";
- } else {
- src = "get_long";
- dst = "put_long";
- }
if ((opcode & 0xfff8) == 0xf620) {
/* MOVE16 (Ax)+,(Ay)+ */
printf ("\tuae_u32 v1, v2, v3, v4;\n");
printf ("\tuaecptr mems = m68k_areg (regs, srcreg) & ~15, memd;\n");
printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword (0));
printf ("\tmemd = m68k_areg (regs, dstreg) & ~15;\n");
- printf ("\tv1 = %s (mems);\n", src);
- printf ("\tv2 = %s (mems + 4);\n", src);
- printf ("\tv3 = %s (mems + 8);\n", src);
- printf ("\tv4 = %s (mems + 12);\n", src);
- printf ("\t%s (memd , v1);\n", dst);
- printf ("\t%s (memd + 4, v2);\n", dst);
- printf ("\t%s (memd + 8, v3);\n", dst);
- printf ("\t%s (memd + 12, v4);\n", dst);
+ printf ("\tv1 = %s (mems);\n", srcl);
+ printf ("\tv2 = %s (mems + 4);\n", srcl);
+ printf ("\tv3 = %s (mems + 8);\n", srcl);
+ printf ("\tv4 = %s (mems + 12);\n", srcl);
+ printf ("\t%s (memd , v1);\n", dstl);
+ printf ("\t%s (memd + 4, v2);\n", dstl);
+ printf ("\t%s (memd + 8, v3);\n", dstl);
+ printf ("\t%s (memd + 12, v4);\n", dstl);
printf ("\tif (srcreg != dstreg)\n");
printf ("\t\tm68k_areg (regs, srcreg) += 16;\n");
printf ("\tm68k_areg (regs, dstreg) += 16;\n");
genamode (curi->dmode, "dstreg", curi->size, "memd", 0, 2, 0);
printf ("\tmemsa &= ~15;\n");
printf ("\tmemda &= ~15;\n");
- printf ("\tv1 = %s (memsa);\n", src);
- printf ("\tv2 = %s (memsa + 4);\n", src);
- printf ("\tv3 = %s (memsa + 8);\n", src);
- printf ("\tv4 = %s (memsa + 12);\n", src);
- printf ("\t%s (memda , v1);\n", dst);
- printf ("\t%s (memda + 4, v2);\n", dst);
- printf ("\t%s (memda + 8, v3);\n", dst);
- printf ("\t%s (memda + 12, v4);\n", dst);
+ printf ("\tv1 = %s (memsa);\n", srcl);
+ printf ("\tv2 = %s (memsa + 4);\n", srcl);
+ printf ("\tv3 = %s (memsa + 8);\n", srcl);
+ printf ("\tv4 = %s (memsa + 12);\n", srcl);
+ printf ("\t%s (memda , v1);\n", dstl);
+ printf ("\t%s (memda + 4, v2);\n", dstl);
+ printf ("\t%s (memda + 8, v3);\n", dstl);
+ printf ("\t%s (memda + 12, v4);\n", dstl);
if ((opcode & 0xfff8) == 0xf600)
printf ("\tm68k_areg (regs, srcreg) += 16;\n");
else if ((opcode & 0xfff8) == 0xf608)
extern void mmu_make_transparent_region(uaecptr baseaddr, uae_u32 size, int datamode);
-STATIC_INLINE void mmu_set_ttr(int regno, uae_u32 val)
-{
- uae_u32 * ttr;
- switch(regno) {
- case TTR_I0: ttr = ®s.itt0; break;
- case TTR_I1: ttr = ®s.itt1; break;
- case TTR_D0: ttr = ®s.dtt0; break;
- case TTR_D1: ttr = ®s.dtt1; break;
- default: abort();
- }
- *ttr = val;
-}
-
-STATIC_INLINE void mmu_set_mmusr(uae_u32 val)
-{
- regs.mmusr = val;
-}
-
-STATIC_INLINE void mmu_set_root_pointer(int regno, uae_u32 val)
-{
- val &= MMU_ROOT_PTR_ADDR_MASK;
- switch (regno) {
- case 0x806:
- regs.urp = val;
- break;
- case 0x807:
- regs.srp = val;
- break;
- default:
- abort();
- }
-}
-
#define FC_DATA (regs.s ? 5 : 1)
#define FC_INST (regs.s ? 6 : 2)
extern void REGPARAM3 mmu_flush_atc_all(bool global) REGPARAM;
extern void REGPARAM3 mmu_op_real(uae_u32 opcode, uae_u16 extra) REGPARAM;
-#ifdef FULLMMU
-
extern void REGPARAM3 mmu_reset(void) REGPARAM;
extern void REGPARAM3 mmu_set_tc(uae_u16 tc) REGPARAM;
extern void REGPARAM3 mmu_set_super(bool super) REGPARAM;
-#else
-
-STATIC_INLINE void mmu_reset(void)
-{
-}
-
-STATIC_INLINE void mmu_set_tc(uae_u16 /*tc*/)
-{
-}
-
-STATIC_INLINE void mmu_set_super(bool /*super*/)
-{
-}
-
-#endif
-
-
-#ifdef FULLMMU
static ALWAYS_INLINE bool is_unaligned(uaecptr addr, int size)
{
return unlikely((addr & (size - 1)) && (addr ^ (addr + size - 1)) & 0x1000);
static ALWAYS_INLINE uaecptr mmu_get_real_address(uaecptr addr, struct mmu_atc_line *cl)
{
- return cl->phys + addr;
+ return cl->phys + addr;
}
static ALWAYS_INLINE void phys_put_long(uaecptr addr, uae_u32 l)
{
- put_long (addr, l);
+ longput(addr, l);
}
static ALWAYS_INLINE void phys_put_word(uaecptr addr, uae_u32 w)
{
- put_word (addr, w);
+ wordput(addr, w);
}
static ALWAYS_INLINE void phys_put_byte(uaecptr addr, uae_u32 b)
{
- put_byte (addr, b);
+ byteput(addr, b);
}
static ALWAYS_INLINE uae_u32 phys_get_long(uaecptr addr)
{
- return get_long (addr);
+ return longget (addr);
}
static ALWAYS_INLINE uae_u32 phys_get_word(uaecptr addr)
{
- return get_word (addr);
+ return wordget (addr);
}
static ALWAYS_INLINE uae_u32 phys_get_byte(uaecptr addr)
{
- return get_byte (addr);
+ return byteget (addr);
}
static ALWAYS_INLINE uae_u32 mmu_get_long(uaecptr addr, int data, int size)
mmu_put_byte(addr, val, 1, sz_byte);
}
-
-
-
-#else
-
-# define get_long(a) phys_get_long(a)
-# define get_word(a) phys_get_word(a)
-# define get_byte(a) phys_get_byte(a)
-# define put_long(a,b) phys_put_long(a,b)
-# define put_word(a,b) phys_put_word(a,b)
-# define put_byte(a,b) phys_put_byte(a,b)
-# define get_real_address(a,w,s) phys_get_real_address(a)
-
-#define valid_address(a,w,s) phys_valid_address(a,w,s)
-#endif
-
-
STATIC_INLINE void put_byte_mmu (uaecptr addr, uae_u32 v)
{
uae_mmu_put_byte (addr, v);
m68k_incpc (4);
return uae_mmu_get_ilong (pc);
}
+
+extern void m68k_do_rts_mmu (void);
+extern void m68k_do_bsr_mmu (uaecptr oldpc, uae_s32 offset);
+
+
#endif /* CPUMMU_H */
byteput(addr, b);
}
+extern void put_long_slow (uaecptr addr, uae_u32 v);
+extern void put_word_slow (uaecptr addr, uae_u32 v);
+extern void put_byte_slow (uaecptr addr, uae_u32 v);
+extern uae_u32 get_long_slow (uaecptr addr);
+extern uae_u32 get_word_slow (uaecptr addr);
+extern uae_u32 get_byte_slow (uaecptr addr);
+
+
/*
* Store host pointer v at addr
*/
STATIC_INLINE void m68k_do_rts (void)
{
- m68k_setpc (get_long(m68k_areg (regs, 7)));
+ m68k_setpc (get_long (m68k_areg (regs, 7)));
m68k_areg (regs, 7) += 4;
}
STATIC_INLINE void m68k_do_rtsi (void)
m68k_incpci (offset);
}
-STATIC_INLINE void m68k_do_jsr (uaecptr oldpc, uaecptr dest)
-{
- m68k_areg (regs, 7) -= 4;
- put_long(m68k_areg (regs, 7), oldpc);
- m68k_setpc (dest);
-}
-
#define get_ibyte(o) do_get_mem_byte((uae_u8 *)((regs).pc_p + (o) + 1))
#define get_iword(o) do_get_mem_word((uae_u16 *)((regs).pc_p + (o)))
#define get_ilong(o) do_get_mem_long((uae_u32 *)((regs).pc_p + (o)))
extern uae_u32 REGPARAM3 get_disp_ea_020 (uae_u32 base, uae_u32 dp) REGPARAM;
extern uae_u32 REGPARAM3 get_disp_ea_020ce (uae_u32 base, uae_u32 dp) REGPARAM;
+extern uae_u32 REGPARAM3 get_disp_ea_040mmu (uae_u32 base, uae_u32 dp) REGPARAM;
extern uae_u32 REGPARAM3 get_disp_ea_000 (uae_u32 base, uae_u32 dp) REGPARAM;
extern void m68k_disasm_ea (void *f, uaecptr addr, uaecptr *nextpc, int cnt, uae_u32 *seaddr, uae_u32 *deaddr);
extern void m68k_disasm (void *f, uaecptr addr, uaecptr *nextpc, int cnt);
* Copyright 1995-2001 Bernd Schmidt
*/
-#define UAEMAJOR 1
-#define UAEMINOR 6
-#define UAESUBREV 2
+#define UAEMAJOR 2
+#define UAEMINOR 0
+#define UAESUBREV 0
typedef enum { KBD_LANG_US, KBD_LANG_DK, KBD_LANG_DE, KBD_LANG_SE, KBD_LANG_FR, KBD_LANG_IT, KBD_LANG_ES } KbdLang;
{
if (quit_program == 0) {
/* do this only in 68010+ mode, there are some tricky A500 programs.. */
- if (currprefs.cpu_model > 68000 || !currprefs.cpu_compatible) {
+ if ((currprefs.cpu_model > 68000 || !currprefs.cpu_compatible) && !currprefs.mmu_model) {
#if defined(ENFORCER)
enforcer_disable ();
#endif
void uae_NewList (uaecptr list)
{
- put_long (list, list + 4);
- put_long (list + 4, 0);
- put_long (list + 8, list);
+ put_long_slow (list, list + 4);
+ put_long_slow (list + 4, 0);
+ put_long_slow (list + 8, list);
}
uaecptr uae_AllocMem (TrapContext *context, uae_u32 size, uae_u32 flags)
void fill_prefetch_slow (void)
{
+ if (currprefs.mmu_model)
+ return;
#ifdef CPUEMU_12
if (currprefs.cpu_cycle_exact) {
regs.ir = get_word_ce (m68k_getpc ());
}
#endif
+static void Exception_mmu (int nr, uaecptr oldpc)
+{
+ uae_u32 currpc = m68k_getpc (), newpc;
+ int sv = regs.s;
+ int i;
+
+ exception_debug (nr);
+ MakeSR ();
+
+ if (!regs.s) {
+ regs.usp = m68k_areg (regs, 7);
+ if (currprefs.cpu_model >= 68020)
+ m68k_areg (regs, 7) = regs.m ? regs.msp : regs.isp;
+ else
+ m68k_areg (regs, 7) = regs.isp;
+ regs.s = 1;
+ mmu_set_super (1);
+ }
+ if (nr == 2) {
+ // bus error
+ for (i = 0 ; i < 7 ; i++) {
+ m68k_areg (regs, 7) -= 4;
+ put_long_mmu (m68k_areg (regs, 7), 0);
+ }
+ m68k_areg (regs, 7) -= 4;
+ put_long_mmu (m68k_areg (regs, 7), regs.wb3_data);
+ m68k_areg (regs, 7) -= 4;
+ put_long_mmu (m68k_areg (regs, 7), regs.mmu_fault_addr);
+ m68k_areg (regs, 7) -= 4;
+ put_long_mmu (m68k_areg (regs, 7), regs.mmu_fault_addr);
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), 0);
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), 0);
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), regs.wb3_status);
+ regs.wb3_status = 0;
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), regs.mmu_ssw);
+ m68k_areg (regs, 7) -= 4;
+ put_long_mmu (m68k_areg (regs, 7), regs.mmu_fault_addr);
+
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), 0x7000 + nr * 4);
+ m68k_areg (regs, 7) -= 4;
+ put_long_mmu (m68k_areg (regs, 7), oldpc);
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), regs.sr);
+ goto kludge_me_do;
+
+ } else if (nr == 3) {
+
+ // address error
+ uae_u16 ssw = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1);
+ ssw |= last_writeaccess_for_exception_3 ? 0 : 0x40;
+ ssw |= 0x20;
+ for (i = 0 ; i < 36; i++) {
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), 0);
+ }
+ m68k_areg (regs, 7) -= 4;
+ put_long_mmu (m68k_areg (regs, 7), last_fault_for_exception_3);
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), 0);
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), 0);
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), 0);
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), ssw);
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), 0xb000 + nr * 4);
+ write_log (L"Exception %d (%x) at %x -> %x!\n", nr, oldpc, currpc, get_long (regs.vbr + 4*nr));
+
+ } else if (nr ==5 || nr == 6 || nr == 7 || nr == 9) {
+
+ m68k_areg (regs, 7) -= 4;
+ put_long_mmu (m68k_areg (regs, 7), oldpc);
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), 0x2000 + nr * 4);
+
+ } else if (regs.m && nr >= 24 && nr < 32) { /* M + Interrupt */
+
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), nr * 4);
+ m68k_areg (regs, 7) -= 4;
+ put_long_mmu (m68k_areg (regs, 7), currpc);
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), regs.sr);
+ regs.sr |= (1 << 13);
+ regs.msp = m68k_areg (regs, 7);
+ m68k_areg (regs, 7) = regs.isp;
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), 0x1000 + nr * 4);
+
+ } else {
+
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), nr * 4);
+
+ }
+ m68k_areg (regs, 7) -= 4;
+ put_long_mmu (m68k_areg (regs, 7), currpc);
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), regs.sr);
+kludge_me_do:
+ newpc = get_long_mmu (regs.vbr + 4 * nr);
+ if (newpc & 1) {
+ if (nr == 2 || nr == 3)
+ uae_reset (1); /* there is nothing else we can do.. */
+ else
+ exception3 (regs.ir, m68k_getpc (), newpc);
+ return;
+ }
+ m68k_setpc (newpc);
+ set_special (SPCFLAG_END_COMPILE);
+ fill_prefetch_slow ();
+ exception_trace (nr);
+}
+
+
static void Exception_normal (int nr, uaecptr oldpc)
{
uae_u32 currpc = m68k_getpc (), newpc;
for (i = 0 ; i < 7 ; i++) {
m68k_areg (regs, 7) -= 4;
- put_long (m68k_areg (regs, 7), 0);
+ put_long_mmu (m68k_areg (regs, 7), 0);
}
m68k_areg (regs, 7) -= 4;
- put_long (m68k_areg (regs, 7), regs.wb3_data);
+ put_long_mmu (m68k_areg (regs, 7), regs.wb3_data);
m68k_areg (regs, 7) -= 4;
- put_long (m68k_areg (regs, 7), regs.mmu_fault_addr);
+ put_long_mmu (m68k_areg (regs, 7), regs.mmu_fault_addr);
m68k_areg (regs, 7) -= 4;
- put_long (m68k_areg (regs, 7), regs.mmu_fault_addr);
+ put_long_mmu (m68k_areg (regs, 7), regs.mmu_fault_addr);
m68k_areg (regs, 7) -= 2;
- put_word (m68k_areg (regs, 7), 0);
+ put_word_mmu (m68k_areg (regs, 7), 0);
m68k_areg (regs, 7) -= 2;
- put_word (m68k_areg (regs, 7), 0);
+ put_word_mmu (m68k_areg (regs, 7), 0);
m68k_areg (regs, 7) -= 2;
- put_word (m68k_areg (regs, 7), regs.wb3_status);
+ put_word_mmu (m68k_areg (regs, 7), regs.wb3_status);
regs.wb3_status = 0;
m68k_areg (regs, 7) -= 2;
- put_word (m68k_areg (regs, 7), regs.mmu_ssw);
+ put_word_mmu (m68k_areg (regs, 7), regs.mmu_ssw);
m68k_areg (regs, 7) -= 4;
- put_long (m68k_areg (regs, 7), regs.mmu_fault_addr);
+ put_long_mmu (m68k_areg (regs, 7), regs.mmu_fault_addr);
+
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), 0x7000 + nr * 4);
+ m68k_areg (regs, 7) -= 4;
+ put_long_mmu (m68k_areg (regs, 7), oldpc);
+ m68k_areg (regs, 7) -= 2;
+ put_word_mmu (m68k_areg (regs, 7), regs.sr);
+ newpc = get_long_mmu (regs.vbr + 4 * nr);
+ if (newpc & 1) {
+ if (nr == 2 || nr == 3)
+ uae_reset (1); /* there is nothing else we can do.. */
+ else
+ exception3 (regs.ir, m68k_getpc (), newpc);
+ return;
+ }
+ m68k_setpc (newpc);
+ set_special (SPCFLAG_END_COMPILE);
+ exception_trace (nr);
+ return;
} else {
put_word (m68k_areg (regs, 7), 0x0140 | (sv ? 6 : 2)); /* SSW */
m68k_areg (regs, 7) -= 4;
put_long (m68k_areg (regs, 7), last_addr_for_exception_3);
+ m68k_areg (regs, 7) -= 2;
+ put_word (m68k_areg (regs, 7), 0x7000 + nr * 4);
+ m68k_areg (regs, 7) -= 4;
+ put_long (m68k_areg (regs, 7), oldpc);
+ m68k_areg (regs, 7) -= 2;
+ put_word (m68k_areg (regs, 7), regs.sr);
+ goto kludge_me_do;
+
}
- m68k_areg (regs, 7) -= 2;
- put_word (m68k_areg (regs, 7), 0x7000 + nr * 4);
- m68k_areg (regs, 7) -= 4;
- put_long (m68k_areg (regs, 7), oldpc);
- m68k_areg (regs, 7) -= 2;
- put_word (m68k_areg (regs, 7), regs.sr);
- goto kludge_me_do;
-
} else {
m68k_areg (regs, 7) -= 4;
put_long (m68k_areg (regs, 7), last_fault_for_exception_3);
Exception_ce (nr, oldpc);
else
#endif
+ if (currprefs.mmu_model)
+ Exception_mmu (nr, oldpc);
+ else
Exception_normal (nr, oldpc);
}
/* We can afford this to be inefficient... */
m68k_setpc (m68k_getpc ());
fill_prefetch_slow ();
- opcode = get_word (regs.pc);
+ if (currprefs.mmu_model)
+ opcode = get_word_mmu (regs.pc);
+ else
+ opcode = get_word (regs.pc);
if (opcode == 0x4e73 /* RTE */
|| opcode == 0x4e74 /* RTD */
|| opcode == 0x4e75 /* RTS */
/* Aranym MMU 68040 */
static void m68k_run_mmu040 (void)
{
- struct regstruct *r = ®s;
uae_u32 opcode;
for (;;) {
cpu_cycles = (*cpufunctbl[opcode])(opcode);
cpu_cycles &= cycles_mask;
cpu_cycles |= cycles_val;
- if (r->spcflags) {
+ if (regs.spcflags) {
if (do_specialties (cpu_cycles))
return;
}
}
}
-/* "cycle exact 68020 */
+/* "cycle exact" 68020 */
static void m68k_run_2ce (void)
{
struct regstruct *r = ®s;
currprefs.cpu_compatible = changed_prefs.cpu_compatible;
currprefs.cpu_cycle_exact = changed_prefs.cpu_cycle_exact;
currprefs.blitter_cycle_exact = changed_prefs.blitter_cycle_exact;
+ currprefs.cpu_frequency = changed_prefs.cpu_frequency = 0;
+ currprefs.cpu_clock_multiplier = changed_prefs.cpu_clock_multiplier = 0;
for (i = 0; i < 15; i++)
regs.regs[i] = restore_u32 ();
regs.pc = restore_u32 ();
} else if (f == 0x8) {
m68k_areg (regs, 7) += 50;
} else if (f == 0x7) {
- uae_u16 ssr = get_word (m68k_areg (regs, 7) + 4);
+ uae_u16 ssr = get_word_mmu (m68k_areg (regs, 7) + 4);
if (ssr & MMU_SSW_CT) {
uaecptr src_a7 = m68k_areg (regs, 7) - 8;
uaecptr dst_a7 = m68k_areg (regs, 7) + 52;
void flush_mmu (uaecptr addr, int n)
{
}
+
+void m68k_do_rts_mmu (void)
+{
+ m68k_setpc (get_long_mmu (m68k_areg (regs, 7)));
+ m68k_areg (regs, 7) += 4;
+}
+void m68k_do_bsr_mmu (uaecptr oldpc, uae_s32 offset)
+{
+ m68k_areg (regs, 7) -= 4;
+ put_long_mmu (m68k_areg (regs, 7), oldpc);
+ m68k_incpc (offset);
+}
+
+
+void put_long_slow (uaecptr addr, uae_u32 v)
+{
+ if (currprefs.mmu_model)
+ put_long_mmu (addr, v);
+ else
+ put_long (addr, v);
+}
+void put_word_slow (uaecptr addr, uae_u32 v)
+{
+ if (currprefs.mmu_model)
+ put_word_mmu (addr, v);
+ else
+ put_word (addr, v);
+}
+void put_byte_slow (uaecptr addr, uae_u32 v)
+{
+ if (currprefs.mmu_model)
+ put_byte_mmu (addr, v);
+ else
+ put_byte (addr, v);
+}
+uae_u32 get_long_slow (uaecptr addr)
+{
+ if (currprefs.mmu_model)
+ return get_long_mmu (addr);
+ else
+ return get_long (addr);
+}
+uae_u32 get_word_slow (uaecptr addr)
+{
+ if (currprefs.mmu_model)
+ return get_word_mmu (addr);
+ else
+ return get_word (addr);
+}
+uae_u32 get_byte_slow (uaecptr addr)
+{
+ if (currprefs.mmu_model)
+ return get_byte_mmu (addr);
+ else
+ return get_byte (addr);
+}
sd->channels, rn[rncnt], sd->freq,
pwfx ? pwfx->nChannels : -1, pwfx ? pwfx->nSamplesPerSec : -1,
hr);
- if (final && SUCCEEDED (hr))
+ if (final && SUCCEEDED (hr)) {
+ if (pwfx_saved) {
+ sd->channels = pwfx_saved->nChannels;
+ sd->freq = pwfx_saved->nSamplesPerSec;
+ CoTaskMemFree (pwfx);
+ pwfx = pwfx_saved;
+ pwfx_saved = NULL;
+ }
break;
+ }
if (hr != AUDCLNT_E_UNSUPPORTED_FORMAT && hr != S_FALSE)
goto error;
if (hr == S_FALSE && pwfx_saved == NULL) {
#define WINUAEPUBLICBETA 1
-#define WINUAEBETA L"11"
-#define WINUAEDATE MAKEBD(2009, 8, 26)
+#define WINUAEBETA L"12"
+#define WINUAEDATE MAKEBD(2009, 8, 29)
#define WINUAEEXTRA L""
#define WINUAEREV L""
#endif
#define AMIGA_WIDTH_MAX (752 / 2)
-#define AMIGA_HEIGHT_MAX (568 / 2)
+#define AMIGA_HEIGHT_MAX (572 / 2)
#define DM_DX_FULLSCREEN 1
#define DM_W_FULLSCREEN 2
if (hz < 0)
return tempvsync;
- if (currprefs.ntscmode)
- newh = h * 60 / 50;
- else
- newh = h * 50 / 60;
+ newh = h * oldhz / hz;
hz = hz * dbl;
found = NULL;
+Beta 12:
+
+- increased vertical filter display buffer size by 4 pixels (max PAL
+ overscan fully visible now, again..)
+- autovsync vertical resolution autoselection really works now
+- more MMU fixes, Linux boots now. MMULib does not work but it most
+ likely is a bug in MMULib which expects some undocumented behavior
+ of 68040 (like how ATC caches work etc..) Commodore's 68040.library
+ works. Note that native code (for example filesystem emulation) can't
+ support MMU address translation (impossible to call bus error handler
+ from non-68k code without some heavy black magic) -> any non-debugging
+ MMU software most likely won't work without using IDE or SCSI
+ emulation. MMU support is considered finished now. Enforcer and Linux
+ working = good enough :)
+- version number bumped to 2.0
+
Beta 11:
- fixed 68020 CE-mode cycle counting bug (too slow memory accesses)
#define SHOW_CONSOLE 0
+static int nodatestamps = 0;
+
int consoleopen = 0;
static int realconsole;
static HANDLE stdinput,stdoutput;
if (bootlogmode)
return NULL;
+ if (nodatestamps)
+ return NULL;
_ftime (&tb);
t = localtime (&tb.time);
_tcsftime (curts, sizeof curts / sizeof (TCHAR), L"%Y-%m-%d %H:%M:%S\n", t);