novagbase: split into several drivers (nw)

This commit is contained in:
hap 2019-02-21 01:35:29 +01:00
parent 61a76b45bd
commit c0610d91fc
24 changed files with 959 additions and 807 deletions

View File

@ -2741,13 +2741,16 @@ files {
createMESSProjects(_target, _subtarget, "novag")
files {
MAME_DIR .. "src/mame/drivers/mk1.cpp",
MAME_DIR .. "src/mame/drivers/mk2.cpp",
MAME_DIR .. "src/mame/drivers/novagbase.cpp",
MAME_DIR .. "src/mame/includes/novagbase.h",
MAME_DIR .. "src/mame/drivers/novag_cforte.cpp",
MAME_DIR .. "src/mame/drivers/novag_delta1.cpp",
MAME_DIR .. "src/mame/drivers/novag_diablo.cpp",
MAME_DIR .. "src/mame/drivers/novag_presto.cpp",
MAME_DIR .. "src/mame/drivers/novag_scon.cpp",
MAME_DIR .. "src/mame/drivers/novag_sexpert.cpp",
MAME_DIR .. "src/mame/drivers/mk1.cpp",
MAME_DIR .. "src/mame/drivers/mk2.cpp",
MAME_DIR .. "src/mame/drivers/ssystem3.cpp",
MAME_DIR .. "src/mame/includes/ssystem3.h",
MAME_DIR .. "src/mame/video/ssystem3.cpp",

View File

@ -44,6 +44,7 @@ public:
m_mainmap(*this, "mainmap")
{ }
// machine drivers
void master(machine_config &config);
void init_master();
@ -53,6 +54,7 @@ private:
required_device<dac_2bit_binary_weighted_ones_complement_device> m_dac;
required_device<address_map_bank_device> m_mainmap;
// address maps
void main_map(address_map &map);
void main_trampoline(address_map &map);
u8 main_trampoline_r(offs_t offset);

View File

@ -35,12 +35,14 @@ public:
m_speaker_off(*this, "speaker_off")
{ }
// machine drivers
void ch2001(machine_config &config);
private:
// devices/pointers
required_device<timer_device> m_speaker_off;
// address maps
void main_map(address_map &map);
TIMER_DEVICE_CALLBACK_MEMBER(speaker_off) { m_dac->write(0); }

View File

@ -38,9 +38,11 @@ public:
fidelbase_state(mconfig, type, tag)
{ }
// machine drivers
void as12(machine_config &config);
private:
// address maps
void main_map(address_map &map);
// I/O handlers

View File

@ -80,6 +80,7 @@ public:
m_beeper(*this, "beeper")
{ }
// machine drivers
void ccx(machine_config &config);
private:

View File

@ -50,6 +50,7 @@ public:
void init_chesster();
private:
// address maps
void main_map(address_map &map);
int m_numbanks;

View File

@ -37,9 +37,11 @@ public:
fidelbase_state(mconfig, type, tag)
{ }
// machine drivers
void dsc(machine_config &config);
private:
// address maps
void main_map(address_map &map);
// I/O handlers

View File

@ -71,6 +71,7 @@ public:
void init_fdes2100d();
protected:
// address maps
void fdes2100d_map(address_map &map);
// I/O handlers

View File

@ -258,16 +258,6 @@ WRITE8_MEMBER(eag_state::mux_w)
prepare_display();
}
WRITE8_MEMBER(excel68k_state::mux_w)
{
// a1-a3,d0: 74259
u8 mask = 1 << offset;
m_led_select = (m_led_select & ~mask) | ((data & 1) ? mask : 0);
// 74259 Q0-Q3: 74145 A-D (Q4-Q7 N/C)
eag_state::mux_w(space, offset, m_led_select & 0xf);
}
READ8_MEMBER(eag_state::input1_r)
{
// a1-a3,d7: multiplexed inputs (active low)
@ -295,6 +285,19 @@ WRITE8_MEMBER(eag_state::digit_w)
}
// fex68k-specific
WRITE8_MEMBER(excel68k_state::mux_w)
{
// a1-a3,d0: 74259
u8 mask = 1 << offset;
m_led_select = (m_led_select & ~mask) | ((data & 1) ? mask : 0);
// 74259 Q0-Q3: 74145 A-D (Q4-Q7 N/C)
eag_state::mux_w(space, offset, m_led_select & 0xf);
}
/******************************************************************************
Address Maps

View File

@ -48,9 +48,11 @@ public:
void fphantom(machine_config &config);
void init_fphantom();
protected:
virtual void machine_reset() override;
private:
void main_map(address_map &map);
virtual void machine_reset() override;
};
void phantom_state::machine_reset()

View File

@ -74,6 +74,7 @@ public:
void sc12b(machine_config &config);
private:
// address maps
void main_map(address_map &map);
// I/O handlers

View File

@ -43,12 +43,14 @@ public:
m_maincpu(*this, "maincpu")
{ }
// machine drivers
void sc6(machine_config &config);
private:
// devices/pointers
required_device<mcs48_cpu_device> m_maincpu;
// address maps
void main_map(address_map &map);
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cartridge);

View File

@ -36,6 +36,7 @@ public:
fidelbase_state(mconfig, type, tag)
{ }
// machine drivers
void scc(machine_config &config);
private:

View File

@ -123,6 +123,7 @@ public:
m_ppi8255(*this, "ppi8255")
{ }
// machine drivers
void vcc(machine_config &config);
protected:

View File

@ -167,6 +167,7 @@ public:
m_ppi8255(*this, "ppi8255")
{ }
// machine drivers
void vsc(machine_config &config);
private:

View File

@ -0,0 +1,260 @@
// license:BSD-3-Clause
// copyright-holders:hap
// thanks-to:Berger
/******************************************************************************
*
* novag_cforte.cpp, subdriver of novagbase.cpp
TODO:
- RS232 port?
*******************************************************************************
Novag Constellation Forte
-------------------------
R65C02P4 @ 5MHz (10MHz XTAL)
2*2KB RAM(NEC D449C-3), 2*32KB ROM(27C256)
HLCD0538P, 10-digit 7seg LCD display
TTL, 18 LEDs, 8*8 chessboard buttons
I/O is similar to supercon
******************************************************************************/
#include "emu.h"
#include "includes/novagbase.h"
#include "cpu/m6502/r65c02.h"
#include "machine/nvram.h"
#include "video/hlcd0538.h"
#include "speaker.h"
// internal artwork
#include "novag_cforte.lh" // clickable
namespace {
class cforte_state : public novagbase_state
{
public:
cforte_state(const machine_config &mconfig, device_type type, const char *tag) :
novagbase_state(mconfig, type, tag),
m_hlcd0538(*this, "hlcd0538")
{ }
// machine drivers
void cforte(machine_config &config);
private:
// devices/pointers
optional_device<hlcd0538_device> m_hlcd0538;
// address maps
void main_map(address_map &map);
// I/O handlers
void prepare_display();
DECLARE_WRITE64_MEMBER(lcd_output_w);
DECLARE_WRITE8_MEMBER(mux_w);
DECLARE_WRITE8_MEMBER(control_w);
DECLARE_READ8_MEMBER(input1_r);
DECLARE_READ8_MEMBER(input2_r);
};
/******************************************************************************
Devices, I/O
******************************************************************************/
// TTL/generic
void cforte_state::prepare_display()
{
// 3 led rows
display_matrix(8, 3, m_led_data, m_led_select, false);
// lcd panel (mostly handled in lcd_output_w)
set_display_segmask(0x3ff0, 0xff);
set_display_size(8, 3+13);
display_update();
}
WRITE64_MEMBER(cforte_state::lcd_output_w)
{
// 4 rows used
u32 rowdata[4];
for (int i = 0; i < 4; i++)
rowdata[i] = (data >> i & 1) ? u32(data >> 8) : 0;
// 2 segments per row
for (int dig = 0; dig < 13; dig++)
{
m_display_state[dig+3] = 0;
for (int i = 0; i < 4; i++)
m_display_state[dig+3] |= ((rowdata[i] >> (2*dig) & 3) << (2*i));
m_display_state[dig+3] = bitswap<8>(m_display_state[dig+3],7,2,0,4,6,5,3,1);
}
prepare_display();
}
WRITE8_MEMBER(cforte_state::mux_w)
{
// d0-d7: input mux, led data
m_inp_mux = m_led_data = data;
prepare_display();
}
WRITE8_MEMBER(cforte_state::control_w)
{
// d0: HLCD0538 data in
// d1: HLCD0538 clk
// d2: HLCD0538 lcd
m_hlcd0538->write_data(data & 1);
m_hlcd0538->write_clk(data >> 1 & 1);
m_hlcd0538->write_lcd(data >> 2 & 1);
// d3: unused?
// d4-d6: select led row
m_led_select = data >> 4 & 7;
prepare_display();
// d7: enable beeper
m_beeper->set_state(data >> 7 & 1);
}
READ8_MEMBER(cforte_state::input1_r)
{
// d0-d7: multiplexed inputs (chessboard squares)
return ~read_inputs(8) & 0xff;
}
READ8_MEMBER(cforte_state::input2_r)
{
// d0-d5: ?
// d6,d7: multiplexed inputs (side panel)
return (read_inputs(8) >> 2 & 0xc0) ^ 0xff;
}
/******************************************************************************
Address Maps
******************************************************************************/
void cforte_state::main_map(address_map &map)
{
map(0x0000, 0x0fff).ram().share("nvram");
map(0x1c00, 0x1c00).nopw(); // printer?
map(0x1d00, 0x1d00).nopw(); // printer?
map(0x1e00, 0x1e00).rw(FUNC(cforte_state::input2_r), FUNC(cforte_state::mux_w));
map(0x1f00, 0x1f00).rw(FUNC(cforte_state::input1_r), FUNC(cforte_state::control_w));
map(0x2000, 0xffff).rom();
}
/******************************************************************************
Input Ports
******************************************************************************/
static INPUT_PORTS_START( cforte )
PORT_INCLUDE( novag_cb_buttons )
PORT_MODIFY("IN.0")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_I) PORT_NAME("New Game")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_NAME("Player/Player / Gambit/Large / King")
PORT_MODIFY("IN.1")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_U) PORT_NAME("Verify/Set Up / Pro-Op")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7) PORT_NAME("Random/Tour/Normal / Training Level / Queen")
PORT_MODIFY("IN.2")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Y) PORT_NAME("Change Color / Time Control / Priority")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_NAME("Sound / Depth Search / Bishop")
PORT_MODIFY("IN.3")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Flip Display / Clear Board / Clear Book")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_NAME("Solve Mate / Infinite / Knight")
PORT_MODIFY("IN.4")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_NAME("Print Moves / Print Evaluations / Print Book")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_NAME("Print Board / Interface / Rook")
PORT_MODIFY("IN.5")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Trace Forward / Auto Play / No/End")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Print List / Acc. Time / Pawn")
PORT_MODIFY("IN.6")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("Hint / Next Best / Yes/Start")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("Set Level")
PORT_MODIFY("IN.7")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("Go / ->")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("Take Back / Restore / <-")
INPUT_PORTS_END
/******************************************************************************
Machine Drivers
******************************************************************************/
void cforte_state::cforte(machine_config &config)
{
/* basic machine hardware */
R65C02(config, m_maincpu, 10_MHz_XTAL/2);
m_maincpu->set_addrmap(AS_PROGRAM, &cforte_state::main_map);
const attotime irq_period = attotime::from_hz(32.768_kHz_XTAL/128); // 256Hz
TIMER(config, m_irq_on).configure_periodic(FUNC(cforte_state::irq_on<M6502_IRQ_LINE>), irq_period);
m_irq_on->set_start_delay(irq_period - attotime::from_usec(11)); // active for 11us
TIMER(config, "irq_off").configure_periodic(FUNC(cforte_state::irq_off<M6502_IRQ_LINE>), irq_period);
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
/* video hardware */
HLCD0538(config, m_hlcd0538, 0);
m_hlcd0538->write_cols_callback().set(FUNC(cforte_state::lcd_output_w));
TIMER(config, "display_decay").configure_periodic(FUNC(cforte_state::display_decay_tick), attotime::from_msec(1));
config.set_default_layout(layout_novag_cforte);
/* sound hardware */
SPEAKER(config, "mono").front_center();
BEEP(config, m_beeper, 32.768_kHz_XTAL/32); // 1024Hz
m_beeper->add_route(ALL_OUTPUTS, "mono", 0.25);
}
/******************************************************************************
ROM Definitions
******************************************************************************/
ROM_START( cfortea )
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD("a_903_l", 0x0000, 0x8000, CRC(01e7e306) SHA1(6a2b982bb0f412a63f5d3603958dd863e38669d9) ) // NEC D27C256AD-12
ROM_LOAD("a_903_h", 0x8000, 0x8000, CRC(c5a5573f) SHA1(7e11eb2f3d96bc41386a14a19635427a386ec1ec) ) // "
ROM_END
ROM_START( cforteb )
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD("forte_b_l.bin", 0x0000, 0x8000, CRC(e3d194a1) SHA1(80457580d7c57e07895fd14bfdaf14b30952afca) )
ROM_LOAD("forte_b_h.bin", 0x8000, 0x8000, CRC(dd824be8) SHA1(cd8666b6b525887f9fc48a730b71ceabcf07f3b9) )
ROM_END
} // anonymous namespace
/******************************************************************************
Drivers
******************************************************************************/
// YEAR NAME PARENT CMP MACHINE INPUT STATE INIT COMPANY, FULLNAME, FLAGS
CONS( 1986, cfortea, 0, 0, cforte, cforte, cforte_state, empty_init, "Novag", "Constellation Forte (version A)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1986, cforteb, cfortea, 0, cforte, cforte, cforte_state, empty_init, "Novag", "Constellation Forte (version B)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )

