g65816: Allow use of separate address spaces for program, data, opcodes and/or vectors

This commit is contained in:
AJR 2018-03-20 20:50:22 -04:00
parent 3330975244
commit 71c9b2fa06
10 changed files with 108 additions and 32 deletions

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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)];

View File

@ -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 &params) override;
private:

View File

@ -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;

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -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;