summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/novag_cforte.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/novag_cforte.cpp')
-rw-r--r--src/mame/drivers/novag_cforte.cpp259
1 files changed, 259 insertions, 0 deletions
diff --git a/src/mame/drivers/novag_cforte.cpp b/src/mame/drivers/novag_cforte.cpp
new file mode 100644
index 00000000000..64c0564f214
--- /dev/null
+++ b/src/mame/drivers/novag_cforte.cpp
@@ -0,0 +1,259 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+// thanks-to:Berger
+/******************************************************************************
+*
+* novag_cforte.cpp, subdriver of machine/novagbase.cpp, machine/chessbase.cpp
+
+TODO:
+- RS232 port?
+
+*******************************************************************************
+
+Novag Constellation Forte overview:
+- 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->data_w(data & 1);
+ m_hlcd0538->clk_w(data >> 1 & 1);
+ m_hlcd0538->lcd_w(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( generic_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);
+ m_hlcd0538->write_cols().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 )