View File

@ -11,8 +11,8 @@ TODO:
*******************************************************************************
Delta-1
------------
Novag Delta-1
-------------
3850PK CPU at ~2MHz, 3853PK memory interface
4KB ROM(2332A), 256 bytes RAM(2*2111A-4)
4-digit 7seg panel, no sound, no chessboard
@ -38,8 +38,12 @@ public:
novagbase_state(mconfig, type, tag)
{ }
// machine drivers
void delta1(machine_config &config);
protected:
virtual void machine_start() override;
private:
// address maps
void main_map(address_map &map);
@ -52,8 +56,6 @@ private:
DECLARE_READ8_MEMBER(io1_r);
u8 m_io[2]; // F8 CPU I/O ports
virtual void machine_start() override;
};
void delta1_state::machine_start()

View File

@ -285,4 +285,5 @@ ROM_END
// YEAR NAME PARENT CMP MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS
CONS( 1991, diablo68, 0, 0, diablo68k, diablo68k, diablo_state, empty_init, "Novag", "Diablo 68000", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1991, scorpio68, 0, 0, scorpio68k, scorpio68k, diablo_state, empty_init, "Novag", "Scorpio 68000", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )

View File

@ -6,7 +6,7 @@
* novag_presto.cpp, subdriver of novagbase.cpp
TODO:
- is presto led handling correct? mux data needs to be auto cleared
- is led handling correct? mux data needs to be auto cleared
similar to diablo/sexpert
*******************************************************************************

View File

@ -0,0 +1,196 @@
// license:BSD-3-Clause
// copyright-holders:hap
/******************************************************************************
*
* novag_scon.cpp, subdriver of novagbase.cpp
TODO:
- verify IRQ and beeper frequency
*******************************************************************************
Novag Super Constellation Chess Computer (model 844)
--------------------
UMC UM6502C @ 4 MHz (8MHz XTAL), 600Hz? IRQ(source unknown?)
2*2KB RAM TC5516APL-2 battery-backed, 2*32KB ROM custom label
TTL, buzzer, 24 LEDs, 8*8 chessboard buttons
external ports for clock and printer, not emulated here
******************************************************************************/
#include "emu.h"
#include "includes/novagbase.h"
#include "cpu/m6502/m6502.h"
#include "machine/nvram.h"
#include "speaker.h"
// internal artwork
#include "novag_supercon.lh" // clickable
namespace {
class scon_state : public novagbase_state
{
public:
scon_state(const machine_config &mconfig, device_type type, const char *tag) :
novagbase_state(mconfig, type, tag)
{ }
// machine drivers
void scon(machine_config &config);
private:
// address maps
void main_map(address_map &map);
// I/O handlers
DECLARE_WRITE8_MEMBER(mux_w);
DECLARE_WRITE8_MEMBER(control_w);
DECLARE_READ8_MEMBER(input1_r);
DECLARE_READ8_MEMBER(input2_r);
};
/******************************************************************************
Devices, I/O
******************************************************************************/
// TTL
WRITE8_MEMBER(scon_state::mux_w)
{
// d0-d7: input mux, led data
m_inp_mux = m_led_data = data;
display_matrix(8, 3, m_led_data, m_led_select);
}
WRITE8_MEMBER(scon_state::control_w)
{
// d0-d3: ?
// d4-d6: select led row
m_led_select = data >> 4 & 7;
display_matrix(8, 3, m_led_data, m_led_select);
// d7: enable beeper
m_beeper->set_state(data >> 7 & 1);
}
READ8_MEMBER(scon_state::input1_r)
{
// d0-d7: multiplexed inputs (chessboard squares)
return ~read_inputs(8) & 0xff;
}
READ8_MEMBER(scon_state::input2_r)
{
// d0-d5: ?
// d6,d7: multiplexed inputs (side panel)
return (read_inputs(8) >> 2 & 0xc0) ^ 0xff;
}
/******************************************************************************
Address Maps
******************************************************************************/
void scon_state::main_map(address_map &map)
{
map(0x0000, 0x0fff).ram().share("nvram");
map(0x1c00, 0x1c00).nopw(); // printer/clock?
map(0x1d00, 0x1d00).nopw(); // printer/clock?
map(0x1e00, 0x1e00).rw(FUNC(scon_state::input2_r), FUNC(scon_state::mux_w));
map(0x1f00, 0x1f00).rw(FUNC(scon_state::input1_r), FUNC(scon_state::control_w));
map(0x2000, 0xffff).rom();
}
/******************************************************************************
Input Ports
******************************************************************************/
static INPUT_PORTS_START( scon )
PORT_INCLUDE( novag_cb_buttons )
PORT_MODIFY("IN.0")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_I) PORT_NAME("New Game")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_NAME("Multi Move / Player/Player / King")
PORT_MODIFY("IN.1")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_U) PORT_NAME("Verify / Set Up")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7) PORT_NAME("Best Move/Random / Training Level / Queen")
PORT_MODIFY("IN.2")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Y) PORT_NAME("Change Color")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_NAME("Sound / Depth Search / Bishop")
PORT_MODIFY("IN.3")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Clear Board")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_NAME("Solve Mate / Knight")
PORT_MODIFY("IN.4")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_NAME("Print Moves")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_NAME("Print Board / Rook")
PORT_MODIFY("IN.5")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Form Size")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Print List / Acc. Time / Pawn")
PORT_MODIFY("IN.6")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("Hint")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("Set Level")
PORT_MODIFY("IN.7")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("Go")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("Take Back")
INPUT_PORTS_END
/******************************************************************************
Machine Drivers
******************************************************************************/
void scon_state::scon(machine_config &config)
{
/* basic machine hardware */
M6502(config, m_maincpu, 8_MHz_XTAL/2); // UM6502C
m_maincpu->set_addrmap(AS_PROGRAM, &scon_state::main_map);
m_maincpu->set_periodic_int(FUNC(scon_state::irq0_line_hold), attotime::from_hz(600)); // guessed
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
TIMER(config, "display_decay").configure_periodic(FUNC(scon_state::display_decay_tick), attotime::from_msec(1));
config.set_default_layout(layout_novag_supercon);
/* sound hardware */
SPEAKER(config, "mono").front_center();
BEEP(config, m_beeper, 1024); // guessed
m_beeper->add_route(ALL_OUTPUTS, "mono", 0.25);
}
/******************************************************************************
ROM Definitions
******************************************************************************/
ROM_START( supercon )
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD("novag_8441", 0x0000, 0x8000, CRC(b853cf6e) SHA1(1a759072a5023b92c07f1fac01b7a21f7b5b45d0) ) // label obscured by Q.C. sticker
ROM_LOAD("novag_8442", 0x8000, 0x8000, CRC(c8f82331) SHA1(f7fd039f9a3344db9749931490ded9e9e309cfbe) )
ROM_END
} // anonymous namespace
/******************************************************************************
Drivers
******************************************************************************/
// YEAR NAME PARENT CMP MACHINE INPUT STATE INIT COMPANY, FULLNAME, FLAGS
CONS( 1984, supercon, 0, 0, scon, scon, scon_state, empty_init, "Novag", "Super Constellation", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )

