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

2414
src/x68k/RASDRV/BRIDGE.C Normal file

File diff suppressed because it is too large Load Diff

256
src/x68k/RASDRV/BRIDGE.H Normal file
View File

@@ -0,0 +1,256 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI (*^..^*)
// for Raspberry Pi
//
// Powered by XM6 TypeG Technorogy.
// Copyright (C) 2016-2017 GIMONS
// [ ホストファイルシステム ブリッジドライバ ]
//
//---------------------------------------------------------------------------
#ifndef bridge_h
#define bridge_h
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef int BOOL;
#if !defined(FALSE)
#define FALSE 0
#endif
#if !defined(TRUE)
#define TRUE 1
#endif
#define FASTCALL
#define ASSERT(x)
//---------------------------------------------------------------------------
//
// 定数定義
//
//---------------------------------------------------------------------------
#define FILEPATH_MAX _MAX_PATH
#define WINDRV_CLIPSIZE_MAX 0xC00000
//---------------------------------------------------------------------------
//
// ステータスコード定義
//
//---------------------------------------------------------------------------
#define FS_INVALIDFUNC 0xFFFFFFFF // 無効なファンクションコードを実行した
#define FS_FILENOTFND 0xFFFFFFFE // 指定したファイルが見つからない
#define FS_DIRNOTFND 0xFFFFFFFD // 指定したディレクトリが見つからない
#define FS_OVEROPENED 0xFFFFFFFC // オープンしているファイルが多すぎる
#define FS_CANTACCESS 0xFFFFFFFB // ディレクトリやボリュームラベルはアクセス不可
#define FS_NOTOPENED 0xFFFFFFFA // 指定したハンドルはオープンされていない
#define FS_INVALIDMEM 0xFFFFFFF9 // メモリ管理領域が破壊された
#define FS_OUTOFMEM 0xFFFFFFF8 // 実行に必要なメモリがない
#define FS_INVALIDPTR 0xFFFFFFF7 // 無効なメモリ管理ポインタを指定した
#define FS_INVALIDENV 0xFFFFFFF6 // 不正な環境を指定した
#define FS_ILLEGALFMT 0xFFFFFFF5 // 実行ファイルのフォーマットが異常
#define FS_ILLEGALMOD 0xFFFFFFF4 // オープンのアクセスモードが異常
#define FS_INVALIDPATH 0xFFFFFFF3 // ファイル名の指定に誤りがある
#define FS_INVALIDPRM 0xFFFFFFF2 // 無効なパラメータでコールした
#define FS_INVALIDDRV 0xFFFFFFF1 // ドライブ指定に誤りがある
#define FS_DELCURDIR 0xFFFFFFF0 // カレントディレクトリは削除できない
#define FS_NOTIOCTRL 0xFFFFFFEF // IOCTRLできないデバイス
#define FS_LASTFILE 0xFFFFFFEE // これ以上ファイルが見つからない
#define FS_CANTWRITE 0xFFFFFFED // 指定のファイルは書き込みできない
#define FS_DIRALREADY 0xFFFFFFEC // 指定のディレクトリは既に登録されている
#define FS_CANTDELETE 0xFFFFFFEB // ファイルがあるので削除できない
#define FS_CANTRENAME 0xFFFFFFEA // ファイルがあるのでリネームできない
#define FS_DISKFULL 0xFFFFFFE9 // ディスクが一杯でファイルが作れない
#define FS_DIRFULL 0xFFFFFFE8 // ディレクトリが一杯でファイルが作れない
#define FS_CANTSEEK 0xFFFFFFE7 // 指定の位置にはシークできない
#define FS_SUPERVISOR 0xFFFFFFE6 // スーパーバイザ状態でスーパバイザ指定した
#define FS_THREADNAME 0xFFFFFFE5 // 同じスレッド名が存在する
#define FS_BUFWRITE 0xFFFFFFE4 // プロセス間通信のバッファが書込み禁止
#define FS_BACKGROUND 0xFFFFFFE3 // バックグラウンドプロセスを起動できない
#define FS_OUTOFLOCK 0xFFFFFFE0 // ロック領域が足りない
#define FS_LOCKED 0xFFFFFFDF // ロックされていてアクセスできない
#define FS_DRIVEOPENED 0xFFFFFFDE // 指定のドライブはハンドラがオープンされている
#define FS_LINKOVER 0xFFFFFFDD // シンボリックリンクネストが16回を超えた
#define FS_FILEEXIST 0xFFFFFFB0 // ファイルが存在する
#define FS_FATAL_MEDIAOFFLINE 0xFFFFFFA3 // メディアが入っていない
#define FS_FATAL_WRITEPROTECT 0xFFFFFFA2 // 書き込み禁止違反
#define FS_FATAL_INVALIDCOMMAND 0xFFFFFFA1 // 不正なコマンド番号
#define FS_FATAL_INVALIDUNIT 0xFFFFFFA0 // 不正なユニット番号
#define HUMAN68K_PATH_MAX 96 // Human68kのパス最大長
//===========================================================================
//
/// Human68k 名前空間
//
//===========================================================================
/// ファイル属性ビット
enum attribute_t {
AT_READONLY = 0x01, // 読み込み専用属性
AT_HIDDEN = 0x02, // 隠し属性
AT_SYSTEM = 0x04, // システム属性
AT_VOLUME = 0x08, // ボリュームラベル属性
AT_DIRECTORY= 0x10, // ディレクトリ属性
AT_ARCHIVE = 0x20, // アーカイブ属性
AT_ALL = 0xFF, // 全ての属性ビットが1
};
/// ファイルオープンモード
enum open_t {
OP_READ = 0, // 読み込み
OP_WRITE = 1, // 書き込み
OP_FULL = 2, // 読み書き
OP_MASK = 0x0F, // 判定用マスク
OP_SHARE_NONE = 0x10, // 共有禁止
OP_SHARE_READ = 0x20, // 読み込み共有
OP_SHARE_WRITE = 0x30, // 書き込み共有
OP_SHARE_FULL = 0x40, // 読み書き共有
OP_SHARE_MASK = 0x70, // 共有判定用マスク
OP_SPECIAL = 0x100,// 辞書アクセス
};
/// シーク種類
enum seek_t {
SK_BEGIN = 0, // ファイル先頭から
SK_CURRENT = 1, // 現在位置から
SK_END = 2, // ファイル末尾から
};
/// メディアバイト
enum media_t {
MEDIA_2DD_10 = 0xE0, // 2DD/10セクタ
MEDIA_1D_9 = 0xE5, // 1D/9セクタ
MEDIA_2D_9 = 0xE6, // 2D/9セクタ
MEDIA_1D_8 = 0xE7, // 1D/8セクタ
MEDIA_2D_8 = 0xE8, // 2D/8セクタ
MEDIA_2HT = 0xEA, // 2HT
MEDIA_2HS = 0xEB, // 2HS
MEDIA_2HDE = 0xEC, // 2DDE
MEDIA_1DD_9 = 0xEE, // 1DD/9セクタ
MEDIA_1DD_8 = 0xEF, // 1DD/8セクタ
MEDIA_MANUAL = 0xF1, // リモートドライブ (手動イジェクト)
MEDIA_REMOVABLE = 0xF2, // リモートドライブ (リムーバブル)
MEDIA_REMOTE = 0xF3, // リモートドライブ
MEDIA_DAT = 0xF4, // SCSI-DAT
MEDIA_CDROM = 0xF5, // SCSI-CDROM
MEDIA_MO = 0xF6, // SCSI-MO
MEDIA_SCSI_HD = 0xF7, // SCSI-HD
MEDIA_SASI_HD = 0xF8, // SASI-HD
MEDIA_RAMDISK = 0xF9, // RAMディスク
MEDIA_2HQ = 0xFA, // 2HQ
MEDIA_2DD_8 = 0xFB, // 2DD/8セクタ
MEDIA_2DD_9 = 0xFC, // 2DD/9セクタ
MEDIA_2HC = 0xFD, // 2HC
MEDIA_2HD = 0xFE, // 2HD
};
/// namests構造体
typedef struct {
BYTE wildcard; // ワイルドカード文字数
BYTE drive; // ドライブ番号
BYTE path[65]; // パス(サブディレクトリ+/)
BYTE name[8]; // ファイル名 (PADDING 0x20)
BYTE ext[3]; // 拡張子 (PADDING 0x20)
BYTE add[10]; // ファイル名追加 (PADDING 0x00)
} namests_t;
/// files構造体
typedef struct {
BYTE fatr; // + 0 検索する属性 読込専用
BYTE pad1[3]; // padding
// BYTE drive; // + 1 ドライブ番号 読込専用
DWORD sector; // + 2 ディレクトリのセクタ DOS _FILES先頭アドレスで代用
// WORD cluster; // + 6 ディレクトリのクラスタ 詳細不明 (未使用)
WORD offset; // + 8 ディレクトリエントリ 書込専用
// BYTE name[8]; // +10 作業用ファイル名 読込専用 (未使用)
// BYTE ext[3]; // +18 作業用拡張子 読込専用 (未使用)
BYTE attr; // +21 ファイル属性 書込専用
BYTE pad2; // padding
WORD time; // +22 最終変更時刻 書込専用
WORD date; // +24 最終変更月日 書込専用
DWORD size; // +26 ファイルサイズ 書込専用
BYTE full[23]; // +30 フルファイル名 書込専用
BYTE pad3; // padding
} files_t;
/// FCB構造体
typedef struct {
// BYTE pad00[6]; // + 0+ 5 (未使用)
DWORD fileptr; // + 6+ 9 ファイルポインタ
// BYTE pad01[4]; // +10+13 (未使用)
WORD mode; // +14+15 オープンモード
// BYTE pad02[16]; // +16+31 (未使用)
// DWORD zero; // +32+35 オープンのとき0が書き込まれている (未使用)
// BYTE name[8]; // +36+43 ファイル名 (PADDING 0x20) (未使用)
// BYTE ext[3]; // +44+46 拡張子 (PADDING 0x20) (未使用)
BYTE attr; // +47 ファイル属性
BYTE pad; // padding
// BYTE add[10]; // +48+57 ファイル名追加 (PADDING 0x00) (未使用)
WORD time; // +58+59 最終変更時刻
WORD date; // +60+61 最終変更月日
// WORD cluster; // +62+63 クラスタ番号 (未使用)
DWORD size; // +64+67 ファイルサイズ
// BYTE pad03[28]; // +68+95 FATキャッシュ (未使用)
} fcb_t;
/// capacity構造体
typedef struct {
WORD freearea; // + 0 使用可能なクラスタ数
WORD clusters; // + 2 総クラスタ数
WORD sectors; // + 4 クラスタあたりのセクタ数
WORD bytes; // + 6 セクタ当たりのバイト数
} capacity_t;
/// ctrldrive構造体
typedef struct {
BYTE status; // +13 状態
BYTE pad[3]; // padding
} ctrldrive_t;
/// DPB構造体
typedef struct {
WORD sector_size; // + 0 1セクタ当りのバイト数
BYTE cluster_size; // + 2 1クラスタ当りのセクタ数-1
BYTE shift; // + 3 クラスタ→セクタのシフト数
WORD fat_sector; // + 4 FATの先頭セクタ番号
BYTE fat_max; // + 6 FAT領域の個数
BYTE fat_size; // + 7 FATの占めるセクタ数(複写分を除く)
WORD file_max; // + 8 ルートディレクトリに入るファイルの個数
WORD data_sector; // +10 データ領域の先頭セクタ番号
WORD cluster_max; // +12 総クラスタ数+1
WORD root_sector; // +14 ルートディレクトリの先頭セクタ番号
// DWORD driverentry; // +16 デバイスドライバへのポインタ (未使用)
BYTE media; // +20 メディア識別子
// BYTE flag; // +21 DPB使用フラグ (未使用)
BYTE pad; // padding
} dpb_t;
/// ディレクトリエントリ構造体
typedef struct {
BYTE name[8]; // + 0 ファイル名 (PADDING 0x20)
BYTE ext[3]; // + 8 拡張子 (PADDING 0x20)
BYTE attr; // +11 ファイル属性
BYTE add[10]; // +12 ファイル名追加 (PADDING 0x00)
WORD time; // +22 最終変更時刻
WORD date; // +24 最終変更月日
WORD cluster; // +26 クラスタ番号
DWORD size; // +28 ファイルサイズ
} dirent_t;
/// IOCTRLパラメータ共用体
typedef union {
BYTE buffer[8]; // バイト単位でのアクセス
DWORD param; // パラメータ(先頭4バイト)
WORD media; // メディアバイト(先頭2バイト)
} ioctrl_t;
/// コマンドライン引数構造体
typedef struct {
BYTE buf[256]; // コマンドライン引数
} argument_t;
#endif // bridge_h

