1 // license:BSD-3-Clause
2 // copyright-holders:Mathis Rosenhauer
3 /*****************************************************************
4 
5 GCE Vectrex
6 
7 Mathis Rosenhauer
8 Christopher Salomon (technical advice)
9 Bruce Tomlin (hardware info)
10 
11 *****************************************************************/
12 
13 #include "emu.h"
14 #include "includes/vectrex.h"
15 
16 #include "cpu/m6809/m6809.h"
17 #include "machine/6522via.h"
18 #include "machine/nvram.h"
19 #include "sound/ay8910.h"
20 #include "video/vector.h"
21 
22 #include "softlist.h"
23 #include "speaker.h"
24 
25 
vectrex_map(address_map & map)26 void vectrex_state::vectrex_map(address_map &map)
27 {
28 	map(0x0000, 0x7fff).noprw(); // cart area, handled at machine_start
29 	map(0xc800, 0xcbff).ram().mirror(0x0400).share("gce_vectorram");
30 	map(0xd000, 0xd7ff).rw(FUNC(vectrex_state::vectrex_via_r), FUNC(vectrex_state::vectrex_via_w));
31 	map(0xe000, 0xffff).rom().region("maincpu", 0);
32 }
33 
34 static INPUT_PORTS_START(vectrex)
35 	PORT_START("CONTR1X")
36 	PORT_BIT(0xff, 0x80, IPT_AD_STICK_X) PORT_MINMAX(0,0xff) PORT_SENSITIVITY(50) PORT_KEYDELTA(30)
37 
38 	PORT_START("CONTR1Y")
39 	PORT_BIT(0xff, 0x80, IPT_AD_STICK_Y) PORT_MINMAX(0,0xff) PORT_SENSITIVITY(50) PORT_KEYDELTA(30) PORT_REVERSE
40 
41 	PORT_START("CONTR2X")
42 	PORT_BIT(0xff, 0x80, IPT_AD_STICK_X) PORT_MINMAX(0,0xff) PORT_SENSITIVITY(50) PORT_KEYDELTA(30) PORT_PLAYER(2)
43 
44 	PORT_START("CONTR2Y")
45 	PORT_BIT(0xff, 0x80, IPT_AD_STICK_Y) PORT_MINMAX(0,0xff) PORT_SENSITIVITY(50) PORT_KEYDELTA(30) PORT_REVERSE PORT_PLAYER(2)
46 
47 	PORT_START("BUTTONS")
48 	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(1)
49 	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_PLAYER(1)
50 	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_PLAYER(1)
51 	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_BUTTON4) PORT_PLAYER(1)
52 	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(2)
53 	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_PLAYER(2)
54 	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_PLAYER(2)
55 	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_BUTTON4) PORT_PLAYER(2)
56 
57 	PORT_START("3DCONF")
58 	PORT_CONFNAME(0x01, 0x00, "3D Imager")
DEF_STR(Off)59 	PORT_CONFSETTING(0x00, DEF_STR(Off))
60 	PORT_CONFSETTING(0x01, DEF_STR(On))
61 	PORT_CONFNAME(0x02, 0x00, "Separate images")
62 	PORT_CONFSETTING(0x00, DEF_STR(No))
63 	PORT_CONFSETTING(0x02, DEF_STR(Yes))
64 	PORT_CONFNAME(0x1c, 0x10, "Left eye")
65 	PORT_CONFSETTING(0x00, "Black")
66 	PORT_CONFSETTING(0x04, "Red")
67 	PORT_CONFSETTING(0x08, "Green")
68 	PORT_CONFSETTING(0x0c, "Blue")
69 	PORT_CONFSETTING(0x10, "Color")
70 	PORT_CONFNAME(0xe0, 0x80, "Right eye")
71 	PORT_CONFSETTING(0x00, "Black")
72 	PORT_CONFSETTING(0x20, "Red")
73 	PORT_CONFSETTING(0x40, "Green")
74 	PORT_CONFSETTING(0x60, "Blue")
75 	PORT_CONFSETTING(0x80, "Color")
76 
77 	PORT_START("LPENCONF")
78 	PORT_CONFNAME(0x03, 0x00, "Lightpen")
79 	PORT_CONFSETTING(0x00, DEF_STR(Off))
80 	PORT_CONFSETTING(0x01, "left port")
81 	PORT_CONFSETTING(0x02, "right port")
82 	PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_BUTTON5) PORT_CODE(MOUSECODE_BUTTON1)
83 
84 	PORT_START("LPENY")
85 	PORT_BIT(0xff, 0x80, IPT_LIGHTGUN_X)  PORT_CROSSHAIR(Y, 1, 0, 0) PORT_MINMAX(0,0xff) PORT_SENSITIVITY(35) PORT_KEYDELTA(1) PORT_PLAYER(1)
86 
87 	PORT_START("LPENX")
88 	PORT_BIT(0xff, 0x80, IPT_LIGHTGUN_Y)  PORT_CROSSHAIR(X, 1, 0, 0) PORT_MINMAX(0,0xff) PORT_SENSITIVITY(35) PORT_KEYDELTA(1) PORT_REVERSE PORT_PLAYER(1)
89 
90 INPUT_PORTS_END
91 
92 void vectrex_base_state::vectrex_cart(device_slot_interface &device)
93 {
94 	device.option_add_internal("vec_rom",    VECTREX_ROM_STD);
95 	device.option_add_internal("vec_rom64k", VECTREX_ROM_64K);
96 	device.option_add_internal("vec_sram",   VECTREX_ROM_SRAM);
97 }
98 
vectrex_base(machine_config & config)99 void vectrex_base_state::vectrex_base(machine_config &config)
100 {
101 	MC6809(config, m_maincpu, 6_MHz_XTAL); // 68A09
102 
103 	/* video hardware */
104 	VECTOR(config, m_vector, 0);
105 	SCREEN(config, m_screen, SCREEN_TYPE_VECTOR);
106 	m_screen->set_refresh_hz(60);
107 	m_screen->set_size(400, 300);
108 	m_screen->set_visarea(0, 399, 0, 299);
109 	m_screen->set_screen_update(FUNC(vectrex_base_state::screen_update_vectrex));
110 
111 	/* sound hardware */
112 	SPEAKER(config, "speaker").front_center();
113 	MC1408(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.25); // mc1408.ic301 (also used for vector generation)
114 
115 	AY8912(config, m_ay8912, 6_MHz_XTAL / 4);
116 	m_ay8912->port_a_read_callback().set_ioport("BUTTONS");
117 	m_ay8912->port_a_write_callback().set(FUNC(vectrex_base_state::vectrex_psg_port_w));
118 	m_ay8912->add_route(ALL_OUTPUTS, "speaker", 0.2);
119 
120 	/* via */
121 	VIA6522(config, m_via6522_0, 6_MHz_XTAL / 4);
122 	m_via6522_0->readpa_handler().set(FUNC(vectrex_base_state::vectrex_via_pa_r));
123 	m_via6522_0->readpb_handler().set(FUNC(vectrex_base_state::vectrex_via_pb_r));
124 	m_via6522_0->writepa_handler().set(FUNC(vectrex_base_state::v_via_pa_w));
125 	m_via6522_0->writepb_handler().set(FUNC(vectrex_base_state::v_via_pb_w));
126 	m_via6522_0->ca2_handler().set(FUNC(vectrex_base_state::v_via_ca2_w));
127 	m_via6522_0->cb2_handler().set(FUNC(vectrex_base_state::v_via_cb2_w));
128 	m_via6522_0->irq_handler().set(FUNC(vectrex_base_state::vectrex_via_irq));
129 }
130 
vectrex(machine_config & config)131 void vectrex_state::vectrex(machine_config &config)
132 {
133 	vectrex_base(config);
134 
135 	m_maincpu->set_addrmap(AS_PROGRAM, &vectrex_state::vectrex_map);
136 
137 	vectrex_cart_slot_device &slot(VECTREX_CART_SLOT(config, "cartslot", 0));
138 	vectrex_cart(slot);
139 
140 	/* software lists */
141 	SOFTWARE_LIST(config, "cart_list").set_original("vectrex");
142 }
143 
144 ROM_START(vectrex)
145 	ROM_REGION(0x2000,"maincpu", 0)
146 	ROM_SYSTEM_BIOS(0, "bios0", "exec rom")
CRC(ba13fb57)147 	ROMX_LOAD("exec_rom.bin", 0x0000, 0x2000, CRC(ba13fb57) SHA1(65d07426b520ddd3115d40f255511e0fd2e20ae7), ROM_BIOS(0) )
148 	ROM_SYSTEM_BIOS(1, "bios1", "exec rom intl 284001-1")
149 	ROMX_LOAD("exec_rom_intl_284001-1.bin", 0x0000, 0x2000, CRC(6d2bd167) SHA1(77a220d5d98846b606dff608f7b5d00183ec3bab), ROM_BIOS(1) )
150 
151 //  The following fastboots are listed here for reference and documentation
152 //  ROM_SYSTEM_BIOS(2, "bios2", "us-fastboot hack")
153 //  ROMX_LOAD("us-fastboot.bin", 0x0000, 0x2000, CRa6e4dac4) SHA1(e0900be6d6858b985fd7f0999d864b2fceaf01a1), ROM_BIOS(2) )
154 //  ROM_SYSTEM_BIOS(3, "bios3", "intl-fastboot hack")
155 //  ROMX_LOAD("intl-fastboot.bin", 0x0000, 0x2000, CRC(71dcf0f4) SHA1(2a257c5111f5cee841bd14acaa9df6496aaf3d8b), ROM_BIOS(3) )
156 
157 ROM_END
158 
159 
160 /*****************************************************************
161 
162   RA+A Spectrum I+
163 
164   The Spectrum I+ was a modified Vectrex. It had a 32K ROM cart
165   and 2K additional battery backed RAM (0x8000 - 0x87ff). PB6
166   was used to signal inserted coins to the VIA. The unit was
167   controlled by 8 buttons (2x4 buttons of controller 1 and 2).
168   Each button had a LED which were mapped to 0xa000.
169   The srvice mode can be accessed by pressing button
170   8 during startup. As soon as all LEDs light up,
171   press 2 and 3 without releasing 8. Then release 8 and
172   after that 2 and 3. You can leave the screen where you enter
173   ads by pressing 8 several times.
174 
175   Character matrix is:
176 
177   btn| 1  2  3  4  5  6  7  8
178   ---+------------------------
179   1  | 0  1  2  3  4  5  6  7
180   2  | 8  9  A  B  C  D  E  F
181   3  | G  H  I  J  K  L  M  N
182   4  | O  P  Q  R  S  T  U  V
183   5  | W  X  Y  Z  sp !  "  #
184   6  | $  %  &  '  (  )  *  +
185   7  | ,  -  _  /  :  ;  ?  =
186   8  |bs ret up dn l  r hom esc
187 
188   The first page of ads is shown with the "result" of the
189   test. Remaining pages are shown in attract mode. If no extra
190   ram is present, the word COLOR is scrolled in big vector!
191   letters in attract mode.
192 
193 *****************************************************************/
194 
195 void raaspec_state::raaspec_map(address_map &map)
196 {
197 	map(0x0000, 0x7fff).rom();
198 	map(0x8000, 0x87ff).ram().share("nvram");
199 	map(0xa000, 0xa000).w(FUNC(raaspec_state::raaspec_led_w));
200 	map(0xc800, 0xcbff).ram().mirror(0x0400).share("gce_vectorram");
201 	map(0xd000, 0xd7ff).rw(FUNC(raaspec_state::vectrex_via_r), FUNC(raaspec_state::vectrex_via_w));
202 	map(0xe000, 0xffff).rom();
203 }
204 
205 static INPUT_PORTS_START(raaspec)
206 	PORT_START("LPENCONF")
207 	PORT_START("LPENY")
208 	PORT_START("LPENX")
209 	PORT_START("3DCONF")
210 	PORT_START("BUTTONS")
211 	PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1)
212 	PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON2)
213 	PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON3)
214 	PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_BUTTON4)
215 	PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON5)
216 	PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON6)
217 	PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_BUTTON7)
218 	PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_BUTTON8)
219 	PORT_START("COIN")
220 	PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_COIN1)
221 INPUT_PORTS_END
222 
223 
raaspec(machine_config & config)224 void raaspec_state::raaspec(machine_config &config)
225 {
226 	vectrex_base(config);
227 
228 	m_maincpu->set_addrmap(AS_PROGRAM, &raaspec_state::raaspec_map);
229 
230 	NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
231 
232 	m_via6522_0->readpb_handler().set(FUNC(raaspec_state::vectrex_s1_via_pb_r));
233 }
234 
235 ROM_START(raaspec)
236 	ROM_REGION(0x10000,"maincpu", 0)
237 	ROM_LOAD("spectrum.bin", 0x0000, 0x8000, CRC(20af7f3f) SHA1(7ce85db8dd32687ad7629631ae113820371faf7c))
238 	ROM_LOAD("exec_rom.bin", 0xe000, 0x2000, CRC(ba13fb57) SHA1(65d07426b520ddd3115d40f255511e0fd2e20ae7))
239 ROM_END
240 
241 /***************************************************************************
242 
243   Game driver(s)
244 
245 ***************************************************************************/
246 
247 //   YEAR  NAME       PARENT    COMPAT   MACHINE   INPUT     STATE          INIT        MONITOR  COMPANY                         FULLNAME
248 CONS( 1982, vectrex,  0,        0,       vectrex,  vectrex,  vectrex_state, empty_init,          "General Consumer Electronics", "Vectrex" , ROT270)
249 
250 GAME( 1984, raaspec,  0,                 raaspec,  raaspec,  raaspec_state, empty_init, ROT270,  "Roy Abel & Associates",        "Spectrum I+", MACHINE_NOT_WORKING ) //TODO: button labels & timings, a mandatory artwork too?
251