New systems marked not working

------------------------------
Igor (Excalibur) [hap, Sean Riddle]
This commit is contained in:
hap 2024-03-27 14:32:32 +01:00
parent bbabfbf7a3
commit b0c36dfdf6
6 changed files with 371 additions and 7 deletions

View File

@ -89,6 +89,7 @@ void h83217_device::map(address_map &map)
map(0xff9b, 0xff9b).rw(m_timer8[2], FUNC(h8_timer8_channel_device::tcsr_r), FUNC(h8_timer8_channel_device::tcsr_w));
map(0xff9c, 0xff9d).rw(m_timer8[2], FUNC(h8_timer8_channel_device::tcor_r), FUNC(h8_timer8_channel_device::tcor_w));
map(0xff9e, 0xff9e).rw(m_timer8[2], FUNC(h8_timer8_channel_device::tcnt_r), FUNC(h8_timer8_channel_device::tcnt_w));
map(0xff9f, 0xff9f).lw8(NAME([this](u8 data) { logerror("tconr = %02x\n", data); }));
map(0xffaa, 0xffab).rw(m_watchdog, FUNC(h8_watchdog_device::wd_r), FUNC(h8_watchdog_device::wd_w));
@ -110,6 +111,7 @@ void h83217_device::map(address_map &map)
map(0xffbc, 0xffbc).w(m_port[6], FUNC(h8_port_device::ddr_w));
map(0xffbe, 0xffbe).rw(m_port[6], FUNC(h8_port_device::port_r), FUNC(h8_port_device::dr_w));
map(0xffc2, 0xffc2).lw8(NAME([this](u8 data) { logerror("wscr = %02x\n", data); }));
map(0xffc3, 0xffc3).rw(FUNC(h83217_device::stcr_r), FUNC(h83217_device::stcr_w));
map(0xffc4, 0xffc4).rw(FUNC(h83217_device::syscr_r), FUNC(h83217_device::syscr_w));
map(0xffc5, 0xffc5).r(FUNC(h83217_device::mdcr_r));

View File

@ -5,7 +5,8 @@
Excalibur Ivan The Terrible
The chess engine is by Ron Nelson, similar to the one in Excalibur Mirage.
The chess engine is by Ron Nelson, similar to the one in Excalibur Mirage. It
has speech, and also sound effects that are reminiscent of Battle Chess.
Hardware notes:
- PCB label: EXCALIBUR ELECTRONICS, INC. 6/28/96, IVANT
@ -148,7 +149,7 @@ void ivant_state::update_lcd()
void ivant_state::lcd_com_w(offs_t offset, u8 data, u8 mem_mask)
{
// P70,P71: LCD common
m_lcd_com = mem_mask << 2 | (data & 3);
m_lcd_com = (mem_mask << 2 & 0xc) | (data & 3);
update_lcd();
}
@ -203,7 +204,7 @@ u8 ivant_state::read_inputs()
u8 ivant_state::p4_r()
{
// P47: multiplexed inputs part
// P47: multiplexed inputs high bit
return (read_inputs() & 0x80) | 0x7f;
}

View File

