📄 cpmfs.cpp
字号:
//*************************************************************************// MODULE : CpmFs - A file system based on the old CP/M design *// AUTHOR : Ron Chernich *// PURPOSE: Provides reudimentary (nonheirarachial) file system for RCOS *// HISTORY: *// 13-AUG-94 First version *// 21-AUG-94 Unit tests on open/create/read/write completed Ok. *//*************************************************************************#include "cpmfs.hpp" //////////////////////////////////////////////////////////////////////////// A CP/M-like file system (RIP, Garry Kildal).//------------------------------------------------------------------------// C::tor regesters us with the Kernel for e-mail and null's out// the BDOS array, awaiting mounting of the drives..//CpmFs::CpmFs (UINT16 id, UINT16 cls, Knl *pK) : port(id, cls, pK){ for (int idx = 0; idx < MAX_DRIVES; idx++) pUnit[idx] = NULL;}/////////////////// close off simulated disks//CpmFs::~CpmFs (void){ for (int idx = 0; idx < MAX_DRIVES; idx++) if (NULL != pUnit[idx]) delete pUnit[idx];}/////////////// This member called when disk has started up ok. We create a new BDOS// object in our private array, passing it the supplied structs which// are used to define the disk layout - for example:// // a CP/M IBM 3740 format 8" diskette reserved the first two tracks// as system tracks (unused) and used 1024 byte allocation blocks.// With 26 x 128 byte sectors and 77 tracks, this results in total// user capacity = ((26 * 128 * 77) - (64 * 32)) / 1024 = 243 K.// By convention, 64 directory entries were specified. The directory// immediatly follows the system tracks, so 64 x 32 bytes = 2K, ie// the first two allocation blocks are reserved for the directory,// leaving 241K for user file space.//// The BDOS also needed to know the actual value used for the first// sector of each track (0 or 1) and what sector "skew" would be used// for track access. This allows the BDOS to convert the logical// sector which it calculates from the record within block numbers into// an actual physical disk sector.//// Finally, since 8" drives did not support any knid of "door opened"// interrupt, removable media needed to be checked to make sure the// disk had not been changed in order to prevent trashing the disk// structure by writing one disks data to another. This was accomplished// by specifying the number of "checked" directory entries. A vector// of checksums was built for each "checked" directory entry which was// checked before all write operations. Slow? You bet!//void CpmFs::MountDrive (UINT16 nDrv, char cUnit, DPB& mac, DPARAM& dprm){ UINT16 idx = UINT16(cUnit - 'A'); if ((idx >= 0) && (idx < MAX_DRIVES) && (NULL == pUnit[idx])) { pUnit[idx] = new CpmBdos(mac, dprm, nDrv); pUnit[idx]->pTx = pTx; pUnit[idx]->nId = uID; pUnit[idx]->LogDisk(); }}///////////////// All File System requests arrive here. We just create an XfReq instance,// fill in what we can, then call the appropriate member func of the BDOS// instance corresponding to the drive unit specified in the FCB.//void CpmFs::RxPort (PMSG pM){ PFCBREF pRef = (PFCBREF)pM->pBody; PFCB pFcb = pRef->pFcbRef; if (pFcb == NULL) return; UINT16 idx = pFcb->de.nUsrNmbr; if ((idx >= MAX_DRIVES) || (NULL == pUnit[idx])) DevError(ET_FileSysErr, FALSE); else { XfReq *pX = new XfReq(pM->wSender, pFcb); pX->pFnCb = pUnit[idx]; switch (pM->wMsgType & ~MM_Sync) { case FS_Open : pUnit[idx]->Open(pX); break; case FS_Creat : pUnit[idx]->Creat(pX); break; case FS_Close : pUnit[idx]->Close(pX); break; case FS_ReadSeq : pUnit[idx]->Read(pX, 0); break; case FS_ReadRan : pUnit[idx]->Read(pX, 1); break; case FS_WriteSeq : pUnit[idx]->Write(pX, 0); break; case FS_WriteRan : pUnit[idx]->Write(pX, 1); break; case FS_Delete : pUnit[idx]->Remov(pX); break; case FS_Rename : break; case FS_Stat : break; case FS_FindFirst: break; case FS_FindNext : break; default: DevError(ET_FileSysErr, FALSE); } }}//////////////////////////////////////////////////////////////////////////// Default Transfer request C::tor - just preset simple stuff.//XfReq::XfReq (UINT16 uOwner) : nSid(1), pNxt(NULL), nRetry(3), bRes(FALSE), uProc(uOwner){ }//////////////// Transfer request C::tor has a user (or BDOS) FCB to work with..//XfReq::XfReq (UINT16 uOwner, PFCB pUfcb) : nSid(1), pNxt(NULL), nRetry(3), bRes(FALSE), uProc(uOwner){ pFcb = pUfcb; pDma = pUfcb->pBuf;}/////////////////////////////////// eof ////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -