trunk/src/mess/drivers/pc9801.c
| r19080 | r19081 | |
| 235 | 235 | #include "cpu/i386/i386.h" |
| 236 | 236 | #include "machine/i8255.h" |
| 237 | 237 | #include "machine/pit8253.h" |
| 238 | | #include "machine/8237dma.h" |
| 238 | #include "machine/am9517a.h" |
| 239 | 239 | #include "machine/pic8259.h" |
| 240 | 240 | #include "machine/upd765.h" |
| 241 | 241 | #include "machine/upd1990a.h" |
| r19080 | r19081 | |
| 256 | 256 | public: |
| 257 | 257 | pc9801_state(const machine_config &mconfig, device_type type, const char *tag) |
| 258 | 258 | : driver_device(mconfig, type, tag), |
| 259 | | m_maincpu(*this, "maincpu"), |
| 260 | | m_rtc(*this, UPD1990A_TAG), |
| 261 | | m_sio(*this, UPD8251_TAG), |
| 262 | | m_hgdc1(*this, "upd7220_chr"), |
| 263 | | m_hgdc2(*this, "upd7220_btm"), |
| 259 | m_maincpu(*this, "maincpu"), |
| 260 | m_dmac(*this, "i8237"), |
| 261 | m_rtc(*this, UPD1990A_TAG), |
| 262 | m_sio(*this, UPD8251_TAG), |
| 263 | m_hgdc1(*this, "upd7220_chr"), |
| 264 | m_hgdc2(*this, "upd7220_btm"), |
| 264 | 265 | m_video_ram_1(*this, "video_ram_1"), |
| 265 | 266 | m_video_ram_2(*this, "video_ram_2"){ } |
| 266 | 267 | |
| 267 | 268 | required_device<cpu_device> m_maincpu; |
| 269 | required_device<am9517a_device> m_dmac; |
| 268 | 270 | required_device<upd1990a_device> m_rtc; |
| 269 | 271 | required_device<i8251_device> m_sio; |
| 270 | 272 | required_device<upd7220_device> m_hgdc1; |
| r19080 | r19081 | |
| 278 | 280 | UINT8 *m_char_rom; |
| 279 | 281 | |
| 280 | 282 | UINT8 m_portb_tmp; |
| 281 | | int m_dma_channel; |
| 282 | | UINT8 m_dma_offset[2][4]; |
| 283 | | UINT8 m_at_pages[0x10]; |
| 283 | UINT8 m_dma_offset[4]; |
| 284 | int m_dack; |
| 284 | 285 | |
| 285 | 286 | UINT8 m_vrtc_irq_mask; |
| 286 | 287 | UINT8 m_video_ff[8]; |
| r19080 | r19081 | |
| 376 | 377 | DECLARE_READ8_MEMBER(pc9821_a0_r); |
| 377 | 378 | DECLARE_WRITE8_MEMBER(pc9821_a0_w); |
| 378 | 379 | DECLARE_READ8_MEMBER(ide_status_r); |
| 379 | | DECLARE_READ8_MEMBER(pc_dma_read_byte); |
| 380 | | DECLARE_WRITE8_MEMBER(pc_dma_write_byte); |
| 381 | 380 | DECLARE_READ8_MEMBER(pc9801rs_access_ctrl_r); |
| 382 | 381 | DECLARE_WRITE8_MEMBER(pc9801rs_access_ctrl_w); |
| 383 | 382 | |
| r19080 | r19081 | |
| 429 | 428 | DECLARE_INPUT_CHANGED_MEMBER(shift_stroke); |
| 430 | 429 | DECLARE_WRITE_LINE_MEMBER(pc9801_master_set_int_line); |
| 431 | 430 | DECLARE_READ8_MEMBER(get_slave_ack); |
| 432 | | DECLARE_WRITE_LINE_MEMBER(pc_dma_hrq_changed); |
| 433 | | DECLARE_WRITE_LINE_MEMBER(pc_dack0_w); |
| 434 | | DECLARE_WRITE_LINE_MEMBER(pc_dack1_w); |
| 435 | | DECLARE_WRITE_LINE_MEMBER(pc_dack2_w); |
| 436 | | DECLARE_WRITE_LINE_MEMBER(pc_dack3_w); |
| 437 | | DECLARE_READ8_MEMBER(test_r); |
| 438 | | DECLARE_WRITE8_MEMBER(test_w); |
| 431 | DECLARE_WRITE_LINE_MEMBER(pc9801_dma_hrq_changed); |
| 432 | DECLARE_WRITE_LINE_MEMBER(pc9801_tc_w); |
| 433 | DECLARE_READ8_MEMBER(pc9801_dma_read_byte); |
| 434 | DECLARE_WRITE8_MEMBER(pc9801_dma_write_byte); |
| 435 | DECLARE_WRITE_LINE_MEMBER(pc9801_dack0_w); |
| 436 | DECLARE_WRITE_LINE_MEMBER(pc9801_dack1_w); |
| 437 | DECLARE_WRITE_LINE_MEMBER(pc9801_dack2_w); |
| 438 | DECLARE_WRITE_LINE_MEMBER(pc9801_dack3_w); |
| 439 | DECLARE_READ8_MEMBER(fdc_r); |
| 440 | DECLARE_WRITE8_MEMBER(fdc_w); |
| 439 | 441 | DECLARE_READ8_MEMBER(ppi_sys_porta_r); |
| 440 | 442 | DECLARE_READ8_MEMBER(ppi_sys_portb_r); |
| 441 | 443 | DECLARE_READ8_MEMBER(ppi_prn_portb_r); |
| r19080 | r19081 | |
| 648 | 650 | } |
| 649 | 651 | else // odd |
| 650 | 652 | { |
| 651 | | return i8237_r(machine().device("dma8237"), space, (offset & 0x1e) >> 1); |
| 653 | return m_dmac->read(space, (offset & 0x1e) >> 1, 0xff); |
| 652 | 654 | } |
| 653 | 655 | |
| 654 | 656 | return 0xff; |
| r19080 | r19081 | |
| 665 | 667 | } |
| 666 | 668 | else // odd |
| 667 | 669 | { |
| 668 | | i8237_w(machine().device("dma8237"), space, (offset & 0x1e) >> 1, data); |
| 670 | m_dmac->write(space, (offset & 0x1e) >> 1, data, 0xff); |
| 669 | 671 | } |
| 670 | 672 | } |
| 671 | 673 | |
| r19080 | r19081 | |
| 708 | 710 | } |
| 709 | 711 | else // odd |
| 710 | 712 | { |
| 711 | | printf("Write to DMA bank register %d %02x\n",((offset >> 1)+1) & 3,data); |
| 712 | | m_dma_offset[0][((offset >> 1)+1) & 3] = data & 0x0f; |
| 713 | printf("Write to DMA bank register %d %02x\n",(offset >> 1) & 3,data); |
| 714 | m_dma_offset[(offset >> 1) & 3] = data & 0x0f; // TODO: old was +1? Why? |
| 713 | 715 | } |
| 714 | 716 | } |
| 715 | 717 | |
| r19080 | r19081 | |
| 2303 | 2305 | * |
| 2304 | 2306 | ****************************************/ |
| 2305 | 2307 | |
| 2306 | | WRITE_LINE_MEMBER(pc9801_state::pc_dma_hrq_changed) |
| 2308 | WRITE_LINE_MEMBER(pc9801_state::pc9801_dma_hrq_changed) |
| 2307 | 2309 | { |
| 2308 | | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); |
| 2310 | m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); |
| 2309 | 2311 | |
| 2310 | | /* Assert HLDA */ |
| 2311 | | i8237_hlda_w( machine().device("dma8237"), state ); |
| 2312 | m_dmac->hack_w(state); |
| 2313 | |
| 2314 | // printf("%02x HLDA\n",state); |
| 2312 | 2315 | } |
| 2313 | 2316 | |
| 2317 | WRITE_LINE_MEMBER(pc9801_state::pc9801_tc_w ) |
| 2318 | { |
| 2319 | /* floppy terminal count */ |
| 2320 | // m_fdc->tc_w(state); |
| 2314 | 2321 | |
| 2315 | | READ8_MEMBER(pc9801_state::pc_dma_read_byte) |
| 2322 | // printf("TC %02x\n",state); |
| 2323 | } |
| 2324 | |
| 2325 | READ8_MEMBER(pc9801_state::pc9801_dma_read_byte) |
| 2316 | 2326 | { |
| 2317 | | offs_t page_offset = (((offs_t) m_dma_offset[0][m_dma_channel]) << 16) |
| 2318 | | & 0xFF0000; |
| 2327 | address_space &program = m_maincpu->space(AS_PROGRAM); |
| 2328 | offs_t addr = (m_dma_offset[m_dack] << 16) | offset; |
| 2319 | 2329 | |
| 2320 | | return space.read_byte(page_offset + offset); |
| 2330 | // printf("%08x\n",addr); |
| 2331 | |
| 2332 | return program.read_byte(addr); |
| 2321 | 2333 | } |
| 2322 | 2334 | |
| 2323 | 2335 | |
| 2324 | | WRITE8_MEMBER(pc9801_state::pc_dma_write_byte) |
| 2336 | WRITE8_MEMBER(pc9801_state::pc9801_dma_write_byte) |
| 2325 | 2337 | { |
| 2326 | | offs_t page_offset = (((offs_t) m_dma_offset[0][m_dma_channel]) << 16) |
| 2327 | | & 0xFF0000; |
| 2338 | address_space &program = m_maincpu->space(AS_PROGRAM); |
| 2339 | offs_t addr = (m_dma_offset[m_dack] << 16) | offset; |
| 2328 | 2340 | |
| 2329 | | space.write_byte(page_offset + offset, data); |
| 2341 | // printf("%08x %02x\n",addr,data); |
| 2342 | |
| 2343 | program.write_byte(addr, data); |
| 2330 | 2344 | } |
| 2331 | 2345 | |
| 2332 | 2346 | static void set_dma_channel(running_machine &machine, int channel, int state) |
| 2333 | 2347 | { |
| 2334 | 2348 | pc9801_state *drvstate = machine.driver_data<pc9801_state>(); |
| 2335 | | if (!state) drvstate->m_dma_channel = channel; |
| 2349 | if (!state) drvstate->m_dack = channel; |
| 2336 | 2350 | } |
| 2337 | 2351 | |
| 2338 | | WRITE_LINE_MEMBER(pc9801_state::pc_dack0_w){ /*printf("%02x 0\n",state);*/ set_dma_channel(machine(), 0, state); } |
| 2339 | | WRITE_LINE_MEMBER(pc9801_state::pc_dack1_w){ /*printf("%02x 1\n",state);*/ set_dma_channel(machine(), 1, state); } |
| 2340 | | WRITE_LINE_MEMBER(pc9801_state::pc_dack2_w){ /*printf("%02x 2\n",state);*/ set_dma_channel(machine(), 2, state); } |
| 2341 | | WRITE_LINE_MEMBER(pc9801_state::pc_dack3_w){ /*printf("%02x 3\n",state);*/ set_dma_channel(machine(), 3, state); } |
| 2352 | WRITE_LINE_MEMBER(pc9801_state::pc9801_dack0_w){ /*printf("%02x 0\n",state);*/ set_dma_channel(machine(), 0, state); } |
| 2353 | WRITE_LINE_MEMBER(pc9801_state::pc9801_dack1_w){ /*printf("%02x 1\n",state);*/ set_dma_channel(machine(), 1, state); } |
| 2354 | WRITE_LINE_MEMBER(pc9801_state::pc9801_dack2_w){ /*printf("%02x 2\n",state);*/ set_dma_channel(machine(), 2, state); } |
| 2355 | WRITE_LINE_MEMBER(pc9801_state::pc9801_dack3_w){ /*printf("%02x 3\n",state);*/ set_dma_channel(machine(), 3, state); } |
| 2342 | 2356 | |
| 2343 | | READ8_MEMBER(pc9801_state::test_r) |
| 2357 | /* TODO: double check channel for this one */ |
| 2358 | READ8_MEMBER(pc9801_state::fdc_r) |
| 2344 | 2359 | { |
| 2345 | 2360 | printf("2dd DACK R\n"); |
| 2346 | 2361 | |
| 2347 | 2362 | return 0xff; |
| 2348 | 2363 | } |
| 2349 | 2364 | |
| 2350 | | WRITE8_MEMBER(pc9801_state::test_w) |
| 2365 | WRITE8_MEMBER(pc9801_state::fdc_w) |
| 2351 | 2366 | { |
| 2352 | 2367 | printf("2dd DACK W\n"); |
| 2353 | 2368 | } |
| 2354 | 2369 | |
| 2355 | | static I8237_INTERFACE( dma8237_config ) |
| 2370 | static I8237_INTERFACE( dmac_intf ) |
| 2356 | 2371 | { |
| 2357 | | DEVCB_DRIVER_LINE_MEMBER(pc9801_state, pc_dma_hrq_changed), |
| 2358 | | DEVCB_NULL, |
| 2359 | | DEVCB_DRIVER_MEMBER(pc9801_state, pc_dma_read_byte), |
| 2360 | | DEVCB_DRIVER_MEMBER(pc9801_state, pc_dma_write_byte), |
| 2361 | | { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DRIVER_MEMBER(pc9801_state,test_r) }, |
| 2362 | | { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DRIVER_MEMBER(pc9801_state,test_w) }, |
| 2363 | | { DEVCB_DRIVER_LINE_MEMBER(pc9801_state, pc_dack0_w), DEVCB_DRIVER_LINE_MEMBER(pc9801_state, pc_dack1_w), DEVCB_DRIVER_LINE_MEMBER(pc9801_state, pc_dack2_w), DEVCB_DRIVER_LINE_MEMBER(pc9801_state, pc_dack3_w) } |
| 2372 | DEVCB_DRIVER_LINE_MEMBER(pc9801_state, pc9801_dma_hrq_changed), |
| 2373 | DEVCB_DRIVER_LINE_MEMBER(pc9801_state, pc9801_tc_w), |
| 2374 | DEVCB_DRIVER_MEMBER(pc9801_state, pc9801_dma_read_byte), |
| 2375 | DEVCB_DRIVER_MEMBER(pc9801_state, pc9801_dma_write_byte), |
| 2376 | { DEVCB_NULL, DEVCB_DRIVER_MEMBER(pc9801_state,fdc_r), DEVCB_NULL, DEVCB_NULL }, |
| 2377 | { DEVCB_NULL, DEVCB_DRIVER_MEMBER(pc9801_state,fdc_w), DEVCB_NULL, DEVCB_NULL }, |
| 2378 | { DEVCB_DRIVER_LINE_MEMBER(pc9801_state, pc9801_dack0_w), DEVCB_DRIVER_LINE_MEMBER(pc9801_state, pc9801_dack1_w), DEVCB_DRIVER_LINE_MEMBER(pc9801_state, pc9801_dack2_w), DEVCB_DRIVER_LINE_MEMBER(pc9801_state, pc9801_dack3_w) } |
| 2364 | 2379 | }; |
| 2365 | 2380 | |
| 2366 | 2381 | /**************************************** |
| r19080 | r19081 | |
| 2654 | 2669 | MCFG_MACHINE_RESET_OVERRIDE(pc9801_state,pc9801f) |
| 2655 | 2670 | |
| 2656 | 2671 | MCFG_PIT8253_ADD( "pit8253", pit8253_config ) |
| 2657 | | MCFG_I8237_ADD( "dma8237", 5000000, dma8237_config ) //unknown clock |
| 2672 | MCFG_I8237_ADD("i8237", 5000000, dmac_intf) // unknown clock |
| 2658 | 2673 | MCFG_PIC8259_ADD( "pic8259_master", pic8259_master_config ) |
| 2659 | 2674 | MCFG_PIC8259_ADD( "pic8259_slave", pic8259_slave_config ) |
| 2660 | 2675 | MCFG_I8255_ADD( "ppi8255_sys", ppi_system_intf ) |
| r19080 | r19081 | |
| 2721 | 2736 | MCFG_MACHINE_RESET_OVERRIDE(pc9801_state,pc9801rs) |
| 2722 | 2737 | |
| 2723 | 2738 | MCFG_PIT8253_ADD( "pit8253", pc9801rs_pit8253_config ) |
| 2724 | | MCFG_I8237_ADD( "dma8237", 16000000, dma8237_config ) //unknown clock |
| 2739 | MCFG_I8237_ADD("i8237", 16000000, dmac_intf) // unknown clock |
| 2725 | 2740 | MCFG_PIC8259_ADD( "pic8259_master", pic8259_master_config ) |
| 2726 | 2741 | MCFG_PIC8259_ADD( "pic8259_slave", pic8259_slave_config ) |
| 2727 | 2742 | MCFG_I8255_ADD( "ppi8255_sys", ppi_system_intf ) |
| r19080 | r19081 | |
| 2782 | 2797 | MCFG_MACHINE_RESET_OVERRIDE(pc9801_state,pc9801rs) |
| 2783 | 2798 | |
| 2784 | 2799 | MCFG_PIT8253_ADD( "pit8253", pc9801rs_pit8253_config ) |
| 2785 | | MCFG_I8237_ADD( "dma8237", 16000000, dma8237_config ) //unknown clock |
| 2800 | MCFG_I8237_ADD("i8237", 16000000, dmac_intf) // unknown clock |
| 2786 | 2801 | MCFG_PIC8259_ADD( "pic8259_master", pic8259_master_config ) |
| 2787 | 2802 | MCFG_PIC8259_ADD( "pic8259_slave", pic8259_slave_config ) |
| 2788 | 2803 | MCFG_I8255_ADD( "ppi8255_sys", ppi_system_intf ) |