src/mess/machine/pmd85.c
| r9683 | r9684 | |
| 19 | 19 | #include "machine/serial.h" |
| 20 | 20 | #include "devices/messram.h" |
| 21 | 21 | |
| 22 | | static UINT8 pmd85_rom_module_present = 0; |
| 23 | 22 | |
| 24 | | static UINT8 pmd85_ppi_port_outputs[4][3]; |
| 25 | 23 | |
| 26 | | static UINT8 pmd85_startup_mem_map = 0; |
| 27 | | static UINT8 pmd853_memory_mapping; |
| 28 | 24 | static void (*pmd85_update_memory)(running_machine *); |
| 29 | | static int previous_level; |
| 30 | | static int clk_level; |
| 31 | | static int clk_level_tape; |
| 32 | 25 | |
| 33 | 26 | enum {PMD85_LED_1, PMD85_LED_2, PMD85_LED_3}; |
| 34 | 27 | enum {PMD85_1, PMD85_2, PMD85_2A, PMD85_2B, PMD85_3, ALFA, MATO, C2717}; |
| 35 | 28 | |
| 36 | | static UINT8 pmd85_model; |
| 37 | 29 | |
| 38 | | static emu_timer * pmd85_cassette_timer; |
| 39 | 30 | |
| 40 | 31 | static void pmd851_update_memory(running_machine *machine) |
| 41 | 32 | { |
| 33 | pmd85_state *state = machine->driver_data<pmd85_state>(); |
| 42 | 34 | address_space* space = cputag_get_address_space(machine, "maincpu",ADDRESS_SPACE_PROGRAM); |
| 43 | 35 | |
| 44 | | if (pmd85_startup_mem_map) |
| 36 | if (state->startup_mem_map) |
| 45 | 37 | { |
| 46 | 38 | UINT8 *mem = memory_region(machine, "maincpu"); |
| 47 | 39 | |
| r9683 | r9684 | |
| 82 | 74 | |
| 83 | 75 | static void pmd852a_update_memory(running_machine *machine) |
| 84 | 76 | { |
| 77 | pmd85_state *state = machine->driver_data<pmd85_state>(); |
| 85 | 78 | address_space* space = cputag_get_address_space(machine, "maincpu",ADDRESS_SPACE_PROGRAM); |
| 86 | 79 | |
| 87 | | if (pmd85_startup_mem_map) |
| 80 | if (state->startup_mem_map) |
| 88 | 81 | { |
| 89 | 82 | UINT8 *mem = memory_region(machine, "maincpu"); |
| 90 | 83 | |
| r9683 | r9684 | |
| 118 | 111 | |
| 119 | 112 | static void pmd853_update_memory(running_machine *machine) |
| 120 | 113 | { |
| 121 | | if (pmd85_startup_mem_map) |
| 114 | pmd85_state *state = machine->driver_data<pmd85_state>(); |
| 115 | if (state->startup_mem_map) |
| 122 | 116 | { |
| 123 | 117 | UINT8 *mem = memory_region(machine, "maincpu"); |
| 124 | 118 | |
| r9683 | r9684 | |
| 148 | 142 | memory_set_bankptr(machine, "bank5", messram_get_ptr(machine->device("messram")) + 0x8000); |
| 149 | 143 | memory_set_bankptr(machine, "bank6", messram_get_ptr(machine->device("messram")) + 0xa000); |
| 150 | 144 | memory_set_bankptr(machine, "bank7", messram_get_ptr(machine->device("messram")) + 0xc000); |
| 151 | | memory_set_bankptr(machine, "bank8", pmd853_memory_mapping ? memory_region(machine, "maincpu") + 0x010000 : messram_get_ptr(machine->device("messram")) + 0xe000); |
| 145 | memory_set_bankptr(machine, "bank8", state->pmd853_memory_mapping ? memory_region(machine, "maincpu") + 0x010000 : messram_get_ptr(machine->device("messram")) + 0xe000); |
| 152 | 146 | } |
| 153 | 147 | } |
| 154 | 148 | |
| 155 | 149 | static void alfa_update_memory(running_machine *machine) |
| 156 | 150 | { |
| 151 | pmd85_state *state = machine->driver_data<pmd85_state>(); |
| 157 | 152 | address_space* space = cputag_get_address_space(machine, "maincpu",ADDRESS_SPACE_PROGRAM); |
| 158 | 153 | |
| 159 | | if (pmd85_startup_mem_map) |
| 154 | if (state->startup_mem_map) |
| 160 | 155 | { |
| 161 | 156 | UINT8 *mem = memory_region(machine, "maincpu"); |
| 162 | 157 | |
| r9683 | r9684 | |
| 186 | 181 | |
| 187 | 182 | static void mato_update_memory(running_machine *machine) |
| 188 | 183 | { |
| 184 | pmd85_state *state = machine->driver_data<pmd85_state>(); |
| 189 | 185 | address_space* space = cputag_get_address_space(machine, "maincpu",ADDRESS_SPACE_PROGRAM); |
| 190 | 186 | |
| 191 | | if (pmd85_startup_mem_map) |
| 187 | if (state->startup_mem_map) |
| 192 | 188 | { |
| 193 | 189 | UINT8 *mem = memory_region(machine, "maincpu"); |
| 194 | 190 | |
| r9683 | r9684 | |
| 210 | 206 | |
| 211 | 207 | static void c2717_update_memory(running_machine *machine) |
| 212 | 208 | { |
| 209 | pmd85_state *state = machine->driver_data<pmd85_state>(); |
| 213 | 210 | address_space* space = cputag_get_address_space(machine, "maincpu",ADDRESS_SPACE_PROGRAM); |
| 214 | 211 | |
| 215 | 212 | UINT8 *mem = memory_region(machine, "maincpu"); |
| 216 | | if (pmd85_startup_mem_map) |
| 213 | if (state->startup_mem_map) |
| 217 | 214 | { |
| 218 | 215 | memory_unmap_write(space, 0x0000, 0x3fff, 0, 0); |
| 219 | 216 | |
| r9683 | r9684 | |
| 245 | 242 | |
| 246 | 243 | static READ8_DEVICE_HANDLER ( pmd85_ppi_0_portb_r ) |
| 247 | 244 | { |
| 245 | pmd85_state *state = device->machine->driver_data<pmd85_state>(); |
| 248 | 246 | static const char *const keynames[] = { |
| 249 | 247 | "KEY0", "KEY1", "KEY2", "KEY3", "KEY4", "KEY5", "KEY6", "KEY7", |
| 250 | 248 | "KEY8", "KEY9", "KEY10", "KEY11", "KEY12", "KEY13", "KEY14", "KEY15" |
| 251 | 249 | }; |
| 252 | 250 | |
| 253 | | return input_port_read(device->machine, keynames[(pmd85_ppi_port_outputs[0][0] & 0x0f)]) & input_port_read(device->machine, "KEY15"); |
| 251 | return input_port_read(device->machine, keynames[(state->ppi_port_outputs[0][0] & 0x0f)]) & input_port_read(device->machine, "KEY15"); |
| 254 | 252 | } |
| 255 | 253 | |
| 256 | 254 | static READ8_DEVICE_HANDLER ( pmd85_ppi_0_portc_r ) |
| r9683 | r9684 | |
| 260 | 258 | |
| 261 | 259 | static WRITE8_DEVICE_HANDLER ( pmd85_ppi_0_porta_w ) |
| 262 | 260 | { |
| 263 | | pmd85_ppi_port_outputs[0][0] = data; |
| 261 | pmd85_state *state = device->machine->driver_data<pmd85_state>(); |
| 262 | state->ppi_port_outputs[0][0] = data; |
| 264 | 263 | } |
| 265 | 264 | |
| 266 | 265 | static WRITE8_DEVICE_HANDLER ( pmd85_ppi_0_portb_w ) |
| 267 | 266 | { |
| 268 | | pmd85_ppi_port_outputs[0][1] = data; |
| 267 | pmd85_state *state = device->machine->driver_data<pmd85_state>(); |
| 268 | state->ppi_port_outputs[0][1] = data; |
| 269 | 269 | } |
| 270 | 270 | |
| 271 | 271 | static WRITE8_DEVICE_HANDLER ( pmd85_ppi_0_portc_w ) |
| 272 | 272 | { |
| 273 | | pmd85_ppi_port_outputs[0][2] = data; |
| 273 | pmd85_state *state = device->machine->driver_data<pmd85_state>(); |
| 274 | state->ppi_port_outputs[0][2] = data; |
| 274 | 275 | set_led_status(device->machine, PMD85_LED_2, (data & 0x08) ? 1 : 0); |
| 275 | 276 | set_led_status(device->machine, PMD85_LED_3, (data & 0x04) ? 1 : 0); |
| 276 | 277 | } |
| r9683 | r9684 | |
| 285 | 286 | |
| 286 | 287 | static READ8_DEVICE_HANDLER ( mato_ppi_0_portb_r ) |
| 287 | 288 | { |
| 289 | pmd85_state *state = device->machine->driver_data<pmd85_state>(); |
| 288 | 290 | int i; |
| 289 | 291 | UINT8 data = 0xff; |
| 290 | 292 | static const char *const keynames[] = { "KEY0", "KEY1", "KEY2", "KEY3", "KEY4", "KEY5", "KEY6", "KEY7" }; |
| 291 | 293 | |
| 292 | 294 | for (i = 0; i < 8; i++) |
| 293 | 295 | { |
| 294 | | if (!BIT(pmd85_ppi_port_outputs[0][0], i)) |
| 296 | if (!BIT(state->ppi_port_outputs[0][0], i)) |
| 295 | 297 | data &= input_port_read(device->machine, keynames[i]); |
| 296 | 298 | } |
| 297 | 299 | return data; |
| r9683 | r9684 | |
| 304 | 306 | |
| 305 | 307 | static WRITE8_DEVICE_HANDLER ( mato_ppi_0_portc_w ) |
| 306 | 308 | { |
| 307 | | pmd85_ppi_port_outputs[0][2] = data; |
| 309 | pmd85_state *state = device->machine->driver_data<pmd85_state>(); |
| 310 | state->ppi_port_outputs[0][2] = data; |
| 308 | 311 | set_led_status(device->machine, PMD85_LED_2, BIT(data, 3)); |
| 309 | 312 | set_led_status(device->machine, PMD85_LED_3, BIT(data, 2)); |
| 310 | 313 | } |
| r9683 | r9684 | |
| 334 | 337 | |
| 335 | 338 | static WRITE8_DEVICE_HANDLER ( pmd85_ppi_1_porta_w ) |
| 336 | 339 | { |
| 337 | | pmd85_ppi_port_outputs[1][0] = data; |
| 340 | pmd85_state *state = device->machine->driver_data<pmd85_state>(); |
| 341 | state->ppi_port_outputs[1][0] = data; |
| 338 | 342 | } |
| 339 | 343 | |
| 340 | 344 | static WRITE8_DEVICE_HANDLER ( pmd85_ppi_1_portb_w ) |
| 341 | 345 | { |
| 342 | | pmd85_ppi_port_outputs[1][1] = data; |
| 346 | pmd85_state *state = device->machine->driver_data<pmd85_state>(); |
| 347 | state->ppi_port_outputs[1][1] = data; |
| 343 | 348 | } |
| 344 | 349 | |
| 345 | 350 | static WRITE8_DEVICE_HANDLER ( pmd85_ppi_1_portc_w ) |
| 346 | 351 | { |
| 347 | | pmd85_ppi_port_outputs[1][2] = data; |
| 352 | pmd85_state *state = device->machine->driver_data<pmd85_state>(); |
| 353 | state->ppi_port_outputs[1][2] = data; |
| 348 | 354 | } |
| 349 | 355 | |
| 350 | 356 | /******************************************************************************* |
| r9683 | r9684 | |
| 376 | 382 | |
| 377 | 383 | static WRITE8_DEVICE_HANDLER ( pmd85_ppi_2_porta_w ) |
| 378 | 384 | { |
| 379 | | pmd85_ppi_port_outputs[2][0] = data; |
| 385 | pmd85_state *state = device->machine->driver_data<pmd85_state>(); |
| 386 | state->ppi_port_outputs[2][0] = data; |
| 380 | 387 | } |
| 381 | 388 | |
| 382 | 389 | static WRITE8_DEVICE_HANDLER ( pmd85_ppi_2_portb_w ) |
| 383 | 390 | { |
| 384 | | pmd85_ppi_port_outputs[2][1] = data; |
| 391 | pmd85_state *state = device->machine->driver_data<pmd85_state>(); |
| 392 | state->ppi_port_outputs[2][1] = data; |
| 385 | 393 | } |
| 386 | 394 | |
| 387 | 395 | static WRITE8_DEVICE_HANDLER ( pmd85_ppi_2_portc_w ) |
| 388 | 396 | { |
| 389 | | pmd85_ppi_port_outputs[2][2] = data; |
| 397 | pmd85_state *state = device->machine->driver_data<pmd85_state>(); |
| 398 | state->ppi_port_outputs[2][2] = data; |
| 390 | 399 | } |
| 391 | 400 | |
| 392 | 401 | /******************************************************************************* |
| r9683 | r9684 | |
| 446 | 455 | |
| 447 | 456 | static READ8_DEVICE_HANDLER ( pmd85_ppi_3_porta_r ) |
| 448 | 457 | { |
| 458 | pmd85_state *state = device->machine->driver_data<pmd85_state>(); |
| 449 | 459 | if (memory_region(device->machine, "user1") != NULL) |
| 450 | | return memory_region(device->machine, "user1")[pmd85_ppi_port_outputs[3][1] | (pmd85_ppi_port_outputs[3][2] << 8)]; |
| 460 | return memory_region(device->machine, "user1")[state->ppi_port_outputs[3][1] | (state->ppi_port_outputs[3][2] << 8)]; |
| 451 | 461 | else |
| 452 | 462 | return 0; |
| 453 | 463 | } |
| r9683 | r9684 | |
| 464 | 474 | |
| 465 | 475 | static WRITE8_DEVICE_HANDLER ( pmd85_ppi_3_porta_w ) |
| 466 | 476 | { |
| 467 | | pmd85_ppi_port_outputs[3][0] = data; |
| 477 | pmd85_state *state = device->machine->driver_data<pmd85_state>(); |
| 478 | state->ppi_port_outputs[3][0] = data; |
| 468 | 479 | } |
| 469 | 480 | |
| 470 | 481 | static WRITE8_DEVICE_HANDLER ( pmd85_ppi_3_portb_w ) |
| 471 | 482 | { |
| 472 | | pmd85_ppi_port_outputs[3][1] = data; |
| 483 | pmd85_state *state = device->machine->driver_data<pmd85_state>(); |
| 484 | state->ppi_port_outputs[3][1] = data; |
| 473 | 485 | } |
| 474 | 486 | |
| 475 | 487 | static WRITE8_DEVICE_HANDLER ( pmd85_ppi_3_portc_w ) |
| 476 | 488 | { |
| 477 | | pmd85_ppi_port_outputs[3][2] = data; |
| 489 | pmd85_state *state = device->machine->driver_data<pmd85_state>(); |
| 490 | state->ppi_port_outputs[3][2] = data; |
| 478 | 491 | } |
| 479 | 492 | |
| 480 | 493 | /******************************************************************************* |
| r9683 | r9684 | |
| 502 | 515 | |
| 503 | 516 | READ8_HANDLER ( pmd85_io_r ) |
| 504 | 517 | { |
| 505 | | if (pmd85_startup_mem_map) |
| 518 | pmd85_state *state = space->machine->driver_data<pmd85_state>(); |
| 519 | if (state->startup_mem_map) |
| 506 | 520 | { |
| 507 | 521 | return 0xff; |
| 508 | 522 | } |
| r9683 | r9684 | |
| 517 | 531 | } |
| 518 | 532 | break; |
| 519 | 533 | case 0x08: /* ROM module connector */ |
| 520 | | switch (pmd85_model) |
| 534 | switch (state->model) |
| 521 | 535 | { |
| 522 | 536 | case PMD85_1: |
| 523 | 537 | case PMD85_2: |
| 524 | 538 | case PMD85_2A: |
| 525 | 539 | case C2717: |
| 526 | 540 | case PMD85_3: |
| 527 | | if (pmd85_rom_module_present) |
| 541 | if (state->rom_module_present) |
| 528 | 542 | { |
| 529 | 543 | switch (offset & 0x80) |
| 530 | 544 | { |
| r9683 | r9684 | |
| 568 | 582 | |
| 569 | 583 | WRITE8_HANDLER ( pmd85_io_w ) |
| 570 | 584 | { |
| 571 | | if (pmd85_startup_mem_map) |
| 585 | pmd85_state *state = space->machine->driver_data<pmd85_state>(); |
| 586 | if (state->startup_mem_map) |
| 572 | 587 | { |
| 573 | | pmd85_startup_mem_map = 0; |
| 588 | state->startup_mem_map = 0; |
| 574 | 589 | (*pmd85_update_memory)(space->machine); |
| 575 | 590 | } |
| 576 | 591 | |
| r9683 | r9684 | |
| 584 | 599 | /* PMD-85.3 memory banking */ |
| 585 | 600 | if ((offset & 0x03) == 0x03) |
| 586 | 601 | { |
| 587 | | pmd853_memory_mapping = data & 0x01; |
| 602 | state->pmd853_memory_mapping = data & 0x01; |
| 588 | 603 | (*pmd85_update_memory)(space->machine); |
| 589 | 604 | } |
| 590 | 605 | break; |
| 591 | 606 | } |
| 592 | 607 | break; |
| 593 | 608 | case 0x08: /* ROM module connector */ |
| 594 | | switch (pmd85_model) |
| 609 | switch (state->model) |
| 595 | 610 | { |
| 596 | 611 | case PMD85_1: |
| 597 | 612 | case PMD85_2: |
| 598 | 613 | case PMD85_2A: |
| 599 | 614 | case C2717: |
| 600 | 615 | case PMD85_3: |
| 601 | | if (pmd85_rom_module_present) |
| 616 | if (state->rom_module_present) |
| 602 | 617 | { |
| 603 | 618 | switch (offset & 0x80) |
| 604 | 619 | { |
| r9683 | r9684 | |
| 654 | 669 | |
| 655 | 670 | READ8_HANDLER ( mato_io_r ) |
| 656 | 671 | { |
| 657 | | if (pmd85_startup_mem_map) |
| 672 | pmd85_state *state = space->machine->driver_data<pmd85_state>(); |
| 673 | if (state->startup_mem_map) |
| 658 | 674 | { |
| 659 | 675 | return 0xff; |
| 660 | 676 | } |
| r9683 | r9684 | |
| 676 | 692 | |
| 677 | 693 | WRITE8_HANDLER ( mato_io_w ) |
| 678 | 694 | { |
| 679 | | if (pmd85_startup_mem_map) |
| 695 | pmd85_state *state = space->machine->driver_data<pmd85_state>(); |
| 696 | if (state->startup_mem_map) |
| 680 | 697 | { |
| 681 | | pmd85_startup_mem_map = 0; |
| 698 | state->startup_mem_map = 0; |
| 682 | 699 | (*pmd85_update_memory)(space->machine); |
| 683 | 700 | } |
| 684 | 701 | |
| r9683 | r9684 | |
| 778 | 795 | |
| 779 | 796 | static TIMER_CALLBACK(pmd85_cassette_timer_callback) |
| 780 | 797 | { |
| 798 | pmd85_state *state = machine->driver_data<pmd85_state>(); |
| 781 | 799 | int data; |
| 782 | 800 | int current_level; |
| 783 | 801 | |
| r9683 | r9684 | |
| 786 | 804 | /* tape reading */ |
| 787 | 805 | if (cassette_get_state(machine->device("cassette"))&CASSETTE_PLAY) |
| 788 | 806 | { |
| 789 | | switch (pmd85_model) |
| 807 | switch (state->model) |
| 790 | 808 | { |
| 791 | 809 | case PMD85_1: |
| 792 | | if (clk_level_tape) |
| 810 | if (state->clk_level_tape) |
| 793 | 811 | { |
| 794 | | previous_level = (cassette_input(machine->device("cassette")) > 0.038) ? 1 : 0; |
| 795 | | clk_level_tape = 0; |
| 812 | state->previous_level = (cassette_input(machine->device("cassette")) > 0.038) ? 1 : 0; |
| 813 | state->clk_level_tape = 0; |
| 796 | 814 | } |
| 797 | 815 | else |
| 798 | 816 | { |
| 799 | 817 | current_level = (cassette_input(machine->device("cassette")) > 0.038) ? 1 : 0; |
| 800 | 818 | |
| 801 | | if (previous_level!=current_level) |
| 819 | if (state->previous_level!=current_level) |
| 802 | 820 | { |
| 803 | | data = (!previous_level && current_level) ? 1 : 0; |
| 821 | data = (!state->previous_level && current_level) ? 1 : 0; |
| 804 | 822 | |
| 805 | 823 | set_out_data_bit(pmd85_cassette_serial_connection.State, data); |
| 806 | 824 | serial_connection_out(machine, &pmd85_cassette_serial_connection); |
| 807 | 825 | msm8251_receive_clock(machine->device("uart")); |
| 808 | 826 | |
| 809 | | clk_level_tape = 1; |
| 827 | state->clk_level_tape = 1; |
| 810 | 828 | } |
| 811 | 829 | } |
| 812 | 830 | return; |
| r9683 | r9684 | |
| 824 | 842 | if (cassette_get_state(machine->device("cassette"))&CASSETTE_RECORD) |
| 825 | 843 | { |
| 826 | 844 | data = get_in_data_bit(pmd85_cassette_serial_connection.input_state); |
| 827 | | data ^= clk_level_tape; |
| 845 | data ^= state->clk_level_tape; |
| 828 | 846 | cassette_output(machine->device("cassette"), data&0x01 ? 1 : -1); |
| 829 | 847 | |
| 830 | | if (!clk_level_tape) |
| 848 | if (!state->clk_level_tape) |
| 831 | 849 | msm8251_transmit_clock(machine->device("uart")); |
| 832 | 850 | |
| 833 | | clk_level_tape = clk_level_tape ? 0 : 1; |
| 851 | state->clk_level_tape = state->clk_level_tape ? 0 : 1; |
| 834 | 852 | |
| 835 | 853 | return; |
| 836 | 854 | } |
| 837 | 855 | |
| 838 | | clk_level_tape = 1; |
| 856 | state->clk_level_tape = 1; |
| 839 | 857 | |
| 840 | | if (!clk_level) |
| 858 | if (!state->clk_level) |
| 841 | 859 | msm8251_transmit_clock(machine->device("uart")); |
| 842 | | clk_level = clk_level ? 0 : 1; |
| 860 | state->clk_level = state->clk_level ? 0 : 1; |
| 843 | 861 | } |
| 844 | 862 | } |
| 845 | 863 | |
| r9683 | r9684 | |
| 857 | 875 | |
| 858 | 876 | static void pmd85_common_driver_init (running_machine *machine) |
| 859 | 877 | { |
| 860 | | previous_level = 0; |
| 861 | | clk_level = clk_level_tape = 1; |
| 862 | | pmd85_cassette_timer = timer_alloc(machine, pmd85_cassette_timer_callback, NULL); |
| 863 | | timer_adjust_periodic(pmd85_cassette_timer, attotime_zero, 0, ATTOTIME_IN_HZ(2400)); |
| 878 | pmd85_state *state = machine->driver_data<pmd85_state>(); |
| 879 | state->previous_level = 0; |
| 880 | state->clk_level = state->clk_level_tape = 1; |
| 881 | state->cassette_timer = timer_alloc(machine, pmd85_cassette_timer_callback, NULL); |
| 882 | timer_adjust_periodic(state->cassette_timer, attotime_zero, 0, ATTOTIME_IN_HZ(2400)); |
| 864 | 883 | |
| 865 | 884 | serial_connection_init(machine, &pmd85_cassette_serial_connection); |
| 866 | 885 | serial_connection_set_in_callback(machine, &pmd85_cassette_serial_connection, pmd85_cassette_write); |
| r9683 | r9684 | |
| 868 | 887 | |
| 869 | 888 | DRIVER_INIT ( pmd851 ) |
| 870 | 889 | { |
| 871 | | pmd85_model = PMD85_1; |
| 890 | pmd85_state *state = machine->driver_data<pmd85_state>(); |
| 891 | state->model = PMD85_1; |
| 872 | 892 | pmd85_update_memory = pmd851_update_memory; |
| 873 | 893 | pmd85_common_driver_init(machine); |
| 874 | 894 | } |
| 875 | 895 | |
| 876 | 896 | DRIVER_INIT ( pmd852a ) |
| 877 | 897 | { |
| 878 | | pmd85_model = PMD85_2A; |
| 898 | pmd85_state *state = machine->driver_data<pmd85_state>(); |
| 899 | state->model = PMD85_2A; |
| 879 | 900 | pmd85_update_memory = pmd852a_update_memory; |
| 880 | 901 | pmd85_common_driver_init(machine); |
| 881 | 902 | } |
| 882 | 903 | |
| 883 | 904 | DRIVER_INIT ( pmd853 ) |
| 884 | 905 | { |
| 885 | | pmd85_model = PMD85_3; |
| 906 | pmd85_state *state = machine->driver_data<pmd85_state>(); |
| 907 | state->model = PMD85_3; |
| 886 | 908 | pmd85_update_memory = pmd853_update_memory; |
| 887 | 909 | pmd85_common_driver_init(machine); |
| 888 | 910 | } |
| 889 | 911 | |
| 890 | 912 | DRIVER_INIT ( alfa ) |
| 891 | 913 | { |
| 892 | | pmd85_model = ALFA; |
| 914 | pmd85_state *state = machine->driver_data<pmd85_state>(); |
| 915 | state->model = ALFA; |
| 893 | 916 | pmd85_update_memory = alfa_update_memory; |
| 894 | 917 | pmd85_common_driver_init(machine); |
| 895 | 918 | } |
| 896 | 919 | |
| 897 | 920 | DRIVER_INIT ( mato ) |
| 898 | 921 | { |
| 899 | | pmd85_model = MATO; |
| 922 | pmd85_state *state = machine->driver_data<pmd85_state>(); |
| 923 | state->model = MATO; |
| 900 | 924 | pmd85_update_memory = mato_update_memory; |
| 901 | 925 | } |
| 902 | 926 | |
| 903 | 927 | DRIVER_INIT ( c2717 ) |
| 904 | 928 | { |
| 905 | | pmd85_model = C2717; |
| 929 | pmd85_state *state = machine->driver_data<pmd85_state>(); |
| 930 | state->model = C2717; |
| 906 | 931 | pmd85_update_memory = c2717_update_memory; |
| 907 | 932 | pmd85_common_driver_init(machine); |
| 908 | 933 | } |
| 909 | 934 | |
| 910 | 935 | static TIMER_CALLBACK( setup_machine_state ) |
| 911 | 936 | { |
| 912 | | if (pmd85_model != MATO) |
| 937 | pmd85_state *state = machine->driver_data<pmd85_state>(); |
| 938 | if (state->model != MATO) |
| 913 | 939 | { |
| 914 | 940 | msm8251_connect(machine->device("uart"), &pmd85_cassette_serial_connection); |
| 915 | 941 | } |
| r9683 | r9684 | |
| 918 | 944 | |
| 919 | 945 | MACHINE_RESET( pmd85 ) |
| 920 | 946 | { |
| 947 | pmd85_state *state = machine->driver_data<pmd85_state>(); |
| 921 | 948 | int i, j; |
| 922 | 949 | |
| 923 | 950 | /* checking for Rom Module */ |
| 924 | | switch (pmd85_model) |
| 951 | switch (state->model) |
| 925 | 952 | { |
| 926 | 953 | case PMD85_1: |
| 927 | 954 | case PMD85_2A: |
| 928 | 955 | case PMD85_3: |
| 929 | 956 | case C2717: |
| 930 | | pmd85_rom_module_present = (input_port_read(machine, "DSW0") & 0x01) ? 1 : 0; |
| 957 | state->rom_module_present = (input_port_read(machine, "DSW0") & 0x01) ? 1 : 0; |
| 931 | 958 | break; |
| 932 | 959 | case ALFA: |
| 933 | 960 | case MATO: |
| r9683 | r9684 | |
| 936 | 963 | |
| 937 | 964 | for (i = 0; i < 4; i++) |
| 938 | 965 | for (j = 0; j < 3; j++) |
| 939 | | pmd85_ppi_port_outputs[i][j] = 0; |
| 966 | state->ppi_port_outputs[i][j] = 0; |
| 940 | 967 | |
| 941 | 968 | /* memory initialization */ |
| 942 | 969 | memset(messram_get_ptr(machine->device("messram")), 0, sizeof(unsigned char)*0x10000); |
| 943 | | pmd853_memory_mapping = 1; |
| 944 | | pmd85_startup_mem_map = 1; |
| 970 | state->pmd853_memory_mapping = 1; |
| 971 | state->startup_mem_map = 1; |
| 945 | 972 | pmd85_update_memory(machine); |
| 946 | 973 | |
| 947 | 974 | timer_set(machine, attotime_zero, NULL, 0, setup_machine_state); |
src/mess/machine/svi318.c
| r9683 | r9684 | |
| 28 | 28 | SVI_EXPRAM3 = 3 |
| 29 | 29 | }; |
| 30 | 30 | |
| 31 | | typedef struct { |
| 32 | | /* general */ |
| 33 | | UINT8 svi318; /* Are we dealing with an SVI-318 or a SVI-328 model. 0 = 328, 1 = 318 */ |
| 34 | | /* memory */ |
| 35 | | UINT8 *empty_bank; |
| 36 | | UINT8 bank_switch; |
| 37 | | UINT8 bankLow; |
| 38 | | UINT8 bankHigh1; |
| 39 | | UINT8 *bankLow_ptr; |
| 40 | | UINT8 bankLow_read_only; |
| 41 | | UINT8 *bankHigh1_ptr; |
| 42 | | UINT8 bankHigh1_read_only; |
| 43 | | UINT8 *bankHigh2_ptr; |
| 44 | | UINT8 bankHigh2_read_only; |
| 45 | | /* keyboard */ |
| 46 | | UINT8 keyboard_row; |
| 47 | | /* SVI-806 80 column card */ |
| 48 | | UINT8 svi806_present; |
| 49 | | UINT8 svi806_ram_enabled; |
| 50 | | region_info *svi806_ram; |
| 51 | | UINT8 *svi806_gfx; |
| 52 | | } SVI_318; |
| 53 | 31 | |
| 54 | | static SVI_318 svi; |
| 55 | | static UINT8 *pcart; |
| 56 | | static UINT32 pcart_rom_size; |
| 57 | | |
| 58 | 32 | static void svi318_set_banks(running_machine *machine); |
| 59 | 33 | |
| 60 | 34 | |
| r9683 | r9684 | |
| 62 | 36 | |
| 63 | 37 | static INS8250_INTERRUPT( svi318_ins8250_interrupt ) |
| 64 | 38 | { |
| 65 | | if (svi.bankLow != SVI_CART) |
| 39 | svi318_state *drvstate = device->machine->driver_data<svi318_state>(); |
| 40 | if (drvstate->svi.bankLow != SVI_CART) |
| 66 | 41 | { |
| 67 | 42 | cputag_set_input_line(device->machine, "maincpu", 0, (state ? HOLD_LINE : CLEAR_LINE)); |
| 68 | 43 | } |
| r9683 | r9684 | |
| 106 | 81 | |
| 107 | 82 | DEVICE_START( svi318_cart ) |
| 108 | 83 | { |
| 109 | | pcart = NULL; |
| 110 | | pcart_rom_size = 0; |
| 84 | svi318_state *state = device->machine->driver_data<svi318_state>(); |
| 85 | state->pcart = NULL; |
| 86 | state->pcart_rom_size = 0; |
| 111 | 87 | } |
| 112 | 88 | |
| 113 | 89 | DEVICE_IMAGE_LOAD( svi318_cart ) |
| 114 | 90 | { |
| 91 | svi318_state *state = image.device().machine->driver_data<svi318_state>(); |
| 115 | 92 | UINT8 *p = memory_region(image.device().machine, "user1"); |
| 116 | 93 | UINT32 size; |
| 117 | 94 | |
| r9683 | r9684 | |
| 137 | 114 | if (svi318_verify_cart(p) == IMAGE_VERIFY_FAIL) |
| 138 | 115 | return IMAGE_INIT_FAIL; |
| 139 | 116 | |
| 140 | | pcart = p; |
| 141 | | pcart_rom_size = size; |
| 117 | state->pcart = p; |
| 118 | state->pcart_rom_size = size; |
| 142 | 119 | |
| 143 | 120 | return IMAGE_INIT_PASS; |
| 144 | 121 | } |
| 145 | 122 | |
| 146 | 123 | DEVICE_IMAGE_UNLOAD( svi318_cart ) |
| 147 | 124 | { |
| 148 | | pcart = NULL; |
| 149 | | pcart_rom_size = 0; |
| 125 | svi318_state *state = image.device().machine->driver_data<svi318_state>(); |
| 126 | state->pcart = NULL; |
| 127 | state->pcart_rom_size = 0; |
| 150 | 128 | } |
| 151 | 129 | |
| 152 | 130 | /* PPI */ |
| r9683 | r9684 | |
| 192 | 170 | |
| 193 | 171 | static READ8_DEVICE_HANDLER ( svi318_ppi_port_b_r ) |
| 194 | 172 | { |
| 173 | svi318_state *state = device->machine->driver_data<svi318_state>(); |
| 195 | 174 | int row; |
| 196 | 175 | static const char *const keynames[] = { |
| 197 | 176 | "LINE0", "LINE1", "LINE2", "LINE3", "LINE4", "LINE5", |
| 198 | 177 | "LINE6", "LINE7", "LINE8", "LINE9", "LINE10" |
| 199 | 178 | }; |
| 200 | 179 | |
| 201 | | row = svi.keyboard_row; |
| 180 | row = state->svi.keyboard_row; |
| 202 | 181 | if (row <= 10) |
| 203 | 182 | return input_port_read(device->machine, keynames[row]); |
| 204 | 183 | |
| r9683 | r9684 | |
| 220 | 199 | |
| 221 | 200 | static WRITE8_DEVICE_HANDLER ( svi318_ppi_port_c_w ) |
| 222 | 201 | { |
| 202 | svi318_state *state = device->machine->driver_data<svi318_state>(); |
| 223 | 203 | int val; |
| 224 | 204 | |
| 225 | 205 | /* key click */ |
| r9683 | r9684 | |
| 239 | 219 | /* cassette signal write */ |
| 240 | 220 | cassette_output(device->machine->device("cassette"), (data & 0x20) ? -1.0 : +1.0); |
| 241 | 221 | |
| 242 | | svi.keyboard_row = data & 0x0F; |
| 222 | state->svi.keyboard_row = data & 0x0F; |
| 243 | 223 | } |
| 244 | 224 | |
| 245 | 225 | I8255A_INTERFACE( svi318_ppi8255_interface ) |
| r9683 | r9684 | |
| 301 | 281 | |
| 302 | 282 | WRITE8_HANDLER( svi318_psg_port_b_w ) |
| 303 | 283 | { |
| 304 | | if ( (svi.bank_switch ^ data) & 0x20) |
| 284 | svi318_state *state = space->machine->driver_data<svi318_state>(); |
| 285 | if ( (state->svi.bank_switch ^ data) & 0x20) |
| 305 | 286 | set_led_status (space->machine, 0, !(data & 0x20) ); |
| 306 | 287 | |
| 307 | | svi.bank_switch = data; |
| 288 | state->svi.bank_switch = data; |
| 308 | 289 | svi318_set_banks(space->machine); |
| 309 | 290 | } |
| 310 | 291 | |
| 311 | 292 | /* Disk drives */ |
| 312 | 293 | |
| 313 | | typedef struct |
| 314 | | { |
| 315 | | UINT8 driveselect; |
| 316 | | int drq; |
| 317 | | int irq; |
| 318 | | UINT8 heads[2]; |
| 319 | | } SVI318_FDC_STRUCT; |
| 320 | | |
| 321 | | static SVI318_FDC_STRUCT svi318_fdc; |
| 322 | | |
| 323 | 294 | static WRITE_LINE_DEVICE_HANDLER( svi_fdc_intrq_w ) |
| 324 | 295 | { |
| 325 | | svi318_fdc.irq = state; |
| 296 | svi318_state *drvstate = device->machine->driver_data<svi318_state>(); |
| 297 | drvstate->fdc.irq = state; |
| 326 | 298 | } |
| 327 | 299 | |
| 328 | 300 | static WRITE_LINE_DEVICE_HANDLER( svi_fdc_drq_w ) |
| 329 | 301 | { |
| 330 | | svi318_fdc.drq = state; |
| 302 | svi318_state *drvstate = device->machine->driver_data<svi318_state>(); |
| 303 | drvstate->fdc.drq = state; |
| 331 | 304 | } |
| 332 | 305 | |
| 333 | 306 | const wd17xx_interface svi_wd17xx_interface = |
| r9683 | r9684 | |
| 340 | 313 | |
| 341 | 314 | static WRITE8_HANDLER( svi318_fdc_drive_motor_w ) |
| 342 | 315 | { |
| 316 | svi318_state *state = space->machine->driver_data<svi318_state>(); |
| 343 | 317 | running_device *fdc = space->machine->device("wd179x"); |
| 344 | 318 | switch (data & 3) |
| 345 | 319 | { |
| 346 | 320 | case 1: |
| 347 | 321 | wd17xx_set_drive(fdc,0); |
| 348 | | svi318_fdc.driveselect = 0; |
| 322 | state->fdc.driveselect = 0; |
| 349 | 323 | break; |
| 350 | 324 | case 2: |
| 351 | 325 | wd17xx_set_drive(fdc,1); |
| 352 | | svi318_fdc.driveselect = 1; |
| 326 | state->fdc.driveselect = 1; |
| 353 | 327 | break; |
| 354 | 328 | } |
| 355 | 329 | } |
| r9683 | r9684 | |
| 364 | 338 | |
| 365 | 339 | static READ8_HANDLER( svi318_fdc_irqdrq_r ) |
| 366 | 340 | { |
| 341 | svi318_state *state = space->machine->driver_data<svi318_state>(); |
| 367 | 342 | UINT8 result = 0; |
| 368 | 343 | |
| 369 | | result |= svi318_fdc.drq << 6; |
| 370 | | result |= svi318_fdc.irq << 7; |
| 344 | result |= state->fdc.drq << 6; |
| 345 | result |= state->fdc.irq << 7; |
| 371 | 346 | |
| 372 | 347 | return result; |
| 373 | 348 | } |
| 374 | 349 | |
| 375 | 350 | MC6845_UPDATE_ROW( svi806_crtc6845_update_row ) |
| 376 | 351 | { |
| 352 | svi318_state *state = device->machine->driver_data<svi318_state>(); |
| 377 | 353 | int i; |
| 378 | 354 | |
| 379 | 355 | for( i = 0; i < x_count; i++ ) |
| 380 | 356 | { |
| 381 | 357 | int j; |
| 382 | | UINT8 data = svi.svi806_gfx[ svi.svi806_ram->u8(( ma + i ) & 0x7FF) * 16 + ra ]; |
| 358 | UINT8 data = state->svi.svi806_gfx[ state->svi.svi806_ram->u8(( ma + i ) & 0x7FF) * 16 + ra ]; |
| 383 | 359 | |
| 384 | 360 | if ( i == cursor_x ) |
| 385 | 361 | { |
| r9683 | r9684 | |
| 398 | 374 | /* 80 column card init */ |
| 399 | 375 | static void svi318_80col_init(running_machine *machine) |
| 400 | 376 | { |
| 377 | svi318_state *state = machine->driver_data<svi318_state>(); |
| 401 | 378 | /* 2K RAM, but allocating 4KB to make banking easier */ |
| 402 | 379 | /* The upper 2KB will be set to FFs and will never be written to */ |
| 403 | | svi.svi806_ram = machine->region_alloc("gfx2", 0x1000, 0 ); |
| 404 | | memset( svi.svi806_ram->base(), 0x00, 0x800 ); |
| 405 | | memset( svi.svi806_ram->base() + 0x800, 0xFF, 0x800 ); |
| 406 | | svi.svi806_gfx = memory_region(machine, "gfx1"); |
| 380 | state->svi.svi806_ram = machine->region_alloc("gfx2", 0x1000, 0 ); |
| 381 | memset( state->svi.svi806_ram->base(), 0x00, 0x800 ); |
| 382 | memset( state->svi.svi806_ram->base() + 0x800, 0xFF, 0x800 ); |
| 383 | state->svi.svi806_gfx = memory_region(machine, "gfx1"); |
| 407 | 384 | } |
| 408 | 385 | |
| 409 | 386 | |
| 410 | 387 | static WRITE8_HANDLER( svi806_ram_enable_w ) |
| 411 | 388 | { |
| 412 | | svi.svi806_ram_enabled = ( data & 0x01 ); |
| 389 | svi318_state *state = space->machine->driver_data<svi318_state>(); |
| 390 | state->svi.svi806_ram_enabled = ( data & 0x01 ); |
| 413 | 391 | svi318_set_banks(space->machine); |
| 414 | 392 | } |
| 415 | 393 | |
| r9683 | r9684 | |
| 438 | 416 | |
| 439 | 417 | MACHINE_RESET( svi328_806 ) |
| 440 | 418 | { |
| 419 | svi318_state *state = machine->driver_data<svi318_state>(); |
| 441 | 420 | MACHINE_RESET_CALL(svi318); |
| 442 | 421 | |
| 443 | 422 | svi318_80col_init(machine); |
| 444 | | svi.svi806_present = 1; |
| 423 | state->svi.svi806_present = 1; |
| 445 | 424 | svi318_set_banks(machine); |
| 446 | 425 | |
| 447 | 426 | /* Set SVI-806 80 column card palette */ |
| r9683 | r9684 | |
| 575 | 554 | |
| 576 | 555 | DRIVER_INIT( svi318 ) |
| 577 | 556 | { |
| 557 | svi318_state *state = machine->driver_data<svi318_state>(); |
| 578 | 558 | /* z80 stuff */ |
| 579 | 559 | z80_set_cycle_tables( machine->device("maincpu"), cc_op, cc_cb, cc_ed, cc_xy, cc_xycb, cc_ex ); |
| 580 | 560 | |
| 581 | | memset(&svi, 0, sizeof (svi) ); |
| 561 | memset(&state->svi, 0, sizeof (state->svi) ); |
| 582 | 562 | |
| 583 | 563 | if ( ! strcmp( machine->gamedrv->name, "svi318" ) || ! strcmp( machine->gamedrv->name, "svi318n" ) ) |
| 584 | 564 | { |
| 585 | | svi.svi318 = 1; |
| 565 | state->svi.svi318 = 1; |
| 586 | 566 | } |
| 587 | 567 | |
| 588 | 568 | cpu_set_input_line_vector(machine->device("maincpu"), 0, 0xff); |
| 589 | 569 | |
| 590 | 570 | /* memory */ |
| 591 | | svi.empty_bank = auto_alloc_array(machine, UINT8, 0x8000); |
| 592 | | memset (svi.empty_bank, 0xff, 0x8000); |
| 571 | state->svi.empty_bank = auto_alloc_array(machine, UINT8, 0x8000); |
| 572 | memset (state->svi.empty_bank, 0xff, 0x8000); |
| 593 | 573 | } |
| 594 | 574 | |
| 595 | 575 | static const TMS9928a_interface svi318_tms9928a_interface = |
| r9683 | r9684 | |
| 622 | 602 | |
| 623 | 603 | static void svi318_load_proc(device_image_interface &image) |
| 624 | 604 | { |
| 605 | svi318_state *state = image.device().machine->driver_data<svi318_state>(); |
| 625 | 606 | int size; |
| 626 | 607 | int id = floppy_get_drive(&image.device()); |
| 627 | 608 | |
| r9683 | r9684 | |
| 629 | 610 | switch (size) |
| 630 | 611 | { |
| 631 | 612 | case 172032: /* SVI-328 SSDD */ |
| 632 | | svi318_fdc.heads[id] = 1; |
| 613 | state->fdc.heads[id] = 1; |
| 633 | 614 | break; |
| 634 | 615 | case 346112: /* SVI-328 DSDD */ |
| 635 | | svi318_fdc.heads[id] = 2; |
| 616 | state->fdc.heads[id] = 2; |
| 636 | 617 | break; |
| 637 | 618 | case 348160: /* SVI-728 DSDD CP/M */ |
| 638 | | svi318_fdc.heads[id] = 2; |
| 619 | state->fdc.heads[id] = 2; |
| 639 | 620 | break; |
| 640 | 621 | } |
| 641 | 622 | } |
| 642 | 623 | |
| 643 | 624 | MACHINE_RESET( svi318 ) |
| 644 | 625 | { |
| 626 | svi318_state *state = machine->driver_data<svi318_state>(); |
| 645 | 627 | int drive; |
| 646 | 628 | /* video stuff */ |
| 647 | 629 | TMS9928A_reset(); |
| 648 | 630 | |
| 649 | | svi.bank_switch = 0xff; |
| 631 | state->svi.bank_switch = 0xff; |
| 650 | 632 | svi318_set_banks(machine); |
| 651 | 633 | |
| 652 | 634 | for(drive=0;drive<2;drive++) |
| r9683 | r9684 | |
| 668 | 650 | |
| 669 | 651 | WRITE8_HANDLER( svi318_writemem1 ) |
| 670 | 652 | { |
| 671 | | if ( svi.bankLow_read_only ) |
| 653 | svi318_state *state = space->machine->driver_data<svi318_state>(); |
| 654 | if ( state->svi.bankLow_read_only ) |
| 672 | 655 | return; |
| 673 | 656 | |
| 674 | | svi.bankLow_ptr[offset] = data; |
| 657 | state->svi.bankLow_ptr[offset] = data; |
| 675 | 658 | } |
| 676 | 659 | |
| 677 | 660 | WRITE8_HANDLER( svi318_writemem2 ) |
| 678 | 661 | { |
| 679 | | if ( svi.bankHigh1_read_only) |
| 662 | svi318_state *state = space->machine->driver_data<svi318_state>(); |
| 663 | if ( state->svi.bankHigh1_read_only) |
| 680 | 664 | return; |
| 681 | 665 | |
| 682 | | svi.bankHigh1_ptr[offset] = data; |
| 666 | state->svi.bankHigh1_ptr[offset] = data; |
| 683 | 667 | } |
| 684 | 668 | |
| 685 | 669 | WRITE8_HANDLER( svi318_writemem3 ) |
| 686 | 670 | { |
| 687 | | if ( svi.bankHigh2_read_only) |
| 671 | svi318_state *state = space->machine->driver_data<svi318_state>(); |
| 672 | if ( state->svi.bankHigh2_read_only) |
| 688 | 673 | return; |
| 689 | 674 | |
| 690 | | svi.bankHigh2_ptr[offset] = data; |
| 675 | state->svi.bankHigh2_ptr[offset] = data; |
| 691 | 676 | } |
| 692 | 677 | |
| 693 | 678 | WRITE8_HANDLER( svi318_writemem4 ) |
| 694 | 679 | { |
| 695 | | if ( svi.svi806_ram_enabled ) |
| 680 | svi318_state *state = space->machine->driver_data<svi318_state>(); |
| 681 | if ( state->svi.svi806_ram_enabled ) |
| 696 | 682 | { |
| 697 | 683 | if ( offset < 0x800 ) |
| 698 | 684 | { |
| 699 | | svi.svi806_ram->u8(offset) = data; |
| 685 | state->svi.svi806_ram->u8(offset) = data; |
| 700 | 686 | } |
| 701 | 687 | } |
| 702 | 688 | else |
| 703 | 689 | { |
| 704 | | if ( svi.bankHigh2_read_only ) |
| 690 | if ( state->svi.bankHigh2_read_only ) |
| 705 | 691 | return; |
| 706 | 692 | |
| 707 | | svi.bankHigh2_ptr[ 0x3000 + offset] = data; |
| 693 | state->svi.bankHigh2_ptr[ 0x3000 + offset] = data; |
| 708 | 694 | } |
| 709 | 695 | } |
| 710 | 696 | |
| 711 | 697 | static void svi318_set_banks(running_machine *machine) |
| 712 | 698 | { |
| 713 | | const UINT8 v = svi.bank_switch; |
| 699 | svi318_state *state = machine->driver_data<svi318_state>(); |
| 700 | const UINT8 v = state->svi.bank_switch; |
| 714 | 701 | |
| 715 | | svi.bankLow = ( v & 1 ) ? ( ( v & 2 ) ? ( ( v & 8 ) ? SVI_INTERNAL : SVI_EXPRAM3 ) : SVI_EXPRAM2 ) : SVI_CART; |
| 716 | | svi.bankHigh1 = ( v & 4 ) ? ( ( v & 16 ) ? SVI_INTERNAL : SVI_EXPRAM3 ) : SVI_EXPRAM2; |
| 702 | state->svi.bankLow = ( v & 1 ) ? ( ( v & 2 ) ? ( ( v & 8 ) ? SVI_INTERNAL : SVI_EXPRAM3 ) : SVI_EXPRAM2 ) : SVI_CART; |
| 703 | state->svi.bankHigh1 = ( v & 4 ) ? ( ( v & 16 ) ? SVI_INTERNAL : SVI_EXPRAM3 ) : SVI_EXPRAM2; |
| 717 | 704 | |
| 718 | | svi.bankLow_ptr = svi.empty_bank; |
| 719 | | svi.bankLow_read_only = 1; |
| 705 | state->svi.bankLow_ptr = state->svi.empty_bank; |
| 706 | state->svi.bankLow_read_only = 1; |
| 720 | 707 | |
| 721 | | switch( svi.bankLow ) |
| 708 | switch( state->svi.bankLow ) |
| 722 | 709 | { |
| 723 | 710 | case SVI_INTERNAL: |
| 724 | | svi.bankLow_ptr = memory_region(machine, "maincpu"); |
| 711 | state->svi.bankLow_ptr = memory_region(machine, "maincpu"); |
| 725 | 712 | break; |
| 726 | 713 | case SVI_CART: |
| 727 | | if ( pcart ) |
| 714 | if ( state->pcart ) |
| 728 | 715 | { |
| 729 | | svi.bankLow_ptr = pcart; |
| 716 | state->svi.bankLow_ptr = state->pcart; |
| 730 | 717 | } |
| 731 | 718 | break; |
| 732 | 719 | case SVI_EXPRAM2: |
| 733 | 720 | if ( messram_get_size(machine->device("messram")) >= 64 * 1024 ) |
| 734 | 721 | { |
| 735 | | svi.bankLow_ptr = messram_get_ptr(machine->device("messram")) + messram_get_size(machine->device("messram")) - 64 * 1024; |
| 736 | | svi.bankLow_read_only = 0; |
| 722 | state->svi.bankLow_ptr = messram_get_ptr(machine->device("messram")) + messram_get_size(machine->device("messram")) - 64 * 1024; |
| 723 | state->svi.bankLow_read_only = 0; |
| 737 | 724 | } |
| 738 | 725 | break; |
| 739 | 726 | case SVI_EXPRAM3: |
| 740 | 727 | if ( messram_get_size(machine->device("messram")) > 128 * 1024 ) |
| 741 | 728 | { |
| 742 | | svi.bankLow_ptr = messram_get_ptr(machine->device("messram")) + messram_get_size(machine->device("messram")) - 128 * 1024; |
| 743 | | svi.bankLow_read_only = 0; |
| 729 | state->svi.bankLow_ptr = messram_get_ptr(machine->device("messram")) + messram_get_size(machine->device("messram")) - 128 * 1024; |
| 730 | state->svi.bankLow_read_only = 0; |
| 744 | 731 | } |
| 745 | 732 | break; |
| 746 | 733 | } |
| 747 | 734 | |
| 748 | | svi.bankHigh1_ptr = svi.bankHigh2_ptr = svi.empty_bank; |
| 749 | | svi.bankHigh1_read_only = svi.bankHigh2_read_only = 1; |
| 735 | state->svi.bankHigh1_ptr = state->svi.bankHigh2_ptr = state->svi.empty_bank; |
| 736 | state->svi.bankHigh1_read_only = state->svi.bankHigh2_read_only = 1; |
| 750 | 737 | |
| 751 | | switch( svi.bankHigh1 ) |
| 738 | switch( state->svi.bankHigh1 ) |
| 752 | 739 | { |
| 753 | 740 | case SVI_INTERNAL: |
| 754 | 741 | if ( messram_get_size(machine->device("messram")) == 16 * 1024 ) |
| 755 | 742 | { |
| 756 | | svi.bankHigh2_ptr = messram_get_ptr(machine->device("messram")); |
| 757 | | svi.bankHigh2_read_only = 0; |
| 743 | state->svi.bankHigh2_ptr = messram_get_ptr(machine->device("messram")); |
| 744 | state->svi.bankHigh2_read_only = 0; |
| 758 | 745 | } |
| 759 | 746 | else |
| 760 | 747 | { |
| 761 | | svi.bankHigh1_ptr = messram_get_ptr(machine->device("messram")); |
| 762 | | svi.bankHigh1_read_only = 0; |
| 763 | | svi.bankHigh2_ptr = messram_get_ptr(machine->device("messram")) + 0x4000; |
| 764 | | svi.bankHigh2_read_only = 0; |
| 748 | state->svi.bankHigh1_ptr = messram_get_ptr(machine->device("messram")); |
| 749 | state->svi.bankHigh1_read_only = 0; |
| 750 | state->svi.bankHigh2_ptr = messram_get_ptr(machine->device("messram")) + 0x4000; |
| 751 | state->svi.bankHigh2_read_only = 0; |
| 765 | 752 | } |
| 766 | 753 | break; |
| 767 | 754 | case SVI_EXPRAM2: |
| 768 | 755 | if ( messram_get_size(machine->device("messram")) > 64 * 1024 ) |
| 769 | 756 | { |
| 770 | | svi.bankHigh1_ptr = messram_get_ptr(machine->device("messram")) + messram_get_size(machine->device("messram")) - 64 * 1024 + 32 * 1024; |
| 771 | | svi.bankHigh1_read_only = 0; |
| 772 | | svi.bankHigh2_ptr = messram_get_ptr(machine->device("messram")) + messram_get_size(machine->device("messram")) - 64 * 1024 + 48 * 1024; |
| 773 | | svi.bankHigh2_read_only = 0; |
| 757 | state->svi.bankHigh1_ptr = messram_get_ptr(machine->device("messram")) + messram_get_size(machine->device("messram")) - 64 * 1024 + 32 * 1024; |
| 758 | state->svi.bankHigh1_read_only = 0; |
| 759 | state->svi.bankHigh2_ptr = messram_get_ptr(machine->device("messram")) + messram_get_size(machine->device("messram")) - 64 * 1024 + 48 * 1024; |
| 760 | state->svi.bankHigh2_read_only = 0; |
| 774 | 761 | } |
| 775 | 762 | break; |
| 776 | 763 | case SVI_EXPRAM3: |
| 777 | 764 | if ( messram_get_size(machine->device("messram")) > 128 * 1024 ) |
| 778 | 765 | { |
| 779 | | svi.bankHigh1_ptr = messram_get_ptr(machine->device("messram")) + messram_get_size(machine->device("messram")) - 128 * 1024 + 32 * 1024; |
| 780 | | svi.bankHigh1_read_only = 0; |
| 781 | | svi.bankHigh2_ptr = messram_get_ptr(machine->device("messram")) + messram_get_size(machine->device("messram")) - 128 * 1024 + 48 * 1024; |
| 782 | | svi.bankHigh2_read_only = 0; |
| 766 | state->svi.bankHigh1_ptr = messram_get_ptr(machine->device("messram")) + messram_get_size(machine->device("messram")) - 128 * 1024 + 32 * 1024; |
| 767 | state->svi.bankHigh1_read_only = 0; |
| 768 | state->svi.bankHigh2_ptr = messram_get_ptr(machine->device("messram")) + messram_get_size(machine->device("messram")) - 128 * 1024 + 48 * 1024; |
| 769 | state->svi.bankHigh2_read_only = 0; |
| 783 | 770 | } |
| 784 | 771 | break; |
| 785 | 772 | } |
| 786 | 773 | |
| 787 | 774 | /* Check for special CART based banking */ |
| 788 | | if ( svi.bankLow == SVI_CART && ( v & 0xc0 ) != 0xc0 ) |
| 775 | if ( state->svi.bankLow == SVI_CART && ( v & 0xc0 ) != 0xc0 ) |
| 789 | 776 | { |
| 790 | | svi.bankHigh1_ptr = svi.empty_bank; |
| 791 | | svi.bankHigh1_read_only = 1; |
| 792 | | svi.bankHigh2_ptr = svi.empty_bank; |
| 793 | | svi.bankHigh2_read_only = 1; |
| 794 | | if ( pcart && ! ( v & 0x80 ) ) |
| 777 | state->svi.bankHigh1_ptr = state->svi.empty_bank; |
| 778 | state->svi.bankHigh1_read_only = 1; |
| 779 | state->svi.bankHigh2_ptr = state->svi.empty_bank; |
| 780 | state->svi.bankHigh2_read_only = 1; |
| 781 | if ( state->pcart && ! ( v & 0x80 ) ) |
| 795 | 782 | { |
| 796 | | svi.bankHigh2_ptr = pcart + 0x4000; |
| 783 | state->svi.bankHigh2_ptr = state->pcart + 0x4000; |
| 797 | 784 | } |
| 798 | | if ( pcart && ! ( v & 0x40 ) ) |
| 785 | if ( state->pcart && ! ( v & 0x40 ) ) |
| 799 | 786 | { |
| 800 | | svi.bankHigh1_ptr = pcart; |
| 787 | state->svi.bankHigh1_ptr = state->pcart; |
| 801 | 788 | } |
| 802 | 789 | } |
| 803 | 790 | |
| 804 | | memory_set_bankptr(machine, "bank1", svi.bankLow_ptr ); |
| 805 | | memory_set_bankptr(machine, "bank2", svi.bankHigh1_ptr ); |
| 806 | | memory_set_bankptr(machine, "bank3", svi.bankHigh2_ptr ); |
| 791 | memory_set_bankptr(machine, "bank1", state->svi.bankLow_ptr ); |
| 792 | memory_set_bankptr(machine, "bank2", state->svi.bankHigh1_ptr ); |
| 793 | memory_set_bankptr(machine, "bank3", state->svi.bankHigh2_ptr ); |
| 807 | 794 | |
| 808 | 795 | /* SVI-806 80 column card specific banking */ |
| 809 | | if ( svi.svi806_present ) |
| 796 | if ( state->svi.svi806_present ) |
| 810 | 797 | { |
| 811 | | if ( svi.svi806_ram_enabled ) |
| 798 | if ( state->svi.svi806_ram_enabled ) |
| 812 | 799 | { |
| 813 | | memory_set_bankptr(machine, "bank4", svi.svi806_ram ); |
| 800 | memory_set_bankptr(machine, "bank4", state->svi.svi806_ram ); |
| 814 | 801 | } |
| 815 | 802 | else |
| 816 | 803 | { |
| 817 | | memory_set_bankptr(machine, "bank4", svi.bankHigh2_ptr + 0x3000 ); |
| 804 | memory_set_bankptr(machine, "bank4", state->svi.bankHigh2_ptr + 0x3000 ); |
| 818 | 805 | } |
| 819 | 806 | } |
| 820 | 807 | } |
| r9683 | r9684 | |
| 834 | 821 | |
| 835 | 822 | READ8_HANDLER( svi318_io_ext_r ) |
| 836 | 823 | { |
| 824 | svi318_state *state = space->machine->driver_data<svi318_state>(); |
| 837 | 825 | UINT8 data = 0xff; |
| 838 | 826 | running_device *device; |
| 839 | 827 | |
| 840 | | if (svi.bankLow == SVI_CART) |
| 828 | if (state->svi.bankLow == SVI_CART) |
| 841 | 829 | { |
| 842 | 830 | return 0xff; |
| 843 | 831 | } |
| r9683 | r9684 | |
| 903 | 891 | |
| 904 | 892 | WRITE8_HANDLER( svi318_io_ext_w ) |
| 905 | 893 | { |
| 894 | svi318_state *state = space->machine->driver_data<svi318_state>(); |
| 906 | 895 | running_device *device; |
| 907 | 896 | |
| 908 | | if (svi.bankLow == SVI_CART) |
| 897 | if (state->svi.bankLow == SVI_CART) |
| 909 | 898 | { |
| 910 | 899 | return; |
| 911 | 900 | } |
src/mess/machine/pc8801.c
| r9683 | r9684 | |
| 23 | 23 | #include "machine/upd765.h" |
| 24 | 24 | #include "sound/beep.h" |
| 25 | 25 | |
| 26 | | static int ROMmode,RAMmode,maptvram; |
| 27 | | static int no4throm,no4throm2,port71_save; |
| 28 | | static unsigned char *mainROM; |
| 29 | | unsigned char *pc8801_mainRAM=NULL; |
| 30 | | static int is_V2mode,is_Nbasic,is_8MHz; |
| 31 | | int pc88sr_is_highspeed; |
| 32 | | static int port32_save; |
| 33 | | static int text_window; |
| 34 | | static int extmem_mode; |
| 35 | | static UINT8 *extRAM; |
| 36 | | static int extRAM_size; |
| 37 | | static void *ext_bank_80[4],*ext_bank_88[256]; |
| 38 | | static UINT8 extmem_ctrl[2]; |
| 39 | 26 | |
| 40 | | static int use_5FD; |
| 41 | 27 | static void pc8801_init_5fd(running_machine *machine); |
| 42 | 28 | |
| 43 | | static void pc88sr_init_fmsound(void); |
| 44 | | static int enable_FM_IRQ; |
| 45 | | static int FM_IRQ_save; |
| 29 | static void pc88sr_init_fmsound(running_machine *machine); |
| 46 | 30 | #define FM_IRQ_LEVEL 4 |
| 47 | 31 | |
| 48 | 32 | WRITE8_HANDLER( pc88_rtc_w ) |
| r9683 | r9684 | |
| 63 | 47 | |
| 64 | 48 | /* interrupt staff */ |
| 65 | 49 | |
| 66 | | static int interrupt_level_reg; |
| 67 | | static int interrupt_mask_reg; |
| 68 | | static int interrupt_trig_reg; |
| 69 | 50 | |
| 70 | 51 | static void pc8801_update_interrupt(running_machine *machine) |
| 71 | 52 | { |
| 53 | pc88_state *state = machine->driver_data<pc88_state>(); |
| 72 | 54 | int level, i; |
| 73 | 55 | |
| 74 | 56 | level = -1; |
| 75 | 57 | for (i = 0; i < 8; i++) |
| 76 | 58 | { |
| 77 | | if ((interrupt_trig_reg & (1<<i)) != 0) |
| 59 | if ((state->interrupt_trig_reg & (1<<i)) != 0) |
| 78 | 60 | level = i; |
| 79 | 61 | } |
| 80 | | if (level >= 0 && level<interrupt_level_reg) |
| 62 | if (level >= 0 && level<state->interrupt_level_reg) |
| 81 | 63 | { |
| 82 | 64 | cputag_set_input_line(machine, "maincpu", 0, HOLD_LINE); |
| 83 | 65 | } |
| r9683 | r9684 | |
| 85 | 67 | |
| 86 | 68 | static IRQ_CALLBACK( pc8801_interrupt_callback ) |
| 87 | 69 | { |
| 70 | pc88_state *state = device->machine->driver_data<pc88_state>(); |
| 88 | 71 | int level, i; |
| 89 | 72 | |
| 90 | 73 | level = 0; |
| 91 | 74 | for (i = 0; i < 8; i++) |
| 92 | 75 | { |
| 93 | | if ((interrupt_trig_reg & (1<<i))!=0) |
| 76 | if ((state->interrupt_trig_reg & (1<<i))!=0) |
| 94 | 77 | level = i; |
| 95 | 78 | } |
| 96 | | interrupt_trig_reg &= ~(1<<level); |
| 79 | state->interrupt_trig_reg &= ~(1<<level); |
| 97 | 80 | return level*2; |
| 98 | 81 | } |
| 99 | 82 | |
| 100 | 83 | WRITE8_HANDLER( pc8801_write_interrupt_level ) |
| 101 | 84 | { |
| 102 | | interrupt_level_reg = data&0x0f; |
| 85 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 86 | state->interrupt_level_reg = data&0x0f; |
| 103 | 87 | pc8801_update_interrupt(space->machine); |
| 104 | 88 | } |
| 105 | 89 | |
| 106 | 90 | WRITE8_HANDLER( pc8801_write_interrupt_mask ) |
| 107 | 91 | { |
| 108 | | interrupt_mask_reg = ((data&0x01)<<2) | (data&0x02) |
| 92 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 93 | state->interrupt_mask_reg = ((data&0x01)<<2) | (data&0x02) |
| 109 | 94 | | ((data&0x04)>>2) | 0xf8; |
| 110 | 95 | } |
| 111 | 96 | |
| 112 | 97 | static void pc8801_raise_interrupt(running_machine *machine, int level) |
| 113 | 98 | { |
| 114 | | interrupt_trig_reg |= interrupt_mask_reg & (1<<level); |
| 99 | pc88_state *state = machine->driver_data<pc88_state>(); |
| 100 | state->interrupt_trig_reg |= state->interrupt_mask_reg & (1<<level); |
| 115 | 101 | pc8801_update_interrupt(machine); |
| 116 | 102 | } |
| 117 | 103 | |
| r9683 | r9684 | |
| 127 | 113 | |
| 128 | 114 | static void pc8801_init_interrupt(running_machine *machine) |
| 129 | 115 | { |
| 130 | | interrupt_level_reg = 0; |
| 131 | | interrupt_mask_reg = 0xf8; |
| 132 | | interrupt_trig_reg = 0x0; |
| 116 | pc88_state *state = machine->driver_data<pc88_state>(); |
| 117 | state->interrupt_level_reg = 0; |
| 118 | state->interrupt_mask_reg = 0xf8; |
| 119 | state->interrupt_trig_reg = 0x0; |
| 133 | 120 | cpu_set_irq_callback(machine->device("maincpu"), pc8801_interrupt_callback); |
| 134 | 121 | } |
| 135 | 122 | |
| r9683 | r9684 | |
| 179 | 166 | UINT8 r; |
| 180 | 167 | |
| 181 | 168 | r = centronics_busy_r(state->centronics); |
| 182 | | r |= pc8801_is_24KHz ? 0x00 : 0x02; |
| 183 | | r |= use_5FD ? 0x00 : 0x08; |
| 169 | r |= state->is_24KHz ? 0x00 : 0x02; |
| 170 | r |= state->use_5FD ? 0x00 : 0x08; |
| 184 | 171 | r |= upd1990a_data_out_r(state->upd1990a) ? 0x10 : 0x00; |
| 185 | 172 | if(space->machine->primary_screen->vblank()) r|=0x20; |
| 186 | 173 | |
| r9683 | r9684 | |
| 199 | 186 | bit 7: N88-BASIC version (0 = V2.x, 1 = V1.x) |
| 200 | 187 | */ |
| 201 | 188 | { |
| 189 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 202 | 190 | int r; |
| 203 | 191 | |
| 204 | 192 | /* read DIP-SW */ |
| 205 | 193 | r=input_port_read(space->machine, "DSW2")<<1; |
| 206 | 194 | /* change bit 6 according speed switch */ |
| 207 | | if(pc88sr_is_highspeed) { |
| 195 | if(state->pc88sr_is_highspeed) { |
| 208 | 196 | r|=0x40; |
| 209 | 197 | } else { |
| 210 | 198 | r&=0xbf; |
| 211 | 199 | } |
| 212 | 200 | /* change bit 7 according BASIC mode */ |
| 213 | | if(is_V2mode) { |
| 201 | if(state->is_V2mode) { |
| 214 | 202 | r&=0x7f; |
| 215 | 203 | } else { |
| 216 | 204 | r|=0x80; |
| r9683 | r9684 | |
| 220 | 208 | |
| 221 | 209 | static WRITE8_HANDLER( pc8801_writemem1 ) |
| 222 | 210 | { |
| 223 | | pc8801_mainRAM[offset]=data; |
| 211 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 212 | state->mainRAM[offset]=data; |
| 224 | 213 | } |
| 225 | 214 | |
| 226 | 215 | static WRITE8_HANDLER( pc8801_writemem2 ) |
| 227 | 216 | { |
| 228 | | pc8801_mainRAM[offset+0x6000]=data; |
| 217 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 218 | state->mainRAM[offset+0x6000]=data; |
| 229 | 219 | } |
| 230 | 220 | |
| 231 | 221 | static READ8_HANDLER( pc8801_read_textwindow ) |
| 232 | 222 | { |
| 233 | | return pc8801_mainRAM[(offset+text_window*0x100)&0xffff]; |
| 223 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 224 | return state->mainRAM[(offset+state->text_window*0x100)&0xffff]; |
| 234 | 225 | } |
| 235 | 226 | |
| 236 | 227 | static WRITE8_HANDLER( pc8801_write_textwindow ) |
| 237 | 228 | { |
| 238 | | pc8801_mainRAM[(offset+text_window*0x100)&0xffff]=data; |
| 229 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 230 | state->mainRAM[(offset+state->text_window*0x100)&0xffff]=data; |
| 239 | 231 | } |
| 240 | 232 | |
| 241 | | static void select_extmem(char **r,char **w,UINT8 *ret_ctrl) |
| 233 | static void select_extmem(pc88_state *state, char **r,char **w,UINT8 *ret_ctrl) |
| 242 | 234 | { |
| 243 | 235 | int i; |
| 244 | 236 | |
| r9683 | r9684 | |
| 281 | 273 | } \ |
| 282 | 274 | } while(0); |
| 283 | 275 | |
| 284 | | if(ext_bank_88[extmem_ctrl[1]]!=NULL) { |
| 285 | | if(extmem_ctrl[0]&0x01) SET_RADDR(ext_bank_88[extmem_ctrl[1]]); |
| 286 | | if(extmem_ctrl[0]&0x10) SET_WADDR(ext_bank_88[extmem_ctrl[1]]); |
| 287 | | SET_RET(0,(~extmem_ctrl[0])&0x11) |
| 288 | | if(ext_bank_88[extmem_ctrl[1]]==ext_bank_88[extmem_ctrl[1]&0x0f]) { |
| 276 | if(state->ext_bank_88[state->extmem_ctrl[1]]!=NULL) { |
| 277 | if(state->extmem_ctrl[0]&0x01) SET_RADDR(state->ext_bank_88[state->extmem_ctrl[1]]); |
| 278 | if(state->extmem_ctrl[0]&0x10) SET_WADDR(state->ext_bank_88[state->extmem_ctrl[1]]); |
| 279 | SET_RET(0,(~state->extmem_ctrl[0])&0x11) |
| 280 | if(state->ext_bank_88[state->extmem_ctrl[1]]==state->ext_bank_88[state->extmem_ctrl[1]&0x0f]) { |
| 289 | 281 | /* PC-8801-N02 */ |
| 290 | | SET_RET(1,extmem_ctrl[1]&0x0f); |
| 282 | SET_RET(1,state->extmem_ctrl[1]&0x0f); |
| 291 | 283 | } else { |
| 292 | 284 | /* PIO-8234H */ |
| 293 | | SET_RET(1,extmem_ctrl[1]); |
| 285 | SET_RET(1,state->extmem_ctrl[1]); |
| 294 | 286 | } |
| 295 | 287 | } |
| 296 | 288 | |
| 297 | 289 | for(i=0;i<4;i++) { |
| 298 | | if(ext_bank_80[i]!=NULL) { |
| 299 | | if(extmem_ctrl[0]&(0x01<<i)) { |
| 300 | | SET_RADDR(ext_bank_80[i]); |
| 290 | if(state->ext_bank_80[i]!=NULL) { |
| 291 | if(state->extmem_ctrl[0]&(0x01<<i)) { |
| 292 | SET_RADDR(state->ext_bank_80[i]); |
| 301 | 293 | SET_RET(0,(0x01<<i)|0xf0); |
| 302 | 294 | } |
| 303 | | if(extmem_ctrl[0]&(0x10<<i)) SET_WADDR(ext_bank_80[i]); |
| 295 | if(state->extmem_ctrl[0]&(0x10<<i)) SET_WADDR(state->ext_bank_80[i]); |
| 304 | 296 | } |
| 305 | 297 | } |
| 306 | 298 | |
| r9683 | r9684 | |
| 311 | 303 | |
| 312 | 304 | void pc8801_update_bank(running_machine *machine) |
| 313 | 305 | { |
| 306 | pc88_state *state = machine->driver_data<pc88_state>(); |
| 314 | 307 | address_space *program = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM); |
| 315 | 308 | char *ext_r,*ext_w; |
| 316 | 309 | |
| 317 | | select_extmem(&ext_r,&ext_w,NULL); |
| 310 | select_extmem(state, &ext_r,&ext_w,NULL); |
| 318 | 311 | if (ext_r!=NULL || ext_w!=NULL) |
| 319 | 312 | { |
| 320 | 313 | if (ext_r==NULL) |
| r9683 | r9684 | |
| 343 | 336 | else |
| 344 | 337 | { |
| 345 | 338 | /* 0x0000 to 0x7fff */ |
| 346 | | if(RAMmode) |
| 339 | if(state->RAMmode) |
| 347 | 340 | { |
| 348 | 341 | /* RAM */ |
| 349 | 342 | memory_install_write_bank(program, 0x0000, 0x5fff, 0, 0, "bank1"); |
| 350 | 343 | memory_install_write_bank(program, 0x6000, 0x7fff, 0, 0, "bank2"); |
| 351 | | memory_set_bankptr(machine, "bank1", pc8801_mainRAM + 0x0000); |
| 352 | | memory_set_bankptr(machine, "bank2", pc8801_mainRAM + 0x6000); |
| 344 | memory_set_bankptr(machine, "bank1", state->mainRAM + 0x0000); |
| 345 | memory_set_bankptr(machine, "bank2", state->mainRAM + 0x6000); |
| 353 | 346 | } |
| 354 | 347 | else |
| 355 | 348 | { |
| r9683 | r9684 | |
| 357 | 350 | /* write through to main RAM */ |
| 358 | 351 | memory_install_write8_handler(program, 0x0000, 0x5fff, 0, 0, pc8801_writemem1); |
| 359 | 352 | memory_install_write8_handler(program, 0x6000, 0x7fff, 0, 0, pc8801_writemem2); |
| 360 | | if(ROMmode) |
| 353 | if(state->ROMmode) |
| 361 | 354 | { |
| 362 | 355 | /* N-BASIC */ |
| 363 | | memory_set_bankptr(machine, "bank1", mainROM + 0x0000); |
| 364 | | memory_set_bankptr(machine, "bank2", mainROM + 0x6000); |
| 356 | memory_set_bankptr(machine, "bank1", state->mainROM + 0x0000); |
| 357 | memory_set_bankptr(machine, "bank2", state->mainROM + 0x6000); |
| 365 | 358 | } |
| 366 | 359 | else |
| 367 | 360 | { |
| 368 | 361 | /* N88-BASIC */ |
| 369 | | memory_set_bankptr(machine, "bank1", mainROM + 0x8000); |
| 370 | | if(no4throm==1) { |
| 362 | memory_set_bankptr(machine, "bank1", state->mainROM + 0x8000); |
| 363 | if(state->no4throm==1) { |
| 371 | 364 | /* 4th ROM 1 */ |
| 372 | | memory_set_bankptr(machine, "bank2", mainROM + 0x10000 + 0x2000 * no4throm2); |
| 365 | memory_set_bankptr(machine, "bank2", state->mainROM + 0x10000 + 0x2000 * state->no4throm2); |
| 373 | 366 | } else { |
| 374 | | memory_set_bankptr(machine, "bank2", mainROM + 0xe000); |
| 367 | memory_set_bankptr(machine, "bank2", state->mainROM + 0xe000); |
| 375 | 368 | } |
| 376 | 369 | } |
| 377 | 370 | } |
| 378 | 371 | } |
| 379 | 372 | |
| 380 | 373 | /* 0x8000 to 0xffff */ |
| 381 | | if (RAMmode || ROMmode) { |
| 374 | if (state->RAMmode || state->ROMmode) { |
| 382 | 375 | memory_install_readwrite_bank(program, 0x8000, 0x83ff, 0, 0, "bank3"); |
| 383 | 376 | } else { |
| 384 | 377 | memory_install_readwrite8_handler(program, 0x8000, 0x83ff, 0, 0, pc8801_read_textwindow, pc8801_write_textwindow); |
| 385 | 378 | } |
| 386 | 379 | |
| 387 | | memory_set_bankptr(machine, "bank4", pc8801_mainRAM + 0x8400); |
| 380 | memory_set_bankptr(machine, "bank4", state->mainRAM + 0x8400); |
| 388 | 381 | |
| 389 | 382 | if (pc8801_is_vram_select(machine)) |
| 390 | 383 | { |
| r9683 | r9684 | |
| 396 | 389 | memory_install_readwrite_bank(program, 0xc000, 0xefff, 0, 0, "bank5"); |
| 397 | 390 | memory_install_readwrite_bank(program, 0xf000, 0xffff, 0, 0, "bank6"); |
| 398 | 391 | |
| 399 | | memory_set_bankptr(machine, "bank5", pc8801_mainRAM + 0xc000); |
| 400 | | if(maptvram) |
| 401 | | memory_set_bankptr(machine, "bank6", pc88sr_textRAM); |
| 392 | memory_set_bankptr(machine, "bank5", state->mainRAM + 0xc000); |
| 393 | if(state->maptvram) |
| 394 | memory_set_bankptr(machine, "bank6", state->pc88sr_textRAM); |
| 402 | 395 | else |
| 403 | | memory_set_bankptr(machine, "bank6", pc8801_mainRAM + 0xf000); |
| 396 | memory_set_bankptr(machine, "bank6", state->mainRAM + 0xf000); |
| 404 | 397 | } |
| 405 | 398 | } |
| 406 | 399 | |
| 407 | 400 | READ8_HANDLER( pc88_extmem_r ) |
| 408 | 401 | { |
| 402 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 409 | 403 | UINT8 ret[2]; |
| 410 | | select_extmem(NULL,NULL,ret); |
| 404 | select_extmem(state,NULL,NULL,ret); |
| 411 | 405 | return ret[offset]; |
| 412 | 406 | } |
| 413 | 407 | |
| 414 | 408 | WRITE8_HANDLER( pc88_extmem_w ) |
| 415 | 409 | { |
| 416 | | extmem_ctrl[offset]=data; |
| 410 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 411 | state->extmem_ctrl[offset]=data; |
| 417 | 412 | pc8801_update_bank(space->machine); |
| 418 | 413 | } |
| 419 | 414 | |
| 420 | 415 | WRITE8_HANDLER( pc88sr_outport_31 ) |
| 421 | 416 | { |
| 417 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 422 | 418 | /* bit 5 not implemented */ |
| 423 | | RAMmode=((data&0x02)!=0); |
| 424 | | ROMmode=((data&0x04)!=0); |
| 419 | state->RAMmode=((data&0x02)!=0); |
| 420 | state->ROMmode=((data&0x04)!=0); |
| 425 | 421 | pc8801_update_bank(space->machine); |
| 426 | 422 | pc88sr_disp_31(space, offset,data); |
| 427 | 423 | } |
| 428 | 424 | |
| 429 | 425 | READ8_HANDLER( pc88sr_inport_32 ) |
| 430 | 426 | { |
| 431 | | return(port32_save); |
| 427 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 428 | return(state->port32_save); |
| 432 | 429 | } |
| 433 | 430 | |
| 434 | 431 | WRITE8_HANDLER( pc88sr_outport_32 ) |
| 435 | 432 | { |
| 433 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 436 | 434 | /* bit 2, 3 not implemented */ |
| 437 | | port32_save=data; |
| 438 | | maptvram=((data&0x10)==0); |
| 439 | | no4throm2=(data&3); |
| 440 | | enable_FM_IRQ=((data & 0x80) == 0x00); |
| 441 | | if(FM_IRQ_save && enable_FM_IRQ) pc8801_raise_interrupt(space->machine, FM_IRQ_LEVEL); |
| 435 | state->port32_save=data; |
| 436 | state->maptvram=((data&0x10)==0); |
| 437 | state->no4throm2=(data&3); |
| 438 | state->enable_FM_IRQ=((data & 0x80) == 0x00); |
| 439 | if(state->FM_IRQ_save && state->enable_FM_IRQ) pc8801_raise_interrupt(space->machine, FM_IRQ_LEVEL); |
| 442 | 440 | pc88sr_disp_32(space, offset,data); |
| 443 | 441 | pc8801_update_bank(space->machine); |
| 444 | 442 | } |
| 445 | 443 | |
| 446 | 444 | READ8_HANDLER( pc8801_inport_70 ) |
| 447 | 445 | { |
| 448 | | return text_window; |
| 446 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 447 | return state->text_window; |
| 449 | 448 | } |
| 450 | 449 | |
| 451 | 450 | WRITE8_HANDLER( pc8801_outport_70 ) |
| 452 | 451 | { |
| 453 | | text_window=data; |
| 452 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 453 | state->text_window=data; |
| 454 | 454 | pc8801_update_bank(space->machine); |
| 455 | 455 | } |
| 456 | 456 | |
| 457 | 457 | WRITE8_HANDLER( pc8801_outport_78 ) |
| 458 | 458 | { |
| 459 | | text_window=((text_window+1)&0xff); |
| 459 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 460 | state->text_window=((state->text_window+1)&0xff); |
| 460 | 461 | pc8801_update_bank(space->machine); |
| 461 | 462 | } |
| 462 | 463 | |
| 463 | 464 | READ8_HANDLER( pc88sr_inport_71 ) |
| 464 | 465 | { |
| 465 | | return(port71_save); |
| 466 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 467 | return(state->port71_save); |
| 466 | 468 | } |
| 467 | 469 | |
| 468 | 470 | WRITE8_HANDLER( pc88sr_outport_71 ) |
| 469 | 471 | /* bit 1-7 not implemented (no ROMs) */ |
| 470 | 472 | { |
| 471 | | port71_save=data; |
| 473 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 474 | state->port71_save=data; |
| 472 | 475 | switch(data) { |
| 473 | | case 0xff: no4throm=0; break; |
| 474 | | case 0xfe: no4throm=1; break; |
| 475 | | case 0xfd: no4throm=2; break; |
| 476 | | case 0xfb: no4throm=3; break; |
| 477 | | case 0xf7: no4throm=4; break; |
| 478 | | case 0xef: no4throm=5; break; |
| 479 | | case 0xdf: no4throm=6; break; |
| 480 | | case 0xbf: no4throm=7; break; |
| 481 | | case 0x7f: no4throm=8; break; |
| 476 | case 0xff: state->no4throm=0; break; |
| 477 | case 0xfe: state->no4throm=1; break; |
| 478 | case 0xfd: state->no4throm=2; break; |
| 479 | case 0xfb: state->no4throm=3; break; |
| 480 | case 0xf7: state->no4throm=4; break; |
| 481 | case 0xef: state->no4throm=5; break; |
| 482 | case 0xdf: state->no4throm=6; break; |
| 483 | case 0xbf: state->no4throm=7; break; |
| 484 | case 0x7f: state->no4throm=8; break; |
| 482 | 485 | default: |
| 483 | 486 | logerror ("pc8801 : write illegal data 0x%.2x to port 0x71, select main rom.\n",data); |
| 484 | | no4throm=0; |
| 487 | state->no4throm=0; |
| 485 | 488 | break; |
| 486 | 489 | } |
| 487 | 490 | pc8801_update_bank(space->machine); |
| r9683 | r9684 | |
| 490 | 493 | // FIXME: shouldn't we use ram device in place of the below code? |
| 491 | 494 | static void pc8801_init_bank(running_machine *machine, int hireso) |
| 492 | 495 | { |
| 496 | pc88_state *state = machine->driver_data<pc88_state>(); |
| 493 | 497 | int i,j; |
| 494 | 498 | int num80,num88,numIO; |
| 495 | 499 | unsigned char *e; |
| 496 | 500 | |
| 497 | | RAMmode=0; |
| 498 | | ROMmode=0; |
| 499 | | maptvram=0; |
| 500 | | no4throm=0; |
| 501 | | no4throm2=0; |
| 502 | | port71_save=0xff; |
| 503 | | port32_save=0x80; |
| 504 | | mainROM = memory_region(machine, "maincpu"); |
| 505 | | pc8801_mainRAM = auto_alloc_array_clear(machine, UINT8, 0x10000); |
| 501 | state->RAMmode=0; |
| 502 | state->ROMmode=0; |
| 503 | state->maptvram=0; |
| 504 | state->no4throm=0; |
| 505 | state->no4throm2=0; |
| 506 | state->port71_save=0xff; |
| 507 | state->port32_save=0x80; |
| 508 | state->mainROM = memory_region(machine, "maincpu"); |
| 509 | state->mainRAM = auto_alloc_array_clear(machine, UINT8, 0x10000); |
| 506 | 510 | |
| 507 | | extmem_ctrl[0]=extmem_ctrl[1]=0; |
| 511 | state->extmem_ctrl[0]=state->extmem_ctrl[1]=0; |
| 508 | 512 | pc8801_update_bank(machine); |
| 509 | 513 | pc8801_video_init(machine, hireso); |
| 510 | 514 | |
| 511 | | if (extmem_mode != input_port_read(machine, "MEM")) |
| 515 | if (state->extmem_mode != input_port_read(machine, "MEM")) |
| 512 | 516 | { |
| 513 | | extmem_mode = input_port_read(machine, "MEM"); |
| 517 | state->extmem_mode = input_port_read(machine, "MEM"); |
| 514 | 518 | |
| 515 | 519 | // reset all the bank-related quantities |
| 516 | | memset(extRAM, 0, extRAM_size); |
| 520 | memset(state->extRAM, 0, state->extRAM_size); |
| 517 | 521 | |
| 518 | 522 | for (i = 0; i < 4; i++) |
| 519 | | ext_bank_80[i] = NULL; |
| 523 | state->ext_bank_80[i] = NULL; |
| 520 | 524 | |
| 521 | 525 | for (i = 0; i < 256; i++) |
| 522 | | ext_bank_88[i] = NULL; |
| 526 | state->ext_bank_88[i] = NULL; |
| 523 | 527 | |
| 524 | 528 | num80 = num88 = numIO = 0; |
| 525 | 529 | |
| 526 | 530 | // set up the required number of banks |
| 527 | | switch (extmem_mode) |
| 531 | switch (state->extmem_mode) |
| 528 | 532 | { |
| 529 | 533 | case 0x00: /* none */ |
| 530 | 534 | break; |
| r9683 | r9684 | |
| 578 | 582 | // point the banks to the correct memory |
| 579 | 583 | if (num80 != 0 || num88 != 0 || numIO != 0) |
| 580 | 584 | { |
| 581 | | e = extRAM; |
| 585 | e = state->extRAM; |
| 582 | 586 | |
| 583 | 587 | for (i = 0; i < num80; i++) |
| 584 | 588 | { |
| 585 | | ext_bank_80[i] = e; |
| 589 | state->ext_bank_80[i] = e; |
| 586 | 590 | e += 0x8000; |
| 587 | 591 | } |
| 588 | 592 | |
| r9683 | r9684 | |
| 590 | 594 | { |
| 591 | 595 | for (j = i; j < 256; j += 16) |
| 592 | 596 | { |
| 593 | | ext_bank_88[j] = e; |
| 597 | state->ext_bank_88[j] = e; |
| 594 | 598 | } |
| 595 | 599 | e += 0x8000; |
| 596 | 600 | } |
| r9683 | r9684 | |
| 599 | 603 | { |
| 600 | 604 | for (i = 0; i < numIO * 32; i++) |
| 601 | 605 | { |
| 602 | | ext_bank_88[(i & 0x07) | ((i & 0x18) << 1) | ((i & 0x20) >> 2) | (i & 0xc0)] = e; |
| 606 | state->ext_bank_88[(i & 0x07) | ((i & 0x18) << 1) | ((i & 0x20) >> 2) | (i & 0xc0)] = e; |
| 603 | 607 | e += 0x8000; |
| 604 | 608 | } |
| 605 | 609 | } |
| r9683 | r9684 | |
| 607 | 611 | { |
| 608 | 612 | for (i = 0; i < numIO * 32; i++) |
| 609 | 613 | { |
| 610 | | ext_bank_88[(i & 0x07) | ((i & 0x78) << 1) | 0x08] = e; |
| 614 | state->ext_bank_88[(i & 0x07) | ((i & 0x78) << 1) | 0x08] = e; |
| 611 | 615 | e += 0x8000; |
| 612 | 616 | } |
| 613 | 617 | } |
| r9683 | r9684 | |
| 615 | 619 | } |
| 616 | 620 | } |
| 617 | 621 | |
| 618 | | static void fix_V1V2(void) |
| 622 | static void fix_V1V2(pc88_state *state) |
| 619 | 623 | { |
| 620 | | if(is_Nbasic) is_V2mode=0; |
| 621 | | if(is_V2mode) pc88sr_is_highspeed=1; |
| 622 | | switch((is_Nbasic ? 1 : 0) | |
| 623 | | (is_V2mode ? 2 : 0) | |
| 624 | | (pc88sr_is_highspeed ? 4 : 0)) |
| 624 | if(state->is_Nbasic) state->is_V2mode=0; |
| 625 | if(state->is_V2mode) state->pc88sr_is_highspeed=1; |
| 626 | switch((state->is_Nbasic ? 1 : 0) | |
| 627 | (state->is_V2mode ? 2 : 0) | |
| 628 | (state->pc88sr_is_highspeed ? 4 : 0)) |
| 625 | 629 | { |
| 626 | 630 | case 0: |
| 627 | 631 | logerror("N88-BASIC(V1-S)"); |
| r9683 | r9684 | |
| 639 | 643 | logerror("N88-BASIC(V2)"); |
| 640 | 644 | break; |
| 641 | 645 | default: |
| 642 | | fatalerror("Illegal basic mode=(%d,%d,%d)",is_Nbasic,is_V2mode,pc88sr_is_highspeed); |
| 646 | fatalerror("Illegal basic mode=(%d,%d,%d)",state->is_Nbasic,state->is_V2mode,state->pc88sr_is_highspeed); |
| 643 | 647 | break; |
| 644 | 648 | } |
| 645 | | if(is_8MHz) { |
| 649 | if(state->is_8MHz) { |
| 646 | 650 | logerror(", 8MHz\n"); |
| 647 | 651 | } else { |
| 648 | 652 | logerror(", 4MHz\n"); |
| r9683 | r9684 | |
| 651 | 655 | |
| 652 | 656 | static void pc88sr_ch_reset(running_machine *machine, int hireso) |
| 653 | 657 | { |
| 658 | pc88_state *state = machine->driver_data<pc88_state>(); |
| 654 | 659 | running_device *speaker = machine->device("beep"); |
| 655 | 660 | int a; |
| 656 | 661 | |
| r9683 | r9684 | |
| 658 | 663 | // but I guess this was the reason of bug #1952. So we now allocate the maximum |
| 659 | 664 | // possible amount of extended RAM, and then we only use the amount we need. |
| 660 | 665 | // eventually, we should convert the driver to use the ram device, imho. |
| 661 | | extRAM_size = 4 * 0x8000 + 4 * 0x20000 + 8 * 0x100000; |
| 662 | | extRAM = auto_alloc_array_clear(machine, UINT8, extRAM_size); |
| 666 | state->extRAM_size = 4 * 0x8000 + 4 * 0x20000 + 8 * 0x100000; |
| 667 | state->extRAM = auto_alloc_array_clear(machine, UINT8, state->extRAM_size); |
| 663 | 668 | |
| 664 | 669 | a = input_port_read(machine, "CFG"); |
| 665 | | is_Nbasic = ((a&0x01)==0x00); |
| 666 | | is_V2mode = ((a&0x02)==0x00); |
| 667 | | pc88sr_is_highspeed = ((a&0x04)!=0x00); |
| 668 | | is_8MHz = ((a&0x08)!=0x00); |
| 669 | | fix_V1V2(); |
| 670 | state->is_Nbasic = ((a&0x01)==0x00); |
| 671 | state->is_V2mode = ((a&0x02)==0x00); |
| 672 | state->pc88sr_is_highspeed = ((a&0x04)!=0x00); |
| 673 | state->is_8MHz = ((a&0x08)!=0x00); |
| 674 | fix_V1V2(state); |
| 670 | 675 | pc8801_init_bank(machine, hireso); |
| 671 | 676 | pc8801_init_5fd(machine); |
| 672 | 677 | pc8801_init_interrupt(machine); |
| 673 | 678 | beep_set_state(speaker, 0); |
| 674 | 679 | beep_set_frequency(speaker, 2400); |
| 675 | | pc88sr_init_fmsound(); |
| 680 | pc88sr_init_fmsound(machine); |
| 676 | 681 | } |
| 677 | 682 | |
| 678 | 683 | /* 5 inch floppy drive */ |
| r9683 | r9684 | |
| 752 | 757 | |
| 753 | 758 | static void pc8801_init_5fd(running_machine *machine) |
| 754 | 759 | { |
| 755 | | use_5FD = (input_port_read(machine, "DSW2") & 0x80) != 0x00; |
| 760 | pc88_state *state = machine->driver_data<pc88_state>(); |
| 761 | state->use_5FD = (input_port_read(machine, "DSW2") & 0x80) != 0x00; |
| 756 | 762 | |
| 757 | | if (!use_5FD) |
| 763 | if (!state->use_5FD) |
| 758 | 764 | machine->device<cpu_device>("sub")->suspend(SUSPEND_REASON_DISABLE, 1); |
| 759 | 765 | else |
| 760 | 766 | machine->device<cpu_device>("sub")->resume(SUSPEND_REASON_DISABLE); |
| r9683 | r9684 | |
| 771 | 777 | FM sound |
| 772 | 778 | */ |
| 773 | 779 | |
| 774 | | static void pc88sr_init_fmsound(void) |
| 780 | static void pc88sr_init_fmsound(running_machine *machine) |
| 775 | 781 | { |
| 776 | | enable_FM_IRQ=0; |
| 777 | | FM_IRQ_save=0; |
| 782 | pc88_state *state = machine->driver_data<pc88_state>(); |
| 783 | state->enable_FM_IRQ=0; |
| 784 | state->FM_IRQ_save=0; |
| 778 | 785 | } |
| 779 | 786 | |
| 780 | 787 | void pc88sr_sound_interupt(running_device *device, int irq) |
| 781 | 788 | { |
| 782 | | FM_IRQ_save=irq; |
| 783 | | if(FM_IRQ_save && enable_FM_IRQ) |
| 789 | pc88_state *state = device->machine->driver_data<pc88_state>(); |
| 790 | state->FM_IRQ_save=irq; |
| 791 | if(state->FM_IRQ_save && state->enable_FM_IRQ) |
| 784 | 792 | pc8801_raise_interrupt(device->machine, FM_IRQ_LEVEL); |
| 785 | 793 | } |
| 786 | 794 | |
| r9683 | r9684 | |
| 846 | 854 | { |
| 847 | 855 | pc88_state *state = machine->driver_data<pc88_state>(); |
| 848 | 856 | |
| 849 | | extmem_mode = -1; |
| 857 | state->extmem_mode = -1; |
| 850 | 858 | |
| 851 | 859 | /* find devices */ |
| 852 | 860 | state->upd765 = machine->device(UPD765_TAG); |
src/mess/video/pc8801.c
| r9683 | r9684 | |
| 14 | 14 | /* NPW 23-Oct-2001 - Adding this so that it compiles */ |
| 15 | 15 | #define palette_transparent_pen 0 |
| 16 | 16 | |
| 17 | | unsigned char *pc88sr_textRAM = NULL; |
| 18 | | int pc8801_is_24KHz; |
| 19 | | static unsigned char *gVRAM = NULL; |
| 20 | | static int selected_vram; |
| 21 | | static int crtc_on, text_on, text_width, text_height, text_invert, text_color; |
| 22 | | static int text_cursor, text_cursorX, text_cursorY; |
| 23 | | static int blink_period; |
| 24 | | static int analog_palette; |
| 25 | | static int alu_1, alu_2, alu_on; |
| 26 | | static unsigned char alu_save0, alu_save1, alu_save2; |
| 27 | 17 | |
| 28 | | static int dmac_fl; |
| 29 | | static UINT16 dmac_addr[3], dmac_size[3]; |
| 30 | | static UINT8 dmac_flag, dmac_status; |
| 31 | 18 | |
| 32 | 19 | enum |
| 33 | 20 | { |
| r9683 | r9684 | |
| 36 | 23 | noblink_block, |
| 37 | 24 | blink_block |
| 38 | 25 | }; |
| 39 | | static int cursor_mode; |
| 40 | 26 | |
| 41 | 27 | enum |
| 42 | 28 | { |
| r9683 | r9684 | |
| 51 | 37 | lpeny, |
| 52 | 38 | other |
| 53 | 39 | }; |
| 54 | | static int crtc_state; |
| 55 | 40 | |
| 56 | 41 | enum |
| 57 | 42 | { |
| r9683 | r9684 | |
| 60 | 45 | GRAPH_200_BW, |
| 61 | 46 | GRAPH_400_BW |
| 62 | 47 | }; |
| 63 | | static int gmode; |
| 64 | 48 | |
| 65 | | static int disp_plane[3]; |
| 66 | 49 | |
| 67 | 50 | #define TX_SEC 0x0001 |
| 68 | 51 | #define TX_BL 0x0002 |
| r9683 | r9684 | |
| 79 | 62 | #define TX_WID_MASK 0x0300 |
| 80 | 63 | #define TX_WID_SHIFT 8 |
| 81 | 64 | |
| 82 | | static char *graph_dirty = NULL; |
| 83 | | static unsigned short *attr_tmp = NULL, *attr_old = NULL, *text_old = NULL; |
| 84 | | static bitmap_t *wbm1, *wbm2; |
| 85 | 65 | |
| 86 | | #define TRAM(x,y) (pc88sr_is_highspeed ? \ |
| 87 | | pc88sr_textRAM[(dmac_addr[2]+(x)+(y)*120)&0xfff] : \ |
| 88 | | pc8801_mainRAM[(dmac_addr[2]+(x)+(y)*120)&0xffff]) |
| 89 | | #define ATTR_TMP(x,y) (attr_tmp[(x)+(y)*80]) |
| 90 | | #define TEXT_OLD(x,y) (text_old[(x)+(y)*80]) |
| 91 | | #define ATTR_OLD(x,y) (attr_old[(x)+(y)*80]) |
| 92 | | #define GRP_DIRTY(x,y) (graph_dirty[(x)+(y)*80]) |
| 66 | #define TRAM(x,y) (state->pc88sr_is_highspeed ? \ |
| 67 | state->pc88sr_textRAM[(state->dmac_addr[2]+(x)+(y)*120)&0xfff] : \ |
| 68 | state->mainRAM[(state->dmac_addr[2]+(x)+(y)*120)&0xffff]) |
| 69 | #define ATTR_TMP(x,y) (state->attr_tmp[(x)+(y)*80]) |
| 70 | #define TEXT_OLD(x,y) (state->text_old[(x)+(y)*80]) |
| 71 | #define ATTR_OLD(x,y) (state->attr_old[(x)+(y)*80]) |
| 72 | #define GRP_DIRTY(x,y) (state->graph_dirty[(x)+(y)*80]) |
| 93 | 73 | |
| 94 | 74 | INLINE void pc8801_plot_pixel( bitmap_t *bitmap, int x, int y, UINT32 color ) |
| 95 | 75 | { |
| r9683 | r9684 | |
| 98 | 78 | |
| 99 | 79 | void pc8801_video_init( running_machine *machine, int hireso ) |
| 100 | 80 | { |
| 81 | pc88_state *state = machine->driver_data<pc88_state>(); |
| 101 | 82 | screen_device *screen = screen_first(*machine); |
| 102 | 83 | int width = screen->width(); |
| 103 | 84 | int height = screen->height(); |
| 104 | 85 | |
| 105 | | wbm1 = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED16); |
| 106 | | wbm2 = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED16); |
| 107 | | pc8801_is_24KHz = hireso; |
| 108 | | crtc_on = 0; |
| 109 | | text_on = 1; |
| 86 | state->wbm1 = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED16); |
| 87 | state->wbm2 = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED16); |
| 88 | state->is_24KHz = hireso; |
| 89 | state->crtc_on = 0; |
| 90 | state->text_on = 1; |
| 110 | 91 | |
| 111 | | dmac_fl = 0; |
| 112 | | dmac_addr[0] = dmac_size[0] = 0; |
| 113 | | dmac_addr[1] = dmac_size[1] = 0; |
| 114 | | dmac_addr[2] = dmac_size[2] = 0; |
| 115 | | dmac_flag = dmac_status = 0; |
| 92 | state->dmac_fl = 0; |
| 93 | state->dmac_addr[0] = state->dmac_size[0] = 0; |
| 94 | state->dmac_addr[1] = state->dmac_size[1] = 0; |
| 95 | state->dmac_addr[2] = state->dmac_size[2] = 0; |
| 96 | state->dmac_flag = state->dmac_status = 0; |
| 116 | 97 | |
| 117 | | gVRAM = auto_alloc_array(machine, UINT8, 0xc000); |
| 118 | | pc88sr_textRAM = auto_alloc_array(machine, UINT8, 0x1000); |
| 119 | | attr_tmp = auto_alloc_array(machine, UINT16, 80*25); |
| 120 | | attr_old = auto_alloc_array(machine, UINT16, 80*100); |
| 121 | | text_old = auto_alloc_array(machine, UINT16, 80*100); |
| 122 | | graph_dirty = auto_alloc_array(machine, char, 80*100); |
| 98 | state->gVRAM = auto_alloc_array(machine, UINT8, 0xc000); |
| 99 | state->pc88sr_textRAM = auto_alloc_array(machine, UINT8, 0x1000); |
| 100 | state->attr_tmp = auto_alloc_array(machine, UINT16, 80*25); |
| 101 | state->attr_old = auto_alloc_array(machine, UINT16, 80*100); |
| 102 | state->text_old = auto_alloc_array(machine, UINT16, 80*100); |
| 103 | state->graph_dirty = auto_alloc_array(machine, char, 80*100); |
| 123 | 104 | |
| 124 | | memset(gVRAM, 0, 0xc000); |
| 125 | | memset(pc88sr_textRAM, 0, 0x1000); |
| 126 | | selected_vram = 0; |
| 127 | | alu_on = 0; |
| 128 | | analog_palette = 0; |
| 105 | memset(state->gVRAM, 0, 0xc000); |
| 106 | memset(state->pc88sr_textRAM, 0, 0x1000); |
| 107 | state->selected_vram = 0; |
| 108 | state->alu_on = 0; |
| 109 | state->analog_palette = 0; |
| 129 | 110 | } |
| 130 | 111 | |
| 131 | 112 | static WRITE8_HANDLER( write_gvram ) |
| 132 | 113 | { |
| 114 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 133 | 115 | int x, y; |
| 134 | 116 | |
| 135 | | if (gVRAM[offset] != data) |
| 117 | if (state->gVRAM[offset] != data) |
| 136 | 118 | { |
| 137 | | gVRAM[offset] = data; |
| 138 | | switch (gmode) |
| 119 | state->gVRAM[offset] = data; |
| 120 | switch (state->gmode) |
| 139 | 121 | { |
| 140 | 122 | case GRAPH_200_COL: |
| 141 | 123 | case GRAPH_200_BW: |
| r9683 | r9684 | |
| 164 | 146 | static WRITE8_HANDLER(write_gvram2_bank6){write_gvram(space, offset + 0x4000 * 2 + 0x3000, data);} |
| 165 | 147 | |
| 166 | 148 | |
| 167 | | static UINT8 read_save_alu( int x, UINT32 offset ) |
| 149 | static UINT8 read_save_alu( address_space *space, int x, UINT32 offset ) |
| 168 | 150 | { |
| 169 | | alu_save0 = gVRAM[offset + 0x0000]; |
| 170 | | alu_save1 = gVRAM[offset + 0x4000]; |
| 171 | | alu_save2 = gVRAM[offset + 0x8000]; |
| 151 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 152 | state->alu_save0 = state->gVRAM[offset + 0x0000]; |
| 153 | state->alu_save1 = state->gVRAM[offset + 0x4000]; |
| 154 | state->alu_save2 = state->gVRAM[offset + 0x8000]; |
| 172 | 155 | |
| 173 | | return (x & 1 ? gVRAM[offset + 0x0000] : ~gVRAM[offset + 0x0000]) & |
| 174 | | (x & 2 ? gVRAM[offset + 0x4000] : ~gVRAM[offset + 0x4000]) & |
| 175 | | (x & 4 ? gVRAM[offset + 0x8000] : ~gVRAM[offset + 0x8000]); |
| 156 | return (x & 1 ? state->gVRAM[offset + 0x0000] : ~state->gVRAM[offset + 0x0000]) & |
| 157 | (x & 2 ? state->gVRAM[offset + 0x4000] : ~state->gVRAM[offset + 0x4000]) & |
| 158 | (x & 4 ? state->gVRAM[offset + 0x8000] : ~state->gVRAM[offset + 0x8000]); |
| 176 | 159 | } |
| 177 | 160 | |
| 178 | | static READ8_HANDLER(read_gvram_alu0_bank5){return read_save_alu(0, offset);} |
| 179 | | static READ8_HANDLER(read_gvram_alu0_bank6){return read_save_alu(0, offset + 0x3000);} |
| 180 | | static READ8_HANDLER(read_gvram_alu1_bank5){return read_save_alu(1, offset);} |
| 181 | | static READ8_HANDLER(read_gvram_alu1_bank6){return read_save_alu(1, offset + 0x3000);} |
| 182 | | static READ8_HANDLER(read_gvram_alu2_bank5){return read_save_alu(2, offset);} |
| 183 | | static READ8_HANDLER(read_gvram_alu2_bank6){return read_save_alu(2, offset + 0x3000);} |
| 184 | | static READ8_HANDLER(read_gvram_alu3_bank5){return read_save_alu(3, offset);} |
| 185 | | static READ8_HANDLER(read_gvram_alu3_bank6){return read_save_alu(3, offset + 0x3000);} |
| 186 | | static READ8_HANDLER(read_gvram_alu4_bank5){return read_save_alu(4, offset);} |
| 187 | | static READ8_HANDLER(read_gvram_alu4_bank6){return read_save_alu(4, offset + 0x3000);} |
| 188 | | static READ8_HANDLER(read_gvram_alu5_bank5){return read_save_alu(5, offset);} |
| 189 | | static READ8_HANDLER(read_gvram_alu5_bank6){return read_save_alu(5, offset + 0x3000);} |
| 190 | | static READ8_HANDLER(read_gvram_alu6_bank5){return read_save_alu(6, offset);} |
| 191 | | static READ8_HANDLER(read_gvram_alu6_bank6){return read_save_alu(6, offset + 0x3000);} |
| 192 | | static READ8_HANDLER(read_gvram_alu7_bank5){return read_save_alu(7, offset);} |
| 193 | | static READ8_HANDLER(read_gvram_alu7_bank6){return read_save_alu(7, offset + 0x3000);} |
| 161 | static READ8_HANDLER(read_gvram_alu0_bank5){return read_save_alu(space, 0, offset);} |
| 162 | static READ8_HANDLER(read_gvram_alu0_bank6){return read_save_alu(space, 0, offset + 0x3000);} |
| 163 | static READ8_HANDLER(read_gvram_alu1_bank5){return read_save_alu(space, 1, offset);} |
| 164 | static READ8_HANDLER(read_gvram_alu1_bank6){return read_save_alu(space, 1, offset + 0x3000);} |
| 165 | static READ8_HANDLER(read_gvram_alu2_bank5){return read_save_alu(space, 2, offset);} |
| 166 | static READ8_HANDLER(read_gvram_alu2_bank6){return read_save_alu(space, 2, offset + 0x3000);} |
| 167 | static READ8_HANDLER(read_gvram_alu3_bank5){return read_save_alu(space, 3, offset);} |
| 168 | static READ8_HANDLER(read_gvram_alu3_bank6){return read_save_alu(space, 3, offset + 0x3000);} |
| 169 | static READ8_HANDLER(read_gvram_alu4_bank5){return read_save_alu(space, 4, offset);} |
| 170 | static READ8_HANDLER(read_gvram_alu4_bank6){return read_save_alu(space, 4, offset + 0x3000);} |
| 171 | static READ8_HANDLER(read_gvram_alu5_bank5){return read_save_alu(space, 5, offset);} |
| 172 | static READ8_HANDLER(read_gvram_alu5_bank6){return read_save_alu(space, 5, offset + 0x3000);} |
| 173 | static READ8_HANDLER(read_gvram_alu6_bank5){return read_save_alu(space, 6, offset);} |
| 174 | static READ8_HANDLER(read_gvram_alu6_bank6){return read_save_alu(space, 6, offset + 0x3000);} |
| 175 | static READ8_HANDLER(read_gvram_alu7_bank5){return read_save_alu(space, 7, offset);} |
| 176 | static READ8_HANDLER(read_gvram_alu7_bank6){return read_save_alu(space, 7, offset + 0x3000);} |
| 194 | 177 | |
| 195 | 178 | |
| 196 | 179 | static WRITE8_HANDLER(write_gvram_alu0) |
| 197 | 180 | { |
| 198 | | switch (alu_1 & 0x11) |
| 181 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 182 | switch (state->alu_1 & 0x11) |
| 199 | 183 | { |
| 200 | 184 | case 0x00: |
| 201 | | write_gvram(space, offset, gVRAM[offset] & ~data); |
| 185 | write_gvram(space, offset, state->gVRAM[offset] & ~data); |
| 202 | 186 | break; |
| 203 | 187 | case 0x01: |
| 204 | | write_gvram(space, offset, gVRAM[offset] | data); |
| 188 | write_gvram(space, offset, state->gVRAM[offset] | data); |
| 205 | 189 | break; |
| 206 | 190 | case 0x10: |
| 207 | | write_gvram(space, offset, gVRAM[offset] ^ data); |
| 191 | write_gvram(space, offset, state->gVRAM[offset] ^ data); |
| 208 | 192 | break; |
| 209 | 193 | case 0x11: |
| 210 | 194 | break; |
| 211 | 195 | } |
| 212 | 196 | |
| 213 | | switch (alu_1 & (0x11 << 1)) |
| 197 | switch (state->alu_1 & (0x11 << 1)) |
| 214 | 198 | { |
| 215 | 199 | case 0x00 << 1: |
| 216 | | write_gvram(space, offset + 0x4000, gVRAM[offset + 0x4000] & ~data); |
| 200 | write_gvram(space, offset + 0x4000, state->gVRAM[offset + 0x4000] & ~data); |
| 217 | 201 | break; |
| 218 | 202 | case 0x01 << 1: |
| 219 | | write_gvram(space, offset + 0x4000, gVRAM[offset + 0x4000] | data); |
| 203 | write_gvram(space, offset + 0x4000, state->gVRAM[offset + 0x4000] | data); |
| 220 | 204 | break; |
| 221 | 205 | case 0x10 << 1: |
| 222 | | write_gvram(space, offset + 0x4000, gVRAM[offset + 0x4000] ^ data); |
| 206 | write_gvram(space, offset + 0x4000, state->gVRAM[offset + 0x4000] ^ data); |
| 223 | 207 | break; |
| 224 | 208 | case 0x11 << 1: |
| 225 | 209 | break; |
| 226 | 210 | } |
| 227 | 211 | |
| 228 | | switch (alu_1 & (0x11 << 2)) |
| 212 | switch (state->alu_1 & (0x11 << 2)) |
| 229 | 213 | { |
| 230 | 214 | case 0x00 << 2: |
| 231 | | write_gvram(space, offset + 0x8000, gVRAM[offset + 0x8000] & ~data); |
| 215 | write_gvram(space, offset + 0x8000, state->gVRAM[offset + 0x8000] & ~data); |
| 232 | 216 | break; |
| 233 | 217 | case 0x01 << 2: |
| 234 | | write_gvram(space, offset + 0x8000, gVRAM[offset + 0x8000] | data); |
| 218 | write_gvram(space, offset + 0x8000, state->gVRAM[offset + 0x8000] | data); |
| 235 | 219 | break; |
| 236 | 220 | case 0x10 << 2: |
| 237 | | write_gvram(space, offset + 0x8000, gVRAM[offset + 0x8000] ^ data); |
| 221 | write_gvram(space, offset + 0x8000, state->gVRAM[offset + 0x8000] ^ data); |
| 238 | 222 | break; |
| 239 | 223 | case 0x11 << 2: |
| 240 | 224 | break; |
| r9683 | r9684 | |
| 243 | 227 | |
| 244 | 228 | static WRITE8_HANDLER(write_gvram_alu1) |
| 245 | 229 | { |
| 246 | | write_gvram(space, offset + 0x0000 , alu_save0); |
| 247 | | write_gvram(space, offset + 0x4000 , alu_save1); |
| 248 | | write_gvram(space, offset + 0x8000 , alu_save2); |
| 230 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 231 | write_gvram(space, offset + 0x0000 , state->alu_save0); |
| 232 | write_gvram(space, offset + 0x4000 , state->alu_save1); |
| 233 | write_gvram(space, offset + 0x8000 , state->alu_save2); |
| 249 | 234 | } |
| 250 | 235 | |
| 251 | | static WRITE8_HANDLER(write_gvram_alu2){write_gvram(space, offset + 0x0000, alu_save1);} |
| 236 | static WRITE8_HANDLER(write_gvram_alu2){ |
| 237 | pc88_state *state = space->machine->driver_data<pc88_state>();write_gvram(space, offset + 0x0000, state->alu_save1);} |
| 252 | 238 | |
| 253 | | static WRITE8_HANDLER(write_gvram_alu3){write_gvram(space, offset + 0x4000, alu_save0);} |
| 239 | static WRITE8_HANDLER(write_gvram_alu3){ |
| 240 | pc88_state *state = space->machine->driver_data<pc88_state>();write_gvram(space, offset + 0x4000, state->alu_save0);} |
| 254 | 241 | |
| 255 | 242 | |
| 256 | 243 | static WRITE8_HANDLER(write_gvram_alu0_bank5){write_gvram_alu0(space, offset,data);} |
| r9683 | r9684 | |
| 265 | 252 | |
| 266 | 253 | int pc8801_is_vram_select( running_machine *machine ) |
| 267 | 254 | { |
| 268 | | if (alu_on) |
| 255 | pc88_state *state = machine->driver_data<pc88_state>(); |
| 256 | if (state->alu_on) |
| 269 | 257 | { |
| 270 | 258 | /* ALU mode */ |
| 271 | | if (alu_2 & 0x80) |
| 259 | if (state->alu_2 & 0x80) |
| 272 | 260 | { |
| 273 | 261 | /* ALU VRAM */ |
| 274 | | switch (alu_2 & 0x07) |
| 262 | switch (state->alu_2 & 0x07) |
| 275 | 263 | { |
| 276 | 264 | case 0: |
| 277 | 265 | memory_install_read8_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xc000, 0xefff, 0, 0, read_gvram_alu0_bank5); |
| r9683 | r9684 | |
| 307 | 295 | break; |
| 308 | 296 | } |
| 309 | 297 | |
| 310 | | switch (alu_2 & 0x30) |
| 298 | switch (state->alu_2 & 0x30) |
| 311 | 299 | { |
| 312 | 300 | case 0x00: |
| 313 | 301 | memory_install_write8_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xc000, 0xefff, 0, 0, write_gvram_alu0_bank5); |
| r9683 | r9684 | |
| 337 | 325 | else |
| 338 | 326 | { |
| 339 | 327 | /* old mode */ |
| 340 | | switch (selected_vram) |
| 328 | switch (state->selected_vram) |
| 341 | 329 | { |
| 342 | 330 | case 1: |
| 343 | | memory_set_bankptr(machine, "bank5", gVRAM ); |
| 344 | | memory_set_bankptr(machine, "bank6", gVRAM + 0x3000 ); |
| 331 | memory_set_bankptr(machine, "bank5", state->gVRAM ); |
| 332 | memory_set_bankptr(machine, "bank6", state->gVRAM + 0x3000 ); |
| 345 | 333 | memory_install_read_bank(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xc000, 0xefff, 0, 0, "bank5"); |
| 346 | 334 | memory_install_write8_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xc000, 0xefff, 0, 0, write_gvram0_bank5); |
| 347 | 335 | memory_install_read_bank(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xf000, 0xffff, 0, 0, "bank6"); |
| r9683 | r9684 | |
| 349 | 337 | return 1; |
| 350 | 338 | |
| 351 | 339 | case 2: |
| 352 | | memory_set_bankptr(machine, "bank5", gVRAM + 0x4000 ); |
| 353 | | memory_set_bankptr(machine, "bank6", gVRAM + 0x4000 + 0x3000 ); |
| 340 | memory_set_bankptr(machine, "bank5", state->gVRAM + 0x4000 ); |
| 341 | memory_set_bankptr(machine, "bank6", state->gVRAM + 0x4000 + 0x3000 ); |
| 354 | 342 | memory_install_read_bank(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xc000, 0xefff, 0, 0, "bank5"); |
| 355 | 343 | memory_install_write8_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xc000, 0xefff, 0, 0, write_gvram1_bank5); |
| 356 | 344 | memory_install_read_bank(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xf000, 0xffff, 0, 0, "bank6"); |
| r9683 | r9684 | |
| 358 | 346 | return 1; |
| 359 | 347 | |
| 360 | 348 | case 3: |
| 361 | | memory_set_bankptr(machine, "bank5", gVRAM + 0x8000 ); |
| 362 | | memory_set_bankptr(machine, "bank6", gVRAM + 0x8000 + 0x3000 ); |
| 349 | memory_set_bankptr(machine, "bank5", state->gVRAM + 0x8000 ); |
| 350 | memory_set_bankptr(machine, "bank6", state->gVRAM + 0x8000 + 0x3000 ); |
| 363 | 351 | memory_install_read_bank(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xc000, 0xefff, 0, 0, "bank5"); |
| 364 | 352 | memory_install_write8_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xc000, 0xefff, 0, 0, write_gvram2_bank5); |
| 365 | 353 | memory_install_read_bank(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xf000, 0xffff, 0, 0, "bank6"); |
| r9683 | r9684 | |
| 375 | 363 | |
| 376 | 364 | WRITE8_HANDLER( pc88sr_disp_32 ) |
| 377 | 365 | { |
| 378 | | analog_palette = ((data & 0x20) != 0x00); |
| 379 | | alu_on = ((data & 0x40) != 0x00); |
| 366 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 367 | state->analog_palette = ((data & 0x20) != 0x00); |
| 368 | state->alu_on = ((data & 0x40) != 0x00); |
| 380 | 369 | pc8801_update_bank(space->machine); |
| 381 | 370 | } |
| 382 | 371 | |
| 383 | 372 | WRITE8_HANDLER( pc88sr_alu ) |
| 384 | 373 | { |
| 374 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 385 | 375 | switch (offset) |
| 386 | 376 | { |
| 387 | 377 | case 0: |
| 388 | | alu_1 = data; |
| 378 | state->alu_1 = data; |
| 389 | 379 | break; |
| 390 | 380 | case 1: |
| 391 | | alu_2 = data; |
| 381 | state->alu_2 = data; |
| 392 | 382 | break; |
| 393 | 383 | } |
| 394 | 384 | pc8801_update_bank(space->machine); |
| r9683 | r9684 | |
| 396 | 386 | |
| 397 | 387 | WRITE8_HANDLER( pc88_vramsel_w ) |
| 398 | 388 | { |
| 389 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 399 | 390 | if (offset == 3) |
| 400 | | selected_vram = 0; |
| 391 | state->selected_vram = 0; |
| 401 | 392 | else |
| 402 | | selected_vram = offset + 1; |
| 393 | state->selected_vram = offset + 1; |
| 403 | 394 | |
| 404 | 395 | pc8801_update_bank(space->machine); |
| 405 | 396 | } |
| 406 | 397 | |
| 407 | 398 | READ8_HANDLER( pc88_vramtest_r ) |
| 408 | 399 | { |
| 409 | | switch (selected_vram) |
| 400 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 401 | switch (state->selected_vram) |
| 410 | 402 | { |
| 411 | 403 | case 1: return 0xf9; |
| 412 | 404 | case 2: return 0xfa; |
| r9683 | r9684 | |
| 417 | 409 | |
| 418 | 410 | VIDEO_START( pc8801 ) |
| 419 | 411 | { |
| 420 | | text_width = 40; |
| 421 | | text_height = 20; |
| 422 | | blink_period = 24; |
| 412 | pc88_state *state = machine->driver_data<pc88_state>(); |
| 413 | state->text_width = 40; |
| 414 | state->text_height = 20; |
| 415 | state->blink_period = 24; |
| 423 | 416 | } |
| 424 | 417 | |
| 425 | | #define BLOCK_YSIZE (pc8801_is_24KHz ? 4 : 2) |
| 418 | #define BLOCK_YSIZE (state->is_24KHz ? 4 : 2) |
| 426 | 419 | |
| 427 | 420 | VIDEO_UPDATE( pc8801 ) |
| 428 | 421 | { |
| 422 | pc88_state *state = screen->machine->driver_data<pc88_state>(); |
| 429 | 423 | int x, y, attr_new, text_new, i, a, tx, ty, oy, gx, gy, ct, cg; |
| 430 | 424 | static int blink_count; |
| 431 | 425 | int full_refresh = 1; |
| 432 | 426 | |
| 433 | | blink_count = (blink_count + 1) % (blink_period * 4); |
| 427 | blink_count = (blink_count + 1) % (state->blink_period * 4); |
| 434 | 428 | /* attribute expand */ |
| 435 | 429 | for (y = 0; y < 25; y++) |
| 436 | 430 | { |
| r9683 | r9684 | |
| 439 | 433 | for (i = 0; i <= 20; i++) |
| 440 | 434 | { |
| 441 | 435 | a = TRAM(80 + i * 2 + 1, y); |
| 442 | | if (text_color) |
| 436 | if (state->text_color) |
| 443 | 437 | { |
| 444 | 438 | /* color mode */ |
| 445 | 439 | if (a & 0x08) |
| r9683 | r9684 | |
| 481 | 475 | x++; |
| 482 | 476 | }; |
| 483 | 477 | } |
| 484 | | if (text_cursor && (text_cursorX >= 0 || text_cursorX < 80) && (text_cursorY >= 0 || text_cursorY < 25)) |
| 478 | if (state->text_cursor && (state->text_cursorX >= 0 || state->text_cursorX < 80) && (state->text_cursorY >= 0 || state->text_cursorY < 25)) |
| 485 | 479 | { |
| 486 | | ATTR_TMP(text_cursorX, text_cursorY) |= TX_CUR; |
| 480 | ATTR_TMP(state->text_cursorX, state->text_cursorY) |= TX_CUR; |
| 487 | 481 | } |
| 488 | 482 | |
| 489 | 483 | /* display draw */ |
| 490 | 484 | for (y = 0; y < 100; y++) |
| 491 | 485 | { |
| 492 | | ty = y / (100 / text_height); |
| 493 | | oy = y % (100 / text_height); |
| 486 | ty = y / (100 / state->text_height); |
| 487 | oy = y % (100 / state->text_height); |
| 494 | 488 | for (x = 0; x < 80; x++) |
| 495 | 489 | { |
| 496 | 490 | /* text */ |
| 497 | | if (text_width == 40) |
| 491 | if (state->text_width == 40) |
| 498 | 492 | tx = x & (~1); |
| 499 | 493 | else |
| 500 | 494 | tx = x; |
| r9683 | r9684 | |
| 515 | 509 | if (attr_new & TX_BL) |
| 516 | 510 | { |
| 517 | 511 | attr_new &= ~TX_BL; |
| 518 | | if ((blink_count / blink_period) & 1) |
| 512 | if ((blink_count / state->blink_period) & 1) |
| 519 | 513 | attr_new ^= TX_REV; |
| 520 | 514 | } |
| 521 | 515 | |
| 522 | 516 | if (attr_new & TX_CUR) |
| 523 | 517 | { |
| 524 | 518 | attr_new &= ~TX_CUR; |
| 525 | | switch (cursor_mode) |
| 519 | switch (state->cursor_mode) |
| 526 | 520 | { |
| 527 | 521 | case noblink_underline: |
| 528 | 522 | attr_new ^= TX_UL; |
| 529 | 523 | break; |
| 530 | 524 | case blink_underline: |
| 531 | | if (blink_count / blink_period) |
| 525 | if (blink_count / state->blink_period) |
| 532 | 526 | attr_new ^= TX_UL; |
| 533 | 527 | break; |
| 534 | 528 | case noblink_block: |
| 535 | 529 | attr_new ^= TX_REV; |
| 536 | 530 | break; |
| 537 | 531 | case blink_block: |
| 538 | | if (blink_count / blink_period) |
| 532 | if (blink_count / state->blink_period) |
| 539 | 533 | attr_new ^= TX_REV; |
| 540 | 534 | break; |
| 541 | 535 | } |
| r9683 | r9684 | |
| 547 | 541 | if ((attr_new & TX_OL) && oy != 0) |
| 548 | 542 | attr_new &= ~TX_OL; |
| 549 | 543 | |
| 550 | | if (text_invert) |
| 544 | if (state->text_invert) |
| 551 | 545 | attr_new ^= TX_REV; |
| 552 | 546 | |
| 553 | | if (!crtc_on || ((dmac_flag & 0x04) == 0x00) || !text_on) |
| 547 | if (!state->crtc_on || ((state->dmac_flag & 0x04) == 0x00) || !state->text_on) |
| 554 | 548 | { |
| 555 | 549 | text_new = 0; |
| 556 | 550 | attr_new = 7 << TX_COL_SHIFT; |
| 557 | 551 | } |
| 558 | | if (text_width == 40) |
| 552 | if (state->text_width == 40) |
| 559 | 553 | { |
| 560 | 554 | if (x & 1) |
| 561 | 555 | attr_new |= TX_40R; |
| r9683 | r9684 | |
| 569 | 563 | |
| 570 | 564 | if (text_new != TEXT_OLD(x, y) || attr_new != ATTR_OLD(x, y) || GRP_DIRTY(x, y) || full_refresh) |
| 571 | 565 | { |
| 572 | | plot_box(wbm2, x * 8, y * BLOCK_YSIZE, 8, BLOCK_YSIZE, palette_transparent_pen); |
| 566 | plot_box(state->wbm2, x * 8, y * BLOCK_YSIZE, 8, BLOCK_YSIZE, palette_transparent_pen); |
| 573 | 567 | ct = ((attr_new & TX_COL_MASK) >> TX_COL_SHIFT) + 8; |
| 574 | 568 | TEXT_OLD(x, y) = text_new; |
| 575 | 569 | ATTR_OLD(x, y) = attr_new; |
| r9683 | r9684 | |
| 584 | 578 | { |
| 585 | 579 | case TX_80: |
| 586 | 580 | if (text_new & 0x04) |
| 587 | | plot_box(wbm2, x * 8, y * BLOCK_YSIZE, 4, BLOCK_YSIZE, ct); |
| 581 | plot_box(state->wbm2, x * 8, y * BLOCK_YSIZE, 4, BLOCK_YSIZE, ct); |
| 588 | 582 | if (text_new & 0x40) |
| 589 | | plot_box(wbm2, x * 8 + 4,y * BLOCK_YSIZE, 4, BLOCK_YSIZE, ct); |
| 583 | plot_box(state->wbm2, x * 8 + 4,y * BLOCK_YSIZE, 4, BLOCK_YSIZE, ct); |
| 590 | 584 | break; |
| 591 | 585 | case TX_40L: |
| 592 | 586 | if (text_new & 0x04) |
| 593 | | plot_box(wbm2, x * 8, y * BLOCK_YSIZE, 8, BLOCK_YSIZE, ct); |
| 587 | plot_box(state->wbm2, x * 8, y * BLOCK_YSIZE, 8, BLOCK_YSIZE, ct); |
| 594 | 588 | break; |
| 595 | 589 | case TX_40R: |
| 596 | 590 | if (text_new & 0x40) |
| 597 | | plot_box(wbm2, x * 8, y * BLOCK_YSIZE, 8, BLOCK_YSIZE, ct); |
| 591 | plot_box(state->wbm2, x * 8, y * BLOCK_YSIZE, 8, BLOCK_YSIZE, ct); |
| 598 | 592 | break; |
| 599 | 593 | } |
| 600 | 594 | } |
| 601 | 595 | else |
| 602 | 596 | { |
| 603 | 597 | /* normal text */ |
| 604 | | drawgfx_transpen(wbm2, NULL, screen->machine->gfx[((attr_new & TX_WID_MASK) >> TX_WID_SHIFT) + (pc8801_is_24KHz ? 3 : 0)], text_new, |
| 598 | drawgfx_transpen(state->wbm2, NULL, screen->machine->gfx[((attr_new & TX_WID_MASK) >> TX_WID_SHIFT) + (state->is_24KHz ? 3 : 0)], text_new, |
| 605 | 599 | ((attr_new & TX_REV) ? 8 : 0) + ((attr_new & TX_COL_MASK) >> TX_COL_SHIFT), 0, 0, x * 8, y * BLOCK_YSIZE, (attr_new & TX_REV) ? 1 : 0); |
| 606 | 600 | } |
| 607 | 601 | if (attr_new & TX_UL) |
| 608 | | plot_box(wbm2, x * 8, y * BLOCK_YSIZE + (pc8801_is_24KHz ? 3 : 1), 8, 1, (attr_new & TX_REV) ? palette_transparent_pen : ct); |
| 602 | plot_box(state->wbm2, x * 8, y * BLOCK_YSIZE + (state->is_24KHz ? 3 : 1), 8, 1, (attr_new & TX_REV) ? palette_transparent_pen : ct); |
| 609 | 603 | |
| 610 | 604 | if (attr_new & TX_OL) |
| 611 | | plot_box(wbm2, x * 8, y * BLOCK_YSIZE, 8, 1, (attr_new & TX_REV) ? palette_transparent_pen : ct); |
| 605 | plot_box(state->wbm2, x * 8, y * BLOCK_YSIZE, 8, 1, (attr_new & TX_REV) ? palette_transparent_pen : ct); |
| 612 | 606 | |
| 613 | 607 | /* graphics */ |
| 614 | 608 | GRP_DIRTY(x, y) = 0; |
| 615 | | if (pc8801_is_24KHz) |
| 609 | if (state->is_24KHz) |
| 616 | 610 | { |
| 617 | | switch (gmode) |
| 611 | switch (state->gmode) |
| 618 | 612 | { |
| 619 | 613 | case GRAPH_200_COL: |
| 620 | 614 | for (gy = 0; gy < 2; gy++) |
| 621 | 615 | { |
| 622 | 616 | for (gx = 0; gx < 8; gx++) |
| 623 | 617 | { |
| 624 | | cg = (((gVRAM[0x0000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) >> 7) | |
| 625 | | (((gVRAM[0x4000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) >> 6) | |
| 626 | | (((gVRAM[0x8000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) >> 5); |
| 627 | | pc8801_plot_pixel(wbm1, x * 8 + gx, y * 4 + gy * 2, cg); |
| 628 | | pc8801_plot_pixel(wbm1, x * 8 + gx, y * 4 + gy * 2 + 1, 17); |
| 618 | cg = (((state->gVRAM[0x0000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) >> 7) | |
| 619 | (((state->gVRAM[0x4000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) >> 6) | |
| 620 | (((state->gVRAM[0x8000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) >> 5); |
| 621 | pc8801_plot_pixel(state->wbm1, x * 8 + gx, y * 4 + gy * 2, cg); |
| 622 | pc8801_plot_pixel(state->wbm1, x * 8 + gx, y * 4 + gy * 2 + 1, 17); |
| 629 | 623 | } |
| 630 | 624 | } |
| 631 | 625 | break; |
| r9683 | r9684 | |
| 634 | 628 | { |
| 635 | 629 | for (gx = 0; gx < 8; gx++) |
| 636 | 630 | { |
| 637 | | cg = (((gVRAM[0x0000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) && disp_plane[0]) || |
| 638 | | (((gVRAM[0x4000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) && disp_plane[1]) || |
| 639 | | (((gVRAM[0x8000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) && disp_plane[2]) ? |
| 631 | cg = (((state->gVRAM[0x0000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) && state->disp_plane[0]) || |
| 632 | (((state->gVRAM[0x4000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) && state->disp_plane[1]) || |
| 633 | (((state->gVRAM[0x8000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) && state->disp_plane[2]) ? |
| 640 | 634 | ((attr_new & TX_COL_MASK) >> TX_COL_SHIFT) + 8 : 16; |
| 641 | | pc8801_plot_pixel(wbm1, x * 8 + gx, y * 4 + gy * 2, cg); |
| 642 | | pc8801_plot_pixel(wbm1, x * 8 + gx, y * 4 + gy * 2 + 1, 17); |
| 635 | pc8801_plot_pixel(state->wbm1, x * 8 + gx, y * 4 + gy * 2, cg); |
| 636 | pc8801_plot_pixel(state->wbm1, x * 8 + gx, y * 4 + gy * 2 + 1, 17); |
| 643 | 637 | } |
| 644 | 638 | } |
| 645 | 639 | break; |
| r9683 | r9684 | |
| 648 | 642 | { |
| 649 | 643 | for (gx = 0; gx < 8; gx++) |
| 650 | 644 | { |
| 651 | | cg = ((gVRAM[(y < 50 ? 0x0000 : 0x4000) + x + (y % 50) * 4 * 80 + gy * 80] << gx) & 0x80) |
| 652 | | && disp_plane[y < 200 ? 0 : 1] ? ((attr_new&TX_COL_MASK) >> TX_COL_SHIFT) + 8 : 16; |
| 653 | | pc8801_plot_pixel(wbm1, x * 8 + gx, y * 4 + gy, cg); |
| 645 | cg = ((state->gVRAM[(y < 50 ? 0x0000 : 0x4000) + x + (y % 50) * 4 * 80 + gy * 80] << gx) & 0x80) |
| 646 | && state->disp_plane[y < 200 ? 0 : 1] ? ((attr_new&TX_COL_MASK) >> TX_COL_SHIFT) + 8 : 16; |
| 647 | pc8801_plot_pixel(state->wbm1, x * 8 + gx, y * 4 + gy, cg); |
| 654 | 648 | } |
| 655 | 649 | } |
| 656 | 650 | break; |
| 657 | 651 | case GRAPH_NO: |
| 658 | 652 | default: |
| 659 | | plot_box(wbm1, x * 8, y * 4, 8, 4, 16); |
| 653 | plot_box(state->wbm1, x * 8, y * 4, 8, 4, 16); |
| 660 | 654 | break; |
| 661 | 655 | } |
| 662 | 656 | } |
| 663 | 657 | else |
| 664 | 658 | { |
| 665 | | switch (gmode) |
| 659 | switch (state->gmode) |
| 666 | 660 | { |
| 667 | 661 | case GRAPH_200_COL: |
| 668 | 662 | for (gy = 0; gy < 2; gy++) |
| 669 | 663 | { |
| 670 | 664 | for (gx = 0; gx < 8; gx++) |
| 671 | 665 | { |
| 672 | | cg = (((gVRAM[0x0000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) >> 7) | |
| 673 | | (((gVRAM[0x4000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) >> 6) | |
| 674 | | (((gVRAM[0x8000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) >> 5); |
| 675 | | pc8801_plot_pixel(wbm1, x * 8 + gx, y * 2 + gy, cg); |
| 666 | cg = (((state->gVRAM[0x0000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) >> 7) | |
| 667 | (((state->gVRAM[0x4000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) >> 6) | |
| 668 | (((state->gVRAM[0x8000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) >> 5); |
| 669 | pc8801_plot_pixel(state->wbm1, x * 8 + gx, y * 2 + gy, cg); |
| 676 | 670 | } |
| 677 | 671 | } |
| 678 | 672 | break; |
| r9683 | r9684 | |
| 681 | 675 | { |
| 682 | 676 | for (gx = 0; gx < 8; gx++) |
| 683 | 677 | { |
| 684 | | cg = (((gVRAM[0x0000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) && disp_plane[0]) || |
| 685 | | (((gVRAM[0x4000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) && disp_plane[1]) || |
| 686 | | (((gVRAM[0x8000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) && disp_plane[2]) ? |
| 678 | cg = (((state->gVRAM[0x0000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) && state->disp_plane[0]) || |
| 679 | (((state->gVRAM[0x4000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) && state->disp_plane[1]) || |
| 680 | (((state->gVRAM[0x8000 + x + y * 2 * 80 + gy * 80] << gx) & 0x80) && state->disp_plane[2]) ? |
| 687 | 681 | ((attr_new & TX_COL_MASK) >> TX_COL_SHIFT) + 8 : 16; |
| 688 | | pc8801_plot_pixel(wbm1, x * 8 + gx, y * 2 + gy, cg); |
| 682 | pc8801_plot_pixel(state->wbm1, x * 8 + gx, y * 2 + gy, cg); |
| 689 | 683 | } |
| 690 | 684 | } |
| 691 | 685 | break; |
| 692 | 686 | case GRAPH_NO: |
| 693 | 687 | default: |
| 694 | | plot_box(wbm1, x * 8, y * 2, 8, 2, 16); |
| 688 | plot_box(state->wbm1, x * 8, y * 2, 8, 2, 16); |
| 695 | 689 | break; |
| 696 | 690 | } |
| 697 | 691 | } |
| r9683 | r9684 | |
| 699 | 693 | } |
| 700 | 694 | } |
| 701 | 695 | |
| 702 | | copyscrollbitmap_trans(wbm1, wbm2, 0, 0, 0, 0, NULL, palette_transparent_pen); |
| 703 | | copybitmap(bitmap, wbm1, 0, 0, 0, 0, NULL); |
| 696 | copyscrollbitmap_trans(state->wbm1, state->wbm2, 0, 0, 0, 0, NULL, palette_transparent_pen); |
| 697 | copybitmap(bitmap, state->wbm1, 0, 0, 0, 0, NULL); |
| 704 | 698 | return 0; |
| 705 | 699 | } |
| 706 | 700 | |
| r9683 | r9684 | |
| 734 | 728 | |
| 735 | 729 | WRITE8_HANDLER( pc88_crtc_w ) |
| 736 | 730 | { |
| 731 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 737 | 732 | if (offset == 1) |
| 738 | 733 | { |
| 739 | 734 | /* command */ |
| r9683 | r9684 | |
| 741 | 736 | { |
| 742 | 737 | case 0x00: |
| 743 | 738 | /* disp stop / initilize */ |
| 744 | | crtc_on = 0; |
| 745 | | crtc_state = parameter0; |
| 739 | state->crtc_on = 0; |
| 740 | state->crtc_state = parameter0; |
| 746 | 741 | return; |
| 747 | 742 | case 0x20: |
| 748 | 743 | /* disp on */ |
| 749 | | crtc_on = 1; |
| 750 | | text_invert = ((data & 1) != 0x00); |
| 744 | state->crtc_on = 1; |
| 745 | state->text_invert = ((data & 1) != 0x00); |
| 751 | 746 | return; |
| 752 | 747 | case 0x40: |
| 753 | 748 | /* case 0x43: */ |
| r9683 | r9684 | |
| 755 | 750 | return; |
| 756 | 751 | case 0x60: |
| 757 | 752 | /* get light pen point */ |
| 758 | | crtc_state = lpenx; |
| 753 | state->crtc_state = lpenx; |
| 759 | 754 | return; |
| 760 | 755 | case 0x80: |
| 761 | 756 | /* set cursor */ |
| 762 | | crtc_state = cursorx; |
| 763 | | text_cursor = ((data & 1) != 0x00); |
| 757 | state->crtc_state = cursorx; |
| 758 | state->text_cursor = ((data & 1) != 0x00); |
| 764 | 759 | return; |
| 765 | 760 | default: |
| 766 | 761 | logerror("pc8801: illegal crtc command 0x%.2x.\n", data); |
| r9683 | r9684 | |
| 770 | 765 | else |
| 771 | 766 | { |
| 772 | 767 | /* parameter */ |
| 773 | | switch (crtc_state) |
| 768 | switch (state->crtc_state) |
| 774 | 769 | { |
| 775 | 770 | case parameter0: |
| 776 | | crtc_state = parameter1; |
| 771 | state->crtc_state = parameter1; |
| 777 | 772 | if (data == 0xce) |
| 778 | 773 | return; |
| 779 | 774 | logerror("pc8801: illegal crtc parameter0 0x%.2x.\n", data); |
| 780 | 775 | return; |
| 781 | 776 | |
| 782 | 777 | case parameter1: |
| 783 | | crtc_state = parameter2; |
| 778 | state->crtc_state = parameter2; |
| 784 | 779 | switch (data & 0xc0) |
| 785 | 780 | { |
| 786 | 781 | case 0x00: |
| 787 | | blink_period = 8; |
| 782 | state->blink_period = 8; |
| 788 | 783 | break; |
| 789 | 784 | case 0x40: |
| 790 | | blink_period = 16; |
| 785 | state->blink_period = 16; |
| 791 | 786 | break; |
| 792 | 787 | case 0x80: |
| 793 | | blink_period = 24; |
| 788 | state->blink_period = 24; |
| 794 | 789 | break; |
| 795 | 790 | case 0xc0: |
| 796 | | blink_period = 32; |
| 791 | state->blink_period = 32; |
| 797 | 792 | break; |
| 798 | 793 | } |
| 799 | 794 | if ((data & 0x3f) == 0x13) |
| 800 | 795 | { |
| 801 | | text_height = 20; |
| 796 | state->text_height = 20; |
| 802 | 797 | return; |
| 803 | 798 | } |
| 804 | 799 | else if ((data & 0x3f) == 0x18) |
| 805 | 800 | { |
| 806 | | text_height = 25; |
| 801 | state->text_height = 25; |
| 807 | 802 | return; |
| 808 | 803 | } |
| 809 | 804 | logerror("pc8801: illegal crtc parameter1 0x%.2x.\n", data); |
| 810 | 805 | return; |
| 811 | 806 | |
| 812 | 807 | case parameter2: |
| 813 | | crtc_state = parameter3; |
| 808 | state->crtc_state = parameter3; |
| 814 | 809 | switch (data & 0x60) |
| 815 | 810 | { |
| 816 | 811 | case 0x00: |
| 817 | | cursor_mode = noblink_underline; |
| 812 | state->cursor_mode = noblink_underline; |
| 818 | 813 | break; |
| 819 | 814 | case 0x20: |
| 820 | | cursor_mode = blink_underline; |
| 815 | state->cursor_mode = blink_underline; |
| 821 | 816 | break; |
| 822 | 817 | case 0x40: |
| 823 | | cursor_mode = noblink_block; |
| 818 | state->cursor_mode = noblink_block; |
| 824 | 819 | break; |
| 825 | 820 | case 0x60: |
| 826 | | cursor_mode = blink_block; |
| 821 | state->cursor_mode = blink_block; |
| 827 | 822 | break; |
| 828 | 823 | } |
| 829 | | if (!pc8801_is_24KHz && (data & 0x9f) == 0x09 && text_height == 20) |
| 824 | if (!state->is_24KHz && (data & 0x9f) == 0x09 && state->text_height == 20) |
| 830 | 825 | return; |
| 831 | | else if (!pc8801_is_24KHz && (data & 0x9f) == 0x07 && text_height == 25) |
| 826 | else if (!state->is_24KHz && (data & 0x9f) == 0x07 && state->text_height == 25) |
| 832 | 827 | return; |
| 833 | | else if (pc8801_is_24KHz && (data & 0x9f) == 0x13 && text_height == 20) |
| 828 | else if (state->is_24KHz && (data & 0x9f) == 0x13 && state->text_height == 20) |
| 834 | 829 | return; |
| 835 | | else if (pc8801_is_24KHz && (data & 0x9f) == 0x0f && text_height == 25) |
| 830 | else if (state->is_24KHz && (data & 0x9f) == 0x0f && state->text_height == 25) |
| 836 | 831 | return; |
| 837 | 832 | logerror("pc8801: illegal crtc parameter2 0x%.2x.\n", data); |
| 838 | 833 | return; |
| 839 | 834 | |
| 840 | 835 | case parameter3: |
| 841 | | crtc_state = parameter4; |
| 842 | | if (!pc8801_is_24KHz && data == 0xbe && text_height == 20) |
| 836 | state->crtc_state = parameter4; |
| 837 | if (!state->is_24KHz && data == 0xbe && state->text_height == 20) |
| 843 | 838 | return; |
| 844 | | else if (!pc8801_is_24KHz && data == 0xde && text_height == 25) |
| 839 | else if (!state->is_24KHz && data == 0xde && state->text_height == 25) |
| 845 | 840 | return; |
| 846 | | else if (pc8801_is_24KHz && data == 0x38 && text_height == 20) |
| 841 | else if (state->is_24KHz && data == 0x38 && state->text_height == 20) |
| 847 | 842 | return; |
| 848 | | else if (pc8801_is_24KHz && data == 0x58 && text_height == 25) |
| 843 | else if (state->is_24KHz && data == 0x58 && state->text_height == 25) |
| 849 | 844 | return; |
| 850 | 845 | logerror("pc8801: illegal crtc parameter3 0x%.2x.\n", data); |
| 851 | 846 | return; |
| 852 | 847 | |
| 853 | 848 | case parameter4: |
| 854 | | crtc_state = other; |
| 849 | state->crtc_state = other; |
| 855 | 850 | if (data == 0x13) |
| 856 | 851 | { |
| 857 | | text_color = 0; |
| 852 | state->text_color = 0; |
| 858 | 853 | return; |
| 859 | 854 | } |
| 860 | 855 | else if (data == 0x53) |
| 861 | 856 | { |
| 862 | | text_color = 1; |
| 857 | state->text_color = 1; |
| 863 | 858 | return; |
| 864 | 859 | } |
| 865 | 860 | logerror("pc8801: illegal crtc parameter4 0x%.2x.\n", data); |
| 866 | 861 | return; |
| 867 | 862 | |
| 868 | 863 | case cursorx: |
| 869 | | crtc_state = cursory; |
| 870 | | text_cursorX = data; |
| 864 | state->crtc_state = cursory; |
| 865 | state->text_cursorX = data; |
| 871 | 866 | return; |
| 872 | 867 | |
| 873 | 868 | case cursory: |
| 874 | | crtc_state = other; |
| 875 | | text_cursorY = data; |
| 869 | state->crtc_state = other; |
| 870 | state->text_cursorY = data; |
| 876 | 871 | return; |
| 877 | 872 | |
| 878 | 873 | default: |
| r9683 | r9684 | |
| 884 | 879 | |
| 885 | 880 | READ8_HANDLER( pc88_crtc_r ) |
| 886 | 881 | { |
| 882 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 887 | 883 | if (offset == 0) |
| 888 | 884 | { |
| 889 | 885 | /* light pen point */ |
| 890 | | switch (crtc_state) |
| 886 | switch (state->crtc_state) |
| 891 | 887 | { |
| 892 | 888 | case lpenx: |
| 893 | | crtc_state = lpeny; |
| 889 | state->crtc_state = lpeny; |
| 894 | 890 | return 0xff; |
| 895 | 891 | case lpeny: |
| 896 | | crtc_state = other; |
| 892 | state->crtc_state = other; |
| 897 | 893 | return 0xff; |
| 898 | 894 | default: |
| 899 | 895 | logerror("pc8801:illegal light pen read\n"); |
| r9683 | r9684 | |
| 903 | 899 | else |
| 904 | 900 | { |
| 905 | 901 | /* status */ |
| 906 | | return crtc_on ? 0x10 : 0x00; |
| 902 | return state->crtc_on ? 0x10 : 0x00; |
| 907 | 903 | } |
| 908 | 904 | } |
| 909 | 905 | |
| 910 | 906 | WRITE8_HANDLER( pc88_dmac_w ) |
| 911 | 907 | { |
| 908 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 912 | 909 | switch (offset) |
| 913 | 910 | { |
| 914 | 911 | case 8: |
| 915 | | dmac_fl = 0; |
| 916 | | dmac_flag = data; |
| 912 | state->dmac_fl = 0; |
| 913 | state->dmac_flag = data; |
| 917 | 914 | return; |
| 918 | 915 | case 1: |
| 919 | 916 | case 3: |
| 920 | 917 | case 5: |
| 921 | 918 | case 7: |
| 922 | | if (dmac_fl == 0) |
| 919 | if (state->dmac_fl == 0) |
| 923 | 920 | { |
| 924 | | dmac_fl = 1; |
| 925 | | dmac_size[offset / 2] = (dmac_size[offset / 2] & 0xff00) | (data & 0x00ff); |
| 921 | state->dmac_fl = 1; |
| 922 | state->dmac_size[offset / 2] = (state->dmac_size[offset / 2] & 0xff00) | (data & 0x00ff); |
| 926 | 923 | return; |
| 927 | 924 | } |
| 928 | 925 | else |
| 929 | 926 | { |
| 930 | | dmac_fl = 0; |
| 931 | | dmac_size[offset / 2] = (dmac_size[offset / 2] & 0x00ff) | ((data << 8) & 0xff00); |
| 927 | state->dmac_fl = 0; |
| 928 | state->dmac_size[offset / 2] = (state->dmac_size[offset / 2] & 0x00ff) | ((data << 8) & 0xff00); |
| 932 | 929 | return; |
| 933 | 930 | } |
| 934 | 931 | case 0: |
| 935 | 932 | case 2: |
| 936 | 933 | case 4: |
| 937 | 934 | case 6: |
| 938 | | if (dmac_fl == 0) |
| 935 | if (state->dmac_fl == 0) |
| 939 | 936 | { |
| 940 | | dmac_fl = 1; |
| 941 | | dmac_addr[offset / 2] = (dmac_addr[offset / 2] & 0xff00) | (data & 0x00ff); |
| 937 | state->dmac_fl = 1; |
| 938 | state->dmac_addr[offset / 2] = (state->dmac_addr[offset / 2] & 0xff00) | (data & 0x00ff); |
| 942 | 939 | return; |
| 943 | 940 | } |
| 944 | 941 | else |
| 945 | 942 | { |
| 946 | | dmac_fl = 0; |
| 947 | | dmac_addr[offset / 2] = (dmac_addr[offset / 2] & 0x00ff) | ((data << 8) & 0xff00); |
| 943 | state->dmac_fl = 0; |
| 944 | state->dmac_addr[offset / 2] = (state->dmac_addr[offset / 2] & 0x00ff) | ((data << 8) & 0xff00); |
| 948 | 945 | return; |
| 949 | 946 | } |
| 950 | 947 | } |
| r9683 | r9684 | |
| 952 | 949 | |
| 953 | 950 | READ8_HANDLER( pc88_dmac_r ) |
| 954 | 951 | { |
| 952 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 955 | 953 | switch (offset) |
| 956 | 954 | { |
| 957 | 955 | case 8: |
| 958 | | return dmac_status; |
| 956 | return state->dmac_status; |
| 959 | 957 | case 1: |
| 960 | 958 | case 3: |
| 961 | 959 | case 5: |
| 962 | 960 | case 7: |
| 963 | | if (dmac_fl == 0) |
| 961 | if (state->dmac_fl == 0) |
| 964 | 962 | { |
| 965 | | dmac_fl = 1; |
| 966 | | return (dmac_size[offset / 2] & 0x00ff); |
| 963 | state->dmac_fl = 1; |
| 964 | return (state->dmac_size[offset / 2] & 0x00ff); |
| 967 | 965 | } |
| 968 | 966 | else |
| 969 | 967 | { |
| 970 | | dmac_fl = 0; |
| 971 | | return ((dmac_size[offset / 2] >> 8) & 0x00ff); |
| 968 | state->dmac_fl = 0; |
| 969 | return ((state->dmac_size[offset / 2] >> 8) & 0x00ff); |
| 972 | 970 | } |
| 973 | 971 | case 0: |
| 974 | 972 | case 2: |
| 975 | 973 | case 4: |
| 976 | 974 | case 6: |
| 977 | | if (dmac_fl == 0) |
| 975 | if (state->dmac_fl == 0) |
| 978 | 976 | { |
| 979 | | dmac_fl = 1; |
| 980 | | return (dmac_addr[offset / 2] & 0x00ff); |
| 977 | state->dmac_fl = 1; |
| 978 | return (state->dmac_addr[offset / 2] & 0x00ff); |
| 981 | 979 | } |
| 982 | 980 | else |
| 983 | 981 | { |
| 984 | | dmac_fl = 0; |
| 985 | | return ((dmac_addr[offset / 2] >> 8) & 0x00ff); |
| 982 | state->dmac_fl = 0; |
| 983 | return ((state->dmac_addr[offset / 2] >> 8) & 0x00ff); |
| 986 | 984 | } |
| 987 | 985 | } |
| 988 | 986 | return 0; |
| r9683 | r9684 | |
| 990 | 988 | |
| 991 | 989 | WRITE8_HANDLER( pc88sr_disp_30 ) |
| 992 | 990 | { |
| 993 | | text_width = ((data & 0x01) == 0x00) ? 40 : 80; |
| 991 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 992 | state->text_width = ((data & 0x01) == 0x00) ? 40 : 80; |
| 994 | 993 | } |
| 995 | 994 | |
| 996 | 995 | WRITE8_HANDLER( pc88sr_disp_31 ) |
| 997 | 996 | { |
| 997 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 998 | 998 | int gmode_new = GRAPH_NO; |
| 999 | 999 | |
| 1000 | 1000 | switch (data & 0x19) |
| r9683 | r9684 | |
| 1006 | 1006 | gmode_new = GRAPH_NO; |
| 1007 | 1007 | break; |
| 1008 | 1008 | case 0x08: |
| 1009 | | gmode_new = pc8801_is_24KHz ? GRAPH_400_BW : GRAPH_200_BW; |
| 1009 | gmode_new = state->is_24KHz ? GRAPH_400_BW : GRAPH_200_BW; |
| 1010 | 1010 | break; |
| 1011 | 1011 | case 0x09: |
| 1012 | 1012 | gmode_new = GRAPH_200_BW; |
| r9683 | r9684 | |
| 1017 | 1017 | break; |
| 1018 | 1018 | } |
| 1019 | 1019 | |
| 1020 | | if (gmode != gmode_new) |
| 1021 | | gmode = gmode_new; |
| 1020 | if (state->gmode != gmode_new) |
| 1021 | state->gmode = gmode_new; |
| 1022 | 1022 | } |
| 1023 | 1023 | |
| 1024 | 1024 | WRITE8_HANDLER(pc88_palette_w) |
| 1025 | 1025 | { |
| 1026 | pc88_state *state = space->machine->driver_data<pc88_state>(); |
| 1026 | 1027 | int palno; |
| 1027 | 1028 | int i; |
| 1028 | 1029 | static int r[10],g[10],b[10]; |
| r9683 | r9684 | |
| 1031 | 1032 | palno = 16; |
| 1032 | 1033 | else if (offset == 1) |
| 1033 | 1034 | { |
| 1034 | | text_on = (data & 1) == 0x00; |
| 1035 | state->text_on = (data & 1) == 0x00; |
| 1035 | 1036 | |
| 1036 | 1037 | for (i = 0; i < 3; i++) |
| 1037 | 1038 | { |
| 1038 | | if (disp_plane[i] != ((data & (2 << i)) == 0x00)) |
| 1039 | | disp_plane[i] = (data & (2<<i)) == 0x00; |
| 1039 | if (state->disp_plane[i] != ((data & (2 << i)) == 0x00)) |
| 1040 | state->disp_plane[i] = (data & (2<<i)) == 0x00; |
| 1040 | 1041 | } |
| 1041 | 1042 | return; |
| 1042 | 1043 | } |
| 1043 | 1044 | else |
| 1044 | 1045 | palno = offset - 2; |
| 1045 | 1046 | |
| 1046 | | if (analog_palette) |
| 1047 | if (state->analog_palette) |
| 1047 | 1048 | { |
| 1048 | 1049 | if ((data & 0x40) == 0x00) |
| 1049 | 1050 | { |
src/mess/drivers/ip22.c
| r9683 | r9684 | |
| 56 | 56 | #include "devices/chd_cd.h" |
| 57 | 57 | #include "sound/dac.h" |
| 58 | 58 | |
| 59 | |
| 60 | class ip22_state : public driver_device |
| 61 | { |
| 62 | public: |
| 63 | ip22_state(running_machine &machine, const driver_device_config_base &config) |
| 64 | : driver_device(machine, config) { } |
| 65 | |
| 66 | UINT32 *mainram; |
| 67 | UINT8 nRTC_Regs[0x80]; |
| 68 | UINT8 nRTC_UserRAM[0x200]; |
| 69 | UINT8 nRTC_RAM[0x800]; |
| 70 | UINT32 nHPC_SCSI0Descriptor; |
| 71 | UINT32 nHPC_SCSI0DMACtrl; |
| 72 | UINT32 int3_regs[64]; |
| 73 | UINT32 nIOC_ParReadCnt; |
| 74 | UINT32 nHPC3_enetr_nbdp; |
| 75 | UINT32 nHPC3_enetr_cbp; |
| 76 | UINT32 nHPC3_unk0; |
| 77 | UINT32 nHPC3_unk1; |
| 78 | UINT32 nHPC3_IC_Unk0; |
| 79 | UINT32 nHAL2_IAR; |
| 80 | UINT32 nHAL2_IDR[4]; |
| 81 | UINT8 nPBUS_DMA_Active; |
| 82 | UINT32 nPBUS_DMA_CurPtr; |
| 83 | UINT32 nPBUS_DMA_DescPtr; |
| 84 | UINT32 nPBUS_DMA_NextPtr; |
| 85 | UINT32 nPBUS_DMA_WordsLeft; |
| 86 | UINT32 *unkpbus0; |
| 87 | UINT32 nIntCounter; |
| 88 | UINT8 dma_buffer[4096]; |
| 89 | }; |
| 90 | |
| 91 | |
| 59 | 92 | #define VERBOSE_LEVEL ( 0 ) |
| 60 | 93 | |
| 61 | | static UINT32 *ip22_mainram; |
| 62 | 94 | |
| 63 | 95 | INLINE void ATTR_PRINTF(3,4) verboselog( running_machine *machine, int n_level, const char *s_fmt, ... ) |
| 64 | 96 | { |
| r9683 | r9684 | |
| 73 | 105 | } |
| 74 | 106 | } |
| 75 | 107 | |
| 76 | | static UINT8 nRTC_Regs[0x80]; |
| 77 | | static UINT8 nRTC_UserRAM[0x200]; |
| 78 | | static UINT8 nRTC_RAM[0x800]; |
| 79 | 108 | |
| 80 | | static UINT32 nHPC_SCSI0Descriptor, nHPC_SCSI0DMACtrl; |
| 81 | 109 | |
| 82 | 110 | static const struct pit8253_config ip22_pit8254_config = |
| 83 | 111 | { |
| r9683 | r9684 | |
| 100 | 128 | |
| 101 | 129 | static NVRAM_HANDLER( ip22 ) |
| 102 | 130 | { |
| 131 | ip22_state *state = machine->driver_data<ip22_state>(); |
| 103 | 132 | if (read_or_write) |
| 104 | 133 | { |
| 105 | | mame_fwrite(file, nRTC_UserRAM, 0x200); |
| 106 | | mame_fwrite(file, nRTC_RAM, 0x200); |
| 134 | mame_fwrite(file, state->nRTC_UserRAM, 0x200); |
| 135 | mame_fwrite(file, state->nRTC_RAM, 0x200); |
| 107 | 136 | } |
| 108 | 137 | else |
| 109 | 138 | { |
| 110 | 139 | if (file) |
| 111 | 140 | { |
| 112 | | mame_fread(file, nRTC_UserRAM, 0x200); |
| 113 | | mame_fread(file, nRTC_RAM, 0x200); |
| 141 | mame_fread(file, state->nRTC_UserRAM, 0x200); |
| 142 | mame_fread(file, state->nRTC_RAM, 0x200); |
| 114 | 143 | } |
| 115 | 144 | } |
| 116 | 145 | } |
| 117 | 146 | |
| 118 | | #define RTC_DAY nRTC_RAM[0x09] |
| 119 | | #define RTC_HOUR nRTC_RAM[0x08] |
| 120 | | #define RTC_MINUTE nRTC_RAM[0x07] |
| 121 | | #define RTC_SECOND nRTC_RAM[0x06] |
| 122 | | #define RTC_HUNDREDTH nRTC_RAM[0x05] |
| 147 | #define RTC_DAY state->nRTC_RAM[0x09] |
| 148 | #define RTC_HOUR state->nRTC_RAM[0x08] |
| 149 | #define RTC_MINUTE state->nRTC_RAM[0x07] |
| 150 | #define RTC_SECOND state->nRTC_RAM[0x06] |
| 151 | #define RTC_HUNDREDTH state->nRTC_RAM[0x05] |
| 123 | 152 | |
| 124 | 153 | // interrupt sources handled by INT3 |
| 125 | 154 | #define INT3_LOCAL0_FIFO (0x01) |
| r9683 | r9684 | |
| 140 | 169 | #define INT3_LOCAL1_VSYNC (0x40) |
| 141 | 170 | #define INT3_LOCAL1_RETRACE (0x80) |
| 142 | 171 | |
| 143 | | static UINT32 int3_regs[64]; |
| 144 | 172 | /*static UINT8 nIOC_ParCntl;*/ |
| 145 | | static UINT32 nIOC_ParReadCnt; |
| 146 | 173 | |
| 147 | 174 | // raise a local0 interrupt |
| 148 | 175 | static void int3_raise_local0_irq(running_machine *machine, UINT8 source_mask) |
| 149 | 176 | { |
| 177 | ip22_state *state = machine->driver_data<ip22_state>(); |
| 150 | 178 | // signal the interrupt is pending |
| 151 | | int3_regs[0] |= source_mask; |
| 179 | state->int3_regs[0] |= source_mask; |
| 152 | 180 | |
| 153 | 181 | // if it's not masked, also assert it now at the CPU |
| 154 | | if (int3_regs[1] & source_mask) |
| 182 | if (state->int3_regs[1] & source_mask) |
| 155 | 183 | { |
| 156 | 184 | cputag_set_input_line(machine, "maincpu", MIPS3_IRQ0, ASSERT_LINE); |
| 157 | 185 | } |
| 158 | 186 | } |
| 159 | 187 | |
| 160 | 188 | // lower a local0 interrupt |
| 161 | | static void int3_lower_local0_irq(UINT8 source_mask) |
| 189 | static void int3_lower_local0_irq(ip22_state *state, UINT8 source_mask) |
| 162 | 190 | { |
| 163 | | int3_regs[0] &= ~source_mask; |
| 191 | state->int3_regs[0] &= ~source_mask; |
| 164 | 192 | } |
| 165 | 193 | |
| 166 | 194 | #ifdef UNUSED_FUNCTION |
| 167 | 195 | // raise a local1 interrupt |
| 168 | 196 | static void int3_raise_local1_irq(running_machine *machine, UINT8 source_mask) |
| 169 | 197 | { |
| 198 | ip22_state *state = machine->driver_data<ip22_state>(); |
| 170 | 199 | // signal the interrupt is pending |
| 171 | | int3_regs[2] |= source_mask; |
| 200 | state->int3_regs[2] |= source_mask; |
| 172 | 201 | |
| 173 | 202 | // if it's not masked, also assert it now at the CPU |
| 174 | | if (int3_regs[2] & source_mask) |
| 203 | if (state->int3_regs[2] & source_mask) |
| 175 | 204 | { |
| 176 | 205 | cputag_set_input_line(machine, "maincpu", MIPS3_IRQ1, ASSERT_LINE); |
| 177 | 206 | } |
| r9683 | r9684 | |
| 180 | 209 | // lower a local1 interrupt |
| 181 | 210 | static void int3_lower_local1_irq(UINT8 source_mask) |
| 182 | 211 | { |
| 183 | | int3_regs[2] &= ~source_mask; |
| 212 | ip22_state *state = machine->driver_data<ip22_state>(); |
| 213 | state->int3_regs[2] &= ~source_mask; |
| 184 | 214 | } |
| 185 | 215 | #endif |
| 186 | 216 | |
| 187 | 217 | static READ32_HANDLER( hpc3_pbus6_r ) |
| 188 | 218 | { |
| 219 | ip22_state *state = space->machine->driver_data<ip22_state>(); |
| 189 | 220 | running_device *lpt = space->machine->device("lpt_0"); |
| 190 | 221 | UINT8 ret8; |
| 191 | 222 | running_machine *machine = space->machine; |
| r9683 | r9684 | |
| 235 | 266 | case 0xa8/4: |
| 236 | 267 | case 0xac/4: |
| 237 | 268 | // mame_printf_info("INT3: r @ %x mask %08x (PC=%x)\n", offset*4, mem_mask, activecpu_get_pc()); |
| 238 | | return int3_regs[offset-0x80/4]; |
| 269 | return state->int3_regs[offset-0x80/4]; |
| 239 | 270 | case 0xb0/4: |
| 240 | 271 | ret8 = pit8253_r(machine->device("pit8254"), 0); |
| 241 | 272 | verboselog( machine, 0, "HPC PBUS6 IOC4 Timer Counter 0 Register Read: 0x%02x (%08x)\n", ret8, mem_mask ); |
| r9683 | r9684 | |
| 261 | 292 | |
| 262 | 293 | static WRITE32_HANDLER( hpc3_pbus6_w ) |
| 263 | 294 | { |
| 295 | ip22_state *state = space->machine->driver_data<ip22_state>(); |
| 264 | 296 | running_device *lpt = space->machine->device("lpt_0"); |
| 265 | 297 | char cChar; |
| 266 | 298 | running_machine *machine = space->machine; |
| r9683 | r9684 | |
| 319 | 351 | case 0xa0/4: |
| 320 | 352 | case 0xa4/4: |
| 321 | 353 | // mame_printf_info("INT3: w %x to %x (reg %d) mask %08x (PC=%x)\n", data, offset*4, offset-0x80/4, mem_mask, activecpu_get_pc()); |
| 322 | | int3_regs[offset-0x80/4] = data; |
| 354 | state->int3_regs[offset-0x80/4] = data; |
| 323 | 355 | |
| 324 | 356 | // if no local0 interrupts now, clear the input to the CPU |
| 325 | | if ((int3_regs[0] & int3_regs[1]) == 0) |
| 357 | if ((state->int3_regs[0] & state->int3_regs[1]) == 0) |
| 326 | 358 | { |
| 327 | 359 | cputag_set_input_line(machine, "maincpu", MIPS3_IRQ0, CLEAR_LINE); |
| 328 | 360 | } |
| r9683 | r9684 | |
| 332 | 364 | } |
| 333 | 365 | |
| 334 | 366 | // if no local1 interrupts now, clear the input to the CPU |
| 335 | | if ((int3_regs[2] & int3_regs[3]) == 0) |
| 367 | if ((state->int3_regs[2] & state->int3_regs[3]) == 0) |
| 336 | 368 | { |
| 337 | 369 | cputag_set_input_line(machine, "maincpu", MIPS3_IRQ1, CLEAR_LINE); |
| 338 | 370 | } |
| r9683 | r9684 | |
| 363 | 395 | } |
| 364 | 396 | } |
| 365 | 397 | |
| 366 | | static UINT32 nHPC3_enetr_nbdp; |
| 367 | | static UINT32 nHPC3_enetr_cbp; |
| 368 | 398 | //UINT32 nHPC3_hd0_register; |
| 369 | 399 | //UINT32 nHPC3_hd0_regs[0x20]; |
| 370 | 400 | //UINT32 nHPC3_hd1_regs[0x20]; |
| 371 | 401 | |
| 372 | 402 | static READ32_HANDLER( hpc3_hd_enet_r ) |
| 373 | 403 | { |
| 404 | ip22_state *state = space->machine->driver_data<ip22_state>(); |
| 374 | 405 | running_machine *machine = space->machine; |
| 375 | 406 | |
| 376 | 407 | switch( offset ) |
| 377 | 408 | { |
| 378 | 409 | case 0x0004/4: |
| 379 | | verboselog(machine, 0, "HPC3 SCSI0DESC Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, nHPC_SCSI0Descriptor ); |
| 380 | | return nHPC_SCSI0Descriptor; |
| 410 | verboselog(machine, 0, "HPC3 SCSI0DESC Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, state->nHPC_SCSI0Descriptor ); |
| 411 | return state->nHPC_SCSI0Descriptor; |
| 381 | 412 | case 0x1004/4: |
| 382 | | verboselog(machine, 0, "HPC3 SCSI0DMACTRL Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, nHPC_SCSI0DMACtrl ); |
| 383 | | return nHPC_SCSI0DMACtrl; |
| 413 | verboselog(machine, 0, "HPC3 SCSI0DMACTRL Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, state->nHPC_SCSI0DMACtrl ); |
| 414 | return state->nHPC_SCSI0DMACtrl; |
| 384 | 415 | case 0x4000/4: |
| 385 | | verboselog(machine, 2, "HPC3 ENETR CBP Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, nHPC3_enetr_nbdp ); |
| 386 | | return nHPC3_enetr_cbp; |
| 416 | verboselog(machine, 2, "HPC3 ENETR CBP Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, state->nHPC3_enetr_nbdp ); |
| 417 | return state->nHPC3_enetr_cbp; |
| 387 | 418 | case 0x4004/4: |
| 388 | | verboselog(machine, 2, "HPC3 ENETR NBDP Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, nHPC3_enetr_nbdp ); |
| 389 | | return nHPC3_enetr_nbdp; |
| 419 | verboselog(machine, 2, "HPC3 ENETR NBDP Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, state->nHPC3_enetr_nbdp ); |
| 420 | return state->nHPC3_enetr_nbdp; |
| 390 | 421 | default: |
| 391 | 422 | verboselog(machine, 0, "Unknown HPC3 ENET/HDx Read: %08x (%08x)\n", 0x1fb90000 + ( offset << 2 ), mem_mask ); |
| 392 | 423 | return 0; |
| r9683 | r9684 | |
| 396 | 427 | |
| 397 | 428 | static WRITE32_HANDLER( hpc3_hd_enet_w ) |
| 398 | 429 | { |
| 430 | ip22_state *state = space->machine->driver_data<ip22_state>(); |
| 399 | 431 | running_machine *machine = space->machine; |
| 400 | 432 | |
| 401 | 433 | switch( offset ) |
| 402 | 434 | { |
| 403 | 435 | case 0x0004/4: |
| 404 | 436 | verboselog(machine, 2, "HPC3 SCSI0DESC Write: %08x\n", data ); |
| 405 | | nHPC_SCSI0Descriptor = data; |
| 437 | state->nHPC_SCSI0Descriptor = data; |
| 406 | 438 | break; |
| 407 | 439 | case 0x1004/4: |
| 408 | 440 | verboselog(machine, 2, "HPC3 SCSI0DMACTRL Write: %08x\n", data ); |
| 409 | | nHPC_SCSI0DMACtrl = data; |
| 441 | state->nHPC_SCSI0DMACtrl = data; |
| 410 | 442 | break; |
| 411 | 443 | case 0x4000/4: |
| 412 | 444 | verboselog(machine, 2, "HPC3 ENETR CBP Write: %08x\n", data ); |
| 413 | | nHPC3_enetr_cbp = data; |
| 445 | state->nHPC3_enetr_cbp = data; |
| 414 | 446 | break; |
| 415 | 447 | case 0x4004/4: |
| 416 | 448 | verboselog(machine, 2, "HPC3 ENETR NBDP Write: %08x\n", data ); |
| 417 | | nHPC3_enetr_nbdp = data; |
| 449 | state->nHPC3_enetr_nbdp = data; |
| 418 | 450 | break; |
| 419 | 451 | default: |
| 420 | 452 | verboselog(machine, 0, "Unknown HPC3 ENET/HDx write: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2 ), mem_mask, data ); |
| r9683 | r9684 | |
| 485 | 517 | } |
| 486 | 518 | } |
| 487 | 519 | |
| 488 | | static UINT32 nHPC3_unk0; |
| 489 | | static UINT32 nHPC3_unk1; |
| 490 | | static UINT32 nHPC3_IC_Unk0; |
| 491 | 520 | |
| 492 | 521 | static READ32_HANDLER( hpc3_pbus4_r ) |
| 493 | 522 | { |
| 523 | ip22_state *state = space->machine->driver_data<ip22_state>(); |
| 494 | 524 | running_machine *machine = space->machine; |
| 495 | 525 | |
| 496 | 526 | switch( offset ) |
| 497 | 527 | { |
| 498 | 528 | case 0x0004/4: |
| 499 | | verboselog(machine, 2, "HPC3 PBUS4 Unknown 0 Read: (%08x): %08x\n", mem_mask, nHPC3_unk0 ); |
| 500 | | return nHPC3_unk0; |
| 529 | verboselog(machine, 2, "HPC3 PBUS4 Unknown 0 Read: (%08x): %08x\n", mem_mask, state->nHPC3_unk0 ); |
| 530 | return state->nHPC3_unk0; |
| 501 | 531 | case 0x000c/4: |
| 502 | | verboselog(machine, 2, "Interrupt Controller(?) Read: (%08x): %08x\n", mem_mask, nHPC3_IC_Unk0 ); |
| 503 | | return nHPC3_IC_Unk0; |
| 532 | verboselog(machine, 2, "Interrupt Controller(?) Read: (%08x): %08x\n", mem_mask, state->nHPC3_IC_Unk0 ); |
| 533 | return state->nHPC3_IC_Unk0; |
| 504 | 534 | case 0x0014/4: |
| 505 | | verboselog(machine, 2, "HPC3 PBUS4 Unknown 1 Read: (%08x): %08x\n", mem_mask, nHPC3_unk1 ); |
| 506 | | return nHPC3_unk1; |
| 535 | verboselog(machine, 2, "HPC3 PBUS4 Unknown 1 Read: (%08x): %08x\n", mem_mask, state->nHPC3_unk1 ); |
| 536 | return state->nHPC3_unk1; |
| 507 | 537 | default: |
| 508 | 538 | verboselog(machine, 0, "Unknown HPC3 PBUS4 Read: %08x (%08x)\n", 0x1fbd9000 + ( offset << 2 ), mem_mask ); |
| 509 | 539 | return 0; |
| r9683 | r9684 | |
| 513 | 543 | |
| 514 | 544 | static WRITE32_HANDLER( hpc3_pbus4_w ) |
| 515 | 545 | { |
| 546 | ip22_state *state = space->machine->driver_data<ip22_state>(); |
| 516 | 547 | running_machine *machine = space->machine; |
| 517 | 548 | |
| 518 | 549 | switch( offset ) |
| 519 | 550 | { |
| 520 | 551 | case 0x0004/4: |
| 521 | 552 | verboselog(machine, 2, "HPC3 PBUS4 Unknown 0 Write: %08x (%08x)\n", data, mem_mask ); |
| 522 | | nHPC3_unk0 = data; |
| 553 | state->nHPC3_unk0 = data; |
| 523 | 554 | break; |
| 524 | 555 | case 0x000c/4: |
| 525 | 556 | verboselog(machine, 2, "Interrupt Controller(?) Write: (%08x): %08x\n", mem_mask, data ); |
| 526 | | nHPC3_IC_Unk0 = data; |
| 557 | state->nHPC3_IC_Unk0 = data; |
| 527 | 558 | break; |
| 528 | 559 | case 0x0014/4: |
| 529 | 560 | verboselog(machine, 2, "HPC3 PBUS4 Unknown 1 Write: %08x (%08x)\n", data, mem_mask ); |
| 530 | | nHPC3_unk1 = data; |
| 561 | state->nHPC3_unk1 = data; |
| 531 | 562 | break; |
| 532 | 563 | default: |
| 533 | 564 | verboselog(machine, 0, "Unknown HPC3 PBUS4 Write: %08x (%08x): %08x\n", 0x1fbd9000 + ( offset << 2 ), mem_mask, data ); |
| r9683 | r9684 | |
| 535 | 566 | } |
| 536 | 567 | } |
| 537 | 568 | |
| 538 | | #define RTC_SECONDS nRTC_Regs[0x00] |
| 539 | | #define RTC_SECONDS_A nRTC_Regs[0x01] |
| 540 | | #define RTC_MINUTES nRTC_Regs[0x02] |
| 541 | | #define RTC_MINUTES_A nRTC_Regs[0x03] |
| 542 | | #define RTC_HOURS nRTC_Regs[0x04] |
| 543 | | #define RTC_HOURS_A nRTC_Regs[0x05] |
| 544 | | #define RTC_DAYOFWEEK nRTC_Regs[0x06] |
| 545 | | #define RTC_DAYOFMONTH nRTC_Regs[0x07] |
| 546 | | #define RTC_MONTH nRTC_Regs[0x08] |
| 547 | | #define RTC_YEAR nRTC_Regs[0x09] |
| 548 | | #define RTC_REGISTERA nRTC_Regs[0x0a] |
| 549 | | #define RTC_REGISTERB nRTC_Regs[0x0b] |
| 550 | | #define RTC_REGISTERC nRTC_Regs[0x0c] |
| 551 | | #define RTC_REGISTERD nRTC_Regs[0x0d] |
| 552 | | #define RTC_MODELBYTE nRTC_Regs[0x40] |
| 553 | | #define RTC_SERBYTE0 nRTC_Regs[0x41] |
| 554 | | #define RTC_SERBYTE1 nRTC_Regs[0x42] |
| 555 | | #define RTC_SERBYTE2 nRTC_Regs[0x43] |
| 556 | | #define RTC_SERBYTE3 nRTC_Regs[0x44] |
| 557 | | #define RTC_SERBYTE4 nRTC_Regs[0x45] |
| 558 | | #define RTC_SERBYTE5 nRTC_Regs[0x46] |
| 559 | | #define RTC_CRC nRTC_Regs[0x47] |
| 560 | | #define RTC_CENTURY nRTC_Regs[0x48] |
| 561 | | #define RTC_DAYOFMONTH_A nRTC_Regs[0x49] |
| 562 | | #define RTC_EXTCTRL0 nRTC_Regs[0x4a] |
| 563 | | #define RTC_EXTCTRL1 nRTC_Regs[0x4b] |
| 564 | | #define RTC_RTCADDR2 nRTC_Regs[0x4e] |
| 565 | | #define RTC_RTCADDR3 nRTC_Regs[0x4f] |
| 566 | | #define RTC_RAMLSB nRTC_Regs[0x50] |
| 567 | | #define RTC_RAMMSB nRTC_Regs[0x51] |
| 568 | | #define RTC_WRITECNT nRTC_Regs[0x5e] |
| 569 | #define RTC_SECONDS state->nRTC_Regs[0x00] |
| 570 | #define RTC_SECONDS_A state->nRTC_Regs[0x01] |
| 571 | #define RTC_MINUTES state->nRTC_Regs[0x02] |
| 572 | #define RTC_MINUTES_A state->nRTC_Regs[0x03] |
| 573 | #define RTC_HOURS state->nRTC_Regs[0x04] |
| 574 | #define RTC_HOURS_A state->nRTC_Regs[0x05] |
| 575 | #define RTC_DAYOFWEEK state->nRTC_Regs[0x06] |
| 576 | #define RTC_DAYOFMONTH state->nRTC_Regs[0x07] |
| 577 | #define RTC_MONTH state->nRTC_Regs[0x08] |
| 578 | #define RTC_YEAR state->nRTC_Regs[0x09] |
| 579 | #define RTC_REGISTERA state->nRTC_Regs[0x0a] |
| 580 | #define RTC_REGISTERB state->nRTC_Regs[0x0b] |
| 581 | #define RTC_REGISTERC state->nRTC_Regs[0x0c] |
| 582 | #define RTC_REGISTERD state->nRTC_Regs[0x0d] |
| 583 | #define RTC_MODELBYTE state->nRTC_Regs[0x40] |
| 584 | #define RTC_SERBYTE0 state->nRTC_Regs[0x41] |
| 585 | #define RTC_SERBYTE1 state->nRTC_Regs[0x42] |
| 586 | #define RTC_SERBYTE2 state->nRTC_Regs[0x43] |
| 587 | #define RTC_SERBYTE3 state->nRTC_Regs[0x44] |
| 588 | #define RTC_SERBYTE4 state->nRTC_Regs[0x45] |
| 589 | #define RTC_SERBYTE5 state->nRTC_Regs[0x46] |
| 590 | #define RTC_CRC state->nRTC_Regs[0x47] |
| 591 | #define RTC_CENTURY state->nRTC_Regs[0x48] |
| 592 | #define RTC_DAYOFMONTH_A state->nRTC_Regs[0x49] |
| 593 | #define RTC_EXTCTRL0 state->nRTC_Regs[0x4a] |
| 594 | #define RTC_EXTCTRL1 state->nRTC_Regs[0x4b] |
| 595 | #define RTC_RTCADDR2 state->nRTC_Regs[0x4e] |
| 596 | #define RTC_RTCADDR3 state->nRTC_Regs[0x4f] |
| 597 | #define RTC_RAMLSB state->nRTC_Regs[0x50] |
| 598 | #define RTC_RAMMSB state->nRTC_Regs[0x51] |
| 599 | #define RTC_WRITECNT state->nRTC_Regs[0x5e] |
| 569 | 600 | |
| 570 | 601 | static READ32_HANDLER( rtc_r ) |
| 571 | 602 | { |
| 603 | ip22_state *state = space->machine->driver_data<ip22_state>(); |
| 572 | 604 | running_machine *machine = space->machine; |
| 573 | 605 | |
| 574 | | // mame_printf_info("RTC_R: offset %x = %x (PC=%x)\n", offset, nRTC_Regs[offset], activecpu_get_pc()); |
| 606 | // mame_printf_info("RTC_R: offset %x = %x (PC=%x)\n", offset, state->nRTC_Regs[offset], activecpu_get_pc()); |
| 575 | 607 | |
| 576 | 608 | if( offset <= 0x0d ) |
| 577 | 609 | { |
| r9683 | r9684 | |
| 626 | 658 | } |
| 627 | 659 | if( offset >= 0x0e && offset < 0x40 ) |
| 628 | 660 | { |
| 629 | | return nRTC_Regs[offset]; |
| 661 | return state->nRTC_Regs[offset]; |
| 630 | 662 | } |
| 631 | 663 | if( offset >= 0x40 && offset < 0x80 && !( RTC_REGISTERA & 0x10 ) ) |
| 632 | 664 | { |
| 633 | | return nRTC_UserRAM[offset - 0x40]; |
| 665 | return state->nRTC_UserRAM[offset - 0x40]; |
| 634 | 666 | } |
| 635 | 667 | if( offset >= 0x40 && offset < 0x80 && ( RTC_REGISTERA & 0x10 ) ) |
| 636 | 668 | { |
| r9683 | r9684 | |
| 685 | 717 | verboselog(machine, 3, "RTC RAM MSB Read: %02x \n", RTC_RAMMSB ); |
| 686 | 718 | return RTC_RAMMSB; |
| 687 | 719 | case 0x0053: |
| 688 | | return nRTC_RAM[ ( RTC_RAMMSB << 8 ) | RTC_RAMLSB ]; |
| 720 | return state->nRTC_RAM[ ( RTC_RAMMSB << 8 ) | RTC_RAMLSB ]; |
| 689 | 721 | case 0x005e: |
| 690 | 722 | return RTC_WRITECNT; |
| 691 | 723 | default: |
| r9683 | r9684 | |
| 695 | 727 | } |
| 696 | 728 | if( offset >= 0x80 ) |
| 697 | 729 | { |
| 698 | | return nRTC_UserRAM[ offset - 0x80 ]; |
| 730 | return state->nRTC_UserRAM[ offset - 0x80 ]; |
| 699 | 731 | } |
| 700 | 732 | return 0; |
| 701 | 733 | } |
| 702 | 734 | |
| 703 | 735 | static WRITE32_HANDLER( rtc_w ) |
| 704 | 736 | { |
| 737 | ip22_state *state = space->machine->driver_data<ip22_state>(); |
| 705 | 738 | running_machine *machine = space->machine; |
| 706 | 739 | |
| 707 | 740 | RTC_WRITECNT++; |
| r9683 | r9684 | |
| 773 | 806 | } |
| 774 | 807 | if( offset >= 0x0e && offset < 0x40 ) |
| 775 | 808 | { |
| 776 | | nRTC_Regs[offset] = data; |
| 809 | state->nRTC_Regs[offset] = data; |
| 777 | 810 | return; |
| 778 | 811 | } |
| 779 | 812 | if( offset >= 0x40 && offset < 0x80 && !( RTC_REGISTERA & 0x10 ) ) |
| 780 | 813 | { |
| 781 | | nRTC_UserRAM[offset - 0x40] = data; |
| 814 | state->nRTC_UserRAM[offset - 0x40] = data; |
| 782 | 815 | return; |
| 783 | 816 | } |
| 784 | 817 | if( offset >= 0x40 && offset < 0x80 && ( RTC_REGISTERA & 0x10 ) ) |
| r9683 | r9684 | |
| 831 | 864 | RTC_RAMMSB = data; |
| 832 | 865 | break; |
| 833 | 866 | case 0x0053: |
| 834 | | nRTC_RAM[ ( RTC_RAMMSB << 8 ) | RTC_RAMLSB ] = data; |
| 867 | state->nRTC_RAM[ ( RTC_RAMMSB << 8 ) | RTC_RAMLSB ] = data; |
| 835 | 868 | break; |
| 836 | 869 | default: |
| 837 | 870 | verboselog(machine, 3, "Unknown RTC Ext. Reg. Write: %02x: %02x\n", offset, data ); |
| r9683 | r9684 | |
| 840 | 873 | } |
| 841 | 874 | if( offset >= 0x80 ) |
| 842 | 875 | { |
| 843 | | nRTC_UserRAM[ offset - 0x80 ] = data; |
| 876 | state->nRTC_UserRAM[ offset - 0x80 ] = data; |
| 844 | 877 | } |
| 845 | 878 | } |
| 846 | 879 | |
| 847 | 880 | // a bit hackish, but makes the memory detection work properly and allows a big cleanup of the mapping |
| 848 | 881 | static WRITE32_HANDLER( ip22_write_ram ) |
| 849 | 882 | { |
| 883 | ip22_state *state = space->machine->driver_data<ip22_state>(); |
| 850 | 884 | // if banks 2 or 3 are enabled, do nothing, we don't support that much memory |
| 851 | 885 | if (sgi_mc_r(space, 0xc8/4, 0xffffffff) & 0x10001000) |
| 852 | 886 | { |
| r9683 | r9684 | |
| 860 | 894 | // a random perturbation so the memory test fails |
| 861 | 895 | data ^= 0xffffffff; |
| 862 | 896 | } |
| 863 | | COMBINE_DATA(&ip22_mainram[offset]); |
| 897 | COMBINE_DATA(&state->mainram[offset]); |
| 864 | 898 | } |
| 865 | 899 | |
| 866 | | static UINT32 nHAL2_IAR; |
| 867 | | static UINT32 nHAL2_IDR[4]; |
| 868 | 900 | |
| 869 | 901 | #define H2_IAR_TYPE 0xf000 |
| 870 | 902 | #define H2_IAR_NUM 0x0f00 |
| r9683 | r9684 | |
| 897 | 929 | |
| 898 | 930 | static WRITE32_HANDLER( hal2_w ) |
| 899 | 931 | { |
| 932 | ip22_state *state = space->machine->driver_data<ip22_state>(); |
| 900 | 933 | running_machine *machine = space->machine; |
| 901 | 934 | |
| 902 | 935 | switch( offset ) |
| r9683 | r9684 | |
| 914 | 947 | break; |
| 915 | 948 | case 0x0030/4: |
| 916 | 949 | verboselog(machine, 0, "HAL2 Indirect Address Register Write: 0x%08x (%08x)\n", data, mem_mask ); |
| 917 | | nHAL2_IAR = data; |
| 950 | state->nHAL2_IAR = data; |
| 918 | 951 | switch( data & H2_IAR_TYPE ) |
| 919 | 952 | { |
| 920 | 953 | case 0x1000: |
| r9683 | r9684 | |
| 991 | 1024 | break; |
| 992 | 1025 | case 0x0040/4: |
| 993 | 1026 | verboselog(machine, 0, "HAL2 Indirect Data Register 0 Write: 0x%08x (%08x)\n", data, mem_mask ); |
| 994 | | nHAL2_IDR[0] = data; |
| 1027 | state->nHAL2_IDR[0] = data; |
| 995 | 1028 | return; |
| 996 | 1029 | case 0x0050/4: |
| 997 | 1030 | verboselog(machine, 0, "HAL2 Indirect Data Register 1 Write: 0x%08x (%08x)\n", data, mem_mask ); |
| 998 | | nHAL2_IDR[1] = data; |
| 1031 | state->nHAL2_IDR[1] = data; |
| 999 | 1032 | return; |
| 1000 | 1033 | case 0x0060/4: |
| 1001 | 1034 | verboselog(machine, 0, "HAL2 Indirect Data Register 2 Write: 0x%08x (%08x)\n", data, mem_mask ); |
| 1002 | | nHAL2_IDR[2] = data; |
| 1035 | state->nHAL2_IDR[2] = data; |
| 1003 | 1036 | return; |
| 1004 | 1037 | case 0x0070/4: |
| 1005 | 1038 | verboselog(machine, 0, "HAL2 Indirect Data Register 3 Write: 0x%08x (%08x)\n", data, mem_mask ); |
| 1006 | | nHAL2_IDR[3] = data; |
| 1039 | state->nHAL2_IDR[3] = data; |
| 1007 | 1040 | return; |
| 1008 | 1041 | } |
| 1009 | 1042 | verboselog(machine, 0, "Unknown HAL2 write: 0x%08x: 0x%08x (%08x)\n", 0x1fbd8000 + offset*4, data, mem_mask ); |
| r9683 | r9684 | |
| 1026 | 1059 | #define PBUS_DMADESC_TXD 0x00008000 |
| 1027 | 1060 | #define PBUS_DMADESC_BC 0x00003fff |
| 1028 | 1061 | |
| 1029 | | static UINT8 nPBUS_DMA_Active; |
| 1030 | | static UINT32 nPBUS_DMA_CurPtr; |
| 1031 | | static UINT32 nPBUS_DMA_DescPtr; |
| 1032 | | static UINT32 nPBUS_DMA_NextPtr; |
| 1033 | | static UINT32 nPBUS_DMA_WordsLeft; |
| 1034 | 1062 | |
| 1035 | 1063 | static TIMER_CALLBACK(ip22_dma) |
| 1036 | 1064 | { |
| 1065 | //ip22_state *state = machine->driver_data<ip22_state>(); |
| 1037 | 1066 | timer_set(machine, attotime_never, NULL, 0, ip22_dma); |
| 1038 | 1067 | #if 0 |
| 1039 | | if( nPBUS_DMA_Active ) |
| 1068 | if( state->nPBUS_DMA_Active ) |
| 1040 | 1069 | { |
| 1041 | | UINT16 temp16 = ( ip22_mainram[(nPBUS_DMA_CurPtr - 0x08000000)/4] & 0xffff0000 ) >> 16; |
| 1070 | UINT16 temp16 = ( state->mainram[(state->nPBUS_DMA_CurPtr - 0x08000000)/4] & 0xffff0000 ) >> 16; |
| 1042 | 1071 | INT16 stemp16 = (INT16)((temp16 >> 8) | (temp16 << 8)); |
| 1043 | 1072 | |
| 1044 | 1073 | dac_signed_data_16_w(machine->device("dac"), stemp16 ^ 0x8000); |
| 1045 | 1074 | |
| 1046 | | nPBUS_DMA_CurPtr += 4; |
| 1075 | state->nPBUS_DMA_CurPtr += 4; |
| 1047 | 1076 | |
| 1048 | | nPBUS_DMA_WordsLeft -= 4; |
| 1049 | | if( nPBUS_DMA_WordsLeft == 0 ) |
| 1077 | state->nPBUS_DMA_WordsLeft -= 4; |
| 1078 | if( state->nPBUS_DMA_WordsLeft == 0 ) |
| 1050 | 1079 | { |
| 1051 | | if( nPBUS_DMA_NextPtr != 0 ) |
| 1080 | if( state->nPBUS_DMA_NextPtr != 0 ) |
| 1052 | 1081 | { |
| 1053 | | nPBUS_DMA_DescPtr = nPBUS_DMA_NextPtr; |
| 1054 | | nPBUS_DMA_CurPtr = ip22_mainram[(nPBUS_DMA_DescPtr - 0x08000000)/4]; |
| 1055 | | nPBUS_DMA_WordsLeft = ip22_mainram[(nPBUS_DMA_DescPtr - 0x08000000)/4+1]; |
| 1056 | | nPBUS_DMA_NextPtr = ip22_mainram[(nPBUS_DMA_DescPtr - 0x08000000)/4+2]; |
| 1082 | state->nPBUS_DMA_DescPtr = state->nPBUS_DMA_NextPtr; |
| 1083 | state->nPBUS_DMA_CurPtr = state->mainram[(state->nPBUS_DMA_DescPtr - 0x08000000)/4]; |
| 1084 | state->nPBUS_DMA_WordsLeft = state->mainram[(state->nPBUS_DMA_DescPtr - 0x08000000)/4+1]; |
| 1085 | state->nPBUS_DMA_NextPtr = state->mainram[(state->nPBUS_DMA_DescPtr - 0x08000000)/4+2]; |
| 1057 | 1086 | } |
| 1058 | 1087 | else |
| 1059 | 1088 | { |
| 1060 | | nPBUS_DMA_Active = 0; |
| 1089 | state->nPBUS_DMA_Active = 0; |
| 1061 | 1090 | return; |
| 1062 | 1091 | } |
| 1063 | 1092 | } |
| r9683 | r9684 | |
| 1075 | 1104 | |
| 1076 | 1105 | static WRITE32_HANDLER( hpc3_pbusdma_w ) |
| 1077 | 1106 | { |
| 1107 | ip22_state *state = space->machine->driver_data<ip22_state>(); |
| 1078 | 1108 | UINT32 channel = offset / (0x2000/4); |
| 1079 | 1109 | running_machine *machine = space->machine; |
| 1080 | 1110 | |
| r9683 | r9684 | |
| 1087 | 1117 | verboselog(machine, 0, "PBUS DMA Channel %d Descriptor Pointer Write: 0x%08x\n", channel, data ); |
| 1088 | 1118 | if( channel == 1 ) |
| 1089 | 1119 | { |
| 1090 | | nPBUS_DMA_DescPtr = data; |
| 1091 | | nPBUS_DMA_CurPtr = ip22_mainram[(nPBUS_DMA_DescPtr - 0x08000000)/4]; |
| 1092 | | nPBUS_DMA_WordsLeft = ip22_mainram[(nPBUS_DMA_DescPtr - 0x08000000)/4+1]; |
| 1093 | | nPBUS_DMA_NextPtr = ip22_mainram[(nPBUS_DMA_DescPtr - 0x08000000)/4+2]; |
| 1094 | | verboselog(machine, 0, "nPBUS_DMA_DescPtr = %08x\n", nPBUS_DMA_DescPtr ); |
| 1095 | | verboselog(machine, 0, "nPBUS_DMA_CurPtr = %08x\n", nPBUS_DMA_CurPtr ); |
| 1096 | | verboselog(machine, 0, "nPBUS_DMA_WordsLeft = %08x\n", nPBUS_DMA_WordsLeft ); |
| 1097 | | verboselog(machine, 0, "nPBUS_DMA_NextPtr = %08x\n", nPBUS_DMA_NextPtr ); |
| 1120 | state->nPBUS_DMA_DescPtr = data; |
| 1121 | state->nPBUS_DMA_CurPtr = state->mainram[(state->nPBUS_DMA_DescPtr - 0x08000000)/4]; |
| 1122 | state->nPBUS_DMA_WordsLeft = state->mainram[(state->nPBUS_DMA_DescPtr - 0x08000000)/4+1]; |
| 1123 | state->nPBUS_DMA_NextPtr = state->mainram[(state->nPBUS_DMA_DescPtr - 0x08000000)/4+2]; |
| 1124 | verboselog(machine, 0, "nPBUS_DMA_DescPtr = %08x\n", state->nPBUS_DMA_DescPtr ); |
| 1125 | verboselog(machine, 0, "nPBUS_DMA_CurPtr = %08x\n", state->nPBUS_DMA_CurPtr ); |
| 1126 | verboselog(machine, 0, "nPBUS_DMA_WordsLeft = %08x\n", state->nPBUS_DMA_WordsLeft ); |
| 1127 | verboselog(machine, 0, "nPBUS_DMA_NextPtr = %08x\n", state->nPBUS_DMA_NextPtr ); |
| 1098 | 1128 | } |
| 1099 | 1129 | return; |
| 1100 | 1130 | case 0x1000/4: |
| r9683 | r9684 | |
| 1133 | 1163 | if( ( data & PBUS_CTRL_DMASTART ) || ( data & PBUS_CTRL_LOAD_EN ) ) |
| 1134 | 1164 | { |
| 1135 | 1165 | timer_set(machine, ATTOTIME_IN_HZ(44100), NULL, 0, ip22_dma); |
| 1136 | | nPBUS_DMA_Active = 1; |
| 1166 | state->nPBUS_DMA_Active = 1; |
| 1137 | 1167 | } |
| 1138 | 1168 | return; |
| 1139 | 1169 | } |
| 1140 | 1170 | verboselog(machine, 0, "Unknown PBUS DMA Channel %d Write: 0x%08x: 0x%08x (%08x)\n", channel, 0x1fb80000 + offset*4, data, mem_mask ); |
| 1141 | 1171 | } |
| 1142 | 1172 | |
| 1143 | | static UINT32 *unkpbus0; |
| 1144 | 1173 | static READ32_HANDLER( hpc3_unkpbus0_r ) |
| 1145 | 1174 | { |
| 1175 | //ip22_state *state = space->machine->driver_data<ip22_state>(); |
| 1146 | 1176 | return 0; |
| 1147 | 1177 | //verboselog(space->machine, 0, "Unknown PBUS Read: 0x%08x (%08x)\n", 0x1fbc8000 + offset*4, mem_mask ); |
| 1148 | | //return unkpbus0[offset]; |
| 1178 | //return state->unkpbus0[offset]; |
| 1149 | 1179 | } |
| 1150 | 1180 | |
| 1151 | 1181 | static WRITE32_HANDLER( hpc3_unkpbus0_w ) |
| 1152 | 1182 | { |
| 1183 | //ip22_state *state = space->machine->driver_data<ip22_state>(); |
| 1153 | 1184 | //verboselog(space->machine, 0, "Unknown PBUS Write: 0x%08x = 0x%08x (%08x)\n", 0x1fbc8000 + offset*4, data, mem_mask ); |
| 1154 | | //COMBINE_DATA(&unkpbus0[offset]); |
| 1185 | //COMBINE_DATA(&state->unkpbus0[offset]); |
| 1155 | 1186 | } |
| 1156 | 1187 | |
| 1157 | 1188 | static ADDRESS_MAP_START( ip225015_map, ADDRESS_SPACE_PROGRAM, 32 ) |
| 1158 | 1189 | AM_RANGE( 0x00000000, 0x0007ffff ) AM_RAMBANK( "bank1" ) /* mirror of first 512k of main RAM */ |
| 1159 | | AM_RANGE( 0x08000000, 0x0fffffff ) AM_SHARE("share1") AM_BASE( &ip22_mainram ) AM_RAM_WRITE(ip22_write_ram) /* 128 MB of main RAM */ |
| 1190 | AM_RANGE( 0x08000000, 0x0fffffff ) AM_SHARE("share1") AM_BASE_MEMBER(ip22_state, mainram ) AM_RAM_WRITE(ip22_write_ram) /* 128 MB of main RAM */ |
| 1160 | 1191 | AM_RANGE( 0x1f0f0000, 0x1f0f1fff ) AM_READWRITE( newport_rex3_r, newport_rex3_w ) |
| 1161 | 1192 | AM_RANGE( 0x1fa00000, 0x1fa1ffff ) AM_READWRITE( sgi_mc_r, sgi_mc_w ) |
| 1162 | 1193 | AM_RANGE( 0x1fb90000, 0x1fb9ffff ) AM_READWRITE( hpc3_hd_enet_r, hpc3_hd_enet_w ) |
| 1163 | 1194 | AM_RANGE( 0x1fbb0000, 0x1fbb0003 ) AM_RAM /* unknown, but read a lot and discarded */ |
| 1164 | 1195 | AM_RANGE( 0x1fbc0000, 0x1fbc7fff ) AM_READWRITE( hpc3_hd0_r, hpc3_hd0_w ) |
| 1165 | | AM_RANGE( 0x1fbc8000, 0x1fbcffff ) AM_READWRITE( hpc3_unkpbus0_r, hpc3_unkpbus0_w ) AM_BASE(&unkpbus0) |
| 1196 | AM_RANGE( 0x1fbc8000, 0x1fbcffff ) AM_READWRITE( hpc3_unkpbus0_r, hpc3_unkpbus0_w ) AM_BASE_MEMBER(ip22_state, unkpbus0) |
| 1166 | 1197 | AM_RANGE( 0x1fb80000, 0x1fb8ffff ) AM_READWRITE( hpc3_pbusdma_r, hpc3_pbusdma_w ) |
| 1167 | 1198 | AM_RANGE( 0x1fbd8000, 0x1fbd83ff ) AM_READWRITE( hal2_r, hal2_w ) |
| 1168 | 1199 | AM_RANGE( 0x1fbd8400, 0x1fbd87ff ) AM_RAM /* hack */ |
| r9683 | r9684 | |
| 1175 | 1206 | AM_RANGE( 0x20000000, 0x27ffffff ) AM_SHARE("share1") AM_RAM_WRITE(ip22_write_ram) |
| 1176 | 1207 | ADDRESS_MAP_END |
| 1177 | 1208 | |
| 1178 | | static UINT32 nIntCounter; |
| 1179 | 1209 | |
| 1180 | 1210 | // sgi_mc_update wants once every millisecond (1/1000th of a second) |
| 1181 | 1211 | static TIMER_CALLBACK(ip22_timer) |
| r9683 | r9684 | |
| 1191 | 1221 | |
| 1192 | 1222 | static MACHINE_RESET( ip225015 ) |
| 1193 | 1223 | { |
| 1224 | ip22_state *state = machine->driver_data<ip22_state>(); |
| 1194 | 1225 | sgi_mc_init(machine); |
| 1195 | | nHPC3_enetr_nbdp = 0x80000000; |
| 1196 | | nHPC3_enetr_cbp = 0x80000000; |
| 1197 | | nIntCounter = 0; |
| 1226 | state->nHPC3_enetr_nbdp = 0x80000000; |
| 1227 | state->nHPC3_enetr_cbp = 0x80000000; |
| 1228 | state->nIntCounter = 0; |
| 1198 | 1229 | RTC_REGISTERB = 0x08; |
| 1199 | 1230 | RTC_REGISTERD = 0x80; |
| 1200 | 1231 | |
| 1201 | 1232 | timer_set(machine, ATTOTIME_IN_MSEC(1), NULL, 0, ip22_timer); |
| 1202 | 1233 | |
| 1203 | 1234 | // set up low RAM mirror |
| 1204 | | memory_set_bankptr(machine, "bank1", ip22_mainram); |
| 1235 | memory_set_bankptr(machine, "bank1", state->mainram); |
| 1205 | 1236 | |
| 1206 | | nPBUS_DMA_Active = 0; |
| 1237 | state->nPBUS_DMA_Active = 0; |
| 1207 | 1238 | |
| 1208 | 1239 | mips3drc_set_options(machine->device("maincpu"), MIPS3DRC_COMPATIBLE_OPTIONS | MIPS3DRC_CHECK_OVERFLOWS); |
| 1209 | 1240 | } |
| r9683 | r9684 | |
| 1225 | 1256 | #define HPC3_DMACTRL_DIR (0x04) |
| 1226 | 1257 | #define HPC3_DMACTRL_ENABLE (0x10) |
| 1227 | 1258 | |
| 1228 | | static UINT8 dma_buffer[4096]; |
| 1229 | 1259 | |
| 1230 | 1260 | static void scsi_irq(running_machine *machine, int state) |
| 1231 | 1261 | { |
| 1262 | ip22_state *drvstate = machine->driver_data<ip22_state>(); |
| 1232 | 1263 | address_space *space = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM); |
| 1233 | 1264 | |
| 1234 | 1265 | if (state) |
| r9683 | r9684 | |
| 1236 | 1267 | if (wd33c93_get_dma_count()) |
| 1237 | 1268 | { |
| 1238 | 1269 | printf("wd33c93_get_dma_count() is %d\n", wd33c93_get_dma_count() ); |
| 1239 | | if (nHPC_SCSI0DMACtrl & HPC3_DMACTRL_ENABLE) |
| 1270 | if (drvstate->nHPC_SCSI0DMACtrl & HPC3_DMACTRL_ENABLE) |
| 1240 | 1271 | { |
| 1241 | | if (nHPC_SCSI0DMACtrl & HPC3_DMACTRL_IRQ) logerror("IP22: Unhandled SCSI DMA IRQ\n"); |
| 1272 | if (drvstate->nHPC_SCSI0DMACtrl & HPC3_DMACTRL_IRQ) logerror("IP22: Unhandled SCSI DMA IRQ\n"); |
| 1242 | 1273 | } |
| 1243 | 1274 | |
| 1244 | 1275 | // HPC3 DMA: host to device |
| 1245 | | if ((nHPC_SCSI0DMACtrl & HPC3_DMACTRL_ENABLE) && (nHPC_SCSI0DMACtrl & HPC3_DMACTRL_DIR)) |
| 1276 | if ((drvstate->nHPC_SCSI0DMACtrl & HPC3_DMACTRL_ENABLE) && (drvstate->nHPC_SCSI0DMACtrl & HPC3_DMACTRL_DIR)) |
| 1246 | 1277 | { |
| 1247 | 1278 | UINT32 wptr, tmpword; |
| 1248 | 1279 | int words, dptr, twords; |
| r9683 | r9684 | |
| 1250 | 1281 | words = wd33c93_get_dma_count(); |
| 1251 | 1282 | words /= 4; |
| 1252 | 1283 | |
| 1253 | | wptr = space->read_dword(nHPC_SCSI0Descriptor); |
| 1254 | | nHPC_SCSI0Descriptor += words*4; |
| 1284 | wptr = space->read_dword(drvstate->nHPC_SCSI0Descriptor); |
| 1285 | drvstate->nHPC_SCSI0Descriptor += words*4; |
| 1255 | 1286 | dptr = 0; |
| 1256 | 1287 | |
| 1257 | 1288 | printf("DMA to device: %d words @ %x\n", words, wptr); |
| 1258 | 1289 | |
| 1259 | | dump_chain(space, nHPC_SCSI0Descriptor); |
| 1290 | dump_chain(space, drvstate->nHPC_SCSI0Descriptor); |
| 1260 | 1291 | |
| 1261 | 1292 | if (words <= (512/4)) |
| 1262 | 1293 | { |
| 1263 | 1294 | // one-shot |
| 1264 | | //wd33c93_get_dma_data(wd33c93_get_dma_count(), dma_buffer); |
| 1295 | //wd33c93_get_dma_data(wd33c93_get_dma_count(), drvstate->dma_buffer); |
| 1265 | 1296 | |
| 1266 | 1297 | while (words) |
| 1267 | 1298 | { |
| 1268 | 1299 | tmpword = space->read_dword(wptr); |
| 1269 | 1300 | |
| 1270 | | if (nHPC_SCSI0DMACtrl & HPC3_DMACTRL_ENDIAN) |
| 1301 | if (drvstate->nHPC_SCSI0DMACtrl & HPC3_DMACTRL_ENDIAN) |
| 1271 | 1302 | { |
| 1272 | | dma_buffer[dptr+3] = (tmpword>>24)&0xff; |
| 1273 | | dma_buffer[dptr+2] = (tmpword>>16)&0xff; |
| 1274 | | dma_buffer[dptr+1] = (tmpword>>8)&0xff; |
| 1275 | | dma_buffer[dptr] = tmpword&0xff; |
| 1303 | drvstate->dma_buffer[dptr+3] = (tmpword>>24)&0xff; |
| 1304 | drvstate->dma_buffer[dptr+2] = (tmpword>>16)&0xff; |
| 1305 | drvstate->dma_buffer[dptr+1] = (tmpword>>8)&0xff; |
| 1306 | drvstate->dma_buffer[dptr] = tmpword&0xff; |
| 1276 | 1307 | } |
| 1277 | 1308 | else |
| 1278 | 1309 | { |
| 1279 | | dma_buffer[dptr] = (tmpword>>24)&0xff; |
| 1280 | | dma_buffer[dptr+1] = (tmpword>>16)&0xff; |
| 1281 | | dma_buffer[dptr+2] = (tmpword>>8)&0xff; |
| 1282 | | dma_buffer[dptr+3] = tmpword&0xff; |
| 1310 | drvstate->dma_buffer[dptr] = (tmpword>>24)&0xff; |
| 1311 | drvstate->dma_buffer[dptr+1] = (tmpword>>16)&0xff; |
| 1312 | drvstate->dma_buffer[dptr+2] = (tmpword>>8)&0xff; |
| 1313 | drvstate->dma_buffer[dptr+3] = tmpword&0xff; |
| 1283 | 1314 | } |
| 1284 | 1315 | |
| 1285 | 1316 | wptr += 4; |
| r9683 | r9684 | |
| 1288 | 1319 | } |
| 1289 | 1320 | |
| 1290 | 1321 | words = wd33c93_get_dma_count(); |
| 1291 | | wd33c93_write_data(words, dma_buffer); |
| 1322 | wd33c93_write_data(words, drvstate->dma_buffer); |
| 1292 | 1323 | } |
| 1293 | 1324 | else |
| 1294 | 1325 | { |
| 1295 | 1326 | while (words) |
| 1296 | 1327 | { |
| 1297 | | //wd33c93_get_dma_data(512, dma_buffer); |
| 1328 | //wd33c93_get_dma_data(512, drvstate->dma_buffer); |
| 1298 | 1329 | twords = 512/4; |
| 1299 | | nHPC_SCSI0Descriptor += 512; |
| 1330 | drvstate->nHPC_SCSI0Descriptor += 512; |
| 1300 | 1331 | dptr = 0; |
| 1301 | 1332 | |
| 1302 | 1333 | while (twords) |
| 1303 | 1334 | { |
| 1304 | 1335 | tmpword = space->read_dword(wptr); |
| 1305 | 1336 | |
| 1306 | | if (nHPC_SCSI0DMACtrl & HPC3_DMACTRL_ENDIAN) |
| 1337 | if (drvstate->nHPC_SCSI0DMACtrl & HPC3_DMACTRL_ENDIAN) |
| 1307 | 1338 | { |
| 1308 | | dma_buffer[dptr+3] = (tmpword>>24)&0xff; |
| 1309 | | dma_buffer[dptr+2] = (tmpword>>16)&0xff; |
| 1310 | | dma_buffer[dptr+1] = (tmpword>>8)&0xff; |
| 1311 | | dma_buffer[dptr] = tmpword&0xff; |
| 1339 | drvstate->dma_buffer[dptr+3] = (tmpword>>24)&0xff; |
| 1340 | drvstate->dma_buffer[dptr+2] = (tmpword>>16)&0xff; |
| 1341 | drvstate->dma_buffer[dptr+1] = (tmpword>>8)&0xff; |
| 1342 | drvstate->dma_buffer[dptr] = tmpword&0xff; |
| 1312 | 1343 | } |
| 1313 | 1344 | else |
| 1314 | 1345 | { |
| 1315 | | dma_buffer[dptr] = (tmpword>>24)&0xff; |
| 1316 | | dma_buffer[dptr+1] = (tmpword>>16)&0xff; |
| 1317 | | dma_buffer[dptr+2] = (tmpword>>8)&0xff; |
| 1318 | | dma_buffer[dptr+3] = tmpword&0xff; |
| 1346 | drvstate->dma_buffer[dptr] = (tmpword>>24)&0xff; |
| 1347 | drvstate->dma_buffer[dptr+1] = (tmpword>>16)&0xff; |
| 1348 | drvstate->dma_buffer[dptr+2] = (tmpword>>8)&0xff; |
| 1349 | drvstate->dma_buffer[dptr+3] = tmpword&0xff; |
| 1319 | 1350 | } |
| 1320 | 1351 | |
| 1321 | 1352 | wptr += 4; |
| r9683 | r9684 | |
| 1323 | 1354 | twords--; |
| 1324 | 1355 | } |
| 1325 | 1356 | |
| 1326 | | wd33c93_write_data(512, dma_buffer); |
| 1357 | wd33c93_write_data(512, drvstate->dma_buffer); |
| 1327 | 1358 | |
| 1328 | 1359 | words -= (512/4); |
| 1329 | 1360 | } |
| r9683 | r9684 | |
| 1333 | 1364 | wd33c93_clear_dma(); |
| 1334 | 1365 | #if 0 |
| 1335 | 1366 | UINT32 dptr, tmpword; |
| 1336 | | UINT32 bc = space->read_dword(nHPC_SCSI0Descriptor + 4); |
| 1337 | | UINT32 rptr = space->read_dword(nHPC_SCSI0Descriptor); |
| 1367 | UINT32 bc = space->read_dword(drvstate->nHPC_SCSI0Descriptor + 4); |
| 1368 | UINT32 rptr = space->read_dword(drvstate->nHPC_SCSI0Descriptor); |
| 1338 | 1369 | int length = bc & 0x3fff; |
| 1339 | 1370 | int xie = (bc & 0x20000000) ? 1 : 0; |
| 1340 | 1371 | int eox = (bc & 0x80000000) ? 1 : 0; |
| 1341 | 1372 | |
| 1342 | | dump_chain(space, nHPC_SCSI0Descriptor); |
| 1373 | dump_chain(space, drvstate->nHPC_SCSI0Descriptor); |
| 1343 | 1374 | |
| 1344 | 1375 | printf("PC is %08x\n", cpu_get_pc(machine->device("maincpu"))); |
| 1345 | 1376 | printf("DMA to device: length %x xie %d eox %d\n", length, xie, eox); |
| r9683 | r9684 | |
| 1350 | 1381 | while (length > 0) |
| 1351 | 1382 | { |
| 1352 | 1383 | tmpword = space->read_dword(rptr); |
| 1353 | | if (nHPC_SCSI0DMACtrl & HPC3_DMACTRL_ENDIAN) |
| 1384 | if (drvstate->nHPC_SCSI0DMACtrl & HPC3_DMACTRL_ENDIAN) |
| 1354 | 1385 | { |
| 1355 | | dma_buffer[dptr+3] = (tmpword>>24)&0xff; |
| 1356 | | dma_buffer[dptr+2] = (tmpword>>16)&0xff; |
| 1357 | | dma_buffer[dptr+1] = (tmpword>>8)&0xff; |
| 1358 | | dma_buffer[dptr] = tmpword&0xff; |
| 1386 | drvstate->dma_buffer[dptr+3] = (tmpword>>24)&0xff; |
| 1387 | drvstate->dma_buffer[dptr+2] = (tmpword>>16)&0xff; |
| 1388 | drvstate->dma_buffer[dptr+1] = (tmpword>>8)&0xff; |
| 1389 | drvstate->dma_buffer[dptr] = tmpword&0xff; |
| 1359 | 1390 | } |
| 1360 | 1391 | else |
| 1361 | 1392 | { |
| 1362 | | dma_buffer[dptr] = (tmpword>>24)&0xff; |
| 1363 | | dma_buffer[dptr+1] = (tmpword>>16)&0xff; |
| 1364 | | dma_buffer[dptr+2] = (tmpword>>8)&0xff; |
| 1365 | | dma_buffer[dptr+3] = tmpword&0xff; |
| 1393 | drvstate->dma_buffer[dptr] = (tmpword>>24)&0xff; |
| 1394 | drvstate->dma_buffer[dptr+1] = (tmpword>>16)&0xff; |
| 1395 | drvstate->dma_buffer[dptr+2] = (tmpword>>8)&0xff; |
| 1396 | drvstate->dma_buffer[dptr+3] = tmpword&0xff; |
| 1366 | 1397 | } |
| 1367 | 1398 | |
| 1368 | 1399 | dptr += 4; |
| r9683 | r9684 | |
| 1370 | 1401 | length -= 4; |
| 1371 | 1402 | } |
| 1372 | 1403 | |
| 1373 | | length = space->read_dword(nHPC_SCSI0Descriptor+4) & 0x3fff; |
| 1374 | | wd33c93_write_data(length, dma_buffer); |
| 1404 | length = space->read_dword(drvstate->nHPC_SCSI0Descriptor+4) & 0x3fff; |
| 1405 | wd33c93_write_data(length, drvstate->dma_buffer); |
| 1375 | 1406 | |
| 1376 | 1407 | // clear DMA on the controller too |
| 1377 | 1408 | wd33c93_clear_dma(); |
| r9683 | r9684 | |
| 1384 | 1415 | } |
| 1385 | 1416 | |
| 1386 | 1417 | // HPC3 DMA: device to host |
| 1387 | | if ((nHPC_SCSI0DMACtrl & HPC3_DMACTRL_ENABLE) && !(nHPC_SCSI0DMACtrl & HPC3_DMACTRL_DIR)) |
| 1418 | if ((drvstate->nHPC_SCSI0DMACtrl & HPC3_DMACTRL_ENABLE) && !(drvstate->nHPC_SCSI0DMACtrl & HPC3_DMACTRL_DIR)) |
| 1388 | 1419 | { |
| 1389 | 1420 | UINT32 wptr, tmpword; |
| 1390 | 1421 | int words, sptr, twords; |
| r9683 | r9684 | |
| 1392 | 1423 | words = wd33c93_get_dma_count(); |
| 1393 | 1424 | words /= 4; |
| 1394 | 1425 | |
| 1395 | | wptr = space->read_dword(nHPC_SCSI0Descriptor); |
| 1426 | wptr = space->read_dword(drvstate->nHPC_SCSI0Descriptor); |
| 1396 | 1427 | sptr = 0; |
| 1397 | 1428 | |
| 1398 | 1429 | // mame_printf_info("DMA from device: %d words @ %x\n", words, wptr); |
| 1399 | 1430 | |
| 1400 | | dump_chain(space, nHPC_SCSI0Descriptor); |
| 1431 | dump_chain(space, drvstate->nHPC_SCSI0Descriptor); |
| 1401 | 1432 | |
| 1402 | 1433 | if (words <= (1024/4)) |
| 1403 | 1434 | { |
| 1404 | 1435 | // one-shot |
| 1405 | | wd33c93_get_dma_data(wd33c93_get_dma_count(), dma_buffer); |
| 1436 | wd33c93_get_dma_data(wd33c93_get_dma_count(), drvstate->dma_buffer); |
| 1406 | 1437 | |
| 1407 | 1438 | while (words) |
| 1408 | 1439 | { |
| 1409 | | if (nHPC_SCSI0DMACtrl & HPC3_DMACTRL_ENDIAN) |
| 1440 | if (drvstate->nHPC_SCSI0DMACtrl & HPC3_DMACTRL_ENDIAN) |
| 1410 | 1441 | { |
| 1411 | | tmpword = dma_buffer[sptr+3]<<24 | dma_buffer[sptr+2]<<16 | dma_buffer[sptr+1]<<8 | dma_buffer[sptr]; |
| 1442 | tmpword = drvstate->dma_buffer[sptr+3]<<24 | drvstate->dma_buffer[sptr+2]<<16 | drvstate->dma_buffer[sptr+1]<<8 | drvstate->dma_buffer[sptr]; |
| 1412 | 1443 | } |
| 1413 | 1444 | else |
| 1414 | 1445 | { |
| 1415 | | tmpword = dma_buffer[sptr]<<24 | dma_buffer[sptr+1]<<16 | dma_buffer[sptr+2]<<8 | dma_buffer[sptr+3]; |
| 1446 | tmpword = drvstate->dma_buffer[sptr]<<24 | drvstate->dma_buffer[sptr+1]<<16 | drvstate->dma_buffer[sptr+2]<<8 | drvstate->dma_buffer[sptr+3]; |
| 1416 | 1447 | } |
| 1417 | 1448 | |
| 1418 | 1449 | space->write_dword(wptr, tmpword); |
| r9683 | r9684 | |
| 1425 | 1456 | { |
| 1426 | 1457 | while (words) |
| 1427 | 1458 | { |
| 1428 | | wd33c93_get_dma_data(512, dma_buffer); |
| 1459 | wd33c93_get_dma_data(512, drvstate->dma_buffer); |
| 1429 | 1460 | twords = 512/4; |
| 1430 | 1461 | sptr = 0; |
| 1431 | 1462 | |
| 1432 | 1463 | while (twords) |
| 1433 | 1464 | { |
| 1434 | | if (nHPC_SCSI0DMACtrl & HPC3_DMACTRL_ENDIAN) |
| 1465 | if (drvstate->nHPC_SCSI0DMACtrl & HPC3_DMACTRL_ENDIAN) |
| 1435 | 1466 | { |
| 1436 | | tmpword = dma_buffer[sptr+3]<<24 | dma_buffer[sptr+2]<<16 | dma_buffer[sptr+1]<<8 | dma_buffer[sptr]; |
| 1467 | tmpword = drvstate->dma_buffer[sptr+3]<<24 | drvstate->dma_buffer[sptr+2]<<16 | drvstate->dma_buffer[sptr+1]<<8 | drvstate->dma_buffer[sptr]; |
| 1437 | 1468 | } |
| 1438 | 1469 | else |
| 1439 | 1470 | { |
| 1440 | | tmpword = dma_buffer[sptr]<<24 | dma_buffer[sptr+1]<<16 | dma_buffer[sptr+2]<<8 | dma_buffer[sptr+3]; |
| 1471 | tmpword = drvstate->dma_buffer[sptr]<<24 | drvstate->dma_buffer[sptr+1]<<16 | drvstate->dma_buffer[sptr+2]<<8 | drvstate->dma_buffer[sptr+3]; |
| 1441 | 1472 | } |
| 1442 | 1473 | space->write_dword(wptr, tmpword); |
| 1443 | 1474 | |
| r9683 | r9684 | |
| 1456 | 1487 | } |
| 1457 | 1488 | |
| 1458 | 1489 | // clear HPC3 DMA active flag |
| 1459 | | nHPC_SCSI0DMACtrl &= ~HPC3_DMACTRL_ENABLE; |
| 1490 | drvstate->nHPC_SCSI0DMACtrl &= ~HPC3_DMACTRL_ENABLE; |
| 1460 | 1491 | |
| 1461 | 1492 | // set the interrupt |
| 1462 | 1493 | int3_raise_local0_irq(machine, INT3_LOCAL0_SCSI0); |
| 1463 | 1494 | } |
| 1464 | 1495 | else |
| 1465 | 1496 | { |
| 1466 | | int3_lower_local0_irq(INT3_LOCAL0_SCSI0); |
| 1497 | int3_lower_local0_irq(drvstate, INT3_LOCAL0_SCSI0); |
| 1467 | 1498 | } |
| 1468 | 1499 | } |
| 1469 | 1500 | |
| r9683 | r9684 | |
| 1500 | 1531 | |
| 1501 | 1532 | static DRIVER_INIT( ip225015 ) |
| 1502 | 1533 | { |
| 1534 | ip22_state *state = machine->driver_data<ip22_state>(); |
| 1503 | 1535 | static const struct kbdc8042_interface at8042 = |
| 1504 | 1536 | { |
| 1505 | 1537 | KBDC8042_STANDARD, NULL, NULL, ip22_get_out2 |
| r9683 | r9684 | |
| 1510 | 1542 | init_pc_common(machine, PCCOMMON_KEYBOARD_AT, NULL); |
| 1511 | 1543 | kbdc8042_init(machine, &at8042); |
| 1512 | 1544 | |
| 1513 | | nIOC_ParReadCnt = 0; |
| 1545 | state->nIOC_ParReadCnt = 0; |
| 1514 | 1546 | } |
| 1515 | 1547 | |
| 1516 | 1548 | static INPUT_PORTS_START( ip225015 ) |
| r9683 | r9684 | |
| 1522 | 1554 | PORT_INCLUDE( pc_mouse_microsoft ) /* IN12 - IN14 */ |
| 1523 | 1555 | INPUT_PORTS_END |
| 1524 | 1556 | |
| 1525 | | static void rtc_update(void) |
| 1557 | static void rtc_update(ip22_state *state) |
| 1526 | 1558 | { |
| 1527 | 1559 | RTC_SECONDS++; |
| 1528 | 1560 | |
| r9683 | r9684 | |
| 1588 | 1620 | |
| 1589 | 1621 | static INTERRUPT_GEN( ip22_vbl ) |
| 1590 | 1622 | { |
| 1591 | | nIntCounter++; |
| 1592 | | // if( nIntCounter == 60 ) |
| 1623 | ip22_state *state = device->machine->driver_data<ip22_state>(); |
| 1624 | state->nIntCounter++; |
| 1625 | // if( state->nIntCounter == 60 ) |
| 1593 | 1626 | { |
| 1594 | | nIntCounter = 0; |
| 1595 | | rtc_update(); |
| 1627 | state->nIntCounter = 0; |
| 1628 | rtc_update(state); |
| 1596 | 1629 | } |
| 1597 | 1630 | } |
| 1598 | 1631 | |
| r9683 | r9684 | |
| 1621 | 1654 | DEVCB_NULL /* no idea if the lpt irq is connected and where */ |
| 1622 | 1655 | }; |
| 1623 | 1656 | |
| 1624 | | static MACHINE_CONFIG_START( ip225015, driver_device ) |
| 1657 | static MACHINE_CONFIG_START( ip225015, ip22_state ) |
| 1625 | 1658 | MDRV_CPU_ADD( "maincpu", R5000BE, 50000000*3 ) |
| 1626 | 1659 | MDRV_CPU_CONFIG( config ) |
| 1627 | 1660 | MDRV_CPU_PROGRAM_MAP( ip225015_map) |
src/mess/drivers/psx.c
| r9683 | r9684 | |
| 21 | 21 | #include "debugger.h" |
| 22 | 22 | #include "zlib.h" |
| 23 | 23 | |
| 24 | typedef struct |
| 25 | { |
| 26 | int n_shiftin; |
| 27 | int n_shiftout; |
| 28 | int n_bits; |
| 29 | int n_state; |
| 30 | int n_byte; |
| 31 | int b_lastclock; |
| 32 | int b_ack; |
| 33 | } pad_t; |
| 34 | |
| 35 | |
| 36 | class psx1_state : public psx_state |
| 37 | { |
| 38 | public: |
| 39 | psx1_state(running_machine &machine, const driver_device_config_base &config) |
| 40 | : psx_state(machine, config) { } |
| 41 | |
| 42 | cdrom_file *cdrom; |
| 43 | UINT8 *exe_buffer; |
| 44 | int exe_size; |
| 45 | pad_t m_pad[ 2 ]; |
| 46 | int cd_param_p; |
| 47 | int cd_result_p; |
| 48 | int cd_result_c; |
| 49 | int cd_result_ready; |
| 50 | int cd_reset; |
| 51 | UINT8 cd_stat; |
| 52 | UINT8 cd_io_status; |
| 53 | UINT8 cd_param[8]; |
| 54 | UINT8 cd_result[8]; |
| 55 | }; |
| 56 | |
| 57 | |
| 24 | 58 | #define VERBOSE_LEVEL ( 0 ) |
| 25 | 59 | |
| 26 | 60 | INLINE void ATTR_PRINTF(3,4) verboselog( running_machine *machine, int n_level, const char *s_fmt, ... ) |
| r9683 | r9684 | |
| 36 | 70 | } |
| 37 | 71 | } |
| 38 | 72 | |
| 39 | | static cdrom_file *psx_cdrom; |
| 40 | | static UINT8 *exe_buffer; |
| 41 | | static int exe_size; |
| 42 | 73 | |
| 43 | 74 | static void psxexe_conv32( UINT32 *p_uint32 ) |
| 44 | 75 | { |
| r9683 | r9684 | |
| 393 | 424 | |
| 394 | 425 | DIRECT_UPDATE_HANDLER( psx_setopbase ) |
| 395 | 426 | { |
| 427 | psx1_state *state = machine->driver_data<psx1_state>(); |
| 396 | 428 | if( address == 0x80030000 ) |
| 397 | 429 | { |
| 398 | 430 | running_device *cpu = machine->device("maincpu"); |
| 399 | 431 | |
| 400 | 432 | cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM)->set_direct_update_handler(direct_update_delegate_create_static(psx_default, *machine)); |
| 401 | 433 | |
| 402 | | if( load_psxexe( cpu, exe_buffer, exe_size ) || |
| 403 | | load_cpe( cpu, exe_buffer, exe_size ) || |
| 404 | | load_psf( cpu, exe_buffer, exe_size ) ) |
| 434 | if( load_psxexe( cpu, state->exe_buffer, state->exe_size ) || |
| 435 | load_cpe( cpu, state->exe_buffer, state->exe_size ) || |
| 436 | load_psf( cpu, state->exe_buffer, state->exe_size ) ) |
| 405 | 437 | { |
| 406 | 438 | /* DEBUGGER_BREAK; */ |
| 407 | 439 | |
| r9683 | r9684 | |
| 412 | 444 | logerror( "psx_exe_load: invalid exe\n" ); |
| 413 | 445 | } |
| 414 | 446 | |
| 415 | | exe_size = 0; |
| 416 | | free( exe_buffer ); |
| 447 | state->exe_size = 0; |
| 448 | free( state->exe_buffer ); |
| 417 | 449 | } |
| 418 | 450 | return address; |
| 419 | 451 | } |
| 420 | 452 | |
| 421 | 453 | static QUICKLOAD_LOAD( psx_exe_load ) |
| 422 | 454 | { |
| 455 | psx1_state *state = image.device().machine->driver_data<psx1_state>(); |
| 423 | 456 | address_space *space = cputag_get_address_space( image.device().machine, "maincpu", ADDRESS_SPACE_PROGRAM ); |
| 424 | 457 | |
| 425 | | exe_size = 0; |
| 426 | | exe_buffer = (UINT8*)malloc( quickload_size ); |
| 427 | | if( exe_buffer == NULL ) |
| 458 | state->exe_size = 0; |
| 459 | state->exe_buffer = (UINT8*)malloc( quickload_size ); |
| 460 | if( state->exe_buffer == NULL ) |
| 428 | 461 | { |
| 429 | 462 | logerror( "psx_exe_load: out of memory\n" ); |
| 430 | 463 | return IMAGE_INIT_FAIL; |
| 431 | 464 | } |
| 432 | | if( image.fread( exe_buffer, quickload_size ) != quickload_size ) |
| 465 | if( image.fread( state->exe_buffer, quickload_size ) != quickload_size ) |
| 433 | 466 | { |
| 434 | | free( exe_buffer ); |
| 467 | free( state->exe_buffer ); |
| 435 | 468 | return IMAGE_INIT_FAIL; |
| 436 | 469 | } |
| 437 | | exe_size = quickload_size; |
| 470 | state->exe_size = quickload_size; |
| 438 | 471 | space->set_direct_update_handler(direct_update_delegate_create_static(psx_setopbase, *image.device().machine)); |
| 439 | 472 | |
| 440 | 473 | return IMAGE_INIT_PASS; |
| r9683 | r9684 | |
| 457 | 490 | #define PAD_DATA_OK ( 0x5a ) /* Z */ |
| 458 | 491 | #define PAD_DATA_IDLE ( 0xff ) |
| 459 | 492 | |
| 460 | | typedef struct |
| 461 | | { |
| 462 | | int n_shiftin; |
| 463 | | int n_shiftout; |
| 464 | | int n_bits; |
| 465 | | int n_state; |
| 466 | | int n_byte; |
| 467 | | int b_lastclock; |
| 468 | | int b_ack; |
| 469 | | } pad_t; |
| 470 | | static pad_t m_pad[ 2 ]; |
| 471 | | |
| 472 | 493 | static TIMER_CALLBACK(psx_pad_ack) |
| 473 | 494 | { |
| 495 | psx1_state *state = machine->driver_data<psx1_state>(); |
| 474 | 496 | int n_port = param; |
| 475 | | pad_t *pad = &m_pad[ n_port]; |
| 497 | pad_t *pad = &state->m_pad[ n_port ]; |
| 476 | 498 | |
| 477 | 499 | if( pad->n_state != PAD_STATE_IDLE ) |
| 478 | 500 | { |
| r9683 | r9684 | |
| 487 | 509 | |
| 488 | 510 | static void psx_pad( running_machine *machine, int n_port, int n_data ) |
| 489 | 511 | { |
| 490 | | pad_t *pad = &m_pad[ n_port]; |
| 512 | psx1_state *state = machine->driver_data<psx1_state>(); |
| 513 | pad_t *pad = &state->m_pad[ n_port ]; |
| 491 | 514 | int b_sel; |
| 492 | 515 | int b_clock; |
| 493 | 516 | int b_data; |
| r9683 | r9684 | |
| 626 | 649 | |
| 627 | 650 | /* ----------------------------------------------------------------------- */ |
| 628 | 651 | |
| 629 | | static int cd_param_p; |
| 630 | | static int cd_result_p; |
| 631 | | static int cd_result_c; |
| 632 | | static int cd_result_ready; |
| 633 | 652 | static const int cd_readed = -1; |
| 634 | | static int cd_reset; |
| 635 | | static UINT8 cd_stat; |
| 636 | | static UINT8 cd_io_status; |
| 637 | | static UINT8 cd_param[8]; |
| 638 | | static UINT8 cd_result[8]; |
| 639 | 653 | |
| 640 | 654 | /* ----------------------------------------------------------------------- */ |
| 641 | 655 | |
| r9683 | r9684 | |
| 646 | 660 | |
| 647 | 661 | static void psx_cdcmd_nop(running_machine *machine) |
| 648 | 662 | { |
| 649 | | cd_stat = 0x02; |
| 663 | psx1_state *state = machine->driver_data<psx1_state>(); |
| 664 | state->cd_stat = 0x02; |
| 650 | 665 | } |
| 651 | 666 | |
| 652 | 667 | static void psx_cdcmd_setloc(running_machine *machine) |
| r9683 | r9684 | |
| 691 | 706 | |
| 692 | 707 | static void psx_cdcmd_init(running_machine *machine) |
| 693 | 708 | { |
| 694 | | cd_result_p = 0; |
| 695 | | cd_result_c = 1; |
| 696 | | cd_stat = 0x02; |
| 697 | | cd_result[0] = cd_stat; |
| 709 | psx1_state *state = machine->driver_data<psx1_state>(); |
| 710 | state->cd_result_p = 0; |
| 711 | state->cd_result_c = 1; |
| 712 | state->cd_stat = 0x02; |
| 713 | state->cd_result[0] = state->cd_stat; |
| 698 | 714 | verboselog(machine, 0, "CD Command: Init: Not fully implemented\n" ); |
| 699 | 715 | } |
| 700 | 716 | |
| r9683 | r9684 | |
| 755 | 771 | |
| 756 | 772 | static void psx_cdcmd_test(running_machine *machine) |
| 757 | 773 | { |
| 774 | psx1_state *state = machine->driver_data<psx1_state>(); |
| 758 | 775 | static const UINT8 test20[] = { 0x98, 0x06, 0x10, 0xC3 }; |
| 759 | 776 | static const UINT8 test22[] = { 0x66, 0x6F, 0x72, 0x20, 0x45, 0x75, 0x72, 0x6F }; |
| 760 | 777 | static const UINT8 test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 }; |
| 761 | 778 | |
| 762 | | switch(cd_param[0]) { |
| 779 | switch(state->cd_param[0]) { |
| 763 | 780 | case 0x04: /* read SCEx counter (returned in 1st byte?) */ |
| 764 | 781 | break; |
| 765 | 782 | case 0x05: /* reset SCEx counter. */ |
| 766 | 783 | break; |
| 767 | 784 | case 0x20: |
| 768 | | memcpy(cd_result, test20, sizeof(test20)); |
| 769 | | cd_result_p = 0; |
| 770 | | cd_result_c = sizeof(test20); |
| 785 | memcpy(state->cd_result, test20, sizeof(test20)); |
| 786 | state->cd_result_p = 0; |
| 787 | state->cd_result_c = sizeof(test20); |
| 771 | 788 | break; |
| 772 | 789 | case 0x22: |
| 773 | | memcpy(cd_result, test22, sizeof(test22)); |
| 774 | | cd_result_p = 0; |
| 775 | | cd_result_c = sizeof(test22); |
| 790 | memcpy(state->cd_result, test22, sizeof(test22)); |
| 791 | state->cd_result_p = 0; |
| 792 | state->cd_result_c = sizeof(test22); |
| 776 | 793 | break; |
| 777 | 794 | case 0x23: |
| 778 | | memcpy(cd_result, test23, sizeof(test23)); |
| 779 | | cd_result_p = 0; |
| 780 | | cd_result_c = sizeof(test23); |
| 795 | memcpy(state->cd_result, test23, sizeof(test23)); |
| 796 | state->cd_result_p = 0; |
| 797 | state->cd_result_c = sizeof(test23); |
| 781 | 798 | break; |
| 782 | 799 | } |
| 783 | | cd_stat = 3; |
| 800 | state->cd_stat = 3; |
| 784 | 801 | } |
| 785 | 802 | |
| 786 | 803 | static void psx_cdcmd_id(running_machine *machine) |
| r9683 | r9684 | |
| 842 | 859 | |
| 843 | 860 | static READ32_HANDLER( psx_cd_r ) |
| 844 | 861 | { |
| 862 | psx1_state *state = space->machine->driver_data<psx1_state>(); |
| 845 | 863 | UINT32 result = 0; |
| 846 | 864 | |
| 847 | 865 | if( ACCESSING_BITS_0_7 ) |
| 848 | 866 | { |
| 849 | 867 | logerror( "%08x cd0 read\n", cpu_get_pc(space->cpu) ); |
| 850 | 868 | |
| 851 | | if (cd_result_ready && cd_result_c) |
| 852 | | cd_io_status |= 0x20; |
| 869 | if (state->cd_result_ready && state->cd_result_c) |
| 870 | state->cd_io_status |= 0x20; |
| 853 | 871 | else |
| 854 | | cd_io_status &= ~0x20; |
| 872 | state->cd_io_status &= ~0x20; |
| 855 | 873 | |
| 856 | 874 | if (cd_readed == 0) |
| 857 | | result = cd_io_status | 0x40; |
| 875 | result = state->cd_io_status | 0x40; |
| 858 | 876 | else |
| 859 | | result = cd_io_status; |
| 877 | result = state->cd_io_status; |
| 860 | 878 | |
| 861 | 879 | /* NPW 21-May-2003 - Seems to expect this on boot */ |
| 862 | 880 | result |= 0x0f; |
| r9683 | r9684 | |
| 865 | 883 | { |
| 866 | 884 | logerror( "%08x cd1 read\n", cpu_get_pc(space->cpu) ); |
| 867 | 885 | |
| 868 | | if (cd_result_ready && cd_result_c) |
| 869 | | result = ((UINT32) cd_result[cd_result_p]) << 8; |
| 886 | if (state->cd_result_ready && state->cd_result_c) |
| 887 | result = ((UINT32) state->cd_result[state->cd_result_p]) << 8; |
| 870 | 888 | |
| 871 | | if (cd_result_ready) |
| 889 | if (state->cd_result_ready) |
| 872 | 890 | { |
| 873 | | cd_result_p++; |
| 874 | | if (cd_result_p == cd_result_c) |
| 875 | | cd_result_ready = 0; |
| 891 | state->cd_result_p++; |
| 892 | if (state->cd_result_p == state->cd_result_c) |
| 893 | state->cd_result_ready = 0; |
| 876 | 894 | } |
| 877 | 895 | } |
| 878 | 896 | else if( ACCESSING_BITS_16_23 ) |
| r9683 | r9684 | |
| 883 | 901 | { |
| 884 | 902 | logerror( "%08x cd3 read\n", cpu_get_pc(space->cpu) ); |
| 885 | 903 | |
| 886 | | result = ((UINT32) cd_stat) << 24; |
| 904 | result = ((UINT32) state->cd_stat) << 24; |
| 887 | 905 | } |
| 888 | 906 | else |
| 889 | 907 | { |
| r9683 | r9684 | |
| 894 | 912 | |
| 895 | 913 | static WRITE32_HANDLER( psx_cd_w ) |
| 896 | 914 | { |
| 915 | psx1_state *state = space->machine->driver_data<psx1_state>(); |
| 897 | 916 | void (*psx_cdcmd)(running_machine* machine); |
| 898 | 917 | |
| 899 | 918 | if( ACCESSING_BITS_0_7 ) |
| r9683 | r9684 | |
| 902 | 921 | data = (data >> 0) & 0xff; |
| 903 | 922 | logerror( "%08x cd0 write %02x\n", cpu_get_pc(space->cpu), data & 0xff ); |
| 904 | 923 | |
| 905 | | cd_param_p = 0; |
| 924 | state->cd_param_p = 0; |
| 906 | 925 | if (data == 0x00) |
| 907 | 926 | { |
| 908 | | cd_result_ready = 0; |
| 927 | state->cd_result_ready = 0; |
| 909 | 928 | } |
| 910 | 929 | else |
| 911 | 930 | { |
| 912 | 931 | if (data & 0x01) |
| 913 | | cd_result_ready = 1; |
| 932 | state->cd_result_ready = 1; |
| 914 | 933 | if (data == 0x01) |
| 915 | | cd_reset = 1; |
| 934 | state->cd_reset = 1; |
| 916 | 935 | } |
| 917 | 936 | } |
| 918 | 937 | else if( ACCESSING_BITS_8_15 ) |
| r9683 | r9684 | |
| 937 | 956 | data = (data >> 16) & 0xff; |
| 938 | 957 | logerror( "%08x cd2 write %02x\n", cpu_get_pc(space->cpu), data & 0xff ); |
| 939 | 958 | |
| 940 | | if ((cd_reset == 2) && (data == 0x07)) |
| 959 | if ((state->cd_reset == 2) && (data == 0x07)) |
| 941 | 960 | { |
| 942 | 961 | /* copied from SOPE; this code is weird */ |
| 943 | | cd_param_p = 0; |
| 944 | | cd_result_ready = 1; |
| 945 | | cd_reset = 0; |
| 946 | | cd_stat = 0; |
| 947 | | cd_io_status = 0x00; |
| 948 | | if (cd_result_ready && cd_result_c) |
| 949 | | cd_io_status |= 0x20; |
| 962 | state->cd_param_p = 0; |
| 963 | state->cd_result_ready = 1; |
| 964 | state->cd_reset = 0; |
| 965 | state->cd_stat = 0; |
| 966 | state->cd_io_status = 0x00; |
| 967 | if (state->cd_result_ready && state->cd_result_c) |
| 968 | state->cd_io_status |= 0x20; |
| 950 | 969 | else |
| 951 | | cd_io_status &= ~0x20; |
| 970 | state->cd_io_status &= ~0x20; |
| 952 | 971 | } |
| 953 | 972 | else |
| 954 | 973 | { |
| 955 | 974 | /* used for sending arguments */ |
| 956 | | cd_reset = 0; |
| 957 | | cd_param[cd_param_p] = data; |
| 958 | | if (cd_param_p < 7) |
| 959 | | cd_param_p++; |
| 975 | state->cd_reset = 0; |
| 976 | state->cd_param[state->cd_param_p] = data; |
| 977 | if (state->cd_param_p < 7) |
| 978 | state->cd_param_p++; |
| 960 | 979 | } |
| 961 | 980 | } |
| 962 | 981 | else if( ACCESSING_BITS_24_31 ) |
| r9683 | r9684 | |
| 965 | 984 | data = (data >> 24) & 0xff; |
| 966 | 985 | logerror( "%08x cd3 write %02x\n", cpu_get_pc(space->cpu), data & 0xff ); |
| 967 | 986 | |
| 968 | | if ((data == 0x07) && (cd_reset == 1)) |
| 987 | if ((data == 0x07) && (state->cd_reset == 1)) |
| 969 | 988 | { |
| 970 | | cd_reset = 2; |
| 989 | state->cd_reset = 2; |
| 971 | 990 | /* psxirq_clear(0x0004); */ |
| 972 | 991 | } |
| 973 | 992 | else |
| 974 | 993 | { |
| 975 | | cd_reset = 0; |
| 994 | state->cd_reset = 0; |
| 976 | 995 | } |
| 977 | 996 | } |
| 978 | 997 | else |
| r9683 | r9684 | |
| 1011 | 1030 | |
| 1012 | 1031 | static MACHINE_RESET( psx ) |
| 1013 | 1032 | { |
| 1033 | psx1_state *state = machine->driver_data<psx1_state>(); |
| 1014 | 1034 | running_device *cdrom_dev = machine->device("cdrom"); |
| 1015 | 1035 | if( cdrom_dev ) |
| 1016 | 1036 | { |
| 1017 | | psx_cdrom = mess_cd_get_cdrom_file(cdrom_dev); |
| 1037 | state->cdrom = mess_cd_get_cdrom_file(cdrom_dev); |
| 1018 | 1038 | } |
| 1019 | 1039 | |
| 1020 | 1040 | psx_machine_init(machine); |
| r9683 | r9684 | |
| 1080 | 1100 | psx_dma_install_write_handler |
| 1081 | 1101 | }; |
| 1082 | 1102 | |
| 1083 | | static MACHINE_CONFIG_START( psxntsc, psx_state ) |
| 1103 | static MACHINE_CONFIG_START( psxntsc, psx1_state ) |
| 1084 | 1104 | /* basic machine hardware */ |
| 1085 | 1105 | MDRV_CPU_ADD( "maincpu", PSXCPU, XTAL_67_7376MHz ) |
| 1086 | 1106 | MDRV_CPU_PROGRAM_MAP( psx_map) |
| r9683 | r9684 | |
| 1115 | 1135 | MDRV_CDROM_ADD("cdrom") |
| 1116 | 1136 | MACHINE_CONFIG_END |
| 1117 | 1137 | |
| 1118 | | static MACHINE_CONFIG_START( psxpal, psx_state ) |
| 1138 | static MACHINE_CONFIG_START( psxpal, psx1_state ) |
| 1119 | 1139 | /* basic machine hardware */ |
| 1120 | 1140 | MDRV_CPU_ADD( "maincpu", PSXCPU, XTAL_67_7376MHz ) |
| 1121 | 1141 | MDRV_CPU_PROGRAM_MAP( psx_map) |
src/mess/drivers/sgi_ip2.c
| r9683 | r9684 | |
| 48 | 48 | #include "machine/68681.h" /* DUART0, DUART1 */ |
| 49 | 49 | #include "machine/terminal.h" |
| 50 | 50 | |
| 51 | |
| 52 | class sgi_ip2_state : public driver_device |
| 53 | { |
| 54 | public: |
| 55 | sgi_ip2_state(running_machine &machine, const driver_device_config_base &config) |
| 56 | : driver_device(machine, config) { } |
| 57 | |
| 58 | UINT8 mbut; |
| 59 | UINT16 mquad; |
| 60 | UINT32 *ptmap; |
| 61 | UINT16 tdbase; |
| 62 | UINT16 tdlmt; |
| 63 | UINT16 stkbase; |
| 64 | UINT16 stklmt; |
| 65 | UINT32 *mainram; |
| 66 | UINT32 *bss; |
| 67 | }; |
| 68 | |
| 69 | |
| 51 | 70 | #define VERBOSE_LEVEL ( 0 ) |
| 52 | 71 | |
| 53 | 72 | #define ENABLE_VERBOSE_LOG (0) |
| r9683 | r9684 | |
| 79 | 98 | #define BOARD_REV1 0x60 /* Board revision - #1 */ |
| 80 | 99 | #define BOARD_REV2 0x50 /* Board revision - #2 */ |
| 81 | 100 | |
| 82 | | static UINT8 sgi_ip2_mbut; |
| 83 | 101 | |
| 84 | 102 | static READ8_HANDLER(sgi_ip2_m_but_r) |
| 85 | 103 | { |
| 86 | | verboselog(space->machine, 0, "sgi_ip2_m_but_r: %02x\n", sgi_ip2_mbut | BOARD_REV1); |
| 87 | | return sgi_ip2_mbut | BOARD_REV1; |
| 104 | sgi_ip2_state *state = space->machine->driver_data<sgi_ip2_state>(); |
| 105 | verboselog(space->machine, 0, "sgi_ip2_m_but_r: %02x\n", state->mbut | BOARD_REV1); |
| 106 | return state->mbut | BOARD_REV1; |
| 88 | 107 | } |
| 89 | 108 | |
| 90 | 109 | static WRITE8_HANDLER(sgi_ip2_m_but_w) |
| 91 | 110 | { |
| 111 | sgi_ip2_state *state = space->machine->driver_data<sgi_ip2_state>(); |
| 92 | 112 | verboselog(space->machine, 0, "sgi_ip2_m_but_w: %02x\n", data); |
| 93 | | sgi_ip2_mbut = data; |
| 113 | state->mbut = data; |
| 94 | 114 | } |
| 95 | 115 | |
| 96 | 116 | #define MOUSE_XFIRE 0x01 /* X Quadrature Fired, active low */ |
| r9683 | r9684 | |
| 98 | 118 | #define MOUSE_YFIRE 0x04 /* Y Quadrature Fired, active low */ |
| 99 | 119 | #define MOUSE_YCHANGE 0x08 /* MOUSE_YCHANGE ? y-- : y++ */ |
| 100 | 120 | |
| 101 | | static UINT16 sgi_ip2_mquad; |
| 102 | 121 | |
| 103 | 122 | static READ16_HANDLER(sgi_ip2_m_quad_r) |
| 104 | 123 | { |
| 105 | | verboselog(space->machine, 0, "sgi_ip2_m_quad_r: %04x\n", sgi_ip2_mquad); |
| 106 | | return sgi_ip2_mquad; |
| 124 | sgi_ip2_state *state = space->machine->driver_data<sgi_ip2_state>(); |
| 125 | verboselog(space->machine, 0, "sgi_ip2_m_quad_r: %04x\n", state->mquad); |
| 126 | return state->mquad; |
| 107 | 127 | } |
| 108 | 128 | |
| 109 | 129 | static WRITE16_HANDLER(sgi_ip2_m_quad_w) |
| 110 | 130 | { |
| 131 | sgi_ip2_state *state = space->machine->driver_data<sgi_ip2_state>(); |
| 111 | 132 | verboselog(space->machine, 0, "sgi_ip2_m_quad_w = %04x & %04x\n", data, mem_mask); |
| 112 | | COMBINE_DATA(&sgi_ip2_mquad); |
| 133 | COMBINE_DATA(&state->mquad); |
| 113 | 134 | } |
| 114 | 135 | |
| 115 | 136 | static READ16_HANDLER(sgi_ip2_swtch_r) |
| r9683 | r9684 | |
| 238 | 259 | sgi_ip2_mbp = data; |
| 239 | 260 | } |
| 240 | 261 | |
| 241 | | static UINT32 *sgi_ip2_ptmap; |
| 242 | 262 | |
| 243 | 263 | static READ32_HANDLER(sgi_ip2_ptmap_r) |
| 244 | 264 | { |
| 245 | | verboselog(space->machine, 0, "sgi_ip2_ptmap_r: %08x = %08x & %08x\n", 0x3b000000 + (offset << 2), sgi_ip2_ptmap[offset], mem_mask); |
| 246 | | return sgi_ip2_ptmap[offset]; |
| 265 | sgi_ip2_state *state = space->machine->driver_data<sgi_ip2_state>(); |
| 266 | verboselog(space->machine, 0, "sgi_ip2_ptmap_r: %08x = %08x & %08x\n", 0x3b000000 + (offset << 2), state->ptmap[offset], mem_mask); |
| 267 | return state->ptmap[offset]; |
| 247 | 268 | } |
| 248 | 269 | |
| 249 | 270 | static WRITE32_HANDLER(sgi_ip2_ptmap_w) |
| 250 | 271 | { |
| 272 | sgi_ip2_state *state = space->machine->driver_data<sgi_ip2_state>(); |
| 251 | 273 | verboselog(space->machine, 0, "sgi_ip2_ptmap_w: %08x = %08x & %08x\n", 0x3b000000 + (offset << 2), data, mem_mask); |
| 252 | | COMBINE_DATA(&sgi_ip2_ptmap[offset]); |
| 274 | COMBINE_DATA(&state->ptmap[offset]); |
| 253 | 275 | } |
| 254 | 276 | |
| 255 | | static UINT16 sgi_ip2_tdbase; |
| 256 | 277 | |
| 257 | 278 | static READ16_HANDLER(sgi_ip2_tdbase_r) |
| 258 | 279 | { |
| 259 | | verboselog(space->machine, 0, "sgi_ip2_tdbase_r: %04x\n", sgi_ip2_tdbase); |
| 260 | | return sgi_ip2_tdbase; |
| 280 | sgi_ip2_state *state = space->machine->driver_data<sgi_ip2_state>(); |
| 281 | verboselog(space->machine, 0, "sgi_ip2_tdbase_r: %04x\n", state->tdbase); |
| 282 | return state->tdbase; |
| 261 | 283 | } |
| 262 | 284 | |
| 263 | 285 | static WRITE16_HANDLER(sgi_ip2_tdbase_w) |
| 264 | 286 | { |
| 287 | sgi_ip2_state *state = space->machine->driver_data<sgi_ip2_state>(); |
| 265 | 288 | verboselog(space->machine, 0, "sgi_ip2_tdbase_w: %04x & %04x\n", data, mem_mask); |
| 266 | | COMBINE_DATA(&sgi_ip2_tdbase); |
| 289 | COMBINE_DATA(&state->tdbase); |
| 267 | 290 | } |
| 268 | 291 | |
| 269 | | static UINT16 sgi_ip2_tdlmt; |
| 270 | 292 | |
| 271 | 293 | static READ16_HANDLER(sgi_ip2_tdlmt_r) |
| 272 | 294 | { |
| 273 | | verboselog(space->machine, 0, "sgi_ip2_tdlmt_r: %04x\n", sgi_ip2_tdlmt); |
| 274 | | return sgi_ip2_tdlmt; |
| 295 | sgi_ip2_state *state = space->machine->driver_data<sgi_ip2_state>(); |
| 296 | verboselog(space->machine, 0, "sgi_ip2_tdlmt_r: %04x\n", state->tdlmt); |
| 297 | return state->tdlmt; |
| 275 | 298 | } |
| 276 | 299 | |
| 277 | 300 | static WRITE16_HANDLER(sgi_ip2_tdlmt_w) |
| 278 | 301 | { |
| 302 | sgi_ip2_state *state = space->machine->driver_data<sgi_ip2_state>(); |
| 279 | 303 | verboselog(space->machine, 0, "sgi_ip2_tdlmt_w: %04x & %04x\n", data, mem_mask); |
| 280 | | COMBINE_DATA(&sgi_ip2_tdlmt); |
| 304 | COMBINE_DATA(&state->tdlmt); |
| 281 | 305 | } |
| 282 | 306 | |
| 283 | | static UINT16 sgi_ip2_stkbase; |
| 284 | 307 | |
| 285 | 308 | static READ16_HANDLER(sgi_ip2_stkbase_r) |
| 286 | 309 | { |
| 287 | | verboselog(space->machine, 0, "sgi_ip2_stkbase_r: %04x\n", sgi_ip2_stkbase); |
| 288 | | return sgi_ip2_stkbase; |
| 310 | sgi_ip2_state *state = space->machine->driver_data<sgi_ip2_state>(); |
| 311 | verboselog(space->machine, 0, "sgi_ip2_stkbase_r: %04x\n", state->stkbase); |
| 312 | return state->stkbase; |
| 289 | 313 | } |
| 290 | 314 | |
| 291 | 315 | static WRITE16_HANDLER(sgi_ip2_stkbase_w) |
| 292 | 316 | { |
| 317 | sgi_ip2_state *state = space->machine->driver_data<sgi_ip2_state>(); |
| 293 | 318 | verboselog(space->machine, 0, "sgi_ip2_stkbase_w: %04x & %04x\n", data, mem_mask); |
| 294 | | COMBINE_DATA(&sgi_ip2_stkbase); |
| 319 | COMBINE_DATA(&state->stkbase); |
| 295 | 320 | } |
| 296 | 321 | |
| 297 | | static UINT16 sgi_ip2_stklmt; |
| 298 | 322 | |
| 299 | 323 | static READ16_HANDLER(sgi_ip2_stklmt_r) |
| 300 | 324 | { |
| 301 | | verboselog(space->machine, 0, "sgi_ip2_stklmt_r: %04x\n", sgi_ip2_stklmt); |
| 302 | | return sgi_ip2_stklmt; |
| 325 | sgi_ip2_state *state = space->machine->driver_data<sgi_ip2_state>(); |
| 326 | verboselog(space->machine, 0, "sgi_ip2_stklmt_r: %04x\n", state->stklmt); |
| 327 | return state->stklmt; |
| 303 | 328 | } |
| 304 | 329 | |
| 305 | 330 | static WRITE16_HANDLER(sgi_ip2_stklmt_w) |
| 306 | 331 | { |
| 332 | sgi_ip2_state *state = space->machine->driver_data<sgi_ip2_state>(); |
| 307 | 333 | verboselog(space->machine, 0, "sgi_ip2_stklmt_w: %04x & %04x\n", data, mem_mask); |
| 308 | | COMBINE_DATA(&sgi_ip2_stklmt); |
| 334 | COMBINE_DATA(&state->stklmt); |
| 309 | 335 | } |
| 310 | 336 | |
| 311 | 337 | static WRITE8_DEVICE_HANDLER( sgi_kbd_put ) |
| r9683 | r9684 | |
| 335 | 361 | ADDRESS MAPS |
| 336 | 362 | ***************************************************************************/ |
| 337 | 363 | |
| 338 | | static UINT32 *mainram; |
| 339 | | static UINT32 *bss; |
| 340 | 364 | |
| 341 | 365 | static ADDRESS_MAP_START(sgi_ip2_map, ADDRESS_SPACE_PROGRAM, 32) |
| 342 | | AM_RANGE(0x00000000, 0x00ffffff) AM_RAM AM_BASE(&mainram) |
| 343 | | AM_RANGE(0x02100000, 0x0210ffff) AM_RAM AM_BASE(&bss) // ??? I don't understand the need for this... |
| 366 | AM_RANGE(0x00000000, 0x00ffffff) AM_RAM AM_BASE_MEMBER(sgi_ip2_state, mainram) |
| 367 | AM_RANGE(0x02100000, 0x0210ffff) AM_RAM AM_BASE_MEMBER(sgi_ip2_state, bss) // ??? I don't understand the need for this... |
| 344 | 368 | AM_RANGE(0x30000000, 0x30017fff) AM_ROM AM_REGION("user1", 0) |
| 345 | 369 | AM_RANGE(0x30800000, 0x30800003) AM_READWRITE8(sgi_ip2_m_but_r, sgi_ip2_m_but_w, 0xffffffff) |
| 346 | 370 | AM_RANGE(0x31000000, 0x31000003) AM_READWRITE16(sgi_ip2_m_quad_r, sgi_ip2_m_quad_w, 0xffffffff) |
| r9683 | r9684 | |
| 354 | 378 | AM_RANGE(0x38000000, 0x38000003) AM_READWRITE16(sgi_ip2_status_r, sgi_ip2_status_w, 0xffffffff) |
| 355 | 379 | AM_RANGE(0x39000000, 0x39000003) AM_READWRITE8(sgi_ip2_parctl_r, sgi_ip2_parctl_w, 0xffffffff) |
| 356 | 380 | AM_RANGE(0x3a000000, 0x3a000003) AM_READWRITE8(sgi_ip2_mbp_r, sgi_ip2_mbp_w, 0xffffffff) |
| 357 | | AM_RANGE(0x3b000000, 0x3b003fff) AM_READWRITE(sgi_ip2_ptmap_r, sgi_ip2_ptmap_w) AM_BASE(&sgi_ip2_ptmap) |
| 381 | AM_RANGE(0x3b000000, 0x3b003fff) AM_READWRITE(sgi_ip2_ptmap_r, sgi_ip2_ptmap_w) AM_BASE_MEMBER(sgi_ip2_state, ptmap) |
| 358 | 382 | AM_RANGE(0x3c000000, 0x3c000003) AM_READWRITE16(sgi_ip2_tdbase_r, sgi_ip2_tdbase_w, 0xffffffff) |
| 359 | 383 | AM_RANGE(0x3d000000, 0x3d000003) AM_READWRITE16(sgi_ip2_tdlmt_r, sgi_ip2_tdlmt_w, 0xffffffff) |
| 360 | 384 | AM_RANGE(0x3e000000, 0x3e000003) AM_READWRITE16(sgi_ip2_stkbase_r, sgi_ip2_stkbase_w, 0xffffffff) |
| r9683 | r9684 | |
| 427 | 451 | duartb_output |
| 428 | 452 | }; |
| 429 | 453 | |
| 430 | | static MACHINE_CONFIG_START( sgi_ip2, driver_device ) |
| 454 | static MACHINE_CONFIG_START( sgi_ip2, sgi_ip2_state ) |
| 431 | 455 | /* basic machine hardware */ |
| 432 | 456 | MDRV_CPU_ADD("maincpu", M68020, 16000000) |
| 433 | 457 | MDRV_CPU_PROGRAM_MAP(sgi_ip2_map) |
| r9683 | r9684 | |
| 501 | 525 | |
| 502 | 526 | static DRIVER_INIT( sgi_ip2 ) |
| 503 | 527 | { |
| 528 | sgi_ip2_state *state = machine->driver_data<sgi_ip2_state>(); |
| 504 | 529 | UINT32 *src = (UINT32*)memory_region(machine, "user1"); |
| 505 | | UINT32 *dst = mainram; |
| 530 | UINT32 *dst = state->mainram; |
| 506 | 531 | memcpy(dst, src, 8); |
| 507 | 532 | |
| 508 | 533 | machine->device("maincpu")->reset(); |
src/mess/drivers/ip20.c
| r9683 | r9684 | |
| 27 | 27 | #include "devices/harddriv.h" |
| 28 | 28 | #include "devices/chd_cd.h" |
| 29 | 29 | |
| 30 | |
| 31 | class ip20_state : public driver_device |
| 32 | { |
| 33 | public: |
| 34 | ip20_state(running_machine &machine, const driver_device_config_base &config) |
| 35 | : driver_device(machine, config) { } |
| 36 | |
| 37 | UINT8 nHPC_MiscStatus; |
| 38 | UINT32 nHPC_ParBufPtr; |
| 39 | UINT32 nHPC_LocalIOReg0Mask; |
| 40 | UINT32 nHPC_LocalIOReg1Mask; |
| 41 | UINT32 nHPC_VMEIntMask0; |
| 42 | UINT32 nHPC_VMEIntMask1; |
| 43 | UINT8 nRTC_RAM[32]; |
| 44 | UINT8 nRTC_Temp; |
| 45 | UINT32 nHPC_SCSI0Descriptor; |
| 46 | UINT32 nHPC_SCSI0DMACtrl; |
| 47 | }; |
| 48 | |
| 49 | |
| 30 | 50 | #define VERBOSE_LEVEL ( 2 ) |
| 31 | 51 | |
| 32 | 52 | INLINE void ATTR_PRINTF(3,4) verboselog(running_machine *machine, int n_level, const char *s_fmt, ... ) |
| r9683 | r9684 | |
| 62 | 82 | "*10011xxxxxxx", // unlock 100x 11xxxx |
| 63 | 83 | }; |
| 64 | 84 | |
| 65 | | static UINT8 nHPC_MiscStatus; |
| 66 | | static UINT32 nHPC_ParBufPtr; |
| 67 | | static UINT32 nHPC_LocalIOReg0Mask; |
| 68 | | static UINT32 nHPC_LocalIOReg1Mask; |
| 69 | | static UINT32 nHPC_VMEIntMask0; |
| 70 | | static UINT32 nHPC_VMEIntMask1; |
| 71 | 85 | |
| 72 | | static UINT8 nRTC_RAM[32]; |
| 73 | | static UINT8 nRTC_Temp; |
| 74 | 86 | |
| 75 | | static UINT32 nHPC_SCSI0Descriptor, nHPC_SCSI0DMACtrl; |
| 76 | 87 | |
| 77 | | #define RTC_DAYOFWEEK nRTC_RAM[0x0e] |
| 78 | | #define RTC_YEAR nRTC_RAM[0x0b] |
| 79 | | #define RTC_MONTH nRTC_RAM[0x0a] |
| 80 | | #define RTC_DAY nRTC_RAM[0x09] |
| 81 | | #define RTC_HOUR nRTC_RAM[0x08] |
| 82 | | #define RTC_MINUTE nRTC_RAM[0x07] |
| 83 | | #define RTC_SECOND nRTC_RAM[0x06] |
| 84 | | #define RTC_HUNDREDTH nRTC_RAM[0x05] |
| 88 | #define RTC_DAYOFWEEK state->nRTC_RAM[0x0e] |
| 89 | #define RTC_YEAR state->nRTC_RAM[0x0b] |
| 90 | #define RTC_MONTH state->nRTC_RAM[0x0a] |
| 91 | #define RTC_DAY state->nRTC_RAM[0x09] |
| 92 | #define RTC_HOUR state->nRTC_RAM[0x08] |
| 93 | #define RTC_MINUTE state->nRTC_RAM[0x07] |
| 94 | #define RTC_SECOND state->nRTC_RAM[0x06] |
| 95 | #define RTC_HUNDREDTH state->nRTC_RAM[0x05] |
| 85 | 96 | |
| 86 | 97 | static READ32_HANDLER( hpc_r ) |
| 87 | 98 | { |
| 99 | ip20_state *state = space->machine->driver_data<ip20_state>(); |
| 88 | 100 | running_device *scc; |
| 89 | 101 | running_machine *machine = space->machine; |
| 90 | 102 | |
| 91 | 103 | offset <<= 2; |
| 92 | 104 | if( offset >= 0x0e00 && offset <= 0x0e7c ) |
| 93 | 105 | { |
| 94 | | verboselog(machine, 2, "RTC RAM[0x%02x] Read: %02x\n", ( offset - 0xe00 ) >> 2, nRTC_RAM[ ( offset - 0xe00 ) >> 2 ] ); |
| 95 | | return nRTC_RAM[ ( offset - 0xe00 ) >> 2 ]; |
| 106 | verboselog(machine, 2, "RTC RAM[0x%02x] Read: %02x\n", ( offset - 0xe00 ) >> 2, state->nRTC_RAM[ ( offset - 0xe00 ) >> 2 ] ); |
| 107 | return state->nRTC_RAM[ ( offset - 0xe00 ) >> 2 ]; |
| 96 | 108 | } |
| 97 | 109 | switch( offset ) |
| 98 | 110 | { |
| r9683 | r9684 | |
| 100 | 112 | verboselog(machine, 2, "HPC Unknown Read: %08x (%08x) (returning 0x000000a5 as kludge)\n", 0x1fb80000 + offset, mem_mask ); |
| 101 | 113 | return 0x0000a500; |
| 102 | 114 | case 0x00ac: |
| 103 | | verboselog(machine, 2, "HPC Parallel Buffer Pointer Read: %08x (%08x)\n", nHPC_ParBufPtr, mem_mask ); |
| 104 | | return nHPC_ParBufPtr; |
| 115 | verboselog(machine, 2, "HPC Parallel Buffer Pointer Read: %08x (%08x)\n", state->nHPC_ParBufPtr, mem_mask ); |
| 116 | return state->nHPC_ParBufPtr; |
| 105 | 117 | case 0x00c0: |
| 106 | 118 | verboselog(machine, 2, "HPC Endianness Read: %08x (%08x)\n", 0x0000001f, mem_mask ); |
| 107 | 119 | return 0x0000001f; |
| r9683 | r9684 | |
| 124 | 136 | return 0; |
| 125 | 137 | } |
| 126 | 138 | case 0x01b0: |
| 127 | | verboselog(machine, 2, "HPC Misc. Status Read: %08x (%08x)\n", nHPC_MiscStatus, mem_mask ); |
| 128 | | return nHPC_MiscStatus; |
| 139 | verboselog(machine, 2, "HPC Misc. Status Read: %08x (%08x)\n", state->nHPC_MiscStatus, mem_mask ); |
| 140 | return state->nHPC_MiscStatus; |
| 129 | 141 | case 0x01bc: |
| 130 | 142 | // verboselog(machine, 2, "HPC CPU Serial EEPROM Read\n" ); |
| 131 | 143 | return ( ( eeprom_read_bit(space->machine->device("eeprom")) << 4 ) ); |
| 132 | 144 | case 0x01c4: |
| 133 | | verboselog(machine, 2, "HPC Local IO Register 0 Mask Read: %08x (%08x)\n", nHPC_LocalIOReg0Mask, mem_mask ); |
| 134 | | return nHPC_LocalIOReg0Mask; |
| 145 | verboselog(machine, 2, "HPC Local IO Register 0 Mask Read: %08x (%08x)\n", state->nHPC_LocalIOReg0Mask, mem_mask ); |
| 146 | return state->nHPC_LocalIOReg0Mask; |
| 135 | 147 | case 0x01cc: |
| 136 | | verboselog(machine, 2, "HPC Local IO Register 1 Mask Read: %08x (%08x)\n", nHPC_LocalIOReg0Mask, mem_mask ); |
| 137 | | return nHPC_LocalIOReg1Mask; |
| 148 | verboselog(machine, 2, "HPC Local IO Register 1 Mask Read: %08x (%08x)\n", state->nHPC_LocalIOReg0Mask, mem_mask ); |
| 149 | return state->nHPC_LocalIOReg1Mask; |
| 138 | 150 | case 0x01d4: |
| 139 | | verboselog(machine, 2, "HPC VME Interrupt Mask 0 Read: %08x (%08x)\n", nHPC_LocalIOReg0Mask, mem_mask ); |
| 140 | | return nHPC_VMEIntMask0; |
| 151 | verboselog(machine, 2, "HPC VME Interrupt Mask 0 Read: %08x (%08x)\n", state->nHPC_LocalIOReg0Mask, mem_mask ); |
| 152 | return state->nHPC_VMEIntMask0; |
| 141 | 153 | case 0x01d8: |
| 142 | | verboselog(machine, 2, "HPC VME Interrupt Mask 1 Read: %08x (%08x)\n", nHPC_LocalIOReg0Mask, mem_mask ); |
| 143 | | return nHPC_VMEIntMask1; |
| 154 | verboselog(machine, 2, "HPC VME Interrupt Mask 1 Read: %08x (%08x)\n", state->nHPC_LocalIOReg0Mask, mem_mask ); |
| 155 | return state->nHPC_VMEIntMask1; |
| 144 | 156 | case 0x0d00: |
| 145 | 157 | verboselog(machine, 2, "HPC DUART0 Channel B Control Read\n" ); |
| 146 | 158 | // return 0x00000004; |
| r9683 | r9684 | |
| 202 | 214 | |
| 203 | 215 | static WRITE32_HANDLER( hpc_w ) |
| 204 | 216 | { |
| 217 | ip20_state *state = space->machine->driver_data<ip20_state>(); |
| 205 | 218 | running_device *scc; |
| 206 | 219 | running_device *eeprom; |
| 207 | 220 | running_machine *machine = space->machine; |
| r9683 | r9684 | |
| 211 | 224 | if( offset >= 0x0e00 && offset <= 0x0e7c ) |
| 212 | 225 | { |
| 213 | 226 | verboselog(machine, 2, "RTC RAM[0x%02x] Write: %02x\n", ( offset - 0xe00 ) >> 2, data & 0x000000ff ); |
| 214 | | nRTC_RAM[ ( offset - 0xe00 ) >> 2 ] = data & 0x000000ff; |
| 227 | state->nRTC_RAM[ ( offset - 0xe00 ) >> 2 ] = data & 0x000000ff; |
| 215 | 228 | switch( ( offset - 0xe00 ) >> 2 ) |
| 216 | 229 | { |
| 217 | 230 | case 0: |
| 218 | 231 | break; |
| 219 | 232 | case 4: |
| 220 | | if( !( nRTC_RAM[0x00] & 0x80 ) ) |
| 233 | if( !( state->nRTC_RAM[0x00] & 0x80 ) ) |
| 221 | 234 | { |
| 222 | 235 | if( data & 0x80 ) |
| 223 | 236 | { |
| 224 | | nRTC_RAM[0x19] = RTC_SECOND; |
| 225 | | nRTC_RAM[0x1a] = RTC_MINUTE; |
| 226 | | nRTC_RAM[0x1b] = RTC_HOUR; |
| 227 | | nRTC_RAM[0x1c] = RTC_DAY; |
| 228 | | nRTC_RAM[0x1d] = RTC_MONTH; |
| 237 | state->nRTC_RAM[0x19] = RTC_SECOND; |
| 238 | state->nRTC_RAM[0x1a] = RTC_MINUTE; |
| 239 | state->nRTC_RAM[0x1b] = RTC_HOUR; |
| 240 | state->nRTC_RAM[0x1c] = RTC_DAY; |
| 241 | state->nRTC_RAM[0x1d] = RTC_MONTH; |
| 229 | 242 | } |
| 230 | 243 | } |
| 231 | 244 | break; |
| r9683 | r9684 | |
| 235 | 248 | switch( offset ) |
| 236 | 249 | { |
| 237 | 250 | case 0x0090: // SCSI0 next descriptor pointer |
| 238 | | nHPC_SCSI0Descriptor = data; |
| 251 | state->nHPC_SCSI0Descriptor = data; |
| 239 | 252 | break; |
| 240 | 253 | |
| 241 | 254 | case 0x0094: // SCSI0 control flags |
| 242 | | nHPC_SCSI0DMACtrl = data; |
| 255 | state->nHPC_SCSI0DMACtrl = data; |
| 243 | 256 | #if 0 |
| 244 | 257 | if (data & 0x80) |
| 245 | 258 | { |
| r9683 | r9684 | |
| 248 | 261 | mame_printf_info("DMA activated for SCSI0\n"); |
| 249 | 262 | mame_printf_info("Descriptor block:\n"); |
| 250 | 263 | mame_printf_info("CTL: %08x BUFPTR: %08x DESCPTR %08x\n", |
| 251 | | program_read_dword(nHPC_SCSI0Descriptor), program_read_dword(nHPC_SCSI0Descriptor+4), |
| 252 | | program_read_dword(nHPC_SCSI0Descriptor+8)); |
| 264 | program_read_dword(state->nHPC_SCSI0Descriptor), program_read_dword(state->nHPC_SCSI0Descriptor+4), |
| 265 | program_read_dword(state->nHPC_SCSI0Descriptor+8)); |
| 253 | 266 | |
| 254 | | next = program_read_dword(nHPC_SCSI0Descriptor+8); |
| 267 | next = program_read_dword(state->nHPC_SCSI0Descriptor+8); |
| 255 | 268 | mame_printf_info("CTL: %08x BUFPTR: %08x DESCPTR %08x\n", |
| 256 | 269 | program_read_dword(next), program_read_dword(next+4), |
| 257 | 270 | program_read_dword(next+8)); |
| r9683 | r9684 | |
| 261 | 274 | |
| 262 | 275 | case 0x00ac: |
| 263 | 276 | verboselog(machine, 2, "HPC Parallel Buffer Pointer Write: %08x (%08x)\n", data, mem_mask ); |
| 264 | | nHPC_ParBufPtr = data; |
| 277 | state->nHPC_ParBufPtr = data; |
| 265 | 278 | break; |
| 266 | 279 | case 0x0120: |
| 267 | 280 | if (ACCESSING_BITS_8_15) |
| r9683 | r9684 | |
| 311 | 324 | { |
| 312 | 325 | verboselog(machine, 2, " SRAM size: 8K\n" ); |
| 313 | 326 | } |
| 314 | | nHPC_MiscStatus = data; |
| 327 | state->nHPC_MiscStatus = data; |
| 315 | 328 | break; |
| 316 | 329 | case 0x01bc: |
| 317 | 330 | // verboselog(machine, 2, "HPC CPU Serial EEPROM Write: %08x (%08x)\n", data, mem_mask ); |
| r9683 | r9684 | |
| 325 | 338 | break; |
| 326 | 339 | case 0x01c4: |
| 327 | 340 | verboselog(machine, 2, "HPC Local IO Register 0 Mask Write: %08x (%08x)\n", data, mem_mask ); |
| 328 | | nHPC_LocalIOReg0Mask = data; |
| 341 | state->nHPC_LocalIOReg0Mask = data; |
| 329 | 342 | break; |
| 330 | 343 | case 0x01cc: |
| 331 | 344 | verboselog(machine, 2, "HPC Local IO Register 1 Mask Write: %08x (%08x)\n", data, mem_mask ); |
| 332 | | nHPC_LocalIOReg1Mask = data; |
| 345 | state->nHPC_LocalIOReg1Mask = data; |
| 333 | 346 | break; |
| 334 | 347 | case 0x01d4: |
| 335 | 348 | verboselog(machine, 2, "HPC VME Interrupt Mask 0 Write: %08x (%08x)\n", data, mem_mask ); |
| 336 | | nHPC_VMEIntMask0 = data; |
| 349 | state->nHPC_VMEIntMask0 = data; |
| 337 | 350 | break; |
| 338 | 351 | case 0x01d8: |
| 339 | 352 | verboselog(machine, 2, "HPC VME Interrupt Mask 1 Write: %08x (%08x)\n", data, mem_mask ); |
| 340 | | nHPC_VMEIntMask1 = data; |
| 353 | state->nHPC_VMEIntMask1 = data; |
| 341 | 354 | break; |
| 342 | 355 | case 0x0d00: |
| 343 | 356 | verboselog(machine, 2, "HPC DUART0 Channel B Control Write: %08x (%08x)\n", data, mem_mask ); |
| r9683 | r9684 | |
| 485 | 498 | // sgi_mc_update wants once every millisecond (1/1000th of a second) |
| 486 | 499 | static TIMER_CALLBACK(ip20_timer) |
| 487 | 500 | { |
| 501 | ip20_state *state = machine->driver_data<ip20_state>(); |
| 488 | 502 | sgi_mc_update(); |
| 489 | 503 | |
| 490 | 504 | // update RTC every 10 milliseconds |
| 491 | | nRTC_Temp++; |
| 492 | | if (nRTC_Temp >= 10) |
| 505 | state->nRTC_Temp++; |
| 506 | if (state->nRTC_Temp >= 10) |
| 493 | 507 | { |
| 494 | | nRTC_Temp = 0; |
| 508 | state->nRTC_Temp = 0; |
| 495 | 509 | RTC_HUNDREDTH++; |
| 496 | 510 | |
| 497 | 511 | if( ( RTC_HUNDREDTH & 0x0f ) == 0x0a ) |
| r9683 | r9684 | |
| 544 | 558 | |
| 545 | 559 | static MACHINE_START( ip204415 ) |
| 546 | 560 | { |
| 561 | ip20_state *state = machine->driver_data<ip20_state>(); |
| 547 | 562 | sgi_mc_timer_init(machine); |
| 548 | 563 | |
| 549 | 564 | wd33c93_init(machine, &scsi_intf); |
| 550 | 565 | |
| 551 | 566 | sgi_mc_init(machine); |
| 552 | 567 | |
| 553 | | nHPC_MiscStatus = 0; |
| 554 | | nHPC_ParBufPtr = 0; |
| 555 | | nHPC_LocalIOReg0Mask = 0; |
| 556 | | nHPC_LocalIOReg1Mask = 0; |
| 557 | | nHPC_VMEIntMask0 = 0; |
| 558 | | nHPC_VMEIntMask1 = 0; |
| 568 | state->nHPC_MiscStatus = 0; |
| 569 | state->nHPC_ParBufPtr = 0; |
| 570 | state->nHPC_LocalIOReg0Mask = 0; |
| 571 | state->nHPC_LocalIOReg1Mask = 0; |
| 572 | state->nHPC_VMEIntMask0 = 0; |
| 573 | state->nHPC_VMEIntMask1 = 0; |
| 559 | 574 | |
| 560 | | nRTC_Temp = 0; |
| 575 | state->nRTC_Temp = 0; |
| 561 | 576 | |
| 562 | 577 | timer_set(machine, ATTOTIME_IN_MSEC(1), NULL, 0, ip20_timer); |
| 563 | 578 | } |
| r9683 | r9684 | |
| 573 | 588 | 32768 /* data cache size */ |
| 574 | 589 | }; |
| 575 | 590 | |
| 576 | | static MACHINE_CONFIG_START( ip204415, driver_device ) |
| 591 | static MACHINE_CONFIG_START( ip204415, ip20_state ) |
| 577 | 592 | MDRV_CPU_ADD( "maincpu", R4600BE, 50000000*3 ) |
| 578 | 593 | MDRV_CPU_CONFIG( config ) |
| 579 | 594 | MDRV_CPU_PROGRAM_MAP( ip204415_map) |