Previous 199869 Revisions Next

r19237 Saturday 1st December, 2012 at 10:28:18 UTC by O. Galibert
wd_fdc: fm support, need to review all timings [O. Galibert]
[src/emu/machine]fdc_pll.c fdc_pll.h wd_fdc.c wd_fdc.h
[src/lib/formats]m20_dsk.c m20_dsk.h
[src/mess/drivers]m20.c

trunk/src/emu/machine/wd_fdc.c
r19236r19237
6969   t_cmd = timer_alloc(TM_CMD);
7070   t_track = timer_alloc(TM_TRACK);
7171   t_sector = timer_alloc(TM_SECTOR);
72   dden = false;
72   dden = disable_mfm;
7373   floppy = 0;
7474
7575   save_item(NAME(status));
r19236r19237
148148
149149void wd_fdc_t::dden_w(bool _dden)
150150{
151   dden = _dden;
151   if(disable_mfm) {
152      logerror("%s: Error, this chip does not have a dden line\n", tag());
153      return;
154   }
155
156   if(dden != _dden) {
157      dden = _dden;
158      logerror("%s: select %s\n", tag(), dden ? "fm" : "mfm");
159   }
152160}
153161
154162astring wd_fdc_t::tts(attotime t)
r19236r19237
333341
334342bool wd_fdc_t::sector_matches() const
335343{
344   if(0)
345      logerror("%s: matching %02x %02x %02x %02x - %02x %02x\n", tag(),
346             cur_live.idbuf[0], cur_live.idbuf[1], cur_live.idbuf[2], cur_live.idbuf[3],
347             track, sector);
348
336349   if(cur_live.idbuf[0] != track || cur_live.idbuf[2] != sector)
337350      return false;
338351   if(!side_compare || (command & 2))
r19236r19237
357370   status = (status & ~(S_CRC|S_LOST|S_RNF|S_WP|S_DDM)) | S_BUSY;
358371   drop_drq();
359372   if(side_control && floppy)
360      floppy->ss_w(command & 0x02);
373      floppy->ss_w((command & 0x02) ? 1 : 0);
361374   sub_state = motor_control ? SPINUP : SPINUP_DONE;
362375   status_type_1 = false;
363376   read_sector_continue();
r19236r19237
447460   status = (status & ~(S_LOST|S_RNF)) | S_BUSY;
448461   drop_drq();
449462   if(side_control && floppy)
450      floppy->ss_w(command & 0x02);
463      floppy->ss_w((command & 0x02) ? 1 : 0);
451464   sub_state = motor_control ? SPINUP : SPINUP_DONE;
452465   status_type_1 = false;
453466   read_track_continue();
r19236r19237
514527   status = (status & ~(S_WP|S_DDM|S_LOST|S_RNF)) | S_BUSY;
515528   drop_drq();
516529   if(side_control && floppy)
517      floppy->ss_w(command & 0x02);
530      floppy->ss_w((command & 0x02) ? 1 : 0);
518531   sub_state = motor_control ? SPINUP : SPINUP_DONE;
519532   status_type_1 = false;
520533   read_id_continue();
r19236r19237
579592   status = (status & ~(S_WP|S_DDM|S_LOST|S_RNF)) | S_BUSY;
580593   drop_drq();
581594   if(side_control && floppy)
582      floppy->ss_w(command & 0x02);
595      floppy->ss_w((command & 0x02) ? 1 : 0);
583596   sub_state = motor_control ? SPINUP : SPINUP_DONE;
584597   status_type_1 = false;
585598
r19236r19237
654667               sprintf(buf, "%02x", format_last_byte);
655668            format_description_string += buf;
656669         }
657         logerror("wd1772: track description %s\n", format_description_string.cstr());
670         logerror("%s: track description %s\n", tag(), format_description_string.cstr());
658671         command_end();
659672         return;
660673
r19236r19237
675688   status = (status & ~(S_CRC|S_LOST|S_RNF|S_WP|S_DDM)) | S_BUSY;
676689   drop_drq();
677690   if(side_control && floppy)
678      floppy->ss_w(command & 0x02);
691      floppy->ss_w((command & 0x02) ? 1 : 0);
679692   sub_state = motor_control  ? SPINUP : SPINUP_DONE;
680693   status_type_1 = false;
681694   write_sector_continue();
r19236r19237
859872   cmd_buffer = -1;
860873
861874   switch(command & 0xf0) {
862   case 0x00: logerror("wd1772: restore\n"); last_dir = 1; seek_start(RESTORE); break;
863   case 0x10: logerror("wd1772: seek %d\n", data); last_dir = data > track ? 0 : 1; seek_start(SEEK); break;
864   case 0x20: case 0x30: logerror("wd1772: step\n"); seek_start(STEP); break;
865   case 0x40: case 0x50: logerror("wd1772: step +\n"); last_dir = 0; seek_start(STEP); break;
866   case 0x60: case 0x70: logerror("wd1772: step -\n"); last_dir = 1; seek_start(STEP); break;
867   case 0x80: case 0x90: logerror("wd1772: read sector%s %d, %d\n", command & 0x10 ? " multiple" : "", track, sector); read_sector_start(); break;
868   case 0xa0: case 0xb0: logerror("wd1772: write sector%s %d, %d\n", command & 0x10 ? " multiple" : "", track, sector); write_sector_start(); break;
869   case 0xc0: logerror("wd1772: read id\n"); read_id_start(); break;
870   case 0xd0: logerror("wd1772: interrupt\n"); interrupt_start(); break;
871   case 0xe0: logerror("wd1772: read track %d\n", track); read_track_start(); break;
872   case 0xf0: logerror("wd1772: write track %d\n", track); write_track_start(); break;
875   case 0x00: logerror("%s: restore\n", tag()); last_dir = 1; seek_start(RESTORE); break;
876   case 0x10: logerror("%s: seek %d\n", tag(), data); last_dir = data > track ? 0 : 1; seek_start(SEEK); break;
877   case 0x20: case 0x30: logerror("%s: step\n", tag()); seek_start(STEP); break;
878   case 0x40: case 0x50: logerror("%s: step +\n", tag()); last_dir = 0; seek_start(STEP); break;
879   case 0x60: case 0x70: logerror("%s: step -\n", tag()); last_dir = 1; seek_start(STEP); break;
880   case 0x80: case 0x90: logerror("%s: read sector%s %d, %d - %02x\n", tag(), command & 0x10 ? " multiple" : "", track, sector, command); read_sector_start(); break;
881   case 0xa0: case 0xb0: logerror("%s: write sector%s %d, %d\n", tag(), command & 0x10 ? " multiple" : "", track, sector); write_sector_start(); break;
882   case 0xc0: logerror("%s: read id\n", tag()); read_id_start(); break;
883   case 0xd0: logerror("%s: interrupt\n", tag()); interrupt_start(); break;
884   case 0xe0: logerror("%s: read track %d\n", tag(), track); read_track_start(); break;
885   case 0xf0: logerror("%s: write track %d\n", tag(), track); write_track_start(); break;
873886   }
874887}
875888
r19236r19237
877890{
878891   if (inverted_bus) val ^= 0xff;
879892   
880   logerror("wd1772 cmd: %02x\n", val);
881
882893   if(intrq && !(intrq_cond & I_IMM)) {
883894      intrq = false;
884895      if(!intrq_cb.isnull())
r19236r19237
891902
892903   cmd_buffer = val;
893904
894   delay_cycles(t_cmd, dden ? 192 : 46);
905   delay_cycles(t_cmd, dden ? 1 : 1);
895906}
896907
897908UINT8 wd_fdc_t::status_r()
r19236r19237
952963      return;
953964
954965   track_buffer = val;
955   delay_cycles(t_track, dden ? 64 : 32);
966   delay_cycles(t_track, dden ? 32 : 16);
956967}
957968
958969UINT8 wd_fdc_t::track_r()
r19236r19237
978989      return;
979990
980991   sector_buffer = val;
981   delay_cycles(t_sector, dden ? 64 : 32);
992   delay_cycles(t_sector, dden ? 32 : 16);
982993}
983994
984995UINT8 wd_fdc_t::sector_r()
r19236r19237
11661177   cur_live.previous_type = live_info::PT_NONE;
11671178   cur_live.data_bit_context = false;
11681179   cur_live.byte_counter = 0;
1169   pll_reset(cur_live.tm);
1180   pll_reset(dden, cur_live.tm);
11701181   checkpoint_live = cur_live;
11711182   pll_save_checkpoint();
11721183
r19236r19237
11961207{
11971208   if(!cur_live.tm.is_never()) {
11981209      if(cur_live.tm > machine().time()) {
1199         //          fprintf(stderr, "%s: Rolling back and replaying (%s)\n", ttsn().cstr(), tts(cur_live.tm).cstr());
1210         //         fprintf(stderr, "%s: Rolling back and replaying (%s)\n", ttsn().cstr(), tts(cur_live.tm).cstr());
12001211         rollback();
12011212         live_run(machine().time());
12021213         pll_commit(floppy, cur_live.tm);
12031214      } else {
1204         //          fprintf(stderr, "%s: Committing (%s)\n", ttsn().cstr(), tts(cur_live.tm).cstr());
1215         //         fprintf(stderr, "%s: Committing (%s)\n", ttsn().cstr(), tts(cur_live.tm).cstr());
12051216         pll_commit(floppy, cur_live.tm);
12061217         if(cur_live.next_state != -1) {
12071218            cur_live.state = cur_live.next_state;
r19236r19237
12881299   //  logerror("write %02x   %04x %04x\n", mfm, cur_live.crc, raw);
12891300}
12901301
1302
1303void wd_fdc_t::live_write_fm(UINT8 fm)
1304{
1305   UINT16 raw = 0xaaaa;
1306   for(int i=0; i<8; i++)
1307      if(fm & (0x80 >> i))
1308         raw |= 0x4000 >> (2*i);
1309   cur_live.data_reg = fm;
1310   cur_live.shift_reg = raw;
1311   cur_live.data_bit_context = fm & 1;
1312   //  logerror("write %02x   %04x %04x\n", fm, cur_live.crc, raw);
1313}
1314
12911315void wd_fdc_t::live_run(attotime limit)
12921316{
12931317   if(cur_live.state == IDLE || cur_live.next_state != -1)
r19236r19237
13281352               cur_live.bit_counter);
13291353#endif
13301354
1331         if(cur_live.shift_reg == 0x4489) {
1355         if(!dden && cur_live.shift_reg == 0x4489) {
13321356            cur_live.crc = 0x443b;
13331357            cur_live.data_separator_phase = false;
13341358            cur_live.bit_counter = 0;
13351359            cur_live.state = READ_HEADER_BLOCK_HEADER;
13361360         }
1361
1362         if(dden && (cur_live.shift_reg == 0xf57e || cur_live.shift_reg == 0xf57e)) {
1363            cur_live.crc = cur_live.shift_reg == 0xf57e ? 0xef21 : 0xff00;
1364            cur_live.data_separator_phase = false;
1365            cur_live.bit_counter = 0;
1366            if(main_state == READ_ID)
1367               cur_live.state = READ_ID_BLOCK_TO_DMA;
1368            else
1369               cur_live.state = READ_ID_BLOCK_TO_LOCAL;
1370         }
13371371         break;
13381372
13391373      case READ_HEADER_BLOCK_HEADER: {
r19236r19237
13821416         if(cur_live.bit_counter & 15)
13831417            break;
13841418         int slot = (cur_live.bit_counter >> 4)-1;
1419         //         fprintf(stderr, "%s: slot[%d] = %02x  crc = %04x\n", tts(cur_live.tm).cstr(), slot, cur_live.data_reg, cur_live.crc);
13851420         cur_live.idbuf[slot] = cur_live.data_reg;
13861421         if(slot == 5) {
13871422            live_delay(IDLE);
r19236r19237
14301465               (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
14311466               cur_live.bit_counter >> 4, cur_live.bit_counter & 15);
14321467#endif
1433         if(cur_live.bit_counter > 43*16) {
1434            live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
1435            return;
1436         }
1468         if(!dden) {
1469            if(cur_live.bit_counter > 43*16) {
1470               live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
1471               return;
1472            }
14371473
1438         if(cur_live.bit_counter >= 28*16 && cur_live.shift_reg == 0x4489) {
1439            cur_live.crc = 0x443b;
1440            cur_live.data_separator_phase = false;
1441            cur_live.bit_counter = 0;
1442            cur_live.state = READ_DATA_BLOCK_HEADER;
1474            if(cur_live.bit_counter >= 28*16 && cur_live.shift_reg == 0x4489) {
1475               cur_live.crc = 0x443b;
1476               cur_live.data_separator_phase = false;
1477               cur_live.bit_counter = 0;
1478               cur_live.state = READ_DATA_BLOCK_HEADER;
1479            }
1480         } else {
1481            if(cur_live.bit_counter > 23*16) {
1482               live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED);
1483               return;
1484            }
1485
1486            if(cur_live.bit_counter >= 11*16 && (cur_live.shift_reg == 0xf56a || cur_live.shift_reg == 0xf56b ||
1487                                        cur_live.shift_reg == 0xf56e || cur_live.shift_reg == 0xf56f)) {
1488               cur_live.crc =
1489                  cur_live.shift_reg == 0xf56a ? 0x8fe7 :
1490                  cur_live.shift_reg == 0xf56b ? 0x9fc6 :
1491                  cur_live.shift_reg == 0xf56e ? 0xafa5 :
1492                  0xbf84;
1493               cur_live.data_separator_phase = false;
1494               cur_live.bit_counter = 0;
1495               cur_live.state = READ_SECTOR_DATA;
1496            }
14431497         }
14441498         break;
14451499
r19236r19237
15701624         } else
15711625            format_last_byte_count++;
15721626
1573         switch(data) {
1574         case 0xf5:
1575            live_write_raw(0x4489);
1576            cur_live.crc = 0x968b; // Ensures that the crc is cdb4 after writing the byte
1577            cur_live.previous_type = live_info::PT_NONE;
1578            break;
1579         case 0xf6:
1580            cur_live.previous_type = live_info::PT_NONE;
1581            live_write_raw(0x5224);
1582            break;
1583         case 0xf7:
1584            if(cur_live.previous_type == live_info::PT_CRC_2) {
1627         if(dden) {
1628            switch(data) {
1629            case 0xf7:
1630               if(cur_live.previous_type == live_info::PT_CRC_2) {
1631                  cur_live.previous_type = live_info::PT_NONE;
1632                  live_write_fm(0xf7);
1633               } else {
1634                  cur_live.previous_type = live_info::PT_CRC_1;
1635                  live_write_fm(cur_live.crc >> 8);
1636               }
1637               break;
1638            case 0xf8:
1639               live_write_raw(0xf56a);
1640               cur_live.crc = 0xffff;
15851641               cur_live.previous_type = live_info::PT_NONE;
1586               live_write_mfm(0xf7);
1587            } else {
1588               cur_live.previous_type = live_info::PT_CRC_1;
1589               live_write_mfm(cur_live.crc >> 8);
1642               break;
1643            case 0xf9:
1644               live_write_raw(0xf56b);
1645               cur_live.crc = 0xffff;
1646               cur_live.previous_type = live_info::PT_NONE;
1647               break;
1648            case 0xfa:
1649               live_write_raw(0xf56e);
1650               cur_live.crc = 0xffff;
1651               cur_live.previous_type = live_info::PT_NONE;
1652               break;
1653            case 0xfb:
1654               live_write_raw(0xf56f);
1655               cur_live.crc = 0xffff;
1656               cur_live.previous_type = live_info::PT_NONE;
1657               break;
1658            case 0xfc:
1659               live_write_raw(0xcf63);
1660               cur_live.previous_type = live_info::PT_NONE;
1661               break;
1662            case 0xfe:
1663               live_write_raw(0xf57e);
1664               cur_live.crc = 0xffff;
1665               cur_live.previous_type = live_info::PT_NONE;
1666               break;
1667            default:
1668               cur_live.previous_type = live_info::PT_NONE;
1669               live_write_fm(data);
1670               break;
15901671            }
1591            break;
1592         default:
1593            cur_live.previous_type = live_info::PT_NONE;
1594            live_write_mfm(data);
1595            break;
1672
1673         } else {
1674            switch(data) {
1675            case 0xf5:
1676               live_write_raw(0x4489);
1677               cur_live.crc = 0x968b; // Ensures that the crc is cdb4 after writing the byte
1678               cur_live.previous_type = live_info::PT_NONE;
1679               break;
1680            case 0xf6:
1681               cur_live.previous_type = live_info::PT_NONE;
1682               live_write_raw(0x5224);
1683               break;
1684            case 0xf7:
1685               if(cur_live.previous_type == live_info::PT_CRC_2) {
1686                  cur_live.previous_type = live_info::PT_NONE;
1687                  live_write_mfm(0xf7);
1688               } else {
1689                  cur_live.previous_type = live_info::PT_CRC_1;
1690                  live_write_mfm(cur_live.crc >> 8);
1691               }
1692               break;
1693            default:
1694               cur_live.previous_type = live_info::PT_NONE;
1695               live_write_mfm(data);
1696               break;
1697            }
15961698         }
15971699         set_drq();
15981700         cur_live.state = WRITE_BYTE;
r19236r19237
16141716         case TRACK_DONE:
16151717            if(cur_live.previous_type == live_info::PT_CRC_1) {
16161718               cur_live.previous_type = live_info::PT_CRC_2;
1617               live_write_mfm(cur_live.crc >> 8);
1719               if(dden)
1720                  live_write_fm(cur_live.crc >> 8);
1721               else
1722                  live_write_mfm(cur_live.crc >> 8);
16181723               cur_live.state = WRITE_BYTE;
16191724               cur_live.bit_counter = 16;
16201725               checkpoint();
r19236r19237
16261731            cur_live.state = WRITE_BYTE;
16271732            cur_live.bit_counter = 16;
16281733            cur_live.byte_counter++;
1629            if(cur_live.byte_counter <= 11)
1630               live_write_mfm(0x00);
1631            else if(cur_live.byte_counter == 12) {
1632               cur_live.crc = 0xffff;
1633               live_write_raw(0x4489);
1634            } else if(cur_live.byte_counter <= 14)
1635               live_write_raw(0x4489);
1636            else if(cur_live.byte_counter == 15)
1637               live_write_mfm(command & 1 ? 0xf8 : 0xfb);
1638            else if(cur_live.byte_counter <= sector_size + 16-2) {
1639               if(drq) {
1640                  status |= S_LOST;
1641                  data = 0;
1734
1735            if(dden) {
1736               if(cur_live.byte_counter < 6)
1737                  live_write_fm(0x00);
1738               else if(cur_live.byte_counter < 7) {
1739                  cur_live.crc = 0xffff;
1740                  live_write_raw(command & 1 ? 0xf56a : 0xf56f);
1741               } else if(cur_live.byte_counter < sector_size + 7-1) {
1742                  if(drq) {
1743                     status |= S_LOST;
1744                     data = 0;
1745                  }
1746                  live_write_fm(data);
1747                  set_drq();
1748               } else if(cur_live.byte_counter < sector_size + 7) {
1749                  if(drq) {
1750                     status |= S_LOST;
1751                     data = 0;
1752                  }
1753                  live_write_fm(data);
1754               } else if(cur_live.byte_counter < sector_size + 7+2)
1755                  live_write_fm(cur_live.crc >> 8);
1756               else if(cur_live.byte_counter < sector_size + 7+3)
1757                  live_write_fm(0xff);
1758               else {
1759                  pll_stop_writing(floppy, cur_live.tm);
1760                  cur_live.state = IDLE;
1761                  return;
16421762               }
1643               live_write_mfm(data);
1644               set_drq();
1645            } else if(cur_live.byte_counter == sector_size + 16-1) {
1646               if(drq) {
1647                  status |= S_LOST;
1648                  data = 0;
1763
1764            } else {
1765               if(cur_live.byte_counter < 12)
1766                  live_write_mfm(0x00);
1767               else if(cur_live.byte_counter < 15)
1768                  live_write_raw(0x4489);
1769               else if(cur_live.byte_counter < 16) {
1770                  cur_live.crc = 0xcdb4;
1771                  live_write_mfm(command & 1 ? 0xf8 : 0xfb);
1772
1773               } else if(cur_live.byte_counter < sector_size + 16-1) {
1774                  if(drq) {
1775                     status |= S_LOST;
1776                     data = 0;
1777                  }
1778                  live_write_mfm(data);
1779                  set_drq();
1780               } else if(cur_live.byte_counter < sector_size + 16) {
1781                  if(drq) {
1782                     status |= S_LOST;
1783                     data = 0;
1784                  }
1785                  live_write_mfm(data);
1786               } else if(cur_live.byte_counter < sector_size + 16+2)
1787                  live_write_mfm(cur_live.crc >> 8);
1788               else if(cur_live.byte_counter < sector_size + 16+3)
1789                  live_write_mfm(0xff);
1790               else {
1791                  pll_stop_writing(floppy, cur_live.tm);
1792                  cur_live.state = IDLE;
1793                  return;
16491794               }
1650               live_write_mfm(data);
1651            } else if(cur_live.byte_counter <= sector_size + 16+1)
1652               live_write_mfm(cur_live.crc >> 8);
1653            else if(cur_live.byte_counter == sector_size + 16+2)
1654               // Is that correct?  It seems required (try ST formatting)
1655               live_write_mfm(0xff);
1656            else {
1657               pll_stop_writing(floppy, cur_live.tm);
1658               cur_live.state = IDLE;
1659               return;
16601795            }
16611796
1797
16621798            checkpoint();
16631799            break;
16641800
r19236r19237
16931829               return;
16941830            }
16951831            break;
1832         case 12:
1833            if(dden) {
1834               cur_live.state = WRITE_BYTE;
1835               cur_live.bit_counter = 16;
1836               cur_live.byte_counter = 0;
1837               cur_live.data_bit_context = cur_live.data_reg & 1;
1838               pll_start_writing(cur_live.tm);
1839               if(dden)
1840                  live_write_fm(0x00);
1841            }
1842            break;
1843
16961844         case 22:
16971845            cur_live.state = WRITE_BYTE;
16981846            cur_live.bit_counter = 16;
r19236r19237
17341882int wd_fdc_t::step_time(int mode) const
17351883{
17361884   const static int step_times[4] = { 12000, 24000, 40000, 60000 };
1737   return step_times[mode];
1885   return step_times[mode]/10;
17381886}
17391887
17401888int wd_fdc_t::settle_time() const
r19236r19237
17481896   clock_ratio = 1;
17491897}
17501898
1751void wd_fdc_analog_t::pll_reset(attotime when)
1899void wd_fdc_analog_t::pll_reset(bool fm, attotime when)
17521900{
17531901   cur_pll.reset(when);
1754   cur_pll.set_clock(clocks_to_attotime(4));
1902   cur_pll.set_clock(clocks_to_attotime(fm ? 4 : 2));
17551903}
17561904
17571905void wd_fdc_analog_t::pll_start_writing(attotime tm)
r19236r19237
17951943   clock_ratio = 4;
17961944}
17971945
1798void wd_fdc_digital_t::pll_reset(attotime when)
1946void wd_fdc_digital_t::pll_reset(bool fm, attotime when)
17991947{
18001948   cur_pll.reset(when);
18011949   cur_pll.set_clock(clocks_to_attotime(1));
r19236r19237
19932141
19942142fd1771_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)
19952143{
2144   disable_mfm = true;
19962145   inverted_bus = true;
19972146   side_control = false;
19982147   side_compare = false;
r19236r19237
20032152
20042153fd1781_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)
20052154{
2155   disable_mfm = false;
20062156   inverted_bus = true;
20072157   side_control = false;
20082158   side_compare = false;
r19236r19237
20132163
20142164fd1791_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)
20152165{
2166   disable_mfm = false;
20162167   inverted_bus = true;
20172168   side_control = false;
20182169   side_compare = true;
r19236r19237
20232174
20242175fd1792_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)
20252176{
2177   disable_mfm = true;
20262178   inverted_bus = true;
20272179   side_control = false;
20282180   side_compare = true;
r19236r19237
20332185
20342186fd1793_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)
20352187{
2188   disable_mfm = false;
20362189   inverted_bus = false;
20372190   side_control = false;
20382191   side_compare = true;
r19236r19237
20432196
20442197fd1794_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)
20452198{
2199   disable_mfm = true;
20462200   inverted_bus = false;
20472201   side_control = false;
20482202   side_compare = true;
r19236r19237
20532207
20542208fd1795_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)
20552209{
2210   disable_mfm = false;
20562211   inverted_bus = true;
2057   side_control = false;
2212   side_control = true;
20582213   side_compare = false;
20592214   head_control = true;
20602215   motor_control = false;
r19236r19237
20632218
20642219fd1797_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)
20652220{
2221   disable_mfm = false;
20662222   inverted_bus = false;
2067   side_control = false;
2223   side_control = true;
20682224   side_compare = false;
20692225   head_control = true;
20702226   motor_control = false;
r19236r19237
20732229
20742230mb8866_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)
20752231{
2232   disable_mfm = false;
20762233   inverted_bus = true;
20772234   side_control = false;
20782235   side_compare = true;
r19236r19237
20832240
20842241mb8876_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)
20852242{
2243   disable_mfm = false;
20862244   inverted_bus = true;
20872245   side_control = false;
20882246   side_compare = true;
r19236r19237
20932251
20942252mb8877_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)
20952253{
2254   disable_mfm = false;
20962255   inverted_bus = false;
20972256   side_control = false;
20982257   side_compare = true;
r19236r19237
21032262
21042263fd1761_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)
21052264{
2265   disable_mfm = false;
21062266   inverted_bus = true;
21072267   side_control = false;
21082268   side_compare = true;
r19236r19237
21132273
21142274fd1763_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)
21152275{
2276   disable_mfm = false;
21162277   inverted_bus = false;
21172278   side_control = false;
21182279   side_compare = true;
r19236r19237
21232284
21242285fd1765_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)
21252286{
2287   disable_mfm = false;
21262288   inverted_bus = true;
21272289   side_control = true;
21282290   side_compare = false;
r19236r19237
21332295
21342296fd1767_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)
21352297{
2298   disable_mfm = false;
21362299   inverted_bus = false;
21372300   side_control = true;
21382301   side_compare = false;
r19236r19237
21432306
21442307wd2791_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)
21452308{
2309   disable_mfm = false;
21462310   inverted_bus = true;
21472311   side_control = false;
21482312   side_compare = true;
r19236r19237
21532317
21542318wd2793_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)
21552319{
2320   disable_mfm = false;
21562321   inverted_bus = false;
21572322   side_control = false;
21582323   side_compare = true;
r19236r19237
21632328
21642329wd2795_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)
21652330{
2331   disable_mfm = false;
21662332   inverted_bus = true;
21672333   side_control = true;
21682334   side_compare = false;
r19236r19237
21732339
21742340wd2797_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)
21752341{
2342   disable_mfm = false;
21762343   inverted_bus = false;
21772344   side_control = true;
21782345   side_compare = false;
r19236r19237
21832350
21842351wd1770_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)
21852352{
2353   disable_mfm = false;
21862354   inverted_bus = false;
21872355   side_control = false;
21882356   side_compare = false;
r19236r19237
21932361
21942362wd1772_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)
21952363{
2364   disable_mfm = false;
21962365   inverted_bus = false;
21972366   side_control = false;
21982367   side_compare = false;
r19236r19237
22142383
22152384wd1773_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)
22162385{
2386   disable_mfm = false;
22172387   inverted_bus = false;
22182388   side_control = false;
22192389   side_compare = true;
trunk/src/emu/machine/wd_fdc.h
r19236r19237
156156
157157protected:
158158   // Chip-specific configuration flags
159   bool disable_mfm;
159160   bool inverted_bus;
160161   bool side_control;
161162   bool side_compare;
r19236r19237
171172   virtual int step_time(int mode) const;
172173   virtual int settle_time() const;
173174
174   virtual void pll_reset(attotime when) = 0;
175   virtual void pll_reset(bool fm, attotime when) = 0;
175176   virtual void pll_start_writing(attotime tm) = 0;
176177   virtual void pll_commit(floppy_image_device *floppy, attotime tm) = 0;
177178   virtual void pll_stop_writing(floppy_image_device *floppy, attotime tm) = 0;
r19236r19237
398399
399400   void live_write_raw(UINT16 raw);
400401   void live_write_mfm(UINT8 mfm);
402   void live_write_fm(UINT8 fm);
401403
402404   void drop_drq();
403405   void set_drq();
r19236r19237
408410   wd_fdc_analog_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
409411
410412protected:
411   virtual void pll_reset(attotime when);
413   virtual void pll_reset(bool fm, attotime when);
412414   virtual void pll_start_writing(attotime tm);
413415   virtual void pll_commit(floppy_image_device *floppy, attotime tm);
414416   virtual void pll_stop_writing(floppy_image_device *floppy, attotime tm);
r19236r19237
426428   wd_fdc_digital_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
427429
428430protected:
429   virtual void pll_reset(attotime when);
431   virtual void pll_reset(bool fm, attotime when);
430432   virtual void pll_start_writing(attotime tm);
431433   virtual void pll_commit(floppy_image_device *floppy, attotime tm);
432434   virtual void pll_stop_writing(floppy_image_device *floppy, attotime tm);
trunk/src/emu/machine/fdc_pll.c
r19236r19237
11#include "fdc_pll.h"
22
3astring fdc_pll_t::tts(attotime t)
4{
5   char buf[256];
6   bool neg = t.seconds < 0;
7   if(neg)
8      t = attotime::zero - t;
9   int nsec = t.attoseconds / ATTOSECONDS_PER_NANOSECOND;
10   sprintf(buf, "%c%3d.%03d,%03d,%03d", neg ? '-' : ' ', int(t.seconds), nsec/1000000, (nsec/1000)%1000, nsec % 1000);
11   return buf;
12}
13
314void fdc_pll_t::set_clock(attotime _period)
415{
516   period = _period;
trunk/src/emu/machine/fdc_pll.h
r19236r19237
2424   void start_writing(attotime tm);
2525   void commit(floppy_image_device *floppy, attotime tm);
2626   void stop_writing(floppy_image_device *floppy, attotime tm);
27
28   astring tts(attotime tm);
2729};
2830
2931#endif
trunk/src/lib/formats/m20_dsk.c
r19236r19237
167167LEGACY_FLOPPY_OPTIONS_START( m20 )
168168   LEGACY_FLOPPY_OPTION(m20_dsk, "img", "M20 disk image", m20_dsk_identify, m20_dsk_construct, NULL, NULL)
169169LEGACY_FLOPPY_OPTIONS_END
170
171
172/***************************************************************************
173
174    Copyright Olivier Galibert
175    All rights reserved.
176
177    Redistribution and use in source and binary forms, with or without
178    modification, are permitted provided that the following conditions are
179    met:
180
181        * Redistributions of source code must retain the above copyright
182          notice, this list of conditions and the following disclaimer.
183        * Redistributions in binary form must reproduce the above copyright
184          notice, this list of conditions and the following disclaimer in
185          the documentation and/or other materials provided with the
186          distribution.
187        * Neither the name 'MAME' nor the names of its contributors may be
188          used to endorse or promote products derived from this software
189          without specific prior written permission.
190
191    THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
192    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
193    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
194    DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
195    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
196    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
197    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
198    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
199    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
200    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
201    POSSIBILITY OF SUCH DAMAGE.
202
203****************************************************************************/
204
205/*********************************************************************
206
207    formats/m20_dsk.c
208
209    m20 format
210
211*********************************************************************/
212
213#include "emu.h"
214#include "formats/m20_dsk.h"
215
216m20_format::m20_format()
217{
218}
219
220const char *m20_format::name() const
221{
222   return "m20";
223}
224
225const char *m20_format::description() const
226{
227   return "M20 disk image";
228}
229
230const char *m20_format::extensions() const
231{
232   return "img";
233}
234
235bool m20_format::supports_save() const
236{
237   return false;
238}
239
240int m20_format::identify(io_generic *io, UINT32 form_factor)
241{
242   if(io_generic_size(io) == 286720)
243      return 50;
244   return 0;
245}
246
247bool m20_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
248{
249   for(int track = 0; track < 35; track++)
250      for(int head = 0; head < 2; head ++) {
251         bool mfm = track || head;
252         desc_pc_sector sects[16];
253         UINT8 sectdata[16*256];
254         io_generic_read(io, sectdata, 16*256*(track*2+head), 16*256);
255         for(int i=0; i<16; i++) {
256            int j = i/2 + (i & 1 ? 0 : 8);
257            sects[i].track = track;
258            sects[i].head = head;
259            sects[i].sector = j+1;
260            sects[i].size = mfm ? 1 : 0;
261            sects[i].actual_size = mfm ? 256 : 128;
262            sects[i].data = sectdata + 256*j;
263            sects[i].deleted = false;
264            sects[i].bad_crc = false;
265         }
266
267         if(mfm)
268            build_wd_track_mfm(track, head, image, 100000, 16, sects, 50, 32, 22);
269         else
270            build_wd_track_fm(track, head, image, 50000, 16, sects, 24, 16, 11);
271      }
272           
273   return true;
274}
275
276bool m20_format::save(io_generic *io, floppy_image *image)
277{
278   return false;
279}
280
281const floppy_format_type FLOPPY_M20_FORMAT = &floppy_image_format_creator<m20_format>;
trunk/src/lib/formats/m20_dsk.h
r19236r19237
1515
1616LEGACY_FLOPPY_OPTIONS_EXTERN(m20);
1717
18
19#include "wd177x_dsk.h"
20
21class m20_format : public floppy_image_format_t {
22public:
23   m20_format();
24
25   virtual int identify(io_generic *io, UINT32 form_factor);
26   virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image);
27   virtual bool save(io_generic *io, floppy_image *image);
28
29   virtual const char *name() const;
30   virtual const char *description() const;
31   virtual const char *extensions() const;
32   virtual bool supports_save() const;
33};
34
35extern const floppy_format_type FLOPPY_M20_FORMAT;
36
1837#endif /* M20_DSK_H */
trunk/src/mess/drivers/m20.c
r19236r19237
3838#include "cpu/z8000/z8000.h"
3939#include "cpu/i86/i86.h"
4040#include "video/mc6845.h"
41#include "machine/wd17xx.h"
41#include "machine/wd_fdc.h"
4242#include "machine/i8251.h"
4343#include "machine/i8255.h"
4444#include "machine/pit8253.h"
r19236r19237
5858        m_ttyi8251(*this, "i8251_2"),
5959        m_i8255(*this, "ppi8255"),
6060        m_i8259(*this, "i8259"),
61      m_wd177x(*this, "fd1797"),
61      m_fd1797(*this, "fd1797"),
62      m_floppy0(*this, "fd1797:0:5dd"),
63      m_floppy1(*this, "fd1797:1:5dd"),
6264      m_p_videoram(*this, "p_videoram"){ }
6365
6466    required_device<z8001_device> m_maincpu;
r19236r19237
6668    required_device<i8251_device> m_ttyi8251;
6769    required_device<i8255_device> m_i8255;
6870    required_device<pic8259_device> m_i8259;
69    required_device<fd1797_device> m_wd177x;
71    required_device<fd1797_t> m_fd1797;
72   required_device<floppy_image_device> m_floppy0;
73   required_device<floppy_image_device> m_floppy1;
7074
7175   required_shared_ptr<UINT16> m_p_videoram;
7276
77    virtual void machine_start();
7378    virtual void machine_reset();
7479
7580    DECLARE_READ16_MEMBER(m20_i8259_r);
r19236r19237
8489   DECLARE_WRITE_LINE_MEMBER(kbd_tx);
8590   DECLARE_WRITE8_MEMBER(kbd_put);
8691
87   bool m_port21_sd;
88
8992private:
9093   bool m_kbrecv_in_progress;
9194   int m_kbrecv_bitcount;
9295   UINT16 m_kbrecv_data;
9396   UINT8 m_port21;
97
9498public:
9599   DECLARE_DRIVER_INIT(m20);
96100   virtual void video_start();
97101   UINT32 screen_update_m20(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
98102   DECLARE_WRITE_LINE_MEMBER(kbd_rxrdy_int);
99   DECLARE_READ_LINE_MEMBER(wd177x_dden_r);
100   DECLARE_WRITE_LINE_MEMBER(wd177x_intrq_w);
103
104   DECLARE_FLOPPY_FORMATS( floppy_formats );
105
106   void fdc_intrq_w(bool state);
101107};
102108
103109
r19236r19237
204210{
205211   //printf("port21 write: offset 0x%x, data 0x%x\n", offset, data);
206212   m_port21 = (m_port21 & 0xf8) | (data & 0x7);
207   m_port21_sd = (data & 8) ? 1 : 0;
208   //printf("port21: sd = %d\n", m_port21_sd);
209213
210214   // floppy drive select
211215   if (data & 1) {
212      wd17xx_set_drive(m_wd177x, 0);
213      floppy_mon_w(floppy_get_device(machine(), 0) , 0);
214      floppy_drive_set_ready_state(floppy_get_device(machine(), 0), 1, 0);
216      m_floppy0->mon_w(0);
217      m_fd1797->set_floppy(m_floppy0);
215218   }
216   else {
217      floppy_mon_w(floppy_get_device(machine(), 0) , 1);
218      floppy_drive_set_ready_state(floppy_get_device(machine(), 0), 0, 0);
219   }
219   else
220      m_floppy0->mon_w(1);
220221
221222   if (data & 2) {
222      wd17xx_set_drive(m_wd177x, 1);
223      floppy_mon_w(floppy_get_device(machine(), 1) , 0);
224      floppy_drive_set_ready_state(floppy_get_device(machine(), 1), 1, 0);
223      m_floppy1->mon_w(0);
224      m_fd1797->set_floppy(m_floppy1);
225225   }
226   else {
227      floppy_mon_w(floppy_get_device(machine(), 1) , 1);
228      floppy_drive_set_ready_state(floppy_get_device(machine(), 1), 0, 0);
229   }
226   else
227      m_floppy1->mon_w(1);
230228
229   if(!(data & 3))
230      m_fd1797->set_floppy(NULL);
231
231232   // density select 1 - sd, 0 - dd
232   wd17xx_dden_w(m_wd177x, m_port21_sd);
233   m_fd1797->dden_w(data & 8);
233234}
234235
235236READ16_MEMBER(m20_state::m20_i8259_r)
r19236r19237
313314static ADDRESS_MAP_START(m20_io, AS_IO, 16, m20_state)
314315   ADDRESS_MAP_UNMAP_HIGH
315316
316   AM_RANGE(0x00, 0x01) AM_DEVREADWRITE8_LEGACY("fd1797", wd17xx_status_r, wd17xx_command_w, 0x00ff)
317   AM_RANGE(0x02, 0x03) AM_DEVREADWRITE8_LEGACY("fd1797", wd17xx_track_r, wd17xx_track_w, 0x00ff)
318   AM_RANGE(0x04, 0x05) AM_DEVREADWRITE8_LEGACY("fd1797", wd17xx_sector_r, wd17xx_sector_w, 0x00ff)
319   AM_RANGE(0x06, 0x07) AM_DEVREADWRITE8_LEGACY("fd1797", wd17xx_data_r, wd17xx_data_w, 0x00ff)
317   AM_RANGE(0x00, 0x07) AM_DEVREADWRITE8("fd1797", fd1797_t, read, write, 0x00ff)
320318
321319   AM_RANGE(0x20, 0x21) AM_READWRITE(port21_r, port21_w);
322320
r19236r19237
368366        return pic8259_acknowledge(device->machine().device("i8259"));
369367}
370368
369void m20_state::machine_start()
370{
371   m_fd1797->setup_intrq_cb(fd1797_t::line_cb(FUNC(m20_state::fdc_intrq_w), this));
372}
373
371374void m20_state::machine_reset()
372375{
373376   UINT8 *ROM = machine().root_device().memregion("maincpu")->base();
r19236r19237
376379    ROM += 0x10000; // don't know why they load at an offset, but let's go with it
377380
378381   m_port21 = 0xff;
379   m_port21_sd = 1;
380382
381383   m_maincpu->set_irq_acknowledge_callback(m20_irq_callback);
382384
383   wd17xx_mr_w(m_wd177x, 0);
384   //wd17xx_mr_w(m_wd177x, space, 1);
385   m_fd1797->reset();
385386
386387    memcpy(RAM, ROM, 8);  // we need only the reset vector
387388    m_maincpu->reset();     // reset the CPU to ensure it picks up the new vector
r19236r19237
416417   pic8259_ir4_w(machine().device("i8259"), state);
417418}
418419
419#if 1
420READ_LINE_MEMBER(m20_state::wd177x_dden_r)
420void m20_state::fdc_intrq_w(bool state)
421421{
422   //printf ("wd177x_dden_r called, returning %d\n", !m_port21_sd);
423   return !m_port21_sd;
424}
425#endif
426
427WRITE_LINE_MEMBER(m20_state::wd177x_intrq_w)
428{
429422   pic8259_ir0_w(machine().device("i8259"), state);
430423}
431424
r19236r19237
455448   DEVCB_NULL          // syndet
456449};
457450
458const wd17xx_interface m20_wd17xx_interface =
459{
460   /*DEVCB_NULL,*/ DEVCB_DRIVER_LINE_MEMBER(m20_state, wd177x_dden_r),
461   DEVCB_DRIVER_LINE_MEMBER(m20_state, wd177x_intrq_w),
462   DEVCB_NULL,
463   {FLOPPY_0, FLOPPY_1, NULL, NULL}
464};
465
466451static const floppy_interface m20_floppy_interface =
467452{
468453   DEVCB_NULL,
r19236r19237
539524   DEVCB_NULL
540525};
541526
527static SLOT_INTERFACE_START( m20_floppies )
528   SLOT_INTERFACE( "5dd", FLOPPY_525_DD )
529SLOT_INTERFACE_END
530
531FLOPPY_FORMATS_MEMBER( m20_state::floppy_formats )
532   FLOPPY_M20_FORMAT
533FLOPPY_FORMATS_END
534
542535static MACHINE_CONFIG_START( m20, m20_state )
543536   /* basic machine hardware */
544537   MCFG_CPU_ADD("maincpu", Z8001, MAIN_CLOCK)
r19236r19237
563556   MCFG_PALETTE_INIT(black_and_white)
564557
565558   /* Devices */
566   MCFG_FD1797_ADD("fd1797", m20_wd17xx_interface )
559   MCFG_FD1797x_ADD("fd1797", 1000000)
560   MCFG_FLOPPY_DRIVE_ADD("fd1797:0", m20_floppies, "5dd", NULL, m20_state::floppy_formats)
561   MCFG_FLOPPY_DRIVE_ADD("fd1797:1", m20_floppies, "5dd", NULL, m20_state::floppy_formats)
567562   MCFG_MC6845_ADD("crtc", MC6845, PIXEL_CLOCK/8, mc6845_intf)   /* hand tuned to get ~50 fps */
568563   MCFG_I8255A_ADD("ppi8255",  ppi_interface)
569564   MCFG_I8251_ADD("i8251_1", kbd_i8251_intf)

Previous 199869 Revisions Next


© 1997-2024 The MAME Team