trunk/src/mess/drivers/pcfx.c
r17381 | r17382 | |
17 | 17 | { |
18 | 18 | public: |
19 | 19 | pcfx_state(const machine_config &mconfig, device_type type, const char *tag) |
20 | | : driver_device(mconfig, type, tag) { } |
| 20 | : driver_device(mconfig, type, tag) |
| 21 | , m_maincpu(*this, "maincpu") |
| 22 | { } |
21 | 23 | |
| 24 | required_device<cpu_device> m_maincpu; |
| 25 | |
22 | 26 | virtual void machine_reset(); |
23 | 27 | |
24 | 28 | UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
| 29 | |
| 30 | // Interrupt controller (component unknown) |
| 31 | UINT16 m_irq_mask; |
| 32 | UINT16 m_irq_pending; |
| 33 | UINT8 m_irq_priority[8]; |
| 34 | |
| 35 | DECLARE_READ16_MEMBER( irq_read ); |
| 36 | DECLARE_WRITE16_MEMBER( irq_write ); |
| 37 | inline void check_irqs(); |
| 38 | inline void set_irq_line(int line, int state); |
| 39 | DECLARE_WRITE_LINE_MEMBER( irq8_w ); |
| 40 | DECLARE_WRITE_LINE_MEMBER( irq9_w ); |
| 41 | DECLARE_WRITE_LINE_MEMBER( irq10_w ); |
| 42 | DECLARE_WRITE_LINE_MEMBER( irq11_w ); |
| 43 | DECLARE_WRITE_LINE_MEMBER( irq12_w ); |
| 44 | DECLARE_WRITE_LINE_MEMBER( irq13_w ); |
| 45 | DECLARE_WRITE_LINE_MEMBER( irq14_w ); |
| 46 | DECLARE_WRITE_LINE_MEMBER( irq15_w ); |
| 47 | |
25 | 48 | }; |
26 | 49 | |
27 | 50 | |
r17381 | r17382 | |
44 | 67 | AM_RANGE( 0x00000500, 0x000005FF ) AM_DEVREADWRITE8( "huc6270_b", huc6270_device, read, write, 0xff ) /* HuC6270-B */ |
45 | 68 | AM_RANGE( 0x00000600, 0x000006FF ) AM_NOP /* HuC6272 */ |
46 | 69 | AM_RANGE( 0x00000C80, 0x00000C83 ) AM_NOP |
47 | | AM_RANGE( 0x00000E00, 0x00000EFF ) AM_NOP |
| 70 | AM_RANGE( 0x00000E00, 0x00000EFF ) AM_READWRITE16( irq_read, irq_write, 0xffff ) /* Interrupt controller */ |
48 | 71 | AM_RANGE( 0x00000F00, 0x00000FFF ) AM_NOP |
49 | 72 | AM_RANGE( 0x80500000, 0x805000FF ) AM_NOP /* HuC6273 */ |
50 | 73 | ADDRESS_MAP_END |
r17381 | r17382 | |
54 | 77 | INPUT_PORTS_END |
55 | 78 | |
56 | 79 | |
57 | | static WRITE_LINE_DEVICE_HANDLER( pcfx_irq_changed ) |
| 80 | READ16_MEMBER( pcfx_state::irq_read ) |
58 | 81 | { |
| 82 | UINT16 data = 0; |
| 83 | |
| 84 | switch( offset ) |
| 85 | { |
| 86 | // Interrupts pending |
| 87 | // Same bit order as mask |
| 88 | case 0x00/4: |
| 89 | data = m_irq_pending; |
| 90 | break; |
| 91 | |
| 92 | // Interrupt mask |
| 93 | case 0x40/4: |
| 94 | data = m_irq_mask; |
| 95 | break; |
| 96 | |
| 97 | // Interrupt priority 0 |
| 98 | case 0x80/4: |
| 99 | data = m_irq_priority[4] | ( m_irq_priority[5] << 3 ) | ( m_irq_priority[6] << 6 ) | ( m_irq_priority[7] << 9 ); |
| 100 | break; |
| 101 | |
| 102 | // Interrupt priority 1 |
| 103 | case 0xC0/4: |
| 104 | data = m_irq_priority[0] | ( m_irq_priority[1] << 3 ) | ( m_irq_priority[2] << 6 ) | ( m_irq_priority[3] << 9 ); |
| 105 | break; |
| 106 | } |
| 107 | |
| 108 | return data; |
59 | 109 | } |
60 | 110 | |
61 | 111 | |
| 112 | WRITE16_MEMBER( pcfx_state::irq_write ) |
| 113 | { |
| 114 | switch( offset ) |
| 115 | { |
| 116 | // Interrupts pending |
| 117 | case 0x00/4: |
| 118 | logerror("irq_write: Attempt to write to irq pending register\n"); |
| 119 | break; |
| 120 | |
| 121 | // Interrupt mask |
| 122 | // --------x------- Mask interrupt level 8 (Unknown) |
| 123 | // ---------x------ Mask interrupt level 9 (Timer) |
| 124 | // ----------x----- Mask interrupt level 10 (Unknown) |
| 125 | // -----------x---- Mask interrupt level 11 (Pad) |
| 126 | // ------------x--- Mask interrupt level 12 (HuC6270-A) |
| 127 | // -------------x-- Mask interrupt level 13 (HuC6272) |
| 128 | // --------------x- Mask interrupt level 14 (HuC6270-B) |
| 129 | // ---------------x Mask interrupt level 15 (HuC6273) |
| 130 | // 0 - allow, 1 - ignore interrupt |
| 131 | case 0x40/4: |
| 132 | m_irq_mask = data; |
| 133 | check_irqs(); |
| 134 | break; |
| 135 | |
| 136 | // Interrupt priority 0 |
| 137 | // ----xxx--------- Priority level interrupt 12 |
| 138 | // -------xxx------ Priority level interrupt 13 |
| 139 | // ----------xxx--- Priority level interrupt 14 |
| 140 | // -------------xxx Priority level interrupt 15 |
| 141 | case 0x80/4: |
| 142 | m_irq_priority[4] = ( data >> 0 ) & 0x07; |
| 143 | m_irq_priority[5] = ( data >> 3 ) & 0x07; |
| 144 | m_irq_priority[6] = ( data >> 6 ) & 0x07; |
| 145 | m_irq_priority[7] = ( data >> 9 ) & 0x07; |
| 146 | check_irqs(); |
| 147 | break; |
| 148 | |
| 149 | // Interrupt priority 1 |
| 150 | // ----xxx--------- Priority level interrupt 8 |
| 151 | // -------xxx------ Priority level interrupt 9 |
| 152 | // ----------xxx--- Priority level interrupt 10 |
| 153 | // -------------xxx Priority level interrupt 11 |
| 154 | case 0xC0/4: |
| 155 | m_irq_priority[0] = ( data >> 0 ) & 0x07; |
| 156 | m_irq_priority[1] = ( data >> 3 ) & 0x07; |
| 157 | m_irq_priority[2] = ( data >> 6 ) & 0x07; |
| 158 | m_irq_priority[3] = ( data >> 9 ) & 0x07; |
| 159 | check_irqs(); |
| 160 | break; |
| 161 | } |
| 162 | } |
| 163 | |
| 164 | |
| 165 | inline void pcfx_state::check_irqs() |
| 166 | { |
| 167 | UINT16 active_irqs = m_irq_pending & ~m_irq_mask; |
| 168 | int highest_prio = -1; |
| 169 | |
| 170 | for ( int i = 0; i < 8; i++ ) |
| 171 | { |
| 172 | if ( active_irqs & 0x80 ) |
| 173 | { |
| 174 | if ( m_irq_priority[i] >= highest_prio ) |
| 175 | { |
| 176 | highest_prio = m_irq_priority[i]; |
| 177 | } |
| 178 | } |
| 179 | active_irqs <<= 1; |
| 180 | } |
| 181 | |
| 182 | if ( highest_prio >= 0 ) |
| 183 | { |
| 184 | device_set_input_line( m_maincpu, 8 + highest_prio, ASSERT_LINE ); |
| 185 | } |
| 186 | else |
| 187 | { |
| 188 | device_set_input_line( m_maincpu, 0, CLEAR_LINE ); |
| 189 | } |
| 190 | } |
| 191 | |
| 192 | |
| 193 | inline void pcfx_state::set_irq_line(int line, int state) |
| 194 | { |
| 195 | if ( state ) |
| 196 | { |
| 197 | printf("Setting irq line %d\n", line); |
| 198 | m_irq_pending |= ( 1 << ( 15 - line ) ); |
| 199 | } |
| 200 | else |
| 201 | { |
| 202 | printf("Clearing irq line %d\n", line); |
| 203 | m_irq_pending &= ~( 1 << ( 15 - line ) ); |
| 204 | } |
| 205 | check_irqs(); |
| 206 | } |
| 207 | |
| 208 | WRITE_LINE_MEMBER( pcfx_state::irq8_w ) |
| 209 | { |
| 210 | set_irq_line(8, state); |
| 211 | } |
| 212 | |
| 213 | WRITE_LINE_MEMBER( pcfx_state::irq9_w ) |
| 214 | { |
| 215 | set_irq_line(9, state); |
| 216 | } |
| 217 | |
| 218 | WRITE_LINE_MEMBER( pcfx_state::irq10_w ) |
| 219 | { |
| 220 | set_irq_line(10, state); |
| 221 | } |
| 222 | |
| 223 | WRITE_LINE_MEMBER( pcfx_state::irq11_w ) |
| 224 | { |
| 225 | set_irq_line(11, state); |
| 226 | } |
| 227 | |
| 228 | WRITE_LINE_MEMBER( pcfx_state::irq12_w ) |
| 229 | { |
| 230 | set_irq_line(12, state); |
| 231 | } |
| 232 | |
| 233 | WRITE_LINE_MEMBER( pcfx_state::irq13_w ) |
| 234 | { |
| 235 | set_irq_line(13, state); |
| 236 | } |
| 237 | |
| 238 | WRITE_LINE_MEMBER( pcfx_state::irq14_w ) |
| 239 | { |
| 240 | set_irq_line(14, state); |
| 241 | } |
| 242 | |
| 243 | WRITE_LINE_MEMBER( pcfx_state::irq15_w ) |
| 244 | { |
| 245 | set_irq_line(15, state); |
| 246 | } |
| 247 | |
| 248 | |
62 | 249 | static const huc6261_interface pcfx_huc6261_config = |
63 | 250 | { |
64 | 251 | "screen", |
r17381 | r17382 | |
70 | 257 | static const huc6270_interface pcfx_huc6270_a_config = |
71 | 258 | { |
72 | 259 | 0x20000, |
73 | | DEVCB_LINE(pcfx_irq_changed), |
| 260 | DEVCB_DRIVER_LINE_MEMBER(pcfx_state, irq12_w) |
74 | 261 | }; |
75 | 262 | |
76 | 263 | |
77 | 264 | static const huc6270_interface pcfx_huc6270_b_config = |
78 | 265 | { |
79 | 266 | 0x20000, |
80 | | DEVCB_LINE(pcfx_irq_changed), |
| 267 | DEVCB_DRIVER_LINE_MEMBER(pcfx_state, irq14_w) |
81 | 268 | }; |
82 | 269 | |
83 | 270 | |
84 | 271 | void pcfx_state::machine_reset() |
85 | 272 | { |
86 | 273 | membank( "bank1" )->set_base( memregion("user1")->base() ); |
| 274 | |
| 275 | m_irq_mask = 0xFF; |
| 276 | m_irq_pending = 0; |
87 | 277 | } |
88 | 278 | |
| 279 | |
89 | 280 | UINT32 pcfx_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
90 | 281 | { |
91 | 282 | return 0; |
92 | 283 | } |
93 | 284 | |
| 285 | |
94 | 286 | static MACHINE_CONFIG_START( pcfx, pcfx_state ) |
95 | 287 | MCFG_CPU_ADD( "maincpu", V810, XTAL_21_4772MHz ) |
96 | 288 | MCFG_CPU_PROGRAM_MAP( pcfx_mem) |