Machines promoted to working

-----------
Boris [hap, Sean Riddle]
This commit is contained in:
hap 2019-03-10 20:17:42 +01:00
parent 9af0dee629
commit 3e1d84b7fa
15 changed files with 348 additions and 128 deletions

View File

@ -59,7 +59,7 @@
<info name="serial" value="CM62218"/>
<part name="cart" interface="k28m2">
<dataarea name="rom" size="0x4000">
<rom name="cm62217.vsm" size="0x4000" crc="x" sha1="x" offset="0" />
<rom name="cm62218.vsm" size="0x4000" crc="x" sha1="x" offset="0" />
</dataarea>
</part>
</software>

View File

@ -3761,6 +3761,7 @@ files {
MAME_DIR .. "src/mame/drivers/aaa.cpp",
MAME_DIR .. "src/mame/drivers/acd.cpp",
MAME_DIR .. "src/mame/drivers/aceex.cpp",
MAME_DIR .. "src/mame/drivers/aci_boris.cpp",
MAME_DIR .. "src/mame/drivers/adm23.cpp",
MAME_DIR .. "src/mame/drivers/adm31.cpp",
MAME_DIR .. "src/mame/drivers/akaiax80.cpp",

View File

@ -37,11 +37,11 @@
/* status flags */
static constexpr u8 S = 0x01;
static constexpr u8 C = 0x02;
static constexpr u8 Z = 0x04;
static constexpr u8 O = 0x08;
static constexpr u8 I = 0x10;
static constexpr u8 S = 0x01; // sign
static constexpr u8 C = 0x02; // carry
static constexpr u8 Z = 0x04; // zero
static constexpr u8 O = 0x08; // overflow
static constexpr u8 I = 0x10; // interrupt control bit (ICB)
/* cycle (short/long) */
static constexpr int cS = 4;
@ -216,30 +216,6 @@ void f8_cpu_device::device_reset()
ROMC_08();
/* fetch the first opcode */
ROMC_00(cS);
/* initialize the timer shift register
* this is an 8 bit polynomial counter which can be loaded parallel
* with 0xff the outputs never change and thus the timer is disabled.
* with 0xfe the shifter starts cycling through 255 states until it
* reaches 0xfe again (and then issues an interrupt).
* the counter output values are not sequential, but go like this:
* 0xfe, 0xfd, 0xfb, 0xf7, 0xee, 0xdc ... etc. :-)
* We have to build a lookup table to tell how many cycles a write
*/
u8 data = 0xfe; /* initial value */
for (int i = 0; i < 256; i++)
{
timer_shifter[i] = data;
if ( (((data >> 3) ^ (data >> 4)) ^ ((data >> 5) ^ (data >> 7))) & 1 )
{
data <<= 1;
}
else
{
data = (data << 1) | 1;
}
}
}
@ -516,7 +492,7 @@ void f8_cpu_device::ROMC_10()
/*
* Inhibit any modification to the interrupt priority logic.
*/
m_w |= 0x20; /* ???? */
// TODO
m_icount -= cL;
}
@ -1002,7 +978,7 @@ void f8_cpu_device::f8_pop()
void f8_cpu_device::f8_lr_w_j()
{
ROMC_1C(cS);
m_w = m_r[9];
m_w = m_r[9] & 0x1f;
}
/***************************************************
@ -1955,17 +1931,19 @@ void f8_cpu_device::execute_run()
case 0xff: /* 1111 1111 */ illegal(); break;
}
switch (op) {
case 0x0d: case 0x1b: case 0x1c: case 0x1d:
case 0x0c: case 0x1b: case 0x1c: case 0x1d:
case 0x27: case 0x28: case 0x29:
case 0xb4: case 0xb5: case 0xb6: case 0xb7:
case 0xb8: case 0xb9: case 0xba: case 0xbb:
case 0xbc: case 0xbd: case 0xbe: case 0xbf:
// don't handle irq after privileged instruction
ROMC_00(cS);
break;
default:
if (m_w&I && m_irq_request)
{
ROMC_10();
ROMC_1C(cL);
ROMC_0F();
ROMC_13();

View File

@ -76,9 +76,6 @@ private:
u8 m_r[64]; /* scratchpad RAM */
int m_irq_request;
/* timer shifter polynomial values (will be used for timer interrupts) */
u8 timer_shifter[256];
u16 m_debug_pc; // only for the MAME debugger
inline void CLR_OZCS();

View File

@ -301,7 +301,7 @@ void tms1k_base_device::read_opcode()
{
debugger_instruction_hook(m_rom_address);
m_opcode = m_program->read_byte(m_rom_address);
m_c4 = bitswap<8>(m_opcode,7,6,5,4,0,1,2,3) & 0xf; // opcode operand is bitswapped for most opcodes
m_c4 = bitswap<4>(m_opcode,0,1,2,3); // opcode operand is bitswapped for most opcodes
m_fixed = m_fixed_decode[m_opcode];
m_micro = m_micro_decode[m_opcode];

View File

@ -0,0 +1,245 @@
// license:BSD-3-Clause
// copyright-holders:hap
// thanks-to:Sean Riddle
/******************************************************************************
Applied Concepts Boris (electronic chess computer)
- MK3850N-3 CPU @ 2 MHz, MK3853N memory interface
- 256 bytes RAM(2*2112), AMI 2KB ROM + AMI 1KB(?*) ROM *: less than 512 bytes used
- 8-digit 16seg led panel
When it was first released, it was in kit form. An extensive assembly manual with
schematics was included. It was later distributed by Chafitz in pre-assembled form.
There's also an updated revision, identifiable by the startup message "Boris awaits
your move"(same as Boris Master) instead of "Boris plays black".
******************************************************************************/
#include "emu.h"
#include "cpu/f8/f8.h"
#include "machine/f3853.h"
#include "machine/timer.h"
#include "aci_boris.lh"
namespace {
class boris_state : public driver_device
{
public:
boris_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_delay_display(*this, "delay_display_%u", 0),
m_inp_matrix(*this, "IN.%u", 0),
m_out_digit(*this, "digit%u", 0U)
{ }
void boris(machine_config &config);
// reset switch is tied to MK3850 RESET pin
DECLARE_INPUT_CHANGED_MEMBER(reset_button) { m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? ASSERT_LINE : CLEAR_LINE); }
protected:
virtual void machine_start() override;
private:
// devices/pointers
required_device<cpu_device> m_maincpu;
required_device_array<timer_device, 8> m_delay_display;
required_ioport_array<4> m_inp_matrix;
output_finder<8> m_out_digit;
void main_map(address_map &map);
void main_io(address_map &map);
TIMER_DEVICE_CALLBACK_MEMBER(delay_display);
DECLARE_WRITE8_MEMBER(mux_w);
DECLARE_WRITE8_MEMBER(digit_w);
DECLARE_READ8_MEMBER(input_r);
void update_4042();
u8 m_io[2]; // MK3850 I/O ports
u8 m_4042; // 4042 latch output
};
void boris_state::machine_start()
{
// resolve handlers
m_out_digit.resolve();
// zerofill
memset(m_io, 0, sizeof(m_io));
m_4042 = 0;
// register for savestates
save_item(NAME(m_io));
save_item(NAME(m_4042));
}
/******************************************************************************
Devices, I/O
******************************************************************************/
// MK3850 ports/TTL
TIMER_DEVICE_CALLBACK_MEMBER(boris_state::delay_display)
{
// 16 segments via port 1 and 4042 output (latched port 1)
u16 mask = (param & 0x10) ? 0xffff : 0;
m_out_digit[param & 7] = ~(m_4042 << 8 | m_io[1]) & mask;
}
void boris_state::update_4042()
{
// port 1 is latched as long as 4042 clock is low
// (yes low, this is actually (~~m_io[0] & 8) since output ports are inverted)
if (m_io[0] & 8)
m_4042 = bitswap<8>(m_io[1],4,2,0,6,5,1,3,7);
}
WRITE8_MEMBER(boris_state::mux_w)
{
// IO00-IO02: 4028 A-C to digit/input mux (4028 D to GND)
u8 prev = ~m_io[0] & 7;
u8 sel = ~data & 7;
if (sel != prev)
{
// digits are strobed, so on falling edge, delay them going off to prevent flicker
m_delay_display[prev]->adjust(attotime::from_msec(50), prev);
// need a short delay on rising edge too, while boris sets up digit segments
// (it writes port 1, increments digit, latches port 1, writes port 1 again)
m_delay_display[sel]->adjust(attotime::from_usec(50), sel | 0x10);
}
// IO03: clock 4042
m_io[0] = data;
update_4042();
}
READ8_MEMBER(boris_state::input_r)
{
// IO04-IO07: multiplexed inputs from 4028 4-7
u8 data = m_io[0];
u8 sel = ~data & 7;
if (sel >= 4)
data |= m_inp_matrix[sel-4]->read() << 4;
return data;
}
WRITE8_MEMBER(boris_state::digit_w)
{
// IO10-IO17: digit segments
m_io[1] = data;
update_4042();
}
/******************************************************************************
Address Maps
******************************************************************************/
void boris_state::main_map(address_map &map)
{
map.global_mask(0x0fff);
map(0x0000, 0x0bff).rom();
map(0x0c00, 0x0fff).ram();
}
void boris_state::main_io(address_map &map)
{
map(0x0, 0x0).rw(FUNC(boris_state::input_r), FUNC(boris_state::mux_w));
map(0x1, 0x1).w(FUNC(boris_state::digit_w));
map(0xc, 0xf).rw("f3853", FUNC(f3853_device::read), FUNC(f3853_device::write));
}
/******************************************************************************
Input Ports
******************************************************************************/
static INPUT_PORTS_START( boris )
PORT_START("IN.0")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_G) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("G.7")
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_H) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("H.8")
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("Set / 9")
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("CE") // clear entry
PORT_START("IN.1")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_D) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("D.4 / Rook")
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("E.5 / Queen")
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("F.6 / King")
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Time")
PORT_START("IN.2")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("A.1 / Pawn")
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_B) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("B.2 / Knight")
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_C) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("C.3 / Bishop")
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_N) PORT_NAME("Rank")
PORT_START("IN.3")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0")
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_SPACE) PORT_CODE(KEYCODE_MINUS) PORT_NAME("-")
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("B/W") // black/white
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter")
PORT_START("RESET")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_R) PORT_TOGGLE PORT_CHANGED_MEMBER(DEVICE_SELF, boris_state, reset_button, nullptr) PORT_NAME("Reset Switch")
INPUT_PORTS_END
/******************************************************************************
Machine Configs
******************************************************************************/
void boris_state::boris(machine_config &config)
{
/* basic machine hardware */
F8(config, m_maincpu, 2_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &boris_state::main_map);
m_maincpu->set_addrmap(AS_IO, &boris_state::main_io);
m_maincpu->set_irq_acknowledge_callback("f3853", FUNC(f3853_device::int_acknowledge));
f3853_device &f3853(F3853(config, "f3853", 2_MHz_XTAL));
f3853.int_req_callback().set_inputline("maincpu", F8_INPUT_LINE_INT_REQ);
/* video hardware */
for (int i = 0; i < 8; i++)
TIMER(config, m_delay_display[i]).configure_generic(FUNC(boris_state::delay_display));
config.set_default_layout(layout_aci_boris);
}
/******************************************************************************
ROM Definitions
******************************************************************************/
ROM_START( boris )
ROM_REGION( 0x1000, "maincpu", 0 )
ROM_LOAD("007-7020-00_c10502", 0x0000, 0x0800, CRC(18182870) SHA1(cb717a4b5269b04b0d7ae61aaf4a8f6a019626a5) )
ROM_LOAD("007-7021-00_c10503", 0x0800, 0x0400, CRC(49b77505) SHA1(474b665ee2955497f6d70878d817f1783ba1a835) )
ROM_END
} // anonymous namespace
/******************************************************************************
Drivers
******************************************************************************/
// YEAR NAME PARENT CMP MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS
COMP( 1978, boris, 0, 0, boris, boris, boris_state, empty_init, "Applied Concepts", "Boris", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND_HW )

