first commit

This commit is contained in:
Xavier Rey-Robert
2018-05-03 15:47:57 +02:00
commit 35866cfb84
47 changed files with 27164 additions and 0 deletions

51
src/raspberrypi/Makefile Normal file
View File

@@ -0,0 +1,51 @@
CC = gcc
CFLAGS = -DNDEBUG -O3
CXX = g++
CXXFLAGS = -DNDEBUG -O3
RASCSI = rascsi
RASCTL = rasctl
RASDUMP = rasdump
BIN_ALL = $(RASCSI) $(RASCTL) $(RASDUMP)
SRC_RASCSI = \
rascsi.cpp \
scsi.cpp \
disk.cpp \
gpiobus.cpp \
ctapdriver.cpp \
cfilesystem.cpp \
filepath.cpp \
fileio.cpp
SRC_RASCTL = \
rasctl.cpp
SRC_RASDUMP = \
rasdump.cpp \
scsi.cpp \
gpiobus.cpp \
filepath.cpp \
fileio.cpp
OBJ_RASCSI := $(SRC_RASCSI:.cpp=.o)
OBJ_RASCTL := $(SRC_RASCTL:.c=.o)
OBJ_RASDUMP := $(SRC_RASDUMP:.c=.o)
.cpp.o:
$(CXX) $(CXXFLAGS) -c $<
ALL: $(BIN_ALL)
$(RASCSI): $(OBJ_RASCSI) $
$(CXX) -o $@ $(OBJ_RASCSI) -lpthread
$(RASCTL): $(OBJ_RASCTL) $
$(CXX) -o $@ $(OBJ_RASCTL)
$(RASDUMP): $(OBJ_RASDUMP) $
$(CXX) -o $@ $(OBJ_RASDUMP)
clean:
rm -f *.o $(BIN_ALL)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

68
src/raspberrypi/cqueue.h Normal file
View File

@@ -0,0 +1,68 @@
//---------------------------------------------------------------------------
//
// X68000 EMULATOR "XM6"
//
// Copyright (C) 2001-2004 (ytanaka@ipc-tokai.or.jp)
// [ MFC キュー ]
//
//---------------------------------------------------------------------------
#if !defined(queue_h)
#define queue_h
//===========================================================================
//
// キュー
//
//===========================================================================
class CQueue
{
public:
// 内部データ定義
typedef struct _QUQUEINFO {
BYTE *pBuf; // バッファ
DWORD dwSize; // サイズ
DWORD dwMask; // マスク(サイズ-1)
DWORD dwRead; // Readポインタ
DWORD dwWrite; // Writeポインタ
DWORD dwNum; // 個数
DWORD dwTotalRead; // 合計Read
DWORD dwTotalWrite; // 合計Write
} QUEUEINFO, *LPQUEUEINFO;
// 基本ファンクション
CQueue();
// コンストラクタ
virtual ~CQueue();
// デストラクタ
BOOL FASTCALL Init(DWORD dwSize);
// 初期化
// API
void FASTCALL Clear();
// クリア
BOOL FASTCALL IsEmpty() const { return (BOOL)(m_Queue.dwNum == 0); }
// キューが空かチェック
DWORD FASTCALL GetNum() const { return m_Queue.dwNum; }
// キューのデータ数を取得
DWORD FASTCALL Get(BYTE *pDest);
// キュー内のデータをすべて取得
DWORD FASTCALL Copy(BYTE *pDest) const;
// キュー内のデータをすべて取得(キュー進めない)
void FASTCALL Discard(DWORD dwNum);
// キューを進める
void FASTCALL Back(DWORD dwNum);
// キューを戻す
DWORD FASTCALL GetFree() const;
// キューの空き個数を取得
BOOL FASTCALL Insert(const BYTE *pSrc, DWORD dwLength);
// キューに挿入
void FASTCALL GetQueue(QUEUEINFO *pInfo) const;
// キュー情報取得
private:
QUEUEINFO m_Queue;
// 内部ワーク
};
#endif // queue_h

View File

@@ -0,0 +1,209 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI (*^..^*)
// for Raspberry Pi
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2018 GIMONS
//
// Imported NetBSD support and some optimisation patch by Rin Okuyama.
//
// [ TAPドライバ ]
//
//---------------------------------------------------------------------------
#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);
}

View File

@@ -0,0 +1,53 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI (*^..^*)
// for Raspberry Pi
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2018 GIMONS
//
// Imported NetBSD support and some optimisation patch by Rin Okuyama.
//
// [ TAPドライバ ]
//
//---------------------------------------------------------------------------
#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

9160
src/raspberrypi/disk.cpp Normal file

File diff suppressed because it is too large Load Diff

1108
src/raspberrypi/disk.h Normal file

File diff suppressed because it is too large Load Diff

367
src/raspberrypi/fileio.cpp Normal file
View File

@@ -0,0 +1,367 @@
//---------------------------------------------------------------------------
//
// X68000 EMULATOR "XM6"
//
// Copyright (C) 2001-2006 (ytanaka@ipc-tokai.or.jp)
// Copyright (C) 2010-2018 GIMONS
// [ ファイルI/O(RaSCSI用サブセット) ]
//
//---------------------------------------------------------------------------
#include "os.h"
#include "xm6.h"
#include "filepath.h"
#include "fileio.h"
//===========================================================================
//
// ファイルI/O
//
//===========================================================================
//---------------------------------------------------------------------------
//
// コンストラクタ
//
//---------------------------------------------------------------------------
Fileio::Fileio()
{
// ワーク初期化
handle = -1;
}
//---------------------------------------------------------------------------
//
// デストラクタ
//
//---------------------------------------------------------------------------
Fileio::~Fileio()
{
ASSERT(handle == -1);
// Releaseでの安全策
Close();
}
//---------------------------------------------------------------------------
//
// ロード
//
//---------------------------------------------------------------------------
BOOL FASTCALL Fileio::Load(const Filepath& path, void *buffer, int size)
{
ASSERT(this);
ASSERT(buffer);
ASSERT(size > 0);
ASSERT(handle < 0);
// オープン
if (!Open(path, ReadOnly)) {
return FALSE;
}
// 読み込み
if (!Read(buffer, size)) {
Close();
return FALSE;
}
// クローズ
Close();
return TRUE;
}
//---------------------------------------------------------------------------
//
// セーブ
//
//---------------------------------------------------------------------------
BOOL FASTCALL Fileio::Save(const Filepath& path, void *buffer, int size)
{
ASSERT(this);
ASSERT(buffer);
ASSERT(size > 0);
ASSERT(handle < 0);
// オープン
if (!Open(path, WriteOnly)) {
return FALSE;
}
// 読み込み
if (!Write(buffer, size)) {
Close();
return FALSE;
}
// クローズ
Close();
return TRUE;
}
//---------------------------------------------------------------------------
//
// オープン
//
//---------------------------------------------------------------------------
BOOL FASTCALL Fileio::Open(LPCTSTR fname, OpenMode mode)
{
ASSERT(this);
ASSERT(fname);
ASSERT(handle < 0);
// ヌル文字列からの読み込みは必ず失敗させる
if (fname[0] == _T('\0')) {
handle = -1;
return FALSE;
}
// モード別
switch (mode) {
// 読み込みのみ
case ReadOnly:
handle = open(fname, O_RDONLY);
break;
// 書き込みのみ
case WriteOnly:
handle = open(fname, O_CREAT | O_WRONLY | O_TRUNC, 0666);
break;
// 読み書き両方
case ReadWrite:
// CD-ROMからの読み込みはRWが成功してしまう
if (access(fname, 0x06) != 0) {
return FALSE;
}
handle = open(fname, O_RDWR);
break;
// アペンド
case Append:
handle = open(fname, O_CREAT | O_WRONLY | O_APPEND, 0666);
break;
// それ以外
default:
ASSERT(FALSE);
break;
}
// 結果評価
if (handle == -1) {
return FALSE;
}
ASSERT(handle >= 0);
return TRUE;
}
//---------------------------------------------------------------------------
//
// オープン
//
//---------------------------------------------------------------------------
BOOL FASTCALL Fileio::OpenDIO(LPCTSTR fname, OpenMode mode)
{
ASSERT(this);
ASSERT(fname);
ASSERT(handle < 0);
// ヌル文字列からの読み込みは必ず失敗させる
if (fname[0] == _T('\0')) {
handle = -1;
return FALSE;
}
// モード別
switch (mode) {
// 読み込みのみ
case ReadOnly:
handle = open(fname, O_RDONLY | O_DIRECT);
break;
// 書き込みのみ
case WriteOnly:
handle = open(fname, O_CREAT | O_WRONLY | O_TRUNC | O_DIRECT, 0666);
break;
// 読み書き両方
case ReadWrite:
// CD-ROMからの読み込みはRWが成功してしまう
if (access(fname, 0x06) != 0) {
return FALSE;
}
handle = open(fname, O_RDWR | O_DIRECT);
break;
// アペンド
case Append:
handle = open(fname, O_CREAT | O_WRONLY | O_APPEND | O_DIRECT, 0666);
break;
// それ以外
default:
ASSERT(FALSE);
break;
}
// 結果評価
if (handle == -1) {
return FALSE;
}
ASSERT(handle >= 0);
return TRUE;
}
//---------------------------------------------------------------------------
//
// オープン
//
//---------------------------------------------------------------------------
BOOL FASTCALL Fileio::Open(const Filepath& path, OpenMode mode)
{
ASSERT(this);
return Open(path.GetPath(), mode);
}
//---------------------------------------------------------------------------
//
// オープン
//
//---------------------------------------------------------------------------
BOOL FASTCALL Fileio::OpenDIO(const Filepath& path, OpenMode mode)
{
ASSERT(this);
return OpenDIO(path.GetPath(), mode);
}
//---------------------------------------------------------------------------
//
// 読み込み
//
//---------------------------------------------------------------------------
BOOL FASTCALL Fileio::Read(void *buffer, int size)
{
int count;
ASSERT(this);
ASSERT(buffer);
ASSERT(size > 0);
ASSERT(handle >= 0);
// 読み込み
count = read(handle, buffer, size);
if (count != size) {
return FALSE;
}
return TRUE;
}
//---------------------------------------------------------------------------
//
// 書き込み
//
//---------------------------------------------------------------------------
BOOL FASTCALL Fileio::Write(const void *buffer, int size)
{
int count;
ASSERT(this);
ASSERT(buffer);
ASSERT(size > 0);
ASSERT(handle >= 0);
// 読み込み
count = write(handle, buffer, size);
if (count != size) {
return FALSE;
}
return TRUE;
}
//---------------------------------------------------------------------------
//
// シーク
//
//---------------------------------------------------------------------------
BOOL FASTCALL Fileio::Seek(off64_t offset, BOOL relative)
{
ASSERT(this);
ASSERT(handle >= 0);
ASSERT(offset >= 0);
// 相対シークならオフセットに現在値を追加
if (relative) {
offset += GetFilePos();
}
if (lseek(handle, offset, SEEK_SET) != offset) {
return FALSE;
}
return TRUE;
}
//---------------------------------------------------------------------------
//
// ファイルサイズ取得
//
//---------------------------------------------------------------------------
off64_t FASTCALL Fileio::GetFileSize()
{
off64_t cur;
off64_t end;
ASSERT(this);
ASSERT(handle >= 0);
// ファイル位置を64bitで取得
cur = GetFilePos();
// ファイルサイズを64bitで取得
end = lseek(handle, 0, SEEK_END);
// 位置を元に戻す
Seek(cur);
return end;
}
//---------------------------------------------------------------------------
//
// ファイル位置取得
//
//---------------------------------------------------------------------------
off64_t FASTCALL Fileio::GetFilePos() const
{
off64_t pos;
ASSERT(this);
ASSERT(handle >= 0);
// ファイル位置を64bitで取得
pos = lseek(handle, 0, SEEK_CUR);
return pos;
}
//---------------------------------------------------------------------------
//
// クローズ
//
//---------------------------------------------------------------------------
void FASTCALL Fileio::Close()
{
ASSERT(this);
if (handle != -1) {
close(handle);
handle = -1;
}
}

