⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cli.c

📁 MMURTL(tm) Computer Operating System Ver x0.8, source code.
💻 C
字号:
/* CLI.C  (A MMURTL Command Line Interpreter) */
/*  Copyright (c) 1993, 1994 R.A. Burgess     */
/*         All Rights Reserved                */

#define U32 unsigned long
#define S32 long
#define U16 unsigned int
#define S16 int
#define U8 unsigned char
#define S8 char
#define TRUE 1
#define FALSE 0


#include <stdio.h>
#include <string.h>
#include <ctype.h>

/* Includes for OS public calls and structures */

#include "MKernel.h"
#include "MMemory.h"
#include "MData.h"
#include "MTimer.h"
#include "MVid.h"
#include "MKbd.h"
#include "MJob.h"
#include "MFiles.h"

/************************* BEGIN Data ********************/
/************************* BEGIN Data ********************/
/************************* BEGIN Data ********************/

/* Define the Foreground and Background colors */

#define EDVID   BLACK|BGWHITE
#define NORMVID WHITE|BGBLACK
#define STATVID BLACK|BGCYAN

long iCol, iLine;

char aStatLine[] =
"mm/dd/yy  00:00:00  CLI  V0.8x   Job     Path:                                  ";

char aPath[70];
long cbPath;
char fUpdatePath;

long olCmd[50];		/* offset in tmp file to last 50 commands */

char aCmd[80];
long cbCmd = 0;

unsigned char Buffer[512];
char text[70];
char ExitChar;

unsigned long GPExch;		/* Messaging for main */
unsigned long GPMsg[2];
unsigned long GPHndl;

unsigned long StatExch;	/* Messaging for status task */
long StatStack[256];	/* 1024 byte stack for stat task */

long time, date;

long JobNum;

char paCmds[15][10] = {
	"",					/* 0 external */
	"xxxxx",			/* 1 - not used */
	"Cls",				/* 2  */
	"Copy",				/* 3  */
	"Del",				/* 4  */
	"Dir",				/* 5  */
	"Debug",			/* 6  */
	"Dump",				/* 7  */
	"Exit",				/* 8  */
	"Help",				/* 9  */
	"Monitor",			/* 10 */
	"Path",				/* 11 */
	"Ren",				/* 12 */
	"Run",				/* 13 */
	"Type",				/* 14 */
	};

#define NCMDS 14

#define EXTCMD 0		/* External Command */
#define RESVDCMD 1
#define CLSCMD  2
#define COPYCMD 3
#define DELCMD  4
#define DIRCMD  5
#define DBGCMD  6
#define DUMPCMD 7
#define EXITCMD 8
#define HELPCMD 9
#define MONCMD  10
#define PATHCMD 11
#define RENCMD  12
#define RUNCMD  13
#define TYPECMD 14

long CmdNum = 0;

char *apParam[13];		/* Param 0 is cmd name */
long acbParam[13];
#define nParamsMax 13

#define ErcBadParams 80

/* Directory Entry Records, 16 records 32 bytes each */

struct dirstruct {
	U8  Name[8];
	U8  Ext[3];
	U8  Attr;
	U8  Rsvd[10];
	U16 Time;
	U16 Date;
	U16 StartClstr;
	U32 FileSize;
	} dirent[16];

/************************* BEGIN CODE ********************/
/************************* BEGIN CODE ********************/
/************************* BEGIN CODE ********************/

/*********************************************************
    This is the status task for the CLI.  It updates
    the status line which has the time and path.
*********************************************************/

void StatTask(void)
{
for(;;) {
	if (fUpdatePath) {
		if (cbPath > 30)
			cbPath = 30;
		FillData(&aStatLine[47], 30, ' ');
		CopyData(aPath, &aStatLine[47], cbPath);
		fUpdatePath = 0;
	}


	GetCMOSDate(&date);
	aStatLine[0] = '0' + ((date >> 20) & 0x0f); /* month */
	aStatLine[1] = '0' + ((date >> 16) & 0x0f);
	aStatLine[3] = '0' + ((date >> 12) & 0x0f); /* Day */
	aStatLine[4] = '0' + ((date >> 8)  & 0x0f);
	aStatLine[6] = '0' + ((date >> 28) & 0x0f); /* year */
	aStatLine[7] = '0' + ((date >> 24) & 0x0f);

	GetCMOSTime(&time);
	aStatLine[10] = '0' + ((time >> 20) & 0x0f);
	aStatLine[11] = '0' + ((time >> 16) & 0x0f);
	aStatLine[13] = '0' + ((time >> 12) & 0x0f);
	aStatLine[14] = '0' + ((time >> 8) & 0x0f);
	aStatLine[16] = '0' + ((time >> 4) & 0x0f);
	aStatLine[17] = '0' + (time & 0x0f);

	PutVidChars(0,0, aStatLine, 80, STATVID);

	Sleep(100);	/* sleep 1 second */


} /* for EVER */
}

