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 |