83
src/raspberrypi/fileio.h Normal file
View File

@@ -0,0 +1,83 @@
//---------------------------------------------------------------------------
//
// X68000 EMULATOR "XM6"
//
// Copyright (C) 2001-2005 (ytanaka@ipc-tokai.or.jp)
// Copyright (C) 2013-2018 GIMONS
// [ ファイルI/O(RaSCSI用サブセット) ]
//
//---------------------------------------------------------------------------
#if !defined(fileio_h)
#define fileio_h
//===========================================================================
//
// マクロ(Load,Save用)
//
//===========================================================================
#define PROP_IMPORT(f, p) \
if (!f->Read(&(p), sizeof(p))) {\
return FALSE;\
}\
#define PROP_EXPORT(f, p) \
if (!f->Write(&(p), sizeof(p))) {\
return FALSE;\
}\
//===========================================================================
//
// ファイルI/O
//
//===========================================================================
class Fileio
{
public:
enum OpenMode {
ReadOnly, // 読み込みのみ
WriteOnly, // 書き込みのみ
ReadWrite, // 読み書き両方
Append // アペンド
};
public:
Fileio();
// コンストラクタ
virtual ~Fileio();
// デストラクタ
BOOL FASTCALL Load(const Filepath& path, void *buffer, int size);
// ROM,RAMロード
BOOL FASTCALL Save(const Filepath& path, void *buffer, int size);
// RAMセーブ
BOOL FASTCALL Open(LPCTSTR fname, OpenMode mode);
// オープン
BOOL FASTCALL OpenDIO(LPCTSTR fname, OpenMode mode);
// オープン
BOOL FASTCALL Open(const Filepath& path, OpenMode mode);
// オープン
BOOL FASTCALL OpenDIO(const Filepath& path, OpenMode mode);
// オープン
BOOL FASTCALL Seek(off64_t offset, BOOL relative = FALSE);
// シーク
BOOL FASTCALL Read(void *buffer, int size);
// 読み込み
BOOL FASTCALL Write(const void *buffer, int size);
// 書き込み
off64_t FASTCALL GetFileSize();
// ファイルサイズ取得
off64_t FASTCALL GetFilePos() const;
// ファイル位置取得
void FASTCALL Close();
// クローズ
BOOL FASTCALL IsValid() const { return (BOOL)(handle != -1); }
// 有効チェック
int FASTCALL GetHandle() const { return handle; }
// ハンドル取得
private:
int handle; // ファイルハンドル
};
#endif // fileio_h

View File

@@ -0,0 +1,273 @@
//---------------------------------------------------------------------------
//
// X68000 EMULATOR "XM6"
//
// Copyright (C) 2001-2006 (ytanaka@ipc-tokai.or.jp)
// Copyright (C) 2012-2018 GIMONS
// [ ファイルパス(サブセット) ]
//
//---------------------------------------------------------------------------
#include "os.h"
#include "xm6.h"
#include "filepath.h"
#include "fileio.h"
//===========================================================================
//
// ファイルパス
//
//===========================================================================
//---------------------------------------------------------------------------
//
// コンストラクタ
//
//---------------------------------------------------------------------------
Filepath::Filepath()
{
// クリア
Clear();
}
//---------------------------------------------------------------------------
//
// デストラクタ
//
//---------------------------------------------------------------------------
Filepath::~Filepath()
{
}
//---------------------------------------------------------------------------
//
// 代入演算子
//
//---------------------------------------------------------------------------
Filepath& Filepath::operator=(const Filepath& path)
{
// パス設定(内部でSplitされる)
SetPath(path.GetPath());
return *this;
}
//---------------------------------------------------------------------------
//
// クリア
//
//---------------------------------------------------------------------------
void FASTCALL Filepath::Clear()
{
ASSERT(this);
// パスおよび各部分をクリア
m_szPath[0] = _T('\0');
m_szDir[0] = _T('\0');
m_szFile[0] = _T('\0');
m_szExt[0] = _T('\0');
}
//---------------------------------------------------------------------------
//
// ファイル設定(ユーザ) MBCS用
//
//---------------------------------------------------------------------------
void FASTCALL Filepath::SetPath(LPCSTR path)
{
ASSERT(this);
ASSERT(path);
ASSERT(strlen(path) < _MAX_PATH);
// パス名コピー
strcpy(m_szPath, (LPTSTR)path);
// 分離
Split();
}
//---------------------------------------------------------------------------
//
// パス分離
//
//---------------------------------------------------------------------------
void FASTCALL Filepath::Split()
{
LPTSTR pDir;
LPTSTR pDirName;
LPTSTR pBase;
LPTSTR pBaseName;
LPTSTR pExtName;
ASSERT(this);
// パーツを初期化
m_szDir[0] = _T('\0');
m_szFile[0] = _T('\0');
m_szExt[0] = _T('\0');
// 分離
pDir = strdup(m_szPath);
pDirName = dirname(pDir);
pBase = strdup(m_szPath);
pBaseName = basename(pBase);
pExtName = strrchr(pBaseName, '.');
// 転送
if (pDirName) {
strcpy(m_szDir, pDirName);
strcat(m_szDir, "/");
}
if (pExtName) {
strcpy(m_szExt, pExtName);
*pExtName = 0;
}
if (pBaseName) {
strcpy(m_szFile, pBaseName);
}
// 解放
free(pDir);
free(pBase);
}
//---------------------------------------------------------------------------
//
// パス合成
//
//---------------------------------------------------------------------------
void FASTCALL Filepath::Make()
{
ASSERT(this);
// パス初期化
m_szPath[0] = _T('\0');
// 合成
strcat(m_szPath, m_szDir);
strcat(m_szPath, m_szFile);
strcat(m_szPath, m_szExt);
}
//---------------------------------------------------------------------------
//
// クリアされているか
//
//---------------------------------------------------------------------------
BOOL FASTCALL Filepath::IsClear() const
{
// Clear()の逆
if ((m_szPath[0] == _T('\0')) &&
(m_szDir[0] == _T('\0')) &&
(m_szFile[0] == _T('\0')) &&
(m_szExt[0] == _T('\0'))) {
// 確かに、クリアされている
return TRUE;
}
// クリアされていない
return FALSE;
}
//---------------------------------------------------------------------------
//
// ショート名取得
// ※返されるポインタは一時的なもの。すぐコピーすること
// ※FDIDiskのdisk.nameとの関係で、文字列は最大59文字+終端とすること
//
//---------------------------------------------------------------------------
const char* FASTCALL Filepath::GetShort() const
{
char szFile[_MAX_FNAME];
char szExt[_MAX_EXT];
ASSERT(this);
// TCHAR文字列からchar文字列へ変換
strcpy(szFile, m_szFile);
strcpy(szExt, m_szExt);
// 固定バッファへ合成
strcpy(ShortName, szFile);
strcat(ShortName, szExt);
// strlenで調べたとき、最大59になるように細工
ShortName[59] = '\0';
// const charとして返す
return (const char*)ShortName;
}
//---------------------------------------------------------------------------
//
// ファイル名+拡張子取得
// ※返されるポインタは一時的なもの。すぐコピーすること
//
//---------------------------------------------------------------------------
LPCTSTR FASTCALL Filepath::GetFileExt() const
{
ASSERT(this);
// 固定バッファへ合成
strcpy(FileExt, m_szExt);
// LPCTSTRとして返す
return (LPCTSTR)FileExt;
}
//---------------------------------------------------------------------------
//
// パス比較
//
//---------------------------------------------------------------------------
BOOL FASTCALL Filepath::CmpPath(const Filepath& path) const
{
// パスが完全一致していればTRUE
if (strcmp(path.GetPath(), GetPath()) == 0) {
return TRUE;
}
return FALSE;
}
//---------------------------------------------------------------------------
//
// セーブ
//
//---------------------------------------------------------------------------
BOOL FASTCALL Filepath::Save(Fileio *fio, int /*ver*/)
{
ASSERT(this);
ASSERT(fio);
return TRUE;
}
//---------------------------------------------------------------------------
//
// ロード
//
//---------------------------------------------------------------------------
BOOL FASTCALL Filepath::Load(Fileio *fio, int /*ver*/)
{
ASSERT(this);
ASSERT(fio);
return TRUE;
}
//---------------------------------------------------------------------------
//
// ショート名
//
//---------------------------------------------------------------------------
char Filepath::ShortName[_MAX_FNAME + _MAX_DIR];
//---------------------------------------------------------------------------
//
// ファイル名+拡張子
//
//---------------------------------------------------------------------------
TCHAR Filepath::FileExt[_MAX_FNAME + _MAX_DIR];

View File

@@ -0,0 +1,81 @@
//---------------------------------------------------------------------------
//
// X68000 EMULATOR "XM6"
//
// Copyright (C) 2001-2006 (ytanaka@ipc-tokai.or.jp)
// Copyright (C) 2012-2018 GIMONS
// [ ファイルパス(サブセット) ]
//
//---------------------------------------------------------------------------
#if !defined(filepath_h)
#define filepath_h
//---------------------------------------------------------------------------
//
// 定数定義
//
//---------------------------------------------------------------------------
#define FILEPATH_MAX _MAX_PATH
//===========================================================================
//
// ファイルパス
// ※代入演算子を用意すること
//
//===========================================================================
class Filepath
{
public:
Filepath();
// コンストラクタ
virtual ~Filepath();
// デストラクタ
Filepath& operator=(const Filepath& path);
// 代入
void FASTCALL Clear();
// クリア
void FASTCALL SetPath(LPCSTR path);
// ファイル設定(ユーザ) MBCS用
BOOL FASTCALL IsClear() const;
// クリアされているか
LPCTSTR FASTCALL GetPath() const { return m_szPath; }
// パス名取得
const char* FASTCALL GetShort() const;
// ショート名取得(const char*)
LPCTSTR FASTCALL GetFileExt() const;
// ショート名取得(LPCTSTR)
BOOL FASTCALL CmpPath(const Filepath& path) const;
// パス比較
BOOL FASTCALL Save(Fileio *fio, int ver);
// セーブ
BOOL FASTCALL Load(Fileio *fio, int ver);
// ロード
private:
void FASTCALL Split();
// パス分割
void FASTCALL Make();
// パス合成
void FASTCALL SetCurDir();
// カレントディレクトリ設定
TCHAR m_szPath[_MAX_PATH];
// ファイルパス
TCHAR m_szDrive[_MAX_DRIVE];
// ドライブ
TCHAR m_szDir[_MAX_DIR];
// ディレクトリ
TCHAR m_szFile[_MAX_FNAME];
// ファイル
TCHAR m_szExt[_MAX_EXT];
// 拡張子
static char ShortName[_MAX_FNAME + _MAX_DIR];
// ショート名(char)
static TCHAR FileExt[_MAX_FNAME + _MAX_DIR];
// ショート名(TCHAR)
};
#endif // filepath_h

1192
src/raspberrypi/gpiobus.cpp Normal file

File diff suppressed because it is too large Load Diff

479
src/raspberrypi/gpiobus.h Normal file
View File