17
src/x68k/RASDRV/Makefile Normal file
View File

@@ -0,0 +1,17 @@
#
# Makefile for RASDRV.SYS
#
CC = gcc -O2 -Wall -fomit-frame-pointer
AS = has
LK = hlk -l -x
RASDRV.SYS : RASDRV.o BRIDGE.o
$(LK) -o $@ $^ libc.a libiocs.a libscsi.a
RASDRV.o : RASDRV.S
$(AS) $^
BRIDGE.o : BRIDGE.C
$(CC) -c -o $@ $^


193
src/x68k/RASDRV/RASDRV.S Normal file
View File

@@ -0,0 +1,193 @@
*---------------------------------------------------------------------------
*
* SCSI Target Emulator RaSCSI (*^..^*)
* for Raspberry Pi
*
* Powered by XM6 TypeG Technorogy.
* Copyright (C) 2016-2017 GIMONS
* [ ]
*
* Based on
* X68k Emulator Host Filesystem Driver version 0.27
* Programmed By co
*
*---------------------------------------------------------------------------
CPU 68010
INCLUDE DOSCALL.MAC
INCLUDE IOCSCALL.MAC
.XREF _Init, _Process ;bridge.c
COMMAND EQU 2
ERRLOW EQU 3 8
ERRHIGH EQU 4 8
MXUNIT EQU 13
DEVEND EQU 14
BDEVNO EQU 22
DDHEADER:
DC.L -1 +$00
DC.W $2040 +$04
DC.L DDSTRATEGY +$06
DC.L DDENTRY_FIRST +$0A
DC.B '*EMUHOST' +$0E
DDREQUEST:
DC.L 0
DDSTRATEGY:
MOVE.L A5,DDREQUEST
RTS
*
DDENTRY:
MOVE.L SP,(STACK_BUFF)
LEA (DEF_STACK),SP
MOVEM.L D1-D3/A0-A2,-(SP)
MOVEM.L DDREQUEST(PC),D0 D0.L:
MOVE.L D0,-(SP)
BSR _Process
ADDQ.L #4,SP
MOVEM.L (SP)+,D1-D3/A0-A2
MOVEA.L (STACK_BUFF),SP
RTS
KEEP_HERE:
*
DDENTRY_FIRST:
MOVEM.L D1-D3/A0-A2/A5,-(SP)
MOVEA.L DDREQUEST(PC),A5 A5.L:
* CMPI.B #$40,COMMAND(A5) Human68k
* BNE UNSUPPORTED :
*
PEA MESSAGE_TITLE(PC)
DOS _PRINT
ADDQ.L #4,SP
*
DEVICE_CHECK:
BSR _Init
TST.L D0
BEQ NOTFOUND :
*
LEA DDENTRY(PC),A1
LEA DDHEADER+$0A(PC),A0
MOVE.L A1,(A0)
MOVE.L #PROG_END,DEVEND(A5)
ST.B MXUNIT(A5)
JSR (A1)
TST.B MXUNIT(A5)
BLE NODRIVE :
MOVE.B BDEVNO(A5),D0
MOVE.B MXUNIT(A5),D1
LEA FIRSTDRIVE(PC),A0
ADD.B D0,(A0)
ADD.B D1,D0
ADD.B D0,LASTDRIVE-FIRSTDRIVE(A0)
PEA MESSAGE_DRIVENAME(PC) : A:
DOS _PRINT
PEA MESSAGE_DRIVENAME2(PC) : Z:
SUBQ.B #2,D1
BCS @F
DOS _PRINT
@@ ADDQ.L #8,SP
PEA MESSAGE_DRIVENAME3(PC) :
BRA QUIT
NOTFOUND:
PEA MESSAGE_NOTFOUND(PC) :
BRA ABORT
UNSUPPORTED:
PEA MESSAGE_UNSUPPORTED(PC) :
BRA ABORT
NODRIVE:
PEA MESSAGE_NODRIVE(PC) :
ABORT:
MOVE.B #$0D,ERRLOW(A5)
MOVE.B #$70,ERRHIGH(A5)
QUIT:
DOS _PRINT
ADDQ.L #4,SP
MOVEM.L (SP)+,D1-D3/A0-A2/A5
RTS
SECRET:
PEA MESSAGE_TITLE2(PC)
DOS _PRINT
PEA CREDIT(PC)
DOS _PRINT
ADDQ.L #8,SP
DOS _EXIT
DATA
*
MESSAGE_NOTFOUND:
DC.B '',$0D,$0A,0
MESSAGE_UNSUPPORTED:
DC.B '',$0D,$0A,0
MESSAGE_NODRIVE:
DC.B '',$0D,$0A,0
*
MESSAGE_DRIVENAME:
DC.B ''
FIRSTDRIVE:
DC.B 'A:',0
MESSAGE_DRIVENAME2:
DC.B ''
LASTDRIVE:
DC.B '@:',0
MESSAGE_DRIVENAME3:
DC.B '',$0D,$0A,0
*
MESSAGE_TITLE:
DC.B $0D,$0A
MESSAGE_TITLE2:
DC.B 'RaSCSI FileSystem Driver version 1.21',$0D,$0A,0
*
CREDIT:
DC.B 'Coded by GIMONS',$0D,$0A
DC.B 'Special thanks to',$0D,$0A
DC.B 9,'co',$0D,$0A
DC.B 9,'',$0D,$0A
DC.B 9,'',$0D,$0A
DC.B 0
BSS
QUAD
STACK_BUFF:
.DS.L 1
STACK
QUAD
.DS.B 1024*2
DEF_STACK:
PROG_END:
END SECRET

