mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
Machines promoted to working
----------- Boris [hap, Sean Riddle]
This commit is contained in:
parent
9af0dee629
commit
3e1d84b7fa
@ -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>
|
||||
|
@ -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",
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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];
|
||||
|
245
src/mame/drivers/aci_boris.cpp
Normal file
245
src/mame/drivers/aci_boris.cpp
Normal 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 )
|
@ -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 )
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 )
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
24
src/mame/layout/aci_boris.lay
Normal file
24
src/mame/layout/aci_boris.lay
Normal 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>
|
@ -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 //
|
||||
|
||||
|
@ -16,6 +16,7 @@ ac1.cpp
|
||||
accomm.cpp
|
||||
acd.cpp
|
||||
aceex.cpp
|
||||
aci_boris.cpp
|
||||
acrnsys1.cpp
|
||||
acrnsys.cpp
|
||||
acvirus.cpp
|
||||
|
Loading…
Reference in New Issue
Block a user