@@ -0,0 +1,479 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI (*^..^*)
// for Raspberry Pi
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2018 GIMONS
// [ GPIO-SCSIバス ]
//
//---------------------------------------------------------------------------
#if !defined(gpiobus_h)
#define gpiobus_h
#include "scsi.h"
//---------------------------------------------------------------------------
//
// 接続方法定義の選択
//
//---------------------------------------------------------------------------
#define CONNECT_TYPE_STANDARD // 標準(SCSI論理,標準ピンアサイン)
//#define CONNECT_TYPE_FULLSPEC // フルスペック(SCSI論理,標準ピンアサイン)
//#define CONNECT_TYPE_AIBOM // AIBOM版(正論理,固有ピンアサイン)
//#define CONNECT_TYPE_GAMERNIUM // GAMERnium.com版(標準論理,固有ピンアサイン)
//---------------------------------------------------------------------------
//
// 信号制御論理及びピンアサインカスタマイズ
//
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
// SIGNAL_CONTROL_MODE:信号制御モード選択
// Version1.22から信号制御の論理をカスタマイズできます。
//
// 0:SCSI論理仕様
// 直結またはHPに公開した74LS641-1等を使用する変換基板
// アーサート:0V
// ネゲート :オープンコレクタ出力(バスから切り離す)
//
// 1:負論理仕様(負論理->SCSI論理への変換基板を使用する場合)
// 現時点でこの仕様による変換基板は存在しません
// アーサート:0V -> (CONVERT) -> 0V
// ネゲート :3.3V -> (CONVERT) -> オープンコレクタ出力
//
// 2:正論理仕様(正論理->SCSI論理への変換基板を使用する場合)
// RaSCSI Adapter Rev.C @132sync等
//
// アーサート:3.3V -> (CONVERT) -> 0V
// ネゲート :0V -> (CONVERT) -> オープンコレクタ出力
//
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
// 制御信号ピンアサイン設定
// 制御信号に対するGPIOピンのマッピングテーブルです。
//
// 制御信号
// PIN_ACT
// SCSIコマンドを処理中の状態を示す信号のピン番号。
// PIN_ENB
// 起動から終了の間の有効信号を示す信号のピン番号。
// PIN_TAD
// ターゲット信号(BSY,IO,CD,MSG,REG)の入出力方向を示す信号のピン番号。
// PIN_IND
// イニシーエータ信号(SEL,ATN,RST,ACK)の入出力方向を示す信号のピン番号。
// PIN_DTD
// データ信号(DT0...DT7,DP)の入出力方向を示す信号のピン番号。
//
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
// 制御信号出力論理
// 0V:FALSE 3.3V:TRUEで指定します。
//
// ACT_ON
// PIN_ACT信号の論理です。
// ENB_ON
// PIN_ENB信号の論理です。
// TAD_IN
// PIN_TAD入力方向時の論理です。
// IND_IN
// PIN_ENB入力方向時の論理です。
// DTD_IN
// PIN_ENB入力方向時の論理です。
//
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
// SCSI信号ピンアサイン設定
// SCSIの信号に対するGPIOピンのマッピングテーブルです。
// PIN_DT0PIN_SEL
//
//---------------------------------------------------------------------------
#ifdef CONNECT_TYPE_STANDARD
//
// RaSCSI 標準(SCSI論理,標準ピンアサイン)
//
#define CONNECT_DESC "STANDARD" // 起動時メッセージ
// 信号制御モード選択
#define SIGNAL_CONTROL_MODE 0 // SCSI論理仕様
// 制御信号ピンアサイン(-1の場合は制御無し)
#define PIN_ACT 4 // ACTIVE
#define PIN_ENB 5 // ENABLE
#define PIN_IND -1 // INITIATOR CTRL DIRECTION
#define PIN_TAD -1 // TARGET CTRL DIRECTION
#define PIN_DTD -1 // DATA DIRECTION
// 制御信号出力論理
#define ACT_ON TRUE // ACTIVE SIGNAL ON
#define ENB_ON TRUE // ENABLE SIGNAL ON
#define IND_IN FALSE // INITIATOR SIGNAL INPUT
#define TAD_IN FALSE // TARGET SIGNAL INPUT
#define DTD_IN TRUE // DATA SIGNAL INPUT
// SCSI信号ピンアサイン
#define PIN_DT0 10 // データ0
#define PIN_DT1 11 // データ1
#define PIN_DT2 12 // データ2
#define PIN_DT3 13 // データ3
#define PIN_DT4 14 // データ4
#define PIN_DT5 15 // データ5
#define PIN_DT6 16 // データ6
#define PIN_DT7 17 // データ7
#define PIN_DP 18 // パリティ
#define PIN_ATN 19 // ATN
#define PIN_RST 20 // RST
#define PIN_ACK 21 // ACK
#define PIN_REQ 22 // REQ
#define PIN_MSG 23 // MSG
#define PIN_CD 24 // CD
#define PIN_IO 25 // IO
#define PIN_BSY 26 // BSY
#define PIN_SEL 27 // SEL
#endif
#ifdef CONNECT_TYPE_FULLSPEC
//
// RaSCSI 標準(SCSI論理,標準ピンアサイン)
//
#define CONNECT_DESC "FULLSPEC" // 起動時メッセージ
// 信号制御モード選択
#define SIGNAL_CONTROL_MODE 0 // SCSI論理仕様
// 制御信号ピンアサイン(-1の場合は制御無し)
#define PIN_ACT 4 // ACTIVE
#define PIN_ENB 5 // ENABLE
#define PIN_IND 6 // INITIATOR CTRL DIRECTION
#define PIN_TAD 7 // TARGET CTRL DIRECTION
#define PIN_DTD 8 // DATA DIRECTION
// 制御信号出力論理
#define ACT_ON TRUE // ACTIVE SIGNAL ON
#define ENB_ON TRUE // ENABLE SIGNAL ON
#define IND_IN FALSE // INITIATOR SIGNAL INPUT
#define TAD_IN FALSE // TARGET SIGNAL INPUT
#define DTD_IN TRUE // DATA SIGNAL INPUT
// SCSI信号ピンアサイン
#define PIN_DT0 10 // データ0
#define PIN_DT1 11 // データ1
#define PIN_DT2 12 // データ2
#define PIN_DT3 13 // データ3
#define PIN_DT4 14 // データ4
#define PIN_DT5 15 // データ5
#define PIN_DT6 16 // データ6
#define PIN_DT7 17 // データ7
#define PIN_DP 18 // パリティ
#define PIN_ATN 19 // ATN
#define PIN_RST 20 // RST
#define PIN_ACK 21 // ACK
#define PIN_REQ 22 // REQ
#define PIN_MSG 23 // MSG
#define PIN_CD 24 // CD
#define PIN_IO 25 // IO
#define PIN_BSY 26 // BSY
#define PIN_SEL 27 // SEL
#endif
#ifdef CONNECT_TYPE_AIBOM
//
// RaSCSI Adapter あいぼむ版
//
#define CONNECT_DESC "AIBOM PRODUCTS version" // 起動時メッセージ
// 信号制御モード選択
#define SIGNAL_CONTROL_MODE 2 // SCSI正論理仕様
// 制御信号出力論理
#define ACT_ON TRUE // ACTIVE SIGNAL ON
#define ENB_ON TRUE // ENABLE SIGNAL ON
#define IND_IN FALSE // INITIATOR SIGNAL INPUT
#define TAD_IN FALSE // TARGET SIGNAL INPUT
#define DTD_IN FALSE // DATA SIGNAL INPUT
// 制御信号ピンアサイン(-1の場合は制御無し)
#define PIN_ACT 4 // ACTIVE
#define PIN_ENB 17 // ENABLE
#define PIN_IND 27 // INITIATOR CTRL DIRECTION
#define PIN_TAD -1 // TARGET CTRL DIRECTION
#define PIN_DTD 18 // DATA DIRECTION
// SCSI信号ピンアサイン
#define PIN_DT0 6 // データ0
#define PIN_DT1 12 // データ1
#define PIN_DT2 13 // データ2
#define PIN_DT3 16 // データ3
#define PIN_DT4 19 // データ4
#define PIN_DT5 20 // データ5
#define PIN_DT6 26 // データ6
#define PIN_DT7 21 // データ7
#define PIN_DP 5 // パリティ
#define PIN_ATN 22 // ATN
#define PIN_RST 25 // RST
#define PIN_ACK 10 // ACK
#define PIN_REQ 7 // REQ
#define PIN_MSG 9 // MSG
#define PIN_CD 11 // CD
#define PIN_IO 23 // IO
#define PIN_BSY 24 // BSY
#define PIN_SEL 8 // SEL
#endif
#ifdef CONNECT_TYPE_GAMERNIUM
//
// RaSCSI Adapter GAMERnium.com版
//
#define CONNECT_DESC "GAMERnium.com version"// 起動時メッセージ
// 信号制御モード選択
#define SIGNAL_CONTROL_MODE 0 // SCSI論理仕様
// 制御信号出力論理
#define ACT_ON TRUE // ACTIVE SIGNAL ON
#define ENB_ON TRUE // ENABLE SIGNAL ON
#define IND_IN FALSE // INITIATOR SIGNAL INPUT
#define TAD_IN FALSE // TARGET SIGNAL INPUT
#define DTD_IN TRUE // DATA SIGNAL INPUT
// 制御信号ピンアサイン(-1の場合は制御無し)
#define PIN_ACT 14 // ACTIVE
#define PIN_ENB 6 // ENABLE
#define PIN_IND 7 // INITIATOR CTRL DIRECTION
#define PIN_TAD 8 // TARGET CTRL DIRECTION
#define PIN_DTD 5 // DATA DIRECTION
// SCSI信号ピンアサイン
#define PIN_DT0 21 // データ0
#define PIN_DT1 26 // データ1
#define PIN_DT2 20 // データ2
#define PIN_DT3 19 // データ3
#define PIN_DT4 16 // データ4
#define PIN_DT5 13 // データ5
#define PIN_DT6 12 // データ6
#define PIN_DT7 11 // データ7
#define PIN_DP 25 // パリティ
#define PIN_ATN 10 // ATN
#define PIN_RST 22 // RST
#define PIN_ACK 24 // ACK
#define PIN_REQ 15 // REQ
#define PIN_MSG 17 // MSG
#define PIN_CD 18 // CD
#define PIN_IO 4 // IO
#define PIN_BSY 27 // BSY
#define PIN_SEL 23 // SEL
#endif
//---------------------------------------------------------------------------
//
// 定数宣言(GPIO)
//
//---------------------------------------------------------------------------
#define GPIO_OFFSET 0x200000
#define PADS_OFFSET 0x100000
#define GPIO_INPUT 0
#define GPIO_OUTPUT 1
#define GPIO_PULLNONE 0
#define GPIO_PULLDOWN 1
#define GPIO_PULLUP 2
#define GPIO_FSEL_0 0
#define GPIO_FSEL_1 1
#define GPIO_FSEL_2 2
#define GPIO_FSEL_3 3
#define GPIO_SET_0 7
#define GPIO_CLR_0 10
#define GPIO_LEV_0 13
#define GPIO_EDS_0 16
#define GPIO_REN_0 19
#define GPIO_FEN_0 22
#define GPIO_HEN_0 25
#define GPIO_LEN_0 28
#define GPIO_AREN_0 31
#define GPIO_AFEN_0 34
#define GPIO_PUD 37
#define GPIO_CLK_0 38
#define PAD_0_27 11
#define GPIO_INEDGE ((1 << PIN_BSY) | \
(1 << PIN_SEL) | \
(1 << PIN_ATN) | \
(1 << PIN_ACK) | \
(1 << PIN_RST))
#define GPIO_MCI ((1 << PIN_MSG) | \
(1 << PIN_CD) | \
(1 << PIN_IO))
//---------------------------------------------------------------------------
//
// 定数宣言(制御信号)
//
//---------------------------------------------------------------------------
#define ACT_OFF !ACT_ON
#define ENB_OFF !ENB_ON
#define TAD_OUT !TAD_IN
#define IND_OUT !IND_IN
#define DTD_OUT !DTD_IN
//---------------------------------------------------------------------------
//
// 定数宣言(SCSI)
//
//---------------------------------------------------------------------------
#define IN GPIO_INPUT
#define OUT GPIO_OUTPUT
#define ON TRUE
#define OFF FALSE
//---------------------------------------------------------------------------
//
// 定数宣言(ドライバ)
//
//---------------------------------------------------------------------------
#define DEVICE_NAME "rascsidrv"
#define DRIVER_PATH "/dev/" DEVICE_NAME
#define IOCTL_INIT 0x100
#define IOCTL_MODE 0x101
#define IOCTL_PADS 0x102
//---------------------------------------------------------------------------
//
// クラス定義
//
//---------------------------------------------------------------------------
class GPIOBUS : public BUS
{
public:
// 基本ファンクション
GPIOBUS();
// コンストラクタ
virtual ~GPIOBUS();
// デストラクタ
BOOL FASTCALL Init(mode_e mode = TARGET);
// 初期化
void FASTCALL Reset();
// リセット
void FASTCALL Cleanup();
// クリーンアップ
DWORD FASTCALL Aquire();
// 信号取り込み
BOOL FASTCALL GetBSY();
// BSYシグナル取得
void FASTCALL SetBSY(BOOL ast);
// BSYシグナル設定
BOOL FASTCALL GetSEL();
// SELシグナル取得
void FASTCALL SetSEL(BOOL ast);
// SELシグナル設定
BOOL FASTCALL GetATN();
// ATNシグナル取得
void FASTCALL SetATN(BOOL ast);
// ATNシグナル設定
BOOL FASTCALL GetACK();
// ACKシグナル取得
void FASTCALL SetACK(BOOL ast);
// ACKシグナル設定
BOOL FASTCALL GetRST();
// RSTシグナル取得
void FASTCALL SetRST(BOOL ast);
// RSTシグナル設定
BOOL FASTCALL GetMSG();
// MSGシグナル取得
void FASTCALL SetMSG(BOOL ast);
// MSGシグナル設定
BOOL FASTCALL GetCD();
// CDシグナル取得
void FASTCALL SetCD(BOOL ast);
// CDシグナル設定
BOOL FASTCALL GetIO();
// IOシグナル取得
void FASTCALL SetIO(BOOL ast);
// IOシグナル設定
BOOL FASTCALL GetREQ();
// REQシグナル取得
void FASTCALL SetREQ(BOOL ast);
// REQシグナル設定
BYTE FASTCALL GetDAT();
// データシグナル取得
void FASTCALL SetDAT(BYTE dat);
// データシグナル設定
int FASTCALL ReceiveHandShake(BYTE *buf, int count);
// データ受信ハンドシェイク
int FASTCALL SendHandShake(BYTE *buf, int count);
// データ送信ハンドシェイク
// タイマ関係
void FASTCALL SleepNsec(DWORD nsec);
// ナノ秒単位のスリープ
private:
void FASTCALL DrvConfig(DWORD drive);
// GPIOドライブ能力設定
void FASTCALL PinConfig(int pin, int mode);
// GPIOピン機能設定(入出力設定)
void FASTCALL PullConfig(int pin, int mode);
// GPIOピン機能設定(プルアップ/ダウン)
void FASTCALL PinSetSignal(int pin, BOOL ast);
// GPIOピン出力信号設定
void FASTCALL MakeTable();
// ワークテーブル作成
void FASTCALL SetControl(int pin, BOOL ast);
// 制御信号設定
void FASTCALL SetMode(int pin, int mode);
// SCSI入出力モード設定
BOOL FASTCALL GetSignal(int pin);
// SCSI入力信号値取得
void FASTCALL SetSignal(int pin, BOOL ast);
// SCSI出力信号値設定
mode_e actmode; // 動作モード
volatile DWORD *gpio; // GPIOレジスタ
volatile DWORD *pads; // PADSレジスタ
volatile DWORD *level; // GPIO入力レベル
DWORD gpfsel[4]; // GPFSEL0-4バックアップ
DWORD signals; // バス全信号
#if SIGNAL_CONTROL_MODE == 0
DWORD tblDatMsk[3][256]; // データマスク用テーブル
DWORD tblDatSet[3][256]; // データ設定用テーブル
#else
DWORD tblDatMsk[256]; // データマスク用テーブル
DWORD tblDatSet[256]; // データ設定用テーブル
#endif
int drvfd; // カーネルドライバファイルディスクプリタ
static const int SignalTable[19]; // シグナルテーブル
};
#endif // gpiobus_h