View File

@@ -0,0 +1,29 @@
RaSCSI ファイルシステムドライバ
RASDRV version 1.21
■概要
 本プログラムはX68000実機で動作しているHuman68kからRaSCSIのブリッジデバイスを
通してRaspberry Pi側のファイルシステムを直接操作するためのデバイスドライバです。
 X68000エミュレータであるXM6及びXM6改ならびにTypeGのWindrvXMと同等の機能を提供
 します。
■解説
 利用するにはRaspberry PiのRaSCSIでブリッジデバイスを有効にする必要があります。
例えばSCSI ID6にブリッジデバイスを有効にする場合はrascsi -ID6 BRIDGEといった
指定が必要です。
 次にデバイスドライバRASCSI.SYSを実機の環境にコピーします。あとはCONFIG.SYSの
後半部分に以下のように記述してください。
DEVICE = \SYS\RASDRV.SYS
 起動オプションを指定しない場合はRaspberry Piのルートディレクトリ配下をマウント
 します。引数にディレクトリ名を指定することでそのディレクトリをマウントできます。
例えば/home/pi/appと/home/pi/dataというディレクトリをマウントする場合は
DEVICE = \SYS\RASDRV.SYS /home/pi/app /home/pi/data
と記述することで二つのディレクトリを別々のドライブとしてマウント可能です。
その他のオプションとしてWindrvXMのものが指定可能です。

View File

@@ -0,0 +1,33 @@
#
# Makefile for RASETHER.SYS
#
TARGET = RASETHER.SYS
OBJS = re.o asmsub.o main.o scsictl.o
LIBS = libc.a libgnu.a libscsi.a
CC = gcc -O2 -Wall -fomit-frame-pointer
CFLAGS = -D__DOS_INLINE__ -D__IOCS_INLINE__
#CFLAGS = -D__DOS_INLINE__ -D__IOCS_INLINE__ -DUSE_DMA
AS = has
ASFLAGS =
LD = hlk
LDFLAGS = -l -x
all: $(TARGET)
$(TARGET): $(OBJS)
$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
scsictl.o: scsictl.c scsictl.h
$(COMPILE.c) $<
main.o: main.c main.h scsictl.h
$(COMPILE.c) $<
asmsub.o: asmsub.s
# EOF


View File

@@ -0,0 +1,42 @@
RaSCSI用 Ethernetドライバ
RASETHER version 1.20
Based on
Neptune-X board driver for Human-68k(ESP-X) version 0.03
Programed 1996-7 by Shi-MAD.
Special thanks to Niggle, FIRST, yamapu ...
● このプログラムは
Shi-MAD さんの作られた Ethernet 用 ISA バスブリッジ "Neptune-X" 用デバ
イスドライバ ether_ne.sys を改造した ether_ne.sys ver0.03 +M01 +1 +L12を
参考にして開発したRaSCSI用のイーサーネット通信ドライバです。
● 使い方
基本的にはオリジナルのドライバと同じようにデバイスドライバとしてCONFIG.SYS
で組み込んで下さい。
 例)
