Additional updates

This commit is contained in:
akuker
2020-08-16 09:42:22 -05:00
parent 537fb82059
commit 19a659953a
7 changed files with 193 additions and 302 deletions

View File

@@ -536,7 +536,9 @@ BOOL Command_Thread::ExecuteCommand(FILE *fp, Rasctl_Command *incoming_command)
BOOL Command_Thread::DoShutdown(FILE *fp, Rasctl_Command *incoming_command){return FALSE;}
BOOL Command_Thread::DoShutdown(FILE *fp, Rasctl_Command *incoming_command){
m_running = FALSE;
}
BOOL Command_Thread::DoList(FILE *fp, Rasctl_Command *incoming_command){
Rascsi_Manager::GetInstance()->ListDevice(fp);
@@ -554,97 +556,70 @@ BOOL Command_Thread::DoAttach(FILE *fp, Rasctl_Command *incoming_command){
// }
// Create a new drive, based upon type
switch (incoming_command->type) {
case rasctl_dev_sasi_hd: // HDF
pUnit = new SASIHD();
break;
case rasctl_dev_scsi_hd: // HDS/HDN/HDI/NHD/HDA
pUnit = new SCSIHD();
break;
case rasctl_dev_scsi_hd_appl:
pUnit = new SCSIHD_APPLE();
break;
case rasctl_dev_scsi_hd_nec:
pUnit = new SCSIHD_NEC();
break;
case rasctl_dev_mo:
pUnit = new SCSIMO();
break;
case rasctl_dev_cd:
pUnit = new SCSICD();
break;
case rasctl_dev_br:
pUnit = new SCSIBR();
break;
default:
FPRT(fp, "Error : Invalid device type\n");
return FALSE;
}
// drive checks files
switch(incoming_command->type){
case rasctl_dev_mo:
case rasctl_dev_scsi_hd_nec:
case rasctl_dev_sasi_hd:
case rasctl_dev_scsi_hd:
case rasctl_dev_cd:
case rasctl_dev_scsi_hd_appl:
// Set the Path
filepath.SetPath(incoming_command->file);
// Open the file path
if (!pUnit->Open(filepath)) {
FPRT(fp, "Error : File open error [%s]\n", incoming_command->file);
delete pUnit;
return FALSE;
}
// Create a new drive, based upon type
switch (incoming_command->type) {
case rasctl_dev_sasi_hd: // HDF
pUnit = new SASIHD();
break;
case rasctl_dev_br:
case rasctl_dev_invalid:
// Do nothing
case rasctl_dev_scsi_hd: // HDS/HDN/HDI/NHD/HDA
pUnit = new SCSIHD();
break;
case rasctl_dev_scsi_hd_appl:
pUnit = new SCSIHD_APPLE();
break;
case rasctl_dev_scsi_hd_nec:
pUnit = new SCSIHD_NEC();
break;
case rasctl_dev_mo:
pUnit = new SCSIMO();
break;
case rasctl_dev_cd:
pUnit = new SCSICD();
break;
case rasctl_dev_br:
pUnit = new SCSIBR();
break;
default:
FPRT(fp, "Error : Invalid device type\n");
return FALSE;
}
// drive checks files
switch(incoming_command->type){
case rasctl_dev_mo:
case rasctl_dev_scsi_hd_nec:
case rasctl_dev_sasi_hd:
case rasctl_dev_scsi_hd:
case rasctl_dev_cd:
case rasctl_dev_scsi_hd_appl:
// Set the Path
filepath.SetPath(incoming_command->file);
// Open the file path
if (!pUnit->Open(filepath)) {
FPRT(fp, "Error : File open error [%s]\n", incoming_command->file);
delete pUnit;
return FALSE;
}
break;
case rasctl_dev_br:
case rasctl_dev_invalid:
// Do nothing
break;
}
// Set the cache to write-through
pUnit->SetCacheWB(FALSE);
// Set the cache to write-through
pUnit->SetCacheWB(FALSE);
// // Replace with the newly created unit
// map[id * Rascsi_Manager::GetInstance()->UnitNum + un] = pUnit;
// Map the controller
return Rascsi_Manager::GetInstance()->AttachDevice(fp, pUnit, incoming_command->id, incoming_command->un);
// Map the controller
Rascsi_Manager::GetInstance()->MapControler(fp, map);
return TRUE;
return FALSE;}
}
BOOL Command_Thread::DoDetach(FILE *fp, Rasctl_Command *incoming_command){
return Rascsi_Manager::GetInstance()->DetachDevice(fp, incoming_command->id, incoming_command->un);
}
// // Does the controller exist?
// if (Rascsi_Manager::GetInstance()->m_ctrl[id] == NULL) {
// FPRT(fp, "Error : No such device\n");
// return FALSE;
// }
// // Does the unit exist?
// pUnit = Rascsi_Manager::GetInstance()->m_disk[id * Rascsi_Manager::GetInstance()->UnitNum + un];
// if (pUnit == NULL) {
// FPRT(fp, "Error : No such device\n");
// return FALSE;
// }
// // Disconnect Command
// if (cmd == 1) { // DETACH
// // Free the existing unit
// map[id * Rascsi_Manager::GetInstance()->UnitNum + un] = NULL;
// // Re-map the controller
// Rascsi_Manager::GetInstance()->MapControler(fp, map);
// return TRUE;
// }
return FALSE;}
BOOL Command_Thread::DoInsert(FILE *fp, Rasctl_Command *incoming_command){

View File

@@ -989,6 +989,18 @@ BOOL FASTCALL Disk::IsSASI() const
return FALSE;
}
//---------------------------------------------------------------------------
//
// SCSI Check
//
//---------------------------------------------------------------------------
BOOL FASTCALL Disk::IsSCSI() const
{
ASSERT(this);
// If this isn't SASI, then it must be SCSI.
return (this->IsSASI()) ? FALSE : TRUE;
}
//---------------------------------------------------------------------------
//
// Open

