From f263dd03b36a86cfdce0e7fab8fb1e768e4ec58c Mon Sep 17 00:00:00 2001 From: akuker Date: Thu, 9 Jul 2020 13:36:25 -0500 Subject: [PATCH] Removed extraneous debug printfs, removed scsimon --- src/raspberrypi/.gitignore | 6 + src/raspberrypi/Makefile | 11 - src/raspberrypi/disk.cpp | 57 +- src/raspberrypi/scsimon.cpp | 1174 -------------------- src/raspberrypi/scsimondev.cpp | 1902 -------------------------------- 5 files changed, 35 insertions(+), 3115 deletions(-) delete mode 100644 src/raspberrypi/scsimon.cpp delete mode 100644 src/raspberrypi/scsimondev.cpp diff --git a/src/raspberrypi/.gitignore b/src/raspberrypi/.gitignore index 02c03f1e..659c6429 100644 --- a/src/raspberrypi/.gitignore +++ b/src/raspberrypi/.gitignore @@ -1,2 +1,8 @@ *.o *.bak +*.HDA +*.save +*.cbp +*.layout +*.log + diff --git a/src/raspberrypi/Makefile b/src/raspberrypi/Makefile index 883e8a0e..81632219 100644 --- a/src/raspberrypi/Makefile +++ b/src/raspberrypi/Makefile @@ -63,17 +63,6 @@ SRC_SASIDUMP = \ filepath.cpp \ fileio.cpp -SRC_SCSIMON = \ - scsimon.cpp \ - scsi.cpp \ - disk.cpp \ - gpiobus.cpp \ - ctapdriver.cpp \ - cfilesystem.cpp \ - filepath.cpp \ - fileio.cpp \ - scsimondev.cpp - OBJ_RASCSI := $(SRC_RASCSI:%.cpp=%.o) OBJ_RASCTL := $(SRC_RASCTL:%.cpp=%.o) OBJ_RASDUMP := $(SRC_RASDUMP:%.cpp=%.o) diff --git a/src/raspberrypi/disk.cpp b/src/raspberrypi/disk.cpp index 676c166a..793a95e0 100644 --- a/src/raspberrypi/disk.cpp +++ b/src/raspberrypi/disk.cpp @@ -1346,20 +1346,20 @@ int FASTCALL Disk::ModeSense(const DWORD *cdb, BYTE *buf) // Get changeable flag if ((cdb[2] & 0xc0) == 0x40) { - printf("MODESENSE: Change = TRUE\n"); + //** printf("MODESENSE: Change = TRUE\n"); change = TRUE; } else { - printf("MODESENSE: Change = FALSE\n"); + //** printf("MODESENSE: Change = FALSE\n"); change = FALSE; } // Get page code (0x00 is valid from the beginning) page = cdb[2] & 0x3f; if (page == 0x00) { - printf("MODESENSE: Page code: OK %02X\n", cdb[2]); + //** printf("MODESENSE: Page code: OK %02X\n", cdb[2]); valid = TRUE; } else { - printf("MODESENSE: Invalid page code received %02X\n", cdb[2]); + //** printf("MODESENSE: Invalid page code received %02X\n", cdb[2]); valid = FALSE; } @@ -1373,7 +1373,7 @@ int FASTCALL Disk::ModeSense(const DWORD *cdb, BYTE *buf) // DEVICE SPECIFIC PARAMETER if (disk.writep) { - printf("MODESENSE: Write protect\n"); + //** printf("MODESENSE: Write protect\n"); buf[2] = 0x80; } @@ -1384,7 +1384,7 @@ int FASTCALL Disk::ModeSense(const DWORD *cdb, BYTE *buf) // Only if ready if (disk.ready) { - printf("MODESENSE: Disk is ready\n"); + //** printf("MODESENSE: Disk is ready\n"); // Block descriptor (number of blocks) buf[5] = (BYTE)(disk.blocks >> 16); buf[6] = (BYTE)(disk.blocks >> 8); @@ -1461,12 +1461,12 @@ int FASTCALL Disk::ModeSense(const DWORD *cdb, BYTE *buf) // Unsupported page if (!valid) { - printf("MODESENSE: Something was invalid...\n"); + //** printf("MODESENSE: Something was invalid...\n"); disk.code = DISK_INVALIDCDB; return 0; } - printf("MODESENSE: mode sense length is %d\n",length); + //** printf("MODESENSE: mode sense length is %d\n",length); // MODE SENSE success disk.code = DISK_NOERROR; @@ -6474,12 +6474,12 @@ void FASTCALL SASIDEV::Command() #ifdef RASCSI // Command reception handshake (10 bytes are automatically received at the first command) count = ctrl.bus->CommandHandShake(ctrl.buffer); - printf("Command received: " ); - for(int i=0; i< count; i++) - { - printf("%02X ", ctrl.buffer[i]); - } - printf("\n"); + //** printf("Command received: " ); + //** for(int i=0; i< count; i++) + //** { + //** printf("%02X ", ctrl.buffer[i]); + //** } + //** printf("\n"); // If no byte can be received move to the status phase if (count == 0) { @@ -7436,7 +7436,7 @@ void FASTCALL SASIDEV::Send() if (ctrl.blocks != 0) { // Set next buffer (set offset, length) result = XferIn(ctrl.buffer); - printf("xfer in: %d \n",result); + //** printf("xfer in: %d \n",result); #ifndef RASCSI ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); @@ -7713,12 +7713,12 @@ BOOL FASTCALL SASIDEV::XferIn(BYTE *buf) ctrl.length = ctrl.unit[lun]->Read(buf, ctrl.next); ctrl.next++; - printf("XferIn read data from disk: "); - for (int i=0; i> 5) & 0x07; diff --git a/src/raspberrypi/scsimon.cpp b/src/raspberrypi/scsimon.cpp deleted file mode 100644 index 3bdf95bf..00000000 --- a/src/raspberrypi/scsimon.cpp +++ /dev/null @@ -1,1174 +0,0 @@ -//--------------------------------------------------------------------------- -// -// SCSI Target Emulator RaSCSI (*^..^*) -// for Raspberry Pi -// -// Powered by XM6 TypeG Technology. -// Copyright (C) 2016-2020 GIMONS -// [ RaSCSI main ] -// -//--------------------------------------------------------------------------- - -#include "os.h" -#include "xm6.h" -#include "filepath.h" -#include "fileio.h" -#include "disk.h" -#include "gpiobus.h" - -//--------------------------------------------------------------------------- -// -// Constant declarations -// -//--------------------------------------------------------------------------- -#define CtrlMax 8 // Maximum number of SCSI controllers -#define UnitNum 2 // Number of units around controller -#ifdef BAREMETAL -#define FPRT(fp, ...) printf( __VA_ARGS__ ) -#else -#define FPRT(fp, ...) fprintf(fp, __VA_ARGS__ ) -#endif // BAREMETAL - -//--------------------------------------------------------------------------- -// -// Variable declarations -// -//--------------------------------------------------------------------------- -static volatile BOOL running; // Running flag -static volatile BOOL active; // Processing flag -SASIDEV *ctrl[CtrlMax]; // Controller -Disk *disk[CtrlMax * UnitNum]; // Disk -GPIOBUS *bus; // GPIO Bus -#ifdef BAREMETAL -FATFS fatfs; // FatFS -#else -int monsocket; // Monitor Socket -pthread_t monthread; // Monitor Thread -static void *MonThread(void *param); -#endif // BAREMETAL - -#ifndef BAREMETAL -//--------------------------------------------------------------------------- -// -// Signal Processing -// -//--------------------------------------------------------------------------- -void KillHandler(int sig) -{ - // Stop instruction - running = FALSE; -} -#endif // BAREMETAL - -//--------------------------------------------------------------------------- -// -// Banner Output -// -//--------------------------------------------------------------------------- -void Banner(int argc, char* argv[]) -{ - FPRT(stdout,"SCSI Target Emulator RaSCSI(*^..^*) "); - FPRT(stdout,"version %01d.%01d%01d(%s, %s)\n", - (int)((VERSION >> 8) & 0xf), - (int)((VERSION >> 4) & 0xf), - (int)((VERSION ) & 0xf), - __DATE__, - __TIME__); - FPRT(stdout,"Powered by XM6 TypeG Technology / "); - FPRT(stdout,"Copyright (C) 2016-2020 GIMONS\n"); - FPRT(stdout,"Connect type : %s\n", CONNECT_DESC); - - if (argc > 1 && strcmp(argv[1], "-h") == 0) { - FPRT(stdout,"\n"); - FPRT(stdout,"Usage: %s [-IDn FILE] ...\n\n", argv[0]); - FPRT(stdout," n is SCSI identification number(0-7).\n"); - FPRT(stdout," FILE is disk image file.\n\n"); - FPRT(stdout,"Usage: %s [-HDn FILE] ...\n\n", argv[0]); - FPRT(stdout," n is X68000 SASI HD number(0-15).\n"); - FPRT(stdout," FILE is disk image file.\n\n"); - FPRT(stdout," Image type is detected based on file extension.\n"); - FPRT(stdout," hdf : SASI HD image(XM6 SASI HD image)\n"); - FPRT(stdout," hds : SCSI HD image(XM6 SCSI HD image)\n"); - FPRT(stdout," hdn : SCSI HD image(NEC GENUINE)\n"); - FPRT(stdout," hdi : SCSI HD image(Anex86 HD image)\n"); - FPRT(stdout," nhd : SCSI HD image(T98Next HD image)\n"); - FPRT(stdout," hda : SCSI HD image(APPLE GENUINE)\n"); - FPRT(stdout," mos : SCSI MO image(XM6 SCSI MO image)\n"); - FPRT(stdout," iso : SCSI CD image(ISO 9660 image)\n"); - -#ifndef BAREMETAL - exit(0); -#endif // BAREMETAL - } -} - -//--------------------------------------------------------------------------- -// -// Initialization -// -//--------------------------------------------------------------------------- -BOOL Init() -{ - int i; - -#ifndef BAREMETAL - struct sockaddr_in server; - int yes; - - // Create socket for monitor - monsocket = socket(PF_INET, SOCK_STREAM, 0); - memset(&server, 0, sizeof(server)); - server.sin_family = PF_INET; - server.sin_port = htons(6868); - server.sin_addr.s_addr = htonl(INADDR_ANY); - - // allow address reuse - yes = 1; - if (setsockopt( - monsocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0){ - return FALSE; - } - - // Bind - if (bind(monsocket, (struct sockaddr *)&server, - sizeof(struct sockaddr_in)) < 0) { - FPRT(stderr, "Error : Already running?\n"); - return FALSE; - } - - // Create Monitor Thread - pthread_create(&monthread, NULL, MonThread, NULL); - - // Interrupt handler settings - if (signal(SIGINT, KillHandler) == SIG_ERR) { - return FALSE; - } - if (signal(SIGHUP, KillHandler) == SIG_ERR) { - return FALSE; - } - if (signal(SIGTERM, KillHandler) == SIG_ERR) { - return FALSE; - } -#endif // BAREMETAL - - // GPIOBUS creation - bus = new GPIOBUS(); - - // GPIO Initialization - if (!bus->Init(BUS::MONITOR)) { - return FALSE; - } - - // Bus Reset - bus->Reset(); - bus->SetIO(FALSE); - - // Controller initialization - for (i = 0; i < CtrlMax; i++) { - ctrl[i] = NULL; - } - - // Disk Initialization - for (i = 0; i < CtrlMax; i++) { - disk[i] = NULL; - } - - // Other - running = FALSE; - active = FALSE; - - return TRUE; -} - -//--------------------------------------------------------------------------- -// -// Cleanup -// -//--------------------------------------------------------------------------- -void Cleanup() -{ - int i; - - // Delete the disks - for (i = 0; i < CtrlMax * UnitNum; i++) { - if (disk[i]) { - delete disk[i]; - disk[i] = NULL; - } - } - - // Delete the Controllers - for (i = 0; i < CtrlMax; i++) { - if (ctrl[i]) { - delete ctrl[i]; - ctrl[i] = NULL; - } - } - - // Cleanup the Bus - bus->Cleanup(); - - // Discard the GPIOBUS object - delete bus; - -#ifndef BAREMETAL - // Close the monitor socket - if (monsocket >= 0) { - close(monsocket); - } -#endif // BAREMETAL -} - -//--------------------------------------------------------------------------- -// -// Reset -// -//--------------------------------------------------------------------------- -void Reset() -{ - int i; - - // Reset all of the controllers - for (i = 0; i < CtrlMax; i++) { - if (ctrl[i]) { - ctrl[i]->Reset(); - } - } - - // Reset the bus - bus->Reset(); -} - -//--------------------------------------------------------------------------- -// -// List Devices -// -//--------------------------------------------------------------------------- -void ListDevice(FILE *fp) -{ - int i; - int id; - int un; - Disk *pUnit; - Filepath filepath; - BOOL find; - char type[5]; - - find = FALSE; - type[4] = 0; - for (i = 0; i < CtrlMax * UnitNum; i++) { - // Initialize ID and unit number - id = i / UnitNum; - un = i % UnitNum; - pUnit = disk[i]; - - // skip if unit does not exist or null disk - if (pUnit == NULL || pUnit->IsNULL()) { - continue; - } - - // Output the header - if (!find) { - FPRT(fp, "\n"); - FPRT(fp, "+----+----+------+-------------------------------------\n"); - FPRT(fp, "| ID | UN | TYPE | DEVICE STATUS\n"); - FPRT(fp, "+----+----+------+-------------------------------------\n"); - find = TRUE; - } - - // ID,UNIT,Type,Device Status - type[0] = (char)(pUnit->GetID() >> 24); - type[1] = (char)(pUnit->GetID() >> 16); - type[2] = (char)(pUnit->GetID() >> 8); - type[3] = (char)(pUnit->GetID()); - FPRT(fp, "| %d | %d | %s | ", id, un, type); - - // mount status output - if (pUnit->GetID() == MAKEID('S', 'C', 'B', 'R')) { - FPRT(fp, "%s", "HOST BRIDGE"); - } else { - pUnit->GetPath(filepath); - FPRT(fp, "%s", - (pUnit->IsRemovable() && !pUnit->IsReady()) ? - "NO MEDIA" : filepath.GetPath()); - } - - // Write protection status - if (pUnit->IsRemovable() && pUnit->IsReady() && pUnit->IsWriteP()) { - FPRT(fp, "(WRITEPROTECT)"); - } - - // Goto the next line - FPRT(fp, "\n"); - } - - // If there is no controller, find will be null - if (!find) { - FPRT(fp, "No device is installed.\n"); - return; - } - - FPRT(fp, "+----+----+------+-------------------------------------\n"); -} - -//--------------------------------------------------------------------------- -// -// Controller Mapping -// -//--------------------------------------------------------------------------- -void MapControler(FILE *fp, Disk **map) -{ - int i; - int j; - int unitno; - int sasi_num; - int scsi_num; - BOOL is_monitor; - - // Replace the changed unit - for (i = 0; i < CtrlMax; i++) { - for (j = 0; j < UnitNum; j++) { - unitno = i * UnitNum + j; - if (disk[unitno] != map[unitno]) { - // Check if the original unit exists - if (disk[unitno]) { - // Disconnect it from the controller - if (ctrl[i]) { - ctrl[i]->SetUnit(j, NULL); - } - - // Free the Unit - delete disk[unitno]; - } - - // Setup a new unit - 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 (disk[unitno]) { - if (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 (ctrl[i]) { - ctrl[i]->SetUnit(j, NULL); - } - } - - // If there are no units connected - if (sasi_num == 0 && scsi_num == 0) { - if (ctrl[i]) { - delete ctrl[i]; - 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 (ctrl[i] && !ctrl[i]->IsSASI()) { - delete ctrl[i]; - ctrl[i] = NULL; - } - - // Create a new SASI controller - if (!ctrl[i]) { - ctrl[i] = new SASIDEV(); - ctrl[i]->Connect(i, bus); - } - } else { - // Only SCSI Unit(s) - - // Release the controller if it is not SCSI - if (ctrl[i] && !ctrl[i]->IsSCSI()) { - delete ctrl[i]; - ctrl[i] = NULL; - } - - // Create a new SCSI controller - if (!ctrl[i]) { - // Check to see if we need a standard SCSI controller - // or if we are creating a "monitor" controller - is_monitor = FALSE; - for (j = 0; j < UnitNum; j++) - { - unitno = i * UnitNum + j; - if( disk[unitno] && disk[unitno]->IsMonitor()) - { - is_monitor = TRUE; - break; - } - } - if(is_monitor == TRUE) - { - ctrl[i] = new SCSIMONDEV(); - } - else - { - ctrl[i] = new SCSIDEV(); - } - ctrl[i]->Connect(i, bus); - } - } - - // connect all units - for (j = 0; j < UnitNum; j++) { - unitno = i * UnitNum + j; - if (disk[unitno]) { - // Add the unit connection - ctrl[i]->SetUnit(j, disk[unitno]); - } - } - } -} - -//--------------------------------------------------------------------------- -// -// Command Processing -// -//--------------------------------------------------------------------------- -BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) -{ - Disk *map[CtrlMax * UnitNum]; - int len; - char *ext; - Filepath filepath; - Disk *pUnit; - - // Copy the Unit List - memcpy(map, disk, sizeof(disk)); - - // Check the Controller Number - if (id < 0 || id >= CtrlMax) { - FPRT(fp, "Error : Invalid ID\n"); - return FALSE; - } - - // Check the Unit Number - if (un < 0 || un >= UnitNum) { - FPRT(fp, "Error : Invalid unit number\n"); - return FALSE; - } - - // Connect Command - if (cmd == 0) { // ATTACH - // Distinguish between SASI and SCSI - ext = NULL; - pUnit = NULL; - if (type == 0) { - // Passed the check - if (!file) { - return FALSE; - } - - // Check that command is at least 5 characters long - len = strlen(file); - if (len < 5) { - return FALSE; - } - - // Check the extension - if (file[len - 4] != '.') { - return FALSE; - } - - // If the extension is not SASI type, replace with SCSI - ext = &file[len - 3]; - if (xstrcasecmp(ext, "hdf") != 0) { - type = 1; - } - } - - // Create a new drive, based upon type - switch (type) { - case 0: // HDF - pUnit = new SASIHD(); - break; - case 1: // HDS/HDN/HDI/NHD/HDA - if (ext == NULL) { - break; - } - if (xstrcasecmp(ext, "hdn") == 0 || - xstrcasecmp(ext, "hdi") == 0 || xstrcasecmp(ext, "nhd") == 0) { - pUnit = new SCSIHD_NEC(); - } else if (xstrcasecmp(ext, "hda") == 0) { - pUnit = new SCSIHD_APPLE(); - } else { - pUnit = new SCSIHD(); - } - break; - case 2: // MO - pUnit = new SCSIMO(); - break; - case 3: // CD - pUnit = new SCSICD(); - break; - case 4: // BRIDGE - pUnit = new SCSIBR(); - break; - case 5: // Logger/Monitor device - pUnit = new MONITORHD(); - break; - default: - FPRT(fp, "Error : Invalid device type\n"); - return FALSE; - } - - // drive checks files - if (type <= 1 || (type <= 3 && xstrcasecmp(file, "-") != 0)) { - // Set the Path - filepath.SetPath(file); - - // Open the file path - if (!pUnit->Open(filepath)) { - FPRT(fp, "Error : File open error [%s]\n", file); - delete pUnit; - return FALSE; - } - } - - // Set the cache to write-through - pUnit->SetCacheWB(FALSE); - - // Replace with the newly created unit - map[id * UnitNum + un] = pUnit; - - // Re-map the controller - MapControler(fp, map); - return TRUE; - } - - // Is this a valid command? - if (cmd > 4) { - FPRT(fp, "Error : Invalid command\n"); - return FALSE; - } - - // Does the controller exist? - if (ctrl[id] == NULL) { - FPRT(fp, "Error : No such device\n"); - return FALSE; - } - - // Does the unit exist? - pUnit = disk[id * 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 * UnitNum + un] = NULL; - - // Re-map the controller - MapControler(fp, map); - return TRUE; - } - - // Valid only for MO or CD - if (pUnit->GetID() != MAKEID('S', 'C', 'M', 'O') && - pUnit->GetID() != MAKEID('S', 'C', 'C', 'D')) { - FPRT(fp, "Error : Operation denied(Deveice isn't removable)\n"); - return FALSE; - } - - switch (cmd) { - case 2: // INSERT - // Set the file path - filepath.SetPath(file); - - // Open the file - if (pUnit->Open(filepath)) { - FPRT(fp, "Error : File open error [%s]\n", file); - return FALSE; - } - break; - - case 3: // EJECT - pUnit->Eject(TRUE); - break; - - case 4: // PROTECT - if (pUnit->GetID() != MAKEID('S', 'C', 'M', 'O')) { - FPRT(fp, "Error : Operation denied(Deveice isn't MO)\n"); - return FALSE; - } - pUnit->WriteP(!pUnit->IsWriteP()); - break; - default: - ASSERT(FALSE); - return FALSE; - } - - return TRUE; -} - -//--------------------------------------------------------------------------- -// -// Argument Parsing -// -//--------------------------------------------------------------------------- -BOOL ParseArgument(int argc, char* argv[]) -{ -#ifdef BAREMETAL - FRESULT fr; - FIL fp; - char line[512]; -#else - int i; -#endif // BAREMETAL - int id; - int un; - int type; - char *argID; - char *argPath; - int len; - char *ext; - -#ifdef BAREMETAL - // Mount the SD card - fr = f_mount(&fatfs, "", 1); - if (fr != FR_OK) { - FPRT(stderr, "Error : SD card mount failed.\n"); - return FALSE; - } - - // If there is no setting file, the processing is interrupted - fr = f_open(&fp, "rascsi.ini", FA_READ); - if (fr != FR_OK) { - return FALSE; - } -#else - // If the ID and path are not specified, the processing is interrupted - if (argc < 3) { - return TRUE; - } - i = 1; - argc--; -#endif // BAREMETAL - - // Start Decoding - - while (TRUE) { -#ifdef BAREMETAL - // Get one Line - memset(line, 0x00, sizeof(line)); - if (f_gets(line, sizeof(line) -1, &fp) == NULL) { - break; - } - - // Delete the CR/LF - len = strlen(line); - while (len > 0) { - if (line[len - 1] != '\r' && line[len - 1] != '\n') { - break; - } - line[len - 1] = '\0'; - len--; - } -#else - if (argc < 2) { - break; - } - - argc -= 2; -#endif // BAREMETAL - - // Get the ID and Path -#ifdef BAREMETAL - argID = &line[0]; - argPath = &line[4]; - line[3] = '\0'; - - // Check if the line is an empty string - if (argID[0] == '\0' || argPath[0] == '\0') { - continue; - } -#else - argID = argv[i++]; - argPath = argv[i++]; - - // Check if the argument is invalid - if (argID[0] != '-') { - FPRT(stderr, - "Error : Invalid argument(-IDn or -HDn) [%s]\n", argID); - goto parse_error; - } - argID++; -#endif // BAREMETAL - - if (strlen(argID) == 3 && xstrncasecmp(argID, "id", 2) == 0) { - // ID or ID Format - - // Check that the ID number is valid (0-7) - if (argID[2] < '0' || argID[2] > '7') { - FPRT(stderr, - "Error : Invalid argument(IDn n=0-7) [%c]\n", argID[2]); - goto parse_error; - } - - // The ID unit is good - id = argID[2] - '0'; - un = 0; - } else if (xstrncasecmp(argID, "hd", 2) == 0) { - // HD or HD format - - if (strlen(argID) == 3) { - // Check that the HD number is valid (0-9) - if (argID[2] < '0' || argID[2] > '9') { - FPRT(stderr, - "Error : Invalid argument(HDn n=0-15) [%c]\n", argID[2]); - goto parse_error; - } - - // ID was confirmed - id = (argID[2] - '0') / UnitNum; - un = (argID[2] - '0') % UnitNum; - } else if (strlen(argID) == 4) { - // Check that the HD number is valid (10-15) - if (argID[2] != '1' || argID[3] < '0' || argID[3] > '5') { - FPRT(stderr, - "Error : Invalid argument(HDn n=0-15) [%c]\n", argID[2]); - goto parse_error; - } - - // The ID unit is good - create the id and unit number - id = ((argID[3] - '0') + 10) / UnitNum; - un = ((argID[3] - '0') + 10) % UnitNum; -#ifdef BAREMETAL - argPath++; -#endif // BAREMETAL - } else { - FPRT(stderr, - "Error : Invalid argument(IDn or HDn) [%s]\n", argID); - goto parse_error; - } - } else { - FPRT(stderr, - "Error : Invalid argument(IDn or HDn) [%s]\n", argID); - goto parse_error; - } - - // Skip if there is already an active device - if (disk[id * UnitNum + un] && - !disk[id * UnitNum + un]->IsNULL()) { - continue; - } - - // Initialize device type - type = -1; - - // Check ethernet and host bridge - if (xstrcasecmp(argPath, "bridge") == 0) { - type = 4; - } else if (xstrcasecmp(argPath, "monitor") == 0){ - type = 5; - } else { - // Check the path length - len = strlen(argPath); - if (len < 5) { - FPRT(stderr, - "Error : Invalid argument(File path is short) [%s]\n", - argPath); - goto parse_error; - } - - // Does the file have an extension? - if (argPath[len - 4] != '.') { - FPRT(stderr, - "Error : Invalid argument(No extension) [%s]\n", argPath); - goto parse_error; - } - - // Figure out what the type is - ext = &argPath[len - 3]; - if (xstrcasecmp(ext, "hdf") == 0 || - xstrcasecmp(ext, "hds") == 0 || - xstrcasecmp(ext, "hdn") == 0 || - xstrcasecmp(ext, "hdi") == 0 || xstrcasecmp(ext, "nhd") == 0 || - xstrcasecmp(ext, "hda") == 0) { - // HD(SASI/SCSI) - type = 0; - } else if (strcasecmp(ext, "mos") == 0) { - // MO - type = 2; - } else if (strcasecmp(ext, "iso") == 0) { - // CD - type = 3; - } else { - // Cannot determine the file type - FPRT(stderr, - "Error : Invalid argument(file type) [%s]\n", ext); - goto parse_error; - } - } - - // Execute the command - if (!ProcessCmd(stderr, id, un, 0, type, argPath)) { - goto parse_error; - } - } - -#ifdef BAREMETAL - // Close the configuration file - f_close(&fp); -#endif // BAREMETAL - - // Display the device list - ListDevice(stdout); - - return TRUE; - -parse_error: - -#ifdef BAREMETAL - // Close the configuration file - f_close(&fp); -#endif // BAREMETAL - - return FALSE; -} - -#ifndef BAREMETAL -//--------------------------------------------------------------------------- -// -// Pin the thread to a specific CPU -// -//--------------------------------------------------------------------------- -void FixCpu(int cpu) -{ - cpu_set_t cpuset; - int cpus; - - // Get the number of CPUs - CPU_ZERO(&cpuset); - sched_getaffinity(0, sizeof(cpu_set_t), &cpuset); - cpus = CPU_COUNT(&cpuset); - - // Set the thread affinity - if (cpu < cpus) { - CPU_ZERO(&cpuset); - CPU_SET(cpu, &cpuset); - sched_setaffinity(0, sizeof(cpu_set_t), &cpuset); - } -} - -//--------------------------------------------------------------------------- -// -// Monitor Thread -// -//--------------------------------------------------------------------------- -static void *MonThread(void *param) -{ - struct sched_param schedparam; - struct sockaddr_in client; - socklen_t len; - int fd; - FILE *fp; - char buf[BUFSIZ]; - char *p; - int i; - char *argv[5]; - int id; - int un; - int cmd; - int type; - char *file; - - // Scheduler Settings - schedparam.sched_priority = 0; - sched_setscheduler(0, SCHED_IDLE, &schedparam); - - // Set the affinity to a specific processor core - FixCpu(2); - - // Wait for the execution to start - while (!running) { - usleep(1); - } - - // Setup the monitor socket to receive commands - listen(monsocket, 1); - - while (1) { - // Wait for connection - memset(&client, 0, sizeof(client)); - len = sizeof(client); - fd = accept(monsocket, (struct sockaddr*)&client, &len); - if (fd < 0) { - break; - } - - // Fetch the command - fp = fdopen(fd, "r+"); - p = fgets(buf, BUFSIZ, fp); - - // Failed to get the command - if (!p) { - goto next; - } - - // Remove the newline character - p[strlen(p) - 1] = 0; - - // List all of the devices - if (xstrncasecmp(p, "list", 4) == 0) { - ListDevice(fp); - goto next; - } - - // Parameter separation - argv[0] = p; - for (i = 1; i < 5; i++) { - // Skip parameter values - while (*p && (*p != ' ')) { - p++; - } - - // Replace spaces with null characters - while (*p && (*p == ' ')) { - *p++ = 0; - } - - // The parameters were lost - if (!*p) { - break; - } - - // Recognized as a parameter - argv[i] = p; - } - - // Failed to get all parameters - if (i < 5) { - goto next; - } - - // ID, unit, command, type, file - id = atoi(argv[0]); - un = atoi(argv[1]); - cmd = atoi(argv[2]); - type = atoi(argv[3]); - file = argv[4]; - - // Wait until we becom idle - while (active) { - usleep(500 * 1000); - } - - // Execute the command - ProcessCmd(fp, id, un, cmd, type, file); - -next: - // Release the connection - fclose(fp); - close(fd); - } - - return NULL; -} -#endif // BAREMETAL - -//--------------------------------------------------------------------------- -// -// Main processing -// -//--------------------------------------------------------------------------- -#ifdef BAREMETAL -extern "C" -int startrascsi(void) -{ - int argc = 0; - char** argv = NULL; -#else -int main(int argc, char* argv[]) -{ -#endif // BAREMETAL - int i; - int ret; - int actid; - DWORD now; - BUS::phase_t phase; - BYTE data; -#ifndef BAREMETAL - struct sched_param schparam; -#endif // BAREMETAL - - // Output the Banner - Banner(argc, argv); - - // Initialize - ret = 0; - if (!Init()) { - ret = EPERM; - goto init_exit; - } - - // Reset - Reset(); - -#ifdef BAREMETAL - // BUSY assert (to hold the host side) - bus->SetBSY(TRUE); -#endif - - // Argument parsing - if (!ParseArgument(argc, argv)) { - ret = EINVAL; - goto err_exit; - } - -#ifdef BAREMETAL - // Release the busy signal - bus->SetBSY(FALSE); -#endif - -#ifndef BAREMETAL - // Set the affinity to a specific processor core - FixCpu(3); - -#ifdef USE_SEL_EVENT_ENABLE - // Scheduling policy setting (highest priority) - schparam.sched_priority = sched_get_priority_max(SCHED_FIFO); - sched_setscheduler(0, SCHED_FIFO, &schparam); -#endif // USE_SEL_EVENT_ENABLE -#endif // BAREMETAL - - // Start execution - running = TRUE; - - // Main Loop - while (running) { - // Work initialization - actid = -1; - phase = BUS::busfree; - -#ifdef USE_SEL_EVENT_ENABLE - // SEL signal polling - if (bus->PollSelectEvent() < 0) { - // Stop on interrupt - if (errno == EINTR) { - break; - } - continue; - } - - // Get the bus - bus->Aquire(); -#else - bus->Aquire(); - if (!bus->GetSEL()) { -#if !defined(BAREMETAL) - usleep(0); -#endif // !BAREMETAL - continue; - } -#endif // USE_SEL_EVENT_ENABLE - - // Wait until BSY is released as there is a possibility for the - // initiator to assert it while setting the ID (for up to 3 seconds) - if (bus->GetBSY()) { - now = SysTimer::GetTimerLow(); - while ((SysTimer::GetTimerLow() - now) < 3 * 1000 * 1000) { - bus->Aquire(); - if (!bus->GetBSY()) { - break; - } - } - } - - // Stop because it the bus is busy or another device responded - if (bus->GetBSY() || !bus->GetSEL()) { - continue; - } - - // Notify all controllers - data = bus->GetDAT(); - for (i = 0; i < CtrlMax; i++) { - if (!ctrl[i] || (data & (1 << i)) == 0) { - continue; - } - - // Find the target that has moved to the selection phase - if (ctrl[i]->Process() == BUS::selection) { - // Get the target ID - actid = i; - - // Bus Selection phase - phase = BUS::selection; - break; - } - } - - // Return to bus monitoring if the selection phase has not started - if (phase != BUS::selection) { - continue; - } - - // Start target device - active = TRUE; - -#if !defined(USE_SEL_EVENT_ENABLE) && !defined(BAREMETAL) - // Scheduling policy setting (highest priority) - schparam.sched_priority = sched_get_priority_max(SCHED_FIFO); - sched_setscheduler(0, SCHED_FIFO, &schparam); -#endif // !USE_SEL_EVENT_ENABLE && !BAREMETAL - - // Loop until the bus is free - while (running) { - // Target drive - phase = ctrl[actid]->Process(); - - // End when the bus is free - if (phase == BUS::busfree) { - break; - } - } - -#if !defined(USE_SEL_EVENT_ENABLE) && !defined(BAREMETAL) - // Set the scheduling priority back to normal - schparam.sched_priority = 0; - sched_setscheduler(0, SCHED_OTHER, &schparam); -#endif // !USE_SEL_EVENT_ENABLE && !BAREMETAL - - // End the target travel - active = FALSE; - } - -err_exit: - // Cleanup - Cleanup(); - -init_exit: -#if !defined(BAREMETAL) - exit(ret); -#else - return ret; -#endif // BAREMETAL -} diff --git a/src/raspberrypi/scsimondev.cpp b/src/raspberrypi/scsimondev.cpp deleted file mode 100644 index c6185fb4..00000000 --- a/src/raspberrypi/scsimondev.cpp +++ /dev/null @@ -1,1902 +0,0 @@ -//--------------------------------------------------------------------------- -// -// X68000 EMULATOR "XM6" -// -// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) -// Copyright (C) 2014-2020 GIMONS -// -// XM6i -// Copyright (C) 2010-2015 isaki@NetBSD.org -// Copyright (C) 2010 Y.Sugahara -// -// Imported sava's Anex86/T98Next image and MO format support patch. -// Imported NetBSD support and some optimisation patch by Rin Okuyama. -// Comments translated to english by akuker. -// -// [ SCSI Monitor Device] -// -//--------------------------------------------------------------------------- - -#include "os.h" -#include "xm6.h" -#include "filepath.h" -#include "fileio.h" -#ifdef RASCSI -#include "gpiobus.h" -#ifndef BAREMETAL -#include "ctapdriver.h" -#endif // BAREMETAL -#include "cfilesystem.h" -#include "disk.h" -#else -#include "vm.h" -#include "disk.h" -#include "windrv.h" -#include "ctapdriver.h" -#include "mfc_com.h" -#include "mfc_host.h" -#endif // RASCSI - -// Temporary? Trick to make the ID understand that RASCSI is set -#ifndef RASCSI -#define RASCSI -#endif // RASCSI - -//=========================================================================== -// -// SCSI Device -// -//=========================================================================== - -//--------------------------------------------------------------------------- -// -// Constructor -// -//--------------------------------------------------------------------------- -#ifdef RASCSI -SCSIMONDEV::SCSIMONDEV() : SASIDEV() -#else -SCSIMONDEV::SCSIMONDEV(Device *dev) : SASIDEV(dev) -#endif -{ - // Synchronous transfer work initialization - scsi.syncenable = FALSE; - scsi.syncperiod = 50; - scsi.syncoffset = 0; - scsi.atnmsg = FALSE; - scsi.msc = 0; - memset(scsi.msb, 0x00, sizeof(scsi.msb)); -} - -//--------------------------------------------------------------------------- -// -// Device reset -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::Reset() -{ - ASSERT(this); - - // Work initialization - scsi.atnmsg = FALSE; - scsi.msc = 0; - memset(scsi.msb, 0x00, sizeof(scsi.msb)); - - // Base class - SASIDEV::Reset(); -} - -//--------------------------------------------------------------------------- -// -// Process -// -//--------------------------------------------------------------------------- -BUS::phase_t FASTCALL SCSIMONDEV::Process() -{ - ASSERT(this); - printf("SCSIMONDEV::Process() %d\n", ctrl.id); - - // Do nothing if not connected - if (ctrl.id < 0 || ctrl.bus == NULL) { - return ctrl.phase; - } - - // Get bus information - ctrl.bus->Aquire(); - - // Reset - if (ctrl.bus->GetRST()) { -#if defined(DISK_LOG) - Log(Log::Normal, "RESET信号受信"); -#endif // DISK_LOG - - // Reset the controller - Reset(); - - // Reset the bus - ctrl.bus->Reset(); - return ctrl.phase; - } - - // Phase processing - switch (ctrl.phase) { - // Bus free phase - case BUS::busfree: - BusFree(); - break; - - // Selection phase - case BUS::selection: - Selection(); - break; - - // Data out (MCI=000) - case BUS::dataout: - DataOut(); - break; - - // Data in (MCI=001) - case BUS::datain: - DataIn(); - break; - - // Command (MCI=010) - case BUS::command: - Command(); - break; - - // Status (MCI=011) - case BUS::status: - Status(); - break; - - // Message out (MCI=110) - case BUS::msgout: - MsgOut(); - break; - - // Message in (MCI=111) - case BUS::msgin: - MsgIn(); - break; - - // Other - default: - ASSERT(FALSE); - break; - } - - return ctrl.phase; -} - -//--------------------------------------------------------------------------- -// -// Phaes -// -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// -// Bus free phase -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::BusFree() -{ - ASSERT(this); - - // Phase change - if (ctrl.phase != BUS::busfree) { - -#if defined(DISK_LOG) - Log(Log::Normal, "Bus free phase"); -#endif // DISK_LOG - - // Phase setting - ctrl.phase = BUS::busfree; - -//////// // Signal line -//////// ctrl.bus->SetREQ(FALSE); -//////// ctrl.bus->SetMSG(FALSE); -//////// ctrl.bus->SetCD(FALSE); -//////// ctrl.bus->SetIO(FALSE); -//////// ctrl.bus->SetBSY(FALSE); - - // Initialize status and message - ctrl.status = 0x00; - ctrl.message = 0x00; - - // Initialize ATN message reception status - scsi.atnmsg = FALSE; - return; - } - - // Move to selection phase - if (ctrl.bus->GetSEL() && !ctrl.bus->GetBSY()) { - Selection(); - } -} - -//--------------------------------------------------------------------------- -// -// Selection Phase -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::Selection() -{ - DWORD id; - - ASSERT(this); - - // Phase change - if (ctrl.phase != BUS::selection) { - // invalid if IDs do not match - id = 1 << ctrl.id; - if ((ctrl.bus->GetDAT() & id) == 0) { - return; - } - - // End if there is no valid unit - if (!HasUnit()) { - return; - } - -#if defined(DISK_LOG) - Log(Log::Normal, - "Selection Phase ID=%d (with device)", ctrl.id); -#endif // DISK_LOG - - // Phase setting - ctrl.phase = BUS::selection; - - // Raise BSY and respond - ctrl.bus->SetBSY(TRUE); - return; - } - - // Selection completed - if (!ctrl.bus->GetSEL() && ctrl.bus->GetBSY()) { - // Message out phase if ATN=1, otherwise command phase - if (ctrl.bus->GetATN()) { - MsgOut(); - } else { - Command(); - } - } -} - -//--------------------------------------------------------------------------- -// -// Execution Phase -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::Execute() -{ - ASSERT(this); - -#if defined(DISK_LOG) - Log(Log::Normal, "Execution phase command $%02X", ctrl.cmd[0]); -#endif // DISK_LOG - - // Phase Setting - ctrl.phase = BUS::execute; - - // Initialization for data transfer - ctrl.offset = 0; - ctrl.blocks = 1; -#ifdef RASCSI - ctrl.execstart = SysTimer::GetTimerLow(); -#endif // RASCSI - - // Process by command - switch (ctrl.cmd[0]) { - // TEST UNIT READY - case 0x00: - CmdTestUnitReady(); - return; - - // REZERO - case 0x01: - CmdRezero(); - return; - - // REQUEST SENSE - case 0x03: - CmdRequestSense(); - return; - - // FORMAT UNIT - case 0x04: - CmdFormat(); - return; - - // REASSIGN BLOCKS - case 0x07: - CmdReassign(); - return; - - // READ(6) - case 0x08: - CmdRead6(); - return; - - // WRITE(6) - case 0x0a: - CmdWrite6(); - return; - - // SEEK(6) - case 0x0b: - CmdSeek6(); - return; - - // INQUIRY - case 0x12: - CmdInquiry(); - return; - - // MODE SELECT - case 0x15: - CmdModeSelect(); - return; - - // MDOE SENSE - case 0x1a: - CmdModeSense(); - return; - - // START STOP UNIT - case 0x1b: - CmdStartStop(); - return; - - // SEND DIAGNOSTIC - case 0x1d: - CmdSendDiag(); - return; - - // PREVENT/ALLOW MEDIUM REMOVAL - case 0x1e: - CmdRemoval(); - return; - - // READ CAPACITY - case 0x25: - CmdReadCapacity(); - return; - - // READ(10) - case 0x28: - CmdRead10(); - return; - - // WRITE(10) - case 0x2a: - CmdWrite10(); - return; - - // SEEK(10) - case 0x2b: - CmdSeek10(); - return; - - // WRITE and VERIFY - case 0x2e: - CmdWrite10(); - return; - - // VERIFY - case 0x2f: - CmdVerify(); - return; - - // SYNCHRONIZE CACHE - case 0x35: - CmdSynchronizeCache(); - return; - - // READ DEFECT DATA(10) - case 0x37: - CmdReadDefectData10(); - return; - - // READ TOC - case 0x43: - CmdReadToc(); - return; - - // PLAY AUDIO(10) - case 0x45: - CmdPlayAudio10(); - return; - - // PLAY AUDIO MSF - case 0x47: - CmdPlayAudioMSF(); - return; - - // PLAY AUDIO TRACK - case 0x48: - CmdPlayAudioTrack(); - return; - - // MODE SELECT(10) - case 0x55: - CmdModeSelect10(); - return; - - // MDOE SENSE(10) - case 0x5a: - CmdModeSense10(); - return; - - // SPECIFY (SASI only/Suppress warning when using SxSI) - case 0xc2: - CmdInvalid(); - return; - - } - - // No other support - Log(Log::Normal, "Unsupported command received: $%02X", ctrl.cmd[0]); - CmdInvalid(); -} - -//--------------------------------------------------------------------------- -// -// Message out phase -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::MsgOut() -{ - ASSERT(this); - - // Phase change - if (ctrl.phase != BUS::msgout) { - -#if defined(DISK_LOG) - Log(Log::Normal, "Message Out Phase"); -#endif // DISK_LOG - - // Message out phase after selection - // process the IDENTIFY message - if (ctrl.phase == BUS::selection) { - scsi.atnmsg = TRUE; - scsi.msc = 0; - memset(scsi.msb, 0x00, sizeof(scsi.msb)); - } - - // Phase Setting - ctrl.phase = BUS::msgout; - -//////// // Signal line operated by the target -//////// ctrl.bus->SetMSG(TRUE); -//////// ctrl.bus->SetCD(TRUE); -//////// ctrl.bus->SetIO(FALSE); - - // Data transfer is 1 byte x 1 block - ctrl.offset = 0; - ctrl.length = 1; - ctrl.blocks = 1; - -#ifndef RASCSI - // Request message - ctrl.bus->SetREQ(TRUE); -#endif // RASCSI - return; - } - -#ifdef RASCSI - // Receive - Receive(); -#else - // Requesting - if (ctrl.bus->GetREQ()) { - // Sent by the initiator - if (ctrl.bus->GetACK()) { - Receive(); - } - } else { - // Request the initator to - if (!ctrl.bus->GetACK()) { - ReceiveNext(); - } - } -#endif // RASCSI -} - -//--------------------------------------------------------------------------- -// -// Common Error Handling -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::Error() -{ - ASSERT(this); - - // Get bus information - ctrl.bus->Aquire(); - - // Reset check - if (ctrl.bus->GetRST()) { - // Reset the controller - Reset(); - - // Reset the bus - ctrl.bus->Reset(); - return; - } - - // Bus free for status phase and message in phase - if (ctrl.phase == BUS::status || ctrl.phase == BUS::msgin) { - BusFree(); - return; - } - -#if defined(DISK_LOG) - Log(Log::Normal, "Error (to status phase)"); -#endif // DISK_LOG - - // Set status and message(CHECK CONDITION) - ctrl.status = 0x02; - ctrl.message = 0x00; - - // status phase - Status(); -} - -//--------------------------------------------------------------------------- -// -// Command -// -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// -// INQUIRY -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdInquiry() -{ - Disk *disk; - int lun; - DWORD major; - DWORD minor; - - ASSERT(this); - -#if defined(DISK_LOG) - Log(Log::Normal, "INQUIRY Command"); -#endif // DISK_LOG - - // Find a valid unit - disk = NULL; - for (lun = 0; lun < UnitMax; lun++) { - if (ctrl.unit[lun]) { - disk = ctrl.unit[lun]; - break; - } - } - - // Processed on the disk side (it is originally processed by the controller) - if (disk) { -#ifdef RASCSI - major = (DWORD)(RASCSI >> 8); - minor = (DWORD)(RASCSI & 0xff); -#else - host->GetVM()->GetVersion(major, minor); -#endif // RASCSI - ctrl.length = - ctrl.unit[lun]->Inquiry(ctrl.cmd, ctrl.buffer, major, minor); - } else { - ctrl.length = 0; - } - - if (ctrl.length <= 0) { - // failure (error) - Error(); - return; - } - - // Add synchronous transfer support information - if (scsi.syncenable) { - ctrl.buffer[7] |= (1 << 4); - } - - // Data-in Phase - DataIn(); -} - -//--------------------------------------------------------------------------- -// -// MODE SELECT -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdModeSelect() -{ - DWORD lun; - - ASSERT(this); - -#if defined(DISK_LOG) - Log(Log::Normal, "MODE SELECT Command"); -#endif // DISK_LOG - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Command processing on drive - ctrl.length = ctrl.unit[lun]->SelectCheck(ctrl.cmd); - if (ctrl.length <= 0) { - // Failure (Error) - Error(); - return; - } - - // Data out phase - DataOut(); -} - -//--------------------------------------------------------------------------- -// -// MODE SENSE -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdModeSense() -{ - DWORD lun; - - ASSERT(this); - -#if defined(DISK_LOG) - Log(Log::Normal, "MODE SENSE Command "); -#endif // DISK_LOG - - printf("Received a Mode Sense command. Contents...."); - for(int i=0; i<10; i++) - { - printf("%08X ", ctrl.cmd[i]); - } - printf("\n"); - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Command processing on drive - ctrl.length = ctrl.unit[lun]->ModeSense(ctrl.cmd, ctrl.buffer); - ASSERT(ctrl.length >= 0); - if (ctrl.length == 0) { - Log(Log::Warning, - "Not supported MODE SENSE page $%02X", ctrl.cmd[2]); - - // Failure (Error) - Error(); - return; - } - - // Data-in Phase - DataIn(); -} - -//--------------------------------------------------------------------------- -// -// START STOP UNIT -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdStartStop() -{ - DWORD lun; - BOOL status; - - ASSERT(this); - -#if defined(DISK_LOG) - Log(Log::Normal, "START STOP UNIT Command "); -#endif // DISK_LOG - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Command processing on drive - status = ctrl.unit[lun]->StartStop(ctrl.cmd); - if (!status) { - // Failure (Error) - Error(); - return; - } - - // status phase - Status(); -} - -//--------------------------------------------------------------------------- -// -// SEND DIAGNOSTIC -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdSendDiag() -{ - DWORD lun; - BOOL status; - - ASSERT(this); - -#if defined(DISK_LOG) - Log(Log::Normal, "SEND DIAGNOSTIC Command "); -#endif // DISK_LOG - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Command processing on drive - status = ctrl.unit[lun]->SendDiag(ctrl.cmd); - if (!status) { - // Failure (Error) - Error(); - return; - } - - // status phase - Status(); -} - -//--------------------------------------------------------------------------- -// -// PREVENT/ALLOW MEDIUM REMOVAL -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdRemoval() -{ - DWORD lun; - BOOL status; - - ASSERT(this); - -#if defined(DISK_LOG) - Log(Log::Normal, "PREVENT/ALLOW MEDIUM REMOVAL Command "); -#endif // DISK_LOG - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Command processing on drive - status = ctrl.unit[lun]->Removal(ctrl.cmd); - if (!status) { - // Failure (Error) - Error(); - return; - } - - // status phase - Status(); -} - -//--------------------------------------------------------------------------- -// -// READ CAPACITY -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdReadCapacity() -{ - DWORD lun; - int length; - - ASSERT(this); - -#if defined(DISK_LOG) - Log(Log::Normal, "READ CAPACITY Command "); -#endif // DISK_LOG - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Command processing on drive - length = ctrl.unit[lun]->ReadCapacity(ctrl.cmd, ctrl.buffer); - ASSERT(length >= 0); - if (length <= 0) { - Error(); - return; - } - - // Length setting - ctrl.length = length; - - // Data-in Phase - DataIn(); -} - -//--------------------------------------------------------------------------- -// -// READ(10) -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdRead10() -{ - DWORD lun; - DWORD record; - - ASSERT(this); - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Receive message if host bridge - if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'B', 'R')) { - CmdGetMessage10(); - return; - } - - // Get record number and block number - record = ctrl.cmd[2]; - record <<= 8; - record |= ctrl.cmd[3]; - record <<= 8; - record |= ctrl.cmd[4]; - record <<= 8; - record |= ctrl.cmd[5]; - ctrl.blocks = ctrl.cmd[7]; - ctrl.blocks <<= 8; - ctrl.blocks |= ctrl.cmd[8]; - -#if defined(DISK_LOG) - Log(Log::Normal, "READ(10) command record=%08X block=%d", record, ctrl.blocks); -#endif // DISK_LOG - - // Do not process 0 blocks - if (ctrl.blocks == 0) { - Status(); - return; - } - - // Command processing on drive - ctrl.length = ctrl.unit[lun]->Read(ctrl.buffer, record); - if (ctrl.length <= 0) { - // Failure (Error) - Error(); - return; - } - - // Set next block - ctrl.next = record + 1; - - // Data-in Phase - DataIn(); -} - -//--------------------------------------------------------------------------- -// -// WRITE(10) -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdWrite10() -{ - DWORD lun; - DWORD record; - - ASSERT(this); - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Receive message with host bridge - if (ctrl.unit[lun]->GetID() == MAKEID('S', 'C', 'B', 'R')) { - CmdSendMessage10(); - return; - } - - // Get record number and block number - record = ctrl.cmd[2]; - record <<= 8; - record |= ctrl.cmd[3]; - record <<= 8; - record |= ctrl.cmd[4]; - record <<= 8; - record |= ctrl.cmd[5]; - ctrl.blocks = ctrl.cmd[7]; - ctrl.blocks <<= 8; - ctrl.blocks |= ctrl.cmd[8]; - -#if defined(DISK_LOG) - Log(Log::Normal, - "WRTIE(10) command record=%08X blocks=%d", record, ctrl.blocks); -#endif // DISK_LOG - - // Do not process 0 blocks - if (ctrl.blocks == 0) { - Status(); - return; - } - - // Command processing on drive - ctrl.length = ctrl.unit[lun]->WriteCheck(record); - if (ctrl.length <= 0) { - // Failure (Error) - Error(); - return; - } - - // Set next block - ctrl.next = record + 1; - - // Data out phase - DataOut(); -} - -//--------------------------------------------------------------------------- -// -// SEEK(10) -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdSeek10() -{ - DWORD lun; - BOOL status; - - ASSERT(this); - -#if defined(DISK_LOG) - Log(Log::Normal, "SEEK(10) Command "); -#endif // DISK_LOG - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Command processing on drive - status = ctrl.unit[lun]->Seek(ctrl.cmd); - if (!status) { - // Failure (Error) - Error(); - return; - } - - // status phase - Status(); -} - -//--------------------------------------------------------------------------- -// -// VERIFY -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdVerify() -{ - DWORD lun; - BOOL status; - DWORD record; - - ASSERT(this); - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Get record number and block number - record = ctrl.cmd[2]; - record <<= 8; - record |= ctrl.cmd[3]; - record <<= 8; - record |= ctrl.cmd[4]; - record <<= 8; - record |= ctrl.cmd[5]; - ctrl.blocks = ctrl.cmd[7]; - ctrl.blocks <<= 8; - ctrl.blocks |= ctrl.cmd[8]; - -#if defined(DISK_LOG) - Log(Log::Normal, - "VERIFY command record=%08X blocks=%d", record, ctrl.blocks); -#endif // DISK_LOG - - // Do not process 0 blocks - if (ctrl.blocks == 0) { - Status(); - return; - } - - // if BytChk=0 - if ((ctrl.cmd[1] & 0x02) == 0) { - // Command processing on drive - status = ctrl.unit[lun]->Seek(ctrl.cmd); - if (!status) { - // Failure (Error) - Error(); - return; - } - - // status phase - Status(); - return; - } - - // Test loading - ctrl.length = ctrl.unit[lun]->Read(ctrl.buffer, record); - if (ctrl.length <= 0) { - // Failure (Error) - Error(); - return; - } - - // Set next block - ctrl.next = record + 1; - - // Data out phase - DataOut(); -} - -//--------------------------------------------------------------------------- -// -// SYNCHRONIZE CACHE -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdSynchronizeCache() -{ - DWORD lun; - - ASSERT(this); - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Make it do something (not implemented)... - - // status phase - Status(); -} - -//--------------------------------------------------------------------------- -// -// READ DEFECT DATA(10) -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdReadDefectData10() -{ - DWORD lun; - - ASSERT(this); - -#if defined(DISK_LOG) - Log(Log::Normal, "READ DEFECT DATA(10) Command "); -#endif // DISK_LOG - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Command processing on drive - ctrl.length = ctrl.unit[lun]->ReadDefectData10(ctrl.cmd, ctrl.buffer); - ASSERT(ctrl.length >= 0); - - if (ctrl.length <= 4) { - Error(); - return; - } - - // Data-in Phase - DataIn(); -} - -//--------------------------------------------------------------------------- -// -// READ TOC -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdReadToc() -{ - DWORD lun; - - ASSERT(this); - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Command processing on drive - ctrl.length = ctrl.unit[lun]->ReadToc(ctrl.cmd, ctrl.buffer); - if (ctrl.length <= 0) { - // Failure (Error) - Error(); - return; - } - - // Data-in Phase - DataIn(); -} - -//--------------------------------------------------------------------------- -// -// PLAY AUDIO(10) -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdPlayAudio10() -{ - DWORD lun; - BOOL status; - - ASSERT(this); - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Command processing on drive - status = ctrl.unit[lun]->PlayAudio(ctrl.cmd); - if (!status) { - // Failure (Error) - Error(); - return; - } - - // status phase - Status(); -} - -//--------------------------------------------------------------------------- -// -// PLAY AUDIO MSF -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdPlayAudioMSF() -{ - DWORD lun; - BOOL status; - - ASSERT(this); - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Command processing on drive - status = ctrl.unit[lun]->PlayAudioMSF(ctrl.cmd); - if (!status) { - // Failure (Error) - Error(); - return; - } - - // status phase - Status(); -} - -//--------------------------------------------------------------------------- -// -// PLAY AUDIO TRACK -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdPlayAudioTrack() -{ - DWORD lun; - BOOL status; - - ASSERT(this); - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Command processing on drive - status = ctrl.unit[lun]->PlayAudioTrack(ctrl.cmd); - if (!status) { - // Failure (Error) - Error(); - return; - } - - // status phase - Status(); -} - -//--------------------------------------------------------------------------- -// -// MODE SELECT10 -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdModeSelect10() -{ - DWORD lun; - - ASSERT(this); - -#if defined(DISK_LOG) - Log(Log::Normal, "MODE SELECT10 Command "); -#endif // DISK_LOG - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Command processing on drive - ctrl.length = ctrl.unit[lun]->SelectCheck10(ctrl.cmd); - if (ctrl.length <= 0) { - // Failure (Error) - Error(); - return; - } - - // Data out phase - DataOut(); -} - -//--------------------------------------------------------------------------- -// -// MODE SENSE(10) -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdModeSense10() -{ - DWORD lun; - - ASSERT(this); - -#if defined(DISK_LOG) - Log(Log::Normal, "MODE SENSE(10) Command "); -#endif // DISK_LOG - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Command processing on drive - ctrl.length = ctrl.unit[lun]->ModeSense10(ctrl.cmd, ctrl.buffer); - ASSERT(ctrl.length >= 0); - if (ctrl.length == 0) { - Log(Log::Warning, - "Not supported MODE SENSE(10) page $%02X", ctrl.cmd[2]); - - // Failure (Error) - Error(); - return; - } - - // Data-in Phase - DataIn(); -} - -//--------------------------------------------------------------------------- -// -// GET MESSAGE(10) -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdGetMessage10() -{ - DWORD lun; - SCSIBR *bridge; - - ASSERT(this); - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Error if not a host bridge - if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'B', 'R')) { - Error(); - return; - } - - // Reallocate buffer (because it is not transfer for each block) - if (ctrl.bufsize < 0x1000000) { - free(ctrl.buffer); - ctrl.bufsize = 0x1000000; - ctrl.buffer = (BYTE *)malloc(ctrl.bufsize); - } - - // Process with drive - bridge = (SCSIBR*)ctrl.unit[lun]; - ctrl.length = bridge->GetMessage10(ctrl.cmd, ctrl.buffer); - - if (ctrl.length <= 0) { - // Failure (Error) - Error(); - return; - } - - // Set next block - ctrl.blocks = 1; - ctrl.next = 1; - - // Data in phase - DataIn(); -} - -//--------------------------------------------------------------------------- -// -// SEND MESSAGE(10) -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::CmdSendMessage10() -{ - DWORD lun; - - ASSERT(this); - - // Logical Unit - lun = (ctrl.cmd[1] >> 5) & 0x07; - if (!ctrl.unit[lun]) { - Error(); - return; - } - - // Error if not a host bridge - if (ctrl.unit[lun]->GetID() != MAKEID('S', 'C', 'B', 'R')) { - Error(); - return; - } - - // Reallocate buffer (because it is not transfer for each block) - if (ctrl.bufsize < 0x1000000) { - free(ctrl.buffer); - ctrl.bufsize = 0x1000000; - ctrl.buffer = (BYTE *)malloc(ctrl.bufsize); - } - - // Set transfer amount - ctrl.length = ctrl.cmd[6]; - ctrl.length <<= 8; - ctrl.length |= ctrl.cmd[7]; - ctrl.length <<= 8; - ctrl.length |= ctrl.cmd[8]; - - if (ctrl.length <= 0) { - // Failure (Error) - Error(); - return; - } - - // Set next block - ctrl.blocks = 1; - ctrl.next = 1; - - // Light phase - DataOut(); -} - -//=========================================================================== -// -// Data Transfer -// -//=========================================================================== - -//--------------------------------------------------------------------------- -// -// Send data -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::Send() -{ -#ifdef RASCSI - int len; -#endif // RASCSI - BOOL result; - - ASSERT(this); - ASSERT(!ctrl.bus->GetREQ()); - ASSERT(ctrl.bus->GetIO()); - -#ifdef RASCSI - //if Length! = 0, send - if (ctrl.length != 0) { - len = ctrl.bus->SendHandShake( - &ctrl.buffer[ctrl.offset], ctrl.length); - - // If you cannot send all, move to status phase - if (len != (int)ctrl.length) { - Error(); - return; - } - - // offset and length - ctrl.offset += ctrl.length; - ctrl.length = 0; - return; - } -#else - // offset and length - ASSERT(ctrl.length >= 1); - ctrl.offset++; - ctrl.length--; - - // Immediately after ACK is asserted, if the data has been - // set by SendNext, raise the request - if (ctrl.length != 0) { - // Signal line operated by the target - ctrl.bus->SetREQ(TRUE); - return; - } -#endif // RASCSI - - // Block subtraction, result initialization - ctrl.blocks--; - result = TRUE; - - // Processing after data collection (read/data-in only) - if (ctrl.phase == BUS::datain) { - if (ctrl.blocks != 0) { - // // set next buffer (set offset, length) - result = XferIn(ctrl.buffer); -#ifndef RASCSI - ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset]); -#endif // RASCSI - } - } - - // If result FALSE, move to status phase - if (!result) { - Error(); - return; - } - - // Continue sending if block !=0 - if (ctrl.blocks != 0){ - ASSERT(ctrl.length > 0); - ASSERT(ctrl.offset == 0); -#ifndef RASCSI - // Signal line operated by the target - ctrl.bus->SetREQ(TRUE); -#endif // RASCSI - return; - } - - // Move to next phase - switch (ctrl.phase) { - // Message in phase - case BUS::msgin: - // Completed sending response to extended message of IDENTIFY message - if (scsi.atnmsg) { - // flag off - scsi.atnmsg = FALSE; - - // command phase - Command(); - } else { - // Bus free phase - BusFree(); - } - break; - - // Data-in Phase - case BUS::datain: - // status phase - Status(); - break; - - // status phase - case BUS::status: - // Message in phase - ctrl.length = 1; - ctrl.blocks = 1; - ctrl.buffer[0] = (BYTE)ctrl.message; - MsgIn(); - break; - - // Other (impossible) - default: - ASSERT(FALSE); - break; - } -} - -#ifndef RASCSI -//--------------------------------------------------------------------------- -// -// Continue data transmission..... -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::SendNext() -{ - ASSERT(this); - - // REQ is up - ASSERT(ctrl.bus->GetREQ()); - ASSERT(ctrl.bus->GetIO()); - - // Signal line operated by the target - ctrl.bus->SetREQ(FALSE); - - // If there is data in the buffer, set it first - if (ctrl.length > 1) { - ctrl.bus->SetDAT(ctrl.buffer[ctrl.offset + 1]); - } -} -#endif // RASCSI - -#ifndef RASCSI -//--------------------------------------------------------------------------- -// -// Receive data -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::Receive() -{ - DWORD data; - - ASSERT(this); - - // Req is up - ASSERT(ctrl.bus->GetREQ()); - ASSERT(!ctrl.bus->GetIO()); - - // Get data - data = (DWORD)ctrl.bus->GetDAT(); - - // Signal line operated by the target - ctrl.bus->SetREQ(FALSE); - - switch (ctrl.phase) { - // Command phase - case BUS::command: - ctrl.cmd[ctrl.offset] = data; -#if defined(DISK_LOG) - Log(Log::Normal, "Command phase $%02X", data); -#endif // DISK_LOG - - // Set the length again with the first data (offset 0) - if (ctrl.offset == 0) { - if (ctrl.cmd[0] >= 0x20) { - // 10バイトCDB - ctrl.length = 10; - } - } - break; - - // Message out phase - case BUS::msgout: - ctrl.message = data; -#if defined(DISK_LOG) - Log(Log::Normal, "Message out phase $%02X", data); -#endif // DISK_LOG - break; - - // Data out phase - case BUS::dataout: - ctrl.buffer[ctrl.offset] = (BYTE)data; - break; - - // Other (impossible) - default: - ASSERT(FALSE); - break; - } -} -#endif // RASCSI - -#ifdef RASCSI -//--------------------------------------------------------------------------- -// -// Receive Data -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::Receive() -#else -//--------------------------------------------------------------------------- -// -// Continue receiving data -// -//--------------------------------------------------------------------------- -void FASTCALL SCSIMONDEV::ReceiveNext() -#endif // RASCSI -{ -#ifdef RASCSI - int len; -#endif // RASCSI - BOOL result; - int i; - BYTE data; - - ASSERT(this); - - // REQ is low - ASSERT(!ctrl.bus->GetREQ()); - ASSERT(!ctrl.bus->GetIO()); - -#ifdef RASCSI - // Length != 0 if received - if (ctrl.length != 0) { - // Receive - len = ctrl.bus->ReceiveHandShake( - &ctrl.buffer[ctrl.offset], ctrl.length); - - // If not able to receive all, move to status phase - if (len != (int)ctrl.length) { - Error(); - return; - } - - // Offset and Length - ctrl.offset += ctrl.length; - ctrl.length = 0;; - return; - } -#else - // Offset and Length - ASSERT(ctrl.length >= 1); - ctrl.offset++; - ctrl.length--; - - // If length!=0, set req again - if (ctrl.length != 0) { - // Signal line operated by the target - ctrl.bus->SetREQ(TRUE); - return; - } -#endif // RASCSI - - // Block subtraction, result initialization - ctrl.blocks--; - result = TRUE; - - // Processing after receiving data (by phase) - switch (ctrl.phase) { - - // Data out phase - case BUS::dataout: - if (ctrl.blocks == 0) { - // End with this buffer - result = XferOut(FALSE); - } else { - // Continue to next buffer (set offset, length) - result = XferOut(TRUE); - } - break; - - // Message out phase - case BUS::msgout: - ctrl.message = ctrl.buffer[0]; - if (!XferMsg(ctrl.message)) { - // Immediately free the bus if message output fails - BusFree(); - return; - } - - // Clear message data in preparation for message-in - ctrl.message = 0x00; - break; - - default: - break; - } - - // If result FALSE, move to status phase - if (!result) { - Error(); - return; - } - - // Continue to receive if block !=0 - if (ctrl.blocks != 0){ - ASSERT(ctrl.length > 0); - ASSERT(ctrl.offset == 0); -#ifndef RASCSI - // Signal line operated by the target - ctrl.bus->SetREQ(TRUE); -#endif // RASCSI - return; - } - - // Move to next phase - switch (ctrl.phase) { - // Command phase - case BUS::command: -#ifdef RASCSI - // Command data transfer - len = 6; - if (ctrl.buffer[0] >= 0x20 && ctrl.buffer[0] <= 0x7D) { - // 10 byte CDB - len = 10; - } - for (i = 0; i < len; i++) { - ctrl.cmd[i] = (DWORD)ctrl.buffer[i]; -#if defined(DISK_LOG) - Log(Log::Normal, "Command $%02X", ctrl.cmd[i]); -#endif // DISK_LOG - } -#endif // RASCSI - - // Execution Phase - Execute(); - break; - - // Message out phase - case BUS::msgout: - // Continue message out phase as long as ATN keeps asserting - if (ctrl.bus->GetATN()) { - // Data transfer is 1 byte x 1 block - ctrl.offset = 0; - ctrl.length = 1; - ctrl.blocks = 1; -#ifndef RASCSI - // Request message - ctrl.bus->SetREQ(TRUE); -#endif // RASCSI - return; - } - - // Parsing messages sent by ATN - if (scsi.atnmsg) { - i = 0; - while (i < scsi.msc) { - // Message type - data = scsi.msb[i]; - - // ABORT - if (data == 0x06) { -#if defined(DISK_LOG) - Log(Log::Normal, - "Message code ABORT $%02X", data); -#endif // DISK_LOG - BusFree(); - return; - } - - // BUS DEVICE RESET - if (data == 0x0C) { -#if defined(DISK_LOG) - Log(Log::Normal, - "Message code BUS DEVICE RESET $%02X", data); -#endif // DISK_LOG - scsi.syncoffset = 0; - BusFree(); - return; - } - - // IDENTIFY - if (data >= 0x80) { -#if defined(DISK_LOG) - Log(Log::Normal, - "Message code IDENTIFY $%02X", data); -#endif // DISK_LOG - } - - // Extended Message - if (data == 0x01) { -#if defined(DISK_LOG) - Log(Log::Normal, - "Message code EXTENDED MESSAGE $%02X", data); -#endif // DISK_LOG - - // Check only when synchronous transfer is possible - if (!scsi.syncenable || scsi.msb[i + 2] != 0x01) { - ctrl.length = 1; - ctrl.blocks = 1; - ctrl.buffer[0] = 0x07; - MsgIn(); - return; - } - - // Transfer period factor (limited to 50 x 4 = 200ns) - scsi.syncperiod = scsi.msb[i + 3]; - if (scsi.syncperiod > 50) { - scsi.syncoffset = 50; - } - - // REQ/ACK offset(limited to 16) - scsi.syncoffset = scsi.msb[i + 4]; - if (scsi.syncoffset > 16) { - scsi.syncoffset = 16; - } - - // STDR response message generation - ctrl.length = 5; - ctrl.blocks = 1; - ctrl.buffer[0] = 0x01; - ctrl.buffer[1] = 0x03; - ctrl.buffer[2] = 0x01; - ctrl.buffer[3] = (BYTE)scsi.syncperiod; - ctrl.buffer[4] = (BYTE)scsi.syncoffset; - MsgIn(); - return; - } - - // next - i++; - } - } - - // Initialize ATN message reception status - scsi.atnmsg = FALSE; - - // Command phase - Command(); - break; - - // Data out phase - case BUS::dataout: - // Flush unit - FlushUnit(); - - // status phase - Status(); - break; - - // Other (impossible) - default: - ASSERT(FALSE); - break; - } -} - -//--------------------------------------------------------------------------- -// -// Transfer MSG -// -//--------------------------------------------------------------------------- -BOOL FASTCALL SCSIMONDEV::XferMsg(DWORD msg) -{ - ASSERT(this); - ASSERT(ctrl.phase == BUS::msgout); - - // Save message out data - if (scsi.atnmsg) { - scsi.msb[scsi.msc] = (BYTE)msg; - scsi.msc++; - scsi.msc %= 256; - } - - return TRUE; -}