View File

@ -301,14 +301,6 @@ ROM_START( chesstrv )
ROM_REGION(0x0100, "ram", ROMREGION_ERASE)
ROM_END
ROM_START( boris )
ROM_REGION(0x0c00, "maincpu", 0)
ROM_LOAD("007-7020-00_c10502_korea.bin", 0x0000, 0x0800, CRC(18182870) SHA1(cb717a4b5269b04b0d7ae61aaf4a8f6a019626a5))
ROM_LOAD("007-7021-00_c10503_korea.bin", 0x0800, 0x0400, CRC(49b77505) SHA1(474b665ee2955497f6d70878d817f1783ba1a835))
ROM_REGION(0x0100, "ram", ROMREGION_ERASE)
ROM_END
ROM_START( borisdpl )
ROM_REGION(0x0800, "maincpu", 0)
ROM_LOAD("007-7024-00_7847.u8", 0x0000, 0x0800, CRC(e20bac03) SHA1(9e17b9d90522371fbf7018926356150f70b9a3b6))
@ -319,5 +311,4 @@ ROM_END
// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS
CONS( 1980, chesstrv, 0, 0, chesstrv, chesstrv, chesstrv_state, empty_init, "Acetronic", "Chess Traveller", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE )
CONS( 1979, boris, 0, 0, borisdpl, borisdpl, borisdpl_state, empty_init, "Applied Concepts", "Boris - Electronic Chess Computer", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE )
CONS( 1979, borisdpl, 0, 0, borisdpl, borisdpl, borisdpl_state, empty_init, "Applied Concepts", "Boris Diplomat", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE )

