trunk/src/mess/drivers/ngen.c
| r241931 | r241932 | |
| 41 | 41 | DECLARE_READ16_MEMBER(peripheral_r); |
| 42 | 42 | DECLARE_WRITE16_MEMBER(port00_w); |
| 43 | 43 | DECLARE_READ16_MEMBER(port00_r); |
| 44 | DECLARE_WRITE_LINE_MEMBER(dma_hrq_changed); |
| 45 | DECLARE_WRITE_LINE_MEMBER(dack0_w); |
| 46 | DECLARE_WRITE_LINE_MEMBER(dack1_w); |
| 47 | DECLARE_WRITE_LINE_MEMBER(dack2_w); |
| 48 | DECLARE_WRITE_LINE_MEMBER(dack3_w); |
| 49 | DECLARE_READ8_MEMBER(dma_read_byte); |
| 50 | DECLARE_WRITE8_MEMBER(dma_write_byte); |
| 44 | 51 | MC6845_UPDATE_ROW(crtc_update_row); |
| 45 | 52 | |
| 46 | 53 | protected: |
| r241931 | r241932 | |
| 55 | 62 | optional_shared_ptr<UINT16> m_vram; |
| 56 | 63 | optional_shared_ptr<UINT16> m_fontram; |
| 57 | 64 | |
| 65 | void set_dma_channel(int channel, int state); |
| 66 | |
| 58 | 67 | UINT16 m_peripheral; |
| 59 | 68 | UINT16 m_upper; |
| 60 | 69 | UINT16 m_middle; |
| 61 | 70 | UINT16 m_port00; |
| 62 | 71 | UINT16 m_periph141; |
| 72 | UINT8 m_dma_offset[4]; |
| 73 | INT8 m_dma_channel; |
| 63 | 74 | }; |
| 64 | 75 | |
| 65 | 76 | WRITE_LINE_MEMBER(ngen_state::pit_out0_w) |
| r241931 | r241932 | |
| 117 | 128 | { |
| 118 | 129 | switch(offset) |
| 119 | 130 | { |
| 131 | case 0x00: |
| 132 | case 0x01: |
| 133 | case 0x02: |
| 134 | case 0x03: |
| 135 | case 0x04: |
| 136 | case 0x05: |
| 137 | case 0x06: |
| 138 | case 0x07: |
| 139 | case 0x08: |
| 140 | case 0x09: |
| 141 | case 0x0a: |
| 142 | case 0x0b: |
| 143 | case 0x0c: |
| 144 | case 0x0d: |
| 145 | case 0x0e: |
| 146 | case 0x0f: |
| 147 | if(mem_mask & 0x00ff) |
| 148 | m_dmac->write(space,offset,data & 0xff); |
| 149 | //logerror("(PC=%06x) DMA write offset %04x data %04x mask %04x\n",m_maincpu->device_t::safe_pc(),offset,data,mem_mask); |
| 150 | break; |
| 151 | case 0x80: // DMA page offset? |
| 152 | case 0x81: |
| 153 | case 0x82: |
| 154 | case 0x83: |
| 155 | if(mem_mask & 0x00ff) |
| 156 | m_dma_offset[offset-0x80] = data & 0xff; |
| 157 | break; |
| 120 | 158 | case 0x110: |
| 121 | 159 | if(mem_mask & 0x00ff) |
| 122 | 160 | m_pit->write(space,0,data & 0x0ff); |
| r241931 | r241932 | |
| 151 | 189 | case 0x147: |
| 152 | 190 | //logerror("Video write offset 0x147 data %04x mask %04x\n",data,mem_mask); |
| 153 | 191 | break; |
| 192 | case 0x1a0: // serial? |
| 193 | logerror("(PC=%06x) Serial(?) 0x1a0 write offset %04x data %04x mask %04x\n",m_maincpu->device_t::safe_pc(),offset,data,mem_mask); |
| 194 | break; |
| 154 | 195 | default: |
| 155 | 196 | logerror("(PC=%06x) Unknown 80186 peripheral write offset %04x data %04x mask %04x\n",m_maincpu->device_t::safe_pc(),offset,data,mem_mask); |
| 156 | 197 | } |
| r241931 | r241932 | |
| 161 | 202 | UINT16 ret = 0xffff; |
| 162 | 203 | switch(offset) |
| 163 | 204 | { |
| 205 | case 0x00: |
| 206 | case 0x01: |
| 207 | case 0x02: |
| 208 | case 0x03: |
| 209 | case 0x04: |
| 210 | case 0x05: |
| 211 | case 0x06: |
| 212 | case 0x07: |
| 213 | case 0x08: |
| 214 | case 0x09: |
| 215 | case 0x0a: |
| 216 | case 0x0b: |
| 217 | case 0x0c: |
| 218 | case 0x0d: |
| 219 | case 0x0e: |
| 220 | case 0x0f: |
| 221 | if(mem_mask & 0x00ff) |
| 222 | ret = m_dmac->read(space,offset); |
| 223 | logerror("(PC=%06x) DMA read offset %04x mask %04x returning %04x\n",m_maincpu->device_t::safe_pc(),offset,mem_mask,ret); |
| 224 | break; |
| 225 | case 0x80: // DMA page offset? |
| 226 | case 0x81: |
| 227 | case 0x82: |
| 228 | case 0x83: |
| 229 | if(mem_mask & 0x00ff) |
| 230 | ret = m_dma_offset[offset-0x80] & 0xff; |
| 231 | break; |
| 164 | 232 | case 0x110: |
| 165 | 233 | if(mem_mask & 0x00ff) |
| 166 | 234 | ret = m_pit->read(space,0); |
| r241931 | r241932 | |
| 189 | 257 | ret = m_crtc->register_r(space,0); |
| 190 | 258 | break; |
| 191 | 259 | case 0x146: |
| 192 | | if(mem_mask & 0x00ff) |
| 193 | | ret = m_iouart->ba_cd_r(space,0); |
| 194 | 260 | break; |
| 195 | | case 0x147: // definitely video related, likely UART sending data to the video board |
| 196 | | if(mem_mask & 0x00ff) |
| 197 | | ret = m_iouart->ba_cd_r(space,1); |
| 261 | case 0x147: // definitely video related, maybe UART sending data to the monitor? |
| 198 | 262 | // expects bit 0 to be set (Video ready signal?) |
| 263 | ret = 0; |
| 199 | 264 | ret |= 1; |
| 200 | 265 | break; |
| 266 | case 0x1a0: // status? |
| 267 | ret = 0; |
| 268 | ret |= 0x02; // end of DMA transfer? |
| 269 | break; |
| 270 | case 0x1b1: |
| 271 | ret = 0; |
| 272 | ret |= 0x02; // also checked after DMA transfer ends |
| 273 | break; |
| 201 | 274 | default: |
| 202 | 275 | logerror("(PC=%06x) Unknown 80186 peripheral read offset %04x mask %04x returning %04x\n",m_maincpu->device_t::safe_pc(),offset,mem_mask,ret); |
| 203 | 276 | } |
| r241931 | r241932 | |
| 220 | 293 | return m_port00; |
| 221 | 294 | } |
| 222 | 295 | |
| 296 | |
| 297 | WRITE_LINE_MEMBER( ngen_state::dma_hrq_changed ) |
| 298 | { |
| 299 | m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); |
| 300 | } |
| 301 | |
| 302 | void ngen_state::set_dma_channel(int channel, int state) |
| 303 | { |
| 304 | if(!state) |
| 305 | m_dma_channel = channel; |
| 306 | else if(m_dma_channel == channel) |
| 307 | m_dma_channel = -1; |
| 308 | } |
| 309 | |
| 310 | WRITE_LINE_MEMBER( ngen_state::dack0_w ) { set_dma_channel(0, state); } |
| 311 | WRITE_LINE_MEMBER( ngen_state::dack1_w ) { set_dma_channel(1, state); } |
| 312 | WRITE_LINE_MEMBER( ngen_state::dack2_w ) { set_dma_channel(2, state); } |
| 313 | WRITE_LINE_MEMBER( ngen_state::dack3_w ) { set_dma_channel(3, state); } |
| 314 | |
| 315 | READ8_MEMBER(ngen_state::dma_read_byte) |
| 316 | { |
| 317 | address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space |
| 318 | UINT8 result; |
| 319 | if(m_dma_channel == -1) |
| 320 | return 0xff; |
| 321 | offs_t page_offset = (((offs_t) m_dma_offset[m_dma_channel]) << 16) & 0xFF0000; |
| 322 | |
| 323 | result = prog_space.read_byte(page_offset + offset); |
| 324 | popmessage("DMA byte address %06x read %02x\n",page_offset+offset,result); |
| 325 | return result; |
| 326 | } |
| 327 | |
| 328 | |
| 329 | WRITE8_MEMBER(ngen_state::dma_write_byte) |
| 330 | { |
| 331 | address_space& prog_space = m_maincpu->space(AS_PROGRAM); // get the right address space |
| 332 | if(m_dma_channel == -1) |
| 333 | return; |
| 334 | offs_t page_offset = (((offs_t) m_dma_offset[m_dma_channel]) << 16) & 0xFF0000; |
| 335 | |
| 336 | prog_space.write_byte(page_offset + offset, data); |
| 337 | popmessage("DMA byte address %06x write %02x\n",page_offset+offset,data); |
| 338 | } |
| 339 | |
| 340 | |
| 223 | 341 | MC6845_UPDATE_ROW( ngen_state::crtc_update_row ) |
| 224 | 342 | { |
| 225 | 343 | UINT16 addr = ma; |
| r241931 | r241932 | |
| 286 | 404 | MCFG_PIT8253_OUT2_HANDLER(WRITELINE(ngen_state, pit_out2_w)) |
| 287 | 405 | |
| 288 | 406 | MCFG_DEVICE_ADD("dmac", AM9517A, XTAL_14_7456MHz / 3) // NEC D8237A, divisor unknown |
| 407 | MCFG_I8237_OUT_HREQ_CB(WRITELINE(ngen_state, dma_hrq_changed)) |
| 408 | MCFG_I8237_IN_MEMR_CB(READ8(ngen_state, dma_read_byte)) |
| 409 | MCFG_I8237_OUT_MEMW_CB(WRITE8(ngen_state, dma_write_byte)) |
| 410 | MCFG_I8237_OUT_DACK_0_CB(WRITELINE(ngen_state, dack0_w)) |
| 411 | MCFG_I8237_OUT_DACK_1_CB(WRITELINE(ngen_state, dack1_w)) |
| 412 | MCFG_I8237_OUT_DACK_2_CB(WRITELINE(ngen_state, dack2_w)) |
| 413 | MCFG_I8237_OUT_DACK_3_CB(WRITELINE(ngen_state, dack3_w)) |
| 289 | 414 | |
| 290 | 415 | // I/O board |
| 291 | | MCFG_UPD7201_ADD("iouart",0, 0,0,0,0) // clocked by PIT channel 2? |
| 416 | MCFG_UPD7201_ADD("iouart",0,0,0,0,0) // clocked by PIT channel 2? |
| 292 | 417 | MCFG_Z80DART_OUT_TXDA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_txd)) |
| 293 | 418 | MCFG_Z80DART_OUT_TXDB_CB(DEVWRITELINE("rs232_b", rs232_port_device, write_txd)) |
| 294 | 419 | MCFG_Z80DART_OUT_DTRA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_dtr)) |