mirror of
https://github.com/holub/mame
synced 2025-05-28 16:43:04 +03:00
mcs96: Replace I/O space with callbacks; use internal space for non-executable register file & SFR area (nw)
This commit is contained in:
parent
0d90924ad0
commit
b0b0840551
@ -13,8 +13,13 @@
|
||||
#include "i8x9xd.h"
|
||||
|
||||
i8x9x_device::i8x9x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
|
||||
mcs96_device(mconfig, type, tag, owner, clock, 8),
|
||||
io_config("io", ENDIANNESS_LITTLE, 16, 16, -1), io(nullptr), base_timer2(0), ad_done(0), hso_command(0), ad_command(0), hso_time(0), ad_result(0),
|
||||
mcs96_device(mconfig, type, tag, owner, clock, 8, address_map_constructor(FUNC(i8x9x_device::internal_regs), this)),
|
||||
m_ach_cb{{*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}},
|
||||
m_serial_tx_cb(*this),
|
||||
m_in_p0_cb(*this),
|
||||
m_out_p1_cb(*this), m_in_p1_cb(*this),
|
||||
m_out_p2_cb(*this), m_in_p2_cb(*this),
|
||||
base_timer2(0), ad_done(0), hso_command(0), ad_command(0), hso_time(0), ad_result(0),
|
||||
ios0(0), ios1(0), ioc0(0), ioc1(0), sbuf(0), sp_stat(0), serial_send_buf(0), serial_send_timer(0)
|
||||
{
|
||||
}
|
||||
@ -24,18 +29,21 @@ std::unique_ptr<util::disasm_interface> i8x9x_device::create_disassembler()
|
||||
return std::make_unique<i8x9x_disassembler>();
|
||||
}
|
||||
|
||||
device_memory_interface::space_config_vector i8x9x_device::memory_space_config() const
|
||||
void i8x9x_device::device_resolve_objects()
|
||||
{
|
||||
return space_config_vector {
|
||||
std::make_pair(AS_PROGRAM, &program_config),
|
||||
std::make_pair(AS_IO, &io_config)
|
||||
};
|
||||
for (auto &cb : m_ach_cb)
|
||||
cb.resolve_safe(0);
|
||||
m_serial_tx_cb.resolve_safe();
|
||||
m_in_p0_cb.resolve_safe(0);
|
||||
m_out_p1_cb.resolve_safe();
|
||||
m_in_p1_cb.resolve_safe(0);
|
||||
m_out_p2_cb.resolve_safe();
|
||||
m_in_p2_cb.resolve_safe(0);
|
||||
}
|
||||
|
||||
void i8x9x_device::device_start()
|
||||
{
|
||||
mcs96_device::device_start();
|
||||
io = &space(AS_IO);
|
||||
cycles_scaling = 3;
|
||||
}
|
||||
|
||||
@ -73,7 +81,7 @@ void i8x9x_device::commit_hso_cam()
|
||||
|
||||
void i8x9x_device::ad_start(uint64_t current_time)
|
||||
{
|
||||
ad_result = (io->read_word((ad_command & 7) + A0) << 6) | 8 | (ad_command & 7);
|
||||
ad_result = (m_ach_cb[ad_command & 7]() << 6) | 8 | (ad_command & 7);
|
||||
ad_done = current_time + 88;
|
||||
internal_update(current_time);
|
||||
}
|
||||
@ -87,184 +95,217 @@ void i8x9x_device::serial_send(uint8_t data)
|
||||
void i8x9x_device::serial_send_done()
|
||||
{
|
||||
serial_send_timer = 0;
|
||||
io->write_word(SERIAL, serial_send_buf);
|
||||
m_serial_tx_cb(serial_send_buf);
|
||||
pending_irq |= IRQ_SERIAL;
|
||||
sp_stat |= 0x20;
|
||||
check_irq();
|
||||
}
|
||||
|
||||
void i8x9x_device::io_w8(uint8_t adr, uint8_t data)
|
||||
void i8x9x_device::internal_regs(address_map &map)
|
||||
{
|
||||
switch(adr) {
|
||||
case 0x02:
|
||||
ad_command = data;
|
||||
if(ad_command & 8)
|
||||
ad_start(total_cycles());
|
||||
break;
|
||||
case 0x03:
|
||||
logerror("%s: hsi_mode %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x04:
|
||||
hso_time = (hso_time & 0xff00) | data;
|
||||
break;
|
||||
case 0x05:
|
||||
hso_time = (hso_time & 0x00ff) | (data << 8);
|
||||
commit_hso_cam();
|
||||
break;
|
||||
case 0x06:
|
||||
hso_command = data;
|
||||
break;
|
||||
case 0x07:
|
||||
logerror("%s: sbuf %02x (%04x)\n", tag(), data, PPC);
|
||||
serial_send(data);
|
||||
break;
|
||||
case 0x08:
|
||||
PSW = (PSW & 0xff00) | data;
|
||||
check_irq();
|
||||
break;
|
||||
case 0x09:
|
||||
pending_irq = data;
|
||||
logerror("%s: int_pending %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x0a:
|
||||
logerror("%s: watchdog %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x0e:
|
||||
logerror("%s: baud rate %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x0f:
|
||||
logerror("%s: io port 1 %02x (%04x)\n", tag(), data, PPC);
|
||||
io->write_word(P1, data);
|
||||
break;
|
||||
case 0x10:
|
||||
logerror("%s: io port 2 %02x (%04x)\n", tag(), data, PPC);
|
||||
io->write_word(P2, data);
|
||||
break;
|
||||
case 0x11:
|
||||
logerror("%s: sp con %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x15:
|
||||
logerror("%s: ioc0 %02x (%04x)\n", tag(), data, PPC);
|
||||
ioc0 = data;
|
||||
break;
|
||||
case 0x16:
|
||||
logerror("%s: ioc1 %02x (%04x)\n", tag(), data, PPC);
|
||||
ioc1 = data;
|
||||
break;
|
||||
case 0x17:
|
||||
logerror("%s: pwm control %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
map(0x00, 0x01).lr16("r0", []() -> u16 { return 0; }).nopw();
|
||||
map(0x02, 0x03).r(FUNC(i8x9x_device::ad_result_r)); // 8-bit access
|
||||
map(0x02, 0x02).w(FUNC(i8x9x_device::ad_command_w));
|
||||
map(0x03, 0x03).w(FUNC(i8x9x_device::hsi_mode_w));
|
||||
map(0x04, 0x05).rw(FUNC(i8x9x_device::hsi_time_r), FUNC(i8x9x_device::hso_time_w)); // 16-bit access
|
||||
map(0x06, 0x06).rw(FUNC(i8x9x_device::hsi_status_r), FUNC(i8x9x_device::hso_command_w));
|
||||
map(0x08, 0x08).rw(FUNC(i8x9x_device::int_mask_r), FUNC(i8x9x_device::int_mask_w));
|
||||
map(0x09, 0x09).rw(FUNC(i8x9x_device::int_pending_r), FUNC(i8x9x_device::int_pending_w));
|
||||
map(0x0a, 0x0b).r(FUNC(i8x9x_device::timer1_r)); // 16-bit access
|
||||
map(0x0c, 0x0d).r(FUNC(i8x9x_device::timer2_r)); // 16-bit access
|
||||
map(0x0a, 0x0a).w(FUNC(i8x9x_device::watchdog_w));
|
||||
map(0x0e, 0x0e).rw(FUNC(i8x9x_device::port0_r), FUNC(i8x9x_device::baud_rate_w));
|
||||
map(0x0f, 0x0f).rw(FUNC(i8x9x_device::port1_r), FUNC(i8x9x_device::port1_w));
|
||||
map(0x10, 0x10).rw(FUNC(i8x9x_device::port2_r), FUNC(i8x9x_device::port2_w));
|
||||
map(0x11, 0x11).rw(FUNC(i8x9x_device::sp_stat_r), FUNC(i8x9x_device::sp_con_w));
|
||||
map(0x15, 0x15).rw(FUNC(i8x9x_device::ios0_r), FUNC(i8x9x_device::ioc0_w));
|
||||
map(0x16, 0x16).rw(FUNC(i8x9x_device::ios1_r), FUNC(i8x9x_device::ioc1_w));
|
||||
map(0x17, 0x17).w(FUNC(i8x9x_device::pwm_control_w));
|
||||
map(0x18, 0xff).ram().share("register_file");
|
||||
}
|
||||
|
||||
void i8x9x_device::io_w16(uint8_t adr, uint16_t data)
|
||||
void i8x9x_device::ad_command_w(u8 data)
|
||||
{
|
||||
switch(adr) {
|
||||
case 0:
|
||||
break;
|
||||
case 4:
|
||||
hso_time = data;
|
||||
commit_hso_cam();
|
||||
break;
|
||||
default:
|
||||
io_w8(adr, data);
|
||||
io_w8(adr+1, data>>8);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
ad_command = data;
|
||||
if (ad_command & 8)
|
||||
ad_start(total_cycles());
|
||||
}
|
||||
|
||||
uint8_t i8x9x_device::io_r8(uint8_t adr)
|
||||
u8 i8x9x_device::ad_result_r(offs_t offset)
|
||||
{
|
||||
switch(adr) {
|
||||
case 0x00:
|
||||
return 0x00;
|
||||
case 0x01:
|
||||
return 0x00;
|
||||
case 0x02:
|
||||
return ad_result;
|
||||
case 0x03:
|
||||
return ad_result >> 8;
|
||||
case 0x04:
|
||||
logerror("%s: read hsi time l (%04x)\n", tag(), PPC);
|
||||
return 0x00;
|
||||
case 0x05:
|
||||
logerror("%s: read hsi time h (%04x)\n", tag(), PPC);
|
||||
return 0x00;
|
||||
case 0x06:
|
||||
logerror("%s: read hsi status (%04x)\n", tag(), PPC);
|
||||
return 0x00;
|
||||
case 0x07:
|
||||
logerror("%s: read sbuf %02x (%04x)\n", tag(), sbuf, PPC);
|
||||
return sbuf;
|
||||
case 0x08:
|
||||
return PSW;
|
||||
case 0x09:
|
||||
logerror("%s: read int pending (%04x)\n", tag(), PPC);
|
||||
return pending_irq;
|
||||
case 0x0a:
|
||||
logerror("%s: read timer1 l (%04x)\n", tag(), PPC);
|
||||
return timer_value(1, total_cycles());
|
||||
case 0x0b:
|
||||
logerror("%s: read timer1 h (%04x)\n", tag(), PPC);
|
||||
return timer_value(1, total_cycles()) >> 8;
|
||||
case 0x0c:
|
||||
logerror("%s: read timer2 l (%04x)\n", tag(), PPC);
|
||||
return timer_value(2, total_cycles());
|
||||
case 0x0d:
|
||||
logerror("%s: read timer2 h (%04x)\n", tag(), PPC);
|
||||
return timer_value(2, total_cycles()) >> 8;
|
||||
case 0x0e: {
|
||||
static int last = -1;
|
||||
if(io->read_word(P0) != last) {
|
||||
last = io->read_word(P0);
|
||||
logerror("%s: read p0 %02x\n", tag(), io->read_word(P0*2));
|
||||
}
|
||||
return io->read_word(P0);
|
||||
return ad_result >> (offset ? 8 : 0);
|
||||
}
|
||||
|
||||
void i8x9x_device::hsi_mode_w(u8 data)
|
||||
{
|
||||
logerror("hsi_mode %02x (%04x)\n", data, PPC);
|
||||
}
|
||||
|
||||
void i8x9x_device::hso_time_w(u16 data)
|
||||
{
|
||||
hso_time = data;
|
||||
commit_hso_cam();
|
||||
}
|
||||
|
||||
u16 i8x9x_device::hsi_time_r()
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
logerror("read hsi time (%04x)\n", PPC);
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
void i8x9x_device::hso_command_w(u8 data)
|
||||
{
|
||||
hso_command = data;
|
||||
}
|
||||
|
||||
u8 i8x9x_device::hsi_status_r()
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
logerror("read hsi status (%04x)\n", PPC);
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void i8x9x_device::sbuf_w(u8 data)
|
||||
{
|
||||
logerror("sbuf %02x (%04x)\n", data, PPC);
|
||||
serial_send(data);
|
||||
}
|
||||
|
||||
u8 i8x9x_device::sbuf_r()
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
logerror("read sbuf %02x (%04x)\n", sbuf, PPC);
|
||||
return sbuf;
|
||||
}
|
||||
|
||||
void i8x9x_device::int_mask_w(u8 data)
|
||||
{
|
||||
PSW = (PSW & 0xff00) | data;
|
||||
check_irq();
|
||||
}
|
||||
|
||||
u8 i8x9x_device::int_mask_r()
|
||||
{
|
||||
return PSW;
|
||||
}
|
||||
|
||||
void i8x9x_device::int_pending_w(u8 data)
|
||||
{
|
||||
pending_irq = data;
|
||||
logerror("int_pending %02x (%04x)\n", data, PPC);
|
||||
}
|
||||
|
||||
u8 i8x9x_device::int_pending_r()
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
logerror("read int pending (%04x)\n", PPC);
|
||||
return pending_irq;
|
||||
}
|
||||
|
||||
void i8x9x_device::watchdog_w(u8 data)
|
||||
{
|
||||
logerror("watchdog %02x (%04x)\n", data, PPC);
|
||||
}
|
||||
|
||||
u16 i8x9x_device::timer1_r()
|
||||
{
|
||||
u16 data = timer_value(1, total_cycles());
|
||||
if (!machine().side_effects_disabled())
|
||||
logerror("read timer1 %04x (%04x)\n", data, PPC);
|
||||
return data;
|
||||
}
|
||||
|
||||
u16 i8x9x_device::timer2_r()
|
||||
{
|
||||
u16 data = timer_value(2, total_cycles());
|
||||
if (!machine().side_effects_disabled())
|
||||
logerror("read timer2 %04x (%04x)\n", data, PPC);
|
||||
return data;
|
||||
}
|
||||
|
||||
void i8x9x_device::baud_rate_w(u8 data)
|
||||
{
|
||||
logerror("baud rate %02x (%04x)\n", data, PPC);
|
||||
}
|
||||
|
||||
u8 i8x9x_device::port0_r()
|
||||
{
|
||||
static int last = -1;
|
||||
if (!machine().side_effects_disabled() && m_in_p0_cb() != last)
|
||||
{
|
||||
last = m_in_p0_cb();
|
||||
logerror("read p0 %02x\n", last);
|
||||
}
|
||||
case 0x0f:
|
||||
return io->read_word(P1);
|
||||
case 0x10:
|
||||
return io->read_word(P2);
|
||||
case 0x11: {
|
||||
uint8_t res = sp_stat;
|
||||
return m_in_p0_cb();
|
||||
}
|
||||
|
||||
void i8x9x_device::port1_w(u8 data)
|
||||
{
|
||||
logerror("io port 1 %02x (%04x)\n", data, PPC);
|
||||
m_out_p1_cb(data);
|
||||
}
|
||||
|
||||
u8 i8x9x_device::port1_r()
|
||||
{
|
||||
return m_in_p1_cb();
|
||||
}
|
||||
|
||||
void i8x9x_device::port2_w(u8 data)
|
||||
{
|
||||
logerror("io port 2 %02x (%04x)\n", data, PPC);
|
||||
m_out_p2_cb(data);
|
||||
}
|
||||
|
||||
u8 i8x9x_device::port2_r()
|
||||
{
|
||||
return m_in_p2_cb();
|
||||
}
|
||||
|
||||
void i8x9x_device::sp_con_w(u8 data)
|
||||
{
|
||||
logerror("sp con %02x (%04x)\n", data, PPC);
|
||||
}
|
||||
|
||||
u8 i8x9x_device::sp_stat_r()
|
||||
{
|
||||
uint8_t res = sp_stat;
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
sp_stat &= 0x80;
|
||||
logerror("%s: read sp stat %02x (%04x)\n", tag(), res, PPC);
|
||||
return res;
|
||||
}
|
||||
case 0x15:
|
||||
logerror("%s: read ios 0 %02x (%04x)\n", tag(), ios0, PPC);
|
||||
return ios0;
|
||||
case 0x16: {
|
||||
uint8_t res = ios1;
|
||||
ios1 = ios1 & 0xc0;
|
||||
return res;
|
||||
}
|
||||
default:
|
||||
logerror("%s: io_r8 %02x (%04x)\n", tag(), adr, PPC);
|
||||
return 0x00;
|
||||
logerror("read sp stat %02x (%04x)\n", res, PPC);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
uint16_t i8x9x_device::io_r16(uint8_t adr)
|
||||
void i8x9x_device::ioc0_w(u8 data)
|
||||
{
|
||||
switch(adr) {
|
||||
case 0x00:
|
||||
return 0x0000;
|
||||
case 0x02:
|
||||
return ad_result;
|
||||
case 0x04:
|
||||
logerror("%s: read hsi time (%04x)\n", tag(), PPC);
|
||||
return 0x0000;
|
||||
case 0x0a:
|
||||
return timer_value(1, total_cycles());
|
||||
case 0x0c:
|
||||
logerror("%s: read timer2 (%04x)\n", tag(), PPC);
|
||||
return timer_value(2, total_cycles());
|
||||
default:
|
||||
return io_r8(adr) | (io_r8(adr+1) << 8);
|
||||
}
|
||||
logerror("ioc0 %02x (%04x)\n", data, PPC);
|
||||
}
|
||||
|
||||
u8 i8x9x_device::ios0_r()
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
logerror("read ios 0 %02x (%04x)\n", ios0, PPC);
|
||||
return ios0;
|
||||
}
|
||||
|
||||
void i8x9x_device::ioc1_w(u8 data)
|
||||
{
|
||||
logerror("ioc1 %02x (%04x)\n", data, PPC);
|
||||
}
|
||||
|
||||
u8 i8x9x_device::ios1_r()
|
||||
{
|
||||
uint8_t res = ios1;
|
||||
if (!machine().side_effects_disabled())
|
||||
ios1 = ios1 & 0xc0;
|
||||
return res;
|
||||
}
|
||||
|
||||
void i8x9x_device::pwm_control_w(u8 data)
|
||||
{
|
||||
logerror("pwm control %02x (%04x)\n", data, PPC);
|
||||
}
|
||||
|
||||
void i8x9x_device::do_exec_partial()
|
||||
|
@ -21,24 +21,67 @@ public:
|
||||
P0, P1, P2
|
||||
};
|
||||
|
||||
auto ach0_cb() { return m_ach_cb[0].bind(); }
|
||||
auto ach1_cb() { return m_ach_cb[1].bind(); }
|
||||
auto ach2_cb() { return m_ach_cb[2].bind(); }
|
||||
auto ach3_cb() { return m_ach_cb[3].bind(); }
|
||||
auto ach4_cb() { return m_ach_cb[4].bind(); }
|
||||
auto ach5_cb() { return m_ach_cb[5].bind(); }
|
||||
auto ach6_cb() { return m_ach_cb[6].bind(); }
|
||||
auto ach7_cb() { return m_ach_cb[7].bind(); }
|
||||
auto serial_tx_cb() { return m_serial_tx_cb.bind(); }
|
||||
|
||||
auto in_p0_cb() { return m_in_p0_cb.bind(); }
|
||||
auto out_p1_cb() { return m_out_p1_cb.bind(); }
|
||||
auto in_p1_cb() { return m_in_p1_cb.bind(); }
|
||||
auto out_p2_cb() { return m_out_p2_cb.bind(); }
|
||||
auto in_p2_cb() { return m_in_p2_cb.bind(); }
|
||||
|
||||
void serial_w(uint8_t val);
|
||||
|
||||
protected:
|
||||
i8x9x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
virtual void device_resolve_objects() override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual space_config_vector memory_space_config() const override;
|
||||
|
||||
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
||||
|
||||
virtual void do_exec_full() override;
|
||||
virtual void do_exec_partial() override;
|
||||
virtual void internal_update(uint64_t current_time) override;
|
||||
virtual void io_w8(uint8_t adr, uint8_t data) override;
|
||||
virtual void io_w16(uint8_t adr, uint16_t data) override;
|
||||
virtual uint8_t io_r8(uint8_t adr) override;
|
||||
virtual uint16_t io_r16(uint8_t adr) override;
|
||||
|
||||
void internal_regs(address_map &map);
|
||||
void ad_command_w(u8 data);
|
||||
u8 ad_result_r(offs_t offset);
|
||||
void hsi_mode_w(u8 data);
|
||||
void hso_time_w(u16 data);
|
||||
u16 hsi_time_r();
|
||||
void hso_command_w(u8 data);
|
||||
u8 hsi_status_r();
|
||||
void sbuf_w(u8 data);
|
||||
u8 sbuf_r();
|
||||
void int_mask_w(u8 data);
|
||||
u8 int_mask_r();
|
||||
void int_pending_w(u8 data);
|
||||
u8 int_pending_r();
|
||||
void watchdog_w(u8 data);
|
||||
u16 timer1_r();
|
||||
u16 timer2_r();
|
||||
void baud_rate_w(u8 data);
|
||||
u8 port0_r();
|
||||
void port1_w(u8 data);
|
||||
u8 port1_r();
|
||||
void port2_w(u8 data);
|
||||
u8 port2_r();
|
||||
void sp_con_w(u8 data);
|
||||
u8 sp_stat_r();
|
||||
void ioc0_w(u8 data);
|
||||
u8 ios0_r();
|
||||
void ioc1_w(u8 data);
|
||||
u8 ios1_r();
|
||||
void pwm_control_w(u8 data);
|
||||
|
||||
private:
|
||||
enum {
|
||||
@ -58,8 +101,16 @@ private:
|
||||
uint16_t time;
|
||||
};
|
||||
|
||||
address_space_config io_config;
|
||||
address_space *io;
|
||||
devcb_read16 m_ach_cb[8];
|
||||
devcb_write8 m_serial_tx_cb;
|
||||
|
||||
devcb_read8 m_in_p0_cb;
|
||||
devcb_write8 m_out_p1_cb;
|
||||
devcb_read8 m_in_p1_cb;
|
||||
devcb_write8 m_out_p2_cb;
|
||||
devcb_read8 m_in_p2_cb;
|
||||
//devcb_write16 m_out_p3_p4_cb;
|
||||
//devcb_read16 m_in_p3_p4_cb;
|
||||
|
||||
hso_cam_entry hso_info[8];
|
||||
hso_cam_entry hso_cam_hold;
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "i8xc196d.h"
|
||||
|
||||
i8xc196_device::i8xc196_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
|
||||
mcs96_device(mconfig, type, tag, owner, clock, 16)
|
||||
mcs96_device(mconfig, type, tag, owner, clock, 16, address_map_constructor(FUNC(i8xc196_device::internal_regs), this))
|
||||
{
|
||||
}
|
||||
|
||||
@ -22,52 +22,10 @@ std::unique_ptr<util::disasm_interface> i8xc196_device::create_disassembler()
|
||||
return std::make_unique<i8xc196_disassembler>();
|
||||
}
|
||||
|
||||
void i8xc196_device::io_w8(uint8_t adr, uint8_t data)
|
||||
void i8xc196_device::internal_regs(address_map &map)
|
||||
{
|
||||
switch(adr) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
logerror("%s: io_w8 %02x, %02x (%04x)\n", tag(), adr, data, PPC);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void i8xc196_device::io_w16(uint8_t adr, uint16_t data)
|
||||
{
|
||||
switch(adr) {
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
io_w8(adr, data);
|
||||
io_w8(adr+1, data>>8);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t i8xc196_device::io_r8(uint8_t adr)
|
||||
{
|
||||
switch(adr) {
|
||||
case 0x00:
|
||||
return 0x00;
|
||||
case 0x01:
|
||||
return 0x00;
|
||||
}
|
||||
uint8_t data = 0x00;
|
||||
logerror("%s: io_r8 %02x, %02x (%04x)\n", tag(), adr, data, PPC);
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t i8xc196_device::io_r16(uint8_t adr)
|
||||
{
|
||||
if(adr < 2)
|
||||
return 0x0000;
|
||||
uint16_t data = 0x0000;
|
||||
logerror("%s: io_r16 %02x, %04x (%04x)\n", tag(), adr, data, PPC);
|
||||
return data;
|
||||
map(0x00, 0x01).lr16("r0", []() -> u16 { return 0; }).nopw();
|
||||
map(0x18, 0xff).ram().share("register_file");
|
||||
}
|
||||
|
||||
void i8xc196_device::do_exec_partial()
|
||||
|
@ -22,10 +22,7 @@ protected:
|
||||
virtual void do_exec_full() override;
|
||||
virtual void do_exec_partial() override;
|
||||
|
||||
virtual void io_w8(uint8_t adr, uint8_t data) override;
|
||||
virtual void io_w16(uint8_t adr, uint16_t data) override;
|
||||
virtual uint8_t io_r8(uint8_t adr) override;
|
||||
virtual uint16_t io_r16(uint8_t adr) override;
|
||||
void internal_regs(address_map &map);
|
||||
|
||||
#define O(o) void o ## _196_full(); void o ## _196_partial()
|
||||
|
||||
|
@ -12,10 +12,12 @@
|
||||
#include "debugger.h"
|
||||
#include "mcs96.h"
|
||||
|
||||
mcs96_device::mcs96_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int data_width) :
|
||||
mcs96_device::mcs96_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int data_width, address_map_constructor regs_map) :
|
||||
cpu_device(mconfig, type, tag, owner, clock),
|
||||
program_config("program", ENDIANNESS_LITTLE, data_width, 16),
|
||||
program(nullptr), icount(0), bcount(0), inst_state(0), cycles_scaling(0), pending_irq(0),
|
||||
regs_config("register", ENDIANNESS_LITTLE, 16, 8, 0, regs_map),
|
||||
program(nullptr), regs(nullptr), register_file(*this, "register_file"),
|
||||
icount(0), bcount(0), inst_state(0), cycles_scaling(0), pending_irq(0),
|
||||
PC(0), PPC(0), PSW(0), OP1(0), OP2(0), OP3(0), OPI(0), TMP(0), irq_requested(false)
|
||||
{
|
||||
}
|
||||
@ -30,23 +32,17 @@ void mcs96_device::device_start()
|
||||
auto cache = program->cache<1, 0, ENDIANNESS_LITTLE>();
|
||||
m_pr8 = [cache](offs_t address) -> u8 { return cache->read_byte(address); };
|
||||
}
|
||||
regs = &space(AS_DATA);
|
||||
|
||||
set_icountptr(icount);
|
||||
|
||||
state_add(STATE_GENPC, "GENPC", PC).noshow();
|
||||
state_add(STATE_GENPCBASE, "CURPC", PPC).noshow();
|
||||
state_add(STATE_GENSP, "GENSP", R[0]).noshow();
|
||||
state_add(STATE_GENSP, "GENSP", register_file[0]).noshow();
|
||||
state_add(STATE_GENFLAGS, "GENFLAGS", PSW).formatstr("%16s").noshow();
|
||||
state_add(MCS96_PC, "PC", PC);
|
||||
state_add(MCS96_PSW, "PSW", PSW);
|
||||
state_add(MCS96_R, "SP", R[0]);
|
||||
for(int i=1; i<0x74; i++) {
|
||||
char buf[10];
|
||||
sprintf(buf, "R%02x", i*2+0x18);
|
||||
state_add(MCS96_R+i, buf, R[i]);
|
||||
}
|
||||
|
||||
memset(R, 0, sizeof(R));
|
||||
state_add(MCS96_R, "SP", register_file[0]);
|
||||
}
|
||||
|
||||
void mcs96_device::device_reset()
|
||||
@ -126,7 +122,8 @@ void mcs96_device::execute_set_input(int inputnum, int state)
|
||||
device_memory_interface::space_config_vector mcs96_device::memory_space_config() const
|
||||
{
|
||||
return space_config_vector {
|
||||
std::make_pair(AS_PROGRAM, &program_config)
|
||||
std::make_pair(AS_PROGRAM, &program_config),
|
||||
std::make_pair(AS_DATA, ®s_config)
|
||||
};
|
||||
}
|
||||
|
||||
@ -163,190 +160,56 @@ void mcs96_device::state_string_export(const device_state_entry &entry, std::str
|
||||
}
|
||||
}
|
||||
|
||||
void mcs96_device::io_w8(uint8_t adr, uint8_t data)
|
||||
void mcs96_device::reg_w8(u8 adr, u8 data)
|
||||
{
|
||||
switch(adr) {
|
||||
case 0x02:
|
||||
logerror("%s: ad_command %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x03:
|
||||
logerror("%s: hsi_mode %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x04:
|
||||
logerror("%s: hso_time.l %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x05:
|
||||
logerror("%s: hso_time.h %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x06:
|
||||
logerror("%s: hso_command %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x07:
|
||||
logerror("%s: sbuf %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x08:
|
||||
PSW = (PSW & 0xff00) | data;
|
||||
break;
|
||||
case 0x09:
|
||||
logerror("%s: int_pending %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x0a:
|
||||
logerror("%s: watchdog %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x0e:
|
||||
logerror("%s: baud rate %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x0f:
|
||||
logerror("%s: io port 1 %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x10:
|
||||
logerror("%s: io port 2 %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x11:
|
||||
logerror("%s: sp con %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x15:
|
||||
logerror("%s: ioc0 %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x16:
|
||||
logerror("%s: ioc1 %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
case 0x17:
|
||||
logerror("%s: pwm control %02x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
regs->write_byte(adr, data);
|
||||
}
|
||||
|
||||
void mcs96_device::io_w16(uint8_t adr, uint16_t data)
|
||||
void mcs96_device::reg_w16(u8 adr, u16 data)
|
||||
{
|
||||
switch(adr) {
|
||||
case 0:
|
||||
break;
|
||||
case 4:
|
||||
logerror("%s: hso_time %04x (%04x)\n", tag(), data, PPC);
|
||||
break;
|
||||
default:
|
||||
io_w8(adr, data);
|
||||
io_w8(adr+1, data>>8);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t mcs96_device::io_r8(uint8_t adr)
|
||||
{
|
||||
switch(adr) {
|
||||
case 0x00:
|
||||
return 0x00;
|
||||
case 0x01:
|
||||
return 0x00;
|
||||
case 0x08:
|
||||
return PSW;
|
||||
}
|
||||
uint8_t data = 0x00;
|
||||
logerror("%s: io_r8 %02x, %02x (%04x)\n", tag(), adr, data, PPC);
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t mcs96_device::io_r16(uint8_t adr)
|
||||
{
|
||||
if(adr < 2)
|
||||
return 0x0000;
|
||||
uint16_t data = 0x0000;
|
||||
logerror("%s: io_r16 %02x, %04x (%04x)\n", tag(), adr, data, PPC);
|
||||
return data;
|
||||
}
|
||||
|
||||
void mcs96_device::reg_w8(uint8_t adr, uint8_t data)
|
||||
{
|
||||
if(adr < 0x18)
|
||||
io_w8(adr, data);
|
||||
else {
|
||||
uint16_t &r = R[(adr - 0x18) >> 1];
|
||||
if(adr & 0x01)
|
||||
r = (r & 0x00ff) | (data << 8);
|
||||
else
|
||||
r = (r & 0xff00) | data;
|
||||
}
|
||||
}
|
||||
|
||||
void mcs96_device::reg_w16(uint8_t adr, uint16_t data)
|
||||
{
|
||||
adr &= 0xfe;
|
||||
if(adr < 0x18)
|
||||
io_w16(adr, data);
|
||||
else
|
||||
R[(adr-0x18) >> 1] = data;
|
||||
regs->write_word(adr & 0xfe, data);
|
||||
}
|
||||
|
||||
uint8_t mcs96_device::reg_r8(uint8_t adr)
|
||||
{
|
||||
if(adr < 0x18)
|
||||
return io_r8(adr);
|
||||
|
||||
uint16_t data = R[(adr - 0x18) >> 1];
|
||||
if(adr & 0x01)
|
||||
return data >> 8;
|
||||
else
|
||||
return data;
|
||||
return regs->read_byte(adr);
|
||||
}
|
||||
|
||||
uint16_t mcs96_device::reg_r16(uint8_t adr)
|
||||
{
|
||||
adr &= 0xfe;
|
||||
if(adr < 0x18)
|
||||
return io_r16(adr);
|
||||
|
||||
return R[(adr-0x18) >> 1];
|
||||
return regs->read_word(adr & 0xfe);
|
||||
}
|
||||
|
||||
void mcs96_device::any_w8(uint16_t adr, uint8_t data)
|
||||
void mcs96_device::any_w8(u16 adr, u8 data)
|
||||
{
|
||||
if(adr < 0x18)
|
||||
io_w8(adr, data);
|
||||
else if(adr < 0x100) {
|
||||
uint16_t &r = R[(adr - 0x18) >> 1];
|
||||
if(adr & 0x01)
|
||||
r = (r & 0x00ff) | (data << 8);
|
||||
else
|
||||
r = (r & 0xff00) | data;
|
||||
} else
|
||||
if (adr < 0x100)
|
||||
regs->write_byte(adr, data);
|
||||
else
|
||||
program->write_byte(adr, data);
|
||||
}
|
||||
|
||||
void mcs96_device::any_w16(uint16_t adr, uint16_t data)
|
||||
void mcs96_device::any_w16(u16 adr, u16 data)
|
||||
{
|
||||
adr &= 0xfffe;
|
||||
if(adr < 0x18)
|
||||
io_w16(adr, data);
|
||||
else if(adr < 0x100)
|
||||
R[(adr-0x18) >> 1] = data;
|
||||
if (adr < 0x100)
|
||||
regs->write_word(adr, data);
|
||||
else
|
||||
program->write_word(adr, data);
|
||||
}
|
||||
|
||||
uint8_t mcs96_device::any_r8(uint16_t adr)
|
||||
u8 mcs96_device::any_r8(u16 adr)
|
||||
{
|
||||
if(adr < 0x18)
|
||||
return io_r8(adr);
|
||||
else if(adr < 0x100) {
|
||||
uint16_t data = R[(adr - 0x18) >> 1];
|
||||
if(adr & 0x01)
|
||||
return data >> 8;
|
||||
else
|
||||
return data;
|
||||
} else
|
||||
if (adr < 0x100)
|
||||
return regs->read_byte(adr);
|
||||
else
|
||||
return program->read_byte(adr);
|
||||
}
|
||||
|
||||
uint16_t mcs96_device::any_r16(uint16_t adr)
|
||||
u16 mcs96_device::any_r16(u16 adr)
|
||||
{
|
||||
adr &= 0xfffe;
|
||||
if(adr < 0x18)
|
||||
return io_r16(adr);
|
||||
else if(adr < 0x100)
|
||||
return R[(adr-0x18) >> 1];
|
||||
if (adr < 0x100)
|
||||
return regs->read_word(adr);
|
||||
else
|
||||
return program->read_word(adr);
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
mcs96_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int data_width);
|
||||
mcs96_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int data_width, address_map_constructor regs_map);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
@ -63,9 +63,10 @@ protected:
|
||||
virtual void state_export(const device_state_entry &entry) override;
|
||||
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
|
||||
|
||||
address_space_config program_config;
|
||||
address_space *program;
|
||||
address_space_config program_config, regs_config;
|
||||
address_space *program, *regs;
|
||||
std::function<u8 (offs_t address)> m_pr8;
|
||||
required_shared_ptr<u16> register_file;
|
||||
|
||||
int icount, bcount, inst_state, cycles_scaling;
|
||||
uint8_t pending_irq;
|
||||
@ -73,16 +74,11 @@ protected:
|
||||
uint16_t OP1;
|
||||
uint8_t OP2, OP3, OPI;
|
||||
uint32_t TMP;
|
||||
uint16_t R[0x74];
|
||||
bool irq_requested;
|
||||
|
||||
virtual void do_exec_full() = 0;
|
||||
virtual void do_exec_partial() = 0;
|
||||
virtual void internal_update(uint64_t current_time) = 0;
|
||||
virtual void io_w8(uint8_t adr, uint8_t data) = 0;
|
||||
virtual void io_w16(uint8_t adr, uint16_t data) = 0;
|
||||
virtual uint8_t io_r8(uint8_t adr) = 0;
|
||||
virtual uint16_t io_r16(uint8_t adr) = 0;
|
||||
|
||||
void recompute_bcount(uint64_t event_time);
|
||||
|
||||
|
@ -77,7 +77,6 @@ private:
|
||||
DECLARE_PALETTE_INIT(d110);
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void d110_io(address_map &map);
|
||||
void d110_map(address_map &map);
|
||||
|
||||
uint8_t m_lcd_data_buffer[256];
|
||||
@ -231,16 +230,11 @@ void d110_state::d110_map(address_map &map)
|
||||
map(0xc000, 0xffff).bankrw("fixed");
|
||||
}
|
||||
|
||||
void d110_state::d110_io(address_map &map)
|
||||
{
|
||||
map(i8x9x_device::SERIAL, i8x9x_device::SERIAL).w(FUNC(d110_state::midi_w));
|
||||
map(i8x9x_device::P0, i8x9x_device::P0).r(FUNC(d110_state::port0_r));
|
||||
}
|
||||
|
||||
MACHINE_CONFIG_START(d110_state::d110)
|
||||
MCFG_DEVICE_ADD( m_maincpu, P8098, XTAL(12'000'000) )
|
||||
MCFG_DEVICE_PROGRAM_MAP( d110_map )
|
||||
MCFG_DEVICE_IO_MAP( d110_io )
|
||||
P8098(config, m_maincpu, 12_MHz_XTAL);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &d110_state::d110_map);
|
||||
m_maincpu->serial_tx_cb().set(FUNC(d110_state::midi_w));
|
||||
m_maincpu->in_p0_cb().set(FUNC(d110_state::port0_r));
|
||||
|
||||
// Battery-backed main ram
|
||||
RAM( config, "ram" ).set_default_size( "32K" );
|
||||
|
@ -220,7 +220,6 @@ private:
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(midi_timer_cb);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(samples_timer_cb);
|
||||
|
||||
void mt32_io(address_map &map);
|
||||
void mt32_map(address_map &map);
|
||||
|
||||
uint8_t lcd_data_buffer[256];
|
||||
@ -348,17 +347,12 @@ void mt32_state::mt32_map(address_map &map)
|
||||
map(0xc000, 0xffff).bankrw("fixed");
|
||||
}
|
||||
|
||||
void mt32_state::mt32_io(address_map &map)
|
||||
{
|
||||
map(i8x9x_device::A7, i8x9x_device::A7).portr("A7");
|
||||
map(i8x9x_device::SERIAL, i8x9x_device::SERIAL).w(FUNC(mt32_state::midi_w));
|
||||
map(i8x9x_device::P0, i8x9x_device::P0).r(FUNC(mt32_state::port0_r));
|
||||
}
|
||||
|
||||
MACHINE_CONFIG_START(mt32_state::mt32)
|
||||
MCFG_DEVICE_ADD( "maincpu", P8098, XTAL(12'000'000) )
|
||||
MCFG_DEVICE_PROGRAM_MAP( mt32_map )
|
||||
MCFG_DEVICE_IO_MAP( mt32_io )
|
||||
i8x9x_device &maincpu(P8098(config, "maincpu", 12_MHz_XTAL));
|
||||
maincpu.set_addrmap(AS_PROGRAM, &mt32_state::mt32_map);
|
||||
maincpu.ach7_cb().set_ioport("A7");
|
||||
maincpu.serial_tx_cb().set(FUNC(mt32_state::midi_w));
|
||||
maincpu.in_p0_cb().set(FUNC(mt32_state::port0_r));
|
||||
|
||||
RAM( config, "ram" ).set_default_size( "32K" );
|
||||
|
||||
|
@ -53,7 +53,6 @@ public:
|
||||
private:
|
||||
required_device<i8x9x_device> m_maincpu;
|
||||
|
||||
void sc55_io(address_map &map);
|
||||
void sc55_map(address_map &map);
|
||||
};
|
||||
|
||||
@ -68,16 +67,12 @@ void sc55_state::sc55_map(address_map &map)
|
||||
map(0x1000, 0x3fff).rom().region("maincpu", 0x1000);
|
||||
}
|
||||
|
||||
void sc55_state::sc55_io(address_map &map)
|
||||
void sc55_state::sc55(machine_config &config)
|
||||
{
|
||||
P8098(config, m_maincpu, XTAL(20'000'000)); // probably not?
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &sc55_state::sc55_map);
|
||||
}
|
||||
|
||||
MACHINE_CONFIG_START(sc55_state::sc55)
|
||||
MCFG_DEVICE_ADD( "maincpu", P8098, XTAL(20'000'000) ) // probably not?
|
||||
MCFG_DEVICE_PROGRAM_MAP( sc55_map )
|
||||
MCFG_DEVICE_IO_MAP( sc55_io )
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
ROM_START( sc55 )
|
||||
ROM_REGION( 0x40000, "maincpu", 0 ) // additional H8/532 code and patch data - revisions match main CPU revisions
|
||||
ROM_LOAD( "roland_r15209363.ic23", 0x000000, 0x040000, CRC(2dc58549) SHA1(9c17f85e784dc1549ac1f98d457b353393331f6b) )
|
||||
|
Loading…
Reference in New Issue
Block a user