View File

@@ -0,0 +1,9 @@
KERNEL_HEADERS=/lib/modules/$(shell uname -r)/build
obj-m := rascsidrv.o
ccflags-y := -O3
all:
$(MAKE) -C $(KERNEL_HEADERS) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNEL_HEADERS) M=$(PWD) clean

File diff suppressed because it is too large Load Diff

31
src/raspberrypi/log.h Normal file
View File

@@ -0,0 +1,31 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI (*^..^*)
// for Raspberry Pi
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2018 GIMONS
// [ ログ ]
//
//---------------------------------------------------------------------------
#if !defined(log_h)
#define log_h
//===========================================================================
//
// ログ
//
//===========================================================================
class Log
{
public:
enum loglevel {
Detail, // 詳細レベル
Normal, // 通常レベル
Warning, // 警告レベル
Debug // デバッグレベル
};
};
#endif // log_h

145
src/raspberrypi/os.h Normal file
View File

@@ -0,0 +1,145 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI (*^..^*)
// for Raspberry Pi
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2018 GIMONS
//
// Imported NetBSD support and some optimisation patch by Rin Okuyama.
//
// [ OS固有 ]
//
//---------------------------------------------------------------------------
#if !defined(os_h)
#define os_h
//---------------------------------------------------------------------------
//
// #define
//
//---------------------------------------------------------------------------
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#ifndef _FILE_OFFSET_BITS
#define _FILE_OFFSET_BITS 64
#endif
//---------------------------------------------------------------------------
//
// #include
//
//---------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <assert.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <utime.h>
#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
#include <string.h>
#include <sched.h>
#include <poll.h>
#include <pthread.h>
#include <dirent.h>
#include <iconv.h>
#include <libgen.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#if defined(__linux__)
#include <linux/if.h>
#include <linux/if_tun.h>
#elif defined(__NetBSD__)
#include <sys/param.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_tap.h>
#include <ifaddrs.h>
#else
#error unsupported platform
#endif
//---------------------------------------------------------------------------
//
// 基本マクロ
//
//---------------------------------------------------------------------------
#undef FASTCALL
#define FASTCALL
#undef CDECL
#define CDECL
#undef INLINE
#define INLINE
#if !defined(ASSERT)
#if !defined(NDEBUG)
#define ASSERT(cond) assert(cond)
#else
#define ASSERT(cond) ((void)0)
#endif // NDEBUG
#endif // ASSERT
#if !defined(ASSERT_DIAG)
#if !defined(NDEBUG)
#define ASSERT_DIAG() AssertDiag()
#else
#define ASSERT_DIAG() ((void)0)
#endif // NDEBUG
#endif // ASSERT_DIAG
//---------------------------------------------------------------------------
//
// 基本型定義
//
//---------------------------------------------------------------------------
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef int BOOL;
typedef char TCHAR;
typedef char *LPTSTR;
typedef const char *LPCTSTR;
typedef const char *LPCSTR;
#if !defined(FALSE)
#define FALSE 0
#endif
#if !defined(TRUE)
#define TRUE 1
#endif
#if !defined(_T)
#define _T(x) x
#endif
#define _MAX_PATH 260
#define _MAX_DRIVE 3
#define _MAX_DIR 256
#define _MAX_FNAME 256
#define _MAX_EXT 256
#define off64_t off_t
#define xstrcasecmp strcasecmp
#define xstrncasecmp strncasecmp
#endif // os_h

758
src/raspberrypi/rascsi.cpp Normal file
View File