DEVICE = \SYS\RASETHER.SYS
 以下のオプションが指定可能です。
-tx [xは数字] : 使用するtrapを指定します。xはからが指定可能です。
ただし、指定したtrapが使用中である場合は、trap #0から
空いている所を自動探索し、見つかった空きtrapを利用し
ます。
-n : APIにtrapを使用しません。
RASETHERで拡張したオプションは以下のとおりです。
-px [xは数字] : パケット受信のポーリング間隔を指定します1がデフォルトです。
1の場合は約16ms毎にポーリングします。2,3・・・8まで指定が可能
です。数字が一つ増えるごとに16ms間隔が大きくなります。
-ix [xは数字] : ポーリングに使用する割り込みのタイプを指定します。
デフォルトは0でMFPのGPIP割り込み(V-DISP)を利用します。
1を指定するとTimer-A割り込みを使用します。
● このドライバについて
オリジナルのether_ne.sys及び改造版のether_ne.sys ver0.03 +M01 +1 +L12の
利用規定に従います。

View File

@@ -0,0 +1,22 @@
* asmsub.s
.xdef _DI, _EI * ne2000.c nagai.
.text
.even
_DI:
move.w sr,sendp_sr
ori.w #$700,sr
rts
_EI:
move.w sendp_sr,sr
rts
sendp_sr:
.ds.w 1
.even

282
src/x68k/RASETHER/main.c Normal file
View File

@@ -0,0 +1,282 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI (*^..^*)
// for Raspberry Pi
//
// Powered by XM6 TypeG Technorogy.
// Copyright (C) 2016-2017 GIMONS
// [ RaSCSI イーサーネット メイン ]
//
// Based on
// Neptune-X board driver for Human-68k(ESP-X) version 0.03
// Programed 1996-7 by Shi-MAD.
// Special thanks to Niggle, FIRST, yamapu ...
//
//---------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <sys/dos.h>
#include "main.h"
#include "scsictl.h"
unsigned int scsiid;
int trap_no;
int num_of_prt;
struct prt PRT_LIST[NPRT];
// マルチキャスト(未対応)
#ifdef MULTICAST
int num_of_multicast;
struct eaddr multicast_array[NMULTICAST];
#endif
/************************************************
* *
************************************************/
static int sprint_eaddr(unsigned char* dst, void* e)
{
unsigned char* p = e;
return sprintf(
dst,
"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
p[0], p[1], p[2], p[3], p[4], p[5]);
}
/************************************************
* TRAP nが使用可能か調べる *
************************************************/
static int is_valid_trap(int trap_no)
{
unsigned int addr;
if (trap_no < 0 || 7 < trap_no) {
return 0;
}
// 使用中かどうかチェック
addr = (unsigned int)_dos_intvcg(TRAP_VECNO(trap_no));
// 処理アドレスの最上位バイトにベクタ番号が入っていれば未使用
if (addr & 0xff000000) {
return -1;
}
return 0;
}
/************************************************
* 未使用のTRAP nを検索 *
************************************************/
static int search_trap_no(int def)
{
int i;
// もしdefが使用可能ならそれに決定
if (is_valid_trap(def)) {
return def;
}
for (i = 0; i <= 6; i++) {
if (is_valid_trap(i)) {
return i;
}
}
return -1;
}
/************************************************
* vector set *
************************************************/
static void* trap_vector(int trap_no, void *func)
{
return _dos_intvcs(TRAP_VECNO(trap_no), func);
}
/************************************************
初期化関数ne.sイニシャライズで呼びます *
************************************************/
int Initialize(void)
{
unsigned char buff[128];
unsigned char buff2[32];
struct eaddr ether_addr;
if (SearchRaSCSI())
{
Print("RaSCSI Ether Adapter の存在を確認できませんでした\r\n");
return -1;
}
if (InitList(NPRT)
|| InitRaSCSI())
{
Print("RaSCSI Ether Adapter Driver の初期化に失敗しました\r\n");
return -1;
}
memset(&ether_addr, 0x00, sizeof(ether_addr));
GetMacAddr(&ether_addr);
// 未使用trap番号を調べる指定番号優先
if (trap_no >= 0) {
trap_no = search_trap_no(trap_no);
}
if (trap_no >= 0) {
// trapをフックする
trap_vector(trap_no, (void*)trap_entry);
sprintf(buff, " API trap number:%d ", trap_no);
} else {
sprintf(buff, " API trap number:n/a ");
}
Print(buff);
sprintf(buff, "SCSI ID:%d ", scsiid);
Print(buff);
sprint_eaddr(buff2, ether_addr.eaddr);
sprintf(buff, "MAC Addr:%s\r\n", buff2);
Print(buff);
// ポーリング開始
RegisterIntProcess(poll_interval);
return 0;
}
/************************************************
* プロトコルリスト初期化 *
************************************************/
int InitList(int n)
{
struct prt* p;
int i;
p = &PRT_LIST[0];
for (i = 0; i < NPRT; i++, p++) {
p->type = -1;
p->func = 0;
p->malloc = (malloc_func)-1;
}
num_of_prt = 0;
#ifdef MULTICAST
num_of_multicast = 0;
#endif
return 0;
}
/************************************************
* 受信ハンドラ(プロトコル)追加 *
************************************************/
int AddList(int type, int_handler handler)
{
struct prt* p;
int i, result;
if (type == -1) {
return -1;
}
result = -1;
// overwrite if alreay exist
p = &PRT_LIST[0];
for (i = 0; i < NPRT; i++, p++) {
if ((p->type == type && p->malloc != (malloc_func)-1)
|| p->type == -1)
{
if (p->type == -1)
num_of_prt++;
p->type = type;
p->func = handler;
p->malloc = (malloc_func)-1;
i++;
p++;
result = 0;
break;
}
}
// clear if exist more
for (; i < NPRT; i++, p++) {
if (p->type == type && p->malloc != (malloc_func)-1) {
p->type = -1;
}
}
return result;
}
/************************************************
* 受信ハンドラ(プロトコル)削除 *
************************************************/
int DeleteList(int type)
{
struct prt* p;
int i, result;
if (type == -1) {
return -1;
}
result = -1;
for (i = 0, p = &PRT_LIST[0]; i < NPRT; i++, p++) {
if (p->type == type && p->malloc != (malloc_func)-1) {
p->type = -1;
result = 0;
num_of_prt--;
}
}
return result;
}
/************************************************
* 受信ハンドラ(プロトコル)サーチ *
************************************************/
int_handler SearchList(int type)
{
struct prt* p;
int i;
if (type == -1) {
return 0;
}
for (i = 0, p = &PRT_LIST[0]; i < NPRT; i++, p++) {
if (p->type == type) {
return p->func;
}
}
return 0;
}
/************************************************
* 受信ハンドラ(プロトコル)サーチ *
************************************************/
int_handler SearchList2(int type, int n)
{
struct prt *p;
int i, cur;
if (type == -1) {
return NULL;
}
cur = 0;
for (i = 0, p = &PRT_LIST[0]; i < NPRT; i++, p++) {
if (p->type == type && cur++ == n) {
return p->func;
}
}
return NULL;
}

81
src/x68k/RASETHER/main.h Normal file
View File

