trunk/src/emu/machine/wd_fdc.c
| r19236 | r19237 | |
| 69 | 69 | t_cmd = timer_alloc(TM_CMD); |
| 70 | 70 | t_track = timer_alloc(TM_TRACK); |
| 71 | 71 | t_sector = timer_alloc(TM_SECTOR); |
| 72 | | dden = false; |
| 72 | dden = disable_mfm; |
| 73 | 73 | floppy = 0; |
| 74 | 74 | |
| 75 | 75 | save_item(NAME(status)); |
| r19236 | r19237 | |
| 148 | 148 | |
| 149 | 149 | void wd_fdc_t::dden_w(bool _dden) |
| 150 | 150 | { |
| 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 | } |
| 152 | 160 | } |
| 153 | 161 | |
| 154 | 162 | astring wd_fdc_t::tts(attotime t) |
| r19236 | r19237 | |
| 333 | 341 | |
| 334 | 342 | bool wd_fdc_t::sector_matches() const |
| 335 | 343 | { |
| 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 | |
| 336 | 349 | if(cur_live.idbuf[0] != track || cur_live.idbuf[2] != sector) |
| 337 | 350 | return false; |
| 338 | 351 | if(!side_compare || (command & 2)) |
| r19236 | r19237 | |
| 357 | 370 | status = (status & ~(S_CRC|S_LOST|S_RNF|S_WP|S_DDM)) | S_BUSY; |
| 358 | 371 | drop_drq(); |
| 359 | 372 | if(side_control && floppy) |
| 360 | | floppy->ss_w(command & 0x02); |
| 373 | floppy->ss_w((command & 0x02) ? 1 : 0); |
| 361 | 374 | sub_state = motor_control ? SPINUP : SPINUP_DONE; |
| 362 | 375 | status_type_1 = false; |
| 363 | 376 | read_sector_continue(); |
| r19236 | r19237 | |
| 447 | 460 | status = (status & ~(S_LOST|S_RNF)) | S_BUSY; |
| 448 | 461 | drop_drq(); |
| 449 | 462 | if(side_control && floppy) |
| 450 | | floppy->ss_w(command & 0x02); |
| 463 | floppy->ss_w((command & 0x02) ? 1 : 0); |
| 451 | 464 | sub_state = motor_control ? SPINUP : SPINUP_DONE; |
| 452 | 465 | status_type_1 = false; |
| 453 | 466 | read_track_continue(); |
| r19236 | r19237 | |
| 514 | 527 | status = (status & ~(S_WP|S_DDM|S_LOST|S_RNF)) | S_BUSY; |
| 515 | 528 | drop_drq(); |
| 516 | 529 | if(side_control && floppy) |
| 517 | | floppy->ss_w(command & 0x02); |
| 530 | floppy->ss_w((command & 0x02) ? 1 : 0); |
| 518 | 531 | sub_state = motor_control ? SPINUP : SPINUP_DONE; |
| 519 | 532 | status_type_1 = false; |
| 520 | 533 | read_id_continue(); |
| r19236 | r19237 | |
| 579 | 592 | status = (status & ~(S_WP|S_DDM|S_LOST|S_RNF)) | S_BUSY; |
| 580 | 593 | drop_drq(); |
| 581 | 594 | if(side_control && floppy) |
| 582 | | floppy->ss_w(command & 0x02); |
| 595 | floppy->ss_w((command & 0x02) ? 1 : 0); |
| 583 | 596 | sub_state = motor_control ? SPINUP : SPINUP_DONE; |
| 584 | 597 | status_type_1 = false; |
| 585 | 598 | |
| r19236 | r19237 | |
| 654 | 667 | sprintf(buf, "%02x", format_last_byte); |
| 655 | 668 | format_description_string += buf; |
| 656 | 669 | } |
| 657 | | logerror("wd1772: track description %s\n", format_description_string.cstr()); |
| 670 | logerror("%s: track description %s\n", tag(), format_description_string.cstr()); |
| 658 | 671 | command_end(); |
| 659 | 672 | return; |
| 660 | 673 | |
| r19236 | r19237 | |
| 675 | 688 | status = (status & ~(S_CRC|S_LOST|S_RNF|S_WP|S_DDM)) | S_BUSY; |
| 676 | 689 | drop_drq(); |
| 677 | 690 | if(side_control && floppy) |
| 678 | | floppy->ss_w(command & 0x02); |
| 691 | floppy->ss_w((command & 0x02) ? 1 : 0); |
| 679 | 692 | sub_state = motor_control ? SPINUP : SPINUP_DONE; |
| 680 | 693 | status_type_1 = false; |
| 681 | 694 | write_sector_continue(); |
| r19236 | r19237 | |
| 859 | 872 | cmd_buffer = -1; |
| 860 | 873 | |
| 861 | 874 | 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; |
| 873 | 886 | } |
| 874 | 887 | } |
| 875 | 888 | |
| r19236 | r19237 | |
| 877 | 890 | { |
| 878 | 891 | if (inverted_bus) val ^= 0xff; |
| 879 | 892 | |
| 880 | | logerror("wd1772 cmd: %02x\n", val); |
| 881 | | |
| 882 | 893 | if(intrq && !(intrq_cond & I_IMM)) { |
| 883 | 894 | intrq = false; |
| 884 | 895 | if(!intrq_cb.isnull()) |
| r19236 | r19237 | |
| 891 | 902 | |
| 892 | 903 | cmd_buffer = val; |
| 893 | 904 | |
| 894 | | delay_cycles(t_cmd, dden ? 192 : 46); |
| 905 | delay_cycles(t_cmd, dden ? 1 : 1); |
| 895 | 906 | } |
| 896 | 907 | |
| 897 | 908 | UINT8 wd_fdc_t::status_r() |
| r19236 | r19237 | |
| 952 | 963 | return; |
| 953 | 964 | |
| 954 | 965 | track_buffer = val; |
| 955 | | delay_cycles(t_track, dden ? 64 : 32); |
| 966 | delay_cycles(t_track, dden ? 32 : 16); |
| 956 | 967 | } |
| 957 | 968 | |
| 958 | 969 | UINT8 wd_fdc_t::track_r() |
| r19236 | r19237 | |
| 978 | 989 | return; |
| 979 | 990 | |
| 980 | 991 | sector_buffer = val; |
| 981 | | delay_cycles(t_sector, dden ? 64 : 32); |
| 992 | delay_cycles(t_sector, dden ? 32 : 16); |
| 982 | 993 | } |
| 983 | 994 | |
| 984 | 995 | UINT8 wd_fdc_t::sector_r() |
| r19236 | r19237 | |
| 1166 | 1177 | cur_live.previous_type = live_info::PT_NONE; |
| 1167 | 1178 | cur_live.data_bit_context = false; |
| 1168 | 1179 | cur_live.byte_counter = 0; |
| 1169 | | pll_reset(cur_live.tm); |
| 1180 | pll_reset(dden, cur_live.tm); |
| 1170 | 1181 | checkpoint_live = cur_live; |
| 1171 | 1182 | pll_save_checkpoint(); |
| 1172 | 1183 | |
| r19236 | r19237 | |
| 1196 | 1207 | { |
| 1197 | 1208 | if(!cur_live.tm.is_never()) { |
| 1198 | 1209 | 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()); |
| 1200 | 1211 | rollback(); |
| 1201 | 1212 | live_run(machine().time()); |
| 1202 | 1213 | pll_commit(floppy, cur_live.tm); |
| 1203 | 1214 | } 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()); |
| 1205 | 1216 | pll_commit(floppy, cur_live.tm); |
| 1206 | 1217 | if(cur_live.next_state != -1) { |
| 1207 | 1218 | cur_live.state = cur_live.next_state; |
| r19236 | r19237 | |
| 1288 | 1299 | // logerror("write %02x %04x %04x\n", mfm, cur_live.crc, raw); |
| 1289 | 1300 | } |
| 1290 | 1301 | |
| 1302 | |
| 1303 | void 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 | |
| 1291 | 1315 | void wd_fdc_t::live_run(attotime limit) |
| 1292 | 1316 | { |
| 1293 | 1317 | if(cur_live.state == IDLE || cur_live.next_state != -1) |
| r19236 | r19237 | |
| 1328 | 1352 | cur_live.bit_counter); |
| 1329 | 1353 | #endif |
| 1330 | 1354 | |
| 1331 | | if(cur_live.shift_reg == 0x4489) { |
| 1355 | if(!dden && cur_live.shift_reg == 0x4489) { |
| 1332 | 1356 | cur_live.crc = 0x443b; |
| 1333 | 1357 | cur_live.data_separator_phase = false; |
| 1334 | 1358 | cur_live.bit_counter = 0; |
| 1335 | 1359 | cur_live.state = READ_HEADER_BLOCK_HEADER; |
| 1336 | 1360 | } |
| 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 | } |
| 1337 | 1371 | break; |
| 1338 | 1372 | |
| 1339 | 1373 | case READ_HEADER_BLOCK_HEADER: { |
| r19236 | r19237 | |
| 1382 | 1416 | if(cur_live.bit_counter & 15) |
| 1383 | 1417 | break; |
| 1384 | 1418 | 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); |
| 1385 | 1420 | cur_live.idbuf[slot] = cur_live.data_reg; |
| 1386 | 1421 | if(slot == 5) { |
| 1387 | 1422 | live_delay(IDLE); |
| r19236 | r19237 | |
| 1430 | 1465 | (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00), |
| 1431 | 1466 | cur_live.bit_counter >> 4, cur_live.bit_counter & 15); |
| 1432 | 1467 | #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 | } |
| 1437 | 1473 | |
| 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 | } |
| 1443 | 1497 | } |
| 1444 | 1498 | break; |
| 1445 | 1499 | |
| r19236 | r19237 | |
| 1570 | 1624 | } else |
| 1571 | 1625 | format_last_byte_count++; |
| 1572 | 1626 | |
| 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; |
| 1585 | 1641 | 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; |
| 1590 | 1671 | } |
| 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 | } |
| 1596 | 1698 | } |
| 1597 | 1699 | set_drq(); |
| 1598 | 1700 | cur_live.state = WRITE_BYTE; |
| r19236 | r19237 | |
| 1614 | 1716 | case TRACK_DONE: |
| 1615 | 1717 | if(cur_live.previous_type == live_info::PT_CRC_1) { |
| 1616 | 1718 | 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); |
| 1618 | 1723 | cur_live.state = WRITE_BYTE; |
| 1619 | 1724 | cur_live.bit_counter = 16; |
| 1620 | 1725 | checkpoint(); |
| r19236 | r19237 | |
| 1626 | 1731 | cur_live.state = WRITE_BYTE; |
| 1627 | 1732 | cur_live.bit_counter = 16; |
| 1628 | 1733 | 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; |
| 1642 | 1762 | } |
| 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; |
| 1649 | 1794 | } |
| 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; |
| 1660 | 1795 | } |
| 1661 | 1796 | |
| 1797 | |
| 1662 | 1798 | checkpoint(); |
| 1663 | 1799 | break; |
| 1664 | 1800 | |
| r19236 | r19237 | |
| 1693 | 1829 | return; |
| 1694 | 1830 | } |
| 1695 | 1831 | 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 | |
| 1696 | 1844 | case 22: |
| 1697 | 1845 | cur_live.state = WRITE_BYTE; |
| 1698 | 1846 | cur_live.bit_counter = 16; |
| r19236 | r19237 | |
| 1734 | 1882 | int wd_fdc_t::step_time(int mode) const |
| 1735 | 1883 | { |
| 1736 | 1884 | const static int step_times[4] = { 12000, 24000, 40000, 60000 }; |
| 1737 | | return step_times[mode]; |
| 1885 | return step_times[mode]/10; |
| 1738 | 1886 | } |
| 1739 | 1887 | |
| 1740 | 1888 | int wd_fdc_t::settle_time() const |
| r19236 | r19237 | |
| 1748 | 1896 | clock_ratio = 1; |
| 1749 | 1897 | } |
| 1750 | 1898 | |
| 1751 | | void wd_fdc_analog_t::pll_reset(attotime when) |
| 1899 | void wd_fdc_analog_t::pll_reset(bool fm, attotime when) |
| 1752 | 1900 | { |
| 1753 | 1901 | cur_pll.reset(when); |
| 1754 | | cur_pll.set_clock(clocks_to_attotime(4)); |
| 1902 | cur_pll.set_clock(clocks_to_attotime(fm ? 4 : 2)); |
| 1755 | 1903 | } |
| 1756 | 1904 | |
| 1757 | 1905 | void wd_fdc_analog_t::pll_start_writing(attotime tm) |
| r19236 | r19237 | |
| 1795 | 1943 | clock_ratio = 4; |
| 1796 | 1944 | } |
| 1797 | 1945 | |
| 1798 | | void wd_fdc_digital_t::pll_reset(attotime when) |
| 1946 | void wd_fdc_digital_t::pll_reset(bool fm, attotime when) |
| 1799 | 1947 | { |
| 1800 | 1948 | cur_pll.reset(when); |
| 1801 | 1949 | cur_pll.set_clock(clocks_to_attotime(1)); |
| r19236 | r19237 | |
| 1993 | 2141 | |
| 1994 | 2142 | fd1771_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) |
| 1995 | 2143 | { |
| 2144 | disable_mfm = true; |
| 1996 | 2145 | inverted_bus = true; |
| 1997 | 2146 | side_control = false; |
| 1998 | 2147 | side_compare = false; |
| r19236 | r19237 | |
| 2003 | 2152 | |
| 2004 | 2153 | fd1781_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) |
| 2005 | 2154 | { |
| 2155 | disable_mfm = false; |
| 2006 | 2156 | inverted_bus = true; |
| 2007 | 2157 | side_control = false; |
| 2008 | 2158 | side_compare = false; |
| r19236 | r19237 | |
| 2013 | 2163 | |
| 2014 | 2164 | fd1791_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) |
| 2015 | 2165 | { |
| 2166 | disable_mfm = false; |
| 2016 | 2167 | inverted_bus = true; |
| 2017 | 2168 | side_control = false; |
| 2018 | 2169 | side_compare = true; |
| r19236 | r19237 | |
| 2023 | 2174 | |
| 2024 | 2175 | fd1792_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) |
| 2025 | 2176 | { |
| 2177 | disable_mfm = true; |
| 2026 | 2178 | inverted_bus = true; |
| 2027 | 2179 | side_control = false; |
| 2028 | 2180 | side_compare = true; |
| r19236 | r19237 | |
| 2033 | 2185 | |
| 2034 | 2186 | fd1793_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) |
| 2035 | 2187 | { |
| 2188 | disable_mfm = false; |
| 2036 | 2189 | inverted_bus = false; |
| 2037 | 2190 | side_control = false; |
| 2038 | 2191 | side_compare = true; |
| r19236 | r19237 | |
| 2043 | 2196 | |
| 2044 | 2197 | fd1794_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) |
| 2045 | 2198 | { |
| 2199 | disable_mfm = true; |
| 2046 | 2200 | inverted_bus = false; |
| 2047 | 2201 | side_control = false; |
| 2048 | 2202 | side_compare = true; |
| r19236 | r19237 | |
| 2053 | 2207 | |
| 2054 | 2208 | fd1795_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) |
| 2055 | 2209 | { |
| 2210 | disable_mfm = false; |
| 2056 | 2211 | inverted_bus = true; |
| 2057 | | side_control = false; |
| 2212 | side_control = true; |
| 2058 | 2213 | side_compare = false; |
| 2059 | 2214 | head_control = true; |
| 2060 | 2215 | motor_control = false; |
| r19236 | r19237 | |
| 2063 | 2218 | |
| 2064 | 2219 | fd1797_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) |
| 2065 | 2220 | { |
| 2221 | disable_mfm = false; |
| 2066 | 2222 | inverted_bus = false; |
| 2067 | | side_control = false; |
| 2223 | side_control = true; |
| 2068 | 2224 | side_compare = false; |
| 2069 | 2225 | head_control = true; |
| 2070 | 2226 | motor_control = false; |
| r19236 | r19237 | |
| 2073 | 2229 | |
| 2074 | 2230 | mb8866_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) |
| 2075 | 2231 | { |
| 2232 | disable_mfm = false; |
| 2076 | 2233 | inverted_bus = true; |
| 2077 | 2234 | side_control = false; |
| 2078 | 2235 | side_compare = true; |
| r19236 | r19237 | |
| 2083 | 2240 | |
| 2084 | 2241 | mb8876_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) |
| 2085 | 2242 | { |
| 2243 | disable_mfm = false; |
| 2086 | 2244 | inverted_bus = true; |
| 2087 | 2245 | side_control = false; |
| 2088 | 2246 | side_compare = true; |
| r19236 | r19237 | |
| 2093 | 2251 | |
| 2094 | 2252 | mb8877_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) |
| 2095 | 2253 | { |
| 2254 | disable_mfm = false; |
| 2096 | 2255 | inverted_bus = false; |
| 2097 | 2256 | side_control = false; |
| 2098 | 2257 | side_compare = true; |
| r19236 | r19237 | |
| 2103 | 2262 | |
| 2104 | 2263 | fd1761_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) |
| 2105 | 2264 | { |
| 2265 | disable_mfm = false; |
| 2106 | 2266 | inverted_bus = true; |
| 2107 | 2267 | side_control = false; |
| 2108 | 2268 | side_compare = true; |
| r19236 | r19237 | |
| 2113 | 2273 | |
| 2114 | 2274 | fd1763_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) |
| 2115 | 2275 | { |
| 2276 | disable_mfm = false; |
| 2116 | 2277 | inverted_bus = false; |
| 2117 | 2278 | side_control = false; |
| 2118 | 2279 | side_compare = true; |
| r19236 | r19237 | |
| 2123 | 2284 | |
| 2124 | 2285 | fd1765_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) |
| 2125 | 2286 | { |
| 2287 | disable_mfm = false; |
| 2126 | 2288 | inverted_bus = true; |
| 2127 | 2289 | side_control = true; |
| 2128 | 2290 | side_compare = false; |
| r19236 | r19237 | |
| 2133 | 2295 | |
| 2134 | 2296 | fd1767_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) |
| 2135 | 2297 | { |
| 2298 | disable_mfm = false; |
| 2136 | 2299 | inverted_bus = false; |
| 2137 | 2300 | side_control = true; |
| 2138 | 2301 | side_compare = false; |
| r19236 | r19237 | |
| 2143 | 2306 | |
| 2144 | 2307 | wd2791_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) |
| 2145 | 2308 | { |
| 2309 | disable_mfm = false; |
| 2146 | 2310 | inverted_bus = true; |
| 2147 | 2311 | side_control = false; |
| 2148 | 2312 | side_compare = true; |
| r19236 | r19237 | |
| 2153 | 2317 | |
| 2154 | 2318 | wd2793_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) |
| 2155 | 2319 | { |
| 2320 | disable_mfm = false; |
| 2156 | 2321 | inverted_bus = false; |
| 2157 | 2322 | side_control = false; |
| 2158 | 2323 | side_compare = true; |
| r19236 | r19237 | |
| 2163 | 2328 | |
| 2164 | 2329 | wd2795_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) |
| 2165 | 2330 | { |
| 2331 | disable_mfm = false; |
| 2166 | 2332 | inverted_bus = true; |
| 2167 | 2333 | side_control = true; |
| 2168 | 2334 | side_compare = false; |
| r19236 | r19237 | |
| 2173 | 2339 | |
| 2174 | 2340 | wd2797_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) |
| 2175 | 2341 | { |
| 2342 | disable_mfm = false; |
| 2176 | 2343 | inverted_bus = false; |
| 2177 | 2344 | side_control = true; |
| 2178 | 2345 | side_compare = false; |
| r19236 | r19237 | |
| 2183 | 2350 | |
| 2184 | 2351 | wd1770_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) |
| 2185 | 2352 | { |
| 2353 | disable_mfm = false; |
| 2186 | 2354 | inverted_bus = false; |
| 2187 | 2355 | side_control = false; |
| 2188 | 2356 | side_compare = false; |
| r19236 | r19237 | |
| 2193 | 2361 | |
| 2194 | 2362 | wd1772_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) |
| 2195 | 2363 | { |
| 2364 | disable_mfm = false; |
| 2196 | 2365 | inverted_bus = false; |
| 2197 | 2366 | side_control = false; |
| 2198 | 2367 | side_compare = false; |
| r19236 | r19237 | |
| 2214 | 2383 | |
| 2215 | 2384 | wd1773_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) |
| 2216 | 2385 | { |
| 2386 | disable_mfm = false; |
| 2217 | 2387 | inverted_bus = false; |
| 2218 | 2388 | side_control = false; |
| 2219 | 2389 | side_compare = true; |
trunk/src/lib/formats/m20_dsk.c
| r19236 | r19237 | |
| 167 | 167 | LEGACY_FLOPPY_OPTIONS_START( m20 ) |
| 168 | 168 | LEGACY_FLOPPY_OPTION(m20_dsk, "img", "M20 disk image", m20_dsk_identify, m20_dsk_construct, NULL, NULL) |
| 169 | 169 | LEGACY_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 | |
| 216 | m20_format::m20_format() |
| 217 | { |
| 218 | } |
| 219 | |
| 220 | const char *m20_format::name() const |
| 221 | { |
| 222 | return "m20"; |
| 223 | } |
| 224 | |
| 225 | const char *m20_format::description() const |
| 226 | { |
| 227 | return "M20 disk image"; |
| 228 | } |
| 229 | |
| 230 | const char *m20_format::extensions() const |
| 231 | { |
| 232 | return "img"; |
| 233 | } |
| 234 | |
| 235 | bool m20_format::supports_save() const |
| 236 | { |
| 237 | return false; |
| 238 | } |
| 239 | |
| 240 | int 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 | |
| 247 | bool 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 | |
| 276 | bool m20_format::save(io_generic *io, floppy_image *image) |
| 277 | { |
| 278 | return false; |
| 279 | } |
| 280 | |
| 281 | const floppy_format_type FLOPPY_M20_FORMAT = &floppy_image_format_creator<m20_format>; |
trunk/src/mess/drivers/m20.c
| r19236 | r19237 | |
| 38 | 38 | #include "cpu/z8000/z8000.h" |
| 39 | 39 | #include "cpu/i86/i86.h" |
| 40 | 40 | #include "video/mc6845.h" |
| 41 | | #include "machine/wd17xx.h" |
| 41 | #include "machine/wd_fdc.h" |
| 42 | 42 | #include "machine/i8251.h" |
| 43 | 43 | #include "machine/i8255.h" |
| 44 | 44 | #include "machine/pit8253.h" |
| r19236 | r19237 | |
| 58 | 58 | m_ttyi8251(*this, "i8251_2"), |
| 59 | 59 | m_i8255(*this, "ppi8255"), |
| 60 | 60 | 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"), |
| 62 | 64 | m_p_videoram(*this, "p_videoram"){ } |
| 63 | 65 | |
| 64 | 66 | required_device<z8001_device> m_maincpu; |
| r19236 | r19237 | |
| 66 | 68 | required_device<i8251_device> m_ttyi8251; |
| 67 | 69 | required_device<i8255_device> m_i8255; |
| 68 | 70 | 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; |
| 70 | 74 | |
| 71 | 75 | required_shared_ptr<UINT16> m_p_videoram; |
| 72 | 76 | |
| 77 | virtual void machine_start(); |
| 73 | 78 | virtual void machine_reset(); |
| 74 | 79 | |
| 75 | 80 | DECLARE_READ16_MEMBER(m20_i8259_r); |
| r19236 | r19237 | |
| 84 | 89 | DECLARE_WRITE_LINE_MEMBER(kbd_tx); |
| 85 | 90 | DECLARE_WRITE8_MEMBER(kbd_put); |
| 86 | 91 | |
| 87 | | bool m_port21_sd; |
| 88 | | |
| 89 | 92 | private: |
| 90 | 93 | bool m_kbrecv_in_progress; |
| 91 | 94 | int m_kbrecv_bitcount; |
| 92 | 95 | UINT16 m_kbrecv_data; |
| 93 | 96 | UINT8 m_port21; |
| 97 | |
| 94 | 98 | public: |
| 95 | 99 | DECLARE_DRIVER_INIT(m20); |
| 96 | 100 | virtual void video_start(); |
| 97 | 101 | UINT32 screen_update_m20(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
| 98 | 102 | 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); |
| 101 | 107 | }; |
| 102 | 108 | |
| 103 | 109 | |
| r19236 | r19237 | |
| 204 | 210 | { |
| 205 | 211 | //printf("port21 write: offset 0x%x, data 0x%x\n", offset, data); |
| 206 | 212 | m_port21 = (m_port21 & 0xf8) | (data & 0x7); |
| 207 | | m_port21_sd = (data & 8) ? 1 : 0; |
| 208 | | //printf("port21: sd = %d\n", m_port21_sd); |
| 209 | 213 | |
| 210 | 214 | // floppy drive select |
| 211 | 215 | 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); |
| 215 | 218 | } |
| 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); |
| 220 | 221 | |
| 221 | 222 | 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); |
| 225 | 225 | } |
| 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); |
| 230 | 228 | |
| 229 | if(!(data & 3)) |
| 230 | m_fd1797->set_floppy(NULL); |
| 231 | |
| 231 | 232 | // density select 1 - sd, 0 - dd |
| 232 | | wd17xx_dden_w(m_wd177x, m_port21_sd); |
| 233 | m_fd1797->dden_w(data & 8); |
| 233 | 234 | } |
| 234 | 235 | |
| 235 | 236 | READ16_MEMBER(m20_state::m20_i8259_r) |
| r19236 | r19237 | |
| 313 | 314 | static ADDRESS_MAP_START(m20_io, AS_IO, 16, m20_state) |
| 314 | 315 | ADDRESS_MAP_UNMAP_HIGH |
| 315 | 316 | |
| 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) |
| 320 | 318 | |
| 321 | 319 | AM_RANGE(0x20, 0x21) AM_READWRITE(port21_r, port21_w); |
| 322 | 320 | |
| r19236 | r19237 | |
| 368 | 366 | return pic8259_acknowledge(device->machine().device("i8259")); |
| 369 | 367 | } |
| 370 | 368 | |
| 369 | void m20_state::machine_start() |
| 370 | { |
| 371 | m_fd1797->setup_intrq_cb(fd1797_t::line_cb(FUNC(m20_state::fdc_intrq_w), this)); |
| 372 | } |
| 373 | |
| 371 | 374 | void m20_state::machine_reset() |
| 372 | 375 | { |
| 373 | 376 | UINT8 *ROM = machine().root_device().memregion("maincpu")->base(); |
| r19236 | r19237 | |
| 376 | 379 | ROM += 0x10000; // don't know why they load at an offset, but let's go with it |
| 377 | 380 | |
| 378 | 381 | m_port21 = 0xff; |
| 379 | | m_port21_sd = 1; |
| 380 | 382 | |
| 381 | 383 | m_maincpu->set_irq_acknowledge_callback(m20_irq_callback); |
| 382 | 384 | |
| 383 | | wd17xx_mr_w(m_wd177x, 0); |
| 384 | | //wd17xx_mr_w(m_wd177x, space, 1); |
| 385 | m_fd1797->reset(); |
| 385 | 386 | |
| 386 | 387 | memcpy(RAM, ROM, 8); // we need only the reset vector |
| 387 | 388 | m_maincpu->reset(); // reset the CPU to ensure it picks up the new vector |
| r19236 | r19237 | |
| 416 | 417 | pic8259_ir4_w(machine().device("i8259"), state); |
| 417 | 418 | } |
| 418 | 419 | |
| 419 | | #if 1 |
| 420 | | READ_LINE_MEMBER(m20_state::wd177x_dden_r) |
| 420 | void m20_state::fdc_intrq_w(bool state) |
| 421 | 421 | { |
| 422 | | //printf ("wd177x_dden_r called, returning %d\n", !m_port21_sd); |
| 423 | | return !m_port21_sd; |
| 424 | | } |
| 425 | | #endif |
| 426 | | |
| 427 | | WRITE_LINE_MEMBER(m20_state::wd177x_intrq_w) |
| 428 | | { |
| 429 | 422 | pic8259_ir0_w(machine().device("i8259"), state); |
| 430 | 423 | } |
| 431 | 424 | |
| r19236 | r19237 | |
| 455 | 448 | DEVCB_NULL // syndet |
| 456 | 449 | }; |
| 457 | 450 | |
| 458 | | const 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 | | |
| 466 | 451 | static const floppy_interface m20_floppy_interface = |
| 467 | 452 | { |
| 468 | 453 | DEVCB_NULL, |
| r19236 | r19237 | |
| 539 | 524 | DEVCB_NULL |
| 540 | 525 | }; |
| 541 | 526 | |
| 527 | static SLOT_INTERFACE_START( m20_floppies ) |
| 528 | SLOT_INTERFACE( "5dd", FLOPPY_525_DD ) |
| 529 | SLOT_INTERFACE_END |
| 530 | |
| 531 | FLOPPY_FORMATS_MEMBER( m20_state::floppy_formats ) |
| 532 | FLOPPY_M20_FORMAT |
| 533 | FLOPPY_FORMATS_END |
| 534 | |
| 542 | 535 | static MACHINE_CONFIG_START( m20, m20_state ) |
| 543 | 536 | /* basic machine hardware */ |
| 544 | 537 | MCFG_CPU_ADD("maincpu", Z8001, MAIN_CLOCK) |
| r19236 | r19237 | |
| 563 | 556 | MCFG_PALETTE_INIT(black_and_white) |
| 564 | 557 | |
| 565 | 558 | /* 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) |
| 567 | 562 | MCFG_MC6845_ADD("crtc", MC6845, PIXEL_CLOCK/8, mc6845_intf) /* hand tuned to get ~50 fps */ |
| 568 | 563 | MCFG_I8255A_ADD("ppi8255", ppi_interface) |
| 569 | 564 | MCFG_I8251_ADD("i8251_1", kbd_i8251_intf) |