Google translation, no changes to code.

This commit is contained in:
Eric Helgeson 2020-09-11 11:19:16 -05:00 committed by Eric Helgeson
parent cca682596c
commit 24badde577

View File

@ -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);