View File

@ -40,6 +40,7 @@ TODO:
#include "tgm.lh"
namespace {
class tgm_state : public driver_device
@ -49,7 +50,7 @@ public:
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_beeper(*this, "beeper"),
m_vfd_delay(*this, "vfd_delay_%u", 0),
m_delay_display(*this, "delay_display_%u", 0),
m_inp_matrix(*this, "IN.%u", 0),
m_out_digit(*this, "digit%u", 0U)
{ }
@ -63,26 +64,26 @@ private:
// devices/pointers
required_device<cpu_device> m_maincpu;
required_device<beep_device> m_beeper;
required_device_array<timer_device, 12> m_vfd_delay;
required_device_array<timer_device, 12> m_delay_display;
required_ioport_array<10> m_inp_matrix;
output_finder<12> m_out_digit;
void main_map(address_map &map);
void main_io(address_map &map);
TIMER_DEVICE_CALLBACK_MEMBER(vfd_delay_off);
TIMER_DEVICE_CALLBACK_MEMBER(delay_display);
void display_update(u16 edge);
void update_display(u16 edge);
DECLARE_WRITE8_MEMBER(mux1_w);
DECLARE_WRITE8_MEMBER(mux2_w);
DECLARE_WRITE8_MEMBER(_7seg_w);
DECLARE_WRITE8_MEMBER(digit_w);
DECLARE_READ8_MEMBER(input_r);
DECLARE_WRITE8_MEMBER(sound_w);
DECLARE_READ8_MEMBER(timer_r);
u16 m_inp_mux;
u16 m_digit_select;
u8 m_7seg_data;
u8 m_digit_data;
};
void tgm_state::machine_start()
@ -93,40 +94,41 @@ void tgm_state::machine_start()
// zerofill
m_inp_mux = 0;
m_digit_select = 0;
m_7seg_data = 0;
m_digit_data = 0;
// register for savestates
save_item(NAME(m_inp_mux));
save_item(NAME(m_digit_select));
save_item(NAME(m_7seg_data));
save_item(NAME(m_digit_data));
}
/******************************************************************************
Devices, I/O
******************************************************************************/
// VFD handling
// display handling
TIMER_DEVICE_CALLBACK_MEMBER(tgm_state::vfd_delay_off)
TIMER_DEVICE_CALLBACK_MEMBER(tgm_state::delay_display)
{
// clear VFD outputs
if (!BIT(m_digit_select, param))
m_out_digit[param] = 0;
}
void tgm_state::display_update(u16 edge)
void tgm_state::update_display(u16 edge)
{
for (int i = 0; i < 12; i++)
{
// output VFD digit data
if (BIT(m_digit_select, i))
m_out_digit[i] = m_7seg_data;
m_out_digit[i] = m_digit_data;
// they're strobed, so on falling edge, delay them going off to prevent flicker
// BTANB: some digit segments get stuck after crashing in the GP game, it's not due to the simulated delay here
else if (BIT(edge, i))
m_vfd_delay[i]->adjust(attotime::from_msec(20), i);
m_delay_display[i]->adjust(attotime::from_msec(20), i);
}
}
@ -141,7 +143,7 @@ WRITE8_MEMBER(tgm_state::mux1_w)
// P00-P07: digit select part
u16 prev = m_digit_select;
m_digit_select = (m_digit_select & 0xf) | (data << 4);
display_update(m_digit_select ^ prev);
update_display(m_digit_select ^ prev);
}
WRITE8_MEMBER(tgm_state::mux2_w)
@ -152,14 +154,14 @@ WRITE8_MEMBER(tgm_state::mux2_w)
// P14-P17: digit select part
u16 prev = m_digit_select;
m_digit_select = (m_digit_select & 0xff0) | (data >> 4 & 0xf);
display_update(m_digit_select ^ prev);
update_display(m_digit_select ^ prev);
}
WRITE8_MEMBER(tgm_state::_7seg_w)
WRITE8_MEMBER(tgm_state::digit_w)
{
// P50-P57: digit 7seg data
m_7seg_data = bitswap<8>(data,0,1,2,3,4,5,6,7);
display_update(0);
m_digit_data = bitswap<8>(data,0,1,2,3,4,5,6,7);
update_display(0);
}
READ8_MEMBER(tgm_state::input_r)
@ -202,17 +204,17 @@ READ8_MEMBER(tgm_state::timer_r)
void tgm_state::main_map(address_map &map)
{
map.global_mask(0x7ff);
map.global_mask(0x07ff);
map(0x0000, 0x07ff).rom();
}
void tgm_state::main_io(address_map &map)
{
map(0x00, 0x00).w(FUNC(tgm_state::mux1_w));
map(0x01, 0x01).rw(FUNC(tgm_state::input_r), FUNC(tgm_state::mux2_w));
map(0x04, 0x04).w(FUNC(tgm_state::sound_w));
map(0x05, 0x05).w(FUNC(tgm_state::_7seg_w));
map(0x07, 0x07).r(FUNC(tgm_state::timer_r));
map(0x0, 0x0).w(FUNC(tgm_state::mux1_w));
map(0x1, 0x1).rw(FUNC(tgm_state::input_r), FUNC(tgm_state::mux2_w));
map(0x4, 0x4).w(FUNC(tgm_state::sound_w));
map(0x5, 0x5).w(FUNC(tgm_state::digit_w));
map(0x7, 0x7).r(FUNC(tgm_state::timer_r));
}
@ -278,7 +280,7 @@ void tgm_state::tgm(machine_config &config)
/* video hardware */
for (int i = 0; i < 12; i++)
TIMER(config, m_vfd_delay[i]).configure_generic(FUNC(tgm_state::vfd_delay_off));
TIMER(config, m_delay_display[i]).configure_generic(FUNC(tgm_state::delay_display));
config.set_default_layout(layout_tgm);