/*********************************************************
  This displays error code text string if listed and
  NON zero.
*********************************************************/

void CheckErc (unsigned long erc)
{
char *pSt;
char st[40]
long i;

FillData(st, 40, 0);

switch (erc) {
	case 0: return;
	case 1:	  pSt = "End of file";		break;
	case 4:	  pSt = "User cancelled";		break;
	case 200: pSt = "Invalid filename (not correct format)";	 break;
	case 201: pSt = "No such drive";	break;
	case 202: pSt = "The name is not a file (it's a directory)"; break;
	case 203: pSt = "File doesn't exist";	break;
	case 204: pSt = "Directory doesn't exist";	break;
	case 205: pSt = "File is ReadOnly"; break;
	case 208: pSt = "File in use"; break;
	case 222: pSt = "Can't rename across drives"; break;
	case 223: pSt = "Can't rename across directories"; break;
	case 228: pSt = "Root directory is full"; break;
	case 230: pSt = "Disk is full (bummer)"; break;
	case 231: pSt = "Directory is full"; break;
	default:
		sprintf(st, "Error %05d on last command", erc);
		pSt = st;
		break;
	}
	printf("%s\r\n", pSt);
}

/*********************************************************
  This simply does a software interrupt 03 (Debugger).
*********************************************************/

void GoDebug(void)
{
;
#asm
	INT 03
#endasm
return;
}

/*********************************************************
    This is called to initialize the screen.
*********************************************************/

void InitScreen(void)
{
	SetNormVid(NORMVID);
	ClrScr();
    PutVidChars(0,0, aStatLine, 80, STATVID);
	SetXY(0,2);
	return;
}

/*********************************************/

U32 Dump(unsigned char *pb, long cb, unsigned long addr)
{
U32 erc, i, j, KeyCode;
unsigned char buff[17];

	erc = 0;
	GetXY(&iCol, &iLine);

	while (cb) {
		printf("%08x ", addr);
		if (cb > 15) j=16;
		else j = cb;
		for (i=0; i<j; i++) {
			printf("%02x ",*pb);
			buff[i] = *pb++;
			if (buff[i] < 0x20)
				buff[i] = 0x2E;
			if (buff[i] > 0x7F)
				buff[i] = 0x2E;
		}
		buff[i+1] = 0;
		printf("%s\r\n", &buff[0]);
		++iLine;
		if (iLine >= 22) {
			SetXY(0,23);
			printf("ESC to cancel, any other key to continue...");
			ReadKbd(&KeyCode, 1);  /* ReadKbd, wait */
			if ((KeyCode & 0xff) == 0x1b) {
				return 4;
			}
			InitScreen();
			SetXY(0,1);
			iLine =1;
		}
		if (cb > 15) cb-=16;
		else cb=0;
        addr+=j;
	}
	return erc;
}

/*********************************************************
  This sets up to call the dump routine for each page.
  This expects to find the filename in param[1].
*********************************************************/

long DoDump(void)
{
unsigned long i, j, k, l, erc, c1, dret, fh;

erc = 0;
if ((apParam[1]) && (acbParam[1])) {
	if (iLine >= 23) {
		ScrollVid(0,1,80,23,1);
		SetXY(0,23);
	}
	erc = OpenFile(apParam[1], acbParam[1], 0, 1, &fh);
	if (!erc) {
		j=0;				/* file lfa */
		GetFileSize(fh, &k);
		while ((j<k) && (!erc)) {
			FillData(Buffer, 512, 0);
			erc = ReadBytes (fh, Buffer, 512, &dret);
			if (k-j > 512)
				l = 512;
			else l=k-j;
			if (erc < 2)
				erc = Dump(Buffer, dret, j);
			j+=512;
		}
		CloseFile (fh);
	}
}
else
	printf("Filename not given\r\n");

return erc;
}

/*********************************************************
  This types a text file to the screen.
*********************************************************/

