diff options
Diffstat (limited to 'src/devices/cpu/mc68hc11')
-rw-r--r-- | src/devices/cpu/mc68hc11/hc11dasm.cpp | 4 | ||||
-rw-r--r-- | src/devices/cpu/mc68hc11/hc11ops.h | 4 | ||||
-rw-r--r-- | src/devices/cpu/mc68hc11/hc11ops.hxx | 82 | ||||
-rw-r--r-- | src/devices/cpu/mc68hc11/mc68hc11.cpp | 1052 | ||||
-rw-r--r-- | src/devices/cpu/mc68hc11/mc68hc11.h | 168 |
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(®ion->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 |