@@ -0,0 +1,81 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI (*^..^*)
// for Raspberry Pi
//
// Powered by XM6 TypeG Technorogy.
// Copyright (C) 2016-2017 GIMONS
// [ RaSCSI イーサーネット メイン ]
//
// Based on
// Neptune-X board driver for Human-68k(ESP-X) version 0.03
// Programed 1996-7 by Shi-MAD.
// Special thanks to Niggle, FIRST, yamapu ...
//
//---------------------------------------------------------------------------
#ifndef main_h
#define main_h
#define ID_EN0 (('e'<<24)+('n'<<16)+('0'<<8))
#undef MULTICAST
// number of protocol type we can handle **EDIT this**
#define NPRT (16)
// number of multicast address we can handle **EDIT this**
#define NMULTICAST (64)
/* ただし、まだマルチキャストには対応していない */
struct eaddr {
unsigned char eaddr [6];
};
typedef void (*int_handler) (int, void*, int);
typedef void (*malloc_func) (unsigned int*);
struct prt {
int type;
int_handler func;
malloc_func malloc;
};
// グローバル変数
extern unsigned int scsiid;
extern int trap_no;
extern int num_of_prt;
extern struct prt PRT_LIST [NPRT];
#ifdef MULTICAST
extern int num_of_multicast;
extern struct eaddr multicast_array [NMULTICAST];
#endif
// プロトタイプ宣言
extern int Initialize (void);
extern int InitList (int);
extern int AddList (int, int_handler);
extern int DeleteList (int);
extern int_handler SearchList (int);
extern int_handler SearchList2 (int, int);
extern malloc_func GetMallocFunc (int, int);
#ifdef MULTICAST
extern int AddMulticastArray (struct eaddr*);
extern void DelMulticastArray (struct eaddr*);
extern void MakeMulticastTable (unsigned char*);
#endif
// ne.s 内関数
extern void trap_entry (void);
#include <sys/iocs.h>
#define Print _iocs_b_print
#define TRAP_VECNO(n) (0x20 + n)
#endif // main_h

574
src/x68k/RASETHER/re.s Normal file
View File

