diff options
Diffstat (limited to 'src/devices/machine/chessmachine.cpp')
-rw-r--r-- | src/devices/machine/chessmachine.cpp | 95 |
1 files changed, 50 insertions, 45 deletions
diff --git a/src/devices/machine/chessmachine.cpp b/src/devices/machine/chessmachine.cpp index d5f6673fbad..13eafaaddb7 100644 --- a/src/devices/machine/chessmachine.cpp +++ b/src/devices/machine/chessmachine.cpp @@ -10,14 +10,15 @@ This is the 2nd (1992) version of The ChessMachine, it is used in: - The ChessMachine EC2, Amiga external module - Mephisto Risc 1MB/II, chess computer -Unlike the SR model (devices/bus/isa/chessmsr.*), RAM size and CPU type -are the same on every known device. - +Hardware notes: - VLSI-ARM VY86C010-12QC (ARM2 CPU) - 1MB RAM (8*Siemens HYB514256B-60) - 128 bytes PROM (4*DM74S288AN) - 2 GALs for I/O handling +Unlike the SR model (devices/bus/isa/chessmsr.*), RAM size and CPU type +are the same on every known device. + Only 4 lines for I/O, so that part is much slower than the SR model. There is no XTAL, it looks like there's a variable resistor for tweaking @@ -25,14 +26,13 @@ CPU speed. It should be around 14-16MHz. The ARM CPU is rated 12MHz, they probably went for this solution to get optimum possible speed for each module. TODO: -- PC version still gives a sync error on boot sometimes, probably related to quantum - is interrupt handling correct? -- timer shouldn't be needed for disabling bootstrap, real ARM has already read the next opcode +- timer shouldn't be needed for disabling bootrom, real ARM has already read the next opcode */ #include "emu.h" -#include "machine/chessmachine.h" +#include "chessmachine.h" DEFINE_DEVICE_TYPE(CHESSMACHINE, chessmachine_device, "chessmachine", "Tasc ChessMachine") @@ -44,9 +44,7 @@ DEFINE_DEVICE_TYPE(CHESSMACHINE, chessmachine_device, "chessmachine", "Tasc Ches chessmachine_device::chessmachine_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, CHESSMACHINE, tag, owner, clock), m_maincpu(*this, "maincpu"), - m_bootstrap(*this, "bootstrap"), - m_ram(*this, "ram"), - m_disable_bootstrap(*this, "disable_bootstrap"), + m_boot_view(*this, "boot_view"), m_data_out(*this) { } @@ -58,15 +56,10 @@ chessmachine_device::chessmachine_device(const machine_config &mconfig, const ch void chessmachine_device::device_start() { - // resolve callbacks - m_data_out.resolve_safe(); - - // zerofill - m_bootstrap_enabled = false; - m_latch[0] = m_latch[1] = 0; + memset(m_latch, 0, sizeof(m_latch)); + m_boot_timer = timer_alloc(FUNC(chessmachine_device::disable_bootrom), this); // register for savestates - save_item(NAME(m_bootstrap_enabled)); save_item(NAME(m_latch)); } @@ -76,35 +69,52 @@ void chessmachine_device::device_start() // external handlers //------------------------------------------------- -void chessmachine_device::sync0_callback(void *ptr, s32 param) +void chessmachine_device::data0_w_sync(s32 param) { - m_latch[0] = (m_latch[0] & 0x80) | param; + if ((m_latch[0] & 1) != param) + { + machine().scheduler().perfect_quantum(attotime::from_usec(50)); + m_latch[0] = (m_latch[0] & 0x80) | param; + } } void chessmachine_device::data0_w(int state) { - machine().scheduler().synchronize(timer_expired_delegate(FUNC(chessmachine_device::sync0_callback), this), state ? 1 : 0); + machine().scheduler().synchronize(timer_expired_delegate(FUNC(chessmachine_device::data0_w_sync), this), state ? 1 : 0); } -void chessmachine_device::sync1_callback(void *ptr, s32 param) +void chessmachine_device::data1_w_sync(s32 param) { - m_latch[0] = (m_latch[0] & 1) | param; - - // cause interrupt? - m_maincpu->set_input_line(ARM_FIRQ_LINE, param ? ASSERT_LINE : CLEAR_LINE); + if ((m_latch[0] & 0x80) != param) + { + machine().scheduler().perfect_quantum(attotime::from_usec(50)); + m_latch[0] = (m_latch[0] & 1) | param; + + // cause interrupt? + m_maincpu->set_input_line(ARM_FIRQ_LINE, param ? ASSERT_LINE : CLEAR_LINE); + } } void chessmachine_device::data1_w(int state) { - machine().scheduler().synchronize(timer_expired_delegate(FUNC(chessmachine_device::sync1_callback), this), state ? 0x80 : 0); + machine().scheduler().synchronize(timer_expired_delegate(FUNC(chessmachine_device::data1_w_sync), this), state ? 0x80 : 0); } -void chessmachine_device::reset_w(int state) +void chessmachine_device::reset_w_sync(s32 param) { - m_maincpu->set_input_line(INPUT_LINE_RESET, state ? ASSERT_LINE : CLEAR_LINE); + m_maincpu->set_input_line(INPUT_LINE_RESET, param ? ASSERT_LINE : CLEAR_LINE); + + if (param) + { + // enable bootrom + m_boot_view.select(0); + m_boot_timer->adjust(attotime::never); + } +} - if (state) - m_bootstrap_enabled = true; +void chessmachine_device::reset_w(int state) +{ + machine().scheduler().synchronize(timer_expired_delegate(FUNC(chessmachine_device::reset_w_sync), this), state ? 1 : 0); } @@ -113,26 +123,23 @@ void chessmachine_device::reset_w(int state) // internal //------------------------------------------------- -u32 chessmachine_device::bootstrap_r(offs_t offset) -{ - return (m_bootstrap_enabled) ? m_bootstrap[offset] : m_ram[offset]; -} - -u32 chessmachine_device::disable_bootstrap_r() +u32 chessmachine_device::disable_bootrom_r() { - // disconnect bootstrap rom from the bus after next opcode - if (m_bootstrap_enabled && !m_disable_bootstrap->enabled() && !machine().side_effects_disabled()) - m_disable_bootstrap->adjust(m_maincpu->cycles_to_attotime(5)); + // disconnect bootrom from the bus after next opcode + if (!machine().side_effects_disabled() && m_boot_timer->remaining().is_never()) + m_boot_timer->adjust(m_maincpu->cycles_to_attotime(5)); return 0; } void chessmachine_device::main_map(address_map &map) { - map(0x00000000, 0x000fffff).ram().share("ram"); - map(0x00000000, 0x0000007f).r(FUNC(chessmachine_device::bootstrap_r)); - map(0x00400000, 0x00400000).mirror(0x003ffffc).rw(FUNC(chessmachine_device::internal_r), FUNC(chessmachine_device::internal_w)); - map(0x01800000, 0x01800003).r(FUNC(chessmachine_device::disable_bootstrap_r)); + map(0x00000000, 0x000fffff).ram(); + map(0x00000000, 0x0000007f).view(m_boot_view); + m_boot_view[0](0x00000000, 0x0000007f).rom().region("bootrom", 0); + + map(0x00400000, 0x00400003).mirror(0x003ffffc).rw(FUNC(chessmachine_device::internal_r), FUNC(chessmachine_device::internal_w)).umask32(0x000000ff); + map(0x01800000, 0x01800003).r(FUNC(chessmachine_device::disable_bootrom_r)); } void chessmachine_device::device_add_mconfig(machine_config &config) @@ -140,8 +147,6 @@ void chessmachine_device::device_add_mconfig(machine_config &config) ARM(config, m_maincpu, DERIVED_CLOCK(1,1)); m_maincpu->set_addrmap(AS_PROGRAM, &chessmachine_device::main_map); m_maincpu->set_copro_type(arm_cpu_device::copro_type::VL86C020); - - TIMER(config, "disable_bootstrap").configure_generic(FUNC(chessmachine_device::disable_bootstrap)); } @@ -151,7 +156,7 @@ void chessmachine_device::device_add_mconfig(machine_config &config) //------------------------------------------------- ROM_START( chessmachine ) - ROM_REGION32_LE( 0x80, "bootstrap", 0 ) + ROM_REGION32_LE( 0x80, "bootrom", 0 ) ROM_LOAD32_BYTE( "74s288.1", 0x00, 0x20, CRC(284114e2) SHA1(df4037536d505d7240bb1d70dc58f59a34ab77b4) ) ROM_LOAD32_BYTE( "74s288.2", 0x01, 0x20, CRC(9f239c75) SHA1(aafaf30dac90f36b01f9ee89903649fc4ea0480d) ) ROM_LOAD32_BYTE( "74s288.3", 0x02, 0x20, CRC(0455360b) SHA1(f1486142330f2c39a4d6c479646030d31443d1c8) ) |