View File

@ -295,8 +295,8 @@ void wildfire_state::speaker_update()
TIMER_DEVICE_CALLBACK_MEMBER(wildfire_state::speaker_decay_sim)
{
// volume decays when speaker is off (divisor and timer period determine duration)
m_speaker_volume /= 1.001;
speaker_update();
m_speaker_volume /= 1.0025;
}
void wildfire_state::prepare_display()

View File

@ -64,7 +64,7 @@ public:
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_ppi8255(*this, "ppi8255"),
m_led_delay(*this, "led_delay_%u", 0),
m_delay_display(*this, "delay_display_%u", 0),
m_keypad(*this, "IN.%u", 0),
m_dac(*this, "dac"),
m_cart(*this, "cartslot"),
@ -85,7 +85,7 @@ private:
// devices/pointers
required_device<cpu_device> m_maincpu;
required_device<i8255_device> m_ppi8255;
required_device_array<timer_device, 6> m_led_delay;
required_device_array<timer_device, 6> m_delay_display;
required_ioport_array<2> m_keypad;
required_device<dac_bit_interface> m_dac;
required_device<generic_slot_device> m_cart;
@ -96,9 +96,9 @@ private:
// display stuff
void update_display();
TIMER_DEVICE_CALLBACK_MEMBER(led_delay_off);
TIMER_DEVICE_CALLBACK_MEMBER(delay_display);
u8 m_7seg_data;
u8 m_digit_data;
u8 m_led_select;
u8 m_led_active;
@ -108,7 +108,7 @@ private:
// I/O handlers
DECLARE_READ8_MEMBER(input_r);
DECLARE_WRITE8_MEMBER(_7seg_w);
DECLARE_WRITE8_MEMBER(digit_w);
DECLARE_WRITE8_MEMBER(control_w);
};
@ -119,17 +119,18 @@ void intel02_state::machine_start()
m_out_digit.resolve();
// zerofill
m_7seg_data = 0;
m_digit_data = 0;
m_led_select = 0;
m_led_active = 0;
// register for savestates
save_item(NAME(m_7seg_data));
save_item(NAME(m_digit_data));
save_item(NAME(m_led_select));
save_item(NAME(m_led_active));
}
/******************************************************************************
Devices, I/O
******************************************************************************/
@ -154,7 +155,7 @@ void intel02_state::update_display()
for (int i = 0; i < 4; i++)
{
if (BIT(m_led_select, i))
m_out_digit[i] = m_7seg_data;
m_out_digit[i] = m_digit_data;
else if (!BIT(m_led_active, i))
m_out_digit[i] = 0;
}
@ -164,7 +165,7 @@ void intel02_state::update_display()
m_out_led[1] = BIT(m_led_active, 5);
}
TIMER_DEVICE_CALLBACK_MEMBER(intel02_state::led_delay_off)
TIMER_DEVICE_CALLBACK_MEMBER(intel02_state::delay_display)
{
u8 mask = 1 << param;
m_led_active = (m_led_active & ~mask) | (m_led_select & mask);
@ -181,10 +182,10 @@ READ8_MEMBER(intel02_state::input_r)
return (count_leading_zeros(m_keypad[0]->read()) - 17) | (~m_keypad[1]->read() << 4 & 0xf0);
}
WRITE8_MEMBER(intel02_state::_7seg_w)
WRITE8_MEMBER(intel02_state::digit_w)
{
// d0-d7: digit segment data
m_7seg_data = bitswap<8>(data,7,0,1,2,3,4,5,6);
m_digit_data = bitswap<8>(data,7,0,1,2,3,4,5,6);
update_display();
}
@ -198,7 +199,7 @@ WRITE8_MEMBER(intel02_state::control_w)
// they're strobed, so on falling edge, delay them going off to prevent flicker
else if (BIT(m_led_select, i))
m_led_delay[i]->adjust(attotime::from_msec(10), i);
m_delay_display[i]->adjust(attotime::from_msec(10), i);
}
m_led_select = data;
@ -274,13 +275,13 @@ void intel02_state::intel02(machine_config &config)
I8255(config, m_ppi8255);
m_ppi8255->in_pa_callback().set(FUNC(intel02_state::input_r));
m_ppi8255->tri_pa_callback().set_constant(0);
m_ppi8255->out_pb_callback().set(FUNC(intel02_state::_7seg_w));
m_ppi8255->out_pb_callback().set(FUNC(intel02_state::digit_w));
m_ppi8255->tri_pb_callback().set_constant(0);
m_ppi8255->out_pc_callback().set(FUNC(intel02_state::control_w));
/* video hardware */
for (int i = 0; i < 6; i++)
TIMER(config, m_led_delay[i]).configure_generic(FUNC(intel02_state::led_delay_off));
TIMER(config, m_delay_display[i]).configure_generic(FUNC(intel02_state::delay_display));
config.set_default_layout(layout_intellect02);

