summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/mc68hc11
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/mc68hc11')
-rw-r--r--src/devices/cpu/mc68hc11/hc11dasm.cpp4
-rw-r--r--src/devices/cpu/mc68hc11/hc11ops.h4
-rw-r--r--src/devices/cpu/mc68hc11/hc11ops.hxx82
-rw-r--r--src/devices/cpu/mc68hc11/mc68hc11.cpp1052
-rw-r--r--src/devices/cpu/mc68hc11/mc68hc11.h168
5 files changed, 921 insertions, 389 deletions
diff --git a/src/devices/cpu/mc68hc11/hc11dasm.cpp b/src/devices/cpu/mc68hc11/hc11dasm.cpp
index c77eaaee08a..f5b6a16657a 100644
--- a/src/devices/cpu/mc68hc11/hc11dasm.cpp
+++ b/src/devices/cpu/mc68hc11/hc11dasm.cpp
@@ -1151,6 +1151,8 @@ offs_t hc11_disassembler::disassemble(std::ostream &stream, offs_t pc, const dat
flags = STEP_OVER;
else if (!strcmp(op_table->mnemonic, "rts") || !strcmp(op_table->mnemonic, "rti"))
flags = STEP_OUT;
+ else if ((opcode >= 0x22 && opcode < 0x30) || !strcmp(op_table->mnemonic, "brset") || !strcmp(op_table->mnemonic, "brclr"))
+ flags = STEP_COND;
switch(op_table->address_mode)
{
@@ -1227,7 +1229,7 @@ offs_t hc11_disassembler::disassemble(std::ostream &stream, offs_t pc, const dat
imm8 = opcodes.r8(cpc++);
mask = opcodes.r8(cpc++);
rel8 = opcodes.r8(cpc++);
- util::stream_format(stream, "%s (Y+0x%02X), 0x%02X, [0x%04X]", op_table->mnemonic, imm8, mask, pc+2+rel8);
+ util::stream_format(stream, "%s (Y+0x%02X), 0x%02X, [0x%04X]", op_table->mnemonic, imm8, mask, pc+5+rel8);
break;
case PAGE2:
diff --git a/src/devices/cpu/mc68hc11/hc11ops.h b/src/devices/cpu/mc68hc11/hc11ops.h
index ee8c538a72f..058aa3cfe17 100644
--- a/src/devices/cpu/mc68hc11/hc11ops.h
+++ b/src/devices/cpu/mc68hc11/hc11ops.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Ville Linde, Angelo Salese, hap
+// copyright-holders:Ville Linde, Angelo Salese
const mc68hc11_cpu_device::hc11_opcode_list_struct mc68hc11_cpu_device::hc11_opcode_list[] =
{
@@ -149,7 +149,7 @@ const mc68hc11_cpu_device::hc11_opcode_list_struct mc68hc11_cpu_device::hc11_opc
{ 0, 0xf8, &HC11OP(eorb_ext) },
{ 0, 0xe8, &HC11OP(eorb_indx) },
{ 0x18, 0xe8, &HC11OP(eorb_indy) },
-// { 0, 0x03, &HC11OP(fdiv) },
+ { 0, 0x03, &HC11OP(fdiv) },
{ 0, 0x02, &HC11OP(idiv) },
{ 0, 0x4c, &HC11OP(inca) },
{ 0, 0x5c, &HC11OP(incb) },
diff --git a/src/devices/cpu/mc68hc11/hc11ops.hxx b/src/devices/cpu/mc68hc11/hc11ops.hxx
index 640bd54342f..3380f39a7bb 100644
--- a/src/devices/cpu/mc68hc11/hc11ops.hxx
+++ b/src/devices/cpu/mc68hc11/hc11ops.hxx
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Ville Linde, Angelo Salese, hap
+// copyright-holders:Ville Linde, Angelo Salese
#define SET_Z8(r) (m_ccr |= ((uint8_t)r == 0) ? CC_Z : 0)
#define SET_Z16(r) (m_ccr |= ((uint16_t)r == 0) ? CC_Z : 0)
@@ -474,7 +474,7 @@ void HC11OP(addd_indx)()
{
uint8_t offset = FETCH();
uint16_t adr = m_ix + offset;
- uint8_t i = READ8(adr);
+ uint16_t i = READ16(adr);
uint32_t r = REG_D + i;
CLEAR_NZVC();
SET_N16(r);
@@ -490,7 +490,7 @@ void HC11OP(addd_indy)()
{
uint8_t offset = FETCH();
uint16_t adr = m_iy + offset;
- uint8_t i = READ8(adr);
+ uint16_t i = READ16(adr);
uint32_t r = REG_D + i;
CLEAR_NZVC();
SET_N16(r);
@@ -1191,7 +1191,7 @@ void HC11OP(brclr_indx)()
CYCLES(7);
}
-/* BRCLR INDX 0x18, 0x1F */
+/* BRCLR INDY 0x18, 0x1F */
void HC11OP(brclr_indy)()
{
uint8_t offset = FETCH();
@@ -1202,7 +1202,7 @@ void HC11OP(brclr_indy)()
if ((i & mask) == 0)
{
- SET_PC(m_ppc + rel + 4);
+ SET_PC(m_ppc + rel + 5);
}
CYCLES(8);
@@ -1216,7 +1216,7 @@ void HC11OP(brset_dir)()
int8_t rel = FETCH();
uint8_t i = READ8(d);
- if(i & mask)
+ if ((~i & mask) == 0)
{
SET_PC(m_ppc + rel + 4);
}
@@ -1253,7 +1253,7 @@ void HC11OP(brset_indy)()
if ((~i & mask) == 0)
{
- SET_PC(m_ppc + rel + 4);
+ SET_PC(m_ppc + rel + 5);
}
CYCLES(8);
@@ -1952,7 +1952,7 @@ void HC11OP(dec_indy)()
/* DES 0x34 */
void HC11OP(des)()
{
- m_ix--;
+ m_sp--;
CYCLES(3);
}
@@ -2099,6 +2099,42 @@ void HC11OP(eorb_indy)()
CYCLES(5);
}
+/* FDIV 0x03 */
+void HC11OP(fdiv)()
+{
+ uint16_t numerator = REG_D;
+ uint16_t denominator = m_ix;
+ uint16_t remainder;
+ uint16_t result;
+
+ CLEAR_ZVC();
+ if(denominator == 0) // divide by zero behaviour
+ {
+ remainder = 0xffff; // TODO: undefined behaviour according to the docs
+ result = 0xffff;
+ logerror("HC11: divide by zero at PC=%04x\n",m_pc-1);
+ m_ccr |= CC_C | CC_V;
+ }
+ else if(denominator <= numerator)
+ {
+ remainder = 0xffff; // TODO: undefined behaviour according to the docs
+ result = 0xffff;
+ logerror("HC11: FDIV overflow at PC=%04x\n",m_pc-1);
+ m_ccr |= CC_V;
+ }
+ else
+ {
+ uint32_t scaled_numerator = numerator * 65536;
+ remainder = scaled_numerator % denominator;
+ result = scaled_numerator / denominator;
+ }
+ m_ix = result;
+ REG_D = remainder;
+ SET_Z16(result);
+
+ CYCLES(41);
+}
+
/* IDIV 0x02 */
void HC11OP(idiv)()
{
@@ -4144,28 +4180,14 @@ void HC11OP(tys)()
/* WAI 0x3E */
void HC11OP(wai)()
{
- if(m_wait_state == 0)
- {
- /* TODO: the following is bogus, pushes regs HERE in an instruction that wants an irq to go out? */
- PUSH16(m_pc);
- PUSH16(m_iy);
- PUSH16(m_ix);
- PUSH8(REG_A);
- PUSH8(REG_B);
- PUSH8(m_ccr);
- CYCLES(14);
- m_wait_state = 1;
- }
- if(m_wait_state == 1)
- {
- SET_PC(m_ppc); // wait for an exception
- CYCLES(1);
- }
- if(m_wait_state == 2)
- {
- m_wait_state = 0;
- CYCLES(1);
- }
+ PUSH16(m_pc);
+ PUSH16(m_iy);
+ PUSH16(m_ix);
+ PUSH8(REG_A);
+ PUSH8(REG_B);
+ PUSH8(m_ccr);
+ CYCLES(14);
+ m_wait_state = 1;
}
/* XGDX 0x8F */
diff --git a/src/devices/cpu/mc68hc11/mc68hc11.cpp b/src/devices/cpu/mc68hc11/mc68hc11.cpp
index d547c29e598..30ef3a30c45 100644
--- a/src/devices/cpu/mc68hc11/mc68hc11.cpp
+++ b/src/devices/cpu/mc68hc11/mc68hc11.cpp
@@ -1,31 +1,41 @@
// license:BSD-3-Clause
-// copyright-holders:Ville Linde, Angelo Salese, hap
+// copyright-holders:Ville Linde, Angelo Salese, AJR
/*
Motorola MC68HC11 emulator
Written by Ville Linde & Angelo Salese
TODO:
-- Interrupts handling is really bare-bones, just to make Hit Poker happy;
-- Timers are really sketchy as per now, only TOC1 is emulated so far;
+- Timers are really sketchy as per now;
- Complete opcodes hook-up;
- Emulate the MC68HC12 (same as HC11 with a bunch of new opcodes);
*/
#include "emu.h"
-#include "debugger.h"
#include "mc68hc11.h"
#include "hc11dasm.h"
+#include <tuple>
+
+#define LOG_IRQ (1U << 1)
+
+#define VERBOSE (0)
+#include "logmacro.h"
+
enum
{
HC11_PC = 1,
HC11_SP,
+ HC11_CCR,
HC11_A,
HC11_B,
+ HC11_D,
HC11_IX,
- HC11_IY
+ HC11_IY,
+ HC11_CONFIG,
+ HC11_INIT,
+ HC11_OPTION
};
#define CC_S 0x80
@@ -42,81 +52,163 @@ static const int div_tab[4] = { 1, 4, 8, 16 };
DEFINE_DEVICE_TYPE(MC68HC11A1, mc68hc11a1_device, "mc68hc11a1", "Motorola MC68HC11A1")
DEFINE_DEVICE_TYPE(MC68HC11D0, mc68hc11d0_device, "mc68hc11d0", "Motorola MC68HC11D0")
+DEFINE_DEVICE_TYPE(MC68HC11E1, mc68hc11e1_device, "mc68hc11e1", "Motorola MC68HC11E1")
+DEFINE_DEVICE_TYPE(MC68HC811E2, mc68hc811e2_device, "mc68hc811e2", "Motorola MC68HC811E2")
+DEFINE_DEVICE_TYPE(MC68HC11F1, mc68hc11f1_device, "mc68hc11f1", "Motorola MC68HC11F1")
DEFINE_DEVICE_TYPE(MC68HC11K1, mc68hc11k1_device, "mc68hc11k1", "Motorola MC68HC11K1")
DEFINE_DEVICE_TYPE(MC68HC11M0, mc68hc11m0_device, "mc68hc11m0", "Motorola MC68HC11M0")
-mc68hc11_cpu_device::mc68hc11_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int reg_bits, uint16_t internal_ram_size, uint8_t init_value, address_map_constructor reg_map)
+mc68hc11_cpu_device::mc68hc11_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint16_t ram_size, uint16_t reg_block_size, uint16_t rom_size, uint16_t eeprom_size, uint8_t init_value, uint8_t config_mask, uint8_t option_mask)
: cpu_device(mconfig, type, tag, owner, clock)
- , m_program_config("program", ENDIANNESS_BIG, 8, 16, 0)
- , m_data_config("data", ENDIANNESS_BIG, 8, internal_ram_size > 1024 ? 11
- : internal_ram_size > 512 ? 10
- : internal_ram_size > 256 ? 9 : 8, 0, address_map_constructor(FUNC(mc68hc11_cpu_device::ram_map), this))
- , m_io_config("I/O", ENDIANNESS_BIG, 8, reg_bits, 0, reg_map)
- , m_port_input_cb{{*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}}
- , m_port_output_cb{{*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}}
- , m_analog_cb{{*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}}
- , m_spi2_data_input_cb(*this)
+ , device_nvram_interface(mconfig, *this, (config_mask & 0xf9) != 0)
+ , m_program_config("program", ENDIANNESS_BIG, 8, 16, 0, address_map_constructor(FUNC(mc68hc11_cpu_device::internal_map), this))
+ , m_irq_asserted(false)
+ , m_port_input_cb(*this, 0xff)
+ , m_port_output_cb(*this)
+ , m_analog_cb(*this, 0)
+ , m_spi2_data_input_cb(*this, 0xff)
, m_spi2_data_output_cb(*this)
- , m_reg_block_size(1 << reg_bits)
- , m_internal_ram_size(internal_ram_size)
+ , m_ram_view(*this, "ram")
+ , m_reg_view(*this, "regs")
+ , m_eeprom_view(*this, "eeprom")
+ , m_eeprom_data(*this, "eeprom")
+ , m_internal_ram_size(ram_size)
+ , m_reg_block_size(reg_block_size)
+ , m_internal_rom_size(rom_size)
+ , m_internal_eeprom_size(eeprom_size)
, m_init_value(init_value)
+ , m_config_mask(config_mask)
+ , m_option_mask(option_mask)
+ , m_config(config_mask & (m_internal_rom_size == 0 ? 0xfd : 0xff) & (m_internal_eeprom_size == 0 ? 0xfe : 0xff))
{
}
-void mc68hc11_cpu_device::ram_map(address_map &map)
+void mc68hc11_cpu_device::internal_map(address_map &map)
{
- map(0, m_internal_ram_size - 1).ram();
+ // TODO: internal ROM
+
+ map(0x0000, 0xffff).view(m_ram_view);
+ for (int pos = 0; pos < 16; pos++)
+ m_ram_view[pos](pos << 12, (pos << 12) + m_internal_ram_size - 1).ram().share("ram");
+ if (m_init_value == 0x00)
+ for (int pos = 0; pos < 16; pos++)
+ m_ram_view[pos + 16]((pos << 12) + m_reg_block_size, (pos << 12) + m_reg_block_size + m_internal_ram_size - 1).ram().share("ram");
+
+ if (m_internal_eeprom_size != 0)
+ {
+ // TODO: allow EEPROM writes in programming mode only, latching address and data
+ map(0x0000, 0xffff).view(m_eeprom_view);
+ if ((m_config_mask & 0xf0) == 0)
+ m_eeprom_view[0](0xb600, 0xb7ff).ram().share(m_eeprom_data);
+ else
+ for (int pos = 0; pos < 16; pos++)
+ m_eeprom_view[pos](((pos + 1) << 12) - m_internal_eeprom_size, ((pos + 1) << 12) - 1).ram().share(m_eeprom_data);
+ }
+
+ map(0x0000, 0xffff).view(m_reg_view);
+ for (int pos = 0; pos < 16; pos++)
+ {
+ m_reg_view[pos](pos << 12, (pos << 12) + m_reg_block_size - 1).unmaprw();
+ mc68hc11_reg_map(m_reg_view[pos], pos << 12);
+ }
}
mc68hc11a1_device::mc68hc11a1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : mc68hc11_cpu_device(mconfig, MC68HC11A1, tag, owner, clock, 6, 256, 0x01,
- address_map_constructor(FUNC(mc68hc11a1_device::io_map), this)) // TODO: also has 512 bytes EEPROM
+ : mc68hc11_cpu_device(mconfig, MC68HC11A1, tag, owner, clock, 256, 64, 0, 512, 0x01, 0x0f, 0xfb)
{
}
mc68hc11d0_device::mc68hc11d0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : mc68hc11_cpu_device(mconfig, MC68HC11D0, tag, owner, clock, 6, 192, 0x00,
- address_map_constructor(FUNC(mc68hc11d0_device::io_map), this))
+ : mc68hc11_cpu_device(mconfig, MC68HC11D0, tag, owner, clock, 192, 64, 0, 0, 0x00, 0x06, 0x3b)
+{
+}
+
+mc68hc11e1_device::mc68hc11e1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : mc68hc11_cpu_device(mconfig, MC68HC11E1, tag, owner, clock, 512, 64, 0, 512, 0x01, 0x0f, 0xfb)
+{
+}
+
+mc68hc811e2_device::mc68hc811e2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : mc68hc11_cpu_device(mconfig, MC68HC811E2, tag, owner, clock, 256, 64, 0, 2048, 0x01, 0xf5, 0xfb)
{
}
+mc68hc11f1_device::mc68hc11f1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : mc68hc11_cpu_device(mconfig, MC68HC11F1, tag, owner, clock, 1024, 96, 0, 512, 0x01, 0xf5, 0xff)
+{
+ m_config &= 0x0f;
+}
+
mc68hc11k1_device::mc68hc11k1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : mc68hc11_cpu_device(mconfig, MC68HC11K1, tag, owner, clock, 7, 768, 0x00,
- address_map_constructor(FUNC(mc68hc11k1_device::io_map), this)) // TODO: also has 640 bytes EEPROM
+ : mc68hc11_cpu_device(mconfig, MC68HC11K1, tag, owner, clock, 768, 128, 0, 640, 0x00, 0xbf, 0xff)
{
}
mc68hc11m0_device::mc68hc11m0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : mc68hc11_cpu_device(mconfig, MC68HC11M0, tag, owner, clock, 8, 1280, 0x00,
- address_map_constructor(FUNC(mc68hc11m0_device::io_map), this))
+ : mc68hc11_cpu_device(mconfig, MC68HC11M0, tag, owner, clock, 1280, 256, 0, 0, 0x00, 0x06, 0xff)
{
}
device_memory_interface::space_config_vector mc68hc11_cpu_device::memory_space_config() const
{
return space_config_vector {
- std::make_pair(AS_PROGRAM, &m_program_config),
- std::make_pair(AS_DATA, &m_data_config),
- std::make_pair(AS_IO, &m_io_config)
+ std::make_pair(AS_PROGRAM, &m_program_config)
};
}
-void mc68hc11_cpu_device::device_resolve_objects()
+std::unique_ptr<util::disasm_interface> mc68hc11_cpu_device::create_disassembler()
{
- for (auto &cb : m_port_input_cb)
- cb.resolve_safe(0xff);
- for (auto &cb : m_port_output_cb)
- cb.resolve_safe();
- for (auto &cb : m_analog_cb)
- cb.resolve_safe(0);
- m_spi2_data_input_cb.resolve_safe(0xff);
- m_spi2_data_output_cb.resolve_safe();
+ return std::make_unique<hc11_disassembler>();
}
-std::unique_ptr<util::disasm_interface> mc68hc11_cpu_device::create_disassembler()
+
+bool mc68hc11_cpu_device::nvram_read(util::read_stream &file)
{
- return std::make_unique<hc11_disassembler>();
+ std::error_condition err;
+ size_t actual;
+
+ std::tie(err, actual) = read(file, &m_eeprom_data[0], m_internal_eeprom_size);
+ if (err || (actual != m_internal_eeprom_size))
+ return false;
+
+ std::tie(err, actual) = read(file, &m_config, 1);
+ if (err || (actual != 1))
+ return false;
+
+ return true;
+}
+
+bool mc68hc11_cpu_device::nvram_write(util::write_stream &file)
+{
+ std::error_condition err;
+ size_t actual;
+
+ std::tie(err, actual) = write(file, &m_eeprom_data[0], m_internal_eeprom_size);
+ if (err)
+ return false;
+
+ std::tie(err, actual) = write(file, &m_config, 1);
+ if (err)
+ return false;
+
+ return true;
+}
+
+void mc68hc11_cpu_device::nvram_default()
+{
+ if ((m_config_mask & 0xf9) == 0)
+ return;
+
+ if (m_internal_eeprom_size != 0)
+ {
+ // use region if it exists
+ memory_region *region = memregion("eeprom");
+ if (region != nullptr)
+ std::copy_n(&region->as_u8(), m_internal_eeprom_size, &m_eeprom_data[0]);
+ else
+ std::fill_n(&m_eeprom_data[0], m_internal_eeprom_size, 0xff);
+ }
}
@@ -167,28 +259,28 @@ uint8_t mc68hc11_cpu_device::pactl_r()
void mc68hc11_cpu_device::pactl_w(uint8_t data)
{
- m_pactl = data & 0x73;
+ m_pactl = data & 0x77;
}
-uint8_t mc68hc11a1_device::pactl_r()
+uint8_t mc68hc11a1_device::pactl_ddra7_r()
{
- return (ddr_r<0>() & 0x80) | mc68hc11_cpu_device::pactl_r();
+ return (ddr_r<0>() & 0x80) | pactl_r();
}
-void mc68hc11a1_device::pactl_w(uint8_t data)
+void mc68hc11a1_device::pactl_ddra7_w(uint8_t data)
{
- mc68hc11_cpu_device::pactl_w(data & 0x73);
+ pactl_w(data & 0x73);
ddr_w<0>((data & 0x80) | 0x78);
}
-uint8_t mc68hc11d0_device::pactl_r()
+uint8_t mc68hc11_cpu_device::pactl_ddra_r()
{
- return (ddr_r<0>() & 0x88) | mc68hc11_cpu_device::pactl_r();
+ return (ddr_r<0>() & 0x88) | pactl_r();
}
-void mc68hc11d0_device::pactl_w(uint8_t data)
+void mc68hc11_cpu_device::pactl_ddra_w(uint8_t data)
{
- mc68hc11_cpu_device::pactl_w(data & 0x73);
+ pactl_w(data & 0x77);
ddr_w<0>((data & 0x88) | 0x70);
}
@@ -202,17 +294,38 @@ void mc68hc11_cpu_device::tcnt_w(offs_t offset, uint8_t data)
logerror("HC11: TCNT%c register write %02x!\n", BIT(offset, 0) ? 'L' : 'H', data);
}
-uint8_t mc68hc11_cpu_device::toc1_r(offs_t offset)
+uint8_t mc68hc11_cpu_device::toc_r(offs_t offset)
{
- return (m_toc1 >> (BIT(offset, 0) ? 0 : 8)) & 0xff;
+ return (m_toc[offset >> 1] >> (BIT(offset, 0) ? 0 : 8)) & 0xff;
}
-void mc68hc11_cpu_device::toc1_w(offs_t offset, uint8_t data)
+void mc68hc11_cpu_device::toc_w(offs_t offset, uint8_t data)
{
+ uint16_t &toc = m_toc[offset >> 1];
if (BIT(offset, 0))
- m_toc1 = (data & 0xff) | (m_toc1 & 0xff00);
+ toc = (data & 0xff) | (toc & 0xff00);
else // TODO: inhibit count for one bus cycle
- m_toc1 = (data << 8) | (m_toc1 & 0xff);
+ toc = (data << 8) | (toc & 0xff);
+}
+
+uint8_t mc68hc11_cpu_device::tctl1_r()
+{
+ return m_tctl1;
+}
+
+void mc68hc11_cpu_device::tctl1_w(uint8_t data)
+{
+ m_tctl1 = data;
+}
+
+uint8_t mc68hc11_cpu_device::tctl2_r()
+{
+ return m_tctl2;
+}
+
+void mc68hc11_cpu_device::tctl2_w(uint8_t data)
+{
+ m_tctl2 = data;
}
uint8_t mc68hc11_cpu_device::tmsk1_r()
@@ -222,6 +335,9 @@ uint8_t mc68hc11_cpu_device::tmsk1_r()
void mc68hc11_cpu_device::tmsk1_w(uint8_t data)
{
+ for (int i = 0; i < 5; i++)
+ if (BIT(m_tflg1 & (m_tmsk1 ^ data), 7 - i))
+ set_irq_state(0x0b + i, BIT(data, 7 - i));
m_tmsk1 = data;
}
@@ -232,12 +348,40 @@ uint8_t mc68hc11_cpu_device::tflg1_r()
void mc68hc11_cpu_device::tflg1_w(uint8_t data)
{
+ for (int i = 0; i < 5; i++)
+ if (BIT(m_tflg1 & data, 7 - i))
+ set_irq_state(0x0b + i, false);
m_tflg1 &= ~data;
}
+uint8_t mc68hc11_cpu_device::tflg2_r()
+{
+ return m_tflg2;
+}
+
+void mc68hc11_cpu_device::tflg2_w(uint8_t data)
+{
+ if (BIT(m_tflg2 & data, 7))
+ set_irq_state(0x10, false);
+ if (BIT(m_tflg2 & data, 6))
+ set_irq_state(0x07, false);
+ m_tflg2 &= ~data;
+}
+
+uint8_t mc68hc11_cpu_device::tmsk2_r()
+{
+ return m_tmsk2;
+}
+
void mc68hc11_cpu_device::tmsk2_w(uint8_t data)
{
- m_pr = data & 3;
+ if (BIT(m_tflg2 & (m_tmsk2 ^ data), 7))
+ set_irq_state(0x10, BIT(data, 7));
+ if (BIT(m_tflg2 & (m_tmsk2 ^ data), 6))
+ set_irq_state(0x07, BIT(data, 6));
+
+ // TODO: prescaler bits are time-protected
+ m_tmsk2 = data;
}
template <int N>
@@ -291,32 +435,78 @@ uint8_t mc68hc11_cpu_device::opt2_r()
return 0;
}
-uint8_t mc68hc11_cpu_device::init_r()
+uint8_t mc68hc11_cpu_device::config_r()
{
- int reg_page = (m_reg_position >> 12) & 0xf;
- int ram_page = (m_ram_position >> 12) & 0xf;
+ return m_config;
+}
- return (ram_page << 4) | reg_page;
+uint8_t mc68hc11_cpu_device::config_1s_r()
+{
+ return m_config | ~m_config_mask;
+}
+
+void mc68hc11_cpu_device::config_w(uint8_t data)
+{
+ // TODO: CONFIG also has EEPROM protection
+ m_config = data & m_config_mask;
+ if (m_internal_eeprom_size != 0)
+ {
+ if (BIT(m_config, 0))
+ m_eeprom_view.select(((m_config_mask & 0xf0) == 0xb0 ? m_init2 : m_config) >> 4);
+ else
+ m_eeprom_view.disable();
+ }
+}
+
+uint8_t mc68hc11_cpu_device::init_r()
+{
+ return m_init;
}
void mc68hc11_cpu_device::init_w(uint8_t data)
{
// TODO: only writeable during first 64 E cycles
+ m_init = data;
+
int reg_page = data & 0xf;
int ram_page = (data >> 4) & 0xf;
if (reg_page == ram_page && m_init_value == 0x00)
{
- m_reg_position = reg_page << 12;
- m_ram_position = (ram_page << 12) + m_reg_block_size;
+ m_reg_view.select(reg_page);
+ m_ram_view.select(ram_page + 16);
}
else
{
- m_reg_position = reg_page << 12;
- m_ram_position = ram_page << 12;
+ m_reg_view.select(reg_page);
+ m_ram_view.select(ram_page);
}
}
+uint8_t mc68hc11_cpu_device::init2_r()
+{
+ return m_init2;
+}
+
+void mc68hc11_cpu_device::init2_w(uint8_t data)
+{
+ m_init2 = data & 0xf0;
+ assert(m_internal_eeprom_size != 0);
+ if (BIT(m_config, 0))
+ m_eeprom_view.select(data >> 4);
+}
+
+uint8_t mc68hc11_cpu_device::option_r()
+{
+ return m_option;
+}
+
+void mc68hc11_cpu_device::option_w(uint8_t data)
+{
+ // TODO: only writeable during first 64 E cycles (except bits 7, 6, 3)
+ m_option = data & m_option_mask;
+}
+
uint8_t mc68hc11_cpu_device::scbd_r(offs_t offset)
{
return 0;
@@ -347,190 +537,316 @@ uint8_t mc68hc11_cpu_device::opt4_r()
return 0;
}
-void mc68hc11a1_device::io_map(address_map &map)
-{
- map(0x00, 0x00).rw(FUNC(mc68hc11a1_device::port_r<0>), FUNC(mc68hc11a1_device::port_w<0>)); // PORTA
- map(0x02, 0x02).r(FUNC(mc68hc11a1_device::pioc_r)); // PIOC
- map(0x03, 0x03).rw(FUNC(mc68hc11a1_device::port_r<2>), FUNC(mc68hc11a1_device::port_w<2>)); // PORTC
- map(0x04, 0x04).rw(FUNC(mc68hc11a1_device::port_r<1>), FUNC(mc68hc11a1_device::port_w<1>)); // PORTB
- map(0x05, 0x05).nopw(); // PORTCL
- map(0x07, 0x07).rw(FUNC(mc68hc11a1_device::ddr_r<2>), FUNC(mc68hc11a1_device::ddr_w<2>)); // DDRC
- map(0x08, 0x08).rw(FUNC(mc68hc11a1_device::port_r<3>), FUNC(mc68hc11a1_device::port_w<3>)); // PORTD
- map(0x09, 0x09).rw(FUNC(mc68hc11a1_device::ddr_r<3>), FUNC(mc68hc11a1_device::ddr_w<3>)); // DDRD
- map(0x0a, 0x0a).r(FUNC(mc68hc11a1_device::port_r<4>)); // PORTE
- map(0x0e, 0x0f).rw(FUNC(mc68hc11a1_device::tcnt_r), FUNC(mc68hc11a1_device::tcnt_w)); // TCNT
- map(0x16, 0x17).rw(FUNC(mc68hc11a1_device::toc1_r), FUNC(mc68hc11a1_device::toc1_w)); // TOC1
- map(0x22, 0x22).rw(FUNC(mc68hc11a1_device::tmsk1_r), FUNC(mc68hc11a1_device::tmsk1_w)); // TMSK1
- map(0x23, 0x23).rw(FUNC(mc68hc11a1_device::tflg1_r), FUNC(mc68hc11a1_device::tflg1_w)); // TFLG1
- map(0x24, 0x24).w(FUNC(mc68hc11a1_device::tmsk2_w)); // TMSK2
- map(0x26, 0x26).rw(FUNC(mc68hc11a1_device::pactl_r), FUNC(mc68hc11a1_device::pactl_w)); // PACTL
- map(0x28, 0x28).r(FUNC(mc68hc11a1_device::spcr_r<0>)).nopw(); // SPCR
- map(0x29, 0x29).r(FUNC(mc68hc11a1_device::spsr_r<0>)).nopw(); // SPSR
- map(0x2a, 0x2a).rw(FUNC(mc68hc11a1_device::spdr_r<0>), FUNC(mc68hc11a1_device::spdr_w<0>)); // SPDR
- map(0x2c, 0x2c).r(FUNC(mc68hc11a1_device::sccr1_r)).nopw(); // SCCR1
- map(0x2d, 0x2d).r(FUNC(mc68hc11a1_device::sccr2_r)).nopw(); // SCCR2
- map(0x30, 0x30).rw(FUNC(mc68hc11a1_device::adctl_r), FUNC(mc68hc11a1_device::adctl_w)); // ADCTL
- map(0x31, 0x34).r(FUNC(mc68hc11a1_device::adr_r)); // ADR1-ADR4
- map(0x39, 0x39).nopw(); // OPTION
- map(0x3a, 0x3a).nopw(); // COPRST (watchdog)
- map(0x3b, 0x3b).nopw(); // PPROG (EEPROM programming)
- map(0x3d, 0x3d).rw(FUNC(mc68hc11a1_device::init_r), FUNC(mc68hc11a1_device::init_w)); // INIT
- map(0x3f, 0x3f).nopw(); // CONFIG
-}
-
-void mc68hc11d0_device::io_map(address_map &map)
-{
- map(0x00, 0x00).rw(FUNC(mc68hc11d0_device::port_r<0>), FUNC(mc68hc11d0_device::port_w<0>)); // PORTA
- map(0x02, 0x02).r(FUNC(mc68hc11d0_device::pioc_r)); // PIOC
- map(0x03, 0x03).rw(FUNC(mc68hc11d0_device::port_r<2>), FUNC(mc68hc11d0_device::port_w<2>)); // PORTC
- map(0x04, 0x04).rw(FUNC(mc68hc11d0_device::port_r<1>), FUNC(mc68hc11d0_device::port_w<1>)); // PORTB
- map(0x06, 0x06).rw(FUNC(mc68hc11d0_device::ddr_r<1>), FUNC(mc68hc11d0_device::ddr_w<1>)); // DDRB
- map(0x07, 0x07).rw(FUNC(mc68hc11d0_device::ddr_r<2>), FUNC(mc68hc11d0_device::ddr_w<2>)); // DDRC
- map(0x08, 0x08).rw(FUNC(mc68hc11d0_device::port_r<3>), FUNC(mc68hc11d0_device::port_w<3>)); // PORTD
- map(0x09, 0x09).rw(FUNC(mc68hc11d0_device::ddr_r<3>), FUNC(mc68hc11d0_device::ddr_w<3>)); // DDRD
- map(0x0e, 0x0f).rw(FUNC(mc68hc11d0_device::tcnt_r), FUNC(mc68hc11d0_device::tcnt_w)); // TCNT
- map(0x16, 0x17).rw(FUNC(mc68hc11d0_device::toc1_r), FUNC(mc68hc11d0_device::toc1_w)); // TOC1
- map(0x22, 0x22).rw(FUNC(mc68hc11d0_device::tmsk1_r), FUNC(mc68hc11d0_device::tmsk1_w)); // TMSK1
- map(0x23, 0x23).rw(FUNC(mc68hc11d0_device::tflg1_r), FUNC(mc68hc11d0_device::tflg1_w)); // TFLG1
- map(0x24, 0x24).w(FUNC(mc68hc11d0_device::tmsk2_w)); // TMSK2
- map(0x26, 0x26).rw(FUNC(mc68hc11d0_device::pactl_r), FUNC(mc68hc11d0_device::pactl_w)); // PACTL
- map(0x28, 0x28).r(FUNC(mc68hc11d0_device::spcr_r<0>)).nopw(); // SPCR
- map(0x29, 0x29).r(FUNC(mc68hc11d0_device::spsr_r<0>)).nopw(); // SPSR
- map(0x2a, 0x2a).rw(FUNC(mc68hc11d0_device::spdr_r<0>), FUNC(mc68hc11d0_device::spdr_w<0>)); // SPDR
- map(0x2c, 0x2c).r(FUNC(mc68hc11d0_device::sccr1_r)).nopw(); // SCCR1
- map(0x2d, 0x2d).r(FUNC(mc68hc11d0_device::sccr2_r)).nopw(); // SCCR2
- map(0x39, 0x39).nopw(); // OPTION
- map(0x3a, 0x3a).nopw(); // COPRST (watchdog)
- map(0x3d, 0x3d).rw(FUNC(mc68hc11d0_device::init_r), FUNC(mc68hc11d0_device::init_w)); // INIT
- map(0x3f, 0x3f).nopw(); // CONFIG
-}
-
-void mc68hc11k1_device::io_map(address_map &map)
-{
- map(0x00, 0x00).rw(FUNC(mc68hc11k1_device::port_r<0>), FUNC(mc68hc11k1_device::port_w<0>)); // PORTA
- map(0x01, 0x01).rw(FUNC(mc68hc11k1_device::ddr_r<0>), FUNC(mc68hc11k1_device::ddr_w<0>)); // DDRA
- map(0x02, 0x02).rw(FUNC(mc68hc11k1_device::ddr_r<1>), FUNC(mc68hc11k1_device::ddr_w<1>)); // DDRB
- map(0x03, 0x03).rw(FUNC(mc68hc11k1_device::ddr_r<5>), FUNC(mc68hc11k1_device::ddr_w<5>)); // DDRF
- map(0x04, 0x04).rw(FUNC(mc68hc11k1_device::port_r<1>), FUNC(mc68hc11k1_device::port_w<1>)); // PORTB
- map(0x05, 0x05).rw(FUNC(mc68hc11k1_device::port_r<5>), FUNC(mc68hc11k1_device::port_w<5>)); // PORTF
- map(0x06, 0x06).rw(FUNC(mc68hc11k1_device::port_r<2>), FUNC(mc68hc11k1_device::port_w<2>)); // PORTC
- map(0x07, 0x07).rw(FUNC(mc68hc11k1_device::ddr_r<2>), FUNC(mc68hc11k1_device::ddr_w<2>)); // DDRC
- map(0x08, 0x08).rw(FUNC(mc68hc11k1_device::port_r<3>), FUNC(mc68hc11k1_device::port_w<3>)); // PORTD
- map(0x09, 0x09).rw(FUNC(mc68hc11k1_device::ddr_r<3>), FUNC(mc68hc11k1_device::ddr_w<3>)); // DDRD
- map(0x0a, 0x0a).r(FUNC(mc68hc11k1_device::port_r<4>)); // PORTE
- map(0x0e, 0x0f).rw(FUNC(mc68hc11k1_device::tcnt_r), FUNC(mc68hc11k1_device::tcnt_w)); // TCNT
- map(0x16, 0x17).rw(FUNC(mc68hc11k1_device::toc1_r), FUNC(mc68hc11k1_device::toc1_w)); // TOC1
- map(0x22, 0x22).rw(FUNC(mc68hc11k1_device::tmsk1_r), FUNC(mc68hc11k1_device::tmsk1_w)); // TMSK1
- map(0x23, 0x23).rw(FUNC(mc68hc11k1_device::tflg1_r), FUNC(mc68hc11k1_device::tflg1_w)); // TFLG1
- map(0x24, 0x24).w(FUNC(mc68hc11k1_device::tmsk2_w)); // TMSK2
- map(0x26, 0x26).rw(FUNC(mc68hc11k1_device::pactl_r), FUNC(mc68hc11k1_device::pactl_w)); // PACTL
- map(0x28, 0x28).r(FUNC(mc68hc11k1_device::spcr_r<0>)).nopw(); // SPCR
- map(0x29, 0x29).r(FUNC(mc68hc11k1_device::spsr_r<0>)).nopw(); // SPSR
- map(0x2a, 0x2a).rw(FUNC(mc68hc11k1_device::spdr_r<0>), FUNC(mc68hc11k1_device::spdr_w<0>)); // SPDR
- map(0x30, 0x30).rw(FUNC(mc68hc11k1_device::adctl_r), FUNC(mc68hc11k1_device::adctl_w)); // ADCTL
- map(0x31, 0x34).r(FUNC(mc68hc11k1_device::adr_r)); // ADR1-ADR4
- map(0x38, 0x38).r(FUNC(mc68hc11k1_device::opt2_r)).nopw(); // OPT2
- map(0x39, 0x39).nopw(); // OPTION
- map(0x3a, 0x3a).nopw(); // COPRST (watchdog)
- map(0x3b, 0x3b).nopw(); // PPROG (EEPROM programming)
- map(0x3d, 0x3d).rw(FUNC(mc68hc11k1_device::init_r), FUNC(mc68hc11k1_device::init_w)); // INIT
- map(0x3f, 0x3f).nopw(); // CONFIG
- map(0x70, 0x71).r(FUNC(mc68hc11k1_device::scbd_r)).nopw(); // SCBD
- map(0x72, 0x72).r(FUNC(mc68hc11k1_device::sccr1_r)).nopw(); // SCCR1
- map(0x73, 0x73).r(FUNC(mc68hc11k1_device::sccr2_r)).nopw(); // SCCR2
- map(0x74, 0x74).r(FUNC(mc68hc11k1_device::scsr1_r)).nopw(); // SCSR1
- map(0x77, 0x77).r(FUNC(mc68hc11k1_device::scrdl_r)).nopw(); // SCRDL
- map(0x7c, 0x7c).rw(FUNC(mc68hc11k1_device::port_r<7>), FUNC(mc68hc11k1_device::port_w<7>)); // PORTH
- map(0x7d, 0x7d).rw(FUNC(mc68hc11k1_device::ddr_r<7>), FUNC(mc68hc11k1_device::ddr_w<7>)); // DDRH
- map(0x7e, 0x7e).rw(FUNC(mc68hc11k1_device::port_r<6>), FUNC(mc68hc11k1_device::port_w<6>)); // PORTG
- map(0x7f, 0x7f).rw(FUNC(mc68hc11k1_device::ddr_r<6>), FUNC(mc68hc11k1_device::ddr_w<6>)); // DDRG
-}
-
-void mc68hc11m0_device::io_map(address_map &map)
-{
- map(0x00, 0x00).rw(FUNC(mc68hc11m0_device::port_r<0>), FUNC(mc68hc11m0_device::port_w<0>)); // PORTA
- map(0x01, 0x01).rw(FUNC(mc68hc11m0_device::ddr_r<0>), FUNC(mc68hc11m0_device::ddr_w<0>)); // DDRA
- map(0x02, 0x02).rw(FUNC(mc68hc11m0_device::ddr_r<1>), FUNC(mc68hc11m0_device::ddr_w<1>)); // DDRB
- map(0x03, 0x03).rw(FUNC(mc68hc11m0_device::ddr_r<5>), FUNC(mc68hc11m0_device::ddr_w<5>)); // DDRF
- map(0x04, 0x04).rw(FUNC(mc68hc11m0_device::port_r<1>), FUNC(mc68hc11m0_device::port_w<1>)); // PORTB
- map(0x05, 0x05).rw(FUNC(mc68hc11m0_device::port_r<5>), FUNC(mc68hc11m0_device::port_w<5>)); // PORTF
- map(0x06, 0x06).rw(FUNC(mc68hc11m0_device::port_r<2>), FUNC(mc68hc11m0_device::port_w<2>)); // PORTC
- map(0x07, 0x07).rw(FUNC(mc68hc11m0_device::ddr_r<2>), FUNC(mc68hc11m0_device::ddr_w<2>)); // DDRC
- map(0x08, 0x08).rw(FUNC(mc68hc11m0_device::port_r<3>), FUNC(mc68hc11m0_device::port_w<3>)); // PORTD
- map(0x09, 0x09).rw(FUNC(mc68hc11m0_device::ddr_r<3>), FUNC(mc68hc11m0_device::ddr_w<3>)); // DDRD
- map(0x0a, 0x0a).r(FUNC(mc68hc11m0_device::port_r<4>)); // PORTE
- map(0x0e, 0x0f).rw(FUNC(mc68hc11m0_device::tcnt_r), FUNC(mc68hc11m0_device::tcnt_w)); // TCNT
- map(0x16, 0x17).rw(FUNC(mc68hc11m0_device::toc1_r), FUNC(mc68hc11m0_device::toc1_w)); // TOC1
- map(0x22, 0x22).rw(FUNC(mc68hc11m0_device::tmsk1_r), FUNC(mc68hc11m0_device::tmsk1_w)); // TMSK1
- map(0x23, 0x23).rw(FUNC(mc68hc11m0_device::tflg1_r), FUNC(mc68hc11m0_device::tflg1_w)); // TFLG1
- map(0x24, 0x24).w(FUNC(mc68hc11m0_device::tmsk2_w)); // TMSK2
- map(0x26, 0x26).rw(FUNC(mc68hc11m0_device::pactl_r), FUNC(mc68hc11m0_device::pactl_w)); // PACTL
- map(0x28, 0x28).r(FUNC(mc68hc11m0_device::spcr_r<0>)).nopw(); // SPCR1
- map(0x29, 0x29).r(FUNC(mc68hc11m0_device::spsr_r<0>)).nopw(); // SPSR1
- map(0x2a, 0x2a).rw(FUNC(mc68hc11m0_device::spdr_r<0>), FUNC(mc68hc11m0_device::spdr_w<0>)); // SPDR1
- map(0x30, 0x30).rw(FUNC(mc68hc11m0_device::adctl_r), FUNC(mc68hc11m0_device::adctl_w)); // ADCTL
- map(0x31, 0x34).r(FUNC(mc68hc11m0_device::adr_r)); // ADR1-ADR4
- map(0x38, 0x38).r(FUNC(mc68hc11m0_device::opt2_r)).nopw(); // OPT2
- map(0x39, 0x39).nopw(); // OPTION
- map(0x3a, 0x3a).nopw(); // COPRST (watchdog)
- map(0x3d, 0x3d).rw(FUNC(mc68hc11m0_device::init_r), FUNC(mc68hc11m0_device::init_w)); // INIT
- map(0x3f, 0x3f).nopw(); // CONFIG
- map(0x70, 0x71).r(FUNC(mc68hc11m0_device::scbd_r)).nopw(); // SCBD
- map(0x72, 0x72).r(FUNC(mc68hc11m0_device::sccr1_r)).nopw(); // SCCR1
- map(0x73, 0x73).r(FUNC(mc68hc11m0_device::sccr2_r)).nopw(); // SCCR2
- map(0x74, 0x74).r(FUNC(mc68hc11m0_device::scsr1_r)); // SCSR1
- map(0x77, 0x77).r(FUNC(mc68hc11m0_device::scrdl_r)).nopw(); // SCRDL
- map(0x7c, 0x7c).rw(FUNC(mc68hc11m0_device::port_r<7>), FUNC(mc68hc11m0_device::port_w<7>)); // PORTH
- map(0x7d, 0x7d).rw(FUNC(mc68hc11m0_device::ddr_r<7>), FUNC(mc68hc11m0_device::ddr_w<7>)); // DDRH
- map(0x7e, 0x7e).rw(FUNC(mc68hc11m0_device::port_r<6>), FUNC(mc68hc11m0_device::port_w<6>)); // PORTG
- map(0x7f, 0x7f).rw(FUNC(mc68hc11m0_device::ddr_r<6>), FUNC(mc68hc11m0_device::ddr_w<6>)); // DDRG
- map(0x88, 0x88).r(FUNC(mc68hc11m0_device::spcr_r<1>)).nopw(); // SPCR2
- map(0x89, 0x89).r(FUNC(mc68hc11m0_device::spsr_r<1>)).nopw(); // SPSR2
- map(0x8a, 0x8a).rw(FUNC(mc68hc11m0_device::spdr_r<1>), FUNC(mc68hc11m0_device::spdr_w<1>)); // SPDR2
- map(0x8b, 0x8b).r(FUNC(mc68hc11m0_device::opt4_r)).nopw(); // OPT4
+uint8_t mc68hc11d0_device::reg01_r()
+{
+ // "Reserved" according to datasheet; asma2k reads from here due to a programming error and writes value back to TFLG1
+ return 0xff;
+}
+
+void mc68hc11a1_device::mc68hc11_reg_map(memory_view::memory_view_entry &block, offs_t base)
+{
+ block(base + 0x00, base + 0x00).rw(FUNC(mc68hc11a1_device::port_r<0>), FUNC(mc68hc11a1_device::port_w<0>)); // PORTA
+ block(base + 0x02, base + 0x02).r(FUNC(mc68hc11a1_device::pioc_r)); // PIOC
+ block(base + 0x03, base + 0x03).rw(FUNC(mc68hc11a1_device::port_r<2>), FUNC(mc68hc11a1_device::port_w<2>)); // PORTC
+ block(base + 0x04, base + 0x04).rw(FUNC(mc68hc11a1_device::port_r<1>), FUNC(mc68hc11a1_device::port_w<1>)); // PORTB
+ block(base + 0x05, base + 0x05).nopw(); // PORTCL
+ block(base + 0x07, base + 0x07).rw(FUNC(mc68hc11a1_device::ddr_r<2>), FUNC(mc68hc11a1_device::ddr_w<2>)); // DDRC
+ block(base + 0x08, base + 0x08).rw(FUNC(mc68hc11a1_device::port_r<3>), FUNC(mc68hc11a1_device::port_w<3>)); // PORTD
+ block(base + 0x09, base + 0x09).rw(FUNC(mc68hc11a1_device::ddr_r<3>), FUNC(mc68hc11a1_device::ddr_w<3>)); // DDRD
+ block(base + 0x0a, base + 0x0a).r(FUNC(mc68hc11a1_device::port_r<4>)); // PORTE
+ block(base + 0x0e, base + 0x0f).rw(FUNC(mc68hc11a1_device::tcnt_r), FUNC(mc68hc11a1_device::tcnt_w)); // TCNT
+ block(base + 0x16, base + 0x1f).rw(FUNC(mc68hc11a1_device::toc_r), FUNC(mc68hc11a1_device::toc_w)); // TOC1-TOC5
+ block(base + 0x20, base + 0x20).rw(FUNC(mc68hc11a1_device::tctl1_r), FUNC(mc68hc11a1_device::tctl1_w)); // TCTL1
+ block(base + 0x21, base + 0x21).rw(FUNC(mc68hc11a1_device::tctl2_r), FUNC(mc68hc11a1_device::tctl2_w)); // TCTL2
+ block(base + 0x22, base + 0x22).rw(FUNC(mc68hc11a1_device::tmsk1_r), FUNC(mc68hc11a1_device::tmsk1_w)); // TMSK1
+ block(base + 0x23, base + 0x23).rw(FUNC(mc68hc11a1_device::tflg1_r), FUNC(mc68hc11a1_device::tflg1_w)); // TFLG1
+ block(base + 0x24, base + 0x24).rw(FUNC(mc68hc11a1_device::tmsk2_r), FUNC(mc68hc11a1_device::tmsk2_w)); // TMSK2
+ block(base + 0x25, base + 0x25).rw(FUNC(mc68hc11a1_device::tflg2_r), FUNC(mc68hc11a1_device::tflg2_w)); // TFLG2
+ block(base + 0x26, base + 0x26).rw(FUNC(mc68hc11a1_device::pactl_ddra7_r), FUNC(mc68hc11a1_device::pactl_ddra7_w)); // PACTL
+ block(base + 0x28, base + 0x28).r(FUNC(mc68hc11a1_device::spcr_r<0>)).nopw(); // SPCR
+ block(base + 0x29, base + 0x29).r(FUNC(mc68hc11a1_device::spsr_r<0>)).nopw(); // SPSR
+ block(base + 0x2a, base + 0x2a).rw(FUNC(mc68hc11a1_device::spdr_r<0>), FUNC(mc68hc11a1_device::spdr_w<0>)); // SPDR
+ block(base + 0x2c, base + 0x2c).r(FUNC(mc68hc11a1_device::sccr1_r)).nopw(); // SCCR1
+ block(base + 0x2d, base + 0x2d).r(FUNC(mc68hc11a1_device::sccr2_r)).nopw(); // SCCR2
+ block(base + 0x30, base + 0x30).rw(FUNC(mc68hc11a1_device::adctl_r), FUNC(mc68hc11a1_device::adctl_w)); // ADCTL
+ block(base + 0x31, base + 0x34).r(FUNC(mc68hc11a1_device::adr_r)); // ADR1-ADR4
+ block(base + 0x39, base + 0x39).rw(FUNC(mc68hc11a1_device::option_r), FUNC(mc68hc11a1_device::option_w)); // OPTION
+ block(base + 0x3a, base + 0x3a).nopw(); // COPRST (watchdog)
+ block(base + 0x3b, base + 0x3b).nopw(); // PPROG (EEPROM programming)
+ block(base + 0x3d, base + 0x3d).rw(FUNC(mc68hc11a1_device::init_r), FUNC(mc68hc11a1_device::init_w)); // INIT
+ block(base + 0x3f, base + 0x3f).rw(FUNC(mc68hc11a1_device::config_r), FUNC(mc68hc11a1_device::config_w)); // CONFIG
+}
+
+void mc68hc11d0_device::mc68hc11_reg_map(memory_view::memory_view_entry &block, offs_t base)
+{
+ block(base + 0x00, base + 0x00).rw(FUNC(mc68hc11d0_device::port_r<0>), FUNC(mc68hc11d0_device::port_w<0>)); // PORTA
+ block(base + 0x01, base + 0x01).r(FUNC(mc68hc11d0_device::reg01_r));
+ block(base + 0x02, base + 0x02).r(FUNC(mc68hc11d0_device::pioc_r)); // PIOC
+ block(base + 0x03, base + 0x03).rw(FUNC(mc68hc11d0_device::port_r<2>), FUNC(mc68hc11d0_device::port_w<2>)); // PORTC
+ block(base + 0x04, base + 0x04).rw(FUNC(mc68hc11d0_device::port_r<1>), FUNC(mc68hc11d0_device::port_w<1>)); // PORTB
+ block(base + 0x06, base + 0x06).rw(FUNC(mc68hc11d0_device::ddr_r<1>), FUNC(mc68hc11d0_device::ddr_w<1>)); // DDRB
+ block(base + 0x07, base + 0x07).rw(FUNC(mc68hc11d0_device::ddr_r<2>), FUNC(mc68hc11d0_device::ddr_w<2>)); // DDRC
+ block(base + 0x08, base + 0x08).rw(FUNC(mc68hc11d0_device::port_r<3>), FUNC(mc68hc11d0_device::port_w<3>)); // PORTD
+ block(base + 0x09, base + 0x09).rw(FUNC(mc68hc11d0_device::ddr_r<3>), FUNC(mc68hc11d0_device::ddr_w<3>)); // DDRD
+ block(base + 0x0e, base + 0x0f).rw(FUNC(mc68hc11d0_device::tcnt_r), FUNC(mc68hc11d0_device::tcnt_w)); // TCNT
+ block(base + 0x16, base + 0x1f).rw(FUNC(mc68hc11d0_device::toc_r), FUNC(mc68hc11d0_device::toc_w)); // TOC1-TOC4, TI4/O5
+ block(base + 0x20, base + 0x20).rw(FUNC(mc68hc11d0_device::tctl1_r), FUNC(mc68hc11d0_device::tctl1_w)); // TCTL1
+ block(base + 0x21, base + 0x21).rw(FUNC(mc68hc11d0_device::tctl2_r), FUNC(mc68hc11d0_device::tctl2_w)); // TCTL2
+ block(base + 0x22, base + 0x22).rw(FUNC(mc68hc11d0_device::tmsk1_r), FUNC(mc68hc11d0_device::tmsk1_w)); // TMSK1
+ block(base + 0x23, base + 0x23).rw(FUNC(mc68hc11d0_device::tflg1_r), FUNC(mc68hc11d0_device::tflg1_w)); // TFLG1
+ block(base + 0x24, base + 0x24).rw(FUNC(mc68hc11d0_device::tmsk2_r), FUNC(mc68hc11d0_device::tmsk2_w)); // TMSK2
+ block(base + 0x25, base + 0x25).rw(FUNC(mc68hc11d0_device::tflg2_r), FUNC(mc68hc11d0_device::tflg2_w)); // TFLG2
+ block(base + 0x26, base + 0x26).rw(FUNC(mc68hc11d0_device::pactl_ddra_r), FUNC(mc68hc11d0_device::pactl_ddra_w)); // PACTL
+ block(base + 0x28, base + 0x28).r(FUNC(mc68hc11d0_device::spcr_r<0>)).nopw(); // SPCR
+ block(base + 0x29, base + 0x29).r(FUNC(mc68hc11d0_device::spsr_r<0>)).nopw(); // SPSR
+ block(base + 0x2a, base + 0x2a).rw(FUNC(mc68hc11d0_device::spdr_r<0>), FUNC(mc68hc11d0_device::spdr_w<0>)); // SPDR
+ block(base + 0x2c, base + 0x2c).r(FUNC(mc68hc11d0_device::sccr1_r)).nopw(); // SCCR1
+ block(base + 0x2d, base + 0x2d).r(FUNC(mc68hc11d0_device::sccr2_r)).nopw(); // SCCR2
+ block(base + 0x2e, base + 0x2e).lr8([] { return 0xc0; }, "scsr_r").nopw(); // SCSR
+ block(base + 0x2f, base + 0x2f).nopw(); // SCDR
+ block(base + 0x39, base + 0x39).rw(FUNC(mc68hc11d0_device::option_r), FUNC(mc68hc11d0_device::option_w)); // OPTION
+ block(base + 0x3a, base + 0x3a).nopw(); // COPRST (watchdog)
+ block(base + 0x3d, base + 0x3d).rw(FUNC(mc68hc11d0_device::init_r), FUNC(mc68hc11d0_device::init_w)); // INIT
+ block(base + 0x3f, base + 0x3f).rw(FUNC(mc68hc11d0_device::config_r), FUNC(mc68hc11d0_device::config_w)); // CONFIG
+}
+
+void mc68hc11e1_device::mc68hc11_reg_map(memory_view::memory_view_entry &block, offs_t base)
+{
+ block(base + 0x00, base + 0x00).rw(FUNC(mc68hc11e1_device::port_r<0>), FUNC(mc68hc11e1_device::port_w<0>)); // PORTA
+ block(base + 0x02, base + 0x02).r(FUNC(mc68hc11e1_device::pioc_r)); // PIOC
+ block(base + 0x03, base + 0x03).rw(FUNC(mc68hc11e1_device::port_r<2>), FUNC(mc68hc11e1_device::port_w<2>)); // PORTC
+ block(base + 0x04, base + 0x04).rw(FUNC(mc68hc11e1_device::port_r<1>), FUNC(mc68hc11e1_device::port_w<1>)); // PORTB
+ block(base + 0x05, base + 0x05).nopw(); // PORTCL
+ block(base + 0x07, base + 0x07).rw(FUNC(mc68hc11e1_device::ddr_r<2>), FUNC(mc68hc11e1_device::ddr_w<2>)); // DDRC
+ block(base + 0x08, base + 0x08).rw(FUNC(mc68hc11e1_device::port_r<3>), FUNC(mc68hc11e1_device::port_w<3>)); // PORTD
+ block(base + 0x09, base + 0x09).rw(FUNC(mc68hc11e1_device::ddr_r<3>), FUNC(mc68hc11e1_device::ddr_w<3>)); // DDRD
+ block(base + 0x0a, base + 0x0a).r(FUNC(mc68hc11e1_device::port_r<4>)); // PORTE
+ block(base + 0x0e, base + 0x0f).rw(FUNC(mc68hc11e1_device::tcnt_r), FUNC(mc68hc11e1_device::tcnt_w)); // TCNT
+ block(base + 0x16, base + 0x1f).rw(FUNC(mc68hc11e1_device::toc_r), FUNC(mc68hc11e1_device::toc_w)); // TOC1-TOC4, TI4/O5
+ block(base + 0x20, base + 0x20).rw(FUNC(mc68hc11e1_device::tctl1_r), FUNC(mc68hc11e1_device::tctl1_w)); // TCTL1
+ block(base + 0x21, base + 0x21).rw(FUNC(mc68hc11e1_device::tctl2_r), FUNC(mc68hc11e1_device::tctl2_w)); // TCTL2
+ block(base + 0x22, base + 0x22).rw(FUNC(mc68hc11e1_device::tmsk1_r), FUNC(mc68hc11e1_device::tmsk1_w)); // TMSK1
+ block(base + 0x23, base + 0x23).rw(FUNC(mc68hc11e1_device::tflg1_r), FUNC(mc68hc11e1_device::tflg1_w)); // TFLG1
+ block(base + 0x24, base + 0x24).rw(FUNC(mc68hc11e1_device::tmsk2_r), FUNC(mc68hc11e1_device::tmsk2_w)); // TMSK2
+ block(base + 0x25, base + 0x25).rw(FUNC(mc68hc11e1_device::tflg2_r), FUNC(mc68hc11e1_device::tflg2_w)); // TFLG2
+ block(base + 0x26, base + 0x26).rw(FUNC(mc68hc11e1_device::pactl_ddra_r), FUNC(mc68hc11e1_device::pactl_ddra_w)); // PACTL
+ block(base + 0x28, base + 0x28).r(FUNC(mc68hc11e1_device::spcr_r<0>)).nopw(); // SPCR
+ block(base + 0x29, base + 0x29).r(FUNC(mc68hc11e1_device::spsr_r<0>)).nopw(); // SPSR
+ block(base + 0x2a, base + 0x2a).rw(FUNC(mc68hc11e1_device::spdr_r<0>), FUNC(mc68hc11e1_device::spdr_w<0>)); // SPDR
+ block(base + 0x2c, base + 0x2c).r(FUNC(mc68hc11e1_device::sccr1_r)).nopw(); // SCCR1
+ block(base + 0x2d, base + 0x2d).r(FUNC(mc68hc11e1_device::sccr2_r)).nopw(); // SCCR2
+ block(base + 0x30, base + 0x30).rw(FUNC(mc68hc11e1_device::adctl_r), FUNC(mc68hc11e1_device::adctl_w)); // ADCTL
+ block(base + 0x31, base + 0x34).r(FUNC(mc68hc11e1_device::adr_r)); // ADR1-ADR4
+ block(base + 0x39, base + 0x39).rw(FUNC(mc68hc11e1_device::option_r), FUNC(mc68hc11e1_device::option_w)); // OPTION
+ block(base + 0x3a, base + 0x3a).nopw(); // COPRST (watchdog)
+ block(base + 0x3b, base + 0x3b).nopw(); // PPROG (EEPROM programming)
+ block(base + 0x3d, base + 0x3d).rw(FUNC(mc68hc11e1_device::init_r), FUNC(mc68hc11e1_device::init_w)); // INIT
+ block(base + 0x3f, base + 0x3f).rw(FUNC(mc68hc11e1_device::config_r), FUNC(mc68hc11e1_device::config_w)); // CONFIG
+}
+
+void mc68hc811e2_device::mc68hc11_reg_map(memory_view::memory_view_entry &block, offs_t base)
+{
+ block(base + 0x00, base + 0x00).rw(FUNC(mc68hc811e2_device::port_r<0>), FUNC(mc68hc811e2_device::port_w<0>)); // PORTA
+ block(base + 0x02, base + 0x02).r(FUNC(mc68hc811e2_device::pioc_r)); // PIOC
+ block(base + 0x03, base + 0x03).rw(FUNC(mc68hc811e2_device::port_r<2>), FUNC(mc68hc811e2_device::port_w<2>)); // PORTC
+ block(base + 0x04, base + 0x04).rw(FUNC(mc68hc811e2_device::port_r<1>), FUNC(mc68hc811e2_device::port_w<1>)); // PORTB
+ block(base + 0x05, base + 0x05).nopw(); // PORTCL
+ block(base + 0x07, base + 0x07).rw(FUNC(mc68hc811e2_device::ddr_r<2>), FUNC(mc68hc811e2_device::ddr_w<2>)); // DDRC
+ block(base + 0x08, base + 0x08).rw(FUNC(mc68hc811e2_device::port_r<3>), FUNC(mc68hc811e2_device::port_w<3>)); // PORTD
+ block(base + 0x09, base + 0x09).rw(FUNC(mc68hc811e2_device::ddr_r<3>), FUNC(mc68hc811e2_device::ddr_w<3>)); // DDRD
+ block(base + 0x0a, base + 0x0a).r(FUNC(mc68hc811e2_device::port_r<4>)); // PORTE
+ block(base + 0x0e, base + 0x0f).rw(FUNC(mc68hc811e2_device::tcnt_r), FUNC(mc68hc811e2_device::tcnt_w)); // TCNT
+ block(base + 0x16, base + 0x1f).rw(FUNC(mc68hc811e2_device::toc_r), FUNC(mc68hc811e2_device::toc_w)); // TOC1-TOC4, TI4/O5
+ block(base + 0x20, base + 0x20).rw(FUNC(mc68hc811e2_device::tctl1_r), FUNC(mc68hc811e2_device::tctl1_w)); // TCTL1
+ block(base + 0x21, base + 0x21).rw(FUNC(mc68hc811e2_device::tctl2_r), FUNC(mc68hc811e2_device::tctl2_w)); // TCTL2
+ block(base + 0x22, base + 0x22).rw(FUNC(mc68hc811e2_device::tmsk1_r), FUNC(mc68hc811e2_device::tmsk1_w)); // TMSK1
+ block(base + 0x23, base + 0x23).rw(FUNC(mc68hc811e2_device::tflg1_r), FUNC(mc68hc811e2_device::tflg1_w)); // TFLG1
+ block(base + 0x24, base + 0x24).rw(FUNC(mc68hc811e2_device::tmsk2_r), FUNC(mc68hc811e2_device::tmsk2_w)); // TMSK2
+ block(base + 0x25, base + 0x25).rw(FUNC(mc68hc811e2_device::tflg2_r), FUNC(mc68hc811e2_device::tflg2_w)); // TFLG2
+ block(base + 0x26, base + 0x26).rw(FUNC(mc68hc811e2_device::pactl_ddra_r), FUNC(mc68hc811e2_device::pactl_ddra_w)); // PACTL
+ block(base + 0x28, base + 0x28).r(FUNC(mc68hc811e2_device::spcr_r<0>)).nopw(); // SPCR
+ block(base + 0x29, base + 0x29).r(FUNC(mc68hc811e2_device::spsr_r<0>)).nopw(); // SPSR
+ block(base + 0x2a, base + 0x2a).rw(FUNC(mc68hc811e2_device::spdr_r<0>), FUNC(mc68hc811e2_device::spdr_w<0>)); // SPDR
+ block(base + 0x2c, base + 0x2c).r(FUNC(mc68hc811e2_device::sccr1_r)).nopw(); // SCCR1
+ block(base + 0x2d, base + 0x2d).r(FUNC(mc68hc811e2_device::sccr2_r)).nopw(); // SCCR2
+ block(base + 0x30, base + 0x30).rw(FUNC(mc68hc811e2_device::adctl_r), FUNC(mc68hc811e2_device::adctl_w)); // ADCTL
+ block(base + 0x31, base + 0x34).r(FUNC(mc68hc811e2_device::adr_r)); // ADR1-ADR4
+ block(base + 0x39, base + 0x39).rw(FUNC(mc68hc811e2_device::option_r), FUNC(mc68hc811e2_device::option_w)); // OPTION
+ block(base + 0x3a, base + 0x3a).nopw(); // COPRST (watchdog)
+ block(base + 0x3b, base + 0x3b).nopw(); // PPROG (EEPROM programming)
+ block(base + 0x3d, base + 0x3d).rw(FUNC(mc68hc811e2_device::init_r), FUNC(mc68hc811e2_device::init_w)); // INIT
+ block(base + 0x3f, base + 0x3f).rw(FUNC(mc68hc811e2_device::config_r), FUNC(mc68hc811e2_device::config_w)); // CONFIG
+}
+
+void mc68hc11f1_device::mc68hc11_reg_map(memory_view::memory_view_entry &block, offs_t base)
+{
+ block(base + 0x00, base + 0x00).rw(FUNC(mc68hc11f1_device::port_r<0>), FUNC(mc68hc11f1_device::port_w<0>)); // PORTA
+ block(base + 0x01, base + 0x01).rw(FUNC(mc68hc11f1_device::ddr_r<0>), FUNC(mc68hc11f1_device::ddr_w<0>)); // DDRA
+ block(base + 0x02, base + 0x02).rw(FUNC(mc68hc11f1_device::port_r<6>), FUNC(mc68hc11f1_device::port_w<6>)); // PORTG
+ block(base + 0x03, base + 0x03).rw(FUNC(mc68hc11f1_device::ddr_r<6>), FUNC(mc68hc11f1_device::ddr_w<6>)); // DDRG
+ block(base + 0x04, base + 0x04).rw(FUNC(mc68hc11f1_device::port_r<1>), FUNC(mc68hc11f1_device::port_w<1>)); // PORTB
+ block(base + 0x05, base + 0x05).rw(FUNC(mc68hc11f1_device::port_r<5>), FUNC(mc68hc11f1_device::port_w<5>)); // PORTF
+ block(base + 0x06, base + 0x06).rw(FUNC(mc68hc11f1_device::port_r<2>), FUNC(mc68hc11f1_device::port_w<2>)); // PORTC
+ block(base + 0x07, base + 0x07).rw(FUNC(mc68hc11f1_device::ddr_r<2>), FUNC(mc68hc11f1_device::ddr_w<2>)); // DDRC
+ block(base + 0x08, base + 0x08).rw(FUNC(mc68hc11f1_device::port_r<3>), FUNC(mc68hc11f1_device::port_w<3>)); // PORTD
+ block(base + 0x09, base + 0x09).rw(FUNC(mc68hc11f1_device::ddr_r<3>), FUNC(mc68hc11f1_device::ddr_w<3>)); // DDRD
+ block(base + 0x0a, base + 0x0a).r(FUNC(mc68hc11f1_device::port_r<4>)); // PORTE
+ block(base + 0x0b, base + 0x0b).nopw(); // CFORC
+ block(base + 0x0c, base + 0x0c).nopw(); // OC1M
+ block(base + 0x0d, base + 0x0d).nopw(); // OC1D
+ block(base + 0x0e, base + 0x0f).rw(FUNC(mc68hc11f1_device::tcnt_r), FUNC(mc68hc11f1_device::tcnt_w)); // TCNT
+ block(base + 0x10, base + 0x11).nopr(); // TIC1
+ block(base + 0x12, base + 0x13).nopr(); // TIC2
+ block(base + 0x14, base + 0x15).nopr(); // TIC3
+ block(base + 0x16, base + 0x1f).rw(FUNC(mc68hc11f1_device::toc_r), FUNC(mc68hc11f1_device::toc_w)); // TOC1-TOC4, TI4/O5
+ block(base + 0x20, base + 0x20).rw(FUNC(mc68hc11f1_device::tctl1_r), FUNC(mc68hc11f1_device::tctl1_w)); // TCTL1
+ block(base + 0x21, base + 0x21).rw(FUNC(mc68hc11f1_device::tctl2_r), FUNC(mc68hc11f1_device::tctl2_w)); // TCTL2
+ block(base + 0x22, base + 0x22).rw(FUNC(mc68hc11f1_device::tmsk1_r), FUNC(mc68hc11f1_device::tmsk1_w)); // TMSK1
+ block(base + 0x23, base + 0x23).rw(FUNC(mc68hc11f1_device::tflg1_r), FUNC(mc68hc11f1_device::tflg1_w)); // TFLG1
+ block(base + 0x24, base + 0x24).rw(FUNC(mc68hc11f1_device::tmsk2_r), FUNC(mc68hc11f1_device::tmsk2_w)); // TMSK2
+ block(base + 0x25, base + 0x25).rw(FUNC(mc68hc11f1_device::tflg2_r), FUNC(mc68hc11f1_device::tflg2_w)); // TFLG2
+ block(base + 0x26, base + 0x26).rw(FUNC(mc68hc11f1_device::pactl_r), FUNC(mc68hc11f1_device::pactl_w)); // PACTL
+ block(base + 0x27, base + 0x27).nopw(); // PACNT
+ block(base + 0x28, base + 0x28).r(FUNC(mc68hc11f1_device::spcr_r<0>)).nopw(); // SPCR
+ block(base + 0x29, base + 0x29).r(FUNC(mc68hc11f1_device::spsr_r<0>)).nopw(); // SPSR
+ block(base + 0x2a, base + 0x2a).rw(FUNC(mc68hc11f1_device::spdr_r<0>), FUNC(mc68hc11f1_device::spdr_w<0>)); // SPDR
+ block(base + 0x2b, base + 0x2b).nopw(); // BAUD
+ block(base + 0x2c, base + 0x2c).r(FUNC(mc68hc11f1_device::sccr1_r)).nopw(); // SCCR1
+ block(base + 0x2d, base + 0x2d).r(FUNC(mc68hc11f1_device::sccr2_r)).nopw(); // SCCR2
+ block(base + 0x2e, base + 0x2e).r(FUNC(mc68hc11f1_device::scsr1_r)); // SCSR
+ block(base + 0x2f, base + 0x2f).nopw(); // SCDR
+ block(base + 0x30, base + 0x30).rw(FUNC(mc68hc11f1_device::adctl_r), FUNC(mc68hc11f1_device::adctl_w)); // ADCTL
+ block(base + 0x31, base + 0x34).r(FUNC(mc68hc11f1_device::adr_r)); // ADR1-ADR4
+ block(base + 0x35, base + 0x35).nopw(); // BPROT
+ block(base + 0x38, base + 0x38).nopw(); // OPT2
+ block(base + 0x39, base + 0x39).rw(FUNC(mc68hc11f1_device::option_r), FUNC(mc68hc11f1_device::option_w)); // OPTION
+ block(base + 0x3a, base + 0x3a).nopw(); // COPRST (watchdog)
+ block(base + 0x3b, base + 0x3b).nopw(); // PPROG (EEPROM programming)
+ block(base + 0x3c, base + 0x3c).nopw(); // HPRIO
+ block(base + 0x3d, base + 0x3d).rw(FUNC(mc68hc11f1_device::init_r), FUNC(mc68hc11f1_device::init_w)); // INIT
+ block(base + 0x3e, base + 0x3e).nopw(); // TEST1
+ block(base + 0x3f, base + 0x3f).rw(FUNC(mc68hc11f1_device::config_1s_r), FUNC(mc68hc11f1_device::config_w)); // CONFIG
+ block(base + 0x5c, base + 0x5c).nopw(); // CSSTRH
+ block(base + 0x5d, base + 0x5d).nopw(); // CSSTRL
+ block(base + 0x5e, base + 0x5e).nopw(); // CSGADR
+ block(base + 0x5f, base + 0x5f).nopw(); // CSGSIZ
+}
+
+void mc68hc11k1_device::mc68hc11_reg_map(memory_view::memory_view_entry &block, offs_t base)
+{
+ block(base + 0x00, base + 0x00).rw(FUNC(mc68hc11k1_device::port_r<0>), FUNC(mc68hc11k1_device::port_w<0>)); // PORTA
+ block(base + 0x01, base + 0x01).rw(FUNC(mc68hc11k1_device::ddr_r<0>), FUNC(mc68hc11k1_device::ddr_w<0>)); // DDRA
+ block(base + 0x02, base + 0x02).rw(FUNC(mc68hc11k1_device::ddr_r<1>), FUNC(mc68hc11k1_device::ddr_w<1>)); // DDRB
+ block(base + 0x03, base + 0x03).rw(FUNC(mc68hc11k1_device::ddr_r<5>), FUNC(mc68hc11k1_device::ddr_w<5>)); // DDRF
+ block(base + 0x04, base + 0x04).rw(FUNC(mc68hc11k1_device::port_r<1>), FUNC(mc68hc11k1_device::port_w<1>)); // PORTB
+ block(base + 0x05, base + 0x05).rw(FUNC(mc68hc11k1_device::port_r<5>), FUNC(mc68hc11k1_device::port_w<5>)); // PORTF
+ block(base + 0x06, base + 0x06).rw(FUNC(mc68hc11k1_device::port_r<2>), FUNC(mc68hc11k1_device::port_w<2>)); // PORTC
+ block(base + 0x07, base + 0x07).rw(FUNC(mc68hc11k1_device::ddr_r<2>), FUNC(mc68hc11k1_device::ddr_w<2>)); // DDRC
+ block(base + 0x08, base + 0x08).rw(FUNC(mc68hc11k1_device::port_r<3>), FUNC(mc68hc11k1_device::port_w<3>)); // PORTD
+ block(base + 0x09, base + 0x09).rw(FUNC(mc68hc11k1_device::ddr_r<3>), FUNC(mc68hc11k1_device::ddr_w<3>)); // DDRD
+ block(base + 0x0a, base + 0x0a).r(FUNC(mc68hc11k1_device::port_r<4>)); // PORTE
+ block(base + 0x0e, base + 0x0f).rw(FUNC(mc68hc11k1_device::tcnt_r), FUNC(mc68hc11k1_device::tcnt_w)); // TCNT
+ block(base + 0x16, base + 0x1f).rw(FUNC(mc68hc11k1_device::toc_r), FUNC(mc68hc11k1_device::toc_w)); // TOC1-TOC4, TI4/O5
+ block(base + 0x20, base + 0x20).rw(FUNC(mc68hc11k1_device::tctl1_r), FUNC(mc68hc11k1_device::tctl1_w)); // TCTL1
+ block(base + 0x21, base + 0x21).rw(FUNC(mc68hc11k1_device::tctl2_r), FUNC(mc68hc11k1_device::tctl2_w)); // TCTL2
+ block(base + 0x22, base + 0x22).rw(FUNC(mc68hc11k1_device::tmsk1_r), FUNC(mc68hc11k1_device::tmsk1_w)); // TMSK1
+ block(base + 0x23, base + 0x23).rw(FUNC(mc68hc11k1_device::tflg1_r), FUNC(mc68hc11k1_device::tflg1_w)); // TFLG1
+ block(base + 0x24, base + 0x24).rw(FUNC(mc68hc11k1_device::tmsk2_r), FUNC(mc68hc11k1_device::tmsk2_w)); // TMSK2
+ block(base + 0x25, base + 0x25).rw(FUNC(mc68hc11k1_device::tflg2_r), FUNC(mc68hc11k1_device::tflg2_w)); // TFLG2
+ block(base + 0x26, base + 0x26).rw(FUNC(mc68hc11k1_device::pactl_r), FUNC(mc68hc11k1_device::pactl_w)); // PACTL
+ block(base + 0x28, base + 0x28).r(FUNC(mc68hc11k1_device::spcr_r<0>)).nopw(); // SPCR
+ block(base + 0x29, base + 0x29).r(FUNC(mc68hc11k1_device::spsr_r<0>)).nopw(); // SPSR
+ block(base + 0x2a, base + 0x2a).rw(FUNC(mc68hc11k1_device::spdr_r<0>), FUNC(mc68hc11k1_device::spdr_w<0>)); // SPDR
+ block(base + 0x30, base + 0x30).rw(FUNC(mc68hc11k1_device::adctl_r), FUNC(mc68hc11k1_device::adctl_w)); // ADCTL
+ block(base + 0x31, base + 0x34).r(FUNC(mc68hc11k1_device::adr_r)); // ADR1-ADR4
+ block(base + 0x37, base + 0x37).rw(FUNC(mc68hc11k1_device::init2_r), FUNC(mc68hc11k1_device::init2_w)); // INIT2
+ block(base + 0x38, base + 0x38).r(FUNC(mc68hc11k1_device::opt2_r)).nopw(); // OPT2
+ block(base + 0x39, base + 0x39).rw(FUNC(mc68hc11k1_device::option_r), FUNC(mc68hc11k1_device::option_w)); // OPTION
+ block(base + 0x3a, base + 0x3a).nopw(); // COPRST (watchdog)
+ block(base + 0x3b, base + 0x3b).nopw(); // PPROG (EEPROM programming)
+ block(base + 0x3d, base + 0x3d).rw(FUNC(mc68hc11k1_device::init_r), FUNC(mc68hc11k1_device::init_w)); // INIT
+ block(base + 0x3f, base + 0x3f).rw(FUNC(mc68hc11k1_device::config_1s_r), FUNC(mc68hc11k1_device::config_w)); // CONFIG
+ block(base + 0x70, base + 0x71).r(FUNC(mc68hc11k1_device::scbd_r)).nopw(); // SCBD
+ block(base + 0x72, base + 0x72).r(FUNC(mc68hc11k1_device::sccr1_r)).nopw(); // SCCR1
+ block(base + 0x73, base + 0x73).r(FUNC(mc68hc11k1_device::sccr2_r)).nopw(); // SCCR2
+ block(base + 0x74, base + 0x74).r(FUNC(mc68hc11k1_device::scsr1_r)).nopw(); // SCSR1
+ block(base + 0x77, base + 0x77).r(FUNC(mc68hc11k1_device::scrdl_r)).nopw(); // SCRDL
+ block(base + 0x7c, base + 0x7c).rw(FUNC(mc68hc11k1_device::port_r<7>), FUNC(mc68hc11k1_device::port_w<7>)); // PORTH
+ block(base + 0x7d, base + 0x7d).rw(FUNC(mc68hc11k1_device::ddr_r<7>), FUNC(mc68hc11k1_device::ddr_w<7>)); // DDRH
+ block(base + 0x7e, base + 0x7e).rw(FUNC(mc68hc11k1_device::port_r<6>), FUNC(mc68hc11k1_device::port_w<6>)); // PORTG
+ block(base + 0x7f, base + 0x7f).rw(FUNC(mc68hc11k1_device::ddr_r<6>), FUNC(mc68hc11k1_device::ddr_w<6>)); // DDRG
+}
+
+void mc68hc11m0_device::mc68hc11_reg_map(memory_view::memory_view_entry &block, offs_t base)
+{
+ block(base + 0x00, base + 0x00).rw(FUNC(mc68hc11m0_device::port_r<0>), FUNC(mc68hc11m0_device::port_w<0>)); // PORTA
+ block(base + 0x01, base + 0x01).rw(FUNC(mc68hc11m0_device::ddr_r<0>), FUNC(mc68hc11m0_device::ddr_w<0>)); // DDRA
+ block(base + 0x02, base + 0x02).rw(FUNC(mc68hc11m0_device::ddr_r<1>), FUNC(mc68hc11m0_device::ddr_w<1>)); // DDRB
+ block(base + 0x03, base + 0x03).rw(FUNC(mc68hc11m0_device::ddr_r<5>), FUNC(mc68hc11m0_device::ddr_w<5>)); // DDRF
+ block(base + 0x04, base + 0x04).rw(FUNC(mc68hc11m0_device::port_r<1>), FUNC(mc68hc11m0_device::port_w<1>)); // PORTB
+ block(base + 0x05, base + 0x05).rw(FUNC(mc68hc11m0_device::port_r<5>), FUNC(mc68hc11m0_device::port_w<5>)); // PORTF
+ block(base + 0x06, base + 0x06).rw(FUNC(mc68hc11m0_device::port_r<2>), FUNC(mc68hc11m0_device::port_w<2>)); // PORTC
+ block(base + 0x07, base + 0x07).rw(FUNC(mc68hc11m0_device::ddr_r<2>), FUNC(mc68hc11m0_device::ddr_w<2>)); // DDRC
+ block(base + 0x08, base + 0x08).rw(FUNC(mc68hc11m0_device::port_r<3>), FUNC(mc68hc11m0_device::port_w<3>)); // PORTD
+ block(base + 0x09, base + 0x09).rw(FUNC(mc68hc11m0_device::ddr_r<3>), FUNC(mc68hc11m0_device::ddr_w<3>)); // DDRD
+ block(base + 0x0a, base + 0x0a).r(FUNC(mc68hc11m0_device::port_r<4>)); // PORTE
+ block(base + 0x0e, base + 0x0f).rw(FUNC(mc68hc11m0_device::tcnt_r), FUNC(mc68hc11m0_device::tcnt_w)); // TCNT
+ block(base + 0x16, base + 0x1f).rw(FUNC(mc68hc11m0_device::toc_r), FUNC(mc68hc11m0_device::toc_w)); // TOC1-TOC4, TI4/O5
+ block(base + 0x20, base + 0x20).rw(FUNC(mc68hc11m0_device::tctl1_r), FUNC(mc68hc11m0_device::tctl1_w)); // TCTL1
+ block(base + 0x21, base + 0x21).rw(FUNC(mc68hc11m0_device::tctl2_r), FUNC(mc68hc11m0_device::tctl2_w)); // TCTL2
+ block(base + 0x22, base + 0x22).rw(FUNC(mc68hc11m0_device::tmsk1_r), FUNC(mc68hc11m0_device::tmsk1_w)); // TMSK1
+ block(base + 0x23, base + 0x23).rw(FUNC(mc68hc11m0_device::tflg1_r), FUNC(mc68hc11m0_device::tflg1_w)); // TFLG1
+ block(base + 0x24, base + 0x24).rw(FUNC(mc68hc11m0_device::tmsk2_r), FUNC(mc68hc11m0_device::tmsk2_w)); // TMSK2
+ block(base + 0x25, base + 0x25).rw(FUNC(mc68hc11m0_device::tflg2_r), FUNC(mc68hc11m0_device::tflg2_w)); // TFLG2
+ block(base + 0x26, base + 0x26).rw(FUNC(mc68hc11m0_device::pactl_r), FUNC(mc68hc11m0_device::pactl_w)); // PACTL
+ block(base + 0x28, base + 0x28).r(FUNC(mc68hc11m0_device::spcr_r<0>)).nopw(); // SPCR1
+ block(base + 0x29, base + 0x29).r(FUNC(mc68hc11m0_device::spsr_r<0>)).nopw(); // SPSR1
+ block(base + 0x2a, base + 0x2a).rw(FUNC(mc68hc11m0_device::spdr_r<0>), FUNC(mc68hc11m0_device::spdr_w<0>)); // SPDR1
+ block(base + 0x30, base + 0x30).rw(FUNC(mc68hc11m0_device::adctl_r), FUNC(mc68hc11m0_device::adctl_w)); // ADCTL
+ block(base + 0x31, base + 0x34).r(FUNC(mc68hc11m0_device::adr_r)); // ADR1-ADR4
+ block(base + 0x38, base + 0x38).r(FUNC(mc68hc11m0_device::opt2_r)).nopw(); // OPT2
+ block(base + 0x39, base + 0x39).rw(FUNC(mc68hc11m0_device::option_r), FUNC(mc68hc11m0_device::option_w)); // OPTION
+ block(base + 0x3a, base + 0x3a).nopw(); // COPRST (watchdog)
+ block(base + 0x3d, base + 0x3d).rw(FUNC(mc68hc11m0_device::init_r), FUNC(mc68hc11m0_device::init_w)); // INIT
+ block(base + 0x3f, base + 0x3f).rw(FUNC(mc68hc11m0_device::config_r), FUNC(mc68hc11m0_device::config_w)); // CONFIG
+ block(base + 0x70, base + 0x71).r(FUNC(mc68hc11m0_device::scbd_r)).nopw(); // SCBD
+ block(base + 0x72, base + 0x72).r(FUNC(mc68hc11m0_device::sccr1_r)).nopw(); // SCCR1
+ block(base + 0x73, base + 0x73).r(FUNC(mc68hc11m0_device::sccr2_r)).nopw(); // SCCR2
+ block(base + 0x74, base + 0x74).r(FUNC(mc68hc11m0_device::scsr1_r)); // SCSR1
+ block(base + 0x77, base + 0x77).r(FUNC(mc68hc11m0_device::scrdl_r)).nopw(); // SCRDL
+ block(base + 0x7c, base + 0x7c).rw(FUNC(mc68hc11m0_device::port_r<7>), FUNC(mc68hc11m0_device::port_w<7>)); // PORTH
+ block(base + 0x7d, base + 0x7d).rw(FUNC(mc68hc11m0_device::ddr_r<7>), FUNC(mc68hc11m0_device::ddr_w<7>)); // DDRH
+ block(base + 0x7e, base + 0x7e).rw(FUNC(mc68hc11m0_device::port_r<6>), FUNC(mc68hc11m0_device::port_w<6>)); // PORTG
+ block(base + 0x7f, base + 0x7f).rw(FUNC(mc68hc11m0_device::ddr_r<6>), FUNC(mc68hc11m0_device::ddr_w<6>)); // DDRG
+ block(base + 0x88, base + 0x88).r(FUNC(mc68hc11m0_device::spcr_r<1>)).nopw(); // SPCR2
+ block(base + 0x89, base + 0x89).r(FUNC(mc68hc11m0_device::spsr_r<1>)).nopw(); // SPSR2
+ block(base + 0x8a, base + 0x8a).rw(FUNC(mc68hc11m0_device::spdr_r<1>), FUNC(mc68hc11m0_device::spdr_w<1>)); // SPDR2
+ block(base + 0x8b, base + 0x8b).r(FUNC(mc68hc11m0_device::opt4_r)).nopw(); // OPT4
}
/*****************************************************************************/
uint8_t mc68hc11_cpu_device::FETCH()
{
- return m_cache->read_byte(m_pc++);
+ return m_cache.read_byte(m_pc++);
}
uint16_t mc68hc11_cpu_device::FETCH16()
{
uint16_t w;
- w = m_cache->read_word(m_pc);
+ w = m_cache.read_word(m_pc);
m_pc += 2;
return w;
}
uint8_t mc68hc11_cpu_device::READ8(uint32_t address)
{
- if(address >= m_reg_position && (address - m_reg_position) < m_reg_block_size)
- {
- return m_io->read_byte(address-m_reg_position);
- }
- else if(address >= m_ram_position && address < m_ram_position+m_internal_ram_size)
- {
- return m_data->read_byte(address-m_ram_position);
- }
- return m_program->read_byte(address);
+ return m_program.read_byte(address);
}
void mc68hc11_cpu_device::WRITE8(uint32_t address, uint8_t value)
{
- if(address >= m_reg_position && (address - m_reg_position) < m_reg_block_size)
- {
- m_io->write_byte(address-m_reg_position, value);
- return;
- }
- else if(address >= m_ram_position && address < m_ram_position+m_internal_ram_size)
- {
- m_data->write_byte(address-m_ram_position, value);
- return;
- }
- m_program->write_byte(address, value);
+ m_program.write_byte(address, value);
}
uint16_t mc68hc11_cpu_device::READ16(uint32_t address)
@@ -581,10 +897,8 @@ void mc68hc11_cpu_device::device_start()
}
}
- m_program = &space(AS_PROGRAM);
- m_cache = m_program->cache<0, 0, ENDIANNESS_BIG>();
- m_data = &space(AS_DATA);
- m_io = &space(AS_IO);
+ space(AS_PROGRAM).cache(m_cache);
+ space(AS_PROGRAM).specific(m_program);
save_item(NAME(m_pc));
save_item(NAME(m_ix));
@@ -596,21 +910,29 @@ void mc68hc11_cpu_device::device_start()
save_item(NAME(m_d.d8.b));
save_item(NAME(m_adctl));
save_item(NAME(m_ad_channel));
- save_item(NAME(m_ram_position));
- save_item(NAME(m_reg_position));
+ save_item(NAME(m_init));
save_item(NAME(m_irq_state));
+ save_item(NAME(m_irq_asserted));
save_item(NAME(m_wait_state));
save_item(NAME(m_stop_state));
+ save_item(NAME(m_tctl1));
+ save_item(NAME(m_tctl2));
save_item(NAME(m_tflg1));
save_item(NAME(m_tmsk1));
- save_item(NAME(m_toc1));
+ save_item(NAME(m_toc));
save_item(NAME(m_tcnt));
// save_item(NAME(m_por));
- save_item(NAME(m_pr));
+ save_item(NAME(m_tflg2));
+ save_item(NAME(m_tmsk2));
save_item(NAME(m_pactl));
save_item(NAME(m_frc_base));
+ save_item(NAME(m_reset_time));
save_item(NAME(m_port_data));
save_item(NAME(m_port_dir));
+ save_item(NAME(m_config));
+ save_item(NAME(m_option));
+ if ((m_config_mask & 0xf0) == 0xb0)
+ save_item(NAME(m_init2));
m_pc = 0;
m_d.d16 = 0;
@@ -620,19 +942,27 @@ void mc68hc11_cpu_device::device_start()
m_ppc = 0;
m_adctl = 0;
m_ad_channel = 0;
- m_irq_state[0] = m_irq_state[1] = 0;
- m_ram_position = 0;
- m_reg_position = 0;
+ m_irq_state = 0;
+ m_init = 0;
+ m_init2 = 0;
+ m_option = 0;
m_tflg1 = 0;
m_tmsk1 = 0;
std::fill(std::begin(m_port_data), std::end(m_port_data), 0x00);
- state_add( HC11_PC, "PC", m_pc).formatstr("%04X");
- state_add( HC11_SP, "SP", m_sp).formatstr("%04X");
- state_add( HC11_A, "A", m_d.d8.a).formatstr("%02X");
- state_add( HC11_B, "B", m_d.d8.b).formatstr("%02X");
- state_add( HC11_IX, "IX", m_ix).formatstr("%04X");
- state_add( HC11_IY, "IY", m_iy).formatstr("%04X");
+ state_add( HC11_PC, "PC", m_pc);
+ state_add( HC11_SP, "SP", m_sp);
+ state_add( HC11_CCR, "CCR", m_ccr);
+ state_add( HC11_A, "A", m_d.d8.a);
+ state_add( HC11_B, "B", m_d.d8.b);
+ state_add( HC11_D, "D", m_d.d16).noshow();
+ state_add( HC11_IX, "IX", m_ix);
+ state_add( HC11_IY, "IY", m_iy);
+
+ using namespace std::placeholders;
+ state_add( HC11_CONFIG, "CONFIG", m_config, std::bind(&mc68hc11_cpu_device::config_w, this, _1)).mask(m_config_mask).formatstr("%02X");
+ state_add( HC11_INIT, "INIT", m_init, std::bind(&mc68hc11_cpu_device::init_w, this, _1));
+ state_add( HC11_OPTION, "OPTION", m_option).mask(m_option_mask);
state_add( STATE_GENPC, "GENPC", m_pc).noshow();
state_add( STATE_GENPCBASE, "CURPC", m_pc).noshow();
@@ -663,17 +993,43 @@ void mc68hc11_cpu_device::state_string_export(const device_state_entry &entry, s
void mc68hc11_cpu_device::device_reset()
{
- m_pc = READ16(0xfffe);
- m_wait_state = 0;
+ if ((m_config_mask & 0xf9) == 0)
+ {
+ m_config = m_config_mask;
+ if (m_internal_rom_size == 0)
+ m_config &= 0xfd;
+ }
+ else
+ {
+ if ((m_config_mask & 0xf0) == 0xb0)
+ m_init2 = 0;
+ if (m_internal_eeprom_size != 0)
+ {
+ if (BIT(m_config, 0))
+ m_eeprom_view.select(m_config_mask < 0xf0 ? 0 : m_config >> 4);
+ else
+ m_eeprom_view.disable();
+ }
+ }
+
+ m_wait_state = 1;
m_stop_state = 0;
m_ccr = CC_X | CC_I | CC_S;
init_w(m_init_value);
- m_toc1 = 0xffff;
+ m_option = 0x10;
+ std::fill(std::begin(m_toc), std::end(m_toc), 0xffff);
m_tcnt = 0xffff;
// m_por = 1; // for first timer overflow / compare stuff
- m_pr = 3; // timer prescale
+ m_tctl1 = 0;
+ m_tctl2 = 0;
+ m_tflg1 = 0;
+ m_tflg2 = 0;
+ m_tmsk2 = 3; // timer prescale
m_pactl = 0;
- m_frc_base = 0;
+ m_irq_state = 0x80000000 | (m_irq_state & 0x04000000);
+ if (m_irq_asserted)
+ set_irq_state(0x06, true);
+ m_frc_base = m_reset_time = total_cycles();
std::fill(std::begin(m_port_dir), std::end(m_port_dir), 0x00);
}
@@ -691,83 +1047,119 @@ void mc68hc11d0_device::device_reset()
{
mc68hc11_cpu_device::device_reset();
- m_port_data[0] &= 0x7f;
+ m_port_data[0] &= 0x8f;
ddr_w<0>(0x70);
}
-/*
-IRQ table vectors:
-0xffd6: SCI
-0xffd8: SPI
-0xffda: Pulse Accumulator Input Edge
-0xffdc: Pulse Accumulator Overflow
-0xffde: Timer Overflow
-0xffe0: Timer Output Capture 5
-0xffe2: Timer Output Capture 4
-0xffe4: Timer Output Capture 3
-0xffe6: Timer Output Capture 2
-0xffe8: Timer Output Capture 1
-0xffea: Timer Input Capture 3
-0xffec: Timer Input Capture 2
-0xffee: Timer Input Capture 1
-0xfff0: Real Time Int
-0xfff2: IRQ
-0xfff4: XIRQ
-0xfff6: SWI (Trap IRQ)
-0xfff8: Illegal Opcode (NMI)
-0xfffa: CO-Processor Fail
-0xfffc: Clock Monitor
-0xfffe: RESET
-*/
+void mc68hc11e1_device::device_reset()
+{
+ mc68hc11_cpu_device::device_reset();
-void mc68hc11_cpu_device::check_irq_lines()
+ m_port_data[0] &= 0x8f;
+ m_port_data[1] = 0x00;
+ ddr_w<0>(0x70);
+ ddr_w<1>(0xff);
+}
+
+void mc68hc811e2_device::device_reset()
{
- if( m_irq_state[MC68HC11_IRQ_LINE]!=CLEAR_LINE && (!(m_ccr & CC_I)) )
- {
- uint16_t pc_vector;
+ mc68hc11_cpu_device::device_reset();
- if(m_wait_state == 0)
- {
- PUSH16(m_pc);
- PUSH16(m_iy);
- PUSH16(m_ix);
- PUSH8(REG_A);
- PUSH8(REG_B);
- PUSH8(m_ccr);
- }
- pc_vector = READ16(0xfff2);
- SET_PC(pc_vector);
- m_ccr |= CC_I; //irq taken, mask the flag
- if(m_wait_state == 1) { m_wait_state = 2; }
- if(m_stop_state == 1) { m_stop_state = 2; }
- standard_irq_callback(MC68HC11_IRQ_LINE);
- }
+ m_port_data[0] &= 0x8f;
+ m_port_data[1] = 0x00;
+ ddr_w<0>(0x70);
+ ddr_w<1>(0xff);
+}
+
+void mc68hc11f1_device::device_reset()
+{
+ mc68hc11_cpu_device::device_reset();
+ m_option = 0x00;
+}
+
+static const char *const s_irq_names[32] =
+{
+ "RESET", // vectored from $FFFE,FF
+ "Clock Monitor", // vectored from $FFFC,FD
+ "COP Failure", // vectored from $FFFA,FB
+ "Illegal Opcode", // vectored from $FFF8,F9
+ "SWI", // vectored from $FFF6,F7
+ "XIRQ", // vectored from $FFF4,F5
+ "IRQ", // vectored from $FFF2,F3
+ "RTI", // vectored from $FFF0,F1
+ "IC1", // vectored from $FFEE,EF
+ "IC2", // vectored from $FFEC,ED
+ "IC3", // vectored from $FFEA,EB
+ "OC1", // vectored from $FFE8,E9
+ "OC2", // vectored from $FFE6,E7
+ "OC3", // vectored from $FFE4,E5
+ "OC4", // vectored from $FFE2,E3
+ "OC5", // vectored from $FFE0,E1
+ "Timer Overflow", // vectored from $FFDE,DF
+ "PAOV", // vectored from $FFDC,DD
+ "PAI", // vectored from $FFDA,DB
+ "SPI", // vectored from $FFD8,D9
+ "SCI", // vectored from $FFD6,F7
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved"
+};
+
+void mc68hc11_cpu_device::check_irq_lines()
+{
/* check timers here */
{
- int divider = div_tab[m_pr & 3];
+ int divider = div_tab[m_tmsk2 & 3];
uint64_t cur_time = total_cycles();
uint32_t add = (cur_time - m_frc_base) / divider;
if (add > 0)
{
- for(uint32_t i=0;i<add;i++)
+ if ((((cur_time - m_reset_time) ^ (m_frc_base - m_reset_time)) >> ((m_pactl & 3) + 13)) > 0)
{
- m_tcnt++;
- if(m_tcnt == m_toc1)
+ m_tflg2 |= 0x40;
+ if (BIT(m_tmsk2, 6))
+ set_irq_state(0x07, true);
+ }
+
+ for (int i = 0; i < 5; i++)
+ {
+ if (add >= uint16_t(m_toc[i] - m_tcnt))
{
- m_tflg1 |= 0x80;
- m_irq_state[MC68HC11_TOC1_LINE] = ASSERT_LINE;
+ m_tflg1 |= 0x80 >> i;
+ if (BIT(m_tmsk1, 7 - i))
+ set_irq_state(0x0b + i, true);
}
}
+ if (add >= 0x10000 - m_tcnt)
+ {
+ m_tflg2 |= 0x80;
+ if (BIT(m_tmsk2, 7))
+ set_irq_state(0x10, true);
+ }
+
+ m_tcnt += add;
m_frc_base = cur_time;
}
}
- if( m_irq_state[MC68HC11_TOC1_LINE]!=CLEAR_LINE && (!(m_ccr & CC_I)) && m_tmsk1 & 0x80)
+ uint32_t irq_state = m_irq_state;
+ if (m_ccr & CC_X)
+ irq_state &= ~0x04000000; // mask XIRQ out
+ if (irq_state != 0 && (!(m_ccr & CC_I) || (irq_state >= 0x04000000)))
{
- uint16_t pc_vector;
+ int level = count_leading_zeros_32(irq_state); // TODO: respect HPRIO setting
+ standard_irq_callback(level, m_pc);
if(m_wait_state == 0)
{
@@ -778,22 +1170,48 @@ void mc68hc11_cpu_device::check_irq_lines()
PUSH8(REG_B);
PUSH8(m_ccr);
}
- pc_vector = READ16(0xffe8);
+ // TODO: vectors differ in bootstrap and special test modes
+ uint16_t pc_vector = READ16(0xfffe - level * 2);
SET_PC(pc_vector);
m_ccr |= CC_I; //irq taken, mask the flag
- if(m_wait_state == 1) { m_wait_state = 2; }
+ if (level < 0x06)
+ m_ccr |= CC_X;
+ if(m_wait_state == 1) { m_wait_state = 0; }
if(m_stop_state == 1) { m_stop_state = 2; }
- standard_irq_callback(MC68HC11_TOC1_LINE);
- m_irq_state[MC68HC11_TOC1_LINE] = CLEAR_LINE; // auto-ack irq
+ if (level < 0x05 || (level == 0x06 && BIT(m_option, 5)))
+ set_irq_state(level, false); // auto-ack edge-triggered IRQ
}
+}
+void mc68hc11_cpu_device::set_irq_state(uint8_t irqn, bool state)
+{
+ LOGMASKED(LOG_IRQ, "%s: %s interrupt %s\n", machine().describe_context(), s_irq_names[irqn], state ? "requested" : "cleared");
+ if (state)
+ m_irq_state |= 0x80000000 >> irqn;
+ else
+ m_irq_state &= ~(0x80000000 >> irqn);
}
void mc68hc11_cpu_device::execute_set_input(int inputnum, int state)
{
- m_irq_state[inputnum] = state;
- if (state == CLEAR_LINE) return;
- check_irq_lines();
+ switch (inputnum)
+ {
+ case MC68HC11_IRQ_LINE:
+ if (!m_irq_asserted && state != CLEAR_LINE)
+ set_irq_state(0x06, true);
+ else if (m_irq_asserted && state == CLEAR_LINE && !BIT(m_option, 5))
+ set_irq_state(0x06, false);
+ m_irq_asserted = state != CLEAR_LINE;
+ break;
+
+ case MC68HC11_XIRQ_LINE:
+ set_irq_state(0x05, state != CLEAR_LINE);
+ break;
+
+ default:
+ logerror("Unknown input %d = %d\n", inputnum, state);
+ break;
+ }
}
void mc68hc11_cpu_device::execute_run()
@@ -804,10 +1222,18 @@ void mc68hc11_cpu_device::execute_run()
check_irq_lines();
- m_ppc = m_pc;
- debugger_instruction_hook(m_pc);
+ if (m_wait_state != 0)
+ {
+ debugger_wait_hook();
+ m_icount = 0;
+ }
+ else
+ {
+ m_ppc = m_pc;
+ debugger_instruction_hook(m_pc);
- op = FETCH();
- (this->*hc11_optable[op])();
+ op = FETCH();
+ (this->*hc11_optable[op])();
+ }
}
}
diff --git a/src/devices/cpu/mc68hc11/mc68hc11.h b/src/devices/cpu/mc68hc11/mc68hc11.h
index 6452c20f8e3..a7248de563b 100644
--- a/src/devices/cpu/mc68hc11/mc68hc11.h
+++ b/src/devices/cpu/mc68hc11/mc68hc11.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Ville Linde, Angelo Salese, hap
+// copyright-holders:Ville Linde, Angelo Salese, AJR
#ifndef MAME_CPU_MC68HC11_MC68HC11_H
#define MAME_CPU_MC68HC11_MC68HC11_H
@@ -8,15 +8,18 @@
enum {
MC68HC11_IRQ_LINE = 0,
- MC68HC11_TOC1_LINE = 1
+ MC68HC11_XIRQ_LINE = 1
};
DECLARE_DEVICE_TYPE(MC68HC11A1, mc68hc11a1_device)
DECLARE_DEVICE_TYPE(MC68HC11D0, mc68hc11d0_device)
+DECLARE_DEVICE_TYPE(MC68HC11E1, mc68hc11e1_device)
+DECLARE_DEVICE_TYPE(MC68HC811E2, mc68hc811e2_device)
+DECLARE_DEVICE_TYPE(MC68HC11F1, mc68hc11f1_device)
DECLARE_DEVICE_TYPE(MC68HC11K1, mc68hc11k1_device)
DECLARE_DEVICE_TYPE(MC68HC11M0, mc68hc11m0_device)
-class mc68hc11_cpu_device : public cpu_device
+class mc68hc11_cpu_device : public cpu_device, public device_nvram_interface
{
public:
// port configuration
@@ -47,30 +50,41 @@ public:
auto in_spi2_data_callback() { return m_spi2_data_input_cb.bind(); }
auto out_spi2_data_callback() { return m_spi2_data_output_cb.bind(); }
+ void set_default_config(uint8_t data) { assert(!configured()); m_config = data & m_config_mask; }
+
protected:
- mc68hc11_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int reg_bits, uint16_t internal_ram_size, uint8_t init_value, address_map_constructor reg_map);
+ mc68hc11_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint16_t ram_size, uint16_t reg_block_size, uint16_t rom_size, uint16_t eeprom_size, uint8_t init_value, uint8_t config_mask, uint8_t option_mask);
- // device-level overrides
- virtual void device_resolve_objects() override;
- virtual void device_start() override;
- virtual void device_reset() override;
+ // device_t implementation
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
- // device_execute_interface overrides
- virtual uint32_t execute_min_cycles() const override { return 1; }
- virtual uint32_t execute_max_cycles() const override { return 41; }
- virtual uint32_t execute_input_lines() const override { return 2; }
+ // device_execute_interface implementation
+ virtual uint32_t execute_min_cycles() const noexcept override { return 1; }
+ virtual uint32_t execute_max_cycles() const noexcept override { return 41; }
+ virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override { return (clocks + 4 - 1) / 4; }
+ virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const noexcept override { return (cycles * 4); }
virtual void execute_run() override;
virtual void execute_set_input(int inputnum, int state) override;
- // device_memory_interface overrides
+ // device_memory_interface implementation
virtual space_config_vector memory_space_config() const override;
- // device_state_interface overrides
+ // device_nvram_interface implementation
+ virtual bool nvram_read(util::read_stream &file) override;
+ virtual bool nvram_write(util::write_stream &file) override;
+ virtual void nvram_default() override;
+
+ // device_state_interface implementation
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
- // device_disasm_interface overrides
+ // device_disasm_interface implementation
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
+ void set_irq_state(uint8_t irqn, bool state);
+
+ virtual void mc68hc11_reg_map(memory_view::memory_view_entry &block, offs_t base) = 0;
+
template <int P> uint8_t port_r();
template <int P> void port_w(uint8_t data);
template <int P> uint8_t ddr_r();
@@ -78,15 +92,24 @@ protected:
uint8_t pioc_r();
uint8_t tcnt_r(offs_t offset);
void tcnt_w(offs_t offset, uint8_t data);
- uint8_t toc1_r(offs_t offset);
- void toc1_w(offs_t offset, uint8_t data);
+ uint8_t toc_r(offs_t offset);
+ void toc_w(offs_t offset, uint8_t data);
+ uint8_t tctl1_r();
+ void tctl1_w(uint8_t data);
+ uint8_t tctl2_r();
+ void tctl2_w(uint8_t data);
uint8_t tmsk1_r();
void tmsk1_w(uint8_t data);
uint8_t tflg1_r();
void tflg1_w(uint8_t data);
+ uint8_t tflg2_r();
+ void tflg2_w(uint8_t data);
+ uint8_t tmsk2_r();
void tmsk2_w(uint8_t data);
uint8_t pactl_r();
void pactl_w(uint8_t data);
+ uint8_t pactl_ddra_r();
+ void pactl_ddra_w(uint8_t data);
template <int N> uint8_t spcr_r();
template <int N> uint8_t spsr_r();
template <int N> uint8_t spdr_r();
@@ -95,8 +118,15 @@ protected:
void adctl_w(uint8_t data);
uint8_t adr_r(offs_t offset);
uint8_t opt2_r();
+ uint8_t config_r();
+ uint8_t config_1s_r();
+ void config_w(uint8_t data);
uint8_t init_r();
void init_w(uint8_t data);
+ uint8_t init2_r();
+ void init2_w(uint8_t data);
+ uint8_t option_r();
+ void option_w(uint8_t data);
uint8_t scbd_r(offs_t offset);
uint8_t sccr1_r();
uint8_t sccr2_r();
@@ -106,8 +136,6 @@ protected:
private:
address_space_config m_program_config;
- address_space_config m_data_config;
- address_space_config m_io_config;
union {
struct {
@@ -137,37 +165,54 @@ private:
uint8_t m_adctl;
int m_ad_channel;
- uint8_t m_irq_state[2];
- memory_access_cache<0, 0, ENDIANNESS_BIG> *m_cache;
- address_space *m_program;
- address_space *m_data;
- address_space *m_io;
- devcb_read8 m_port_input_cb[8];
- devcb_write8 m_port_output_cb[8];
- devcb_read8 m_analog_cb[8];
+ uint32_t m_irq_state;
+ bool m_irq_asserted;
+
+ memory_access<16, 0, 0, ENDIANNESS_BIG>::cache m_cache;
+ memory_access<16, 0, 0, ENDIANNESS_BIG>::specific m_program;
+ devcb_read8::array<8> m_port_input_cb;
+ devcb_write8::array<8> m_port_output_cb;
+ devcb_read8::array<8> m_analog_cb;
devcb_read8 m_spi2_data_input_cb;
devcb_write8 m_spi2_data_output_cb;
int m_icount;
- int m_ram_position;
- int m_reg_position;
+ memory_view m_ram_view;
+ memory_view m_reg_view;
+ memory_view m_eeprom_view;
+ optional_shared_ptr<uint8_t> m_eeprom_data;
- const uint16_t m_reg_block_size; // size of internal I/O space
const uint16_t m_internal_ram_size;
+ const uint16_t m_reg_block_size; // size of internal I/O space
+ const uint16_t m_internal_rom_size;
+ const uint16_t m_internal_eeprom_size;
const uint8_t m_init_value; // default value for INIT register
+ const uint8_t m_config_mask;
+ const uint8_t m_option_mask;
uint8_t m_wait_state;
uint8_t m_stop_state;
+ uint8_t m_tctl1;
+ uint8_t m_tctl2;
uint8_t m_tflg1;
uint8_t m_tmsk1;
- uint16_t m_toc1;
+ uint16_t m_toc[5];
uint16_t m_tcnt;
// uint8_t m_por;
- uint8_t m_pr;
+ uint8_t m_tflg2;
+ uint8_t m_tmsk2;
uint8_t m_pactl;
+ uint8_t m_init;
+ uint8_t m_init2;
+protected:
+ uint8_t m_config;
+ uint8_t m_option;
+
+private:
uint64_t m_frc_base;
+ uint64_t m_reset_time;
typedef void (mc68hc11_cpu_device::*ophandler)();
struct hc11_opcode_list_struct
@@ -183,7 +228,7 @@ private:
ophandler hc11_optable_page3[256];
ophandler hc11_optable_page4[256];
- void ram_map(address_map &map);
+ void internal_map(address_map &map) ATTR_COLD;
uint8_t FETCH();
uint16_t FETCH16();
@@ -342,6 +387,7 @@ private:
void hc11_eorb_ext();
void hc11_eorb_indx();
void hc11_eorb_indy();
+ void hc11_fdiv();
void hc11_idiv();
void hc11_inca();
void hc11_incb();
@@ -518,12 +564,12 @@ public:
mc68hc11a1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
- virtual void device_reset() override;
+ virtual void device_reset() override ATTR_COLD;
- uint8_t pactl_r();
- void pactl_w(uint8_t data);
+ virtual void mc68hc11_reg_map(memory_view::memory_view_entry &block, offs_t base) override;
- void io_map(address_map &map);
+ uint8_t pactl_ddra7_r();
+ void pactl_ddra7_w(uint8_t data);
};
class mc68hc11d0_device : public mc68hc11_cpu_device
@@ -533,12 +579,48 @@ public:
mc68hc11d0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
- virtual void device_reset() override;
+ virtual void device_reset() override ATTR_COLD;
- uint8_t pactl_r();
- void pactl_w(uint8_t data);
+ virtual void mc68hc11_reg_map(memory_view::memory_view_entry &block, offs_t base) override;
+
+private:
+ uint8_t reg01_r();
+};
+
+class mc68hc11e1_device : public mc68hc11_cpu_device
+{
+public:
+ // construction/destruction
+ mc68hc11e1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual void device_reset() override ATTR_COLD;
+
+ virtual void mc68hc11_reg_map(memory_view::memory_view_entry &block, offs_t base) override;
+};
+
+class mc68hc811e2_device : public mc68hc11_cpu_device
+{
+public:
+ // construction/destruction
+ mc68hc811e2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual void device_reset() override ATTR_COLD;
+
+ virtual void mc68hc11_reg_map(memory_view::memory_view_entry &block, offs_t base) override;
+};
+
+class mc68hc11f1_device : public mc68hc11_cpu_device
+{
+public:
+ // construction/destruction
+ mc68hc11f1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual void device_reset() override ATTR_COLD;
- void io_map(address_map &map);
+ virtual void mc68hc11_reg_map(memory_view::memory_view_entry &block, offs_t base) override;
};
class mc68hc11k1_device : public mc68hc11_cpu_device
@@ -548,7 +630,7 @@ public:
mc68hc11k1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
- void io_map(address_map &map);
+ virtual void mc68hc11_reg_map(memory_view::memory_view_entry &block, offs_t base) override;
};
class mc68hc11m0_device : public mc68hc11_cpu_device
@@ -558,7 +640,7 @@ public:
mc68hc11m0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
- void io_map(address_map &map);
+ virtual void mc68hc11_reg_map(memory_view::memory_view_entry &block, offs_t base) override;
};
#endif // MAME_CPU_MC68HC11_MC68HC11_H