View File

@ -0,0 +1,444 @@
// license:BSD-3-Clause
// copyright-holders:hap
// thanks-to:Berger
/******************************************************************************
*
* novag_sexpert.cpp, subdriver of novagbase.cpp
TODO:
- sforte irq active time (21.5us is too long)
- led handling is correct?
*******************************************************************************
Novag Super Expert (model 878/887/902):
--------------------
65C02 @ 5MHz or 6MHz (10MHz or 12MHz XTAL)
8KB RAM battery-backed, 3*32KB ROM
HD44780 LCD controller (16x1)
beeper(32KHz/32), IRQ(32KHz/128) via MC14060
optional R65C51P2 ACIA @ 1.8432MHz, for IBM PC interface (only works in version C?)
printer port, magnetic sensors, 8*8 chessboard leds
I/O via TTL, hardware design was very awkward.
Super Forte is very similar, just a cheaper plastic case and chessboard buttons
instead of magnet sensors.
******************************************************************************/
#include "emu.h"
#include "includes/novagbase.h"
#include "bus/rs232/rs232.h"
#include "cpu/m6502/m65c02.h"
#include "machine/mos6551.h"
#include "machine/nvram.h"
#include "screen.h"
#include "speaker.h"
// internal artwork
#include "novag_sexpert.lh" // clickable
#include "novag_sforte.lh" // clickable
namespace {
class sexpert_state : public novagbase_state
{
public:
sexpert_state(const machine_config &mconfig, device_type type, const char *tag) :
novagbase_state(mconfig, type, tag)
{ }
// machine drivers
void sexpert(machine_config &config);
void init_sexpert();
DECLARE_INPUT_CHANGED_MEMBER(sexpert_cpu_freq) { sexpert_set_cpu_freq(); }
protected:
virtual void machine_reset() override;
void sexpert_set_cpu_freq();
// address maps
void sexpert_map(address_map &map);
// I/O handlers
virtual DECLARE_WRITE8_MEMBER(lcd_control_w);
virtual DECLARE_WRITE8_MEMBER(lcd_data_w);
DECLARE_WRITE8_MEMBER(leds_w);
DECLARE_WRITE8_MEMBER(mux_w);
DECLARE_READ8_MEMBER(input1_r);
DECLARE_READ8_MEMBER(input2_r);
};
class sforte_state : public sexpert_state
{
public:
sforte_state(const machine_config &mconfig, device_type type, const char *tag) :
sexpert_state(mconfig, type, tag)
{ }
// machine drivers
void sforte(machine_config &config);
private:
// address maps
void sforte_map(address_map &map);
// I/O handlers
virtual DECLARE_WRITE8_MEMBER(lcd_control_w) override;
virtual DECLARE_WRITE8_MEMBER(lcd_data_w) override;
};
void sexpert_state::sexpert_set_cpu_freq()
{
// machines were released with either 5MHz or 6MHz CPU
m_maincpu->set_unscaled_clock((ioport("FAKE")->read() & 1) ? (12_MHz_XTAL/2) : (10_MHz_XTAL/2));
}
void sexpert_state::machine_reset()
{
novagbase_state::machine_reset();
sexpert_set_cpu_freq();
m_rombank->set_entry(0);
}
void sexpert_state::init_sexpert()
{
m_rombank->configure_entries(0, 2, memregion("maincpu")->base() + 0x8000, 0x8000);
}
/******************************************************************************
Devices, I/O
******************************************************************************/
// TTL/generic
WRITE8_MEMBER(sexpert_state::lcd_control_w)
{
// d0: HD44780 RS
// d1: HD44780 R/W
// d2: HD44780 E
if (m_lcd_control & ~data & 4 && ~data & 2)
m_lcd->write(m_lcd_control & 1, m_lcd_data);
m_lcd_control = data & 7;
}
WRITE8_MEMBER(sexpert_state::lcd_data_w)
{
// d0-d7: HD44780 data
m_lcd_data = data;
}
WRITE8_MEMBER(sexpert_state::leds_w)
{
// d0-d7: chessboard leds
m_led_data = data;
}
WRITE8_MEMBER(sexpert_state::mux_w)
{
// d0: rom bankswitch
m_rombank->set_entry(data & 1);
// d3: enable beeper
m_beeper->set_state(data >> 3 & 1);
// d4-d7: 74145 to input mux/led select
m_inp_mux = 1 << (data >> 4 & 0xf) & 0xff;
display_matrix(8, 8, m_led_data, m_inp_mux);
m_led_data = 0; // ?
}
READ8_MEMBER(sexpert_state::input1_r)
{
// d0-d7: multiplexed inputs (chessboard squares)
return ~read_inputs(8) & 0xff;
}
READ8_MEMBER(sexpert_state::input2_r)
{
// d0-d2: printer port
// d5-d7: multiplexed inputs (side panel)
return ~read_inputs(8) >> 3 & 0xe0;
}
// sforte-specific
WRITE8_MEMBER(sforte_state::lcd_control_w)
{
// d3: rom bankswitch
m_rombank->set_entry(data >> 3 & 1);
// assume same as sexpert
sexpert_state::lcd_control_w(space, offset, data);
}
WRITE8_MEMBER(sforte_state::lcd_data_w)
{
// d0-d2: input mux/led select
m_inp_mux = 1 << (data & 7);
// if lcd is disabled, misc control
if (~m_lcd_control & 4)
{
// d5,d6: led data, but not both at same time?
if ((data & 0x60) != 0x60)
display_matrix(2, 8, data >> 5 & 3, m_inp_mux);
// d7: enable beeper
m_beeper->set_state(data >> 7 & 1);
}
// assume same as sexpert
sexpert_state::lcd_data_w(space, offset, data);
}
/******************************************************************************
Address Maps
******************************************************************************/
void sexpert_state::sexpert_map(address_map &map)
{
map(0x0000, 0x1fef).ram().share("nvram"); // 8KB RAM, but RAM CE pin is deactivated on $1ff0-$1fff
map(0x1ff0, 0x1ff0).r(FUNC(sexpert_state::input1_r));
map(0x1ff1, 0x1ff1).r(FUNC(sexpert_state::input2_r));
map(0x1ff2, 0x1ff2).nopw(); // printer
map(0x1ff3, 0x1ff3).nopw(); // printer
map(0x1ff4, 0x1ff4).w(FUNC(sexpert_state::leds_w));
map(0x1ff5, 0x1ff5).w(FUNC(sexpert_state::mux_w));
map(0x1ff6, 0x1ff6).w(FUNC(sexpert_state::lcd_control_w));
map(0x1ff7, 0x1ff7).w(FUNC(sexpert_state::lcd_data_w));
map(0x1ffc, 0x1fff).rw("acia", FUNC(mos6551_device::read), FUNC(mos6551_device::write));
map(0x2000, 0x7fff).rom();
map(0x8000, 0xffff).bankr("rombank");
}
void sforte_state::sforte_map(address_map &map)
{
sexpert_map(map);
map(0x1ff4, 0x1ff4).nopw();
map(0x1ff5, 0x1ff5).nopw();
map(0x1ff6, 0x1ff6).w(FUNC(sforte_state::lcd_control_w));
map(0x1ff7, 0x1ff7).w(FUNC(sforte_state::lcd_data_w));
}
/******************************************************************************
Input Ports
******************************************************************************/
static INPUT_PORTS_START( sexy_shared )
PORT_MODIFY("IN.0")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_NAME("Go")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("Take Back / Analyze Games")
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("->")
PORT_MODIFY("IN.1")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_NAME("Set Level")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("Flip Display / Time Control")
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("<-")
PORT_MODIFY("IN.2")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_D) PORT_NAME("Hint / Next Best")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Priority / Tournament Book / Pawn")
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Yes/Start / Start of Game")
PORT_MODIFY("IN.3")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F) PORT_NAME("Trace Forward / AutoPlay")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_NAME("Pro-Op / Restore Game / Rook")
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_NAME("No/End / End of Game")
PORT_MODIFY("IN.4")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_G) PORT_NAME("Clear Board / Delete Pro-Op")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Best Move/Random / Review / Knight")
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_NAME("Print Book / Store Game")
PORT_MODIFY("IN.5")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_H) PORT_NAME("Change Color")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Y) PORT_NAME("Sound / Info / Bishop")
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_NAME("Print Moves / Print Evaluations")
PORT_MODIFY("IN.6")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_J) PORT_NAME("Verify/Set Up / Pro-Op Book/Both Books")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_U) PORT_NAME("Solve Mate / Infinite / Queen")
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7) PORT_NAME("Print List / Acc. Time")
PORT_MODIFY("IN.7")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_K) PORT_NAME("New Game")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_I) PORT_NAME("Player/Player / Gambit Book / King")
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_NAME("Print Board / Interface")
PORT_START("FAKE")
PORT_CONFNAME( 0x01, 0x00, "CPU Frequency" ) PORT_CHANGED_MEMBER(DEVICE_SELF, sexpert_state, sexpert_cpu_freq, nullptr) // factory set
PORT_CONFSETTING( 0x00, "5MHz" )
PORT_CONFSETTING( 0x01, "6MHz" )
INPUT_PORTS_END
static INPUT_PORTS_START( sexpert )
PORT_INCLUDE( novag_cb_magnets )
PORT_INCLUDE( sexy_shared )
INPUT_PORTS_END
static INPUT_PORTS_START( sforte )
PORT_INCLUDE( novag_cb_buttons )
PORT_INCLUDE( sexy_shared )
INPUT_PORTS_END
/******************************************************************************
Machine Drivers
******************************************************************************/
void sexpert_state::sexpert(machine_config &config)
{
/* basic machine hardware */
M65C02(config, m_maincpu, 10_MHz_XTAL/2); // or 12_MHz_XTAL/2
m_maincpu->set_addrmap(AS_PROGRAM, &sexpert_state::sexpert_map);
const attotime irq_period = attotime::from_hz(32.768_kHz_XTAL/128); // 256Hz
TIMER(config, m_irq_on).configure_periodic(FUNC(sexpert_state::irq_on<M6502_IRQ_LINE>), irq_period);
m_irq_on->set_start_delay(irq_period - attotime::from_nsec(21500)); // active for 21.5us
TIMER(config, "irq_off").configure_periodic(FUNC(sexpert_state::irq_off<M6502_IRQ_LINE>), irq_period);
mos6551_device &acia(MOS6551(config, "acia", 0)); // R65C51P2 - RTS to CTS, DCD to GND
acia.set_xtal(1.8432_MHz_XTAL);
acia.irq_handler().set_inputline("maincpu", m65c02_device::NMI_LINE);
acia.rts_handler().set("acia", FUNC(mos6551_device::write_cts));
acia.txd_handler().set("rs232", FUNC(rs232_port_device::write_txd));
acia.dtr_handler().set("rs232", FUNC(rs232_port_device::write_dtr));
rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, nullptr));
rs232.rxd_handler().set("acia", FUNC(mos6551_device::write_rxd));
rs232.dsr_handler().set("acia", FUNC(mos6551_device::write_dsr));
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD));
screen.set_refresh_hz(60); // arbitrary
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500));
screen.set_size(6*16+1, 10);
screen.set_visarea(0, 6*16, 0, 10-1);
screen.set_screen_update("hd44780", FUNC(hd44780_device::screen_update));
screen.set_palette("palette");
PALETTE(config, "palette", FUNC(sexpert_state::novag_lcd_palette), 3);
HD44780(config, m_lcd, 0);
m_lcd->set_lcd_size(2, 8);
m_lcd->set_pixel_update_cb(FUNC(sexpert_state::novag_lcd_pixel_update), this);
TIMER(config, "display_decay").configure_periodic(FUNC(sexpert_state::display_decay_tick), attotime::from_msec(1));
config.set_default_layout(layout_novag_sexpert);
/* sound hardware */
SPEAKER(config, "mono").front_center();
BEEP(config, m_beeper, 32.768_kHz_XTAL/32); // 1024Hz
m_beeper->add_route(ALL_OUTPUTS, "mono", 0.25);
}
void sforte_state::sforte(machine_config &config)
{
sexpert(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_PROGRAM, &sforte_state::sforte_map);
m_irq_on->set_start_delay(m_irq_on->period() - attotime::from_usec(11)); // active for ?us (assume same as cforte)
config.set_default_layout(layout_novag_sforte);
}
/******************************************************************************
ROM Definitions
******************************************************************************/
ROM_START( sexperta )
ROM_REGION( 0x18000, "maincpu", 0 )
ROM_LOAD("se_lo_b15.u3", 0x0000, 0x8000, CRC(6cc9527c) SHA1(29bab809399f2863a88a9c41535ecec0a4fd65ea) )
ROM_LOAD("se_hi1_b15.u1", 0x8000, 0x8000, CRC(6e57f0c0) SHA1(ea44769a6f54721fd4543366bda932e86e497d43) )
ROM_LOAD("sef_hi0_a23.u2", 0x10000, 0x8000, CRC(7d4e1528) SHA1(53c7d458a5571afae402f00ae3d0f5066634b068) )
ROM_END
ROM_START( sexpertb )
ROM_REGION( 0x18000, "maincpu", 0 )
ROM_LOAD("se_lo_619.u3", 0x0000, 0x8000, CRC(92002eb6) SHA1(ed8ca16701e00b48fa55c856fa4a8c6613079c02) )
ROM_LOAD("se_hi1_619.u1", 0x8000, 0x8000, CRC(814b4420) SHA1(c553e6a8c048dcc1cf48d410111a86e06b99d356) )
ROM_LOAD("sef_hi0_605.u2", 0x10000, 0x8000, CRC(bb07ad52) SHA1(30cf9005021ab2d7b03facdf2d3588bc94dc68a6) )
ROM_END
ROM_START( sexpertc )
ROM_REGION( 0x18000, "maincpu", 0 )
ROM_LOAD("se_lo_v3.6.u3", 0x0000, 0x8000, CRC(5a29105e) SHA1(be37bb29b530dbba847a5e8d27d81b36525e47f7) )
ROM_LOAD("se_hi1.u1", 0x8000, 0x8000, CRC(0085c2c4) SHA1(d84bf4afb022575db09dd9dc12e9b330acce35fa) )
ROM_LOAD("se_hi0.u2", 0x10000, 0x8000, CRC(2d085064) SHA1(76162322aa7d23a5c07e8356d0bbbb33816419af) )
ROM_END
ROM_START( sexpertc1 )
ROM_REGION( 0x18000, "maincpu", 0 )
ROM_LOAD("se_lo_v1.2.u3", 0x0000, 0x8000, CRC(43ed7a9e) SHA1(273c485e5be6b107b6c5c448003ba7686d4a6d06) )
ROM_LOAD("se_hi1.u1", 0x8000, 0x8000, CRC(0085c2c4) SHA1(d84bf4afb022575db09dd9dc12e9b330acce35fa) )
ROM_LOAD("se_hi0.u2", 0x10000, 0x8000, CRC(2d085064) SHA1(76162322aa7d23a5c07e8356d0bbbb33816419af) )
ROM_END
ROM_START( sfortea )
ROM_REGION( 0x18000, "maincpu", 0 )
ROM_LOAD("sfalo.u3", 0x0000, 0x8000, CRC(86e0230a) SHA1(0d6e18a17e636b8c7292c8f331349d361892d1a8) )
ROM_LOAD("sfahi.u1", 0x8000, 0x8000, CRC(81c02746) SHA1(0bf68b68ade5a3263bead88da0a8965fc71483c1) )
ROM_LOAD("sfabook.u2", 0x10000, 0x8000, CRC(3e42cf7c) SHA1(b2faa36a127e08e5755167a25ed4a07f12d62957) )
ROM_END
ROM_START( sfortea1 )
ROM_REGION( 0x18000, "maincpu", 0 )
ROM_LOAD("sfa_lo.u3", 0x0000, 0x8000, CRC(78734bfd) SHA1(b6d8e9efccee6f6d0b0cd257a82162bf8ccec719) )
ROM_LOAD("sfa_hi_1.u1", 0x8000, 0x8000, CRC(e5e84580) SHA1(bae55c3da7b720bf6ccfb450e383c53cebd5e9ef) )
ROM_LOAD("sfa_hi_0.u2", 0x10000, 0x8000, CRC(3e42cf7c) SHA1(b2faa36a127e08e5755167a25ed4a07f12d62957) )
ROM_END
ROM_START( sforteb )
ROM_REGION( 0x18000, "maincpu", 0 )
ROM_LOAD("forte_b_lo.u3", 0x0000, 0x8000, CRC(48bfe5d6) SHA1(323642686b6d2fb8db2b7d50c6cd431058078ce1) )
ROM_LOAD("forte_b_hi1.u1", 0x8000, 0x8000, CRC(9778ca2c) SHA1(d8b88b9768a1a9171c68cbb0892b817d68d78351) )
ROM_LOAD("forte_b_hi0.u2", 0x10000, 0x8000, CRC(bb07ad52) SHA1(30cf9005021ab2d7b03facdf2d3588bc94dc68a6) )
ROM_END
ROM_START( sfortec )
ROM_REGION( 0x18000, "maincpu", 0 )
ROM_LOAD("sfl_c_111.u3", 0x0000, 0x8000, CRC(f040cf30) SHA1(1fc1220b8ed67cdffa3866d230ce001721cf684f) ) // Toshiba TC57256AD-12
ROM_LOAD("sfh_c_111.u1", 0x8000, 0x8000, CRC(0f926b32) SHA1(9c7270ecb3f41dd9172a9a7928e6e04e64b2a340) ) // NEC D27C256AD-12
ROM_LOAD("h0_c_c26.u2", 0x10000, 0x8000, CRC(c6a1419a) SHA1(017a0ffa9aa59438c879624a7ddea2071d1524b8) ) // Toshiba TC57256AD-12
ROM_END
} // anonymous namespace
/******************************************************************************
Drivers
******************************************************************************/
// YEAR NAME PARENT CMP MACHINE INPUT STATE INIT COMPANY, FULLNAME, FLAGS
CONS( 1987, sexperta, 0, 0, sexpert, sexpert, sexpert_state, init_sexpert, "Novag", "Super Expert (version A)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1988, sexpertb, sexperta, 0, sexpert, sexpert, sexpert_state, init_sexpert, "Novag", "Super Expert (version B)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1990, sexpertc, sexperta, 0, sexpert, sexpert, sexpert_state, init_sexpert, "Novag", "Super Expert (version C, V3.6)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1990, sexpertc1, sexperta, 0, sexpert, sexpert, sexpert_state, init_sexpert, "Novag", "Super Expert (version C, V1.2)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1987, sfortea, 0, 0, sforte, sforte, sforte_state, init_sexpert, "Novag", "Super Forte (version A, set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1987, sfortea1, sfortea, 0, sforte, sforte, sforte_state, init_sexpert, "Novag", "Super Forte (version A, set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1988, sforteb, sfortea, 0, sforte, sforte, sforte_state, init_sexpert, "Novag", "Super Forte (version B)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1990, sfortec, sfortea, 0, sforte, sforte, sforte_state, init_sexpert, "Novag", "Super Forte (version C)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )

View File

@ -1,6 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:hap
// thanks-to:Berger
/******************************************************************************
Novag chess computer driver base class
@ -13,165 +12,11 @@ such as Arena(in editmode).
TODO:
- printer port
- verify supercon IRQ and beeper frequency
- sforte irq active time (21.5us is too long)
- sforte/sexpert led handling is correct?
*******************************************************************************
Super Constellation Chess Computer (model 844):
- UMC UM6502C @ 4 MHz (8MHz XTAL), 600Hz? IRQ(source unknown?)
- 2*2KB RAM TC5516APL-2 battery-backed, 2*32KB ROM custom label
- TTL, buzzer, 24 LEDs, 8*8 chessboard buttons
- external ports for clock and printer, not emulated here
*******************************************************************************
Constellation Forte:
- R65C02P4 @ 5MHz (10MHz XTAL)
- 2*2KB RAM(NEC D449C-3), 2*32KB ROM(27C256)
- HLCD0538P, 10-digit 7seg LCD display
- TTL, 18 LEDs, 8*8 chessboard buttons
I/O is similar to supercon
*******************************************************************************
Super Expert (model 878/887/902):
- 65C02 @ 5MHz or 6MHz (10MHz or 12MHz XTAL)
- 8KB RAM battery-backed, 3*32KB ROM
- HD44780 LCD controller (16x1)
- beeper(32KHz/32), IRQ(32KHz/128) via MC14060
- optional R65C51P2 ACIA @ 1.8432MHz, for IBM PC interface (only works in version C?)
- printer port, magnetic sensors, 8*8 chessboard leds
I/O via TTL, hardware design was very awkward.
Super Forte is very similar, just a cheaper plastic case and chessboard buttons
instead of magnet sensors.
******************************************************************************/
#include "emu.h"
#include "includes/novagbase.h"
#include "bus/rs232/rs232.h"
#include "cpu/m6502/m6502.h"
#include "cpu/m6502/m65c02.h"
#include "cpu/m6502/r65c02.h"
#include "machine/mos6551.h"
#include "machine/nvram.h"
#include "video/hlcd0538.h"
#include "screen.h"
#include "speaker.h"
// internal artwork
#include "novag_cforte.lh" // clickable
#include "novag_sexpert.lh" // clickable
#include "novag_sforte.lh" // clickable
#include "novag_supercon.lh" // clickable
class sexpert_state : public novagbase_state
{
public:
sexpert_state(const machine_config &mconfig, device_type type, const char *tag) :
novagbase_state(mconfig, type, tag)
{ }
void sexpert(machine_config &config);
void sforte(machine_config &config);
void init_sexpert();
DECLARE_INPUT_CHANGED_MEMBER(sexpert_cpu_freq) { sexpert_set_cpu_freq(); }
private:
// Super Expert
DECLARE_WRITE8_MEMBER(sexpert_leds_w);
DECLARE_WRITE8_MEMBER(sexpert_mux_w);
DECLARE_WRITE8_MEMBER(sexpert_lcd_control_w);
DECLARE_WRITE8_MEMBER(sexpert_lcd_data_w);
DECLARE_READ8_MEMBER(sexpert_input1_r);
DECLARE_READ8_MEMBER(sexpert_input2_r);
DECLARE_MACHINE_RESET(sexpert);
void sexpert_map(address_map &map);
void sexpert_set_cpu_freq();
// Super Forte
DECLARE_WRITE8_MEMBER(sforte_lcd_control_w);
DECLARE_WRITE8_MEMBER(sforte_lcd_data_w);
void sforte_map(address_map &map);
protected:
virtual void machine_reset() override;
};
void sexpert_state::sexpert_set_cpu_freq()
{
// machines were released with either 5MHz or 6MHz CPU
m_maincpu->set_unscaled_clock((ioport("FAKE")->read() & 1) ? (12_MHz_XTAL/2) : (10_MHz_XTAL/2));
}
void sexpert_state::machine_reset()
{
novagbase_state::machine_reset();
sexpert_set_cpu_freq();
m_rombank->set_entry(0);
}
void sexpert_state::init_sexpert()
{
m_rombank->configure_entries(0, 2, memregion("maincpu")->base() + 0x8000, 0x8000);
}
class cforte_state : public novagbase_state
{
public:
cforte_state(const machine_config &mconfig, device_type type, const char *tag) :
novagbase_state(mconfig, type, tag),
m_hlcd0538(*this, "hlcd0538")
{ }
void cforte(machine_config &config);
private:
optional_device<hlcd0538_device> m_hlcd0538;
// Constellation Forte
void cforte_prepare_display();
DECLARE_WRITE64_MEMBER(cforte_lcd_output_w);
DECLARE_WRITE8_MEMBER(cforte_mux_w);
DECLARE_WRITE8_MEMBER(cforte_control_w);
DECLARE_READ8_MEMBER(cforte_input1_r);
DECLARE_READ8_MEMBER(cforte_input2_r);
void cforte_map(address_map &map);
};
class scon_state : public novagbase_state
{
public:
scon_state(const machine_config &mconfig, device_type type, const char *tag) :
novagbase_state(mconfig, type, tag)
{ }
void supercon(machine_config &config);
private:
// Super Constellation
DECLARE_WRITE8_MEMBER(supercon_mux_w);
DECLARE_WRITE8_MEMBER(supercon_control_w);
DECLARE_READ8_MEMBER(supercon_input1_r);
DECLARE_READ8_MEMBER(supercon_input2_r);
void supercon_map(address_map &map);
};
// machine start/reset
@ -216,11 +61,8 @@ void novagbase_state::machine_reset()
}
/***************************************************************************
Helper Functions
Helper Functions
***************************************************************************/
// The device may strobe the outputs very fast, it is unnoticeable to the user.
@ -335,284 +177,7 @@ u16 novagbase_state::read_inputs(int columns)
}
// Devices, I/O
/******************************************************************************
Super Constellation
******************************************************************************/
// TTL
WRITE8_MEMBER(scon_state::supercon_mux_w)
{
// d0-d7: input mux, led data
m_inp_mux = m_led_data = data;
display_matrix(8, 3, m_led_data, m_led_select);
}
WRITE8_MEMBER(scon_state::supercon_control_w)
{
// d0-d3: ?
// d4-d6: select led row
m_led_select = data >> 4 & 7;
display_matrix(8, 3, m_led_data, m_led_select);
// d7: enable beeper
m_beeper->set_state(data >> 7 & 1);
}
READ8_MEMBER(scon_state::supercon_input1_r)
{
// d0-d7: multiplexed inputs (chessboard squares)
return ~read_inputs(8) & 0xff;
}
READ8_MEMBER(scon_state::supercon_input2_r)
{
// d0-d5: ?
// d6,d7: multiplexed inputs (side panel)
return (read_inputs(8) >> 2 & 0xc0) ^ 0xff;
}
/******************************************************************************
Constellation Forte
******************************************************************************/
// TTL/generic
void cforte_state::cforte_prepare_display()
{
// 3 led rows
display_matrix(8, 3, m_led_data, m_led_select, false);
// lcd panel (mostly handled in cforte_lcd_output_w)
set_display_segmask(0x3ff0, 0xff);
set_display_size(8, 3+13);
display_update();
}
WRITE64_MEMBER(cforte_state::cforte_lcd_output_w)
{
// 4 rows used
u32 rowdata[4];
for (int i = 0; i < 4; i++)
rowdata[i] = (data >> i & 1) ? u32(data >> 8) : 0;
// 2 segments per row
for (int dig = 0; dig < 13; dig++)
{
m_display_state[dig+3] = 0;
for (int i = 0; i < 4; i++)
m_display_state[dig+3] |= ((rowdata[i] >> (2*dig) & 3) << (2*i));
m_display_state[dig+3] = bitswap<8>(m_display_state[dig+3],7,2,0,4,6,5,3,1);
}
cforte_prepare_display();
}
WRITE8_MEMBER(cforte_state::cforte_mux_w)
{
// d0-d7: input mux, led data
m_inp_mux = m_led_data = data;
cforte_prepare_display();
}
WRITE8_MEMBER(cforte_state::cforte_control_w)
{
// d0: HLCD0538 data in
// d1: HLCD0538 clk
// d2: HLCD0538 lcd
m_hlcd0538->write_data(data & 1);
m_hlcd0538->write_clk(data >> 1 & 1);
m_hlcd0538->write_lcd(data >> 2 & 1);
// d3: unused?
// d4-d6: select led row
m_led_select = data >> 4 & 7;
cforte_prepare_display();
// d7: enable beeper
m_beeper->set_state(data >> 7 & 1);
}
READ8_MEMBER(cforte_state::cforte_input1_r)
{
// d0-d7: multiplexed inputs (chessboard squares)
return ~read_inputs(8) & 0xff;
}
READ8_MEMBER(cforte_state::cforte_input2_r)
{
// d0-d5: ?
// d6,d7: multiplexed inputs (side panel)
return (read_inputs(8) >> 2 & 0xc0) ^ 0xff;
}
/******************************************************************************
Super Expert
******************************************************************************/
// TTL/generic
WRITE8_MEMBER(sexpert_state::sexpert_lcd_control_w)
{
// d0: HD44780 RS
// d1: HD44780 R/W
// d2: HD44780 E
if (m_lcd_control & ~data & 4 && ~data & 2)
m_lcd->write(m_lcd_control & 1, m_lcd_data);
m_lcd_control = data & 7;
}
WRITE8_MEMBER(sexpert_state::sexpert_lcd_data_w)
{
// d0-d7: HD44780 data
m_lcd_data = data;
}
WRITE8_MEMBER(sexpert_state::sexpert_leds_w)
{
// d0-d7: chessboard leds
m_led_data = data;
}
WRITE8_MEMBER(sexpert_state::sexpert_mux_w)
{
// d0: rom bankswitch
m_rombank->set_entry(data & 1);
// d3: enable beeper
m_beeper->set_state(data >> 3 & 1);
// d4-d7: 74145 to input mux/led select
m_inp_mux = 1 << (data >> 4 & 0xf) & 0xff;
display_matrix(8, 8, m_led_data, m_inp_mux);
m_led_data = 0; // ?
}
READ8_MEMBER(sexpert_state::sexpert_input1_r)
{
// d0-d7: multiplexed inputs (chessboard squares)
return ~read_inputs(8) & 0xff;
}
READ8_MEMBER(sexpert_state::sexpert_input2_r)
{
// d0-d2: printer port
// d5-d7: multiplexed inputs (side panel)
return ~read_inputs(8) >> 3 & 0xe0;
}
/******************************************************************************
Super Forte
******************************************************************************/
WRITE8_MEMBER(sexpert_state::sforte_lcd_control_w)
{
// d3: rom bankswitch
m_rombank->set_entry(data >> 3 & 1);
// assume same as sexpert
sexpert_lcd_control_w(space, offset, data);
}
WRITE8_MEMBER(sexpert_state::sforte_lcd_data_w)
{
// d0-d2: input mux/led select
m_inp_mux = 1 << (data & 7);
// if lcd is disabled, misc control
if (~m_lcd_control & 4)
{
// d5,d6: led data, but not both at same time?
if ((data & 0x60) != 0x60)
display_matrix(2, 8, data >> 5 & 3, m_inp_mux);
// d7: enable beeper
m_beeper->set_state(data >> 7 & 1);
}
// assume same as sexpert
sexpert_lcd_data_w(space, offset, data);
}
/******************************************************************************
Address Maps
******************************************************************************/
// Super Constellation / Constellation Forte
void scon_state::supercon_map(address_map &map)
{
map(0x0000, 0x0fff).ram().share("nvram");
map(0x1c00, 0x1c00).nopw(); // printer/clock?
map(0x1d00, 0x1d00).nopw(); // printer/clock?
map(0x1e00, 0x1e00).rw(FUNC(scon_state::supercon_input2_r), FUNC(scon_state::supercon_mux_w));
map(0x1f00, 0x1f00).rw(FUNC(scon_state::supercon_input1_r), FUNC(scon_state::supercon_control_w));
map(0x2000, 0xffff).rom();
}
void cforte_state::cforte_map(address_map &map)
{
map(0x0000, 0x0fff).ram().share("nvram");
map(0x1c00, 0x1c00).nopw(); // printer?
map(0x1d00, 0x1d00).nopw(); // printer?
map(0x1e00, 0x1e00).rw(FUNC(cforte_state::cforte_input2_r), FUNC(cforte_state::cforte_mux_w));
map(0x1f00, 0x1f00).rw(FUNC(cforte_state::cforte_input1_r), FUNC(cforte_state::cforte_control_w));
map(0x2000, 0xffff).rom();
}
// Super Expert / Super Forte
void sexpert_state::sforte_map(address_map &map)
{
map(0x0000, 0x1fef).ram().share("nvram"); // 8KB RAM, but RAM CE pin is deactivated on $1ff0-$1fff
map(0x1ff0, 0x1ff0).r(FUNC(sexpert_state::sexpert_input1_r));
map(0x1ff1, 0x1ff1).r(FUNC(sexpert_state::sexpert_input2_r));
map(0x1ff2, 0x1ff2).nopw(); // printer
map(0x1ff3, 0x1ff3).nopw(); // printer
map(0x1ff4, 0x1ff4).nopw();
map(0x1ff5, 0x1ff5).nopw();
map(0x1ff6, 0x1ff6).w(FUNC(sexpert_state::sforte_lcd_control_w));
map(0x1ff7, 0x1ff7).w(FUNC(sexpert_state::sforte_lcd_data_w));
map(0x1ffc, 0x1fff).rw("acia", FUNC(mos6551_device::read), FUNC(mos6551_device::write));
map(0x2000, 0x7fff).rom();
map(0x8000, 0xffff).bankr("rombank");
}
void sexpert_state::sexpert_map(address_map &map)
{
map(0x0000, 0x1fef).ram().share("nvram"); // 8KB RAM, but RAM CE pin is deactivated on $1ff0-$1fff
map(0x1ff0, 0x1ff0).r(FUNC(sexpert_state::sexpert_input1_r));
map(0x1ff1, 0x1ff1).r(FUNC(sexpert_state::sexpert_input2_r));
map(0x1ff2, 0x1ff2).nopw(); // printer
map(0x1ff3, 0x1ff3).nopw(); // printer
map(0x1ff4, 0x1ff4).w(FUNC(sexpert_state::sexpert_leds_w));
map(0x1ff5, 0x1ff5).w(FUNC(sexpert_state::sexpert_mux_w));
map(0x1ff6, 0x1ff6).w(FUNC(sexpert_state::sexpert_lcd_control_w));
map(0x1ff7, 0x1ff7).w(FUNC(sexpert_state::sexpert_lcd_data_w));
map(0x1ffc, 0x1fff).rw("acia", FUNC(mos6551_device::read), FUNC(mos6551_device::write));
map(0x2000, 0x7fff).rom();
map(0x8000, 0xffff).bankr("rombank");
}
/******************************************************************************
Input Ports
******************************************************************************/
// chessboard generic inputs
INPUT_PORTS_START( novag_cb_buttons )
PORT_START("IN.0")
@ -777,351 +342,3 @@ INPUT_PORTS_START( novag_cb_magnets )
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_TOGGLE PORT_NAME("Board Sensor")
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_TOGGLE PORT_NAME("Board Sensor")
INPUT_PORTS_END
static INPUT_PORTS_START( supercon )
PORT_INCLUDE( novag_cb_buttons )
PORT_MODIFY("IN.0")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_I) PORT_NAME("New Game")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_NAME("Multi Move / Player/Player / King")
PORT_MODIFY("IN.1")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_U) PORT_NAME("Verify / Set Up")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7) PORT_NAME("Best Move/Random / Training Level / Queen")
PORT_MODIFY("IN.2")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Y) PORT_NAME("Change Color")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_NAME("Sound / Depth Search / Bishop")
PORT_MODIFY("IN.3")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Clear Board")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_NAME("Solve Mate / Knight")
PORT_MODIFY("IN.4")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_NAME("Print Moves")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_NAME("Print Board / Rook")
PORT_MODIFY("IN.5")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Form Size")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Print List / Acc. Time / Pawn")
PORT_MODIFY("IN.6")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("Hint")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("Set Level")
PORT_MODIFY("IN.7")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("Go")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("Take Back")
INPUT_PORTS_END
static INPUT_PORTS_START( cforte )
PORT_INCLUDE( novag_cb_buttons )
PORT_MODIFY("IN.0")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_I) PORT_NAME("New Game")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_NAME("Player/Player / Gambit/Large / King")
PORT_MODIFY("IN.1")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_U) PORT_NAME("Verify/Set Up / Pro-Op")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7) PORT_NAME("Random/Tour/Normal / Training Level / Queen")
PORT_MODIFY("IN.2")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Y) PORT_NAME("Change Color / Time Control / Priority")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_NAME("Sound / Depth Search / Bishop")
PORT_MODIFY("IN.3")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Flip Display / Clear Board / Clear Book")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_NAME("Solve Mate / Infinite / Knight")
PORT_MODIFY("IN.4")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_NAME("Print Moves / Print Evaluations / Print Book")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_NAME("Print Board / Interface / Rook")
PORT_MODIFY("IN.5")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Trace Forward / Auto Play / No/End")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Print List / Acc. Time / Pawn")
PORT_MODIFY("IN.6")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("Hint / Next Best / Yes/Start")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("Set Level")
PORT_MODIFY("IN.7")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("Go / ->")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("Take Back / Restore / <-")
INPUT_PORTS_END
static INPUT_PORTS_START( sexy_shared )
PORT_MODIFY("IN.0")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_NAME("Go")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("Take Back / Analyze Games")
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("->")
PORT_MODIFY("IN.1")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_NAME("Set Level")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("Flip Display / Time Control")
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("<-")
PORT_MODIFY("IN.2")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_D) PORT_NAME("Hint / Next Best")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("Priority / Tournament Book / Pawn")
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("Yes/Start / Start of Game")
PORT_MODIFY("IN.3")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F) PORT_NAME("Trace Forward / AutoPlay")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_NAME("Pro-Op / Restore Game / Rook")
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_NAME("No/End / End of Game")
PORT_MODIFY("IN.4")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_G) PORT_NAME("Clear Board / Delete Pro-Op")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Best Move/Random / Review / Knight")
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_NAME("Print Book / Store Game")
PORT_MODIFY("IN.5")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_H) PORT_NAME("Change Color")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Y) PORT_NAME("Sound / Info / Bishop")
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_NAME("Print Moves / Print Evaluations")
PORT_MODIFY("IN.6")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_J) PORT_NAME("Verify/Set Up / Pro-Op Book/Both Books")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_U) PORT_NAME("Solve Mate / Infinite / Queen")
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7) PORT_NAME("Print List / Acc. Time")
PORT_MODIFY("IN.7")
PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_K) PORT_NAME("New Game")
PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_I) PORT_NAME("Player/Player / Gambit Book / King")
PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_NAME("Print Board / Interface")
PORT_START("FAKE")
PORT_CONFNAME( 0x01, 0x00, "CPU Frequency" ) PORT_CHANGED_MEMBER(DEVICE_SELF, sexpert_state, sexpert_cpu_freq, nullptr) // factory set
PORT_CONFSETTING( 0x00, "5MHz" )
PORT_CONFSETTING( 0x01, "6MHz" )
INPUT_PORTS_END
static INPUT_PORTS_START( sexpert )
PORT_INCLUDE( novag_cb_magnets )
PORT_INCLUDE( sexy_shared )
INPUT_PORTS_END
static INPUT_PORTS_START( sforte )
PORT_INCLUDE( novag_cb_buttons )
PORT_INCLUDE( sexy_shared )
INPUT_PORTS_END
/******************************************************************************
Machine Drivers
******************************************************************************/
void scon_state::supercon(machine_config &config)
{
/* basic machine hardware */
M6502(config, m_maincpu, 8_MHz_XTAL/2);
m_maincpu->set_addrmap(AS_PROGRAM, &scon_state::supercon_map);
m_maincpu->set_periodic_int(FUNC(scon_state::irq0_line_hold), attotime::from_hz(600)); // guessed
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
TIMER(config, "display_decay").configure_periodic(FUNC(scon_state::display_decay_tick), attotime::from_msec(1));
config.set_default_layout(layout_novag_supercon);
/* sound hardware */
SPEAKER(config, "mono").front_center();
BEEP(config, m_beeper, 1024); // guessed
m_beeper->add_route(ALL_OUTPUTS, "mono", 0.25);
}
void cforte_state::cforte(machine_config &config)
{
/* basic machine hardware */
R65C02(config, m_maincpu, 10_MHz_XTAL/2);
m_maincpu->set_addrmap(AS_PROGRAM, &cforte_state::cforte_map);
const attotime irq_period = attotime::from_hz(32.768_kHz_XTAL/128); // 256Hz
TIMER(config, m_irq_on).configure_periodic(FUNC(cforte_state::irq_on<M6502_IRQ_LINE>), irq_period);
m_irq_on->set_start_delay(irq_period - attotime::from_usec(11)); // active for 11us
TIMER(config, "irq_off").configure_periodic(FUNC(cforte_state::irq_off<M6502_IRQ_LINE>), irq_period);
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
/* video hardware */
HLCD0538(config, m_hlcd0538, 0);
m_hlcd0538->write_cols_callback().set(FUNC(cforte_state::cforte_lcd_output_w));
TIMER(config, "display_decay").configure_periodic(FUNC(cforte_state::display_decay_tick), attotime::from_msec(1));
config.set_default_layout(layout_novag_cforte);
/* sound hardware */
SPEAKER(config, "mono").front_center();
BEEP(config, m_beeper, 32.768_kHz_XTAL/32); // 1024Hz
m_beeper->add_route(ALL_OUTPUTS, "mono", 0.25);
}
void sexpert_state::sexpert(machine_config &config)
{
/* basic machine hardware */
M65C02(config, m_maincpu, 10_MHz_XTAL/2); // or 12_MHz_XTAL/2
m_maincpu->set_addrmap(AS_PROGRAM, &sexpert_state::sexpert_map);
const attotime irq_period = attotime::from_hz(32.768_kHz_XTAL/128); // 256Hz
TIMER(config, m_irq_on).configure_periodic(FUNC(sexpert_state::irq_on<M6502_IRQ_LINE>), irq_period);
m_irq_on->set_start_delay(irq_period - attotime::from_nsec(21500)); // active for 21.5us
TIMER(config, "irq_off").configure_periodic(FUNC(sexpert_state::irq_off<M6502_IRQ_LINE>), irq_period);
mos6551_device &acia(MOS6551(config, "acia", 0)); // R65C51P2 - RTS to CTS, DCD to GND
acia.set_xtal(1.8432_MHz_XTAL);
acia.irq_handler().set_inputline("maincpu", m65c02_device::NMI_LINE);
acia.rts_handler().set("acia", FUNC(mos6551_device::write_cts));
acia.txd_handler().set("rs232", FUNC(rs232_port_device::write_txd));
acia.dtr_handler().set("rs232", FUNC(rs232_port_device::write_dtr));
rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, nullptr));
rs232.rxd_handler().set("acia", FUNC(mos6551_device::write_rxd));
rs232.dsr_handler().set("acia", FUNC(mos6551_device::write_dsr));
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD));
screen.set_refresh_hz(60); // arbitrary
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500));
screen.set_size(6*16+1, 10);
screen.set_visarea(0, 6*16, 0, 10-1);
screen.set_screen_update("hd44780", FUNC(hd44780_device::screen_update));
screen.set_palette("palette");
PALETTE(config, "palette", FUNC(sexpert_state::novag_lcd_palette), 3);
HD44780(config, m_lcd, 0);
m_lcd->set_lcd_size(2, 8);
m_lcd->set_pixel_update_cb(FUNC(sexpert_state::novag_lcd_pixel_update), this);
TIMER(config, "display_decay").configure_periodic(FUNC(sexpert_state::display_decay_tick), attotime::from_msec(1));
config.set_default_layout(layout_novag_sexpert);
/* sound hardware */
SPEAKER(config, "mono").front_center();
BEEP(config, m_beeper, 32.768_kHz_XTAL/32); // 1024Hz
m_beeper->add_route(ALL_OUTPUTS, "mono", 0.25);
}
void sexpert_state::sforte(machine_config &config)
{
sexpert(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_PROGRAM, &sexpert_state::sforte_map);
m_irq_on->set_start_delay(m_irq_on->period() - attotime::from_usec(11)); // active for ?us (assume same as cforte)
config.set_default_layout(layout_novag_sforte);
}
/******************************************************************************
ROM Definitions
******************************************************************************/
ROM_START( supercon )
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD("novag_8441", 0x0000, 0x8000, CRC(b853cf6e) SHA1(1a759072a5023b92c07f1fac01b7a21f7b5b45d0) ) // label obscured by Q.C. sticker
ROM_LOAD("novag_8442", 0x8000, 0x8000, CRC(c8f82331) SHA1(f7fd039f9a3344db9749931490ded9e9e309cfbe) )
ROM_END
ROM_START( cfortea )
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD("a_903_l", 0x0000, 0x8000, CRC(01e7e306) SHA1(6a2b982bb0f412a63f5d3603958dd863e38669d9) ) // NEC D27C256AD-12
ROM_LOAD("a_903_h", 0x8000, 0x8000, CRC(c5a5573f) SHA1(7e11eb2f3d96bc41386a14a19635427a386ec1ec) ) // "
ROM_END
ROM_START( cforteb )
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD("forte_b_l.bin", 0x0000, 0x8000, CRC(e3d194a1) SHA1(80457580d7c57e07895fd14bfdaf14b30952afca) )
ROM_LOAD("forte_b_h.bin", 0x8000, 0x8000, CRC(dd824be8) SHA1(cd8666b6b525887f9fc48a730b71ceabcf07f3b9) )
ROM_END
ROM_START( sfortea )
ROM_REGION( 0x18000, "maincpu", 0 )
ROM_LOAD("sfalo.u3", 0x0000, 0x8000, CRC(86e0230a) SHA1(0d6e18a17e636b8c7292c8f331349d361892d1a8) )
ROM_LOAD("sfahi.u1", 0x8000, 0x8000, CRC(81c02746) SHA1(0bf68b68ade5a3263bead88da0a8965fc71483c1) )
ROM_LOAD("sfabook.u2", 0x10000, 0x8000, CRC(3e42cf7c) SHA1(b2faa36a127e08e5755167a25ed4a07f12d62957) )
ROM_END
ROM_START( sfortea1 )
ROM_REGION( 0x18000, "maincpu", 0 )
ROM_LOAD("sfa_lo.u3", 0x0000, 0x8000, CRC(78734bfd) SHA1(b6d8e9efccee6f6d0b0cd257a82162bf8ccec719) )
ROM_LOAD("sfa_hi_1.u1", 0x8000, 0x8000, CRC(e5e84580) SHA1(bae55c3da7b720bf6ccfb450e383c53cebd5e9ef) )
ROM_LOAD("sfa_hi_0.u2", 0x10000, 0x8000, CRC(3e42cf7c) SHA1(b2faa36a127e08e5755167a25ed4a07f12d62957) )
ROM_END
ROM_START( sforteb )
ROM_REGION( 0x18000, "maincpu", 0 )
ROM_LOAD("forte_b_lo.u3", 0x0000, 0x8000, CRC(48bfe5d6) SHA1(323642686b6d2fb8db2b7d50c6cd431058078ce1) )
ROM_LOAD("forte_b_hi1.u1", 0x8000, 0x8000, CRC(9778ca2c) SHA1(d8b88b9768a1a9171c68cbb0892b817d68d78351) )
ROM_LOAD("forte_b_hi0.u2", 0x10000, 0x8000, CRC(bb07ad52) SHA1(30cf9005021ab2d7b03facdf2d3588bc94dc68a6) )
ROM_END
ROM_START( sfortec )
ROM_REGION( 0x18000, "maincpu", 0 )
ROM_LOAD("sfl_c_111.u3", 0x0000, 0x8000, CRC(f040cf30) SHA1(1fc1220b8ed67cdffa3866d230ce001721cf684f) ) // Toshiba TC57256AD-12
ROM_LOAD("sfh_c_111.u1", 0x8000, 0x8000, CRC(0f926b32) SHA1(9c7270ecb3f41dd9172a9a7928e6e04e64b2a340) ) // NEC D27C256AD-12
ROM_LOAD("h0_c_c26.u2", 0x10000, 0x8000, CRC(c6a1419a) SHA1(017a0ffa9aa59438c879624a7ddea2071d1524b8) ) // Toshiba TC57256AD-12
ROM_END
ROM_START( sexperta )
ROM_REGION( 0x18000, "maincpu", 0 )
ROM_LOAD("se_lo_b15.u3", 0x0000, 0x8000, CRC(6cc9527c) SHA1(29bab809399f2863a88a9c41535ecec0a4fd65ea) )
ROM_LOAD("se_hi1_b15.u1", 0x8000, 0x8000, CRC(6e57f0c0) SHA1(ea44769a6f54721fd4543366bda932e86e497d43) )
ROM_LOAD("sef_hi0_a23.u2", 0x10000, 0x8000, CRC(7d4e1528) SHA1(53c7d458a5571afae402f00ae3d0f5066634b068) )
ROM_END
ROM_START( sexpertb )
ROM_REGION( 0x18000, "maincpu", 0 )
ROM_LOAD("se_lo_619.u3", 0x0000, 0x8000, CRC(92002eb6) SHA1(ed8ca16701e00b48fa55c856fa4a8c6613079c02) )
ROM_LOAD("se_hi1_619.u1", 0x8000, 0x8000, CRC(814b4420) SHA1(c553e6a8c048dcc1cf48d410111a86e06b99d356) )
ROM_LOAD("sef_hi0_605.u2", 0x10000, 0x8000, CRC(bb07ad52) SHA1(30cf9005021ab2d7b03facdf2d3588bc94dc68a6) )
ROM_END
ROM_START( sexpertc )
ROM_REGION( 0x18000, "maincpu", 0 )
ROM_LOAD("se_lo_v3.6.u3", 0x0000, 0x8000, CRC(5a29105e) SHA1(be37bb29b530dbba847a5e8d27d81b36525e47f7) )
ROM_LOAD("se_hi1.u1", 0x8000, 0x8000, CRC(0085c2c4) SHA1(d84bf4afb022575db09dd9dc12e9b330acce35fa) )
ROM_LOAD("se_hi0.u2", 0x10000, 0x8000, CRC(2d085064) SHA1(76162322aa7d23a5c07e8356d0bbbb33816419af) )
ROM_END
ROM_START( sexpertc1 )
ROM_REGION( 0x18000, "maincpu", 0 )
ROM_LOAD("se_lo_v1.2.u3", 0x0000, 0x8000, CRC(43ed7a9e) SHA1(273c485e5be6b107b6c5c448003ba7686d4a6d06) )
ROM_LOAD("se_hi1.u1", 0x8000, 0x8000, CRC(0085c2c4) SHA1(d84bf4afb022575db09dd9dc12e9b330acce35fa) )
ROM_LOAD("se_hi0.u2", 0x10000, 0x8000, CRC(2d085064) SHA1(76162322aa7d23a5c07e8356d0bbbb33816419af) )
ROM_END
/******************************************************************************
Drivers
******************************************************************************/
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
CONS( 1984, supercon, 0, 0, supercon, supercon, scon_state, empty_init, "Novag", "Super Constellation", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1986, cfortea, 0, 0, cforte, cforte, cforte_state, empty_init, "Novag", "Constellation Forte (version A)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1986, cforteb, cfortea, 0, cforte, cforte, cforte_state, empty_init, "Novag", "Constellation Forte (version B)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1987, sfortea, 0, 0, sforte, sforte, sexpert_state, init_sexpert, "Novag", "Super Forte (version A, set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1987, sfortea1, sfortea, 0, sforte, sforte, sexpert_state, init_sexpert, "Novag", "Super Forte (version A, set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1988, sforteb, sfortea, 0, sforte, sforte, sexpert_state, init_sexpert, "Novag", "Super Forte (version B)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1990, sfortec, sfortea, 0, sforte, sforte, sexpert_state, init_sexpert, "Novag", "Super Forte (version C)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1987, sexperta, 0, 0, sexpert, sexpert, sexpert_state, init_sexpert, "Novag", "Super Expert (version A)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1988, sexpertb, sexperta, 0, sexpert, sexpert, sexpert_state, init_sexpert, "Novag", "Super Expert (version B)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1990, sexpertc, sexperta, 0, sexpert, sexpert, sexpert_state, init_sexpert, "Novag", "Super Expert (version C, V3.6)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )
CONS( 1990, sexpertc1, sexperta, 0, sexpert, sexpert, sexpert_state, init_sexpert, "Novag", "Super Expert (version C, V1.2)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS )

View File

@ -30696,6 +30696,10 @@ pkunwarj // UPL-????? (c) 1985 (Arcade Game TV List - P.9
raiders5 // UPL-85004 (c) 1985
raiders5t // UPL-85004 (c) 1985 Taito license
@source:novag_cforte.cpp
cfortea //
cforteb //
@source:novag_delta1.cpp
ccdelta1 //
@ -30707,9 +30711,10 @@ scorpio68 //
nocto //
npresto //
@source:novagbase.cpp
cfortea //
cforteb //
@source:novag_scon.cpp
supercon //
@source:novag_sexpert.cpp
sexperta //
sexpertb //
sexpertc //
@ -30718,7 +30723,6 @@ sfortea //
sfortea1 //
sforteb //
sfortec //
supercon //
@source:nsg6809.cpp
pitchhit //

View File

@ -523,9 +523,12 @@ ngen.cpp
ngp.cpp
nokia_3310.cpp
notetaker.cpp
novag_cforte.cpp
novag_delta1.cpp
novag_diablo.cpp
novag_presto.cpp
novag_scon.cpp
novag_sexpert.cpp
novagbase.cpp
o2.cpp
ob68k1a.cpp