mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
f3853: add preliminary support for 3856, enough to get borisdpl playable (nw)
This commit is contained in:
parent
fa671f9308
commit
68c97d055c
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 )
|
||||
|
Loading…
Reference in New Issue
Block a user