From: Toni Wilen Date: Sun, 12 Sep 2010 14:32:14 +0000 (+0300) Subject: 2300b17 X-Git-Tag: 2300~4 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=b2f47797599a25548a919f294771793beaf9abee;p=francis%2Fwinuae.git 2300b17 --- diff --git a/cpummu.cpp b/cpummu.cpp index f918d8a1..d152f334 100644 --- a/cpummu.cpp +++ b/cpummu.cpp @@ -1,66 +1,70 @@ /* -* cpummu.cpp - MMU emulation -* -* Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) -* -* Inspired by UAE MMU patch -* -* This file is part of the ARAnyM project which builds a new and powerful -* TOS/FreeMiNT compatible virtual machine running on almost any hardware. -* -* ARAnyM is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* ARAnyM is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with ARAnyM; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ + * cpummu.cpp - MMU emulation + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by UAE MMU patch + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * ARAnyM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * ARAnyM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ #define DEBUG 0 +#define USETAG 0 + #include "sysconfig.h" #include "sysdeps.h" #include "options.h" #include "memory.h" -#include "custom.h" #include "newcpu.h" -#include "cpummu.h" #include "debug.h" +#include "cpummu.h" #define DBG_MMU_VERBOSE 1 #define DBG_MMU_SANITY 1 -static mmu_atc_l1_array atc_l1[2]; -static struct mmu_atc_line atc_l2[2][ATC_L2_SIZE]; +#ifdef FULLMMU + +mmu_atc_l1_array atc_l1[2]; mmu_atc_l1_array *current_atc; +static struct mmu_atc_line atc_l2[2][ATC_L2_SIZE]; -#ifdef ATC_STATS +# ifdef ATC_STATS static unsigned int mmu_atc_hits[ATC_L2_SIZE]; -#endif +# endif static void mmu_dump_ttr(const TCHAR * label, uae_u32 ttr) { + DUNUSED(label); uae_u32 from_addr, to_addr; from_addr = ttr & MMU_TTR_LOGICAL_BASE; to_addr = (ttr & MMU_TTR_LOGICAL_MASK) << 8; D(bug(L"%s: [%08lx] %08lx - %08lx enabled=%d supervisor=%d wp=%d cm=%02d\n", - label, ttr, - from_addr, to_addr, - ttr & MMU_TTR_BIT_ENABLED ? 1 : 0, - (ttr & (MMU_TTR_BIT_SFIELD_ENABLED | MMU_TTR_BIT_SFIELD_SUPER)) >> MMU_TTR_SFIELD_SHIFT, - ttr & MMU_TTR_BIT_WRITE_PROTECT ? 1 : 0, - (ttr & MMU_TTR_CACHE_MASK) >> MMU_TTR_CACHE_SHIFT - )); + label, ttr, + from_addr, to_addr, + ttr & MMU_TTR_BIT_ENABLED ? 1 : 0, + (ttr & (MMU_TTR_BIT_SFIELD_ENABLED | MMU_TTR_BIT_SFIELD_SUPER)) >> MMU_TTR_SFIELD_SHIFT, + ttr & MMU_TTR_BIT_WRITE_PROTECT ? 1 : 0, + (ttr & MMU_TTR_CACHE_MASK) >> MMU_TTR_CACHE_SHIFT + )); } void mmu_make_transparent_region(uaecptr baseaddr, uae_u32 size, int datamode) @@ -84,7 +88,7 @@ void mmu_make_transparent_region(uaecptr baseaddr, uae_u32 size, int datamode) } /* check if an address matches a ttr */ -static int mmu_do_match_ttr(uae_u32 ttr, uaecptr addr, int super) +static int mmu_do_match_ttr(uae_u32 ttr, uaecptr addr, bool super) { if (ttr & MMU_TTR_BIT_ENABLED) { /* TTR enabled */ uae_u8 msb, mask; @@ -106,7 +110,7 @@ static int mmu_do_match_ttr(uae_u32 ttr, uaecptr addr, int super) return TTR_NO_MATCH; } -STATIC_INLINE int mmu_match_ttr(uaecptr addr, int super, int data) +static inline int mmu_match_ttr(uaecptr addr, bool super, bool data) { int res; @@ -123,22 +127,22 @@ STATIC_INLINE int mmu_match_ttr(uaecptr addr, int super, int data) } #if DEBUG -#define ROOT_TABLE_SIZE 128 -#define PTR_TABLE_SIZE 128 -#define PAGE_TABLE_SIZE 64 -#define ROOT_INDEX_SHIFT 25 -#define PTR_INDEX_SHIFT 18 /* {{{ mmu_dump_table */ -static void mmu_dump_table(const TCHAR * label, uaecptr root_ptr) +static void mmu_dump_table(const char * label, uaecptr root_ptr) { - // DUNUSED(label); + DUNUSED(label); + const int ROOT_TABLE_SIZE = 128, + PTR_TABLE_SIZE = 128, + PAGE_TABLE_SIZE = 64, + ROOT_INDEX_SHIFT = 25, + PTR_INDEX_SHIFT = 18; // const int PAGE_INDEX_SHIFT = 12; int root_idx, ptr_idx, page_idx; uae_u32 root_des, ptr_des, page_des; uaecptr ptr_des_addr, page_addr, root_log, ptr_log, page_log; - D(bug(L"%s: root=%lx", label, root_ptr)); + D(bug(L"%s: root=%lx\n", label, root_ptr)); for (root_idx = 0; root_idx < ROOT_TABLE_SIZE; root_idx++) { root_des = phys_get_long(root_ptr + root_idx); @@ -146,11 +150,11 @@ static void mmu_dump_table(const TCHAR * label, uaecptr root_ptr) if ((root_des & 2) == 0) continue; /* invalid */ - 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 - )); + 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 + )); root_log = root_idx << ROOT_INDEX_SHIFT; @@ -179,62 +183,61 @@ static void mmu_dump_table(const TCHAR * label, uaecptr root_ptr) page_log = ptr_log | (page_idx << 2); // ??? PAGE_INDEX_SHIFT switch (page_des & 3) { - case 0: /* invalid */ - continue; - case 1: case 3: /* resident */ - case 2: /* indirect */ - if (n_pages_used == -1 || page_info[n_pages_used].match != page_des) { - /* use the next entry */ - n_pages_used++; - - page_info[n_pages_used].match = page_des; - page_info[n_pages_used].n_pages = 1; - page_info[n_pages_used].start_idx = page_idx; - page_info[n_pages_used].log = page_log; - } else { - page_info[n_pages_used].n_pages++; - } - break; + case 0: /* invalid */ + continue; + case 1: case 3: /* resident */ + case 2: /* indirect */ + if (n_pages_used == -1 || page_info[n_pages_used].match != page_des) { + /* use the next entry */ + n_pages_used++; + + page_info[n_pages_used].match = page_des; + page_info[n_pages_used].n_pages = 1; + page_info[n_pages_used].start_idx = page_idx; + page_info[n_pages_used].log = page_log; + } else { + page_info[n_pages_used].n_pages++; + } + break; } } if (n_pages_used == -1) continue; - D(bug(L" PTR: %08X %03d U=%d W=%d UDT=%02d\n", page_addr, ptr_idx, + D(bug(L" PTR: %03d U=%d W=%d UDT=%02d\n", ptr_idx, ptr_des & 8 ? 1 : 0, ptr_des & 4 ? 1 : 0, ptr_des & 3 - )); + )); for (page_idx = 0; page_idx <= n_pages_used; page_idx++) { 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 (%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, - phys_get_long (page_des & MMU_PAGE_INDIRECT_MASK) - )); + D(bug(L" PAGE: %03d-%03d log=%08lx INDIRECT --> addr=%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 + )); } else { D(bug(L" PAGE: %03d-%03d log=%08lx addr=%08lx UR=%02d G=%d U1/0=%d S=%d CM=%d M=%d U=%d W=%d\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 & (regs.mmu_pagesize_8k ? MMU_PAGE_ADDR_MASK_8 : MMU_PAGE_ADDR_MASK_4), - (page_des & (regs.mmu_pagesize_8k ? MMU_PAGE_UR_MASK_8 : MMU_PAGE_UR_MASK_4)) >> MMU_PAGE_UR_SHIFT, - page_des & MMU_DES_GLOBAL ? 1 : 0, - (page_des & MMU_TTR_UX_MASK) >> MMU_TTR_UX_SHIFT, - page_des & MMU_DES_SUPER ? 1 : 0, - (page_des & MMU_TTR_CACHE_MASK) >> MMU_TTR_CACHE_SHIFT, - page_des & MMU_DES_MODIFIED ? 1 : 0, - page_des & MMU_DES_USED ? 1 : 0, - page_des & MMU_DES_WP ? 1 : 0 - )); + 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 & (regs.mmu_pagesize_8k ? MMU_PAGE_ADDR_MASK_8 : MMU_PAGE_ADDR_MASK_4), + (page_des & (regs.mmu_pagesize_8k ? MMU_PAGE_UR_MASK_8 : MMU_PAGE_UR_MASK_4)) >> MMU_PAGE_UR_SHIFT, + page_des & MMU_DES_GLOBAL ? 1 : 0, + (page_des & MMU_TTR_UX_MASK) >> MMU_TTR_UX_SHIFT, + page_des & MMU_DES_SUPER ? 1 : 0, + (page_des & MMU_TTR_CACHE_MASK) >> MMU_TTR_CACHE_SHIFT, + page_des & MMU_DES_MODIFIED ? 1 : 0, + page_des & MMU_DES_USED ? 1 : 0, + page_des & MMU_DES_WP ? 1 : 0 + )); } } } @@ -269,22 +272,21 @@ void mmu_dump_tables(void) 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); + mmu_dump_table("SRP", regs.srp); #endif } /* }}} */ -static uaecptr REGPARAM2 mmu_lookup_pagetable(uaecptr addr, int super, int write); +static uaecptr REGPARAM2 mmu_lookup_pagetable(uaecptr addr, bool super, bool write); static ALWAYS_INLINE int mmu_get_fc(bool super, bool data) { return (super ? 4 : 0) | (data ? 1 : 2); } -static void mmu_bus_error(uaecptr addr, int fc, int write, int size) +static void mmu_bus_error(uaecptr addr, int fc, bool write, int size) { uae_u16 ssw = 0; @@ -305,24 +307,21 @@ static void mmu_bus_error(uaecptr addr, int fc, int write, int size) if (!write) ssw |= MMU_SSW_RW; - if (regs.t0 || regs.t1) - ssw |= MMU_SSW_CT; - regs.mmu_fault_addr = addr; regs.mmu_ssw = ssw | MMU_SSW_ATC; - //write_log (L"BUS ERROR: fc=%d w=%d log=%08x ssw=%04x PC=%08x\n", fc, write, addr, ssw, M68K_GETPC); - //activate_debugger (); - //mmu_dump_tables (); + D(bug(L"BUS ERROR: fc=%d w=%d log=%08x ssw=%04x PC=%08x\n", fc, write, addr, ssw, m68k_getpc())); + + //write_log(L"BUS ERROR: fc=%d w=%d log=%08x ssw=%04x PC=%08x\n", fc, write, addr, ssw, m68k_getpc()); THROW(2); } /* -* Update the atc line for a given address by doing a mmu lookup. -*/ -static uaecptr mmu_fill_atc_l2(uaecptr addr, int super, int data, int write, -struct mmu_atc_line *l) + * Update the atc line for a given address by doing a mmu lookup. + */ +static uaecptr mmu_fill_atc_l2(uaecptr addr, bool super, bool data, bool write, + struct mmu_atc_line *l) { int res; uae_u32 desc; @@ -362,7 +361,9 @@ struct mmu_atc_line *l) SAVE_EXCEPTION; TRY(prb) { desc = mmu_lookup_pagetable(addr, super, write); - D(bug(L"translate: %x,%u,%u,%u -> %x PC=%08x\n", addr, super, write, data, desc, M68K_GETPC)); +#if DEBUG > 2 + D(bug(L"translate: %x,%u,%u,%u -> %x\n", addr, super, write, data, desc)); +#endif RESTORE_EXCEPTION; } CATCH(prb) { @@ -373,7 +374,7 @@ struct mmu_atc_line *l) } if ((desc & 1) == 0 || (!super && desc & MMU_MMUSR_S)) { -fail: + fail: l->valid_data = l->valid_inst = 0; l->global = 0; } else { @@ -386,21 +387,18 @@ fail: l->modified = (desc & MMU_MMUSR_M) != 0; l->write_protect = (desc & MMU_MMUSR_W) != 0; } - D(bug(L"-> %08x\n", l->phys + addr)); return desc; } -static ALWAYS_INLINE bool - mmu_fill_atc_l1(uaecptr addr, int super, int data, int write, -struct mmu_atc_line *l1) +static ALWAYS_INLINE bool mmu_fill_atc_l1(uaecptr addr, bool super, bool data, bool write, struct mmu_atc_line *l1) { int idx = ATC_L2_INDEX(addr); int tag = ATC_TAG(addr); - struct mmu_atc_line *l = &atc_l2[super][idx]; + struct mmu_atc_line *l = &atc_l2[super ? 1 : 0][idx]; if (l->tag != tag) { -restart: + restart: mmu_fill_atc_l2(addr, super, data, write, l); } if (!(data ? l->valid_data : l->valid_inst)) { @@ -416,9 +414,8 @@ restart: goto restart; } *l1 = *l; -#if 0 // some Atari specific stuff? - uaecptr phys_addr; - phys_addr = addr + l1->phys; +#if 0 + uaecptr phys_addr = addr + l1->phys; if ((phys_addr & 0xfff00000) == 0x00f00000) { l1->hw = 1; goto fail; @@ -441,23 +438,24 @@ fail: return false; } -uaecptr REGPARAM2 mmu_translate(uaecptr addr, int super, int data, int write) +uaecptr REGPARAM2 mmu_translate(uaecptr addr, bool super, bool data, bool write) { struct mmu_atc_line *l; - l = &atc_l2[super][ATC_L2_INDEX(addr)]; + l = &atc_l2[super ? 1 : 0][ATC_L2_INDEX(addr)]; mmu_fill_atc_l2(addr, super, data, write, l); if (!(data ? l->valid_data : l->valid_inst)) THROW(2); return addr + l->phys; } + /* -* Lookup the address by walking the page table and updating -* the page descriptors accordingly. Returns the found descriptor -* or produces a bus error. -*/ -static uaecptr REGPARAM2 mmu_lookup_pagetable(uaecptr addr, int super, int write) + * Lookup the address by walking the page table and updating + * the page descriptors accordingly. Returns the found descriptor + * or produces a bus error. + */ +static uaecptr REGPARAM2 mmu_lookup_pagetable(uaecptr addr, bool super, bool write) { uae_u32 desc, desc_addr, wp; int i; @@ -518,9 +516,9 @@ static uaecptr REGPARAM2 mmu_lookup_pagetable(uaecptr addr, int super, int write phys_put_long(desc_addr, desc); } } else if ((desc & (MMU_DES_USED|MMU_DES_MODIFIED)) != - (MMU_DES_USED|MMU_DES_MODIFIED)) { - desc |= MMU_DES_USED|MMU_DES_MODIFIED; - phys_put_long(desc_addr, desc); + (MMU_DES_USED|MMU_DES_MODIFIED)) { + desc |= MMU_DES_USED|MMU_DES_MODIFIED; + phys_put_long(desc_addr, desc); } } else { if ((desc & MMU_DES_USED) == 0) { @@ -531,7 +529,7 @@ static uaecptr REGPARAM2 mmu_lookup_pagetable(uaecptr addr, int super, int write return desc; } -uae_u16 REGPARAM2 mmu_get_word_unaligned(uaecptr addr, int data) +uae_u16 REGPARAM2 mmu_get_word_unaligned(uaecptr addr, bool data) { uae_u16 res; @@ -550,7 +548,7 @@ uae_u16 REGPARAM2 mmu_get_word_unaligned(uaecptr addr, int data) return res; } -uae_u32 REGPARAM2 mmu_get_long_unaligned(uaecptr addr, int data) +uae_u32 REGPARAM2 mmu_get_long_unaligned(uaecptr addr, bool data) { uae_u32 res; @@ -586,13 +584,13 @@ uae_u32 REGPARAM2 mmu_get_long_unaligned(uaecptr addr, int data) return res; } -uae_u8 REGPARAM2 mmu_get_byte_slow(uaecptr addr, int super, int data, - int size, struct mmu_atc_line *cl) +uae_u8 REGPARAM2 mmu_get_byte_slow(uaecptr addr, bool super, bool data, + int size, struct mmu_atc_line *cl) { uae_u32 tag = ATC_TAG(addr); - if (cl->tag == (uae_u16)~tag) { -redo: + if (USETAG && cl->tag == (uae_u16)~tag) { + redo: if (cl->hw) return HWget_b(cl->phys + addr); mmu_bus_error(addr, mmu_get_fc(super, data), 0, size); @@ -605,13 +603,13 @@ redo: return phys_get_byte(mmu_get_real_address(addr, cl)); } -uae_u16 REGPARAM2 mmu_get_word_slow(uaecptr addr, int super, int data, - int size, struct mmu_atc_line *cl) +uae_u16 REGPARAM2 mmu_get_word_slow(uaecptr addr, bool super, bool data, + int size, struct mmu_atc_line *cl) { uae_u32 tag = ATC_TAG(addr); - if (cl->tag == (uae_u16)~tag) { -redo: + if (USETAG && cl->tag == (uae_u16)~tag) { + redo: if (cl->hw) return HWget_w(cl->phys + addr); mmu_bus_error(addr, mmu_get_fc(super, data), 0, size); @@ -624,13 +622,13 @@ redo: return phys_get_word(mmu_get_real_address(addr, cl)); } -uae_u32 REGPARAM2 mmu_get_long_slow(uaecptr addr, int super, int data, - int size, struct mmu_atc_line *cl) +uae_u32 REGPARAM2 mmu_get_long_slow(uaecptr addr, bool super, bool data, + int size, struct mmu_atc_line *cl) { uae_u32 tag = ATC_TAG(addr); - if (cl->tag == (uae_u16)~tag) { -redo: + if (USETAG && cl->tag == (uae_u16)~tag) { + redo: if (cl->hw) return HWget_l(cl->phys + addr); mmu_bus_error(addr, mmu_get_fc(super, data), 0, size); @@ -643,7 +641,7 @@ redo: return phys_get_long(mmu_get_real_address(addr, cl)); } -void REGPARAM2 mmu_put_long_unaligned(uaecptr addr, uae_u32 val, int data) +void REGPARAM2 mmu_put_long_unaligned(uaecptr addr, uae_u32 val, bool data) { SAVE_EXCEPTION; TRY(prb) { @@ -669,12 +667,12 @@ void REGPARAM2 mmu_put_long_unaligned(uaecptr addr, uae_u32 val, int data) } } -void REGPARAM2 mmu_put_word_unaligned(uaecptr addr, uae_u16 val, int data) +void REGPARAM2 mmu_put_word_unaligned(uaecptr addr, uae_u16 val, bool data) { SAVE_EXCEPTION; TRY(prb) { mmu_put_byte(addr, val >> 8, data, sz_word); - mmu_put_byte(addr + 1, (uae_u8)val, data, sz_word); + mmu_put_byte(addr + 1, val, data, sz_word); RESTORE_EXCEPTION; } CATCH(prb) { @@ -688,13 +686,13 @@ void REGPARAM2 mmu_put_word_unaligned(uaecptr addr, uae_u16 val, int data) } } -void REGPARAM2 mmu_put_byte_slow(uaecptr addr, uae_u8 val, int super, int data, - int size, struct mmu_atc_line *cl) +void REGPARAM2 mmu_put_byte_slow(uaecptr addr, uae_u8 val, bool super, bool data, + int size, struct mmu_atc_line *cl) { uae_u32 tag = ATC_TAG(addr); - if (cl->tag == (uae_u16)~tag) { -redo: + if (USETAG && cl->tag == (uae_u16)~tag) { + redo: if (cl->hw) { HWput_b(cl->phys + addr, val); return; @@ -707,17 +705,16 @@ redo: if (!mmu_fill_atc_l1(addr, super, data, 1, cl)) goto redo; - phys_put_byte(mmu_get_real_address(addr, cl), val); } -void REGPARAM2 mmu_put_word_slow(uaecptr addr, uae_u16 val, int super, int data, - int size, struct mmu_atc_line *cl) +void REGPARAM2 mmu_put_word_slow(uaecptr addr, uae_u16 val, bool super, bool data, + int size, struct mmu_atc_line *cl) { uae_u32 tag = ATC_TAG(addr); - if (cl->tag == (uae_u16)~tag) { -redo: + if (USETAG && cl->tag == (uae_u16)~tag) { + redo: if (cl->hw) { HWput_w(cl->phys + addr, val); return; @@ -733,13 +730,13 @@ redo: phys_put_word(mmu_get_real_address(addr, cl), val); } -void REGPARAM2 mmu_put_long_slow(uaecptr addr, uae_u32 val, int super, int data, - int size, struct mmu_atc_line *cl) +void REGPARAM2 mmu_put_long_slow(uaecptr addr, uae_u32 val, bool super, bool data, + int size, struct mmu_atc_line *cl) { uae_u32 tag = ATC_TAG(addr); - if (cl->tag == (uae_u16)~tag) { -redo: + if (USETAG && cl->tag == (uae_u16)~tag) { + redo: if (cl->hw) { HWput_l(cl->phys + addr, val); return; @@ -757,8 +754,8 @@ redo: uae_u32 REGPARAM2 sfc_get_long(uaecptr addr) { - int super = (regs.sfc & 4) != 0; - int data = (regs.sfc & 3) != 2; + bool super = (regs.sfc & 4) != 0; + bool data = (regs.sfc & 3) != 2; uae_u32 res; if (likely(!is_unaligned(addr, 4))) @@ -798,8 +795,8 @@ uae_u32 REGPARAM2 sfc_get_long(uaecptr addr) uae_u16 REGPARAM2 sfc_get_word(uaecptr addr) { - int super = (regs.sfc & 4) != 0; - int data = (regs.sfc & 3) != 2; + bool super = (regs.sfc & 4) != 0; + bool data = (regs.sfc & 3) != 2; uae_u16 res; if (likely(!is_unaligned(addr, 2))) @@ -822,16 +819,16 @@ uae_u16 REGPARAM2 sfc_get_word(uaecptr addr) uae_u8 REGPARAM2 sfc_get_byte(uaecptr addr) { - int super = (regs.sfc & 4) != 0; - int data = (regs.sfc & 3) != 2; + bool super = (regs.sfc & 4) != 0; + bool data = (regs.sfc & 3) != 2; return mmu_get_user_byte(addr, super, data, sz_byte); } void REGPARAM2 dfc_put_long(uaecptr addr, uae_u32 val) { - int super = (regs.dfc & 4) != 0; - int data = (regs.dfc & 3) != 2; + bool super = (regs.dfc & 4) != 0; + bool data = (regs.dfc & 3) != 2; SAVE_EXCEPTION; TRY(prb) { @@ -861,8 +858,8 @@ void REGPARAM2 dfc_put_long(uaecptr addr, uae_u32 val) void REGPARAM2 dfc_put_word(uaecptr addr, uae_u16 val) { - int super = (regs.dfc & 4) != 0; - int data = (regs.dfc & 3) != 2; + bool super = (regs.dfc & 4) != 0; + bool data = (regs.dfc & 3) != 2; SAVE_EXCEPTION; TRY(prb) { @@ -870,7 +867,7 @@ void REGPARAM2 dfc_put_word(uaecptr addr, uae_u16 val) mmu_put_user_word(addr, val, super, data, sz_word); else { mmu_put_user_byte(addr, val >> 8, super, data, sz_word); - mmu_put_user_byte(addr + 1, (uae_u8)val, super, data, sz_word); + mmu_put_user_byte(addr + 1, val, super, data, sz_word); } RESTORE_EXCEPTION; } @@ -887,8 +884,8 @@ void REGPARAM2 dfc_put_word(uaecptr addr, uae_u16 val) void REGPARAM2 dfc_put_byte(uaecptr addr, uae_u8 val) { - int super = (regs.dfc & 4) != 0; - int data = (regs.dfc & 3) != 2; + bool super = (regs.dfc & 4) != 0; + bool data = (regs.dfc & 3) != 2; SAVE_EXCEPTION; TRY(prb) { @@ -904,10 +901,11 @@ void REGPARAM2 dfc_put_byte(uaecptr addr, uae_u8 val) void REGPARAM2 mmu_op_real(uae_u32 opcode, uae_u16 extra) { - int super = (regs.dfc & 4) != 0; + bool super = (regs.dfc & 4) != 0; DUNUSED(extra); if ((opcode & 0xFE0) == 0x0500) { - int regno, glob; + bool glob; + int regno; //D(didflush = 0); uae_u32 addr; /* PFLUSH */ @@ -923,8 +921,12 @@ void REGPARAM2 mmu_op_real(uae_u32 opcode, uae_u16 extra) mmu_flush_atc(addr, super, glob); } flush_internals(); +#ifdef USE_JIT + flush_icache(0); +#endif } else if ((opcode & 0x0FD8) == 0x548) { - int write, regno; + bool write; + int regno; uae_u32 addr; regno = opcode & 7; @@ -938,7 +940,7 @@ void REGPARAM2 mmu_op_real(uae_u32 opcode, uae_u16 extra) uae_u32 desc; bool data = (regs.dfc & 3) != 2; - l = &atc_l2[super][ATC_L2_INDEX(addr)]; + l = &atc_l2[super ? 1 : 0][ATC_L2_INDEX(addr)]; desc = mmu_fill_atc_l2(addr, super, data, write, l); if (!(data ? l->valid_data : l->valid_inst)) regs.mmusr = MMU_MMUSR_B; @@ -946,7 +948,7 @@ void REGPARAM2 mmu_op_real(uae_u32 opcode, uae_u16 extra) regs.mmusr = MMU_MMUSR_T | MMU_MMUSR_R; else { regs.mmusr = desc & (~0xfff|MMU_MMUSR_G|MMU_MMUSR_Ux|MMU_MMUSR_S| - MMU_MMUSR_CM|MMU_MMUSR_M|MMU_MMUSR_W); + MMU_MMUSR_CM|MMU_MMUSR_M|MMU_MMUSR_W); regs.mmusr |= MMU_MMUSR_R; } } @@ -959,12 +961,12 @@ void REGPARAM2 mmu_op_real(uae_u32 opcode, uae_u16 extra) op_illg (opcode); } -void REGPARAM2 mmu_flush_atc(uaecptr addr, bool super, bool global) +static void REGPARAM2 mmu_flush_atc(uaecptr addr, bool super, bool global) { struct mmu_atc_line *l; int i, j; - l = atc_l1[super][0][0]; + l = atc_l1[super ? 1 : 0][0][0]; i = ATC_L1_INDEX(addr); for (j = 0; j < 4; j++) { if (global || !l[i].global) @@ -979,7 +981,7 @@ void REGPARAM2 mmu_flush_atc(uaecptr addr, bool super, bool global) l += ATC_L1_SIZE; } } - l = atc_l2[super]; + l = atc_l2[super ? 1 : 0]; i = ATC_L2_INDEX(addr); if (global || !l[i].global) l[i].tag = 0x8000; @@ -990,7 +992,7 @@ void REGPARAM2 mmu_flush_atc(uaecptr addr, bool super, bool global) } } -void REGPARAM2 mmu_flush_atc_all(bool global) +static void REGPARAM2 mmu_flush_atc_all(bool global) { struct mmu_atc_line *l; unsigned int i; @@ -1011,25 +1013,49 @@ void REGPARAM2 mmu_flush_atc_all(bool global) void REGPARAM2 mmu_reset(void) { mmu_flush_atc_all(true); +#if 0 + regs.urp = regs.srp = 0; + regs.itt0 = regs.itt0 = 0; + regs.dtt0 = regs.dtt0 = 0; + regs.mmusr = 0; +#endif } void REGPARAM2 mmu_set_tc(uae_u16 tc) { - // if (regs.tcr == tc) - // return; - // regs.tcr = tc; - +#if 0 + if (regs.tcr == tc) + return; + regs.tcr = tc; +#endif 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)); - write_log (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); } void REGPARAM2 mmu_set_super(bool super) { - current_atc = &atc_l1[super]; + current_atc = &atc_l1[super ? 1 : 0]; } +#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: +*/ diff --git a/custom.cpp b/custom.cpp index 00a9d736..f0444c61 100644 --- a/custom.cpp +++ b/custom.cpp @@ -1923,15 +1923,26 @@ static void record_color_change (int hpos, int regno, unsigned long value) if (regno < 0x1000 && hpos < HBLANK_OFFSET && !(beamcon0 & 0x80) && prev_lineno >= 0) { struct draw_info *pdip = curr_drawinfo + prev_lineno; int idx = pdip->last_color_change; + bool lastsync = false; /* Move color changes in horizontal cycles 0 to HBLANK_OFFSET to end of previous line. * Cycles 0 to HBLANK_OFFSET are visible in right border on real Amigas. (because of late hsync) */ + if (curr_color_changes[idx - 1].regno == 0xffff) { + idx--; + lastsync = true; + } pdip->last_color_change++; pdip->nr_color_changes++; curr_color_changes[idx].linepos = (hpos + maxhpos) * 2; curr_color_changes[idx].regno = regno; curr_color_changes[idx].value = value; - curr_color_changes[idx + 1].regno = -1; + if (lastsync) { + curr_color_changes[idx + 1].linepos = hsyncstartpos * 2; + curr_color_changes[idx + 1].regno = 0xffff; + curr_color_changes[idx + 2].regno = -1; + } else { + curr_color_changes[idx + 1].regno = -1; + } } record_color_change2 (hpos, regno, value); diff --git a/gencpu.cpp b/gencpu.cpp index 93073ffe..003d4c69 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -2117,30 +2117,26 @@ static void gen_opcode (unsigned long int opcode) printf ("\t\tuae_s16 sr = %s (a);\n", srcw); printf ("\t\tuae_s32 pc = %s (a + 2);\n", srcl); printf ("\t\tuae_s16 format = %s (a + 2 + 4);\n", srcw); + printf ("\t\tint frame = format >> 12;\n"); printf ("\t\tint offset = 8;\n"); -#if 0 - genamode (Aipi, "7", sz_word, "sr", 1, 0, 0); - genamode (Aipi, "7", sz_long, "pc", 1, 0, 0); - genamode (Aipi, "7", sz_word, "format", 1, 0, 0); -#endif printf ("\t\tnewsr = sr; newpc = pc;\n"); - printf ("\t\tif ((format & 0xF000) == 0x0000) { m68k_areg (regs, 7) += offset; break; }\n"); - printf ("\t\telse if ((format & 0xF000) == 0x1000) { m68k_areg (regs, 7) += offset; }\n"); - printf ("\t\telse if ((format & 0xF000) == 0x2000) { m68k_areg (regs, 7) += offset + 4; break; }\n"); - printf ("\t\telse if ((format & 0xF000) == 0x4000) { m68k_areg (regs, 7) += offset + 8; break; }\n"); - printf ("\t\telse if ((format & 0xF000) == 0x8000) { m68k_areg (regs, 7) += offset + 50; break; }\n"); + printf ("\t\tif (frame == 0x0) { m68k_areg (regs, 7) += offset; break; }\n"); + printf ("\t\telse if (frame == 0x1) { m68k_areg (regs, 7) += offset; }\n"); + printf ("\t\telse if (frame == 0x2) { m68k_areg (regs, 7) += offset + 4; break; }\n"); + printf ("\t\telse if (frame == 0x4) { m68k_areg (regs, 7) += offset + 8; break; }\n"); if (using_mmu) - printf ("\t\telse if ((format & 0xF000) == 0x7000) { m68k_do_rte_mmu (a); m68k_areg (regs, 7) += offset + 52; break; }\n"); - printf ("\t\telse if ((format & 0xF000) == 0x9000) { m68k_areg (regs, 7) += offset + 12; break; }\n"); - printf ("\t\telse if ((format & 0xF000) == 0xa000) { m68k_areg (regs, 7) += offset + 24; break; }\n"); - printf ("\t\telse if ((format & 0xF000) == 0xb000) { m68k_areg (regs, 7) += offset + 84; break; }\n"); + printf ("\t\telse if (frame == 0x7) { m68k_do_rte_mmu (a); m68k_areg (regs, 7) += offset + 52; break; }\n"); + printf ("\t\telse if (frame == 0x8) { m68k_areg (regs, 7) += offset + 50; break; }\n"); + printf ("\t\telse if (frame == 0x9) { m68k_areg (regs, 7) += offset + 12; break; }\n"); + printf ("\t\telse if (frame == 0xa) { m68k_areg (regs, 7) += offset + 24; break; }\n"); + printf ("\t\telse if (frame == 0xb) { m68k_areg (regs, 7) += offset + 84; break; }\n"); printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception (14, 0); goto %s; }\n", endlabelstr); printf ("\t\tregs.sr = newsr; MakeFromSR ();\n}\n"); pop_braces (old_brace_level); printf ("\tregs.sr = newsr; MakeFromSR ();\n"); printf ("\tif (newpc & 1) {\n"); - printf ("\t\texception3 (0x%04X, m68k_getpc (), newpc);\n", opcode); - printf ("\t\t goto %s;\n", endlabelstr); + printf ("\t\texception3i (0x%04X, m68k_getpc (), newpc);\n", opcode); + printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t}\n"); printf ("\t\tm68k_setpc (newpc);\n"); printf ("\tipl_fetch ();\n"); @@ -2155,17 +2151,20 @@ static void gen_opcode (unsigned long int opcode) genamode (curi->smode, "srcreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0); genamode (Aipi, "7", sz_long, "pc", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0); printf ("\tm68k_areg(regs, 7) += offs;\n"); - setpc ("pc"); } else { genamode (Aipi, "7", sz_long, "pc", 1, 0, 0); genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0, 0); printf ("\tm68k_areg (regs, 7) += offs;\n"); printf ("\tif (pc & 1) {\n"); - printf ("\t\texception3 (0x%04X, m68k_getpc (), pc);\n", opcode); + printf ("\t\texception3i (0x%04X, m68k_getpc (), pc);\n", opcode); printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t}\n"); - setpc ("pc"); } + printf ("\tif (pc & 1) {\n"); + printf ("\t\texception3i (0x%04X, m68k_getpc(), pc);\n", opcode); + printf ("\t\tgoto %s;\n", endlabelstr); + printf ("\t}\n"); + setpc ("pc"); /* PC is set and prefetch filled. */ m68k_pc_offset = 0; fill_prefetch_full (); @@ -2222,7 +2221,7 @@ static void gen_opcode (unsigned long int opcode) printf ("\tif (m68k_getpc () & 1) {\n"); printf ("\t\tuaecptr faultpc = m68k_getpc ();\n"); printf ("\t\tm68k_setpc (pc);\n"); - printf ("\t\texception3 (0x%04X, pc, faultpc);\n", opcode); + printf ("\t\texception3i (0x%04X, pc, faultpc);\n", opcode); printf ("\t\tgoto %s;\n", endlabelstr); printf ("\t}\n"); count_read += 2; diff --git a/include/cpummu.h b/include/cpummu.h index 13c65f6d..13760e49 100644 --- a/include/cpummu.h +++ b/include/cpummu.h @@ -30,8 +30,6 @@ #define FULLMMU #endif -#define ALWAYS_INLINE __forceinline -#define bool int #define DUNUSED(x) #define D #if DEBUG @@ -39,18 +37,24 @@ #else #define bug #endif -#define MMUEX 0x4d4d5520 -#define TRY(x) __try -#define CATCH(x) __except(GetExceptionCode() == MMUEX) -#define THROW(x) RaiseException(MMUEX,EXCEPTION_NONCONTINUABLE,0,NULL) -#define THROW_AGAIN(x) THROW(x) + +struct m68k_exception { + int prb; + m68k_exception (int exc) : prb (exc) {} + operator int() { return prb; } +}; #define SAVE_EXCEPTION #define RESTORE_EXCEPTION -#define true 1 -#define false 0 +#define TRY(var) try +#define CATCH(var) catch(m68k_exception var) +#define THROW(n) throw m68k_exception(n) +#define THROW_AGAIN(var) throw +#define VOLATILE +#define ALWAYS_INLINE __inline + #define likely(x) x #define unlikely(x) x -static ALWAYS_INLINE void flush_internals (void) { } +static __inline void flush_internals (void) { } typedef uae_u8 flagtype; @@ -231,43 +235,43 @@ extern struct mmu_atc_line atc_l2[2][ATC_L2_SIZE]; * the data and write arguments are constant in the common, * thus allows gcc to generate a constant offset. */ -static ALWAYS_INLINE int mmu_lookup(uaecptr addr, bool data, bool write, +static ALWAYS_INLINE bool mmu_lookup(uaecptr addr, bool data, bool write, struct mmu_atc_line **cl) { addr >>= 12; - *cl = &(*current_atc)[data][write][addr % ATC_L1_SIZE]; + *cl = &(*current_atc)[data ? 1 : 0][write ? 1 : 0][addr % ATC_L1_SIZE]; return (*cl)->tag == addr >> (ATC_TAG_SHIFT - 12); } /* * similiar to mmu_user_lookup, but for the use of the moves instruction */ -static ALWAYS_INLINE int mmu_user_lookup(uaecptr addr, bool super, bool data, +static ALWAYS_INLINE bool mmu_user_lookup(uaecptr addr, bool super, bool data, bool write, struct mmu_atc_line **cl) { addr >>= 12; - *cl = &atc_l1[super][data][write][addr % ATC_L1_SIZE]; + *cl = &atc_l1[super ? 1 : 0][data ? 1 : 0][write ? 1 : 0][addr % ATC_L1_SIZE]; return (*cl)->tag == addr >> (ATC_TAG_SHIFT - 12); } -extern uae_u16 REGPARAM3 mmu_get_word_unaligned(uaecptr addr, int data) REGPARAM; -extern uae_u32 REGPARAM3 mmu_get_long_unaligned(uaecptr addr, int data) REGPARAM; +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 uae_u8 REGPARAM3 mmu_get_byte_slow(uaecptr addr, int super, int data, +extern uae_u8 REGPARAM3 mmu_get_byte_slow(uaecptr addr, bool super, bool data, int size, struct mmu_atc_line *cl) REGPARAM; -extern uae_u16 REGPARAM3 mmu_get_word_slow(uaecptr addr, int super, int data, +extern uae_u16 REGPARAM3 mmu_get_word_slow(uaecptr addr, bool super, bool data, int size, struct mmu_atc_line *cl) REGPARAM; -extern uae_u32 REGPARAM3 mmu_get_long_slow(uaecptr addr, int super, int data, +extern uae_u32 REGPARAM3 mmu_get_long_slow(uaecptr addr, bool super, bool data, int size, struct mmu_atc_line *cl) REGPARAM; -extern void REGPARAM3 mmu_put_word_unaligned(uaecptr addr, uae_u16 val, int data) REGPARAM; -extern void REGPARAM3 mmu_put_long_unaligned(uaecptr addr, uae_u32 val, int data) 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_byte_slow(uaecptr addr, uae_u8 val, int super, int data, +extern void REGPARAM3 mmu_put_byte_slow(uaecptr addr, uae_u8 val, bool super, bool data, int size, struct mmu_atc_line *cl) REGPARAM; -extern void REGPARAM3 mmu_put_word_slow(uaecptr addr, uae_u16 val, int super, int data, +extern void REGPARAM3 mmu_put_word_slow(uaecptr addr, uae_u16 val, bool super, bool data, int size, struct mmu_atc_line *cl) REGPARAM; -extern void REGPARAM3 mmu_put_long_slow(uaecptr addr, uae_u32 val, int super, int data, +extern void REGPARAM3 mmu_put_long_slow(uaecptr addr, uae_u32 val, bool super, bool data, int size, struct mmu_atc_line *cl) REGPARAM; extern void mmu_make_transparent_region(uaecptr baseaddr, uae_u32 size, int datamode); @@ -275,7 +279,7 @@ extern void mmu_make_transparent_region(uaecptr baseaddr, uae_u32 size, int data #define FC_DATA (regs.s ? 5 : 1) #define FC_INST (regs.s ? 6 : 2) -extern uaecptr REGPARAM3 mmu_translate(uaecptr addr, int super, int data, int write) REGPARAM; +extern uaecptr REGPARAM3 mmu_translate(uaecptr addr, bool super, bool data, bool write) REGPARAM; extern uae_u32 REGPARAM3 sfc_get_long(uaecptr addr) REGPARAM; extern uae_u16 REGPARAM3 sfc_get_word(uaecptr addr) REGPARAM; @@ -328,116 +332,116 @@ static ALWAYS_INLINE uae_u32 phys_get_byte(uaecptr addr) return byteget (addr); } -static ALWAYS_INLINE uae_u32 mmu_get_long(uaecptr addr, int data, int size) +static ALWAYS_INLINE uae_u32 mmu_get_long(uaecptr addr, bool data, int size) { struct mmu_atc_line *cl; - if (likely(mmu_lookup(addr, data, 0, &cl))) + 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, data, size, cl); + return mmu_get_long_slow(addr, regs.s != 0, data, size, cl); } -static ALWAYS_INLINE uae_u16 mmu_get_word(uaecptr addr, int data, int size) +static ALWAYS_INLINE uae_u16 mmu_get_word(uaecptr addr, bool data, int size) { struct mmu_atc_line *cl; - if (likely(mmu_lookup(addr, data, 0, &cl))) + 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, data, size, cl); + return mmu_get_word_slow(addr, regs.s != 0, data, size, cl); } -static ALWAYS_INLINE uae_u8 mmu_get_byte(uaecptr addr, int data, int size) +static ALWAYS_INLINE uae_u8 mmu_get_byte(uaecptr addr, bool data, int size) { struct mmu_atc_line *cl; - if (likely(mmu_lookup(addr, data, 0, &cl))) + 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, data, size, cl); + return mmu_get_byte_slow(addr, regs.s != 0, data, size, cl); } -static ALWAYS_INLINE void mmu_put_long(uaecptr addr, uae_u32 val, int data, int size) +static ALWAYS_INLINE void mmu_put_long(uaecptr addr, uae_u32 val, bool data, int size) { struct mmu_atc_line *cl; - if (likely(mmu_lookup(addr, data, 1, &cl))) + 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, data, size, cl); + mmu_put_long_slow(addr, val, regs.s != 0, data, size, cl); } -static ALWAYS_INLINE void mmu_put_word(uaecptr addr, uae_u16 val, int data, int size) +static ALWAYS_INLINE void mmu_put_word(uaecptr addr, uae_u16 val, bool data, int size) { struct mmu_atc_line *cl; - if (likely(mmu_lookup(addr, data, 1, &cl))) + 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, data, size, cl); + mmu_put_word_slow(addr, val, regs.s != 0, data, size, cl); } -static ALWAYS_INLINE void mmu_put_byte(uaecptr addr, uae_u8 val, int data, int size) +static ALWAYS_INLINE void mmu_put_byte(uaecptr addr, uae_u8 val, bool data, int size) { struct mmu_atc_line *cl; - if (likely(mmu_lookup(addr, data, 1, &cl))) + 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, data, size, cl); + mmu_put_byte_slow(addr, val, regs.s != 0, data, size, cl); } -static ALWAYS_INLINE uae_u32 mmu_get_user_long(uaecptr addr, int super, int data, int size) +static ALWAYS_INLINE uae_u32 mmu_get_user_long(uaecptr addr, bool super, bool data, int size) { struct mmu_atc_line *cl; - if (likely(mmu_user_lookup(addr, super, data, 0, &cl))) + if (likely(mmu_user_lookup(addr, super, data, false, &cl))) return phys_get_long(mmu_get_real_address(addr, cl)); return mmu_get_long_slow(addr, super, data, size, cl); } -static ALWAYS_INLINE uae_u16 mmu_get_user_word(uaecptr addr, int super, int data, int size) +static ALWAYS_INLINE uae_u16 mmu_get_user_word(uaecptr addr, bool super, bool data, int size) { struct mmu_atc_line *cl; - if (likely(mmu_user_lookup(addr, super, data, 0, &cl))) + if (likely(mmu_user_lookup(addr, super, data, false, &cl))) return phys_get_word(mmu_get_real_address(addr, cl)); return mmu_get_word_slow(addr, super, data, size, cl); } -static ALWAYS_INLINE uae_u8 mmu_get_user_byte(uaecptr addr, int super, int data, int size) +static ALWAYS_INLINE uae_u8 mmu_get_user_byte(uaecptr addr, bool super, bool data, int size) { struct mmu_atc_line *cl; - if (likely(mmu_user_lookup(addr, super, data, 0, &cl))) + if (likely(mmu_user_lookup(addr, super, data, false, &cl))) return phys_get_byte(mmu_get_real_address(addr, cl)); return mmu_get_byte_slow(addr, super, data, size, cl); } -static ALWAYS_INLINE void mmu_put_user_long(uaecptr addr, uae_u32 val, int super, int data, int size) +static ALWAYS_INLINE void mmu_put_user_long(uaecptr addr, uae_u32 val, bool super, bool data, int size) { struct mmu_atc_line *cl; - if (likely(mmu_user_lookup(addr, super, data, 1, &cl))) + 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); } -static ALWAYS_INLINE void mmu_put_user_word(uaecptr addr, uae_u16 val, int super, int data, int size) +static ALWAYS_INLINE void mmu_put_user_word(uaecptr addr, uae_u16 val, bool super, bool data, int size) { struct mmu_atc_line *cl; - if (likely(mmu_user_lookup(addr, super, data, 1, &cl))) + 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); } -static ALWAYS_INLINE void mmu_put_user_byte(uaecptr addr, uae_u8 val, int super, int data, int size) +static ALWAYS_INLINE void mmu_put_user_byte(uaecptr addr, uae_u8 val, bool super, bool data, int size) { struct mmu_atc_line *cl; - if (likely(mmu_user_lookup(addr, super, data, 1, &cl))) + 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); @@ -472,52 +476,52 @@ static ALWAYS_INLINE uae_u32 HWget_b(uaecptr addr) static ALWAYS_INLINE uae_u32 uae_mmu_get_ilong(uaecptr addr) { if (unlikely(is_unaligned(addr, 4))) - return mmu_get_long_unaligned(addr, 0); - return mmu_get_long(addr, 0, sz_long); + return mmu_get_long_unaligned(addr, false); + return mmu_get_long(addr, false, sz_long); } static ALWAYS_INLINE uae_u16 uae_mmu_get_iword(uaecptr addr) { if (unlikely(is_unaligned(addr, 2))) - return mmu_get_word_unaligned(addr, 0); - return mmu_get_word(addr, 0, sz_word); + return mmu_get_word_unaligned(addr, false); + return mmu_get_word(addr, false, sz_word); } static ALWAYS_INLINE uae_u16 uae_mmu_get_ibyte(uaecptr addr) { - return mmu_get_byte(addr, 0, sz_byte); + return mmu_get_byte(addr, false, sz_byte); } static ALWAYS_INLINE uae_u32 uae_mmu_get_long(uaecptr addr) { if (unlikely(is_unaligned(addr, 4))) - return mmu_get_long_unaligned(addr, 1); - return mmu_get_long(addr, 1, sz_long); + return mmu_get_long_unaligned(addr, true); + return mmu_get_long(addr, true, sz_long); } static ALWAYS_INLINE uae_u16 uae_mmu_get_word(uaecptr addr) { if (unlikely(is_unaligned(addr, 2))) - return mmu_get_word_unaligned(addr, 1); - return mmu_get_word(addr, 1, sz_word); + return mmu_get_word_unaligned(addr, true); + return mmu_get_word(addr, true, sz_word); } static ALWAYS_INLINE uae_u8 uae_mmu_get_byte(uaecptr addr) { - return mmu_get_byte(addr, 1, sz_byte); + return mmu_get_byte(addr, true, sz_byte); } static ALWAYS_INLINE void uae_mmu_put_long(uaecptr addr, uae_u32 val) { if (unlikely(is_unaligned(addr, 4))) - mmu_put_long_unaligned(addr, val, 1); + mmu_put_long_unaligned(addr, val, true); else - mmu_put_long(addr, val, 1, sz_long); + mmu_put_long(addr, val, true, sz_long); } static ALWAYS_INLINE void uae_mmu_put_word(uaecptr addr, uae_u16 val) { if (unlikely(is_unaligned(addr, 2))) - mmu_put_word_unaligned(addr, val, 1); + mmu_put_word_unaligned(addr, val, true); else - mmu_put_word(addr, val, 1, sz_word); + mmu_put_word(addr, val, true, sz_word); } static ALWAYS_INLINE void uae_mmu_put_byte(uaecptr addr, uae_u8 val) { - mmu_put_byte(addr, val, 1, sz_byte); + mmu_put_byte(addr, val, true, sz_byte); } STATIC_INLINE void put_byte_mmu (uaecptr addr, uae_u32 v) diff --git a/include/zfile.h b/include/zfile.h index 08602c8e..72148ff9 100644 --- a/include/zfile.h +++ b/include/zfile.h @@ -103,7 +103,7 @@ extern const TCHAR *uae_diskimageextensions[]; extern struct zvolume *zfile_fopen_archive (const TCHAR *filename); extern struct zvolume *zfile_fopen_archive (const TCHAR *filename, int flags); -extern struct zvolume *zfile_fopen_archive_root (const TCHAR *filename); +extern struct zvolume *zfile_fopen_archive_root (const TCHAR *filename, int flags); extern void zfile_fclose_archive (struct zvolume *zv); extern int zfile_fs_usage_archive (const TCHAR *path, const TCHAR *disk, struct fs_usage *fsp); extern int zfile_stat_archive (const TCHAR *path, struct _stat64 *statbuf); diff --git a/newcpu.cpp b/newcpu.cpp index 8cffb837..bb2e23b2 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -402,7 +402,7 @@ static void build_cpufunctbl (void) if (currprefs.mmu_model) { mmu_reset (); mmu_set_tc (regs.tcr); - mmu_set_super (regs.s); + mmu_set_super (regs.s != 0); } } @@ -1243,7 +1243,7 @@ void REGPARAM2 MakeFromSR (void) } } if (currprefs.mmu_model) - mmu_set_super (regs.s); + mmu_set_super (regs.s != 0); doint (); if (regs.t1 || regs.t0) @@ -1590,7 +1590,7 @@ static void Exception_normal (int nr, uaecptr oldpc) m68k_areg (regs, 7) = regs.isp; regs.s = 1; if (currprefs.mmu_model) - mmu_set_super (regs.s); + mmu_set_super (regs.s != 0); } if (currprefs.cpu_model > 68000) { if (nr == 2 || nr == 3) { @@ -2271,7 +2271,7 @@ void m68k_reset (int hardreset) if (currprefs.mmu_model) { mmu_reset (); mmu_set_tc (regs.tcr); - mmu_set_super (regs.s); + mmu_set_super (regs.s != 0); } a3000_fakekick (0); @@ -3050,6 +3050,29 @@ retry: TRY (prb) { for (;;) { pc = regs.fault_pc = m68k_getpc (); +#if 0 + static int done; + if (pc == 0x16AF94) { + write_log (L"D0=%d A7=%08x\n", regs.regs[0], regs.regs[15]); + if (regs.regs[0] == 360) { + done = 1; + activate_debugger (); + } + } + if (pc == 0x16B01A) { + write_log (L"-> ERR\n"); + } + if (pc == 0x16B018) { + write_log (L"->\n"); + } + if (pc == 0x17967C || pc == 0x13b5e2 - 4) { + if (done) { + write_log (L"*\n"); + mmu_dump_tables (); + activate_debugger (); + } + } +#endif opcode = x_prefetch (0); count_instr (opcode); do_cycles (cpu_cycles); @@ -3087,10 +3110,15 @@ retry: } //activate_debugger (); TRY (prb2) { - Exception (2, regs.fault_pc); + Exception (prb, regs.fault_pc); } CATCH (prb2) { write_log (L"MMU: double bus error, rebooting..\n"); + regs.tcr = 0; + m68k_reset (0); + m68k_setpc (0xf80002); + mmu_reset (); uae_reset (1); + return; } goto retry; } @@ -4409,7 +4437,7 @@ STATIC_INLINE void fill_icache030 (uae_u32 addr, int idx) STATIC_INLINE bool cancache030 (uaecptr addr) { - return ce_cachable[addr >> 16]; + return ce_cachable[addr >> 16] != 0; } // and finally the worst part, 68030 data cache.. diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index f92f3507..92f9ec55 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -2011,7 +2011,7 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth t_depth ); - if ((d3dCaps.PixelShaderVersion < D3DPS_VERSION(3,0) || d3dCaps.VertexShaderVersion < D3DVS_VERSION(3,0) || !psEnabled || max_texture_w < 4096 || max_texture_h < 4096 || !shaderon) && d3d_ex) { + if ((d3dCaps.PixelShaderVersion < D3DPS_VERSION(2,0) || !psEnabled || max_texture_w < 2048 || max_texture_h < 2048 || !shaderon) && d3d_ex) { D3DEX = 0; write_log (L"Disabling D3D9Ex\n"); return D3D_init (ahwnd, w_w, w_h, t_w, t_h, depth, mult); diff --git a/od-win32/hardfile_win32.cpp b/od-win32/hardfile_win32.cpp index b7625154..af55625d 100644 --- a/od-win32/hardfile_win32.cpp +++ b/od-win32/hardfile_win32.cpp @@ -507,6 +507,10 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname) goto end; low &= ~(hfd->blocksize - 1); hfd->physsize = hfd->virtsize = ((uae_u64)high2 << 32) | low; + if (hfd->physsize < hfd->blocksize || hfd->physsize == 0) { + write_log (L"HDF '%s' is too small\n", name); + goto end; + } hfd->handle_valid = HDF_HANDLE_WIN32; if (hfd->physsize < 64 * 1024 * 1024 && zmode) { write_log (L"HDF '%s' re-opened in zfile-mode\n", name); diff --git a/od-win32/mman.cpp b/od-win32/mman.cpp index b237f9fc..0375c2f7 100644 --- a/od-win32/mman.cpp +++ b/od-win32/mman.cpp @@ -522,6 +522,9 @@ void *shmat (int shmid, void *shmaddr, int shmflg) if (shmaddr) virtualfreewithlock (shmaddr, size, MEM_DECOMMIT); result = virtualallocwithlock (shmaddr, size, MEM_COMMIT, protect); + if (result == NULL) + virtualfreewithlock (shmaddr, 0, MEM_DECOMMIT); + result = virtualallocwithlock (shmaddr, size, MEM_COMMIT, protect); if (result == NULL) { result = (void*)-1; write_log (L"VirtualAlloc %08X - %08X %x (%dk) failed %d\n", diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index be133cc3..a30d0971 100644 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -523,6 +523,7 @@ END IDD_HARDFILE DIALOGEX 0, 0, 299, 249 STYLE DS_LOCALEDIT | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER | DS_CENTERMOUSE | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_ACCEPTFILES CAPTION "Hardfile Settings" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN diff --git a/od-win32/win32.h b/od-win32/win32.h index f037abaf..404b18a9 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -18,8 +18,8 @@ #define WINUAEPUBLICBETA 1 #define LANG_DLL 1 -#define WINUAEBETA L"16" -#define WINUAEDATE MAKEBD(2010, 9, 9) +#define WINUAEBETA L"17" +#define WINUAEDATE MAKEBD(2010, 9, 12) #define WINUAEEXTRA L"" #define WINUAEREV L"" diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index b1ac7c5f..9ad4a43c 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -168,6 +168,8 @@ static HWND pages[MAX_C_PAGES]; #define MAX_IMAGETOOLTIPS 10 static HWND guiDlg, panelDlg, ToolTipHWND; static HACCEL hAccelTable; +static HWND customDlg; +static int customDlgType; struct ToolTipHWNDS { WNDPROC proc; HWND hwnd; @@ -8788,6 +8790,10 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam TCHAR tmp[MAX_DPATH]; switch (msg) { + case WM_DROPFILES: + dragdrop (hDlg, (HDROP)wParam, &changed_prefs, -1); + return FALSE; + case WM_INITDIALOG: recursive++; inithardfile (hDlg); @@ -8796,6 +8802,8 @@ static INT_PTR CALLBACK HardfileSettingsProc (HWND hDlg, UINT msg, WPARAM wParam updatehdfinfo (hDlg, 1); setac (hDlg, IDC_PATH_NAME); recursive--; + customDlgType = IDD_HARDFILE; + customDlg = hDlg; return TRUE; case WM_CONTEXTMENU: @@ -12279,7 +12287,6 @@ static void values_to_hw3ddlg (HWND hDlg) int overlaytype = SendDlgItemMessage (hDlg, IDC_FILTEROVERLAYTYPE, CB_GETCURSEL, 0, 0L); if (workprefs.gfx_api && D3D_goodenough ()) { WIN32GUI_LoadUIString (IDS_NONE, tmp, MAX_DPATH); - SendDlgItemMessage (hDlg, IDC_FILTERMODE, CB_ADDSTRING, 0, (LPARAM)tmp); SendDlgItemMessage (hDlg, IDC_FILTEROVERLAY, CB_ADDSTRING, 0, (LPARAM)tmp); SendDlgItemMessage (hDlg, IDC_FILTEROVERLAY, CB_SETCURSEL, 0, 0); HANDLE h; @@ -13658,6 +13665,13 @@ int dragdrop (HWND hDlg, HDROP hd, struct uae_prefs *prefs, int currentpage) } } + if (customDlgType == IDD_HARDFILE) { + _tcscpy (current_hfdlg.filename, file); + SetDlgItemText (hDlg, IDC_PATH_NAME, current_hfdlg.filename); + updatehdfinfo (customDlg, 1); + continue; + } + if (drvdrag) { type = ZFILE_DISKIMAGE; } else if (zip || harddrive) { @@ -13945,6 +13959,8 @@ INT_PTR CustomDialogBox (int templ, HWND hDlg, DLGPROC proc) h = DialogBoxIndirect (r->inst, r->resource, hDlg, proc); freescaleresource (r); } + customDlgType = 0; + customDlg = NULL; freescaleresource (res); return h; } diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 9fd04a23..1ed3fe6f 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,16 @@ +- removed duplicate "none" in filter list +- RTD also missed address error check +- MMU emulation bus error handler uses C++ exceptions again (like in original Aranym version), + removed some not so useful forced inlining, smaller executable. +- decided to disable some MMU table caching and suddenly NetBSD crash disappeared, MMU emulation + is probably much slower now but at least it seems to work until proper fix is found, + (hopefully Aranym developers have some ideas) Debian 68k Sarge Linux confirmed working now +- right border color "glitch" when waiting for hpos<7 in copper list broke in b3 +- only disable Direct3D9Ex if pixel shader support is < 2.0 +- do not open files smaller than blocksize (512 bytes) as a hardfile +- hardfile dialog accepts dragged and dropped files + Beta 16: - removed old audio hack that was left accidentally, not needed since DMAL was emulated diff --git a/uaeunp.cpp b/uaeunp.cpp index 8d33ab2e..10e6697d 100644 --- a/uaeunp.cpp +++ b/uaeunp.cpp @@ -209,7 +209,7 @@ static int unlist2 (struct arcdir *adp, const TCHAR *src, int all) TCHAR fn[MAX_DPATH]; struct arcdir *ad; - zv = zfile_fopen_archive_root (src); + zv = zfile_fopen_archive_root (src, ZFD_ALL); if (zv == NULL) { geterror(); _tprintf (L"Couldn't open archive '%s'\n", src); @@ -377,7 +377,7 @@ static int unpack (const TCHAR *src, const TCHAR *filename, const TCHAR *dst, in TCHAR fn[MAX_DPATH]; ret = 0; - zv = zfile_fopen_archive_root (src); + zv = zfile_fopen_archive_root (src, ZFD_ALL | ZFD_NORECURSE); if (zv == NULL) { geterror(); _tprintf (L"Couldn't open archive '%s'\n", src); @@ -421,7 +421,7 @@ static int unpack (const TCHAR *src, const TCHAR *filename, const TCHAR *dst, in return 0; } - s = zfile_open_archive (tmp, 0); + s = zfile_open_archive (tmp, ZFD_ARCHIVE | ZFD_NORECURSE); if (!s) { geterror(); _tprintf (L"Couldn't open '%s' for reading\n", src); @@ -472,7 +472,7 @@ static int unpack2 (const TCHAR *src, const TCHAR *match, int level) TCHAR fn[MAX_DPATH]; ret = 0; - zv = zfile_fopen_archive_root (src); + zv = zfile_fopen_archive_root (src, ZFD_ALL | ZFD_NORECURSE); if (zv == NULL) { geterror(); _tprintf (L"Couldn't open archive '%s'\n", src); @@ -514,7 +514,7 @@ static int unpack2 (const TCHAR *src, const TCHAR *match, int level) } found = 1; dst = fn; - s = zfile_open_archive (tmp, 0); + s = zfile_open_archive (tmp, ZFD_NORECURSE); if (!s) { geterror(); _tprintf (L"Couldn't open '%s' for reading\n", tmp); @@ -554,7 +554,7 @@ static int scanpath (TCHAR *src, TCHAR *outpath) struct zdirectory *h; TCHAR fn[MAX_DPATH]; - zv = zfile_fopen_archive_root (src); + zv = zfile_fopen_archive_root (src, ZFD_ALL | ZFD_NORECURSE); if (zv == NULL) { geterror(); _tprintf (L"Couldn't open archive '%s'\n", src); @@ -722,6 +722,10 @@ int __cdecl wmain (int argc, wchar_t *argv[], wchar_t *envp[]) /* +0.8c: + +- do not extract archives inside archive in recursive extraction mode + 0.8b: - DMS full cylinder 0 BBS ADs skipped when extracting diff --git a/zfile.cpp b/zfile.cpp index 8a6fe81e..57d6012b 100644 --- a/zfile.cpp +++ b/zfile.cpp @@ -2903,7 +2903,7 @@ struct zvolume *zfile_fopen_archive (const TCHAR *filename) return zfile_fopen_archive (filename, ZFD_ALL); } -struct zvolume *zfile_fopen_archive_root (const TCHAR *filename) +struct zvolume *zfile_fopen_archive_root (const TCHAR *filename, int flags) { TCHAR path[MAX_DPATH], *p1, *p2, *lastp; struct zvolume *zv = NULL; @@ -2929,7 +2929,7 @@ struct zvolume *zfile_fopen_archive_root (const TCHAR *filename) *p1 = 0; lastp = p1; if (my_existsfile (p2)) - return zfile_fopen_archive (p2); + return zfile_fopen_archive (p2, flags); num++; } @@ -3039,7 +3039,7 @@ struct zdirectory *zfile_opendir_archive (const TCHAR *path, int flags) } struct zdirectory *zfile_opendir_archive (const TCHAR *path) { - return zfile_opendir_archive (path, ZFD_ALL); + return zfile_opendir_archive (path, ZFD_ALL | ZFD_NORECURSE); } void zfile_closedir_archive (struct zdirectory *zd) {