1 // license:BSD-3-Clause
2 // copyright-holders:hap
3 // thanks-to:Berger
4 /******************************************************************************
5
6 SciSys President Chess (model 231)
7 (not to be confused with Saitek Kasparov President)
8
9 The ROMs are inside a module, at the top-right. No known upgrades were released.
10 Apparently the chessboard was not that reliable. The manual even says to flip the
11 computer and shake it when one of the sensors is malfunctioning.
12
13 Hardware notes:
14 - 6502A @ 2MHz
15 - 16KB ROM(2*HN482764G), 2KB RAM(HM6116P-4)
16 - buzzer, 64+12 leds, magnet sensors chessboard
17
18 TODO:
19 - verify CPU speed / XTAL
20 - measure interrupt frequency
21 - the manual claims that it does a self-test at boot, but on MAME that only
22 happens if you hold down one of the buttons
23
24 ******************************************************************************/
25
26 #include "emu.h"
27 #include "cpu/m6502/m6502.h"
28 #include "machine/sensorboard.h"
29 #include "sound/dac.h"
30 #include "video/pwm.h"
31 #include "speaker.h"
32
33 // internal artwork
34 #include "saitek_prschess.lh" // clickable
35
36
37 namespace {
38
39 class prschess_state : public driver_device
40 {
41 public:
prschess_state(const machine_config & mconfig,device_type type,const char * tag)42 prschess_state(const machine_config &mconfig, device_type type, const char *tag) :
43 driver_device(mconfig, type, tag),
44 m_maincpu(*this, "maincpu"),
45 m_board(*this, "board"),
46 m_display(*this, "display"),
47 m_dac(*this, "dac"),
48 m_inputs(*this, "IN.%u", 0)
49 { }
50
51 // machine configs
52 void prschess(machine_config &config);
53
54 protected:
55 virtual void machine_start() override;
56
57 private:
58 // devices/pointers
59 required_device<cpu_device> m_maincpu;
60 required_device<sensorboard_device> m_board;
61 required_device<pwm_display_device> m_display;
62 required_device<dac_bit_interface> m_dac;
63 required_ioport_array<3> m_inputs;
64
65 // address maps
66 void main_map(address_map &map);
67
68 // I/O handlers
69 void update_display();
70 void leds_w(offs_t offset, u8 data);
71 void control_w(u8 data);
72 u8 input_r();
73
74 u8 m_inp_mux = 0;
75 u8 m_led_data[2] = { 0, 0 };
76 };
77
machine_start()78 void prschess_state::machine_start()
79 {
80 save_item(NAME(m_inp_mux));
81 save_item(NAME(m_led_data));
82 }
83
84
85
86 /******************************************************************************
87 I/O
88 ******************************************************************************/
89
update_display()90 void prschess_state::update_display()
91 {
92 u16 led_data = m_led_data[1] << 8 | m_led_data[0];
93 led_data = bitswap<16>(led_data,15,14,5,4,3,2,1,0, 7,6,13,12,11,10,9,8);
94 m_display->matrix(1 << m_inp_mux, led_data);
95 }
96
leds_w(offs_t offset,u8 data)97 void prschess_state::leds_w(offs_t offset, u8 data)
98 {
99 m_led_data[offset >> 8] = ~data;
100 update_display();
101 }
102
control_w(u8 data)103 void prschess_state::control_w(u8 data)
104 {
105 // d0-d3: input mux, led select
106 m_inp_mux = data & 0xf;
107 update_display();
108
109 // d5: speaker out
110 m_dac->write(BIT(data, 5));
111
112 // other: ?
113 }
114
input_r()115 u8 prschess_state::input_r()
116 {
117 u8 data = 0;
118
119 // read chessboard sensors
120 if (m_inp_mux < 8)
121 data = m_board->read_file(m_inp_mux);
122
123 // read other buttons
124 else if (m_inp_mux < 11)
125 data = m_inputs[m_inp_mux - 8]->read();
126
127 return data;
128 }
129
130
131
132 /******************************************************************************
133 Address Maps
134 ******************************************************************************/
135
main_map(address_map & map)136 void prschess_state::main_map(address_map &map)
137 {
138 map(0x0000, 0x07ff).ram();
139 map(0x4000, 0x4000).select(0x0100).w(FUNC(prschess_state::leds_w));
140 map(0x4200, 0x4200).w(FUNC(prschess_state::control_w));
141 map(0x4300, 0x4300).r(FUNC(prschess_state::input_r));
142 map(0xc000, 0xffff).rom();
143 }
144
145
146
147 /******************************************************************************
148 Input Ports
149 ******************************************************************************/
150
151 static INPUT_PORTS_START( prschess )
152 PORT_START("IN.0")
153 PORT_BIT(0x03, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_CODE(KEYCODE_I)154 PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_I) PORT_NAME("Interrupt")
155 PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_M) PORT_NAME("Move")
156 PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Take Back")
157 PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_H) PORT_NAME("Hint")
158 PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_G) PORT_NAME("Legal")
159 PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_L) PORT_NAME("Level")
160
161 PORT_START("IN.1")
162 PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_UNUSED)
163 PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_NAME("Reset")
164 PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Z) PORT_NAME("Player V Computer")
165 PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_X) PORT_NAME("Player V Player")
166 PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_NAME("Change Sides")
167 PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_C) PORT_NAME("Clear Board")
168 PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_V) PORT_NAME("Verify / Set Up")
169 PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("White")
170
171 PORT_START("IN.2")
172 PORT_BIT(0x03, IP_ACTIVE_HIGH, IPT_UNUSED)
173 PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("Pawn")
174 PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Knight")
175 PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Bishop")
176 PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Rook")
177 PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Queen")
178 PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("King")
179 INPUT_PORTS_END
180
181
182
183 /******************************************************************************
184 Machine Configs
185 ******************************************************************************/
186
187 void prschess_state::prschess(machine_config &config)
188 {
189 /* basic machine hardware */
190 M6502(config, m_maincpu, 2000000);
191 m_maincpu->set_addrmap(AS_PROGRAM, &prschess_state::main_map);
192 m_maincpu->set_periodic_int(FUNC(prschess_state::nmi_line_pulse), attotime::from_hz(100)); // guessed
193
194 SENSORBOARD(config, m_board).set_type(sensorboard_device::MAGNETS);
195 m_board->init_cb().set(m_board, FUNC(sensorboard_device::preset_chess));
196 m_board->set_delay(attotime::from_msec(150));
197
198 /* video hardware */
199 PWM_DISPLAY(config, m_display).set_size(8+1, 16);
200 config.set_default_layout(layout_saitek_prschess);
201
202 /* sound hardware */
203 SPEAKER(config, "speaker").front_center();
204 DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25);
205 }
206
207
208
209 /******************************************************************************
210 ROM Definitions
211 ******************************************************************************/
212
213 ROM_START( prschess )
214 ROM_REGION( 0x10000, "maincpu", 0 )
215 ROM_LOAD("y03_rl", 0xc000, 0x2000, CRC(862c3f42) SHA1(e2d2f1d7a0382b0774e86ca83e270dab1df700c2) ) // HN482764G
216 ROM_LOAD("y03_rh", 0xe000, 0x2000, CRC(ef95cb9f) SHA1(02f763cf9cab1b4be8964ddb5d93efb05a898123) ) // "
217 ROM_END
218
219 } // anonymous namespace
220
221
222
223 /******************************************************************************
224 Drivers
225 ******************************************************************************/
226
227 // YEAR NAME PARENT CMP MACHINE INPUT STATE INIT COMPANY, FULLNAME, FLAGS
228 CONS( 1982, prschess, 0, 0, prschess, prschess, prschess_state, empty_init, "SciSys", "President Chess", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
229