@@ -0,0 +1,758 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI (*^..^*)
// for Raspberry Pi
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2018 GIMONS
// [ メイン ]
//
//---------------------------------------------------------------------------
#include "os.h"
#include "xm6.h"
#include "fileio.h"
#include "filepath.h"
#include "disk.h"
#include "gpiobus.h"
//---------------------------------------------------------------------------
//
// 変数宣言
//
//---------------------------------------------------------------------------
enum {
CtrlMax = 8, // 最大SCSIコントローラ数
};
SASIDEV *ctrl[CtrlMax]; // コントローラ
Disk *disk[CtrlMax]; // ディスク
Filepath image[CtrlMax]; // イメージファイルパス
GPIOBUS bus; // バス
BUS::phase_t phase; // フェーズ
int actid; // アクティブなコントローラID
volatile BOOL bRun; // 実行中フラグ
BOOL bServer; // サーバーモードフラグ
int monfd; // モニター用ソケットFD
pthread_t monthread; // モニタースレッド
static void *MonThread(void *param);
//---------------------------------------------------------------------------
//
// シグナル処理
//
//---------------------------------------------------------------------------
void KillHandler(int sig)
{
// 停止指示
bRun = FALSE;
}
//---------------------------------------------------------------------------
//
// バナー出力
//
//---------------------------------------------------------------------------
BOOL Banner(int argc, char* argv[])
{
printf("SCSI Target Emulator RaSCSI(*^..^*) ");
printf("version %01d.%01d%01d\n",
(int)((VERSION >> 8) & 0xf),
(int)((VERSION >> 4) & 0xf),
(int)((VERSION ) & 0xf));
printf("Powered by XM6 TypeG Technology / ");
printf("Copyright (C) 2016-2018 GIMONS\n");
printf("Connect type : %s\n", CONNECT_DESC);
if (argc > 1 && strcmp(argv[1], "-h") == 0) {
printf("\n");
printf("Usage: %s [-ID{0|1|2|3|4|5|6|7} FILE] ...\n\n", argv[0]);
printf(" IDn is SCSI identification number.\n");
printf(" FILE is disk image file.\n\n");
printf(" Detected images type based on file extension.\n");
printf(" hdf : SASI HD image(XM6 SASI HD image)\n");
printf(" hds : SCSI HD image(XM6 SCSI HD image)\n");
printf(" hdn : SCSI HD image(NEC GENUINE)\n");
printf(" hdi : SCSI HD image(Anex86 HD image)\n");
printf(" nhd : SCSI HD image(T98Next HD image)\n");
printf(" hda : SCSI HD image(APPLE GENUINE)\n");
printf(" mos : SCSI MO image(XM6 SCSI MO image)\n");
printf(" iso : SCSI CD image(ISO 9660 image)\n");
return FALSE;
}
return TRUE;
}
//---------------------------------------------------------------------------
//
// 初期化
//
//---------------------------------------------------------------------------
BOOL Init()
{
int i;
struct sockaddr_in server;
// モニター用ソケット生成
monfd = socket(PF_INET, SOCK_STREAM, 0);
memset(&server, 0, sizeof(server));
server.sin_family = PF_INET;
server.sin_port = htons(6868);
server.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(monfd, (struct sockaddr *)&server,
sizeof(struct sockaddr_in)) < 0) {
if (errno != EADDRINUSE) {
return FALSE;
}
bServer = FALSE;
return TRUE;
} else {
bServer = TRUE;
}
// 割り込みハンドラ設定
if (signal(SIGINT, KillHandler) == SIG_ERR) {
return FALSE;
}
if (signal(SIGHUP, KillHandler) == SIG_ERR) {
return FALSE;
}
if (signal(SIGTERM, KillHandler) == SIG_ERR) {
return FALSE;
}
// GPIO初期化
if (!bus.Init()) {
return FALSE;
}
// コントローラ初期化
for (i = 0; i < CtrlMax; i++) {
ctrl[i] = NULL;
}
// ディスク初期化
for (i = 0; i < CtrlMax; i++) {
disk[i] = NULL;
}
// イメージパス初期化
for (i = 0; i < CtrlMax; i++) {
image[i].Clear();
}
// アクティブID初期化
actid = -1;
return TRUE;
}
//---------------------------------------------------------------------------
//
// クリーンアップ
//
//---------------------------------------------------------------------------
void Cleanup()
{
int i;
// ディスク削除
for (i = 0; i < CtrlMax; i++) {
if (disk[i]) {
delete disk[i];
disk[i] = NULL;
}
}
// コントローラ削除
for (i = 0; i < CtrlMax; i++) {
if (ctrl[i]) {
delete ctrl[i];
ctrl[i] = NULL;
}
}
// バスをクリーンアップ
bus.Cleanup();
// モニター用ソケットクローズ
if (monfd >= 0) {
close(monfd);
}
}
//---------------------------------------------------------------------------
//
// リセット
//
//---------------------------------------------------------------------------
void Reset()
{
int i;
// アクティブID初期化
actid = -1;
// コントローラリセット
for (i = 0; i < CtrlMax; i++) {
if (ctrl[i]) {
ctrl[i]->Reset();
}
}
// バス信号線をリセット
bus.Reset();
}
//---------------------------------------------------------------------------
//
// デバイス一覧表示
//
//---------------------------------------------------------------------------
void ListDevice(FILE *fp)
{
int i;
Filepath filepath;
BOOL find;
char type[5];
find = FALSE;
type[4] = 0;
for (i = 0; i < 8; i++) {
if (disk[i] == NULL) {
continue;
}
// ヘッダー出力
if (!find) {
fprintf(fp, "\n");
fprintf(fp, "---+------+---------------------------------------\n");
fprintf(fp, "ID | TYPE | DEVICE STATUS\n");
fprintf(fp, "---+------+---------------------------------------\n");
find = TRUE;
}
// ID,タイプ出力
type[0] = (char)(disk[i]->GetID() >> 24);
type[1] = (char)(disk[i]->GetID() >> 16);
type[2] = (char)(disk[i]->GetID() >> 8);
type[3] = (char)(disk[i]->GetID());
fprintf(fp, " %d | %s | ", i, type);
// マウント状態出力
if (disk[i]->GetID() == MAKEID('S', 'C', 'B', 'R')) {
fprintf(fp, "%s", "RaSCSI BRIDGE");
} else {
disk[i]->GetPath(filepath);
fprintf(fp, "%s",
(disk[i]->IsRemovable() && !disk[i]->IsReady()) ?
"NO MEDIA" : filepath.GetPath());
}
// ライトプロテクト状態出力
if (disk[i]->IsRemovable() && disk[i]->IsReady() && disk[i]->IsWriteP()) {
fprintf(fp, "(WRITEPROTECT)");
}
// 次の行へ
fprintf(fp, "\n");
}
// コントローラが無い場合
if (!find) {
fprintf(fp, "No device is installed.\n");
return;
}
fprintf(fp, "---+------+---------------------------------------\n");
}
//---------------------------------------------------------------------------
//
// コマンド処理
//
//---------------------------------------------------------------------------
BOOL ProcessCmd(FILE *fp, int id, int cmd, int type, char *file)
{
int len;
char *ext;
Filepath filepath;
// IDチェック
if (id < 0 || id > 7) {
fprintf(fp, "Error : Invalid ID\n");
return FALSE;
}
// 接続コマンド
if (cmd == 0) { // ATTACH
// コントローラを解放
if (ctrl[id]) {
ctrl[id]->SetUnit(0, NULL);
delete ctrl[id];
ctrl[id] = NULL;
}
// ディスクを解放
if (disk[id]) {
delete disk[id];
disk[id] = NULL;
}
// SASIとSCSIを見分ける
if (type == 0) {
// パスチェック
if (!file) {
return FALSE;
}
// 最低5文字
len = strlen(file);
if (len < 5) {
return FALSE;
}
// 拡張子チェック
if (file[len - 4] != '.') {
return FALSE;
}
// 拡張子がSASIタイプで無ければSCSIに差し替え
ext = &file[len - 3];
if (xstrcasecmp(ext, "hdf") != 0) {
type = 1;
}
}
// タイプ別のインスタンスを生成
switch (type) {
case 0: // HDF
disk[id] = new SASIHD();
break;
case 1: // HDS/HDN/HDI/NHD/HDA
if (xstrcasecmp(ext, "hdn") == 0 ||
xstrcasecmp(ext, "hdi") == 0 || xstrcasecmp(ext, "nhd") == 0) {
disk[id] = new SCSIHD_NEC();
} else if (xstrcasecmp(ext, "hda") == 0) {
disk[id] = new SCSIHD_APPLE();
} else {
disk[id] = new SCSIHD();
}
break;
case 2: // MO
disk[id] = new SCSIMO();
break;
case 3: // CD
disk[id] = new SCSICD();
break;
case 4: // BRIDGE
disk[id] = new SCSIBR();
break;
default:
fprintf(fp, "Error : Invalid device type\n");
return FALSE;
}
// タイプに合わせてコントローラを作る
if (type == 0) {
ctrl[id] = new SASIDEV();
} else {
ctrl[id] = new SCSIDEV();
}
// ドライブはファイルの確認を行う
if (type <= 1 || (type <= 3 && xstrcasecmp(file, "-") != 0)) {
// パスを設定
filepath.SetPath(file);
// オープン
if (!disk[id]->Open(filepath)) {
fprintf(fp, "Error : File open error [%s]\n", file);
delete disk[id];
disk[id] = NULL;
delete ctrl[id];
ctrl[id] = NULL;
return FALSE;
}
}
// ライトスルーに設定
disk[id]->SetCacheWB(FALSE);
// 新たなディスクを接続
ctrl[id]->Connect(id, &bus);
ctrl[id]->SetUnit(0, disk[id]);
return TRUE;
}
// 有効なコマンドか
if (cmd > 4) {
fprintf(fp, "Error : Invalid command\n");
return FALSE;
}
// コントローラが存在するか
if (ctrl[id] == NULL) {
fprintf(fp, "Error : No such device\n");
return FALSE;
}
// ディスクが存在するか
if (disk[id] == NULL) {
fprintf(fp, "Error : No such device\n");
return FALSE;
}
// 切断コマンド
if (cmd == 1) { // DETACH
ctrl[id]->SetUnit(0, NULL);
delete disk[id];
disk[id] = NULL;
delete ctrl[id];
ctrl[id] = NULL;
return TRUE;
}
// MOかCDの場合だけ有効
if (disk[id]->GetID() != MAKEID('S', 'C', 'M', 'O') &&
disk[id]->GetID() != MAKEID('S', 'C', 'C', 'D')) {
fprintf(fp, "Error : Operation denied(Deveice isn't MO or CD)\n");
return FALSE;
}
switch (cmd) {
case 2: // INSERT
// パスを設定
filepath.SetPath(file);
// オープン
if (!disk[id]->Open(filepath)) {
fprintf(fp, "Error : File open error [%s]\n", file);
return FALSE;
}
break;
case 3: // EJECT
disk[id]->Eject(TRUE);
break;
case 4: // PROTECT
if (disk[id]->GetID() != MAKEID('S', 'C', 'M', 'O')) {
fprintf(fp, "Error : Operation denied(Deveice isn't MO)\n");
return FALSE;
}
disk[id]->WriteP(!disk[id]->IsWriteP());
break;
default:
ASSERT(FALSE);
return FALSE;
}
return TRUE;
}
//---------------------------------------------------------------------------
//
// 引数処理
//
//---------------------------------------------------------------------------
BOOL ParseArgument(int argc, char* argv[])
{
int i;
int id;
int type;
char *argID;
char *argPath;
int len;
char *ext;
// IDとパス指定がなければ処理を中断
if (argc < 3) {
return TRUE;
}
// 引数の解読開始
i = 1;
argc--;
// IDとパスを取得
while (argc >= 2) {
argc -= 2;
argID = argv[i++];
argPath = argv[i++];
// -ID or -idの形式をチェック
if (strlen(argID) != 4 || xstrncasecmp(argID, "-id", 3) != 0) {
fprintf(stderr,
"Error : Invalid argument(-IDn) [%s]\n", argID);
return FALSE;
}
// ID番号をチェック(0-7)
if (argID[3] < '0' || argID[3] > '7') {
fprintf(stderr,
"Error : Invalid argument(-IDn n=0-7) [%c]\n", argID[3]);
return FALSE;
}
// ID確定
id = argID[3] - '0';
// すでにアクティブなデバイスがあるならスキップ
if (disk[id]) {
continue;
}
// デバイスタイプを初期化
type = -1;
// イーサネットとホストブリッジのチェック
if (xstrcasecmp(argPath, "bridge") == 0) {
type = 4;
} else {
// パスの長さをチェック
len = strlen(argPath);
if (len < 5) {
fprintf(stderr,
"Error : Invalid argument(File path is short) [%s]\n",
argPath);
return FALSE;
}
// 拡張子を持っているか?
if (argPath[len - 4] != '.') {
fprintf(stderr,
"Error : Invalid argument(No extension) [%s]\n", argPath);
return FALSE;
}
// タイプを決める
ext = &argPath[len - 3];
if (xstrcasecmp(ext, "hdf") == 0 ||
xstrcasecmp(ext, "hds") == 0 ||
xstrcasecmp(ext, "hdn") == 0 ||
xstrcasecmp(ext, "hdi") == 0 || xstrcasecmp(ext, "nhd") == 0 ||
xstrcasecmp(ext, "hda") == 0) {
// HD(SASI/SCSI)
type = 0;
} else if (strcasecmp(ext, "mos") == 0) {
// MO
type = 2;
} else if (strcasecmp(ext, "iso") == 0) {
// CD
type = 3;
} else {
// タイプが判別できない
fprintf(stderr,
"Error : Invalid argument(file type) [%s]\n", ext);
return FALSE;
}
}
// コマンド実行
if (!ProcessCmd(stderr, id, 0, type, argPath)) {
return FALSE;
}
}
// デバイスリスト表示
ListDevice(stdout);
return TRUE;
}
//---------------------------------------------------------------------------
//
// モニタースレッド
//
//---------------------------------------------------------------------------
static void *MonThread(void *param)
{
struct sockaddr_in client;
socklen_t len;
int fd;
FILE *fp;
BYTE buf[BUFSIZ];
int id;
int cmd;
int type;
char *file;
BOOL list;
// 監視準備
listen(monfd, 1);
while (1) {
// 接続待ち
memset(&client, 0, sizeof(client));
len = sizeof(client);
fd = accept(monfd, (struct sockaddr*)&client, &len);
if (fd < 0) {
break;
}
// コマンド取得
fp = fdopen(fd, "r+");
fgets((char *)buf, BUFSIZ, fp);
buf[strlen((const char*)buf) - 1] = 0;
// デバイスリスト表示なのか制御コマンドかを判断
if (strncasecmp((char*)buf, "list", 4) == 0) {
list = TRUE;
} else {
list = FALSE;
id = (int)(buf[0] - '0');
cmd = (int)(buf[2] - '0');
type = (int)(buf[4] - '0');
file = (char*)&buf[6];
}
// バスフリーのタイミングまで待つ
while (phase != BUS::busfree) {
usleep(500 * 1000);
}
if (list) {
// リスト表示
ListDevice(fp);
} else {
// コマンド実行
ProcessCmd(fp, id, cmd, type, file);
}
// 接続解放
fclose(fp);
close(fd);
}
return NULL;
}
//---------------------------------------------------------------------------
//
// 主処理
//
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
int i;
DWORD dwBusBak;
DWORD dwBusIn;
struct sched_param schparam;
// バナー出力
if (!Banner(argc, argv)) {
exit(0);
}
// 初期化
if (!Init()) {
fprintf(stderr, "Error : Initializing\n");
// 恐らくrootでは無い
exit(EPERM);
}
// 既に起動している?
if (!bServer) {
fprintf(stderr, "Error : Already running RaSCSI\n");
exit(0);
}
// 構築
if (!ParseArgument(argc, argv)) {
// クリーンアップ
Cleanup();
// 引数エラーで終了
exit(EINVAL);
}
// モニタースレッド生成
bRun = TRUE;
pthread_create(&monthread, NULL, MonThread, NULL);
// リセット
Reset();
// メインループ準備
phase = BUS::busfree;
dwBusBak = bus.Aquire();
// メインループ
while(bRun) {
// バスの入力信号変化検出
dwBusIn = bus.Aquire();
// 入力信号変化検出
if ((dwBusIn & GPIO_INEDGE) == (dwBusBak & GPIO_INEDGE)) {
usleep(0);
continue;
}
// バスの入力信号を保存
dwBusBak = dwBusIn;
// そもそもセレクション信号が無ければ無視
if (!bus.GetSEL() || bus.GetBSY()) {
continue;
}
// 全コントローラに通知
for (i = 0; i < CtrlMax; i++) {
if (!ctrl[i]) {
continue;
}
// セレクションフェーズに移行したターゲットを探す
if (ctrl[i]->Process() == BUS::selection) {
// ターゲットのIDを取得
actid = i;
// セレクションフェーズ
phase = BUS::selection;
break;
}
}
// セレクションフェーズが開始されていなければバスの監視へ戻る
if (phase != BUS::selection) {
continue;
}
// ターゲット走行開始
// スケジューリングポリシー設定(最優先)
schparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
sched_setscheduler(0, SCHED_FIFO, &schparam);
// バスフリーになるまでループ
while (bRun) {
// ターゲット駆動
phase = ctrl[actid]->Process();
// バスフリーになったら終了
if (phase == BUS::busfree) {
break;
}
}
// バスフリーでセッション終了
actid = -1;
phase = BUS::busfree;
bus.Reset();
dwBusBak = bus.Aquire();
// スケジューリングポリシー設定(ノーマル)
schparam.sched_priority = 0;
sched_setscheduler(0, SCHED_OTHER, &schparam);
}
// クリーンアップ
Cleanup();
// 終了
exit(0);
}

