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