/*
-* 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)
}
/* 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;
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;
}
#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);
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;
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
+ ));
}
}
}
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;
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;
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) {
}
if ((desc & 1) == 0 || (!super && desc & MMU_MMUSR_S)) {
-fail:
+ fail:
l->valid_data = l->valid_inst = 0;
l->global = 0;
} else {
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)) {
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;
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;
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) {
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;
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;
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);
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);
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);
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) {
}
}
-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) {
}
}
-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;
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;
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;
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)))
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)))
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) {
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) {
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;
}
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) {
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 */
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;
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;
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;
}
}
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)
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;
}
}
-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;
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:
+*/
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);
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");
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 ();
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;
#define FULLMMU
#endif
-#define ALWAYS_INLINE __forceinline
-#define bool int
#define DUNUSED(x)
#define D
#if DEBUG
#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;
* 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);
#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;
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);
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)
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);
if (currprefs.mmu_model) {
mmu_reset ();
mmu_set_tc (regs.tcr);
- mmu_set_super (regs.s);
+ mmu_set_super (regs.s != 0);
}
}
}
}
if (currprefs.mmu_model)
- mmu_set_super (regs.s);
+ mmu_set_super (regs.s != 0);
doint ();
if (regs.t1 || regs.t0)
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) {
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);
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);
}
//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;
}
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..
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);
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);
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",
\r
IDD_HARDFILE DIALOGEX 0, 0, 299, 249\r
STYLE DS_LOCALEDIT | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER | DS_CENTERMOUSE | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU\r
+EXSTYLE WS_EX_ACCEPTFILES\r
CAPTION "Hardfile Settings"\r
FONT 8, "MS Sans Serif", 0, 0, 0x0\r
BEGIN\r
#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""
#define MAX_IMAGETOOLTIPS 10
static HWND guiDlg, panelDlg, ToolTipHWND;
static HACCEL hAccelTable;
+static HWND customDlg;
+static int customDlgType;
struct ToolTipHWNDS {
WNDPROC proc;
HWND hwnd;
TCHAR tmp[MAX_DPATH];
switch (msg) {
+ case WM_DROPFILES:
+ dragdrop (hDlg, (HDROP)wParam, &changed_prefs, -1);
+ return FALSE;
+
case WM_INITDIALOG:
recursive++;
inithardfile (hDlg);
updatehdfinfo (hDlg, 1);
setac (hDlg, IDC_PATH_NAME);
recursive--;
+ customDlgType = IDD_HARDFILE;
+ customDlg = hDlg;
return TRUE;
case WM_CONTEXTMENU:
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;
}
}
+ 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) {
h = DialogBoxIndirect (r->inst, r->resource, hDlg, proc);
freescaleresource (r);
}
+ customDlgType = 0;
+ customDlg = NULL;
freescaleresource (res);
return h;
}
+- 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
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);
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);
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);
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);
}
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);
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);
/*
+0.8c:
+
+- do not extract archives inside archive in recursive extraction mode
+
0.8b:
- DMS full cylinder 0 BBS ADs skipped when extracting
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;
*p1 = 0;
lastp = p1;
if (my_existsfile (p2))
- return zfile_fopen_archive (p2);
+ return zfile_fopen_archive (p2, flags);
num++;
}
}
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)
{