mirror of
https://github.com/thewesker/RASCSI.git
synced 2025-12-21 04:41:12 -05:00
231 lines
5.5 KiB
C++
231 lines
5.5 KiB
C++
//---------------------------------------------------------------------------
|
|
//
|
|
// SCSI Target Emulator RaSCSI (*^..^*)
|
|
// for Raspberry Pi
|
|
//
|
|
// Powered by XM6 TypeG Technology.
|
|
// Copyright (C) 2016-2020 GIMONS
|
|
// Copyright (C) akuker
|
|
//
|
|
// [ RaSCSI main ]
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
#include "os.h"
|
|
#include "xm6.h"
|
|
#include "filepath.h"
|
|
#include "fileio.h"
|
|
#include "disk.h"
|
|
#include "gpiobus.h"
|
|
#include "command_thread.h"
|
|
#include "rascsi_mgr.h"
|
|
|
|
#include "sasidev_ctrl.h"
|
|
#include "scsidev_ctrl.h"
|
|
|
|
#include "sasihd.h"
|
|
#include "scsihd.h"
|
|
#include "scsihd_apple.h"
|
|
#include "scsihd_nec.h"
|
|
#include "scsicd.h"
|
|
#include "scsimo.h"
|
|
#include "scsi_host_bridge.h"
|
|
|
|
//---------------------------------------------------------------------------
|
|
//
|
|
// Constant declarations
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------
|
|
//
|
|
// Variable declarations
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
#ifdef BAREMETAL
|
|
FATFS fatfs; // FatFS
|
|
#else
|
|
#endif // BAREMETAL
|
|
Rascsi_Manager *mgr;
|
|
|
|
#ifndef BAREMETAL
|
|
//---------------------------------------------------------------------------
|
|
//
|
|
// Signal Processing
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
void KillHandler(int sig)
|
|
{
|
|
// Stop instruction
|
|
Command_Thread::Stop();
|
|
}
|
|
#endif // BAREMETAL
|
|
|
|
//---------------------------------------------------------------------------
|
|
//
|
|
// Banner Output
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
void Banner(int argc, char* argv[])
|
|
{
|
|
FPRT(stdout,"SCSI Target Emulator RaSCSI(*^..^*)\n");
|
|
FPRT(stdout," 68k MLA Edition\n");
|
|
FPRT(stdout,"Forked from GIMONS 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);
|
|
FPRT(stdout,"Build on %s at %s\n", __DATE__, __TIME__);
|
|
|
|
if ((argc > 1 && strcmp(argv[1], "-h") == 0) ||
|
|
(argc > 1 && strcmp(argv[1], "--help") == 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()
|
|
{
|
|
if(!Command_Thread::Init()){
|
|
return FALSE;
|
|
}
|
|
|
|
mgr = Rascsi_Manager::GetInstance();
|
|
if(!mgr->Init()){
|
|
return FALSE;
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
//
|
|
// Cleanup
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
void Cleanup()
|
|
{
|
|
mgr->Close();
|
|
|
|
#ifndef BAREMETAL
|
|
Command_Thread::Close();
|
|
#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 ret;
|
|
#ifndef BAREMETAL
|
|
struct sched_param schparam;
|
|
#endif // BAREMETAL
|
|
|
|
// Output the Banner
|
|
Banner(argc, argv);
|
|
|
|
// Initialize
|
|
ret = 0;
|
|
if (!Init()) {
|
|
ret = EPERM;
|
|
goto init_exit;
|
|
}
|
|
|
|
|
|
#ifdef BAREMETAL
|
|
// BUSY assert (to hold the host side)
|
|
Rascsi_Manager::GetInstance()->m_bus->SetBSY(TRUE);
|
|
|
|
// Argument parsing
|
|
if (!Command_Thread::ParseConfig(argc, argv)) {
|
|
ret = EINVAL;
|
|
goto err_exit;
|
|
}
|
|
// Release the busy signal
|
|
Rascsi_Manager::GetInstance()->m_bus->SetBSY(FALSE);
|
|
|
|
#endif
|
|
|
|
// For non-baremetal versions, we won't process the startup arguments... yet
|
|
|
|
|
|
#ifndef BAREMETAL
|
|
// Set the affinity to a specific processor core
|
|
FixCpu(3);
|
|
|
|
#if defined(USE_SEL_EVENT_ENABLE) && defined(__linux__)
|
|
// 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
|
|
Command_Thread::Start();
|
|
|
|
// Main Loop
|
|
while (Command_Thread::IsRunning()) {
|
|
mgr->Step();
|
|
}
|
|
|
|
err_exit:
|
|
// Cleanup
|
|
Cleanup();
|
|
|
|
init_exit:
|
|
#if !defined(BAREMETAL)
|
|
exit(ret);
|
|
#else
|
|
return ret;
|
|
#endif // BAREMETAL
|
|
}
|