void Z47Interface::out(BYTE addr, BYTE val) { BYTE offset = getPortOffset(addr); debugss(ssH47, ALL, "(%d) = 0x%02x\n", addr, val); switch (offset) { case StatusPort_Offset_c: debugss(ssH47, ALL, "StatusPort\n"); writeStatus(val); break; case DataPort_Offset_c: debugss(ssH47, ALL, " DataPort\n"); writeData(val); break; default: debugss(ssH47, ERROR, "Unknown Port offset - %d\n", offset); break; } }
void HardSectoredDisk::eject(const char* name) { FILE* file; debugss(ssFloppyDisk, ALL, "Save: %s\n", name); if ((file = fopen(name, "wb")) != nullptr) { unsigned long readCount; for (int head = 0; head < sides_m; head++) { for (int track = 0; track < tracks_m; track++) { if ((readCount = fwrite(&rawImage_m[head][track][0], bytesPerTrack_c, 1, file)) != 1) { debugss(ssFloppyDisk, ERROR, "Unable to save file: %s head: %d track: %d\n", name, head, track); } } } fclose(file); } else { debugss(ssFloppyDisk, WARNING, "unable to save file - %s\n", name); } }
void Z47Controller::processReadReadyStatus(void) { debugss(ssH47, ALL, "\n"); statePosition_m++; if (statePosition_m == 2) { commandComplete(); return; } if (statePosition_m != 1) { debugss(ssH47, ERROR, "Unexpected position\n"); } dataToTransmit_m = readyState; curLinkState = st_Link_AwaitingToTransmit_c; countDown_m = 10; // after reading the status, the changed status bits must be reset. readyState &= ~(stat_Ready_Drive0ReadyChanged_c | stat_Ready_Drive1ReadyChanged_c | stat_Ready_Drive2ReadyChanged_c | stat_Ready_Drive3ReadyChanged_c); }
void Z47Controller::processReadSectorsBufffered(BYTE val) { statePosition_m++; debugss(ssH47, ALL, "statePosition: %d\n", statePosition_m); if (bytesToTransfer == 0) { debugss(ssH47, ALL, "All Sectors Read\n"); commandComplete(); return; } if (statePosition_m > 3) { dataToTransmit_m = diskData[diskOffset++]; bytesToTransfer--; curLinkState = st_Link_AwaitingToTransmit_c; countDown_m = 10; return; } if (statePosition_m == 3) { // val passed in is drive and side. decodeSideDriveSector(val); diskOffset = track_m * (sectorSize * 26) + ((sector_m - 1) * sectorSize); bytesToTransfer = sectorCount * sectorSize - 1; // reset sector count sectorCount = 1; dataToTransmit_m = diskData[diskOffset++]; curLinkState = st_Link_AwaitingToTransmit_c; countDown_m = 10; return; } if (statePosition_m == 2) { decodeTrack(val); // based on side_m and drive_m set value to return (by asking drive - which asks disk) // but for now just say single sided, single density, and sector length byte of 128 // (which is hopefully 0); curLinkState = st_Link_AwaitingToReqReceive_c; countDown_m = 10; return; } if (statePosition_m == 1) { // val invalid. curLinkState = st_Link_AwaitingToReqReceive_c; countDown_m = 10; } }
bool Z47Controller::connectDrive(BYTE unitNum, DiskDrive* drive) { debugss(ssH47, ALL, "%d - %p\n", unitNum, drive); if (unitNum < numDrives_c) { if (drives_m[unitNum] == 0) { drives_m[unitNum] = drive; } else { debugss(ssH47, ERROR, "drive conflict - %d.\n", unitNum); return false; } } else { debugss(ssH47, ERROR, "invalid drive - %d\n", unitNum); return false; } return true; }
BYTE Z47Interface::in(BYTE addr) { debugss(ssH47, ALL, "(%d)\n", addr); BYTE offset = getPortOffset(addr); BYTE data = 0; switch (offset) { case StatusPort_Offset_c: readStatus(data); debugss(ssH47, ALL, "StatusPort - 0x%02x\n", data); break; case DataPort_Offset_c: readData(data); debugss(ssH47, ALL, "DataPort - 0x%02x\n", data); break; default: debugss(ssH47, ERROR, "Unknown Port offset - %d\n", offset); break; } return data; }
SoftSectoredDisk::SoftSectoredDisk(const char* name, DiskImageFormat format): initialized_m(false) { debugss(ssFloppyDisk, INFO, "Insert Disk: %s\n", name); if (format == dif_Unknown) { determineDiskFormat(name, format); } switch (format) { case dif_IMD: readIMD(name); break; case dif_TD0: readTD0(name); break; case dif_RAW: readRaw(name); break; case dif_8RAW: readRaw8(name); break; default: // Unknown format debugss(ssFloppyDisk, ERROR, "Unknown disk format: %d\n", format); break; } }
bool MMS77320::connectDrive(BYTE unitNum, GenericSASIDrive* drive) { bool retVal = false; debugss(ssMMS77320, INFO, "unit (%d), drive (%p)\n", unitNum, drive); if (unitNum < numDisks_c) { if (drives_m[unitNum] == NULL) { drives_m[unitNum] = drive; retVal = true; } else { debugss(ssMMS77320, ERROR, "drive already connect\n"); } } else { debugss(ssMMS77320, ERROR, "Invalid unit number (%d)\n", unitNum); } return (retVal); }
void Z47Controller::processLoadSectorCount(BYTE val) { debugss(ssH47, ALL, "\n"); statePosition_m++; if (statePosition_m == 3) { sectorCount |= val; debugss(ssH47, ALL, "sector Count = %d\n", sectorCount); commandComplete(); return; } if (statePosition_m == 2) { // val passed in is MSB of sector count. sectorCount = (val << 8); curLinkState = st_Link_AwaitingToReqReceive_c; countDown_m = 10; return; } if (statePosition_m == 1) { // val invalid. curLinkState = st_Link_AwaitingToReqReceive_c; countDown_m = 10; } }
void Z47Interface::writeStatus(BYTE cmd) { debugss(ssH47, ALL, "cmd = 0x%02x\n", cmd); if ((cmd & cmd_MasterReset_c) == cmd_MasterReset_c) { debugss(ssH47, INFO, "Master Reset\n"); reset(); } if ((cmd & cmd_U137BSet_c) == cmd_U137BSet_c) { debugss(ssH47, INFO, "FlipFlop U137B\n"); } if ((cmd & cmd_InterruptsEnabled_c) == cmd_InterruptsEnabled_c) { debugss(ssH47, INFO, "Interrupts Enabled\n"); interruptsEnabled_m = true; } else { interruptsEnabled_m = false; } if ((cmd & cmd_Undefined_c) != 0) { debugss(ssH47, WARNING, "Unexpected command bits: 0x%02x\n", cmd); } }
bool SoftSectoredDisk::readRaw(const char* name) { // Currently just supporting the RAW HDOS 3.0 disk images... 40 track, single density, // single sided, 10 sectors/track, 256 bytes/sector. std::ifstream file; unsigned long int fileSize; unsigned long int pos = 0; BYTE* buf; file.open(name, std::ios::binary); if (!file.is_open()) { debugss(ssFloppyDisk, ERROR, "Unable to open file: %s\n", name); return false; } file.seekg(0, std::ios::end); fileSize = file.tellg(); file.seekg(0, std::ios::beg); buf = new BYTE[fileSize]; file.read((char*) buf, fileSize); file.close(); debugss(ssFloppyDisk, INFO, "RAW File: %s\n", name); if (fileSize != (256 * 10 * 40)) { debugss(ssFloppyDisk, ERROR, "Invalid File Size: %s - %ld\n", name, fileSize); delete [] buf; return false; } for (int trk = 0; trk < 40; trk++) { Track* track = new Track(0, trk); for (int sect = 0; sect < 10; sect++, pos += 256) { Sector* sector = new Sector(0, trk, sect, 256, &buf[pos]); track->addSector(sector); track->setDensity(Track::singleDensity); track->setDataRate(Track::dr_300kbps); } tracks_m[0].push_back(track); } numTracks_m = 40; numHeads_m = 1; initialized_m = false; return true; }
HardSectoredDisk::HardSectoredDisk(const char* name) { FILE* file; initialized_m = true; memset(rawImage_m, 0, maxHeads_c * bytesPerTrack_c * maxTracksPerSide_c); if ((file = fopen(name, "r")) != nullptr) { unsigned long readCount; int trk = 0; int head = 0; do { if (trk == 80) { // Check to see if we read both sides. if (head == 1) { break; } trk = 0; head++; } if ((readCount = fread(&rawImage_m[head][trk][0], bytesPerTrack_c, 1, file)) == 1) { trk++; } else if ((trk == 0) && (head == 1)) { // check to see if we have to adjust side and track. head = 0; trk = 80; } } while (readCount == 1); tracks_m = trk; sides_m = head + 1; debugss(ssFloppyDisk, ALL, "Sides: %d Tracks: %d\n", sides_m, tracks_m); fclose(file); } else { debugss(ssFloppyDisk, ERROR, "unable to open file - %s\n", name); initialized_m = false; } if (initialized_m) { debugss(ssFloppyDisk, INFO, "Success %s\n", name); } }
void MMS77316::out(BYTE addr, BYTE val) { BYTE offset = getPortOffset(addr); debugss(ssMMS77316, VERBOSE, "(addr: %d, %d (0x%x))\n", addr, val, val); if (offset >= Wd1797_Offset_c) { offset -= Wd1797_Offset_c; if (offset == WD1797::DataPort_Offset_c) { // See notes for MMS77316::in()... int timeout = 0; while (burstMode() && !drqRaised_m && !intrqRaised_m && ++timeout < 16) { wd1797_m->waitForData(); } } wd1797_m->out(offset, val); } else if (offset == ControlPort_Offset_c) { debugss(ssMMS77316, VERBOSE, "(ControlPort) %02x\n", val); controlReg_m = val; drqCount_m = 0; if ((controlReg_m & ctrl_525DriveSel_c) != 0) { GenericFloppyDrive* drive = getCurrentDrive(); if (drive) { drive->motor(true); } } wd1797_m->setDoubleDensity((controlReg_m & ctrl_SetMFMRecordingN_c) == 0); if ((controlReg_m & ctrl_EnableIntReq_c) != 0 && (intrqRaised_m || drqRaised_m)) { // Interrupt still pending, but now un-masked. Raise it. ic_m->setIntrq(intrqRaised_m); ic_m->setDrq(drqRaised_m); } } else { debugss(ssMMS77316, ERROR, "(Unknown addr- 0x%02x): %d\n", addr, val); } }
GenericFloppyDrive* GenericFloppyDrive::getInstance(std::string type) { unsigned int heads; unsigned int tracks; unsigned int mediaSize; if (type.find("FDD_5_25") == 0) { mediaSize = 5; if (type.find("ST") != std::string::npos) { tracks = 40; } else if (type.find("DT") != std::string::npos) { tracks = 80; } else { debugss(ssGenericFloppyDrive, ERROR, "number of tracks not specified\n"); return nullptr; } } else if (type.find("FDD_8" == 0)) { mediaSize = 8; tracks = 77; } else { debugss(ssGenericFloppyDrive, ERROR, "disk size not specified\n"); return NULL; } if (type.find("SS") != std::string::npos) { heads = 1; } else if (type.find("DS") != std::string::npos) { heads = 2; } else { debugss(ssGenericFloppyDrive, ERROR, "number of sides not specified\n"); return nullptr; } return new GenericFloppyDrive(heads, tracks, mediaSize); }
void Z47Interface::writeData(BYTE data) { debugss(ssH47, ALL, "data = 0x%02x\n", data); if (linkToDrive_m) { linkToDrive_m->sendDriveData(data); } else { debugss(ssH47, ERROR, "link to Drive not configured\n"); } }
void Z47Controller::connectHostLink(ParallelLink* link) { debugss(ssH47, ALL, "\n"); linkToHost_m = link; if (linkToHost_m) { linkToHost_m->registerDevice(this); } else { debugss(ssH47, ERROR, "link invalid\n"); } }
void IOBus::out(BYTE addr, BYTE val) { debugss(ssIO, ALL, "(%03o) = 0x%02x\n", addr, val); if (iodevices[addr]) { iodevices[addr]->out(addr, val); } else { debugss(ssIO, WARNING, "undefined port (%03o) = 0x%02x\n", addr, val); } }
bool IOBus::removeDevice(IODevice* device) { bool retVal = true; if (device) { BYTE base = device->getBaseAddress(); BYTE num = device->getNumPorts(); BYTE last = base + num; debugss(ssIO, INFO, "ports (%03o - %03o)\n", base, last); if (num) { for (BYTE port = base; port < last; ++port) { if (iodevices[port] == device) { // TODO: call destructor? (i.e. "delete iodevices[port];"?) iodevices[port] = 0; } else { // Doesn't match what is attempting to be removed. debugss(ssIO, ERROR, "non-matching device on port (%03o)\n", port); retVal = false; } } } else { // no ports. debugss(ssIO, ERROR, "no ports\n"); retVal = false; } } else { // NULL device passed in debugss(ssIO, ERROR, "Null Device\n"); retVal = false; } return (retVal); }
void Z47Interface::connectDriveLink(ParallelLink* link) { debugss(ssH47, ALL, "\n"); linkToDrive_m = link; if (linkToDrive_m) { linkToDrive_m->registerHost(this); } else { debugss(ssH47, ERROR, "link to Drive not configured\n"); } }
void Z47Controller::processFormatDoubleDensity(BYTE val) { debugss(ssH47, ALL, "\n"); statePosition_m++; if (statePosition_m == 3) { commandComplete(); return; } if (statePosition_m == 2) { // decodeSideDriveSector(val); countDown_m = 10000; memset(&diskData[0], 0xe5, 256256); curLinkState = st_Link_AwaitingControllerComplete_c; return; } if (statePosition_m == 1) { // val invalid. curLinkState = st_Link_AwaitingToReqReceive_c; countDown_m = 10; } }
void MMS77316::lowerIntrq() { debugss(ssMMS77316, INFO, "\n"); intrqRaised_m = false; ic_m->setIntrq(intrqRaised_m); }
void MMS77316::lowerDrq() { debugss(ssMMS77316, INFO, "\n"); drqRaised_m = false; ic_m->setDrq(drqRaised_m); }
void SoftSectoredDisk::determineDiskFormat(const char* name, DiskImageFormat& format) { debugss(ssFloppyDisk, INFO, "Name: %s\n", name); /// \todo implement format = dif_Unknown; }
ROM::~ROM() { debugss(ssROM, INFO, "Destroying ROM\n"); delete[] data_m; data_m = 0; size_m = 0; }
void Z47Controller::pulseSignal(SignalType sigType) { debugss(ssH47, ALL, "\n"); raiseSignal(sigType); lowerSignal(sigType); }
bool IOBus::addDevice(IODevice* device) { debugss(ssIO, INFO, "\n"); if (device == nullptr) { // NULL device passed in debugss(ssIO, ERROR, "Null Device\n"); return (false); } BYTE base = device->getBaseAddress(); BYTE num = device->getNumPorts(); BYTE last = base + num; debugss(ssIO, INFO, "ports (%03o - %03o)\n", base, last); if (!num) { // no ports. debugss(ssIO, ERROR, "no ports\n"); return (false); } // First make sure there is no conflict for (BYTE port = base; port < last; ++port) { if (iodevices[port]) { // Address already in use debugss(ssIO, ERROR, "duplicate devices on port (%03o)\n", port); return (false); } } // Now set the new value for (BYTE port = base; port < last; ++port) { iodevices[port] = device; } return (true); }
void ROM::writeByte(WORD addr, BYTE val) { // can't write to ROM. /// \todo update to set the RAM. debugss(ssROM, INFO, "Attempting to write to ROM [%d] = %d\n", addr, val); return; }
ROM::ROM(int size): data_m(0), base_m(0), size_m(size) { debugss(ssROM, INFO, "Creating ROM: %d\n", size_m); data_m = new BYTE[size_m]; }
void Z47Controller::commandComplete(void) { debugss(ssH47, ALL, "state: %s\n", getStateStr(curState)); curState = st_None_c; curLinkState = st_Link_AwaitingReadyState_c; countDown_m = 120; if (linkToHost_m) { linkToHost_m->setBusy(false); // linkToHost_m->setDTR(true); } debugss(ssH47, ALL, "=============END of CMD============\n"); }
IOBus::IOBus() { debugss(ssIO, INFO, "%\n"); for (int port = 0; port < 256; ++port) { iodevices[port] = 0; } }