long DoType(char *pName, long cbName)
{
long i, j, lfa, erc, dret, fh, KeyCode;

erc = 0;
if ((pName) && (cbName)) {

	if (iLine >= 23) {
		ScrollVid(0,1,80,23,1);
		SetXY(0,23);
	}
	erc = OpenFile(pName, cbName, 0, 1, &fh);
	if (!erc) {
		FillData(Buffer, 512, 0);
		dret = 1;
		while ((erc<2) && (dret)) {
			GetFileLFA(fh, &lfa);
			erc = ReadBytes (fh, Buffer, 78, &dret);
			i = 1;
			while ((Buffer[i-1] != 0x0A) && (i < dret)) {
				i++;
			}
			for (j=0; j<=i; j++) {
				if ((Buffer[j] == 0x09) || (Buffer[j] == 0x0d) ||
                    (Buffer[j] == 0x0a))
                   Buffer[j] = 0x20;
			}
			if (dret) {
				PutVidChars(0, iLine, Buffer, i, NORMVID);
				iLine++;
			}
			SetXY(0,iLine);
			SetFileLFA(fh, lfa+i);
			if (iLine >= 22) {
				SetXY(0,23);
				printf("ESC to cancel, any other key to continue...");
				ReadKbd(&KeyCode, 1);  /* ReadKbd, wait */
				if ((KeyCode & 0xff) == 0x1b)
			      return(4);
				InitScreen();
				SetXY(0,1);
				iLine =1;
			}
		}
		printf("\r\nError: %d\r\n", erc);
		CloseFile (fh);
	}
}
else
	printf("Filename not given\r\n");

return erc;
}

/*******************************************************
  This converts DOS FAT date & time and converts it into
  strings with the format  MM/DD/YY  HH/MM/SS.
********************************************************/
void CnvrtFATTime(U16 time,
				  U16 date,
				  char *pTimeRet,
				  char *pDateRet)
{
U32 yr,mo,da,hr,mi,se;
char st[15];

	yr = ((date & 0xFE00) >> 9) + 1980 - 1900;
	if (yr > 99) yr -=100;
	mo = (date & 0x01E0) >> 5;
	da = date & 0x001F;
	hr = (time & 0xF800) >> 11;
	mi = (time & 0x07E0) >> 5;
	se = (time & 0x001F) * 2;
	sprintf(st, "%02d:%02d:%02d",hr,mi,se);
	CopyData(st, pTimeRet, 8);
	sprintf(st, "%02d-%02d-%02d",mo,da,yr);
	CopyData(st, pDateRet, 8);

}

/*********************************************************
  Does a directory listing for param 1 or current path.
*********************************************************/

U32 DoDir(void)
{
U8 fDone;
U32 SectNum, erc, KeyCode, i;
char st[78];

if (iLine >= 23) {
	ScrollVid(0,1,80,23,1);
	SetXY(0,23);
}
fDone = 0;
SectNum = 0;
while (!fDone) {
	erc = GetDirSector(apParam[1], acbParam[1], &dirent[0], 512, SectNum);
	if (!erc) {
		for (i=0; i<16; i++) {
			if (!dirent[i].Name[0])
				erc = 1;
			if ((dirent[i].Name[0]) && (dirent[i].Name[0] != 0xE5)) {
				sprintf(st, "%8s %3s  %8d  xx/xx/xx xx/xx/xx  %2x   %04x\r\n",
			 			dirent[i].Name,
			 			dirent[i].Ext,
			 			dirent[i].FileSize,
			 			dirent[i].Attr,
						dirent[i].StartClstr);
				CnvrtFATTime(dirent[i].Time, dirent[i].Date, &st[33], &st[24]);
				printf("%s", st);
				iLine++;
				if (iLine >= 22) {
					SetXY(0,23);
					printf("ESC to cancel, any other key to continue...");
					ReadKbd(&KeyCode, 1);  /* ReadKbd, wait */
					if ((KeyCode & 0xff) == 0x1b) {
						erc = 4;
						fDone = TRUE;
					}
					InitScreen();
					SetXY(0,1);
					iLine =1;
				}
			}
		}
	}
	else
		fDone = TRUE;
	SectNum++;
}

return(erc);
}

/*********************************************************
  This Fills in the ptrs to and sizes of each parameter
  found on the command line in the arrays apParams and
  acbParams.
*********************************************************/