View File

@ -214,4 +214,4 @@ ROM_END
***************************************************************************/
// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS
CONS( 1979, ccmk1, 0, 0, mk1, mk1, mk1_state, empty_init, "Novag", "Chess Champion: MK I", MACHINE_NO_SOUND_HW )
CONS( 1978, ccmk1, 0, 0, mk1, mk1, mk1_state, empty_init, "Novag", "Chess Champion: MK I", MACHINE_NO_SOUND_HW )

View File

@ -5,17 +5,18 @@
*
* novag_delta1.cpp, subdriver of machine/novagbase.cpp, machine/chessbase.cpp
TODO:
- ccdelta1 doesn't work, goes bonkers when you press Enter. CPU core bug?
I suspect related to interrupts
Novag Delta-1, the chess engine seems similar to Boris (see aci_boris.cpp)
*******************************************************************************
Novag Delta-1 overview:
- 3850PK CPU at ~2MHz, 3853PK memory interface
- 4KB ROM(2332A), 256 bytes RAM(2*2111A-4)
- 4-digit 7seg panel, no sound, no chessboard
TODO:
- After the computer is done calculating its move, sometimes it will blank the
display, making game progress impossible. CPU bug, or unexpected interrupt?
An easy way to repro this is by repeatedly pressing enter without inputting
a move: it's a feature to make it play against itself.
******************************************************************************/
#include "emu.h"
@ -40,32 +41,17 @@ public:
// machine drivers
void delta1(machine_config &config);
protected:
virtual void machine_start() override;
private:
// address maps
void main_map(address_map &map);
void main_io(address_map &map);
// I/O handlers
DECLARE_WRITE8_MEMBER(io0_w);
DECLARE_WRITE8_MEMBER(io1_w);
DECLARE_READ8_MEMBER(io0_r);
DECLARE_READ8_MEMBER(io1_r);
u8 m_io[2]; // F8 CPU I/O ports
DECLARE_WRITE8_MEMBER(mux_w);
DECLARE_WRITE8_MEMBER(digit_w);
DECLARE_READ8_MEMBER(input_r);
};
void delta1_state::machine_start()
{
novagbase_state::machine_start();
// zerofill/register for savestates
memset(m_io, 0, sizeof(m_io));
save_item(NAME(m_io));
}
/******************************************************************************
Devices, I/O
@ -73,10 +59,8 @@ void delta1_state::machine_start()
// CPU I/O ports
WRITE8_MEMBER(delta1_state::io0_w)
WRITE8_MEMBER(delta1_state::mux_w)
{
m_io[0] = data;
// IO00-02: MC14028B A-C (IO03: GND)
// MC14028B Q3-Q7: input mux
// MC14028B Q4-Q7: digit select through 75492
@ -86,30 +70,24 @@ WRITE8_MEMBER(delta1_state::io0_w)
// update display here
set_display_segmask(0xf, 0x7f);
display_matrix(7, 4, m_7seg_data, sel >> 4);
m_led_select = data;
}
READ8_MEMBER(delta1_state::io0_r)
READ8_MEMBER(delta1_state::input_r)
{
// IO04-07: multiplexed inputs
return read_inputs(5) << 4 | m_io[0];
return read_inputs(5) << 4 | m_led_select;
}
WRITE8_MEMBER(delta1_state::io1_w)
WRITE8_MEMBER(delta1_state::digit_w)
{
m_io[1] = data;
// IO17: segment commons, active low (always 0?)
// IO10-16: digit segments A-G
data = (data & 0x80) ? 0 : (data & 0x7f);
m_7seg_data = bitswap<7>(data, 0,1,2,3,4,5,6);
}
READ8_MEMBER(delta1_state::io1_r)
{
// unused?
return m_io[1];
}
/******************************************************************************
@ -125,8 +103,8 @@ void delta1_state::main_map(address_map &map)
void delta1_state::main_io(address_map &map)
{
map(0x0, 0x0).rw(FUNC(delta1_state::io0_r), FUNC(delta1_state::io0_w));
map(0x1, 0x1).rw(FUNC(delta1_state::io1_r), FUNC(delta1_state::io1_w));
map(0x0, 0x0).rw(FUNC(delta1_state::input_r), FUNC(delta1_state::mux_w));
map(0x1, 0x1).w(FUNC(delta1_state::digit_w));
map(0xc, 0xf).rw("f3853", FUNC(f3853_device::read), FUNC(f3853_device::write));
}

View File

@ -0,0 +1,24 @@
<?xml version="1.0"?>
<mamelayout version="2">
<!-- define elements -->
<element name="digit" defstate="0">
<led16seg><color red="1.0" green="0.1" blue="0.15" /></led16seg>
</element>
<!-- build screen -->
<view name="Internal Layout">
<bezel name="digit7" element="digit"><bounds x="0" y="0" width="10" height="15" /></bezel>
<bezel name="digit6" element="digit"><bounds x="10" y="0" width="10" height="15" /></bezel>
<bezel name="digit5" element="digit"><bounds x="20" y="0" width="10" height="15" /></bezel>
<bezel name="digit4" element="digit"><bounds x="30" y="0" width="10" height="15" /></bezel>
<bezel name="digit3" element="digit"><bounds x="40" y="0" width="10" height="15" /></bezel>
<bezel name="digit2" element="digit"><bounds x="50" y="0" width="10" height="15" /></bezel>
<bezel name="digit1" element="digit"><bounds x="60" y="0" width="10" height="15" /></bezel>
<bezel name="digit0" element="digit"><bounds x="70" y="0" width="10" height="15" /></bezel>
</view>
</mamelayout>

View File

@ -872,6 +872,9 @@ sp_zigzgk //
sp_zigzgl //
sp_zigzgm //
@source:aci_boris.cpp
boris //
@source:acommand.cpp
acommand // (c) 1990
@ -9755,7 +9758,6 @@ chessmsta //
chessmstdm //
@source:chesstrv.cpp
boris //
borisdpl //
chesstrv //

View File

@ -16,6 +16,7 @@ ac1.cpp
accomm.cpp
acd.cpp
aceex.cpp
aci_boris.cpp
acrnsys1.cpp
acrnsys.cpp
acvirus.cpp