From 8906fe34855789a63a0b0a666a2b904fa7a85426 Mon Sep 17 00:00:00 2001 From: Josh Dersch Date: Mon, 30 Mar 2020 21:13:15 +0200 Subject: [PATCH] Code cleanup/simplification. Moved stuff out to rp_drive_c that belonged there. --- 10.02_devices/2_src/massbus_device.hpp | 8 +- 10.02_devices/2_src/massbus_rp.cpp | 192 +++++++++---------------- 10.02_devices/2_src/massbus_rp.hpp | 24 +--- 10.02_devices/2_src/rh11.cpp | 24 +++- 10.02_devices/2_src/rp_drive.cpp | 62 ++++---- 10.02_devices/2_src/rp_drive.hpp | 28 +++- 6 files changed, 149 insertions(+), 189 deletions(-) diff --git a/10.02_devices/2_src/massbus_device.hpp b/10.02_devices/2_src/massbus_device.hpp index 71961e0..ef4a498 100644 --- a/10.02_devices/2_src/massbus_device.hpp +++ b/10.02_devices/2_src/massbus_device.hpp @@ -44,12 +44,14 @@ public: // Writable bits virtual uint16_t RegisterWritableBits(uint32_t register) = 0; + // Selects the specified unit + virtual void SelectUnit(uint32_t uint) = 0; // - // MASSBUS Register reads and writes + // MASSBUS Register reads and writes (to the unit selected by SelectUnit) // - virtual void WriteRegister(uint32_t unit, uint32_t register, uint16_t value) = 0; - virtual uint16_t ReadRegister(uint32_t unit, uint32_t register) = 0; + virtual void WriteRegister(uint32_t register, uint16_t value) = 0; + virtual uint16_t ReadRegister(uint32_t register) = 0; // // Block transfers diff --git a/10.02_devices/2_src/massbus_rp.cpp b/10.02_devices/2_src/massbus_rp.cpp index 9b41343..9f08fe2 100644 --- a/10.02_devices/2_src/massbus_rp.cpp +++ b/10.02_devices/2_src/massbus_rp.cpp @@ -36,9 +36,6 @@ massbus_rp_c::massbus_rp_c( device_c(), _controller(controller), _selectedUnit(0), - _desiredSector(0), - _desiredTrack(0), - _desiredCylinder(0), _workerState(WorkerState::Idle), _workerWakeupCond(PTHREAD_COND_INITIALIZER), _workerMutex(PTHREAD_MUTEX_INITIALIZER), @@ -124,21 +121,33 @@ massbus_rp_c::RegisterWritableBits( return _registerMetadata[reg].WritableBits; } +void +massbus_rp_c::SelectUnit( + uint32_t unit) +{ + _selectedUnit = unit; + UpdateStatus(_selectedUnit, false, false); + UpdateDriveRegisters(); +} + void massbus_rp_c::WriteRegister( - uint32_t unit, uint32_t reg, uint16_t value) { - DEBUG("RP reg write: unit %d register 0%o value 0%o", unit, reg, value); + DEBUG("RP reg write: unit %d register 0%o value 0%o", _selectedUnit, reg, value); - if (!SelectedDrive()->IsDriveReady() && + rp_drive_c* drive = SelectedDrive(); + + if (!drive->IsDriveReady() && reg != 0 && // CS1 is allowed as long as GO isn't set (will be checked in DoCommand) reg != (uint32_t)Registers::AttentionSummary) { // Any attempt to modify a drive register other than Attention Summary - // while the drive is busy is invalid. - DEBUG("Register modification while drive busy."); + // while the drive is busy is invalid. + // For now treat this as fatal (it's not but real code shouldn't be doing it so this + // is a diagnostic at the moment.) + FATAL("Register modification while drive busy."); _rmr = true; UpdateStatus(_selectedUnit, false, false); return; @@ -147,24 +156,18 @@ massbus_rp_c::WriteRegister( switch(static_cast(reg)) { case Registers::Control: - DoCommand(unit, value); + DoCommand(value); break; case Registers::DesiredSectorTrackAddress: - _desiredTrack = (value & 0x1f00) >> 8; - _desiredSector = (value & 0x1f); - UpdateDesiredSectorTrack(); - - DEBUG("Desired Sector Track Address: track %d, sector %d", - _desiredTrack, - _desiredSector); + drive->SetDesiredTrack((value & 0x1f00) >> 8); + drive->SetDesiredSector(value & 0x1f); + UpdateDriveRegisters(); break; case Registers::DesiredCylinderAddress: - _desiredCylinder = value & 0x3ff; - UpdateDesiredCylinder(); - - DEBUG("Desired Cylinder Address o%o (o%o)", _desiredCylinder, value); + drive->SetDesiredCylinder(value & 0x3ff); + UpdateDriveRegisters(); break; case Registers::AttentionSummary: @@ -193,30 +196,27 @@ massbus_rp_c::WriteRegister( } void massbus_rp_c::DoCommand( - uint32_t unit, uint16_t command) { FunctionCode function = static_cast((command & RP_FUNC) >> 1); - _selectedUnit = unit; + rp_drive_c* drive = SelectedDrive(); // check for GO bit; if unset we have nothing to do here, - // but we will update status in case the drive unit has changed. if ((command & RP_GO) == 0) { - UpdateStatus(_selectedUnit, false, false); return; } DEBUG("RP function 0%o, unit %o", function, _selectedUnit); - if (!SelectedDrive()->IsConnected()) + if (!drive->IsConnected()) { // Early return for disconnected drives; // set NED and ERR bits _err = true; _ata = true; _ned = true; // TODO: should be done at RH11 level! - SelectedDrive()->ClearVolumeValid(); + drive->ClearVolumeValid(); UpdateStatus(_selectedUnit, true, false); return; } @@ -286,19 +286,18 @@ void massbus_rp_c::DoCommand( // sector/track address register, and clears the FMT, HCI, and ECI // bits in the offset register. It is used to bootstrap the device." // - SelectedDrive()->SetVolumeValid(); - SelectedDrive()->SetDriveReady(); - _desiredSector = 0; - _desiredTrack = 0; - _offset = 0; - UpdateDesiredSectorTrack(); - UpdateOffset(); + drive->SetVolumeValid(); + drive->SetDriveReady(); + drive->SetDesiredSector(0); + drive->SetDesiredTrack(0);; + drive->SetOffset(0); + UpdateDriveRegisters(); UpdateStatus(_selectedUnit, false, false); /* do not interrupt */ break; case FunctionCode::PackAcknowledge: DEBUG("RP Pack Acknowledge"); - SelectedDrive()->SetVolumeValid(); + drive->SetVolumeValid(); UpdateStatus(_selectedUnit, false, false); break; @@ -314,7 +313,7 @@ void massbus_rp_c::DoCommand( DEBUG("RP Read/Write Data or head-motion command"); { // Clear the unit's DRY bit - SelectedDrive()->ClearDriveReady(); + drive->ClearDriveReady(); if (function == FunctionCode::Search || function == FunctionCode::Seek || @@ -322,7 +321,7 @@ void massbus_rp_c::DoCommand( function == FunctionCode::Offset || function == FunctionCode::ReturnToCenterline) { - SelectedDrive()->SetPositioningInProgress(); + drive->SetPositioningInProgress(); } UpdateStatus(_selectedUnit, false, false); @@ -331,11 +330,7 @@ void massbus_rp_c::DoCommand( // Save a copy of command data for the worker to consume _newCommand.unit = _selectedUnit; - _newCommand.drive = SelectedDrive(); _newCommand.function = function; - _newCommand.cylinder = _desiredCylinder; - _newCommand.track = _desiredTrack; - _newCommand.sector = _desiredSector; _newCommand.bus_address = _controller->GetBusAddress(); _newCommand.word_count = _controller->GetWordCount(); _newCommand.ready = true; @@ -355,10 +350,9 @@ void massbus_rp_c::DoCommand( uint16_t massbus_rp_c::ReadRegister( - uint32_t unit, uint32_t reg) { - DEBUG("RP reg read: unit %d register 0%o", unit, reg); + DEBUG("RP reg read: unit %d register 0%o", _selectedUnit, reg); switch(static_cast(reg)) { @@ -384,7 +378,7 @@ massbus_rp_c::ReadRegister( // void massbus_rp_c::UpdateStatus( - uint16_t unit, + uint32_t unit, bool complete, bool diagForceError) { @@ -445,36 +439,26 @@ massbus_rp_c::UpdateStatus( } void -massbus_rp_c::UpdateDesiredSectorTrack() +massbus_rp_c::UpdateDriveRegisters() { - uint16_t desiredSectorTrack = (_desiredSector | (_desiredTrack << 8)); - _controller->WriteRegister(static_cast(Registers::DesiredSectorTrackAddress), desiredSectorTrack); -} + rp_drive_c* drive = SelectedDrive(); -void -massbus_rp_c::UpdateDesiredCylinder() -{ - _controller->WriteRegister(static_cast(Registers::DesiredCylinderAddress), _desiredCylinder); -} + _controller->WriteRegister(static_cast(Registers::CurrentCylinderAddress), + drive->GetCurrentCylinder()); -void -massbus_rp_c::UpdateOffset() -{ - _controller->WriteRegister(static_cast(Registers::Offset), _offset); -} + _controller->WriteRegister(static_cast(Registers::DesiredCylinderAddress), + drive->GetDesiredCylinder()); -void -massbus_rp_c::UpdateCurrentCylinder() -{ - _controller->WriteRegister(static_cast(Registers::CurrentCylinderAddress), - SelectedDrive()->GetCurrentCylinder()); + uint16_t desiredSectorTrack = drive->GetDesiredSector() | (drive->GetDesiredTrack() << 8); + _controller->WriteRegister(static_cast(Registers::DesiredSectorTrackAddress), + desiredSectorTrack); + + _controller->WriteRegister(static_cast(Registers::Offset), drive->GetOffset()); } void massbus_rp_c::Reset() { - // TODO: reset all drives - // Reset registers to their defaults _ata = false; _attnSummary = 0; @@ -483,19 +467,8 @@ massbus_rp_c::Reset() _selectedUnit = 0; UpdateStatus(_selectedUnit, false, false); - _desiredSector = 0; - _desiredTrack = 0; - UpdateDesiredSectorTrack(); + UpdateDriveRegisters(); - _desiredCylinder = 0; - UpdateDesiredCylinder(); - - UpdateCurrentCylinder(); - - _offset = 0; - UpdateOffset(); - - _selectedUnit = 0; _newCommand.ready = false; } @@ -548,31 +521,23 @@ massbus_rp_c::Worker() break; case WorkerState::Execute: + { + rp_drive_c* drive = GetDrive(command.unit); switch(command.function) { case FunctionCode::ReadData: { - DEBUG("READ CHS %d/%d/%d, %d words to address o%o", - _newCommand.cylinder, - _newCommand.track, - _newCommand.sector, - _newCommand.word_count, - _newCommand.bus_address); - uint16_t* buffer = nullptr; - if (_newCommand.drive->Read( - _newCommand.cylinder, - _newCommand.track, - _newCommand.sector, - _newCommand.word_count, + if (drive->Read( + command.word_count, &buffer)) { // // Data read: do DMA transfer to memory. // _controller->DiskReadTransfer( - _newCommand.bus_address, - _newCommand.word_count, + command.bus_address, + command.word_count, buffer); // Free buffer @@ -586,7 +551,7 @@ massbus_rp_c::Worker() } // Return drive to ready state - _newCommand.drive->SetDriveReady(); + drive->SetDriveReady(); _workerState = WorkerState::Finish; } @@ -594,25 +559,15 @@ massbus_rp_c::Worker() case FunctionCode::WriteData: { - DEBUG("WRITE CHS %d/%d/%d, %d words from address o%o", - _newCommand.cylinder, - _newCommand.track, - _newCommand.sector, - _newCommand.word_count, - _newCommand.bus_address); - // // Data write: do DMA transfer from memory. // uint16_t* buffer = _controller->DiskWriteTransfer( - _newCommand.bus_address, - _newCommand.word_count); + command.bus_address, + command.word_count); - if (!buffer || !_newCommand.drive->Write( - _newCommand.cylinder, - _newCommand.track, - _newCommand.sector, - _newCommand.word_count, + if (!buffer || !drive->Write( + command.word_count, buffer)) { // Write failed: @@ -623,7 +578,7 @@ massbus_rp_c::Worker() delete buffer; // Return drive to ready state - _newCommand.drive->SetDriveReady(); + drive->SetDriveReady(); _workerState = WorkerState::Finish; } @@ -631,15 +586,7 @@ massbus_rp_c::Worker() case FunctionCode::Search: { - DEBUG("SEARCH CHS %d/%d/%d", - _newCommand.cylinder, - _newCommand.track, - _newCommand.sector); - - if (!_newCommand.drive->Search( - _newCommand.cylinder, - _newCommand.track, - _newCommand.sector)) + if (!drive->Search()) { // Search failed DEBUG("Search failed"); @@ -647,20 +594,19 @@ massbus_rp_c::Worker() // Return to ready state, set attention bit. - _newCommand.drive->SetDriveReady(); + drive->SetDriveReady(); _ata = true; _workerState = WorkerState::Finish; } break; case FunctionCode::Seek: - DEBUG("SEEK Cylinder %d", _newCommand.cylinder); - if (!_newCommand.drive->SeekTo(_newCommand.cylinder)) + if (!drive->SeekTo()) { // Seek failed DEBUG("Seek failed"); } - _newCommand.drive->SetDriveReady(); + drive->SetDriveReady(); _ata = true; _workerState = WorkerState::Finish; break; @@ -673,7 +619,7 @@ massbus_rp_c::Worker() // to complete. DEBUG("OFFSET/RETURN TO CL"); timeout.wait_ms(10); - _newCommand.drive->SetDriveReady(); + drive->SetDriveReady(); _ata = true; _workerState = WorkerState::Finish; break; @@ -682,14 +628,14 @@ massbus_rp_c::Worker() FATAL("Unimplemented drive function %d", command.function); break; } - + } break; case WorkerState::Finish: _workerState = WorkerState::Idle; - _newCommand.drive->SetDriveReady(); - UpdateCurrentCylinder(); + GetDrive(_newCommand.unit)->SetDriveReady(); UpdateStatus(_newCommand.unit, true, false); + UpdateDriveRegisters(); break; } diff --git a/10.02_devices/2_src/massbus_rp.hpp b/10.02_devices/2_src/massbus_rp.hpp index b59f6d0..5d32830 100644 --- a/10.02_devices/2_src/massbus_rp.hpp +++ b/10.02_devices/2_src/massbus_rp.hpp @@ -102,8 +102,10 @@ public: uint16_t RegisterResetValue(uint32_t register) override; uint16_t RegisterWritableBits(uint32_t register) override; - void WriteRegister(uint32_t unit, uint32_t register, uint16_t value) override; - uint16_t ReadRegister(uint32_t unit, uint32_t register) override; + void WriteRegister(uint32_t register, uint16_t value) override; + uint16_t ReadRegister(uint32_t register) override; + + void SelectUnit(uint32_t unit); // Background worker functions void Worker(); @@ -113,13 +115,9 @@ private: struct WorkerCommand { uint16_t unit; - rp_drive_c* drive; volatile uint32_t bus_address; volatile uint32_t word_count; volatile FunctionCode function; - volatile uint32_t cylinder; - volatile uint32_t track; - volatile uint32_t sector; volatile bool ready; } _newCommand; @@ -130,16 +128,13 @@ private: Finish = 2, } _workerState; - void DoCommand(uint32_t unit, uint16_t command); + void DoCommand(uint16_t command); void on_power_changed(void) override; void on_init_changed(void) override; - void UpdateStatus(uint16_t unit, bool completion, bool diagForceError); - void UpdateDesiredSectorTrack(); - void UpdateDesiredCylinder(); - void UpdateOffset(); - void UpdateCurrentCylinder(); + void UpdateStatus(uint32_t unit, bool completion, bool diagForceError); + void UpdateDriveRegisters(); rp_drive_c* SelectedDrive(); rp_drive_c* GetDrive(uint16_t unit); @@ -176,11 +171,6 @@ private: volatile uint16_t _error1; volatile uint16_t _maint; volatile uint16_t _attnSummary; - volatile uint16_t _desiredSector; - volatile uint16_t _desiredTrack; - volatile uint16_t _offset; - volatile uint16_t _desiredCylinder; - volatile uint16_t _currentCylinder; volatile uint16_t _error2; volatile uint16_t _error3; diff --git a/10.02_devices/2_src/rh11.cpp b/10.02_devices/2_src/rh11.cpp index 6c6b393..efb3686 100755 --- a/10.02_devices/2_src/rh11.cpp +++ b/10.02_devices/2_src/rh11.cpp @@ -615,7 +615,7 @@ void rh11_c::on_after_register_access( if ((dato_mask & 0x00ff) == 0x00ff) { // Let the massbus device take a crack at the shared bits. - _massbus->WriteRegister(_unit, RHCS1, value & 077); + _massbus->WriteRegister(RHCS1, value & 077); } } } @@ -625,7 +625,7 @@ void rh11_c::on_after_register_access( { if (UNIBUS_CONTROL_DATO == unibus_control) { - _unit = (value & 07); + uint16_t newUnit = (value & 07); _busAddressIncrementProhibit = !!(value & 010); _parityTest = !!(value & 020); _controllerClear = !!(value & 040); @@ -634,13 +634,25 @@ void rh11_c::on_after_register_access( DEBUG("RHCS2 write: o%o", value); DEBUG("RHCS2: perror %d, unit %d inc %d ptest %d clear %d", _parityError, _unit, _busAddressIncrementProhibit, _parityTest, _controllerClear); - + + // On unit change, select new drive + if (newUnit != _unit) + { + _unit = newUnit; + _massbus->SelectUnit(_unit); + } + // TODO: handle System Register Clear (bit 5) if (_controllerClear) { DEBUG("Controller Clear"); _interruptEnable = false; + for (uint32_t i=0; iReset(); + } + _massbus->Reset(); // clear error and the clear bits @@ -691,7 +703,7 @@ void rh11_c::on_after_register_access( { if (UNIBUS_CONTROL_DATO == unibus_control) { - _massbus->WriteRegister(_unit, _unibusToMassbusRegisterMap[device_reg->index], value); + _massbus->WriteRegister(_unibusToMassbusRegisterMap[device_reg->index], value); // Massbus is responsible for writing back the appropriate dati value. } else @@ -699,7 +711,7 @@ void rh11_c::on_after_register_access( DEBUG("massbus reg read %o", device_reg->index); set_register_dati_value( device_reg, - _massbus->ReadRegister(_unit, _unibusToMassbusRegisterMap[device_reg->index]), + _massbus->ReadRegister(_unibusToMassbusRegisterMap[device_reg->index]), "on_after_register_access"); } } @@ -715,6 +727,8 @@ void rh11_c::on_after_register_access( void rh11_c::reset_controller(void) { reset_unibus_registers(); + + // TODO: do more } diff --git a/10.02_devices/2_src/rp_drive.cpp b/10.02_devices/2_src/rp_drive.cpp index a09a96d..9ee77dc 100644 --- a/10.02_devices/2_src/rp_drive.cpp +++ b/10.02_devices/2_src/rp_drive.cpp @@ -18,6 +18,10 @@ using namespace std; rp_drive_c::rp_drive_c(storagecontroller_c *controller, uint32_t driveNumber) : storagedrive_c(controller), _driveNumber(driveNumber), + _desiredCylinder(0), + _currentCylinder(0), + _desiredTrack(0), + _offset(0), _ready(true), _lst(false), _aoe(false), @@ -39,6 +43,12 @@ rp_drive_c::~rp_drive_c() } } +void +rp_drive_c::Reset() +{ + +} + // on_param_changed(): // Handles configuration parameter changes. bool @@ -96,20 +106,19 @@ rp_drive_c::IsPackLoaded() } bool -rp_drive_c::SeekTo( - uint32_t destinationCylinder) +rp_drive_c::SeekTo() { // TODO: delay by appropriate amount timeout_c timeout; - _iae = !(destinationCylinder < _driveInfo.Cylinders); + _iae = !(_desiredCylinder < _driveInfo.Cylinders); if (IsConnected() && IsPackLoaded() && !_iae) { timeout.wait_ms(20); - _currentCylinder = destinationCylinder; + _currentCylinder = _desiredCylinder; return true; } else @@ -118,12 +127,6 @@ rp_drive_c::SeekTo( } } -uint32_t -rp_drive_c::GetCurrentCylinder() -{ - return _currentCylinder; -} - // // TODO: on all reads/writes, an implied seek takes place if the @@ -136,13 +139,10 @@ rp_drive_c::GetCurrentCylinder() // bool rp_drive_c::Write( - uint32_t cylinder, - uint32_t track, - uint32_t sector, size_t countInWords, uint16_t* buffer) { - _iae = !ValidateCHS(cylinder, track, sector); + _iae = !ValidateCHS(_desiredCylinder, _desiredTrack, _desiredSector); _wle = IsWriteLocked(); // TODO: handle address overflow @@ -153,11 +153,11 @@ rp_drive_c::Write( } else { - _currentCylinder = cylinder; - uint32_t offset = GetSectorForCHS(cylinder, track, sector); + _currentCylinder = _desiredCylinder; + uint32_t offset = GetSectorForCHS(_currentCylinder, _desiredTrack, _desiredSector); file_write(reinterpret_cast(buffer), offset * GetSectorSize(), countInWords * 2); - //timeout_c timeout; - //timeout.wait_ms(20); + timeout_c timeout; + timeout.wait_us(500); return true; } @@ -170,51 +170,45 @@ rp_drive_c::Write( // bool rp_drive_c::Read( - uint32_t cylinder, - uint32_t track, - uint32_t sector, size_t countInWords, uint16_t** buffer) { - _iae = !ValidateCHS(cylinder, track, sector); + _iae = !ValidateCHS(_desiredCylinder, _desiredTrack, _desiredSector); _wle = false; if (!IsConnected() || !IsPackLoaded() || _iae) { *buffer = nullptr; - DEBUG("Failure: connected %d loaded %d valid %d", IsConnected(), IsPackLoaded(), ValidateCHS(cylinder, track, sector)); + DEBUG("Failure: connected %d loaded %d valid %d", IsConnected(), IsPackLoaded(), _iae); return false; } else { - _currentCylinder = cylinder; + _currentCylinder = _desiredCylinder; *buffer = new uint16_t[countInWords]; assert(nullptr != *buffer); - uint32_t offset = GetSectorForCHS(cylinder, track, sector); + uint32_t offset = GetSectorForCHS(_currentCylinder, _desiredTrack, _desiredSector); DEBUG("Read from sector offset o%o", offset); file_read(reinterpret_cast(*buffer), offset * GetSectorSize(), countInWords * 2); - //timeout_c timeout; - //timeout.wait_ms(20); + timeout_c timeout; + timeout.wait_us(500); return true; } } bool -rp_drive_c::Search( - uint32_t cylinder, - uint32_t track, - uint32_t sector) +rp_drive_c::Search(void) { - _iae = !ValidateCHS(cylinder, track, sector); + _iae = !ValidateCHS(_desiredCylinder, _desiredTrack, _desiredSector); if (!IsConnected() || !IsPackLoaded() || _iae) { - DEBUG("Failure: connected &d loaded %d valid %d", IsConnected(), IsPackLoaded(), ValidateCHS(cylinder, track, sector)); + DEBUG("Failure: connected &d loaded %d valid %d", IsConnected(), IsPackLoaded(), _iae); return false; } else @@ -226,7 +220,7 @@ rp_drive_c::Search( timeout.wait_ms(20); _pip = false; DEBUG("Search completed."); - _currentCylinder = cylinder; + _currentCylinder = _desiredCylinder; return true; } diff --git a/10.02_devices/2_src/rp_drive.hpp b/10.02_devices/2_src/rp_drive.hpp index 51d7eb2..38119a2 100644 --- a/10.02_devices/2_src/rp_drive.hpp +++ b/10.02_devices/2_src/rp_drive.hpp @@ -23,12 +23,24 @@ public: rp_drive_c(storagecontroller_c *controller, uint32_t driveNumber); ~rp_drive_c(void); + void Reset(); + bool on_param_changed(parameter_c *param) override; uint32_t GetSectorSize(void); uint32_t GetType(void); - bool IsConnected(void) { return _driveNumber == 0; /* todo: make config. parameter */ } + void SetDesiredCylinder(uint32_t cylinder) { _desiredCylinder = cylinder; } + void SetDesiredTrack(uint32_t track) { _desiredTrack = track; } + void SetDesiredSector(uint32_t sector) { _desiredSector = sector; } + void SetOffset(uint16_t offset) { _offset = offset; } + uint32_t GetDesiredCylinder(void) { return _desiredCylinder; } + uint32_t GetDesiredTrack(void) { return _desiredTrack; } + uint32_t GetDesiredSector(void) { return _desiredSector; } + uint16_t GetOffset(void) { return _offset; } + uint32_t GetCurrentCylinder(void) { return _currentCylinder; } + + bool IsConnected(void) { return true; /* todo: make config. parameter */ } bool IsPackLoaded(void); bool IsDriveReady(void) { return _ready; } bool IsWriteLocked(void) { return false; /* for now */ } @@ -46,18 +58,20 @@ public: uint16_t GetDriveType(void) { return _driveInfo.TypeNumber; } uint16_t GetSerialNumber(void) { return 012345; } // TODO: Make configurable parameter - bool SeekTo(uint32_t cylinder); - uint32_t GetCurrentCylinder(); - - bool Write(uint32_t cylinder, uint32_t track, uint32_t sector, uint32_t countInWords, uint16_t* buffer); - bool Read(uint32_t cylinder, uint32_t track, uint32_t sector, uint32_t countInWords, uint16_t** outBuffer); - bool Search(uint32_t cylinder, uint32_t track, uint32_t sector); + bool SeekTo(); + bool Write(uint32_t countInWords, uint16_t* buffer); + bool Read(uint32_t countInWords, uint16_t** outBuffer); + bool Search(); public: void on_power_changed(void) override; void on_init_changed(void) override; private: + uint32_t _desiredCylinder; + uint32_t _desiredTrack; + uint32_t _desiredSector; + uint16_t _offset; uint32_t _currentCylinder; uint32_t _driveNumber; bool _ready;