trunk/src/mess/drivers/odyssey2.c
| r20214 | r20215 | |
| 47 | 47 | AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE(p2_read, p2_write) |
| 48 | 48 | AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_READWRITE(bus_read, bus_write) |
| 49 | 49 | AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_READ(t0_read) |
| 50 | | AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(t1_read_g7400) |
| 50 | AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(t1_read) |
| 51 | 51 | AM_RANGE(MCS48_PORT_PROG, MCS48_PORT_PROG) AM_DEVWRITE("i8243", i8243_device, i8243_prog_w); |
| 52 | 52 | ADDRESS_MAP_END |
| 53 | 53 | |
| r20214 | r20215 | |
| 137 | 137 | } |
| 138 | 138 | |
| 139 | 139 | |
| 140 | | WRITE8_MEMBER(odyssey2_state::lum_write) |
| 141 | | { |
| 142 | | m_lum = ( data & 0x01 ) << 3; |
| 143 | | } |
| 144 | | |
| 145 | | |
| 146 | 140 | WRITE16_MEMBER(odyssey2_state::scanline_postprocess) |
| 147 | 141 | { |
| 148 | 142 | int vpos = data; |
| r20214 | r20215 | |
| 156 | 150 | } |
| 157 | 151 | |
| 158 | 152 | |
| 159 | | READ8_MEMBER(odyssey2_state::t1_read_g7400) |
| 153 | READ8_MEMBER(odyssey2_state::t1_read) |
| 160 | 154 | { |
| 161 | 155 | if ( m_i8244->vblank() || m_i8244->hblank() ) |
| 162 | 156 | { |
| r20214 | r20215 | |
| 166 | 160 | } |
| 167 | 161 | |
| 168 | 162 | |
| 163 | READ8_MEMBER(odyssey2_state::p1_read) |
| 164 | { |
| 165 | UINT8 data = m_p1; |
| 166 | |
| 167 | logerror("%.9f p1 read %.2x\n", machine().time().as_double(), data); |
| 168 | return data; |
| 169 | } |
| 170 | |
| 171 | |
| 172 | WRITE8_MEMBER(odyssey2_state::p1_write) |
| 173 | { |
| 174 | m_p1 = data; |
| 175 | m_lum = ( data & 0x80 ) >> 4; |
| 176 | |
| 177 | switch_banks(); |
| 178 | |
| 179 | logerror("%.6f p1 written %.2x\n", machine().time().as_double(), data); |
| 180 | } |
| 181 | |
| 182 | |
| 183 | READ8_MEMBER(odyssey2_state::p2_read) |
| 184 | { |
| 185 | UINT8 h = 0xFF; |
| 186 | int i, j; |
| 187 | static const char *const keynames[] = { "KEY0", "KEY1", "KEY2", "KEY3", "KEY4", "KEY5" }; |
| 188 | |
| 189 | if (!(m_p1 & P1_KEYBOARD_SCAN_ENABLE)) |
| 190 | { |
| 191 | if ((m_p2 & P2_KEYBOARD_SELECT_MASK) <= 5) /* read keyboard */ |
| 192 | { |
| 193 | h &= ioport(keynames[m_p2 & P2_KEYBOARD_SELECT_MASK])->read(); |
| 194 | } |
| 195 | |
| 196 | for (i= 0x80, j = 0; i > 0; i >>= 1, j++) |
| 197 | { |
| 198 | if (!(h & i)) |
| 199 | { |
| 200 | m_p2 &= ~0x10; /* set key was pressed indicator */ |
| 201 | m_p2 = (m_p2 & ~0xE0) | (j << 5); /* column that was pressed */ |
| 202 | |
| 203 | break; |
| 204 | } |
| 205 | } |
| 206 | |
| 207 | if (h == 0xFF) /* active low inputs, so no keypresses */ |
| 208 | { |
| 209 | m_p2 = m_p2 | 0xF0; |
| 210 | } |
| 211 | } |
| 212 | else |
| 213 | { |
| 214 | m_p2 = m_p2 | 0xF0; |
| 215 | } |
| 216 | |
| 217 | logerror("%.6f p2 read %.2x\n", machine().time().as_double(), m_p2); |
| 218 | return m_p2; |
| 219 | } |
| 220 | |
| 221 | |
| 222 | WRITE8_MEMBER(odyssey2_state::p2_write) |
| 223 | { |
| 224 | m_p2 = data; |
| 225 | |
| 226 | if ( m_i8243 ) |
| 227 | { |
| 228 | m_i8243->i8243_p2_w( space, 0, m_p2 & 0x0f ); |
| 229 | } |
| 230 | |
| 231 | logerror("%.6f p2 written %.2x\n", machine().time().as_double(), data); |
| 232 | } |
| 233 | |
| 234 | |
| 235 | READ8_MEMBER(odyssey2_state::bus_read) |
| 236 | { |
| 237 | UINT8 data = 0xff; |
| 238 | |
| 239 | if ((m_p2 & P2_KEYBOARD_SELECT_MASK) == 1) |
| 240 | { |
| 241 | data &= ioport("JOY0")->read(); /* read joystick 1 */ |
| 242 | } |
| 243 | |
| 244 | if ((m_p2 & P2_KEYBOARD_SELECT_MASK) == 0) |
| 245 | { |
| 246 | data &= ioport("JOY1")->read(); /* read joystick 2 */ |
| 247 | } |
| 248 | |
| 249 | logerror("%.6f bus read %.2x\n", machine().time().as_double(), data); |
| 250 | return data; |
| 251 | } |
| 252 | |
| 253 | |
| 254 | WRITE8_MEMBER(odyssey2_state::bus_write) |
| 255 | { |
| 256 | logerror("%.6f bus written %.2x\n", machine().time().as_double(), data); |
| 257 | } |
| 258 | |
| 259 | |
| 260 | /* |
| 261 | i8243 in the g7400 |
| 262 | */ |
| 263 | |
| 264 | WRITE8_MEMBER(odyssey2_state::i8243_port_w) |
| 265 | { |
| 266 | switch ( offset & 3 ) |
| 267 | { |
| 268 | case 0: // "port 4" |
| 269 | m_g7400_ic674_decode[4] = BIT(data,0); |
| 270 | m_g7400_ic674_decode[5] = BIT(data,1); |
| 271 | m_g7400_ic674_decode[6] = BIT(data,2); |
| 272 | m_g7400_ic674_decode[7] = BIT(data,3); |
| 273 | break; |
| 274 | |
| 275 | case 1: // "port 5" |
| 276 | m_g7400_ic674_decode[0] = BIT(data,0); |
| 277 | m_g7400_ic674_decode[1] = BIT(data,1); |
| 278 | m_g7400_ic674_decode[2] = BIT(data,2); |
| 279 | m_g7400_ic674_decode[3] = BIT(data,3); |
| 280 | break; |
| 281 | |
| 282 | case 2: // "port 6" |
| 283 | m_g7400_ic678_decode[4] = BIT(data,0); |
| 284 | m_g7400_ic678_decode[5] = BIT(data,1); |
| 285 | m_g7400_ic678_decode[6] = BIT(data,2); |
| 286 | m_g7400_ic678_decode[7] = BIT(data,3); |
| 287 | break; |
| 288 | |
| 289 | case 3: // "port 7" |
| 290 | m_g7400_ic678_decode[0] = BIT(data,0); |
| 291 | m_g7400_ic678_decode[1] = BIT(data,1); |
| 292 | m_g7400_ic678_decode[2] = BIT(data,2); |
| 293 | m_g7400_ic678_decode[3] = BIT(data,3); |
| 294 | break; |
| 295 | |
| 296 | } |
| 297 | } |
| 298 | |
| 299 | |
| 169 | 300 | static const gfx_layout odyssey2_graphicslayout = |
| 170 | 301 | { |
| 171 | 302 | 8,1, |
| r20214 | r20215 | |
| 234 | 365 | |
| 235 | 366 | /* video hardware */ |
| 236 | 367 | MCFG_SCREEN_ADD("screen", RASTER) |
| 237 | | MCFG_SCREEN_RAW_PARAMS( XTAL_7_15909MHz/2, I824X_LINE_CLOCKS, I824X_START_ACTIVE_SCAN, I824X_END_ACTIVE_SCAN, 262, I824X_START_Y, I824X_START_Y + I824X_SCREEN_HEIGHT ) |
| 368 | MCFG_SCREEN_RAW_PARAMS( XTAL_7_15909MHz/2, i8244_device::LINE_CLOCKS, i8244_device::START_ACTIVE_SCAN, i8244_device::END_ACTIVE_SCAN, i8244_device::LINES, i8244_device::START_Y, i8244_device::START_Y + i8244_device::SCREEN_HEIGHT ) |
| 238 | 369 | MCFG_SCREEN_UPDATE_DRIVER(odyssey2_state, screen_update_odyssey2) |
| 239 | 370 | |
| 240 | 371 | MCFG_GFXDECODE( odyssey2 ) |
| r20214 | r20215 | |
| 242 | 373 | |
| 243 | 374 | /* sound hardware */ |
| 244 | 375 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 245 | | MCFG_SOUND_ADD("custom", ODYSSEY2, XTAL_7_15909MHz/2) |
| 376 | MCFG_I8244_ADD( "i8244", XTAL_17_73447MHz/5, "screen", WRITELINE( odyssey2_state, irq_callback ), WRITE16( odyssey2_state, scanline_postprocess ) ) |
| 246 | 377 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.40) |
| 247 | 378 | |
| 248 | 379 | MCFG_SOUND_ADD("sp0256_speech", SP0256, 3120000) |
| r20214 | r20215 | |
| 263 | 394 | |
| 264 | 395 | /* video hardware */ |
| 265 | 396 | MCFG_SCREEN_ADD("screen", RASTER) |
| 266 | | MCFG_SCREEN_RAW_PARAMS( XTAL_17_73447MHz/5, I824X_LINE_CLOCKS, I824X_START_ACTIVE_SCAN, I824X_END_ACTIVE_SCAN, 312, I824X_START_Y, I824X_START_Y + I824X_SCREEN_HEIGHT ) |
| 397 | MCFG_SCREEN_RAW_PARAMS( XTAL_17_73447MHz/5, i8244_device::LINE_CLOCKS, i8244_device::START_ACTIVE_SCAN, i8244_device::END_ACTIVE_SCAN, i8245_device::LINES, i8244_device::START_Y, i8244_device::START_Y + i8244_device::SCREEN_HEIGHT ) |
| 267 | 398 | MCFG_SCREEN_UPDATE_DRIVER(odyssey2_state, screen_update_odyssey2) |
| 268 | 399 | |
| 269 | 400 | MCFG_GFXDECODE( odyssey2 ) |
| r20214 | r20215 | |
| 271 | 402 | |
| 272 | 403 | /* sound hardware */ |
| 273 | 404 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 274 | | MCFG_SOUND_ADD("custom", ODYSSEY2, XTAL_17_73447MHz/5) |
| 405 | MCFG_I8245_ADD( "i8244", XTAL_17_73447MHz/5, "screen", WRITELINE( odyssey2_state, irq_callback ), WRITE16( odyssey2_state, scanline_postprocess ) ) |
| 275 | 406 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.40) |
| 276 | 407 | |
| 277 | 408 | MCFG_SOUND_ADD("sp0256_speech", SP0256, 3120000) |
| r20214 | r20215 | |
| 302 | 433 | MCFG_I8243_ADD( "i8243", NOOP, WRITE8(odyssey2_state,i8243_port_w)) |
| 303 | 434 | |
| 304 | 435 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 305 | | MCFG_I8244_ADD( "i8244", 3540000, "screen", WRITELINE( odyssey2_state, irq_callback ), WRITE16( odyssey2_state, scanline_postprocess ) ) |
| 436 | MCFG_I8245_ADD( "i8244", 3540000, "screen", WRITELINE( odyssey2_state, irq_callback ), WRITE16( odyssey2_state, scanline_postprocess ) ) |
| 306 | 437 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.40) |
| 307 | 438 | |
| 308 | 439 | MCFG_FRAGMENT_ADD(odyssey2_cartslot) |
trunk/src/mess/video/odyssey2.c
| r20214 | r20215 | |
| 74 | 74 | 0xFF, 0xFF, 0xFF |
| 75 | 75 | }; |
| 76 | 76 | |
| 77 | | static const UINT8 o2_shape[0x40][8]={ |
| 78 | | { 0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00 }, // 0 |
| 79 | | { 0x18,0x38,0x18,0x18,0x18,0x18,0x3C,0x00 }, |
| 80 | | { 0x3C,0x66,0x0C,0x18,0x30,0x60,0x7E,0x00 }, |
| 81 | | { 0x7C,0xC6,0x06,0x3C,0x06,0xC6,0x7C,0x00 }, |
| 82 | | { 0xCC,0xCC,0xCC,0xFE,0x0C,0x0C,0x0C,0x00 }, |
| 83 | | { 0xFE,0xC0,0xC0,0x7C,0x06,0xC6,0x7C,0x00 }, |
| 84 | | { 0x7C,0xC6,0xC0,0xFC,0xC6,0xC6,0x7C,0x00 }, |
| 85 | | { 0xFE,0x06,0x0C,0x18,0x30,0x60,0xC0,0x00 }, |
| 86 | | { 0x7C,0xC6,0xC6,0x7C,0xC6,0xC6,0x7C,0x00 }, |
| 87 | | { 0x7C,0xC6,0xC6,0x7E,0x06,0xC6,0x7C,0x00 }, |
| 88 | | { 0x00,0x18,0x18,0x00,0x18,0x18,0x00,0x00 }, |
| 89 | | { 0x18,0x7E,0x58,0x7E,0x1A,0x7E,0x18,0x00 }, |
| 90 | | { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, |
| 91 | | { 0x3C,0x66,0x0C,0x18,0x18,0x00,0x18,0x00 }, |
| 92 | | { 0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFE,0x00 }, |
| 93 | | { 0xFC,0xC6,0xC6,0xFC,0xC0,0xC0,0xC0,0x00 }, |
| 94 | | { 0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00 }, |
| 95 | | { 0xC6,0xC6,0xC6,0xD6,0xFE,0xEE,0xC6,0x00 }, |
| 96 | | { 0xFE,0xC0,0xC0,0xF8,0xC0,0xC0,0xFE,0x00 }, |
| 97 | | { 0xFC,0xC6,0xC6,0xFC,0xD8,0xCC,0xC6,0x00 }, |
| 98 | | { 0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x00 }, |
| 99 | | { 0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00 }, |
| 100 | | { 0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00 }, |
| 101 | | { 0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00 }, |
| 102 | | { 0x7C,0xC6,0xC6,0xC6,0xDE,0xCC,0x76,0x00 }, |
| 103 | | { 0x7C,0xC6,0xC0,0x7C,0x06,0xC6,0x7C,0x00 }, |
| 104 | | { 0xFC,0xC6,0xC6,0xC6,0xC6,0xC6,0xFC,0x00 }, |
| 105 | | { 0xFE,0xC0,0xC0,0xF8,0xC0,0xC0,0xC0,0x00 }, |
| 106 | | { 0x7C,0xC6,0xC0,0xC0,0xCE,0xC6,0x7E,0x00 }, |
| 107 | | { 0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00 }, |
| 108 | | { 0x06,0x06,0x06,0x06,0x06,0xC6,0x7C,0x00 }, |
| 109 | | { 0xC6,0xCC,0xD8,0xF0,0xD8,0xCC,0xC6,0x00 }, |
| 110 | | { 0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0x00 }, |
| 111 | | { 0x7E,0x06,0x0C,0x18,0x30,0x60,0x7E,0x00 }, |
| 112 | | { 0xC6,0xC6,0x6C,0x38,0x6C,0xC6,0xC6,0x00 }, |
| 113 | | { 0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x00 }, |
| 114 | | { 0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x00 }, |
| 115 | | { 0xFC,0xC6,0xC6,0xFC,0xC6,0xC6,0xFC,0x00 }, |
| 116 | | { 0xC6,0xEE,0xFE,0xD6,0xC6,0xC6,0xC6,0x00 }, |
| 117 | | { 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00 }, |
| 118 | | { 0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00 }, |
| 119 | | { 0x00,0x66,0x3C,0x18,0x3C,0x66,0x00,0x00 }, |
| 120 | | { 0x00,0x18,0x00,0x7E,0x00,0x18,0x00,0x00 }, |
| 121 | | { 0x00,0x00,0x7E,0x00,0x7E,0x00,0x00,0x00 }, |
| 122 | | { 0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x00 }, |
| 123 | | { 0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0x00 }, |
| 124 | | { 0x03,0x06,0x0C,0x18,0x30,0x60,0xC0,0x00 }, |
| 125 | | { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00 }, |
| 126 | | { 0xCE,0xDB,0xDB,0xDB,0xDB,0xDB,0xCE,0x00 }, |
| 127 | | { 0x00,0x00,0x3C,0x7E,0x7E,0x7E,0x3C,0x00 }, |
| 128 | | { 0x1C,0x1C,0x18,0x1E,0x18,0x18,0x1C,0x00 }, |
| 129 | | { 0x1C,0x1C,0x18,0x1E,0x18,0x34,0x26,0x00 }, |
| 130 | | { 0x38,0x38,0x18,0x78,0x18,0x2C,0x64,0x00 }, |
| 131 | | { 0x38,0x38,0x18,0x78,0x18,0x18,0x38,0x00 }, |
| 132 | | { 0x00,0x18,0x0C,0xFE,0x0C,0x18,0x00,0x00 }, |
| 133 | | { 0x18,0x3C,0x7E,0xFF,0xFF,0x18,0x18,0x00 }, |
| 134 | | { 0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF,0x00 }, |
| 135 | | { 0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF,0x00 }, |
| 136 | | { 0x38,0x38,0x12,0xFE,0xB8,0x28,0x6C,0x00 }, |
| 137 | | { 0xC0,0x60,0x30,0x18,0x0C,0x06,0x03,0x00 }, |
| 138 | | { 0x00,0x00,0x0C,0x08,0x08,0x7F,0x3E,0x00 }, |
| 139 | | { 0x00,0x03,0x63,0xFF,0xFF,0x18,0x08,0x00 }, |
| 140 | | { 0x00,0x00,0x00,0x10,0x38,0xFF,0x7E,0x00 } |
| 141 | | }; |
| 142 | 77 | |
| 143 | | |
| 144 | 78 | void odyssey2_state::palette_init() |
| 145 | 79 | { |
| 146 | 80 | int i; |
| r20214 | r20215 | |
| 152 | 86 | } |
| 153 | 87 | |
| 154 | 88 | |
| 155 | | READ8_MEMBER(odyssey2_state::video_read) |
| 156 | | { |
| 157 | | UINT8 data = 0; |
| 158 | | |
| 159 | | switch (offset) |
| 160 | | { |
| 161 | | case 0xa1: |
| 162 | | data = m_control_status; |
| 163 | | m_iff = 0; |
| 164 | | m_maincpu->set_input_line(0, CLEAR_LINE); |
| 165 | | m_control_status &= ~ 0x08; |
| 166 | | if ( m_screen->hpos() < I824X_START_ACTIVE_SCAN || m_screen->hpos() > I824X_END_ACTIVE_SCAN ) |
| 167 | | { |
| 168 | | data |= 1; |
| 169 | | } |
| 170 | | break; |
| 171 | | |
| 172 | | case 0xa2: |
| 173 | | data = m_collision_status; |
| 174 | | m_collision_status = 0; |
| 175 | | break; |
| 176 | | |
| 177 | | case 0xa4: |
| 178 | | if (m_o2_vdc.s.control & OLD_VDC_CONTROL_REG_STROBE_XY) |
| 179 | | { |
| 180 | | m_y_beam_pos = m_screen->vpos() - m_start_vpos; |
| 181 | | } |
| 182 | | |
| 183 | | data = m_y_beam_pos; |
| 184 | | |
| 185 | | break; |
| 186 | | |
| 187 | | |
| 188 | | case 0xa5: |
| 189 | | |
| 190 | | if ((m_o2_vdc.s.control & OLD_VDC_CONTROL_REG_STROBE_XY)) |
| 191 | | { |
| 192 | | m_x_beam_pos = m_screen->hpos(); |
| 193 | | if ( m_x_beam_pos < I824X_START_ACTIVE_SCAN ) |
| 194 | | { |
| 195 | | m_x_beam_pos = m_x_beam_pos - I824X_START_ACTIVE_SCAN + I824X_LINE_CLOCKS; |
| 196 | | } |
| 197 | | else |
| 198 | | { |
| 199 | | m_x_beam_pos = m_x_beam_pos - I824X_START_ACTIVE_SCAN; |
| 200 | | } |
| 201 | | } |
| 202 | | |
| 203 | | data = m_x_beam_pos; |
| 204 | | |
| 205 | | break; |
| 206 | | |
| 207 | | default: |
| 208 | | data = m_o2_vdc.reg[offset]; |
| 209 | | } |
| 210 | | |
| 211 | | return data; |
| 212 | | } |
| 213 | | |
| 214 | | |
| 215 | | WRITE8_MEMBER(odyssey2_state::video_write) |
| 216 | | { |
| 217 | | /* Update the sound */ |
| 218 | | if( offset >= 0xa7 && offset <= 0xaa ) |
| 219 | | m_sh_channel->update(); |
| 220 | | |
| 221 | | if (offset == 0xa0) { |
| 222 | | if ( m_o2_vdc.s.control & OLD_VDC_CONTROL_REG_STROBE_XY |
| 223 | | && !(data & OLD_VDC_CONTROL_REG_STROBE_XY)) |
| 224 | | { |
| 225 | | /* Toggling strobe bit, tuck away values */ |
| 226 | | m_x_beam_pos = m_screen->hpos(); |
| 227 | | if ( m_x_beam_pos < I824X_START_ACTIVE_SCAN ) |
| 228 | | { |
| 229 | | m_x_beam_pos = m_x_beam_pos - I824X_START_ACTIVE_SCAN + 228; |
| 230 | | } |
| 231 | | else |
| 232 | | { |
| 233 | | m_x_beam_pos = m_x_beam_pos - I824X_START_ACTIVE_SCAN; |
| 234 | | } |
| 235 | | |
| 236 | | m_y_beam_pos = m_screen->vpos() - m_start_vpos; |
| 237 | | } |
| 238 | | } |
| 239 | | |
| 240 | | m_o2_vdc.reg[offset] = data; |
| 241 | | } |
| 242 | | |
| 243 | | |
| 244 | | READ8_MEMBER(odyssey2_state::t1_read) |
| 245 | | { |
| 246 | | if ( m_screen->vpos() > m_start_vpos && m_screen->vpos() < m_start_vblank ) |
| 247 | | { |
| 248 | | if ( m_screen->hpos() >= I824X_START_ACTIVE_SCAN && m_screen->hpos() < I824X_END_ACTIVE_SCAN ) |
| 249 | | { |
| 250 | | return 1; |
| 251 | | } |
| 252 | | } |
| 253 | | return 0; |
| 254 | | } |
| 255 | | |
| 256 | | |
| 257 | | void odyssey2_state::i824x_scanline(int vpos) |
| 258 | | { |
| 259 | | UINT8 collision_map[160]; |
| 260 | | |
| 261 | | if ( vpos < m_start_vpos ) |
| 262 | | return; |
| 263 | | |
| 264 | | if ( vpos == m_start_vpos ) |
| 265 | | { |
| 266 | | m_control_status &= ~0x08; |
| 267 | | } |
| 268 | | |
| 269 | | if ( vpos < m_start_vblank ) |
| 270 | | { |
| 271 | | rectangle rect; |
| 272 | | //static const int sprite_width[4] = { 8, 8, 8, 8 }; |
| 273 | | int i; |
| 274 | | |
| 275 | | m_control_status &= ~ 0x01; |
| 276 | | |
| 277 | | /* Draw a line */ |
| 278 | | rect.set(I824X_START_ACTIVE_SCAN, I824X_END_ACTIVE_SCAN - 1, vpos, vpos); |
| 279 | | m_tmp_bitmap.fill(( (m_o2_vdc.s.color >> 3) & 0x7 ) | ( ( m_lum << 3 ) ^ 0x08 ), rect ); |
| 280 | | |
| 281 | | /* Clear collision map */ |
| 282 | | memset( collision_map, 0, sizeof( collision_map ) ); |
| 283 | | |
| 284 | | /* Display grid if enabled */ |
| 285 | | if ( m_o2_vdc.s.control & 0x08 ) |
| 286 | | { |
| 287 | | UINT16 color = ( m_o2_vdc.s.color & 7 ) | ( ( m_o2_vdc.s.color >> 3 ) & 0x08 ) | ( ( m_lum << 3 ) ^ 0x08 ); |
| 288 | | int x_grid_offset = 8; |
| 289 | | int y_grid_offset = 24; |
| 290 | | int width = 16; |
| 291 | | int height = 24; |
| 292 | | int w = ( m_o2_vdc.s.control & 0x80 ) ? width : 2; |
| 293 | | int j, k, y; |
| 294 | | |
| 295 | | /* Draw horizontal part of grid */ |
| 296 | | for ( j = 1, y = 0; y < 9; y++, j <<= 1 ) |
| 297 | | { |
| 298 | | if ( y_grid_offset + y * height <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y_grid_offset + y * height + 3 ) |
| 299 | | { |
| 300 | | for ( i = 0; i < 9; i++ ) |
| 301 | | { |
| 302 | | if ( ( m_o2_vdc.s.hgrid[0][i] & j ) || ( m_o2_vdc.s.hgrid[1][i] & ( j >> 8 ) ) ) |
| 303 | | { |
| 304 | | for ( k = 0; k < width + 2; k++ ) |
| 305 | | { |
| 306 | | int px = x_grid_offset + i * width + k; |
| 307 | | collision_map[ px ] |= COLLISION_HORIZ_GRID_DOTS; |
| 308 | | m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + px ) = color; |
| 309 | | } |
| 310 | | } |
| 311 | | } |
| 312 | | } |
| 313 | | } |
| 314 | | |
| 315 | | /* Draw vertical part of grid */ |
| 316 | | for( j = 1, y = 0; y < 8; y++, j <<= 1 ) |
| 317 | | { |
| 318 | | if ( y_grid_offset + y * height <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y_grid_offset + ( y + 1 ) * height ) |
| 319 | | { |
| 320 | | for ( i = 0; i < 10; i++ ) |
| 321 | | { |
| 322 | | if ( m_o2_vdc.s.vgrid[i] & j ) |
| 323 | | { |
| 324 | | for ( k = 0; k < w; k++ ) |
| 325 | | { |
| 326 | | int px = x_grid_offset + i * width + k; |
| 327 | | |
| 328 | | /* Check if we collide with an already drawn source object */ |
| 329 | | if ( collision_map[ px ] & m_o2_vdc.s.collision ) |
| 330 | | { |
| 331 | | m_collision_status |= COLLISION_VERTICAL_GRID; |
| 332 | | } |
| 333 | | /* Check if an already drawn object would collide with us */ |
| 334 | | if ( COLLISION_VERTICAL_GRID & m_o2_vdc.s.collision && collision_map[ px ] ) |
| 335 | | { |
| 336 | | m_collision_status |= collision_map[ px ]; |
| 337 | | } |
| 338 | | collision_map[ px ] |= COLLISION_VERTICAL_GRID; |
| 339 | | m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + px ) = color; |
| 340 | | } |
| 341 | | } |
| 342 | | } |
| 343 | | } |
| 344 | | } |
| 345 | | } |
| 346 | | |
| 347 | | /* Display objects if enabled */ |
| 348 | | if ( m_o2_vdc.s.control & 0x20 ) |
| 349 | | { |
| 350 | | /* Regular foreground objects */ |
| 351 | | for ( i = 0; i < ARRAY_LENGTH( m_o2_vdc.s.foreground ); i++ ) |
| 352 | | { |
| 353 | | int y = m_o2_vdc.s.foreground[i].y; |
| 354 | | int height = 8 - ( ( ( y >> 1 ) + m_o2_vdc.s.foreground[i].ptr ) & 7 ); |
| 355 | | |
| 356 | | if ( y <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y + height * 2 ) |
| 357 | | { |
| 358 | | UINT16 color = 16 + ( ( m_o2_vdc.s.foreground[i].color & 0x0E ) >> 1 ); |
| 359 | | int offset = ( m_o2_vdc.s.foreground[i].ptr | ( ( m_o2_vdc.s.foreground[i].color & 0x01 ) << 8 ) ) + ( y >> 1 ) + ( ( vpos - m_start_vpos - y ) >> 1 ); |
| 360 | | UINT8 chr = ((char*)o2_shape)[ offset & 0x1FF ]; |
| 361 | | int x = m_o2_vdc.s.foreground[i].x; |
| 362 | | UINT8 m; |
| 363 | | |
| 364 | | for ( m = 0x80; m > 0; m >>= 1, x++ ) |
| 365 | | { |
| 366 | | if ( chr & m ) |
| 367 | | { |
| 368 | | if ( x >= 0 && x < 160 ) |
| 369 | | { |
| 370 | | /* Check if we collide with an already drawn source object */ |
| 371 | | if ( collision_map[ x ] & m_o2_vdc.s.collision ) |
| 372 | | { |
| 373 | | m_collision_status |= COLLISION_CHARACTERS; |
| 374 | | } |
| 375 | | /* Check if an already drawn object would collide with us */ |
| 376 | | if ( COLLISION_CHARACTERS & m_o2_vdc.s.collision && collision_map[ x ] ) |
| 377 | | { |
| 378 | | m_collision_status |= collision_map[ x ]; |
| 379 | | } |
| 380 | | collision_map[ x ] |= COLLISION_CHARACTERS; |
| 381 | | m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + x ) = color; |
| 382 | | } |
| 383 | | } |
| 384 | | } |
| 385 | | } |
| 386 | | } |
| 387 | | |
| 388 | | /* Quad objects */ |
| 389 | | for ( i = 0; i < ARRAY_LENGTH( m_o2_vdc.s.quad ); i++ ) |
| 390 | | { |
| 391 | | int y = m_o2_vdc.s.quad[i].single[0].y; |
| 392 | | int height = 8; |
| 393 | | |
| 394 | | if ( y <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y + height * 2 ) |
| 395 | | { |
| 396 | | int x = m_o2_vdc.s.quad[i].single[0].x; |
| 397 | | int j; |
| 398 | | |
| 399 | | // Charaecter height is always determined by the height of the 4th character |
| 400 | | int char_height = 8 - ( ( ( y >> 1 ) + m_o2_vdc.s.quad[i].single[3].ptr ) & 7 ); |
| 401 | | |
| 402 | | for ( j = 0; j < ARRAY_LENGTH( m_o2_vdc.s.quad[0].single ); j++, x += 8 ) |
| 403 | | { |
| 404 | | if ( y <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y + char_height * 2 ) |
| 405 | | { |
| 406 | | UINT16 color = 16 + ( ( m_o2_vdc.s.quad[i].single[j].color & 0x0E ) >> 1 ); |
| 407 | | |
| 408 | | |
| 409 | | int offset = ( m_o2_vdc.s.quad[i].single[j].ptr | ( ( m_o2_vdc.s.quad[i].single[j].color & 0x01 ) << 8 ) ) + ( y >> 1 ) + ( ( vpos - m_start_vpos - y ) >> 1 ); |
| 410 | | |
| 411 | | UINT8 chr = ((char*)o2_shape)[ offset & 0x1FF ]; |
| 412 | | |
| 413 | | UINT8 m; |
| 414 | | for ( m = 0x80; m > 0; m >>= 1, x++ ) |
| 415 | | { |
| 416 | | if ( chr & m ) |
| 417 | | { |
| 418 | | if ( x >= 0 && x < 160 ) |
| 419 | | { |
| 420 | | /* Check if we collide with an already drawn source object */ |
| 421 | | if ( collision_map[ x ] & m_o2_vdc.s.collision ) |
| 422 | | { |
| 423 | | m_collision_status |= COLLISION_CHARACTERS; |
| 424 | | } |
| 425 | | /* Check if an already drawn object would collide with us */ |
| 426 | | if ( COLLISION_CHARACTERS & m_o2_vdc.s.collision && collision_map[ x ] ) |
| 427 | | { |
| 428 | | m_collision_status |= collision_map[ x ]; |
| 429 | | } |
| 430 | | collision_map[ x ] |= COLLISION_CHARACTERS; |
| 431 | | m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + x ) = color; |
| 432 | | } |
| 433 | | } |
| 434 | | } |
| 435 | | } |
| 436 | | else |
| 437 | | { |
| 438 | | x += 8; |
| 439 | | } |
| 440 | | } |
| 441 | | } |
| 442 | | } |
| 443 | | |
| 444 | | /* Sprites */ |
| 445 | | for ( i = 0; i < ARRAY_LENGTH( m_o2_vdc.s.sprites ); i++ ) |
| 446 | | { |
| 447 | | int y = m_o2_vdc.s.sprites[i].y; |
| 448 | | int height = 8; |
| 449 | | if ( m_o2_vdc.s.sprites[i].color & 4 ) |
| 450 | | { |
| 451 | | /* Zoomed sprite */ |
| 452 | | //sprite_width[i] = 16; |
| 453 | | if ( y <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y + height * 4 ) |
| 454 | | { |
| 455 | | UINT16 color = 16 + ( ( m_o2_vdc.s.sprites[i].color >> 3 ) & 0x07 ); |
| 456 | | UINT8 chr = m_o2_vdc.s.shape[i][ ( ( vpos - m_start_vpos - y ) >> 2 ) ]; |
| 457 | | int x = m_o2_vdc.s.sprites[i].x; |
| 458 | | UINT8 m; |
| 459 | | |
| 460 | | for ( m = 0x01; m > 0; m <<= 1, x += 2 ) |
| 461 | | { |
| 462 | | if ( chr & m ) |
| 463 | | { |
| 464 | | if ( x >= 0 && x < 160 ) |
| 465 | | { |
| 466 | | /* Check if we collide with an already drawn source object */ |
| 467 | | if ( collision_map[ x ] & m_o2_vdc.s.collision ) |
| 468 | | { |
| 469 | | m_collision_status |= ( 1 << i ); |
| 470 | | } |
| 471 | | /* Check if an already drawn object would collide with us */ |
| 472 | | if ( ( 1 << i ) & m_o2_vdc.s.collision && collision_map[ x ] ) |
| 473 | | { |
| 474 | | m_collision_status |= collision_map[ x ]; |
| 475 | | } |
| 476 | | collision_map[ x ] |= ( 1 << i ); |
| 477 | | m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + x ) = color; |
| 478 | | } |
| 479 | | if ( x >= -1 && x < 159 ) |
| 480 | | { |
| 481 | | /* Check if we collide with an already drawn source object */ |
| 482 | | if ( collision_map[ x ] & m_o2_vdc.s.collision ) |
| 483 | | { |
| 484 | | m_collision_status |= ( 1 << i ); |
| 485 | | } |
| 486 | | /* Check if an already drawn object would collide with us */ |
| 487 | | if ( ( 1 << i ) & m_o2_vdc.s.collision && collision_map[ x ] ) |
| 488 | | { |
| 489 | | m_collision_status |= collision_map[ x ]; |
| 490 | | } |
| 491 | | collision_map[ x ] |= ( 1 << i ); |
| 492 | | m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + x + 1 ) = color; |
| 493 | | } |
| 494 | | } |
| 495 | | } |
| 496 | | } |
| 497 | | } |
| 498 | | else |
| 499 | | { |
| 500 | | /* Regular sprite */ |
| 501 | | if ( y <= ( vpos - m_start_vpos ) && ( vpos - m_start_vpos ) < y + height * 2 ) |
| 502 | | { |
| 503 | | UINT16 color = 16 + ( ( m_o2_vdc.s.sprites[i].color >> 3 ) & 0x07 ); |
| 504 | | UINT8 chr = m_o2_vdc.s.shape[i][ ( ( vpos - m_start_vpos - y ) >> 1 ) ]; |
| 505 | | int x = m_o2_vdc.s.sprites[i].x; |
| 506 | | UINT8 m; |
| 507 | | |
| 508 | | for ( m = 0x01; m > 0; m <<= 1, x++ ) |
| 509 | | { |
| 510 | | if ( chr & m ) |
| 511 | | { |
| 512 | | if ( x >= 0 && x < 160 ) |
| 513 | | { |
| 514 | | /* Check if we collide with an already drawn source object */ |
| 515 | | if ( collision_map[ x ] & m_o2_vdc.s.collision ) |
| 516 | | { |
| 517 | | m_collision_status |= ( 1 << i ); |
| 518 | | } |
| 519 | | /* Check if an already drawn object would collide with us */ |
| 520 | | if ( ( 1 << i ) & m_o2_vdc.s.collision && collision_map[ x ] ) |
| 521 | | { |
| 522 | | m_collision_status |= collision_map[ x ]; |
| 523 | | } |
| 524 | | collision_map[ x ] |= ( 1 << i ); |
| 525 | | m_tmp_bitmap.pix16(vpos, I824X_START_ACTIVE_SCAN + x ) = color; |
| 526 | | } |
| 527 | | } |
| 528 | | } |
| 529 | | } |
| 530 | | } |
| 531 | | } |
| 532 | | } |
| 533 | | } |
| 534 | | |
| 535 | | /* Check for start of VBlank */ |
| 536 | | if ( vpos == m_start_vblank ) |
| 537 | | { |
| 538 | | m_control_status |= 0x08; |
| 539 | | if ( ! m_iff ) |
| 540 | | { |
| 541 | | m_maincpu->set_input_line(0, ASSERT_LINE); |
| 542 | | m_iff = 1; |
| 543 | | } |
| 544 | | } |
| 545 | | } |
| 546 | | |
| 547 | | |
| 548 | 89 | void odyssey2_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) |
| 549 | 90 | { |
| 550 | 91 | int vpos = m_screen->vpos(); |
| r20214 | r20215 | |
| 552 | 93 | switch ( id ) |
| 553 | 94 | { |
| 554 | 95 | case TIMER_LINE: |
| 555 | | // handle i824x line timer |
| 556 | | i824x_scanline(vpos); |
| 557 | 96 | if ( m_g7400 ) |
| 558 | 97 | { |
| 559 | 98 | ef9340_scanline(vpos); |
| r20214 | r20215 | |
| 561 | 100 | break; |
| 562 | 101 | |
| 563 | 102 | case TIMER_HBLANK: |
| 564 | | // handle i824x HBlank timer |
| 565 | | if ( vpos < m_start_vpos - 1 ) |
| 566 | | { |
| 567 | | return; |
| 568 | | } |
| 569 | | |
| 570 | | if ( vpos < m_start_vblank - 1 ) |
| 571 | | { |
| 572 | | m_control_status |= 0x01; |
| 573 | | } |
| 574 | 103 | break; |
| 575 | 104 | } |
| 576 | 105 | } |
| r20214 | r20215 | |
| 584 | 113 | |
| 585 | 114 | void odyssey2_state::video_start() |
| 586 | 115 | { |
| 587 | | memset(m_o2_vdc.reg, 0, 0x100); |
| 588 | | |
| 589 | | m_o2_snd_shift[0] = m_o2_snd_shift[1] = 0; |
| 590 | | m_x_beam_pos = 0; |
| 591 | | m_y_beam_pos = 0; |
| 592 | | m_control_status = 0; |
| 593 | | m_collision_status = 0; |
| 594 | | m_iff = 0; |
| 595 | | m_start_vpos = 0; |
| 596 | | m_start_vblank = 0; |
| 597 | | m_lum = 0; |
| 598 | | |
| 599 | | m_o2_snd_shift[0] = machine().sample_rate() / 983; |
| 600 | | m_o2_snd_shift[1] = machine().sample_rate() / 3933; |
| 601 | | |
| 602 | 116 | m_start_vpos = I824X_START_Y; |
| 603 | 117 | m_start_vblank = I824X_START_Y + I824X_SCREEN_HEIGHT; |
| 604 | | m_control_status = 0; |
| 605 | | m_iff = 0; |
| 606 | 118 | |
| 607 | 119 | m_screen->register_screen_bitmap(m_tmp_bitmap); |
| 608 | 120 | |
| r20214 | r20215 | |
| 639 | 151 | |
| 640 | 152 | UINT32 odyssey2_state::screen_update_odyssey2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) |
| 641 | 153 | { |
| 642 | | copybitmap( bitmap, m_tmp_bitmap, 0, 0, 0, 0, cliprect ); |
| 643 | | |
| 644 | | if ( m_i8244 ) |
| 645 | | { |
| 646 | | return m_i8244->screen_update(screen, bitmap, cliprect); |
| 647 | | } |
| 648 | | return 0; |
| 154 | return m_i8244->screen_update(screen, bitmap, cliprect); |
| 649 | 155 | } |
| 650 | 156 | |
| 651 | | static DEVICE_START( odyssey2_sound ) |
| 652 | | { |
| 653 | | odyssey2_state *state = device->machine().driver_data<odyssey2_state>(); |
| 654 | | state->m_sh_channel = device->machine().sound().stream_alloc(*device, 0, 1, device->clock()/(I824X_LINE_CLOCKS*4), 0, odyssey2_sh_update ); |
| 655 | | } |
| 656 | 157 | |
| 657 | | |
| 658 | | STREAM_UPDATE( odyssey2_sh_update ) |
| 659 | | { |
| 660 | | odyssey2_state *state = device->machine().driver_data<odyssey2_state>(); |
| 661 | | UINT32 old_signal, signal; |
| 662 | | int ii; |
| 663 | | int period; |
| 664 | | stream_sample_t *buffer = outputs[0]; |
| 665 | | |
| 666 | | /* Generate the signal */ |
| 667 | | old_signal = signal = state->m_o2_vdc.s.shift3 | (state->m_o2_vdc.s.shift2 << 8) | (state->m_o2_vdc.s.shift1 << 16); |
| 668 | | |
| 669 | | if( state->m_o2_vdc.s.sound & 0x80 ) /* Sound is enabled */ |
| 670 | | { |
| 671 | | for( ii = 0; ii < samples; ii++, buffer++ ) |
| 672 | | { |
| 673 | | *buffer = 0; |
| 674 | | *buffer = signal & 0x1; |
| 675 | | period = (state->m_o2_vdc.s.sound & 0x20) ? 1 : 4; |
| 676 | | if( ++state->m_sh_count >= period ) |
| 677 | | { |
| 678 | | state->m_sh_count = 0; |
| 679 | | signal >>= 1; |
| 680 | | /* Loop sound */ |
| 681 | | signal |= *buffer << 23; |
| 682 | | /* Check if noise should be applied */ |
| 683 | | if ( state->m_o2_vdc.s.sound & 0x10 ) |
| 684 | | { |
| 685 | | /* Noise tap is on bits 0 and 5 and fed back to bits 15 (and 23!) */ |
| 686 | | UINT32 new_bit = ( ( old_signal ) ^ ( old_signal >> 5 ) ) & 0x01; |
| 687 | | signal = ( old_signal & 0xFF0000 ) | ( ( old_signal & 0xFFFF ) >> 1 ) | ( new_bit << 15 ) | ( new_bit << 23 ); |
| 688 | | } |
| 689 | | state->m_o2_vdc.s.shift3 = signal & 0xFF; |
| 690 | | state->m_o2_vdc.s.shift2 = ( signal >> 8 ) & 0xFF; |
| 691 | | state->m_o2_vdc.s.shift1 = ( signal >> 16 ) & 0xFF; |
| 692 | | old_signal = signal; |
| 693 | | } |
| 694 | | |
| 695 | | /* Throw an interrupt if enabled */ |
| 696 | | if( state->m_o2_vdc.s.control & 0x4 ) |
| 697 | | { |
| 698 | | state->m_maincpu->set_input_line(1, HOLD_LINE); /* Is this right? */ |
| 699 | | } |
| 700 | | |
| 701 | | /* Adjust volume */ |
| 702 | | *buffer *= state->m_o2_vdc.s.sound & 0xf; |
| 703 | | /* Pump the volume up */ |
| 704 | | *buffer <<= 10; |
| 705 | | } |
| 706 | | } |
| 707 | | else |
| 708 | | { |
| 709 | | /* Sound disabled, so clear the buffer */ |
| 710 | | for( ii = 0; ii < samples; ii++, buffer++ ) |
| 711 | | *buffer = 0; |
| 712 | | } |
| 713 | | } |
| 714 | | |
| 715 | 158 | /* |
| 716 | | i8243 in the g7400 |
| 717 | | */ |
| 718 | | |
| 719 | | WRITE8_MEMBER(odyssey2_state::i8243_port_w) |
| 720 | | { |
| 721 | | switch ( offset & 3 ) |
| 722 | | { |
| 723 | | case 0: // "port 4" |
| 724 | | m_g7400_ic674_decode[4] = BIT(data,0); |
| 725 | | m_g7400_ic674_decode[5] = BIT(data,1); |
| 726 | | m_g7400_ic674_decode[6] = BIT(data,2); |
| 727 | | m_g7400_ic674_decode[7] = BIT(data,3); |
| 728 | | break; |
| 729 | | |
| 730 | | case 1: // "port 5" |
| 731 | | m_g7400_ic674_decode[0] = BIT(data,0); |
| 732 | | m_g7400_ic674_decode[1] = BIT(data,1); |
| 733 | | m_g7400_ic674_decode[2] = BIT(data,2); |
| 734 | | m_g7400_ic674_decode[3] = BIT(data,3); |
| 735 | | break; |
| 736 | | |
| 737 | | case 2: // "port 6" |
| 738 | | m_g7400_ic678_decode[4] = BIT(data,0); |
| 739 | | m_g7400_ic678_decode[5] = BIT(data,1); |
| 740 | | m_g7400_ic678_decode[6] = BIT(data,2); |
| 741 | | m_g7400_ic678_decode[7] = BIT(data,3); |
| 742 | | break; |
| 743 | | |
| 744 | | case 3: // "port 7" |
| 745 | | m_g7400_ic678_decode[0] = BIT(data,0); |
| 746 | | m_g7400_ic678_decode[1] = BIT(data,1); |
| 747 | | m_g7400_ic678_decode[2] = BIT(data,2); |
| 748 | | m_g7400_ic678_decode[3] = BIT(data,3); |
| 749 | | break; |
| 750 | | |
| 751 | | } |
| 752 | | } |
| 753 | | |
| 754 | | |
| 755 | | /* |
| 756 | 159 | Thomson EF9340/EF9341 extra chips in the g7400 |
| 757 | 160 | */ |
| 758 | 161 | |
| r20214 | r20215 | |
| 1007 | 410 | } |
| 1008 | 411 | } |
| 1009 | 412 | |
| 1010 | | |
| 1011 | | const device_type ODYSSEY2 = &device_creator<odyssey2_sound_device>; |
| 1012 | | |
| 1013 | | odyssey2_sound_device::odyssey2_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 1014 | | : device_t(mconfig, ODYSSEY2, "P8244/P8245", tag, owner, clock), |
| 1015 | | device_sound_interface(mconfig, *this) |
| 1016 | | { |
| 1017 | | } |
| 1018 | | |
| 1019 | | //------------------------------------------------- |
| 1020 | | // device_config_complete - perform any |
| 1021 | | // operations now that the configuration is |
| 1022 | | // complete |
| 1023 | | //------------------------------------------------- |
| 1024 | | |
| 1025 | | void odyssey2_sound_device::device_config_complete() |
| 1026 | | { |
| 1027 | | } |
| 1028 | | |
| 1029 | | //------------------------------------------------- |
| 1030 | | // device_start - device-specific startup |
| 1031 | | //------------------------------------------------- |
| 1032 | | |
| 1033 | | void odyssey2_sound_device::device_start() |
| 1034 | | { |
| 1035 | | DEVICE_START_NAME( odyssey2_sound )(this); |
| 1036 | | } |
| 1037 | | |
| 1038 | | //------------------------------------------------- |
| 1039 | | // sound_stream_update - handle a stream update |
| 1040 | | //------------------------------------------------- |
| 1041 | | |
| 1042 | | void odyssey2_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) |
| 1043 | | { |
| 1044 | | // should never get here |
| 1045 | | fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); |
| 1046 | | } |