trunk/src/emu/machine/hd63450.c
| r29473 | r29474 | |
| 83 | 83 | } |
| 84 | 84 | } |
| 85 | 85 | |
| 86 | void hd63450_device::device_reset() |
| 87 | { |
| 88 | m_drq_state[0] = m_drq_state[1] = m_drq_state[2] = m_drq_state[3] = 0; |
| 89 | } |
| 90 | |
| 86 | 91 | READ16_MEMBER(hd63450_device::read) |
| 87 | 92 | { |
| 88 | 93 | int channel,reg; |
| r29473 | r29474 | |
| 143 | 148 | case 0x00: // CSR / CER |
| 144 | 149 | if(ACCESSING_BITS_8_15) |
| 145 | 150 | { |
| 146 | | // m_reg[channel].csr = (data & 0xff00) >> 8; |
| 151 | m_reg[channel].csr &= ~((data & 0xff00) >> 8); |
| 147 | 152 | // logerror("DMA#%i: Channel status write : %02x\n",channel,dmac.reg[channel].csr); |
| 148 | 153 | } |
| 149 | 154 | // CER is read-only, so no action needed there. |
| r29473 | r29474 | |
| 170 | 175 | { |
| 171 | 176 | m_reg[channel].ccr = data & 0x00ff; |
| 172 | 177 | if((data & 0x0080))// && !m_dma_read[channel] && !m_dma_write[channel]) |
| 173 | | dma_transfer_start(channel,0); |
| 178 | dma_transfer_start(channel); |
| 174 | 179 | if(data & 0x0010) // software abort |
| 175 | 180 | dma_transfer_abort(channel); |
| 176 | 181 | if(data & 0x0020) // halt operation |
| r29473 | r29474 | |
| 243 | 248 | } |
| 244 | 249 | } |
| 245 | 250 | |
| 246 | | void hd63450_device::dma_transfer_start(int channel, int dir) |
| 251 | void hd63450_device::dma_transfer_start(int channel) |
| 247 | 252 | { |
| 248 | 253 | address_space &space = m_cpu->space(AS_PROGRAM); |
| 249 | 254 | m_in_progress[channel] = 1; |
| r29473 | r29474 | |
| 293 | 298 | |
| 294 | 299 | void hd63450_device::dma_transfer_abort(int channel) |
| 295 | 300 | { |
| 301 | if(!m_in_progress[channel]) |
| 302 | return; |
| 303 | |
| 296 | 304 | logerror("DMA#%i: Transfer aborted\n",channel); |
| 297 | | m_timer[channel]->adjust(attotime::zero); |
| 305 | m_timer[channel]->adjust(attotime::never); |
| 298 | 306 | m_in_progress[channel] = 0; |
| 299 | | m_reg[channel].mtc = m_transfer_size[channel]; |
| 300 | | m_reg[channel].csr |= 0xe0; // channel operation complete, block transfer complete |
| 307 | m_reg[channel].csr |= 0x90; // channel error |
| 301 | 308 | m_reg[channel].csr &= ~0x08; // channel no longer active |
| 309 | m_reg[channel].cer = 0x11; |
| 310 | m_reg[channel].ccr &= ~0xc0; |
| 311 | m_dma_error((offs_t)3, 1); |
| 302 | 312 | } |
| 303 | 313 | |
| 304 | 314 | void hd63450_device::dma_transfer_halt(int channel) |
| 305 | 315 | { |
| 306 | 316 | m_halted[channel] = 1; |
| 307 | | m_timer[channel]->adjust(attotime::zero); |
| 317 | m_timer[channel]->adjust(attotime::never); |
| 308 | 318 | } |
| 309 | 319 | |
| 310 | 320 | void hd63450_device::dma_transfer_continue(int channel) |
| r29473 | r29474 | |
| 478 | 488 | m_in_progress[x] = 0; |
| 479 | 489 | m_reg[x].csr |= 0xe0; // channel operation complete, block transfer complete |
| 480 | 490 | m_reg[x].csr &= ~0x08; // channel no longer active |
| 491 | m_reg[x].ccr &= ~0xc0; |
| 481 | 492 | |
| 482 | 493 | // Burst transfer |
| 483 | 494 | if((m_reg[x].dcr & 0xc0) == 0x00) |
| r29473 | r29474 | |
| 491 | 502 | } |
| 492 | 503 | } |
| 493 | 504 | |
| 505 | WRITE_LINE_MEMBER(hd63450_device::drq0_w) |
| 506 | { |
| 507 | bool ostate = m_drq_state[0]; |
| 508 | m_drq_state[0] = state; |
| 509 | |
| 510 | if((m_reg[0].ocr & 2) && (state && !ostate)) |
| 511 | single_transfer(0); |
| 512 | } |
| 513 | |
| 514 | WRITE_LINE_MEMBER(hd63450_device::drq1_w) |
| 515 | { |
| 516 | bool ostate = m_drq_state[1]; |
| 517 | m_drq_state[1] = state; |
| 518 | |
| 519 | if((m_reg[1].ocr & 2) && (state && !ostate)) |
| 520 | single_transfer(1); |
| 521 | } |
| 522 | |
| 523 | WRITE_LINE_MEMBER(hd63450_device::drq2_w) |
| 524 | { |
| 525 | bool ostate = m_drq_state[2]; |
| 526 | m_drq_state[2] = state; |
| 527 | |
| 528 | if((m_reg[2].ocr & 2) && (state && !ostate)) |
| 529 | single_transfer(2); |
| 530 | } |
| 531 | |
| 532 | WRITE_LINE_MEMBER(hd63450_device::drq3_w) |
| 533 | { |
| 534 | bool ostate = m_drq_state[3]; |
| 535 | m_drq_state[3] = state; |
| 536 | |
| 537 | if((m_reg[3].ocr & 2) && (state && !ostate)) |
| 538 | single_transfer(3); |
| 539 | } |
| 540 | |
| 494 | 541 | int hd63450_device::get_vector(int channel) |
| 495 | 542 | { |
| 496 | 543 | return m_reg[channel].niv; |
trunk/src/mess/includes/x68k.h
| r29473 | r29474 | |
| 15 | 15 | #include "machine/upd765.h" |
| 16 | 16 | #include "sound/okim6258.h" |
| 17 | 17 | #include "machine/ram.h" |
| 18 | #include "machine/8530scc.h" |
| 19 | #include "sound/2151intf.h" |
| 20 | #include "machine/i8255.h" |
| 18 | 21 | |
| 19 | 22 | #define MC68901_TAG "mc68901" |
| 20 | 23 | #define RP5C15_TAG "rp5c15" |
| r29473 | r29474 | |
| 40 | 43 | TIMER_X68K_CRTC_RASTER_IRQ, |
| 41 | 44 | TIMER_X68K_CRTC_VBLANK_IRQ, |
| 42 | 45 | TIMER_X68K_FDC_TC, |
| 46 | TIMER_X68K_ADPCM |
| 43 | 47 | }; |
| 44 | 48 | |
| 45 | 49 | x68k_state(const machine_config &mconfig, device_type type, const char *tag) |
| r29473 | r29474 | |
| 52 | 56 | m_palette(*this, "palette"), |
| 53 | 57 | m_mfpdev(*this, MC68901_TAG), |
| 54 | 58 | m_rtc(*this, RP5C15_TAG), |
| 59 | m_scc(*this, "scc"), |
| 60 | m_ym2151(*this, "ym2151"), |
| 61 | m_ppi(*this, "ppi8255"), |
| 55 | 62 | m_nvram16(*this, "nvram16"), |
| 56 | 63 | m_nvram32(*this, "nvram32"), |
| 57 | 64 | m_gvram16(*this, "gvram16"), |
| 58 | 65 | m_tvram16(*this, "tvram16"), |
| 59 | 66 | m_gvram32(*this, "gvram32"), |
| 60 | | m_tvram32(*this, "tvram32") { } |
| 67 | m_tvram32(*this, "tvram32"), |
| 68 | m_options(*this, "options"), |
| 69 | m_mouse1(*this, "mouse1"), |
| 70 | m_mouse2(*this, "mouse2"), |
| 71 | m_mouse3(*this, "mouse3"), |
| 72 | m_xpd1lr(*this, "xpd1lr"), |
| 73 | m_ctrltype(*this, "ctrltype"), |
| 74 | m_joy1(*this, "joy1"), |
| 75 | m_joy2(*this, "joy2"), |
| 76 | m_md3b(*this, "md3b"), |
| 77 | m_md6b(*this, "md6b"), |
| 78 | m_md6b_extra(*this, "md6b_extra") |
| 79 | { } |
| 61 | 80 | |
| 62 | 81 | required_device<m68000_base_device> m_maincpu; |
| 63 | 82 | required_device<okim6258_device> m_okim6258; |
| r29473 | r29474 | |
| 67 | 86 | required_device<palette_device> m_palette; |
| 68 | 87 | required_device<mc68901_device> m_mfpdev; |
| 69 | 88 | required_device<rp5c15_device> m_rtc; |
| 89 | required_device<scc8530_t> m_scc; |
| 90 | required_device<ym2151_device> m_ym2151; |
| 91 | required_device<i8255_device> m_ppi; |
| 70 | 92 | |
| 71 | 93 | optional_shared_ptr<UINT16> m_nvram16; |
| 72 | 94 | optional_shared_ptr<UINT32> m_nvram32; |
| r29473 | r29474 | |
| 75 | 97 | optional_shared_ptr<UINT16> m_tvram16; |
| 76 | 98 | optional_shared_ptr<UINT32> m_gvram32; |
| 77 | 99 | optional_shared_ptr<UINT32> m_tvram32; |
| 100 | |
| 101 | required_ioport m_options; |
| 102 | required_ioport m_mouse1; |
| 103 | required_ioport m_mouse2; |
| 104 | required_ioport m_mouse3; |
| 105 | required_ioport m_xpd1lr; |
| 106 | required_ioport m_ctrltype; |
| 107 | required_ioport m_joy1; |
| 108 | required_ioport m_joy2; |
| 109 | required_ioport m_md3b; |
| 110 | required_ioport m_md6b; |
| 111 | required_ioport m_md6b_extra; |
| 78 | 112 | |
| 79 | 113 | DECLARE_WRITE_LINE_MEMBER( mfp_tbo_w ); |
| 80 | 114 | |
| r29473 | r29474 | |
| 100 | 134 | int eject[4]; |
| 101 | 135 | int motor[4]; |
| 102 | 136 | int selected_drive; |
| 103 | | int drq_state; |
| 104 | 137 | } m_fdc; |
| 105 | 138 | struct |
| 106 | 139 | { |
| r29473 | r29474 | |
| 203 | 236 | emu_timer* m_raster_irq; |
| 204 | 237 | emu_timer* m_vblank_irq; |
| 205 | 238 | emu_timer* m_fdc_tc; |
| 239 | emu_timer* m_adpcm_timer; |
| 206 | 240 | UINT16* m_spriteram; |
| 207 | 241 | UINT16* m_spritereg; |
| 208 | 242 | tilemap_t* m_bg0_8; |
| r29473 | r29474 | |
| 241 | 275 | DECLARE_READ8_MEMBER(ppi_port_c_r); |
| 242 | 276 | DECLARE_WRITE8_MEMBER(ppi_port_c_w); |
| 243 | 277 | DECLARE_WRITE_LINE_MEMBER(fdc_irq); |
| 244 | | DECLARE_WRITE_LINE_MEMBER(fdc_drq); |
| 245 | 278 | DECLARE_WRITE8_MEMBER(x68k_ct_w); |
| 246 | 279 | DECLARE_WRITE_LINE_MEMBER(x68k_rtc_alarm_irq); |
| 247 | 280 | DECLARE_WRITE8_MEMBER(x68030_adpcm_w); |
trunk/src/mess/drivers/x68k.c
| r29473 | r29474 | |
| 115 | 115 | */ |
| 116 | 116 | |
| 117 | 117 | #include "emu.h" |
| 118 | | #include "cpu/m68000/m68000.h" |
| 119 | | #include "machine/i8255.h" |
| 120 | 118 | #include "machine/mc68901.h" |
| 121 | 119 | #include "machine/upd765.h" |
| 122 | | #include "sound/2151intf.h" |
| 123 | 120 | #include "sound/okim6258.h" |
| 124 | | #include "machine/8530scc.h" |
| 125 | 121 | #include "machine/rp5c15.h" |
| 126 | 122 | #include "machine/mb89352.h" |
| 127 | 123 | #include "formats/xdf_dsk.h" |
| r29473 | r29474 | |
| 181 | 177 | m_fdc.fdc->tc_w(ASSERT_LINE); |
| 182 | 178 | m_fdc.fdc->tc_w(CLEAR_LINE); |
| 183 | 179 | break; |
| 180 | case TIMER_X68K_ADPCM: |
| 181 | m_hd63450->drq3_w(1); |
| 182 | m_hd63450->drq3_w(0); |
| 183 | break; |
| 184 | 184 | default: |
| 185 | 185 | assert_always(FALSE, "Unknown id in x68k_state::device_timer"); |
| 186 | 186 | } |
| r29473 | r29474 | |
| 213 | 213 | // typically read from the SCC data port on receive buffer full interrupt per byte |
| 214 | 214 | int x68k_state::x68k_read_mouse() |
| 215 | 215 | { |
| 216 | | scc8530_t *scc = machine().device<scc8530_t>("scc"); |
| 217 | 216 | char val = 0; |
| 218 | 217 | char ipt = 0; |
| 219 | 218 | |
| 220 | | if(!(scc->get_reg_b(5) & 0x02)) |
| 219 | if(!(m_scc->get_reg_b(5) & 0x02)) |
| 221 | 220 | return 0xff; |
| 222 | 221 | |
| 223 | 222 | switch(m_mouse.inputtype) |
| 224 | 223 | { |
| 225 | 224 | case 0: |
| 226 | | ipt = ioport("mouse1")->read(); |
| 225 | ipt = m_mouse1->read(); |
| 227 | 226 | break; |
| 228 | 227 | case 1: |
| 229 | | val = ioport("mouse2")->read(); |
| 228 | val = m_mouse2->read(); |
| 230 | 229 | ipt = val - m_mouse.last_mouse_x; |
| 231 | 230 | m_mouse.last_mouse_x = val; |
| 232 | 231 | break; |
| 233 | 232 | case 2: |
| 234 | | val = ioport("mouse3")->read(); |
| 233 | val = m_mouse3->read(); |
| 235 | 234 | ipt = val - m_mouse.last_mouse_y; |
| 236 | 235 | m_mouse.last_mouse_y = val; |
| 237 | 236 | break; |
| r29473 | r29474 | |
| 239 | 238 | m_mouse.inputtype++; |
| 240 | 239 | if(m_mouse.inputtype > 2) |
| 241 | 240 | { |
| 242 | | int i_val = scc->get_reg_b(0); |
| 241 | int i_val = m_scc->get_reg_b(0); |
| 243 | 242 | m_mouse.inputtype = 0; |
| 244 | 243 | m_mouse.bufferempty = 1; |
| 245 | 244 | i_val &= ~0x01; |
| 246 | | scc->set_reg_b(0, i_val); |
| 245 | m_scc->set_reg_b(0, i_val); |
| 247 | 246 | logerror("SCC: mouse buffer empty\n"); |
| 248 | 247 | } |
| 249 | 248 | |
| r29473 | r29474 | |
| 258 | 257 | */ |
| 259 | 258 | READ16_MEMBER(x68k_state::x68k_scc_r ) |
| 260 | 259 | { |
| 261 | | scc8530_t *scc = machine().device<scc8530_t>("scc"); |
| 262 | 260 | offset %= 4; |
| 263 | 261 | switch(offset) |
| 264 | 262 | { |
| 265 | 263 | case 0: |
| 266 | | return scc->reg_r(space, 0); |
| 264 | return m_scc->reg_r(space, 0); |
| 267 | 265 | case 1: |
| 268 | 266 | return x68k_read_mouse(); |
| 269 | 267 | case 2: |
| 270 | | return scc->reg_r(space, 1); |
| 268 | return m_scc->reg_r(space, 1); |
| 271 | 269 | case 3: |
| 272 | | return scc->reg_r(space, 3); |
| 270 | return m_scc->reg_r(space, 3); |
| 273 | 271 | default: |
| 274 | 272 | return 0xff; |
| 275 | 273 | } |
| r29473 | r29474 | |
| 277 | 275 | |
| 278 | 276 | WRITE16_MEMBER(x68k_state::x68k_scc_w ) |
| 279 | 277 | { |
| 280 | | scc8530_t *scc = machine().device<scc8530_t>("scc"); |
| 281 | 278 | offset %= 4; |
| 282 | 279 | |
| 283 | 280 | switch(offset) |
| 284 | 281 | { |
| 285 | 282 | case 0: |
| 286 | | scc->reg_w(space, 0,(UINT8)data); |
| 287 | | if((scc->get_reg_b(5) & 0x02) != m_scc_prev) |
| 283 | m_scc->reg_w(space, 0,(UINT8)data); |
| 284 | if((m_scc->get_reg_b(5) & 0x02) != m_scc_prev) |
| 288 | 285 | { |
| 289 | | if(scc->get_reg_b(5) & 0x02) // Request to Send |
| 286 | if(m_scc->get_reg_b(5) & 0x02) // Request to Send |
| 290 | 287 | { |
| 291 | | int val = scc->get_reg_b(0); |
| 288 | int val = m_scc->get_reg_b(0); |
| 292 | 289 | m_mouse.bufferempty = 0; |
| 293 | 290 | val |= 0x01; |
| 294 | | scc->set_reg_b(0,val); |
| 291 | m_scc->set_reg_b(0,val); |
| 295 | 292 | } |
| 296 | 293 | } |
| 297 | 294 | break; |
| 298 | 295 | case 1: |
| 299 | | scc->reg_w(space, 2,(UINT8)data); |
| 296 | m_scc->reg_w(space, 2,(UINT8)data); |
| 300 | 297 | break; |
| 301 | 298 | case 2: |
| 302 | | scc->reg_w(space, 1,(UINT8)data); |
| 299 | m_scc->reg_w(space, 1,(UINT8)data); |
| 303 | 300 | break; |
| 304 | 301 | case 3: |
| 305 | | scc->reg_w(space, 3,(UINT8)data); |
| 302 | m_scc->reg_w(space, 3,(UINT8)data); |
| 306 | 303 | break; |
| 307 | 304 | } |
| 308 | | m_scc_prev = scc->get_reg_b(5) & 0x02; |
| 305 | m_scc_prev = m_scc->get_reg_b(5) & 0x02; |
| 309 | 306 | } |
| 310 | 307 | |
| 311 | 308 | TIMER_CALLBACK_MEMBER(x68k_state::x68k_scc_ack) |
| 312 | 309 | { |
| 313 | | scc8530_t *scc = machine().device<scc8530_t>("scc"); |
| 314 | 310 | if(m_mouse.bufferempty != 0) // nothing to do if the mouse data buffer is empty |
| 315 | 311 | return; |
| 316 | 312 | |
| r29473 | r29474 | |
| 318 | 314 | // return; |
| 319 | 315 | |
| 320 | 316 | // hard-code the IRQ vector for now, until the SCC code is more complete |
| 321 | | if((scc->get_reg_a(9) & 0x08) || (scc->get_reg_b(9) & 0x08)) // SCC reg WR9 is the same for both channels |
| 317 | if((m_scc->get_reg_a(9) & 0x08) || (m_scc->get_reg_b(9) & 0x08)) // SCC reg WR9 is the same for both channels |
| 322 | 318 | { |
| 323 | | if((scc->get_reg_b(1) & 0x18) != 0) // if bits 3 and 4 of WR1 are 0, then Rx IRQs are disabled on this channel |
| 319 | if((m_scc->get_reg_b(1) & 0x18) != 0) // if bits 3 and 4 of WR1 are 0, then Rx IRQs are disabled on this channel |
| 324 | 320 | { |
| 325 | | if(scc->get_reg_b(5) & 0x02) // RTS signal |
| 321 | if(m_scc->get_reg_b(5) & 0x02) // RTS signal |
| 326 | 322 | { |
| 327 | 323 | m_mouse.irqactive = 1; |
| 328 | 324 | m_current_vector[5] = 0x54; |
| r29473 | r29474 | |
| 354 | 350 | } |
| 355 | 351 | if(m_adpcm.clock != 0) |
| 356 | 352 | rate = rate/2; |
| 357 | | m_hd63450->set_timer(3,attotime::from_hz(rate)); |
| 353 | m_adpcm_timer->adjust(attotime::from_hz(rate), 0, attotime::from_hz(rate)); |
| 358 | 354 | } |
| 359 | 355 | |
| 360 | 356 | // Megadrive 3 button gamepad |
| r29473 | r29474 | |
| 367 | 363 | { |
| 368 | 364 | if(port == 1) |
| 369 | 365 | { |
| 370 | | UINT8 porta = ioport("md3b")->read() & 0xff; |
| 371 | | UINT8 portb = (ioport("md3b")->read() >> 8) & 0xff; |
| 366 | UINT8 porta = m_md3b->read() & 0xff; |
| 367 | UINT8 portb = (m_md3b->read() >> 8) & 0xff; |
| 372 | 368 | if(m_mdctrl.mux1 & 0x10) |
| 373 | 369 | { |
| 374 | 370 | return porta | 0x90; |
| r29473 | r29474 | |
| 380 | 376 | } |
| 381 | 377 | if(port == 2) |
| 382 | 378 | { |
| 383 | | UINT8 porta = (ioport("md3b")->read() >> 16) & 0xff; |
| 384 | | UINT8 portb = (ioport("md3b")->read() >> 24) & 0xff; |
| 379 | UINT8 porta = (m_md3b->read() >> 16) & 0xff; |
| 380 | UINT8 portb = (m_md3b->read() >> 24) & 0xff; |
| 385 | 381 | if(m_mdctrl.mux2 & 0x20) |
| 386 | 382 | { |
| 387 | 383 | return porta | 0x90; |
| r29473 | r29474 | |
| 415 | 411 | { |
| 416 | 412 | if(port == 1) |
| 417 | 413 | { |
| 418 | | UINT8 porta = ioport("md6b")->read() & 0xff; |
| 419 | | UINT8 portb = (ioport("md6b")->read() >> 8) & 0xff; |
| 420 | | UINT8 extra = ioport("md6b_extra")->read() & 0x0f; |
| 414 | UINT8 porta = m_md6b->read() & 0xff; |
| 415 | UINT8 portb = (m_md6b->read() >> 8) & 0xff; |
| 416 | UINT8 extra = m_md6b_extra->read() & 0x0f; |
| 421 | 417 | |
| 422 | 418 | switch(m_mdctrl.seq1) |
| 423 | 419 | { |
| r29473 | r29474 | |
| 453 | 449 | } |
| 454 | 450 | if(port == 2) |
| 455 | 451 | { |
| 456 | | UINT8 porta = (ioport("md6b")->read() >> 16) & 0xff; |
| 457 | | UINT8 portb = (ioport("md6b")->read() >> 24) & 0xff; |
| 458 | | UINT8 extra = (ioport("md6b_extra")->read() >> 4) & 0x0f; |
| 452 | UINT8 porta = (m_md6b->read() >> 16) & 0xff; |
| 453 | UINT8 portb = (m_md6b->read() >> 24) & 0xff; |
| 454 | UINT8 extra = (m_md6b_extra->read() >> 4) & 0x0f; |
| 459 | 455 | |
| 460 | 456 | switch(m_mdctrl.seq2) |
| 461 | 457 | { |
| r29473 | r29474 | |
| 503 | 499 | { |
| 504 | 500 | if(port == 1) |
| 505 | 501 | { |
| 506 | | UINT8 porta = ioport("xpd1lr")->read() & 0xff; |
| 507 | | UINT8 portb = (ioport("xpd1lr")->read() >> 8) & 0xff; |
| 502 | UINT8 porta = m_xpd1lr->read() & 0xff; |
| 503 | UINT8 portb = (m_xpd1lr->read() >> 8) & 0xff; |
| 508 | 504 | if(m_mdctrl.mux1 & 0x10) |
| 509 | 505 | { |
| 510 | 506 | return porta; |
| r29473 | r29474 | |
| 516 | 512 | } |
| 517 | 513 | if(port == 2) |
| 518 | 514 | { |
| 519 | | UINT8 porta = (ioport("xpd1lr")->read() >> 16) & 0xff; |
| 520 | | UINT8 portb = (ioport("xpd1lr")->read() >> 24) & 0xff; |
| 515 | UINT8 porta = (m_xpd1lr->read() >> 16) & 0xff; |
| 516 | UINT8 portb = (m_xpd1lr->read() >> 24) & 0xff; |
| 521 | 517 | if(m_mdctrl.mux2 & 0x20) |
| 522 | 518 | { |
| 523 | 519 | return porta; |
| r29473 | r29474 | |
| 533 | 529 | // Judging from the XM6 source code, PPI ports A and B are joystick inputs |
| 534 | 530 | READ8_MEMBER(x68k_state::ppi_port_a_r) |
| 535 | 531 | { |
| 536 | | int ctrl = ioport("ctrltype")->read() & 0x0f; |
| 532 | int ctrl = m_ctrltype->read() & 0x0f; |
| 537 | 533 | |
| 538 | 534 | switch(ctrl) |
| 539 | 535 | { |
| 540 | 536 | case 0x00: // standard MSX/FM-Towns joystick |
| 541 | 537 | if(m_joy.joy1_enable == 0) |
| 542 | | return ioport("joy1")->read(); |
| 538 | return m_joy1->read(); |
| 543 | 539 | else |
| 544 | 540 | return 0xff; |
| 545 | 541 | case 0x01: // 3-button Megadrive gamepad |
| r29473 | r29474 | |
| 555 | 551 | |
| 556 | 552 | READ8_MEMBER(x68k_state::ppi_port_b_r) |
| 557 | 553 | { |
| 558 | | int ctrl = ioport("ctrltype")->read() & 0xf0; |
| 554 | int ctrl = m_ctrltype->read() & 0xf0; |
| 559 | 555 | |
| 560 | 556 | switch(ctrl) |
| 561 | 557 | { |
| 562 | 558 | case 0x00: // standard MSX/FM-Towns joystick |
| 563 | 559 | if(m_joy.joy2_enable == 0) |
| 564 | | return ioport("joy2")->read(); |
| 560 | return m_joy2->read(); |
| 565 | 561 | else |
| 566 | 562 | return 0xff; |
| 567 | 563 | case 0x10: // 3-button Megadrive gamepad |
| r29473 | r29474 | |
| 736 | 732 | return m_fdc.fdc->dma_w(data); |
| 737 | 733 | } |
| 738 | 734 | |
| 739 | | WRITE_LINE_MEMBER( x68k_state::fdc_drq ) |
| 740 | | { |
| 741 | | bool ostate = m_fdc.drq_state; |
| 742 | | m_fdc.drq_state = state; |
| 743 | | if(state && !ostate) |
| 744 | | { |
| 745 | | m_hd63450->single_transfer(0); |
| 746 | | } |
| 747 | | } |
| 748 | | |
| 749 | 735 | WRITE16_MEMBER(x68k_state::x68k_fm_w) |
| 750 | 736 | { |
| 751 | 737 | switch(offset) |
| 752 | 738 | { |
| 753 | 739 | case 0x00: |
| 754 | 740 | case 0x01: |
| 755 | | machine().device<ym2151_device>("ym2151")->write(space, offset, data); |
| 741 | m_ym2151->write(space, offset, data); |
| 756 | 742 | break; |
| 757 | 743 | } |
| 758 | 744 | } |
| r29473 | r29474 | |
| 760 | 746 | READ16_MEMBER(x68k_state::x68k_fm_r) |
| 761 | 747 | { |
| 762 | 748 | if(offset == 0x01) |
| 763 | | return machine().device<ym2151_device>("ym2151")->read(space, 1); |
| 749 | return m_ym2151->read(space, 1); |
| 764 | 750 | |
| 765 | 751 | return 0xffff; |
| 766 | 752 | } |
| r29473 | r29474 | |
| 901 | 887 | |
| 902 | 888 | WRITE16_MEMBER(x68k_state::x68k_ppi_w) |
| 903 | 889 | { |
| 904 | | i8255_device *ppi = machine().device<i8255_device>("ppi8255"); |
| 905 | | ppi->write(space,offset & 0x03,data); |
| 890 | m_ppi->write(space,offset & 0x03,data); |
| 906 | 891 | } |
| 907 | 892 | |
| 908 | 893 | READ16_MEMBER(x68k_state::x68k_ppi_r) |
| 909 | 894 | { |
| 910 | | i8255_device *ppi = machine().device<i8255_device>("ppi8255"); |
| 911 | | return ppi->read(space,offset & 0x03); |
| 895 | return m_ppi->read(space,offset & 0x03); |
| 912 | 896 | } |
| 913 | 897 | |
| 914 | 898 | |
| r29473 | r29474 | |
| 1066 | 1050 | then access causes a bus error */ |
| 1067 | 1051 | m_current_vector[2] = 0x02; // bus error |
| 1068 | 1052 | m_current_irq_line = 2; |
| 1069 | | if((ioport("options")->read() & 0x02) && !space.debugger_access()) |
| 1053 | if((m_options->read() & 0x02) && !space.debugger_access()) |
| 1070 | 1054 | set_bus_error((offset << 1) + 0xbffffc, 0, mem_mask); |
| 1071 | 1055 | return 0xff; |
| 1072 | 1056 | } |
| r29473 | r29474 | |
| 1077 | 1061 | then access causes a bus error */ |
| 1078 | 1062 | m_current_vector[2] = 0x02; // bus error |
| 1079 | 1063 | m_current_irq_line = 2; |
| 1080 | | if((ioport("options")->read() & 0x02) && !space.debugger_access()) |
| 1064 | if((m_options->read() & 0x02) && !space.debugger_access()) |
| 1081 | 1065 | set_bus_error((offset << 1) + 0xbffffc, 1, mem_mask); |
| 1082 | 1066 | } |
| 1083 | 1067 | |
| r29473 | r29474 | |
| 1087 | 1071 | Often a method for detecting amount of installed RAM, is to read or write at 1MB intervals, until a bus error occurs */ |
| 1088 | 1072 | m_current_vector[2] = 0x02; // bus error |
| 1089 | 1073 | m_current_irq_line = 2; |
| 1090 | | if((ioport("options")->read() & 0x02) && !space.debugger_access()) |
| 1074 | if((m_options->read() & 0x02) && !space.debugger_access()) |
| 1091 | 1075 | set_bus_error((offset << 1), 0, mem_mask); |
| 1092 | 1076 | return 0xff; |
| 1093 | 1077 | } |
| r29473 | r29474 | |
| 1098 | 1082 | Often a method for detecting amount of installed RAM, is to read or write at 1MB intervals, until a bus error occurs */ |
| 1099 | 1083 | m_current_vector[2] = 0x02; // bus error |
| 1100 | 1084 | m_current_irq_line = 2; |
| 1101 | | if((ioport("options")->read() & 0x02) && !space.debugger_access()) |
| 1085 | if((m_options->read() & 0x02) && !space.debugger_access()) |
| 1102 | 1086 | set_bus_error((offset << 1), 1, mem_mask); |
| 1103 | 1087 | } |
| 1104 | 1088 | |
| r29473 | r29474 | |
| 1107 | 1091 | /* These are expansion devices, if not present, they cause a bus error */ |
| 1108 | 1092 | m_current_vector[2] = 0x02; // bus error |
| 1109 | 1093 | m_current_irq_line = 2; |
| 1110 | | if((ioport("options")->read() & 0x02) && !space.debugger_access()) |
| 1094 | if((m_options->read() & 0x02) && !space.debugger_access()) |
| 1111 | 1095 | set_bus_error((offset << 1) + 0xeafa00, 0, mem_mask); |
| 1112 | 1096 | return 0xff; |
| 1113 | 1097 | } |
| r29473 | r29474 | |
| 1117 | 1101 | /* These are expansion devices, if not present, they cause a bus error */ |
| 1118 | 1102 | m_current_vector[2] = 0x02; // bus error |
| 1119 | 1103 | m_current_irq_line = 2; |
| 1120 | | if((ioport("options")->read() & 0x02) && !space.debugger_access()) |
| 1104 | if((m_options->read() & 0x02) && !space.debugger_access()) |
| 1121 | 1105 | set_bus_error((offset << 1) + 0xeafa00, 1, mem_mask); |
| 1122 | 1106 | } |
| 1123 | 1107 | |
| r29473 | r29474 | |
| 1147 | 1131 | { |
| 1148 | 1132 | m_current_vector[3] = m_hd63450->get_error_vector(offset); |
| 1149 | 1133 | m_current_irq_line = 3; |
| 1134 | logerror("DMA#%i: DMA Error (vector 0x%02x)\n",offset,m_current_vector[3]); |
| 1150 | 1135 | m_maincpu->set_input_line_and_vector(3,ASSERT_LINE,m_current_vector[3]); |
| 1151 | 1136 | } |
| 1152 | 1137 | } |
| r29473 | r29474 | |
| 1793 | 1778 | m_led_timer = timer_alloc(TIMER_X68K_LED); |
| 1794 | 1779 | m_net_timer = timer_alloc(TIMER_X68K_NET_IRQ); |
| 1795 | 1780 | m_fdc_tc = timer_alloc(TIMER_X68K_FDC_TC); |
| 1781 | m_adpcm_timer = timer_alloc(TIMER_X68K_ADPCM); |
| 1796 | 1782 | |
| 1797 | 1783 | // Initialise timers for 6-button MD controllers |
| 1798 | 1784 | md_6button_init(); |
| r29473 | r29474 | |
| 1891 | 1877 | |
| 1892 | 1878 | MCFG_UPD72065_ADD("upd72065", true, true) |
| 1893 | 1879 | MCFG_UPD765_INTRQ_CALLBACK(WRITELINE(x68k_state, fdc_irq)) |
| 1894 | | MCFG_UPD765_DRQ_CALLBACK(WRITELINE(x68k_state, fdc_drq)) |
| 1880 | MCFG_UPD765_DRQ_CALLBACK(DEVWRITELINE("hd63450", hd63450_device, drq0_w)) |
| 1895 | 1881 | MCFG_FLOPPY_DRIVE_ADD("upd72065:0", x68k_floppies, "525hd", x68k_state::floppy_formats) |
| 1896 | 1882 | MCFG_FLOPPY_DRIVE_ADD("upd72065:1", x68k_floppies, "525hd", x68k_state::floppy_formats) |
| 1897 | 1883 | MCFG_FLOPPY_DRIVE_ADD("upd72065:2", x68k_floppies, "525hd", x68k_state::floppy_formats) |