247
src/raspberrypi/rasctl.cpp Normal file
View File

@@ -0,0 +1,247 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI (*^..^*)
// for Raspberry Pi
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2018 GIMONS
// [ 制御コマンド送信 ]
//
//---------------------------------------------------------------------------
#include "os.h"
//---------------------------------------------------------------------------
//
// コマンド送信
//
//---------------------------------------------------------------------------
BOOL SendCommand(char *buf)
{
int fd;
struct sockaddr_in server;
FILE *fp;
// コマンド用ソケット生成
fd = socket(PF_INET, SOCK_STREAM, 0);
memset(&server, 0, sizeof(server));
server.sin_family = PF_INET;
server.sin_port = htons(6868);
server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
// 接続
if (connect(fd, (struct sockaddr *)&server,
sizeof(struct sockaddr_in)) < 0) {
fprintf(stderr, "Error : Can't connect to rascsi process\n");
return FALSE;
}
// 送信
fp = fdopen(fd, "r+");
setvbuf(fp, NULL, _IONBF, 0);
fprintf(fp, buf);
// メッセージ受信
while (1) {
if (fgets((char *)buf, BUFSIZ, fp) == NULL) {
break;
}
printf("%s", buf);
}
// ソケットを閉じる
fclose(fp);
close(fd);
return TRUE;
}
//---------------------------------------------------------------------------
//
// 主処理
//
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
int opt;
int id;
int cmd;
int type;
char *file;
BOOL list;
int len;
char *ext;
char buf[BUFSIZ];
id = -1;
cmd = -1;
type = -1;
file = NULL;
list = FALSE;
// ヘルプの表示
if (argc < 2) {
fprintf(stderr, "SCSI Target Emulator RaSCSI Controller\n");
fprintf(stderr,
"Usage: %s -i ID [-c CMD] [-t TYPE] [-f FILE]\n",
argv[0]);
fprintf(stderr, " where ID := {0|1|2|3|4|5|6|7}\n");
fprintf(stderr, " CMD := {attach|detatch|insert|eject|protect}\n");
fprintf(stderr, " TYPE := {hd|mo|cd|bridge}\n");
fprintf(stderr, " FILE := image file path\n");
fprintf(stderr, " CMD is 'attach' or 'insert' and FILE parameter is required.\n");
fprintf(stderr, "Usage: %s -l\n", argv[0]);
fprintf(stderr, " Print device list.\n");
exit(0);
}
// 引数解析
opterr = 0;
while ((opt = getopt(argc, argv, "i:c:t:f:l")) != -1) {
switch (opt) {
case 'i':
id = optarg[0] - '0';
break;
case 'c':
switch (optarg[0]) {
case 'a': // ATTACH
case 'A':
cmd = 0;
break;
case 'd': // DETACH
case 'D':
cmd = 1;
break;
case 'i': // INSERT
case 'I':
cmd = 2;
break;
case 'e': // EJECT
case 'E':
cmd = 3;
break;
case 'p': // PROTECT
case 'P':
cmd = 4;
break;
}
break;
case 't':
switch (optarg[0]) {
case 's': // HD(SASI)
case 'S':
case 'h': // HD(SCSI)
case 'H':
type = 0;
break;
case 'm': // MO
case 'M':
type = 2;
break;
case 'c': // CD
case 'C':
type = 3;
break;
case 'b': // BRIDGE
case 'B':
type = 4;
break;
}
break;
case 'f':
file = optarg;
break;
case 'l':
list = TRUE;
break;
}
}
// リスト表示のみ
if (id < 0 && cmd < 0 && type < 0 && file == NULL && list) {
sprintf(buf, "list\n");
SendCommand(buf);
exit(0);
}
// IDチェック
if (id < 0 || id > 7) {
fprintf(stderr, "Error : Invalid ID\n");
exit(EINVAL);
}
// コマンドチェック
if (cmd < 0) {
cmd = 0; // デフォルトはATTATCHとする
}
// タイプチェック
if (cmd == 0 && type < 0) {
// 拡張子からタイプ判別を試みる
len = file ? strlen(file) : 0;
if (len > 4 && file[len - 4] == '.') {
ext = &file[len - 3];
if (xstrcasecmp(ext, "hdf") == 0 ||
xstrcasecmp(ext, "hds") == 0 ||
xstrcasecmp(ext, "hdn") == 0 ||
xstrcasecmp(ext, "hdi") == 0 ||
xstrcasecmp(ext, "nhd") == 0 ||
xstrcasecmp(ext, "hda") == 0) {
// HD(SASI/SCSI)
type = 0;
} else if (xstrcasecmp(ext, "mos") == 0) {
// MO
type = 2;
} else if (xstrcasecmp(ext, "iso") == 0) {
// CD
type = 3;
}
}
if (type < 0) {
fprintf(stderr, "Error : Invalid type\n");
exit(EINVAL);
}
}
// ファイルチェック(コマンドはATTACHでタイプはHD)
if (cmd == 0 && type >= 0 && type <= 1) {
if (!file) {
fprintf(stderr, "Error : Invalid file path\n");
exit(EINVAL);
}
}
// ファイルチェック(コマンドはINSERT)
if (cmd == 2) {
if (!file) {
fprintf(stderr, "Error : Invalid file path\n");
exit(EINVAL);
}
}
// 必要でないtypeは0としておく
if (type < 0) {
type = 0;
}
// 送信コマンド生成
sprintf(buf, "%d %d %d %s\n", id, cmd, type, file ? file : "-");
if (!SendCommand(buf)) {
exit(ENOTCONN);
}
// リスト表示
if (list) {
sprintf(buf, "list\n");
SendCommand(buf);
}
// 終了
exit(0);
}

