trunk/src/mess/drivers/scv.c
| r20452 | r20453 | |
| 15 | 15 | { |
| 16 | 16 | public: |
| 17 | 17 | scv_state(const machine_config &mconfig, device_type type, const char *tag) |
| 18 | | : driver_device(mconfig, type, tag), |
| 19 | | m_videoram(*this,"videoram") { } |
| 18 | : driver_device(mconfig, type, tag) |
| 19 | , m_videoram(*this,"videoram") |
| 20 | , m_maincpu(*this, "maincpu") |
| 21 | , m_upd1771c(*this, "upd1771c") |
| 22 | , m_pa0(*this, "PA0") |
| 23 | , m_pa1(*this, "PA1") |
| 24 | , m_pa2(*this, "PA2") |
| 25 | , m_pa3(*this, "PA3") |
| 26 | , m_pa4(*this, "PA4") |
| 27 | , m_pa5(*this, "PA5") |
| 28 | , m_pa6(*this, "PA6") |
| 29 | , m_pa7(*this, "PA7") |
| 30 | , m_pc0(*this, "PC0") |
| 31 | , m_bank0(NULL) |
| 32 | , m_bank1(NULL) |
| 33 | , m_bank2(NULL) |
| 34 | , m_bank3(NULL) |
| 35 | , m_bank4(NULL) |
| 36 | { } |
| 20 | 37 | |
| 21 | 38 | DECLARE_WRITE8_MEMBER(scv_porta_w); |
| 22 | 39 | DECLARE_READ8_MEMBER(scv_portb_r); |
| r20452 | r20453 | |
| 39 | 56 | virtual void palette_init(); |
| 40 | 57 | UINT32 screen_update_scv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 41 | 58 | TIMER_CALLBACK_MEMBER(scv_vb_callback); |
| 42 | | }; |
| 43 | 59 | |
| 60 | protected: |
| 61 | required_device<cpu_device> m_maincpu; |
| 62 | required_device<upd1771c_device> m_upd1771c; |
| 63 | required_ioport m_pa0; |
| 64 | required_ioport m_pa1; |
| 65 | required_ioport m_pa2; |
| 66 | required_ioport m_pa3; |
| 67 | required_ioport m_pa4; |
| 68 | required_ioport m_pa5; |
| 69 | required_ioport m_pa6; |
| 70 | required_ioport m_pa7; |
| 71 | required_ioport m_pc0; |
| 72 | memory_bank *m_bank0; |
| 73 | memory_bank *m_bank1; |
| 74 | memory_bank *m_bank2; |
| 75 | memory_bank *m_bank3; |
| 76 | memory_bank *m_bank4; |
| 77 | UINT8 *m_charrom; |
| 44 | 78 | |
| 79 | void scv_set_banks(); |
| 80 | }; |
| 45 | 81 | |
| 46 | 82 | |
| 47 | 83 | static ADDRESS_MAP_START( scv_mem, AS_PROGRAM, 8, scv_state ) |
| r20452 | r20453 | |
| 157 | 193 | { |
| 158 | 194 | /* Check if cartridge ram is enabled */ |
| 159 | 195 | if ( m_cart_ram_enabled ) |
| 196 | { |
| 160 | 197 | m_cart_ram[offset] = data; |
| 198 | } |
| 161 | 199 | } |
| 162 | 200 | |
| 163 | 201 | |
| r20452 | r20453 | |
| 167 | 205 | if ( m_cart_ram_enabled ) |
| 168 | 206 | { |
| 169 | 207 | if ( m_cart_ram_size > 0x1000 ) |
| 208 | { |
| 170 | 209 | offset += 0x1000; |
| 210 | } |
| 171 | 211 | |
| 172 | 212 | m_cart_ram[offset] = data; |
| 173 | 213 | } |
| r20452 | r20453 | |
| 185 | 225 | UINT8 data = 0xff; |
| 186 | 226 | |
| 187 | 227 | if ( ! ( m_porta & 0x01 ) ) |
| 188 | | data &= ioport( "PA0" )->read(); |
| 228 | { |
| 229 | data &= m_pa0->read(); |
| 230 | } |
| 189 | 231 | |
| 190 | 232 | if ( ! ( m_porta & 0x02 ) ) |
| 191 | | data &= ioport( "PA1" )->read(); |
| 233 | { |
| 234 | data &= m_pa1->read(); |
| 235 | } |
| 192 | 236 | |
| 193 | 237 | if ( ! ( m_porta & 0x04 ) ) |
| 194 | | data &= ioport( "PA2" )->read(); |
| 238 | { |
| 239 | data &= m_pa2->read(); |
| 240 | } |
| 195 | 241 | |
| 196 | 242 | if ( ! ( m_porta & 0x08 ) ) |
| 197 | | data &= ioport( "PA3" )->read(); |
| 243 | { |
| 244 | data &= m_pa3->read(); |
| 245 | } |
| 198 | 246 | |
| 199 | 247 | if ( ! ( m_porta & 0x10 ) ) |
| 200 | | data &= ioport( "PA4" )->read(); |
| 248 | { |
| 249 | data &= m_pa4->read(); |
| 250 | } |
| 201 | 251 | |
| 202 | 252 | if ( ! ( m_porta & 0x20 ) ) |
| 203 | | data &= ioport( "PA5" )->read(); |
| 253 | { |
| 254 | data &= m_pa5->read(); |
| 255 | } |
| 204 | 256 | |
| 205 | 257 | if ( ! ( m_porta & 0x40 ) ) |
| 206 | | data &= ioport( "PA6" )->read(); |
| 258 | { |
| 259 | data &= m_pa6->read(); |
| 260 | } |
| 207 | 261 | |
| 208 | 262 | if ( ! ( m_porta & 0x80 ) ) |
| 209 | | data &= ioport( "PA7" )->read(); |
| 263 | { |
| 264 | data &= m_pa7->read(); |
| 265 | } |
| 210 | 266 | |
| 211 | 267 | return data; |
| 212 | 268 | } |
| r20452 | r20453 | |
| 216 | 272 | { |
| 217 | 273 | UINT8 data = m_portc; |
| 218 | 274 | |
| 219 | | data = ( data & 0xfe ) | ( ioport( "PC0" )->read() & 0x01 ); |
| 275 | data = ( data & 0xfe ) | ( m_pc0->read() & 0x01 ); |
| 220 | 276 | |
| 221 | 277 | return data; |
| 222 | 278 | } |
| 223 | 279 | |
| 224 | 280 | |
| 225 | | static void scv_set_banks( running_machine &machine ) |
| 281 | void scv_state::scv_set_banks() |
| 226 | 282 | { |
| 227 | | scv_state *state = machine.driver_data<scv_state>(); |
| 283 | m_cart_ram_enabled = false; |
| 228 | 284 | |
| 229 | | state->m_cart_ram_enabled = false; |
| 230 | | |
| 231 | | switch( state->m_cart_rom_size ) |
| 285 | switch( m_cart_rom_size ) |
| 232 | 286 | { |
| 233 | 287 | case 0: |
| 234 | 288 | case 0x2000: |
| 235 | | state->membank( "bank0" )->set_base( state->m_cart_rom ); |
| 236 | | state->membank( "bank1" )->set_base( state->m_cart_rom ); |
| 237 | | state->membank( "bank2" )->set_base( state->m_cart_rom ); |
| 238 | | state->membank( "bank3" )->set_base( state->m_cart_rom ); |
| 239 | | state->membank( "bank4" )->set_base( state->m_cart_rom + 0x1000 ); |
| 289 | m_bank0->set_base( m_cart_rom ); |
| 290 | m_bank1->set_base( m_cart_rom ); |
| 291 | m_bank2->set_base( m_cart_rom ); |
| 292 | m_bank3->set_base( m_cart_rom ); |
| 293 | m_bank4->set_base( m_cart_rom + 0x1000 ); |
| 240 | 294 | break; |
| 241 | 295 | case 0x4000: |
| 242 | | state->membank( "bank0" )->set_base( state->m_cart_rom ); |
| 243 | | state->membank( "bank1" )->set_base( state->m_cart_rom + 0x2000 ); |
| 244 | | state->membank( "bank2" )->set_base( state->m_cart_rom ); |
| 245 | | state->membank( "bank3" )->set_base( state->m_cart_rom + 0x2000 ); |
| 246 | | state->membank( "bank4" )->set_base( state->m_cart_rom + 0x3000 ); |
| 296 | m_bank0->set_base( m_cart_rom ); |
| 297 | m_bank1->set_base( m_cart_rom + 0x2000 ); |
| 298 | m_bank2->set_base( m_cart_rom ); |
| 299 | m_bank3->set_base( m_cart_rom + 0x2000 ); |
| 300 | m_bank4->set_base( m_cart_rom + 0x3000 ); |
| 247 | 301 | break; |
| 248 | 302 | case 0x8000: |
| 249 | | state->membank( "bank0" )->set_base( state->m_cart_rom ); |
| 250 | | state->membank( "bank1" )->set_base( state->m_cart_rom + 0x2000 ); |
| 251 | | state->membank( "bank2" )->set_base( state->m_cart_rom + 0x4000 ); |
| 252 | | state->membank( "bank3" )->set_base( state->m_cart_rom + 0x6000 ); |
| 253 | | state->membank( "bank4" )->set_base( state->m_cart_rom + 0x7000 ); |
| 303 | m_bank0->set_base( m_cart_rom ); |
| 304 | m_bank1->set_base( m_cart_rom + 0x2000 ); |
| 305 | m_bank2->set_base( m_cart_rom + 0x4000 ); |
| 306 | m_bank3->set_base( m_cart_rom + 0x6000 ); |
| 307 | m_bank4->set_base( m_cart_rom + 0x7000 ); |
| 254 | 308 | break; |
| 255 | 309 | case 0x10000: |
| 256 | | state->membank( "bank0" )->set_base( state->m_cart_rom + ( ( state->m_portc & 0x20 ) ? 0x8000 : 0 ) ); |
| 257 | | state->membank( "bank1" )->set_base( state->m_cart_rom + ( ( state->m_portc & 0x20 ) ? 0xa000 : 0x2000 ) ); |
| 258 | | state->membank( "bank2" )->set_base( state->m_cart_rom + ( ( state->m_portc & 0x20 ) ? 0xc000 : 0x4000 ) ); |
| 259 | | state->membank( "bank3" )->set_base( state->m_cart_rom + ( ( state->m_portc & 0x20 ) ? 0xe000 : 0x6000 ) ); |
| 260 | | state->membank( "bank4" )->set_base( state->m_cart_rom + ( ( state->m_portc & 0x20 ) ? 0xf000 : 0x7000 ) ); |
| 310 | m_bank0->set_base( m_cart_rom + ( ( m_portc & 0x20 ) ? 0x8000 : 0 ) ); |
| 311 | m_bank1->set_base( m_cart_rom + ( ( m_portc & 0x20 ) ? 0xa000 : 0x2000 ) ); |
| 312 | m_bank2->set_base( m_cart_rom + ( ( m_portc & 0x20 ) ? 0xc000 : 0x4000 ) ); |
| 313 | m_bank3->set_base( m_cart_rom + ( ( m_portc & 0x20 ) ? 0xe000 : 0x6000 ) ); |
| 314 | m_bank4->set_base( m_cart_rom + ( ( m_portc & 0x20 ) ? 0xf000 : 0x7000 ) ); |
| 261 | 315 | break; |
| 262 | 316 | case 0x20000: /* Pole Position 2 */ |
| 263 | | int base = ( ( state->m_portc >> 5 ) & 0x03 ) * 0x8000 ; |
| 264 | | state->membank( "bank0" )->set_base( state->m_cart_rom + base + 0 ); |
| 265 | | state->membank( "bank1" )->set_base( state->m_cart_rom + base + 0x2000 ); |
| 266 | | state->membank( "bank2" )->set_base( state->m_cart_rom + base + 0x4000 ); |
| 267 | | state->membank( "bank3" )->set_base( state->m_cart_rom + base + 0x6000 ); |
| 268 | | state->membank( "bank4" )->set_base( state->m_cart_rom + base + 0x7000 ); |
| 317 | int base = ( ( m_portc >> 5 ) & 0x03 ) * 0x8000 ; |
| 318 | m_bank0->set_base( m_cart_rom + base + 0 ); |
| 319 | m_bank1->set_base( m_cart_rom + base + 0x2000 ); |
| 320 | m_bank2->set_base( m_cart_rom + base + 0x4000 ); |
| 321 | m_bank3->set_base( m_cart_rom + base + 0x6000 ); |
| 322 | m_bank4->set_base( m_cart_rom + base + 0x7000 ); |
| 269 | 323 | /* On-cart RAM is enabled when PC6 is high */ |
| 270 | | if ( state->m_cart_ram && state->m_portc & 0x40 ) |
| 324 | if ( m_cart_ram && m_portc & 0x40 ) |
| 271 | 325 | { |
| 272 | | state->m_cart_ram_enabled = true; |
| 273 | | state->membank( "bank4" )->set_base( state->m_cart_ram ); |
| 326 | m_cart_ram_enabled = true; |
| 327 | m_bank4->set_base( m_cart_ram ); |
| 274 | 328 | } |
| 275 | 329 | break; |
| 276 | 330 | } |
| 277 | 331 | |
| 278 | 332 | /* Check if cartridge RAM is available and should be enabled */ |
| 279 | | if ( state->m_cart_rom_size < 0x20000 && state->m_cart_ram && state->m_cart_ram_size && ( state->m_portc & 0x20 ) ) |
| 333 | if ( m_cart_rom_size < 0x20000 && m_cart_ram && m_cart_ram_size && ( m_portc & 0x20 ) ) |
| 280 | 334 | { |
| 281 | | if ( state->m_cart_ram_size == 0x1000 ) |
| 335 | if ( m_cart_ram_size == 0x1000 ) |
| 282 | 336 | { |
| 283 | | state->membank( "bank4" )->set_base( state->m_cart_ram ); |
| 337 | m_bank4->set_base( m_cart_ram ); |
| 284 | 338 | } |
| 285 | 339 | else |
| 286 | 340 | { |
| 287 | | state->membank( "bank3" )->set_base( state->m_cart_ram ); |
| 288 | | state->membank( "bank4" )->set_base( state->m_cart_ram + 0x1000 ); |
| 341 | m_bank3->set_base( m_cart_ram ); |
| 342 | m_bank4->set_base( m_cart_ram + 0x1000 ); |
| 289 | 343 | } |
| 290 | | state->m_cart_ram_enabled = true; |
| 344 | m_cart_ram_enabled = true; |
| 291 | 345 | } |
| 292 | 346 | |
| 293 | 347 | } |
| r20452 | r20453 | |
| 295 | 349 | |
| 296 | 350 | WRITE8_MEMBER( scv_state::scv_portc_w ) |
| 297 | 351 | { |
| 298 | | //logerror("%04x: scv_portc_w: data = 0x%02x\n", machine().device("maincpu")->safe_pc(), data ); |
| 352 | //logerror("%04x: scv_portc_w: data = 0x%02x\n", m_maincpu->pc(), data ); |
| 299 | 353 | m_portc = data; |
| 300 | 354 | |
| 301 | | scv_set_banks( machine() ); |
| 302 | | upd1771_pcm_w( machine().device( "upd1771c" ), m_portc & 0x08 ); |
| 355 | scv_set_banks(); |
| 356 | upd1771_pcm_w( m_upd1771c, m_portc & 0x08 ); |
| 303 | 357 | } |
| 304 | 358 | |
| 305 | 359 | |
| r20452 | r20453 | |
| 311 | 365 | state->m_cart_rom_size = 0; |
| 312 | 366 | state->m_cart_ram = NULL; |
| 313 | 367 | state->m_cart_ram_size = 0; |
| 314 | | |
| 315 | | scv_set_banks( device->machine() ); |
| 316 | 368 | } |
| 317 | 369 | |
| 318 | 370 | |
| r20452 | r20453 | |
| 350 | 402 | state->m_cart_ram_size = image.get_software_region_length( "ram" ); |
| 351 | 403 | } |
| 352 | 404 | |
| 353 | | scv_set_banks( image.device().machine() ); |
| 354 | | |
| 355 | 405 | return IMAGE_INIT_PASS; |
| 356 | 406 | } |
| 357 | 407 | |
| r20452 | r20453 | |
| 415 | 465 | switch( vpos ) |
| 416 | 466 | { |
| 417 | 467 | case 240: |
| 418 | | machine().device("maincpu")->execute().set_input_line(UPD7810_INTF2, ASSERT_LINE); |
| 468 | m_maincpu->set_input_line(UPD7810_INTF2, ASSERT_LINE); |
| 419 | 469 | break; |
| 420 | 470 | case 0: |
| 421 | | machine().device("maincpu")->execute().set_input_line(UPD7810_INTF2, CLEAR_LINE); |
| 471 | m_maincpu->set_input_line(UPD7810_INTF2, CLEAR_LINE); |
| 422 | 472 | break; |
| 423 | 473 | } |
| 424 | 474 | |
| r20452 | r20453 | |
| 611 | 661 | if ( text_x && text_y ) |
| 612 | 662 | { |
| 613 | 663 | /* Text mode */ |
| 614 | | UINT8 *char_data = memregion( "charrom" )->base() + ( d & 0x7f ) * 8; |
| 664 | UINT8 *char_data = m_charrom + ( d & 0x7f ) * 8; |
| 615 | 665 | draw_text( bitmap, x * 8, y * 16, char_data, fg, bg ); |
| 616 | 666 | } |
| 617 | 667 | else |
| r20452 | r20453 | |
| 744 | 794 | |
| 745 | 795 | WRITE_LINE_MEMBER( scv_state::scv_upd1771_ack_w ) |
| 746 | 796 | { |
| 747 | | machine().device("maincpu")->execute().set_input_line(UPD7810_INTF1, (state) ? ASSERT_LINE : CLEAR_LINE); |
| 797 | m_maincpu->set_input_line(UPD7810_INTF1, (state) ? ASSERT_LINE : CLEAR_LINE); |
| 748 | 798 | } |
| 749 | 799 | |
| 750 | 800 | |
| 751 | 801 | void scv_state::machine_start() |
| 752 | 802 | { |
| 753 | 803 | m_vb_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(scv_state::scv_vb_callback),this)); |
| 804 | m_charrom = memregion( "charrom" )->base(); |
| 805 | m_bank0 = membank( "bank0" ); |
| 806 | m_bank1 = membank( "bank1" ); |
| 807 | m_bank2 = membank( "bank2" ); |
| 808 | m_bank3 = membank( "bank3" ); |
| 809 | m_bank4 = membank( "bank4" ); |
| 754 | 810 | } |
| 755 | 811 | |
| 756 | 812 | |
| 757 | 813 | void scv_state::machine_reset() |
| 758 | 814 | { |
| 759 | 815 | m_vb_timer->adjust( machine().primary_screen->time_until_pos(0, 0 ) ); |
| 816 | scv_set_banks(); |
| 760 | 817 | } |
| 761 | 818 | |
| 762 | 819 | |