mirror of
https://github.com/holub/mame
synced 2025-07-04 09:28:51 +03:00
tidy up for pull request
This commit is contained in:
parent
17e3abc6b7
commit
24dba19f8c
File diff suppressed because it is too large
Load Diff
@ -137,6 +137,7 @@ enum clipper_exception_vectors
|
||||
EXCEPTION_INTERRUPT_BASE = 0x800,
|
||||
};
|
||||
|
||||
// trap source values are shifted into the correct field in the psw
|
||||
enum clipper_cpu_trap_sources
|
||||
{
|
||||
CTS_NO_CPU_TRAP = 0 << 24,
|
||||
@ -157,6 +158,10 @@ enum clipper_memory_trap_sources
|
||||
MTS_WRITE_PROTECT_FAULT = 7 << 28,
|
||||
};
|
||||
|
||||
// convenience macros for frequently used instruction fields
|
||||
#define R1 (m_info.r1)
|
||||
#define R2 (m_info.r2)
|
||||
|
||||
// convenience macros for dealing with the psw
|
||||
#define PSW(mask) (m_psw & PSW_##mask)
|
||||
#define SSW(mask) (m_ssw & SSW_##mask)
|
||||
@ -176,27 +181,27 @@ enum clipper_memory_trap_sources
|
||||
#define UF_SUB(a, b) ((b > 0) && (a < INT_MIN + b))
|
||||
|
||||
// CLIPPER logic for carry and overflow flags
|
||||
#define C_ADD(a, b) ((uint32_t)a + (uint32_t)b < (uint32_t)a)
|
||||
#define V_ADD(a, b) (OF_ADD((int32_t)a, (int32_t)b) || UF_ADD((int32_t)a, (int32_t)b))
|
||||
#define C_SUB(a, b) ((uint32_t)a < (uint32_t)b)
|
||||
#define V_SUB(a, b) (OF_SUB((int32_t)a, (int32_t)b) || UF_SUB((int32_t)a, (int32_t)b))
|
||||
#define C_ADD(a, b) ((u32)a + (u32)b < (u32)a)
|
||||
#define V_ADD(a, b) (OF_ADD((s32)a, (s32)b) || UF_ADD((s32)a, (s32)b))
|
||||
#define C_SUB(a, b) ((u32)a < (u32)b)
|
||||
#define V_SUB(a, b) (OF_SUB((s32)a, (s32)b) || UF_SUB((s32)a, (s32)b))
|
||||
|
||||
class clipper_device : public cpu_device
|
||||
{
|
||||
public:
|
||||
clipper_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
clipper_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, u32 clock, const char *shortname, const char *source);
|
||||
|
||||
DECLARE_READ_LINE_MEMBER(ssw) { return m_ssw; }
|
||||
|
||||
bool supervisor_mode() { return SSW(U) == 0; }
|
||||
bool mapped_mode() { return SSW(M) != 0; }
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
// device_execute_interface overrides
|
||||
virtual uint32_t execute_min_cycles() const override { return 1; };
|
||||
virtual uint32_t execute_max_cycles() const override { return 1; }; // FIXME: don't know, especially macro instructions
|
||||
virtual uint32_t execute_input_lines() const override { return 2; }; // number of input/interrupt lines (irq/nmi)
|
||||
virtual u32 execute_min_cycles() const override { return 1; };
|
||||
virtual u32 execute_max_cycles() const override { return 1; }; // FIXME: don't know, especially macro instructions
|
||||
virtual u32 execute_input_lines() const override { return 2; }; // number of input/interrupt lines (irq/nmi)
|
||||
virtual void execute_run() override;
|
||||
virtual void execute_set_input(int inputnum, int state) override;
|
||||
|
||||
@ -213,17 +218,17 @@ protected:
|
||||
// device_disasm_interface overrides
|
||||
virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } // smallest instruction
|
||||
virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } // largest instruction
|
||||
virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override;
|
||||
virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override;
|
||||
|
||||
// core registers
|
||||
uint32_t m_pc;
|
||||
uint32_t m_psw;
|
||||
uint32_t m_ssw;
|
||||
u32 m_pc;
|
||||
u32 m_psw;
|
||||
u32 m_ssw;
|
||||
|
||||
// integer registers
|
||||
int32_t *m_r; // active registers
|
||||
int32_t m_ru[16]; // user registers
|
||||
int32_t m_rs[16]; // supervisor registers
|
||||
s32 *m_r; // active registers
|
||||
s32 m_ru[16]; // user registers
|
||||
s32 m_rs[16]; // supervisor registers
|
||||
|
||||
// floating registers
|
||||
double m_f[16];
|
||||
@ -236,37 +241,54 @@ private:
|
||||
address_space *m_data;
|
||||
|
||||
int m_icount;
|
||||
int m_interrupt_cycles;
|
||||
|
||||
int m_irq;
|
||||
int m_nmi;
|
||||
|
||||
// decoded instruction information
|
||||
struct
|
||||
{
|
||||
// decoded operand information
|
||||
union {
|
||||
int32_t imm;
|
||||
uint32_t r2 : 4;
|
||||
uint16_t macro;
|
||||
} op;
|
||||
u8 opcode, subopcode;
|
||||
u8 r1, r2;
|
||||
|
||||
s32 imm;
|
||||
u16 macro;
|
||||
|
||||
// total size of instruction in bytes
|
||||
uint32_t size;
|
||||
u32 size;
|
||||
|
||||
// computed effective address
|
||||
uint32_t address;
|
||||
u32 address;
|
||||
} m_info;
|
||||
|
||||
void clipper_device::decode_instruction(uint16_t insn);
|
||||
int clipper_device::execute_instruction(uint16_t insn);
|
||||
void clipper_device::decode_instruction(u16 insn);
|
||||
int clipper_device::execute_instruction();
|
||||
bool clipper_device::evaluate_branch();
|
||||
|
||||
// condition code evaluation
|
||||
void clipper_device::evaluate_cc2f(double v0, double v1);
|
||||
|
||||
bool clipper_device::evaluate_branch(uint32_t condition);
|
||||
|
||||
uint32_t clipper_device::intrap(uint32_t vector, uint32_t pc, uint32_t cts = CTS_NO_CPU_TRAP, uint32_t mts = MTS_NO_MEMORY_TRAP);
|
||||
uint32_t clipper_device::intrap(u32 vector, u32 pc, u32 cts = CTS_NO_CPU_TRAP, u32 mts = MTS_NO_MEMORY_TRAP);
|
||||
};
|
||||
|
||||
extern const device_type CLIPPER;
|
||||
class clipper_c100_device : public clipper_device
|
||||
{
|
||||
public:
|
||||
clipper_c100_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
};
|
||||
|
||||
class clipper_c300_device : public clipper_device
|
||||
{
|
||||
public:
|
||||
clipper_c300_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
};
|
||||
|
||||
class clipper_c400_device : public clipper_device
|
||||
{
|
||||
public:
|
||||
clipper_c400_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
};
|
||||
|
||||
extern const device_type CLIPPER_C100;
|
||||
extern const device_type CLIPPER_C300;
|
||||
extern const device_type CLIPPER_C400;
|
||||
|
||||
extern CPU_DISASSEMBLE(clipper);
|
||||
#endif /* __CLIPPER_H__ */
|
||||
|
@ -5,10 +5,10 @@
|
||||
|
||||
/*
|
||||
* TODO
|
||||
* * dynamically switch between C400 and C100/C300 instruction sets
|
||||
* * handle failures of addressing mode decoding more elegantly
|
||||
* * improve address decoding to use streams
|
||||
* * detect various cases of illegal instruction encoding
|
||||
* - dynamically switch between C400 and C100/C300 instruction sets
|
||||
* - handle failures of addressing mode decoding more elegantly
|
||||
* - improve address decoding to use streams
|
||||
* - detect various cases of illegal instruction encoding
|
||||
*/
|
||||
|
||||
// enable C400 instruction decoding
|
||||
@ -72,7 +72,7 @@ static const char *const cc[] =
|
||||
/*
|
||||
* Decode an addressing mode into a string.
|
||||
*/
|
||||
char *address (offs_t pc, uint16_t *insn)
|
||||
char *address (offs_t pc, u16 *insn)
|
||||
{
|
||||
static char buffer[32];
|
||||
|
||||
@ -102,8 +102,8 @@ char *address (offs_t pc, uint16_t *insn)
|
||||
*/
|
||||
CPU_DISASSEMBLE(clipper)
|
||||
{
|
||||
uint16_t *insn = (uint16_t *)oprom;
|
||||
uint32_t flags = DASMFLAG_SUPPORTED;
|
||||
u16 *insn = (u16 *)oprom;
|
||||
u32 flags = DASMFLAG_SUPPORTED;
|
||||
offs_t bytes;
|
||||
|
||||
switch (insn[0] >> 8)
|
||||
@ -310,7 +310,7 @@ CPU_DISASSEMBLE(clipper)
|
||||
case 0x3f: util::stream_format(stream, "loadfs r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
|
||||
|
||||
default:
|
||||
util::stream_format(stream, "macro 0x%04x 0x%04x ; invalid", insn[0], insn[1]);
|
||||
util::stream_format(stream, "macro 0x%04x 0x%04x", insn[0], insn[1]);
|
||||
break;
|
||||
}
|
||||
bytes = 4;
|
||||
@ -330,7 +330,7 @@ CPU_DISASSEMBLE(clipper)
|
||||
case 0x07: util::stream_format(stream, "loadts r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
|
||||
#endif
|
||||
default:
|
||||
util::stream_format(stream, "macro 0x%04x %04x", insn[0], insn[1]);
|
||||
util::stream_format(stream, "macro 0x%04x 0x%04x", insn[0], insn[1]);
|
||||
break;
|
||||
}
|
||||
bytes = 4;
|
||||
|
@ -1,30 +1,72 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Patrick Mackinlay
|
||||
|
||||
/*
|
||||
* An implementation of the Fairchild/Intergraph Cache and Memory Management Unit (CAMMU) designed for use with the CLIPPER CPU family.
|
||||
*
|
||||
* Primary reference: http://bitsavers.trailing-edge.com/pdf/fairchild/clipper/CLIPPER%20C300%2032-Bit%20Compute%20Engine.pdf
|
||||
* Another reference: http://www.eecs.berkeley.edu/Pubs/TechRpts/1986/CSD-86-289.pdf
|
||||
*
|
||||
* This implementation is currently at a very early stage, and is only sufficient to handle the bare minimum of boot/diagnostic code.
|
||||
*
|
||||
* TODO
|
||||
* - almost everything
|
||||
* - map registers
|
||||
* - refactor hardware tlb
|
||||
* - address translation
|
||||
* - faults
|
||||
* - tlb
|
||||
* - cache
|
||||
* - bus errors
|
||||
*/
|
||||
|
||||
#include "cammu.h"
|
||||
|
||||
#define VERBOSE 0
|
||||
|
||||
// each variant of the cammu has different registers and a different addressing map
|
||||
// TODO: decode the cammu registers properly
|
||||
DEVICE_ADDRESS_MAP_START(map, 32, cammu_device)
|
||||
DEVICE_ADDRESS_MAP_START(map, 32, cammu_c4t_device)
|
||||
AM_RANGE(0x000, 0xfff) AM_READWRITE(cammu_r, cammu_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
const device_type CAMMU = &device_creator<cammu_device>;
|
||||
DEVICE_ADDRESS_MAP_START(map, 32, cammu_c4i_device)
|
||||
AM_RANGE(0x000, 0xfff) AM_READWRITE(cammu_r, cammu_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
cammu_device::cammu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, CAMMU, "Cache and MMU", tag, owner, clock, "cammu", __FILE__)
|
||||
DEVICE_ADDRESS_MAP_START(map, 32, cammu_c3_device)
|
||||
AM_RANGE(0x000, 0xfff) AM_READWRITE(cammu_r, cammu_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
const device_type CAMMU_C4T = &device_creator<cammu_c4t_device>;
|
||||
const device_type CAMMU_C4I = &device_creator<cammu_c4i_device>;
|
||||
const device_type CAMMU_C3 = &device_creator<cammu_c3_device>;
|
||||
|
||||
cammu_c4t_device::cammu_c4t_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: cammu_device(mconfig, CAMMU_C4T, "C4E/C4T CAMMU", tag, owner, clock, "C4T", __FILE__) { }
|
||||
|
||||
cammu_c4i_device::cammu_c4i_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: cammu_device(mconfig, CAMMU_C4I, "C4I CAMMU", tag, owner, clock, "C4I", __FILE__) { }
|
||||
|
||||
cammu_c3_device::cammu_c3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: cammu_device(mconfig, CAMMU_C4T, "C1/C3 CAMMU", tag, owner, clock, "C3", __FILE__) { }
|
||||
|
||||
cammu_device::cammu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source)
|
||||
: device_t(mconfig, type, name, tag, owner, clock, shortname, source)
|
||||
, device_memory_interface(mconfig, *this),
|
||||
m_main_space_config("main", ENDIANNESS_LITTLE, 32, 32, 0),
|
||||
m_io_space_config("io", ENDIANNESS_LITTLE, 32, 32, 0),
|
||||
m_boot_space_config("boot", ENDIANNESS_LITTLE, 32, 32, 0),
|
||||
m_main_space(nullptr),
|
||||
m_io_space(nullptr),
|
||||
m_boot_space(nullptr)
|
||||
m_boot_space(nullptr),
|
||||
m_ssw_func(*this)
|
||||
{ }
|
||||
|
||||
void cammu_device::device_start()
|
||||
{
|
||||
m_ssw_func.resolve_safe(0);
|
||||
|
||||
m_main_space = &space(AS_0);
|
||||
m_io_space = &space(AS_1);
|
||||
m_boot_space = &space(AS_2);
|
||||
@ -48,70 +90,91 @@ const address_space_config *cammu_device::memory_space_config (address_spacenum
|
||||
|
||||
READ32_MEMBER(cammu_device::mmu_r)
|
||||
{
|
||||
// handle htlb
|
||||
u32 ssw = m_ssw_func();
|
||||
u32 address = offset << 2;
|
||||
|
||||
//if (m_maincpu->supervisor_mode() && (offset & ~0x1FFF) == 0)
|
||||
if ((offset & ~0x1FFF) == 0)
|
||||
// in supervisor mode, the first 8 pages are always mapped via the hard-wired tlb
|
||||
if ((ssw & 0x40000000) == 0 && (address & ~0x7fff) == 0)
|
||||
{
|
||||
switch (offset & 0x3C00)
|
||||
switch (address & 0xf000)
|
||||
{
|
||||
case 0x000:
|
||||
case 0x400:
|
||||
case 0x800:
|
||||
case 0xC00:
|
||||
return m_main_space->read_dword(offset << 2, mem_mask);
|
||||
|
||||
case 0x0000:
|
||||
case 0x1000:
|
||||
case 0x1400:
|
||||
return m_io_space->read_dword((offset & 0x7ff) << 2, mem_mask);
|
||||
case 0x2000:
|
||||
case 0x3000:
|
||||
// pages 0-3: main space pages 0-3
|
||||
return m_main_space->read_dword(address, mem_mask);
|
||||
|
||||
case 0x1800:
|
||||
case 0x1C00:
|
||||
return m_boot_space->read_dword((offset & 0x7ff) << 2, mem_mask);
|
||||
case 0x4000:
|
||||
case 0x5000:
|
||||
// pages 4-5: i/o space pages 0-1
|
||||
return m_io_space->read_dword(address & 0x1fff, mem_mask);
|
||||
|
||||
case 0x6000:
|
||||
case 0x7000:
|
||||
// pages 6-7: boot space pages 0-1
|
||||
return m_boot_space->read_dword(address & 0x1fff, mem_mask);
|
||||
}
|
||||
}
|
||||
|
||||
// address with upper bytes 0 or 0x7f1
|
||||
if ((offset >> 22) == 0x00 || (offset >> 18) == 0x7f1)
|
||||
return m_main_space->read_dword(offset << 2, mem_mask);
|
||||
// FIXME: currently maps addresses with upper bits 0x00 or 0x7f1 to main memory and everything else to I/O
|
||||
if ((address & 0xff000000) == 0x00000000 || (address & 0xfff00000) == 0x7f100000)
|
||||
{
|
||||
#ifdef ICACHE_ENTRIES
|
||||
// if this is an instruction fetch, check the cache first
|
||||
if (space.spacenum() == AS_PROGRAM)
|
||||
{
|
||||
if (m_icache[offset & (ICACHE_ENTRIES-1)].offset != offset)
|
||||
{
|
||||
m_icache[offset & (ICACHE_ENTRIES - 1)].offset = offset;
|
||||
m_icache[offset & (ICACHE_ENTRIES - 1)].data = m_main_space->read_dword(address, mem_mask);
|
||||
}
|
||||
|
||||
return m_icache[offset & (ICACHE_ENTRIES - 1)].data;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return m_main_space->read_dword(address, mem_mask);
|
||||
}
|
||||
else
|
||||
return m_io_space->read_dword(offset << 2, mem_mask);
|
||||
return m_io_space->read_dword(address, mem_mask);
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(cammu_device::mmu_w)
|
||||
{
|
||||
// handle htlb
|
||||
//if (m_maincpu->supervisor_mode() && (offset & ~0x1FFF) == 0)
|
||||
if ((offset & ~0x1FFF) == 0)
|
||||
u32 ssw = m_ssw_func();
|
||||
u32 address = offset << 2;
|
||||
|
||||
// in supervisor mode, the first 8 pages are always mapped via the hard-wired tlb
|
||||
if ((ssw & 0x40000000) == 0 && (address & ~0x7fff) == 0)
|
||||
{
|
||||
switch (offset & 0x3C00)
|
||||
switch (address & 0xf000)
|
||||
{
|
||||
case 0x000:
|
||||
case 0x400:
|
||||
case 0x800:
|
||||
case 0xC00:
|
||||
// pages 0-3: main space
|
||||
m_main_space->write_dword(offset << 2, data, mem_mask);
|
||||
return;
|
||||
|
||||
case 0x0000:
|
||||
case 0x1000:
|
||||
case 0x1400:
|
||||
// pages 4-5: pages 0-1 i/o space
|
||||
m_io_space->write_dword((offset & 0x7ff) << 2, data, mem_mask);
|
||||
case 0x2000:
|
||||
case 0x3000:
|
||||
// pages 0-3: main space pages 0-3
|
||||
m_main_space->write_dword(address, data, mem_mask);
|
||||
return;
|
||||
|
||||
case 0x1800:
|
||||
case 0x1C00:
|
||||
// pages 6-7: pages 0-1 boot space
|
||||
m_boot_space->write_dword((offset & 0x7ff) << 2, data, mem_mask);
|
||||
case 0x4000:
|
||||
case 0x5000:
|
||||
// pages 4-5: i/o space pages 0-1
|
||||
m_io_space->write_dword(address & 0x1fff, data, mem_mask);
|
||||
return;
|
||||
|
||||
case 0x6000:
|
||||
case 0x7000:
|
||||
// pages 6-7: boot space pages 0-1
|
||||
m_boot_space->write_dword(address & 0x1fff, data, mem_mask);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// address with upper byte 0x00 or upper 3 bytes 0x7f1
|
||||
if ((offset >> 22) == 0x00 || (offset >> 18) == 0x7f1)
|
||||
m_main_space->write_dword(offset << 2, data, mem_mask);
|
||||
// FIXME: currently maps addresses with upper bits 0x00 or 0x7f1 to main memory and everything else to I/O
|
||||
if ((address & 0xff000000) == 0x00000000 || (address & 0xfff00000) == 0x7f100000)
|
||||
m_main_space->write_dword(address, data, mem_mask);
|
||||
else
|
||||
m_io_space->write_dword(offset << 2, data, mem_mask);
|
||||
m_io_space->write_dword(address, data, mem_mask);
|
||||
}
|
||||
|
@ -8,12 +8,22 @@
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
// the following enables a very crude instruction cache - it has known (future)
|
||||
// problems, but speeds up cpu execution quite noticeably in the short term by
|
||||
// avoiding some of the delays in the mame memory subsystem
|
||||
#define ICACHE_ENTRIES 32768
|
||||
|
||||
#define MCFG_CAMMU_SSW_CB(_sswcb) \
|
||||
devcb = &cammu_device::static_set_ssw_callback(*device, DEVCB_##_sswcb);
|
||||
|
||||
class cammu_device : public device_t, public device_memory_interface
|
||||
{
|
||||
public:
|
||||
cammu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
cammu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
|
||||
|
||||
virtual DECLARE_ADDRESS_MAP(map, 8);
|
||||
template<class _Object> static devcb_base &static_set_ssw_callback(device_t &device, _Object object) { return downcast<cammu_device &>(device).m_ssw_func.set_callback(object); }
|
||||
|
||||
virtual DECLARE_ADDRESS_MAP(map, 32) = 0;
|
||||
|
||||
DECLARE_READ32_MEMBER(mmu_r);
|
||||
DECLARE_WRITE32_MEMBER(mmu_w);
|
||||
@ -30,6 +40,8 @@ protected:
|
||||
virtual const address_space_config *memory_space_config (address_spacenum spacenum) const override;
|
||||
|
||||
private:
|
||||
devcb_read32 m_ssw_func;
|
||||
|
||||
address_space_config m_main_space_config;
|
||||
address_space_config m_io_space_config;
|
||||
address_space_config m_boot_space_config;
|
||||
@ -39,9 +51,43 @@ private:
|
||||
address_space *m_boot_space;
|
||||
|
||||
u32 m_cammu[1024];
|
||||
|
||||
#ifdef ICACHE_ENTRIES
|
||||
struct icache
|
||||
{
|
||||
u32 offset;
|
||||
u32 data;
|
||||
} m_icache[ICACHE_ENTRIES];
|
||||
#endif
|
||||
};
|
||||
|
||||
// device type definition
|
||||
extern const device_type CAMMU;
|
||||
class cammu_c4t_device : public cammu_device
|
||||
{
|
||||
public:
|
||||
cammu_c4t_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
virtual DECLARE_ADDRESS_MAP(map, 32) override;
|
||||
};
|
||||
|
||||
class cammu_c4i_device : public cammu_device
|
||||
{
|
||||
public:
|
||||
cammu_c4i_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
virtual DECLARE_ADDRESS_MAP(map, 32) override;
|
||||
};
|
||||
|
||||
class cammu_c3_device : public cammu_device
|
||||
{
|
||||
public:
|
||||
cammu_c3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
virtual DECLARE_ADDRESS_MAP(map, 32) override;
|
||||
};
|
||||
|
||||
// device type definitions
|
||||
extern const device_type CAMMU_C4T;
|
||||
extern const device_type CAMMU_C4I;
|
||||
extern const device_type CAMMU_C3;
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user