1 // license:BSD-3-Clause
2 // copyright-holders:hap
3 // thanks-to:yoyo_chessboard
4 /******************************************************************************
5 
6 Fidelity Sensory Chess Challenger "8"
7 
8 It is the first chesscomputer with sensors under the chessboard.
9 
10 The box names it Sensory Chess Challenger, Sensory Chess Challenger "8" title
11 is on the 1st page of the manual. Like other Fidelity chesscomputers from
12 around this time, the number indicates maximum difficulty level.
13 
14 It was also rereleased in 1983 as "Poppy", marketed for children, the housing
15 was in bright red color.
16 
17 Hardware notes:
18 - Z80A CPU @ 3.9MHz
19 - 4KB ROM(MOS 2732), 256 bytes RAM(35391CP)
20 - chessboard buttons, 8*8+1 leds
21 - PCB label 510-1011 REV.2
22 
23 ******************************************************************************/
24 
25 #include "emu.h"
26 #include "cpu/z80/z80.h"
27 #include "machine/sensorboard.h"
28 #include "sound/dac.h"
29 #include "video/pwm.h"
30 #include "speaker.h"
31 
32 // internal artwork
33 #include "fidel_sc8.lh" // clickable
34 
35 
36 namespace {
37 
38 class scc_state : public driver_device
39 {
40 public:
scc_state(const machine_config & mconfig,device_type type,const char * tag)41 	scc_state(const machine_config &mconfig, device_type type, const char *tag) :
42 		driver_device(mconfig, type, tag),
43 		m_maincpu(*this, "maincpu"),
44 		m_board(*this, "board"),
45 		m_display(*this, "display"),
46 		m_dac(*this, "dac"),
47 		m_inputs(*this, "IN.0")
48 	{ }
49 
50 	// machine configs
51 	void scc(machine_config &config);
52 
53 protected:
54 	virtual void machine_start() override;
55 
56 private:
57 	// devices/pointers
58 	required_device<cpu_device> m_maincpu;
59 	required_device<sensorboard_device> m_board;
60 	required_device<pwm_display_device> m_display;
61 	required_device<dac_bit_interface> m_dac;
62 	required_ioport m_inputs;
63 
64 	// address maps
65 	void main_map(address_map &map);
66 	void main_io(address_map &map);
67 
68 	// I/O handlers
69 	u8 input_r();
70 	void control_w(offs_t offset, u8 data);
71 
72 	u8 m_inp_mux = 0;
73 	u8 m_led_data = 0;
74 };
75 
machine_start()76 void scc_state::machine_start()
77 {
78 	// register for savestates
79 	save_item(NAME(m_inp_mux));
80 	save_item(NAME(m_led_data));
81 }
82 
83 
84 
85 /******************************************************************************
86     I/O
87 ******************************************************************************/
88 
89 // TTL
90 
control_w(offs_t offset,u8 data)91 void scc_state::control_w(offs_t offset, u8 data)
92 {
93 	// a0-a2,d7: led data
94 	u8 mask = 1 << (offset & 7);
95 	m_led_data = (m_led_data & ~mask) | ((data & 0x80) ? mask : 0);
96 
97 	// d0-d3: led select, input mux (row 9 is speaker out)
98 	// d4: corner led(direct)
99 	m_inp_mux = data & 0xf;
100 	u16 sel = 1 << m_inp_mux;
101 	m_dac->write(BIT(sel, 9));
102 	m_display->matrix((sel & 0xff) | (data << 4 & 0x100), m_led_data);
103 }
104 
input_r()105 u8 scc_state::input_r()
106 {
107 	u8 data = 0;
108 
109 	// d0-d7: multiplexed inputs (active low)
110 	// read chessboard sensors
111 	if (m_inp_mux < 8)
112 		data = m_board->read_file(m_inp_mux);
113 
114 	// read button panel
115 	else if (m_inp_mux == 8)
116 		data = m_inputs->read();
117 
118 	return ~data;
119 }
120 
121 
122 
123 /******************************************************************************
124     Address Maps
125 ******************************************************************************/
126 
main_map(address_map & map)127 void scc_state::main_map(address_map &map)
128 {
129 	map(0x0000, 0x0fff).rom();
130 	map(0x5000, 0x50ff).ram();
131 }
132 
main_io(address_map & map)133 void scc_state::main_io(address_map &map)
134 {
135 	map.global_mask(0x07);
136 	map(0x00, 0x07).rw(FUNC(scc_state::input_r), FUNC(scc_state::control_w));
137 }
138 
139 
140 
141 /******************************************************************************
142     Input Ports
143 ******************************************************************************/
144 
145 static INPUT_PORTS_START( scc )
146 	PORT_START("IN.0")
PORT_CODE(KEYCODE_1)147 	PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("Pawn")
148 	PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Rook")
149 	PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Knight")
150 	PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Bishop")
151 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Queen")
152 	PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("King")
153 	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_DEL) PORT_NAME("CL")
154 	PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_NAME("RE")
155 INPUT_PORTS_END
156 
157 
158 
159 /******************************************************************************
160     Machine Configs
161 ******************************************************************************/
162 
163 void scc_state::scc(machine_config &config)
164 {
165 	/* basic machine hardware */
166 	Z80(config, m_maincpu, 3.9_MHz_XTAL);
167 	m_maincpu->set_addrmap(AS_PROGRAM, &scc_state::main_map);
168 	m_maincpu->set_addrmap(AS_IO, &scc_state::main_io);
169 
170 	SENSORBOARD(config, m_board).set_type(sensorboard_device::BUTTONS);
171 	m_board->init_cb().set(m_board, FUNC(sensorboard_device::preset_chess));
172 	m_board->set_delay(attotime::from_msec(150));
173 
174 	/* video hardware */
175 	PWM_DISPLAY(config, m_display).set_size(9, 8);
176 	config.set_default_layout(layout_fidel_sc8);
177 
178 	/* sound hardware */
179 	SPEAKER(config, "speaker").front_center();
180 	DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25);
181 }
182 
183 
184 
185 /******************************************************************************
186     ROM Definitions
187 ******************************************************************************/
188 
189 ROM_START( fscc8 ) // model SCC
190 	ROM_REGION( 0x10000, "maincpu", 0 )
191 	ROM_LOAD( "101-32017", 0x0000, 0x1000, CRC(5340820d) SHA1(e3494c7624b3cacbbb9a0a8cc9e1ed3e00326dfd) ) // 2732
192 ROM_END
193 
194 } // anonymous namespace
195 
196 
197 
198 /******************************************************************************
199     Drivers
200 ******************************************************************************/
201 
202 //    YEAR  NAME   PARENT CMP MACHINE  INPUT  STATE      INIT        COMPANY, FULLNAME, FLAGS
203 CONS( 1980, fscc8, 0,      0, scc,     scc,   scc_state, empty_init, "Fidelity Electronics", "Sensory Chess Challenger \"8\"", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
204