trunk/src/mame/machine/vectrex.c
| r20858 | r20859 | |
| 66 | 66 | |
| 67 | 67 | DEVICE_IMAGE_LOAD_MEMBER(vectrex_state,vectrex_cart) |
| 68 | 68 | { |
| 69 | | vectrex_state *state = image.device().machine().driver_data<vectrex_state>(); |
| 70 | | UINT8 *mem = state->memregion("maincpu")->base(); |
| 69 | UINT8 *mem = memregion("maincpu")->base(); |
| 71 | 70 | if (image.software_entry() == NULL) |
| 72 | 71 | { |
| 73 | 72 | image.fread( mem, 0x8000); |
| 74 | 73 | if (image.length() > 0x8000) |
| 75 | 74 | { |
| 76 | 75 | image.fread( mem+0x10000, 0x8000); |
| 77 | | state->m_64k_cart = 1; |
| 76 | m_64k_cart = 1; |
| 78 | 77 | } |
| 79 | 78 | } else { |
| 80 | 79 | int size = image.get_software_region_length("rom"); |
| r20858 | r20859 | |
| 89 | 88 | } |
| 90 | 89 | |
| 91 | 90 | if (memcmp(mem + 0x06,"SRAM",4)) { |
| 92 | | image.device().machine().device("maincpu")->memory().space(AS_PROGRAM).unmap_write(0x0000, 0x7fff); |
| 91 | m_maincpu->space(AS_PROGRAM).unmap_write(0x0000, 0x7fff); |
| 93 | 92 | } |
| 94 | 93 | |
| 95 | 94 | /* If VIA T2 starts, reset refresh timer. |
| 96 | 95 | This is the best strategy for most games. */ |
| 97 | | state->m_reset_refresh = 1; |
| 96 | m_reset_refresh = 1; |
| 98 | 97 | |
| 99 | | state->m_imager_angles = narrow_escape_angles; |
| 98 | m_imager_angles = narrow_escape_angles; |
| 100 | 99 | |
| 101 | 100 | /* let's do this 3D detection with a strcmp using data inside the cart images */ |
| 102 | 101 | /* slightly prettier than having to hardcode CRCs */ |
| r20858 | r20859 | |
| 104 | 103 | /* handle 3D Narrow Escape but skip the 2-d hack of it from Fred Taft */ |
| 105 | 104 | if (!memcmp(mem + 0x11,"NARROW",6) && (((char*)mem)[0x39] == 0x0c)) |
| 106 | 105 | { |
| 107 | | state->m_imager_angles = narrow_escape_angles; |
| 106 | m_imager_angles = narrow_escape_angles; |
| 108 | 107 | } |
| 109 | 108 | |
| 110 | 109 | if (!memcmp(mem + 0x11,"CRAZY COASTER", 13)) |
| 111 | 110 | { |
| 112 | | state->m_imager_angles = crazy_coaster_angles; |
| 111 | m_imager_angles = crazy_coaster_angles; |
| 113 | 112 | } |
| 114 | 113 | |
| 115 | 114 | if (!memcmp(mem + 0x11,"3D MINE STORM", 13)) |
| 116 | 115 | { |
| 117 | | state->m_imager_angles = minestorm_3d_angles; |
| 116 | m_imager_angles = minestorm_3d_angles; |
| 118 | 117 | |
| 119 | 118 | /* Don't reset T2 each time it's written. |
| 120 | 119 | This would cause jerking in mine3. */ |
| 121 | | state->m_reset_refresh = 0; |
| 120 | m_reset_refresh = 0; |
| 122 | 121 | } |
| 123 | 122 | |
| 124 | 123 | return IMAGE_INIT_PASS; |
| r20858 | r20859 | |
| 131 | 130 | |
| 132 | 131 | *********************************************************************/ |
| 133 | 132 | |
| 134 | | void vectrex_configuration(running_machine &machine) |
| 133 | void vectrex_state::vectrex_configuration() |
| 135 | 134 | { |
| 136 | | vectrex_state *state = machine.driver_data<vectrex_state>(); |
| 137 | | unsigned char cport = state->ioport("3DCONF")->read(); |
| 135 | unsigned char cport = m_io_3dconf->read(); |
| 138 | 136 | |
| 139 | 137 | /* Vectrex 'dipswitch' configuration */ |
| 140 | 138 | |
| 141 | 139 | /* Imager control */ |
| 142 | 140 | if (cport & 0x01) /* Imager enabled */ |
| 143 | 141 | { |
| 144 | | if (state->m_imager_status == 0) |
| 145 | | state->m_imager_status = cport & 0x01; |
| 142 | if (m_imager_status == 0) |
| 143 | m_imager_status = cport & 0x01; |
| 146 | 144 | |
| 147 | | state->vector_add_point_function = cport & 0x02 ? vectrex_add_point_stereo: vectrex_add_point; |
| 145 | vector_add_point_function = cport & 0x02 ? &vectrex_state::vectrex_add_point_stereo: &vectrex_state::vectrex_add_point; |
| 148 | 146 | |
| 149 | 147 | switch ((cport >> 2) & 0x07) |
| 150 | 148 | { |
| 151 | 149 | case 0x00: |
| 152 | | state->m_imager_colors[0] = state->m_imager_colors[1] = state->m_imager_colors[2] = RGB_BLACK; |
| 150 | m_imager_colors[0] = m_imager_colors[1] = m_imager_colors[2] = RGB_BLACK; |
| 153 | 151 | break; |
| 154 | 152 | case 0x01: |
| 155 | | state->m_imager_colors[0] = state->m_imager_colors[1] = state->m_imager_colors[2] = VC_DARKRED; |
| 153 | m_imager_colors[0] = m_imager_colors[1] = m_imager_colors[2] = VC_DARKRED; |
| 156 | 154 | break; |
| 157 | 155 | case 0x02: |
| 158 | | state->m_imager_colors[0] = state->m_imager_colors[1] = state->m_imager_colors[2] = VC_GREEN; |
| 156 | m_imager_colors[0] = m_imager_colors[1] = m_imager_colors[2] = VC_GREEN; |
| 159 | 157 | break; |
| 160 | 158 | case 0x03: |
| 161 | | state->m_imager_colors[0] = state->m_imager_colors[1] = state->m_imager_colors[2] = VC_BLUE; |
| 159 | m_imager_colors[0] = m_imager_colors[1] = m_imager_colors[2] = VC_BLUE; |
| 162 | 160 | break; |
| 163 | 161 | case 0x04: |
| 164 | 162 | /* mine3 has a different color sequence */ |
| 165 | | if (state->m_imager_angles == minestorm_3d_angles) |
| 163 | if (m_imager_angles == minestorm_3d_angles) |
| 166 | 164 | { |
| 167 | | state->m_imager_colors[0] = VC_GREEN; |
| 168 | | state->m_imager_colors[1] = VC_RED; |
| 165 | m_imager_colors[0] = VC_GREEN; |
| 166 | m_imager_colors[1] = VC_RED; |
| 169 | 167 | } |
| 170 | 168 | else |
| 171 | 169 | { |
| 172 | | state->m_imager_colors[0] = VC_RED; |
| 173 | | state->m_imager_colors[1] = VC_GREEN; |
| 170 | m_imager_colors[0] = VC_RED; |
| 171 | m_imager_colors[1] = VC_GREEN; |
| 174 | 172 | } |
| 175 | | state->m_imager_colors[2]=VC_BLUE; |
| 173 | m_imager_colors[2]=VC_BLUE; |
| 176 | 174 | break; |
| 177 | 175 | } |
| 178 | 176 | |
| 179 | 177 | switch ((cport >> 5) & 0x07) |
| 180 | 178 | { |
| 181 | 179 | case 0x00: |
| 182 | | state->m_imager_colors[3] = state->m_imager_colors[4] = state->m_imager_colors[5] = RGB_BLACK; |
| 180 | m_imager_colors[3] = m_imager_colors[4] = m_imager_colors[5] = RGB_BLACK; |
| 183 | 181 | break; |
| 184 | 182 | case 0x01: |
| 185 | | state->m_imager_colors[3] = state->m_imager_colors[4] = state->m_imager_colors[5] = VC_DARKRED; |
| 183 | m_imager_colors[3] = m_imager_colors[4] = m_imager_colors[5] = VC_DARKRED; |
| 186 | 184 | break; |
| 187 | 185 | case 0x02: |
| 188 | | state->m_imager_colors[3] = state->m_imager_colors[4] = state->m_imager_colors[5] = VC_GREEN; |
| 186 | m_imager_colors[3] = m_imager_colors[4] = m_imager_colors[5] = VC_GREEN; |
| 189 | 187 | break; |
| 190 | 188 | case 0x03: |
| 191 | | state->m_imager_colors[3] = state->m_imager_colors[4] = state->m_imager_colors[5] = VC_BLUE; |
| 189 | m_imager_colors[3] = m_imager_colors[4] = m_imager_colors[5] = VC_BLUE; |
| 192 | 190 | break; |
| 193 | 191 | case 0x04: |
| 194 | | if (state->m_imager_angles == minestorm_3d_angles) |
| 192 | if (m_imager_angles == minestorm_3d_angles) |
| 195 | 193 | { |
| 196 | | state->m_imager_colors[3] = VC_GREEN; |
| 197 | | state->m_imager_colors[4] = VC_RED; |
| 194 | m_imager_colors[3] = VC_GREEN; |
| 195 | m_imager_colors[4] = VC_RED; |
| 198 | 196 | } |
| 199 | 197 | else |
| 200 | 198 | { |
| 201 | | state->m_imager_colors[3] = VC_RED; |
| 202 | | state->m_imager_colors[4] = VC_GREEN; |
| 199 | m_imager_colors[3] = VC_RED; |
| 200 | m_imager_colors[4] = VC_GREEN; |
| 203 | 201 | } |
| 204 | | state->m_imager_colors[5]=VC_BLUE; |
| 202 | m_imager_colors[5]=VC_BLUE; |
| 205 | 203 | break; |
| 206 | 204 | } |
| 207 | 205 | } |
| 208 | 206 | else |
| 209 | 207 | { |
| 210 | | state->vector_add_point_function = vectrex_add_point; |
| 211 | | state->m_beam_color = RGB_WHITE; |
| 212 | | state->m_imager_colors[0] = state->m_imager_colors[1] = state->m_imager_colors[2] = state->m_imager_colors[3] = state->m_imager_colors[4] = state->m_imager_colors[5] = RGB_WHITE; |
| 208 | vector_add_point_function = &vectrex_state::vectrex_add_point; |
| 209 | m_beam_color = RGB_WHITE; |
| 210 | m_imager_colors[0] = m_imager_colors[1] = m_imager_colors[2] = m_imager_colors[3] = m_imager_colors[4] = m_imager_colors[5] = RGB_WHITE; |
| 213 | 211 | } |
| 214 | | state->m_lightpen_port = machine.root_device().ioport("LPENCONF")->read() & 0x03; |
| 212 | m_lightpen_port = m_io_lpenconf->read() & 0x03; |
| 215 | 213 | } |
| 216 | 214 | |
| 217 | 215 | |
| r20858 | r20859 | |
| 221 | 219 | |
| 222 | 220 | *********************************************************************/ |
| 223 | 221 | |
| 224 | | void vectrex_via_irq(device_t *device, int level) |
| 222 | WRITE_LINE_MEMBER(vectrex_state::vectrex_via_irq) |
| 225 | 223 | { |
| 226 | | device->machine().device("maincpu")->execute().set_input_line(M6809_IRQ_LINE, level); |
| 224 | m_maincpu->set_input_line(M6809_IRQ_LINE, state); |
| 227 | 225 | } |
| 228 | 226 | |
| 229 | 227 | |
| 230 | 228 | READ8_MEMBER(vectrex_state::vectrex_via_pb_r) |
| 231 | 229 | { |
| 232 | 230 | int pot; |
| 233 | | static const char *const ctrlnames[] = { "CONTR1X", "CONTR1Y", "CONTR2X", "CONTR2Y" }; |
| 231 | ioport_port *io_port[4] = { m_io_contr1x, m_io_contr1y, m_io_contr2x, m_io_contr2y }; |
| 234 | 232 | |
| 235 | | pot = machine().root_device().ioport(ctrlnames[(m_via_out[PORTB] & 0x6) >> 1])->read() - 0x80; |
| 233 | pot = io_port[(m_via_out[PORTB] & 0x6) >> 1]->read() - 0x80; |
| 236 | 234 | |
| 237 | 235 | if (pot > (signed char)m_via_out[PORTA]) |
| 238 | 236 | m_via_out[PORTB] |= 0x20; |
| r20858 | r20859 | |
| 248 | 246 | if ((!(m_via_out[PORTB] & 0x10)) && (m_via_out[PORTB] & 0x08)) |
| 249 | 247 | /* BDIR inactive, we can read the PSG. BC1 has to be active. */ |
| 250 | 248 | { |
| 251 | | device_t *ay = machine().device("ay8912"); |
| 252 | | |
| 253 | | m_via_out[PORTA] = ay8910_r(ay, space, 0) |
| 249 | m_via_out[PORTA] = ay8910_r(m_ay8912, space, 0) |
| 254 | 250 | & ~(m_imager_pinlevel & 0x80); |
| 255 | 251 | } |
| 256 | 252 | return m_via_out[PORTA]; |
| r20858 | r20859 | |
| 259 | 255 | |
| 260 | 256 | READ8_MEMBER(vectrex_state::vectrex_s1_via_pb_r) |
| 261 | 257 | { |
| 262 | | return (m_via_out[PORTB] & ~0x40) | (ioport("COIN")->read() & 0x40); |
| 258 | return (m_via_out[PORTB] & ~0x40) | (m_io_coin->read() & 0x40); |
| 263 | 259 | } |
| 264 | 260 | |
| 265 | 261 | |
| r20858 | r20859 | |
| 284 | 280 | |
| 285 | 281 | TIMER_CALLBACK_MEMBER(vectrex_state::vectrex_imager_eye) |
| 286 | 282 | { |
| 287 | | via6522_device *via_0 = machine().device<via6522_device>("via6522_0"); |
| 288 | 283 | int coffset; |
| 289 | 284 | double rtime = (1.0 / m_imager_freq); |
| 290 | 285 | |
| r20858 | r20859 | |
| 301 | 296 | machine().scheduler().timer_set (attotime::from_double(rtime * 0.50), timer_expired_delegate(FUNC(vectrex_state::vectrex_imager_eye),this), 1); |
| 302 | 297 | |
| 303 | 298 | /* Index hole sensor is connected to IO7 which triggers also CA1 of VIA */ |
| 304 | | via_0->write_ca1(1); |
| 305 | | via_0->write_ca1(0); |
| 299 | m_via6522_0->write_ca1(1); |
| 300 | m_via6522_0->write_ca1(0); |
| 306 | 301 | m_imager_pinlevel |= 0x80; |
| 307 | 302 | machine().scheduler().timer_set (attotime::from_double(rtime / 360.0), timer_expired_delegate(FUNC(vectrex_state::update_level),this), 0, &m_imager_pinlevel); |
| 308 | 303 | } |
trunk/src/mame/includes/vectrex.h
| r20858 | r20859 | |
| 8 | 8 | #define VECTREX_H_ |
| 9 | 9 | |
| 10 | 10 | #include "machine/6522via.h" |
| 11 | #include "sound/dac.h" |
| 11 | 12 | |
| 13 | |
| 12 | 14 | #define NVECT 10000 |
| 13 | 15 | |
| 14 | 16 | struct vectrex_point |
| r20858 | r20859 | |
| 22 | 24 | { |
| 23 | 25 | public: |
| 24 | 26 | vectrex_state(const machine_config &mconfig, device_type type, const char *tag) |
| 25 | | : driver_device(mconfig, type, tag) , |
| 26 | | m_gce_vectorram(*this, "gce_vectorram"){ } |
| 27 | : driver_device(mconfig, type, tag) |
| 28 | , m_gce_vectorram(*this, "gce_vectorram") |
| 29 | , m_maincpu(*this, "maincpu") |
| 30 | , m_via6522_0(*this, "via6522_0") |
| 31 | , m_dac(*this, "dac") |
| 32 | , m_ay8912(*this, "ay8912") |
| 33 | , m_io_contr1x(*this, "CONTR1X") |
| 34 | , m_io_contr1y(*this, "CONTR1Y") |
| 35 | , m_io_contr2x(*this, "CONTR2X") |
| 36 | , m_io_contr2y(*this, "CONTR2Y") |
| 37 | , m_io_buttons(*this, "BUTTONS") |
| 38 | , m_io_3dconf(*this, "3DCONF") |
| 39 | , m_io_lpenconf(*this, "LPENCONF") |
| 40 | , m_io_lpenx(*this, "LPENX") |
| 41 | , m_io_lpeny(*this, "LPENY") |
| 42 | , m_io_coin(*this, "COIN") |
| 43 | { } |
| 27 | 44 | |
| 28 | 45 | required_shared_ptr<UINT8> m_gce_vectorram; |
| 29 | 46 | int m_64k_cart; |
| r20858 | r20859 | |
| 61 | 78 | UINT16 m_via_timer2; |
| 62 | 79 | attotime m_vector_start_time; |
| 63 | 80 | UINT8 m_cb2; |
| 64 | | void (*vector_add_point_function) (running_machine &, int, int, rgb_t, int); |
| 81 | void (vectrex_state::*vector_add_point_function)(int, int, rgb_t, int); |
| 65 | 82 | DECLARE_WRITE8_MEMBER(vectrex_psg_port_w); |
| 66 | 83 | DECLARE_READ8_MEMBER(vectrex_via_r); |
| 67 | 84 | DECLARE_WRITE8_MEMBER(vectrex_via_w); |
| r20858 | r20859 | |
| 85 | 102 | DECLARE_WRITE8_MEMBER(v_via_ca2_w); |
| 86 | 103 | DECLARE_WRITE8_MEMBER(v_via_cb2_w); |
| 87 | 104 | DECLARE_DEVICE_IMAGE_LOAD_MEMBER( vectrex_cart ); |
| 88 | | }; |
| 105 | DECLARE_WRITE_LINE_MEMBER(vectrex_via_irq); |
| 89 | 106 | |
| 107 | protected: |
| 108 | required_device<cpu_device> m_maincpu; |
| 109 | required_device<via6522_device> m_via6522_0; |
| 110 | required_device<dac_device> m_dac; |
| 111 | required_device<device_t> m_ay8912; |
| 112 | optional_ioport m_io_contr1x; |
| 113 | optional_ioport m_io_contr1y; |
| 114 | optional_ioport m_io_contr2x; |
| 115 | optional_ioport m_io_contr2y; |
| 116 | required_ioport m_io_buttons; |
| 117 | required_ioport m_io_3dconf; |
| 118 | required_ioport m_io_lpenconf; |
| 119 | required_ioport m_io_lpenx; |
| 120 | required_ioport m_io_lpeny; |
| 121 | optional_ioport m_io_coin; |
| 90 | 122 | |
| 91 | | /*----------- defined in machine/vectrex.c -----------*/ |
| 123 | void vectrex_configuration(); |
| 124 | void vectrex_multiplexer(int mux); |
| 125 | void vectrex_add_point(int x, int y, rgb_t color, int intensity); |
| 126 | void vectrex_add_point_stereo(int x, int y, rgb_t color, int intensity); |
| 127 | }; |
| 92 | 128 | |
| 93 | | void vectrex_configuration(running_machine &machine); |
| 94 | | void vectrex_via_irq (device_t *device, int level); |
| 129 | /*---------- defined in video/vectrex.c -----------*/ |
| 95 | 130 | |
| 96 | | /*----------- defined in video/vectrex.c -----------*/ |
| 97 | | |
| 98 | 131 | extern const via6522_interface vectrex_via6522_interface; |
| 99 | 132 | extern const via6522_interface spectrum1_via6522_interface; |
| 100 | 133 | |
| 101 | | void vectrex_add_point_stereo (running_machine &machine, int x, int y, rgb_t color, int intensity); |
| 102 | | void vectrex_add_point (running_machine &machine, int x, int y, rgb_t color, int intensity); |
| 103 | | |
| 104 | 134 | #endif /* VECTREX_H_ */ |
trunk/src/mame/video/vectrex.c
| r20858 | r20859 | |
| 2 | 2 | #include "emu.h" |
| 3 | 3 | #include "includes/vectrex.h" |
| 4 | 4 | #include "video/vector.h" |
| 5 | | #include "machine/6522via.h" |
| 6 | 5 | #include "cpu/m6809/m6809.h" |
| 7 | 6 | #include "sound/ay8910.h" |
| 8 | | #include "sound/dac.h" |
| 9 | 7 | |
| 10 | 8 | |
| 11 | 9 | #define ANALOG_DELAY 7800 |
| r20858 | r20859 | |
| 47 | 45 | DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, /* read ca1, cb1, ca2, cb2 */ |
| 48 | 46 | DEVCB_DRIVER_MEMBER(vectrex_state,v_via_pa_w), DEVCB_DRIVER_MEMBER(vectrex_state,v_via_pb_w), /* write PA/B */ |
| 49 | 47 | DEVCB_NULL, DEVCB_NULL, DEVCB_DRIVER_MEMBER(vectrex_state,v_via_ca2_w), DEVCB_DRIVER_MEMBER(vectrex_state,v_via_cb2_w), /* write ca1, cb1, ca2, cb2 */ |
| 50 | | DEVCB_LINE(vectrex_via_irq), /* IRQ */ |
| 48 | DEVCB_DRIVER_LINE_MEMBER(vectrex_state,vectrex_via_irq), /* IRQ */ |
| 51 | 49 | }; |
| 52 | 50 | |
| 53 | 51 | |
| r20858 | r20859 | |
| 62 | 60 | { |
| 63 | 61 | if (m_lightpen_port & 1) |
| 64 | 62 | { |
| 65 | | via6522_device *via_0 = machine().device<via6522_device>("via6522_0"); |
| 66 | | via_0->write_ca1(1); |
| 67 | | via_0->write_ca1(0); |
| 63 | m_via6522_0->write_ca1(1); |
| 64 | m_via6522_0->write_ca1(0); |
| 68 | 65 | } |
| 69 | 66 | |
| 70 | 67 | if (m_lightpen_port & 2) |
| 71 | 68 | { |
| 72 | | machine().device("maincpu")->execute().set_input_line(M6809_FIRQ_LINE, PULSE_LINE); |
| 69 | m_maincpu->set_input_line(M6809_FIRQ_LINE, PULSE_LINE); |
| 73 | 70 | } |
| 74 | 71 | } |
| 75 | 72 | |
| r20858 | r20859 | |
| 95 | 92 | |
| 96 | 93 | READ8_MEMBER(vectrex_state::vectrex_via_r) |
| 97 | 94 | { |
| 98 | | via6522_device *via = machine().device<via6522_device>("via6522_0"); |
| 99 | | return via->read(space, offset); |
| 95 | return m_via6522_0->read(space, offset); |
| 100 | 96 | } |
| 101 | 97 | |
| 102 | 98 | WRITE8_MEMBER(vectrex_state::vectrex_via_w) |
| 103 | 99 | { |
| 104 | | via6522_device *via = machine().device<via6522_device>("via6522_0"); |
| 105 | 100 | attotime period; |
| 106 | 101 | |
| 107 | 102 | switch (offset) |
| r20858 | r20859 | |
| 113 | 108 | case 9: |
| 114 | 109 | m_via_timer2 = (m_via_timer2 & 0x00ff) | (data << 8); |
| 115 | 110 | |
| 116 | | period = (attotime::from_hz(machine().device("maincpu")->unscaled_clock()) * m_via_timer2); |
| 111 | period = (attotime::from_hz(m_maincpu->unscaled_clock()) * m_via_timer2); |
| 117 | 112 | |
| 118 | 113 | if (m_reset_refresh) |
| 119 | 114 | m_refresh->adjust(period, 0, period); |
| r20858 | r20859 | |
| 124 | 119 | period); |
| 125 | 120 | break; |
| 126 | 121 | } |
| 127 | | via->write(space, offset, data); |
| 122 | m_via6522_0->write(space, offset, data); |
| 128 | 123 | } |
| 129 | 124 | |
| 130 | 125 | |
| r20858 | r20859 | |
| 147 | 142 | { |
| 148 | 143 | int i; |
| 149 | 144 | |
| 150 | | vectrex_configuration(machine()); |
| 145 | vectrex_configuration(); |
| 151 | 146 | |
| 152 | 147 | /* start black */ |
| 153 | 148 | vector_add_point(machine(), |
| r20858 | r20859 | |
| 177 | 172 | |
| 178 | 173 | *********************************************************************/ |
| 179 | 174 | |
| 180 | | void vectrex_add_point(running_machine &machine, int x, int y, rgb_t color, int intensity) |
| 175 | void vectrex_state::vectrex_add_point(int x, int y, rgb_t color, int intensity) |
| 181 | 176 | { |
| 182 | | vectrex_state *state = machine.driver_data<vectrex_state>(); |
| 183 | 177 | vectrex_point *newpoint; |
| 184 | 178 | |
| 185 | | state->m_point_index = (state->m_point_index+1) % NVECT; |
| 186 | | newpoint = &state->m_points[state->m_point_index]; |
| 179 | m_point_index = (m_point_index+1) % NVECT; |
| 180 | newpoint = &m_points[m_point_index]; |
| 187 | 181 | |
| 188 | 182 | newpoint->x = x; |
| 189 | 183 | newpoint->y = y; |
| r20858 | r20859 | |
| 192 | 186 | } |
| 193 | 187 | |
| 194 | 188 | |
| 195 | | void vectrex_add_point_stereo(running_machine &machine, int x, int y, rgb_t color, int intensity) |
| 189 | void vectrex_state::vectrex_add_point_stereo(int x, int y, rgb_t color, int intensity) |
| 196 | 190 | { |
| 197 | | vectrex_state *state = machine.driver_data<vectrex_state>(); |
| 198 | | if (state->m_imager_status == 2) /* left = 1, right = 2 */ |
| 199 | | vectrex_add_point(machine, (int)(y * M_SQRT1_2)+ state->m_x_center, |
| 200 | | (int)(((state->m_x_max - x) * M_SQRT1_2)), |
| 191 | if (m_imager_status == 2) /* left = 1, right = 2 */ |
| 192 | vectrex_add_point((int)(y * M_SQRT1_2)+ m_x_center, |
| 193 | (int)(((m_x_max - x) * M_SQRT1_2)), |
| 201 | 194 | color, |
| 202 | 195 | intensity); |
| 203 | 196 | else |
| 204 | | vectrex_add_point(machine, (int)(y * M_SQRT1_2), |
| 205 | | (int)((state->m_x_max - x) * M_SQRT1_2), |
| 197 | vectrex_add_point((int)(y * M_SQRT1_2), |
| 198 | (int)((m_x_max - x) * M_SQRT1_2), |
| 206 | 199 | color, |
| 207 | 200 | intensity); |
| 208 | 201 | } |
| r20858 | r20859 | |
| 212 | 205 | { |
| 213 | 206 | m_x_int = m_x_center + (m_analog[A_ZR] * INT_PER_CLOCK); |
| 214 | 207 | m_y_int = m_y_center + (m_analog[A_ZR] * INT_PER_CLOCK); |
| 215 | | (*vector_add_point_function)(machine(), m_x_int, m_y_int, m_beam_color, 0); |
| 208 | (this->*vector_add_point_function)(m_x_int, m_y_int, m_beam_color, 0); |
| 216 | 209 | } |
| 217 | 210 | |
| 218 | 211 | |
| r20858 | r20859 | |
| 232 | 225 | |
| 233 | 226 | if (!m_ramp) |
| 234 | 227 | { |
| 235 | | length = machine().device("maincpu")->unscaled_clock() * INT_PER_CLOCK |
| 228 | length = m_maincpu->unscaled_clock() * INT_PER_CLOCK |
| 236 | 229 | * (machine().time() - m_vector_start_time).as_double(); |
| 237 | 230 | |
| 238 | 231 | m_x_int += length * (m_analog[A_X] + m_analog[A_ZR]); |
| 239 | 232 | m_y_int += length * (m_analog[A_Y] + m_analog[A_ZR]); |
| 240 | 233 | |
| 241 | | (*vector_add_point_function)(machine(), m_x_int, m_y_int, m_beam_color, 2 * m_analog[A_Z] * m_blank); |
| 234 | (this->*vector_add_point_function)(m_x_int, m_y_int, m_beam_color, 2 * m_analog[A_Z] * m_blank); |
| 242 | 235 | } |
| 243 | 236 | else |
| 244 | 237 | { |
| 245 | 238 | if (m_blank) |
| 246 | | (*vector_add_point_function)(machine(), m_x_int, m_y_int, m_beam_color, 2 * m_analog[A_Z]); |
| 239 | (this->*vector_add_point_function)(m_x_int, m_y_int, m_beam_color, 2 * m_analog[A_Z]); |
| 247 | 240 | } |
| 248 | 241 | |
| 249 | 242 | m_vector_start_time = machine().time(); |
| r20858 | r20859 | |
| 271 | 264 | |
| 272 | 265 | m_imager_freq = 1; |
| 273 | 266 | |
| 274 | | vector_add_point_function = vectrex_add_point; |
| 267 | vector_add_point_function = &vectrex_state::vectrex_add_point; |
| 275 | 268 | m_imager_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(vectrex_state::vectrex_imager_eye),this)); |
| 276 | 269 | m_imager_timer->adjust( |
| 277 | 270 | attotime::from_hz(m_imager_freq), |
| r20858 | r20859 | |
| 292 | 285 | |
| 293 | 286 | *********************************************************************/ |
| 294 | 287 | |
| 295 | | static void vectrex_multiplexer(running_machine &machine, int mux) |
| 288 | void vectrex_state::vectrex_multiplexer(int mux) |
| 296 | 289 | { |
| 297 | | vectrex_state *state = machine.driver_data<vectrex_state>(); |
| 298 | | dac_device *dac = machine.device<dac_device>("dac"); |
| 290 | machine().scheduler().timer_set(attotime::from_nsec(ANALOG_DELAY), timer_expired_delegate(FUNC(vectrex_state::update_signal),this), m_via_out[PORTA], &m_analog[mux]); |
| 299 | 291 | |
| 300 | | machine.scheduler().timer_set(attotime::from_nsec(ANALOG_DELAY), timer_expired_delegate(FUNC(vectrex_state::update_signal),state), state->m_via_out[PORTA], &state->m_analog[mux]); |
| 301 | | |
| 302 | 292 | if (mux == A_AUDIO) |
| 303 | | dac->write_unsigned8(state->m_via_out[PORTA]); |
| 293 | m_dac->write_unsigned8(m_via_out[PORTA]); |
| 304 | 294 | } |
| 305 | 295 | |
| 306 | 296 | |
| r20858 | r20859 | |
| 344 | 334 | +(double)(m_pen_y - m_y_int) * (m_pen_y - m_y_int); |
| 345 | 335 | d2 = b2 - ab * ab / a2; |
| 346 | 336 | if (d2 < 2e10 && m_analog[A_Z] * m_blank > 0) |
| 347 | | m_lp_t->adjust(attotime::from_double(ab / a2 / (machine().device("maincpu")->unscaled_clock() * INT_PER_CLOCK))); |
| 337 | m_lp_t->adjust(attotime::from_double(ab / a2 / (m_maincpu->unscaled_clock() * INT_PER_CLOCK))); |
| 348 | 338 | } |
| 349 | 339 | } |
| 350 | 340 | } |
| r20858 | r20859 | |
| 386 | 376 | } |
| 387 | 377 | |
| 388 | 378 | if (!(data & 0x1) && (m_via_out[PORTB] & 0x1)) |
| 389 | | vectrex_multiplexer (machine(), (data >> 1) & 0x3); |
| 379 | vectrex_multiplexer((data >> 1) & 0x3); |
| 390 | 380 | |
| 391 | 381 | m_via_out[PORTB] = data; |
| 392 | 382 | machine().scheduler().timer_set(attotime::from_nsec(ANALOG_DELAY), timer_expired_delegate(FUNC(vectrex_state::update_signal),this), data & 0x80, &m_ramp); |
| r20858 | r20859 | |
| 400 | 390 | machine().scheduler().timer_set(attotime::from_nsec(ANALOG_DELAY), timer_expired_delegate(FUNC(vectrex_state::update_signal),this), data, &m_analog[A_Y]); |
| 401 | 391 | |
| 402 | 392 | if (!(m_via_out[PORTB] & 0x1)) |
| 403 | | vectrex_multiplexer (machine(), (m_via_out[PORTB] >> 1) & 0x3); |
| 393 | vectrex_multiplexer((m_via_out[PORTB] >> 1) & 0x3); |
| 404 | 394 | } |
| 405 | 395 | |
| 406 | 396 | |
| r20858 | r20859 | |
| 450 | 440 | { |
| 451 | 441 | /*inputs : A/B,CA/B1,CA/B2 */ DEVCB_DRIVER_MEMBER(vectrex_state,vectrex_via_pa_r), DEVCB_DRIVER_MEMBER(vectrex_state,vectrex_s1_via_pb_r), DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, |
| 452 | 442 | /*outputs: A/B,CA/B1,CA/B2 */ DEVCB_DRIVER_MEMBER(vectrex_state,v_via_pa_w), DEVCB_DRIVER_MEMBER(vectrex_state,v_via_pb_w), DEVCB_NULL, DEVCB_NULL, DEVCB_DRIVER_MEMBER(vectrex_state,v_via_ca2_w), DEVCB_DRIVER_MEMBER(vectrex_state,v_via_cb2_w), |
| 453 | | /*irq */ DEVCB_LINE(vectrex_via_irq), |
| 443 | /*irq */ DEVCB_DRIVER_LINE_MEMBER(vectrex_state,vectrex_via_irq), |
| 454 | 444 | }; |
| 455 | 445 | |
| 456 | 446 | |
| r20858 | r20859 | |
| 472 | 462 | m_x_max = visarea.max_x << 16; |
| 473 | 463 | m_y_max = visarea.max_y << 16; |
| 474 | 464 | |
| 475 | | vector_add_point_function = vectrex_add_point; |
| 465 | vector_add_point_function = &vectrex_state::vectrex_add_point; |
| 476 | 466 | m_refresh = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(vectrex_state::vectrex_refresh),this)); |
| 477 | 467 | |
| 478 | 468 | VIDEO_START_CALL_LEGACY(vector); |