trunk/src/emu/bus/ieee488/c2040.c
| r242243 | r242244 | |
| 626 | 626 | { |
| 627 | 627 | } |
| 628 | 628 | |
| 629 | | c2040_device::c2040_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 630 | | : device_t(mconfig, C2040, "C2040", tag, owner, clock, "c2040", __FILE__), |
| 631 | | device_ieee488_interface(mconfig, *this), |
| 632 | | m_maincpu(*this, M6502_TAG), |
| 633 | | m_fdccpu(*this, M6504_TAG), |
| 634 | | m_riot0(*this, M6532_0_TAG), |
| 635 | | m_riot1(*this, M6532_1_TAG), |
| 636 | | m_miot(*this, M6530_TAG), |
| 637 | | m_via(*this, M6522_TAG), |
| 638 | | m_floppy0(*this, FDC_TAG":0:525ssqd"), |
| 639 | | m_floppy1(*this, FDC_TAG":1:525ssqd"), |
| 640 | | m_fdc(*this, FDC_TAG), |
| 641 | | m_gcr(*this, "gcr"), |
| 642 | | m_address(*this, "ADDRESS"), |
| 643 | | m_rfdo(1), |
| 644 | | m_daco(1), |
| 645 | | m_atna(1), |
| 646 | | m_miot_irq(CLEAR_LINE) |
| 629 | c2040_device::c2040_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 630 | device_t(mconfig, C2040, "C2040", tag, owner, clock, "c2040", __FILE__), |
| 631 | device_ieee488_interface(mconfig, *this), |
| 632 | m_maincpu(*this, M6502_TAG), |
| 633 | m_fdccpu(*this, M6504_TAG), |
| 634 | m_riot0(*this, M6532_0_TAG), |
| 635 | m_riot1(*this, M6532_1_TAG), |
| 636 | m_miot(*this, M6530_TAG), |
| 637 | m_via(*this, M6522_TAG), |
| 638 | m_floppy0(*this, FDC_TAG":0:525ssqd"), |
| 639 | m_floppy1(*this, FDC_TAG":1:525ssqd"), |
| 640 | m_fdc(*this, FDC_TAG), |
| 641 | m_gcr(*this, "gcr"), |
| 642 | m_address(*this, "ADDRESS"), |
| 643 | m_rfdo(1), |
| 644 | m_daco(1), |
| 645 | m_atna(1), |
| 646 | m_miot_irq(CLEAR_LINE) |
| 647 | 647 | { |
| 648 | 648 | } |
| 649 | 649 | |
trunk/src/emu/bus/ieee488/c2040fdc.c
| r242243 | r242244 | |
| 119 | 119 | } |
| 120 | 120 | |
| 121 | 121 | c8050_fdc_t::c8050_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 122 | | c2040_fdc_t(mconfig, C2040_FDC, "C2040 FDC", tag, owner, clock, "c2040fdc", __FILE__) { } |
| 122 | c2040_fdc_t(mconfig, C8050_FDC, "C8050 FDC", tag, owner, clock, "c8050fdc", __FILE__) { } |
| 123 | 123 | |
| 124 | 124 | |
| 125 | 125 | |
| r242243 | r242244 | |
| 567 | 567 | } |
| 568 | 568 | } |
| 569 | 569 | |
| 570 | | WRITE_LINE_MEMBER( c2040_fdc_t::odd_hd_w ) |
| 571 | | { |
| 572 | | if (m_odd_hd != state) |
| 573 | | { |
| 574 | | live_sync(); |
| 575 | | m_odd_hd = cur_live.odd_hd = state; |
| 576 | | if (LOG) logerror("%s ODD HD %u\n", machine().time().as_string(), state); |
| 577 | | m_floppy0->ss_w(!state); |
| 578 | | if (m_floppy1) m_floppy1->ss_w(!state); |
| 579 | | checkpoint(); |
| 580 | | live_run(); |
| 581 | | } |
| 582 | | } |
| 583 | | |
| 584 | | WRITE_LINE_MEMBER( c2040_fdc_t::pull_sync_w ) |
| 585 | | { |
| 586 | | // TODO |
| 587 | | if (LOG) logerror("%s PULL SYNC %u\n", machine().time().as_string(), state); |
| 588 | | } |
| 589 | | |
| 590 | 570 | void c2040_fdc_t::stp_w(floppy_image_device *floppy, int mtr, int &old_stp, int stp) |
| 591 | 571 | { |
| 592 | 572 | if (mtr) return; |
| r242243 | r242244 | |
| 617 | 597 | old_stp = stp; |
| 618 | 598 | } |
| 619 | 599 | |
| 600 | void c2040_fdc_t::stp0_w(int stp) |
| 601 | { |
| 602 | if (m_stp0 != stp) |
| 603 | { |
| 604 | live_sync(); |
| 605 | this->stp_w(m_floppy0, m_mtr0, m_stp0, stp); |
| 606 | checkpoint(); |
| 607 | live_run(); |
| 608 | } |
| 609 | } |
| 610 | |
| 611 | void c2040_fdc_t::stp1_w(int stp) |
| 612 | { |
| 613 | if (m_stp1 != stp) |
| 614 | { |
| 615 | live_sync(); |
| 616 | if (m_floppy1) this->stp_w(m_floppy1, m_mtr1, m_stp1, stp); |
| 617 | checkpoint(); |
| 618 | live_run(); |
| 619 | } |
| 620 | } |
| 621 | |
| 622 | void c2040_fdc_t::ds_w(int ds) |
| 623 | { |
| 624 | if (m_ds != ds) |
| 625 | { |
| 626 | live_sync(); |
| 627 | m_ds = cur_live.ds = ds; |
| 628 | checkpoint(); |
| 629 | live_run(); |
| 630 | } |
| 631 | } |
| 632 | |
| 633 | void c2040_fdc_t::set_floppy(floppy_image_device *floppy0, floppy_image_device *floppy1) |
| 634 | { |
| 635 | m_floppy0 = floppy0; |
| 636 | m_floppy1 = floppy1; |
| 637 | } |
| 638 | |
| 639 | void c8050_fdc_t::live_start() |
| 640 | { |
| 641 | cur_live.tm = machine().time(); |
| 642 | cur_live.state = RUNNING; |
| 643 | cur_live.next_state = -1; |
| 644 | |
| 645 | cur_live.shift_reg = 0; |
| 646 | cur_live.shift_reg_write = 0; |
| 647 | cur_live.cycle_counter = 0; |
| 648 | cur_live.cell_counter = 0; |
| 649 | cur_live.bit_counter = 0; |
| 650 | cur_live.ds = m_ds; |
| 651 | cur_live.drv_sel = m_drv_sel; |
| 652 | cur_live.mode_sel = m_mode_sel; |
| 653 | cur_live.rw_sel = m_rw_sel; |
| 654 | cur_live.pi = m_pi; |
| 655 | |
| 656 | pll_reset(cur_live.tm, attotime::from_hz(0)); |
| 657 | checkpoint_live = cur_live; |
| 658 | pll_save_checkpoint(); |
| 659 | |
| 660 | live_run(); |
| 661 | } |
| 662 | |
| 663 | void c8050_fdc_t::pll_reset(const attotime &when, const attotime clock) |
| 664 | { |
| 665 | cur_pll.reset(when); |
| 666 | cur_pll.set_clock(clock); |
| 667 | } |
| 668 | |
| 669 | void c8050_fdc_t::pll_save_checkpoint() |
| 670 | { |
| 671 | checkpoint_pll = cur_pll; |
| 672 | } |
| 673 | |
| 674 | void c8050_fdc_t::pll_retrieve_checkpoint() |
| 675 | { |
| 676 | cur_pll = checkpoint_pll; |
| 677 | } |
| 678 | |
| 679 | void c8050_fdc_t::checkpoint() |
| 680 | { |
| 681 | checkpoint_live = cur_live; |
| 682 | pll_save_checkpoint(); |
| 683 | } |
| 684 | |
| 685 | void c8050_fdc_t::rollback() |
| 686 | { |
| 687 | cur_live = checkpoint_live; |
| 688 | pll_retrieve_checkpoint(); |
| 689 | } |
| 690 | |
| 691 | void c8050_fdc_t::live_run(const attotime &limit) |
| 692 | { |
| 693 | if(cur_live.state == IDLE || cur_live.next_state != -1) |
| 694 | return; |
| 695 | |
| 696 | for(;;) { |
| 697 | switch(cur_live.state) { |
| 698 | case RUNNING: { |
| 699 | bool syncpoint = false; |
| 700 | |
| 701 | if (cur_live.tm > limit) |
| 702 | return; |
| 703 | |
| 704 | int bit = get_next_bit(cur_live.tm, limit); |
| 705 | if(bit < 0) |
| 706 | return; |
| 707 | |
| 708 | if (syncpoint) { |
| 709 | commit(cur_live.tm); |
| 710 | |
| 711 | cur_live.tm += m_period; |
| 712 | live_delay(RUNNING_SYNCPOINT); |
| 713 | return; |
| 714 | } |
| 715 | |
| 716 | cur_live.tm += m_period; |
| 717 | break; |
| 718 | } |
| 719 | |
| 720 | case RUNNING_SYNCPOINT: { |
| 721 | m_write_ready(cur_live.ready); |
| 722 | m_write_sync(cur_live.sync); |
| 723 | m_write_error(cur_live.error); |
| 724 | |
| 725 | cur_live.state = RUNNING; |
| 726 | checkpoint(); |
| 727 | break; |
| 728 | } |
| 729 | } |
| 730 | } |
| 731 | } |
| 732 | |
| 733 | int c8050_fdc_t::get_next_bit(attotime &tm, const attotime &limit) |
| 734 | { |
| 735 | return cur_pll.get_next_bit(tm, get_floppy(), limit); |
| 736 | } |
| 737 | |
| 620 | 738 | void c8050_fdc_t::stp_w(floppy_image_device *floppy, int mtr, int &old_stp, int stp) |
| 621 | 739 | { |
| 622 | 740 | if (mtr) return; |
| r242243 | r242244 | |
| 647 | 765 | old_stp = stp; |
| 648 | 766 | } |
| 649 | 767 | |
| 650 | | void c2040_fdc_t::stp0_w(int stp) |
| 768 | WRITE_LINE_MEMBER( c8050_fdc_t::odd_hd_w ) |
| 651 | 769 | { |
| 652 | | if (m_stp0 != stp) |
| 770 | if (m_odd_hd != state) |
| 653 | 771 | { |
| 654 | 772 | live_sync(); |
| 655 | | this->stp_w(m_floppy0, m_mtr0, m_stp0, stp); |
| 773 | m_odd_hd = cur_live.odd_hd = state; |
| 774 | if (LOG) logerror("%s ODD HD %u\n", machine().time().as_string(), state); |
| 775 | m_floppy0->ss_w(!state); |
| 776 | if (m_floppy1) m_floppy1->ss_w(!state); |
| 656 | 777 | checkpoint(); |
| 657 | 778 | live_run(); |
| 658 | 779 | } |
| 659 | 780 | } |
| 660 | 781 | |
| 661 | | void c2040_fdc_t::stp1_w(int stp) |
| 782 | WRITE_LINE_MEMBER( c8050_fdc_t::pull_sync_w ) |
| 662 | 783 | { |
| 663 | | if (m_stp1 != stp) |
| 664 | | { |
| 665 | | live_sync(); |
| 666 | | if (m_floppy1) this->stp_w(m_floppy1, m_mtr1, m_stp1, stp); |
| 667 | | checkpoint(); |
| 668 | | live_run(); |
| 669 | | } |
| 784 | // TODO |
| 785 | if (LOG) logerror("%s PULL SYNC %u\n", machine().time().as_string(), state); |
| 670 | 786 | } |
| 671 | | |
| 672 | | void c2040_fdc_t::ds_w(int ds) |
| 673 | | { |
| 674 | | if (m_ds != ds) |
| 675 | | { |
| 676 | | live_sync(); |
| 677 | | m_ds = cur_live.ds = ds; |
| 678 | | checkpoint(); |
| 679 | | live_run(); |
| 680 | | } |
| 681 | | } |
| 682 | | |
| 683 | | void c2040_fdc_t::set_floppy(floppy_image_device *floppy0, floppy_image_device *floppy1) |
| 684 | | { |
| 685 | | m_floppy0 = floppy0; |
| 686 | | m_floppy1 = floppy1; |
| 687 | | } |
trunk/src/emu/bus/ieee488/c2040fdc.h
| r242243 | r242244 | |
| 15 | 15 | #define __C2040_FLOPPY__ |
| 16 | 16 | |
| 17 | 17 | #include "emu.h" |
| 18 | | #include "imagedev/floppy.h" |
| 19 | 18 | #include "formats/d64_dsk.h" |
| 20 | 19 | #include "formats/d67_dsk.h" |
| 21 | 20 | #include "formats/g64_dsk.h" |
| 21 | #include "formats/d80_dsk.h" |
| 22 | #include "formats/d82_dsk.h" |
| 23 | #include "imagedev/floppy.h" |
| 24 | #include "machine/fdc_pll.h" |
| 22 | 25 | |
| 23 | 26 | |
| 24 | 27 | |
| r242243 | r242244 | |
| 47 | 50 | { |
| 48 | 51 | public: |
| 49 | 52 | // construction/destruction |
| 53 | c2040_fdc_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); |
| 50 | 54 | c2040_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 51 | | c2040_fdc_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); |
| 52 | 55 | |
| 53 | 56 | template<class _Object> static devcb_base &set_sync_wr_callback(device_t &device, _Object object) { return downcast<c2040_fdc_t &>(device).m_write_sync.set_callback(object); } |
| 54 | 57 | template<class _Object> static devcb_base &set_ready_wr_callback(device_t &device, _Object object) { return downcast<c2040_fdc_t &>(device).m_write_ready.set_callback(object); } |
| r242243 | r242244 | |
| 62 | 65 | DECLARE_WRITE_LINE_MEMBER( rw_sel_w ); |
| 63 | 66 | DECLARE_WRITE_LINE_MEMBER( mtr0_w ); |
| 64 | 67 | DECLARE_WRITE_LINE_MEMBER( mtr1_w ); |
| 65 | | DECLARE_WRITE_LINE_MEMBER( odd_hd_w ); |
| 66 | | DECLARE_WRITE_LINE_MEMBER( pull_sync_w ); |
| 67 | 68 | |
| 68 | 69 | DECLARE_READ_LINE_MEMBER( wps_r ) { return checkpoint_live.drv_sel ? m_floppy1->wpt_r() : m_floppy0->wpt_r(); } |
| 69 | 70 | DECLARE_READ_LINE_MEMBER( sync_r ) { return checkpoint_live.sync; } |
| r242243 | r242244 | |
| 146 | 147 | emu_timer *t_gen; |
| 147 | 148 | |
| 148 | 149 | floppy_image_device* get_floppy(); |
| 149 | | void live_start(); |
| 150 | | void checkpoint(); |
| 151 | | void rollback(); |
| 150 | virtual void live_start(); |
| 151 | virtual void checkpoint(); |
| 152 | virtual void rollback(); |
| 152 | 153 | bool write_next_bit(bool bit, const attotime &limit); |
| 153 | 154 | void start_writing(const attotime &tm); |
| 154 | 155 | void commit(const attotime &tm); |
| r242243 | r242244 | |
| 156 | 157 | void live_delay(int state); |
| 157 | 158 | void live_sync(); |
| 158 | 159 | void live_abort(); |
| 159 | | void live_run(const attotime &limit = attotime::never); |
| 160 | virtual void live_run(const attotime &limit = attotime::never); |
| 160 | 161 | void get_next_edge(const attotime &when); |
| 161 | | int get_next_bit(attotime &tm, const attotime &limit); |
| 162 | virtual int get_next_bit(attotime &tm, const attotime &limit); |
| 162 | 163 | }; |
| 163 | 164 | |
| 164 | 165 | |
| r242243 | r242244 | |
| 170 | 171 | // construction/destruction |
| 171 | 172 | c8050_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 172 | 173 | |
| 174 | DECLARE_WRITE_LINE_MEMBER( odd_hd_w ); |
| 175 | DECLARE_WRITE_LINE_MEMBER( pull_sync_w ); |
| 176 | |
| 173 | 177 | protected: |
| 178 | fdc_pll_t cur_pll, checkpoint_pll; |
| 179 | |
| 174 | 180 | void stp_w(floppy_image_device *floppy, int mtr, int &old_stp, int stp); |
| 181 | |
| 182 | virtual void live_start(); |
| 183 | virtual void checkpoint(); |
| 184 | virtual void rollback(); |
| 185 | void pll_reset(const attotime &when, const attotime clock); |
| 186 | void pll_save_checkpoint(); |
| 187 | void pll_retrieve_checkpoint(); |
| 188 | virtual void live_run(const attotime &limit = attotime::never); |
| 189 | virtual int get_next_bit(attotime &tm, const attotime &limit); |
| 175 | 190 | }; |
| 176 | 191 | |
| 177 | 192 | |
| r242243 | r242244 | |
| 179 | 194 | // device type definition |
| 180 | 195 | extern const device_type C2040_FDC; |
| 181 | 196 | extern const device_type C8050_FDC; |
| 182 | | //extern const device_type C8250_FDC; |
| 183 | | //extern const device_type SFD1001_FDC; |
| 184 | 197 | |
| 185 | 198 | |
| 186 | 199 | |