void ParseCmdLine(void)
{
long iCmd, iPrm, i;		/* iCmd is index to aCmd */
	iCmd = 0;
	for (iPrm=0; iPrm<nParamsMax; iPrm++) {
		acbParam[iPrm] = 0;		/* default the param to empty */
		apParam[iPrm] = 0;		/* Null the ptr */
		if (iCmd < cbCmd) {
			if (!isspace(aCmd[iCmd])) {
				apParam[iPrm] = &aCmd[iCmd++];	/* ptr to param */
				i = 1;
				while ((iCmd < cbCmd) && (!isspace(aCmd[iCmd]))) {
					i++;
					iCmd++;
				}
				acbParam[iPrm] = i;		/* size of param */
			}
			while ((iCmd < cbCmd) && (isspace(aCmd[iCmd])))
				iCmd++;
		}
	}
}


void main(void)
{
unsigned long erc, i, j, fh;

	erc = AllocExch(&StatExch);
	erc = AllocExch(&GPExch);

	InitScreen();

	SpawnTask(&StatTask, 24, 0, &StatStack[255], 0);

	SetExitJob("C:\\MMURTL\\CLI.RUN", 17);

	SetPath("C:\\MMURTL\\", 10);
	GetJobNum(&JobNum);
	sprintf(&aStatLine[37], "%02d", JobNum);
	GetPath(JobNum, aPath, &cbPath);

	fUpdatePath = 1;
	iLine = 1;

	while (1) {
		FillData(aCmd, 79, ' ');
		aCmd[79] = 0;
		cbCmd = 0;
		SetXY(0, iLine);
		TTYOut (">", 1, NORMVID);
		EditLine(aCmd, cbCmd, 79, &cbCmd, &ExitChar, EDVID);
		TTYOut ("\r\n", 2, NORMVID);
		GetXY(&iCol, &iLine);

		acbParam[0] = 0;
		apParam[0] = 0;
        CmdNum = 0;

		if ((ExitChar == 0x01) || (ExitChar == 0x81)) {

		}

		if (ExitChar == 0x0d)
			ParseCmdLine();			/* set up all params */

		if ((acbParam[0]) && (apParam[0])) {	/* It's a command! */

			i = 1;
			while (i <= NCMDS) {
				j = strlen(paCmds[i]);
				if ((acbParam[0] == j) &&
					(CompareNCS(apParam[0],	paCmds[i], j) == -1))
				{
	                CmdNum = i;
	                break;
				}
				i++;
			}
			erc = 0;
			switch (CmdNum) {
				case EXTCMD:			/* external command */
						printf("Command not found\r\n");
					break;
				case CLSCMD:
					InitScreen();
					break;
				case COPYCMD:
					break;
				case DELCMD:
					erc = OpenFile(apParam[1], acbParam[1], 1, 0, &fh);
					if (!erc)
						erc = DeleteFile(fh);
					if (!erc)
						printf("Done.\r\n");
					break;
				case DIRCMD:
					erc = DoDir();
					break;
				case DBGCMD:
					GoDebug();
					break;
				case DUMPCMD:
					erc = DoDump();
					break;
				case EXITCMD:
					SetExitJob("", 0);
					ExitJob(0);
					break;
				case HELPCMD:
					erc = DoType("C:\\MMURTL\\CLI.Hlp", 17);
					break;
				case MONCMD:
					erc = Request("KEYBOARD", 4, GPExch, &GPHndl, 0,
									0, 0,   0, 0,   1, 0, 0);
					erc = WaitMsg(GPExch, GPMsg);
					SetVidOwner(1);
					break;
				case PATHCMD:
					erc = SetPath(apParam[1], acbParam[1]);
					if (!erc)
						erc = GetPath(JobNum, aPath, &cbPath);
					fUpdatePath = 1;
					break;
				case RENCMD:
                    if ((acbParam[1]) && (acbParam[2]))
                    	erc = RenameFile(apParam[1], acbParam[1],
                                         apParam[2], acbParam[2]);
					else erc = ErcBadParams;
					break;
				case RUNCMD:
					if (acbParam[1]) {
						SetCmdLine(aCmd, cbCmd);
						SetExitJob("C:\\MMURTL\\CLI.RUN", 17);
						erc = Chain(apParam[1], acbParam[1], 0);
					}
					break;
				case TYPECMD:
					erc = DoType(apParam[1], acbParam[1]);
					break;
				default:
					break;
			}

			CheckErc(erc);

		}

		GetXY(&iCol, &iLine);
		if (iLine >= 23) {
			ScrollVid(0,1,80,23,1);
			SetXY(0,23);
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -