trunk/src/mame/drivers/viper.c
r18092 | r18093 | |
292 | 292 | #define VIPER_DEBUG_LOG |
293 | 293 | #define VIPER_DEBUG_EPIC_INTS 1 |
294 | 294 | #define VIPER_DEBUG_EPIC_TIMERS 0 |
| 295 | #define VIPER_DEBUG_EPIC_REGS 0 |
| 296 | #define VIPER_DEBUG_EPIC_I2C 0 |
295 | 297 | |
296 | 298 | |
297 | 299 | #define SDRAM_CLOCK 166666666 // Main SDRAMs run at 166MHz |
r18092 | r18093 | |
491 | 493 | // TODO: move to viper_state |
492 | 494 | static MPC8240_EPIC epic; |
493 | 495 | |
| 496 | #if VIPER_DEBUG_EPIC_REGS |
494 | 497 | static const char* epic_get_register_name(UINT32 reg) |
495 | 498 | { |
496 | 499 | switch (reg >> 16) |
r18092 | r18093 | |
604 | 607 | |
605 | 608 | return NULL; |
606 | 609 | } |
| 610 | #endif |
607 | 611 | |
608 | 612 | static TIMER_CALLBACK(epic_global_timer_callback) |
609 | 613 | { |
r18092 | r18093 | |
682 | 686 | int reg; |
683 | 687 | reg = offset * 4; |
684 | 688 | |
| 689 | #if VIPER_DEBUG_EPIC_REGS |
685 | 690 | if (reg != 0x600a0) // IACK is spammy |
686 | 691 | { |
687 | 692 | const char *regname = epic_get_register_name(reg); |
r18092 | r18093 | |
694 | 699 | printf("EPIC: read %08X at %08X\n", reg, space.device().safe_pc()); |
695 | 700 | } |
696 | 701 | } |
| 702 | #endif |
697 | 703 | |
| 704 | UINT32 ret = 0; |
| 705 | |
698 | 706 | switch (reg >> 16) |
699 | 707 | { |
700 | 708 | // 0x00000 - 0x0ffff |
r18092 | r18093 | |
704 | 712 | { |
705 | 713 | case 0x3000: // Offset 0x3000 - I2CADR |
706 | 714 | { |
707 | | return epic.i2c_adr; |
| 715 | ret = epic.i2c_adr; |
| 716 | break; |
708 | 717 | } |
709 | 718 | case 0x3004: // Offset 0x3004 - I2CFDR |
710 | 719 | { |
711 | | return epic.i2c_freq_div | (epic.i2c_freq_sample_rate << 8); |
| 720 | ret = epic.i2c_freq_div | (epic.i2c_freq_sample_rate << 8); |
| 721 | break; |
712 | 722 | } |
713 | 723 | case 0x3008: // Offset 0x3008 - I2CCR |
714 | 724 | { |
715 | | return epic.i2c_cr; |
| 725 | ret = epic.i2c_cr; |
| 726 | break; |
716 | 727 | } |
717 | 728 | case 0x300c: // Offset 0x300c - I2CSR |
718 | 729 | { |
719 | | return epic.i2c_sr; |
| 730 | ret = epic.i2c_sr; |
| 731 | break; |
720 | 732 | } |
721 | 733 | case 0x3010: // Offset 0x3010 - I2CDR |
722 | 734 | { |
r18092 | r18093 | |
778 | 790 | case 0x11e0: // Offset 0x411e0 - Global Timer 3 vector/priority register |
779 | 791 | { |
780 | 792 | int timer_num = ((reg & 0xffff) - 0x1120) >> 6; |
781 | | UINT32 value = 0; |
782 | | value |= epic.irq[MPC8240_GTIMER0_IRQ + timer_num].mask ? 0x80000000 : 0; |
783 | | value |= epic.irq[MPC8240_GTIMER0_IRQ + timer_num].priority << 16; |
784 | | value |= epic.irq[MPC8240_GTIMER0_IRQ + timer_num].vector; |
785 | | value |= epic.irq[MPC8240_GTIMER0_IRQ + timer_num].active ? 0x40000000 : 0; |
786 | | return value; |
| 793 | |
| 794 | ret |= epic.irq[MPC8240_GTIMER0_IRQ + timer_num].mask ? 0x80000000 : 0; |
| 795 | ret |= epic.irq[MPC8240_GTIMER0_IRQ + timer_num].priority << 16; |
| 796 | ret |= epic.irq[MPC8240_GTIMER0_IRQ + timer_num].vector; |
| 797 | ret |= epic.irq[MPC8240_GTIMER0_IRQ + timer_num].active ? 0x40000000 : 0; |
| 798 | break; |
787 | 799 | } |
788 | 800 | } |
789 | 801 | break; |
r18092 | r18093 | |
812 | 824 | case 0x03e0: // Offset 0x503e0 - IRQ15 vector/priority register |
813 | 825 | { |
814 | 826 | int irq = ((reg & 0xffff) - 0x200) >> 5; |
815 | | int value = 0; |
816 | 827 | |
817 | | value |= epic.irq[MPC8240_IRQ0 + irq].mask ? 0x80000000 : 0; |
818 | | value |= epic.irq[MPC8240_IRQ0 + irq].priority << 16; |
819 | | value |= epic.irq[MPC8240_IRQ0 + irq].vector; |
820 | | value |= epic.irq[MPC8240_IRQ0 + irq].active ? 0x40000000 : 0; |
821 | | |
822 | | return value; |
| 828 | ret |= epic.irq[MPC8240_IRQ0 + irq].mask ? 0x80000000 : 0; |
| 829 | ret |= epic.irq[MPC8240_IRQ0 + irq].priority << 16; |
| 830 | ret |= epic.irq[MPC8240_IRQ0 + irq].vector; |
| 831 | ret |= epic.irq[MPC8240_IRQ0 + irq].active ? 0x40000000 : 0; |
| 832 | break; |
823 | 833 | } |
824 | 834 | case 0x1020: // Offset 0x51020 - I2C IRQ vector/priority register |
825 | 835 | { |
826 | | UINT32 value = 0; |
827 | | value |= epic.irq[MPC8240_I2C_IRQ].mask ? 0x80000000 : 0; |
828 | | value |= epic.irq[MPC8240_I2C_IRQ].priority << 16; |
829 | | value |= epic.irq[MPC8240_I2C_IRQ].vector; |
830 | | value |= epic.irq[MPC8240_I2C_IRQ].active ? 0x40000000 : 0; |
831 | | return value; |
| 836 | ret |= epic.irq[MPC8240_I2C_IRQ].mask ? 0x80000000 : 0; |
| 837 | ret |= epic.irq[MPC8240_I2C_IRQ].priority << 16; |
| 838 | ret |= epic.irq[MPC8240_I2C_IRQ].vector; |
| 839 | ret |= epic.irq[MPC8240_I2C_IRQ].active ? 0x40000000 : 0; |
| 840 | return ret; |
832 | 841 | } |
833 | 842 | } |
834 | 843 | break; |
r18092 | r18093 | |
845 | 854 | |
846 | 855 | if (epic.active_irq >= 0) |
847 | 856 | { |
848 | | return epic.iack; |
| 857 | ret = epic.iack; |
849 | 858 | } |
850 | 859 | else |
851 | 860 | { |
852 | 861 | // spurious vector register is returned if no pending interrupts |
853 | | return epic.svr; |
| 862 | ret = epic.svr; |
854 | 863 | } |
| 864 | break; |
855 | 865 | } |
856 | 866 | |
857 | 867 | } |
r18092 | r18093 | |
859 | 869 | } |
860 | 870 | } |
861 | 871 | |
862 | | return 0; |
| 872 | return FLIPENDIAN_INT32(ret); |
863 | 873 | } |
864 | 874 | |
865 | 875 | WRITE32_MEMBER(viper_state::epic_w) |
r18092 | r18093 | |
867 | 877 | int reg; |
868 | 878 | reg = offset * 4; |
869 | 879 | |
| 880 | data = FLIPENDIAN_INT32(data); |
| 881 | |
| 882 | #if VIPER_DEBUG_EPIC_REGS |
870 | 883 | if (reg != 0x600b0) // interrupt clearing is spammy |
871 | 884 | { |
872 | 885 | const char *regname = epic_get_register_name(reg); |
r18092 | r18093 | |
879 | 892 | printf("EPIC: write %08X, %08X at %08X\n", data, reg, space.device().safe_pc()); |
880 | 893 | } |
881 | 894 | } |
| 895 | #endif |
882 | 896 | |
883 | 897 | switch (reg >> 16) |
884 | 898 | { |
r18092 | r18093 | |
921 | 935 | { |
922 | 936 | if (epic.i2c_state == I2C_STATE_ADDRESS_CYCLE) // waiting for address cycle |
923 | 937 | { |
924 | | int addr = (data >> 1) & 0x7f; |
925 | 938 | //int rw = data & 1; |
926 | 939 | |
| 940 | #if VIPER_DEBUG_EPIC_I2C |
| 941 | int addr = (data >> 1) & 0x7f; |
927 | 942 | printf("I2C address cycle, addr = %02X\n", addr); |
| 943 | #endif |
928 | 944 | epic.i2c_state = I2C_STATE_DATA_TRANSFER; |
929 | 945 | |
930 | 946 | // set transfer complete in status register |
r18092 | r18093 | |
933 | 949 | // generate interrupt if interrupt are enabled |
934 | 950 | if (epic.i2c_cr & 0x40) |
935 | 951 | { |
| 952 | #if VIPER_DEBUG_EPIC_I2C |
936 | 953 | printf("I2C interrupt\n"); |
| 954 | #endif |
937 | 955 | mpc8240_interrupt(machine(), MPC8240_I2C_IRQ); |
938 | 956 | |
939 | 957 | // set interrupt flag in status register |
r18092 | r18093 | |
942 | 960 | } |
943 | 961 | else if (epic.i2c_state == I2C_STATE_DATA_TRANSFER) // waiting for data transfer |
944 | 962 | { |
| 963 | #if VIPER_DEBUG_EPIC_I2C |
945 | 964 | printf("I2C data transfer, data = %02X\n", data); |
| 965 | #endif |
946 | 966 | epic.i2c_state = I2C_STATE_ADDRESS_CYCLE; |
947 | 967 | |
948 | 968 | // set transfer complete in status register |
r18092 | r18093 | |
951 | 971 | // generate interrupt if interrupts are enabled |
952 | 972 | if (epic.i2c_cr & 0x40) |
953 | 973 | { |
| 974 | #if VIPER_DEBUG_EPIC_I2C |
954 | 975 | printf("I2C interrupt\n"); |
| 976 | #endif |
955 | 977 | mpc8240_interrupt(machine(), MPC8240_I2C_IRQ); |
956 | 978 | |
957 | 979 | // set interrupt flag in status register |