summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2019-03-11 22:42:09 +0100
committer hap <happppp@users.noreply.github.com>2019-03-11 22:43:39 +0100
commit68c97d055c8cca63bdcd3eba193ae5f379de7a44 (patch)
tree1b342ce0a97fd9ba002a355142e3a5e0d5cfb604
parentfa671f93083db6b82f424206729bb050e8c5737a (diff)
f3853: add preliminary support for 3856, enough to get borisdpl playable (nw)
-rw-r--r--src/devices/cpu/f8/f8.cpp60
-rw-r--r--src/devices/machine/f3853.cpp111
-rw-r--r--src/devices/machine/f3853.h20
-rw-r--r--src/mame/drivers/chesstrv.cpp46
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 )