-sun4c_mmu.cpp: Made generic to support sun4 MMU mode, and cleaned up save state usage. [Ryan Holtz]

-sun4.cpp: Various changes: [Ryan Holtz]
 * Split sun4 and sun4c hardware emulation into separate derived classes.
 * Hooked up Sbus IRQs.
 * Removed now-unnecessary duplicate MMU code.

-cgsix.cpp: Added VSync IRQ, cleaned up save state usage, and added THC MISC register. [Ryan Holtz]

-sparc.cpp: Renamed MB86901 to SPARCV7, and added a separate class for SPARCV8. [Ryan Holtz]

-bt45x.cpp: Made logmacro.h usage more consistent. [Ryan Holtz]
This commit is contained in:
mooglyguy 2019-11-18 17:30:38 +01:00 committed by MooglyGuy
parent 0a0d0fd9b0
commit b54cb1804b
15 changed files with 6447 additions and 1462 deletions

View File

@ -2772,21 +2772,20 @@ if (CPUS["ALTO2"]~=null or _OPTIONS["with-tools"]) then
end
------------------------------------------
-- Sun SPARC, Fujitus MB86901 implementation
--@src/devices/cpu/sparc/sparc.h,CPUS["MB86901"] = true
-- Sun SPARCv7, SPARCv8 implementation
--@src/devices/cpu/sparc/sparc.h,CPUS["SPARC"] = true
--------------------------------------------------
if (CPUS["MB86901"]~=null) then
if (CPUS["SPARC"]~=null) then
files {
MAME_DIR .. "src/devices/cpu/sparc/mb86901.cpp",
MAME_DIR .. "src/devices/cpu/sparc/sparcv8ops.ipp",
MAME_DIR .. "src/devices/cpu/sparc/sparc.cpp",
MAME_DIR .. "src/devices/cpu/sparc/sparcdefs.h",
MAME_DIR .. "src/devices/cpu/sparc/sparc_intf.h",
MAME_DIR .. "src/devices/cpu/sparc/sparc.h",
}
end
if (CPUS["MB86901"]~=null or _OPTIONS["with-tools"]) then
if (CPUS["SPARC"]~=null or _OPTIONS["with-tools"]) then
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/sparc/sparcdasm.cpp")
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/sparc/sparcdasm.h")
end

View File

@ -132,7 +132,7 @@ CPUS["E0C6200"] = true
CPUS["MELPS4"] = true
CPUS["HPHYBRID"] = true
CPUS["SM510"] = true
CPUS["MB86901"] = true
CPUS["SPARC"] = true
CPUS["NANOPROCESSOR"] = true
CPUS["CLIPPER"] = true
CPUS["CAPRICORN"] = true

View File

