trunk/src/mess/machine/svi318.c
| r32257 | r32258 | |
| 27 | 27 | |
| 28 | 28 | WRITE_LINE_MEMBER(svi318_state::ins8250_interrupt) |
| 29 | 29 | { |
| 30 | | if (m_svi.bankLow != SVI_CART) |
| 31 | | { |
| 30 | if (m_bank_low != SVI_CART) |
| 32 | 31 | m_maincpu->set_input_line(0, (state ? HOLD_LINE : CLEAR_LINE)); |
| 33 | | } |
| 34 | 32 | } |
| 35 | 33 | |
| 36 | 34 | #if 0 |
| r32257 | r32258 | |
| 116 | 114 | |
| 117 | 115 | READ8_MEMBER(svi318_state::ppi_port_b_r) |
| 118 | 116 | { |
| 119 | | if (m_svi.keyboard_row <= 10) |
| 120 | | return m_line[m_svi.keyboard_row]->read(); |
| 117 | if (m_keyboard_row <= 10) |
| 118 | return m_line[m_keyboard_row]->read(); |
| 121 | 119 | else |
| 122 | 120 | return 0xff; |
| 123 | 121 | } |
| r32257 | r32258 | |
| 155 | 153 | /* cassette signal write */ |
| 156 | 154 | m_cassette->output((data & 0x20) ? -1.0 : +1.0); |
| 157 | 155 | |
| 158 | | m_svi.keyboard_row = data & 0x0f; |
| 156 | m_keyboard_row = data & 0x0f; |
| 159 | 157 | } |
| 160 | 158 | |
| 161 | 159 | WRITE8_MEMBER(svi318_state::ppi_w) |
| r32257 | r32258 | |
| 202 | 200 | |
| 203 | 201 | WRITE8_MEMBER(svi318_state::psg_port_b_w) |
| 204 | 202 | { |
| 205 | | if ( (m_svi.bank_switch ^ data) & 0x20) |
| 206 | | set_led_status (machine(), 0, !(data & 0x20) ); |
| 203 | if ((m_bank_switch ^ data) & 0x20) |
| 204 | set_led_status(machine(), 0, !(data & 0x20)); |
| 207 | 205 | |
| 208 | | m_svi.bank_switch = data; |
| 206 | m_bank_switch = data; |
| 209 | 207 | svi318_set_banks(); |
| 210 | 208 | } |
| 211 | 209 | |
| r32257 | r32258 | |
| 213 | 211 | |
| 214 | 212 | WRITE_LINE_MEMBER(svi318_state::fdc_intrq_w) |
| 215 | 213 | { |
| 216 | | m_fdc.irq = state; |
| 214 | m_irq = state; |
| 217 | 215 | } |
| 218 | 216 | |
| 219 | 217 | WRITE_LINE_MEMBER(svi318_state::fdc_drq_w) |
| 220 | 218 | { |
| 221 | | m_fdc.drq = state; |
| 219 | m_drq = state; |
| 222 | 220 | } |
| 223 | 221 | |
| 224 | 222 | WRITE8_MEMBER(svi318_state::fdc_drive_motor_w) |
| r32257 | r32258 | |
| 227 | 225 | { |
| 228 | 226 | case 1: |
| 229 | 227 | m_fd1793->set_drive(0); |
| 230 | | m_fdc.driveselect = 0; |
| 228 | m_driveselect = 0; |
| 231 | 229 | break; |
| 232 | 230 | case 2: |
| 233 | 231 | m_fd1793->set_drive(1); |
| 234 | | m_fdc.driveselect = 1; |
| 232 | m_driveselect = 1; |
| 235 | 233 | break; |
| 236 | 234 | } |
| 237 | 235 | } |
| r32257 | r32258 | |
| 246 | 244 | { |
| 247 | 245 | UINT8 result = 0; |
| 248 | 246 | |
| 249 | | result |= m_fdc.drq << 6; |
| 250 | | result |= m_fdc.irq << 7; |
| 247 | result |= m_drq << 6; |
| 248 | result |= m_irq << 7; |
| 251 | 249 | |
| 252 | 250 | return result; |
| 253 | 251 | } |
| r32257 | r32258 | |
| 258 | 256 | |
| 259 | 257 | for (int i = 0; i < x_count; i++) |
| 260 | 258 | { |
| 261 | | UINT8 data = m_svi.svi806_gfx[m_svi.svi806_ram->u8((ma + i) & 0x7ff) * 16 + ra]; |
| 259 | UINT8 data = m_svi806_gfx[m_svi806_ram->u8((ma + i) & 0x7ff) * 16 + ra]; |
| 262 | 260 | |
| 263 | 261 | if (i == cursor_x) |
| 264 | 262 | { |
| r32257 | r32258 | |
| 279 | 277 | { |
| 280 | 278 | /* 2K RAM, but allocating 4KB to make banking easier */ |
| 281 | 279 | /* The upper 2KB will be set to FFs and will never be written to */ |
| 282 | | m_svi.svi806_ram = machine().memory().region_alloc("gfx2", 0x1000, 1, ENDIANNESS_LITTLE); |
| 283 | | memset(m_svi.svi806_ram->base(), 0x00, 0x800); |
| 284 | | memset(m_svi.svi806_ram->base() + 0x800, 0xff, 0x800); |
| 285 | | m_svi.svi806_gfx = memregion("gfx1")->base(); |
| 280 | m_svi806_ram = machine().memory().region_alloc("gfx2", 0x1000, 1, ENDIANNESS_LITTLE); |
| 281 | memset(m_svi806_ram->base(), 0x00, 0x800); |
| 282 | memset(m_svi806_ram->base() + 0x800, 0xff, 0x800); |
| 283 | m_svi806_gfx = memregion("gfx1")->base(); |
| 286 | 284 | } |
| 287 | 285 | |
| 288 | 286 | |
| 289 | 287 | WRITE8_MEMBER(svi318_state::svi806_ram_enable_w) |
| 290 | 288 | { |
| 291 | | m_svi.svi806_ram_enabled = (data & 0x01); |
| 289 | m_svi806_ram_enabled = (data & 0x01); |
| 292 | 290 | svi318_set_banks(); |
| 293 | 291 | } |
| 294 | 292 | |
| r32257 | r32258 | |
| 301 | 299 | MACHINE_RESET_CALL_MEMBER(svi318); |
| 302 | 300 | |
| 303 | 301 | svi318_80col_init(); |
| 304 | | m_svi.svi806_present = 1; |
| 302 | m_svi806_present = 1; |
| 305 | 303 | svi318_set_banks(); |
| 306 | 304 | |
| 307 | 305 | /* Set SVI-806 80 column card palette */ |
| r32257 | r32258 | |
| 438 | 436 | /* z80 stuff */ |
| 439 | 437 | m_maincpu->z80_set_cycle_tables(cc_op, cc_cb, cc_ed, cc_xy, cc_xycb, cc_ex); |
| 440 | 438 | |
| 441 | | memset(&m_svi, 0, sizeof(m_svi)); |
| 442 | | |
| 443 | | if (!strcmp(machine().system().name, "svi318") || !strcmp(machine().system().name, "svi318n")) |
| 444 | | m_svi.svi318 = 1; |
| 445 | | |
| 446 | 439 | m_maincpu->set_input_line_vector(0, 0xff); |
| 447 | 440 | |
| 448 | 441 | /* memory */ |
| 449 | | m_svi.empty_bank = auto_alloc_array(machine(), UINT8, 0x8000); |
| 450 | | memset(m_svi.empty_bank, 0xff, 0x8000); |
| 442 | m_empty_bank = auto_alloc_array(machine(), UINT8, 0x8000); |
| 443 | memset(m_empty_bank, 0xff, 0x8000); |
| 444 | |
| 445 | m_bank_low_ptr = m_empty_bank; |
| 446 | m_bank_high1_ptr = m_empty_bank; |
| 447 | m_bank_high2_ptr = m_empty_bank; |
| 448 | |
| 451 | 449 | } |
| 452 | 450 | |
| 453 | 451 | MACHINE_START_MEMBER(svi318_state, svi318_ntsc) |
| 454 | 452 | { |
| 455 | 453 | astring region_tag; |
| 456 | 454 | m_cart_rom = memregion(region_tag.cpy(m_cart->tag()).cat(GENERIC_ROM_REGION_TAG)); |
| 455 | m_bios_rom = memregion("maincpu"); |
| 457 | 456 | } |
| 458 | 457 | |
| 459 | 458 | MACHINE_START_MEMBER(svi318_state, svi318_pal) |
| 460 | 459 | { |
| 461 | 460 | astring region_tag; |
| 462 | 461 | m_cart_rom = memregion(region_tag.cpy(m_cart->tag()).cat(GENERIC_ROM_REGION_TAG)); |
| 462 | m_bios_rom = memregion("maincpu"); |
| 463 | 463 | } |
| 464 | 464 | |
| 465 | 465 | static void svi318_load_proc(device_image_interface &image) |
| r32257 | r32258 | |
| 471 | 471 | switch (size) |
| 472 | 472 | { |
| 473 | 473 | case 172032: /* SVI-328 SSDD */ |
| 474 | | state->m_fdc.heads[id] = 1; |
| 474 | state->m_heads[id] = 1; |
| 475 | 475 | break; |
| 476 | 476 | case 346112: /* SVI-328 DSDD */ |
| 477 | | state->m_fdc.heads[id] = 2; |
| 477 | state->m_heads[id] = 2; |
| 478 | 478 | break; |
| 479 | 479 | case 348160: /* SVI-728 DSDD CP/M */ |
| 480 | | state->m_fdc.heads[id] = 2; |
| 480 | state->m_heads[id] = 2; |
| 481 | 481 | break; |
| 482 | 482 | } |
| 483 | 483 | } |
| 484 | 484 | |
| 485 | 485 | MACHINE_RESET_MEMBER(svi318_state, svi318) |
| 486 | | { |
| 487 | | m_svi.bank_switch = 0xff; |
| 486 | { |
| 487 | m_keyboard_row = 0; |
| 488 | m_centronics_busy = 0; |
| 489 | m_svi806_present = 0; |
| 490 | m_svi806_ram_enabled = 0; |
| 491 | m_driveselect = 0; |
| 492 | m_drq = 0; |
| 493 | m_irq = 0; |
| 494 | |
| 495 | m_bank_low = 0; |
| 496 | m_bank_high = 0; |
| 497 | m_bank_low_read_only = 0; |
| 498 | m_bank_high1_read_only = 0; |
| 499 | m_bank_high2_read_only = 0; |
| 500 | |
| 501 | m_bank_switch = 0xff; |
| 488 | 502 | svi318_set_banks(); |
| 489 | 503 | |
| 490 | 504 | for (int drive = 0; drive < 2; drive++) |
| 491 | | { |
| 492 | 505 | floppy_get_device(machine(), drive)->floppy_install_load_proc(svi318_load_proc); |
| 493 | | } |
| 494 | 506 | } |
| 495 | 507 | |
| 496 | 508 | /* Memory */ |
| 497 | 509 | |
| 498 | 510 | WRITE8_MEMBER(svi318_state::writemem1) |
| 499 | 511 | { |
| 500 | | if (m_svi.bankLow_read_only) |
| 512 | if (m_bank_low_read_only) |
| 501 | 513 | return; |
| 502 | 514 | |
| 503 | | m_svi.bankLow_ptr[offset] = data; |
| 515 | m_bank_low_ptr[offset] = data; |
| 504 | 516 | } |
| 505 | 517 | |
| 506 | 518 | WRITE8_MEMBER(svi318_state::writemem2) |
| 507 | 519 | { |
| 508 | | if (m_svi.bankHigh1_read_only) |
| 520 | if (m_bank_high1_read_only) |
| 509 | 521 | return; |
| 510 | 522 | |
| 511 | | m_svi.bankHigh1_ptr[offset] = data; |
| 523 | m_bank_high1_ptr[offset] = data; |
| 512 | 524 | } |
| 513 | 525 | |
| 514 | 526 | WRITE8_MEMBER(svi318_state::writemem3) |
| 515 | 527 | { |
| 516 | | if (m_svi.bankHigh2_read_only) |
| 528 | if (m_bank_high2_read_only) |
| 517 | 529 | return; |
| 518 | 530 | |
| 519 | | m_svi.bankHigh2_ptr[offset] = data; |
| 531 | m_bank_high2_ptr[offset] = data; |
| 520 | 532 | } |
| 521 | 533 | |
| 522 | 534 | WRITE8_MEMBER(svi318_state::writemem4) |
| 523 | 535 | { |
| 524 | | if (m_svi.svi806_ram_enabled) |
| 536 | if (m_svi806_ram_enabled) |
| 525 | 537 | { |
| 526 | 538 | if (offset < 0x800) |
| 527 | | { |
| 528 | | m_svi.svi806_ram->u8(offset) = data; |
| 529 | | } |
| 539 | m_svi806_ram->u8(offset) = data; |
| 530 | 540 | } |
| 531 | 541 | else |
| 532 | 542 | { |
| 533 | | if (m_svi.bankHigh2_read_only) |
| 543 | if (m_bank_high2_read_only) |
| 534 | 544 | return; |
| 535 | 545 | |
| 536 | | m_svi.bankHigh2_ptr[0x3000 + offset] = data; |
| 546 | m_bank_high2_ptr[0x3000 + offset] = data; |
| 537 | 547 | } |
| 538 | 548 | } |
| 539 | 549 | |
| 540 | 550 | void svi318_state::svi318_set_banks() |
| 541 | 551 | { |
| 542 | | const UINT8 v = m_svi.bank_switch; |
| 552 | const UINT8 v = m_bank_switch; |
| 543 | 553 | UINT8 *ram = m_ram->pointer(); |
| 544 | 554 | UINT32 ram_size = m_ram->size(); |
| 545 | 555 | |
| 546 | | m_svi.bankLow = ( v & 1 ) ? ( ( v & 2 ) ? ( ( v & 8 ) ? SVI_INTERNAL : SVI_EXPRAM3 ) : SVI_EXPRAM2 ) : SVI_CART; |
| 547 | | m_svi.bankHigh1 = ( v & 4 ) ? ( ( v & 16 ) ? SVI_INTERNAL : SVI_EXPRAM3 ) : SVI_EXPRAM2; |
| 556 | m_bank_low = (v & 1) ? ((v & 2) ? ((v & 8) ? SVI_INTERNAL : SVI_EXPRAM3) : SVI_EXPRAM2) : SVI_CART; |
| 557 | m_bank_high = (v & 4) ? ((v & 16) ? SVI_INTERNAL : SVI_EXPRAM3) : SVI_EXPRAM2; |
| 548 | 558 | |
| 549 | | m_svi.bankLow_ptr = m_svi.empty_bank; |
| 550 | | m_svi.bankLow_read_only = 1; |
| 559 | m_bank_low_ptr = m_empty_bank; |
| 560 | m_bank_low_read_only = 1; |
| 551 | 561 | |
| 552 | | switch( m_svi.bankLow ) |
| 562 | switch (m_bank_low) |
| 553 | 563 | { |
| 554 | 564 | case SVI_INTERNAL: |
| 555 | | m_svi.bankLow_ptr = memregion("maincpu")->base(); |
| 565 | m_bank_low_ptr = m_bios_rom->base(); |
| 556 | 566 | break; |
| 557 | 567 | case SVI_CART: |
| 558 | 568 | if (m_cart_rom) |
| 559 | | m_svi.bankLow_ptr = m_cart_rom->base(); |
| 569 | m_bank_low_ptr = m_cart_rom->base(); |
| 560 | 570 | break; |
| 561 | 571 | case SVI_EXPRAM2: |
| 562 | | if ( ram_size >= 64 * 1024 ) |
| 572 | if (ram_size >= 64 * 1024) |
| 563 | 573 | { |
| 564 | | m_svi.bankLow_ptr = ram + ram_size - 64 * 1024; |
| 565 | | m_svi.bankLow_read_only = 0; |
| 574 | m_bank_low_ptr = ram + ram_size - 64 * 1024; |
| 575 | m_bank_low_read_only = 0; |
| 566 | 576 | } |
| 567 | 577 | break; |
| 568 | 578 | case SVI_EXPRAM3: |
| 569 | | if ( ram_size > 128 * 1024 ) |
| 579 | if (ram_size > 128 * 1024) |
| 570 | 580 | { |
| 571 | | m_svi.bankLow_ptr = ram + ram_size - 128 * 1024; |
| 572 | | m_svi.bankLow_read_only = 0; |
| 581 | m_bank_low_ptr = ram + ram_size - 128 * 1024; |
| 582 | m_bank_low_read_only = 0; |
| 573 | 583 | } |
| 574 | 584 | break; |
| 575 | 585 | } |
| 576 | 586 | |
| 577 | | m_svi.bankHigh1_ptr = m_svi.bankHigh2_ptr = m_svi.empty_bank; |
| 578 | | m_svi.bankHigh1_read_only = m_svi.bankHigh2_read_only = 1; |
| 587 | m_bank_high1_ptr = m_empty_bank; |
| 588 | m_bank_high1_read_only = 1; |
| 589 | m_bank_high2_ptr = m_empty_bank; |
| 590 | m_bank_high2_read_only = 1; |
| 579 | 591 | |
| 580 | | switch( m_svi.bankHigh1 ) |
| 592 | switch (m_bank_high) |
| 581 | 593 | { |
| 582 | 594 | case SVI_INTERNAL: |
| 583 | | if ( ram_size == 16 * 1024 ) |
| 595 | if (ram_size == 16 * 1024) |
| 584 | 596 | { |
| 585 | | m_svi.bankHigh2_ptr = ram; |
| 586 | | m_svi.bankHigh2_read_only = 0; |
| 597 | m_bank_high2_ptr = ram; |
| 598 | m_bank_high2_read_only = 0; |
| 587 | 599 | } |
| 588 | 600 | else |
| 589 | 601 | { |
| 590 | | m_svi.bankHigh1_ptr = ram; |
| 591 | | m_svi.bankHigh1_read_only = 0; |
| 592 | | m_svi.bankHigh2_ptr = ram + 0x4000; |
| 593 | | m_svi.bankHigh2_read_only = 0; |
| 602 | m_bank_high1_ptr = ram; |
| 603 | m_bank_high1_read_only = 0; |
| 604 | m_bank_high2_ptr = ram + 0x4000; |
| 605 | m_bank_high2_read_only = 0; |
| 594 | 606 | } |
| 595 | 607 | break; |
| 596 | 608 | case SVI_EXPRAM2: |
| 597 | | if ( ram_size > 64 * 1024 ) |
| 609 | if (ram_size > 64 * 1024) |
| 598 | 610 | { |
| 599 | | m_svi.bankHigh1_ptr = ram + ram_size - 64 * 1024 + 32 * 1024; |
| 600 | | m_svi.bankHigh1_read_only = 0; |
| 601 | | m_svi.bankHigh2_ptr = ram + ram_size - 64 * 1024 + 48 * 1024; |
| 602 | | m_svi.bankHigh2_read_only = 0; |
| 611 | m_bank_high1_ptr = ram + ram_size - 64 * 1024 + 32 * 1024; |
| 612 | m_bank_high1_read_only = 0; |
| 613 | m_bank_high2_ptr = ram + ram_size - 64 * 1024 + 48 * 1024; |
| 614 | m_bank_high2_read_only = 0; |
| 603 | 615 | } |
| 604 | 616 | break; |
| 605 | 617 | case SVI_EXPRAM3: |
| 606 | | if ( ram_size > 128 * 1024 ) |
| 618 | if (ram_size > 128 * 1024) |
| 607 | 619 | { |
| 608 | | m_svi.bankHigh1_ptr = ram + ram_size - 128 * 1024 + 32 * 1024; |
| 609 | | m_svi.bankHigh1_read_only = 0; |
| 610 | | m_svi.bankHigh2_ptr = ram + ram_size - 128 * 1024 + 48 * 1024; |
| 611 | | m_svi.bankHigh2_read_only = 0; |
| 620 | m_bank_high1_ptr = ram + ram_size - 128 * 1024 + 32 * 1024; |
| 621 | m_bank_high1_read_only = 0; |
| 622 | m_bank_high2_ptr = ram + ram_size - 128 * 1024 + 48 * 1024; |
| 623 | m_bank_high2_read_only = 0; |
| 612 | 624 | } |
| 613 | 625 | break; |
| 614 | 626 | } |
| 615 | 627 | |
| 616 | 628 | /* Check for special CART based banking */ |
| 617 | | if ( m_svi.bankLow == SVI_CART && ( v & 0xc0 ) != 0xc0 ) |
| 629 | if (m_bank_low == SVI_CART && (v & 0xc0 ) != 0xc0) |
| 618 | 630 | { |
| 619 | | m_svi.bankHigh1_ptr = m_svi.empty_bank; |
| 620 | | m_svi.bankHigh1_read_only = 1; |
| 621 | | m_svi.bankHigh2_ptr = m_svi.empty_bank; |
| 622 | | m_svi.bankHigh2_read_only = 1; |
| 631 | m_bank_high1_ptr = m_empty_bank; |
| 632 | m_bank_high1_read_only = 1; |
| 633 | m_bank_high2_ptr = m_empty_bank; |
| 634 | m_bank_high2_read_only = 1; |
| 635 | |
| 623 | 636 | if (m_cart_rom && !(v & 0x80)) |
| 624 | | m_svi.bankHigh2_ptr = m_cart_rom->base() + 0x4000; |
| 637 | m_bank_high2_ptr = m_cart_rom->base() + 0x4000; |
| 625 | 638 | if (m_cart_rom && !(v & 0x40)) |
| 626 | | m_svi.bankHigh1_ptr = m_cart_rom->base(); |
| 639 | m_bank_high1_ptr = m_cart_rom->base(); |
| 627 | 640 | } |
| 628 | 641 | |
| 629 | | membank("bank1")->set_base(m_svi.bankLow_ptr); |
| 630 | | membank("bank2")->set_base(m_svi.bankHigh1_ptr); |
| 631 | | membank("bank3")->set_base(m_svi.bankHigh2_ptr); |
| 642 | m_bank1->set_base(m_bank_low_ptr); |
| 643 | m_bank2->set_base(m_bank_high1_ptr); |
| 644 | m_bank3->set_base(m_bank_high2_ptr); |
| 632 | 645 | |
| 633 | 646 | /* SVI-806 80 column card specific banking */ |
| 634 | | if (m_svi.svi806_present) |
| 647 | if (m_svi806_present) |
| 635 | 648 | { |
| 636 | | if (m_svi.svi806_ram_enabled) |
| 637 | | { |
| 638 | | membank("bank4")->set_base(m_svi.svi806_ram); |
| 639 | | } |
| 649 | if (m_svi806_ram_enabled) |
| 650 | m_bank4->set_base(m_svi806_ram); |
| 640 | 651 | else |
| 641 | | { |
| 642 | | membank("bank4")->set_base(m_svi.bankHigh2_ptr + 0x3000); |
| 643 | | } |
| 652 | m_bank4->set_base(m_bank_high2_ptr + 0x3000); |
| 644 | 653 | } |
| 645 | 654 | } |
| 646 | 655 | |
| r32257 | r32258 | |
| 653 | 662 | |
| 654 | 663 | READ8_MEMBER(svi318_state::io_ext_r) |
| 655 | 664 | { |
| 656 | | if (m_svi.bankLow == SVI_CART) |
| 665 | if (m_bank_low == SVI_CART) |
| 657 | 666 | return 0xff; |
| 658 | 667 | |
| 659 | 668 | switch (offset) |
| r32257 | r32258 | |
| 705 | 714 | |
| 706 | 715 | WRITE8_MEMBER(svi318_state::io_ext_w) |
| 707 | 716 | { |
| 708 | | if (m_svi.bankLow == SVI_CART) |
| 717 | if (m_bank_low == SVI_CART) |
| 709 | 718 | return; |
| 710 | 719 | |
| 711 | 720 | switch (offset) |