mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
g65816: Allow use of separate address spaces for program, data, opcodes and/or vectors
This commit is contained in:
parent
3330975244
commit
71c9b2fa06
@ -112,6 +112,9 @@ g65816_device::g65816_device(const machine_config &mconfig, const char *tag, dev
|
||||
g65816_device::g65816_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int cpu_type, address_map_constructor internal)
|
||||
: cpu_device(mconfig, type, tag, owner, clock)
|
||||
, m_program_config("program", ENDIANNESS_LITTLE, 8, 24, 0, internal)
|
||||
, m_data_config("data", ENDIANNESS_LITTLE, 8, 24, 0, internal)
|
||||
, m_opcode_config("opcodes", ENDIANNESS_LITTLE, 8, 24, 0, internal)
|
||||
, m_vector_config("vectors", ENDIANNESS_LITTLE, 8, 5, 0)
|
||||
, m_cpu_type(cpu_type)
|
||||
{
|
||||
}
|
||||
@ -119,9 +122,16 @@ g65816_device::g65816_device(const machine_config &mconfig, device_type type, co
|
||||
|
||||
device_memory_interface::space_config_vector g65816_device::memory_space_config() const
|
||||
{
|
||||
return space_config_vector {
|
||||
space_config_vector spaces = {
|
||||
std::make_pair(AS_PROGRAM, &m_program_config)
|
||||
};
|
||||
if (has_configured_map(AS_DATA))
|
||||
spaces.push_back(std::make_pair(AS_DATA, &m_data_config));
|
||||
if (has_configured_map(AS_OPCODES))
|
||||
spaces.push_back(std::make_pair(AS_OPCODES, &m_opcode_config));
|
||||
if (has_configured_map(AS_VECTORS))
|
||||
spaces.push_back(std::make_pair(AS_VECTORS, &m_vector_config));
|
||||
return spaces;
|
||||
}
|
||||
|
||||
|
||||
@ -222,6 +232,13 @@ unsigned g65816_device::g65816i_read_8_immediate(unsigned address)
|
||||
return g65816_read_8_immediate(address);
|
||||
}
|
||||
|
||||
unsigned g65816_device::g65816i_read_8_opcode(unsigned address)
|
||||
{
|
||||
address = ADDRESS_65816(address);
|
||||
CLOCKS -= (bus_5A22_cycle_burst(address));
|
||||
return g65816_read_8_opcode(address);
|
||||
}
|
||||
|
||||
unsigned g65816_device::g65816i_read_8_direct(unsigned address)
|
||||
{
|
||||
if (FLAG_E)
|
||||
@ -240,10 +257,11 @@ unsigned g65816_device::g65816i_read_8_direct(unsigned address)
|
||||
|
||||
unsigned g65816_device::g65816i_read_8_vector(unsigned address)
|
||||
{
|
||||
if (!READ_VECTOR.isnull())
|
||||
return READ_VECTOR(*m_program, address, 0xff);
|
||||
CLOCKS -= (bus_5A22_cycle_burst(address));
|
||||
if (has_space(AS_VECTORS))
|
||||
return space(AS_VECTORS).read_byte(address & 0x001f);
|
||||
else
|
||||
return g65816i_read_8_normal(address);
|
||||
return g65816_read_8_immediate(address);
|
||||
}
|
||||
|
||||
void g65816_device::g65816i_write_8_normal(unsigned address, unsigned value)
|
||||
@ -589,7 +607,7 @@ void g65816_device::g65816i_interrupt_software(unsigned vector)
|
||||
FLAG_D = DFLAG_CLEAR;
|
||||
g65816i_set_flag_i(IFLAG_SET);
|
||||
REGISTER_PB = 0;
|
||||
g65816i_jump_16(g65816i_read_16_normal(vector));
|
||||
g65816i_jump_16(g65816i_read_16_immediate(vector));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -600,7 +618,7 @@ void g65816_device::g65816i_interrupt_software(unsigned vector)
|
||||
FLAG_D = DFLAG_CLEAR;
|
||||
g65816i_set_flag_i(IFLAG_SET);
|
||||
REGISTER_PB = 0;
|
||||
g65816i_jump_16(g65816i_read_16_normal(vector));
|
||||
g65816i_jump_16(g65816i_read_16_immediate(vector));
|
||||
}
|
||||
}
|
||||
|
||||
@ -613,7 +631,7 @@ void g65816_device::g65816i_interrupt_nmi()
|
||||
g65816i_push_8(g65816i_get_reg_p() & ~FLAGPOS_B);
|
||||
FLAG_D = DFLAG_CLEAR;
|
||||
REGISTER_PB = 0;
|
||||
g65816i_jump_16(g65816i_read_16_normal((FLAG_E) ? VECTOR_NMI_E : VECTOR_NMI_N));
|
||||
g65816i_jump_16(g65816i_read_16_vector((FLAG_E) ? VECTOR_NMI_E : VECTOR_NMI_N));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -623,7 +641,7 @@ void g65816_device::g65816i_interrupt_nmi()
|
||||
g65816i_push_8(g65816i_get_reg_p());
|
||||
FLAG_D = DFLAG_CLEAR;
|
||||
REGISTER_PB = 0;
|
||||
g65816i_jump_16(g65816i_read_16_normal((FLAG_E) ? VECTOR_NMI_E : VECTOR_NMI_N));
|
||||
g65816i_jump_16(g65816i_read_16_vector((FLAG_E) ? VECTOR_NMI_E : VECTOR_NMI_N));
|
||||
}
|
||||
}
|
||||
|
||||
@ -706,7 +724,10 @@ void g65816_device::device_reset()
|
||||
REGISTER_S = 0x1ff;
|
||||
|
||||
/* Fetch the reset vector */
|
||||
REGISTER_PC = g65816_read_8(VECTOR_RESET) | (g65816_read_8(VECTOR_RESET+1)<<8);
|
||||
if (has_space(AS_VECTORS))
|
||||
REGISTER_PC = space(AS_VECTORS).read_word(VECTOR_RESET & 0x001f);
|
||||
else
|
||||
REGISTER_PC = g65816_read_8_immediate(VECTOR_RESET) | (g65816_read_8_immediate(VECTOR_RESET+1)<<8);
|
||||
g65816i_jumping(REGISTER_PB | REGISTER_PC);
|
||||
}
|
||||
|
||||
@ -833,7 +854,10 @@ void g65816_device::device_start()
|
||||
m_execute = nullptr;
|
||||
m_debugger_temp = 0;
|
||||
|
||||
m_program = &space(AS_PROGRAM);
|
||||
address_space &program_space = space(AS_PROGRAM);
|
||||
m_data_space = has_space(AS_DATA) ? &space(AS_DATA) : &program_space;
|
||||
m_program_direct = program_space.direct<0>();
|
||||
m_opcode_direct = (has_space(AS_OPCODES) ? space(AS_OPCODES) : program_space).direct<0>();
|
||||
|
||||
save_item(NAME(m_a));
|
||||
save_item(NAME(m_b));
|
||||
@ -987,11 +1011,6 @@ void g65816_device::state_string_export(const device_state_entry &entry, std::st
|
||||
}
|
||||
}
|
||||
|
||||
void g65816_device::set_read_vector_callback(read8_delegate read_vector)
|
||||
{
|
||||
READ_VECTOR = read_vector;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
SNES specific, used to handle master cycles, based off byuu's BSNES code
|
||||
|
@ -49,11 +49,13 @@ enum
|
||||
class g65816_device : public cpu_device, public g65816_disassembler::config
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
AS_VECTORS = AS_OPCODES + 1,
|
||||
};
|
||||
|
||||
// construction/destruction
|
||||
g65816_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
void set_read_vector_callback(read8_delegate read_vector);
|
||||
|
||||
protected:
|
||||
/* Registers - used by g65816_set_reg() and g65816_get_reg() */
|
||||
enum
|
||||
@ -91,6 +93,9 @@ protected:
|
||||
virtual bool get_x_flag() const override;
|
||||
|
||||
address_space_config m_program_config;
|
||||
address_space_config m_data_config;
|
||||
address_space_config m_opcode_config;
|
||||
address_space_config m_vector_config;
|
||||
|
||||
typedef void (g65816_device::*opcode_func) ();
|
||||
typedef unsigned (g65816_device::*get_reg_func)(int regnum);
|
||||
@ -139,6 +144,7 @@ protected:
|
||||
void g65816_restore_state();
|
||||
unsigned g65816i_read_8_normal(unsigned address);
|
||||
unsigned g65816i_read_8_immediate(unsigned address);
|
||||
unsigned g65816i_read_8_opcode(unsigned address);
|
||||
unsigned g65816i_read_8_direct(unsigned address);
|
||||
unsigned g65816i_read_8_vector(unsigned address);
|
||||
void g65816i_write_8_normal(unsigned address, unsigned value);
|
||||
@ -222,8 +228,9 @@ protected:
|
||||
unsigned m_fastROM; /* SNES specific */
|
||||
unsigned m_ir; /* Instruction Register */
|
||||
unsigned m_irq_delay; /* delay 1 instruction before checking irq */
|
||||
address_space *m_program;
|
||||
read8_delegate m_read_vector; /* Read vector override */
|
||||
address_space *m_data_space;
|
||||
direct_read_data<0> *m_program_direct;
|
||||
direct_read_data<0> *m_opcode_direct;
|
||||
unsigned m_stopped; /* Sets how the CPU is stopped */
|
||||
const opcode_func* m_opcodes;
|
||||
get_reg_func m_get_reg;
|
||||
|
@ -13,9 +13,10 @@
|
||||
#undef G65816_CALL_DEBUGGER
|
||||
#define G65816_CALL_DEBUGGER(x) debugger_instruction_hook(this, x)
|
||||
|
||||
#define g65816_read_8(addr) m_program->read_byte(addr)
|
||||
#define g65816_write_8(addr,data) m_program->write_byte(addr,data)
|
||||
#define g65816_read_8_immediate(A) m_program->read_byte(A)
|
||||
#define g65816_read_8(addr) m_data_space->read_byte(addr)
|
||||
#define g65816_write_8(addr,data) m_data_space->write_byte(addr,data)
|
||||
#define g65816_read_8_immediate(A) m_program_direct->read_byte(A)
|
||||
#define g65816_read_8_opcode(A) m_opcode_direct->read_byte(A)
|
||||
#define g65816_jumping(A)
|
||||
#define g65816_branching(A)
|
||||
|
||||
@ -75,7 +76,6 @@
|
||||
#define LINE_NMI m_line_nmi /* Status of the NMI line */
|
||||
#define REGISTER_IR m_ir /* Instruction Register */
|
||||
#define INT_ACK m_int_ack /* Interrupt Acknowledge function pointer */
|
||||
#define READ_VECTOR m_read_vector /* Vector reading override */
|
||||
#define CLOCKS m_ICount /* Clock cycles remaining */
|
||||
#define IRQ_DELAY m_irq_delay /* Delay 1 instruction before checking IRQ */
|
||||
#define CPU_STOPPED m_stopped /* Stopped status of the CPU */
|
||||
|
@ -24,6 +24,16 @@ u32 g65816_disassembler::opcode_alignment() const
|
||||
return 1;
|
||||
}
|
||||
|
||||
u32 g65816_disassembler::interface_flags() const
|
||||
{
|
||||
return PAGED;
|
||||
}
|
||||
|
||||
u32 g65816_disassembler::page_address_bits() const
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
const char *g65816_disassembler::opcode_struct::name() const
|
||||
{
|
||||
return g65816_disassembler::s_opnames[unsigned(m_name)];
|
||||
|
@ -29,6 +29,8 @@ public:
|
||||
g65816_disassembler(config *conf);
|
||||
|
||||
virtual u32 opcode_alignment() const override;
|
||||
virtual u32 interface_flags() const override;
|
||||
virtual u32 page_address_bits() const override;
|
||||
virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override;
|
||||
|
||||
private:
|
||||
|
@ -59,6 +59,7 @@
|
||||
/* Effective-address based memory access macros */
|
||||
#define read_8_NORM(A) g65816i_read_8_normal(A)
|
||||
#define read_8_IMM(A) g65816i_read_8_immediate(A)
|
||||
#define read_8_OP(A) g65816i_read_8_opcode(A)
|
||||
#define read_8_D(A) g65816i_read_8_direct(A)
|
||||
#define read_8_A(A) g65816i_read_8_normal(A)
|
||||
#define read_8_AL(A) g65816i_read_8_normal(A)
|
||||
@ -1952,7 +1953,7 @@ TABLE_FUNCTION(int, execute, (int clocks))
|
||||
G65816_CALL_DEBUGGER(REGISTER_PB | REGISTER_PC);
|
||||
|
||||
REGISTER_PC++;
|
||||
REGISTER_IR = read_8_IMM(REGISTER_PB | REGISTER_PPC);
|
||||
REGISTER_IR = read_8_OP(REGISTER_PB | REGISTER_PPC);
|
||||
(this->*FTABLE_OPCODES[REGISTER_IR])();
|
||||
} while((CLOCKS > 0) && g65816i_correct_mode());
|
||||
return clocks - CLOCKS;
|
||||
|
@ -186,6 +186,11 @@ void apple2gs_state::apple2gs_map(address_map &map)
|
||||
/* nothing in the address map - everything is added dynamically */
|
||||
}
|
||||
|
||||
void apple2gs_state::vectors_map(address_map &map)
|
||||
{
|
||||
map(0x00, 0x1f).r(this, FUNC(apple2gs_state::apple2gs_read_vector));
|
||||
}
|
||||
|
||||
// ADB microcontroller emulation
|
||||
//
|
||||
// Huge thanks to Neil Parker's writeup on the ADB microcontroller!
|
||||
@ -311,6 +316,7 @@ MACHINE_CONFIG_START(apple2gs_state::apple2gs)
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD("maincpu", G65816, APPLE2GS_14M/5)
|
||||
MCFG_CPU_PROGRAM_MAP(apple2gs_map)
|
||||
MCFG_DEVICE_ADDRESS_MAP(g65816_device::AS_VECTORS, vectors_map)
|
||||
#if RUN_ADB_MICRO
|
||||
MCFG_CPU_ADD(ADBMICRO_TAG, M50741, XTAL(3'579'545))
|
||||
MCFG_M5074X_PORT0_READ_CALLBACK(READ8(apple2gs_state, adbmicro_p0_in))
|
||||
|
@ -9,9 +9,11 @@ TeleVideo 9320 appears to run on similar hardware with a 2681 DUART replacing th
|
||||
************************************************************************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
//#include "bus/rs232/rs232.h"
|
||||
#include "cpu/g65816/g65816.h"
|
||||
//#include "machine/mos6551.h"
|
||||
#include "machine/mos6551.h"
|
||||
#include "machine/nvram.h"
|
||||
//#include "video/scn2674.h"
|
||||
#include "screen.h"
|
||||
|
||||
class tv965_state : public driver_device
|
||||
@ -27,7 +29,10 @@ public:
|
||||
private:
|
||||
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
DECLARE_READ8_MEMBER(ga_hack_r);
|
||||
|
||||
void mem_map(address_map &map);
|
||||
void program_map(address_map &map);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<screen_device> m_screen;
|
||||
@ -38,20 +43,37 @@ u32 tv965_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, cons
|
||||
return 0;
|
||||
}
|
||||
|
||||
READ8_MEMBER(tv965_state::ga_hack_r)
|
||||
{
|
||||
return 0x08;
|
||||
}
|
||||
|
||||
void tv965_state::mem_map(address_map &map)
|
||||
{
|
||||
map.global_mask(0x3ffff);
|
||||
map(0x00000, 0x01fff).ram().share("nvram");
|
||||
map(0x04000, 0x04000).r(this, FUNC(tv965_state::ga_hack_r));
|
||||
map(0x06200, 0x06203).rw("acia1", FUNC(mos6551_device::read), FUNC(mos6551_device::write));
|
||||
map(0x06400, 0x06403).rw("acia2", FUNC(mos6551_device::read), FUNC(mos6551_device::write));
|
||||
map(0x08000, 0x09fff).ram().mirror(0x2000).share("charram");
|
||||
map(0x0c000, 0x0dfff).ram().mirror(0x2000).share("attrram");
|
||||
map(0x10000, 0x1ffff).rom().region("eprom1", 0);
|
||||
map(0x30000, 0x3ffff).rom().region("eprom2", 0);
|
||||
}
|
||||
|
||||
void tv965_state::program_map(address_map &map)
|
||||
{
|
||||
map.global_mask(0x2ffff);
|
||||
map(0x00000, 0x0ffff).rom().region("eprom1", 0);
|
||||
map(0x20000, 0x2ffff).rom().region("eprom2", 0);
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START( tv965 )
|
||||
INPUT_PORTS_END
|
||||
|
||||
MACHINE_CONFIG_START(tv965_state::tv965)
|
||||
MCFG_CPU_ADD("maincpu", G65816, 44.4528_MHz_XTAL / 10)
|
||||
MCFG_CPU_PROGRAM_MAP(mem_map)
|
||||
MCFG_CPU_DATA_MAP(mem_map)
|
||||
MCFG_CPU_PROGRAM_MAP(program_map)
|
||||
|
||||
MCFG_NVRAM_ADD_0FILL("nvram") // CXK5864BP-10L + battery
|
||||
|
||||
@ -59,6 +81,17 @@ MACHINE_CONFIG_START(tv965_state::tv965)
|
||||
MCFG_SCREEN_RAW_PARAMS(26.9892_MHz_XTAL, 1020, 0, 800, 378, 0, 350)
|
||||
//MCFG_SCREEN_RAW_PARAMS(44.4528_MHz_XTAL, 1680, 0, 1320, 378, 0, 350)
|
||||
MCFG_SCREEN_UPDATE_DRIVER(tv965_state, screen_update)
|
||||
|
||||
//MCFG_DEVICE_ADD("crtc", SCN2672, 26.9892_MHz_XTAL / 10)
|
||||
//MCFG_SCN2672_CHARACTER_WIDTH(10)
|
||||
//MCFG_SCN2672_DRAW_CHARACTER_CALLBACK_OWNER(tv965_state, draw_character)
|
||||
//MCFG_VIDEO_SET_SCREEN("screen")
|
||||
|
||||
MCFG_DEVICE_ADD("acia1", MOS6551, 0)
|
||||
MCFG_MOS6551_XTAL(3.6864_MHz_XTAL / 2) // divider not verified, possibly even programmable
|
||||
|
||||
MCFG_DEVICE_ADD("acia2", MOS6551, 0)
|
||||
MCFG_MOS6551_XTAL(3.6864_MHz_XTAL / 2) // divider not verified, possibly even programmable
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
/**************************************************************************************************************
|
||||
@ -73,7 +106,7 @@ ROM_START( tv965 )
|
||||
ROM_REGION(0x10000, "eprom1", 0)
|
||||
ROM_LOAD( "180003-30h.u8", 0x00000, 0x10000, CRC(c7b9ca39) SHA1(1d95a8b0a4ea5caf3fb628c44c7a3567700a0b59) )
|
||||
|
||||
ROM_REGION(0x10000, "eprom2", 0)
|
||||
ROM_REGION(0x10000, "eprom2", ROMREGION_ERASE00)
|
||||
ROM_LOAD( "180003-38h.u9", 0x00000, 0x08000, CRC(30fae408) SHA1(f05bb2a9ce2df60b046733f746d8d8a1eb3ac8bc) )
|
||||
ROM_END
|
||||
|
||||
|
@ -271,6 +271,7 @@ public:
|
||||
void apple2gs(machine_config &config);
|
||||
void apple2gsr1(machine_config &config);
|
||||
void apple2gs_map(address_map &map);
|
||||
void vectors_map(address_map &map);
|
||||
};
|
||||
|
||||
#endif // MAME_INCLUDES_APPLE2GS_H
|
||||
|
@ -1913,7 +1913,7 @@ void apple2gs_state::apple2gs_setup_memory()
|
||||
|
||||
READ8_MEMBER(apple2gs_state::apple2gs_read_vector)
|
||||
{
|
||||
return space.read_byte(offset | 0xFF0000);
|
||||
return m_maincpu->space(AS_PROGRAM).read_byte(offset | 0xFFFFE0);
|
||||
}
|
||||
|
||||
MACHINE_RESET_MEMBER(apple2gs_state,apple2gs)
|
||||
@ -1978,9 +1978,6 @@ MACHINE_START_MEMBER(apple2gs_state,apple2gscommon)
|
||||
m_machinetype = APPLE_IIGS;
|
||||
apple2eplus_init_common(nullptr);
|
||||
|
||||
/* set up Apple IIgs vectoring */
|
||||
m_maincpu->set_read_vector_callback(read8_delegate(FUNC(apple2gs_state::apple2gs_read_vector),this));
|
||||
|
||||
/* setup globals */
|
||||
m_is_rom3 = true;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user