mirror of
https://github.com/akuker/RASCSI.git
synced 2024-06-28 05:29:33 +00:00
Break up disk.h and disk.cpp to be smaller files (#22)
This commit is contained in:
parent
051161693d
commit
5def9e3dfe
|
@ -9,15 +9,17 @@ CXX = $(CROSS_COMPILE)g++
|
|||
DEBUG ?= 0
|
||||
ifeq ($(DEBUG), 1)
|
||||
# Debug CFLAGS
|
||||
CFLAGS = -DDISK_LOG -O0 -g -Wall -DDEBUG
|
||||
CXXFLAGS = -DDISK_LOG -O0 -g -Wall -DDEBUG
|
||||
CFLAGS += -DDISK_LOG -O0 -g -Wall -DDEBUG
|
||||
CXXFLAGS += -DDISK_LOG -O0 -g -Wall -DDEBUG
|
||||
BUILD_TYPE = Debug
|
||||
else
|
||||
# Release CFLAGS
|
||||
CFLAGS ?= -O3 -Wall -Werror
|
||||
CXXFLAGS ?= -O3 -Wall -Werror
|
||||
CFLAGS += -O3 -Wall -Werror
|
||||
CXXFLAGS += -O3 -Wall -Werror
|
||||
BUILD_TYPE = Release
|
||||
endif
|
||||
CFLAGS += -iquote .
|
||||
CXXFLAGS += -std=c++14 -iquote .
|
||||
|
||||
# If its not specified, build for STANDARD configuration
|
||||
CONNECT_TYPE ?= STANDARD
|
||||
|
@ -37,24 +39,31 @@ USR_LOCAL_BIN = /usr/local/bin
|
|||
MAN_PAGE_DIR = /usr/share/man/man1
|
||||
DOC_DIR = ../../doc
|
||||
|
||||
OBJDIR := ./obj
|
||||
BINDIR := ./bin
|
||||
|
||||
#BIN_ALL = $(RASCSI) $(RASCTL) $(RASDUMP) $(SASIDUMP) $(SCSIMON)
|
||||
# Temporarily remove the RASDUMP and RASDUMP tools, since they're not needed
|
||||
# for my specific use case. If you need them - add them back in!
|
||||
BIN_ALL = $(RASCSI) $(RASCTL)
|
||||
BIN_ALL = $(BINDIR)/$(RASCSI) $(BINDIR)/$(RASCTL)
|
||||
|
||||
|
||||
SRC_RASCSI = \
|
||||
rascsi.cpp \
|
||||
scsi.cpp \
|
||||
disk.cpp \
|
||||
gpiobus.cpp \
|
||||
ctapdriver.cpp \
|
||||
cfilesystem.cpp \
|
||||
filepath.cpp \
|
||||
fileio.cpp
|
||||
fileio.cpp\
|
||||
# os.cpp
|
||||
# rasctl_command.cpp
|
||||
# rascsi_mgr.cpp
|
||||
# command_thread.cpp
|
||||
SRC_RASCSI += $(notdir $(shell find ./controllers -name '*.cpp'))
|
||||
SRC_RASCSI += $(notdir $(shell find ./devices -name '*.cpp'))
|
||||
|
||||
SRC_RASCTL = \
|
||||
rasctl.cpp
|
||||
# rasctl_command.cpp
|
||||
|
||||
SRC_RASDUMP = \
|
||||
rasdump.cpp \
|
||||
|
@ -70,18 +79,31 @@ SRC_SASIDUMP = \
|
|||
filepath.cpp \
|
||||
fileio.cpp
|
||||
|
||||
OBJ_RASCSI := $(SRC_RASCSI:%.cpp=%.o)
|
||||
OBJ_RASCTL := $(SRC_RASCTL:%.cpp=%.o)
|
||||
OBJ_RASDUMP := $(SRC_RASDUMP:%.cpp=%.o)
|
||||
OBJ_SASIDUMP := $(SRC_SASIDUMP:%.cpp=%.o)
|
||||
OBJ_SCSIMON := $(SRC_SCSIMON:%.cpp=%.o)
|
||||
vpath %.h ./ ./controllers ./devices
|
||||
vpath %.cpp ./ ./controllers ./devices
|
||||
vpath %.o ./$(OBJDIR)
|
||||
vpath ./$(BINDIR)
|
||||
|
||||
|
||||
OBJ_RASCSI := $(SRC_RASCSI:%.cpp=$(OBJDIR)/%.o)
|
||||
OBJ_RASCTL := $(SRC_RASCTL:%.cpp=$(OBJDIR)/%.o)
|
||||
OBJ_RASDUMP := $(SRC_RASDUMP:%.cpp=$(OBJDIR)/%.o)
|
||||
OBJ_SASIDUMP := $(SRC_SASIDUMP:%.cpp=$(OBJDIR)/%.o)
|
||||
OBJ_SCSIMON := $(SRC_SCSIMON:%.cpp=$(OBJDIR)/%.o)
|
||||
#OBJ_ALL := $(OBJ_RASCSI) $(OBJ_RASCTL) $(OBJ_RASDUMP) $(OBJ_SASIDUMP) $(OBJ_SCSIMON)
|
||||
OBJ_ALL := $(OBJ_RASCSI) $(OBJ_RASCTL) $(OBJ_RASDUMP) $(OBJ_SASIDUMP)
|
||||
|
||||
%.o: %.cpp
|
||||
$(OBJDIR) $(BINDIR):
|
||||
mkdir -p $@
|
||||
|
||||
$(OBJDIR)/%.o: %.cpp $(OBJDIR)
|
||||
$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
# $(OBJDIR)/%.o: %.c
|
||||
# $(CXX) $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
# %.o: %.cpp
|
||||
# $(CXX) $(CXXFLAGS) -c $(OBJDIR)/$< -o $@
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
.PHONY: all ALL docs
|
||||
|
@ -90,23 +112,25 @@ ALL: all
|
|||
|
||||
docs: $(DOC_DIR)/rascsi_man_page.txt $(DOC_DIR)/rasctl_man_page.txt
|
||||
|
||||
$(RASCSI): $(OBJ_RASCSI)
|
||||
$(BINDIR)/$(RASCSI): $(OBJ_RASCSI) $(BINDIR)
|
||||
@echo -- Linking $(RASCSI)
|
||||
$(CXX) -o $@ $(OBJ_RASCSI) -lpthread
|
||||
|
||||
$(RASCTL): $(OBJ_RASCTL)
|
||||
$(BINDIR)/$(RASCTL): $(OBJ_RASCTL) $(BINDIR)
|
||||
@echo -- Linking $(RASCTL)
|
||||
$(CXX) -o $@ $(OBJ_RASCTL)
|
||||
|
||||
$(RASDUMP): $(OBJ_RASDUMP)
|
||||
$(RASDUMP): $(OBJ_RASDUMP) $(BINDIR)
|
||||
$(CXX) -o $@ $(OBJ_RASDUMP)
|
||||
|
||||
$(SASIDUMP): $(OBJ_SASIDUMP)
|
||||
$(SASIDUMP): $(OBJ_SASIDUMP) $(BINDIR)
|
||||
$(CXX) -o $@ $(OBJ_SASIDUMP)
|
||||
|
||||
$(SCSIMON): $(OBJ_SCSIMON)
|
||||
$(SCSIMON): $(OBJ_SCSIMON) $(BINDIR)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_SCSIMON) -lpthread
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ_ALL) $(BIN_ALL)
|
||||
rm -rf $(OBJDIR) $(BINDIR)
|
||||
|
||||
run:
|
||||
sudo ./$(RASCSI) -ID1 /home/pi/HARDDISK2.hda -ID6 /home/pi/marathon.iso
|
||||
|
|
1999
src/raspberrypi/controllers/sasidev_ctrl.cpp
Normal file
1999
src/raspberrypi/controllers/sasidev_ctrl.cpp
Normal file
File diff suppressed because it is too large
Load Diff
211
src/raspberrypi/controllers/sasidev_ctrl.h
Normal file
211
src/raspberrypi/controllers/sasidev_ctrl.h
Normal file
|
@ -0,0 +1,211 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2014-2020 GIMONS
|
||||
// Copyright (C) akuker
|
||||
//
|
||||
// Licensed under the BSD 3-Clause License.
|
||||
// See LICENSE file in the project root folder.
|
||||
//
|
||||
// [ SASI device controller ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "os.h"
|
||||
#include "scsi.h"
|
||||
#include "fileio.h"
|
||||
#include "devices/disk.h"
|
||||
#include "log.h"
|
||||
#include "xm6.h"
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SASI Controller
|
||||
//
|
||||
//===========================================================================
|
||||
class SASIDEV
|
||||
{
|
||||
public:
|
||||
// Maximum number of logical units
|
||||
enum {
|
||||
UnitMax = 8
|
||||
};
|
||||
|
||||
#ifdef RASCSI
|
||||
// For timing adjustments
|
||||
enum {
|
||||
min_exec_time_sasi = 100, // SASI BOOT/FORMAT 30:NG 35:OK
|
||||
min_exec_time_scsi = 50
|
||||
};
|
||||
#endif // RASCSI
|
||||
|
||||
// Internal data definition
|
||||
typedef struct {
|
||||
// 全般
|
||||
BUS::phase_t phase; // Transition phase
|
||||
int id; // Controller ID (0-7)
|
||||
BUS *bus; // Bus
|
||||
|
||||
// commands
|
||||
DWORD cmd[10]; // Command data
|
||||
DWORD status; // Status data
|
||||
DWORD message; // Message data
|
||||
|
||||
#ifdef RASCSI
|
||||
// Run
|
||||
DWORD execstart; // Execution start time
|
||||
#endif // RASCSI
|
||||
|
||||
// Transfer
|
||||
BYTE *buffer; // Transfer data buffer
|
||||
int bufsize; // Transfer data buffer size
|
||||
DWORD blocks; // Number of transfer block
|
||||
DWORD next; // Next record
|
||||
DWORD offset; // Transfer offset
|
||||
DWORD length; // Transfer remaining length
|
||||
|
||||
// Logical unit
|
||||
Disk *unit[UnitMax];
|
||||
// Logical Unit
|
||||
} ctrl_t;
|
||||
|
||||
public:
|
||||
// Basic Functions
|
||||
#ifdef RASCSI
|
||||
SASIDEV();
|
||||
#else
|
||||
SASIDEV(Device *dev);
|
||||
#endif //RASCSI
|
||||
|
||||
// Constructor
|
||||
virtual ~SASIDEV();
|
||||
// Destructor
|
||||
virtual void FASTCALL Reset();
|
||||
// Device Reset
|
||||
#ifndef RASCSI
|
||||
virtual BOOL FASTCALL Save(Fileio *fio, int ver);
|
||||
// Save
|
||||
virtual BOOL FASTCALL Load(Fileio *fio, int ver);
|
||||
// Load
|
||||
#endif //RASCSI
|
||||
|
||||
// External API
|
||||
virtual BUS::phase_t FASTCALL Process();
|
||||
// Run
|
||||
|
||||
// Connect
|
||||
void FASTCALL Connect(int id, BUS *sbus);
|
||||
// Controller connection
|
||||
Disk* FASTCALL GetUnit(int no);
|
||||
// Get logical unit
|
||||
void FASTCALL SetUnit(int no, Disk *dev);
|
||||
// Logical unit setting
|
||||
BOOL FASTCALL HasUnit();
|
||||
// Has a valid logical unit
|
||||
|
||||
// Other
|
||||
BUS::phase_t FASTCALL GetPhase() {return ctrl.phase;}
|
||||
// Get the phase
|
||||
#ifdef DISK_LOG
|
||||
// Function to get the current phase as a String.
|
||||
void FASTCALL GetPhaseStr(char *str);
|
||||
#endif
|
||||
|
||||
int FASTCALL GetID() {return ctrl.id;}
|
||||
// Get the ID
|
||||
void FASTCALL GetCTRL(ctrl_t *buffer);
|
||||
// Get the internal information
|
||||
ctrl_t* FASTCALL GetWorkAddr() { return &ctrl; }
|
||||
// Get the internal information address
|
||||
virtual BOOL FASTCALL IsSASI() const {return TRUE;}
|
||||
// SASI Check
|
||||
virtual BOOL FASTCALL IsSCSI() const {return FALSE;}
|
||||
// SCSI check
|
||||
Disk* FASTCALL GetBusyUnit();
|
||||
// Get the busy unit
|
||||
|
||||
protected:
|
||||
// Phase processing
|
||||
virtual void FASTCALL BusFree();
|
||||
// Bus free phase
|
||||
virtual void FASTCALL Selection();
|
||||
// Selection phase
|
||||
virtual void FASTCALL Command();
|
||||
// Command phase
|
||||
virtual void FASTCALL Execute();
|
||||
// Execution phase
|
||||
void FASTCALL Status();
|
||||
// Status phase
|
||||
void FASTCALL MsgIn();
|
||||
// Message in phase
|
||||
void FASTCALL DataIn();
|
||||
// Data in phase
|
||||
void FASTCALL DataOut();
|
||||
// Data out phase
|
||||
virtual void FASTCALL Error();
|
||||
// Common error handling
|
||||
|
||||
// commands
|
||||
void FASTCALL CmdTestUnitReady();
|
||||
// TEST UNIT READY command
|
||||
void FASTCALL CmdRezero();
|
||||
// REZERO UNIT command
|
||||
void FASTCALL CmdRequestSense();
|
||||
// REQUEST SENSE command
|
||||
void FASTCALL CmdFormat();
|
||||
// FORMAT command
|
||||
void FASTCALL CmdReassign();
|
||||
// REASSIGN BLOCKS command
|
||||
void FASTCALL CmdRead6();
|
||||
// READ(6) command
|
||||
void FASTCALL CmdWrite6();
|
||||
// WRITE(6) command
|
||||
void FASTCALL CmdSeek6();
|
||||
// SEEK(6) command
|
||||
void FASTCALL CmdAssign();
|
||||
// ASSIGN command
|
||||
void FASTCALL CmdSpecify();
|
||||
// SPECIFY command
|
||||
void FASTCALL CmdInvalid();
|
||||
// Unsupported command
|
||||
|
||||
// データ転送
|
||||
virtual void FASTCALL Send();
|
||||
// Send data
|
||||
#ifndef RASCSI
|
||||
virtual void FASTCALL SendNext();
|
||||
// Continue sending data
|
||||
#endif // RASCSI
|
||||
virtual void FASTCALL Receive();
|
||||
// Receive data
|
||||
#ifndef RASCSI
|
||||
virtual void FASTCALL ReceiveNext();
|
||||
// Continue receiving data
|
||||
#endif // RASCSI
|
||||
BOOL FASTCALL XferIn(BYTE* buf);
|
||||
// Data transfer IN
|
||||
BOOL FASTCALL XferOut(BOOL cont);
|
||||
// Data transfer OUT
|
||||
|
||||
// Special operations
|
||||
void FASTCALL FlushUnit();
|
||||
// Flush the logical unit
|
||||
|
||||
// Log
|
||||
void FASTCALL Log(Log::loglevel level, const char *format, ...);
|
||||
// Log output
|
||||
|
||||
protected:
|
||||
#ifndef RASCSI
|
||||
Device *host;
|
||||
// Host device
|
||||
#endif // RASCSI
|
||||
|
||||
ctrl_t ctrl;
|
||||
// Internal data
|
||||
};
|
1869
src/raspberrypi/controllers/scsidev_ctrl.cpp
Normal file
1869
src/raspberrypi/controllers/scsidev_ctrl.cpp
Normal file
File diff suppressed because it is too large
Load Diff
142
src/raspberrypi/controllers/scsidev_ctrl.h
Normal file
142
src/raspberrypi/controllers/scsidev_ctrl.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2014-2020 GIMONS
|
||||
// Copyright (C) akuker
|
||||
//
|
||||
// Licensed under the BSD 3-Clause License.
|
||||
// See LICENSE file in the project root folder.
|
||||
//
|
||||
// [ SCSI device controller ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
#include "controllers/sasidev_ctrl.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SCSI Device (Interits SASI device)
|
||||
//
|
||||
//===========================================================================
|
||||
class SCSIDEV : public SASIDEV
|
||||
{
|
||||
public:
|
||||
// Internal data definition
|
||||
typedef struct {
|
||||
// Synchronous transfer
|
||||
BOOL syncenable; // Synchronous transfer possible
|
||||
int syncperiod; // Synchronous transfer period
|
||||
int syncoffset; // Synchronous transfer offset
|
||||
int syncack; // Number of synchronous transfer ACKs
|
||||
|
||||
// ATN message
|
||||
BOOL atnmsg;
|
||||
int msc;
|
||||
BYTE msb[256];
|
||||
} scsi_t;
|
||||
|
||||
public:
|
||||
// Basic Functions
|
||||
#ifdef RASCSI
|
||||
SCSIDEV();
|
||||
#else
|
||||
SCSIDEV(Device *dev);
|
||||
#endif // RASCSI
|
||||
// Constructor
|
||||
|
||||
void FASTCALL Reset();
|
||||
// Device Reset
|
||||
|
||||
// 外部API
|
||||
BUS::phase_t FASTCALL Process();
|
||||
// Run
|
||||
|
||||
void FASTCALL SyncTransfer(BOOL enable) { scsi.syncenable = enable; }
|
||||
// Synchronouse transfer enable setting
|
||||
|
||||
// Other
|
||||
BOOL FASTCALL IsSASI() const {return FALSE;}
|
||||
// SASI Check
|
||||
BOOL FASTCALL IsSCSI() const {return TRUE;}
|
||||
// SCSI check
|
||||
|
||||
private:
|
||||
// Phase
|
||||
void FASTCALL BusFree();
|
||||
// Bus free phase
|
||||
void FASTCALL Selection();
|
||||
// Selection phase
|
||||
void FASTCALL Execute();
|
||||
// Execution phase
|
||||
void FASTCALL MsgOut();
|
||||
// Message out phase
|
||||
void FASTCALL Error();
|
||||
// Common erorr handling
|
||||
|
||||
// commands
|
||||
void FASTCALL CmdInquiry();
|
||||
// INQUIRY command
|
||||
void FASTCALL CmdModeSelect();
|
||||
// MODE SELECT command
|
||||
void FASTCALL CmdModeSense();
|
||||
// MODE SENSE command
|
||||
void FASTCALL CmdStartStop();
|
||||
// START STOP UNIT command
|
||||
void FASTCALL CmdSendDiag();
|
||||
// SEND DIAGNOSTIC command
|
||||
void FASTCALL CmdRemoval();
|
||||
// PREVENT/ALLOW MEDIUM REMOVAL command
|
||||
void FASTCALL CmdReadCapacity();
|
||||
// READ CAPACITY command
|
||||
void FASTCALL CmdRead10();
|
||||
// READ(10) command
|
||||
void FASTCALL CmdWrite10();
|
||||
// WRITE(10) command
|
||||
void FASTCALL CmdSeek10();
|
||||
// SEEK(10) command
|
||||
void FASTCALL CmdVerify();
|
||||
// VERIFY command
|
||||
void FASTCALL CmdSynchronizeCache();
|
||||
// SYNCHRONIZE CACHE command
|
||||
void FASTCALL CmdReadDefectData10();
|
||||
// READ DEFECT DATA(10) command
|
||||
void FASTCALL CmdReadToc();
|
||||
// READ TOC command
|
||||
void FASTCALL CmdPlayAudio10();
|
||||
// PLAY AUDIO(10) command
|
||||
void FASTCALL CmdPlayAudioMSF();
|
||||
// PLAY AUDIO MSF command
|
||||
void FASTCALL CmdPlayAudioTrack();
|
||||
// PLAY AUDIO TRACK INDEX command
|
||||
void FASTCALL CmdModeSelect10();
|
||||
// MODE SELECT(10) command
|
||||
void FASTCALL CmdModeSense10();
|
||||
// MODE SENSE(10) command
|
||||
void FASTCALL CmdGetMessage10();
|
||||
// GET MESSAGE(10) command
|
||||
void FASTCALL CmdSendMessage10();
|
||||
// SEND MESSAGE(10) command
|
||||
|
||||
// データ転送
|
||||
void FASTCALL Send();
|
||||
// Send data
|
||||
#ifndef RASCSI
|
||||
void FASTCALL SendNext();
|
||||
// Continue sending data
|
||||
#endif // RASCSI
|
||||
void FASTCALL Receive();
|
||||
// Receive data
|
||||
#ifndef RASCSI
|
||||
void FASTCALL ReceiveNext();
|
||||
// Continue receiving data
|
||||
#endif // RASCSI
|
||||
BOOL FASTCALL XferMsg(DWORD msg);
|
||||
// Data transfer message
|
||||
|
||||
scsi_t scsi;
|
||||
// Internal data
|
||||
};
|
||||
|
4794
src/raspberrypi/devices/cfilesystem.cpp
Normal file
4794
src/raspberrypi/devices/cfilesystem.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1184
src/raspberrypi/devices/cfilesystem.h
Normal file
1184
src/raspberrypi/devices/cfilesystem.h
Normal file
File diff suppressed because it is too large
Load Diff
209
src/raspberrypi/devices/ctapdriver.cpp
Normal file
209
src/raspberrypi/devices/ctapdriver.cpp
Normal file
|
@ -0,0 +1,209 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technology.
|
||||
// Copyright (C) 2016-2020 GIMONS
|
||||
//
|
||||
// Imported NetBSD support and some optimisation patch by Rin Okuyama.
|
||||
//
|
||||
// [ TAP Driver ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "os.h"
|
||||
#include "xm6.h"
|
||||
#include "ctapdriver.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// コンストラクタ
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
CTapDriver::CTapDriver()
|
||||
{
|
||||
// 初期化
|
||||
m_hTAP = -1;
|
||||
memset(&m_MacAddr, 0, sizeof(m_MacAddr));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 初期化
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#ifdef __linux__
|
||||
BOOL FASTCALL CTapDriver::Init()
|
||||
{
|
||||
char dev[IFNAMSIZ] = "ras0";
|
||||
struct ifreq ifr;
|
||||
int ret;
|
||||
|
||||
ASSERT(this);
|
||||
|
||||
// TAPデバイス初期化
|
||||
if ((m_hTAP = open("/dev/net/tun", O_RDWR)) < 0) {
|
||||
printf("Error: can't open tun\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// IFF_NO_PI for no extra packet information
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
|
||||
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
|
||||
if ((ret = ioctl(m_hTAP, TUNSETIFF, (void *)&ifr)) < 0) {
|
||||
printf("Error: can't ioctl TUNSETIFF\n");
|
||||
close(m_hTAP);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// MACアドレス取得
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
if ((ret = ioctl(m_hTAP, SIOCGIFHWADDR, &ifr)) < 0) {
|
||||
printf("Error: can't ioctl SIOCGIFHWADDR\n");
|
||||
close(m_hTAP);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// MACアドレス保存
|
||||
memcpy(m_MacAddr, ifr.ifr_hwaddr.sa_data, sizeof(m_MacAddr));
|
||||
return TRUE;
|
||||
}
|
||||
#endif // __linux__
|
||||
|
||||
#ifdef __NetBSD__
|
||||
BOOL FASTCALL CTapDriver::Init()
|
||||
{
|
||||
struct ifreq ifr;
|
||||
struct ifaddrs *ifa, *a;
|
||||
|
||||
ASSERT(this);
|
||||
|
||||
// TAPデバイス初期化
|
||||
if ((m_hTAP = open("/dev/tap", O_RDWR)) < 0) {
|
||||
printf("Error: can't open tap\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// デバイス名取得
|
||||
if (ioctl(m_hTAP, TAPGIFNAME, (void *)&ifr) < 0) {
|
||||
printf("Error: can't ioctl TAPGIFNAME\n");
|
||||
close(m_hTAP);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// MACアドレス取得
|
||||
if (getifaddrs(&ifa) == -1) {
|
||||
printf("Error: can't getifaddrs\n");
|
||||
close(m_hTAP);
|
||||
return FALSE;
|
||||
}
|
||||
for (a = ifa; a != NULL; a = a->ifa_next)
|
||||
if (strcmp(ifr.ifr_name, a->ifa_name) == 0 &&
|
||||
a->ifa_addr->sa_family == AF_LINK)
|
||||
break;
|
||||
if (a == NULL) {
|
||||
printf("Error: can't get MAC address\n");
|
||||
close(m_hTAP);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// MACアドレス保存
|
||||
memcpy(m_MacAddr, LLADDR((struct sockaddr_dl *)a->ifa_addr),
|
||||
sizeof(m_MacAddr));
|
||||
freeifaddrs(ifa);
|
||||
|
||||
printf("Tap device : %s\n", ifr.ifr_name);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif // __NetBSD__
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// クリーンアップ
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void FASTCALL CTapDriver::Cleanup()
|
||||
{
|
||||
ASSERT(this);
|
||||
|
||||
// TAPデバイス解放
|
||||
if (m_hTAP != -1) {
|
||||
close(m_hTAP);
|
||||
m_hTAP = -1;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// MACアドレス取得
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void FASTCALL CTapDriver::GetMacAddr(BYTE *mac)
|
||||
{
|
||||
ASSERT(this);
|
||||
ASSERT(mac);
|
||||
|
||||
memcpy(mac, m_MacAddr, sizeof(m_MacAddr));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 受信
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int FASTCALL CTapDriver::Rx(BYTE *buf)
|
||||
{
|
||||
struct pollfd fds;
|
||||
DWORD dwReceived;
|
||||
|
||||
ASSERT(this);
|
||||
ASSERT(m_hTAP != -1);
|
||||
|
||||
// 受信可能なデータがあるか調べる
|
||||
fds.fd = m_hTAP;
|
||||
fds.events = POLLIN | POLLERR;
|
||||
fds.revents = 0;
|
||||
poll(&fds, 1, 0);
|
||||
if (!(fds.revents & POLLIN)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 受信
|
||||
dwReceived = read(m_hTAP, buf, ETH_FRAME_LEN);
|
||||
if (dwReceived == (DWORD)-1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 受信が有効であれば
|
||||
if (dwReceived > 0) {
|
||||
// FCSを除く最小フレームサイズ(60バイト)にパディング
|
||||
if (dwReceived < 60) {
|
||||
memset(buf + dwReceived, 0, 60 - dwReceived);
|
||||
dwReceived = 60;
|
||||
}
|
||||
|
||||
// ダミーのFCSを付加する
|
||||
memset(buf + dwReceived, 0, 4);
|
||||
dwReceived += 4;
|
||||
}
|
||||
|
||||
// バイト数を返却
|
||||
return dwReceived;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 送信
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int FASTCALL CTapDriver::Tx(BYTE *buf, int len)
|
||||
{
|
||||
ASSERT(this);
|
||||
ASSERT(m_hTAP != -1);
|
||||
|
||||
// 送信開始
|
||||
return write(m_hTAP, buf, len);
|
||||
}
|
53
src/raspberrypi/devices/ctapdriver.h
Normal file
53
src/raspberrypi/devices/ctapdriver.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technology.
|
||||
// Copyright (C) 2016-2020 GIMONS
|
||||
//
|
||||
// Imported NetBSD support and some optimisation patch by Rin Okuyama.
|
||||
//
|
||||
// [ TAP Driver ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#if !defined(ctapdriver_h)
|
||||
#define ctapdriver_h
|
||||
|
||||
#ifndef ETH_FRAME_LEN
|
||||
#define ETH_FRAME_LEN 1514
|
||||
#endif
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Tapドライバ
|
||||
//
|
||||
//===========================================================================
|
||||
class CTapDriver
|
||||
{
|
||||
public:
|
||||
// 基本ファンクション
|
||||
CTapDriver();
|
||||
// コンストラクタ
|
||||
BOOL FASTCALL Init();
|
||||
// 初期化
|
||||
void FASTCALL Cleanup();
|
||||
// クリーンアップ
|
||||
void FASTCALL GetMacAddr(BYTE *mac);
|
||||
// MACアドレス取得
|
||||
int FASTCALL Rx(BYTE *buf);
|
||||
// 受信
|
||||
int FASTCALL Tx(BYTE *buf, int len);
|
||||
// 送信
|
||||
|
||||
private:
|
||||
BYTE m_MacAddr[6];
|
||||
// MACアドレス
|
||||
BOOL m_bTxValid;
|
||||
// 送信有効フラグ
|
||||
int m_hTAP;
|
||||
// ディスクプリタ
|
||||
};
|
||||
|
||||
#endif // ctapdriver_h
|
2346
src/raspberrypi/devices/disk.cpp
Normal file
2346
src/raspberrypi/devices/disk.cpp
Normal file
File diff suppressed because it is too large
Load Diff
368
src/raspberrypi/devices/disk.h
Normal file
368
src/raspberrypi/devices/disk.h
Normal file
|
@ -0,0 +1,368 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// Imported sava's Anex86/T98Next image and MO format support patch.
|
||||
// Comments translated to english by akuker.
|
||||
//
|
||||
// [ Disk ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xm6.h"
|
||||
#include "log.h"
|
||||
#include "scsi.h"
|
||||
#include "filepath.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Error definition (sense code returned by REQUEST SENSE)
|
||||
//
|
||||
// MSB Reserved (0x00)
|
||||
// Sense Key
|
||||
// Additional Sense Code (ASC)
|
||||
// LSB Additional Sense Code Qualifier(ASCQ)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#define DISK_NOERROR 0x00000000 // NO ADDITIONAL SENSE INFO.
|
||||
#define DISK_DEVRESET 0x00062900 // POWER ON OR RESET OCCURED
|
||||
#define DISK_NOTREADY 0x00023a00 // MEDIUM NOT PRESENT
|
||||
#define DISK_ATTENTION 0x00062800 // MEDIUM MAY HAVE CHANGED
|
||||
#define DISK_PREVENT 0x00045302 // MEDIUM REMOVAL PREVENTED
|
||||
#define DISK_READFAULT 0x00031100 // UNRECOVERED READ ERROR
|
||||
#define DISK_WRITEFAULT 0x00030300 // PERIPHERAL DEVICE WRITE FAULT
|
||||
#define DISK_WRITEPROTECT 0x00042700 // WRITE PROTECTED
|
||||
#define DISK_MISCOMPARE 0x000e1d00 // MISCOMPARE DURING VERIFY
|
||||
#define DISK_INVALIDCMD 0x00052000 // INVALID COMMAND OPERATION CODE
|
||||
#define DISK_INVALIDLBA 0x00052100 // LOGICAL BLOCK ADDR. OUT OF RANGE
|
||||
#define DISK_INVALIDCDB 0x00052400 // INVALID FIELD IN CDB
|
||||
#define DISK_INVALIDLUN 0x00052500 // LOGICAL UNIT NOT SUPPORTED
|
||||
#define DISK_INVALIDPRM 0x00052600 // INVALID FIELD IN PARAMETER LIST
|
||||
#define DISK_INVALIDMSG 0x00054900 // INVALID MESSAGE ERROR
|
||||
#define DISK_PARAMLEN 0x00051a00 // PARAMETERS LIST LENGTH ERROR
|
||||
#define DISK_PARAMNOT 0x00052601 // PARAMETERS NOT SUPPORTED
|
||||
#define DISK_PARAMVALUE 0x00052602 // PARAMETERS VALUE INVALID
|
||||
#define DISK_PARAMSAVE 0x00053900 // SAVING PARAMETERS NOT SUPPORTED
|
||||
#define DISK_NODEFECT 0x00010000 // DEFECT LIST NOT FOUND
|
||||
|
||||
#if 0
|
||||
#define DISK_AUDIOPROGRESS 0x00??0011 // AUDIO PLAY IN PROGRESS
|
||||
#define DISK_AUDIOPAUSED 0x00??0012 // AUDIO PLAY PAUSED
|
||||
#define DISK_AUDIOSTOPPED 0x00??0014 // AUDIO PLAY STOPPED DUE TO ERROR
|
||||
#define DISK_AUDIOCOMPLETE 0x00??0013 // AUDIO PLAY SUCCESSFULLY COMPLETED
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef RASCSI
|
||||
#define BENDER_SIGNATURE "RaSCSI"
|
||||
// The following line was to mimic Apple's CDROM ID
|
||||
// #define BENDER_SIGNATURE "SONY "
|
||||
#else
|
||||
#define BENDER_SIGNATURE "XM6"
|
||||
#endif
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Disk Track
|
||||
//
|
||||
//===========================================================================
|
||||
class DiskTrack
|
||||
{
|
||||
public:
|
||||
// Internal data definition
|
||||
typedef struct {
|
||||
int track; // Track Number
|
||||
int size; // Sector Size(8 or 9)
|
||||
int sectors; // Number of sectors(<=0x100)
|
||||
DWORD length; // Data buffer length
|
||||
BYTE *buffer; // Data buffer
|
||||
BOOL init; // Is it initilized?
|
||||
BOOL changed; // Changed flag
|
||||
DWORD maplen; // Changed map length
|
||||
BOOL *changemap; // Changed map
|
||||
BOOL raw; // RAW mode flag
|
||||
off64_t imgoffset; // Offset to actual data
|
||||
} disktrk_t;
|
||||
|
||||
public:
|
||||
// Basic Functions
|
||||
DiskTrack();
|
||||
// Constructor
|
||||
virtual ~DiskTrack();
|
||||
// Destructor
|
||||
void FASTCALL Init(int track, int size, int sectors, BOOL raw = FALSE,
|
||||
off64_t imgoff = 0);
|
||||
// Initialization
|
||||
BOOL FASTCALL Load(const Filepath& path);
|
||||
// Load
|
||||
BOOL FASTCALL Save(const Filepath& path);
|
||||
// Save
|
||||
|
||||
// Read / Write
|
||||
BOOL FASTCALL Read(BYTE *buf, int sec) const;
|
||||
// Sector Read
|
||||
BOOL FASTCALL Write(const BYTE *buf, int sec);
|
||||
// Sector Write
|
||||
|
||||
// Other
|
||||
int FASTCALL GetTrack() const { return dt.track; }
|
||||
// Get track
|
||||
BOOL FASTCALL IsChanged() const { return dt.changed; }
|
||||
// Changed flag check
|
||||
|
||||
private:
|
||||
// Internal data
|
||||
disktrk_t dt;
|
||||
// Internal data
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Disk Cache
|
||||
//
|
||||
//===========================================================================
|
||||
class DiskCache
|
||||
{
|
||||
public:
|
||||
// Internal data definition
|
||||
typedef struct {
|
||||
DiskTrack *disktrk; // Disk Track
|
||||
DWORD serial; // Serial
|
||||
} cache_t;
|
||||
|
||||
// Number of caches
|
||||
enum {
|
||||
CacheMax = 16 // Number of tracks to cache
|
||||
};
|
||||
|
||||
public:
|
||||
// Basic Functions
|
||||
DiskCache(const Filepath& path, int size, int blocks,
|
||||
off64_t imgoff = 0);
|
||||
// Constructor
|
||||
virtual ~DiskCache();
|
||||
// Destructor
|
||||
void FASTCALL SetRawMode(BOOL raw);
|
||||
// CD-ROM raw mode setting
|
||||
|
||||
// Access
|
||||
BOOL FASTCALL Save();
|
||||
// Save and release all
|
||||
BOOL FASTCALL Read(BYTE *buf, int block);
|
||||
// Sector Read
|
||||
BOOL FASTCALL Write(const BYTE *buf, int block);
|
||||
// Sector Write
|
||||
BOOL FASTCALL GetCache(int index, int& track, DWORD& serial) const;
|
||||
// Get cache information
|
||||
|
||||
private:
|
||||
// Internal Management
|
||||
void FASTCALL Clear();
|
||||
// Clear all tracks
|
||||
DiskTrack* FASTCALL Assign(int track);
|
||||
// Load track
|
||||
BOOL FASTCALL Load(int index, int track, DiskTrack *disktrk = NULL);
|
||||
// Load track
|
||||
void FASTCALL Update();
|
||||
// Update serial number
|
||||
|
||||
// Internal data
|
||||
cache_t cache[CacheMax];
|
||||
// Cache management
|
||||
DWORD serial;
|
||||
// Last serial number
|
||||
Filepath sec_path;
|
||||
// Path
|
||||
int sec_size;
|
||||
// Sector size (8 or 9 or 11)
|
||||
int sec_blocks;
|
||||
// Blocks per sector
|
||||
BOOL cd_raw;
|
||||
// CD-ROM RAW mode
|
||||
off64_t imgoffset;
|
||||
// Offset to actual data
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Disk
|
||||
//
|
||||
//===========================================================================
|
||||
class Disk
|
||||
{
|
||||
public:
|
||||
// Internal data structure
|
||||
typedef struct {
|
||||
DWORD id; // Media ID
|
||||
BOOL ready; // Valid Disk
|
||||
BOOL writep; // Write protected
|
||||
BOOL readonly; // Read only
|
||||
BOOL removable; // Removable
|
||||
BOOL lock; // Locked
|
||||
BOOL attn; // Attention
|
||||
BOOL reset; // Reset
|
||||
int size; // Sector Size
|
||||
DWORD blocks; // Total number of sectors
|
||||
DWORD lun; // LUN
|
||||
DWORD code; // Status code
|
||||
DiskCache *dcache; // Disk cache
|
||||
off64_t imgoffset; // Offset to actual data
|
||||
} disk_t;
|
||||
|
||||
public:
|
||||
// Basic Functions
|
||||
Disk();
|
||||
// Constructor
|
||||
virtual ~Disk();
|
||||
// Destructor
|
||||
virtual void FASTCALL Reset();
|
||||
// Device Reset
|
||||
#ifndef RASCSI
|
||||
virtual BOOL FASTCALL Save(Fileio *fio, int ver);
|
||||
// Save
|
||||
virtual BOOL FASTCALL Load(Fileio *fio, int ver);
|
||||
// Load
|
||||
#endif // RASCSI
|
||||
|
||||
// ID
|
||||
DWORD FASTCALL GetID() const { return disk.id; }
|
||||
// Get media ID
|
||||
BOOL FASTCALL IsNULL() const;
|
||||
// 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);
|
||||
// Open
|
||||
void FASTCALL GetPath(Filepath& path) const;
|
||||
// Get the path
|
||||
void FASTCALL Eject(BOOL force);
|
||||
// Eject
|
||||
BOOL FASTCALL IsReady() const { return disk.ready; }
|
||||
// Ready check
|
||||
void FASTCALL WriteP(BOOL flag);
|
||||
// Set Write Protect flag
|
||||
BOOL FASTCALL IsWriteP() const { return disk.writep; }
|
||||
// Get write protect flag
|
||||
BOOL FASTCALL IsReadOnly() const { return disk.readonly; }
|
||||
// Get read only flag
|
||||
BOOL FASTCALL IsRemovable() const { return disk.removable; }
|
||||
// Get is removable flag
|
||||
BOOL FASTCALL IsLocked() const { return disk.lock; }
|
||||
// Get locked status
|
||||
BOOL FASTCALL IsAttn() const { return disk.attn; }
|
||||
// Get attention flag
|
||||
BOOL FASTCALL Flush();
|
||||
// Flush the cache
|
||||
void FASTCALL GetDisk(disk_t *buffer) const;
|
||||
// Get the internal data struct
|
||||
|
||||
// Properties
|
||||
void FASTCALL SetLUN(DWORD lun) { disk.lun = lun; }
|
||||
// LUN set
|
||||
DWORD FASTCALL GetLUN() { return disk.lun; }
|
||||
// LUN get
|
||||
// commands
|
||||
virtual int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor);
|
||||
// INQUIRY command
|
||||
virtual int FASTCALL RequestSense(const DWORD *cdb, BYTE *buf);
|
||||
// REQUEST SENSE command
|
||||
int FASTCALL SelectCheck(const DWORD *cdb);
|
||||
// SELECT check
|
||||
int FASTCALL SelectCheck10(const DWORD *cdb);
|
||||
// SELECT(10) check
|
||||
virtual BOOL FASTCALL ModeSelect(const DWORD *cdb, const BYTE *buf, int length);
|
||||
// MODE SELECT command
|
||||
virtual int FASTCALL ModeSense(const DWORD *cdb, BYTE *buf);
|
||||
// MODE SENSE command
|
||||
virtual int FASTCALL ModeSense10(const DWORD *cdb, BYTE *buf);
|
||||
// MODE SENSE(10) command
|
||||
int FASTCALL ReadDefectData10(const DWORD *cdb, BYTE *buf);
|
||||
// READ DEFECT DATA(10) command
|
||||
virtual BOOL FASTCALL TestUnitReady(const DWORD *cdb);
|
||||
// TEST UNIT READY command
|
||||
BOOL FASTCALL Rezero(const DWORD *cdb);
|
||||
// REZERO command
|
||||
BOOL FASTCALL Format(const DWORD *cdb);
|
||||
// FORMAT UNIT command
|
||||
BOOL FASTCALL Reassign(const DWORD *cdb);
|
||||
// REASSIGN UNIT command
|
||||
virtual int FASTCALL Read(BYTE *buf, DWORD block);
|
||||
// READ command
|
||||
int FASTCALL WriteCheck(DWORD block);
|
||||
// WRITE check
|
||||
BOOL FASTCALL Write(const BYTE *buf, DWORD block);
|
||||
// WRITE command
|
||||
BOOL FASTCALL Seek(const DWORD *cdb);
|
||||
// SEEK command
|
||||
BOOL FASTCALL Assign(const DWORD *cdb);
|
||||
// ASSIGN command
|
||||
BOOL FASTCALL Specify(const DWORD *cdb);
|
||||
// SPECIFY command
|
||||
BOOL FASTCALL StartStop(const DWORD *cdb);
|
||||
// START STOP UNIT command
|
||||
BOOL FASTCALL SendDiag(const DWORD *cdb);
|
||||
// SEND DIAGNOSTIC command
|
||||
BOOL FASTCALL Removal(const DWORD *cdb);
|
||||
// PREVENT/ALLOW MEDIUM REMOVAL command
|
||||
int FASTCALL ReadCapacity(const DWORD *cdb, BYTE *buf);
|
||||
// READ CAPACITY command
|
||||
BOOL FASTCALL Verify(const DWORD *cdb);
|
||||
// VERIFY command
|
||||
virtual int FASTCALL ReadToc(const DWORD *cdb, BYTE *buf);
|
||||
// READ TOC command
|
||||
virtual BOOL FASTCALL PlayAudio(const DWORD *cdb);
|
||||
// PLAY AUDIO command
|
||||
virtual BOOL FASTCALL PlayAudioMSF(const DWORD *cdb);
|
||||
// PLAY AUDIO MSF command
|
||||
virtual BOOL FASTCALL PlayAudioTrack(const DWORD *cdb);
|
||||
// PLAY AUDIO TRACK command
|
||||
void FASTCALL InvalidCmd() { disk.code = DISK_INVALIDCMD; }
|
||||
// Unsupported command
|
||||
|
||||
// Other
|
||||
BOOL IsCacheWB() { return cache_wb; }
|
||||
// Get cache writeback mode
|
||||
void SetCacheWB(BOOL enable) { cache_wb = enable; }
|
||||
// Set cache writeback mode
|
||||
|
||||
protected:
|
||||
// Internal processing
|
||||
virtual int FASTCALL AddError(BOOL change, BYTE *buf);
|
||||
// Add error
|
||||
virtual int FASTCALL AddFormat(BOOL change, BYTE *buf);
|
||||
// Add format
|
||||
virtual int FASTCALL AddDrive(BOOL change, BYTE *buf);
|
||||
// Add drive
|
||||
int FASTCALL AddOpt(BOOL change, BYTE *buf);
|
||||
// Add optical
|
||||
int FASTCALL AddCache(BOOL change, BYTE *buf);
|
||||
// Add cache
|
||||
int FASTCALL AddCDROM(BOOL change, BYTE *buf);
|
||||
// Add CD-ROM
|
||||
int FASTCALL AddCDDA(BOOL change, BYTE *buf);
|
||||
// Add CD_DA
|
||||
virtual int FASTCALL AddVendor(int page, BOOL change, BYTE *buf);
|
||||
// Add vendor special info
|
||||
BOOL FASTCALL CheckReady();
|
||||
// Check if ready
|
||||
|
||||
// Internal data
|
||||
disk_t disk;
|
||||
// Internal disk data
|
||||
Filepath diskpath;
|
||||
// File path (for GetPath)
|
||||
BOOL cache_wb;
|
||||
// Cache mode
|
||||
};
|
164
src/raspberrypi/devices/sasihd.cpp
Normal file
164
src/raspberrypi/devices/sasihd.cpp
Normal file
|
@ -0,0 +1,164 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2014-2020 GIMONS
|
||||
// Copyright (C) akuker
|
||||
//
|
||||
// Licensed under the BSD 3-Clause License.
|
||||
// See LICENSE file in the project root folder.
|
||||
//
|
||||
// [ SASI hard disk ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#include "sasihd.h"
|
||||
#include "xm6.h"
|
||||
#include "fileio.h"
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SASI Hard Disk
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
SASIHD::SASIHD() : Disk()
|
||||
{
|
||||
// SASI ハードディスク
|
||||
disk.id = MAKEID('S', 'A', 'H', 'D');
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// リセット
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void FASTCALL SASIHD::Reset()
|
||||
{
|
||||
// ロック状態解除、アテンション解除
|
||||
disk.lock = FALSE;
|
||||
disk.attn = FALSE;
|
||||
|
||||
// Resetなし、コードをクリア
|
||||
disk.reset = FALSE;
|
||||
disk.code = 0x00;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// オープン
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL SASIHD::Open(const Filepath& path, BOOL /*attn*/)
|
||||
{
|
||||
Fileio fio;
|
||||
off64_t size;
|
||||
|
||||
ASSERT(this);
|
||||
ASSERT(!disk.ready);
|
||||
|
||||
// Open as read-only
|
||||
if (!fio.Open(path, Fileio::ReadOnly)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Get file size
|
||||
size = fio.GetFileSize();
|
||||
fio.Close();
|
||||
|
||||
#if defined(USE_MZ1F23_1024_SUPPORT)
|
||||
// MZ-2500/MZ-2800用 MZ-1F23(SASI 20M/セクタサイズ1024)専用
|
||||
// 20M(22437888 BS=1024 C=21912)
|
||||
if (size == 0x1566000) {
|
||||
// セクタサイズとブロック数
|
||||
disk.size = 10;
|
||||
disk.blocks = (DWORD)(size >> 10);
|
||||
|
||||
// Call the base class
|
||||
return Disk::Open(path);
|
||||
}
|
||||
#endif // USE_MZ1F23_1024_SUPPORT
|
||||
|
||||
#if defined(REMOVE_FIXED_SASIHD_SIZE)
|
||||
// 256バイト単位であること
|
||||
if (size & 0xff) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 10MB以上
|
||||
if (size < 0x9f5400) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 512MB程度に制限しておく
|
||||
if (size > 512 * 1024 * 1024) {
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
// 10MB, 20MB, 40MBのみ
|
||||
switch (size) {
|
||||
// 10MB(10441728 BS=256 C=40788)
|
||||
case 0x9f5400:
|
||||
break;
|
||||
|
||||
// 20MB(20748288 BS=256 C=81048)
|
||||
case 0x13c9800:
|
||||
break;
|
||||
|
||||
// 40MB(41496576 BS=256 C=162096)
|
||||
case 0x2793000:
|
||||
break;
|
||||
|
||||
// Other(サポートしない)
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
#endif // REMOVE_FIXED_SASIHD_SIZE
|
||||
|
||||
// セクタサイズとブロック数
|
||||
disk.size = 8;
|
||||
disk.blocks = (DWORD)(size >> 8);
|
||||
|
||||
// Call the base class
|
||||
return Disk::Open(path);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// REQUEST SENSE
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int FASTCALL SASIHD::RequestSense(const DWORD *cdb, BYTE *buf)
|
||||
{
|
||||
int size;
|
||||
|
||||
ASSERT(this);
|
||||
ASSERT(cdb);
|
||||
ASSERT(buf);
|
||||
|
||||
// サイズ決定
|
||||
size = (int)cdb[4];
|
||||
ASSERT((size >= 0) && (size < 0x100));
|
||||
|
||||
// サイズ0のときに4バイト転送する(Shugart Associates System Interface仕様)
|
||||
if (size == 0) {
|
||||
size = 4;
|
||||
}
|
||||
|
||||
// SASIは非拡張フォーマットに固定
|
||||
memset(buf, 0, size);
|
||||
buf[0] = (BYTE)(disk.code >> 16);
|
||||
buf[1] = (BYTE)(disk.lun << 5);
|
||||
|
||||
// コードをクリア
|
||||
disk.code = 0x00;
|
||||
|
||||
return size;
|
||||
}
|
40
src/raspberrypi/devices/sasihd.h
Normal file
40
src/raspberrypi/devices/sasihd.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2014-2020 GIMONS
|
||||
// Copyright (C) akuker
|
||||
//
|
||||
// Licensed under the BSD 3-Clause License.
|
||||
// See LICENSE file in the project root folder.
|
||||
//
|
||||
// [ SASI hard disk ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "os.h"
|
||||
#include "disk.h"
|
||||
#include "filepath.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SASI Hard Disk
|
||||
//
|
||||
//===========================================================================
|
||||
class SASIHD : public Disk
|
||||
{
|
||||
public:
|
||||
// Basic Functions
|
||||
SASIHD();
|
||||
// Constructor
|
||||
void FASTCALL Reset();
|
||||
// Reset
|
||||
BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE);
|
||||
// Open
|
||||
// commands
|
||||
int FASTCALL RequestSense(const DWORD *cdb, BYTE *buf);
|
||||
// REQUEST SENSE command
|
||||
};
|
1502
src/raspberrypi/devices/scsi_host_bridge.cpp
Normal file
1502
src/raspberrypi/devices/scsi_host_bridge.cpp
Normal file
File diff suppressed because it is too large
Load Diff
153
src/raspberrypi/devices/scsi_host_bridge.h
Normal file
153
src/raspberrypi/devices/scsi_host_bridge.h
Normal file
|
@ -0,0 +1,153 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2014-2020 GIMONS
|
||||
// Copyright (C) akuker
|
||||
//
|
||||
// Licensed under the BSD 3-Clause License.
|
||||
// See LICENSE file in the project root folder.
|
||||
//
|
||||
// [ SCSI Host Bridge for the Sharp X68000 ]
|
||||
//
|
||||
// Note: This requires a special driver on the host system and will only
|
||||
// work with the Sharp X68000 operating system.
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "xm6.h"
|
||||
#include "os.h"
|
||||
#include "disk.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SCSI Host Bridge
|
||||
//
|
||||
//===========================================================================
|
||||
#if defined(RASCSI) && !defined(BAREMETAL)
|
||||
class CTapDriver;
|
||||
#endif // RASCSI && !BAREMETAL
|
||||
class CFileSys;
|
||||
class SCSIBR : public Disk
|
||||
{
|
||||
public:
|
||||
// Basic Functions
|
||||
SCSIBR();
|
||||
// Constructor
|
||||
virtual ~SCSIBR();
|
||||
// Destructor
|
||||
|
||||
// commands
|
||||
int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor);
|
||||
// INQUIRY command
|
||||
BOOL FASTCALL TestUnitReady(const DWORD *cdb);
|
||||
// TEST UNIT READY command
|
||||
int FASTCALL GetMessage10(const DWORD *cdb, BYTE *buf);
|
||||
// GET MESSAGE10 command
|
||||
BOOL FASTCALL SendMessage10(const DWORD *cdb, BYTE *buf);
|
||||
// SEND MESSAGE10 command
|
||||
|
||||
private:
|
||||
#if defined(RASCSI) && !defined(BAREMETAL)
|
||||
int FASTCALL GetMacAddr(BYTE *buf);
|
||||
// Get MAC address
|
||||
void FASTCALL SetMacAddr(BYTE *buf);
|
||||
// Set MAC address
|
||||
void FASTCALL ReceivePacket();
|
||||
// Receive a packet
|
||||
void FASTCALL GetPacketBuf(BYTE *buf);
|
||||
// Get a packet
|
||||
void FASTCALL SendPacket(BYTE *buf, int len);
|
||||
// Send a packet
|
||||
|
||||
CTapDriver *tap;
|
||||
// TAP driver
|
||||
BOOL m_bTapEnable;
|
||||
// TAP valid flag
|
||||
BYTE mac_addr[6];
|
||||
// MAC Addres
|
||||
int packet_len;
|
||||
// Receive packet size
|
||||
BYTE packet_buf[0x1000];
|
||||
// Receive packet buffer
|
||||
BOOL packet_enable;
|
||||
// Received packet valid
|
||||
#endif // RASCSI && !BAREMETAL
|
||||
|
||||
int FASTCALL ReadFsResult(BYTE *buf);
|
||||
// Read filesystem (result code)
|
||||
int FASTCALL ReadFsOut(BYTE *buf);
|
||||
// Read filesystem (return data)
|
||||
int FASTCALL ReadFsOpt(BYTE *buf);
|
||||
// Read file system (optional data)
|
||||
void FASTCALL WriteFs(int func, BYTE *buf);
|
||||
// File system write (execute)
|
||||
void FASTCALL WriteFsOpt(BYTE *buf, int len);
|
||||
// File system write (optional data)
|
||||
// Command handlers
|
||||
void FASTCALL FS_InitDevice(BYTE *buf);
|
||||
// $40 - boot
|
||||
void FASTCALL FS_CheckDir(BYTE *buf);
|
||||
// $41 - directory check
|
||||
void FASTCALL FS_MakeDir(BYTE *buf);
|
||||
// $42 - create directory
|
||||
void FASTCALL FS_RemoveDir(BYTE *buf);
|
||||
// $43 - delete directory
|
||||
void FASTCALL FS_Rename(BYTE *buf);
|
||||
// $44 - change filename
|
||||
void FASTCALL FS_Delete(BYTE *buf);
|
||||
// $45 - delete file
|
||||
void FASTCALL FS_Attribute(BYTE *buf);
|
||||
// $46 - get/set file attributes
|
||||
void FASTCALL FS_Files(BYTE *buf);
|
||||
// $47 - file search
|
||||
void FASTCALL FS_NFiles(BYTE *buf);
|
||||
// $48 - find next file
|
||||
void FASTCALL FS_Create(BYTE *buf);
|
||||
// $49 - create file
|
||||
void FASTCALL FS_Open(BYTE *buf);
|
||||
// $4A - open file
|
||||
void FASTCALL FS_Close(BYTE *buf);
|
||||
// $4B - close file
|
||||
void FASTCALL FS_Read(BYTE *buf);
|
||||
// $4C - read file
|
||||
void FASTCALL FS_Write(BYTE *buf);
|
||||
// $4D - write file
|
||||
void FASTCALL FS_Seek(BYTE *buf);
|
||||
// $4E - seek file
|
||||
void FASTCALL FS_TimeStamp(BYTE *buf);
|
||||
// $4F - get/set file time
|
||||
void FASTCALL FS_GetCapacity(BYTE *buf);
|
||||
// $50 - get capacity
|
||||
void FASTCALL FS_CtrlDrive(BYTE *buf);
|
||||
// $51 - drive status check/control
|
||||
void FASTCALL FS_GetDPB(BYTE *buf);
|
||||
// $52 - get DPB
|
||||
void FASTCALL FS_DiskRead(BYTE *buf);
|
||||
// $53 - read sector
|
||||
void FASTCALL FS_DiskWrite(BYTE *buf);
|
||||
// $54 - write sector
|
||||
void FASTCALL FS_Ioctrl(BYTE *buf);
|
||||
// $55 - IOCTRL
|
||||
void FASTCALL FS_Flush(BYTE *buf);
|
||||
// $56 - flush cache
|
||||
void FASTCALL FS_CheckMedia(BYTE *buf);
|
||||
// $57 - check media
|
||||
void FASTCALL FS_Lock(BYTE *buf);
|
||||
// $58 - get exclusive control
|
||||
|
||||
CFileSys *fs;
|
||||
// File system accessor
|
||||
DWORD fsresult;
|
||||
// File system access result code
|
||||
BYTE fsout[0x800];
|
||||
// File system access result buffer
|
||||
DWORD fsoutlen;
|
||||
// File system access result buffer size
|
||||
BYTE fsopt[0x1000000];
|
||||
// File system access buffer
|
||||
DWORD fsoptlen;
|
||||
// File system access buffer size
|
||||
};
|
1089
src/raspberrypi/devices/scsicd.cpp
Normal file
1089
src/raspberrypi/devices/scsicd.cpp
Normal file
File diff suppressed because it is too large
Load Diff
230
src/raspberrypi/devices/scsicd.h
Normal file
230
src/raspberrypi/devices/scsicd.h
Normal file
|
@ -0,0 +1,230 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2014-2020 GIMONS
|
||||
// Copyright (C) akuker
|
||||
//
|
||||
// Licensed under the BSD 3-Clause License.
|
||||
// See LICENSE file in the project root folder.
|
||||
//
|
||||
// [ SCSI Hard Disk for Apple Macintosh ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "os.h"
|
||||
#include "disk.h"
|
||||
#include "filepath.h"
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Class precedence definition
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
class SCSICD;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CD-ROM Track
|
||||
//
|
||||
//===========================================================================
|
||||
class CDTrack
|
||||
{
|
||||
public:
|
||||
// Basic Functions
|
||||
CDTrack(SCSICD *scsicd);
|
||||
// Constructor
|
||||
virtual ~CDTrack();
|
||||
// Destructor
|
||||
BOOL FASTCALL Init(int track, DWORD first, DWORD last);
|
||||
// Initialization
|
||||
|
||||
// Properties
|
||||
void FASTCALL SetPath(BOOL cdda, const Filepath& path);
|
||||
// Set the path
|
||||
void FASTCALL GetPath(Filepath& path) const;
|
||||
// Get the path
|
||||
void FASTCALL AddIndex(int index, DWORD lba);
|
||||
// Add index
|
||||
DWORD FASTCALL GetFirst() const;
|
||||
// Get the start LBA
|
||||
DWORD FASTCALL GetLast() const;
|
||||
// Get the last LBA
|
||||
DWORD FASTCALL GetBlocks() const;
|
||||
// Get the number of blocks
|
||||
int FASTCALL GetTrackNo() const;
|
||||
// Get the track number
|
||||
BOOL FASTCALL IsValid(DWORD lba) const;
|
||||
// Is this a valid LBA?
|
||||
BOOL FASTCALL IsAudio() const;
|
||||
// Is this an audio track?
|
||||
|
||||
private:
|
||||
SCSICD *cdrom;
|
||||
// Parent device
|
||||
BOOL valid;
|
||||
// Valid track
|
||||
int track_no;
|
||||
// Track number
|
||||
DWORD first_lba;
|
||||
// First LBA
|
||||
DWORD last_lba;
|
||||
// Last LBA
|
||||
BOOL audio;
|
||||
// Audio track flag
|
||||
BOOL raw;
|
||||
// RAW data flag
|
||||
Filepath imgpath;
|
||||
// Image file path
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CD-DA Buffer
|
||||
//
|
||||
//===========================================================================
|
||||
class CDDABuf
|
||||
{
|
||||
public:
|
||||
// Basic Functions
|
||||
CDDABuf();
|
||||
// Constructor
|
||||
virtual ~CDDABuf();
|
||||
// Destructor
|
||||
#if 0
|
||||
BOOL Init();
|
||||
// Initialization
|
||||
BOOL FASTCALL Load(const Filepath& path);
|
||||
// Load
|
||||
BOOL FASTCALL Save(const Filepath& path);
|
||||
// Save
|
||||
|
||||
// API
|
||||
void FASTCALL Clear();
|
||||
// Clear the buffer
|
||||
BOOL FASTCALL Open(Filepath& path);
|
||||
// File specification
|
||||
BOOL FASTCALL GetBuf(DWORD *buffer, int frames);
|
||||
// Get the buffer
|
||||
BOOL FASTCALL IsValid();
|
||||
// Check if Valid
|
||||
BOOL FASTCALL ReadReq();
|
||||
// Read Request
|
||||
BOOL FASTCALL IsEnd() const;
|
||||
// Finish check
|
||||
|
||||
private:
|
||||
Filepath wavepath;
|
||||
// Wave path
|
||||
BOOL valid;
|
||||
// Open result (is it valid?)
|
||||
DWORD *buf;
|
||||
// Data buffer
|
||||
DWORD read;
|
||||
// Read pointer
|
||||
DWORD write;
|
||||
// Write pointer
|
||||
DWORD num;
|
||||
// Valid number of data
|
||||
DWORD rest;
|
||||
// Remaining file size
|
||||
#endif
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SCSI CD-ROM
|
||||
//
|
||||
//===========================================================================
|
||||
class SCSICD : public Disk
|
||||
{
|
||||
public:
|
||||
// Number of tracks
|
||||
enum {
|
||||
TrackMax = 96 // Maximum number of tracks
|
||||
};
|
||||
|
||||
public:
|
||||
// Basic Functions
|
||||
SCSICD();
|
||||
// Constructor
|
||||
virtual ~SCSICD();
|
||||
// Destructor
|
||||
BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE);
|
||||
// Open
|
||||
#ifndef RASCSI
|
||||
BOOL FASTCALL Load(Fileio *fio, int ver);
|
||||
// Load
|
||||
#endif // RASCSI
|
||||
|
||||
// commands
|
||||
int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor);
|
||||
// INQUIRY command
|
||||
int FASTCALL Read(BYTE *buf, DWORD block);
|
||||
// READ command
|
||||
int FASTCALL ReadToc(const DWORD *cdb, BYTE *buf);
|
||||
// READ TOC command
|
||||
BOOL FASTCALL PlayAudio(const DWORD *cdb);
|
||||
// PLAY AUDIO command
|
||||
BOOL FASTCALL PlayAudioMSF(const DWORD *cdb);
|
||||
// PLAY AUDIO MSF command
|
||||
BOOL FASTCALL PlayAudioTrack(const DWORD *cdb);
|
||||
// PLAY AUDIO TRACK command
|
||||
|
||||
// CD-DA
|
||||
BOOL FASTCALL NextFrame();
|
||||
// Frame notification
|
||||
void FASTCALL GetBuf(DWORD *buffer, int samples, DWORD rate);
|
||||
// Get CD-DA buffer
|
||||
|
||||
// LBA-MSF変換
|
||||
void FASTCALL LBAtoMSF(DWORD lba, BYTE *msf) const;
|
||||
// LBA→MSF conversion
|
||||
DWORD FASTCALL MSFtoLBA(const BYTE *msf) const;
|
||||
// MSF→LBA conversion
|
||||
|
||||
private:
|
||||
// Open
|
||||
BOOL FASTCALL OpenCue(const Filepath& path);
|
||||
// Open(CUE)
|
||||
BOOL FASTCALL OpenIso(const Filepath& path);
|
||||
// Open(ISO)
|
||||
BOOL FASTCALL OpenPhysical(const Filepath& path);
|
||||
// Open(Physical)
|
||||
BOOL rawfile;
|
||||
// RAW flag
|
||||
|
||||
// Track management
|
||||
void FASTCALL ClearTrack();
|
||||
// Clear the track
|
||||
int FASTCALL SearchTrack(DWORD lba) const;
|
||||
// Track search
|
||||
CDTrack* track[TrackMax];
|
||||
// Track opbject references
|
||||
int tracks;
|
||||
// Effective number of track objects
|
||||
int dataindex;
|
||||
// Current data track
|
||||
int audioindex;
|
||||
// Current audio track
|
||||
|
||||
int frame;
|
||||
// Frame number
|
||||
|
||||
#if 0
|
||||
CDDABuf da_buf;
|
||||
// CD-DA buffer
|
||||
int da_num;
|
||||
// Number of CD-DA tracks
|
||||
int da_cur;
|
||||
// CD-DA current track
|
||||
int da_next;
|
||||
// CD-DA next track
|
||||
BOOL da_req;
|
||||
// CD-DA data request
|
||||
#endif
|
||||
};
|
268
src/raspberrypi/devices/scsihd.cpp
Normal file
268
src/raspberrypi/devices/scsihd.cpp
Normal file
|
@ -0,0 +1,268 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2014-2020 GIMONS
|
||||
// Copyright (C) akuker
|
||||
//
|
||||
// Licensed under the BSD 3-Clause License.
|
||||
// See LICENSE file in the project root folder.
|
||||
//
|
||||
// [ SCSI hard disk ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#include "scsihd.h"
|
||||
#include "xm6.h"
|
||||
#include "fileio.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SCSI Hard Disk
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
SCSIHD::SCSIHD() : Disk()
|
||||
{
|
||||
// SCSI Hard Disk
|
||||
disk.id = MAKEID('S', 'C', 'H', 'D');
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Reset
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
void FASTCALL SCSIHD::Reset()
|
||||
{
|
||||
// Unlock and release attention
|
||||
disk.lock = FALSE;
|
||||
disk.attn = FALSE;
|
||||
|
||||
// No reset, clear code
|
||||
disk.reset = FALSE;
|
||||
disk.code = 0x00;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Open
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL SCSIHD::Open(const Filepath& path, BOOL /*attn*/)
|
||||
{
|
||||
Fileio fio;
|
||||
off64_t size;
|
||||
|
||||
ASSERT(this);
|
||||
ASSERT(!disk.ready);
|
||||
|
||||
// read open required
|
||||
if (!fio.Open(path, Fileio::ReadOnly)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Get file size
|
||||
size = fio.GetFileSize();
|
||||
fio.Close();
|
||||
|
||||
// Must be 512 bytes
|
||||
if (size & 0x1ff) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 10MB or more
|
||||
if (size < 0x9f5400) {
|
||||
return FALSE;
|
||||
}
|
||||
// 2TB according to xm6i
|
||||
// There is a similar one in wxw/wxw_cfg.cpp
|
||||
if (size > 2LL * 1024 * 1024 * 1024 * 1024) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// sector size and number of blocks
|
||||
disk.size = 9;
|
||||
disk.blocks = (DWORD)(size >> 9);
|
||||
|
||||
// Call base class
|
||||
return Disk::Open(path);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// INQUIRY
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int FASTCALL SCSIHD::Inquiry(
|
||||
const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor)
|
||||
{
|
||||
char vendor[32];
|
||||
char product[32];
|
||||
char rev[32];
|
||||
int size;
|
||||
|
||||
ASSERT(this);
|
||||
ASSERT(cdb);
|
||||
ASSERT(buf);
|
||||
ASSERT(cdb[0] == 0x12);
|
||||
|
||||
// EVPD check
|
||||
if (cdb[1] & 0x01) {
|
||||
disk.code = DISK_INVALIDCDB;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Ready check (Error if no image file)
|
||||
if (!disk.ready) {
|
||||
disk.code = DISK_NOTREADY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Basic data
|
||||
// buf[0] ... Direct Access Device
|
||||
// buf[2] ... SCSI-2 compliant command system
|
||||
// buf[3] ... SCSI-2 compliant Inquiry response
|
||||
// buf[4] ... Inquiry additional data
|
||||
memset(buf, 0, 8);
|
||||
|
||||
// SCSI-2 p.104 4.4.3 Incorrect logical unit handling
|
||||
if (((cdb[1] >> 5) & 0x07) != disk.lun) {
|
||||
buf[0] = 0x7f;
|
||||
}
|
||||
|
||||
buf[2] = 0x02;
|
||||
buf[3] = 0x02;
|
||||
buf[4] = 122 + 3; // Value close to real HDD
|
||||
|
||||
// Fill with blanks
|
||||
memset(&buf[8], 0x20, buf[4] - 3);
|
||||
|
||||
// Determine vendor name/product name
|
||||
sprintf(vendor, BENDER_SIGNATURE);
|
||||
size = disk.blocks >> 11;
|
||||
if (size < 300)
|
||||
sprintf(product, "PRODRIVE LPS%dS", size);
|
||||
else if (size < 600)
|
||||
sprintf(product, "MAVERICK%dS", size);
|
||||
else if (size < 800)
|
||||
sprintf(product, "LIGHTNING%dS", size);
|
||||
else if (size < 1000)
|
||||
sprintf(product, "TRAILBRAZER%dS", size);
|
||||
else if (size < 2000)
|
||||
sprintf(product, "FIREBALL%dS", size);
|
||||
else
|
||||
sprintf(product, "FBSE%d.%dS", size / 1000, (size % 1000) / 100);
|
||||
|
||||
// Vendor name
|
||||
memcpy(&buf[8], vendor, strlen(vendor));
|
||||
|
||||
// Product name
|
||||
memcpy(&buf[16], product, strlen(product));
|
||||
|
||||
// Revision
|
||||
sprintf(rev, "0%01d%01d%01d",
|
||||
(int)major, (int)(minor >> 4), (int)(minor & 0x0f));
|
||||
memcpy(&buf[32], rev, 4);
|
||||
|
||||
// Size of data that can be returned
|
||||
size = (buf[4] + 5);
|
||||
|
||||
// Limit if the other buffer is small
|
||||
if (size > (int)cdb[4]) {
|
||||
size = (int)cdb[4];
|
||||
}
|
||||
|
||||
// Success
|
||||
disk.code = DISK_NOERROR;
|
||||
return size;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// MODE SELECT
|
||||
// *Not affected by disk.code
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL SCSIHD::ModeSelect(const DWORD *cdb, const BYTE *buf, int length)
|
||||
{
|
||||
BYTE page;
|
||||
int size;
|
||||
|
||||
ASSERT(this);
|
||||
ASSERT(buf);
|
||||
ASSERT(length >= 0);
|
||||
|
||||
// PF
|
||||
if (cdb[1] & 0x10) {
|
||||
// Mode Parameter header
|
||||
if (length >= 12) {
|
||||
// Check the block length bytes
|
||||
size = 1 << disk.size;
|
||||
if (buf[9] != (BYTE)(size >> 16) ||
|
||||
buf[10] != (BYTE)(size >> 8) ||
|
||||
buf[11] != (BYTE)size) {
|
||||
// currently does not allow changing sector length
|
||||
disk.code = DISK_INVALIDPRM;
|
||||
return FALSE;
|
||||
}
|
||||
buf += 12;
|
||||
length -= 12;
|
||||
}
|
||||
|
||||
// Parsing the page
|
||||
while (length > 0) {
|
||||
// Get page
|
||||
page = buf[0];
|
||||
|
||||
switch (page) {
|
||||
// format device
|
||||
case 0x03:
|
||||
// check the number of bytes in the physical sector
|
||||
size = 1 << disk.size;
|
||||
if (buf[0xc] != (BYTE)(size >> 8) ||
|
||||
buf[0xd] != (BYTE)size) {
|
||||
// currently does not allow changing sector length
|
||||
disk.code = DISK_INVALIDPRM;
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
// CD-ROM Parameters
|
||||
// According to the SONY CDU-541 manual, Page code 8 is supposed
|
||||
// to set the Logical Block Adress Format, as well as the
|
||||
// inactivity timer multiplier
|
||||
case 0x08:
|
||||
// Debug code for Issue #2:
|
||||
// https://github.com/akuker/RASCSI/issues/2
|
||||
printf("[Unhandled page code] Received mode page code 8 with total length %d\n ", length);
|
||||
for (int i = 0; i<length; i++)
|
||||
{
|
||||
printf("%02X ", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
break;
|
||||
// Other page
|
||||
default:
|
||||
printf("Unknown Mode Select page code received: %02X\n",page);
|
||||
break;
|
||||
}
|
||||
|
||||
// Advance to the next page
|
||||
size = buf[1] + 2;
|
||||
length -= size;
|
||||
buf += size;
|
||||
}
|
||||
}
|
||||
|
||||
// Do not generate an error for the time being (MINIX)
|
||||
disk.code = DISK_NOERROR;
|
||||
|
||||
return TRUE;
|
||||
}
|
44
src/raspberrypi/devices/scsihd.h
Normal file
44
src/raspberrypi/devices/scsihd.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2014-2020 GIMONS
|
||||
// Copyright (C) akuker
|
||||
//
|
||||
// Licensed under the BSD 3-Clause License.
|
||||
// See LICENSE file in the project root folder.
|
||||
//
|
||||
// [ SCSI hard disk ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "os.h"
|
||||
#include "disk.h"
|
||||
#include "filepath.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SCSI Hard Disk
|
||||
//
|
||||
//===========================================================================
|
||||
class SCSIHD : public Disk
|
||||
{
|
||||
public:
|
||||
// Basic Functions
|
||||
SCSIHD();
|
||||
// Constructor
|
||||
void FASTCALL Reset();
|
||||
// Reset
|
||||
BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE);
|
||||
// Open
|
||||
|
||||
// commands
|
||||
int FASTCALL Inquiry(
|
||||
const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor);
|
||||
// INQUIRY command
|
||||
BOOL FASTCALL ModeSelect(const DWORD *cdb, const BYTE *buf, int length);
|
||||
// MODE SELECT(6) command
|
||||
};
|
93
src/raspberrypi/devices/scsihd_apple.cpp
Normal file
93
src/raspberrypi/devices/scsihd_apple.cpp
Normal file
|
@ -0,0 +1,93 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2014-2020 GIMONS
|
||||
// Copyright (C) akuker
|
||||
//
|
||||
// Licensed under the BSD 3-Clause License.
|
||||
// See LICENSE file in the project root folder.
|
||||
//
|
||||
// [ SCSI Hard Disk for Apple Macintosh ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "scsihd_apple.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SCSI hard disk (Macintosh Apple genuine)
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
SCSIHD_APPLE::SCSIHD_APPLE() : SCSIHD()
|
||||
{
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// INQUIRY
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int FASTCALL SCSIHD_APPLE::Inquiry(
|
||||
const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor)
|
||||
{
|
||||
int size;
|
||||
char vendor[32];
|
||||
char product[32];
|
||||
|
||||
// Call the base class
|
||||
size = SCSIHD::Inquiry(cdb, buf, major, minor);
|
||||
|
||||
// End if there is an error in the base class
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Vendor name
|
||||
sprintf(vendor, " SEAGATE");
|
||||
memcpy(&buf[8], vendor, strlen(vendor));
|
||||
|
||||
// Product name
|
||||
sprintf(product, " ST225N");
|
||||
memcpy(&buf[16], product, strlen(product));
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Add Vendor special page
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int FASTCALL SCSIHD_APPLE::AddVendor(int page, BOOL change, BYTE *buf)
|
||||
{
|
||||
ASSERT(this);
|
||||
ASSERT(buf);
|
||||
|
||||
// Page code 48
|
||||
if ((page != 0x30) && (page != 0x3f)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the message length
|
||||
buf[0] = 0x30;
|
||||
buf[1] = 0x1c;
|
||||
|
||||
// No changeable area
|
||||
if (change) {
|
||||
return 30;
|
||||
}
|
||||
|
||||
// APPLE COMPUTER, INC.
|
||||
memcpy(&buf[0xa], "APPLE COMPUTER, INC.", 20);
|
||||
|
||||
return 30;
|
||||
}
|
39
src/raspberrypi/devices/scsihd_apple.h
Normal file
39
src/raspberrypi/devices/scsihd_apple.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2014-2020 GIMONS
|
||||
// Copyright (C) akuker
|
||||
//
|
||||
// Licensed under the BSD 3-Clause License.
|
||||
// See LICENSE file in the project root folder.
|
||||
//
|
||||
// [ SCSI Hard Disk for Apple Macintosh ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "scsihd.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SCSI Hard Disk(Genuine Apple Macintosh)
|
||||
//
|
||||
//===========================================================================
|
||||
class SCSIHD_APPLE : public SCSIHD
|
||||
{
|
||||
public:
|
||||
// Basic Functions
|
||||
SCSIHD_APPLE();
|
||||
// Constructor
|
||||
// commands
|
||||
int FASTCALL Inquiry(
|
||||
const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor);
|
||||
// INQUIRY command
|
||||
|
||||
// Internal processing
|
||||
int FASTCALL AddVendor(int page, BOOL change, BYTE *buf);
|
||||
// Add vendor special page
|
||||
};
|
295
src/raspberrypi/devices/scsihd_nec.cpp
Normal file
295
src/raspberrypi/devices/scsihd_nec.cpp
Normal file
|
@ -0,0 +1,295 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2014-2020 GIMONS
|
||||
// Copyright (C) akuker
|
||||
//
|
||||
// Licensed under the BSD 3-Clause License.
|
||||
// See LICENSE file in the project root folder.
|
||||
//
|
||||
// [ SCSI NEC "Genuine" Hard Disk]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "scsihd_nec.h"
|
||||
#include "fileio.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SCSI hard disk (PC-9801-55 NEC genuine /Anex86/T98Next)
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
SCSIHD_NEC::SCSIHD_NEC() : SCSIHD()
|
||||
{
|
||||
// ワーク初期化
|
||||
cylinders = 0;
|
||||
heads = 0;
|
||||
sectors = 0;
|
||||
sectorsize = 0;
|
||||
imgoffset = 0;
|
||||
imgsize = 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// リトルエンディアンと想定したワードを取り出す
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
static inline WORD getWordLE(const BYTE *b)
|
||||
{
|
||||
return ((WORD)(b[1]) << 8) | b[0];
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// リトルエンディアンと想定したロングワードを取り出す
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
static inline DWORD getDwordLE(const BYTE *b)
|
||||
{
|
||||
return ((DWORD)(b[3]) << 24) | ((DWORD)(b[2]) << 16) |
|
||||
((DWORD)(b[1]) << 8) | b[0];
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// オープン
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL SCSIHD_NEC::Open(const Filepath& path, BOOL /*attn*/)
|
||||
{
|
||||
Fileio fio;
|
||||
off64_t size;
|
||||
BYTE hdr[512];
|
||||
LPCTSTR ext;
|
||||
|
||||
ASSERT(this);
|
||||
ASSERT(!disk.ready);
|
||||
|
||||
// Open as read-only
|
||||
if (!fio.Open(path, Fileio::ReadOnly)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Get file size
|
||||
size = fio.GetFileSize();
|
||||
|
||||
// ヘッダー読み込み
|
||||
if (size >= (off64_t)sizeof(hdr)) {
|
||||
if (!fio.Read(hdr, sizeof(hdr))) {
|
||||
fio.Close();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
fio.Close();
|
||||
|
||||
// 512バイト単位であること
|
||||
if (size & 0x1ff) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 10MB以上
|
||||
if (size < 0x9f5400) {
|
||||
return FALSE;
|
||||
}
|
||||
// xm6iに準じて2TB
|
||||
// よく似たものが wxw/wxw_cfg.cpp にもある
|
||||
if (size > 2LL * 1024 * 1024 * 1024 * 1024) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 拡張子別にパラメータを決定
|
||||
ext = path.GetFileExt();
|
||||
if (xstrcasecmp(ext, _T(".HDN")) == 0) {
|
||||
// デフォルト設定としてセクタサイズ512,セクタ数25,ヘッド数8を想定
|
||||
imgoffset = 0;
|
||||
imgsize = size;
|
||||
sectorsize = 512;
|
||||
sectors = 25;
|
||||
heads = 8;
|
||||
cylinders = (int)(size >> 9);
|
||||
cylinders >>= 3;
|
||||
cylinders /= 25;
|
||||
} else if (xstrcasecmp(ext, _T(".HDI")) == 0) { // Anex86 HD image?
|
||||
imgoffset = getDwordLE(&hdr[4 + 4]);
|
||||
imgsize = getDwordLE(&hdr[4 + 4 + 4]);
|
||||
sectorsize = getDwordLE(&hdr[4 + 4 + 4 + 4]);
|
||||
sectors = getDwordLE(&hdr[4 + 4 + 4 + 4 + 4]);
|
||||
heads = getDwordLE(&hdr[4 + 4 + 4 + 4 + 4 + 4]);
|
||||
cylinders = getDwordLE(&hdr[4 + 4 + 4 + 4 + 4 + 4 + 4]);
|
||||
} else if (xstrcasecmp(ext, _T(".NHD")) == 0 &&
|
||||
memcmp(hdr, "T98HDDIMAGE.R0\0", 15) == 0) { // T98Next HD image?
|
||||
imgoffset = getDwordLE(&hdr[0x10 + 0x100]);
|
||||
cylinders = getDwordLE(&hdr[0x10 + 0x100 + 4]);
|
||||
heads = getWordLE(&hdr[0x10 + 0x100 + 4 + 4]);
|
||||
sectors = getWordLE(&hdr[0x10 + 0x100 + 4 + 4 + 2]);
|
||||
sectorsize = getWordLE(&hdr[0x10 + 0x100 + 4 + 4 + 2 + 2]);
|
||||
imgsize = (off64_t)cylinders * heads * sectors * sectorsize;
|
||||
}
|
||||
|
||||
// セクタサイズは256または512をサポート
|
||||
if (sectorsize != 256 && sectorsize != 512) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// イメージサイズの整合性チェック
|
||||
if (imgoffset + imgsize > size || (imgsize % sectorsize != 0)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// セクタサイズ
|
||||
for(disk.size = 16; disk.size > 0; --(disk.size)) {
|
||||
if ((1 << disk.size) == sectorsize)
|
||||
break;
|
||||
}
|
||||
if (disk.size <= 0 || disk.size > 16) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ブロック数
|
||||
disk.blocks = (DWORD)(imgsize >> disk.size);
|
||||
disk.imgoffset = imgoffset;
|
||||
|
||||
// Call the base class
|
||||
return Disk::Open(path);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// INQUIRY
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int FASTCALL SCSIHD_NEC::Inquiry(
|
||||
const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor)
|
||||
{
|
||||
int size;
|
||||
|
||||
// 基底クラス
|
||||
size = SCSIHD::Inquiry(cdb, buf, major, minor);
|
||||
|
||||
// 基底クラスでエラーなら終了
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// SCSI1相当に変更
|
||||
buf[2] = 0x01;
|
||||
buf[3] = 0x01;
|
||||
|
||||
// Replace Vendor name
|
||||
buf[8] = 'N';
|
||||
buf[9] = 'E';
|
||||
buf[10] = 'C';
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// エラーページ追加
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int FASTCALL SCSIHD_NEC::AddError(BOOL change, BYTE *buf)
|
||||
{
|
||||
ASSERT(this);
|
||||
ASSERT(buf);
|
||||
|
||||
// Set the message length
|
||||
buf[0] = 0x01;
|
||||
buf[1] = 0x06;
|
||||
|
||||
// No changeable area
|
||||
if (change) {
|
||||
return 8;
|
||||
}
|
||||
|
||||
// リトライカウントは0、リミットタイムは装置内部のデフォルト値を使用
|
||||
return 8;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// フォーマットページ追加
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int FASTCALL SCSIHD_NEC::AddFormat(BOOL change, BYTE *buf)
|
||||
{
|
||||
int size;
|
||||
|
||||
ASSERT(this);
|
||||
ASSERT(buf);
|
||||
|
||||
// Set the message length
|
||||
buf[0] = 0x80 | 0x03;
|
||||
buf[1] = 0x16;
|
||||
|
||||
// 物理セクタのバイト数は変更可能に見せる(実際には変更できないが)
|
||||
if (change) {
|
||||
buf[0xc] = 0xff;
|
||||
buf[0xd] = 0xff;
|
||||
return 24;
|
||||
}
|
||||
|
||||
if (disk.ready) {
|
||||
// 1ゾーンのトラック数を設定(PC-9801-55はこの値を見ているようだ)
|
||||
buf[0x2] = (BYTE)(heads >> 8);
|
||||
buf[0x3] = (BYTE)heads;
|
||||
|
||||
// 1トラックのセクタ数を設定
|
||||
buf[0xa] = (BYTE)(sectors >> 8);
|
||||
buf[0xb] = (BYTE)sectors;
|
||||
|
||||
// 物理セクタのバイト数を設定
|
||||
size = 1 << disk.size;
|
||||
buf[0xc] = (BYTE)(size >> 8);
|
||||
buf[0xd] = (BYTE)size;
|
||||
}
|
||||
|
||||
// リムーバブル属性を設定(昔の名残)
|
||||
if (disk.removable) {
|
||||
buf[20] = 0x20;
|
||||
}
|
||||
|
||||
return 24;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// ドライブページ追加
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int FASTCALL SCSIHD_NEC::AddDrive(BOOL change, BYTE *buf)
|
||||
{
|
||||
ASSERT(this);
|
||||
ASSERT(buf);
|
||||
|
||||
// Set the message length
|
||||
buf[0] = 0x04;
|
||||
buf[1] = 0x12;
|
||||
|
||||
// No changeable area
|
||||
if (change) {
|
||||
return 20;
|
||||
}
|
||||
|
||||
if (disk.ready) {
|
||||
// シリンダ数を設定
|
||||
buf[0x2] = (BYTE)(cylinders >> 16);
|
||||
buf[0x3] = (BYTE)(cylinders >> 8);
|
||||
buf[0x4] = (BYTE)cylinders;
|
||||
|
||||
// ヘッド数を設定
|
||||
buf[0x5] = (BYTE)heads;
|
||||
}
|
||||
|
||||
return 20;
|
||||
}
|
61
src/raspberrypi/devices/scsihd_nec.h
Normal file
61
src/raspberrypi/devices/scsihd_nec.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2014-2020 GIMONS
|
||||
// Copyright (C) akuker
|
||||
//
|
||||
// Licensed under the BSD 3-Clause License.
|
||||
// See LICENSE file in the project root folder.
|
||||
//
|
||||
// [ SCSI NEC "Genuine" Hard Disk]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "scsihd.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SCSI hard disk (PC-9801-55 NEC genuine /Anex86/T98Next)
|
||||
//
|
||||
//===========================================================================
|
||||
class SCSIHD_NEC : public SCSIHD
|
||||
{
|
||||
public:
|
||||
// Basic Functions
|
||||
SCSIHD_NEC();
|
||||
// Constructor
|
||||
|
||||
BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE);
|
||||
// Open
|
||||
|
||||
// commands
|
||||
int FASTCALL Inquiry(
|
||||
const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor);
|
||||
// INQUIRY command
|
||||
|
||||
// Internal processing
|
||||
int FASTCALL AddError(BOOL change, BYTE *buf);
|
||||
// Add error
|
||||
int FASTCALL AddFormat(BOOL change, BYTE *buf);
|
||||
// Add format
|
||||
int FASTCALL AddDrive(BOOL change, BYTE *buf);
|
||||
// Add drive
|
||||
|
||||
private:
|
||||
int cylinders;
|
||||
// Number of cylinders
|
||||
int heads;
|
||||
// Number of heads
|
||||
int sectors;
|
||||
// Number of sectors
|
||||
int sectorsize;
|
||||
// Sector size
|
||||
off64_t imgoffset;
|
||||
// Image offset
|
||||
off64_t imgsize;
|
||||
// Image size
|
||||
};
|
421
src/raspberrypi/devices/scsimo.cpp
Normal file
421
src/raspberrypi/devices/scsimo.cpp
Normal file
|
@ -0,0 +1,421 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2014-2020 GIMONS
|
||||
// Copyright (C) akuker
|
||||
//
|
||||
// Licensed under the BSD 3-Clause License.
|
||||
// See LICENSE file in the project root folder.
|
||||
//
|
||||
// [ SCSI Magneto-Optical Disk]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "scsimo.h"
|
||||
#include "xm6.h"
|
||||
#include "fileio.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SCSI magneto-optical disk
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
SCSIMO::SCSIMO() : Disk()
|
||||
{
|
||||
// SCSI magneto-optical disk
|
||||
disk.id = MAKEID('S', 'C', 'M', 'O');
|
||||
|
||||
// Set as removable
|
||||
disk.removable = TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Open
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL SCSIMO::Open(const Filepath& path, BOOL attn)
|
||||
{
|
||||
Fileio fio;
|
||||
off64_t size;
|
||||
|
||||
ASSERT(this);
|
||||
ASSERT(!disk.ready);
|
||||
|
||||
// Open as read-only
|
||||
if (!fio.Open(path, Fileio::ReadOnly)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Get file size
|
||||
size = fio.GetFileSize();
|
||||
fio.Close();
|
||||
|
||||
switch (size) {
|
||||
// 128MB
|
||||
case 0x797f400:
|
||||
disk.size = 9;
|
||||
disk.blocks = 248826;
|
||||
break;
|
||||
|
||||
// 230MB
|
||||
case 0xd9eea00:
|
||||
disk.size = 9;
|
||||
disk.blocks = 446325;
|
||||
break;
|
||||
|
||||
// 540MB
|
||||
case 0x1fc8b800:
|
||||
disk.size = 9;
|
||||
disk.blocks = 1041500;
|
||||
break;
|
||||
|
||||
// 640MB
|
||||
case 0x25e28000:
|
||||
disk.size = 11;
|
||||
disk.blocks = 310352;
|
||||
break;
|
||||
|
||||
// Other (this is an error)
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Call the base class
|
||||
Disk::Open(path);
|
||||
|
||||
// Attention if ready
|
||||
if (disk.ready && attn) {
|
||||
disk.attn = TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifndef RASCSI
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Load
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL SCSIMO::Load(Fileio *fio, int ver)
|
||||
{
|
||||
DWORD sz;
|
||||
disk_t buf;
|
||||
DWORD padding;
|
||||
Filepath path;
|
||||
|
||||
ASSERT(this);
|
||||
ASSERT(fio);
|
||||
ASSERT(ver >= 0x0200);
|
||||
|
||||
// Prior to version 2.03, the disk was not saved
|
||||
if (ver <= 0x0202) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// load size, match
|
||||
if (!fio->Read(&sz, sizeof(sz))) {
|
||||
return FALSE;
|
||||
}
|
||||
if (sz != 52) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// load into buffer
|
||||
PROP_IMPORT(fio, buf.id);
|
||||
PROP_IMPORT(fio, buf.ready);
|
||||
PROP_IMPORT(fio, buf.writep);
|
||||
PROP_IMPORT(fio, buf.readonly);
|
||||
PROP_IMPORT(fio, buf.removable);
|
||||
PROP_IMPORT(fio, buf.lock);
|
||||
PROP_IMPORT(fio, buf.attn);
|
||||
PROP_IMPORT(fio, buf.reset);
|
||||
PROP_IMPORT(fio, buf.size);
|
||||
PROP_IMPORT(fio, buf.blocks);
|
||||
PROP_IMPORT(fio, buf.lun);
|
||||
PROP_IMPORT(fio, buf.code);
|
||||
PROP_IMPORT(fio, padding);
|
||||
|
||||
// Load path
|
||||
if (!path.Load(fio, ver)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Always eject
|
||||
Eject(TRUE);
|
||||
|
||||
// Move only if IDs match
|
||||
if (disk.id != buf.id) {
|
||||
// Not MO at the time of save. Maintain eject status
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Re-try opening
|
||||
if (!Open(path, FALSE)) {
|
||||
// Cannot reopen. Maintain eject status
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Disk cache is created in Open. Move property only
|
||||
if (!disk.readonly) {
|
||||
disk.writep = buf.writep;
|
||||
}
|
||||
disk.lock = buf.lock;
|
||||
disk.attn = buf.attn;
|
||||
disk.reset = buf.reset;
|
||||
disk.lun = buf.lun;
|
||||
disk.code = buf.code;
|
||||
|
||||
// loaded successfully
|
||||
return TRUE;
|
||||
}
|
||||
#endif // RASCSI
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// INQUIRY
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int FASTCALL SCSIMO::Inquiry(
|
||||
const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor)
|
||||
{
|
||||
int size;
|
||||
char rev[32];
|
||||
|
||||
ASSERT(this);
|
||||
ASSERT(cdb);
|
||||
ASSERT(buf);
|
||||
ASSERT(cdb[0] == 0x12);
|
||||
|
||||
// EVPD check
|
||||
if (cdb[1] & 0x01) {
|
||||
disk.code = DISK_INVALIDCDB;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 基本データ
|
||||
// buf[0] ... Optical Memory Device
|
||||
// buf[1] ... Removable
|
||||
// buf[2] ... SCSI-2 compliant command system
|
||||
// buf[3] ... SCSI-2 compliant Inquiry response
|
||||
// buf[4] ... Inquiry additional data
|
||||
memset(buf, 0, 8);
|
||||
buf[0] = 0x07;
|
||||
|
||||
// SCSI-2 p.104 4.4.3 Incorrect logical unit handling
|
||||
if (((cdb[1] >> 5) & 0x07) != disk.lun) {
|
||||
buf[0] = 0x7f;
|
||||
}
|
||||
|
||||
buf[1] = 0x80;
|
||||
buf[2] = 0x02;
|
||||
buf[3] = 0x02;
|
||||
buf[4] = 36 - 5; // required
|
||||
|
||||
// Fill with blanks
|
||||
memset(&buf[8], 0x20, buf[4] - 3);
|
||||
|
||||
// Vendor name
|
||||
memcpy(&buf[8], BENDER_SIGNATURE, strlen(BENDER_SIGNATURE));
|
||||
|
||||
// Product name
|
||||
memcpy(&buf[16], "M2513A", 6);
|
||||
|
||||
// Revision (XM6 version number)
|
||||
sprintf(rev, "0%01d%01d%01d",
|
||||
(int)major, (int)(minor >> 4), (int)(minor & 0x0f));
|
||||
memcpy(&buf[32], rev, 4);
|
||||
|
||||
// Size return data
|
||||
size = (buf[4] + 5);
|
||||
|
||||
// Limit the size if the buffer is too small
|
||||
if (size > (int)cdb[4]) {
|
||||
size = (int)cdb[4];
|
||||
}
|
||||
|
||||
// Success
|
||||
disk.code = DISK_NOERROR;
|
||||
return size;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// MODE SELECT
|
||||
// *Not affected by disk.code
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL FASTCALL SCSIMO::ModeSelect(const DWORD *cdb, const BYTE *buf, int length)
|
||||
{
|
||||
int page;
|
||||
int size;
|
||||
|
||||
ASSERT(this);
|
||||
ASSERT(buf);
|
||||
ASSERT(length >= 0);
|
||||
|
||||
// PF
|
||||
if (cdb[1] & 0x10) {
|
||||
// Mode Parameter header
|
||||
if (length >= 12) {
|
||||
// Check the block length (in bytes)
|
||||
size = 1 << disk.size;
|
||||
if (buf[9] != (BYTE)(size >> 16) ||
|
||||
buf[10] != (BYTE)(size >> 8) || buf[11] != (BYTE)size) {
|
||||
// Currently does not allow changing sector length
|
||||
disk.code = DISK_INVALIDPRM;
|
||||
return FALSE;
|
||||
}
|
||||
buf += 12;
|
||||
length -= 12;
|
||||
}
|
||||
|
||||
// Parsing the page
|
||||
while (length > 0) {
|
||||
// Get the page
|
||||
page = buf[0];
|
||||
|
||||
switch (page) {
|
||||
// format device
|
||||
case 0x03:
|
||||
// Check the number of bytes in the physical sector
|
||||
size = 1 << disk.size;
|
||||
if (buf[0xc] != (BYTE)(size >> 8) ||
|
||||
buf[0xd] != (BYTE)size) {
|
||||
// Currently does not allow changing sector length
|
||||
disk.code = DISK_INVALIDPRM;
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
// vendor unique format
|
||||
case 0x20:
|
||||
// just ignore, for now
|
||||
break;
|
||||
|
||||
// Other page
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Advance to the next page
|
||||
size = buf[1] + 2;
|
||||
length -= size;
|
||||
buf += size;
|
||||
}
|
||||
}
|
||||
|
||||
// Do not generate an error for the time being (MINIX)
|
||||
disk.code = DISK_NOERROR;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Vendor Unique Format Page 20h (MO)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int FASTCALL SCSIMO::AddVendor(int page, BOOL change, BYTE *buf)
|
||||
{
|
||||
ASSERT(this);
|
||||
ASSERT(buf);
|
||||
|
||||
// Page code 20h
|
||||
if ((page != 0x20) && (page != 0x3f)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the message length
|
||||
buf[0] = 0x20;
|
||||
buf[1] = 0x0a;
|
||||
|
||||
// No changeable area
|
||||
if (change) {
|
||||
return 12;
|
||||
}
|
||||
|
||||
/*
|
||||
mode page code 20h - Vendor Unique Format Page
|
||||
format mode XXh type 0
|
||||
information: http://h20628.www2.hp.com/km-ext/kmcsdirect/emr_na-lpg28560-1.pdf
|
||||
|
||||
offset description
|
||||
02h format mode
|
||||
03h type of format (0)
|
||||
04~07h size of user band (total sectors?)
|
||||
08~09h size of spare band (spare sectors?)
|
||||
0A~0Bh number of bands
|
||||
|
||||
actual value of each 3.5inches optical medium (grabbed by Fujitsu M2513EL)
|
||||
|
||||
128M 230M 540M 640M
|
||||
---------------------------------------------------
|
||||
size of user band 3CBFAh 6CF75h FE45Ch 4BC50h
|
||||
size of spare band 0400h 0401h 08CAh 08C4h
|
||||
number of bands 0001h 000Ah 0012h 000Bh
|
||||
|
||||
further information: http://r2089.blog36.fc2.com/blog-entry-177.html
|
||||
*/
|
||||
|
||||
if (disk.ready) {
|
||||
unsigned spare = 0;
|
||||
unsigned bands = 0;
|
||||
|
||||
if (disk.size == 9) switch (disk.blocks) {
|
||||
// 128MB
|
||||
case 248826:
|
||||
spare = 1024;
|
||||
bands = 1;
|
||||
break;
|
||||
|
||||
// 230MB
|
||||
case 446325:
|
||||
spare = 1025;
|
||||
bands = 10;
|
||||
break;
|
||||
|
||||
// 540MB
|
||||
case 1041500:
|
||||
spare = 2250;
|
||||
bands = 18;
|
||||
break;
|
||||
}
|
||||
|
||||
if (disk.size == 11) switch (disk.blocks) {
|
||||
// 640MB
|
||||
case 310352:
|
||||
spare = 2244;
|
||||
bands = 11;
|
||||
break;
|
||||
|
||||
// 1.3GB (lpproj: not tested with real device)
|
||||
case 605846:
|
||||
spare = 4437;
|
||||
bands = 18;
|
||||
break;
|
||||
}
|
||||
|
||||
buf[2] = 0; // format mode
|
||||
buf[3] = 0; // type of format
|
||||
buf[4] = (BYTE)(disk.blocks >> 24);
|
||||
buf[5] = (BYTE)(disk.blocks >> 16);
|
||||
buf[6] = (BYTE)(disk.blocks >> 8);
|
||||
buf[7] = (BYTE)disk.blocks;
|
||||
buf[8] = (BYTE)(spare >> 8);
|
||||
buf[9] = (BYTE)spare;
|
||||
buf[10] = (BYTE)(bands >> 8);
|
||||
buf[11] = (BYTE)bands;
|
||||
}
|
||||
|
||||
return 12;
|
||||
}
|
49
src/raspberrypi/devices/scsimo.h
Normal file
49
src/raspberrypi/devices/scsimo.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI (*^..^*)
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp)
|
||||
// Copyright (C) 2014-2020 GIMONS
|
||||
// Copyright (C) akuker
|
||||
//
|
||||
// Licensed under the BSD 3-Clause License.
|
||||
// See LICENSE file in the project root folder.
|
||||
//
|
||||
// [ SCSI Magneto-Optical Disk]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "os.h"
|
||||
#include "disk.h"
|
||||
#include "filepath.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SCSI magneto-optical disk
|
||||
//
|
||||
//===========================================================================
|
||||
class SCSIMO : public Disk
|
||||
{
|
||||
public:
|
||||
// Basic Functions
|
||||
SCSIMO();
|
||||
// Constructor
|
||||
BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE);
|
||||
// Open
|
||||
#ifndef RASCSI
|
||||
BOOL FASTCALL Load(Fileio *fio, int ver);
|
||||
// Load
|
||||
#endif // RASCSI
|
||||
|
||||
// commands
|
||||
int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor);
|
||||
// INQUIRY command
|
||||
BOOL FASTCALL ModeSelect(const DWORD *cdb, const BYTE *buf, int length);
|
||||
// MODE SELECT(6) command
|
||||
|
||||
// Internal processing
|
||||
int FASTCALL AddVendor(int page, BOOL change, BYTE *buf);
|
||||
// Add vendor special page
|
||||
};
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -11,6 +11,8 @@
|
|||
#if !defined(fileio_h)
|
||||
#define fileio_h
|
||||
|
||||
#include "filepath.h"
|
||||
|
||||
#ifdef BAREMETAL
|
||||
#include "ff.h"
|
||||
#endif // BAREMETAL
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#if !defined(filepath_h)
|
||||
#define filepath_h
|
||||
|
||||
class Fileio;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 定数定義
|
||||
|
|
|
@ -13,9 +13,19 @@
|
|||
#include "xm6.h"
|
||||
#include "filepath.h"
|
||||
#include "fileio.h"
|
||||
#include "disk.h"
|
||||
#include "devices/disk.h"
|
||||
#include "devices/sasihd.h"
|
||||
#include "devices/scsihd.h"
|
||||
#include "devices/scsihd_apple.h"
|
||||
#include "devices/scsihd_nec.h"
|
||||
#include "devices/scsicd.h"
|
||||
#include "devices/scsimo.h"
|
||||
#include "devices/scsi_host_bridge.h"
|
||||
#include "controllers/scsidev_ctrl.h"
|
||||
#include "controllers/sasidev_ctrl.h"
|
||||
#include "gpiobus.h"
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constant declarations
|
||||
|
|
Loading…
Reference in New Issue
Block a user