branches/code_cleanup/src/mame/machine/n64.cpp
r250319 | r250320 | |
9 | 9 | #include "includes/n64.h" |
10 | 10 | #include "video/n64.h" |
11 | 11 | |
12 | | UINT32 *n64_sram; |
13 | | UINT32 *rdram; |
14 | | UINT32 *rsp_imem; |
15 | | UINT32 *rsp_dmem; |
16 | | |
17 | 12 | // device type definition |
18 | 13 | const device_type N64PERIPH = &device_creator<n64_periphs>; |
19 | 14 | |
20 | | |
21 | | |
22 | | |
23 | 15 | n64_periphs::n64_periphs(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
24 | 16 | : device_t(mconfig, N64PERIPH, "N64 Periphal Chips", tag, owner, clock, "n64_periphs", __FILE__) |
25 | 17 | , device_video_interface(mconfig, *this) |
r250319 | r250320 | |
49 | 41 | void n64_periphs::reset_tick() |
50 | 42 | { |
51 | 43 | reset_timer->adjust(attotime::never); |
52 | | maincpu->reset(); |
53 | | maincpu->execute().set_input_line(INPUT_LINE_IRQ2, CLEAR_LINE); |
54 | | rspcpu->reset(); |
55 | | rspcpu->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
56 | | rspcpu->state().set_state_int(RSP_SR, rspcpu->state().state_int(RSP_SR) | RSP_STATUS_HALT); |
| 44 | m_vr4300->reset(); |
| 45 | m_vr4300->set_input_line(INPUT_LINE_IRQ2, CLEAR_LINE); |
| 46 | m_rsp->reset(); |
| 47 | m_rsp->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 48 | m_rsp->set_state_int(RSP_SR, m_rsp->state_int(RSP_SR) | RSP_STATUS_HALT); |
57 | 49 | reset_held = false; |
58 | 50 | cic_status = 0; |
59 | 51 | memset(pif_ram, 0, sizeof(pif_ram)); |
r250319 | r250320 | |
104 | 96 | reset_held = button; |
105 | 97 | if(!old_held && reset_held) |
106 | 98 | { |
107 | | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ2, ASSERT_LINE); |
| 99 | m_vr4300->set_input_line(INPUT_LINE_IRQ2, ASSERT_LINE); |
108 | 100 | } |
109 | 101 | else if(old_held && reset_held) |
110 | 102 | { |
r250319 | r250320 | |
123 | 115 | si_dma_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(n64_periphs::si_dma_callback),this)); |
124 | 116 | vi_scanline_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(n64_periphs::vi_scanline_callback),this)); |
125 | 117 | reset_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(n64_periphs::reset_timer_callback),this)); |
| 118 | m_n64 = machine().driver_data<n64_state>(); |
126 | 119 | } |
127 | 120 | |
128 | 121 | void n64_periphs::device_reset() |
129 | 122 | { |
130 | 123 | UINT32 *cart = (UINT32*)machine().root_device().memregion("user2")->base(); |
131 | 124 | |
132 | | maincpu = machine().device("maincpu"); |
133 | | rspcpu = machine().device("rsp"); |
134 | | mem_map = &maincpu->memory().space(AS_PROGRAM); |
| 125 | m_vr4300 = machine().device<mips3_device>("maincpu"); |
| 126 | m_rsp = machine().device<rsp_device>("rsp"); |
| 127 | m_mem_map = &m_vr4300->space(AS_PROGRAM); |
135 | 128 | |
| 129 | m_rdram = m_n64->rdram(); |
| 130 | m_rsp_imem = m_n64->rsp_imem(); |
| 131 | m_rsp_dmem = m_n64->rsp_dmem(); |
| 132 | m_sram = m_n64->sram(); |
| 133 | |
136 | 134 | mi_version = 0x01010101; |
137 | 135 | mi_interrupt = 0; |
138 | 136 | mi_intr_mask = 0; |
r250319 | r250320 | |
238 | 236 | pif_ram[0x26] = 0x3f; |
239 | 237 | pif_ram[0x27] = 0x3f; |
240 | 238 | cic_type=2; |
241 | | mem_map->write_dword(0x00000318, 0x800000); /* RDRAM Size */ |
| 239 | m_mem_map->write_dword(0x00000318, 0x800000); /* RDRAM Size */ |
242 | 240 | |
243 | 241 | if (boot_checksum == U64(0x00000000001ff230)) |
244 | 242 | { |
r250319 | r250320 | |
274 | 272 | pif_ram[0x26] = 0x91; |
275 | 273 | pif_ram[0x27] = 0x3f; |
276 | 274 | cic_type=5; |
277 | | mem_map->write_dword(0x000003f0, 0x800000); |
| 275 | m_mem_map->write_dword(0x000003f0, 0x800000); |
278 | 276 | } |
279 | 277 | else if (boot_checksum == U64(0x000000d6d5de4ba0)) |
280 | 278 | { |
r250319 | r250320 | |
329 | 327 | break; |
330 | 328 | |
331 | 329 | default: |
332 | | logerror("mi_reg_r: %08X, %08X at %08X\n", offset, mem_mask, mem_map->device().safe_pc()); |
| 330 | logerror("mi_reg_r: %08X, %08X at %08X\n", offset, mem_mask, m_vr4300->pc()); |
333 | 331 | break; |
334 | 332 | } |
335 | 333 | |
r250319 | r250320 | |
414 | 412 | } |
415 | 413 | |
416 | 414 | default: |
417 | | logerror("mi_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, maincpu->safe_pc()); |
| 415 | logerror("mi_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, m_vr4300->pc()); |
418 | 416 | break; |
419 | 417 | } |
420 | 418 | } |
r250319 | r250320 | |
428 | 426 | { |
429 | 427 | if (mi_intr_mask & mi_interrupt) |
430 | 428 | { |
431 | | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE); |
| 429 | m_vr4300->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE); |
432 | 430 | } |
433 | 431 | else |
434 | 432 | { |
435 | | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE); |
| 433 | m_vr4300->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE); |
436 | 434 | } |
437 | 435 | } |
438 | 436 | |
r250319 | r250320 | |
529 | 527 | { |
530 | 528 | if(offset > 0x24/4) |
531 | 529 | { |
532 | | logerror("rdram_reg_r: %08X, %08X at %08X\n", offset, mem_mask, maincpu->safe_pc()); |
| 530 | logerror("rdram_reg_r: %08X, %08X at %08X\n", offset, mem_mask, m_vr4300->pc()); |
533 | 531 | return 0; |
534 | 532 | } |
535 | 533 | return rdram_regs[offset]; |
r250319 | r250320 | |
539 | 537 | { |
540 | 538 | if(offset > 0x24/4) |
541 | 539 | { |
542 | | logerror("rdram_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, maincpu->safe_pc()); |
| 540 | logerror("rdram_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, m_vr4300->pc()); |
543 | 541 | return; |
544 | 542 | } |
545 | 543 | COMBINE_DATA(&rdram_regs[offset]); |
r250319 | r250320 | |
570 | 568 | length = 0x1000 - (sp_mem_addr & 0xfff); |
571 | 569 | } |
572 | 570 | |
573 | | UINT32 *sp_mem[2] = { rsp_dmem, rsp_imem }; |
| 571 | UINT32 *sp_mem[2] = { m_rsp_dmem, m_rsp_imem }; |
574 | 572 | |
575 | 573 | int sp_mem_page = (sp_mem_addr >> 12) & 1; |
576 | 574 | if(direction == 0)// RDRAM -> I/DMEM |
r250319 | r250320 | |
582 | 580 | |
583 | 581 | for(int i = 0; i < length / 4; i++) |
584 | 582 | { |
585 | | sp_mem[sp_mem_page][(dst + i) & 0x3ff] = rdram[src + i]; |
| 583 | sp_mem[sp_mem_page][(dst + i) & 0x3ff] = m_rdram[src + i]; |
586 | 584 | } |
587 | 585 | |
588 | 586 | sp_mem_addr += length; |
r250319 | r250320 | |
600 | 598 | |
601 | 599 | for(int i = 0; i < length / 4; i++) |
602 | 600 | { |
603 | | rdram[dst + i] = sp_mem[sp_mem_page][(src + i) & 0x3ff]; |
| 601 | m_rdram[dst + i] = sp_mem[sp_mem_page][(src + i) & 0x3ff]; |
604 | 602 | } |
605 | 603 | |
606 | 604 | sp_mem_addr += length; |
r250319 | r250320 | |
615 | 613 | { |
616 | 614 | if (data & 0x1) |
617 | 615 | { |
618 | | rspcpu->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
619 | | rspcpu->state().set_state_int(RSP_SR, rspcpu->state().state_int(RSP_SR) | RSP_STATUS_HALT); |
| 616 | m_rsp->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 617 | m_rsp->set_state_int(RSP_SR, m_rsp->state_int(RSP_SR) | RSP_STATUS_HALT); |
620 | 618 | } |
621 | 619 | |
622 | 620 | if (data & 0x2) |
623 | 621 | { |
624 | | rspcpu->state().set_state_int(RSP_SR, rspcpu->state().state_int(RSP_SR) | RSP_STATUS_BROKE); |
| 622 | m_rsp->set_state_int(RSP_SR, m_rsp->state_int(RSP_SR) | RSP_STATUS_BROKE); |
625 | 623 | |
626 | | if (rspcpu->state().state_int(RSP_SR) & RSP_STATUS_INTR_BREAK) |
| 624 | if (m_rsp->state_int(RSP_SR) & RSP_STATUS_INTR_BREAK) |
627 | 625 | { |
628 | 626 | signal_rcp_interrupt(SP_INTERRUPT); |
629 | 627 | } |
r250319 | r250320 | |
632 | 630 | |
633 | 631 | READ32_MEMBER(n64_periphs::sp_reg_r) |
634 | 632 | { |
635 | | UINT32 ret = 0; |
636 | 633 | switch (offset) |
637 | 634 | { |
638 | 635 | case 0x00/4: // SP_MEM_ADDR_REG |
639 | | ret = sp_mem_addr; |
640 | | break; |
| 636 | return sp_mem_addr; |
641 | 637 | |
642 | 638 | case 0x04/4: // SP_DRAM_ADDR_REG |
643 | | ret = sp_dram_addr; |
644 | | break; |
| 639 | return sp_dram_addr; |
645 | 640 | |
646 | 641 | case 0x08/4: // SP_RD_LEN_REG |
647 | | ret = (sp_dma_skip << 20) | (sp_dma_count << 12) | sp_dma_length; |
648 | | break; |
| 642 | return (sp_dma_skip << 20) | (sp_dma_count << 12) | sp_dma_length; |
649 | 643 | |
650 | 644 | case 0x10/4: // SP_STATUS_REG |
651 | | ret = rspcpu->state().state_int(RSP_SR); |
652 | | break; |
| 645 | return m_rsp->state_int(RSP_SR); |
653 | 646 | |
654 | 647 | case 0x14/4: // SP_DMA_FULL_REG |
655 | | ret = 0; |
656 | | break; |
| 648 | return 0; |
657 | 649 | |
658 | 650 | case 0x18/4: // SP_DMA_BUSY_REG |
659 | | ret = 0; |
660 | | break; |
| 651 | return 0; |
661 | 652 | |
662 | 653 | case 0x1c/4: // SP_SEMAPHORE_REG |
663 | | machine().device("maincpu")->execute().yield(); |
| 654 | m_vr4300->yield(); |
664 | 655 | if( sp_semaphore ) |
665 | 656 | { |
666 | | ret = 1; |
| 657 | return 1; |
667 | 658 | } |
668 | 659 | else |
669 | 660 | { |
670 | 661 | sp_semaphore = 1; |
671 | | ret = 0; |
| 662 | return 0; |
672 | 663 | } |
673 | 664 | break; |
674 | 665 | |
675 | 666 | case 0x20/4: // DP_CMD_START |
676 | | { |
677 | | n64_state *state = machine().driver_data<n64_state>(); |
678 | | ret = state->m_rdp->get_start(); |
679 | | break; |
680 | | } |
| 667 | return m_n64->rdp()->get_start(); |
681 | 668 | |
682 | 669 | case 0x24/4: // DP_CMD_END |
683 | | { |
684 | | n64_state *state = machine().driver_data<n64_state>(); |
685 | | ret = state->m_rdp->get_end(); |
686 | | break; |
687 | | } |
| 670 | return m_n64->rdp()->get_end(); |
688 | 671 | |
689 | 672 | case 0x28/4: // DP_CMD_CURRENT |
690 | | { |
691 | | n64_state *state = machine().driver_data<n64_state>(); |
692 | | ret = state->m_rdp->get_current(); |
693 | | break; |
694 | | } |
| 673 | return m_n64->rdp()->get_current(); |
695 | 674 | |
696 | 675 | case 0x34/4: // DP_CMD_BUSY |
697 | 676 | case 0x38/4: // DP_CMD_PIPE_BUSY |
698 | 677 | case 0x3c/4: // DP_CMD_TMEM_BUSY |
699 | | break; |
| 678 | return 0; |
700 | 679 | |
701 | 680 | case 0x2c/4: // DP_CMD_STATUS |
702 | | { |
703 | | n64_state *state = machine().driver_data<n64_state>(); |
704 | | ret = state->m_rdp->get_status(); |
705 | | break; |
706 | | } |
| 681 | return m_n64->rdp()->get_status(); |
707 | 682 | |
708 | 683 | case 0x30/4: // DP_CMD_CLOCK |
709 | | { |
710 | | if(!(machine().driver_data<n64_state>()->m_rdp->get_status() & DP_STATUS_FREEZE)) |
| 684 | if(!(m_n64->rdp()->get_status() & DP_STATUS_FREEZE)) |
711 | 685 | { |
712 | 686 | dp_clock += 13; |
713 | | ret = dp_clock; |
| 687 | return dp_clock; |
714 | 688 | } |
715 | 689 | break; |
716 | | } |
717 | 690 | |
718 | 691 | case 0x40000/4: // PC |
719 | | ret = rspcpu->state().state_int(RSP_PC) & 0x00000fff; |
720 | | break; |
| 692 | return m_rsp->state_int(RSP_PC) & 0x00000fff; |
721 | 693 | |
722 | 694 | default: |
723 | | logerror("sp_reg_r: %08X at %08X\n", offset, maincpu->safe_pc()); |
| 695 | logerror("sp_reg_r: %08X at %08X\n", offset, m_vr4300->pc()); |
724 | 696 | break; |
725 | 697 | } |
726 | 698 | |
727 | | return ret; |
| 699 | return 0; |
728 | 700 | } |
729 | 701 | |
730 | 702 | |
r250319 | r250320 | |
758 | 730 | |
759 | 731 | case 0x10/4: // RSP_STATUS_REG |
760 | 732 | { |
761 | | UINT32 oldstatus = rspcpu->state().state_int(RSP_SR); |
| 733 | UINT32 oldstatus = m_rsp->state_int(RSP_SR); |
762 | 734 | UINT32 newstatus = oldstatus; |
763 | 735 | |
764 | 736 | if (data & 0x00000001) // clear halt |
765 | 737 | { |
766 | | rspcpu->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); |
| 738 | m_rsp->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); |
767 | 739 | newstatus &= ~RSP_STATUS_HALT; |
768 | 740 | } |
769 | 741 | if (data & 0x00000002) // set halt |
770 | 742 | { |
771 | | rspcpu->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 743 | m_rsp->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
772 | 744 | newstatus |= RSP_STATUS_HALT; |
773 | 745 | } |
774 | 746 | if (data & 0x00000004) |
r250319 | r250320 | |
792 | 764 | newstatus |= RSP_STATUS_SSTEP; // set single step |
793 | 765 | if(!(oldstatus & (RSP_STATUS_BROKE | RSP_STATUS_HALT))) |
794 | 766 | { |
795 | | rspcpu->state().set_state_int(RSP_STEPCNT, 1 ); |
796 | | machine().device("rsp")->execute().yield(); |
| 767 | m_rsp->set_state_int(RSP_STEPCNT, 1 ); |
| 768 | m_rsp->yield(); |
797 | 769 | } |
798 | 770 | } |
799 | 771 | if (data & 0x00000080) |
r250319 | r250320 | |
868 | 840 | { |
869 | 841 | newstatus |= RSP_STATUS_SIGNAL7; // set signal 7 |
870 | 842 | } |
871 | | rspcpu->state().set_state_int(RSP_SR, newstatus); |
| 843 | m_rsp->set_state_int(RSP_SR, newstatus); |
872 | 844 | break; |
873 | 845 | } |
874 | 846 | |
r250319 | r250320 | |
880 | 852 | break; |
881 | 853 | |
882 | 854 | default: |
883 | | logerror("sp_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, maincpu->safe_pc()); |
| 855 | logerror("sp_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, m_vr4300->pc()); |
884 | 856 | break; |
885 | 857 | } |
886 | 858 | } |
r250319 | r250320 | |
889 | 861 | switch (offset & 0xffff) |
890 | 862 | { |
891 | 863 | case 0x00/4: // SP_PC_REG |
892 | | if( rspcpu->state().state_int(RSP_NEXTPC) != 0xffffffff ) |
| 864 | if( m_rsp->state_int(RSP_NEXTPC) != 0xffffffff ) |
893 | 865 | { |
894 | | rspcpu->state().set_state_int(RSP_NEXTPC, 0x1000 | (data & 0xfff)); |
| 866 | m_rsp->set_state_int(RSP_NEXTPC, 0x1000 | (data & 0xfff)); |
895 | 867 | } |
896 | 868 | else |
897 | 869 | { |
898 | | rspcpu->state().set_state_int(RSP_PC, 0x1000 | (data & 0xfff)); |
| 870 | m_rsp->set_state_int(RSP_PC, 0x1000 | (data & 0xfff)); |
899 | 871 | } |
900 | 872 | break; |
901 | 873 | |
902 | 874 | default: |
903 | | logerror("sp_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, maincpu->safe_pc()); |
| 875 | logerror("sp_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, m_vr4300->pc()); |
904 | 876 | break; |
905 | 877 | } |
906 | 878 | } |
r250319 | r250320 | |
916 | 888 | |
917 | 889 | READ32_MEMBER( n64_periphs::dp_reg_r ) |
918 | 890 | { |
919 | | n64_state *state = space.machine().driver_data<n64_state>(); |
920 | | UINT32 ret = 0; |
921 | | |
922 | 891 | switch (offset) |
923 | 892 | { |
924 | 893 | case 0x00/4: // DP_START_REG |
925 | | ret = state->m_rdp->get_start(); |
926 | | break; |
| 894 | return m_n64->rdp()->get_start(); |
927 | 895 | |
928 | 896 | case 0x04/4: // DP_END_REG |
929 | | ret = state->m_rdp->get_end(); |
930 | | break; |
| 897 | return m_n64->rdp()->get_end(); |
931 | 898 | |
932 | 899 | case 0x08/4: // DP_CURRENT_REG |
933 | | ret = state->m_rdp->get_current(); |
934 | | break; |
| 900 | return m_n64->rdp()->get_current(); |
935 | 901 | |
936 | 902 | case 0x0c/4: // DP_STATUS_REG |
937 | | ret = state->m_rdp->get_status(); |
938 | | break; |
| 903 | return m_n64->rdp()->get_status(); |
939 | 904 | |
940 | 905 | case 0x10/4: // DP_CLOCK_REG |
941 | | { |
942 | | if(!(state->m_rdp->get_status() & DP_STATUS_FREEZE)) |
| 906 | if(!(m_n64->rdp()->get_status() & DP_STATUS_FREEZE)) |
943 | 907 | { |
944 | 908 | dp_clock += 13; |
945 | | ret = dp_clock; |
| 909 | return dp_clock; |
946 | 910 | } |
947 | 911 | break; |
948 | | } |
949 | 912 | |
950 | 913 | default: |
951 | | logerror("dp_reg_r: %08X, %08X at %08X\n", offset, mem_mask, safe_pc()); |
| 914 | logerror("dp_reg_r: %08X, %08X at %08X\n", offset, mem_mask, m_vr4300->pc()); |
952 | 915 | break; |
953 | 916 | } |
954 | 917 | |
955 | | return ret; |
| 918 | return 0; |
956 | 919 | } |
957 | 920 | |
958 | 921 | WRITE32_MEMBER( n64_periphs::dp_reg_w ) |
959 | 922 | { |
960 | | n64_state *state = space.machine().driver_data<n64_state>(); |
961 | | UINT32 status = state->m_rdp->get_status(); |
| 923 | UINT32 status = m_n64->rdp()->get_status(); |
962 | 924 | |
963 | 925 | switch (offset) |
964 | 926 | { |
965 | 927 | case 0x00/4: // DP_START_REG |
966 | 928 | if(status & DP_STATUS_START_VALID) |
| 929 | { |
967 | 930 | break; |
| 931 | } |
968 | 932 | else |
969 | 933 | { |
970 | | state->m_rdp->set_status(status | DP_STATUS_START_VALID); |
971 | | state->m_rdp->set_start(data & ~7); |
| 934 | m_n64->rdp()->set_status(status | DP_STATUS_START_VALID); |
| 935 | m_n64->rdp()->set_start(data & ~7); |
972 | 936 | } |
973 | 937 | break; |
974 | 938 | |
975 | 939 | case 0x04/4: // DP_END_REG |
976 | 940 | if(status & DP_STATUS_START_VALID) |
977 | 941 | { |
978 | | state->m_rdp->set_status(status & ~DP_STATUS_START_VALID); |
979 | | state->m_rdp->set_current(state->m_rdp->get_start()); |
980 | | state->m_rdp->set_end(data & ~7); |
| 942 | m_n64->rdp()->set_status(status & ~DP_STATUS_START_VALID); |
| 943 | m_n64->rdp()->set_current(m_n64->rdp()->get_start()); |
| 944 | m_n64->rdp()->set_end(data & ~7); |
981 | 945 | g_profiler.start(PROFILER_USER1); |
982 | | state->m_rdp->process_command_list(); |
| 946 | m_n64->rdp()->process_command_list(); |
983 | 947 | g_profiler.stop(); |
984 | 948 | break; |
985 | 949 | } |
986 | 950 | else |
987 | 951 | { |
988 | | state->m_rdp->set_end(data & ~7); |
| 952 | m_n64->rdp()->set_end(data & ~7); |
989 | 953 | g_profiler.start(PROFILER_USER1); |
990 | | state->m_rdp->process_command_list(); |
| 954 | m_n64->rdp()->process_command_list(); |
991 | 955 | g_profiler.stop(); |
992 | 956 | break; |
993 | 957 | } |
994 | 958 | |
995 | 959 | case 0x0c/4: // DP_STATUS_REG |
996 | 960 | { |
997 | | UINT32 current_status = state->m_rdp->get_status(); |
| 961 | UINT32 current_status = m_n64->rdp()->get_status(); |
998 | 962 | if (data & 0x00000001) current_status &= ~DP_STATUS_XBUS_DMA; |
999 | 963 | if (data & 0x00000002) current_status |= DP_STATUS_XBUS_DMA; |
1000 | 964 | if (data & 0x00000004) current_status &= ~DP_STATUS_FREEZE; |
r250319 | r250320 | |
1002 | 966 | if (data & 0x00000010) current_status &= ~DP_STATUS_FLUSH; |
1003 | 967 | if (data & 0x00000020) current_status |= DP_STATUS_FLUSH; |
1004 | 968 | if (data & 0x00000200) dp_clock = 0; |
1005 | | state->m_rdp->set_status(current_status); |
| 969 | m_n64->rdp()->set_status(current_status); |
1006 | 970 | break; |
1007 | 971 | } |
1008 | 972 | |
1009 | 973 | default: |
1010 | | logerror("dp_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, safe_pc()); |
| 974 | logerror("dp_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, m_vr4300->pc()); |
1011 | 975 | break; |
1012 | 976 | } |
1013 | 977 | } |
1014 | 978 | |
1015 | 979 | TIMER_CALLBACK_MEMBER(n64_periphs::vi_scanline_callback) |
1016 | 980 | { |
1017 | | machine().device<n64_periphs>("rcp")->vi_scanline_tick(); |
1018 | | } |
1019 | | |
1020 | | void n64_periphs::vi_scanline_tick() |
1021 | | { |
1022 | 981 | signal_rcp_interrupt(VI_INTERRUPT); |
1023 | 982 | vi_scanline_timer->adjust(m_screen->time_until_pos(vi_intr >> 1)); |
1024 | 983 | } |
r250319 | r250320 | |
1124 | 1083 | break; |
1125 | 1084 | |
1126 | 1085 | default: |
1127 | | logerror("vi_reg_r: %08X, %08X at %08X\n", offset, mem_mask, maincpu->safe_pc()); |
| 1086 | logerror("vi_reg_r: %08X, %08X at %08X\n", offset, mem_mask, m_vr4300->pc()); |
1128 | 1087 | break; |
1129 | 1088 | } |
1130 | 1089 | |
r250319 | r250320 | |
1152 | 1111 | vi_recalculate_resolution(); |
1153 | 1112 | } |
1154 | 1113 | vi_width = data; |
1155 | | //state->m_rdp->m_misc_state.m_fb_width = data; |
1156 | 1114 | break; |
1157 | 1115 | |
1158 | 1116 | case 0x0c/4: // VI_INTR_REG |
r250319 | r250320 | |
1214 | 1172 | */ |
1215 | 1173 | |
1216 | 1174 | default: |
1217 | | logerror("vi_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, maincpu->safe_pc()); |
| 1175 | logerror("vi_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, m_vr4300->pc()); |
1218 | 1176 | break; |
1219 | 1177 | } |
1220 | 1178 | } |
r250319 | r250320 | |
1289 | 1247 | |
1290 | 1248 | void n64_periphs::ai_dma() |
1291 | 1249 | { |
1292 | | INT16 *ram = (INT16*)rdram; |
| 1250 | INT16 *ram = (INT16*)m_rdram; |
1293 | 1251 | AUDIO_DMA *current = ai_fifo_get_top(); |
1294 | 1252 | attotime period; |
1295 | 1253 | |
r250319 | r250320 | |
1365 | 1323 | break; |
1366 | 1324 | |
1367 | 1325 | default: |
1368 | | logerror("ai_reg_r: %08X, %08X at %08X\n", offset, mem_mask, maincpu->safe_pc()); |
| 1326 | logerror("ai_reg_r: %08X, %08X at %08X\n", offset, mem_mask, m_vr4300->pc()); |
1369 | 1327 | break; |
1370 | 1328 | } |
1371 | 1329 | |
r250319 | r250320 | |
1404 | 1362 | break; |
1405 | 1363 | |
1406 | 1364 | default: |
1407 | | logerror("ai_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, maincpu->safe_pc()); |
| 1365 | logerror("ai_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, m_vr4300->pc()); |
1408 | 1366 | break; |
1409 | 1367 | } |
1410 | 1368 | } |
r250319 | r250320 | |
1414 | 1372 | |
1415 | 1373 | TIMER_CALLBACK_MEMBER(n64_periphs::pi_dma_callback) |
1416 | 1374 | { |
1417 | | machine().device<n64_periphs>("rcp")->pi_dma_tick(); |
1418 | | machine().device("rsp")->execute().yield(); |
| 1375 | pi_dma_tick(); |
| 1376 | m_rsp->yield(); |
1419 | 1377 | } |
1420 | 1378 | |
1421 | 1379 | void n64_periphs::pi_dma_tick() |
1422 | 1380 | { |
1423 | 1381 | bool update_bm = false; |
1424 | 1382 | UINT16 *cart16; |
1425 | | UINT16 *dram16 = (UINT16*)rdram; |
| 1383 | UINT16 *dram16 = (UINT16*)m_rdram; |
1426 | 1384 | |
1427 | 1385 | UINT32 cart_addr = (pi_cart_addr & 0x0fffffff) >> 1; |
1428 | 1386 | UINT32 dram_addr = (pi_dram_addr & 0x007fffff) >> 1; |
r250319 | r250320 | |
1441 | 1399 | } |
1442 | 1400 | else if((cart_addr & 0x04000000) == 0x04000000) |
1443 | 1401 | { |
1444 | | cart16 = (UINT16*)n64_sram; |
| 1402 | cart16 = (UINT16*)m_sram; |
1445 | 1403 | cart_addr = (pi_cart_addr & 0x0001ffff) >> 1; |
1446 | 1404 | } |
1447 | 1405 | else if((cart_addr & 0x03000000) == 0x03000000 && dd_present) |
r250319 | r250320 | |
1549 | 1507 | break; |
1550 | 1508 | |
1551 | 1509 | default: |
1552 | | logerror("pi_reg_r: %08X, %08X at %08X\n", offset, mem_mask, maincpu->safe_pc()); |
| 1510 | logerror("pi_reg_r: %08X, %08X at %08X\n", offset, mem_mask, m_vr4300->pc()); |
1553 | 1511 | break; |
1554 | 1512 | } |
1555 | 1513 | |
r250319 | r250320 | |
1574 | 1532 | dd_status_reg &= ~DD_ASIC_STATUS_DREQ; |
1575 | 1533 | dd_status_reg &= ~DD_ASIC_STATUS_BM_INT; |
1576 | 1534 | //logerror("Clearing DREQ, INT\n"); |
1577 | | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE); |
| 1535 | m_vr4300->set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE); |
1578 | 1536 | } |
1579 | 1537 | if(pi_cart_addr == 0x05000000 && dd_present) |
1580 | 1538 | { |
1581 | 1539 | dd_status_reg &= ~DD_ASIC_STATUS_C2_XFER; |
1582 | 1540 | dd_status_reg &= ~DD_ASIC_STATUS_BM_INT; |
1583 | 1541 | //logerror("Clearing C2, INT\n"); |
1584 | | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE); |
| 1542 | m_vr4300->set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE); |
1585 | 1543 | } |
1586 | 1544 | break; |
1587 | 1545 | } |
r250319 | r250320 | |
1658 | 1616 | break; |
1659 | 1617 | |
1660 | 1618 | default: |
1661 | | logerror("pi_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, maincpu->safe_pc()); |
| 1619 | logerror("pi_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, m_vr4300->pc()); |
1662 | 1620 | break; |
1663 | 1621 | } |
1664 | 1622 | } |
r250319 | r250320 | |
1669 | 1627 | { |
1670 | 1628 | if(offset == 0x0C/4) // RI_SELECT |
1671 | 1629 | { |
1672 | | /* This is to 'simulate' the time that RDRAM initialization |
| 1630 | /* This is to 'simulate' the time that RDRAM initialization |
1673 | 1631 | would take if the RI registers were not set to skip the RDRAM |
1674 | 1632 | testing during device reset. Proper simulation would require |
1675 | | emulating the RDRAM modules and bus stalls for the mips cpu. |
| 1633 | emulating the RDRAM modules and bus stalls for the mips cpu. |
1676 | 1634 | The cycle amount chosen represents 1/2 second, which is not |
1677 | 1635 | necessarily the time for RDRAM initialization, but rather the |
1678 | 1636 | time recommended for letting the SI devices settle after startup. |
1679 | 1637 | This allows the initialization routines for the SI to see that a |
1680 | 1638 | proper amount of time has passed since system startup. */ |
1681 | | machine().device<mips3_device>("maincpu")->burn_cycles(93750000/2); |
| 1639 | m_vr4300->burn_cycles(93750000/2); |
1682 | 1640 | } |
1683 | 1641 | |
1684 | 1642 | if(offset > 0x1c/4) |
1685 | 1643 | { |
1686 | | logerror("ri_reg_r: %08X, %08X at %08X\n", offset, mem_mask, maincpu->safe_pc()); |
| 1644 | logerror("ri_reg_r: %08X, %08X at %08X\n", offset, mem_mask, m_vr4300->pc()); |
1687 | 1645 | return 0; |
1688 | 1646 | } |
1689 | 1647 | return ri_regs[offset]; |
r250319 | r250320 | |
1693 | 1651 | { |
1694 | 1652 | if(offset > 0x1c/4) |
1695 | 1653 | { |
1696 | | logerror("ri_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, maincpu->safe_pc()); |
| 1654 | logerror("ri_reg_w: %08X, %08X, %08X at %08X\n", data, offset, mem_mask, m_vr4300->pc()); |
1697 | 1655 | return; |
1698 | 1656 | } |
1699 | 1657 | COMBINE_DATA(&ri_regs[offset]); |
r250319 | r250320 | |
2138 | 2096 | |
2139 | 2097 | if (direction) // RDRAM -> PIF RAM |
2140 | 2098 | { |
2141 | | UINT32 *src = (UINT32*)&rdram[(si_dram_addr & 0x1fffffff) / 4]; |
| 2099 | UINT32 *src = m_rdram + ((si_dram_addr & 0x1fffffff) / 4); |
2142 | 2100 | |
2143 | 2101 | for(int i = 0; i < 64; i+=4) |
2144 | 2102 | { |
r250319 | r250320 | |
2155 | 2113 | { |
2156 | 2114 | handle_pif(); |
2157 | 2115 | |
2158 | | UINT32 *dst = (UINT32*)&rdram[(si_dram_addr & 0x1fffffff) / 4]; |
| 2116 | UINT32 *dst = m_rdram + ((si_dram_addr & 0x1fffffff) / 4); |
2159 | 2117 | |
2160 | 2118 | for(int i = 0; i < 64; i+=4) |
2161 | 2119 | { |
r250319 | r250320 | |
2315 | 2273 | } |
2316 | 2274 | //logerror("DD Write, Sending Interrupt\n"); |
2317 | 2275 | dd_status_reg |= DD_ASIC_STATUS_BM_INT; |
2318 | | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ1, ASSERT_LINE); |
| 2276 | m_vr4300->set_input_line(INPUT_LINE_IRQ1, ASSERT_LINE); |
2319 | 2277 | return; |
2320 | 2278 | } |
2321 | 2279 | else // dd read, BM Mode 1 |
r250319 | r250320 | |
2359 | 2317 | } |
2360 | 2318 | //logerror("DD Read, Sending Interrupt\n"); |
2361 | 2319 | dd_status_reg |= DD_ASIC_STATUS_BM_INT; |
2362 | | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ1, ASSERT_LINE); |
| 2320 | m_vr4300->set_input_line(INPUT_LINE_IRQ1, ASSERT_LINE); |
2363 | 2321 | return; |
2364 | 2322 | } |
2365 | 2323 | } |
r250319 | r250320 | |
2452 | 2410 | { |
2453 | 2411 | dd_status_reg &= ~DD_ASIC_STATUS_BM_INT; |
2454 | 2412 | //logerror("DD Read Gap, Clearing INT\n"); |
2455 | | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE); |
| 2413 | m_vr4300->set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE); |
2456 | 2414 | dd_update_bm(); |
2457 | 2415 | } |
2458 | 2416 | break; |
r250319 | r250320 | |
2623 | 2581 | } |
2624 | 2582 | //logerror("Sending MECHA Int\n"); |
2625 | 2583 | dd_status_reg |= DD_ASIC_STATUS_MECHA_INT; |
2626 | | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ1, ASSERT_LINE); |
| 2584 | m_vr4300->set_input_line(INPUT_LINE_IRQ1, ASSERT_LINE); |
2627 | 2585 | break; |
2628 | 2586 | |
2629 | 2587 | case 0x10/4: // BM Status |
r250319 | r250320 | |
2664 | 2622 | if(!(dd_status_reg & DD_ASIC_STATUS_BM_INT) && !(dd_status_reg & DD_ASIC_STATUS_MECHA_INT)) |
2665 | 2623 | { |
2666 | 2624 | //logerror("DD Status, Clearing INT\n"); |
2667 | | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE); |
| 2625 | m_vr4300->set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE); |
2668 | 2626 | } |
2669 | 2627 | if(data & DD_BM_START) |
2670 | 2628 | { |
r250319 | r250320 | |
2742 | 2700 | device_image_interface *image = dynamic_cast<device_image_interface *>(periphs->m_nvram_image); |
2743 | 2701 | |
2744 | 2702 | UINT8 data[0x30800]; |
2745 | | memcpy(data, n64_sram, 0x20000); |
| 2703 | if (m_sram != NULL) |
| 2704 | { |
| 2705 | memset(data, 0, 0x20000); |
| 2706 | } |
| 2707 | else |
| 2708 | { |
| 2709 | memcpy(data, m_sram, 0x20000); |
| 2710 | } |
2746 | 2711 | memcpy(data + 0x20000, periphs->m_save_data.eeprom, 0x800); |
2747 | 2712 | memcpy(data + 0x20800, periphs->m_save_data.mempak[0], 0x8000); |
2748 | 2713 | memcpy(data + 0x28800, periphs->m_save_data.mempak[1], 0x8000); |
r250319 | r250320 | |
2751 | 2716 | |
2752 | 2717 | void n64_state::machine_start() |
2753 | 2718 | { |
2754 | | rdram = reinterpret_cast<UINT32 *>(memshare("rdram")->ptr()); |
2755 | | n64_sram = reinterpret_cast<UINT32 *>(memshare("sram")->ptr()); |
2756 | | rsp_imem = reinterpret_cast<UINT32 *>(memshare("rsp_imem")->ptr()); |
2757 | | rsp_dmem = reinterpret_cast<UINT32 *>(memshare("rsp_dmem")->ptr()); |
| 2719 | m_vr4300->mips3drc_set_options(MIPS3DRC_COMPATIBLE_OPTIONS); |
2758 | 2720 | |
2759 | | dynamic_cast<mips3_device *>(machine().device("maincpu"))->mips3drc_set_options(MIPS3DRC_COMPATIBLE_OPTIONS); |
2760 | | |
2761 | 2721 | /* configure fast RAM regions */ |
2762 | | dynamic_cast<mips3_device *>(machine().device("maincpu"))->add_fastram(0x00000000, 0x007fffff, FALSE, rdram); |
| 2722 | m_vr4300->add_fastram(0x00000000, 0x007fffff, FALSE, m_rdram); |
2763 | 2723 | |
2764 | 2724 | rsp_device *rsp = machine().device<rsp_device>("rsp"); |
2765 | 2725 | rsp->rspdrc_set_options(RSPDRC_STRICT_VERIFY); |
2766 | 2726 | rsp->rspdrc_flush_drc_cache(); |
2767 | | rsp->rsp_add_dmem(rsp_dmem); |
2768 | | rsp->rsp_add_imem(rsp_imem); |
| 2727 | rsp->rsp_add_dmem(m_rsp_dmem); |
| 2728 | rsp->rsp_add_imem(m_rsp_imem); |
2769 | 2729 | |
2770 | 2730 | /* add a hook for battery save */ |
2771 | 2731 | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(n64_state::n64_machine_stop),this)); |
r250319 | r250320 | |
2773 | 2733 | |
2774 | 2734 | void n64_state::machine_reset() |
2775 | 2735 | { |
2776 | | machine().device("rsp")->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 2736 | m_rsp->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
2777 | 2737 | } |