@ -486,7 +486,7 @@ u8 mirage_state::p7_r()
void mirage_state::p7_w(offs_t offset, u8 data, u8 mem_mask)
{
// P70,P71: LCD common
m_lcd_com = mem_mask << 2 | (data & 3);
m_lcd_com = (mem_mask << 2 & 0xc) | (data & 3);
update_lcd();
// P74: motor X direction

358
src/mame/excalibur/igor.cpp Normal file
View File

@ -0,0 +1,358 @@
// license:BSD-3-Clause
// copyright-holders:hap
// thanks-to:Sean Riddle
/*******************************************************************************
Excalibur Igor (model 711E)
Hardware notes:
- PCB label: EXCALIBUR ELECTRONICS, INC. 510-1005A01, 5/28/97 IGOR
- Hitachi H8/3214 MCU, 12MHz XTAL
- small daughterboard (27C080 pinout) with a 128KB ROM under epoxy
- 8-bit DAC (Yageo 10L503G resistor array), KA8602 amplifier
- no LEDs, button sensors chessboard
There's also a newer version from 2000 (model 711E-2) on weaker hardware, it has
a Samsung KS57C2308 MCU instead.
TODO:
- it does a cold boot at every reset, so nvram won't work properly unless MAME
adds some kind of auxillary autosave state feature at power-off
- internal artwork
- add SVG for LCD
- where is the low battery signal?
*******************************************************************************/
#include "emu.h"
#include "cpu/h8/h83217.h"
#include "machine/sensorboard.h"
#include "sound/dac.h"
#include "video/pwm.h"
#include "screen.h"
#include "speaker.h"
// internal artwork
//#include "excal_igor.lh"
namespace {
class igor_state : public driver_device
{
public:
igor_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_board(*this, "board"),
m_cobrom(*this, "cobrom"),
m_lcd_pwm(*this, "lcd_pwm"),
m_dac(*this, "dac"),
m_inputs(*this, "IN.%u", 0),
m_out_lcd(*this, "s%u.%u", 0U, 0U)
{ }
void init_igor();
void igor(machine_config &config);
protected:
virtual void machine_start() override;
private:
// devices/pointers
required_device<h83214_device> m_maincpu;
required_device<sensorboard_device> m_board;
required_region_ptr<u8> m_cobrom;
required_device<pwm_display_device> m_lcd_pwm;
required_device<dac_8bit_r2r_device> m_dac;
required_ioport_array<2> m_inputs;
output_finder<2, 24> m_out_lcd;
u8 m_lcd_com = 0;
u8 m_dac_data = 0;
emu_timer *m_irqtimer;
u8 m_port1 = 0xff;
u8 m_port2 = 0xff;
u8 m_port5 = 0xff;
u8 m_port7 = 0xff;
// I/O handlers
void lcd_pwm_w(offs_t offset, u8 data);
void update_lcd();
void update_dac();
u8 read_inputs();
TIMER_CALLBACK_MEMBER(update_irq) { read_inputs(); }
void p1_w(u8 data);
void p2_w(u8 data);
u8 p3_r();
void p4_w(u8 data);
u8 p5_r();
void p5_w(offs_t offset, u8 data, u8 mem_mask);
u8 p6_r();
void p7_w(u8 data);
};
/*******************************************************************************
Initialization
*******************************************************************************/
void igor_state::init_igor()
{
u8 *rom = memregion("cobrom")->base();
const u32 len = memregion("cobrom")->bytes();
// descramble data lines
for (int i = 0; i < len; i++)
rom[i] = bitswap<8>(rom[i], 2,3,1,4,0,5,6,7);
// descramble address lines
std::vector<u8> buf(len);
memcpy(&buf[0], rom, len);
for (int i = 0; i < len; i++)
rom[i] = buf[bitswap<20>(i,19,18,17,16, 15,14,12,13,6,3,8,10, 11,9,7,5,4,2,1,0)];
}
void igor_state::machine_start()
{
m_out_lcd.resolve();
// periodically check for interrupts
m_irqtimer = timer_alloc(FUNC(igor_state::update_irq), this);
attotime period = attotime::from_msec(1);
m_irqtimer->adjust(period, 0, period);
// register for savestates
save_item(NAME(m_lcd_com));
save_item(NAME(m_dac_data));
save_item(NAME(m_port1));
save_item(NAME(m_port2));
save_item(NAME(m_port5));
save_item(NAME(m_port7));
}
/*******************************************************************************
I/O
*******************************************************************************/
void igor_state::lcd_pwm_w(offs_t offset, u8 data)
{
m_out_lcd[offset & 0x3f][offset >> 6] = data;
}
void igor_state::update_lcd()
{
u32 lcd_segs = bitswap<8>(m_port1,0,1,2,3,4,5,6,7) << 16 | bitswap<8>(m_port2,0,1,2,3,4,5,6,7) << 8 | m_port7;
for (int i = 0; i < 2; i++)
{
// LCD common is 0/1/Hi-Z
const u32 data = BIT(m_lcd_com, i + 2) ? (BIT(m_lcd_com, i) ? ~lcd_segs : lcd_segs) : 0;
m_lcd_pwm->write_row(i, data);
}
}
void igor_state::update_dac()
{
m_dac->write((m_port5 & 4) ? 0x80 : m_dac_data);
}
u8 igor_state::read_inputs()
{
u8 data = 0;
// get input mux from P2/P7/P5
u16 inp_mux = BIT(~m_port5, 5) << 9 | bitswap<8>(~m_port7,0,1,7,6,5,4,3,2) << 1 | BIT(~m_port2, 6);
// read buttons
for (int i = 0; i < 2; i++)
if (BIT(inp_mux, i + 8))
data |= m_inputs[i]->read();
// read chessboard
for (int i = 0; i < 8; i++)
if (BIT(inp_mux, i))
data |= m_board->read_file(i, true);
// P64-P66 are also IRQ pins (the ON button is IRQ0)
for (int i = 0; i < 3; i++)
m_maincpu->set_input_line(INPUT_LINE_IRQ0 + i, BIT(data, i + 4) ? ASSERT_LINE : CLEAR_LINE);
return ~data;
}
void igor_state::p1_w(u8 data)
{
// P10-P17: COB ROM address + LCD segs
m_port1 = data;
}
void igor_state::p2_w(u8 data)
{
// P20-P27: COB ROM address + LCD segs
// P26: input mux low bit
m_port2 = data;
read_inputs();
}
u8 igor_state::p3_r()
{
// P30-P37: read COB ROM
u32 address = bitswap<4>(m_port7,4,7,6,5) << 16 | m_port2 << 8 | m_port1;
return (m_port5 & 4) ? 0xff : m_cobrom[address & (m_cobrom.bytes() - 1)];
}
void igor_state::p4_w(u8 data)
{
// P40-P47 (not P46): DAC data
m_dac_data = (m_dac_data & 0x40) | (data & 0xbf);
update_dac();
}
u8 igor_state::p5_r()
{
// P50: multiplexed inputs high bit
return read_inputs() >> 7 | 0xfe;
}
void igor_state::p5_w(offs_t offset, u8 data, u8 mem_mask)
{
// P51: DAC bit 6
m_dac_data = (m_dac_data & 0xbf) | BIT(data, 1) << 6;
// P52: COB ROM CS, KA8602 mute
// P55: input mux high bit
m_port5 = data;
update_dac();
read_inputs();
// P53,P54: LCD common
u8 lcd_com = (mem_mask >> 1 & 0xc) | (data >> 3 & 3);
if (lcd_com != m_lcd_com)
{
m_lcd_com = lcd_com;
update_lcd();
}
}
u8 igor_state::p6_r()
{
// P60-P66: multiplexed inputs part
return read_inputs() | 0x80;
}
void igor_state::p7_w(u8 data)
{
// P70-P77: input mux part + LCD segs
// P74-P77: COB ROM address
m_port7 = data;
read_inputs();
}
/*******************************************************************************
Input Ports
*******************************************************************************/
static INPUT_PORTS_START( igor )
PORT_START("IN.0")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_U) PORT_CODE(KEYCODE_LEFT) PORT_NAME("No / Left")
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_NAME("Repeat")
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_V) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Verify / Queen")
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_O) PORT_NAME("Option")
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_N) PORT_NAME("New Game")
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_B) PORT_NAME("Black / White")
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Takeback")
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Y) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Yes / Right")
PORT_START("IN.1")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Mode")
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("Set Up / King")
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_I) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Multi-Move / Bishop")
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F2) PORT_NAME("Off / Save")
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F1) PORT_CODE(KEYCODE_C) PORT_NAME("On / Clear")
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_M) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("Move / Pawn")
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_L) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Level / Rook")
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_H) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Hint / Knight")
INPUT_PORTS_END
/*******************************************************************************
Machine Configs
*******************************************************************************/
void igor_state::igor(machine_config &config)
{
// basic machine hardware
H83214(config, m_maincpu, 12_MHz_XTAL);
m_maincpu->nvram_enable_backup(true);
m_maincpu->standby_cb().set(m_maincpu, FUNC(h83214_device::nvram_set_battery));
m_maincpu->standby_cb().append([this](int state) { if (state) m_lcd_pwm->clear(); });
m_maincpu->write_port1().set(FUNC(igor_state::p1_w));
m_maincpu->write_port2().set(FUNC(igor_state::p2_w));
m_maincpu->read_port3().set(FUNC(igor_state::p3_r));
m_maincpu->read_port4().set_constant(0xff); // discard
m_maincpu->write_port4().set(FUNC(igor_state::p4_w));
m_maincpu->read_port5().set(FUNC(igor_state::p5_r));
m_maincpu->write_port5().set(FUNC(igor_state::p5_w));
m_maincpu->read_port6().set(FUNC(igor_state::p6_r));
m_maincpu->write_port7().set(FUNC(igor_state::p7_w));
SENSORBOARD(config, m_board).set_type(sensorboard_device::BUTTONS);
m_board->init_cb().set(m_board, FUNC(sensorboard_device::preset_chess));
m_board->set_delay(attotime::from_msec(150));
//m_board->set_nvram_enable(true);
// video hardware
PWM_DISPLAY(config, m_lcd_pwm).set_size(2, 24);
m_lcd_pwm->output_x().set(FUNC(igor_state::lcd_pwm_w));
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
screen.set_refresh_hz(60);
screen.set_size(1920/5, 1080/5);
screen.set_visarea_full();
//config.set_default_layout(layout_excal_igor);
// sound hardware
SPEAKER(config, "speaker").front_center();
DAC_8BIT_R2R(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.5);
}
/*******************************************************************************
ROM Definitions
*******************************************************************************/
ROM_START( igor )
ROM_REGION16_BE( 0x8000, "maincpu", 0 )
ROM_LOAD("1997_rcn_1002a_excal_hd6433214l02p.ic1", 0x0000, 0x8000, CRC(adbc7e07) SHA1(0d297ad2fd0d18312966195cfad4658da4bc4442) )
ROM_REGION( 0x20000, "cobrom", 0 )
ROM_LOAD("sound.ic2", 0x00000, 0x20000, CRC(bc540da3) SHA1(68647ce1c7e87eba90d9d1912921213af03e3c5d) ) // no label
ROM_REGION( 200000, "screen", 0 )
ROM_LOAD("igor.svg", 0, 200000, NO_DUMP )
ROM_END
} // anonymous namespace
/*******************************************************************************
Drivers
*******************************************************************************/
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS
SYST( 1997, igor, 0, 0, igor, igor, igor_state, init_igor, "Excalibur", "Igor (Excalibur)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )

View File

@ -17761,6 +17761,9 @@ e9161 //
@source:ericsson/eispc.cpp
epc // 1984 Ericsson PC
@source:excalibur/igor.cpp
igor
@source:excellent/aquarium.cpp
aquarium // (c) 1996 Excellent System
aquariumj // (c) 1996 Excellent System

View File

@ -83,9 +83,9 @@ private:
u8 m_led_data = 0;
u32 m_adpdm_address = 0;
u8 m_port3 = 0;
u8 m_port5 = 0;
u8 m_port7 = 0;
u8 m_port3 = 0xff;
u8 m_port5 = 0xff;
u8 m_port7 = 0xff;
// I/O handlers
void lcd_pwm_w(offs_t offset, u8 data);