Previous 199869 Revisions Next

r19186 Wednesday 28th November, 2012 at 13:22:44 UTC by O. Galibert
wd_fdc: Change the feature functions into bools, and use the correct pll for each chip [O. Galibert]
[src/emu/machine]wd_fdc.c wd_fdc.h

trunk/src/emu/machine/wd_fdc.c
r19185r19186
3636#include "debugger.h"
3737
3838const device_type FD1771x = &device_creator<fd1771_t>;
39const device_type FD1781x = &device_creator<fd1781_t>;
40const device_type FD1791x = &device_creator<fd1791_t>;
41const device_type FD1792x = &device_creator<fd1792_t>;
3942const device_type FD1793x = &device_creator<fd1793_t>;
43const device_type FD1794x = &device_creator<fd1794_t>;
44const device_type FD1795x = &device_creator<fd1795_t>;
4045const device_type FD1797x = &device_creator<fd1797_t>;
46const device_type MB8866x = &device_creator<mb8866_t>;
47const device_type MB8876x = &device_creator<mb8876_t>;
48const device_type MB8877x = &device_creator<mb8877_t>;
49const device_type FD1761x = &device_creator<fd1761_t>;
50const device_type FD1763x = &device_creator<fd1763_t>;
51const device_type FD1765x = &device_creator<fd1765_t>;
52const device_type FD1767x = &device_creator<fd1767_t>;
53const device_type WD2791x = &device_creator<wd2791_t>;
4154const device_type WD2793x = &device_creator<wd2793_t>;
55const device_type WD2795x = &device_creator<wd2795_t>;
4256const device_type WD2797x = &device_creator<wd2797_t>;
4357const device_type WD1770x = &device_creator<wd1770_t>;
4458const device_type WD1772x = &device_creator<wd1772_t>;
r19185r19186
106120   floppy = _floppy;
107121
108122   if(floppy) {
109      if(has_motor())
123      if(motor_control)
110124         floppy->mon_w(status & S_MON ? 0 : 1);
111125      floppy->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(FUNC(wd_fdc_t::index_callback), this));
112126   }
r19185r19186
178192{
179193   main_state = state;
180194   status = (status & ~(S_CRC|S_RNF|S_SPIN)) | S_BUSY;
181   if(has_head_load()) {
195   if(head_control) {
182196      // TODO get value from HLT callback
183      if (command & 8)
197      if(command & 8)
184198         status |= S_HLD;
185199      else
186200         status &= ~S_HLD;
187201   }
188   sub_state = has_motor() && !has_head_load() ? SPINUP : SPINUP_DONE;
202   sub_state = motor_control ? SPINUP : SPINUP_DONE;
189203   status_type_1 = true;
190204   seek_continue();
191205}
r19185r19186
259273
260274            if(command & 0x04) {
261275               sub_state = SEEK_WAIT_STABILIZATION_TIME;
262               delay_cycles(t_gen, 120000);
276               delay_cycles(t_gen, 30000);
263277               return;
264278            } else
265279               sub_state = SEEK_DONE;
r19185r19186
279293
280294      case SEEK_DONE:
281295         if(command & 0x04) {
282            if(has_ready() && !is_ready()) {
296            if(!is_ready()) {
283297               status |= S_RNF;
284298               command_end();
285299               return;
r19185r19186
321335{
322336   if(cur_live.idbuf[0] != track || cur_live.idbuf[2] != sector)
323337      return false;
324   if(!has_side_check() || (command & 2))
338   if(!side_compare || (command & 2))
325339      return true;
326340   if(command & 8)
327341      return cur_live.idbuf[1] & 1;
r19185r19186
331345
332346bool wd_fdc_t::is_ready()
333347{
334   return (floppy && !floppy->ready_r());
348   return !ready_hooked || (floppy && !floppy->ready_r());
335349}
336350
337351void wd_fdc_t::read_sector_start()
338352{
339   if(has_ready() && !is_ready())
353   if(!is_ready())
340354      command_end();
341355
342356   main_state = READ_SECTOR;
343357   status = (status & ~(S_CRC|S_LOST|S_RNF|S_WP|S_DDM)) | S_BUSY;
344358   drop_drq();
345   if (has_side_select() && floppy)
346      floppy->ss_w(BIT(command, 1));
347   sub_state = has_motor() && !has_head_load() ? SPINUP : SPINUP_DONE;
359   if(side_control && floppy)
360      floppy->ss_w(command & 0x02);
361   sub_state = motor_control ? SPINUP : SPINUP_DONE;
348362   status_type_1 = false;
349363   read_sector_continue();
350364}
r19185r19186
426440
427441void wd_fdc_t::read_track_start()
428442{
429   if(has_ready() && !is_ready())
443   if(!is_ready())
430444      command_end();
431   
445
432446   main_state = READ_TRACK;
433447   status = (status & ~(S_LOST|S_RNF)) | S_BUSY;
434448   drop_drq();
435   if (has_side_select() && floppy)
436      floppy->ss_w(BIT(command, 1));
437   sub_state = has_motor() && !has_head_load()  ? SPINUP : SPINUP_DONE;
449   if(side_control && floppy)
450      floppy->ss_w(command & 0x02);
451   sub_state = motor_control ? SPINUP : SPINUP_DONE;
438452   status_type_1 = false;
439453   read_track_continue();
440454}
r19185r19186
493507
494508void wd_fdc_t::read_id_start()
495509{
496   if(has_ready() && !is_ready())
510   if(!is_ready())
497511      command_end();
498   
512
499513   main_state = READ_ID;
500514   status = (status & ~(S_WP|S_DDM|S_LOST|S_RNF)) | S_BUSY;
501515   drop_drq();
502   if (has_side_select() && floppy)
503      floppy->ss_w(BIT(command, 1));
504   sub_state = has_motor() && !has_head_load()  ? SPINUP : SPINUP_DONE;
516   if(side_control && floppy)
517      floppy->ss_w(command & 0x02);
518   sub_state = motor_control ? SPINUP : SPINUP_DONE;
505519   status_type_1 = false;
506520   read_id_continue();
507521}
r19185r19186
558572
559573void wd_fdc_t::write_track_start()
560574{
561   if(has_ready() && !is_ready())
575   if(!is_ready())
562576      command_end();
563   
577
564578   main_state = WRITE_TRACK;
565579   status = (status & ~(S_WP|S_DDM|S_LOST|S_RNF)) | S_BUSY;
566580   drop_drq();
567   if (has_side_select() && floppy)
568      floppy->ss_w(BIT(command, 1));
569   sub_state = has_motor()  && !has_head_load() ? SPINUP : SPINUP_DONE;
581   if(side_control && floppy)
582      floppy->ss_w(command & 0x02);
583   sub_state = motor_control ? SPINUP : SPINUP_DONE;
570584   status_type_1 = false;
571585   write_track_continue();
572586}
r19185r19186
602616      case SETTLE_DONE:
603617         set_drq();
604618         sub_state = DATA_LOAD_WAIT;
605         delay_cycles(t_gen, 768);
619         delay_cycles(t_gen, 192);
606620         return;
607621
608622      case DATA_LOAD_WAIT:
r19185r19186
623637      case WAIT_INDEX_DONE:
624638         sub_state = TRACK_DONE;
625639         live_start(WRITE_TRACK_DATA);
626         cur_live.pll.start_writing(machine().time());
640         pll_start_writing(machine().time());
627641         return;
628642
629643      case TRACK_DONE:
r19185r19186
640654
641655void wd_fdc_t::write_sector_start()
642656{
643   if(has_ready() && !is_ready())
657   if(!is_ready())
644658      command_end();
645   
659
646660   main_state = WRITE_SECTOR;
647661   status = (status & ~(S_CRC|S_LOST|S_RNF|S_WP|S_DDM)) | S_BUSY;
648662   drop_drq();
649   if (has_side_select() && floppy)
650      floppy->ss_w(BIT(command, 1));
651   sub_state = has_motor() && !has_head_load()  ? SPINUP : SPINUP_DONE;
663   if(side_control && floppy)
664      floppy->ss_w(command & 0x02);
665   sub_state = motor_control  ? SPINUP : SPINUP_DONE;
652666   status_type_1 = false;
653667   write_sector_continue();
654668}
r19185r19186
734748      drop_drq();
735749      motor_timeout = 0;
736750   }
737   
751
738752   if(!(command & 0x0f)) {
739753      intrq_cond = 0;
740754   } else {
r19185r19186
848862void wd_fdc_t::cmd_w(UINT8 val)
849863{
850864   logerror("wd1772 cmd: %02x\n", val);
851   
865
852866   if(intrq && !(intrq_cond & I_IMM)) {
853867      intrq = false;
854868      if(!intrq_cb.isnull())
r19185r19186
861875
862876   cmd_buffer = val;
863877
864   delay_cycles(t_cmd, dden ? 384 : 184);
878   delay_cycles(t_cmd, dden ? 192 : 46);
865879}
866880
867881UINT8 wd_fdc_t::status_r()
r19185r19186
894908      }
895909   }
896910
897   if(has_ready()) {
911   if(ready_hooked) {
898912      if(!is_ready())
899913         status |= S_NRDY;
900914      else
r19185r19186
917931      return;
918932
919933   track_buffer = val;
920   delay_cycles(t_track, dden ? 256 : 128);
934   delay_cycles(t_track, dden ? 64 : 32);
921935}
922936
923937UINT8 wd_fdc_t::track_r()
r19185r19186
938952      return;
939953
940954   sector_buffer = val;
941   delay_cycles(t_sector, dden ? 256 : 128);
955   delay_cycles(t_sector, dden ? 64 : 32);
942956}
943957
944958UINT8 wd_fdc_t::sector_r()
r19185r19186
981995
982996void wd_fdc_t::delay_cycles(emu_timer *tm, int cycles)
983997{
984   tm->adjust(clocks_to_attotime(cycles));
998   tm->adjust(clocks_to_attotime(cycles*clock_ratio));
985999}
9861000
9871001void wd_fdc_t::spinup()
r19185r19186
10161030
10171031   switch(sub_state) {
10181032   case IDLE:
1019      if(has_motor()) {
1033      if(motor_control) {
10201034         motor_timeout ++;
10211035         if(motor_timeout >= 5) {
10221036            status &= ~S_MON;
r19185r19186
11171131   cur_live.previous_type = live_info::PT_NONE;
11181132   cur_live.data_bit_context = false;
11191133   cur_live.byte_counter = 0;
1120   cur_live.pll.reset(cur_live.tm);
1121   cur_live.pll.set_clock(clocks_to_attotime(1));
1134   pll_reset(cur_live.tm);
11221135   checkpoint_live = cur_live;
1136   pll_save_checkpoint();
11231137
11241138   live_run();
11251139}
11261140
11271141void wd_fdc_t::checkpoint()
11281142{
1129   cur_live.pll.commit(floppy, cur_live.tm);
1143   pll_commit(floppy, cur_live.tm);
11301144   checkpoint_live = cur_live;
1145   pll_save_checkpoint();
11311146}
11321147
11331148void wd_fdc_t::rollback()
11341149{
11351150   cur_live = checkpoint_live;
1151   pll_retrieve_checkpoint();
11361152}
11371153
11381154void wd_fdc_t::live_delay(int state)
r19185r19186
11481164         //          fprintf(stderr, "%s: Rolling back and replaying (%s)\n", ttsn().cstr(), tts(cur_live.tm).cstr());
11491165         rollback();
11501166         live_run(machine().time());
1151         cur_live.pll.commit(floppy, cur_live.tm);
1167         pll_commit(floppy, cur_live.tm);
11521168      } else {
11531169         //          fprintf(stderr, "%s: Committing (%s)\n", ttsn().cstr(), tts(cur_live.tm).cstr());
1154         cur_live.pll.commit(floppy, cur_live.tm);
1170         pll_commit(floppy, cur_live.tm);
11551171         if(cur_live.next_state != -1) {
11561172            cur_live.state = cur_live.next_state;
11571173            cur_live.next_state = -1;
11581174         }
11591175         if(cur_live.state == IDLE) {
1160            cur_live.pll.stop_writing(floppy, cur_live.tm);
1176            pll_stop_writing(floppy, cur_live.tm);
11611177            cur_live.tm = attotime::never;
11621178         }
11631179      }
r19185r19186
11731189      live_run(machine().time());
11741190   }
11751191
1176   cur_live.pll.stop_writing(floppy, cur_live.tm);
1192   pll_stop_writing(floppy, cur_live.tm);
11771193   cur_live.tm = attotime::never;
11781194   cur_live.state = IDLE;
11791195   cur_live.next_state = -1;
r19185r19186
11811197
11821198bool wd_fdc_t::read_one_bit(attotime limit)
11831199{
1184   int bit = cur_live.pll.get_next_bit(cur_live.tm, floppy, limit);
1200   int bit = pll_get_next_bit(cur_live.tm, floppy, limit);
11851201   if(bit < 0)
11861202      return true;
11871203   cur_live.shift_reg = (cur_live.shift_reg << 1) | bit;
r19185r19186
12001216bool wd_fdc_t::write_one_bit(attotime limit)
12011217{
12021218   bool bit = cur_live.shift_reg & 0x8000;
1203   if(cur_live.pll.write_next_bit(bit, cur_live.tm, floppy, limit))
1219   if(pll_write_next_bit(bit, cur_live.tm, floppy, limit))
12041220      return true;
12051221   if(cur_live.bit_counter & 1) {
12061222      if((cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000)
r19185r19186
15901606               // Is that correct?  It seems required (try ST formatting)
15911607               live_write_mfm(0xff);
15921608            else {
1593               cur_live.pll.stop_writing(floppy, cur_live.tm);
1609               pll_stop_writing(floppy, cur_live.tm);
15941610               cur_live.state = IDLE;
15951611               return;
15961612            }
r19185r19186
16341650            cur_live.bit_counter = 16;
16351651            cur_live.byte_counter = 0;
16361652            cur_live.data_bit_context = cur_live.data_reg & 1;
1637            cur_live.pll.start_writing(cur_live.tm);
1653            pll_start_writing(cur_live.tm);
16381654            live_write_mfm(0x00);
16391655            break;
16401656         }
r19185r19186
16671683   }
16681684}
16691685
1670void wd_fdc_t::pll_t::set_clock(attotime period)
1686int wd_fdc_t::step_time(int mode) const
16711687{
1688   const static int step_times[4] = { 12000, 24000, 40000, 60000 };
1689   return step_times[mode];
1690}
1691
1692int wd_fdc_t::settle_time() const
1693{
1694   return 60000;
1695}
1696
1697wd_fdc_analog_t::wd_fdc_analog_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) :
1698   wd_fdc_t(mconfig, type, name, tag, owner, clock)
1699{
1700   clock_ratio = 1;
1701}
1702
1703void wd_fdc_analog_t::pll_reset(attotime when)
1704{
1705   cur_pll.reset(when);
1706   cur_pll.set_clock(clocks_to_attotime(4));
1707}
1708
1709void wd_fdc_analog_t::pll_start_writing(attotime tm)
1710{
1711   cur_pll.start_writing(tm);
1712}
1713
1714void wd_fdc_analog_t::pll_commit(floppy_image_device *floppy, attotime tm)
1715{
1716   cur_pll.commit(floppy, tm);
1717}
1718
1719void wd_fdc_analog_t::pll_stop_writing(floppy_image_device *floppy, attotime tm)
1720{
1721   cur_pll.stop_writing(floppy, tm);
1722}
1723
1724void wd_fdc_analog_t::pll_save_checkpoint()
1725{
1726   checkpoint_pll = cur_pll;
1727}
1728
1729void wd_fdc_analog_t::pll_retrieve_checkpoint()
1730{
1731   cur_pll = checkpoint_pll;
1732}
1733
1734int wd_fdc_analog_t::pll_get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit)
1735{
1736   return cur_pll.get_next_bit(tm, floppy, limit);
1737}
1738
1739bool wd_fdc_analog_t::pll_write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit)
1740{
1741   return cur_pll.write_next_bit(bit, tm, floppy, limit);
1742}
1743
1744wd_fdc_digital_t::wd_fdc_digital_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) :
1745   wd_fdc_t(mconfig, type, name, tag, owner, clock)
1746{
1747   clock_ratio = 4;
1748}
1749
1750void wd_fdc_digital_t::pll_reset(attotime when)
1751{
1752   cur_pll.reset(when);
1753   cur_pll.set_clock(clocks_to_attotime(1));
1754}
1755
1756void wd_fdc_digital_t::pll_start_writing(attotime tm)
1757{
1758   cur_pll.start_writing(tm);
1759}
1760
1761void wd_fdc_digital_t::pll_commit(floppy_image_device *floppy, attotime tm)
1762{
1763   cur_pll.commit(floppy, tm);
1764}
1765
1766void wd_fdc_digital_t::pll_stop_writing(floppy_image_device *floppy, attotime tm)
1767{
1768   cur_pll.stop_writing(floppy, tm);
1769}
1770
1771int wd_fdc_digital_t::pll_get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit)
1772{
1773   return cur_pll.get_next_bit(tm, floppy, limit);
1774}
1775
1776bool wd_fdc_digital_t::pll_write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit)
1777{
1778   return cur_pll.write_next_bit(bit, tm, floppy, limit);
1779}
1780
1781void wd_fdc_digital_t::pll_save_checkpoint()
1782{
1783   checkpoint_pll = cur_pll;
1784}
1785
1786void wd_fdc_digital_t::pll_retrieve_checkpoint()
1787{
1788   cur_pll = checkpoint_pll;
1789}
1790
1791void wd_fdc_digital_t::digital_pll_t::set_clock(attotime period)
1792{
16721793   for(int i=0; i<42; i++)
16731794      delays[i] = period*(i+1);
16741795}
16751796
1676void wd_fdc_t::pll_t::reset(attotime when)
1797void wd_fdc_digital_t::digital_pll_t::reset(attotime when)
16771798{
16781799   counter = 0;
16791800   increment = 128;
r19185r19186
16891810   write_start_time = attotime::never;
16901811}
16911812
1692int wd_fdc_t::pll_t::get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit)
1813int wd_fdc_digital_t::digital_pll_t::get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit)
16931814{
16941815   attotime when = floppy ? floppy->get_next_transition(ctime) : attotime::never;
16951816#if 0
r19185r19186
17691890   return bit;
17701891}
17711892
1772void wd_fdc_t::pll_t::start_writing(attotime tm)
1893void wd_fdc_digital_t::digital_pll_t::start_writing(attotime tm)
17731894{
17741895   write_start_time = tm;
17751896   write_position = 0;
17761897}
17771898
1778void wd_fdc_t::pll_t::stop_writing(floppy_image_device *floppy, attotime tm)
1899void wd_fdc_digital_t::digital_pll_t::stop_writing(floppy_image_device *floppy, attotime tm)
17791900{
17801901   commit(floppy, tm);
17811902   write_start_time = attotime::never;
17821903}
17831904
1784bool wd_fdc_t::pll_t::write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit)
1905bool wd_fdc_digital_t::digital_pll_t::write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit)
17851906{
17861907   if(write_start_time.is_never()) {
17871908      write_start_time = ctime;
r19185r19186
18111932   return false;
18121933}
18131934
1814void wd_fdc_t::pll_t::commit(floppy_image_device *floppy, attotime tm)
1935void wd_fdc_digital_t::digital_pll_t::commit(floppy_image_device *floppy, attotime tm)
18151936{
18161937   if(write_start_time.is_never() || tm == write_start_time)
18171938      return;
r19185r19186
18221943   write_position = 0;
18231944}
18241945
1825int wd_fdc_t::step_time(int mode) const
1946fd1771_t::fd1771_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1771x, "FD1771", tag, owner, clock)
18261947{
1827   const static int step_times[4] = { 48000, 96000, 160000, 240000 };
1828   return step_times[mode];
1948   inverted_bus = true;
1949   side_control = false;
1950   side_compare = false;
1951   head_control = true;
1952   motor_control = false;
1953   ready_hooked = true;
18291954}
18301955
1831int wd_fdc_t::settle_time() const
1956fd1781_t::fd1781_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1781x, "FD1781", tag, owner, clock)
18321957{
1833   return 240000;
1958   inverted_bus = true;
1959   side_control = false;
1960   side_compare = false;
1961   head_control = true;
1962   motor_control = false;
1963   ready_hooked = true;
18341964}
18351965
1836bool wd_fdc_t::has_ready() const
1966fd1791_t::fd1791_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1791x, "FD1791", tag, owner, clock)
18371967{
1838   return false;
1968   inverted_bus = true;
1969   side_control = false;
1970   side_compare = true;
1971   head_control = true;
1972   motor_control = false;
1973   ready_hooked = true;
18391974}
18401975
1841bool wd_fdc_t::has_head_load() const
1976fd1792_t::fd1792_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1792x, "FD1792", tag, owner, clock)
18421977{
1843   return false;
1978   inverted_bus = true;
1979   side_control = false;
1980   side_compare = true;
1981   head_control = true;
1982   motor_control = false;
1983   ready_hooked = true;
18441984}
18451985
1846bool wd_fdc_t::has_side_check() const
1986fd1793_t::fd1793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1793x, "FD1793", tag, owner, clock)
18471987{
1848   return false;
1988   inverted_bus = false;
1989   side_control = false;
1990   side_compare = true;
1991   head_control = true;
1992   motor_control = false;
1993   ready_hooked = true;
18491994}
18501995
1851bool wd_fdc_t::has_side_select() const
1996fd1794_t::fd1794_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1794x, "FD1794", tag, owner, clock)
18521997{
1853   return false;
1998   inverted_bus = false;
1999   side_control = false;
2000   side_compare = true;
2001   head_control = true;
2002   motor_control = false;
2003   ready_hooked = true;
18542004}
18552005
1856bool wd_fdc_t::has_sector_length_select() const
2006fd1795_t::fd1795_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1795x, "FD1795", tag, owner, clock)
18572007{
1858   return false;
2008   inverted_bus = true;
2009   side_control = false;
2010   side_compare = false;
2011   head_control = true;
2012   motor_control = false;
2013   ready_hooked = true;
18592014}
18602015
1861bool wd_fdc_t::has_precompensation() const
2016fd1797_t::fd1797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1797x, "FD1797", tag, owner, clock)
18622017{
1863   return false;
2018   inverted_bus = false;
2019   side_control = false;
2020   side_compare = false;
2021   head_control = true;
2022   motor_control = false;
2023   ready_hooked = true;
18642024}
18652025
1866fd1771_t::fd1771_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_t(mconfig, FD1771x, "FD1771", tag, owner, clock)
2026mb8866_t::mb8866_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, MB8866x, "MB8866", tag, owner, clock)
18672027{
2028   inverted_bus = true;
2029   side_control = false;
2030   side_compare = true;
2031   head_control = true;
2032   motor_control = false;
2033   ready_hooked = true;
18682034}
18692035
1870fd1793_t::fd1793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_t(mconfig, FD1793x, "FD1793", tag, owner, clock)
2036mb8876_t::mb8876_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, MB8876x, "MB8876", tag, owner, clock)
18712037{
2038   inverted_bus = true;
2039   side_control = false;
2040   side_compare = true;
2041   head_control = true;
2042   motor_control = false;
2043   ready_hooked = true;
18722044}
18732045
1874fd1797_t::fd1797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_t(mconfig, FD1797x, "FD1797", tag, owner, clock)
2046mb8877_t::mb8877_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, MB8877x, "MB8877", tag, owner, clock)
18752047{
2048   inverted_bus = false;
2049   side_control = false;
2050   side_compare = true;
2051   head_control = true;
2052   motor_control = false;
2053   ready_hooked = true;
18762054}
18772055
1878wd2793_t::wd2793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_t(mconfig, WD2793x, "WD2793", tag, owner, clock)
2056fd1761_t::fd1761_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1761x, "FD1761", tag, owner, clock)
18792057{
2058   inverted_bus = true;
2059   side_control = false;
2060   side_compare = true;
2061   head_control = true;
2062   motor_control = false;
2063   ready_hooked = true;
18802064}
18812065
1882wd2797_t::wd2797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_t(mconfig, WD2797x, "WD2797", tag, owner, clock)
2066fd1763_t::fd1763_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1763x, "FD1763", tag, owner, clock)
18832067{
2068   inverted_bus = false;
2069   side_control = false;
2070   side_compare = true;
2071   head_control = true;
2072   motor_control = false;
2073   ready_hooked = true;
18842074}
18852075
1886wd1770_t::wd1770_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_t(mconfig, WD1770x, "WD1770", tag, owner, clock)
2076fd1765_t::fd1765_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1765x, "FD1765", tag, owner, clock)
18872077{
2078   inverted_bus = true;
2079   side_control = true;
2080   side_compare = false;
2081   head_control = true;
2082   motor_control = false;
2083   ready_hooked = true;
18882084}
18892085
1890wd1772_t::wd1772_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_t(mconfig, WD1772x, "WD1772", tag, owner, clock)
2086fd1767_t::fd1767_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, FD1767x, "FD1767", tag, owner, clock)
18912087{
2088   inverted_bus = false;
2089   side_control = true;
2090   side_compare = false;
2091   head_control = true;
2092   motor_control = false;
2093   ready_hooked = true;
18922094}
18932095
2096wd2791_t::wd2791_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, WD2791x, "WD2791", tag, owner, clock)
2097{
2098   inverted_bus = true;
2099   side_control = false;
2100   side_compare = true;
2101   head_control = true;
2102   motor_control = false;
2103   ready_hooked = true;
2104}
2105
2106wd2793_t::wd2793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, WD2793x, "WD2793", tag, owner, clock)
2107{
2108   inverted_bus = false;
2109   side_control = false;
2110   side_compare = true;
2111   head_control = true;
2112   motor_control = false;
2113   ready_hooked = true;
2114}
2115
2116wd2795_t::wd2795_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, WD2795x, "WD2795", tag, owner, clock)
2117{
2118   inverted_bus = true;
2119   side_control = true;
2120   side_compare = false;
2121   head_control = true;
2122   motor_control = false;
2123   ready_hooked = true;
2124}
2125
2126wd2797_t::wd2797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_analog_t(mconfig, WD2797x, "WD2797", tag, owner, clock)
2127{
2128   inverted_bus = false;
2129   side_control = true;
2130   side_compare = false;
2131   head_control = true;
2132   motor_control = false;
2133   ready_hooked = true;
2134}
2135
2136wd1770_t::wd1770_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_digital_t(mconfig, WD1770x, "WD1770", tag, owner, clock)
2137{
2138   inverted_bus = false;
2139   side_control = false;
2140   side_compare = false;
2141   head_control = false;
2142   motor_control = true;
2143   ready_hooked = false;
2144}
2145
2146wd1772_t::wd1772_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_digital_t(mconfig, WD1772x, "WD1772", tag, owner, clock)
2147{
2148   inverted_bus = false;
2149   side_control = false;
2150   side_compare = false;
2151   head_control = false;
2152   motor_control = true;
2153   ready_hooked = false;
2154}
2155
18942156int wd1772_t::step_time(int mode) const
18952157{
1896   const static int step_times[4] = { 48000, 96000, 16000, 24000 };
2158   const static int step_times[4] = { 12000, 24000, 4000, 6000 };
18972159   return step_times[mode];
18982160}
18992161
19002162int wd1772_t::settle_time() const
19012163{
1902   return 120000;
2164   return 30000;
19032165}
19042166
1905wd1773_t::wd1773_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_t(mconfig, WD1773x, "WD1773", tag, owner, clock)
2167wd1773_t::wd1773_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : wd_fdc_digital_t(mconfig, WD1773x, "WD1773", tag, owner, clock)
19062168{
2169   inverted_bus = false;
2170   side_control = false;
2171   side_compare = true;
2172   head_control = false;
2173   motor_control = false;
2174   ready_hooked = true;
19072175}
trunk/src/emu/machine/wd_fdc.h
r19185r19186
33
44#include "emu.h"
55#include "imagedev/floppy.h"
6#include "fdc_pll.h"
67
78/*
89 * The Western Digital floppy controller family
r19185r19186
4445#define MCFG_FD1771x_ADD(_tag, _clock)  \
4546   MCFG_DEVICE_ADD(_tag, FD1771x, _clock)
4647
48#define MCFG_FD1781x_ADD(_tag, _clock)  \
49   MCFG_DEVICE_ADD(_tag, FD1781x, _clock)
50
51#define MCFG_FD1791x_ADD(_tag, _clock)  \
52   MCFG_DEVICE_ADD(_tag, FD1791x, _clock)
53
54#define MCFG_FD1792x_ADD(_tag, _clock)  \
55   MCFG_DEVICE_ADD(_tag, FD1792x, _clock)
56
4757#define MCFG_FD1793x_ADD(_tag, _clock)  \
4858   MCFG_DEVICE_ADD(_tag, FD1793x, _clock)
4959
60#define MCFG_FD1794x_ADD(_tag, _clock)  \
61   MCFG_DEVICE_ADD(_tag, FD1794x, _clock)
62
63#define MCFG_FD1795x_ADD(_tag, _clock)  \
64   MCFG_DEVICE_ADD(_tag, FD1795x, _clock)
65
5066#define MCFG_FD1797x_ADD(_tag, _clock)  \
5167   MCFG_DEVICE_ADD(_tag, FD1797x, _clock)
5268
69#define MCFG_MB866x_ADD(_tag, _clock)  \
70   MCFG_DEVICE_ADD(_tag, MB8866x, _clock)
71
72#define MCFG_MB876x_ADD(_tag, _clock)  \
73   MCFG_DEVICE_ADD(_tag, MB8876x, _clock)
74
75#define MCFG_MB877x_ADD(_tag, _clock)  \
76   MCFG_DEVICE_ADD(_tag, MB8877x, _clock)
77
78#define MCFG_FD1761x_ADD(_tag, _clock)  \
79   MCFG_DEVICE_ADD(_tag, FD1761x, _clock)
80
81#define MCFG_FD1763x_ADD(_tag, _clock)  \
82   MCFG_DEVICE_ADD(_tag, FD1763x, _clock)
83
84#define MCFG_FD1765x_ADD(_tag, _clock)  \
85   MCFG_DEVICE_ADD(_tag, FD1765x, _clock)
86
87#define MCFG_FD1767x_ADD(_tag, _clock)  \
88   MCFG_DEVICE_ADD(_tag, FD1767x, _clock)
89
90#define MCFG_WD2791x_ADD(_tag, _clock)  \
91   MCFG_DEVICE_ADD(_tag, WD2791x, _clock)
92
5393#define MCFG_WD2793x_ADD(_tag, _clock)  \
5494   MCFG_DEVICE_ADD(_tag, WD2793x, _clock)
5595
96#define MCFG_WD2795x_ADD(_tag, _clock)  \
97   MCFG_DEVICE_ADD(_tag, WD2795x, _clock)
98
5699#define MCFG_WD2797x_ADD(_tag, _clock)  \
57100   MCFG_DEVICE_ADD(_tag, WD2797x, _clock)
58101
r19185r19186
112155   bool enp_r();
113156
114157protected:
158   // Chip-specific configuration flags
159   bool inverted_bus;
160   bool side_control;
161   bool side_compare;
162   bool head_control;
163   bool motor_control;
164   bool ready_hooked;
165   int clock_ratio;
166
115167   virtual void device_start();
116168   virtual void device_reset();
117169   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
118170
119   virtual bool has_ready() const;
120   virtual bool has_motor() const = 0;
121   virtual bool has_head_load() const;
122   virtual bool has_side_check() const;
123   virtual bool has_side_select() const;
124   virtual bool has_sector_length_select() const;
125   virtual bool has_precompensation() const;
126171   virtual int step_time(int mode) const;
127172   virtual int settle_time() const;
128173
174   virtual void pll_reset(attotime when) = 0;
175   virtual void pll_start_writing(attotime tm) = 0;
176   virtual void pll_commit(floppy_image_device *floppy, attotime tm) = 0;
177   virtual void pll_stop_writing(floppy_image_device *floppy, attotime tm) = 0;
178   virtual int pll_get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit) = 0;
179   virtual bool pll_write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit) = 0;
180   virtual void pll_save_checkpoint() = 0;
181   virtual void pll_retrieve_checkpoint() = 0;
182
129183private:
130184   enum { TM_GEN, TM_CMD, TM_TRACK, TM_SECTOR };
131185
r19185r19186
233287      WRITE_SECTOR_PRE_BYTE,
234288   };
235289
236   struct pll_t {
237      UINT16 counter;
238      UINT16 increment;
239      UINT16 transition_time;
240      UINT8 history;
241      UINT8 slot;
242      UINT8 phase_add, phase_sub, freq_add, freq_sub;
243      attotime ctime;
244
245      attotime delays[42];
246
247      attotime write_start_time;
248      attotime write_buffer[32];
249      int write_position;
250
251      void set_clock(attotime period);
252      void reset(attotime when);
253      int get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit);
254      bool write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit);
255      void start_writing(attotime tm);
256      void commit(floppy_image_device *floppy, attotime tm);
257      void stop_writing(floppy_image_device *floppy, attotime tm);
258   };
259
260290   struct live_info {
261291      enum { PT_NONE, PT_CRC_1, PT_CRC_2 };
262292
r19185r19186
268298      bool data_separator_phase, data_bit_context;
269299      UINT8 data_reg;
270300      UINT8 idbuf[6];
271      pll_t pll;
272301   };
273302
274303   enum {
r19185r19186
295324      I_IMM = 0x08
296325   };
297326
327
298328   floppy_image_device *floppy;
299329
300330   emu_timer *t_gen, *t_cmd, *t_track, *t_sector;
r19185r19186
369399   void set_drq();
370400};
371401
372class fd1771_t : public wd_fdc_t {
402class wd_fdc_analog_t : public wd_fdc_t {
373403public:
374   fd1771_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
404   wd_fdc_analog_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
375405
376406protected:
377   virtual bool has_ready() const { return true; }
378   virtual bool has_motor() const { return false; }
379   virtual bool has_head_load() const { return true; }
380   virtual bool has_side_check() const { return true; }
407   virtual void pll_reset(attotime when);
408   virtual void pll_start_writing(attotime tm);
409   virtual void pll_commit(floppy_image_device *floppy, attotime tm);
410   virtual void pll_stop_writing(floppy_image_device *floppy, attotime tm);
411   virtual int pll_get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit);
412   virtual bool pll_write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit);
413   virtual void pll_save_checkpoint();
414   virtual void pll_retrieve_checkpoint();
415
416private:
417   fdc_pll_t cur_pll, checkpoint_pll;
381418};
382419
383class fd1793_t : public wd_fdc_t {
420class wd_fdc_digital_t : public wd_fdc_t {
384421public:
385   fd1793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
422   wd_fdc_digital_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
386423
387424protected:
388   virtual bool has_ready() const { return true; }
389   virtual bool has_motor() const { return false; }
390   virtual bool has_head_load() const { return true; }
391   virtual bool has_side_check() const { return true; }
425   virtual void pll_reset(attotime when);
426   virtual void pll_start_writing(attotime tm);
427   virtual void pll_commit(floppy_image_device *floppy, attotime tm);
428   virtual void pll_stop_writing(floppy_image_device *floppy, attotime tm);
429   virtual int pll_get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit);
430   virtual bool pll_write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit);
431   virtual void pll_save_checkpoint();
432   virtual void pll_retrieve_checkpoint();
433
434private:
435   struct digital_pll_t {
436      UINT16 counter;
437      UINT16 increment;
438      UINT16 transition_time;
439      UINT8 history;
440      UINT8 slot;
441      UINT8 phase_add, phase_sub, freq_add, freq_sub;
442      attotime ctime;
443
444      attotime delays[42];
445
446      attotime write_start_time;
447      attotime write_buffer[32];
448      int write_position;
449
450      void set_clock(attotime period);
451      void reset(attotime when);
452      int get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit);
453      bool write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit);
454      void start_writing(attotime tm);
455      void commit(floppy_image_device *floppy, attotime tm);
456      void stop_writing(floppy_image_device *floppy, attotime tm);
457   };
458
459   digital_pll_t cur_pll, checkpoint_pll;
392460};
393461
394class fd1797_t : public wd_fdc_t {
462class fd1771_t : public wd_fdc_analog_t {
395463public:
464   fd1771_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
465};
466
467class fd1781_t : public wd_fdc_analog_t {
468public:
469   fd1781_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
470};
471
472class fd1791_t : public wd_fdc_analog_t {
473public:
474   fd1791_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
475};
476
477class fd1792_t : public wd_fdc_analog_t {
478public:
479   fd1792_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
480};
481
482class fd1793_t : public wd_fdc_analog_t {
483public:
484   fd1793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
485};
486
487class fd1794_t : public wd_fdc_analog_t {
488public:
489   fd1794_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
490};
491
492class fd1795_t : public wd_fdc_analog_t {
493public:
494   fd1795_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
495};
496
497class fd1797_t : public wd_fdc_analog_t {
498public:
396499   fd1797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
500};
397501
398protected:
399   virtual bool has_ready() const { return true; }
400   virtual bool has_motor() const { return false; }
401   virtual bool has_head_load() const { return true; }
402   virtual bool has_side_select() const { return true; }
403   virtual bool has_sector_length_select() const { return true; }
502class mb8866_t : public wd_fdc_analog_t {
503public:
504   mb8866_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
404505};
405506
406class wd2793_t : public wd_fdc_t {
507class mb8876_t : public wd_fdc_analog_t {
407508public:
509   mb8876_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
510};
511
512class mb8877_t : public wd_fdc_analog_t {
513public:
514   mb8877_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
515};
516
517class fd1761_t : public wd_fdc_analog_t {
518public:
519   fd1761_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
520};
521
522class fd1763_t : public wd_fdc_analog_t {
523public:
524   fd1763_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
525};
526
527class fd1765_t : public wd_fdc_analog_t {
528public:
529   fd1765_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
530};
531
532class fd1767_t : public wd_fdc_analog_t {
533public:
534   fd1767_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
535};
536
537class wd2791_t : public wd_fdc_analog_t {
538public:
539   wd2791_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
540};
541
542class wd2793_t : public wd_fdc_analog_t {
543public:
408544   wd2793_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
545};
409546
410protected:
411   virtual bool has_ready() const { return true; }
412   virtual bool has_motor() const { return false; }
413   virtual bool has_head_load() const { return true; }
414   virtual bool has_side_check() const { return true; }
547class wd2795_t : public wd_fdc_analog_t {
548public:
549   wd2795_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
415550};
416551
417class wd2797_t : public wd_fdc_t {
552class wd2797_t : public wd_fdc_analog_t {
418553public:
419554   wd2797_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
420
421protected:
422   virtual bool has_ready() const { return true; }
423   virtual bool has_motor() const { return false; }
424   virtual bool has_head_load() const { return true; }
425   virtual bool has_side_select() const { return true; }
426   virtual bool has_sector_length_select() const { return true; }
427555};
428556
429class wd1770_t : public wd_fdc_t {
557class wd1770_t : public wd_fdc_digital_t {
430558public:
431559   wd1770_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
432
433protected:
434   virtual bool has_motor() const { return true; }
435   virtual bool has_precompensation() const { return true; }
436560};
437561
438class wd1772_t : public wd_fdc_t {
562class wd1772_t : public wd_fdc_digital_t {
439563public:
440564   wd1772_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
441565
442566protected:
443   virtual bool has_motor() const { return true; }
444   virtual bool has_precompensation() const { return true; }
445567   virtual int step_time(int mode) const;
446568   virtual int settle_time() const;
447569};
448570
449class wd1773_t : public wd_fdc_t {
571class wd1773_t : public wd_fdc_digital_t {
450572public:
451573   wd1773_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
452
453protected:
454   virtual bool has_motor() const { return false; }
455   virtual bool has_head_load() const { return true; }
456   virtual bool has_side_check() const { return true; }
457574};
458575
459576extern const device_type FD1771x;
577
578extern const device_type FD1781x;
579
580extern const device_type FD1791x;
581extern const device_type FD1792x;
460582extern const device_type FD1793x;
583extern const device_type FD1795x;
461584extern const device_type FD1797x;
585
586extern const device_type MB8866x;
587extern const device_type MB8876x;
588extern const device_type MB8877x;
589
590extern const device_type FD1761x;
591extern const device_type FD1763x;
592extern const device_type FD1765x;
593extern const device_type FD1767x;
594
595extern const device_type WD2791x;
462596extern const device_type WD2793x;
597extern const device_type WD2795x;
463598extern const device_type WD2797x;
599
464600extern const device_type WD1770x;
465601extern const device_type WD1772x;
466602extern const device_type WD1773x;

Previous 199869 Revisions Next


© 1997-2024 The MAME Team