RASCSI/src/raspberrypi/disk.h
2020-07-06 19:23:54 -05:00

1145 lines
31 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//---------------------------------------------------------------------------
//
// X68000 EMULATOR "XM6"
//
// Copyright (C) 2001-2006 (ytanaka@ipc-tokai.or.jp)
// Copyright (C) 2014-2020 GIMONS
//
// XM6i
// Copyright (C) 2010-2015 isaki@NetBSD.org
//
// Imported sava's Anex86/T98Next image and MO format support patch.
// Comments translated to english by akuker.
//
// [ Disk ]
//
//---------------------------------------------------------------------------
#if !defined(disk_h)
#define disk_h
#include "log.h"
#include "scsi.h"
//---------------------------------------------------------------------------
//
// Error definition (sense code returned by REQUEST SENSE)
//
// MSB Reserved (0x00)
// Sense Key
// Additional Sense Code (ASC)
// LSB Additional Sense Code Qualifier(ASCQ)
//
//---------------------------------------------------------------------------
#define DISK_NOERROR 0x00000000 // NO ADDITIONAL SENSE INFO.
#define DISK_DEVRESET 0x00062900 // POWER ON OR RESET OCCURED
#define DISK_NOTREADY 0x00023a00 // MEDIUM NOT PRESENT
#define DISK_ATTENTION 0x00062800 // MEDIUM MAY HAVE CHANGED
#define DISK_PREVENT 0x00045302 // MEDIUM REMOVAL PREVENTED
#define DISK_READFAULT 0x00031100 // UNRECOVERED READ ERROR
#define DISK_WRITEFAULT 0x00030300 // PERIPHERAL DEVICE WRITE FAULT
#define DISK_WRITEPROTECT 0x00042700 // WRITE PROTECTED
#define DISK_MISCOMPARE 0x000e1d00 // MISCOMPARE DURING VERIFY
#define DISK_INVALIDCMD 0x00052000 // INVALID COMMAND OPERATION CODE
#define DISK_INVALIDLBA 0x00052100 // LOGICAL BLOCK ADDR. OUT OF RANGE
#define DISK_INVALIDCDB 0x00052400 // INVALID FIELD IN CDB
#define DISK_INVALIDLUN 0x00052500 // LOGICAL UNIT NOT SUPPORTED
#define DISK_INVALIDPRM 0x00052600 // INVALID FIELD IN PARAMETER LIST
#define DISK_INVALIDMSG 0x00054900 // INVALID MESSAGE ERROR
#define DISK_PARAMLEN 0x00051a00 // PARAMETERS LIST LENGTH ERROR
#define DISK_PARAMNOT 0x00052601 // PARAMETERS NOT SUPPORTED
#define DISK_PARAMVALUE 0x00052602 // PARAMETERS VALUE INVALID
#define DISK_PARAMSAVE 0x00053900 // SAVING PARAMETERS NOT SUPPORTED
#define DISK_NODEFECT 0x00010000 // DEFECT LIST NOT FOUND
#if 0
#define DISK_AUDIOPROGRESS 0x00??0011 // AUDIO PLAY IN PROGRESS
#define DISK_AUDIOPAUSED 0x00??0012 // AUDIO PLAY PAUSED
#define DISK_AUDIOSTOPPED 0x00??0014 // AUDIO PLAY STOPPED DUE TO ERROR
#define DISK_AUDIOCOMPLETE 0x00??0013 // AUDIO PLAY SUCCESSFULLY COMPLETED
#endif
//===========================================================================
//
// Disk Track
//
//===========================================================================
class DiskTrack
{
public:
// Internal data definition
typedef struct {
int track; // Track Number
int size; // Sector Size(8 or 9)
int sectors; // Number of sectors(<=0x100)
DWORD length; // Data buffer length
BYTE *buffer; // Data buffer
BOOL init; // Is it initilized?
BOOL changed; // Changed flag
DWORD maplen; // Changed map length
BOOL *changemap; // Changed map
BOOL raw; // RAW mode flag
off64_t imgoffset; // Offset to actual data
} disktrk_t;
public:
// Basic Functions
DiskTrack();
// Constructor
virtual ~DiskTrack();
// Destructor
void FASTCALL Init(int track, int size, int sectors, BOOL raw = FALSE,
off64_t imgoff = 0);
// Initialization
BOOL FASTCALL Load(const Filepath& path);
// Load
BOOL FASTCALL Save(const Filepath& path);
// Save
// Read / Write
BOOL FASTCALL Read(BYTE *buf, int sec) const;
// Sector Read
BOOL FASTCALL Write(const BYTE *buf, int sec);
// Sector Write
// Other
int FASTCALL GetTrack() const { return dt.track; }
// Get track
BOOL FASTCALL IsChanged() const { return dt.changed; }
// Changed flag check
private:
// Internal data
disktrk_t dt;
// Internal data
};
//===========================================================================
//
// Disk Cache
//
//===========================================================================
class DiskCache
{
public:
// Internal data definition
typedef struct {
DiskTrack *disktrk; // Disk Track
DWORD serial; // Serial
} cache_t;
// Number of caches
enum {
CacheMax = 16 // Number of tracks to cache
};
public:
// Basic Functions
DiskCache(const Filepath& path, int size, int blocks,
off64_t imgoff = 0);
// Constructor
virtual ~DiskCache();
// Destructor
void FASTCALL SetRawMode(BOOL raw);
// CD-ROM raw mode setting
// Access
BOOL FASTCALL Save();
// Save and release all
BOOL FASTCALL Read(BYTE *buf, int block);
// Sector Read
BOOL FASTCALL Write(const BYTE *buf, int block);
// Sector Write
BOOL FASTCALL GetCache(int index, int& track, DWORD& serial) const;
// Get cache information
private:
// Internal Management
void FASTCALL Clear();
// Clear all tracks
DiskTrack* FASTCALL Assign(int track);
// Load track
BOOL FASTCALL Load(int index, int track, DiskTrack *disktrk = NULL);
// Load track
void FASTCALL Update();
// Update serial number
// Internal data
cache_t cache[CacheMax];
// Cache management
DWORD serial;
// Last serial number
Filepath sec_path;
// Path
int sec_size;
// Sector size (8 or 9 or 11)
int sec_blocks;
// Blocks per sector
BOOL cd_raw;
// CD-ROM RAW mode
off64_t imgoffset;
// Offset to actual data
};
//===========================================================================
//
// Disk
//
//===========================================================================
class Disk
{
public:
// Internal data structure
typedef struct {
DWORD id; // Media ID
BOOL ready; // Valid Disk
BOOL writep; // Write protected
BOOL readonly; // Read only
BOOL removable; // Removable
BOOL lock; // Locked
BOOL attn; // Attention
BOOL reset; // Reset
int size; // Sector Size
DWORD blocks; // Total number of sectors
DWORD lun; // LUN
DWORD code; // Status code
DiskCache *dcache; // Disk cache
off64_t imgoffset; // Offset to actual data
} disk_t;
public:
// Basic Functions
Disk();
// Constructor
virtual ~Disk();
// Destructor
virtual void FASTCALL Reset();
// Device Reset
#ifndef RASCSI
virtual BOOL FASTCALL Save(Fileio *fio, int ver);
// Save
virtual BOOL FASTCALL Load(Fileio *fio, int ver);
// Load
#endif // RASCSI
// ID
DWORD FASTCALL GetID() const { return disk.id; }
// Get media ID
BOOL FASTCALL IsNULL() const;
// NULL check
BOOL FASTCALL IsSASI() const;
// SASI Check
// Media Operations
virtual BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE);
// Open
void FASTCALL GetPath(Filepath& path) const;
// Get the path
void FASTCALL Eject(BOOL force);
// Eject
BOOL FASTCALL IsReady() const { return disk.ready; }
// Ready check
void FASTCALL WriteP(BOOL flag);
// Set Write Protect flag
BOOL FASTCALL IsWriteP() const { return disk.writep; }
// Get write protect flag
BOOL FASTCALL IsReadOnly() const { return disk.readonly; }
// Get read only flag
BOOL FASTCALL IsRemovable() const { return disk.removable; }
// Get is removable flag
BOOL FASTCALL IsLocked() const { return disk.lock; }
// Get locked status
BOOL FASTCALL IsAttn() const { return disk.attn; }
// Get attention flag
BOOL FASTCALL Flush();
// Flush the cache
void FASTCALL GetDisk(disk_t *buffer) const;
// Get the internal data struct
// Properties
void FASTCALL SetLUN(DWORD lun) { disk.lun = lun; }
// LUN set
DWORD FASTCALL GetLUN() { return disk.lun; }
// LUN get
// commands
virtual int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor);
// INQUIRY command
virtual int FASTCALL RequestSense(const DWORD *cdb, BYTE *buf);
// REQUEST SENSE command
int FASTCALL SelectCheck(const DWORD *cdb);
// SELECT check
int FASTCALL SelectCheck10(const DWORD *cdb);
// SELECT(10) check
virtual BOOL FASTCALL ModeSelect(const DWORD *cdb, const BYTE *buf, int length);
// MODE SELECT command
virtual int FASTCALL ModeSense(const DWORD *cdb, BYTE *buf);
// MODE SENSE command
virtual int FASTCALL ModeSense10(const DWORD *cdb, BYTE *buf);
// MODE SENSE(10) command
int FASTCALL ReadDefectData10(const DWORD *cdb, BYTE *buf);
// READ DEFECT DATA(10) command
virtual BOOL FASTCALL TestUnitReady(const DWORD *cdb);
// TEST UNIT READY command
BOOL FASTCALL Rezero(const DWORD *cdb);
// REZERO command
BOOL FASTCALL Format(const DWORD *cdb);
// FORMAT UNIT command
BOOL FASTCALL Reassign(const DWORD *cdb);
// REASSIGN UNIT command
virtual int FASTCALL Read(BYTE *buf, DWORD block);
// READ command
int FASTCALL WriteCheck(DWORD block);
// WRITE check
BOOL FASTCALL Write(const BYTE *buf, DWORD block);
// WRITE command
BOOL FASTCALL Seek(const DWORD *cdb);
// SEEK command
BOOL FASTCALL Assign(const DWORD *cdb);
// ASSIGN command
BOOL FASTCALL Specify(const DWORD *cdb);
// SPECIFY command
BOOL FASTCALL StartStop(const DWORD *cdb);
// START STOP UNIT command
BOOL FASTCALL SendDiag(const DWORD *cdb);
// SEND DIAGNOSTIC command
BOOL FASTCALL Removal(const DWORD *cdb);
// PREVENT/ALLOW MEDIUM REMOVAL command
int FASTCALL ReadCapacity(const DWORD *cdb, BYTE *buf);
// READ CAPACITY command
BOOL FASTCALL Verify(const DWORD *cdb);
// VERIFY command
virtual int FASTCALL ReadToc(const DWORD *cdb, BYTE *buf);
// READ TOC command
virtual BOOL FASTCALL PlayAudio(const DWORD *cdb);
// PLAY AUDIO command
virtual BOOL FASTCALL PlayAudioMSF(const DWORD *cdb);
// PLAY AUDIO MSF command
virtual BOOL FASTCALL PlayAudioTrack(const DWORD *cdb);
// PLAY AUDIO TRACK command
void FASTCALL InvalidCmd() { disk.code = DISK_INVALIDCMD; }
// Unsupported command
// Other
BOOL IsCacheWB() { return cache_wb; }
// Get cache writeback mode
void SetCacheWB(BOOL enable) { cache_wb = enable; }
// Set cache writeback mode
protected:
// Internal processing
virtual int FASTCALL AddError(BOOL change, BYTE *buf);
// Add error
virtual int FASTCALL AddFormat(BOOL change, BYTE *buf);
// Add format
virtual int FASTCALL AddDrive(BOOL change, BYTE *buf);
// Add drive
int FASTCALL AddOpt(BOOL change, BYTE *buf);
// Add optical
int FASTCALL AddCache(BOOL change, BYTE *buf);
// Add cache
int FASTCALL AddCDROM(BOOL change, BYTE *buf);
// Add CD-ROM
int FASTCALL AddCDDA(BOOL change, BYTE *buf);
// Add CD_DA
virtual int FASTCALL AddVendor(int page, BOOL change, BYTE *buf);
// Add vendor special info
BOOL FASTCALL CheckReady();
// Check if ready
// Internal data
disk_t disk;
// Internal disk data
Filepath diskpath;
// File path (for GetPath)
BOOL cache_wb;
// Cache mode
};
//===========================================================================
//
// SASI Hard Disk
//
//===========================================================================
class SASIHD : public Disk
{
public:
// Basic Functions
SASIHD();
// Constructor
void FASTCALL Reset();
// Reset
BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE);
// Open
// commands
int FASTCALL RequestSense(const DWORD *cdb, BYTE *buf);
// REQUEST SENSE command
};
//===========================================================================
//
// SCSI Hard Disk
//
//===========================================================================
class SCSIHD : public Disk
{
public:
// Basic Functions
SCSIHD();
// Constructor
void FASTCALL Reset();
// Reset
BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE);
// Open
// commands
int FASTCALL Inquiry(
const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor);
// INQUIRY command
BOOL FASTCALL ModeSelect(const DWORD *cdb, const BYTE *buf, int length);
// MODE SELECT(6) command
};
//===========================================================================
//
// SCSI hard disk (PC-9801-55 NEC genuine /Anex86/T98Next)
//
//===========================================================================
class SCSIHD_NEC : public SCSIHD
{
public:
// Basic Functions
SCSIHD_NEC();
// Constructor
BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE);
// Open
// commands
int FASTCALL Inquiry(
const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor);
// INQUIRY command
// Internal processing
int FASTCALL AddError(BOOL change, BYTE *buf);
// Add error
int FASTCALL AddFormat(BOOL change, BYTE *buf);
// Add format
int FASTCALL AddDrive(BOOL change, BYTE *buf);
// Add drive
private:
int cylinders;
// Number of cylinders
int heads;
// Number of heads
int sectors;
// Number of sectors
int sectorsize;
// Sector size
off64_t imgoffset;
// Image offset
off64_t imgsize;
// Image size
};
//===========================================================================
//
// SCSI Hard Disk(Genuine Apple Macintosh)
//
//===========================================================================
class SCSIHD_APPLE : public SCSIHD
{
public:
// Basic Functions
SCSIHD_APPLE();
// Constructor
// commands
int FASTCALL Inquiry(
const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor);
// INQUIRY command
// Internal processing
int FASTCALL AddVendor(int page, BOOL change, BYTE *buf);
// Add vendor special page
};
//===========================================================================
//
// SCSI magneto-optical disk
//
//===========================================================================
class SCSIMO : public Disk
{
public:
// Basic Functions
SCSIMO();
// Constructor
BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE);
// Open
#ifndef RASCSI
BOOL FASTCALL Load(Fileio *fio, int ver);
// Load
#endif // RASCSI
// commands
int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor);
// INQUIRY command
BOOL FASTCALL ModeSelect(const DWORD *cdb, const BYTE *buf, int length);
// MODE SELECT(6) command
// Internal processing
int FASTCALL AddVendor(int page, BOOL change, BYTE *buf);
// Add vendor special page
};
//---------------------------------------------------------------------------
//
// Class precedence definition
//
//---------------------------------------------------------------------------
class SCSICD;
//===========================================================================
//
// CD-ROM Track
//
//===========================================================================
class CDTrack
{
public:
// Basic Functions
CDTrack(SCSICD *scsicd);
// Constructor
virtual ~CDTrack();
// Destructor
BOOL FASTCALL Init(int track, DWORD first, DWORD last);
// Initialization
// Properties
void FASTCALL SetPath(BOOL cdda, const Filepath& path);
// Set the path
void FASTCALL GetPath(Filepath& path) const;
// Get the path
void FASTCALL AddIndex(int index, DWORD lba);
// Add index
DWORD FASTCALL GetFirst() const;
// Get the start LBA
DWORD FASTCALL GetLast() const;
// Get the last LBA
DWORD FASTCALL GetBlocks() const;
// Get the number of blocks
int FASTCALL GetTrackNo() const;
// Get the track number
BOOL FASTCALL IsValid(DWORD lba) const;
// Is this a valid LBA?
BOOL FASTCALL IsAudio() const;
// Is this an audio track?
private:
SCSICD *cdrom;
// Parent device
BOOL valid;
// Valid track
int track_no;
// Track number
DWORD first_lba;
// First LBA
DWORD last_lba;
// Last LBA
BOOL audio;
// Audio track flag
BOOL raw;
// RAW data flag
Filepath imgpath;
// Image file path
};
//===========================================================================
//
// CD-DA Buffer
//
//===========================================================================
class CDDABuf
{
public:
// Basic Functions
CDDABuf();
// Constructor
virtual ~CDDABuf();
// Destructor
#if 0
BOOL Init();
// Initialization
BOOL FASTCALL Load(const Filepath& path);
// Load
BOOL FASTCALL Save(const Filepath& path);
// Save
// API
void FASTCALL Clear();
// Clear the buffer
BOOL FASTCALL Open(Filepath& path);
// File specification
BOOL FASTCALL GetBuf(DWORD *buffer, int frames);
// Get the buffer
BOOL FASTCALL IsValid();
// Check if Valid
BOOL FASTCALL ReadReq();
// Read Request
BOOL FASTCALL IsEnd() const;
// Finish check
private:
Filepath wavepath;
// Wave path
BOOL valid;
// Open result (is it valid?)
DWORD *buf;
// Data buffer
DWORD read;
// Read pointer
DWORD write;
// Write pointer
DWORD num;
// Valid number of data
DWORD rest;
// Remaining file size
#endif
};
//===========================================================================
//
// SCSI CD-ROM
//
//===========================================================================
class SCSICD : public Disk
{
public:
// Number of tracks
enum {
TrackMax = 96 // Maximum number of tracks
};
public:
// Basic Functions
SCSICD();
// Constructor
virtual ~SCSICD();
// Destructor
BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE);
// Open
#ifndef RASCSI
BOOL FASTCALL Load(Fileio *fio, int ver);
// Load
#endif // RASCSI
// commands
int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor);
// INQUIRY command
int FASTCALL Read(BYTE *buf, DWORD block);
// READ command
int FASTCALL ReadToc(const DWORD *cdb, BYTE *buf);
// READ TOC command
BOOL FASTCALL PlayAudio(const DWORD *cdb);
// PLAY AUDIO command
BOOL FASTCALL PlayAudioMSF(const DWORD *cdb);
// PLAY AUDIO MSF command
BOOL FASTCALL PlayAudioTrack(const DWORD *cdb);
// PLAY AUDIO TRACK command
// CD-DA
BOOL FASTCALL NextFrame();
// Frame notification
void FASTCALL GetBuf(DWORD *buffer, int samples, DWORD rate);
// Get CD-DA buffer
// LBA-MSF変換
void FASTCALL LBAtoMSF(DWORD lba, BYTE *msf) const;
// LBA→MSF conversion
DWORD FASTCALL MSFtoLBA(const BYTE *msf) const;
// MSF→LBA conversion
private:
// Open
BOOL FASTCALL OpenCue(const Filepath& path);
// Open(CUE)
BOOL FASTCALL OpenIso(const Filepath& path);
// Open(ISO)
BOOL FASTCALL OpenPhysical(const Filepath& path);
// Open(Physical)
BOOL rawfile;
// RAW flag
// Track management
void FASTCALL ClearTrack();
// Clear the track
int FASTCALL SearchTrack(DWORD lba) const;
// Track search
CDTrack* track[TrackMax];
// Track opbject references
int tracks;
// Effective number of track objects
int dataindex;
// Current data track
int audioindex;
// Current audio track
int frame;
// Frame number
#if 0
CDDABuf da_buf;
// CD-DA buffer
int da_num;
// Number of CD-DA tracks
int da_cur;
// CD-DA current track
int da_next;
// CD-DA next track
BOOL da_req;
// CD-DA data request
#endif
};
//===========================================================================
//
// SCSI Host Bridge
//
//===========================================================================
#if defined(RASCSI) && !defined(BAREMETAL)
class CTapDriver;
#endif // RASCSI && !BAREMETAL
class CFileSys;
class SCSIBR : public Disk
{
public:
// Basic Functions
SCSIBR();
// Constructor
virtual ~SCSIBR();
// Destructor
// commands
int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor);
// INQUIRY command
BOOL FASTCALL TestUnitReady(const DWORD *cdb);
// TEST UNIT READY command
int FASTCALL GetMessage10(const DWORD *cdb, BYTE *buf);
// GET MESSAGE10 command
BOOL FASTCALL SendMessage10(const DWORD *cdb, BYTE *buf);
// SEND MESSAGE10 command
private:
#if defined(RASCSI) && !defined(BAREMETAL)
int FASTCALL GetMacAddr(BYTE *buf);
// Get MAC address
void FASTCALL SetMacAddr(BYTE *buf);
// Set MAC address
void FASTCALL ReceivePacket();
// Receive a packet
void FASTCALL GetPacketBuf(BYTE *buf);
// Get a packet
void FASTCALL SendPacket(BYTE *buf, int len);
// Send a packet
CTapDriver *tap;
// TAP driver
BOOL m_bTapEnable;
// TAP valid flag
BYTE mac_addr[6];
// MAC Addres
int packet_len;
// Receive packet size
BYTE packet_buf[0x1000];
// Receive packet buffer
BOOL packet_enable;
// Received packet valid
#endif // RASCSI && !BAREMETAL
int FASTCALL ReadFsResult(BYTE *buf);
// Read filesystem (result code)
int FASTCALL ReadFsOut(BYTE *buf);
// Read filesystem (return data)
int FASTCALL ReadFsOpt(BYTE *buf);
// Read file system (optional data)
void FASTCALL WriteFs(int func, BYTE *buf);
// File system write (execute)
void FASTCALL WriteFsOpt(BYTE *buf, int len);
// File system write (optional data)
// Command handlers
void FASTCALL FS_InitDevice(BYTE *buf);
// $40 - boot
void FASTCALL FS_CheckDir(BYTE *buf);
// $41 - directory check
void FASTCALL FS_MakeDir(BYTE *buf);
// $42 - create directory
void FASTCALL FS_RemoveDir(BYTE *buf);
// $43 - delete directory
void FASTCALL FS_Rename(BYTE *buf);
// $44 - change filename
void FASTCALL FS_Delete(BYTE *buf);
// $45 - delete file
void FASTCALL FS_Attribute(BYTE *buf);
// $46 - get/set file attributes
void FASTCALL FS_Files(BYTE *buf);
// $47 - file search
void FASTCALL FS_NFiles(BYTE *buf);
// $48 - find next file
void FASTCALL FS_Create(BYTE *buf);
// $49 - create file
void FASTCALL FS_Open(BYTE *buf);
// $4A - open file
void FASTCALL FS_Close(BYTE *buf);
// $4B - close file
void FASTCALL FS_Read(BYTE *buf);
// $4C - read file
void FASTCALL FS_Write(BYTE *buf);
// $4D - write file
void FASTCALL FS_Seek(BYTE *buf);
// $4E - seek file
void FASTCALL FS_TimeStamp(BYTE *buf);
// $4F - get/set file time
void FASTCALL FS_GetCapacity(BYTE *buf);
// $50 - get capacity
void FASTCALL FS_CtrlDrive(BYTE *buf);
// $51 - drive status check/control
void FASTCALL FS_GetDPB(BYTE *buf);
// $52 - get DPB
void FASTCALL FS_DiskRead(BYTE *buf);
// $53 - read sector
void FASTCALL FS_DiskWrite(BYTE *buf);
// $54 - write sector
void FASTCALL FS_Ioctrl(BYTE *buf);
// $55 - IOCTRL
void FASTCALL FS_Flush(BYTE *buf);
// $56 - flush cache
void FASTCALL FS_CheckMedia(BYTE *buf);
// $57 - check media
void FASTCALL FS_Lock(BYTE *buf);
// $58 - get exclusive control
CFileSys *fs;
// File system accessor
DWORD fsresult;
// File system access result code
BYTE fsout[0x800];
// File system access result buffer
DWORD fsoutlen;
// File system access result buffer size
BYTE fsopt[0x1000000];
// File system access buffer
DWORD fsoptlen;
// File system access buffer size
};
//===========================================================================
//
// SASI Controller
//
//===========================================================================
class SASIDEV
{
public:
// Maximum number of logical units
enum {
UnitMax = 8
};
#ifdef RASCSI
// For timing adjustments
enum {
min_exec_time_sasi = 100, // SASI BOOT/FORMAT 30:NG 35:OK
min_exec_time_scsi = 50
};
#endif // RASCSI
// Internal data definition
typedef struct {
// 全般
BUS::phase_t phase; // Transition phase
int id; // Controller ID (0-7)
BUS *bus; // Bus
// commands
DWORD cmd[10]; // Command data
DWORD status; // Status data
DWORD message; // Message data
#ifdef RASCSI
// Run
DWORD execstart; // Execution start time
#endif // RASCSI
// Transfer
BYTE *buffer; // Transfer data buffer
int bufsize; // Transfer data buffer size
DWORD blocks; // Number of transfer block
DWORD next; // Next record
DWORD offset; // Transfer offset
DWORD length; // Transfer remaining length
// Logical unit
Disk *unit[UnitMax];
// Logical Unit
} ctrl_t;
public:
// Basic Functions
#ifdef RASCSI
SASIDEV();
#else
SASIDEV(Device *dev);
#endif //RASCSI
// Constructor
virtual ~SASIDEV();
// Destructor
virtual void FASTCALL Reset();
// Device Reset
#ifndef RASCSI
virtual BOOL FASTCALL Save(Fileio *fio, int ver);
// Save
virtual BOOL FASTCALL Load(Fileio *fio, int ver);
// Load
#endif //RASCSI
// External API
virtual BUS::phase_t FASTCALL Process();
// Run
// Connect
void FASTCALL Connect(int id, BUS *sbus);
// Controller connection
Disk* FASTCALL GetUnit(int no);
// Get logical unit
void FASTCALL SetUnit(int no, Disk *dev);
// Logical unit setting
BOOL FASTCALL HasUnit();
// Has a valid logical unit
// Other
BUS::phase_t FASTCALL GetPhase() {return ctrl.phase;}
// Get the phase
void FASTCALL GetPhaseStr(char *str);
int FASTCALL GetID() {return ctrl.id;}
// Get the ID
void FASTCALL GetCTRL(ctrl_t *buffer);
// Get the internal information
ctrl_t* FASTCALL GetWorkAddr() { return &ctrl; }
// Get the internal information address
virtual BOOL FASTCALL IsSASI() const {return TRUE;}
// SASI Check
virtual BOOL FASTCALL IsSCSI() const {return FALSE;}
// SCSI check
Disk* FASTCALL GetBusyUnit();
// Get the busy unit
protected:
// Phase processing
virtual void FASTCALL BusFree();
// Bus free phase
virtual void FASTCALL Selection();
// Selection phase
virtual void FASTCALL Command();
// Command phase
virtual void FASTCALL Execute();
// Execution phase
void FASTCALL Status();
// Status phase
void FASTCALL MsgIn();
// Message in phase
void FASTCALL DataIn();
// Data in phase
void FASTCALL DataOut();
// Data out phase
virtual void FASTCALL Error();
// Common error handling
// commands
void FASTCALL CmdTestUnitReady();
// TEST UNIT READY command
void FASTCALL CmdRezero();
// REZERO UNIT command
void FASTCALL CmdRequestSense();
// REQUEST SENSE command
void FASTCALL CmdFormat();
// FORMAT command
void FASTCALL CmdReassign();
// REASSIGN BLOCKS command
void FASTCALL CmdRead6();
// READ(6) command
void FASTCALL CmdWrite6();
// WRITE(6) command
void FASTCALL CmdSeek6();
// SEEK(6) command
void FASTCALL CmdAssign();
// ASSIGN command
void FASTCALL CmdSpecify();
// SPECIFY command
void FASTCALL CmdInvalid();
// Unsupported command
// データ転送
virtual void FASTCALL Send();
// Send data
#ifndef RASCSI
virtual void FASTCALL SendNext();
// Continue sending data
#endif // RASCSI
virtual void FASTCALL Receive();
// Receive data
#ifndef RASCSI
virtual void FASTCALL ReceiveNext();
// Continue receiving data
#endif // RASCSI
BOOL FASTCALL XferIn(BYTE* buf);
// Data transfer IN
BOOL FASTCALL XferOut(BOOL cont);
// Data transfer OUT
// Special operations
void FASTCALL FlushUnit();
// Flush the logical unit
// Log
void FASTCALL Log(Log::loglevel level, const char *format, ...);
// Log output
protected:
#ifndef RASCSI
Device *host;
// Host device
#endif // RASCSI
ctrl_t ctrl;
// Internal data
};
//===========================================================================
//
// SCSI Device (Interits SASI device)
//
//===========================================================================
class SCSIDEV : public SASIDEV
{
public:
// Internal data definition
typedef struct {
// Synchronous transfer
BOOL syncenable; // Synchronous transfer possible
int syncperiod; // Synchronous transfer period
int syncoffset; // Synchronous transfer offset
int syncack; // Number of synchronous transfer ACKs
// ATN message
BOOL atnmsg;
int msc;
BYTE msb[256];
} scsi_t;
public:
// Basic Functions
#ifdef RASCSI
SCSIDEV();
#else
SCSIDEV(Device *dev);
#endif // RASCSI
// Constructor
void FASTCALL Reset();
// Device Reset
// 外部API
BUS::phase_t FASTCALL Process();
// Run
void FASTCALL SyncTransfer(BOOL enable) { scsi.syncenable = enable; }
// Synchronouse transfer enable setting
// Other
BOOL FASTCALL IsSASI() const {return FALSE;}
// SASI Check
BOOL FASTCALL IsSCSI() const {return TRUE;}
// SCSI check
private:
// Phase
void FASTCALL BusFree();
// Bus free phase
void FASTCALL Selection();
// Selection phase
void FASTCALL Execute();
// Execution phase
void FASTCALL MsgOut();
// Message out phase
void FASTCALL Error();
// Common erorr handling
// commands
void FASTCALL CmdInquiry();
// INQUIRY command
void FASTCALL CmdModeSelect();
// MODE SELECT command
void FASTCALL CmdModeSense();
// MODE SENSE command
void FASTCALL CmdStartStop();
// START STOP UNIT command
void FASTCALL CmdSendDiag();
// SEND DIAGNOSTIC command
void FASTCALL CmdRemoval();
// PREVENT/ALLOW MEDIUM REMOVAL command
void FASTCALL CmdReadCapacity();
// READ CAPACITY command
void FASTCALL CmdRead10();
// READ(10) command
void FASTCALL CmdWrite10();
// WRITE(10) command
void FASTCALL CmdSeek10();
// SEEK(10) command
void FASTCALL CmdVerify();
// VERIFY command
void FASTCALL CmdSynchronizeCache();
// SYNCHRONIZE CACHE command
void FASTCALL CmdReadDefectData10();
// READ DEFECT DATA(10) command
void FASTCALL CmdReadToc();
// READ TOC command
void FASTCALL CmdPlayAudio10();
// PLAY AUDIO(10) command
void FASTCALL CmdPlayAudioMSF();
// PLAY AUDIO MSF command
void FASTCALL CmdPlayAudioTrack();
// PLAY AUDIO TRACK INDEX command
void FASTCALL CmdModeSelect10();
// MODE SELECT(10) command
void FASTCALL CmdModeSense10();
// MODE SENSE(10) command
void FASTCALL CmdGetMessage10();
// GET MESSAGE(10) command
void FASTCALL CmdSendMessage10();
// SEND MESSAGE(10) command
// データ転送
void FASTCALL Send();
// Send data
#ifndef RASCSI
void FASTCALL SendNext();
// Continue sending data
#endif // RASCSI
void FASTCALL Receive();
// Receive data
#ifndef RASCSI
void FASTCALL ReceiveNext();
// Continue receiving data
#endif // RASCSI
BOOL FASTCALL XferMsg(DWORD msg);
// Data transfer message
scsi_t scsi;
// Internal data
};
#endif // disk_h