mirror of
https://github.com/holub/mame
synced 2025-07-04 17:38:08 +03:00
Add M68HC11 internal EEPROM for relevant models
This commit is contained in:
parent
44343b8f3f
commit
78e33c5479
@ -34,8 +34,9 @@ void cdd2000_device::mem_map(address_map &map)
|
||||
|
||||
void cdd2000_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
MC68HC11F1(config, m_cdcpu, 8'000'000); // type and clock guessed
|
||||
m_cdcpu->set_addrmap(AS_PROGRAM, &cdd2000_device::mem_map);
|
||||
mc68hc11f1_device &cdcpu(MC68HC11F1(config, m_cdcpu, 8'000'000)); // type and clock guessed
|
||||
cdcpu.set_addrmap(AS_PROGRAM, &cdd2000_device::mem_map);
|
||||
cdcpu.set_default_config(0x0b);
|
||||
|
||||
NCR53CF94(config, "scsic", 25'000'000); // type and clock guessed
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ DEFINE_DEVICE_TYPE(MC68HC11M0, mc68hc11m0_device, "mc68hc11m0", "Motorola MC68HC
|
||||
|
||||
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)
|
||||
, device_nvram_interface(mconfig, *this)
|
||||
, m_program_config("program", ENDIANNESS_BIG, 8, 16, 0, address_map_constructor(FUNC(mc68hc11_cpu_device::internal_map), this))
|
||||
, m_port_input_cb(*this)
|
||||
, m_port_output_cb(*this)
|
||||
@ -63,6 +64,8 @@ mc68hc11_cpu_device::mc68hc11_cpu_device(const machine_config &mconfig, device_t
|
||||
, m_spi2_data_output_cb(*this)
|
||||
, 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)
|
||||
@ -70,17 +73,13 @@ mc68hc11_cpu_device::mc68hc11_cpu_device(const machine_config &mconfig, device_t
|
||||
, m_init_value(init_value)
|
||||
, m_config_mask(config_mask)
|
||||
, m_option_mask(option_mask)
|
||||
, m_config(config_mask)
|
||||
, m_config(config_mask & (m_internal_rom_size == 0 ? 0xfd : 0xff) & (m_internal_eeprom_size == 0 ? 0xfe : 0xff))
|
||||
{
|
||||
if (m_internal_rom_size == 0)
|
||||
m_config &= 0xfd;
|
||||
if (m_internal_eeprom_size == 0)
|
||||
m_config &= 0xfe;
|
||||
}
|
||||
|
||||
void mc68hc11_cpu_device::internal_map(address_map &map)
|
||||
{
|
||||
// TODO: internal ROM & EEPROM
|
||||
// TODO: internal ROM
|
||||
|
||||
map(0x0000, 0xffff).view(m_ram_view);
|
||||
for (int pos = 0; pos < 16; pos++)
|
||||
@ -89,6 +88,17 @@ void mc68hc11_cpu_device::internal_map(address_map &map)
|
||||
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++)
|
||||
{
|
||||
@ -120,6 +130,7 @@ mc68hc811e2_device::mc68hc811e2_device(const machine_config &mconfig, const char
|
||||
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)
|
||||
@ -154,6 +165,54 @@ std::unique_ptr<util::disasm_interface> mc68hc11_cpu_device::create_disassembler
|
||||
}
|
||||
|
||||
|
||||
bool mc68hc11_cpu_device::nvram_can_write()
|
||||
{
|
||||
return (m_config_mask & 0xf9) != 0;
|
||||
}
|
||||
|
||||
bool mc68hc11_cpu_device::nvram_read(util::read_stream &file)
|
||||
{
|
||||
size_t actual;
|
||||
|
||||
if (file.read(&m_eeprom_data[0], m_internal_eeprom_size, actual) || actual != m_internal_eeprom_size)
|
||||
return false;
|
||||
|
||||
if (file.read(&m_config, 1, actual) || actual != 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mc68hc11_cpu_device::nvram_write(util::write_stream &file)
|
||||
{
|
||||
size_t actual;
|
||||
|
||||
if (file.write(&m_eeprom_data[0], m_internal_eeprom_size, actual) || actual != m_internal_eeprom_size)
|
||||
return false;
|
||||
|
||||
if (file.write(&m_config, 1, actual) || actual != 1)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define HC11OP(XX) mc68hc11_cpu_device::hc11_##XX
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -374,7 +433,15 @@ uint8_t mc68hc11_cpu_device::config_1s_r()
|
||||
|
||||
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()
|
||||
@ -402,6 +469,19 @@ void mc68hc11_cpu_device::init_w(uint8_t data)
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@ -665,6 +745,7 @@ void mc68hc11k1_device::mc68hc11_reg_map(memory_view::memory_view_entry &block,
|
||||
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)
|
||||
@ -835,6 +916,8 @@ void mc68hc11_cpu_device::device_start()
|
||||
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;
|
||||
@ -846,6 +929,7 @@ void mc68hc11_cpu_device::device_start()
|
||||
m_ad_channel = 0;
|
||||
std::fill(std::begin(m_irq_state), std::end(m_irq_state), CLEAR_LINE);
|
||||
m_init = 0;
|
||||
m_init2 = 0;
|
||||
m_option = 0;
|
||||
m_tflg1 = 0;
|
||||
m_tmsk1 = 0;
|
||||
@ -894,6 +978,25 @@ void mc68hc11_cpu_device::state_string_export(const device_state_entry &entry, s
|
||||
|
||||
void mc68hc11_cpu_device::device_reset()
|
||||
{
|
||||
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_pc = READ16(0xfffe); // TODO: vectors differ in bootstrap and special test modes
|
||||
m_wait_state = 0;
|
||||
m_stop_state = 0;
|
||||
@ -929,7 +1032,6 @@ void mc68hc11d0_device::device_reset()
|
||||
|
||||
m_port_data[0] &= 0x8f;
|
||||
ddr_w<0>(0x70);
|
||||
m_config = 0x00;
|
||||
}
|
||||
|
||||
void mc68hc11e1_device::device_reset()
|
||||
@ -959,13 +1061,6 @@ void mc68hc11f1_device::device_reset()
|
||||
m_option = 0x00;
|
||||
}
|
||||
|
||||
void mc68hc11m0_device::device_reset()
|
||||
{
|
||||
mc68hc11_cpu_device::device_reset();
|
||||
|
||||
m_config = 0x04;
|
||||
}
|
||||
|
||||
/*
|
||||
IRQ table vectors:
|
||||
0xffd6: SCI
|
||||
|
@ -20,7 +20,7 @@ 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
|
||||
@ -51,6 +51,8 @@ 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, 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);
|
||||
|
||||
@ -71,6 +73,12 @@ protected:
|
||||
// device_memory_interface overrides
|
||||
virtual space_config_vector memory_space_config() const override;
|
||||
|
||||
// device_nvram_interface overrides
|
||||
virtual bool nvram_can_write() override;
|
||||
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 overrides
|
||||
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
|
||||
|
||||
@ -117,6 +125,8 @@ protected:
|
||||
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);
|
||||
@ -169,6 +179,8 @@ private:
|
||||
|
||||
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_internal_ram_size;
|
||||
const uint16_t m_reg_block_size; // size of internal I/O space
|
||||
@ -192,6 +204,7 @@ private:
|
||||
uint8_t m_tmsk2;
|
||||
uint8_t m_pactl;
|
||||
uint8_t m_init;
|
||||
uint8_t m_init2;
|
||||
|
||||
protected:
|
||||
uint8_t m_config;
|
||||
@ -627,8 +640,6 @@ public:
|
||||
mc68hc11m0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
protected:
|
||||
virtual void device_reset() override;
|
||||
|
||||
virtual void mc68hc11_reg_map(memory_view::memory_view_entry &block, offs_t base) override;
|
||||
};
|
||||
|
||||
|
@ -10,8 +10,7 @@ Many thanks to Olivier Galibert for the CPU identify effort ;-)
|
||||
TODO:
|
||||
- CPU core bugs?
|
||||
- Protection controls inputs;
|
||||
- Understand & fix EEPROM emulation;
|
||||
- Hangs during attract mode, eeprom or protection?
|
||||
- Hangs during attract mode due to unemulated PIC protection;
|
||||
- complete video HW (unknown bits and hblank);
|
||||
- 24Khz monitor isn't supported, it changes the resolution to 648 x 480 and
|
||||
changes the register 9 (raster lines x character lines) from 7 to 0xf.
|
||||
@ -61,8 +60,7 @@ public:
|
||||
: driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_palette(*this, "palette"),
|
||||
m_eeprom(*this, "eeprom")
|
||||
m_palette(*this, "palette")
|
||||
{
|
||||
}
|
||||
|
||||
@ -71,8 +69,6 @@ public:
|
||||
void init_hitpoker();
|
||||
|
||||
private:
|
||||
uint8_t m_sys_regs = 0;
|
||||
|
||||
uint8_t m_pic_data = 0;
|
||||
std::unique_ptr<uint8_t[]> m_videoram;
|
||||
std::unique_ptr<uint8_t[]> m_paletteram;
|
||||
@ -84,14 +80,13 @@ private:
|
||||
void hitpoker_cram_w(offs_t offset, uint8_t data);
|
||||
uint8_t hitpoker_paletteram_r(offs_t offset);
|
||||
void hitpoker_paletteram_w(offs_t offset, uint8_t data);
|
||||
uint8_t hitpoker_pic_r(offs_t offset);
|
||||
void hitpoker_pic_w(offs_t offset, uint8_t data);
|
||||
uint8_t hitpoker_pic_r();
|
||||
void hitpoker_pic_w(uint8_t data);
|
||||
virtual void video_start() override;
|
||||
uint32_t screen_update_hitpoker(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
required_device<mc68hc11_cpu_device> m_maincpu;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<palette_device> m_palette;
|
||||
required_shared_ptr<uint8_t> m_eeprom;
|
||||
void hitpoker_map(address_map &map);
|
||||
};
|
||||
|
||||
@ -190,30 +185,23 @@ void hitpoker_state::hitpoker_paletteram_w(offs_t offset, uint8_t data)
|
||||
}
|
||||
|
||||
|
||||
uint8_t hitpoker_state::hitpoker_pic_r(offs_t offset)
|
||||
uint8_t hitpoker_state::hitpoker_pic_r()
|
||||
{
|
||||
// logerror("R\n");
|
||||
|
||||
if(offset == 0)
|
||||
{
|
||||
if(m_maincpu->pc() == 0x3143 ||
|
||||
m_maincpu->pc() == 0x314e ||
|
||||
m_maincpu->pc() == 0x3164 ||
|
||||
m_maincpu->pc() == 0x3179)
|
||||
return m_pic_data;
|
||||
if(m_maincpu->pc() == 0x3143 ||
|
||||
m_maincpu->pc() == 0x314e ||
|
||||
m_maincpu->pc() == 0x3164 ||
|
||||
m_maincpu->pc() == 0x3179)
|
||||
return m_pic_data;
|
||||
|
||||
return (m_pic_data & 0x7f) | (m_pic_data & 0x40 ? 0x80 : 0x00);
|
||||
}
|
||||
|
||||
return m_sys_regs;
|
||||
return (m_pic_data & 0x7f) | (m_pic_data & 0x40 ? 0x80 : 0x00);
|
||||
}
|
||||
|
||||
void hitpoker_state::hitpoker_pic_w(offs_t offset, uint8_t data)
|
||||
void hitpoker_state::hitpoker_pic_w(uint8_t data)
|
||||
{
|
||||
if(offset == 0)
|
||||
m_pic_data = (data & 0xff);// | (data & 0x40) ? 0x80 : 0x00;
|
||||
m_pic_data = (data & 0xff);// | (data & 0x40) ? 0x80 : 0x00;
|
||||
// logerror("%02x W\n",data);
|
||||
m_sys_regs = data;
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -230,7 +218,7 @@ void hitpoker_state::hitpoker_map(address_map &map)
|
||||
map(0xbf00, 0xffff).rom();
|
||||
|
||||
map(0x8000, 0xb5ff).rw(FUNC(hitpoker_state::hitpoker_vram_r), FUNC(hitpoker_state::hitpoker_vram_w));
|
||||
map(0xb600, 0xbdff).ram().share("eeprom");
|
||||
map(0xb800, 0xbdff).ram();
|
||||
map(0xbe00, 0xbe7f).rw("rtc", FUNC(ds17x85_device::read_direct), FUNC(ds17x85_device::write_direct));
|
||||
map(0xbe80, 0xbe80).w("crtc", FUNC(mc6845_device::address_w));
|
||||
map(0xbe81, 0xbe81).w("crtc", FUNC(mc6845_device::register_w));
|
||||
@ -395,16 +383,19 @@ void hitpoker_state::init_hitpoker()
|
||||
ROM[0x10c7] = 0x01; //patch the checksum routine
|
||||
|
||||
// must match RTC serial number
|
||||
m_eeprom[3] = 'M';
|
||||
m_eeprom[2] = 'A';
|
||||
m_eeprom[1] = 'M';
|
||||
m_eeprom[0] = 'E';
|
||||
}
|
||||
|
||||
ROM_START( hitpoker )
|
||||
ROM_REGION( 0x10000, "maincpu", 0 )
|
||||
ROM_LOAD( "u4.bin", 0x00000, 0x10000, CRC(0016497a) SHA1(017320bfe05fea8a48e26a66c0412415846cee7c) )
|
||||
|
||||
ROM_REGION( 0x200, "maincpu:eeprom", ROMREGION_ERASEFF )
|
||||
// must match RTC serial number
|
||||
ROM_FILL( 0x003, 1, 0x4d )
|
||||
ROM_FILL( 0x002, 1, 0x41 )
|
||||
ROM_FILL( 0x001, 1, 0x4d )
|
||||
ROM_FILL( 0x000, 1, 0x45 )
|
||||
|
||||
ROM_REGION( 0x10000, "pic", 0 )
|
||||
ROM_LOAD( "pic", 0x00000, 0x1000, NO_DUMP ) // unknown type
|
||||
|
||||
|
@ -46,6 +46,7 @@ void slsstars_state::slsstars(machine_config &config)
|
||||
{
|
||||
MC68HC11F1(config, m_maincpu, 8'000'000); // unknown clock
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &slsstars_state::mem_map);
|
||||
m_maincpu->set_default_config(0x3f);
|
||||
|
||||
M48T58(config, "timekpr"); // U3
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ private:
|
||||
|
||||
void vanguardmk1_state::mcu_map(address_map &map)
|
||||
{
|
||||
map(0xf800, 0xffff).rom().region("mcu", 0);
|
||||
}
|
||||
|
||||
|
||||
@ -34,11 +33,12 @@ void vanguardmk1_state::vanguardmk1(machine_config &config)
|
||||
{
|
||||
mc68hc811e2_device &mcu(MC68HC811E2(config, "mcu", 8000000)); // unknown clock
|
||||
mcu.set_addrmap(AS_PROGRAM, &vanguardmk1_state::mcu_map);
|
||||
mcu.set_default_config(0xff);
|
||||
}
|
||||
|
||||
|
||||
ROM_START(vngrdmk1)
|
||||
ROM_REGION(0x800, "mcu", 0)
|
||||
ROM_REGION(0x800, "mcu:eeprom", 0)
|
||||
ROM_LOAD( "van24_aug04", 0x000, 0x800, CRC(ce63fcb9) SHA1(8f688e866e8fea888c77aa5be92ad09f684afd59) )
|
||||
ROM_END
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user