Files
RASCSI/src/raspberrypi/rascsi.cpp
2020-08-15 19:22:14 -05:00

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
}