mirror of
https://github.com/holub/mame
synced 2025-06-06 21:03:47 +03:00
New systems marked not working
------------------------------ Igor (Excalibur) [hap, Sean Riddle]
This commit is contained in:
parent
bbabfbf7a3
commit
b0c36dfdf6
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
358
src/mame/excalibur/igor.cpp
Normal 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 )
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user