@ -21,6 +21,8 @@ void sbus_cgsix_device::base_map(address_map &map)
map(0x00000000, 0x01ffffff).rw(FUNC(sbus_cgsix_device::unknown_r), FUNC(sbus_cgsix_device::unknown_w));
map(0x00000000, 0x00007fff).r(FUNC(sbus_cgsix_device::rom_r));
map(0x00200000, 0x0020000f).m(m_ramdac, FUNC(bt458_device::map)).umask32(0xff000000);
map(0x00300000, 0x00300fff).rw(FUNC(sbus_cgsix_device::fbc_r), FUNC(sbus_cgsix_device::fbc_w));
map(0x00301818, 0x0030181b).rw(FUNC(sbus_cgsix_device::thc_misc_r), FUNC(sbus_cgsix_device::thc_misc_w));
map(0x003018fc, 0x003018ff).rw(FUNC(sbus_cgsix_device::cursor_address_r), FUNC(sbus_cgsix_device::cursor_address_w));
map(0x00301900, 0x003019ff).rw(FUNC(sbus_cgsix_device::cursor_ram_r), FUNC(sbus_cgsix_device::cursor_ram_w));
map(0x00700000, 0x00700fff).rw(FUNC(sbus_cgsix_device::fbc_r), FUNC(sbus_cgsix_device::fbc_w));
@ -44,6 +46,8 @@ void sbus_cgsix_device::device_start()
m_cursor_ram = std::make_unique<uint32_t[]>(32 * 2);
save_pointer(NAME(m_cursor_ram), 32 * 2);
save_item(NAME(m_fbc.m_config));
save_item(NAME(m_fbc.m_misc));
save_item(NAME(m_fbc.m_clip_check));
save_item(NAME(m_fbc.m_status));
save_item(NAME(m_fbc.m_draw_status));
@ -149,29 +153,20 @@ void sbus_cgsix_device::device_start()
save_item(NAME(m_fbc.m_vertex_count));
for (int i = 0; i < 0x1000; i++)
{
save_item(NAME(m_fbc.m_prim_buf[i].m_absx), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_absy), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_absz), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_relx), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_rely), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_relz), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_r), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_g), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_b), i);
save_item(NAME(m_fbc.m_prim_buf[i].m_a), i);
}
m_fbc.m_prim_buf = std::make_unique<vertex[]>(0x1000); // Unknown size on hardware
save_pointer(NAME(reinterpret_cast<uint8_t*>(m_fbc.m_prim_buf.get())), sizeof(vertex) * 0x1000);
save_item(NAME(m_fbc.m_curr_prim_type));
save_item(NAME(m_thc_misc));
save_item(NAME(m_cursor_x));
save_item(NAME(m_cursor_y));
}
void sbus_cgsix_device::device_reset()
{
memset(&m_fbc, 0, sizeof(m_fbc));
m_fbc.m_vertex_count = 0;
m_thc_misc = 0;
}
uint32_t sbus_cgsix_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
@ -255,7 +250,8 @@ uint8_t sbus_cgsix_device::perform_rasterop(uint8_t src, uint8_t dst, uint8_t ma
const uint8_t s = src & mask;
const uint8_t d = dst & mask;
const uint32_t rop = rops[f | b];
//logerror("f:%d b:%d s:%02x d:%02x rop:%d\n", f >> 1, b, s, d, rop);
//if (fbc_misc_data() == FBC_MISC_DATA_COLOR8)
//logerror("f:%d b:%d s:%02x d:%02x rop:%d\n", f >> 1, b, s, d, rop);
uint8_t value = 0;
switch (rop)
@ -280,17 +276,21 @@ uint8_t sbus_cgsix_device::perform_rasterop(uint8_t src, uint8_t dst, uint8_t ma
}
result |= value & mask;
}
//if (fbc_misc_data() == FBC_MISC_DATA_COLOR8)
//logerror("result: %02x\n", result);
return result;
}
void sbus_cgsix_device::handle_font_poke()
{
if (fbc_misc_draw() != FBC_MISC_DRAW_RENDER)
if (fbc_misc_draw() > FBC_MISC_DRAW_RENDER)
{
logerror("handle_font_poke: Unsupported font draw mode %d, abandoning draw\n", fbc_misc_draw());
return;
}
const bool color8 = (fbc_misc_data() == FBC_MISC_DATA_COLOR8);
uint32_t pixel_mask = fbc_get_pixel_mask();
uint8_t plane_mask = fbc_get_plane_mask();
@ -300,13 +300,20 @@ void sbus_cgsix_device::handle_font_poke()
const int width = (int)m_fbc.m_x1 - (int)m_fbc.m_x0;
const uint32_t font = m_fbc.m_font;
uint32_t x = m_fbc.m_x0;
logerror("Width: %d, bits %d to %d\n", width, 31, 31 - width);
for (int bit = 31; bit >= (31 - width) && x < 1152; bit--, x++)
//logerror("Width: %d, bits %d to %d\n", width, 31, 31 - width);
int step_size = color8 ? 8 : 1;
int start_bit = 32 - step_size;
for (int bit = start_bit; bit >= (start_bit - width * step_size) && x < 1152; bit -= step_size, x++)
{
if (!BIT(pixel_mask, 31 - (x % 32)))
continue;
const uint8_t src = BIT(font, bit) ? 0xff : 0x00;
uint8_t src = 0;
if (color8)
src = (font >> bit) & 0xff;
else
src = BIT(font, bit) ? 0xff : 0x00;
const uint8_t dst = vram[BYTE4_XOR_BE(x)];
vram[BYTE4_XOR_BE(x)]= perform_rasterop(src, dst, plane_mask);
}
@ -351,7 +358,7 @@ uint8_t sbus_cgsix_device::fbc_get_plane_mask()
// NOTE: This is basically untested, and probably full of bugs!
void sbus_cgsix_device::handle_draw_command()
{
if (fbc_misc_draw() != FBC_MISC_DRAW_RENDER)
if (fbc_misc_draw() > FBC_MISC_DRAW_RENDER)
{
logerror("handle_draw_command: Unsupported draw mode %d, abandoning draw\n", fbc_misc_draw());
return;
@ -377,8 +384,8 @@ void sbus_cgsix_device::handle_draw_command()
uint32_t vindex = 0;
while (vindex < m_fbc.m_vertex_count)
{
vertex_t &v0 = m_fbc.m_prim_buf[vindex++];
vertex_t &v1 = m_fbc.m_prim_buf[vindex++];
vertex &v0 = m_fbc.m_prim_buf[vindex++];
vertex &v1 = m_fbc.m_prim_buf[vindex++];
for (uint32_t y = v0.m_absy; y <= v1.m_absy; y++)
{
@ -454,6 +461,12 @@ READ32_MEMBER(sbus_cgsix_device::fbc_r)
uint32_t ret = 0;
switch (offset)
{
case FBC_CONFIG:
{
const uint32_t data = (m_fbc.m_config & FBC_CONFIG_MASK) | FBC_CONFIG_FBID | FBC_CONFIG_VERSION;
logerror("%s: fbc_r: CONFIG (%08x & %08x)\n", machine().describe_context(), data, mem_mask);
return data;
}
case FBC_MISC:
logerror("fbc_r: MISC (%08x & %08x)\n", m_fbc.m_misc, mem_mask);
return m_fbc.m_misc;
@ -780,6 +793,10 @@ WRITE32_MEMBER(sbus_cgsix_device::fbc_w)
switch (offset)
{
case FBC_CONFIG:
COMBINE_DATA(&m_fbc.m_config);
logerror("fbc_w: CONFIG = %08x & %08x)\n", data, mem_mask);
break;
case FBC_MISC:
COMBINE_DATA(&m_fbc.m_misc);
logerror("fbc_w: MISC = %08x & %08x\n", data, mem_mask);
@ -1237,6 +1254,50 @@ WRITE32_MEMBER(sbus_cgsix_device::cursor_ram_w)
COMBINE_DATA(&m_cursor_ram[offset]);
}
READ32_MEMBER(sbus_cgsix_device::thc_misc_r)
{
logerror("thc_misc_r: %08x & %08x\n", m_thc_misc | THC_MISC_REV, mem_mask);
return m_thc_misc | THC_MISC_REV;
}
WRITE32_MEMBER(sbus_cgsix_device::thc_misc_w)
{
logerror("thc_misc_w: %08x & %08x\n", data, mem_mask);
if (BIT(data, THC_MISC_IRQ_BIT) && BIT(m_thc_misc, THC_MISC_IRQ_BIT))
{
data &= ~(1 << THC_MISC_IRQ_BIT);
lower_irq(4);
}
if (BIT(data, THC_MISC_IRQEN_BIT))
{
data &= ~(1 << THC_MISC_IRQ_BIT);
}
COMBINE_DATA(&m_thc_misc);
m_thc_misc &= THC_MISC_WRITE_MASK;
}
WRITE_LINE_MEMBER(sbus_cgsix_device::vblank_w)
{
int old_state = BIT(m_thc_misc, THC_MISC_VSYNC_BIT);
if (old_state != state)
{
if (state)
{
m_thc_misc |= 1 << THC_MISC_VSYNC_BIT;
if (BIT(m_thc_misc, THC_MISC_IRQEN_BIT))
{
m_thc_misc |= 1 << THC_MISC_IRQ_BIT;
raise_irq(4);
}
}
else
{
m_thc_misc &= ~(1 << THC_MISC_VSYNC_BIT);
}
}
}
//-------------------------------------------------
// TurboGX implementation
//-------------------------------------------------
@ -1262,6 +1323,7 @@ void sbus_turbogx_device::device_add_mconfig(machine_config &config)
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_screen_update(FUNC(sbus_turbogx_device::screen_update));
m_screen->set_raw(105.561_MHz_XTAL, 1472, 0, 1152, 943, 0, 900);
m_screen->screen_vblank().set(FUNC(sbus_turbogx_device::vblank_w));
BT458(config, m_ramdac, 0);
}
@ -1303,6 +1365,7 @@ void sbus_turbogxp_device::device_add_mconfig(machine_config &config)
m_screen->set_size(1152, 900);
m_screen->set_visarea(0, 1152-1, 0, 900-1);
m_screen->set_refresh_hz(72);
m_screen->screen_vblank().set(FUNC(sbus_turbogxp_device::vblank_w));
BT467(config, m_ramdac, 0);
}

View File

@ -44,10 +44,13 @@ protected:
DECLARE_WRITE32_MEMBER(vram_w);
DECLARE_READ32_MEMBER(fbc_r);
DECLARE_WRITE32_MEMBER(fbc_w);
DECLARE_READ32_MEMBER(thc_misc_r);
DECLARE_WRITE32_MEMBER(thc_misc_w);
DECLARE_READ32_MEMBER(cursor_address_r);
DECLARE_WRITE32_MEMBER(cursor_address_w);
DECLARE_READ32_MEMBER(cursor_ram_r);
DECLARE_WRITE32_MEMBER(cursor_ram_w);
DECLARE_WRITE_LINE_MEMBER(vblank_w);
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint8_t perform_rasterop(uint8_t src, uint8_t dst, uint8_t mask = 0xff);
@ -77,6 +80,27 @@ protected:
ROP_SET = 0x0f
};
enum
{
THC_MISC_IRQ_BIT = 4,
THC_MISC_IRQEN_BIT = 5,
THC_MISC_CURRES_BIT = 6,
THC_MISC_SYNCEN_BIT = 7,
THC_MISC_VSYNC_BIT = 8,
THC_MISC_SYNC_BIT = 9,
THC_MISC_ENVID_BIT = 10,
THC_MISC_RESET_BIT = 12,
THC_MISC_REV = 0x00010000,
THC_MISC_WRITE_MASK = 0x000014ff
};
enum
{
FBC_CONFIG_FBID = 0x60000000,
FBC_CONFIG_VERSION = 0x00100000,
FBC_CONFIG_MASK = 0x000f3fff
};
enum
{
FBC_MISC_INDEX_SHIFT = 4,
@ -233,6 +257,7 @@ protected:
enum
{
FBC_CONFIG = 0x000/4,
FBC_MISC = 0x004/4,
FBC_CLIP_CHECK = 0x008/4,
@ -339,7 +364,7 @@ protected:
FBC_IRECT_A = 0x93c/4,
};
struct vertex_t
struct vertex
{
uint32_t m_absx;
uint32_t m_absy;
@ -364,8 +389,9 @@ protected:
PRIM_COUNT
};
struct fbc_t
struct fbc
{
uint32_t m_config;
uint32_t m_misc;
uint32_t m_clip_check;
uint32_t m_status;
@ -471,11 +497,12 @@ protected:
uint32_t m_irect_b;
uint32_t m_irect_a;
vertex_t m_prim_buf[0x1000]; // unknown size
std::unique_ptr<vertex[]> m_prim_buf;
uint32_t m_vertex_count;
uint32_t m_curr_prim_type;
};
uint32_t m_thc_misc;
int16_t m_cursor_x;
int16_t m_cursor_y;
@ -485,7 +512,7 @@ protected:
required_device<screen_device> m_screen;
required_device<bt458_device> m_ramdac;
fbc_t m_fbc;
fbc m_fbc;
uint32_t m_vram_size;
};

View File

@ -103,7 +103,7 @@ protected:
virtual void device_start() override;
// internal state
required_device<mb86901_device> m_maincpu;
required_device<sparc_base_device> m_maincpu;
required_device<address_map_bank_device> m_type1space;
address_space *m_space;

File diff suppressed because it is too large Load Diff

View File

@ -12,24 +12,22 @@
#include "sparcdasm.h"
#include "sparc_intf.h"
#define SPARCV8 (1)
#define LOG_FCODES (0)
#if LOG_FCODES
#include <map>
#endif
class mb86901_device : public cpu_device, public sparc_mmu_host_interface, protected sparc_disassembler::config
class sparc_base_device : public cpu_device, public sparc_mmu_host_interface, protected sparc_disassembler::config
{
public:
mb86901_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
sparc_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
template <typename T> void set_mmu(T &&tag) { m_mmu.set_tag(std::forward<T>(tag)); }
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_stop() override;
virtual void device_post_load() override;
virtual void device_resolve_objects() override;
@ -75,11 +73,8 @@ protected:
void execute_rett(uint32_t op);
void execute_saverestore(uint32_t op);
void execute_jmpl(uint32_t op);
#if SPARCV8
void execute_mul(uint32_t op);
void execute_div(uint32_t op);
#endif
inline void execute_group2(uint32_t op);
virtual bool execute_extra_group2(uint32_t op) = 0;
inline void execute_ldd(uint32_t op);
inline void execute_ld(uint32_t op);
@ -102,10 +97,8 @@ protected:
void execute_store(uint32_t op);
void execute_ldstub(uint32_t op);
#if SPARCV8
void execute_swap(uint32_t op);
#endif
inline void execute_group3(uint32_t op);
virtual bool execute_extra_group3(uint32_t op) = 0;
enum set_cc
{
@ -122,12 +115,21 @@ protected:
bool evaluate_condition(uint32_t op);
inline void execute_bicc(uint32_t op);
bool evaluate_fp_condition(uint32_t op);
inline void execute_fbfcc(uint32_t op);
void execute_ticc(uint32_t op);
void select_trap();
void execute_trap();
virtual void update_tt() = 0;
void check_fdiv_zero_exception();
bool check_fp_exceptions();
bool set_fpr32(const uint32_t rd, const uint32_t data);
bool set_fpr64(const uint32_t rd, const uint64_t data);
void complete_instruction_execution(uint32_t op);
inline void dispatch_instruction(uint32_t op);
virtual bool dispatch_extra_instruction(uint32_t op) = 0;
void complete_fp_execution(uint32_t /*op*/);
inline void execute_step();
@ -198,17 +200,11 @@ protected:
bool m_illegal_instruction;
bool m_mem_address_not_aligned;
bool m_fp_disabled;
bool m_cp_disabled;
bool m_fp_exception;
bool m_cp_disabled; // SPARCv8
bool m_cp_exception; // SPARCv8
bool m_unimplemented_FLUSH; // SPARCv8
bool m_r_register_access_error; // SPARCv8
bool m_instruction_access_error; // SPARCv8
bool m_cp_exception;
bool m_instruction_access_exception;
bool m_data_access_error; // SPARCv8
bool m_data_store_error; // SPARCv8
bool m_data_access_exception;
bool m_division_by_zero; // SPARCv8
bool m_trap_instruction;
bool m_window_underflow;
bool m_window_overflow;
@ -221,8 +217,8 @@ protected:
uint8_t m_cp_sequence_err;
// fields separated out from PSR (Processor State Register)
uint8_t m_impl; // implementation (always 0 in MB86901)
uint8_t m_ver; // version (always 0 in MB86901)
uint8_t m_impl; // implementation (always 0 in SPARCv7)
uint8_t m_ver; // version (always 0 in SPARCv7)
uint8_t m_icc; // integer condition codes
bool m_ec; // enable coprocessor
bool m_ef; // enable FPU
@ -269,8 +265,48 @@ protected:
std::function<void (sparc_disassembler *)> m_asi_desc_adder;
};
class sparcv7_device : public sparc_base_device
{
public:
sparcv7_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual bool execute_extra_group2(uint32_t op) override;
virtual bool execute_extra_group3(uint32_t op) override;
virtual bool dispatch_extra_instruction(uint32_t op) override;
virtual void update_tt() override;
};
class sparcv8_device : public sparc_base_device
{
public:
sparcv8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual bool execute_extra_group2(uint32_t op) override;
virtual bool execute_extra_group3(uint32_t op) override;
virtual bool dispatch_extra_instruction(uint32_t op) override;
virtual void update_tt() override;
private:
void execute_mul(uint32_t op);
void execute_div(uint32_t op);
void execute_swap(uint32_t op);
bool m_unimplemented_FLUSH;
bool m_r_register_access_error;
bool m_instruction_access_error;
bool m_data_access_error;
bool m_data_store_error;
bool m_division_by_zero;
};
// device type definition
DECLARE_DEVICE_TYPE(MB86901, mb86901_device)
DECLARE_DEVICE_TYPE(SPARCV7, sparcv7_device)
DECLARE_DEVICE_TYPE(SPARCV8, sparcv8_device)
enum
{
@ -297,6 +333,12 @@ enum
SPARC_S,
SPARC_PS,
SPARC_FSR,
SPARC_F0, SPARC_F1, SPARC_F2, SPARC_F3, SPARC_F4, SPARC_F5, SPARC_F6, SPARC_F7,
SPARC_F8, SPARC_F9, SPARC_F10, SPARC_F11, SPARC_F12, SPARC_F13, SPARC_F14, SPARC_F15,
SPARC_F16, SPARC_F17, SPARC_F18, SPARC_F19, SPARC_F20, SPARC_F21, SPARC_F22, SPARC_F23,
SPARC_F24, SPARC_F25, SPARC_F26, SPARC_F27, SPARC_F28, SPARC_F29, SPARC_F30, SPARC_F31,
SPARC_R0, SPARC_R1, SPARC_R2, SPARC_R3, SPARC_R4, SPARC_R5, SPARC_R6, SPARC_R7, SPARC_R8, SPARC_R9, SPARC_R10, SPARC_R11, SPARC_R12, SPARC_R13, SPARC_R14, SPARC_R15,
SPARC_R16, SPARC_R17, SPARC_R18, SPARC_R19, SPARC_R20, SPARC_R21, SPARC_R22, SPARC_R23, SPARC_R24, SPARC_R25, SPARC_R26, SPARC_R27, SPARC_R28, SPARC_R29, SPARC_R30, SPARC_R31,
SPARC_R32, SPARC_R33, SPARC_R34, SPARC_R35, SPARC_R36, SPARC_R37, SPARC_R38, SPARC_R39, SPARC_R40, SPARC_R41, SPARC_R42, SPARC_R43, SPARC_R44, SPARC_R45, SPARC_R46, SPARC_R47,

View File

@ -9,8 +9,8 @@
#pragma once
#ifndef __MB86901_DEFS_H__
#define __MB86901_DEFS_H__
#ifndef CPU_SPARC_SPARC_DEFS_H
#define CPU_SPARC_SPARC_DEFS_H
#define PSR_CWP_MASK 0x0000001f
#define PSR_ET_SHIFT 5
@ -127,9 +127,12 @@
#define CMASK ((op >> 4) & 7)
#define RD ((op >> 25) & 31)
#define RD_D ((op >> 25) & 30)
#define RDBITS (op & 0x3e000000)
#define RS1 ((op >> 14) & 31)
#define RS1_D ((op >> 14) & 30)
#define RS2 (op & 31)
#define RS2_D (op & 30)
#define FREG(x) m_fpr[(x)]
#define FDREG m_fpr[RD]
@ -386,4 +389,96 @@
#define SDIV (OP3 == OP3_SDIV)
#define SDIVCC (OP3 == OP3_SDIVCC)
#endif // __MB86901_DEFS_H__
#define FSR_CEXC_MASK 0x0000001f
#define FSR_CEXC_NXC 0x00000001
#define FSR_CEXC_DZC 0x00000002
#define FSR_CEXC_UFC 0x00000004
#define FSR_CEXC_OFC 0x00000008
#define FSR_CEXC_NVC 0x00000010
#define FSR_AEXC_SHIFT 5
#define FSR_AEXC_MASK 0x000003e0
#define FSR_AEXC_NXA 0x00000020
#define FSR_AEXC_DZA 0x00000040
#define FSR_AEXC_UFA 0x00000080
#define FSR_AEXC_OFA 0x00000100
#define FSR_AEXC_NVA 0x00000200
#define FSR_FCC_SHIFT 10
#define FSR_FCC_MASK 0x00000c00
#define FSR_FCC_EQ 0x00000000
#define FSR_FCC_LT 0x00000400
#define FSR_FCC_GT 0x00000800
#define FSR_FCC_UO 0x00000c00
#define FSR_QNE 0x00002000
#define FSR_FTT_MASK 0x0001c000
#define FSR_FTT_NONE 0x00000000
#define FSR_FTT_IEEE 0x00004000
#define FSR_FTT_UNFIN 0x00008000
#define FSR_FTT_UNIMP 0x0000c000
#define FSR_FTT_SEQ 0x00010000
#define FSR_VER 0x00020000
#define FSR_NS 0x00400000
#define FSR_TEM_SHIFT 23
#define FSR_TEM_MASK 0x0f800000
#define FSR_TEM_NXM 0x00800000
#define FSR_TEM_DZM 0x01000000
#define FSR_TEM_UFM 0x02000000
#define FSR_TEM_OFM 0x04000000
#define FSR_TEM_NVM 0x08000000
#define FSR_RD_SHIFT 30
#define FSR_RD_MASK 0xc0000000
#define FSR_RD_NEAR 0x00000000
#define FSR_RD_ZERO 0x40000000
#define FSR_RD_UP 0x80000000
#define FSR_RD_DOWN 0xc0000000
#define FSR_RESV_MASK 0x30301000
// FPop1
#define FPOP_FMOVS 0x001
#define FPOP_FNEGS 0x005
#define FPOP_FABSS 0x009
#define FPOP_FSQRTS 0x029
#define FPOP_FSQRTD 0x02a
#define FPOP_FSQRTX 0x02b
#define FPOP_FADDS 0x041
#define FPOP_FADDD 0x042
#define FPOP_FADDX 0x043
#define FPOP_FSUBS 0x045
#define FPOP_FSUBD 0x046
#define FPOP_FSUBX 0x047
#define FPOP_FMULS 0x049
#define FPOP_FMULD 0x04a
#define FPOP_FMULX 0x04b
#define FPOP_FDIVS 0x04d
#define FPOP_FDIVD 0x04e
#define FPOP_FDIVX 0x04f
#define FPOP_FITOS 0x0c4
#define FPOP_FDTOS 0x0c6
#define FPOP_FXTOS 0x0c7
#define FPOP_FITOD 0x0c8
#define FPOP_FSTOD 0x0c9
#define FPOP_FXTOD 0x0cb
#define FPOP_FITOX 0x0cc
#define FPOP_FSTOX 0x0cd
#define FPOP_FDTOX 0x0ce
#define FPOP_FSTOI 0x0d1
#define FPOP_FDTOI 0x0d2
#define FPOP_FXTOI 0x0d3
// FPop2
#define FPOP_FCMPS 0x051
#define FPOP_FCMPD 0x052
#define FPOP_FCMPX 0x053
#define FPOP_FCMPES 0x055
#define FPOP_FCMPED 0x056
#define FPOP_FCMPEX 0x057
#endif // CPU_SPARC_SPARC_DEFS_H

View File

@ -1,293 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
//================================================================
//
// sparcv8ops.ipp - Emulation for SPARCv8-class instructions
//
//================================================================
//-------------------------------------------------
// execute_swap - execute a swap instruction
//-------------------------------------------------
void mb86901_device::execute_swap(uint32_t op)
{
/* The SPARC Instruction Manual: Version 8, page 169, "Appendix C - ISP Descriptions - Atomic Load-Store Unsigned Byte Instructions" (SPARCv8.pdf, pg. 166)
if (SWAP) then (
address <- r[rs1] + (if (i = 0) then r[rs2] else sign_extend(simm13));
addr_space <- (if (S = 0) then 10 else 11)
) else if (SWAPA) then (
if (S = 0) then (
trap <- 1;
privileged_instruction <- 1
) else if (i = 1) then (
trap <- 1;
illegal_instruction <- 1
) else (
address <- r[rs1] + r[rs1];
addr_space <- asi
)
);
next;
if (trap = 0) then (
temp <- r[rd];
while ( (pb_block_ldst_byte = 1) or (pb_block_ldst_word = 1) ) (
{ wait for lock(s) to be lifted }
{ an implementation actually need only block when another SWAP is pending on
the same word in memory as the one addressed by this SWAP, or a LDSTUB is
pending on any byte of the word in memory addressed by this SWAP }
);
next;
pb_block_ldst_word <- 1;
next;
(word, MAE) <- memory_read(addr_space, address);
next;
if (MAE = 1) then (
trap <- 1;
data_access_exception = 1
)
next;
if (trap = 0) then (
MAE <- memory_write(addr_space, address, 1111, temp);
next;
pb_block_ldst_word <- 0;
if (MAE = 1) then ( { MAE = 1 only due to a "non-resumable machine-check error" }
trap <- 1;
data_access_exception <- 1
) else (
if (rd != 0) then r[rd] <- word
)
);
*/
uint32_t address = 0;
uint8_t addr_space = 0;
if (SWAP)
{
address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
addr_space = (IS_USER ? 10 : 11);
}
else if (SWAPA)
{
if (IS_USER)
{
m_trap = 1;
m_privileged_instruction = 1;
}
else if (USEIMM)
{
m_trap = 1;
m_illegal_instruction = 1;
}
else
{
address = RS1REG + RS2REG;
addr_space = ASI;
}
}
uint32_t word = 0;
uint32_t temp = 0;
if (!m_trap)
{
temp = RDREG;
while (m_pb_block_ldst_byte || m_pb_block_ldst_word)
{
// { wait for lock(s) to be lifted }
// { an implementation actually need only block when another SWAP is pending on
// the same word in memory as the one addressed by this SWAP, or a LDSTUB is
// pending on any byte of the word in memory addressed by this SWAP }
}
m_pb_block_ldst_word = 1;
word = read_sized_word(addr_space, address, 4);
if (MAE)
{
m_trap = 1;
m_data_access_exception = 1;
}
}
if (!m_trap)
{
write_sized_word(addr_space, address, temp, 4);
m_pb_block_ldst_word = 0;
if (MAE)
{
m_trap = 1;
m_data_access_exception = 1;
}
else
{
if (RD != 0)
RDREG = word;
}
}
}
//-------------------------------------------------
// execute_mul - execute a multiply opcode
//-------------------------------------------------
void mb86901_device::execute_mul(uint32_t op)
{
/* The SPARC Instruction Manual: Version 8, page 175, "Appendix C - ISP Descriptions - Multiply Instructions" (SPARCv8.pdf, pg. 172)
operand2 := if (i = 0) then r[rs2] else sign_extend(simm13);
if (UMUL or UMULScc) then (Y, result) <- multiply_unsigned(r[rs1], operand2)
else if (SMUL or SMULcc) then (Y, result) <- multiply_signed(r[rs1], operand2)
next;
if (rd != 0) then (
r[rd] <- result;
)
if (UMULcc or SMULcc) then (
N <- result<31>;
Z <- if (result = 0) then 1 else 0;
V <- 0
C <- 0
);
*/
uint32_t operand2 = (USEIMM ? SIMM13 : RS2REG);
uint32_t result = 0;
if (UMUL || UMULCC)
{
uint64_t dresult = (uint64_t)RS1REG * (uint64_t)operand2;
Y = (uint32_t)(dresult >> 32);
result = (uint32_t)dresult;
}
else if (SMUL || SMULCC)
{
int64_t dresult = (int64_t)(int32_t)RS1REG * (int64_t)(int32_t)operand2;
Y = (uint32_t)(dresult >> 32);
result = (uint32_t)dresult;
}
if (RD != 0)
{
RDREG = result;
}
if (UMULCC || SMULCC)
{
CLEAR_ICC;
PSR |= BIT31(result) ? PSR_N_MASK : 0;
PSR |= (result == 0) ? PSR_Z_MASK : 0;
}
}
//-------------------------------------------------
// execute_div - execute a divide opcode
//-------------------------------------------------
void mb86901_device::execute_div(uint32_t op)
{
/* The SPARC Instruction Manual: Version 8, page 176, "Appendix C - ISP Descriptions - Multiply Instructions" (SPARCv8.pdf, pg. 173)
operand2 := if (i = 0) then r[rs2] else sign_extend(simm13);
next;
if (operand2 = 0) then (
trap <- 1;
division_by_zero <- 1
) else (
if (UDIV or UDIVcc) then (
temp_64bit <- divide_unsigned(Y[]r[rs1], operand2);
next;
result <- temp_64bit<31:0>;
temp_V <- if (temp_64bit<63:32> = 0) then 0 else 1;
) else if (SDIV or SDIVcc) then (
temp_64bit <- divide_signed(Y[]r[rs1], operand2);
next;
result <- temp_64bit<31:0>;
temp_V <- if (temp_64bit<63:31> = 0) or
(temp_64bit<63:31> = (2^33 - 1)) ) then 0 else 1;
) ;
next;
if (temp_V) then (
{ result overflowed 32 bits; return largest appropriate integer }
if (UDIV or UDIVcc) then result <- 2^32 - 1;
else if (SDIV or SDIVcc) then (
if (temp_64bit > 0) then result <- 2^31 - 1;
else result <- -2^31
)
);
next;
if (rd != 0) then (
r[rd] <- result
) ;
if (UDIVcc or SDIVcc) then (
N <- result<31>;
Z <- if (result = 0) then 1 else 0;
V <- temp_V;
C <- 0
)
);
*/
uint32_t operand2 = (USEIMM ? SIMM13 : RS2REG);
if (operand2 == 0)
{
m_trap = 1;
m_division_by_zero = 1;
}
else
{
uint32_t result = 0;
bool temp_v = false;
int64_t temp_64bit = 0;
if (UDIV || UDIVCC)
{
temp_64bit = int64_t(uint64_t((uint64_t(Y) << 32) | uint64_t(RS1REG)) / operand2);
result = uint32_t(temp_64bit);
temp_v = ((temp_64bit & 0xffffffff00000000) == 0) ? false : true;
}
else if (SDIV || SDIVCC)
{
temp_64bit = int64_t(int64_t((uint64_t(Y) << 32) | uint64_t(RS1REG)) / operand2);
result = uint32_t(temp_64bit);
uint64_t shifted = uint64_t(temp_64bit) >> 31;
temp_v = (shifted == 0 || shifted == 0x1ffffffff) ? false : true;
}
if (temp_v)
{
if (UDIV || UDIVCC)
{
result = 0xffffffff;
}
else if (SDIV || SDIVCC)
{
if (temp_64bit > 0)
result = 0x7fffffff;
else
result = 0x80000000;
}
}
if (RD != 0)
RDREG = result;
if (UDIVCC || SDIVCC)
{
CLEAR_ICC;
PSR |= BIT31(result) ? PSR_N_MASK : 0;
PSR |= (result == 0) ? PSR_Z_MASK : 0;
PSR |= temp_v ? PSR_V_MASK : 0;
}
}
}

View File

@ -7,7 +7,7 @@
//
//================================================================
void mb86901_device::log_fcodes()
void sparc_base_device::log_fcodes()
{
if (PC != 0xffef0000 && PC != m_ss1_next_entry_point)
return;
@ -57,7 +57,7 @@ void mb86901_device::log_fcodes()
}
}
void mb86901_device::indent()
void sparc_base_device::indent()
{
uint32_t program_depth = (0xffeff000 - (REG(6) - 4)) / 4;
@ -71,7 +71,7 @@ void mb86901_device::indent()
}
}
void mb86901_device::disassemble_ss1_fcode(uint32_t r5, uint32_t opcode, uint32_t handler_base, uint32_t entry_point, uint32_t stack)
void sparc_base_device::disassemble_ss1_fcode(uint32_t r5, uint32_t opcode, uint32_t handler_base, uint32_t entry_point, uint32_t stack)
{
std::string opdesc = m_ss1_fcode_table[opcode];
if (opdesc.length() == 0)

View File

@ -2,15 +2,21 @@
// copyright-holders:Ryan Holtz
/***************************************************************************
sun4c_mmu.cpp - Sun 4c MMU emulation
sun4c_mmu.cpp - Sun 4/4c MMU emulation
***************************************************************************/
#include "emu.h"
#include "sun4c_mmu.h"
#include "cpu/sparc/sparc.h"
DEFINE_DEVICE_TYPE(SUN4C_MMU, sun4c_mmu_device, "sun4c_mmu", "Sun 4C MMU")
#include "debug/debugcon.h"
#include "debug/debugcmd.h"
#include "debugger.h"
DEFINE_DEVICE_TYPE(SUN4_MMU, sun4_mmu_device, "sun4_mmu", "Sun 4 MMU")
DEFINE_DEVICE_TYPE(SUN4C_MMU, sun4c_mmu_device, "sun4c_mmu", "Sun 4c MMU")
#define LOG_PAGE_MAP (1U << 0)
#define LOG_SEGMENT_MAP (1U << 1)
@ -31,8 +37,8 @@ DEFINE_DEVICE_TYPE(SUN4C_MMU, sun4c_mmu_device, "sun4c_mmu", "Sun 4C MMU")
#define VERBOSE (0)
#include "logmacro.h"
sun4c_mmu_device::sun4c_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, SUN4C_MMU, tag, owner, clock)
sun4_mmu_base_device::sun4_mmu_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
, m_cpu(*this, finder_base::DUMMY_TAG)
, m_ram(*this, finder_base::DUMMY_TAG)
, m_rom(*this, finder_base::DUMMY_TAG)
@ -53,7 +59,17 @@ sun4c_mmu_device::sun4c_mmu_device(const machine_config &mconfig, const char *ta
{
}
void sun4c_mmu_device::device_start()
sun4_mmu_device::sun4_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: sun4_mmu_base_device(mconfig, SUN4_MMU, tag, owner, clock, 7, 0x7f, 0x7ff, 11, 0x1f, 0x7ffff, 0xfff)
{
}
sun4c_mmu_device::sun4c_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: sun4_mmu_base_device(mconfig, SUN4C_MMU, tag, owner, clock, 7, 0x7f, 0x3ff, 10, 0x3f, 0xffff, 0x3fff)
{
}
void sun4_mmu_base_device::device_start()
{
m_type1_r.resolve_safe(0xffffffff);
m_type1_w.resolve_safe();
@ -62,26 +78,29 @@ void sun4c_mmu_device::device_start()
m_reset_timer = timer_alloc(TIMER_RESET);
m_reset_timer->adjust(attotime::never);
m_segmap = std::make_unique<std::unique_ptr<uint8_t[]>[]>(16);
m_segmap_masked = std::make_unique<std::unique_ptr<uint32_t[]>[]>(16);
for (int i = 0; i < 16; i++)
{
save_item(NAME(m_segmap[i]), i);
save_item(NAME(m_segmap_masked[i]), i);
m_segmap[i] = std::make_unique<uint8_t[]>(16384);
m_segmap_masked[i] = std::make_unique<uint32_t[]>(16384);
save_pointer(NAME(m_segmap[i]), 16384, i);
save_pointer(NAME(m_segmap_masked[i]), 16384, i);
}
for (int i = 0; i < 16384; i++)
{
save_item(NAME(m_pagemap[i].valid), i);
save_item(NAME(m_pagemap[i].writable), i);
save_item(NAME(m_pagemap[i].supervisor), i);
save_item(NAME(m_pagemap[i].uncached), i);
save_item(NAME(m_pagemap[i].accessed), i);
save_item(NAME(m_pagemap[i].modified), i);
save_item(NAME(m_pagemap[i].page), i);
save_item(NAME(m_pagemap[i].type), i);
}
m_pagemap = std::make_unique<page_entry[]>(16384);
save_pointer(NAME(reinterpret_cast<uint8_t*>(m_pagemap.get())), sizeof(page_entry) * 16384);
m_cachetags = std::make_unique<uint32_t[]>(16384);
save_pointer(NAME(m_cachetags), 16384);
m_cachedata = std::make_unique<uint32_t[]>(16384);
save_pointer(NAME(m_cachedata), 16384);
m_page_valid = std::make_unique<bool[]>(16384);
save_pointer(NAME(m_page_valid), 16384);
save_item(NAME(m_cachetags));
save_item(NAME(m_cachedata));
save_item(NAME(m_ram_size));
save_item(NAME(m_ram_size_words));
save_item(NAME(m_context));
@ -89,15 +108,25 @@ void sun4c_mmu_device::device_start()
save_item(NAME(m_system_enable));
save_item(NAME(m_fetch_bootrom));
save_item(NAME(m_buserr));
save_item(NAME(m_page_valid));
save_item(NAME(m_ctx_mask));
save_item(NAME(m_pmeg_mask));
save_item(NAME(m_page_mask));
save_item(NAME(m_seg_entry_shift));
save_item(NAME(m_seg_entry_mask));
save_item(NAME(m_page_entry_mask));
save_item(NAME(m_cache_mask));
save_item(NAME(m_ram_set_mask));
save_item(NAME(m_ram_set_base));
save_item(NAME(m_populated_ram_words));
if (machine().debug_flags & DEBUG_FLAG_ENABLED)
{
using namespace std::placeholders;
machine().debugger().console().register_command("l2p", CMDFLAG_NONE, 0, 1, 1, std::bind(&sun4_mmu_base_device::l2p_command, this, _1, _2));
}
}
void sun4c_mmu_device::device_reset()
void sun4_mmu_base_device::device_reset()
{
m_rom_ptr = (uint32_t *)m_rom->base();
m_ram_ptr = (uint32_t *)m_ram->pointer();
@ -129,19 +158,22 @@ void sun4c_mmu_device::device_reset()
m_context = 0;
m_context_masked = 0;
m_curr_segmap = m_segmap[0];
m_curr_segmap_masked = m_segmap_masked[0];
m_curr_segmap = &m_segmap[0][0];
m_curr_segmap_masked = &m_segmap_masked[0][0];
m_system_enable = 0;
m_fetch_bootrom = true;
memset(m_buserr, 0, sizeof(uint32_t) * 4);
memset(m_segmap, 0, sizeof(uint8_t) * 16 * 4096);
memset(m_pagemap, 0, sizeof(page_entry_t) * 16384);
memset(m_cachetags, 0, sizeof(uint32_t) * 16384);
memset(m_cachedata, 0, sizeof(uint32_t) * 16384);
for (int i = 0; i < 16; i++)
{
memset(&m_segmap[i][0], 0, 4096);
}
memset(&m_pagemap[0], 0, sizeof(page_entry) * 16384);
memset(&m_cachetags[0], 0, sizeof(uint32_t) * 16384);
memset(&m_cachedata[0], 0, sizeof(uint32_t) * 16384);
}
void sun4c_mmu_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
void sun4_mmu_base_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
if (id == TIMER_RESET)
{
@ -150,7 +182,7 @@ void sun4c_mmu_device::device_timer(emu_timer &timer, device_timer_id id, int pa
}
}
uint32_t sun4c_mmu_device::fetch_insn(const bool supervisor, const uint32_t offset)
uint32_t sun4_mmu_base_device::fetch_insn(const bool supervisor, const uint32_t offset)
{
if (supervisor)
return insn_data_r<SUPER_INSN>(offset, 0xffffffff);
@ -158,7 +190,7 @@ uint32_t sun4c_mmu_device::fetch_insn(const bool supervisor, const uint32_t offs
return insn_data_r<USER_INSN>(offset, 0xffffffff);
}
uint32_t sun4c_mmu_device::read_asi(uint8_t asi, uint32_t offset, uint32_t mem_mask)
uint32_t sun4_mmu_base_device::read_asi(uint8_t asi, uint32_t offset, uint32_t mem_mask)
{
LOGMASKED(LOG_ALL_ASI, "read_asi %d: %08x & %08x\n", asi, offset << 2, mem_mask);
switch (asi)
@ -187,7 +219,7 @@ uint32_t sun4c_mmu_device::read_asi(uint8_t asi, uint32_t offset, uint32_t mem_m
}
}
void sun4c_mmu_device::write_asi(uint8_t asi, uint32_t offset, uint32_t data, uint32_t mem_mask)
void sun4_mmu_base_device::write_asi(uint8_t asi, uint32_t offset, uint32_t data, uint32_t mem_mask)
{
LOGMASKED(LOG_ALL_ASI, "write_asi %d: %08x = %08x & %08x\n", asi, offset << 2, data, mem_mask);
switch (asi)
@ -223,18 +255,18 @@ void sun4c_mmu_device::write_asi(uint8_t asi, uint32_t offset, uint32_t data, ui
}
}
uint32_t sun4c_mmu_device::cache_flush_r()
uint32_t sun4_mmu_base_device::cache_flush_r()
{
// Do nothing for now
return 0;
}
void sun4c_mmu_device::cache_flush_w()
void sun4_mmu_base_device::cache_flush_w()
{
// Do nothing for now
}
uint32_t sun4c_mmu_device::system_r(const uint32_t offset, const uint32_t mem_mask)
uint32_t sun4_mmu_base_device::system_r(const uint32_t offset, const uint32_t mem_mask)
{
LOGMASKED(LOG_SYSTEM, "%s: system_r: %08x & %08x\n", machine().describe_context(), offset << 2, mem_mask);
switch (offset >> 26)
@ -264,11 +296,11 @@ uint32_t sun4c_mmu_device::system_r(const uint32_t offset, const uint32_t mem_ma
case 8: // (d-)cache tags
LOGMASKED(LOG_CACHE_TAGS, "sun4_mmu: read dcache tags @ %x, PC = %x\n", offset, m_cpu->pc());
return m_cachetags[offset & 0x3fff];
return m_cachetags[offset & m_cache_mask];
case 9: // (d-)cache data
LOGMASKED(LOG_CACHE_DATA, "sun4c_mmu: read dcache data @ %x, PC = %x\n", offset, m_cpu->pc());
return m_cachedata[offset & 0x3fff];
return m_cachedata[offset & m_cache_mask];
case 0xf: // UART bypass
switch (offset & 3)
@ -285,7 +317,7 @@ uint32_t sun4c_mmu_device::system_r(const uint32_t offset, const uint32_t mem_ma
}
}
void sun4c_mmu_device::system_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
void sun4_mmu_base_device::system_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
{
LOGMASKED(LOG_SYSTEM, "system_w: %08x = %08x & %08x\n", offset << 2, data, mem_mask);
switch (offset >> 26)
@ -295,8 +327,8 @@ void sun4c_mmu_device::system_w(const uint32_t offset, const uint32_t data, cons
m_context = data >> 24;
m_context_masked = m_context & m_ctx_mask;
m_cache_context = m_context & m_ctx_mask;
m_curr_segmap = m_segmap[m_context_masked];
m_curr_segmap_masked = m_segmap_masked[m_context_masked];
m_curr_segmap = &m_segmap[m_context_masked][0];
m_curr_segmap_masked = &m_segmap_masked[m_context_masked][0];
return;
case 4: // system enable reg
@ -336,12 +368,12 @@ void sun4c_mmu_device::system_w(const uint32_t offset, const uint32_t data, cons
case 8: // cache tags
LOGMASKED(LOG_CACHE_TAGS, "write cache tags %08x = %08x & %08x\n", offset << 2, data, mem_mask);
m_cachetags[offset&0x3fff] = data & 0x03f8fffc;
m_cachetags[offset & m_cache_mask] = data & 0x03f8fffc;
return;
case 9: // cache data
LOGMASKED(LOG_CACHE_DATA, "write cache data %08x = %08x & %08x\n", offset << 2, data, mem_mask);
m_cachedata[offset&0x3fff] = data | (1 << 19);
m_cachedata[offset & m_cache_mask] = data | (1 << 19);
return;
case 0xf: // UART bypass
@ -359,7 +391,7 @@ void sun4c_mmu_device::system_w(const uint32_t offset, const uint32_t data, cons
}
}
uint32_t sun4c_mmu_device::segment_map_r(const uint32_t offset, const uint32_t mem_mask)
uint32_t sun4_mmu_base_device::segment_map_r(const uint32_t offset, const uint32_t mem_mask)
{
uint32_t ret = 0;
if (mem_mask == 0xffff0000)
@ -374,7 +406,7 @@ uint32_t sun4c_mmu_device::segment_map_r(const uint32_t offset, const uint32_t m
return ret;
}
void sun4c_mmu_device::segment_map_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
void sun4_mmu_base_device::segment_map_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
{
LOGMASKED(LOG_SEGMENT_MAP, "write segment map %08x = %08x & %08x\n", offset << 2, data, mem_mask);
@ -389,23 +421,23 @@ void sun4c_mmu_device::segment_map_w(const uint32_t offset, const uint32_t data,
m_curr_segmap_masked[seg] = (segdata & m_pmeg_mask) << 6;
}
uint32_t sun4c_mmu_device::page_map_r(const uint32_t offset, const uint32_t mem_mask)
uint32_t sun4_mmu_base_device::page_map_r(const uint32_t offset, const uint32_t mem_mask)
{
const uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> 10) & 0x3f);
const uint32_t ret = m_pagemap[page].to_uint();
const uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> m_seg_entry_shift) & m_seg_entry_mask);
const uint32_t ret = page_entry_to_uint(page);
LOGMASKED(LOG_PAGE_MAP, "read page map %08x & %08x (%x) = %08x\n", offset << 2, mem_mask, page, ret);
return ret;
}
void sun4c_mmu_device::page_map_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
void sun4_mmu_base_device::page_map_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
{
uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> 10) & 0x3f);
uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> m_seg_entry_shift) & m_seg_entry_mask);
LOGMASKED(LOG_PAGE_MAP, "write page map %08x (%x) = %08x & %08x\n", offset << 2, page, data, mem_mask);
m_pagemap[page].merge_uint(data, mem_mask);
merge_page_entry(page, data, mem_mask);
m_page_valid[page] = m_pagemap[page].valid;
}
void sun4c_mmu_device::type0_timeout_r(const uint32_t offset)
void sun4_mmu_base_device::type0_timeout_r(const uint32_t offset)
{
LOGMASKED(LOG_TYPE0_TIMEOUT, "type 0 read timeout %08x, PC=%08x\n", offset << 2, m_cpu->pc());
m_buserr[0] = 0x20; // read timeout
@ -413,7 +445,7 @@ void sun4c_mmu_device::type0_timeout_r(const uint32_t offset)
m_host->set_mae();
}
void sun4c_mmu_device::type0_timeout_w(const uint32_t offset)
void sun4_mmu_base_device::type0_timeout_w(const uint32_t offset)
{
LOGMASKED(LOG_TYPE0_TIMEOUT, "type 0 write timeout %08x, PC=%08x\n", offset << 2, m_cpu->pc());
m_buserr[0] = 0x8020; // write timeout
@ -421,31 +453,33 @@ void sun4c_mmu_device::type0_timeout_w(const uint32_t offset)
m_host->set_mae();
}
uint32_t sun4c_mmu_device::page_entry_t::to_uint()
uint32_t sun4_mmu_base_device::page_entry_to_uint(uint32_t index)
{
return valid | writable | supervisor | uncached | (type << 26) | accessed | modified | (page >> 10);
const page_entry &pe = m_pagemap[index];
return pe.valid | pe.writable | pe.supervisor | pe.uncached | (pe.type << 26) | pe.accessed | pe.modified | (pe.page >> m_seg_entry_shift);
}
void sun4c_mmu_device::page_entry_t::merge_uint(uint32_t data, uint32_t mem_mask)
void sun4_mmu_base_device::merge_page_entry(uint32_t index, uint32_t data, uint32_t mem_mask)
{
const uint32_t new_value = (to_uint() & ~mem_mask) | (data & mem_mask);
valid = new_value & PM_VALID;
writable = new_value & PM_WRITEMASK;
supervisor = new_value & PM_SYSMASK;
uncached = new_value & PM_CACHE;
type = (new_value & PM_TYPEMASK) >> 26;
accessed = new_value & PM_ACCESSED;
modified = new_value & PM_MODIFIED;
page = (new_value & 0xffff) << 10;
page_entry &pe = m_pagemap[index];
const uint32_t new_value = (page_entry_to_uint(index) & ~mem_mask) | (data & mem_mask);
pe.valid = new_value & PM_VALID;
pe.writable = new_value & PM_WRITEMASK;
pe.supervisor = new_value & PM_SYSMASK;
pe.uncached = new_value & PM_CACHE;
pe.type = (new_value & PM_TYPEMASK) >> 26;
pe.accessed = new_value & PM_ACCESSED;
pe.modified = new_value & PM_MODIFIED;
pe.page = (new_value & m_page_entry_mask) << m_seg_entry_shift;
}
template uint32_t sun4c_mmu_device::insn_data_r<sun4c_mmu_device::USER_INSN>(const uint32_t, const uint32_t);
template uint32_t sun4c_mmu_device::insn_data_r<sun4c_mmu_device::SUPER_INSN>(const uint32_t, const uint32_t);
template uint32_t sun4c_mmu_device::insn_data_r<sun4c_mmu_device::USER_DATA>(const uint32_t, const uint32_t);
template uint32_t sun4c_mmu_device::insn_data_r<sun4c_mmu_device::SUPER_DATA>(const uint32_t, const uint32_t);
template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::USER_INSN>(const uint32_t, const uint32_t);
template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::SUPER_INSN>(const uint32_t, const uint32_t);
template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::USER_DATA>(const uint32_t, const uint32_t);
template uint32_t sun4_mmu_base_device::insn_data_r<sun4_mmu_base_device::SUPER_DATA>(const uint32_t, const uint32_t);
template <sun4c_mmu_device::insn_data_mode MODE>
uint32_t sun4c_mmu_device::insn_data_r(const uint32_t offset, const uint32_t mem_mask)
template <sun4_mmu_base_device::insn_data_mode MODE>
uint32_t sun4_mmu_base_device::insn_data_r(const uint32_t offset, const uint32_t mem_mask)
{
// supervisor program fetches in boot state are special
if (MODE == SUPER_INSN && m_fetch_bootrom)
@ -455,14 +489,14 @@ uint32_t sun4c_mmu_device::insn_data_r(const uint32_t offset, const uint32_t mem
// it's translation time
const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];// & m_pmeg_mask;
const uint32_t entry_index = pmeg | ((offset >> 10) & 0x3f);
const uint32_t entry_index = pmeg | ((offset >> m_seg_entry_shift) & m_seg_entry_mask);
if (m_page_valid[entry_index])
{
page_entry_t &entry = m_pagemap[entry_index];
page_entry &entry = m_pagemap[entry_index];
entry.accessed = PM_ACCESSED;
const uint32_t tmp = entry.page | (offset & 0x3ff);
const uint32_t tmp = entry.page | (offset & m_page_mask);
switch (entry.type)
{
@ -495,7 +529,7 @@ uint32_t sun4c_mmu_device::insn_data_r(const uint32_t offset, const uint32_t mem
{
if (!machine().side_effects_disabled())
{
LOGMASKED(LOG_INVALID_PTE, "read invalid PTE %d (%08x), %08x & %08x, PC=%08x\n", entry_index, m_pagemap[entry_index].to_uint(), offset << 2, mem_mask, m_cpu->pc());
LOGMASKED(LOG_INVALID_PTE, "read invalid PTE %d (%08x), %08x & %08x, PC=%08x\n", entry_index, page_entry_to_uint(entry_index), offset << 2, mem_mask, m_cpu->pc());
m_host->set_mae();
m_buserr[0] |= 0x80; // invalid PTE
m_buserr[0] &= ~0x8000; // read
@ -520,24 +554,24 @@ uint32_t sun4c_mmu_device::insn_data_r(const uint32_t offset, const uint32_t mem
}
}
template void sun4c_mmu_device::insn_data_w<sun4c_mmu_device::USER_INSN>(const uint32_t, const uint32_t, const uint32_t);
template void sun4c_mmu_device::insn_data_w<sun4c_mmu_device::SUPER_INSN>(const uint32_t, const uint32_t, const uint32_t);
template void sun4c_mmu_device::insn_data_w<sun4c_mmu_device::USER_DATA>(const uint32_t, const uint32_t, const uint32_t);
template void sun4c_mmu_device::insn_data_w<sun4c_mmu_device::SUPER_DATA>(const uint32_t, const uint32_t, const uint32_t);
template void sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::USER_INSN>(const uint32_t, const uint32_t, const uint32_t);
template void sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::SUPER_INSN>(const uint32_t, const uint32_t, const uint32_t);
template void sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::USER_DATA>(const uint32_t, const uint32_t, const uint32_t);
template void sun4_mmu_base_device::insn_data_w<sun4_mmu_base_device::SUPER_DATA>(const uint32_t, const uint32_t, const uint32_t);
template <sun4c_mmu_device::insn_data_mode MODE>
void sun4c_mmu_device::insn_data_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
template <sun4_mmu_base_device::insn_data_mode MODE>
void sun4_mmu_base_device::insn_data_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
{
// it's translation time
const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];// & m_pmeg_mask;
const uint32_t entry_index = pmeg | ((offset >> 10) & 0x3f);
const uint32_t entry_index = pmeg | ((offset >> m_seg_entry_shift) & m_seg_entry_mask);
if (m_page_valid[entry_index])
{
page_entry_t &entry = m_pagemap[entry_index];
page_entry &entry = m_pagemap[entry_index];
if ((!entry.writable) || (entry.supervisor && MODE != SUPER_DATA && MODE != SUPER_INSN))
{
LOGMASKED(LOG_WRITE_PROTECT, "write protect error with PTE %d (%08x), %08x = %08x & %08x, PC=%08x\n", entry_index, m_pagemap[entry_index].to_uint(), offset << 2, data, mem_mask, m_cpu->pc());
LOGMASKED(LOG_WRITE_PROTECT, "write protect error with PTE %d (%08x), %08x = %08x & %08x, PC=%08x\n", entry_index, page_entry_to_uint(entry_index), offset << 2, data, mem_mask, m_cpu->pc());
m_buserr[0] |= 0x8040; // write, protection error
m_buserr[1] = offset << 2;
m_host->set_mae();
@ -547,7 +581,7 @@ void sun4c_mmu_device::insn_data_w(const uint32_t offset, const uint32_t data, c
entry.accessed = PM_ACCESSED;
entry.modified = PM_MODIFIED;
const uint32_t tmp = entry.page | (offset & 0x3ff);
const uint32_t tmp = entry.page | (offset & m_page_mask);
switch (entry.type)
{
@ -579,7 +613,7 @@ void sun4c_mmu_device::insn_data_w(const uint32_t offset, const uint32_t data, c
}
else
{
LOGMASKED(LOG_INVALID_PTE, "write invalid PTE %d (%08x), %08x = %08x & %08x, PC=%08x\n", entry_index, m_pagemap[entry_index].to_uint(), offset << 2, data, mem_mask, m_cpu->pc());
LOGMASKED(LOG_INVALID_PTE, "write invalid PTE %d (%08x), %08x = %08x & %08x, PC=%08x\n", entry_index, page_entry_to_uint(entry_index), offset << 2, data, mem_mask, m_cpu->pc());
m_host->set_mae();
m_buserr[0] |= 0x8080; // write cycle, invalid PTE
m_buserr[1] = offset << 2;
@ -601,3 +635,30 @@ void sun4c_mmu_device::insn_data_w(const uint32_t offset, const uint32_t data, c
}
}
void sun4_mmu_base_device::l2p_command(int ref, const std::vector<std::string> &params)
{
uint64_t addr, offset;
if (!machine().debugger().commands().validate_number_parameter(params[0], addr)) return;
addr &= 0xffffffff;
offset = addr >> 2;
uint8_t pmeg = 0;
uint32_t entry_index = 0, tmp = 0;
uint32_t entry_value = 0;
pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];
entry_index = pmeg | ((offset >> m_seg_entry_shift) & m_seg_entry_mask);
tmp = m_pagemap[entry_index].page | (offset & m_page_mask);
entry_value = page_entry_to_uint(entry_index);
if (m_page_valid[entry_index])
{
machine().debugger().console().printf("logical %08x => phys %08x, type %d (pmeg %d, entry %d PTE %08x)\n", addr, tmp << 2, m_pagemap[entry_index].type, pmeg, entry_index, entry_value);
}
else
{
machine().debugger().console().printf("logical %08x points to an invalid PTE! (pmeg %d, entry %d PTE %08x)\n", addr, tmp << 2, pmeg, entry_index, entry_value);
}
}

View File

@ -2,31 +2,36 @@
// copyright-holders:Ryan Holtz
/***************************************************************************
sun4c_mmu.h - Sun 4c MMU emulation
sun4c_mmu.h - Sun 4/4c MMU emulation
***************************************************************************/
#ifndef MAME_MACHINE_SUN4C_MMU_H
#define MAME_MACHINE_SUN4C_MMU_H
#pragma once
#ifndef DEVICE_MACHINE_SUN4C_MMU_H
#define DEVICE_MACHINE_SUN4C_MMU_H
#include "cpu/sparc/sparc_intf.h"
#include "machine/ram.h"
#include "machine/z80scc.h"
class sun4c_mmu_device : public device_t, public sparc_mmu_interface
class sun4_mmu_base_device : public device_t, public sparc_mmu_interface
{
public:
sun4c_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint8_t ctx_mask, uint8_t pmeg_mask)
: sun4c_mmu_device(mconfig, tag, owner, clock)
sun4_mmu_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock
, uint8_t ctx_mask, uint8_t pmeg_mask, uint32_t page_mask, uint32_t seg_entry_shift, uint32_t seg_entry_mask
, uint32_t page_entry_mask, uint32_t cache_mask)
: sun4_mmu_base_device(mconfig, type, tag, owner, clock)
{
set_ctx_mask(ctx_mask);
set_pmeg_mask(pmeg_mask);
set_page_mask(page_mask);
set_seg_entry_shift(seg_entry_shift);
set_seg_entry_mask(seg_entry_mask);
set_page_entry_mask(page_entry_mask);
set_cache_mask(cache_mask);
}
sun4c_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template <typename T> void set_cpu(T &&cpu_tag) { m_cpu.set_tag(std::forward<T>(cpu_tag)); }
template <typename T> void set_ram(T &&ram_tag) { m_ram.set_tag(std::forward<T>(ram_tag)); }
template <typename T> void set_rom(T &&rom_tag) { m_rom.set_tag(std::forward<T>(rom_tag)); }
@ -37,6 +42,11 @@ public:
void set_ctx_mask(uint8_t ctx_mask) { m_ctx_mask = ctx_mask; }
void set_pmeg_mask(uint8_t pmeg_mask) { m_pmeg_mask = pmeg_mask; }
void set_page_mask(uint32_t page_mask) { m_page_mask = page_mask; }
void set_seg_entry_shift(uint32_t seg_entry_shift) { m_seg_entry_shift = seg_entry_shift; }
void set_seg_entry_mask(uint32_t seg_entry_mask) { m_seg_entry_mask = seg_entry_mask; }
void set_page_entry_mask(uint32_t page_entry_mask) { m_page_entry_mask = page_entry_mask; }
void set_cache_mask(uint32_t cache_mask) { m_cache_mask = cache_mask; }
enum insn_data_mode
{
@ -56,12 +66,17 @@ public:
void set_host(sparc_mmu_host_interface *host) override { m_host = host; }
protected:
sun4_mmu_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
static const device_timer_id TIMER_RESET = 0;
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
uint32_t page_entry_to_uint(uint32_t index);
void merge_page_entry(uint32_t index, uint32_t data, uint32_t mem_mask);
uint32_t cache_flush_r();
void cache_flush_w();
uint32_t system_r(const uint32_t offset, const uint32_t mem_mask);
@ -72,6 +87,7 @@ protected:
void page_map_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask);
void type0_timeout_r(const uint32_t offset);
void type0_timeout_w(const uint32_t offset);
void l2p_command(int ref, const std::vector<std::string> &params);
enum
{
@ -92,7 +108,7 @@ protected:
PM_MODIFIED = 0x01000000 // modified flag
};
struct page_entry_t
struct page_entry
{
uint32_t valid;
uint32_t writable;
@ -103,9 +119,6 @@ protected:
uint32_t page;
uint8_t type;
uint8_t pad[3];
uint32_t to_uint();
void merge_uint(uint32_t data, uint32_t mem_mask);
};
required_device<cpu_device> m_cpu;
@ -120,10 +133,10 @@ protected:
devcb_write32 m_type1_w;
// Actual SRAM
uint8_t m_segmap[16][4096];
page_entry_t m_pagemap[16384];
uint32_t m_cachetags[16384];
uint32_t m_cachedata[16384];
std::unique_ptr<std::unique_ptr<uint8_t[]>[]> m_segmap;
std::unique_ptr<page_entry[]> m_pagemap;
std::unique_ptr<uint32_t[]> m_cachetags;
std::unique_ptr<uint32_t[]> m_cachedata;
uint32_t *m_rom_ptr;
uint32_t *m_ram_ptr;
@ -137,21 +150,38 @@ protected:
uint32_t m_buserr[4];
// Pre-computed data for optimization purposes
uint32_t m_segmap_masked[16][4096];
std::unique_ptr<std::unique_ptr<uint32_t[]>[]> m_segmap_masked;
uint8_t *m_curr_segmap;
uint32_t *m_curr_segmap_masked;
bool m_page_valid[16384];
std::unique_ptr<bool[]> m_page_valid;
// Internal MAME device state
uint8_t m_ctx_mask; // SS2 is sun4c but has 16 contexts; most have 8
uint8_t m_pmeg_mask; // SS2 is sun4c but has 16384 PTEs; most have 8192
uint32_t m_page_mask;
uint32_t m_seg_entry_shift;
uint32_t m_seg_entry_mask;
uint32_t m_page_entry_mask;
uint32_t m_cache_mask;
uint32_t m_ram_set_mask[4]; // Used for mirroring within 4 megabyte sets
uint32_t m_ram_set_base[4];
uint32_t m_populated_ram_words;
emu_timer *m_reset_timer;
};
class sun4_mmu_device : public sun4_mmu_base_device
{
public:
sun4_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
class sun4c_mmu_device : public sun4_mmu_base_device
{
public:
sun4c_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
DECLARE_DEVICE_TYPE(SUN4_MMU, sun4_mmu_device)
DECLARE_DEVICE_TYPE(SUN4C_MMU, sun4c_mmu_device)
#endif // MAME_MACHINE_SUN4C_MMU_H
#endif // DEVICE_MACHINE_SUN4C_MMU_H

View File

@ -36,8 +36,8 @@
#include "emu.h"
#include "bt45x.h"
#define LOG_GENERAL (1U << 0)
#define LOG_READS (1U << 1)
#define LOG_READS (1U << 0)
#define LOG_WRITES (1U << 1)
#define VERBOSE (0)
@ -180,7 +180,7 @@ void bt45x_device_base::device_reset()
READ8_MEMBER(bt45x_device_base::address_r)
{
LOGMASKED(LOG_READS, "address_r 0x%02x\n", m_address & (m_palette_colors - 1));
LOGMASKED(LOG_READS, "%s: address_r 0x%02x\n", machine().describe_context(), m_address & (m_palette_colors - 1));
if (!machine().side_effects_disabled())
m_address_rgb = 0;
@ -190,7 +190,8 @@ READ8_MEMBER(bt45x_device_base::address_r)
WRITE8_MEMBER(bt45x_device_base::address_w)
{
LOG("address_w 0x%02x\n", data);
LOGMASKED(LOG_WRITES, "%s: address_w 0x%02x\n", machine().describe_context(), data);
m_address_rgb = 0;
m_address = data & (m_palette_colors - 1);
@ -230,7 +231,7 @@ READ8_MEMBER(bt45x_rgb_device_base::palette_r)
increment_address();
LOGMASKED(LOG_READS, "palette_r 0x%02x\n", data & get_mask());
LOGMASKED(LOG_READS, "%s: palette_r 0x%02x\n", machine().describe_context(), data & get_mask());
return data & get_mask();
}
@ -244,7 +245,7 @@ READ8_MEMBER(bt45x_mono_device_base::palette_r)
increment_address();
LOGMASKED(LOG_READS, "palette_r 0x%02x\n", data & get_mask());
LOGMASKED(LOG_READS, "%s: palette_r 0x%02x\n", machine().describe_context(), data & get_mask());
return data & get_mask();
}
@ -259,14 +260,14 @@ READ8_MEMBER(bt457_device::palette_r)
increment_address();
LOGMASKED(LOG_READS, "palette_r 0x%02x\n", data);
LOGMASKED(LOG_READS, "%s: palette_r 0x%02x\n", machine().describe_context(), data);
return data;
}
WRITE8_MEMBER(bt45x_rgb_device_base::palette_w)
{
LOG("palette_w 0x%02x\n", data);
LOGMASKED(LOG_WRITES, "%s: palette_w 0x%02x\n", machine().describe_context(), data);
m_color_ram[m_address][m_address_rgb] = data & get_mask();
@ -279,7 +280,7 @@ WRITE8_MEMBER(bt45x_rgb_device_base::palette_w)
WRITE8_MEMBER(bt45x_mono_device_base::palette_w)
{
LOG("palette_w 0x%02x\n", data);
LOGMASKED(LOG_WRITES, "%s: palette_w 0x%02x\n", machine().describe_context(), data);
if (m_address_rgb == 1)
m_color_ram[m_address] = data & get_mask();
@ -289,7 +290,7 @@ WRITE8_MEMBER(bt45x_mono_device_base::palette_w)
WRITE8_MEMBER(bt457_device::palette_w)
{
LOG("palette_w 0x%02x\n", data);
LOGMASKED(LOG_WRITES, "%s: palette_w 0x%02x\n", machine().describe_context(), data);
// device in normal mode, or rgb mode and selected
if (!(m_control & RGB) || (m_control & RGB) == (1 << m_address_rgb))
@ -300,7 +301,7 @@ WRITE8_MEMBER(bt457_device::palette_w)
READ8_MEMBER(bt45x_device_base::register_r)
{
LOGMASKED(LOG_READS, "register_r 0x%02x\n", m_address);
LOGMASKED(LOG_READS, "%s: register_r 0x%02x\n", machine().describe_context(), m_address);
switch (m_address)
{
@ -318,17 +319,18 @@ WRITE8_MEMBER(bt45x_device_base::register_w)
switch (m_address)
{
case REG_READ_MASK:
LOG("read mask 0x%02x\n", data);
LOGMASKED(LOG_WRITES, "%s: register_w: read mask 0x%02x\n", machine().describe_context(), data);
m_read_mask = data;
break;
case REG_BLINK_MASK:
LOG("blink mask 0x%02x\n", data);
LOGMASKED(LOG_WRITES, "%s: register_w: blink mask 0x%02x\n", machine().describe_context(), data);
m_blink_mask = data;
break;
case REG_COMMAND:
LOG("command 0x%02x, %d:1 multiplexing, use %s, %s, OL1 %s blinking, OL0 %s blinking, OL1 display %s, OL0 display %s\n",
LOGMASKED(LOG_WRITES, "%s: register_w: command 0x%02x, %d:1 multiplexing, use %s, %s, OL1 %s blinking, OL0 %s blinking, OL1 display %s, OL0 display %s\n",
machine().describe_context(),
data,
(data & CR7) ? 5 : 4,
(data & CR6) ? "color palette RAM" : "overlay color 0",
@ -344,7 +346,7 @@ WRITE8_MEMBER(bt45x_device_base::register_w)
break;
case REG_CONTROL:
LOG("control 0x%02x, %s nibble%s%s%s\n",
LOGMASKED(LOG_WRITES, "%s: register_w: control 0x%02x, %s nibble%s%s%s\n",
data,
(data & D3) ? "low" : "high",
(data & D2) ? ", blue channel enable" : "",
@ -367,7 +369,7 @@ READ8_MEMBER(bt45x_rgb_device_base::overlay_r)
increment_address();
LOGMASKED(LOG_READS, "overlay_r 0x%02x\n", data & get_mask());
LOGMASKED(LOG_READS, "%s: overlay_r 0x%02x\n", machine().describe_context(), data & get_mask());
return data & get_mask();
}
@ -384,7 +386,7 @@ READ8_MEMBER(bt45x_mono_device_base::overlay_r)
increment_address();
LOGMASKED(LOG_READS, "overlay_r 0x%02x\n", data & get_mask());
LOGMASKED(LOG_READS, "%s: overlay_r 0x%02x\n", machine().describe_context(), data & get_mask());
return data & get_mask();
}
@ -402,14 +404,14 @@ READ8_MEMBER(bt457_device::overlay_r)
increment_address();
LOGMASKED(LOG_READS, "overlay_r 0x%02x\n", data);
LOGMASKED(LOG_READS, "%s: overlay_r 0x%02x\n", machine().describe_context(), data);
return data;
}
WRITE8_MEMBER(bt45x_rgb_device_base::overlay_w)
{
LOG("overlay_w 0x%02x\n", data);
LOGMASKED(LOG_WRITES, "%s: overlay_w 0x%02x\n", machine().describe_context(), data);
// address is ignored for 1 bit overlay devices
const u8 address = (m_overlay_colors == 1) ? 0 : m_address;
@ -431,7 +433,7 @@ WRITE8_MEMBER(bt45x_rgb_device_base::overlay_w)
WRITE8_MEMBER(bt45x_mono_device_base::overlay_w)
{
LOG("overlay_w 0x%02x\n", data);
LOGMASKED(LOG_WRITES, "%s: overlay_w 0x%02x\n", machine().describe_context(), data);
// address is ignored for 1 bit overlay devices
const u8 address = (m_overlay_colors == 1) ? 0 : m_address;
@ -444,7 +446,7 @@ WRITE8_MEMBER(bt45x_mono_device_base::overlay_w)
WRITE8_MEMBER(bt457_device::overlay_w)
{
LOG("overlay_w 0x%02x\n", data);
LOGMASKED(LOG_WRITES, "%s: overlay_w 0x%02x\n", machine().describe_context(), data);
if (m_address < m_overlay_colors)
{

File diff suppressed because it is too large Load Diff