trunk/src/emu/machine/mcf5206e.c
| r22644 | r22645 | |
| 48 | 48 | |
| 49 | 49 | AM_RANGE(0x100, 0x103) AM_READWRITE16(TMR1_r, TMR1_w, 0xffffffff) |
| 50 | 50 | AM_RANGE(0x104, 0x107) AM_READWRITE16(TRR1_r, TRR1_w, 0xffffffff) |
| 51 | AM_RANGE(0x110, 0x113) AM_READWRITE8(TER1_r, TER1_w, 0xffffffff) |
| 51 | 52 | |
| 52 | 53 | |
| 53 | 54 | AM_RANGE(0x1c4, 0x1c7) AM_READWRITE8(PPDDR_r, PPDDR_w, 0xffffffff) |
| r22644 | r22645 | |
| 58 | 59 | ADDRESS_MAP_END |
| 59 | 60 | |
| 60 | 61 | |
| 62 | |
| 61 | 63 | READ8_MEMBER( mcf5206e_peripheral_device::ICR1_ICR2_ICR3_ICR4_r ) |
| 62 | 64 | { |
| 63 | 65 | switch (offset) |
| 64 | 66 | { |
| 65 | 67 | case 0: // 0x014 |
| 66 | 68 | printf("(External IRQ1/IPL1 Interrupt Vector) ICR1_r\n"); |
| 67 | | return m_ICR1; |
| 69 | return m_ICR[ICR1]; |
| 68 | 70 | case 1: // 0x015 |
| 69 | 71 | printf("(External IPL2 Interrupt Vector) ICR2_r\n"); |
| 70 | | return m_ICR2; |
| 72 | return m_ICR[ICR2]; |
| 71 | 73 | case 2: // 0x016 |
| 72 | 74 | printf("(External IPL3 Interrupt Vector) ICR3_r\n"); |
| 73 | | return m_ICR3; |
| 75 | return m_ICR[ICR3]; |
| 74 | 76 | case 3: // 0x017 |
| 75 | 77 | printf("(External IRQ4/IPL4 Interrupt Vector) ICR4_r\n"); |
| 76 | | return m_ICR4; |
| 78 | return m_ICR[ICR4]; |
| 77 | 79 | } |
| 78 | 80 | |
| 79 | 81 | return 0; |
| r22644 | r22645 | |
| 84 | 86 | switch (offset) |
| 85 | 87 | { |
| 86 | 88 | case 0: // 0x014 |
| 87 | | m_ICR1 = data; |
| 89 | m_ICR[ICR1] = data; |
| 88 | 90 | printf("(External IRQ1/IPL1 Interrupt Vector) ICR1_w %02x\n",data); |
| 91 | ICR_info(m_ICR[ICR1]); |
| 89 | 92 | break; |
| 90 | 93 | case 1: // 0x015 |
| 91 | | m_ICR2 = data; |
| 94 | m_ICR[ICR2] = data; |
| 92 | 95 | printf("(External IPL2 Interrupt Vector) ICR2_w %02x\n",data); |
| 96 | ICR_info(m_ICR[ICR2]); |
| 93 | 97 | break; |
| 94 | 98 | case 2: // 0x016 |
| 95 | | m_ICR3 = data; |
| 99 | m_ICR[ICR3] = data; |
| 96 | 100 | printf("(External IPL3 Interrupt Vector) ICR3_w %02x\n",data); |
| 101 | ICR_info(m_ICR[ICR3]); |
| 97 | 102 | break; |
| 98 | 103 | case 3: // 0x017 |
| 99 | | m_ICR4 = data; |
| 104 | m_ICR[ICR4] = data; |
| 100 | 105 | printf("(External IRQ4/IPL4 Interrupt Vector) ICR4_w %02x\n",data); |
| 106 | ICR_info(m_ICR[ICR4]); |
| 101 | 107 | break; |
| 102 | 108 | } |
| 103 | 109 | } |
| r22644 | r22645 | |
| 108 | 114 | { |
| 109 | 115 | case 0: // 0x01c |
| 110 | 116 | printf("(Timer 1 Interrupt Vector) ICR9_r\n"); |
| 111 | | return m_ICR9; |
| 117 | return m_ICR[ICR9]; |
| 112 | 118 | case 1: // 0x01d |
| 113 | 119 | printf("(Timer 2 Interrupt Vector) ICR10_r\n"); |
| 114 | | return m_ICR10; |
| 120 | return m_ICR[ICR10]; |
| 115 | 121 | case 2: // 0x01e |
| 116 | 122 | printf("(MBUS Interrupt Vector) ICR11_r\n"); |
| 117 | | return m_ICR11; |
| 123 | return m_ICR[ICR11]; |
| 118 | 124 | case 3: // 0x01f |
| 119 | 125 | printf("(UART1 Interrupt Vector) ICR12_r\n"); |
| 120 | | return m_ICR12; |
| 126 | return m_ICR[ICR12]; |
| 121 | 127 | } |
| 122 | 128 | |
| 123 | 129 | return 0; |
| r22644 | r22645 | |
| 128 | 134 | switch (offset) |
| 129 | 135 | { |
| 130 | 136 | case 0: // 0x01c |
| 131 | | m_ICR9 = data; |
| 137 | m_ICR[ICR9] = data; |
| 132 | 138 | printf("(Timer 1 Interrupt Vector) ICR9_w %02x\n",data); |
| 139 | ICR_info(m_ICR[ICR9]); |
| 133 | 140 | break; |
| 134 | 141 | case 1: // 0x01d |
| 135 | | m_ICR10 = data; |
| 142 | m_ICR[ICR10] = data; |
| 136 | 143 | printf("(Timer 2 Interrupt Vector) ICR10_w %02x\n",data); |
| 144 | ICR_info(m_ICR[ICR10]); |
| 137 | 145 | break; |
| 138 | 146 | case 2: // 0x01e |
| 139 | | m_ICR11 = data; |
| 147 | m_ICR[ICR11] = data; |
| 140 | 148 | printf("(MBUS Interrupt Vector) ICR11_w %02x\n",data); |
| 149 | ICR_info(m_ICR[ICR11]); |
| 141 | 150 | break; |
| 142 | 151 | case 3: // 0x01f |
| 143 | | m_ICR12 = data; |
| 152 | m_ICR[ICR12] = data; |
| 144 | 153 | printf("(UART1 Interrupt Vector) ICR12_w %02x\n",data); |
| 154 | ICR_info(m_ICR[ICR12]); |
| 145 | 155 | break; |
| 146 | 156 | } |
| 147 | 157 | } |
| r22644 | r22645 | |
| 152 | 162 | { |
| 153 | 163 | case 0: // 0x020 |
| 154 | 164 | printf("(UART2 Interrupt Vector) ICR13_r\n"); |
| 155 | | return m_ICR13; |
| 165 | return m_ICR[ICR13]; |
| 156 | 166 | case 1: |
| 157 | 167 | case 2: |
| 158 | 168 | case 3: |
| r22644 | r22645 | |
| 168 | 178 | switch (offset) |
| 169 | 179 | { |
| 170 | 180 | case 0: // 0x020 |
| 171 | | m_ICR13 = data; |
| 181 | m_ICR[ICR13] = data; |
| 172 | 182 | printf("(UART2 Interrupt Vector) ICR13_w %02x\n",data); |
| 183 | ICR_info(m_ICR[ICR13]); |
| 173 | 184 | break; |
| 174 | 185 | case 1: |
| 175 | 186 | case 2: |
| r22644 | r22645 | |
| 540 | 551 | } |
| 541 | 552 | } |
| 542 | 553 | |
| 554 | void mcf5206e_peripheral_device::ICR_info(UINT8 ICR) |
| 555 | { |
| 556 | printf(" (AutoVector) AVEC : %01x | ", (ICR&0x80)>>7); |
| 557 | printf("(Interrupt Level) IL : %01x | ", (ICR&0x1c)>>2); // if autovector (AVEC) is used then the vectors referenced are at +24 (+0x18) + IL, ie the standard 68k autovectors, otherwise vector must be provided by device |
| 558 | printf("(Interrupt Priority) IP : %01x |", (ICR&0x03)>>0); |
| 559 | printf("(Unused bits) : %01x\n", (ICR&0x60)>>5); |
| 560 | } |
| 543 | 561 | |
| 562 | /* The timer module seems practically the same as the 68307 one, possibly make into a common device once the code isn't a hardcoded piece of junk ;-) */ |
| 544 | 563 | |
| 564 | TIMER_CALLBACK_MEMBER(mcf5206e_peripheral_device::timer1_callback) |
| 565 | { |
| 566 | UINT8 ICR = m_ICR[ICR9]; |
| 567 | |
| 568 | // technically we should do the vector check in the IRQ callback as well as various checks based on the IRQ masks before asserting the interrupt |
| 569 | if (ICR & 0x80) // AVEC |
| 570 | { |
| 571 | m_cpu->set_input_line((ICR&0x1c)>>2, HOLD_LINE); |
| 572 | } |
| 573 | |
| 574 | printf("timer1_callback\n"); |
| 575 | |
| 576 | timer1->adjust(attotime::from_seconds(1)); // completely made up value just to fire our timers for now |
| 577 | } |
| 578 | |
| 579 | |
| 545 | 580 | READ16_MEMBER( mcf5206e_peripheral_device::TMR1_r) |
| 546 | 581 | { |
| 547 | 582 | switch (offset) |
| r22644 | r22645 | |
| 564 | 599 | case 0: |
| 565 | 600 | COMBINE_DATA(&m_TMR1); |
| 566 | 601 | printf("TMR1_w %04x %04x\n",data, mem_mask); |
| 602 | |
| 603 | printf(" (Prescale) PS : %02x (Capture Edge/Interrupt) CE : %01x (Output Mode) OM : %01x (Output Reference Interrupt En) ORI : %01x Free Run (FRR) : %01x Input Clock Source (ICLK) : %01x (Reset Timer) RST : %01x \n", |
| 604 | (m_TMR1 & 0xff00)>>8, (m_TMR1 & 0x00c0)>>6, (m_TMR1 & 0x0020)>>5, (m_TMR1 & 0x0010)>>4, (m_TMR1 & 0x0008)>>3, (m_TMR1 & 0x0006)>>1, (m_TMR1 & 0x0001)>>0); |
| 605 | |
| 606 | if (m_TMR1 & 0x0001) |
| 607 | { |
| 608 | timer1->adjust(attotime::from_seconds(1)); // completely made up value just to fire our timers for now |
| 609 | } |
| 610 | else |
| 611 | { |
| 612 | timer1->adjust(attotime::never); |
| 613 | } |
| 614 | |
| 615 | |
| 567 | 616 | break; |
| 568 | 617 | case 1: |
| 569 | 618 | printf("invalid TMR1_w %d, %04x %04x\n", offset, data, mem_mask); |
| r22644 | r22645 | |
| 603 | 652 | } |
| 604 | 653 | |
| 605 | 654 | |
| 655 | |
| 656 | READ8_MEMBER( mcf5206e_peripheral_device::TER1_r) |
| 657 | { |
| 658 | switch (offset) |
| 659 | { |
| 660 | case 1: |
| 661 | printf("TER1_r\n"); |
| 662 | return 2; // hack, timer events should set bits, this just stops the code going crazy for now |
| 663 | case 0: |
| 664 | case 2: |
| 665 | case 3: |
| 666 | printf("invalid TER1_r %d\n", offset); |
| 667 | return 0; |
| 668 | } |
| 669 | |
| 670 | return 0; |
| 671 | } |
| 672 | |
| 673 | WRITE8_MEMBER( mcf5206e_peripheral_device::TER1_w) |
| 674 | { |
| 675 | switch (offset) |
| 676 | { |
| 677 | case 1: |
| 678 | m_TER1 = data; // writes should clear the bits.. |
| 679 | printf("TER1_w %02x\n",data); |
| 680 | break; |
| 681 | case 0: |
| 682 | case 2: |
| 683 | case 3: |
| 684 | printf("invalid TER1_w %d, %02x\n", offset, data); |
| 685 | break; |
| 686 | |
| 687 | } |
| 688 | } |
| 689 | |
| 690 | |
| 606 | 691 | //************************************************************************** |
| 607 | 692 | // LIVE DEVICE |
| 608 | 693 | //************************************************************************** |
| r22644 | r22645 | |
| 644 | 729 | void mcf5206e_peripheral_device::device_start() |
| 645 | 730 | { |
| 646 | 731 | init_regs(true); |
| 732 | |
| 733 | timer1 = machine().scheduler().timer_alloc( timer_expired_delegate( FUNC( mcf5206e_peripheral_device::timer1_callback ), this) ); |
| 734 | |
| 647 | 735 | } |
| 648 | 736 | |
| 737 | void mcf5206e_peripheral_device::device_reset() |
| 738 | { |
| 739 | m_cpu = (cpu_device*)machine().device(":maincpu"); // hack. this device should really be attached to a modern CPU core |
| 649 | 740 | |
| 741 | init_regs(false); |
| 742 | timer1->adjust(attotime::never); |
| 743 | } |
| 650 | 744 | |
| 651 | 745 | READ32_MEMBER(mcf5206e_peripheral_device::dev_r) |
| 652 | 746 | { |
| r22644 | r22645 | |
| 692 | 786 | |
| 693 | 787 | void mcf5206e_peripheral_device::init_regs(bool first_init) |
| 694 | 788 | { |
| 695 | | m_ICR1 = 0x04; |
| 696 | | m_ICR2 = 0x08; |
| 697 | | m_ICR3 = 0x0C; |
| 698 | | m_ICR4 = 0x10; |
| 699 | | m_ICR5 = 0x14; |
| 700 | | m_ICR6 = 0x18; |
| 701 | | m_ICR7 = 0x1C; |
| 702 | | m_ICR8 = 0x1C; |
| 703 | | m_ICR9 = 0x80; |
| 704 | | m_ICR10 = 0x80; |
| 705 | | m_ICR11 = 0x80; |
| 706 | | m_ICR12 = 0x00; |
| 707 | | m_ICR13 = 0x00; |
| 789 | m_ICR[ICR1] = 0x04; |
| 790 | m_ICR[ICR2] = 0x08; |
| 791 | m_ICR[ICR3] = 0x0C; |
| 792 | m_ICR[ICR4] = 0x10; |
| 793 | m_ICR[ICR5] = 0x14; |
| 794 | m_ICR[ICR6] = 0x18; |
| 795 | m_ICR[ICR7] = 0x1C; |
| 796 | m_ICR[ICR8] = 0x1C; |
| 797 | m_ICR[ICR9] = 0x80; |
| 798 | m_ICR[ICR10] = 0x80; |
| 799 | m_ICR[ICR11] = 0x80; |
| 800 | m_ICR[ICR12] = 0x00; |
| 801 | m_ICR[ICR13] = 0x00; |
| 708 | 802 | |
| 709 | 803 | m_CSAR[0] = 0x0000; |
| 710 | 804 | m_CSMR[0] = 0x00000000; |
trunk/src/emu/machine/mcf5206e.h
| r22644 | r22645 | |
| 26 | 26 | |
| 27 | 27 | // ======================> mcf5206e_peripheral_device |
| 28 | 28 | |
| 29 | enum |
| 30 | { |
| 31 | ICR1 = 0, |
| 32 | ICR2, |
| 33 | ICR3, |
| 34 | ICR4, |
| 35 | ICR5, |
| 36 | ICR6, |
| 37 | ICR7, |
| 38 | ICR8, |
| 39 | ICR9, |
| 40 | ICR10, |
| 41 | ICR11, |
| 42 | ICR12, |
| 43 | ICR13, |
| 44 | MAX_ICR |
| 45 | }; |
| 46 | |
| 29 | 47 | class mcf5206e_peripheral_device : public device_t, |
| 30 | 48 | public device_memory_interface |
| 31 | 49 | { |
| 32 | 50 | public: |
| 33 | 51 | // construction/destruction |
| 34 | 52 | mcf5206e_peripheral_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 53 | |
| 54 | void ICR_info(UINT8 ICR); |
| 35 | 55 | |
| 36 | 56 | DECLARE_READ32_MEMBER( dev_r ); |
| 37 | 57 | DECLARE_WRITE32_MEMBER( dev_w ); |
| r22644 | r22645 | |
| 111 | 131 | DECLARE_WRITE16_MEMBER( TMR1_w ); |
| 112 | 132 | DECLARE_READ16_MEMBER( TRR1_r ); |
| 113 | 133 | DECLARE_WRITE16_MEMBER( TRR1_w ); |
| 134 | DECLARE_READ8_MEMBER( TER1_r ); |
| 135 | DECLARE_WRITE8_MEMBER(TER1_w ); |
| 114 | 136 | |
| 115 | 137 | DECLARE_READ8_MEMBER( PPDDR_r ); |
| 116 | 138 | DECLARE_WRITE8_MEMBER( PPDDR_w ); |
| r22644 | r22645 | |
| 126 | 148 | DECLARE_READ8_MEMBER( MBSR_r ); |
| 127 | 149 | DECLARE_WRITE8_MEMBER( MBSR_w ); |
| 128 | 150 | |
| 151 | cpu_device* m_cpu; |
| 129 | 152 | |
| 130 | 153 | protected: |
| 131 | 154 | // device-level overrides |
| 132 | 155 | virtual void device_config_complete(); |
| 133 | 156 | virtual void device_start(); |
| 134 | | virtual void device_reset() { } |
| 157 | virtual void device_reset(); |
| 135 | 158 | virtual void device_post_load() { } |
| 136 | 159 | virtual void device_clock_changed() { } |
| 137 | 160 | virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const; |
| r22644 | r22645 | |
| 142 | 165 | |
| 143 | 166 | void init_regs(bool first_init); |
| 144 | 167 | |
| 145 | | UINT8 m_ICR1; |
| 146 | | UINT8 m_ICR2; |
| 147 | | UINT8 m_ICR3; |
| 148 | | UINT8 m_ICR4; |
| 149 | | UINT8 m_ICR5; |
| 150 | | UINT8 m_ICR6; |
| 151 | | UINT8 m_ICR7; |
| 152 | | UINT8 m_ICR8; |
| 153 | | UINT8 m_ICR9; |
| 154 | | UINT8 m_ICR10; |
| 155 | | UINT8 m_ICR11; |
| 156 | | UINT8 m_ICR12; |
| 157 | | UINT8 m_ICR13; |
| 168 | UINT8 m_ICR[MAX_ICR]; |
| 158 | 169 | |
| 159 | 170 | UINT16 m_CSAR[8]; |
| 160 | 171 | UINT32 m_CSMR[8]; |
| r22644 | r22645 | |
| 163 | 174 | UINT16 m_DMCR; |
| 164 | 175 | UINT16 m_PAR; |
| 165 | 176 | |
| 177 | emu_timer *timer1; |
| 166 | 178 | UINT16 m_TMR1; |
| 167 | 179 | UINT16 m_TRR1; |
| 180 | UINT8 m_TER1; |
| 181 | TIMER_CALLBACK_MEMBER(timer1_callback); |
| 168 | 182 | |
| 183 | |
| 169 | 184 | UINT8 m_PPDDR; |
| 170 | 185 | UINT8 m_PPDAT; |
| 171 | 186 | |