1006
src/raspberrypi/rasdump.cpp Normal file

File diff suppressed because it is too large Load Diff

58
src/raspberrypi/scsi.cpp Normal file
View File

@@ -0,0 +1,58 @@
//---------------------------------------------------------------------------
//
// X68000 EMULATOR "XM6"
//
// Copyright (C) 2001-2006 (ytanaka@ipc-tokai.or.jp)
// Copyright (C) 2014-2018 GIMONS
//
// [ SCSI共通 ]
//
//---------------------------------------------------------------------------
#include "os.h"
#include "xm6.h"
#include "scsi.h"
//---------------------------------------------------------------------------
//
// フェーズ取得
//
//---------------------------------------------------------------------------
BUS::phase_t FASTCALL BUS::GetPhase()
{
DWORD mci;
ASSERT(this);
// セレクションフェーズ
if (GetSEL()) {
return selection;
}
// バスフリーフェーズ
if (!GetBSY()) {
return busfree;
}
// バスの信号線からターゲットのフェーズを取得
mci = GetMSG() ? 0x04 : 0x00;
mci |= GetCD() ? 0x02 : 0x00;
mci |= GetIO() ? 0x01 : 0x00;
return GetPhase(mci);
}
//---------------------------------------------------------------------------
//
// フェーズテーブル
//
//---------------------------------------------------------------------------
const BUS::phase_t BUS::phase_table[8] = {
dataout,
datain,
command,
status,
reserved,
reserved,
msgout,
msgin
};

128
src/raspberrypi/scsi.h Normal file
View File

@@ -0,0 +1,128 @@
//---------------------------------------------------------------------------
//
// X68000 EMULATOR "XM6"
//
// Copyright (C) 2001-2006 (ytanaka@ipc-tokai.or.jp)
// Copyright (C) 2014-2018 GIMONS
//
// [ SCSI共通 ]
//
//---------------------------------------------------------------------------
#if !defined(scsi_h)
#define scsi_h
//===========================================================================
//
// SASI/SCSI バス
//
//===========================================================================
class BUS
{
public:
// 動作モード定義
enum mode_e {
TARGET = 0,
INITIATOR = 1,
MONITOR = 2,
};
// フェーズ定義
enum phase_t {
busfree, // バスフリーフェーズ
arbitration, // アービトレーションフェーズ
selection, // セレクションフェーズ
reselection, // リセレクションフェーズ
command, // コマンドフェーズ
execute, // 実行フェーズ
datain, // データイン
dataout, // データアウト
status, // ステータスフェーズ
msgin, // メッセージフェーズ
msgout, // メッセージアウトフェーズ
reserved // 未使用/リザーブ
};
// 基本ファンクション
virtual BOOL FASTCALL Init(mode_e mode) = 0;
// 初期化
virtual void FASTCALL Reset() = 0;
// リセット
virtual void FASTCALL Cleanup() = 0;
// クリーンアップ
phase_t FASTCALL GetPhase();
// フェーズ取得
static phase_t FASTCALL GetPhase(DWORD mci)
{
return phase_table[mci];
}
// フェーズ取得
virtual DWORD FASTCALL Aquire() = 0;
// 信号取り込み
virtual BOOL FASTCALL GetBSY() = 0;
// BSYシグナル取得
virtual void FASTCALL SetBSY(BOOL ast) = 0;
// BSYシグナル設定
virtual BOOL FASTCALL GetSEL() = 0;
// SELシグナル取得
virtual void FASTCALL SetSEL(BOOL ast) = 0;
// SELシグナル設定
virtual BOOL FASTCALL GetATN() = 0;
// ATNシグナル取得
virtual void FASTCALL SetATN(BOOL ast) = 0;
// ATNシグナル設定
virtual BOOL FASTCALL GetACK() = 0;
// ACKシグナル取得
virtual void FASTCALL SetACK(BOOL ast) = 0;
// ACKシグナル設定
virtual BOOL FASTCALL GetRST() = 0;
// RSTシグナル取得
virtual void FASTCALL SetRST(BOOL ast) = 0;
// RSTシグナル設定
virtual BOOL FASTCALL GetMSG() = 0;
// MSGシグナル取得
virtual void FASTCALL SetMSG(BOOL ast) = 0;
// MSGシグナル設定
virtual BOOL FASTCALL GetCD() = 0;
// CDシグナル取得
virtual void FASTCALL SetCD(BOOL ast) = 0;
// CDシグナル設定
virtual BOOL FASTCALL GetIO() = 0;
// IOシグナル取得
virtual void FASTCALL SetIO(BOOL ast) = 0;
// IOシグナル設定
virtual BOOL FASTCALL GetREQ() = 0;
// REQシグナル取得
virtual void FASTCALL SetREQ(BOOL ast) = 0;
// REQシグナル設定
virtual BYTE FASTCALL GetDAT() = 0;
// データシグナル取得
virtual void FASTCALL SetDAT(BYTE dat) = 0;
// データシグナル設定
virtual int FASTCALL ReceiveHandShake(BYTE *buf, int count) = 0;
// データ受信ハンドシェイク
virtual int FASTCALL SendHandShake(BYTE *buf, int count) = 0;
// データ送信ハンドシェイク
virtual void FASTCALL SleepNsec(DWORD nsec) = 0;
// ナノ秒単位のスリープ
private:
static const phase_t phase_table[8];
// フェーズテーブル
};
#endif // scsi_h

49
src/raspberrypi/xm6.h Normal file
View File

@@ -0,0 +1,49 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI (*^..^*)
// for Raspberry Pi
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2018 GIMONS
//
// [ 共通定義 ]
//
//---------------------------------------------------------------------------
#if !defined(xm6_h)
#define xm6_h
//---------------------------------------------------------------------------
//
// VERSION
//
//---------------------------------------------------------------------------
#define VERSION 0x0134
//---------------------------------------------------------------------------
//
// RaSCSI
//
//---------------------------------------------------------------------------
#define RASCSI VERSION
//---------------------------------------------------------------------------
//
// IDマクロ
//
//---------------------------------------------------------------------------
#define MAKEID(a, b, c, d) ((DWORD)((a<<24) | (b<<16) | (c<<8) | d))
//---------------------------------------------------------------------------
//
// クラス宣言
//
//---------------------------------------------------------------------------
class Fileio;
// ファイル入出力
class Disk;
// SASI/SCSIディスク
class Filepath;
// ファイルパス
#endif // xm6_h