1 // license:BSD-3-Clause
2 // copyright-holders:Sandro Ronco, hap
3 // thanks-to:Berger
4 /***************************************************************************
5 
6 Mephisto Mondial 68000XL
7 The chess engine is actually the one from Mephisto Dallas.
8 
9 Hardware:
10 - TS68000CP12 @ 12MHz
11 - 64KB ROM
12 - 16KB RAM
13 - PCF2112T LCD driver
14 
15 ***************************************************************************/
16 
17 #include "emu.h"
18 
19 #include "cpu/m68000/m68000.h"
20 #include "machine/74259.h"
21 #include "machine/sensorboard.h"
22 #include "sound/dac.h"
23 #include "video/pcf2100.h"
24 #include "video/pwm.h"
25 
26 #include "speaker.h"
27 
28 // internal artwork
29 #include "mephisto_mondial68k.lh"
30 
31 
32 namespace {
33 
34 class mondial68k_state : public driver_device
35 {
36 public:
mondial68k_state(const machine_config & mconfig,device_type type,const char * tag)37 	mondial68k_state(const machine_config &mconfig, device_type type, const char *tag)
38 		: driver_device(mconfig, type, tag)
39 		, m_maincpu(*this, "maincpu")
40 		, m_board(*this, "board")
41 		, m_display(*this, "display")
42 		, m_lcd(*this, "lcd")
43 		, m_inputs(*this, "IN.%u", 0)
44 		, m_digits(*this, "digit%u", 0U)
45 	{ }
46 
47 	void mondial68k(machine_config &config);
48 
49 protected:
50 	virtual void machine_start() override;
51 
52 	void mondial68k_mem(address_map &map);
53 
54 	void lcd_s_w(u32 data);
55 	void input_mux_w(u8 data);
56 	void board_mux_w(u8 data);
57 	u8 inputs_r();
58 	void update_display();
59 
60 	required_device<cpu_device> m_maincpu;
61 	required_device<sensorboard_device> m_board;
62 	required_device<pwm_display_device> m_display;
63 	required_device<pcf2112_device> m_lcd;
64 	required_ioport_array<4> m_inputs;
65 	output_finder<4> m_digits;
66 
67 	u8 m_input_mux = 0xff;
68 	u8 m_board_mux = 0xff;
69 };
70 
71 
machine_start()72 void mondial68k_state::machine_start()
73 {
74 	m_digits.resolve();
75 
76 	save_item(NAME(m_input_mux));
77 	save_item(NAME(m_board_mux));
78 }
79 
80 
81 
82 /******************************************************************************
83     I/O
84 ******************************************************************************/
85 
update_display()86 void mondial68k_state::update_display()
87 {
88 	m_display->matrix(m_input_mux >> 6, ~m_board_mux);
89 }
90 
lcd_s_w(u32 data)91 void mondial68k_state::lcd_s_w(u32 data)
92 {
93 	// output LCD digits (note: last digit DP segment is unused)
94 	for (int i=0; i<4; i++)
95 		m_digits[i] = bitswap<8>((data & 0x7fffffff) >> (8 * i), 7,4,5,0,1,2,3,6);
96 }
97 
board_mux_w(u8 data)98 void mondial68k_state::board_mux_w(u8 data)
99 {
100 	// d0-d7: chessboard mux, led data
101 	m_board_mux = data;
102 	update_display();
103 }
104 
input_mux_w(u8 data)105 void mondial68k_state::input_mux_w(u8 data)
106 {
107 	// d0-d3: button mux
108 	// d6,d7: led select
109 	m_input_mux = data;
110 	update_display();
111 }
112 
inputs_r()113 u8 mondial68k_state::inputs_r()
114 {
115 	u8 data = 0x00;
116 
117 	// read buttons
118 	for (int i=0; i<4; i++)
119 		if (!BIT(m_input_mux, i))
120 			data |= m_inputs[i]->read();
121 
122 	// read chessboard sensors
123 	for (int i=0; i<8; i++)
124 		if (!BIT(m_board_mux, i))
125 			data |= m_board->read_rank(i);
126 
127 	return data;
128 }
129 
130 
131 
132 /******************************************************************************
133     Address Maps
134 ******************************************************************************/
135 
mondial68k_mem(address_map & map)136 void mondial68k_state::mondial68k_mem(address_map &map)
137 {
138 	map(0x000000, 0x00ffff).rom();
139 	map(0x800000, 0x800000).r(FUNC(mondial68k_state::inputs_r));
140 	map(0x820000, 0x82000f).nopr().w("outlatch", FUNC(hc259_device::write_d0)).umask16(0xff00);
141 	map(0x840000, 0x840000).w(FUNC(mondial68k_state::input_mux_w));
142 	map(0x860000, 0x860000).w(FUNC(mondial68k_state::board_mux_w));
143 	map(0xc00000, 0xc03fff).ram();
144 }
145 
146 
147 
148 /******************************************************************************
149     Input Ports
150 ******************************************************************************/
151 
152 static INPUT_PORTS_START( mondial68k )
153 	PORT_START("IN.0")
PORT_CODE(KEYCODE_A)154 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("A / 1") PORT_CODE(KEYCODE_A) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD)
155 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("E / 5 / Rook") PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD)
156 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Left / Black / 9") PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_CODE(KEYCODE_LEFT)
157 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("LEV") PORT_CODE(KEYCODE_L)
158 
159 	PORT_START("IN.1")
160 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("B / 2 / Pawn") PORT_CODE(KEYCODE_B) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD)
161 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("F / 6 / Queen") PORT_CODE(KEYCODE_F) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD)
162 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Right / White / 0") PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_CODE(KEYCODE_RIGHT)
163 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("MEM") PORT_CODE(KEYCODE_M)
164 
165 	PORT_START("IN.2")
166 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("C / 3 / Knight") PORT_CODE(KEYCODE_C) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD)
167 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("G / 7 / King") PORT_CODE(KEYCODE_G) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD)
168 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("INFO") PORT_CODE(KEYCODE_I)
169 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("CL") PORT_CODE(KEYCODE_BACKSPACE) PORT_CODE(KEYCODE_DEL)
170 
171 	PORT_START("IN.3")
172 	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("D / 4 / Bishop") PORT_CODE(KEYCODE_D) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD)
173 	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("H / 8") PORT_CODE(KEYCODE_H) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD)
174 	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("POS") PORT_CODE(KEYCODE_O)
175 	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("ENT") PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD)
176 INPUT_PORTS_END
177 
178 
179 
180 /******************************************************************************
181     Machine Configs
182 ******************************************************************************/
183 
184 void mondial68k_state::mondial68k(machine_config &config)
185 {
186 	/* basic machine hardware */
187 	M68000(config, m_maincpu, 12_MHz_XTAL);
188 	m_maincpu->set_addrmap(AS_PROGRAM, &mondial68k_state::mondial68k_mem);
189 	m_maincpu->set_periodic_int(FUNC(mondial68k_state::irq5_line_hold), attotime::from_hz(128));
190 
191 	hc259_device &outlatch(HC259(config, "outlatch"));
192 	outlatch.q_out_cb<0>().set(m_lcd, FUNC(pcf2112_device::clb_w));
193 	outlatch.q_out_cb<1>().set(m_lcd, FUNC(pcf2112_device::data_w));
194 	outlatch.q_out_cb<2>().set(m_lcd, FUNC(pcf2112_device::dlen_w));
195 	outlatch.q_out_cb<6>().set_nop(); // another DAC input?
196 	outlatch.q_out_cb<7>().set("dac", FUNC(dac_1bit_device::write));
197 
198 	SENSORBOARD(config, m_board).set_type(sensorboard_device::BUTTONS);
199 	m_board->init_cb().set(m_board, FUNC(sensorboard_device::preset_chess));
200 	m_board->set_delay(attotime::from_msec(100));
201 
202 	/* video hardware */
203 	PCF2112(config, m_lcd, 50); // frequency guessed
204 	m_lcd->write_segs().set(FUNC(mondial68k_state::lcd_s_w));
205 
206 	PWM_DISPLAY(config, m_display).set_size(2, 8);
207 	config.set_default_layout(layout_mephisto_mondial68k);
208 
209 	/* sound hardware */
210 	SPEAKER(config, "speaker").front_center();
211 	DAC_1BIT(config, "dac").add_route(ALL_OUTPUTS, "speaker", 0.25);
212 }
213 
214 
215 
216 /******************************************************************************
217     ROM Definitions
218 ******************************************************************************/
219 
220 ROM_START( mondl68k )
221 	ROM_REGION16_BE( 0x10000, "maincpu", 0 )
222 	ROM_LOAD16_BYTE("68000xl_u_06.11.87", 0x0000, 0x8000, CRC(aebe482a) SHA1(900c91ec836cd65e4cd38e50555976ab8064be41) )
223 	ROM_LOAD16_BYTE("68000xl_l_06.11.87", 0x0001, 0x8000, CRC(564e32c5) SHA1(8c9df46bc5ced114e72fb663f1055d775b8e2e0b) )
224 ROM_END
225 
226 } // anonymous namespace
227 
228 
229 
230 /***************************************************************************
231     Game Drivers
232 ***************************************************************************/
233 
234 /*    YEAR, NAME,      PARENT    COMPAT  MACHINE      INPUT       CLASS             INIT        COMPANY             FULLNAME                     FLAGS */
235 CONS( 1988, mondl68k,  0,        0,      mondial68k,  mondial68k, mondial68k_state, empty_init, "Hegener + Glaser", "Mephisto Mondial 68000XL",  MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
236