1
0
mirror of https://github.com/livingcomputermuseum/UniBone.git synced 2026-02-27 01:00:00 +00:00

Status bit fixes; 2.11BSD gets a bit further.

This commit is contained in:
Josh Dersch
2020-02-03 02:44:09 +01:00
parent a72a845623
commit f2b6ece8f1
5 changed files with 76 additions and 39 deletions

View File

@@ -23,6 +23,11 @@ public:
//
// MASSBUS Register Metadata:
//
// The total number of registers (including RH11 registers) exposed
// by this device.
virtual uint32_t GetRegisterCount() = 0;
// Indicates whether this device implements the specified register.
virtual bool ImplementsRegister(uint32_t register) = 0;

View File

@@ -36,9 +36,9 @@ massbus_rp_c::massbus_rp_c(
_workerMutex(PTHREAD_MUTEX_INITIALIZER),
_err(false),
_ata(false),
_ready(true),
_ned(false),
_attnSummary(0)
_attnSummary(0),
_rmr(false)
{
name.value="MASSBUS_RP";
type_name.value = "massbus_rp_c";
@@ -114,6 +114,20 @@ massbus_rp_c::WriteRegister(
{
INFO("RP reg write: unit %d register 0%o value 0%o", unit, reg, value);
if (!SelectedDrive()->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.
INFO("Register modification while drive busy.");
_rmr = true;
UpdateStatus(false);
return;
}
static uint32_t frup = 0;
switch(static_cast<Registers>(reg))
{
case Registers::Control:
@@ -141,10 +155,18 @@ massbus_rp_c::WriteRegister(
// Clear bits in the Attention Summary register specified in the
// written value:
_attnSummary &= ~(value & 0xff);
_controller->WriteRegister(static_cast<uint32_t>(Registers::AttentionSummary), _attnSummary);
_controller->WriteRegister(reg, _attnSummary);
INFO("Attention Summary write o%o, value is now o%o", value, _attnSummary);
break;
case Registers::Error1:
// Clear any bits in the Error 1 Register specified in the
// written value:
_error1 &= ~(value & 0xff);
_controller->WriteRegister(reg, _error1);
INFO("Error 1 Reg write o%o, value is now o%o", value, _error1);
break;
default:
FATAL("Unimplemented RP register write.");
break;
@@ -178,13 +200,19 @@ void massbus_rp_c::DoCommand(
return;
}
if (!SelectedDrive()->IsDriveReady())
{
// This should never happen.
FATAL("Command sent while not ready!");
}
_ned = false;
_ata = false;
switch(static_cast<FunctionCode>(function))
{
case FunctionCode::Nop:
// Nothing.
_ata = false;
UpdateStatus(true);
break;
@@ -200,11 +228,9 @@ void massbus_rp_c::DoCommand(
_desiredSector = 0;
_desiredTrack = 0;
_offset = 0;
_ata = false;
_ready = true;
UpdateStatus(true);
UpdateDesiredSectorTrack();
UpdateOffset();
UpdateOffset();
UpdateStatus(false); /* do not interrupt */
break;
case FunctionCode::ReadData:
@@ -222,9 +248,7 @@ void massbus_rp_c::DoCommand(
SelectedDrive()->SetPositioningInProgress();
}
// Clear ATA and READY
_ata = false;
_ready = false;
// Clear READY
UpdateStatus(false);
pthread_mutex_lock(&_workerMutex);
@@ -273,6 +297,7 @@ massbus_rp_c::UpdateStatus(
{
_error1 =
(_rmr ? 04 : 0) |
(SelectedDrive()->GetAddressOverflow() ? 01000 : 0) |
(SelectedDrive()->GetInvalidAddress() ? 02000 : 0) |
(SelectedDrive()->GetWriteLockError() ? 04000 : 0);
@@ -308,12 +333,13 @@ massbus_rp_c::UpdateStatus(
{
_attnSummary |= (0x1 << _selectedUnit); // TODO: these only get set, and are latched until
// manually cleared?
INFO("Attention Summary is now o%o", _attnSummary);
}
_controller->WriteRegister(static_cast<uint32_t>(Registers::AttentionSummary), _attnSummary);
// Inform controller of status update.
_controller->BusStatus(complete, _ready, _ata, _err, SelectedDrive()->IsAvailable(), _ned);
_controller->BusStatus(complete, SelectedDrive()->IsDriveReady(), _ata, _err, SelectedDrive()->IsAvailable(), _ned);
}
void
@@ -323,7 +349,7 @@ massbus_rp_c::UpdateDesiredSectorTrack()
_controller->WriteRegister(static_cast<uint32_t>(Registers::DesiredSectorTrackAddress), desiredSectorTrack);
// Fudge: We update the look-ahead sector value to be the last-requested sector - 1
uint16_t lookAhead = (((_desiredSector - 5) % 22) << 6);
uint16_t lookAhead = (((_desiredSector - 1) % 22) << 6);
_controller->WriteRegister(static_cast<uint32_t>(Registers::LookAhead), lookAhead);
}
@@ -353,8 +379,9 @@ massbus_rp_c::Reset()
// Reset registers to their defaults
_ata = false;
_ready = true;
_attnSummary = 0;
_error1 = 0;
_rmr = false;
UpdateStatus(false);
_desiredSector = 0;
@@ -455,8 +482,6 @@ massbus_rp_c::Worker()
// Return drive to ready state
SelectedDrive()->SetDriveReady();
// Signal ready status.
_ready = true;
_workerState = WorkerState::Finish;
}
break;
@@ -494,8 +519,6 @@ massbus_rp_c::Worker()
// Return drive to ready state
SelectedDrive()->SetDriveReady();
// Signal ready status.
_ready = true;
_workerState = WorkerState::Finish;
}
break;
@@ -520,7 +543,6 @@ massbus_rp_c::Worker()
// Return to ready state, set attention bit.
SelectedDrive()->SetDriveReady();
_ata = true;
_ready = true;
_workerState = WorkerState::Finish;
}
break;

View File

@@ -87,6 +87,12 @@ public:
public:
void Reset();
uint32_t GetRegisterCount() override
{
// Total registers for RH11 + RP06:
return 20;
}
bool ImplementsRegister(uint32_t register) override;
std::string RegisterName(uint32_t register) override;
@@ -141,9 +147,9 @@ private:
{
// Name DATI DATO
{ "INV", false, false, 0, 0 }, // 0, not used
{ "CS1", false, 0, 0177700 }, // Status
{ "ER1", false, true , 0, 0177777 }, // Error #1 - writable by diagnostics
{ "MR" , false, true , 0, 0177777 }, // Maintenance
{ "CS1", false, true, 0, 0401477 }, // Status
{ "ER1", false, true, 0, 0177777 }, // Error #1 - writable by diagnostics
{ "MR" , false, true, 0, 0177777 }, // Maintenance
{ "ATN", false, true, 0, 0377 }, // Attention summary
{ "DA" , false, true, 0, 0017437 }, // Desired Sector/Track
{ "LA" , false, false, 0, 0 }, // Look Ahead
@@ -177,9 +183,9 @@ private:
// Status bits that we track
volatile bool _err;
volatile bool _ata;
volatile bool _rmr;
// RH11 ready signal (ugly: this should be in the rh11 code!)
volatile bool _ready;
volatile bool _ned; // ditto
// Worker thread

View File

@@ -107,14 +107,14 @@ rh11_c::rh11_c() :
// base addr, intr-vector, intr level
// TODO: make configurable based on type (fixed, tape, moving-head disk)
// right now it is hardcoded for moving-head disks.
set_default_bus_params(0776700, 21, 0254, 6);
set_default_bus_params(0776700, 5, 0254, 6);
_massbus.reset(new massbus_rp_c(this));
// The RH11 controller exposes up to 32 registers, not all are used
// and use depends on the devices attached to the MASSBUS.
// TODO: What does an RH11 do when an unimplemented register is accessed?
register_count = 32;
register_count = _massbus->GetRegisterCount();
for (int i=0; i<register_count; i++)
{
@@ -127,8 +127,8 @@ rh11_c::rh11_c() :
strcpy(RH_reg[i]->name, "RHCS1");
RH_reg[i]->active_on_dati = false;
RH_reg[i]->active_on_dato = true;
RH_reg[i]->reset_value = 0x0080;
RH_reg[i]->writable_bits = 0x037f;
RH_reg[i]->reset_value = 0000200;
RH_reg[i]->writable_bits = 041577;
break;
case RHWC:
@@ -137,7 +137,7 @@ rh11_c::rh11_c() :
RH_reg[i]->active_on_dati = false;
RH_reg[i]->active_on_dato = true;
RH_reg[i]->reset_value = 0;
RH_reg[i]->writable_bits = 0xffff;
RH_reg[i]->writable_bits = 0177777;
break;
case RHBA:
@@ -146,7 +146,7 @@ rh11_c::rh11_c() :
RH_reg[i]->active_on_dati = false;
RH_reg[i]->active_on_dato = true;
RH_reg[i]->reset_value = 0;
RH_reg[i]->writable_bits = 0xfffe;
RH_reg[i]->writable_bits = 0177776;
break;
case RHCS2:
@@ -155,7 +155,7 @@ rh11_c::rh11_c() :
RH_reg[i]->active_on_dati = false;
RH_reg[i]->active_on_dato = true;
RH_reg[i]->reset_value = 0;
RH_reg[i]->writable_bits = 0x223f;
RH_reg[i]->writable_bits = 0021077;
break;
case RHDB:
@@ -164,7 +164,7 @@ rh11_c::rh11_c() :
RH_reg[i]->active_on_dati = false;
RH_reg[i]->active_on_dato = false;
RH_reg[i]->reset_value = 0;
RH_reg[i]->writable_bits = 0xffff;
RH_reg[i]->writable_bits = 0177777;
break;
default:
@@ -229,17 +229,17 @@ rh11_c::BusStatus(
INFO("RHCS1 is currently o%o", currentStatus);
currentStatus &= ~(0140300); // clear status bits, IE, and GO bit : move to constant
currentStatus &= ~(0144300); // clear status bits, IE, and GO bit : move to constant
currentStatus |=
(attention ? 0100000 : 0) | // check when this actually gets set?
(error ? 0040000 : 0) |
(avail ? 0004000 : 0) | // drive available
(ready ? 0000200 : 0); // controller ready bit (should clear when busy)
(ready ? 0000200 : 0); // controller ready bit
if (completion)
{
// clear the GO bit from the CS word if the drive is finished.
currentStatus &= ~(01);
currentStatus &= ~(01);
}
set_register_dati_value(
@@ -326,6 +326,8 @@ rh11_c::DiskReadTransfer(
}
else
{
// TODO: raise errors, etc.
FATAL("DMA Write failed!");
return false;
}
}
@@ -348,6 +350,11 @@ rh11_c::DiskWriteTransfer(
IncrementBusAddress(lengthInWords);
DecrementWordCount(lengthInWords);
}
else
{
// TODO: raise errors, etc.
FATAL("DMA Read failed!");
}
return buffer;
}
@@ -607,7 +614,6 @@ void rh11_c::on_after_register_access(
void rh11_c::Interrupt(void)
{
INFO("interrupt enable is %d", _interruptEnable);
if(_interruptEnable)
{
INFO("Interrupt!");

View File

@@ -208,11 +208,9 @@ rp_drive_c::Search(
timeout_c timeout;
INFO("Search commencing.");
_pip = true;
timeout.wait_ms(500);
timeout.wait_ms(30);
_pip = false;
INFO("Search completed.");
_currentCylinder = cylinder;
return true;