View File

@@ -239,6 +239,8 @@ public:
// NULL check
BOOL FASTCALL IsSASI() const;
// SASI Check
BOOL FASTCALL IsSCSI() const;
// SASI Check
// Media Operations
virtual BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE);

View File

@@ -124,6 +124,8 @@ BOOL FASTCALL Fileio::Open(LPCTSTR fname, OpenMode mode, BOOL directIO)
#ifndef __APPLE__
// デフォルトモード
omode = directIO ? O_DIRECT : 0;
#else
omode = 0;
#endif // ifndef __APPLE__
// モード別

View File

@@ -48,6 +48,10 @@ FATFS fatfs; // FatFS
#endif // BAREMETAL
Rascsi_Manager *mgr;
#ifndef CONNECT_DESC
#define CONNECT_DESC "UNKNOWN"
#endif
#ifndef BAREMETAL
//---------------------------------------------------------------------------
//

View File

@@ -25,238 +25,121 @@ Rascsi_Manager* Rascsi_Manager::GetInstance(){
return m_instance;
}
BOOL Rascsi_Manager::AttachDevice(FILE *fp, Disk *disk, int id, int unit_num){
BOOL result;
m_locked.lock();
result = AttachDevicePrivate(fp, disk, id, unit_num);
m_locked.unlock();
return result;
}
void Rascsi_Manager::AttachDevice(FILE *fp, Disk *disk, int id, int unit_num){
BOOL Rascsi_Manager::DetachDevice(FILE *fp, int id, int unit_num){
BOOL result;
m_locked.lock();
result = DetachDevicePrivate(fp, id, unit_num);
m_locked.unlock();
return result;
}
BOOL Rascsi_Manager::AttachDevicePrivate(FILE *fp, Disk *disk, int id, int unit_num)
{
Rascsi_Device_Mode_e cur_mode = GetCurrentDeviceMode();
int unitno = (id * UnitNum) + unit_num;
// Get the lock
m_locked.lock();
if((disk->IsSASI() && (cur_mode == rascsi_device_scsi_mode)) ||
(!disk->IsSCSI() && (cur_mode == rascsi_device_sasi_mode))){
FPRT(fp, "Warning: Can't mix SASI and SCSI devices!\n");
return FALSE;
}
// Check if something already exists at that SCSI ID / Unit Number
if (m_disk[unitno]) {
// Disconnect it from the controller
if (m_ctrl[i]) {
m_ctrl[i]->SetUnit(j, NULL);
}else{
printf("Warning: A controller was not connected to the drive at id %d un %d\n",id, unit_num);
}
// Free the Unit
delete m_disk[unitno];
DetachDevice(fp,id,unit_num);
}
// Add the new unit
m_disk[unitno] = disk;
// Reconfigure all of the controllers
for (i = 0; i < CtrlMax; i++) {
// Examine the unit configuration
sasi_num = 0;
scsi_num = 0;
for (j = 0; j < UnitNum; j++) {
unitno = i * UnitNum + j;
// branch by unit type
if (m_disk[unitno]) {
if (m_disk[unitno]->IsSASI()) {
// Drive is SASI, so increment SASI count
sasi_num++;
} else {
// Drive is SCSI, so increment SCSI count
scsi_num++;
}
}
// Remove the unit
if (m_ctrl[i]) {
m_ctrl[i]->SetUnit(j, NULL);
}
}
// If there are no units connected
if (sasi_num == 0 && scsi_num == 0) {
if (m_ctrl[i]) {
delete m_ctrl[i];
m_ctrl[i] = NULL;
continue;
}
}
// Mixture of SCSI and SASI
if (sasi_num > 0 && scsi_num > 0) {
FPRT(fp, "Error : SASI and SCSI can't be mixed\n");
continue;
}
if (sasi_num > 0) {
// Only SASI Unit(s)
// Release the controller if it is not SASI
if (m_ctrl[i] && !m_ctrl[i]->IsSASI()) {
delete m_ctrl[i];
m_ctrl[i] = NULL;
}
// Create a new SASI controller
if (!m_ctrl[i]) {
m_ctrl[i] = new SASIDEV();
m_ctrl[i]->Connect(i, m_bus);
}
} else {
// Only SCSI Unit(s)
// Release the controller if it is not SCSI
if (m_ctrl[i] && !m_ctrl[i]->IsSCSI()) {
delete m_ctrl[i];
m_ctrl[i] = NULL;
}
// Create a new SCSI controller
if (!m_ctrl[i]) {
m_ctrl[i] = new SCSIDEV();
m_ctrl[i]->Connect(i, m_bus);
}
}
// connect all units
for (j = 0; j < UnitNum; j++) {
unitno = i * UnitNum + j;
if (m_disk[unitno]) {
// Add the unit connection
m_ctrl[i]->SetUnit(j, m_disk[unitno]);
}
// If the controllder doesn't already exist, create it.
if (m_ctrl[id] == nullptr){
// We need to create a new controller
if(disk->IsSASI()){
m_ctrl[id] = new SASIDEV();
}else{
m_ctrl[id] = new SCSIDEV();
}
m_ctrl[id]->Connect(id, m_bus);
}
}
void Rascsi_Manager::DetachDevice(FILE *fp, Disk *map, int id, int ui)
{
return;
}
Disk* Rascsi_Manager::GetDevice(FILE *fp, int id, int ui)
{
return nullptr;
}
//---------------------------------------------------------------------------
//
// Controller Mapping
//
//---------------------------------------------------------------------------
void Rascsi_Manager::MapControler(FILE *fp, Disk **map)
{
int i;
int j;
int unitno;
int sasi_num;
int scsi_num;
// Replace the changed unit
for (i = 0; i < CtrlMax; i++) {
for (j = 0; j < UnitNum; j++) {
unitno = i * UnitNum + j;
if (m_disk[unitno] != map[unitno]) {
// Check if the original unit exists
if (m_disk[unitno]) {
// Disconnect it from the controller
if (m_ctrl[i]) {
m_ctrl[i]->SetUnit(j, NULL);
}
// Free the Unit
delete m_disk[unitno];
}
// Setup a new unit
m_disk[unitno] = map[unitno];
}
}
}
// Reconfigure all of the controllers
for (i = 0; i < CtrlMax; i++) {
// Examine the unit configuration
sasi_num = 0;
scsi_num = 0;
for (j = 0; j < UnitNum; j++) {
unitno = i * UnitNum + j;
// branch by unit type
if (m_disk[unitno]) {
if (m_disk[unitno]->IsSASI()) {
// Drive is SASI, so increment SASI count
sasi_num++;
} else {
// Drive is SCSI, so increment SCSI count
scsi_num++;
}
}
// Remove the unit
if (m_ctrl[i]) {
m_ctrl[i]->SetUnit(j, NULL);
}
}
// If there are no units connected
if (sasi_num == 0 && scsi_num == 0) {
if (m_ctrl[i]) {
delete m_ctrl[i];
m_ctrl[i] = NULL;
continue;
}
}
// Mixture of SCSI and SASI
if (sasi_num > 0 && scsi_num > 0) {
FPRT(fp, "Error : SASI and SCSI can't be mixed\n");
continue;
}
if (sasi_num > 0) {
// Only SASI Unit(s)
// Release the controller if it is not SASI
if (m_ctrl[i] && !m_ctrl[i]->IsSASI()) {
delete m_ctrl[i];
m_ctrl[i] = NULL;
}
// Create a new SASI controller
if (!m_ctrl[i]) {
m_ctrl[i] = new SASIDEV();
m_ctrl[i]->Connect(i, m_bus);
}
} else {
// Only SCSI Unit(s)
// Release the controller if it is not SCSI
if (m_ctrl[i] && !m_ctrl[i]->IsSCSI()) {
delete m_ctrl[i];
m_ctrl[i] = NULL;
}
// Create a new SCSI controller
if (!m_ctrl[i]) {
m_ctrl[i] = new SCSIDEV();
m_ctrl[i]->Connect(i, m_bus);
}
}
// connect all units
for (j = 0; j < UnitNum; j++) {
unitno = i * UnitNum + j;
if (m_disk[unitno]) {
// Add the unit connection
m_ctrl[i]->SetUnit(j, m_disk[unitno]);
}
}
}
// Add the disk to the controller
m_ctrl[id]->SetUnit(unit_num, disk);
}
BOOL Rascsi_Manager::DetachDevicePrivate(FILE *fp, int id, int unit_num)
{
int unitno = (id * UnitNum) + unit_num;
// Disconnect it from the controller
if (m_ctrl[id]) {
m_ctrl[id]->SetUnit(unit_num, NULL);
// Free the Unit
delete m_disk[unitno];
m_disk[unitno] = nullptr;
}else{
fprintf(fp, "Warning: A controller was not connected to the drive at id %d un %d\n",id, unit_num);
fprintf(fp, "This is some sort of internal error, since you can't have a device without a controller.\n");
return FALSE;
}
// If there are no longer any units connected to this controller, delete it
if(!m_ctrl[id]->HasUnit()){
delete m_ctrl[id];
m_ctrl[id] = nullptr;
}
return TRUE;
}
Disk* Rascsi_Manager::GetDevice(FILE *fp, int id, int unit_num)
{
int unitno = (id * UnitNum) + unit_num;
return m_disk[unitno];
}
//---------------------------------------------------------------------------
//
// GetCurrentDeviceMode
//
// Loop through all of the controllers and check if we have SCSI or SASI
// controllers already created. (Note: We can't have a mix of them)
//
//---------------------------------------------------------------------------
Rascsi_Device_Mode_e Rascsi_Manager::GetCurrentDeviceMode(){
Rascsi_Device_Mode_e mode = rascsi_device_unknown_mode;
for(int i =0; i < CtrlMax; i++){
if(m_ctrl[i] != nullptr){
if(m_ctrl[i]->IsSASI()){
if(mode == rascsi_device_unknown_mode){
mode = rascsi_device_sasi_mode;
}else if(mode == rascsi_device_scsi_mode){
mode = rascsi_device_invalid_mode;
printf("Error: Mix of SCSI and SASI devices. This isn't allowed. Device %d was SASI, but expecting SCSI\n", i);
}
}else { // This is SCSI
if(mode == rascsi_device_unknown_mode){
mode = rascsi_device_scsi_mode;
}else if(mode == rascsi_device_sasi_mode){
mode = rascsi_device_invalid_mode;
printf("Error: Mix of SCSI and SASI devices. This isn't allowed. Device %d was SCSI, but expecting SASI\n", i);
}
}
}
}
return mode;
}
//---------------------------------------------------------------------------
//

View File

@@ -27,18 +27,28 @@
#include "sasidev_ctrl.h"
#include <mutex>
enum Rascsi_Device_Mode_e{
rascsi_device_unknown_mode,
rascsi_device_sasi_mode,
rascsi_device_scsi_mode,
rascsi_device_invalid_mode,
};
class Rascsi_Manager{
public:
static Rascsi_Manager* GetInstance();
void MapControler(FILE *fp, Disk **map);
void AttachDevice(FILE *fp, Disk *disk, int id, int ui);
void DetachDevice(FILE *fp, Disk *disk, int id, int ui);
BOOL AttachDevice(FILE *fp, Disk *disk, int id, int ui);
BOOL DetachDevice(FILE *fp, int id, int ui);
Disk* GetDevice(FILE *fp, int id, int ui);
void ListDevice(FILE *fp);
BOOL Init();
void Close();
void Reset();
BOOL Step();
Rascsi_Device_Mode_e GetCurrentDeviceMode();
static const int CtrlMax = 8; // Maximum number of SCSI controllers
static const int UnitNum=2; // Number of units around controller
@@ -62,6 +72,9 @@ class Rascsi_Manager{
static BOOL m_active;
static BOOL m_running;
BOOL AttachDevicePrivate(FILE *fp, Disk *disk, int id, int ui);
BOOL DetachDevicePrivate(FILE *fp, int id, int ui);
// Any PUBLIC functions should lock this before accessing the m_ctrl
// m_disk or m_bus data structures. The Public functions could be
// called from a different thread.