diff options
author | 2019-03-11 22:42:09 +0100 | |
---|---|---|
committer | 2019-03-11 22:43:39 +0100 | |
commit | 68c97d055c8cca63bdcd3eba193ae5f379de7a44 (patch) | |
tree | 1b342ce0a97fd9ba002a355142e3a5e0d5cfb604 | |
parent | fa671f93083db6b82f424206729bb050e8c5737a (diff) |
f3853: add preliminary support for 3856, enough to get borisdpl playable (nw)
-rw-r--r-- | src/devices/cpu/f8/f8.cpp | 60 | ||||
-rw-r--r-- | src/devices/machine/f3853.cpp | 111 | ||||
-rw-r--r-- | src/devices/machine/f3853.h | 20 | ||||
-rw-r--r-- | src/mame/drivers/chesstrv.cpp | 46 |
4 files changed, 158 insertions, 79 deletions
diff --git a/src/devices/cpu/f8/f8.cpp b/src/devices/cpu/f8/f8.cpp index 8e550d48d27..a93b7aebd3a 100644 --- a/src/devices/cpu/f8/f8.cpp +++ b/src/devices/cpu/f8/f8.cpp @@ -1716,16 +1716,16 @@ void f8_cpu_device::execute_run() case 0x2e: illegal(); break; case 0x2f: illegal(); break; - case 0x30: f8_ds_r( 0); break; - case 0x31: f8_ds_r( 1); break; - case 0x32: f8_ds_r( 2); break; - case 0x33: f8_ds_r( 3); break; - case 0x34: f8_ds_r( 4); break; - case 0x35: f8_ds_r( 5); break; - case 0x36: f8_ds_r( 6); break; - case 0x37: f8_ds_r( 7); break; - case 0x38: f8_ds_r( 8); break; - case 0x39: f8_ds_r( 9); break; + case 0x30: f8_ds_r(0); break; + case 0x31: f8_ds_r(1); break; + case 0x32: f8_ds_r(2); break; + case 0x33: f8_ds_r(3); break; + case 0x34: f8_ds_r(4); break; + case 0x35: f8_ds_r(5); break; + case 0x36: f8_ds_r(6); break; + case 0x37: f8_ds_r(7); break; + case 0x38: f8_ds_r(8); break; + case 0x39: f8_ds_r(9); break; case 0x3a: f8_ds_r(10); break; case 0x3b: f8_ds_r(11); break; case 0x3c: f8_ds_isar(); break; @@ -1733,16 +1733,16 @@ void f8_cpu_device::execute_run() case 0x3e: f8_ds_isar_d(); break; case 0x3f: illegal(); break; - case 0x40: f8_lr_a_r( 0); break; - case 0x41: f8_lr_a_r( 1); break; - case 0x42: f8_lr_a_r( 2); break; - case 0x43: f8_lr_a_r( 3); break; - case 0x44: f8_lr_a_r( 4); break; - case 0x45: f8_lr_a_r( 5); break; - case 0x46: f8_lr_a_r( 6); break; - case 0x47: f8_lr_a_r( 7); break; - case 0x48: f8_lr_a_r( 8); break; - case 0x49: f8_lr_a_r( 9); break; + case 0x40: f8_lr_a_r(0); break; + case 0x41: f8_lr_a_r(1); break; + case 0x42: f8_lr_a_r(2); break; + case 0x43: f8_lr_a_r(3); break; + case 0x44: f8_lr_a_r(4); break; + case 0x45: f8_lr_a_r(5); break; + case 0x46: f8_lr_a_r(6); break; + case 0x47: f8_lr_a_r(7); break; + case 0x48: f8_lr_a_r(8); break; + case 0x49: f8_lr_a_r(9); break; case 0x4a: f8_lr_a_r(10); break; case 0x4b: f8_lr_a_r(11); break; case 0x4c: f8_lr_a_isar(); break; @@ -1750,16 +1750,16 @@ void f8_cpu_device::execute_run() case 0x4e: f8_lr_a_isar_d(); break; case 0x4f: illegal(); break; - case 0x50: f8_lr_r_a( 0); break; - case 0x51: f8_lr_r_a( 1); break; - case 0x52: f8_lr_r_a( 2); break; - case 0x53: f8_lr_r_a( 3); break; - case 0x54: f8_lr_r_a( 4); break; - case 0x55: f8_lr_r_a( 5); break; - case 0x56: f8_lr_r_a( 6); break; - case 0x57: f8_lr_r_a( 7); break; - case 0x58: f8_lr_r_a( 8); break; - case 0x59: f8_lr_r_a( 9); break; + case 0x50: f8_lr_r_a(0); break; + case 0x51: f8_lr_r_a(1); break; + case 0x52: f8_lr_r_a(2); break; + case 0x53: f8_lr_r_a(3); break; + case 0x54: f8_lr_r_a(4); break; + case 0x55: f8_lr_r_a(5); break; + case 0x56: f8_lr_r_a(6); break; + case 0x57: f8_lr_r_a(7); break; + case 0x58: f8_lr_r_a(8); break; + case 0x59: f8_lr_r_a(9); break; case 0x5a: f8_lr_r_a(10); break; case 0x5b: f8_lr_r_a(11); break; case 0x5c: f8_lr_isar_a(); break; diff --git a/src/devices/machine/f3853.cpp b/src/devices/machine/f3853.cpp index f4713f3fa3a..85b982634bb 100644 --- a/src/devices/machine/f3853.cpp +++ b/src/devices/machine/f3853.cpp @@ -32,19 +32,30 @@ // device type definition DEFINE_DEVICE_TYPE(F3853, f3853_device, "f3853_device", "F3853 SMI") +DEFINE_DEVICE_TYPE(F3856, f3856_device, "f3856_device", "F3856 PSU") //------------------------------------------------- // f3853_device - constructor //------------------------------------------------- -f3853_device::f3853_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, F3853, tag, owner, clock) - , m_int_req_callback(*this) - , m_pri_out_callback(*this) - , m_priority_line(false) - , m_external_interrupt_line(true) -{ -} +f3853_device::f3853_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : + device_t(mconfig, type, tag, owner, clock), + m_int_req_callback(*this), + m_pri_out_callback(*this), + m_int_vector(0), + m_prescaler(31), + m_priority_line(false), + m_external_interrupt_line(true) +{ } + +f3853_device::f3853_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + f3853_device(mconfig, F3853, tag, owner, clock) +{ } + +f3856_device::f3856_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + f3853_device(mconfig, F3856, tag, owner, clock) +{ } + void f3853_device::device_resolve_objects() { @@ -68,7 +79,14 @@ void f3853_device::device_start() m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(f3853_device::timer_callback),this)); + // zerofill (what's not in constructor) + m_external_enable = false; + m_timer_enable = false; + m_request_flipflop = false; + + // register for savestates save_item(NAME(m_int_vector)); + save_item(NAME(m_prescaler)); save_item(NAME(m_external_enable)); save_item(NAME(m_timer_enable)); save_item(NAME(m_request_flipflop)); @@ -83,14 +101,9 @@ void f3853_device::device_start() void f3853_device::device_reset() { - m_int_vector = 0; - m_external_enable = false; - m_timer_enable = false; - m_request_flipflop = false; - m_external_interrupt_line = true; - set_interrupt_request_line(); - - m_timer->enable(false); + // clear ports + for (int i = 0; i < 4; i++) + write(machine().dummy_space(), i, 0); } @@ -127,7 +140,7 @@ IRQ_CALLBACK_MEMBER(f3853_device::int_acknowledge) void f3853_device::timer_start(uint8_t value) { - attotime period = (value != 0xff) ? attotime::from_hz(clock()) * (m_value_to_cycle[value]*31) : attotime::never; + attotime period = (value != 0xff) ? attotime::from_hz(clock()) * (m_value_to_cycle[value] * m_prescaler) : attotime::never; m_timer->adjust(period); } @@ -181,7 +194,6 @@ READ8_MEMBER(f3853_device::read) return data; } - WRITE8_MEMBER(f3853_device::write) { switch(offset) @@ -194,13 +206,72 @@ WRITE8_MEMBER(f3853_device::write) m_int_vector = data | (m_int_vector & 0xff00); break; - case 2: //interrupt control + // interrupt control + case 2: m_external_enable = ((data & 3) == 1); m_timer_enable = ((data & 3) == 3); set_interrupt_request_line(); break; - case 3: //timer + // timer + case 3: + m_request_flipflop = false; + set_interrupt_request_line(); + timer_start(data); + break; + } +} + + +READ8_MEMBER(f3856_device::read) +{ + uint8_t data = 0; + + switch (offset) + { + case 0: + break; + + case 1: + break; + + case 2: + break; + + case 3: + break; + } + + return data; +} + +WRITE8_MEMBER(f3856_device::write) +{ + switch(offset) + { + case 0: + break; + + case 1: + break; + + // interrupt control + case 2: + // timer prescaler in high 3 bits + static const u8 prescaler[8] = { 0, 2, 5, 10, 20, 40, 100, 200 }; + m_prescaler = prescaler[data >> 5 & 7]; + + // TODO: event counter mode + if (m_prescaler == 0) + m_prescaler = 100; + + m_external_enable = bool(data & 1); + m_timer_enable = bool(data & 2); + set_interrupt_request_line(); + break; + + // timer + case 3: m_request_flipflop = false; set_interrupt_request_line(); timer_start(data); diff --git a/src/devices/machine/f3853.h b/src/devices/machine/f3853.h index 14c922871b1..d0fbfc09406 100644 --- a/src/devices/machine/f3853.h +++ b/src/devices/machine/f3853.h @@ -51,12 +51,15 @@ public: // construction/destruction f3853_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + // interrupt vector is a mask option on 3851 and 3856 + void set_int_vector(u16 vector) { m_int_vector = vector; } + auto int_req_callback() { return m_int_req_callback.bind(); } auto pri_out_callback() { return m_pri_out_callback.bind(); } template<typename Object> void set_int_daisy_chain_callback(Object &&cb) { m_int_daisy_chain_callback = std::forward<Object>(cb); } - DECLARE_READ8_MEMBER(read); - DECLARE_WRITE8_MEMBER(write); + virtual DECLARE_READ8_MEMBER(read); + virtual DECLARE_WRITE8_MEMBER(write); DECLARE_WRITE_LINE_MEMBER(ext_int_w); DECLARE_WRITE_LINE_MEMBER(pri_in_w); @@ -66,12 +69,13 @@ public: IRQ_CALLBACK_MEMBER(int_acknowledge); protected: + f3853_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + // device-level overrides virtual void device_resolve_objects() override; virtual void device_start() override; virtual void device_reset() override; -private: uint16_t timer_interrupt_vector() const { return m_int_vector & ~uint16_t(0x0080); } uint16_t external_interrupt_vector() const { return m_int_vector | uint16_t(0x0080); } @@ -83,6 +87,7 @@ private: device_irq_acknowledge_delegate m_int_daisy_chain_callback; uint16_t m_int_vector; // Bit 7 is set to 0 for timer interrupts, 1 for external interrupts + u8 m_prescaler; bool m_external_enable; bool m_timer_enable; @@ -96,8 +101,17 @@ private: uint8_t m_value_to_cycle[0x100]; }; +class f3856_device : public f3853_device +{ +public: + f3856_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual DECLARE_READ8_MEMBER(read) override; + virtual DECLARE_WRITE8_MEMBER(write) override; +}; // device type definition DECLARE_DEVICE_TYPE(F3853, f3853_device) +DECLARE_DEVICE_TYPE(F3856, f3856_device) #endif // MAME_MACHINE_F3853_H diff --git a/src/mame/drivers/chesstrv.cpp b/src/mame/drivers/chesstrv.cpp index 65620815942..6390002269f 100644 --- a/src/mame/drivers/chesstrv.cpp +++ b/src/mame/drivers/chesstrv.cpp @@ -4,14 +4,11 @@ Acetronic Chess Traveller - TODO: - - Add emulation of the 3870 MCU to the F8 core, including timer interrupt - that is used by the Boris Diplomat. - ******************************************************************************/ #include "emu.h" #include "cpu/f8/f8.h" +#include "machine/f3853.h" #include "machine/timer.h" #include "chesstrv.lh" #include "borisdpl.lh" @@ -83,8 +80,6 @@ private: DECLARE_WRITE8_MEMBER(display_w); DECLARE_READ8_MEMBER(keypad_r); - //TIMER_DEVICE_CALLBACK_MEMBER(timer_interrupt); - output_finder<8> m_digits; required_ioport_array<4> m_keypad; }; @@ -156,7 +151,7 @@ READ8_MEMBER(borisdpl_state::keypad_r) case 3: data |= m_keypad[3]->read(); break; } - return data; + return data | m_matrix; } @@ -179,6 +174,7 @@ void borisdpl_state::borisdpl_io(address_map &map) { map(0x00, 0x00).rw(FUNC(borisdpl_state::keypad_r), FUNC(borisdpl_state::matrix_w)); map(0x01, 0x01).w(FUNC(borisdpl_state::display_w)); + map(0x04, 0x07).rw("f3856", FUNC(f3856_device::read), FUNC(f3856_device::write)); map(0x04, 0x04).rw(FUNC(borisdpl_state::ram_r), FUNC(borisdpl_state::ram_w)); map(0x05, 0x05).rw(FUNC(borisdpl_state::ram_addr_r), FUNC(borisdpl_state::ram_addr_w)); } @@ -241,15 +237,8 @@ static INPUT_PORTS_START( borisdpl ) PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("H8") PORT_CODE(KEYCODE_H) PORT_CODE(KEYCODE_8) PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("9/SET") PORT_CODE(KEYCODE_S) PORT_CODE(KEYCODE_9) PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("CE") PORT_CODE(KEYCODE_DEL) - INPUT_PORTS_END -/* -TIMER_DEVICE_CALLBACK_MEMBER(borisdpl_state::timer_interrupt) -{ - m_maincpu->set_input_line_and_vector(F8_INPUT_LINE_INT_REQ, HOLD_LINE, 0x20); -} -*/ void chesstrv_base_state::machine_start() { @@ -271,27 +260,32 @@ void borisdpl_state::machine_start() m_digits.resolve(); } -MACHINE_CONFIG_START(chesstrv_state::chesstrv) +void chesstrv_state::chesstrv(machine_config &config) +{ /* basic machine hardware */ - MCFG_DEVICE_ADD( "maincpu", F8, 3000000 ) // Fairchild 3870 - MCFG_DEVICE_PROGRAM_MAP( chesstrv_mem ) - MCFG_DEVICE_IO_MAP( chesstrv_io ) + F8(config, m_maincpu, 3000000/2); // Fairchild 3870, measured ~3MHz + m_maincpu->set_addrmap(AS_PROGRAM, &chesstrv_state::chesstrv_mem); + m_maincpu->set_addrmap(AS_IO, &chesstrv_state::chesstrv_io); /* video hardware */ config.set_default_layout(layout_chesstrv); -MACHINE_CONFIG_END +} -MACHINE_CONFIG_START(borisdpl_state::borisdpl) +void borisdpl_state::borisdpl(machine_config &config) +{ /* basic machine hardware */ - MCFG_DEVICE_ADD( "maincpu", F8, 30000000 ) // Motorola SC80265P - MCFG_DEVICE_PROGRAM_MAP( chesstrv_mem ) - MCFG_DEVICE_IO_MAP( borisdpl_io ) + F8(config, m_maincpu, 4000000/2); // Motorola SC80265P, frequency guessed + m_maincpu->set_addrmap(AS_PROGRAM, &borisdpl_state::chesstrv_mem); + m_maincpu->set_addrmap(AS_IO, &borisdpl_state::borisdpl_io); + m_maincpu->set_irq_acknowledge_callback("f3856", FUNC(f3856_device::int_acknowledge)); + + f3856_device &f3856(F3856(config, "f3856", 4000000/2)); + f3856.set_int_vector(0x5020); + f3856.int_req_callback().set_inputline("maincpu", F8_INPUT_LINE_INT_REQ); /* video hardware */ config.set_default_layout(layout_borisdpl); - - //TIMER(config, "timer_interrupt").configure_periodic(FUNC(borisdpl_state::timer_interrupt), attotime::from_hz(40)); -MACHINE_CONFIG_END +} ROM_START( chesstrv ) |