mirror of
https://github.com/dkgrizzly/GreenSCSI.git
synced 2024-12-01 18:51:57 +00:00
Google translation, no changes to code.
This commit is contained in:
parent
cca682596c
commit
24badde577
156
ArdSCSino.ino
156
ArdSCSino.ino
@ -1,10 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* SCSI-HDデバイスエミュレータ
|
* SCSI-HD device emulator
|
||||||
*/
|
*/
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include "SdFat.h"
|
#include "SdFat.h"
|
||||||
|
|
||||||
//ENABLE_EXTENDED_TRANSFER_CLASSを1に設定する
|
//Set ENABLE_EXTENDED_TRANSFER_CLASS to 1
|
||||||
//libraries/SdFat/SdFatConfig.h
|
//libraries/SdFat/SdFatConfig.h
|
||||||
SPIClass SPI_2(2);
|
SPIClass SPI_2(2);
|
||||||
SdFatEX SD(&SPI_2);
|
SdFatEX SD(&SPI_2);
|
||||||
@ -51,25 +51,25 @@ SdFatEX SD(&SPI_2);
|
|||||||
|
|
||||||
#define SCSIID 0 // SCSI-ID
|
#define SCSIID 0 // SCSI-ID
|
||||||
|
|
||||||
#define BLOCKSIZE 512 // 1BLOCKサイズ
|
#define BLOCKSIZE 512 // 1BLOCK size
|
||||||
uint8_t m_senseKey = 0; //センスキー
|
uint8_t m_senseKey = 0; // Sense key
|
||||||
volatile bool m_isBusReset = false; //バスリセット
|
volatile bool m_isBusReset = false; // Bus reset
|
||||||
|
|
||||||
#define HDIMG_FILE "HD.HDS" // HDイメージファイル名
|
#define HDIMG_FILE "HD.HDS" // HD image file name
|
||||||
File m_file; // ファイルオブジェクト
|
File m_file; // File object
|
||||||
uint32_t m_fileSize; // ファイルサイズ
|
uint32_t m_fileSize; // file size
|
||||||
byte m_buf[BLOCKSIZE]; // 汎用バッファ
|
byte m_buf[BLOCKSIZE]; // General purpose buffer
|
||||||
|
|
||||||
int m_msc;
|
int m_msc;
|
||||||
bool m_msb[256];
|
bool m_msb[256];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IO読み込み.
|
* IO read
|
||||||
*/
|
*/
|
||||||
inline byte readIO(void)
|
inline byte readIO(void)
|
||||||
{
|
{
|
||||||
//GPIO(SCSI BUS)初期化
|
//GPIO (SCSI BUS) initialization
|
||||||
//ポート設定レジスタ(下位
|
//Port setting register (lower level)
|
||||||
GPIOA->regs->CRL = 0x88888888; // Configure GPIOA[7:0]
|
GPIOA->regs->CRL = 0x88888888; // Configure GPIOA[7:0]
|
||||||
uint32 ret = GPIOA->regs->IDR;
|
uint32 ret = GPIOA->regs->IDR;
|
||||||
byte bret = 0x00;
|
byte bret = 0x00;
|
||||||
@ -85,15 +85,15 @@ inline byte readIO(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IO書き込み.
|
* IO writing.
|
||||||
*/
|
*/
|
||||||
inline void writeIO(byte v)
|
inline void writeIO(byte v)
|
||||||
{
|
{
|
||||||
//GPIO(SCSI BUS)初期化
|
//GPIO (SCSI BUS) initialization
|
||||||
//ポート設定レジスタ(下位)
|
//Port setting register (lower)
|
||||||
// GPIOA->regs->CRL = 0x11111111; // Configure GPIOA PP[7:0]10MHz
|
// GPIOA->regs->CRL = 0x11111111; // Configure GPIOA PP[7:0]10MHz
|
||||||
GPIOA->regs->CRL = 0x33333333; // Configure GPIOA PP[7:0]50MHz
|
GPIOA->regs->CRL = 0x33333333; // Configure GPIOA PP[7:0]50MHz
|
||||||
//ポート設定レジスタ(上位)
|
//Port setting register (upper)
|
||||||
GPIOA->regs->CRH = 0x00000003; // Configure GPIOA PP[16:8]50MHz
|
GPIOA->regs->CRH = 0x00000003; // Configure GPIOA PP[16:8]50MHz
|
||||||
uint32 retL = 0x00;
|
uint32 retL = 0x00;
|
||||||
uint32 retH = 0x00;
|
uint32 retH = 0x00;
|
||||||
@ -143,15 +143,15 @@ inline void writeIO(byte v)
|
|||||||
} else {
|
} else {
|
||||||
bitWrite(retH, 0, 1);
|
bitWrite(retH, 0, 1);
|
||||||
}
|
}
|
||||||
//ビットがLOWに設定される
|
// Bit set to LOW
|
||||||
GPIOA->regs->BRR = retL ;
|
GPIOA->regs->BRR = retL ;
|
||||||
// ビットがHIGHに設定される
|
// Bit set to HIGH
|
||||||
GPIOA->regs->BSRR = retH ;
|
GPIOA->regs->BSRR = retH ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 初期化.
|
* Initialization.
|
||||||
* パリティチェック
|
* Parity check
|
||||||
*/
|
*/
|
||||||
inline int parity(byte val) {
|
inline int parity(byte val) {
|
||||||
val ^= val >> 16;
|
val ^= val >> 16;
|
||||||
@ -164,25 +164,25 @@ inline int parity(byte val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 初期化.
|
* Initialization.
|
||||||
* バスの初期化、PINの向きの設定を行う
|
* Initialize the bus and set the PIN orientation
|
||||||
*/
|
*/
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
// PA15 / PB3 / PB4 が使えない
|
// PA15 / PB3 / PB4 Cannot be used
|
||||||
// JTAG デバッグ用に使われているからです。
|
// JTAG Because it is used for debugging.
|
||||||
disableDebugPorts();
|
disableDebugPorts();
|
||||||
|
|
||||||
//シリアル初期化
|
//Serial initialization
|
||||||
//Serial.begin(9600);
|
//Serial.begin(9600);
|
||||||
//while (!Serial);
|
//while (!Serial);
|
||||||
|
|
||||||
//PINの初期化
|
//PIN initialization
|
||||||
gpio_mode(LED, GPIO_OUTPUT_OD);
|
gpio_mode(LED, GPIO_OUTPUT_OD);
|
||||||
gpio_write(LED, low);
|
gpio_write(LED, low);
|
||||||
|
|
||||||
//GPIO(SCSI BUS)初期化
|
//GPIO(SCSI BUS)Initialization
|
||||||
//ポート設定レジスタ(下位)
|
//Port setting register (lower)
|
||||||
GPIOA->regs->CRL = 0x888888888; // Configure GPIOA[8:0]
|
GPIOA->regs->CRL = 0x888888888; // Configure GPIOA[8:0]
|
||||||
|
|
||||||
gpio_mode(ATN, GPIO_INPUT_PU);
|
gpio_mode(ATN, GPIO_INPUT_PU);
|
||||||
@ -201,14 +201,14 @@ void setup()
|
|||||||
gpio_write(REQ, low);
|
gpio_write(REQ, low);
|
||||||
gpio_write(IO, low);
|
gpio_write(IO, low);
|
||||||
|
|
||||||
//RSTピンの状態がHIGHからLOWに変わったときに発生
|
//Occurs when the RST pin state changes from HIGH to LOW
|
||||||
attachInterrupt(PIN_MAP[RST].gpio_bit, onBusReset, FALLING);
|
attachInterrupt(PIN_MAP[RST].gpio_bit, onBusReset, FALLING);
|
||||||
|
|
||||||
if(!SD.begin(SD_CS,SPI_FULL_SPEED)) {
|
if(!SD.begin(SD_CS,SPI_FULL_SPEED)) {
|
||||||
Serial.println("SD initialization failed!");
|
Serial.println("SD initialization failed!");
|
||||||
onFalseInit();
|
onFalseInit();
|
||||||
}
|
}
|
||||||
//HDイメージファイル
|
//HD image file
|
||||||
m_file = SD.open(HDIMG_FILE, O_RDWR);
|
m_file = SD.open(HDIMG_FILE, O_RDWR);
|
||||||
if(!m_file) {
|
if(!m_file) {
|
||||||
Serial.println("Error: open hdimg");
|
Serial.println("Error: open hdimg");
|
||||||
@ -225,7 +225,7 @@ void setup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 初期化失敗.
|
* Initialization failure.
|
||||||
*/
|
*/
|
||||||
void onFalseInit(void)
|
void onFalseInit(void)
|
||||||
{
|
{
|
||||||
@ -238,7 +238,7 @@ void onFalseInit(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* バスリセット割り込み.
|
* Bus reset interrupt.
|
||||||
*/
|
*/
|
||||||
void onBusReset(void)
|
void onBusReset(void)
|
||||||
{
|
{
|
||||||
@ -252,7 +252,7 @@ void onBusReset(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ハンドシェイクで読み込む.
|
* Read by handshake.
|
||||||
*/
|
*/
|
||||||
byte readHandshake(void)
|
byte readHandshake(void)
|
||||||
{
|
{
|
||||||
@ -273,7 +273,7 @@ byte readHandshake(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ハンドシェイクで書込み.
|
* Write with a handshake.
|
||||||
*/
|
*/
|
||||||
void writeHandshake(byte d)
|
void writeHandshake(byte d)
|
||||||
{
|
{
|
||||||
@ -293,8 +293,8 @@ void writeHandshake(byte d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* データインフェーズ.
|
* Data in phase.
|
||||||
* データ配列 p を len バイト送信する。
|
* Send len bytes of data array p.
|
||||||
*/
|
*/
|
||||||
void writeDataPhase(int len, byte* p)
|
void writeDataPhase(int len, byte* p)
|
||||||
{
|
{
|
||||||
@ -311,9 +311,9 @@ void writeDataPhase(int len, byte* p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* データインフェーズ.
|
* Data in phase.
|
||||||
* SDカードからの読み込みながら len ブロック送信する。
|
* Send len block while reading from SD card.
|
||||||
*/
|
*/
|
||||||
void writeDataPhaseSD(uint32_t adds, uint32_t len)
|
void writeDataPhaseSD(uint32_t adds, uint32_t len)
|
||||||
{
|
{
|
||||||
LOGN("DATAIN PHASE(SD)");
|
LOGN("DATAIN PHASE(SD)");
|
||||||
@ -334,9 +334,9 @@ void writeDataPhaseSD(uint32_t adds, uint32_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* データアウトフェーズ.
|
* Data out phase.
|
||||||
* len ブロック読み込みながら SDカードへ書き込む。
|
* Write to SD card while reading len block.
|
||||||
*/
|
*/
|
||||||
void readDataPhaseSD(uint32_t adds, uint32_t len)
|
void readDataPhaseSD(uint32_t adds, uint32_t len)
|
||||||
{
|
{
|
||||||
LOGN("DATAOUT PHASE(SD)");
|
LOGN("DATAOUT PHASE(SD)");
|
||||||
@ -358,18 +358,18 @@ void readDataPhaseSD(uint32_t adds, uint32_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* INQUIRY コマンド処理.
|
* INQUIRY command processing.
|
||||||
*/
|
*/
|
||||||
void onInquiryCommand(byte len)
|
void onInquiryCommand(byte len)
|
||||||
{
|
{
|
||||||
byte buf[36] = {
|
byte buf[36] = {
|
||||||
0x00, //デバイスタイプ
|
0x00, //Device type
|
||||||
0x00, //RMB = 0
|
0x00, //RMB = 0
|
||||||
0x01, //ISO,ECMA,ANSIバージョン
|
0x01, //ISO,ECMA,ANSI version
|
||||||
0x01, //レスポンスデータ形式
|
0x01, //Response data format
|
||||||
35 - 4, //追加データ長
|
35 - 4, //Additional data length
|
||||||
0, 0, //Reserve
|
0, 0, //Reserve
|
||||||
0x00, //サポート機能
|
0x00, //Support function
|
||||||
'T', 'N', 'B', ' ', ' ', ' ', ' ', ' ',
|
'T', 'N', 'B', ' ', ' ', ' ', ' ', ' ',
|
||||||
'A', 'r', 'd', 'S', 'C', 'S', 'i', 'n', 'o', ' ', ' ',' ', ' ', ' ', ' ', ' ',
|
'A', 'r', 'd', 'S', 'C', 'S', 'i', 'n', 'o', ' ', ' ',' ', ' ', ' ', ' ', ' ',
|
||||||
'0', '0', '1', '0',
|
'0', '0', '1', '0',
|
||||||
@ -378,16 +378,16 @@ void onInquiryCommand(byte len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* REQUEST SENSE コマンド処理.
|
* REQUEST SENSE command processing.
|
||||||
*/
|
*/
|
||||||
void onRequestSenseCommand(byte len)
|
void onRequestSenseCommand(byte len)
|
||||||
{
|
{
|
||||||
byte buf[18] = {
|
byte buf[18] = {
|
||||||
0x70, //CheckCondition
|
0x70, //CheckCondition
|
||||||
0, //セグメント番号
|
0, //Segment number
|
||||||
0x00, //センスキー
|
0x00, //Sense key
|
||||||
0, 0, 0, 0, //インフォメーション
|
0, 0, 0, 0, //information
|
||||||
17 - 7 , //追加データ長
|
17 - 7 , //Additional data length
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
buf[2] = m_senseKey;
|
buf[2] = m_senseKey;
|
||||||
@ -396,7 +396,7 @@ void onRequestSenseCommand(byte len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* READ CAPACITY コマンド処理.
|
* READ CAPACITY command processing.
|
||||||
*/
|
*/
|
||||||
void onReadCapacityCommand(byte pmi)
|
void onReadCapacityCommand(byte pmi)
|
||||||
{
|
{
|
||||||
@ -410,7 +410,7 @@ void onReadCapacityCommand(byte pmi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* READ6/10 コマンド処理.
|
* READ6/10 Command processing.
|
||||||
*/
|
*/
|
||||||
byte onReadCommand(uint32_t adds, uint32_t len)
|
byte onReadCommand(uint32_t adds, uint32_t len)
|
||||||
{
|
{
|
||||||
@ -424,7 +424,7 @@ byte onReadCommand(uint32_t adds, uint32_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* WRITE6/10 コマンド処理.
|
* WRITE6/10 Command processing.
|
||||||
*/
|
*/
|
||||||
byte onWriteCommand(uint32_t adds, uint32_t len)
|
byte onWriteCommand(uint32_t adds, uint32_t len)
|
||||||
{
|
{
|
||||||
@ -438,7 +438,7 @@ byte onWriteCommand(uint32_t adds, uint32_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MODE SENSE コマンド処理.
|
* MODE SENSE command processing.
|
||||||
*/
|
*/
|
||||||
void onModeSenseCommand(byte dbd, int pageCode, uint32_t len)
|
void onModeSenseCommand(byte dbd, int pageCode, uint32_t len)
|
||||||
{
|
{
|
||||||
@ -448,7 +448,7 @@ void onModeSenseCommand(byte dbd, int pageCode, uint32_t len)
|
|||||||
uint32_t bc = m_fileSize / BLOCKSIZE;
|
uint32_t bc = m_fileSize / BLOCKSIZE;
|
||||||
uint32_t bl = BLOCKSIZE;
|
uint32_t bl = BLOCKSIZE;
|
||||||
byte c[8] = {
|
byte c[8] = {
|
||||||
0,//デンシティコード
|
0,//Dense code
|
||||||
bc >> 16, bc >> 8, bc,
|
bc >> 16, bc >> 8, bc,
|
||||||
0, //Reserve
|
0, //Reserve
|
||||||
bl >> 16, bl >> 8, bl
|
bl >> 16, bl >> 8, bl
|
||||||
@ -459,23 +459,23 @@ void onModeSenseCommand(byte dbd, int pageCode, uint32_t len)
|
|||||||
}
|
}
|
||||||
switch(pageCode) {
|
switch(pageCode) {
|
||||||
case 0x3F:
|
case 0x3F:
|
||||||
case 0x03: //ドライブパラメータ
|
case 0x03: //Drive parameters
|
||||||
m_buf[a + 0] = 0x03; //ページコード
|
m_buf[a + 0] = 0x03; //Page code
|
||||||
m_buf[a + 1] = 0x16; // ページ長
|
m_buf[a + 1] = 0x16; //Page length
|
||||||
m_buf[a + 11] = 0x3F;//セクタ数/トラック
|
m_buf[a + 11] = 0x3F;//number of sectors/track
|
||||||
a += 24;
|
a += 24;
|
||||||
if(pageCode != 0x3F) {
|
if(pageCode != 0x3F) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x04: //ドライブパラメータ
|
case 0x04: //Drive parameters
|
||||||
{
|
{
|
||||||
uint32_t bc = m_fileSize / BLOCKSIZE;
|
uint32_t bc = m_fileSize / BLOCKSIZE;
|
||||||
m_buf[a + 0] = 0x04; //ページコード
|
m_buf[a + 0] = 0x04; //Page code
|
||||||
m_buf[a + 1] = 0x16; // ページ長
|
m_buf[a + 1] = 0x16; // Page length
|
||||||
m_buf[a + 2] = bc >> 16;// シリンダ長
|
m_buf[a + 2] = bc >> 16;// Cylinder length
|
||||||
m_buf[a + 3] = bc >> 8;
|
m_buf[a + 3] = bc >> 8;
|
||||||
m_buf[a + 4] = bc;
|
m_buf[a + 4] = bc;
|
||||||
m_buf[a + 5] = 1; //ヘッド数
|
m_buf[a + 5] = 1; //Number of heads
|
||||||
a += 24;
|
a += 24;
|
||||||
}
|
}
|
||||||
if(pageCode != 0x3F) {
|
if(pageCode != 0x3F) {
|
||||||
@ -515,20 +515,20 @@ void MsgOut2()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* メインループ.
|
* Main loop.
|
||||||
*/
|
*/
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
int sts = 0;
|
int sts = 0;
|
||||||
int msg = 0;
|
int msg = 0;
|
||||||
|
|
||||||
//BSY,SELが+はバスフリー
|
//BSY,SEL + is bus free
|
||||||
// セレクションチェック
|
// Selection check
|
||||||
// BSYが-の間ループ
|
// Loop between BSY-
|
||||||
if(isHigh(gpio_read(BSY))) {
|
if(isHigh(gpio_read(BSY))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// SELが+の間ループ
|
// Loop while SEL is +
|
||||||
if(isLow(gpio_read(SEL))) {
|
if(isLow(gpio_read(SEL))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -540,7 +540,7 @@ void loop()
|
|||||||
|
|
||||||
LOGN("Selection");
|
LOGN("Selection");
|
||||||
m_isBusReset = false;
|
m_isBusReset = false;
|
||||||
// セレクトされたらBSYを-にする
|
// Set BSY to-when selected
|
||||||
gpio_mode(BSY, GPIO_OUTPUT_PP);
|
gpio_mode(BSY, GPIO_OUTPUT_PP);
|
||||||
gpio_write(BSY, high);
|
gpio_write(BSY, high);
|
||||||
while(isHigh(gpio_read(SEL))) {
|
while(isHigh(gpio_read(SEL))) {
|
||||||
@ -570,24 +570,24 @@ void loop()
|
|||||||
// IDENTIFY
|
// IDENTIFY
|
||||||
if (m_msb[i] >= 0x80) {
|
if (m_msb[i] >= 0x80) {
|
||||||
}
|
}
|
||||||
// 拡張メッセージ
|
// Extended message
|
||||||
if (m_msb[i] == 0x01) {
|
if (m_msb[i] == 0x01) {
|
||||||
// 同期転送が可能な時だけチェック
|
// Check only when synchronous transfer is possible
|
||||||
if (!syncenable || m_msb[i + 2] != 0x01) {
|
if (!syncenable || m_msb[i + 2] != 0x01) {
|
||||||
MsgIn2(0x07);
|
MsgIn2(0x07);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Transfer period factor(50 x 4 = 200nsに制限)
|
// Transfer period factor(50 x 4 = Limited to 200ns)
|
||||||
syncperiod = m_msb[i + 3];
|
syncperiod = m_msb[i + 3];
|
||||||
if (syncperiod > 50) {
|
if (syncperiod > 50) {
|
||||||
syncoffset = 50;
|
syncoffset = 50;
|
||||||
}
|
}
|
||||||
// REQ/ACK offset(16に制限)
|
// REQ/ACK offset(Limited to 16)
|
||||||
syncoffset = m_msb[i + 4];
|
syncoffset = m_msb[i + 4];
|
||||||
if (syncoffset > 16) {
|
if (syncoffset > 16) {
|
||||||
syncoffset = 16;
|
syncoffset = 16;
|
||||||
}
|
}
|
||||||
// STDR応答メッセージ生成
|
// STDR response message generation
|
||||||
MsgIn2(0x01);
|
MsgIn2(0x01);
|
||||||
MsgIn2(0x03);
|
MsgIn2(0x03);
|
||||||
MsgIn2(0x01);
|
MsgIn2(0x01);
|
||||||
|
Loading…
Reference in New Issue
Block a user