mirror of
https://github.com/thewesker/RASCSI.git
synced 2025-12-20 12:21:10 -05:00
Additional updates
This commit is contained in:
@@ -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);
|
||||
@@ -610,41 +612,14 @@ BOOL Command_Thread::DoAttach(FILE *fp, Rasctl_Command *incoming_command){
|
||||
// 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
|
||||
Rascsi_Manager::GetInstance()->MapControler(fp, map);
|
||||
return TRUE;
|
||||
return Rascsi_Manager::GetInstance()->AttachDevice(fp, pUnit, incoming_command->id, incoming_command->un);
|
||||
|
||||
|
||||
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){
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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__
|
||||
|
||||
// モード別
|
||||
|
||||
@@ -48,6 +48,10 @@ FATFS fatfs; // FatFS
|
||||
#endif // BAREMETAL
|
||||
Rascsi_Manager *mgr;
|
||||
|
||||
#ifndef CONNECT_DESC
|
||||
#define CONNECT_DESC "UNKNOWN"
|
||||
#endif
|
||||
|
||||
#ifndef BAREMETAL
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
@@ -25,237 +25,120 @@ 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++;
|
||||
// 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{
|
||||
// Drive is SCSI, so increment SCSI count
|
||||
scsi_num++;
|
||||
m_ctrl[id] = new SCSIDEV();
|
||||
}
|
||||
m_ctrl[id]->Connect(id, m_bus);
|
||||
}
|
||||
|
||||
// Remove the unit
|
||||
if (m_ctrl[i]) {
|
||||
m_ctrl[i]->SetUnit(j, NULL);
|
||||
}
|
||||
// Add the disk to the controller
|
||||
m_ctrl[id]->SetUnit(unit_num, disk);
|
||||
}
|
||||
|
||||
// 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
void Rascsi_Manager::DetachDevice(FILE *fp, Disk *map, int id, int ui)
|
||||
BOOL Rascsi_Manager::DetachDevicePrivate(FILE *fp, int id, int unit_num)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Disk* Rascsi_Manager::GetDevice(FILE *fp, int id, int ui)
|
||||
{
|
||||
return nullptr;
|
||||
int unitno = (id * UnitNum) + unit_num;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 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);
|
||||
}
|
||||
|
||||
if (m_ctrl[id]) {
|
||||
m_ctrl[id]->SetUnit(unit_num, 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++;
|
||||
m_disk[unitno] = nullptr;
|
||||
}else{
|
||||
// Drive is SCSI, so increment SCSI count
|
||||
scsi_num++;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
// Remove the unit
|
||||
if (m_ctrl[i]) {
|
||||
m_ctrl[i]->SetUnit(j, NULL);
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Mixture of SCSI and SASI
|
||||
if (sasi_num > 0 && scsi_num > 0) {
|
||||
FPRT(fp, "Error : SASI and SCSI can't be mixed\n");
|
||||
continue;
|
||||
Disk* Rascsi_Manager::GetDevice(FILE *fp, int id, int unit_num)
|
||||
{
|
||||
int unitno = (id * UnitNum) + unit_num;
|
||||
return m_disk[unitno];
|
||||
}
|
||||
|
||||
if (sasi_num > 0) {
|
||||
// Only SASI Unit(s)
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 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(){
|
||||
|
||||
// Release the controller if it is not SASI
|
||||
if (m_ctrl[i] && !m_ctrl[i]->IsSASI()) {
|
||||
delete m_ctrl[i];
|
||||
m_ctrl[i] = NULL;
|
||||
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;
|
||||
}
|
||||
|
||||
// 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user