@@ -0,0 +1,574 @@
**---------------------------------------------------------------------------
**
** SCSI Target Emulator RaSCSI (*^..^*)
** for Raspberry Pi
**
** Powered by XM6 TypeG Technorogy.
** Copyright (C) 2016-2017 GIMONS
** [ RaSCSI ]
**
** Based on
** Neptune-X board driver for Human-68k(ESP-X) version 0.03
** Programed 1996-7 by Shi-MAD.
** Special thanks to Niggle, FIRST, yamapu ...
**
**---------------------------------------------------------------------------
* Include Files ----------------------- *
.include doscall.mac
.include iocscall.mac
* Global Symbols ---------------------- *
*
*
*
.xref _Initialize, _AddList, _SearchList, _DeleteList ;main.c
.xref _GetMacAddr, _SetMacAddr ;scsictl.c
.xref _SendPacket, _SetPacketReception ;scsictl.c
* .xref _AddMulticastAddr, _DelMulticastAddr ;未実装
*
*
*
.xref _num_of_prt ;main.c 登録プロトコル数
.xref _trap_no ;使用trapナンバー
.xref _trans_counter ;scsictl.c 送信/受信バイト数
.xref _intr_type ;scsictl.c 割り込み種別
.xref _poll_interval ;scsictl.c ポーリング間隔
* Text Section -------------------------------- *
.cpu 68000
.text
*
*
*
device_header:
.dc.l -1 ;リンクポインター
.dc $8000 ;device att.
.dc.l strategy_entry ;stategy entry
.dc.l interupt_entry ;interupt entry
.dc.b '/dev/en0' ;device name
.dc.b 'EthD' ;for etherlib.a
.dc.b 'RASC' ;driver name (この後にエントリーを置く)
* 'RASC' superjsr_entry
*
* ( for DOS _SUPERJSR )
* in: d0: command number
* a0: args
*
superjsr_entry:
movem.l d1-d7/a1-a7,-(sp)
* move.l d0,-(sp)
* pea (mes11,pc)
* DOS _PRINT
* addq.l #4,sp
* move.l (sp)+,d0
* .data
*mes11: .dc.b 'en0:spjEntry',13,10,0
* .text
bsr do_command
movem.l (sp)+,d1-d7/a1-a7
rts ;普通のリターン
*
* ( for trap #n )
* in: d0: command number
* a0: args
*
_trap_entry::
movem.l d1-d7/a1-a7,-(sp)
* move.l d0,-(sp)
* pea (mes10,pc)
* DOS _PRINT
* addq.l #4,sp
* move.l (sp)+,d0
* .data
*mes10: .dc.b 'en0:trapEntry',13,10,0
* .text
bsr do_command
movem.l (sp)+,d1-d7/a1-a7
rte ;割り込みリターン
*
*
*
do_command:
moveq #FUNC_MIN,d1
cmp.l d0,d1
bgt error ;d0<-2 なら未対応コマンド番号
moveq #FUNC_MAX,d1
cmp.l d1,d0
bgt error ;9<d0 なら未対応コマンド番号
add d0,d0
move (jumptable,pc,d0.w),d0
jmp (jumptable,pc,d0.w) ;引数 a0 をレジスタ渡し
** rts
error:
moveq #-1,d0
rts
*
*
*
FUNC_MIN: .equ ($-jumptable)/2
.dc get_cnt_addr-jumptable ;-2 ... 送受信カウンタのアドレス取得
.dc driver_entry-jumptable ;-1 ... 使用trap番号の取得
jumptable:
.dc get_driver_version-jumptable ;00 ...
.dc get_mac_addr-jumptable ;01 ... 現在のMACアドレス取得
.dc get_prom_addr-jumptable ;02 ... PROMに書かれたMACアドレス取得
.dc set_mac_addr-jumptable ;03 ... MACアドレスの設定
.dc send_packet-jumptable ;04 ... パケット送信
.dc set_int_addr-jumptable ;05 ... パケット受信ハンドラ設定
.dc get_int_addr-jumptable ;06 ... パケット受信ハンドラのアドレス取得
.dc del_int_addr-jumptable ;07 ... ハンドラ削除
.dc set_multicast_addr-jumptable ;08 ... (マルチキャストの設定<未対応>)
.dc get_statistics-jumptable ;09 ... (統計読み出し<未対応>)
FUNC_MAX: .equ ($-jumptable)/2-1
*
* -2:
* return: address
*
get_cnt_addr:
pea (_trans_counter,pc)
move.l (sp)+,d0
rts
*
* -1: 使trap
* return: trap number to use (-1:use SUPERJSR)
*
driver_entry:
* pea (mesff,pc)
* DOS _PRINT
* addq.l #4,sp
* .data
*mesff: .dc.b 'DriverEntry',13,10,0
* .text
move.l (_trap_no,pc),d0 ;trap_no ... main.c 変数
rts
*
* 00:
* return: version number (... ver1.00 100 )
*
get_driver_version:
* pea (mes00,pc)
* DOS _PRINT
* addq.l #4,sp
* .data
*mes00: .dc.b 'GetDriverVersion',13,10,0
* .text
moveq #3,d0 ;ver 0.03
rts
*
* 01: MAC
* return: same as *dst
*
get_mac_addr:
* pea (mes01,pc)
* DOS _PRINT
* addq.l #4,sp
* .data
*mes01: .dc.b 'GetMacAddr',13,10,0
* .text
pea (a0)
pea (a0)
bsr _GetMacAddr ;scsictl.c 関数
addq.l #4,sp
move.l (sp)+,d0 ;引数の a0 を d0 にそのまま返す
rts
*
* 02: EEPROM MAC
* return: same as *dst
*
get_prom_addr:
* pea (mes02,pc)
* DOS _PRINT
* addq.l #4,sp
* .data
*mes02: .dc.b 'GePromAddr',13,10,0
* .text
pea (a0)
pea (a0)
bsr _GetMacAddr ;scsictl.c 関数
addq.l #4,sp
move.l (sp)+,d0 ;引数の a0 を d0 にそのまま返す
rts
*
* 03: MAC
* return: 0 (if no errors)
*
set_mac_addr:
* pea (mes03,pc)
* DOS _PRINT
* addq.l #4,sp
* .data
*mes03: .dc.b 'SetMacAddr',13,10,0
* .text
pea (a0)
bsr _SetMacAddr ;scsictl.c 関数
addq.l #4,sp
rts
*
* 04:
* packet contents:
* Distination MAC: 6 bytes
* Source(own) MAC: 6 bytes
* Protcol type: 2 bytes
* Data: ? bytes
* return: 0 (if no errors)
*
send_packet:
* pea (mes04,pc)
* DOS _PRINT
* addq.l #4,sp
move.l (a0)+,d0 ;パケットサイズ
move.l (a0),-(sp) ;パケットアドレス
move.l d0,-(sp)
bsr _SendPacket ;scsictl.c 関数
addq.l #8,sp
* move.l d0,-(sp)
* pea (mes04e,pc)
* DOS _PRINT
* addq.l #4,sp
* move.l (sp)+,d0
* .data
*mes04: .dc.b 13,10,'SendPacket,13,10',0
*mes04e:.dc.b 13,10,'SendPacket',13,10,0
* .text
rts
*
* 05:
* type: 0x00000800 IP packet
* 0x00000806 ARP packet
* return: 0 (if no errors)
*
set_int_addr:
* pea (mes05,pc)
* DOS _PRINT
* addq.l #4,sp
* .data
*mes05: .dc.b 'SetIntAddr',13,10,0
* .text
move.l (a0)+,d0 ;プロトコル番号
move.l (a0),-(sp) ;ハンドラ関数のアドレス
move.l d0,-(sp)
bsr _AddList ;main.c 関数
addq.l #8,sp
tst.l d0
bmi set_int_addr_rts ;登録失敗
cmpi.l #1,(_num_of_prt) ;ハンドラ数が1なら割り込み許可へ
bne set_int_addr_rts
pea (1) ;1=<許可>
bsr _SetPacketReception ;割り込み許可 ... scsictl.c
addq.l #4,sp
* moveq #0,d0 ;SetPacketReception() で常に 0 が返るので省略
set_int_addr_rts:
rts
*
* 06:
* return: interupt address
*
get_int_addr:
* pea (mes07,pc)
* DOS _PRINT
* addq.l #4,sp
* .data
*mes07: .dc.b 'GetIntAddr',13,10,0
* .text
pea (a0)
bsr _SearchList
addq.l #4,sp
rts
*
* 07:
* return: 0 (if no errors)
*
del_int_addr:
* pea (mes06,pc)
* DOS _PRINT
* addq.l #4,sp
* .data
*mes06: .dc.b 'DelIntAddr',13,10,0
* .text
pea (a0)
bsr _DeleteList ;main.c 関数
move.l d0,(sp)+
bmi del_int_addr_ret ;削除失敗
tst.l (_num_of_prt) ;ハンドラが一つもなくなれば割り込みを禁止する
bne del_int_addr_ret
clr.l -(sp) ;0=<禁止>
bsr _SetPacketReception ;割り込み禁止 ... scsictl.c
addq.l #4,sp
* moveq #0,d0 ;SetPacketReception() で常に 0 が返るので省略
del_int_addr_ret:
rts
*
* 08:
*
set_multicast_addr:
* pea (mes08,pc)
* .data
* DOS _PRINT
* addq.l #4,sp
*mes08: .dc.b 'SetMulticastAddr',13,10,0
* .text
moveq #0,d0
rts
*
* 09:
*
get_statistics:
* pea (mes09,pc)
* DOS _PRINT
* addq.l #4,sp
* .data
*mes09: .dc.b 'GetStatistics',13,10,0
* .text
moveq #0,d0
rts
*
*
*
strategy_entry:
move.l a5,(request_buffer)
rts
interupt_entry:
move.l sp,(stack_buff) ;自前のスタックエリアを使う
lea (def_stack),sp ;
movem.l d1-d7/a0-a5,-(sp)
movea.l (request_buffer,pc),a5
tst.b (2,a5)
bne errorret
pea (mestitle,pc)
DOS _PRINT
addq.l #4,sp
movea.l (18,a5),a4
@@:
tst.b (a4)+
bne @b
moveq #0,d0
move.l d0,(_trap_no)
move.l d0,(_intr_type)
moveq #1,d0
move.l d0,(_poll_interval)
arg_loop:
move.b (a4)+,d0
beq arg_end
cmpi.b #'-',d0
beq @f
cmpi.b #'/',d0
bne param_errret
@@:
move.b (a4)+,d0
beq param_errret
opt_loop:
andi.b #$df,d0
cmpi.b #'I',d0
beq opt_i
cmpi.b #'P',d0
beq opt_p
cmpi.b #'T',d0
beq opt_t
cmpi.b #'N',d0
beq opt_n
bra param_errret
opt_n:
moveq #-1,d0
move.l d0,(_trap_no)
move.b (a4)+,d0
beq arg_loop
bra opt_loop
opt_t:
bsr get_num
tst.b d0
bne param_errret
cmpi #6,d2
bgt param_errret
move.l d2,(_trap_no)
move.b (a4)+,d0
beq arg_loop
bra opt_loop
opt_p:
bsr get_num
tst.b d0
bne param_errret
cmpi #1,d2
blt param_errret
cmpi #8,d2
bgt param_errret
move.l d2,(_poll_interval)
move.b (a4)+,d0
beq arg_loop
bra opt_loop
opt_i:
bsr get_num
tst.b d0
bne param_errret
cmpi #1,d2
bgt param_errret
move.l d2,(_intr_type)
move.b (a4)+,d0
beq arg_loop
bra opt_loop
arg_end:
bsr _Initialize ;main.c 関数
;I/Oアドレス設定
;MACアドレス取得
;プロトコルリスト初期化
;SCSICTL初期化
;割り込みハンドラ(ベクタ設定)
;trapサービスベクタ設定
tst.l d0
bne errorret
* moveq #0,d0
move.l #prog_end,(14,a5)
bra intret
param_errret:
pea (mesparam_err,pc)
DOS _PRINT
addq.l #4,sp
errorret:
move #$5003,d0
intret:
move.b d0,(4,a5)
lsr #8,d0
move.b d0,(3,a5)
movem.l (sp)+,d1-d7/a0-a5
movea.l (stack_buff,pc),sp ;スタックポインタを元にもどす
rts
get_num:
moveq #1,d0
moveq #0,d1
moveq #0,d2
@@:
move.b (a4),d1
subi.b #'0',d1
bcs @f
cmpi.b #9,d1
bgt @f
move.b #0,d0
andi #$f,d1
mulu #10,d2
add d1,d2
addq.l #1,a4
bra @b
@@:
rts
* Data Section ------------------------ *
.data
mestitle:
.dc.b 13,10
.dc.b 'RaSCSI Ethernet Driver version 1.20 / Based on ether_ne.sys+M01L12',13,10
.dc.b 0
mesparam_err:
.dc.b '',13,10,0
.even
* BSS --------------------------------- *
.bss
.quad
stack_buff:
.ds.l 1
request_buffer:
.ds.l 1
stack_buff_i:
.ds.l 1
* Stack Section ----------------------- *
.stack
.quad
*
*
*
.ds.b 1024*8
def_stack:
prog_end:
.end
* EOF --------------------------------- *

537
src/x68k/RASETHER/scsictl.c Normal file
View File

@@ -0,0 +1,537 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI (*^..^*)
// for Raspberry Pi
//
// Powered by XM6 TypeG Technorogy.
// Copyright (C) 2016-2017 GIMONS
// [ RaSCSI イーサーネット SCSI制御部 ]
//
// Based on
// Neptune-X board driver for Human-68k(ESP-X) version 0.03
// Programed 1996-7 by Shi-MAD.
// Special thanks to Niggle, FIRST, yamapu ...
//
//---------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <sys/dos.h>
#include <sys/scsi.h>
#include <iocslib.h>
#include "main.h"
#include "scsictl.h"
typedef struct
{
char DeviceType;
char RMB;
char ANSI_Ver;
char RDF;
char AddLen;
char RESV0;
char RESV1;
char OptFunc;
char VendorID[8];
char ProductID[16];
char FirmRev[4];
} INQUIRY_T;
typedef struct
{
INQUIRY_T info;
char options[8];
} INQUIRYOPT_T;
#define MFP_AEB 0xe88003
#define MFP_IERB 0xe88009
#define MFP_IMRB 0xe88015
// asmsub.s 内のサブルーチン
extern void DI();
extern void EI();
volatile short* iocsexec = (short*)0xa0e; // IOCS実行中ワーク
struct trans_counter trans_counter; // 送受信カウンタ
unsigned char rx_buff[2048]; // 受信バッファ
int imr; // 割り込み許可フラグ
int scsistop; // SCSI停止中フラグ
int intr_type; // 割り込み種別(0:V-DISP 1:TimerA)
int poll_interval; // ポーリング間隔(設定)
int poll_current; // ポーリング間隔(現在)
int idle; // アイドルカウンタ
#define POLLING_SLEEP 255 // 4-5s
/************************************************
* MACアドレス取得命令発行 *
************************************************/
int SCSI_GETMACADDR(unsigned char *mac)
{
unsigned char cmd[10];
unsigned char sts;
unsigned char msg;
if (S_SELECT(scsiid) != 0) {
return 0;
}
cmd[0] = 0x28;
cmd[1] = 0;
cmd[2] = 1;
cmd[3] = 0;
cmd[4] = 0;
cmd[5] = 0;
cmd[6] = 0;
cmd[7] = 0;
cmd[8] = 6;
cmd[9] = 0;
if (S_CMDOUT(10, cmd) != 0) {
return 0;
}
#ifdef USE_DMA
if (S_DATAIN(6, mac) != 0) {
#else
if (S_DATAIN_P(6, mac) != 0) {
#endif
return 0;
}
S_STSIN(&sts);
S_MSGIN(&msg);
return 1;
}
/************************************************
* MACアドレス設定命令発行 *
************************************************/
int SCSI_SETMACADDR(const unsigned char *mac)
{
unsigned char cmd[10];
unsigned char sts;
unsigned char msg;
if (S_SELECT(scsiid) != 0) {
return 0;
}
cmd[0] = 0x2a;
cmd[1] = 0;
cmd[2] = 1;
cmd[3] = 0;
cmd[4] = 0;
cmd[5] = 0;
cmd[6] = 0;
cmd[7] = 0;
cmd[8] = 6;
cmd[9] = 0;
if (S_CMDOUT(10, cmd) != 0) {
return 0;
}
#ifdef USE_DMA
S_DATAOUT(6, mac);
#else
S_DATAOUT_P(6, mac);
#endif
S_STSIN(&sts);
S_MSGIN(&msg);
return 1;
}
/************************************************
* パケット受信サイズ取得命令発行 *
************************************************/
int SCSI_GETPACKETLEN(int *len)
{
unsigned char cmd[10];
unsigned char buf[2];
unsigned char sts;
unsigned char msg;
if (S_SELECT(scsiid) != 0) {
return 0;
}
cmd[0] = 0x28;
cmd[1] = 0;
cmd[2] = 1;
cmd[3] = 1;
cmd[4] = 0;
cmd[5] = 0;
cmd[6] = 0;
cmd[7] = 0;
cmd[8] = 2;
cmd[9] = 0;
if (S_CMDOUT(10, cmd) != 0) {
return 0;
}
#ifdef USE_DMA
if (S_DATAIN(2, buf) != 0) {
#else
if (S_DATAIN_P(2, buf) != 0) {
#endif
return 0;
}
S_STSIN(&sts);
S_MSGIN(&msg);
*len = (int)(buf[0] << 8) + (int)(buf[1]);
return 1;
}
/************************************************
* パケット受信命令発行 *
************************************************/
int SCSI_GETPACKETBUF(unsigned char *buf, int len)
{
unsigned char cmd[10];
unsigned char sts;
unsigned char msg;
if (S_SELECT(scsiid) != 0) {
return 0;
}
cmd[0] = 0x28;
cmd[1] = 0;
cmd[2] = 1;
cmd[3] = 1;
cmd[4] = 0;
cmd[5] = 0;
cmd[6] = (unsigned char)(len >> 16);
cmd[7] = (unsigned char)(len >> 8);
cmd[8] = (unsigned char)len;
cmd[9] = 1;
if (S_CMDOUT(10, cmd) != 0) {
return 0;
}
#ifdef USE_DMA
if (S_DATAIN(len, buf) != 0) {
#else
if (S_DATAIN_P(len, buf) != 0) {
#endif
return 0;
}
S_STSIN(&sts);
S_MSGIN(&msg);
return 1;
}
/************************************************
* パケット送信命令発行 *
************************************************/
int SCSI_SENDPACKET(const unsigned char *buf, int len)
{
unsigned char cmd[10];
unsigned char sts;
unsigned char msg;
if (S_SELECT(scsiid) != 0) {
return 0;
}
cmd[0] = 0x2a;
cmd[1] = 0;
cmd[2] = 1;
cmd[3] = 1;
cmd[4] = 0;
cmd[5] = 0;
cmd[6] = (unsigned char)(len >> 16);
cmd[7] = (unsigned char)(len >> 8);
cmd[8] = (unsigned char)len;
cmd[9] = 0;
if (S_CMDOUT(10, cmd) != 0) {
return 0;
}
#ifdef USE_DMA
S_DATAOUT(len, buf);
#else
S_DATAOUT_P(len, buf);
#endif
S_STSIN(&sts);
S_MSGIN(&msg);
return 1;
}
/************************************************
* MACアドレス取得 *
************************************************/
int GetMacAddr(struct eaddr* buf)
{
if (SCSI_GETMACADDR(buf->eaddr) != 0) {
return 0;
} else {
return -1;
}
}
/************************************************
* MACアドレス設定 *
************************************************/
int SetMacAddr(const struct eaddr* data)
{
if (SCSI_SETMACADDR(data->eaddr) != 0) {
return 0;
} else {
return -1;
}
}
/************************************************
* RaSCSI検索 *
************************************************/
int SearchRaSCSI()
{
int i;
INQUIRYOPT_T inq;
for (i = 0; i <= 7; i++) {
// BRIDGEデバイス検索
if (S_INQUIRY(sizeof(INQUIRY_T) , i, (struct INQUIRY*)&inq) < 0) {
continue;
}
if (memcmp(&(inq.info.ProductID), "RASCSI BRIDGE", 13) != 0) {
continue;
}
// TAP初期化状態を取得
if (S_INQUIRY(sizeof(INQUIRYOPT_T) , i, (struct INQUIRY*)&inq) < 0) {
continue;
}
if (inq.options[1] != '1') {
continue;
}
// SCSI ID確定
scsiid = i;
return 0;
}
return -1;
}
/************************************************
* RaSCSI初期化 関数 *
************************************************/
int InitRaSCSI(void)
{
#ifdef MULTICAST
unsigned char multicast_table[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
#endif
imr = 0;
scsistop = 0;
poll_current = -1;
idle = 0;
return 0;
}
/************************************************
* RaSCSI 割り込み処理 関数(ポーリング) *
************************************************/
void interrupt IntProcess(void)
{
unsigned char phase;
unsigned int len;
int type;
int_handler func;
int i;
// V-DISP GPIP割り込みはアイドルカウンタで制御
if (intr_type == 0) {
// アイドル加算
idle++;
// 次回の処理予定に到達していないならスキップ
if (idle < poll_current) {
return;
}
// アイドルカウンタをクリア
idle = 0;
}
// 割り込み開始
// 割り込み許可の時だけ
if (imr == 0) {
return;
}
// IOCS実行中ならばスキップ
if (*iocsexec != -1) {
return;
}
// 受信処理中は割り込み禁止
DI ();
// バスフリーの時だけ
phase = S_PHASE();
if (phase != 0) {
// 終了
goto ei_exit;
}
// 受信処理
if (SCSI_GETPACKETLEN(&len) == 0) {
// RaSCSI停止中
scsistop = 1;
// ポーリング間隔の再設定(寝る)
UpdateIntProcess(POLLING_SLEEP);
// 終了
goto ei_exit;
}
// RaSCSIは動作中
if (scsistop) {
scsistop = 0;
// ポーリング間隔の再設定(急ぐ)
UpdateIntProcess(poll_interval);
}
// パケットは到着してなかった
if (len == 0) {
// 終了
goto ei_exit;
}
// 受信バッファメモリへパケット転送
if (SCSI_GETPACKETBUF(rx_buff, len) == 0) {
// 失敗
goto ei_exit;
}
// 割り込み許可
EI ();
// パケットタイプでデータ分別
type = rx_buff[12] * 256 + rx_buff[13];
i = 0;
while ((func = SearchList2(type, i))) {
i++;
func(len, (void*)&rx_buff, ID_EN0);
}
trans_counter.recv_byte += len;
return;
ei_exit:
// 割り込み許可
EI ();
}
/************************************************
* RaSCSI パケット送信 関数 (ne.sから) *
************************************************/
int SendPacket(int len, const unsigned char* data)
{
if (len < 1) {
return 0;
}
if (len > 1514) { // 6 + 6 + 2 + 1500
return -1; // エラー
}
// RaSCSI停止中のようならエラー
if (scsistop) {
return -1;
}
// 送信処理中は割り込み禁止
DI ();
// 送信処理と送信フラグアップ
if (SCSI_SENDPACKET(data, len) == 0) {
// 割り込み許可
EI ();
return -1;
}
// 割り込み許可
EI ();
// 送信依頼済み
trans_counter.send_byte += len;
return 0;
}
/************************************************
* RaSCSI 割り込み許可、不許可設定 関数 *
************************************************/
int SetPacketReception(int i)
{
imr = i;
return 0;
}
/************************************************
* RaSCSI 割り込み処理登録 *
************************************************/
void RegisterIntProcess(int n)
{
volatile unsigned char *p;
// ポーリング間隔(現在)の更新とアイドルカウンタクリア
poll_current = n;
idle = 0;
if (intr_type == 0) {
// V-DISP GPIP割り込みベクタを書き換えて
// 割り込みを有効にする
B_INTVCS(0x46, (int)IntProcess);
p = (unsigned char *)MFP_AEB;
*p = *p | 0x10;
p = (unsigned char *)MFP_IERB;
*p = *p | 0x40;
p = (unsigned char *)MFP_IMRB;
*p = *p | 0x40;
} else if (intr_type == 1) {
// TimerAはカウントモードを設定
VDISPST(NULL, 0, 0);
VDISPST(IntProcess, 0, poll_current);
}
}
/************************************************
* RaSCSI 割り込み処理変更 *
************************************************/
void UpdateIntProcess(int n)
{
// ポーリング間隔(現在)と同じなら更新しない
if (n == poll_current) {
return;
}
// ポーリング間隔(現在)の更新とアイドルカウンタクリア
poll_current = n;
idle = 0;
if (intr_type == 1) {
// TimerAは再登録必要
VDISPST(NULL, 0, 0);
VDISPST(IntProcess, 0, poll_current);
}
}
// EOF

View File

@@ -0,0 +1,40 @@
//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI (*^..^*)
// for Raspberry Pi
//
// Powered by XM6 TypeG Technorogy.
// Copyright (C) 2016-2017 GIMONS
// [ RaSCSI イーサーネット SCSI制御部 ]
//
// Based on
// Neptune-X board driver for Human-68k(ESP-X) version 0.03
// Programed 1996-7 by Shi-MAD.
// Special thanks to Niggle, FIRST, yamapu ...
//
//---------------------------------------------------------------------------
#ifndef scsictl_h
#define scsictl_h
// グローバル変数
extern int intr_type;
extern int poll_interval;
// 送受信カウンタ
struct trans_counter {
unsigned int send_byte;
unsigned int recv_byte;
};
extern struct trans_counter trans_counter;
extern int SearchRaSCSI();
extern int InitRaSCSI(void);
extern int GetMacAddr(struct eaddr* buf);
extern int SetMacAddr(const struct eaddr* data);
extern int SetPacketReception(int i);
extern int SendPacket(int len, const unsigned char* data);
extern void RegisterIntProcess(int n);
extern void UpdateIntProcess(int n);
#endif // scsictl_h