Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

View File

@@ -0,0 +1,967 @@
#include <portab.h>
#include "cpmfunc.h"
EXTERN WORD _EXTERR; /* Has AX after an O.S. call */
#define DMA_LEN 128
#define FCB_LEN 36
#define REC_LEN 23
#define REC_DRIVE 0
#define REC_FILE 1
#define REC_TYPE 9
#define REC_PASSWORD 12
#define REC_FIELDS 20
#define REC_8087 20
#define REC_SHARED 21
#define REC_SUSPEND 22
#define REC_F_8087 0
#define REC_F_SHARED 1
#define REC_F_SUSPEND 2
#define NOT_FOUND -1
#define LOW_TO_UP ('a' - 'A')
#define EXIT_PROGRAM -1
#define CONTINUE 1
#define BDOS_MASK 0x00ff
#define OS_MASK 0xff00
#define PASSWORD 0x07ff
#define RO_ERROR 0x03ff
#define RO_OR_PASS 0xfe
#define BDOS_VER 0x0031
#define OS_TYPE 0x1400
/*** FUNCTIONS THAT RETURN A POINTER ***/
BYTE *a_white_char();
BYTE *check_format();
BYTE *expand_file_name();
BYTE *get_token();
BYTE *search();
BYTE *short_string();
BYTE *getspass();
struct _fcblst *expfcb();
/**BYTE *getpass();**/
BYTE *strncpy();
BYTE *index();
BYTE *strncmp();
BYTE *strcmp();
/* strlen(); */
/*** ERROR MESSAGES ***/
BYTE *err_00_msg = "REQUIRES CONCURRENT CP/M-86 3.1$";
BYTE *err_01_msg = "Invalid syntax -- one filespec only";
BYTE *err_02_msg = "Use CMD or blank filetype in CHSET command line";
BYTE *err_03_msg = "Invalid filespec"; /* too long */
BYTE *err_04_msg = "Invalid filespec"; /* can't add .cmd */
BYTE *err_05_msg = "Invalid syntax -- expected a '['";
BYTE *err_06_msg = "Not a valid CHSET field";
BYTE *err_07_msg = "Not a valid CHSET setting";
BYTE *err_08_msg = "Duplicate field";
BYTE *err_09_msg = "Invalid syntax -- expected a '='";
BYTE *err_10_msg = "Invalid syntax -- expected ',' or ']'";
BYTE *err_11_msg = "Wildcards are not allowed when using CHSET to change a setting";
BYTE *err_12_msg = "Invalid filespec";
BYTE *err_13_msg = "File not found";
BYTE *err_14_msg = "Too many directory entries for query";
BYTE *pass_prompt = " Password? ";
BYTE *set_to = " set to ";
BYTE *setting_is = " settings are ";
BYTE *blanks = " "; /* 10 blanks */
/*** GLOBAL VARIABLES ***/
BYTE buff_01[DMA_LEN]; /* Buffer to hold current token */
BYTE *token; /* Points to buffer */
BYTE buff_02[24];
BYTE *file_spec;
BYTE buff_03[FCB_LEN];
BYTE *fcb;
BYTE *cmd = ".CMD" ;
BYTE *deli_01 = "\t\\\" !@#$%^&*()_+{}~:|<>?-=[]`;',./" ;
BYTE *deli_02 = "\t =<>,|[]" ;
struct _fcblst
{
BYTE fcb[FCB_LEN];
struct _fcblst *next_fcb;
};
struct pfcb_str
{
BYTE *filename;
BYTE *fcb_adr;
};
struct abcd_str
{
WORD start;
WORD end;
};
struct fie1_str
{
BYTE *fieldstr;
WORD field_nu;
};
#define EMPTY -1 /* Can not be same as option number */
#define FIE1_START 0
#define FIE1_END 2
struct fie1_str fie1_tab[] =
{
"8*087",0,
"SH*ARED",1,
"SU*SPEND",2
};
struct fie1_str opt1_tab[] =
{
"ON*",0,
"OF*F",1,
"OP*TIONAL",2
};
struct abcd_str xref_tab[] =
{
0,2, /* on, off, optional */
0,1, /* on, off */
0,1 /* on, off */
};
VOID main()
{
BYTE *dma;
WORD dma_len;
if ( (ok_ver(BDOS_VER,OS_TYPE) == FALSE) )
{ /* Not the right system */
c_writestr(err_00_msg); /* delimited with $ */
p_termcpm(); /* Terminate */
}
token = &buff_01[0];
file_spec = &buff_02[0];
fcb = &buff_03[0];
f_errmode( 0xfe ); /* Sets BDOS errors to verbose */
c_delimit( NULL ); /* Sets output delimiter to NULL */
dma = f_dmaget(); /* Get DMA ptr */
dma_len = *dma++; /* Get length, move ptr to str portion */
*(dma+dma_len) = NULL;
upper_case(dma); /* Change all lowercase to upper */
if ( (dma_len == 0) )
{ /* Have no tail */
display_help();
}
else
{
dma = a_white_char(dma); /* DMA now points to a white char */
if ( (*dma == '[') )
{ /* Give help on [... */
display_help();
}
else
{
set_or_show(dma); /* Does return on success */
}
}
} /*** MAIN ***/
VOID show_mode(string,token,file_spec)
BYTE *string;
BYTE *token;
BYTE *file_spec;
{
WORD error;
BYTE buffer[REC_LEN]; /* record buffer */
BYTE *record;
BYTE *pass; /* pts to password from C RTL */
WORD first; /* flag for search first or next */
struct _fcblst *files; /* linklist of file names */
if ( (*token == NULL) )
{ /* user type 'chset $...' so token will be null */
print_err(err_04_msg,EXIT_PROGRAM);
}
record = &buffer[0];
string = a_white_char(string);
if ( (*string != NULL) )
{ /* extra characters on line ???two filespecs??? */
print_err(err_01_msg,EXIT_PROGRAM);
}
files = expfcb(file_spec); /* Returns linklist */
while ( (files != NULL) )
{
copy(files->fcb,record,20);
error = get_settings(record);
if ( error == PASSWORD )
{
passget(record);
error = get_settings(record);
}
if ( (error == 0) )
{
print(record,setting_is);
}
else
{ /* extra line after bdos error */
c_writestr("\n\r");
}
files = files->next_fcb;
}
}
VOID set_mode(string,token,file_spec)
BYTE *string;
BYTE *token;
BYTE *file_spec;
{
BYTE buffer[REC_LEN]; /* record buffer */
BYTE *record;
BYTE i;
WORD error;
BYTE *pass; /* pts to password from C RTL */
struct _fcblst *files; /* linklist of files */
record = &buffer[0];
if ( (index(file_spec,'?') == NULL) &&
(index(file_spec,'*') == NULL) )
{ /* O.K. no wild cards are present */
string = a_white_char(string); /* Move to a white char */
if ( (*string == '[') )
{ /* O.K. start symbol */
string = check_format(string,token,record);
string = a_white_char(string); /* White char */
if ( (*string == NULL) || (*string == ']') )
{ /* COMMAND OPTIONS HAVE BEEN ACCEPTED */
files = expfcb(file_spec); /* Linklist */
/* FCB has dfffffffftttpppppppp */
for ( i=0; i<20; i++)
{
*(record+i) = *(files->fcb+i);
}
error = set_fields(record);
if ( error == PASSWORD )
{
passget(record);
error = set_fields(record);
}
if ( error == 0)
{
print(record,set_to);
}
else
{ /* extra line after bdos error */
c_writestr("\n\r");
}
}
else
{
print_err(err_10_msg,EXIT_PROGRAM);
}
}
else
{ /* Illegal start symbol */
print_err(err_05_msg,EXIT_PROGRAM);
}
}
else
{ /* No wild cards are allowed */
print_err(err_11_msg,EXIT_PROGRAM);
}
}
BYTE *check_format(string,token,record)
BYTE *string;
BYTE *token;
BYTE *record; /* Record to set fields in */
{
WORD field;
WORD option;
WORD start;
WORD end;
*(record+REC_8087) = EMPTY; /* 8087 field */
*(record+REC_SHARED) = EMPTY; /* SHARED field of record */
*(record+REC_SUSPEND) = EMPTY; /* SUSPEND field of record */
string++;
FOREVER /* Exits on an error or success */
{
/***** string++; ****/
string = get_token(string,deli_01,token);
field = fisttonu(token,fie1_tab,FIE1_START,FIE1_END);
if ( (field != NOT_FOUND) )
{ /* O.K. field */
string = a_white_char(string);
if ( (*string++ == '=') )
{ /* O.K. seperator */
string = get_token(string,deli_01,token);
start = xref_tab[field].start;
end = xref_tab[field].end;
option = fisttonu(token,opt1_tab,start,end);
if ( (option != NOT_FOUND) )
{ /* Have 'field=option' check and record */
if (((*(record+REC_FIELDS+field)) == ((BYTE)EMPTY)))
{ /* EVERTHING O.K. on this pass */
*(record+REC_FIELDS+field) = option;
string = a_white_char(string);
if ( (*string == ']') || (*string == '\0') )
/************** if ( (*string != ',') ) ***********/
{ /* No more 'field=option' */
return(string);
}
else
{ /* accept ',' as well as ' ' */
if (*string == ',') string++;
}
}
else
{ /* Duplication error */
print_err(err_08_msg,EXIT_PROGRAM);
}
}
else
{
print_err(err_07_msg,EXIT_PROGRAM);
}
}
else
{ /* Expected an '=' */
print_err(err_09_msg,EXIT_PROGRAM);
}
}
else
{ /* Token is not legal field */
print_err(err_06_msg,EXIT_PROGRAM);
}
}
}
VOID set_or_show(string,file_spec)
BYTE *string;
BYTE *file_spec;
{
string = get_token(string,deli_02,token);
add_cmd(token,file_spec);
if ( (index(string,'[') == NULL) ) /* i.e. did not find it */
{ /* User wishes to set */
show_mode(string,token,file_spec);
}
else
{ /* User wishes to show */
set_mode(string,token,file_spec);
}
}
BYTE *get_token(string,delimiters,token)
BYTE *string;
BYTE *delimiters;
BYTE *token;
{
BYTE *index;
string = a_white_char(string);
while ( (*string != NULL) )
{
for ( index=delimiters; *index != NULL; *index++ )
{
if (*index == *string)
{ /* Found a delimiter, prepare to return */
*token = NULL;
return(string);
}
}
*token++ = *string++;
}
*token = NULL;
return(token);
}
VOID display_help()
{
c_writestr("Syntax:\n\r\n\r");
c_writestr(" CHSET {d:}filename{.CMD}\n\r");
c_writestr(" CHSET {d:}filename{.CMD} [field=setting{,field=setting...}]\n\r");
c_writestr(" CHSET [HELP]\n\r\n\r");
c_writestr("Fields and Settings:\n\r\n\r");
c_writestr(" 8087 ON or OPT or OFF\n\r");
c_writestr(" SHARED ON or OFF \n\r");
c_writestr(" SUSPEND ON or OFF \n\r\n\r");
c_writestr("Examples:\n\r\n\r");
c_writestr(" CHSET qwe.cmd [shared=on] ; Sets the shared field of qwe.cmd\n\r");
c_writestr(" CHSET editor [sus=on] ; Sets editor.cmd to suspend\n\r");
c_writestr(" CHSET pie [80=opt] ; Sets the 8087 field to optional\n\r");
c_writestr(" CHSET * ; Displays settings for all CMD files\n\r");
c_writestr(" CHSET qwerty ; Display current settings of qwerty.cmd\n\r");
/***
c_writestr(" CHSET calc.cmd [8=on,su=off,sh=on]\n\r");
c_writestr(" CHSET calc1 [8=off,su=on,sh=off]\n\r");
c_writestr(" CHSET a*\n\r");
***/
}
VOID add_cmd(token,file_spec)
BYTE *token; /* current file_spec */
BYTE *file_spec;
{
BYTE *found;
BYTE *spec_index = file_spec;
if ( (strlen(token) < 24) )
{
found = search(".",token);
if ( (*found == NULL) )
{ /* We must add '.CMD' */
if ( (strlen(token) < 20) )
{
found = search(";",token); /* found pts to NULL or ';' */
while ( (*token != *found) )
{
*spec_index++ = *token++;
}
found = strncpy(spec_index,cmd,4);
spec_index = spec_index + 4;
while ( (*token != NULL) )
{
*spec_index++ = *token++;
}
*spec_index = NULL;
}
else
{ /* File spec to long to add '.cmd' */
print_err(err_04_msg,EXIT_PROGRAM);
}
}
else
{ /* User has specified extension */
found = strncmp(found,cmd,4); /* Is ext '.CMD' */
if ( (found == NULL) )
{ /* Extension is 'CMD' */
strncpy(file_spec,token,24);
}
else
{ /* Illegal extension */
print_err(err_02_msg,EXIT_PROGRAM);
}
}
}
else
{ /* File spec is too long to be in correct form */
print_err(err_03_msg,EXIT_PROGRAM);
}
}
VOID print_err(string,mode)
BYTE *string;
WORD mode;
{
c_writestr(string);
c_writestr("\n\r");
if ( (mode == EXIT_PROGRAM) )
{
p_termcpm();
}
}
BYTE *search(sub_string,string)
/******
OUTPUT
returns ptr to first character of match or ptr to NULL if no match.
RESTRICTIONS
Sub_string is defined as 1+ characters ending with a NULL.
*******/
BYTE *sub_string; /* String searching for */
BYTE *string; /* String looking in */
{
BYTE *tmp1;
BYTE *tmp2;
while ( (*string != NULL) )
{
tmp1 = sub_string;
tmp2 = string;
while ( (*tmp1++ == *tmp2++) )
{
if ( (*tmp1 == NULL) )
{ /* Found a match */
return(string);
}
if ( (*tmp2 == NULL) )
{ /* Tmp1 is longer so no match possible */
return(tmp2);
}
}
string++;
}
return(string);
}
VOID upper_case(string)
BYTE *string;
{
while ( ((*string) != NULL) )
{
if ( ('a' <= (*string)) && ((*string) <= 'z') )
{
*string = (*string) - LOW_TO_UP;
}
string++;
}
}
WORD fisttonu(string,table,start,end)
/****
Will return NOT_FOUND if given a NULL string
****/
BYTE *string;
struct fie1_str table[];
WORD start;
WORD end;
{
struct fie1_str *loop = &table[start];
WORD cnt = start;
if ( (*string == NULL) )
{ /* Special case */
return(NOT_FOUND);
}
while ( (cnt <= end) )
{
if ( (abrmatch(string,loop->fieldstr)) > -10 )
{
return(loop->field_nu);
}
else
{
cnt++;
loop++;
}
}
return(NOT_FOUND);
}
WORD abrmatch(word1,word2)
BYTE *word1;
BYTE *word2;
{
WORD state = -30;
while ( (*word2 != NULL) )
{
if ( (*word2 == '*') )
{
if ( (*word1 == NULL) )
{
if ( (*++word2 == NULL) )
{
return(20);
}
else
{
return(10);
}
}
*word2++;
state = -10;
}
else
{
if ( (*word1 != *word2) )
{
if ( (*word1 == NULL) && (state == -10) )
{
return(0);
}
else
{
return(state);
}
}
else
{
*word1++;
*word2++;
}
}
}
/*** at end of word2 ***/
if ( (*word1 == *word2) )
{ /*** at end of word1 also ***/
return(20); /* perfect match */
}
else
{ /*** word1 has more letters left ***/
return(-20);
}
}
BYTE *a_white_char(string)
BYTE *string;
{
while ( (*string == ' ') || (*string == '\t') )
{
string++;
}
return(string);
}
VOID print(record,string)
BYTE *record;
BYTE *string;
{
BYTE print_buffer[80];
BYTE *prt_buf;
WORD index;
WORD i;
prt_buf = &print_buffer[0];
prt_buf = expand_file_name(record,prt_buf);
strcpy(prt_buf,string); /* Gets string */
prt_buf = prt_buf + strlen(string);
/*** Now have D:FILENAME.TYP'string' ***/
*prt_buf++ = '[';
record = record + REC_FIELDS; /* Pts to fields */
for ( i = FIE1_START; i <= FIE1_END; i++,record++)
{
if ( (*record != (BYTE)EMPTY) )
{ /* Only print if field is not empty */
prt_buf = short_string(prt_buf,fie1_tab[i].fieldstr);
*prt_buf++ = '=';
index = xref_tab[i].start + (*record);
prt_buf = short_string(prt_buf,opt1_tab[index].fieldstr);
*prt_buf++ = ',';
}
}
*(--prt_buf) = ']'; /* write over last ',' */
*(++prt_buf) = '\n';
*(++prt_buf) = '\r';
*(++prt_buf) = NULL;
c_writestr(&print_buffer[0]);
}
BYTE *short_string(buffer,string)
BYTE *buffer; /* Destination */
BYTE *string; /* Source string */
/***
Copies all characters of a string except '*' and the NULL
terminator to a buffer.
OUTPUT
A ptr to the location one past the last copied
character in the buffer.
***/
{
while ( *string != NULL )
{
if ( *string != '*')
{ /* Copy character */
*buffer++ = *string++;
}
else
{
string++;
}
}
return(buffer);
}
/*----------------------------------------------------------------------*\
| NAME : expfcb |
| CREATED : 10-August-83 LAST MODIFIED: 12-September-83 |
| FUNCTION: Expfcb expands the input filespec into a list of |
| FCB's |
| INPUT : filespec -- ptr to filespec given on command line |
| OUTPUT : Returns ptr to list of FCB's created from filespec |
\*----------------------------------------------------------------------*/
struct _fcblst *expfcb( filespec )
BYTE *filespec;
{
/**** BYTE fcb[FCB_LEN]; /* file control block buffer */
BYTE dma[DMA_LEN]; /* DMA buffer */
WORD dindex; /* DMA buffer index */
WORD findex; /* FCB buffer index */
WORD fcount; /* file count */
BYTE *save_dma; /* DMA offset save area */
struct _fcblst *fhead;/* fcb list head ptr */
struct _fcblst *ftail;/* fcb list tail ptr */
struct _fcblst *flist;/* fcb list */
/**** struct _pfcb pfcb; /* parse FCB for F_PARSE */
WORD error_code;
struct pfcb_str pfcb;
save_dma = f_dmaget();
pfcb.filename = filespec;
pfcb.fcb_adr = fcb;
error_code = f_parse(&pfcb);
if ( (error_code != FALSE) )
{ /* We got an error */
print_err(err_12_msg,EXIT_PROGRAM);
}
fcb[12] = 0; /* extent number */
fcount = 0;
fhead = malloc( sizeof( struct _fcblst ) );
if (fhead == 0)
{ /* Out of room */
print_err(err_14_msg,EXIT_PROGRAM);
}
f_dmaset( dma );
dindex = f_sfirst( fcb );
if ( dindex == 0x00ff )
{
print_err(err_13_msg,EXIT_PROGRAM);
}
while( dindex != 0x00ff )
{
dindex = (dindex << 5) + 1; /* dindex * 32, skip */
fcount++; /* user number field */
flist = malloc( sizeof( struct _fcblst ) );
if (flist == 0)
{ /* Out of room */
print_err(err_14_msg,EXIT_PROGRAM);
}
fhead->next_fcb = flist;
fhead = flist;
if( fcount == 1 )
ftail = flist;
flist->fcb[0] = fcb[0]; /* insert drive code */
for( findex=1; findex < FCB_LEN; findex++ ) /* copy FCB */
flist->fcb[findex] = dma[dindex++];
for( findex=16; findex < 24; findex++ ) /* copy password*/
flist->fcb[findex-4] = fcb[findex];
dindex = f_snext( fcb );
}
flist->next_fcb = NULL; /* end FCB list */
f_dmaset( save_dma ); /* reset DMA address */
return( ftail ); /* front of list */
}
VOID passget(record)
BYTE *record;
{
BYTE *pass;
BYTE buffer[15];
BYTE *prt_buf;
c_writestr("\n\r");
prt_buf = &buffer[0];
prt_buf = expand_file_name(record,prt_buf);
*prt_buf = NULL;
c_writestr(&buffer[0]);
pass = getspass(pass_prompt); /* C RTL routine */
c_writestr("\n\r");
upper_case(pass); /* Convert to upper case */
strncpy(record+12,blanks,8); /* Blank out */
strncpy(record+12,pass,strlen(pass)); /* Replace */
}
/*----------------------------------------------------------------------*\
| NAME : ok_ver |
| CREATED : 5-August-83 LAST MODIFIED: 12-September-83 |
| FUNCTION: Ok_ver checks to see that the correct BDOS and OS |
| are being used. |
| INPUT : bdos_ver -- BDOS version number to look for. |
| os_ver -- OS version number to look for. |
| OUTPUT : Returns 1 for true, 0 for false. |
\*----------------------------------------------------------------------*/
WORD ok_ver( bdos_ver,os_ver )
WORD bdos_ver; /* min. BDOS version */
WORD os_ver; /* min. CP/M version */
{
WORD ver; /* S_BDOSVER return value (version #) */
s_bdosver();
ver = _EXTERR;
if(((ver & BDOS_MASK) < bdos_ver) || ((ver & OS_MASK) != os_ver))
return(FALSE);
return(TRUE);
}
BYTE *getspass(prompt)
BYTE *prompt;
{
BYTE pasword[8];
WORD pindex,xindex,ch;
c_writestr(prompt);
for (xindex=0;xindex<8;xindex++)
{
pasword[xindex] = ' ';
}
pindex = 0;
while (pindex<8)
{
ch = c_rawio(0x00fd); /* read a character */
if ( ch > ' ')
{
pasword[pindex++] = (BYTE)ch;
}
else
{
switch(ch)
{
case '\003' : p_termcpm(); /* ^C */
break;
case '\010' : if (pindex > 0 ) /* backspace */
pasword[--pindex] = ' ';
break;
case '\015' : c_writestr("\n\r"); /* CR */
pindex = 8;
break;
case '\030' : for( xindex=0;xindex<8;xindex++) /* ^X */
pasword[xindex] = ' ';
pindex = 0;
break;
default : break;
}
}
}
ch = c_stat();
return(&pasword[0]);
}
BYTE *expand_file_name(record,buffer)
BYTE *record;
BYTE *buffer;
{
BYTE *prt_buf;
WORD i;
prt_buf = buffer; /* pts to buffer to store name */
if (*record != 0)
{ /* not the default drive */
*prt_buf++ = (*record) + 64; /* store letter */
*prt_buf++ = ':';
}
record++; /* Move record ptr to filename */
for ( i=0; i<8 ; prt_buf++,i++,record++ )
{ /* Get filename 7-bit ASCII */
*prt_buf = *record & 0x7f;
}
*prt_buf++ = '.';
for ( i=0; i<3 ; prt_buf++,i++,record++ )
{ /* Get type 7-bits ASCII */
*prt_buf = *record & 0x7f;
}
return(prt_buf);
}
VOID patch_area()
{
WORD i;
i=i+5; i=i+5; i=i+5; i=i+5; i=i+5;
i=i+5; i=i+5; i=i+5; i=i+5; i=i+5;
i=i+5; i=i+5; i=i+5; i=i+5; i=i+5;
i=i+5; i=i+5; i=i+5; i=i+5; i=i+5;
i=i+5; i=i+5; i=i+5; i=i+5; i=i+5;
i=i+5; i=i+5; i=i+5; i=i+5; i=i+5;
i=i+5; i=i+5; i=i+5; i=i+5; i=i+5;
i=i+5; i=i+5; i=i+5; i=i+5; i=i+5;
i=i+5; i=i+5; i=i+5; i=i+5; i=i+5;
i=i+5; i=i+5; i=i+5; i=i+5; i=i+5;
}


View File

@@ -0,0 +1,15 @@
;
; FILES: main.c,chset.c,function.c,cpmfunc.h,portab.h,cpmif.a86
;
; CMD: drc,rasm86,link86
;
drc main.c -lmain.lst
drc chset.c -lchset.lst
drc function.c -lfunction.lst
;
rasm86 cpmif.a86
;
link86 chset[map]=main,chset,function,cpmif
;
;


View File

@@ -0,0 +1,18 @@
declare
lit literally 'literally',
dcl lit 'declare',
true lit '0ffh',
false lit '0',
no lit 'not',
boolean lit 'byte',
forever lit 'while true',
cr lit '13',
lf lit '10',
tab lit '9',
ctrlc lit '3',
ff lit '12',
page$len$offset lit '1ch',
nopage$mode$offset lit '2Ch',
sectorlen lit '128';


View File

@@ -0,0 +1,9 @@
/*
Copyright (C) 1983
Digital Research
P.O. Box 579
Pacific Grove, CA 93950
*/


View File

@@ -0,0 +1,28 @@
/*----------------------------------------------------------------------*\
| NAME : cpmerr |
| CREATED : 10-August-83 LAST MODIFIED: 12-September-83 |
| FUNCTION: Cpmerr prints CP/M error messages, specifically |
| BDOS error messages. |
| INPUT : term_msg -- ptr to an error message to print. |
| err_mode -- return or exit after printing. |
| OUTPUT : No return value. |
\*----------------------------------------------------------------------*/
#include <portab.h>
#include "utildef.h"
#include "cpmfunc.h"
/* THIS REFERENCE IS IN CPMFUNC.H
EXTERN VOID c_writestr();
*/
VOID cpmerr( term_msg,err_mode )
BYTE *term_msg; /* termination message */
WORD err_mode; /* exit/return mode */
{
c_writestr( term_msg );
if( err_mode < 0 )
p_termcpm();
}


View File

@@ -0,0 +1,247 @@
#define S_BDOSVER 12
#define DIR_SET 14
#define F_OPEN 15
#define F_CLOSE 16
#define F_SEARCH 17
#define F_DELETE 19
#define F_READ 20
#define F_WRITE 21
#define F_MAKE 22
#define F_RENAME 23
#define DIR_LOGINVEC 24
#define DIR_GET 25
#define F_DMASET 26
#define DIR_SETRO 28
#define DIR_ROVEC 29
#define F_ATTRIB 30
#define F_READRAND 33
#define F_WRITERAND 34
#define F_SIZE 35
#define F_RANDREC 36
#define DRV_RESET 37
#define DRV_ACCESS 38
#define DRV_FREE 39
#define F_WRITEZF 40
#define F_LOCK 42
#define F_UNLOCK 43
#define F_ERRMODE 45
#define DRV_SPACE 46
#define P_CHAIN 47
#define DRV_FLUSH 48
#define S_SYSVAR 49
#define F_DMAGET 52
#define P_RSX 60
#define P_EXCEPT 61
#define F_TRUNCATE 99
#define DRV_SETLABEL 100
#define F_TIMEDATE 102
#define F_WRITEXFCB 103
#define F_PASSWD 106
#define S_SERIAL 107
#define P_CODE 108
#define C_KTRAN 114
#define G_GSX 115
#define C_COPY 116
#define C_ALTER 117
#define CH_READ 118
#define CH_WRITE 119
#define CH_STAT 120
#define CH_DELIM 121
#define CH_MODE 122
#define CH_SET 123
#define CH_OWNER 124
#define CH_INFO 125
#define DRV_LOCK 126
#define DRV_UNLOCK 127
#define M_ALLOC 128
#define M_FREE 130
#define DEV_POLL 131
#define DEV_WAITFLAG 132
#define DEV_SETFLAG 133
#define Q_MAKE 134
#define Q_OPEN 135
#define Q_DELETE 136
#define Q_READ 137
#define Q_CREAD 138
#define Q_WRITE 139
#define Q_CWRITE 140
#define P_DELAY 141
#define P_DISPATCH 142
#define P_TERM 143
#define P_CREATE 144
#define P_PRIORITY 145
#define P_CLI 150
#define P_CALL 151
#define F_PARSE 152
#define P_PID 156
#define P_ABORT 157
#define S_OSVER 163
#define W_CREATE 165
#define W_TOP 166
#define W_WINDOW 167
#define W_KGIVE 168
#define W_KEYPUT 169
#define W_KCTRL 170
#define W_DELETE 171
#define F_LOCKMODE 172
#define F_SETDATE 173
#define F_TESTFCB 174
#define DRV_READLABEL 175
#define DRV_VECTOR 176
#define DRV_INFO 177
#define DRV_PHYIO 178
#define DIR_ASSIGN 179
#define DIR_MAKE 180
#define DIR_DELETE 181
#define DIR_PATHNAME 182
#define DIR_INFO 183
#define DEV_GETFLAG 184
#define DEV_RELFLAG 185
#define DEV_RESETFLAG 186
#define P_LOADPO 187
#define T_TIMEDATE 188
#define DRV_USERS 189
#define CD_INSTALL 190
#define CD_INFO 191
#define CD_SET 192
#define P_ASYNC 193
#define P_MWAIT 194
#define P_ACANCEL 195
#define P_ARET 196
#define P_EVENTS 197
/* CPM 4 RTL functions that do not need */
/* parameter conversion */
#define c_ktran(x) (WORD)__CPMIF(C_KTRAN,x)
#define dev_getflag() (UWORD)__CPMIF(DEV_GETFLAG,0)
#define dev_poll(x) (WORD)__CPMIF(DEV_POLL,x)
#define dev_relflag(x) (WORD)__CPMIF(DEV_RELFLAG,x)
#define dev_resetflag(x) (WORD)__CPMIF(DEV_RESETFLAG,x)
#define dev_setflag(x) (WORD)__CPMIF(DEV_SETFLAG,x)
#define dev_waitflag(x) (WORD)__CPMIF(DEV_WAITFLAG,x)
#define dir_delete(x) (BYTE)__CPMIF(DIR_DELETE,x)
#define dir_get() (BYTE)__CPMIF(DIR_GET,0)
#define dir_info(x) (UWORD)__CPMIF(DIR_INFO,x)
#define dir_loginvec() (UWORD)__CPMIF(DIR_LOGINVEC,0)
#define dir_make(x) (BYTE)__CPMIF(DIR_MAKE,x)
#define dir_pathname(x) (UBYTE)__CPMIF(DIR_PATHNAME,x)
#define dir_rovec() (UWORD)__CPMIF(DIR_ROVEC,0)
#define dir_set(x) (BYTE)__CPMIF(DIR_SET,x)
#define dir_setro() (BYTE)__CPMIF(DIR_SETRO,0)
#define drv_access(x) (BYTE)__CPMIF(DRV_ACCESS,x)
#define drv_flush(x) (BYTE)__CPMIF(DRV_FLUSH,x)
#define drv_free(x) (BYTE)__CPMIF(DRV_FREE,x)
#define drv_lock(x) (BYTE)__CPMIF(DRV_LOCK,x)
#define drv_readlabel(x) (BYTE)__CPMIF(DRV_READLABEL,x)
#define drv_reset(x) (BYTE)__CPMIF(DRV_RESET,x)
#define drv_setlabel(x) (BYTE)__CPMIF(DRV_SETLABEL,x)
#define drv_space(x) (BYTE)__CPMIF(DRV_SPACE,x)
#define drv_unlock(x) (BYTE)__CPMIF(DRV_UNLOCK,x)
#define drv_vector() (UWORD)__CPMIF(DRV_VECTOR,0)
#define f_attrib(x) (BYTE)__CPMIF(F_ATTRIB,x)
#define f_close(x) (BYTE)__CPMIF(F_CLOSE,x)
#define f_delete(x) (BYTE)__CPMIF(F_DELETE,x)
#define f_dmaget() (UBYTE *)__CPMIF(F_DMAGET,0)
#define f_dmaset(x) __CPMIF(F_DMASET,x)
#define f_errmode(x) __CPMIF(F_ERRMODE,x)
#define f_lock(x) (BYTE)__CPMIF(F_LOCK,x)
#define f_lockmode(x) (BYTE)__CPMIF(F_LOCKMODE,x)
#define f_make(x) (BYTE)__CPMIF(F_MAKE,x)
#define f_open(x) (BYTE)__CPMIF(F_OPEN,x)
#define f_passwd(x) (BYTE)__CPMIF(F_PASSWD,x)
#define f_parse(x) (UBYTE *)__CPMIF(F_PARSE,x)
#define f_randrec(x) (BYTE)__CPMIF(F_RANDREC,x)
#define f_read(x) (BYTE)__CPMIF(F_READ,x)
#define f_readrand(x) (BYTE)__CPMIF(F_READRAND,x)
#define f_rename(x) (BYTE)__CPMIF(F_RENAME,x)
#define f_setdate(x) (BYTE)__CPMIF(F_SETDATE,x)
#define f_search(x) (BYTE *)__CPMIF(F_SEARCH,x)
#define f_size(x) (BYTE)__CPMIF(F_SIZE,x)
#define f_testfcb(x) (BYTE)__CPMIF(F_TESTFCB,x)
#define f_timedate(x) (BYTE)__CPMIF(F_TIMEDATE,x)
#define f_truncate(x) (BYTE)__CPMIF(F_TRUNCATE,x)
#define f_unlock(x) (BYTE)__CPMIF(F_UNLOCK,x)
#define f_write(x) (BYTE)__CPMIF(F_WRITE,x)
#define f_writerand(x) (BYTE)__CPMIF(F_WRITERAND,x)
#define f_writexfcb(x) (BYTE)__CPMIF(F_WRITEXFCB,x)
#define f_writezf(x) (BYTE)__CPMIF(F_WRITEZF,x)
#define m_alloc(x) (WORD)__CPMIF(M_ALLOC,x)
#define m_free(x) (WORD)__CPMIF(M_FREE,x)
#define p_abort(x) (WORD)__CPMIF(P_ABORT,x)
#define p_acancel(x) (UWORD)__CPMIF(P_ACANCEL,x)
#define p_aret(x) (UWORD)__CPMIF(P_ARET,x)
#define p_asynch(x) (UWORD)__CPMIF(P_ASYNCH,x)
#define p_chain(x) (WORD)__CPMIF(P_CHAIN,x)
#define p_cli(x) (WORD)__CPMIF(P_CLI,x)
#define p_code(x) (LONG)__CPMIF(P_CODE,x)
#define p_create(x) (WORD)__CPMIF(P_CREATE,x)
#define p_delay(x) (WORD)__CPMIF(P_DELAY,x)
#define p_dispatch() __CPMIF(P_DISPATCH,0)
#define p_events() (UWORD)__CPMIF(P_EVENTS,0)
#define p_except(x) (WORD)__CPMIF(P_EXCEPT,x)
#define p_id() (UWORD)__CPMIF(P_ID,0)
#define p_loadpo(x) (WORD)__CPMIF(P_LOADPO,x)
#define p_mwait(x) (UWORD)__CPMIF(P_MWAIT,x)
#define p_priority(x) __CPMIF(P_PRIORITY,x)
#define p_super() __CPMIF(P_SUPER,0)
#define p_term(x) (WORD)__CPMIF(P_TERM,x)
#define q_cread(x) (WORD)__CPMIF(Q_CREAD,x)
#define q_cwrite(x) (WORD)__CPMIF(Q_CWRITE,x)
#define q_delete(x) (WORD)__CPMIF(Q_DELETE,x)
#define q_make(x) (WORD)__CPMIF(Q_MAKE,x)
#define q_read(x) (WORD)__CPMIF(Q_READ,x)
#define q_write(x) (WORD)__CPMIF(Q_WRITE,x)
#define s_bdosver() (WORD)__CPMIF(S_BDOSVER,0)
#define s_osver() (WORD)__CPMIF(S_OSVER,0)
#define s_serial() (WORD)__CPMIF(S_SERIAL,0)
#define s_sysvar(x) (WORD)__CPMIF(S_SYSVAR,x)
#define w_delete(x) (WORD)__CPMIF(W_DELETE,x)
#define w_kgive(x) (WORD)__CPMIF(W_KGIVE,x)
#define w_top(x) (WORD)__CPMIF(W_TOP,x)
#define w_window(x) (WORD)__CPMIF(W_WINDOW,x)
#define C_READ 1
#define C_WRITE 2
#define C_RAWIO 6
#define C_WRITESTR 9
#define C_READSTR 10
#define C_STAT 11
#define C_DELIMIT 110
#define C_GET 153
#define F_USERNUM 32
#define F_SFIRST 17
#define F_SNEXT 18
#define L_SETNUM 160
#define L_GETNUM 164
#define L_ATTACH 158
#define L_DETACH 159
#define L_CATTACH 161
#define L_WRITE 5
#define L_WRITEBLK 112
#define P_TERMCPM 0
#define c_get() (BYTE)__CPMIF(C_GET,0)
#define c_read() (BYTE)__CPMIF(C_READ,0)
#define c_write(x) __CPMIF(C_WRITE,x)
#define c_rawio(x) (BYTE)__CPMIF(C_RAWIO,x)
#define c_writestr(x) __CPMIF(C_WRITESTR,x)
#define c_readstr(x) __CPMIF(C_READSTR,x)
#define c_stat() (BYTE)__CPMIF(C_STAT,0)
#define c_delimit(x) (BYTE)__CPMIF(C_DELIMIT,x)
#define f_usernum(x) (BYTE)__CPMIF(F_USERNUM,x)
#define f_sfirst(x) (WORD)__CPMIF(F_SFIRST,x)
#define f_snext() (WORD)__CPMIF(F_SNEXT,0)
#define l_setnum(x) __CPMIF(L_SETNUM,x)
#define l_getnum() (WORD)__CPMIF(L_GETNUM,0)
#define l_attach() (WORD)__CPMIF(L_ATTACH,0)
#define l_detach() __CPMIF(L_DETACH,0)
#define l_cattach() (WORD)__CPMIF(L_CATTACH,0)
#define l_write(x) __CPMIF(L_WRITE,x)
#define l_writeblk(x) __CPMIF(L_WRITEBLK,x)
#define p_termcpm() __CPMIF(P_TERMCPM,0)


View File

@@ -0,0 +1,44 @@
;
; __CPMIF( func,arg ) is an extended version of __BDOS( func,arg )
; supplied with the DRC compiler. The extension made was the
; saving of registers AX and CX in common data segments, as
; recommended by the DRC Language Programmer's Guide (p. 5-6,5-7)
;
; _SYSERR CX register save area
; _EXTERR AX register save area
;
PUBLIC __CPMIF
_SYSERR DSEG COMMON BYTE
REG_CX RW 1
_EXTERR DSEG COMMON BYTE
REG_AX RW 1
DSEG
DGROUP GROUP DATA
DGROUP GROUP _SYSERR
DGROUP GROUP _EXTERR
CSEG
__CPMIF: ;(FUNC,ARG)
PUSH BP
MOV BP,SP
PUSH DI
PUSH SI
MOV CX,4[BP]
MOV DX,6[BP]
PUSH BP
INT 0E0H
POP BP
POP SI
POP DI
POP BP
MOV REG_AX,AX ;SAVE REG. AX
MOV REG_CX,CX ;SAVE REG. CX
XOR AH,AH
RET


View File

@@ -0,0 +1,41 @@
/*----------------------------------------------------------------------*\
| NAME : copy_ucase |
| CREATED : 24-August-83 LAST MODIFIED: 6-October-83 |
| FUNCTION: Copy_ucase copies n characters from the source |
| destination string, upper casing each char first. |
| NULL characters are replaced with a space if it |
| is not the last character on the line. |
| INPUT : src -- ptr to source string |
| dst -- ptr to destination string |
| max -- number of characters to copy |
| OUTPUT : No return value. |
\*----------------------------------------------------------------------*/
#include <portab.h>
#include "utildef.h"
#include "cpmfunc.h"
/* THIS REFERENCE IS IN CPMFUNC.H
EXTERN VOID c_write();
*/
VOID copy_ucase( dst,src,max_len )
BYTE dst[];
BYTE *src;
WORD max_len;
{
BYTE ch;
WORD dindex;
for( dindex=0; dindex < max_len; dindex++ )
{
ch = *src++;
if( ch == NULL )
dst[dindex] = ' ';
else
dst[dindex] = toupper( ch );
}
dst[dindex] = NULL;
}


View File

@@ -0,0 +1,24 @@
/*----------------------------------------------------------------------*\
| NAME : crlf |
| CREATED : 20-August-83 LAST MODIFIED: 12-September-83 |
| FUNCTION: Crlf writes a <cr> <lf> sequence to the attatched |
| console. |
| INPUT : No input values. |
| OUTPUT : No return value. |
\*----------------------------------------------------------------------*/
#include <portab.h>
#include "utildef.h"
#include "cpmfunc.h"
/* THIS REFERENCE IS IN CPMFUNC.H
EXTERN VOID c_write();
*/
VOID crlf()
{
c_write( '\015' );
c_write( '\012' );
}


View File

@@ -0,0 +1,23 @@
declare
f$drvusr lit '0', /* drive/user byte */
f$name lit '1', /* file name */
f$namelen lit '8', /* file name length */
f$type lit '9', /* file type field */
f$typelen lit '3', /* type length */
f$rw lit '9', /* high bit is R/W attribute */
f$dirsys lit '10', /* high bit is dir/sys attribute */
f$arc lit '11', /* high bit is archive attribute */
f$ex lit '12', /* extent */
f$s1 lit '13', /* module byte */
f$rc lit '15', /* record count */
f$diskmap lit '16', /* file disk map */
diskmaplen lit '16', /* disk map length */
f$drvusr2 lit '16', /* fcb2 */
f$name2 lit '17',
f$type2 lit '25',
f$cr lit '32', /* current record */
f$rrec lit '33', /* random record */
f$rreco lit '35'; /* " " overflow */


View File

@@ -0,0 +1,46 @@
/*----------------------------------------------------------------------*\
| NAME : fileopen |
| CREATED : 19-August-83 LAST MODIFIED: 12-September-83 |
| FUNCTION: Fileopen opens a files specified in the passed FCB, |
| checking for errors. If a password error is detected|
| user is prompted, and open is retried once. After |
| that BDOS extended or physical error is returned. |
| INPUT : fcb -- ptr to FCB for file to open. |
| OUTPUT : Returns BDOS extended or physical error code. |
\*----------------------------------------------------------------------*/
#include <portab.h>
#include "utildef.h"
#include "cpmfunc.h"
/* THESE REFERENCES ARE IN CPMFUNC.H
EXTERN WORD f_dmaget();
EXTERN VOID f_dmaset();
EXTERN WORD f_open();
EXTERN VOID c_writestr();
*/
EXTERN VOID cpmerr();
EXTERN BYTE *err10;
WORD fileopen( fcb )
BYTE fcb[];
{
WORD ret_code;
f_dmaset( &fcb[16] ); /* set DMA to password */
f_open( fcb );
ret_code = _EXTERR;
if( (ret_code & 0x00ff) == 0x00ff ) /* logical error */
if( (ret_code >> 8) == 7 ) /* if password error, */
{
crlf();
cpmerr( err10,0 );
putfname( fcb,0 );
}
ret_code = ret_code >> 8; /* error, return extend-*/
return( ret_code );
}


View File

@@ -0,0 +1,25 @@
/*----------------------------------------------------------------------*\
| NAME : firstch |
| CREATED : 15-August-83 LAST MODIFIED: 15-August-83 |
| FUNCTION: Firstch finds and returns the first non-white |
| character in a string passed to it. |
| INPUT : str -- ptr to string to scan. |
| OUTPUT : Returns first non-white character found, or NULL |
| if none was found. |
\*----------------------------------------------------------------------*/
#include <portab.h>
#include "utildef.h"
BYTE firstch( str )
BYTE *str; /* source to search */
{
BYTE *sptr;
sptr = str;
while( *sptr == ' ' || *sptr == '\t' )
sptr++; /* ignore white space */
return( *sptr );
}


View File

@@ -0,0 +1,8 @@
/* Flag Format */
dcl flag$structure lit 'structure(
pd word,
ignore byte)';


View File

@@ -0,0 +1,426 @@
/***
This file contains all the necessary routines to perform the
functioniality of CHSET. The two entry points are the functions
get_settings and set_fields. Both functions are called with a
byte pointer that points to a record. Both functions return an
error code from BDOS if you have set f_errmode (O.S. call 0x2d)
to 0xfe or 0xff.
Format of record:
---------------------------------------------------
| d | filename | typ | password | fields |
---------------------------------------------------
byte 0 1 8 9 11 12 19 20 22
d drive number
filename filename (can have attribute bits on)
typ type (can have attribute bits on)
password password
fields offset name
20 8087
21 SHARED
22 SUSPEND
GET_SETTINGS:
On exit, without an error, all fields will have a byte number in
them corresponding to the bit pattern that was match in com_tab. For
example the field SUSPEND has to possible settings ON and OFF, since
ON is before OFF in com_tab a zero will represent it while a one will
represent the setting of OFF.
SET_FIELDS:
On exit, without an error, all fields that where not EMPTY(i.e. -1)
will have caused the corresponding bit(s) in the given filespec to
be set or reset.
NOTES:
All offsets and counts are from zero unless specified otherwise.
BDOS opens write password protected files in R/O mode when the
wrong password is given; and then wrongly reports an R/O file
error when we try to write to the file. Therefore set_fields
prints out a proper error msg. If you set f_errmode to 0xff
you will need to compile with the -dno_errors option so this
special error message will not be printed.
***/
#include <portab.h>
#include "cpmfunc.h"
EXTERN WORD _EXTERR; /* holds AX after O.S. call */
#define NOT_FOUND -1
#define EXIT_PROGRAM -1
#define CONTINUE 1
#define LOW_TO_UP ('a' - 'A')
#define T1 9 /* T1 attribute */
#define F7 7 /* F7 attribute */
#define F6 6 /* F6 attribute */
#define ON 0x80 /* mask for attribute bit */
#define PASSWORD 0x07ff /* BDOS error for wrong password */
#define RO_ERROR 0x03ff /* BDOS error for R/O file */
#define DMA_LEN 128
#define FCB_LEN 36
/*** Record Constants ***/
/* offsets */
#define REC_PASSWORD 12
#define REC_FIELDS 20
/* values */
#define EMPTY -1 /* Can not be same as option number */
/***
ADDING NEW FIELDS:
Add the correct data to com_tab[], add one to MAX_FIELD for
each new field and modify first_opt[] to reflect where the new options
are in the com_tab[].
***/
struct comm_str
{
LONG rec_num; /* Record 0,1,....big */
WORD byte_num; /* Byte 0,1,...,127 */
BYTE bit_num; /* Bit 7,6,...,1,0 */
BYTE *pattern; /* Pattern 0 or 1 or X */
};
struct comm_str com_tab[] =
{
0L, 127, 6, "X1", /* 80 = on */
0L, 127, 6, "00", /* 80 = of */
0L, 127, 6, "10", /* 80 = op */
0L, 0, 3, "1", /* sh = on */
0L, 0, 3, "0", /* sh = of */
0L, 127, 3, "1", /* su = on */
0L, 127, 3, "0" /* su = of */
};
#define MAX_FIELD 3
BYTE first_opt[] =
{
0, /* 8087 */
3, /* shared */
5, /* suspend */
7 /* tells routines that suspend is 5,6 only */
};
BYTE *bdos_01_msg = "\n\rFile password protected in Write mode\n\r";
BYTE buffer[DMA_LEN];
BYTE fcb_01[FCB_LEN];
WORD get_settings(record)
BYTE *record;
{
BYTE *fcb; /* FCB pointer */
BYTE *dma; /* DMA pointer */
BYTE *field; /* pts to field's options */
LONG cur_rec; /* current record in DMA */
WORD error;
WORD i;
BYTE start,end;
fcb = &fcb_01[0]; /* set up FCB */
field = record + REC_FIELDS; /* pts to the first field's option */
copy(record,fcb,12); /* put dfilenametyp in FCB */
*(fcb+12) = 0; /* extent number */
f_dmaset(record+REC_PASSWORD); /* DMA points to the password */
*(fcb+F6) = *(fcb+F6) | ON; /* Set to Read/Only */
f_open(fcb);
if ( (error = _EXTERR) != 0)
{
return(error);
}
dma = &buffer[0];
f_dmaset(dma);
cur_rec = -1; /* i.e. no record in DMA */
for ( i=0; i < MAX_FIELD; i++)
{
if ( cur_rec != com_tab[i].rec_num )
{
if ( (error=get_rec(fcb,com_tab[i].rec_num,FALSE)) != 0)
{
f_close(fcb);
return(error);
}
}
start = first_opt[i];
end = first_opt[i+1] - 1;
end = cmp_patterns(start,end,dma);
*field++ = end;
}
f_close(fcb);
if (_EXTERR !=0)
{
return(_EXTERR);
}
return(0);
}
VOID set_ran_rec(fcb,rec_number)
BYTE *fcb;
LONG rec_number;
{
*(fcb+33) = (0xffL & rec_number);
*(fcb+34) = ((0xff00L & rec_number) >> 8);
*(fcb+35) = ((0xff0000L & rec_number) >> 16);
}
WORD cmp_patterns(start,end,dma)
BYTE start;
BYTE end;
BYTE *dma; /* ptr to DMA buffer */
{
BYTE index;
BYTE *byte_ptr;
for (index=start; index<=end; index++)
{
if ( ((bits_match(&com_tab[index],dma)) == TRUE) )
{
return(index-start);
}
}
return(-1);
}
WORD bits_match(com_rec,dma)
struct comm_str *com_rec;
BYTE *dma;
{
BYTE *byte_ptr; /* points to byte */
BYTE bit_number; /* 8 0's and 1's */
BYTE bit; /* contains a 0 or 1 */
BYTE *bit_pattern; /* pts to pattern */
BYTE is_on;
byte_ptr = dma + com_rec->byte_num;
bit_pattern = com_rec->pattern;
bit_number = com_rec->bit_num;
while ( (*bit_pattern != NULL) )
{ /* still in pattern */
is_on = ((*byte_ptr) >> (bit_number)) & 0x01;
/** is_on is 1 if bit coresponding to pattern is on **/
if ( ((is_on == 1) && (*bit_pattern == '0')) ||
((is_on == 0) && (*bit_pattern == '1')) )
{ /* not a match */
return(FALSE);
}
bit_pattern++; /* pts to next char that represents a bit */
bit_number--; /* dec bit postion to check pattern against */
}
return(TRUE);
}
VOID copy(source,dest,cnt)
BYTE *source;
BYTE *dest;
WORD cnt;
{
BYTE i;
for (i=0; i<cnt; i++)
{
*dest++ = *source++;
}
}
WORD get_rec(fcb,rec_num,write)
BYTE *fcb;
LONG rec_num;
WORD write; /* flag to dump DMA or not */
{
if ( write == TRUE )
{ /* Will write out DMA buffer */
f_writerand(fcb);
if (_EXTERR != 0)
{
return(_EXTERR);
}
}
set_ran_rec(fcb,rec_num);
f_readrand(fcb);
if (_EXTERR != 0)
{
return(_EXTERR);
}
return(0);
}
WORD set_fields(record)
BYTE *record;
{
BYTE *fcb; /* FCB pointer */
BYTE *dma; /* DMA pointer */
BYTE *field; /* pts to field's options */
LONG cur_rec; /* current record in DMA */
WORD error;
WORD i;
WORD ro_wr_pass = FALSE; /* RO because of wrong pass */
BYTE start;
WORD end;
WORD write; /* Flag to write DMA or not */
fcb = &fcb_01[0]; /* set up FCB */
field = record + REC_FIELDS; /* pts to the first field's option */
copy(record,fcb,12); /* put dfilenametyp in FCB */
*(fcb+12) = 0; /* extent number */
f_dmaset(record+REC_PASSWORD); /* DMA points to the password */
f_open(fcb);
if (_EXTERR != 0)
{
return(_EXTERR);
}
if ( (((*(fcb+T1)) & 0x80) != ON) && (((*(fcb+F7)) & 0x80) == ON) )
{ /* File is RW and write protected but wrong password */
ro_wr_pass = TRUE;
}
dma = &buffer[0];
f_dmaset(dma);
cur_rec = -1; /* i.e. no record in DMA */
write = FALSE;
for ( i=0; i < MAX_FIELD; i++)
{
if ( (*(field+i) != ((BYTE)EMPTY)) )
{ /* given field needs to be set */
if ( (cur_rec != com_tab[i].rec_num) )
{ /* In different record so fetch it */
if ((error=get_rec(fcb,com_tab[i].rec_num,write)) != 0)
{
f_close(fcb);
return(error);
}
else
{
cur_rec = com_tab[i].rec_num;
write = FALSE; /* default after a read */
}
}
start = first_opt[i] + *(field+i); /* opt loc in table */
end = cmp_patterns(start,start,dma);
if ( (end == -1) )
{ /* must set field */
if ( ro_wr_pass == TRUE )
{ /* Need password so bug user for it */
/***
Next line needed as BDOS will not print a error msg.
if you compile with -dno_errors then you will
not get this error msg.
***/
#ifndef no_errors
c_writestr(bdos_01_msg);
#endif
return(PASSWORD);
}
write = TRUE; /* will need to write DMA */
set_pattern(&com_tab[start],dma);
}
}
}
if ( write == TRUE)
{
f_writerand(fcb);
error = _EXTERR;
if ( (error != 0) )
{
f_close(fcb); /* will try to close */
return(error); /* returning write error */
}
}
f_close(fcb);
if (_EXTERR !=0)
{
return(_EXTERR);
}
return(0);
}
VOID set_pattern(com_rec,dma)
struct comm_str *com_rec;
BYTE *dma; /* pts to buffer */
{
BYTE *byte_ptr; /* points to byte */
BYTE bit_number; /* the bit number */
BYTE *bit_pattern; /* pts to pattern */
BYTE mask;
byte_ptr = dma + com_rec->byte_num;
bit_pattern = com_rec->pattern;
bit_number = com_rec->bit_num;
while ( (*bit_pattern != NULL) )
{ /* still have bits to do */
if ( (*bit_pattern != 'X') )
{ /* either a '1' or '0' so set */
mask = (0x01 << (bit_number));
if (*bit_pattern == '0')
{ /* AND bit to zero */
*byte_ptr = (*byte_ptr & ~(mask));
}
else
{ /* OR bit to a one */
*byte_ptr = (*byte_ptr | mask);
}
}
bit_pattern++; /* point to next bit in pattern */
bit_number--; /* point to next bit in DMA */
}
}


View File

@@ -0,0 +1,31 @@
/*----------------------------------------------------------------------*\
| NAME : get_drv |
| CREATED : 5-August-83 LAST MODIFIED: 12-September-83 |
| FUNCTION: Get_drv extracts the drive code from the FCB passed |
| to it and converts it to an ASCII character that |
| that code represents. |
| INPUT : ptr to FCB to check. |
| OUTPUT : Returns A-P drive value. |
\*----------------------------------------------------------------------*/
#include <portab.h>
#include "utildef.h"
#include "cpmfunc.h"
/* THIS REFERENCE IS IN CPMFUNC.H
EXTERN WORD dir_get();
*/
BYTE get_drv( fcb )
BYTE fcb[]; /* ptr to current FCB */
{
BYTE drv; /* current drive (A-P) */
if( *fcb == 0 )
drv = dir_get() + 'A';
else
drv = fcb[0] + 'A' - 1;
return( drv );
}


View File

@@ -0,0 +1,32 @@
/*----------------------------------------------------------------------*\
| NAME : get_num |
| CREATED : 5-August-83 LAST MODIFIED : 7-October-83 |
| FUNCTION: Get_num retrieves a number appended to the end of |
| a string pointed to by option. If none is found the |
| default value, dflt, is returned. |
| INPUT : option -- pointer to command option string |
| dflt -- default value of number if none was found |
| OUTPUT : Returns number appened to option, or default if not |
| found. |
\*----------------------------------------------------------------------*/
#include <portab.h>
#include "utildef.h"
WORD get_num( option,dflt )
BYTE *option; /* ptr to current option */
WORD dflt; /* default number, if not found */
{
WORD num; /* number taken from option */
num = 0;
while( isalpha( *option ) ) /* skip alphabetic ch. */
option++;
if( !isdigit( *option ) ) /* no digits found */
num = dflt;
else /* extract number */
num = atoi( option );
return( num );
}


View File

@@ -0,0 +1,43 @@
/*----------------------------------------------------------------------*\
| NAME : get_tail |
| CREATED : 29-July-83 LAST MODIFIED: 12-September-83 |
| FUNCTION: Get_tail retrieves the command tail from the user |
| when it is not explicitly given on the command line. |
| INPUT : prompt -- pointer to a user prompt string |
| tail -- pointer to a character array for the |
| tail input |
| OUTPUT : tail -- filled in with input command tail |
| No return value |
\*----------------------------------------------------------------------*/
#include <portab.h>
#include "utildef.h"
#include "cpmfunc.h"
/* THIS REFERENCE IS IN CPMFUNC.H
EXTERN VOID c_writestr();
EXTERN VOID c_readstr();
*/
EXTERN VOID crlf();
VOID get_tail( prompt,tail )
BYTE *prompt; /* user prompt */
BYTE *tail; /* ptr to tail buffer */
{
struct _cbuf cbuf;
BYTE *tptr;
WORD cindex;
tptr = tail;
cbuf.max_char = DMA_LEN;
c_writestr( prompt ); /* promt user */
c_readstr( &cbuf ); /* read user response */
crlf(); /* echo carraige return, line feed */
for( cindex=0; cindex < cbuf.nchar; cindex++ )
*tptr++ = toupper( cbuf.buffer[cindex] );
*tptr = NULL;
}


View File

@@ -0,0 +1,20 @@
/*----------------------------------------------------------------------*\
| NAME : is_sysfile |
| CREATED : 18-August-83 LAST MODIFIED: 18-August-83 |
| FUNCTION: Is_sysfile checks to see if an FCB references a |
| system type file. |
| INPUT : fcb -- ptr to an FCB to check |
| OUTPUT : Return 1 if a system file was found, 0 if not. |
\*----------------------------------------------------------------------*/
#include <portab.h>
WORD is_sysfile( fcb )
BYTE fcb[];
{
if( fcb[10] & ~0x7f )
return( YES );
return( NO );
}


View File

@@ -0,0 +1,39 @@
/*----------------------------------------------------------------------*\
| NAME : itoa |
| CREATED : 16-August-83 LAST MODIFIED: 16-August-83 |
| FUNCTION: Itoa converts a WORD (integer) into an ASCII string |
| that represents that number. |
| INPUT : number -- number to conver. |
| str -- ptr to string that will hold the |
| converted number. |
| OUTPUT : Fills in the string pointed to by str with the ASCII |
| representation of number. |
| No return value. |
\*----------------------------------------------------------------------*/
#include <portab.h>
#include "utildef.h"
EXTERN VOID reverse();
VOID itoa( number,str )
WORD number; /* number to convert to string */
BYTE str[]; /* converted number */
{
WORD sindex; /* string index */
WORD sign; /* number sign */
if( (sign = number) < 0 )
number = -number;
sindex = 0;
do
str[sindex++] = (number % 10) + '0';
while( (number /= 10) > 0 );
if( sign < 0 )
str[sindex++] = '-';
str[sindex] = NULL;
reverse( str );
}


View File

@@ -0,0 +1,9 @@
#include "portab.h"
#include "cpmfunc.h"
_main()
{
main();
p_termcpm();
}


View File

@@ -0,0 +1,24 @@
declare md$structure literally
'structure(
link word,
start word,
length word,
plist word,
unused word)';
declare ms$structure literally
'structure(
link word,
start word,
length word,
flags word,
mau word)';
declare sat$structure literally
'structure(
start word,
len word,
num$allocs byte)';


View File

@@ -0,0 +1,46 @@
/* Concurrent CP/M function numbers */
dcl m$prtbuf lit '9',
m$select lit '14',
m$openf lit '15',
m$closef lit '16',
m$deletef lit '19',
m$readf lit '20',
m$writef lit '21',
m$makef lit '22',
m$getlogin lit '24',
m$curdsk lit '25',
m$setdma lit '26',
m$setatt lit '30',
m$setusr lit '32',
m$readrf lit '33',
m$writerf lit '34',
m$resetdrv lit '37',
m$errmode lit '45',
m$dirbios lit '50',
m$makeq lit '134',
m$openq lit '135',
m$deleteq lit '136',
m$readq lit '137',
m$creadq lit '138',
m$writeq lit '139',
m$cwriteq lit '140',
m$delay lit '141',
m$dispatch lit '142',
m$setprior lit '145',
m$attach lit '146',
m$detach lit '147',
m$setcns lit '148',
m$parse lit '152',
m$getcns lit '153',
m$sysdat lit '154',
m$getpd lit '156',
m$abort lit '157';
/* Internal calls */
dcl mi$sleep lit '0212H',
mi$wakeup lit '0213H';


View File

@@ -0,0 +1,12 @@
declare
lit literally 'literally',
dcl lit 'declare',
true lit '0ffh',
false lit '0',
no lit 'not',
boolean lit 'byte',
forever lit 'while true',
tab lit '9';


View File

@@ -0,0 +1,82 @@
/*----------------------------------------------------------------------*\
| NAME : nextfcb |
| CREATED : 7-September-83 LAST MODIFIED: 10-February-84 |
| FUNCTION: Nextfcb parses the passed filespec when it is called |
| for the first time and returns the first matching |
| FCB for the passed filespec. On subsequent calls |
| nextfcb does not parse the filespec. It will find |
| and return the next matching FCB. |
| INPUT : filespec -- pointer to a filespec. |
| curfcb -- pointer to the current FCB |
| (set to 0xff the first time) |
| OUTPUT : Fills in the current FCB (curfcb) |
| Returns: |
| -1 -- no files found |
| 0 -- file found, no more following |
\*----------------------------------------------------------------------*/
#include <portab.h>
#include "utildef.h"
#include "cpmfunc.h"
/* THESE REFERENCES ARE IN CPMFUNC.H
EXTERN WORD f_sfirst();
EXTERN WORD f_snext();
EXTERN VOID f_dmaset();
EXTERN WORD f_dmaget();
*/
EXTERN BYTE *parse();
WORD nextfcb( filespec,wild_fcb,curfcb )
BYTE *filespec;
BYTE wild_fcb[];
BYTE curfcb[];
{
struct _pfcb pfcb;
WORD dcnt;
WORD ret_code;
WORD findex;
BYTE *save_dma;
BYTE dma[DMA_LEN];
BYTE tmpfcb[FCB_LEN];
f_dmaset( dma ); /* set DMA to local area */
if( curfcb[0] == 0xff ) /* first time through ? */
{
pfcb.fname = filespec; /* parse the filespec */
pfcb.fcbaddr = wild_fcb;
if( parse( &pfcb ) == 0xffff )
return( -2 );
wild_fcb[EX_FIELD] = 0x00;
wild_fcb[CR_FIELD] = 0x00;
dcnt = f_sfirst( wild_fcb );
}
else /* second, and subsequent calls */
{ /* jump to this point */
if( (dcnt = f_sfirst( curfcb )) != 0x00ff )
{
for( findex=0; findex < FCB_LEN; findex++ )
curfcb[findex] = wild_fcb[findex]; /* reset wildcard */
dcnt = f_snext();
}
}
if( dcnt != 0x00ff )
{
dcnt = (dcnt << 5) + 1; /* dcnt * 32 + 1 */
tmpfcb[0] = wild_fcb[0];
for( findex=1; findex < FCB_LEN; findex++ ) /* save matched FCB */
tmpfcb[findex] = dma[dcnt++];
for( findex=16; findex < 24; findex++ ) /* save password */
tmpfcb[findex] = wild_fcb[findex];
for( findex=0; findex < FCB_LEN; findex++ ) /* set curfcb */
curfcb[findex] = tmpfcb[findex];
ret_code = 0;
}
else
ret_code = -1; /* file not found */
return( ret_code );
}


View File

@@ -0,0 +1,32 @@
/*----------------------------------------------------------------------*\
| NAME : ok_ver |
| CREATED : 5-August-83 LAST MODIFIED: 12-September-83 |
| FUNCTION: Ok_ver checks to see that the correct BDOS and OS |
| are being used. |
| INPUT : bdos_ver -- BDOS version number to look for. |
| os_ver -- OS version number to look for. |
| OUTPUT : Returns 1 for true, 0 for false. |
\*----------------------------------------------------------------------*/
#include <portab.h>
#include "utildef.h"
#include "cpmfunc.h"
/* THIS REFERENCE IS IN CPMFUNC.H
EXTERN WORD s_bdosver();
*/
WORD ok_ver( bdos_ver,os_ver )
WORD bdos_ver; /* min. BDOS version */
WORD os_ver; /* min. CP/M version */
{
WORD ver; /* S_BDOSVER return value (version #) */
s_bdosver();
ver = _EXTERR;
if(((ver & BDOS_MASK) < bdos_ver) || ((ver & OS_MASK) != os_ver))
return( NOT_OK );
return( OK );
}


View File

@@ -0,0 +1,59 @@
/*----------------------------------------------------------------------*\
| NAME : parse |
| CREATED : 29-July-83 LAST MODIFIED: 16-September-83 |
| FUNCTION: Parse calls f_parse to parse a filespec. It is |
| responsible for handling error conditions returned |
| by f_parse. |
| INPUT : pfcb_ptr -- ptr to a parse FCB structure, which |
| contains address for a filespec |
| and an FCB. |
| OUTPUT : Fills in FCB pointed to by pfcb.fcbaddr. |
| Returns pointer to filespec delimiter. |
\*----------------------------------------------------------------------*/
#include <portab.h>
#include "utildef.h"
#include "cpmfunc.h"
/* THIS REFERENCE IS IN CPMFUNC.H
EXTERN WORD f_parse();
*/
EXTERN VOID cpmerr();
EXTERN VOID crlf();
EXTERN VOID putfname();
EXTERN BYTE *err06;
EXTERN BYTE *err10;
BYTE *parse( pfcb_ptr )
struct _pfcb *pfcb_ptr; /* ptr to a parse FCB */
{
WORD ret_code; /* BDOS call return code */
WORD err_code; /* BDOS call error code */
f_parse( pfcb_ptr );
ret_code = _EXTERR;
err_code = _SYSERR;
if( ret_code == FPAR_ERR )
{
crlf();
switch( err_code )
{
case 23 : /* bad drive */
case 24 : /* bad name */
case 25 : cpmerr( err06,0 ); /* bad type */
putfname( pfcb_ptr->fcbaddr,0 );
crlf();
break;
case 38 : cpmerr( err10,0 ); /* bad password */
putfname( pfcb_ptr->fcbaddr,0 );
crlf();
break;
default : break;
}
}
return( ret_code ); /* return ptr to delimiter */
}


View File

@@ -0,0 +1,59 @@
/*****************************************************************************
*
* C P / M C R U N T I M E L I B H E A D E R F I L E
* -------------------------------------------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* This is an include file for assisting the user to write portable
* programs for C.
*
*****************************************************************************/
#define UCHARA 1 /* if char is unsigned */
/*
* Standard type definitions
*/
/***************************/
#define BYTE char /* Signed byte */
#define BOOLEAN int /* 2 valued (true/false) */
#define WORD int /* Signed word (16 bits) */
#define UWORD unsigned int /* unsigned word */
#define LONG long /* signed long (32 bits) */
#define ULONG long /* Unsigned long */
#define REG register /* register variable */
#define LOCAL auto /* Local var on 68000 */
#define EXTERN extern /* External variable */
#define MLOCAL static /* Local to module */
#define GLOBAL /**/ /* Global variable */
#define VOID /**/ /* Void function return */
#define DEFAULT int /* Default size */
/***************************/
#ifdef UCHARA
#define UBYTE char /* Unsigned byte */
#else
#define UBYTE unsigned char /* Unsigned byte */
#endif
/****************************************************************************/
/* Miscellaneous Definitions: */
/****************************************************************************/
#define FAILURE (-1) /* Function failure return val */
#define SUCCESS (0) /* Function success return val */
#define YES 1 /* "TRUE" */
#define NO 0 /* "FALSE" */
#define FOREVER for(;;) /* Infinite loop declaration */
#define NULL 0 /* Null pointer value */
#define NULLPTR (char *) 0 /* */
#define EOF (-1) /* EOF Value */
#define TRUE (1) /* Function TRUE value */
#define FALSE (0) /* Function FALSE value */
/*************************** end of portab.h ********************************/


View File

@@ -0,0 +1,49 @@
/*
Proces Literals MP/M-8086 II
*/
declare pnamsiz literally '8';
declare pd$hdr literally 'structure
(link word,thread word,stat byte,prior byte,flag word,
name (8) byte,uda word,dsk byte,user byte,ldsk byte,luser byte,
mem word';
declare pd$structure literally 'pd$hdr,
dvract word,wait word,org byte,net byte,parent word,
cns byte,abort byte,conmode word,lst byte,sf3 byte,sf4 byte,sf5 byte,
reservd (4) byte,pret word,scratch word)';
declare psrun lit '00',
pspoll lit '01',
psdelay lit '02',
psswap lit '03',
psterm lit '04',
pssleep lit '05',
psdq lit '06',
psnq lit '07',
psflagwait lit '08',
psciowait lit '09';
declare pf$sys lit '00001h',
pf$keep lit '00002h',
pf$kernal lit '00004h',
pf$pure lit '00008h',
pf$table lit '00010h',
pf$resource lit '00020h',
pf$raw lit '00040h',
pf$ctlc lit '00080h',
pf$active lit '00100h',
pf$tempkeep lit '00200h',
pf$ctld lit '00400h',
pf$childabort lit '00800h',
pf$noctls lit '01000h';
declare pcm$11 lit '00001h',
pcm$ctls lit '00002h',
pcm$rout lit '00004h',
pcm$ctlc lit '00008h',
pcm$ctlo lit '00080h',
pcm$rsx lit '00300h';


View File

@@ -0,0 +1,47 @@
/*----------------------------------------------------------------------*\
| NAME : putfname |
| CREATED : 26-August-83 LAST MODIFIED: 12-September-83 |
| FUNCTION: Putfname writes out a drive and filename to the |
| console from the FCB passed to it. The high bits |
| (attributes) are masked off first. As an option, |
| a space may be printed inseated of the drive char. |
| INPUT : fcb -- ptr to modified FCB with filename to print, |
| where the drive code has been translated |
| into the appropriate drive char. |
| mode -- print drive char. or space flag |
| OUTPUT : No return value. |
\*----------------------------------------------------------------------*/
#include <portab.h>
#include "utildef.h"
#include "cpmfunc.h"
/* THIS REFERENCE IS IN CPMFUNC.H
EXTERN VOID c_write();
*/
VOID putfname( fcb,mode )
BYTE fcb[];
WORD mode;
{
WORD findex;
BYTE drive;
if( mode == 0 ) /* If mode = 0 then translate */
{ /* the drive code into the */
drive = get_drv( fcb ); /* appropriate drive char. */
c_write( drive ); /* If mode != 0 then print a */
} /* space for the drive char. */
else
c_write( ' ' );
c_write( ':' );
c_write( ' ' );
for( findex=1; findex < 12; findex++ )
{
if( findex == 9 )
c_write( ' ' );
c_write( (fcb[findex] & ~0x80) );
}
}


View File

@@ -0,0 +1,40 @@
/* Queue Descriptor */
dcl qnamsiz lit '8';
dcl qd$structure lit 'structure(
link word,
net byte,
org byte,
flags word,
name(qnamsiz) byte,
msglen word,
nmsgs word,
dq word,
nq word,
msgcnt word,
msgout word,
buffer word)';
/* queue flag values */
dcl qf$mx lit '001h'; /* Mutual Exclusion */
dcl qf$keep lit '002h'; /* NO DELETE */
dcl qf$hide lit '004h'; /* Not User writable */
dcl qf$rsp lit '008h'; /* rsp queue */
dcl qf$table lit '010h'; /* from qd table */
dcl qf$rpl lit '020h'; /* rpl queue */
dcl qf$dev lit '040h'; /* device queue */
/* Queue Parameter Block */
dcl qpb$structure lit 'structure(
flgs byte,
net byte,
qaddr word,
nmsgs word,
buffptr word,
name (qnamsiz) byte )';


View File

@@ -0,0 +1,44 @@
/*----------------------------------------------------------------------*\
| NAME : readsect |
| CREATED : 19-August-83 LAST MODIFIED: 16-August-83 |
| FUNCTION: Readsect reads a sector from the file referenced in |
| passed FCB. |
| INPUT : fcb -- ptr to FCB for file to read from. |
| OUTPUT : Returns 0 if successful, F_READ error code otherwise |
\*----------------------------------------------------------------------*/
#include <portab.h>
#include "utildef.h"
#include "cpmfunc.h"
/* THIS REFERENCE IS IN CPMFUNC.H
EXTERN WORD f_read();
*/
EXTERN VOID cpmerr();
EXTERN VOID putfname();
EXTERN VOID crlf();
EXTERN BYTE *err08;
WORD readsect( fcb,buff )
BYTE fcb[];
BYTE *buff;
{
WORD ret_code;
f_dmaset( buff ); /* set input buffer */
f_read( fcb );
ret_code = _EXTERR; /* if phy. or ext err */
if( (ret_code & 0x00ff) == 0x00ff ) /* display message */
{
crlf();
cpmerr( err08,0 );
putfname( fcb,0 );
crlf();
ret_code = ret_code & 0x00ff;
} /* return F_READ error */
return( ret_code ); /* code, 0 = sucecss */
}


View File

@@ -0,0 +1,28 @@
/*----------------------------------------------------------------------*\
| NAME : reverse |
| CREATED : 16-August-83 LAST MODIFIED: 16-August-83 |
| FUNCTION: Reverse reverses a string in place. |
| INPUT : str -- ptr to string that will be reversed.|
| OUTPUT : Reverses string pointed to by str in place. |
| No return value. |
\*----------------------------------------------------------------------*/
#include <portab.h>
#include "utildef.h"
VOID reverse( str )
BYTE str[]; /* string to reverse */
{
WORD head; /* head of string index */
WORD tail; /* tail of string index */
WORD cbuff; /* current char. buffer */
for( head=0,tail=strlen( str )-1; head < tail; head++,tail-- )
{
cbuff = str[head];
str[head] = str[tail];
str[tail] = cbuff;
}
}


View File

@@ -0,0 +1,105 @@
;
; Concurrent CP/M-86 v2.0 with BDOS version 3.1
; Interface for PLM-86 with separate code and data
; Code org'd at 0
; Created:
; October 5, 1981 by Danny Horovitz
; Revised:
; 28 Mar 83 by Bill Fitler
name scd
dgroup group dats,stack
cgroup group code
assume cs:cgroup, ds:dgroup, ss:dgroup
stack segment word stack 'STACK'
stack_base label byte
stack ends
dats segment para public 'DATA' ;CP/M page 0 - LOC86'd at 0H
org 4
bdisk db ?
org 6
maxb dw ?
org 50h
cmdrv db ?
pass0 dw ?
len0 db ?
pass1 dw ?
len1 db ?
org 5ch
fcb db 16 dup (?)
fcb16 db 16 dup (?)
cr db ?
rr dw ?
ro db ?
buff db 128 dup (?)
tbuff equ buff
buffa equ buff
fcba equ fcb
org 100h ;past CPM data space
saveax dw 0 ;save registers for mon functions
savebx dw 0
savecx dw 0
savedx dw 0
public bdisk,maxb,cmdrv,pass0,len0
public pass1,len1,fcb,fcb16,cr,rr
public ro,buff,tbuff,buffa,fcba
public saveax,savebx,savecx,savedx
dats ends
code segment public 'CODE'
public xdos,mon1,mon2,mon3,mon4
extrn plmstart:near
org 0h ; for separate code and data
jmp pastserial ; skip copyright
jmp patch ; store address of patch routine at start
db 'COPYRIGHT (C) 1983, DIGITAL RESEARCH '
db ' CONCURRENT CP/M-86 2.0, 03/31/83 ' ; db ' MP/M-86 2.0, 10/5/81 '
pastserial:
pushf
pop ax
cli
mov cx,ds
mov ss,cx
lea sp,stack_base
push ax
popf
jmp plmstart
xdos proc
push bp
mov bp,sp
mov dx,[bp+4]
mov cx,[bp+6]
int 224
mov saveax,ax
mov savebx,bx
mov savecx,cx
mov savedx,dx
pop bp
ret 4
xdos endp
mon1 equ xdos ; no returned value
mon2 equ xdos ; returns byte in AL
mon3 equ xdos ; returns address or word BX
mon4 equ xdos ; returns pointer in BX and ES
patch:
nop
nop
nop
nop
org 0100h ; leave room for patch area
code ends
end


File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,65 @@
/* System Data Page */
dcl sysdat$pointer pointer;
dcl sysdat$ptr structure(
offset word,
segment word) at (@sysdat$pointer);
declare sd based sysdat$pointer structure (
supmod (4) word,
/* rtmmod (4) word,
memmod (4) word,
ciomod (4) word,
bdosmod (4) word,
xiosmod (4) word,
netmod (4) word,
reservd (4) word */
space(28) word,
mpmseg word,
rspseg word,
endseg word,
module$map byte,
ncns byte,
nlst byte,
nccb byte,
nflags byte,
srchdisk byte,
mmp word,
nslaves byte,
dayfile byte,
tempdisk byte,
tickspersec byte,
lul word,
ccb word,
flags word,
mdul word,
mfl word,
pul word,
qul word,
qmau (4) word,
rlr word,
dlr word,
drl word,
plr word,
slr word,
thrdrt word,
qlr word,
mal word,
version word,
vernum word,
mpmvernum word,
tod (2) word,
tod_sec byte,
ncondev byte,
nlstdev byte,
nciodev byte,
lcb (2) word,
lckmax byte,
opmax byte,
sysltot (2) word,
cmod byte );
declare sd$byte based sysdat$pointer (1) byte;


File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
rasm86 cpmif
drc sqprint
drc cpyucase
drc cpmerr
drc crlf
drc fileopen
drc firstch
drc getdrv
drc getnum
drc gettail
drc issysfil
drc itoa
drc main
drc nextfcb
drc okver
drc parse
drc putfname
drc readsect
drc reverse
drc tlex
drc valid
link86 sqlink[i]


View File

@@ -0,0 +1,20 @@
sqlib=
cpyucase,
cpmerr,
crlf,
fileopen,
firstch,
getdrv,
getnum,
gettail,
issysfil,
itoa,
nextfcb,
okver,
parse,
putfname,
readsect,
reverse,
tlex,
valid


View File

@@ -0,0 +1,22 @@
print=main,
sqprint,
cpmif,
cpyucase,
cpmerr,
crlf,
fileopen,
firstch,
getdrv,
getnum,
gettail,
issysfil,
itoa,
nextfcb,
okver,
parse,
putfname,
readsect,
reverse,
tlex,
valid


View File

@@ -0,0 +1,428 @@
#include <portab.h>
#include "utildef.h"
#include "cpmfunc.h"
#define TAB_DEFAULT 8 /* default tab position */
struct _cmdtail /* command tail */
{
WORD gbl_sys; /* global system option */
WORD gbl_grp; /* global group option */
WORD gbl_tab; /* global tab option */
WORD lcl_sys[MAX_FILESPEC]; /* local system option */
WORD lcl_grp[MAX_FILESPEC]; /* local group option */
WORD lcl_tab[MAX_FILESPEC]; /* local tab option */
BYTE filespec[MAX_FILESPEC][FILESPEC_LEN];/* filespec list */
};
EXTERN VOID cpmerr();
EXTERN WORD ok_ver();
EXTERN VOID get_tail();
EXTERN VOID copy_ucase();
EXTERN WORD nextfcb();
EXTERN WORD fileopen();
EXTERN WORD readsect();
EXTERN VOID crlf();
EXTERN BYTE firstch(); /* return first non-white char */
EXTERN BYTE *tlex(); /* tlex returns a pointer */
EXTERN VOID putfname();
EXTERN VOID itoa();
BYTE *pmt00 = "Enter Filename: ";
BYTE *pmt01 = "Do you want to W(ait) or C(ancel) ? ";
BYTE *pmt02 = "Do you want to S(top printing), skip to the";
BYTE *pmt03 = "N(ext file), or R(esume printing this file) ? ";
BYTE *msg00 = "Printing file: ";
BYTE *msg01 = "Press SPACE BAR to stop ";
BYTE *msg02 = "Printer is being used by another console.";
BYTE *msg03 = "Printing is completed.";
BYTE *msg04 = " files printed.";
BYTE *msg05 = "Print cancelled.";
BYTE *err00 = "No files were specified on the command line.";
BYTE *err01 = "File Not Found.";
BYTE *err03 = "Invalid Command Option.";
BYTE *err04 = "Requires Concurrent CP/M-86 3.1$";
BYTE *err05 = "Could not find file: ";
BYTE *err06 = "Invalid file name: ";
BYTE *err07 = "Error while opening file: ";
BYTE *err08 = "Error while reading file: ";
BYTE *err09 = "Error while closing file: ";
BYTE *err10 = "A file password is required for file: ";
BYTE *index(); /* index returns pointer */
WORD ptail();
WORD set_opt();
VOID main()
{
BYTE buff[DMA_LEN]; /* file input buffer */
BYTE tail[DMA_LEN]; /* command tail buffer */
BYTE num_buff[6]; /* character buffer for numbers */
BYTE response[24]; /* user response buffer */
BYTE *dma; /* ptr to DMA buffer area */
BYTE ch; /* single char. response */
struct _cmdtail cmdtail; /* command tail structure */
REG WORD eod; /* end of data flag */
REG WORD i; /* loop control */
WORD op_code; /* option validation code */
WORD fsindex; /* filespec list index */
WORD findex; /* FCB array index */
WORD curr_user; /* current user number */
WORD nofile; /* no files flag */
WORD valid_file; /* filespec validation flag */
WORD completed; /* # files completed processing */
WORD attempted; /* # files attempted processing */
WORD col; /* output column counter */
WORD msg_len; /* prompt message length */
WORD open_err; /* open file error return code */
WORD bad_resp; /* bad user response flag */
UBYTE tail_len; /* length of command tail */
BYTE cur_fcb[FCB_LEN]; /* current FCB buffer */
BYTE wild_fcb[FCB_LEN]; /* filespec FCB buffer */
if( !ok_ver(BDOS_VER,OS_TYPE) ) /* version number check */
cpmerr( err04,-1 );
f_errmode( 0xff ); /* return BDOS errors */
c_delimit( NULL ); /* set console output */
/* string delimiter */
dma = f_dmaget(); /* get DMA ptr, byte 0 */
/* is length, get it */
tail_len = *dma++; /* then skip over it */
if( tail_len < 1 ) /* tail present ? */
cpmerr( err00,-1 );
else
copy_ucase( tail,dma,tail_len );
if( (op_code = ptail( tail,&cmdtail )) != 0 ) /* parse tail */
cpmerr( err03,-1 );
if( l_cattach() == 0x00ff ) /* if list device is */
{ /* in use, prompt user. */
c_writestr( msg02 ); /* the user may W(ait) */
crlf(); /* or C(ancel) */
get_tail( pmt01,response );
if( firstch(response) == 'W' )
l_attach();
else
cpmerr( msg05,-1 ); /* display cancel msg */
} /* and exit */
completed = attempted = 0; /* no files so far */
curr_user = f_usernum( 0xff ); /* get current user # */
fsindex = 0;
while( cmdtail.filespec[fsindex][0] != NULL )
{
f_usernum( cmdtail.lcl_grp[fsindex] );
nofile = 1;
cur_fcb[0] = 0xff; /* init to 0xff on first pass through */
while( (valid_file = nextfcb(cmdtail.filespec[fsindex],wild_fcb,
cur_fcb)) > -1 )
{
if( is_sysfile( cur_fcb ) == YES
&& cmdtail.lcl_sys[fsindex] == NO )
continue; /* skip to next file */
attempted++; /* attempt to process */
nofile = 0; /* another file */
cur_fcb[EX_FIELD] = 0x00; /* extent set for open */
cur_fcb[F6_FIELD] |= 0x80; /* open file read only */
/* mode */
if( (open_err = fileopen( cur_fcb )) != 0 )
{ /* error on open,print */
if( open_err != 7 ) /* message if not */
{ /* password error, */
crlf(); /* then skip to the */
cpmerr( err07,0 ); /* next file */
putfname( cur_fcb,0 );
}
continue;
}
put_header( cur_fcb,&cmdtail ); /* print file header */
/* on the console */
eod = 0;
cur_fcb[CR_FIELD] = 0x00; /* set CR field = 0 */
col = 0; /* set output col count */
while( !eod && (readsect( cur_fcb,buff ) == 0) )
{
for( i=0; i < SEC_LEN && !eod; i++ ) /* write sector */
{
if( buff[i] == 0x1a ) /* end of file */
{
eod = 1;
break;
}
if( cmdtail.lcl_tab[fsindex] != 0 ) /* expand tabs */
{
switch( buff[i] )
{
case 0x09 : do
{
l_write( ' ' );
col++;
}
while( col % cmdtail.lcl_tab[fsindex] );
break;
case 0x0a : l_write( buff[i] );
col = 0;
break;
default : l_write( buff[i] );
col++;
break;
}
}
else
{
l_write( buff[i] );
col++;
}
if( c_stat() ) /* check to see if the */
{ /* user wants to */
ch = c_rawio( 0x00fd ); /* intervene */
if( ch == '\003' ) /* cntrol-c, absolute */
p_termcpm(); /* halt of print */
if( ch == SP ) /* user intervenes if */
{ /* he hits SPACE BAR */
c_write( CR ); /* clear prompt area */
msg_len = strlen( msg01 );
while( msg_len-- ) /* and display new */
c_write( SP ); /* prompt */
c_write( CR );
do
{
bad_resp = FALSE;
c_writestr( pmt02 );
crlf();
get_tail( pmt03,response );
switch( firstch( response ) )
{
case 'S' : l_write( FF );
p_termcpm();
break;
case 'N' : eod = 1;
--completed;
break;
case NULL :
case 'R' : c_writestr( msg01 );
break;
default : bad_resp = TRUE;
break;
}
}
while( bad_resp == TRUE );
}
}
}
}
completed++;
c_write( CR ); /* erase prompt */
msg_len = strlen( msg01 );
while( msg_len-- )
c_write( SP );
c_write( CR );
l_write( FF ); /* eject a page, next file */
/* begins on a new page */
if( (f_close(cur_fcb) & 0x00ff) == 0x00ff )
{
crlf();
cpmerr( err09,0 );
putfname( cur_fcb,0 );
}
}
if( nofile && ( valid_file != INVALID_FILE ) )
{
crlf();
cpmerr( err05,0 );
putfname( wild_fcb,0 );
}
fsindex++;
}
crlf(); /* display print completion */
c_writestr( msg03 ); /* message */
crlf();
itoa( completed,num_buff );
c_writestr( num_buff );
c_write( '/' );
itoa( attempted,num_buff );
c_writestr( num_buff );
c_writestr( msg04 );
f_usernum( curr_user ); /* reset current user */
f_errmode( 0 ); /* reset BDOS error mode */
l_detach(); /* detach list device */
}
WORD ptail( tail,t_struct )
BYTE *tail; /* command tail to parse */
struct _cmdtail *t_struct; /* struct. to hold parsed tail */
{
BYTE token[128]; /* cmd. line identifier */
BYTE *delim; /* string of delimiters */
BYTE *tptr; /* tail pointer */
WORD ret_code; /* return code */
WORD op_cnt; /* option count */
WORD fsindex; /* filespec list index */
struct _oplist oplist[5]; /* valid options list */
strcpy( oplist[0].opname,OP_TAB ); /* initialize options list */
oplist[0].max_num = 32767;
strcpy( oplist[1].opname,OP_SYSTEM );
oplist[1].max_num = 0;
strcpy( oplist[2].opname,OP_DIRECTORY );
oplist[2].max_num = 0;
strcpy( oplist[3].opname,OP_GROUP );
oplist[3].max_num = 15;
oplist[4].opname = NULL; /* sentinal */
oplist[4].max_num = 0;
t_struct->gbl_sys = NO; /* assume no system option */
t_struct->gbl_grp = f_usernum( 0x00ff );/* assume no system opt */
t_struct->gbl_tab = TAB_DEFAULT; /* default tab position */
tptr = tail;
fsindex = 0;
ret_code = 0;
op_cnt = 0;
delim = ",]";
while( firstch( tptr ) == '[' && ret_code == 0 )
{
tptr++; /* skip start symbol */
op_cnt++;
tptr = tlex( tptr,delim,token );
ret_code = set_opt( token,t_struct,fsindex,oplist,0 );
while( firstch( tptr ) == ',' && ret_code == 0 )
{
tptr++;
op_cnt++;
tptr = tlex( tptr,delim,token );
ret_code = set_opt( token,t_struct,fsindex,oplist,0 );
}
if( *(tptr+1) == '[' ) /* skip '][' condition */
tptr++;
}
if( op_cnt > 2 ) /* to many options given */
ret_code = -1;
if( firstch( tptr ) == ']' )
tptr++;
if( firstch( tptr ) == NULL ) /* no files specified on command */
cpmerr( err00,-1 ); /* line is an error */
while ( firstch( tptr ) != NULL && ret_code == 0 )
{
delim = "[, ";
tptr = tlex( tptr,delim,token );
t_struct->lcl_sys[fsindex] = t_struct->gbl_sys;
t_struct->lcl_grp[fsindex] = t_struct->gbl_grp;
t_struct->lcl_tab[fsindex] = t_struct->gbl_tab;
strcpy( t_struct->filespec[fsindex],token );
op_cnt = 0;
while( firstch( tptr ) == '[' && ret_code == 0 )
{
tptr++;
op_cnt++;
delim = ",]";
tptr = tlex( tptr,delim,token );
ret_code = set_opt( token,t_struct,fsindex,oplist,1 );
while( firstch( tptr ) == ',' && ret_code == 0 )
{
tptr++;
op_cnt++;
tptr = tlex( tptr,delim,token );
ret_code = set_opt( token,t_struct,fsindex,oplist,1 );
}
if( *(tptr+1) == '[' )
tptr++;
}
if( op_cnt > 2 ) /* too many options */
ret_code = -1;
if( firstch( tptr ) == ']' )
tptr++; /* skip delimiter */
if( firstch( tptr ) == ',' )
tptr++;
fsindex++;
}
t_struct->filespec[fsindex][0] = NULL; /* end filespec list */
return( ret_code );
}
WORD set_opt( token,t_ptr,fsindex,oplist,type )
BYTE *token;
struct _cmdtail *t_ptr;
WORD fsindex;
struct _oplist *oplist;
WORD type;
{
WORD ret_code;
if( (ret_code = valid( token,oplist )) == 0 )
{
switch( (WORD)token[0] )
{
case 'S' : if( type == 0 )
t_ptr->gbl_sys = YES;
else
t_ptr->lcl_sys[fsindex] = YES;
break;
case 'D' : if( type == 0 )
t_ptr->gbl_sys = NO;
else
t_ptr->lcl_sys[fsindex] = NO;
break;
case 'G' : if( type == 0 )
t_ptr->gbl_grp = get_num(token,t_ptr->gbl_grp);
else
t_ptr->lcl_grp[fsindex] = get_num( token,
t_ptr->lcl_grp[fsindex] );
break;
case 'T' : if( type == 0 )
t_ptr->gbl_tab = get_num(token,TAB_DEFAULT);
else
t_ptr->lcl_tab[fsindex] = get_num(token,
t_ptr->lcl_tab[fsindex] );
break;
default : break;
}
}
return( ret_code );
}
VOID put_header( cur_fcb,cmdtail )
BYTE cur_fcb[];
struct _cmdtail *cmdtail;
{
WORD findex;
crlf(); /* display user header */
c_writestr( msg00 ); /* on console */
putfname( cur_fcb,0 );
crlf();
c_writestr( msg01 );
}


File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,155 @@
$title('CCP/M-86 1.0 Systat Process - Transient')
$compact
/* want 32 bit pointers */
status:
do;
$include (:f2:copyrt.lit)
$include (:f2:vaxcmd.lit)
$include (scomon.plm)
/**************************************************************************
MAIN PROGRAM
**************************************************************************/
plmstart: procedure public;
dcl (i,version) byte,
ver address,
validchar byte;
dcl bdosversion lit '30h'; /* BDOS 3.o or later */
dcl osproduct lit '14h'; /* CCP/M-86 */
dcl mpmproduct lit '11h'; /* MP/M-86 */
dcl vers$str$pointer pointer;
dcl vers$str$ptr structure (
offset word,
segment word) at (@vers$str$pointer);
dcl (doscan,chr) byte;
ver = get$version;
if low(ver) < bdosversion or
( (high(ver) < osproduct) and (high(ver) <> mpmproduct) ) then
do;
call print$buffer (.('Requires Concurrent CP/M-86 or MP/M-86$'));
call reboot; /* use CP/M exit */
end;
else
do;
version = high(ver) mod 2; /* 0 = CCP/M-86, 1 = MP/M-86 */
sysdat$pointer = get$sysdat;
flag$ptr.segment,md$ptr.segment,ms$ptr.segment,
sat$ptr.segment,qd$ptr.segment,pd$ptr.segment,vccb$ptr.segment
= sysdat$ptr.segment;
doscan = true;
repeat = false;
specified = false; /* Default */
intrval = 01h; /* Default */
/* Scan for option */
do while doscan ; /* Loop until Q(uit)*/
if buff(0) <> 0 then do; /* Command line arg */
i = 1; /* was used. Get it.*/
do while buff(i) = ' ' ; /* Skip intervening blanks */
i = i + 1;
end;
if buff(i) = lbracket then
i = i + 1;
else
call print$opt$err;
chr = buff(i); /* 1st arg */
i = i + 1;
if (buff(i) = ',') or (buff(i) = ' ') or (buff(i) = ']') then
i = i + 1; /* Skip blank or comma */
else
call print$opt$err;
if (buff(i-1) <> rbracket) then do; /* Keep going,more args*/
if (buff(i) = 'c') or (buff(i) = 'C') then do;
repeat = true;
i = i + 1;
end;
else
call print$opt$err;
if (buff(i) <> rbracket) then do; /* Still more ?*/
if (buff(i) = ' ') or (buff(i) = ',') then do;
i = i + 1;
end;
else
call print$opt$err;
/* Get ascii hex interval data */
intrval = aschex(buff(i));
i = i + 1;
if (buff(i) <> rbracket) then do;
intrval = shl(intrval,4);
intrval = intrval + aschex(buff(i));
end; /* Now convert to system ticks */
intrval = intrval * sd.tickspersec;
end;
end;
buff(0) = 0; /* Go back to menu*/
specified = true; /* next time. */
end;
else do; /* No args's given*/
call disp$mainhdr; /* Show the menu */
chr = conin;
end;
validchar = false;
do while not(validchar); /* Select action */
validchar = true;
if (chr = 'h') or (chr = 'H') then do;
call display$help;
end;
else if (chr = 'm') or (chr = 'M') then do;
call display$mem;
end;
else if (chr = 'o') or (chr = 'O') then do;
call display$gen(version);
end;
else if (chr = 'e') or (chr = 'E') then do;
call terminate; /* The Exit */
end;
else if (chr = 'p') or (chr = 'P') then do;
call display$proc(0);
end;
else if (chr = 'q') or (chr = 'Q') then do;
call display$queue;
end;
else if (chr = 'u') or (chr = 'U') then do;
call display$proc(1);
end;
else if (chr = 'c') or (chr = 'C') then do;
call display$cons(version);
end;
else do; /* Incorrect character was used */
validchar = false;
if not(specified) then do; /* Invalid char was from menu */
if (chr = CR) then
call print$buffer(.(' ->$'));
call print$buffer(.(' Invalid Option.$'));
call co(CR); /* Move left to beginning of line */
call print$buffer(.(' ->$'));
chr = conin; /* Get another char, hopefully a good one */
end;
else /* Invalid char was from the command line */
call print$opt$err;
end; /* Incorrect char case */
end; /* inner while loop - validchar */
end; /* outer while loop - doscan */
end;
end plmstart;
end status;


View File

@@ -0,0 +1,27 @@
/*----------------------------------------------------------------------*\
| NAME : tabinit |
| CREATED : 23-August-83 LAST MODIFIED: 19-September-83 |
| FUNCTION: Tabinit initializes a tab position array used to |
| determine how many spaces to replace the tab with. |
| INPUT : tabstop -- ptr to tab stop array |
| max_len -- length of tabstop array |
| OUTPUT : Tabstop array initialized: 1 at tab stop colums and |
| zero elsewhere. |
| No return value. |
\*----------------------------------------------------------------------*/
#include <portab.h>
VOID tabinit( tabstop,max_len,tabpos )
WORD tabstop[];
WORD max_len;
WORD tabpos;
{
WORD col;
tabstop[0] = 0; /* using 1 index addr. */
for( col=1; col < max_len; col++ ) /* tabstop[0] not used */
tabstop[col] = ( (col % tabpos) == 1 );
}


View File

@@ -0,0 +1,47 @@
/*----------------------------------------------------------------------*\
| NAME : tlex |
| CREATED : 29-July-83 LAST MODIFIED: 9-August-83 |
| FUNCTION: Tlex retrieves a token from the source line. Tokens |
| are identified by their delimiters only. Tokens are |
| thus defined as all characters found until the |
| delimiter is found. Leading white space is ignored. |
| INPUT : line -- ptr to source line containing tokens |
| delim -- ptr to string containing delimiter(s) |
| token -- ptr to token buffer area loaded by tlex |
| OUTPUT : token -- loaded with a token if found |
| Returns ptr to the delimiter that was found. |
| If no token found then returns ptr to a null. |
\*----------------------------------------------------------------------*/
#include <portab.h>
#include "utildef.h"
BYTE *tlex( line,delim,token )
BYTE *line; /* ptr to null terminated source line */
BYTE *delim; /* ptr to delimiter(s) (null terminated)*/
BYTE *token; /* ptr to token buffer (output) */
{
BYTE *del_ptr; /* index ptr. into delimiter string */
WORD found; /* flag set when finding a delimiter */
found = 0;
while( *line == ' ' || *line == '\t' ) /* ignore white space */
line++;
while( *line && !found )
{
for( del_ptr=delim; *del_ptr; del_ptr++ )
{
if( *line == *del_ptr )
{
found = 1;
break;
}
}
if( !found )
*token++ = *line++;
}
*token = NULL; /* delimit token string */
return( line ); /* return null if eoln or not found */
}


View File

@@ -0,0 +1,379 @@
$title ('TYPE utility: Types file to Console')
type:
do;
$include (:f2:copyrt.lit)
$include(:f2:vaxcmd.lit)
/*
Revised:
19 Jan 80 by Thomas Rolander (mp/m 1.1)
21 July 81 by Doug Huskey (mp/m 2.0)
6 Aug 81 by Danny Horovitz (mp/m-86 2.0)
23 Jun 82 by Bill Fitler (ccp/m-86)
25 Jan 83 by Fran Borda & Bill Fitler (ccp/m-86 2.0)
*/
/* MODIFICATION LOG:
* July 82 whf: abort if wildcard char in filename.
Jan 83 fmb : check for openfile error codes in AH reg.
*/
$include (:f2:vermpm.lit)
declare
true literally '0FFh',
false literally '0',
forever literally 'while true',
lit literally 'literally',
proc literally 'procedure',
dcl literally 'declare',
addr literally 'address',
cr literally '13',
lf literally '10',
ctrlc literally '3',
ctrlx literally '18h',
bksp literally '8';
/**************************************
* *
* B D O S INTERFACE *
* *
**************************************/
mon1:
procedure (func,info) external;
declare func byte;
declare info address;
end mon1;
mon2:
procedure (func,info) byte external;
declare func byte;
declare info address;
end mon2;
mon3:
procedure (func,info) address external;
declare func byte;
declare info address;
end mon3;
mon4: procedure(f,a) pointer external;
declare f byte, a address;
end mon4;
declare cmdrv byte external; /* command drive */
declare fcb (1) byte external; /* 1st default fcb */
declare fcb16 (1) byte external; /* 2nd default fcb */
declare pass0 address external; /* 1st password ptr */
declare len0 byte external; /* 1st passwd length */
declare pass1 address external; /* 2nd password ptr */
declare len1 byte external; /* 2nd passwd length */
declare tbuff (1) byte external; /* default dma buffer */
/**************************************
* *
* B D O S Externals *
* *
**************************************/
read$console:
procedure byte;
return mon2 (1,0);
end read$console;
printchar:
procedure (char);
declare char byte;
call mon1 (2,char);
end printchar;
conin:
procedure byte;
return mon2(6,0fdh);
end conin;
print$buf:
procedure (buff$adr);
declare buff$adr address;
call mon1 (9,buff$adr);
end print$buf;
check$con$stat:
procedure byte;
return mon2(11,0);
end check$con$stat;
version: procedure address;
/* returns current cp/m version # */
return mon3(12,0);
end version;
con$status:
procedure byte;
return mon2 (11,0);
end con$status;
open$file:
procedure (fcb$address) address;
declare fcb$address address;
return mon3 (15,fcb$address);
end open$file;
close$file:
procedure (fcb$address) byte;
declare fcb$address address;
return mon2 (16,fcb$address);
end close$file;
read$record:
procedure (fcb$address) byte;
declare fcb$address address;
return mon2 (20,fcb$address);
end read$record;
setdma: procedure(dma);
declare dma address;
call mon1(26,dma);
end setdma;
/* 0ff => return BDOS errors */
return$errors:
procedure(mode);
declare mode byte;
call mon1 (45,mode);
end return$errors;
terminate:
procedure;
call mon1 (143,0);
end terminate;
declare
parse$fn structure ( /* The input to parsefilename */
buff$adr address,
fcb$adr address);
declare (saveax,savecx) word external; /* reg return vals, set in mon1 */
parse: procedure;
declare (retcode,errcode) word;
call mon1(152,.parse$fn);
retcode = saveax;
errcode = savecx;
if retcode = 0ffffh then /* parse returned an error */
do;
call print$buf(.('Invalid Filespec$'));
if errcode = 23 then call print$buf(.(' (drive)$'));
else if errcode = 24 then call print$buf(.(' (filename)$'));
else if errcode = 25 then call print$buf(.(' (filetype)$'));
else if errcode = 38 then call print$buf(.(' (password)$'));
call print$buf(.('.',13,10,'$')); call terminate;
end;
end parse;
/**************************************
* *
* S U B R O U T I N E S *
* *
**************************************/
/* upper case character from console */
crlf: proc;
call printchar(cr);
call printchar(lf);
end crlf;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* fill string @ s for c bytes with f */
fill: proc(s,f,c);
dcl s addr,
(f,c) byte,
a based s byte;
do while (c:=c-1)<>255;
a = f;
s = s+1;
end;
end fill;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* upper case character from console */
ucase: proc byte;
dcl c byte;
if (c:=conin) >= 'a' then
if c < '{' then
return(c-20h);
return c;
end ucase;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* get password and place at fcb + 16 */
getpasswd: proc;
dcl (i,c) byte;
call crlf;
call crlf;
call print$buf(.('Password ? ','$'));
retry:
call fill(.fcb16,' ',8);
do i = 0 to 7;
nxtchr:
if (c:=ucase) >= ' ' then
fcb16(i)=c;
if c = cr then
goto exit;
if c = ctrlx then
goto retry;
if c = bksp then do;
if i<1 then
goto retry;
else do;
fcb16(i:=i-1)=' ';
goto nxtchr;
end;
end;
if c = 3 then
call terminate;
end;
exit:
c = check$con$stat;
end getpasswd;
/**************************************
* *
* M A I N P R O G R A M *
* *
**************************************/
declare (eod,i,char) byte;
declare control$z literally '1AH';
/*
Main Program
*/
declare (cnt,tcnt) byte;
declare (ver, error$code) address;
declare last$dseg$byte byte
initial (0);
plm$start: procedure public;
ver = version;
if low(ver) < Ver$BDOS or (high(ver) and Ver$Mask) = 0 then do;
call print$buf (.(Ver$Needs$OS,'$'));
call mon1(0,0);
end;
tcnt,
cnt = 0;
if fcb16(1) = 'P' then
do;
if fcb16(2) = ' ' or fcb16(2) = 'A' then
cnt = 24;
else
cnt = (fcb16(2)-'0')*10
+(fcb16(3)-'0');
end;
parse$fn.buff$adr = .tbuff(1);
parse$fn.fcb$adr = .fcb;
call parse;
do i = 1 to 11; /* check for wildcards */
if fcb(i) = '?' then do;
call print$buf(.('No wildcards allowed.','$'));
call crlf;
call terminate;
end;
end;
call return$errors(0FEh); /* return after error message */
call setdma(.fcb16); /* set dma to password */
fcb(6) = fcb(6) or 80h; /* open in RO mode */
error$code = open$file (.fcb);
if low(error$code) = 0FFh then
do;
if high(error$code) = 0 then
do;
call print$buf (.('File not found.','$'));
call terminate;
end;
else if high(error$code) = 7 then /* User left out password*/
do;
call getpasswd;
call crlf;
call setdma(.fcb16); /* set dma to password */
fcb(6) = fcb(6) or 80h; /* open in RO mode */
error$code = open$file(.fcb);
end;
else if high(error$code) = 4 then
do;
call crlf;
call print$buf(.('Invalid Filespec.','$'));
end;
end; /* Error Checks */
if low(error$code) <> 0FFH then
do;
call return$errors(0); /* reset error mode */
call setdma(.tbuff);
fcb(32) = 0;
eod = 0;
do while (not eod) and (read$record (.fcb) = 0);
do i = 0 to 127;
if (char := tbuff(i)) = control$z
then eod = true;
if not eod then
do;
/**** allow type-ahead whf
if con$status then
do;
i = read$console;
call terminate;
end;
****/
if cnt <> 0 then
do;
if char = 0ah then
do;
if (tcnt:=tcnt+1) = cnt then
do;
tcnt = read$console;
tcnt = 0;
end;
end;
end;
call printchar (char);
end;
end;
end;
/*
call close (.fcb);
*** Warning ***
If this call is left in, the file can be destroyed.
*/
end;
call terminate;
end plm$start;
end type;


View File

@@ -0,0 +1,19 @@
/* MP/M-86 II User Data Area format - August 8, 1981 */
declare uda$structure lit 'structure (
dparam word,
dma$ofst word,
dma$seg word,
func byte,
searchl byte,
searcha word,
searchabase word,
dcnt word,
dblk word,
error$mode byte,
mult$cnt byte,
df$password (8) byte,
pd$cnt byte)';


View File

@@ -0,0 +1,156 @@
/*----------------------------------------------------------------------*\
| NAME : utildef.h |
| FUNCTION : This is a header file used by the utilities |
| for the Portable Concurrent CP/M 4.0. |
| |
| CREATED : 26-July-83 LAST MODIFIED: 16-September-83 |
| AUTHOR : Kim S. Ouye |
| |
| COPYRIGHT (c) Digital Research 1983 |
| all rights reserved |
\*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*\
| Conditional compile flags |
\*----------------------------------------------------------------------*/
#define CCPM2 1 /* 1 CCP/M 2.0 0 not CCPM 2.0 */
#define CCPM4 0 /* 1 PCCP/M 4.0 0 not CCPM 4.0 */
#define CPM68K 0 /* 1 CP/M 68K 1.1 0 not CP/M 68K 1.1 */
#define CPU_8086 1 /* 1 8086 CPU 0 not 8086 CPU */
#define CPU_68K 0 /* 1 68K CPU 0 not 68K CPU */
#define CPU_286 0 /* 1 80286 CPU 0 not 80286 CPU */
#define CPU_Z8000 0 /* 1 Z8000 CPU 0 not Z8000 CPU */
/*----------------------------------------------------------------------*\
| Max. & min. length, sizes, values |
\*----------------------------------------------------------------------*/
#define FCB_LEN 36 /* FCB buffer length */
#define DMA_LEN 128 /* DMA buffer length */
#define PW_LEN 8 /* file password length */
#define SEC_LEN 128 /* sector length */
#define MAX_MSEC 128 /* max. mutl-sector count */
#define FNAME_LEN 12 /* FCB name field length */
#define FILESPEC_LEN 15 /* max. filespec length */
#define MAX_FILESPEC 16 /* max. list of filespec */
#define PAGE_LEN 23 /* default page length */
#define MAX_USER_NUM 15 /* max. user number */
#define NUM_DIR_COL 4 /* # column DIR display */
/*----------------------------------------------------------------------*\
| Masks |
\*----------------------------------------------------------------------*/
#define BDOS_MASK 0x00ff /* BDOS version mask */
#define OS_MASK 0xff00 /* CP/M system version mask */
#define RO_MASK 0x0080 /* set F6' (read only) attrib. */
/*----------------------------------------------------------------------*\
| CP/M specific misc. defines |
\*----------------------------------------------------------------------*/
#if (CCPM2 & CPU_8086)
#define BDOS_VER 0x0031 /* BDOS Ver. 3.1 */
#define OS_TYPE 0x1400 /* CCP/M on 8086 cpu */
#endif
#if (CCPM4 & CPU_68K)
#define BDOS_VER 0x0040 /* BDOS Ver. 4.0 */
#define OS_TYPE 0x2400 /* CCP/M on 68K cpu */
#endif
#if (CPM68K)
#define BDOS_VER 0x0022 /* BDOS Ver. 2.2 */
#define OS_TYPE 0x2000 /* CCP/M Ver. 2.0 */
#endif
#define WILDCARD "*.*" /* CP/M full filespec wildcard */
#define RET_DISP 0x00fe /* f_errmode, return & display */
#define NO_RET 0x0000 /* f_errmode, no return */
#define FPAR_ERR 0xffff /* f_parse error return code */
#define CR_FIELD 32 /* CR FCB field index */
#define EX_FIELD 12 /* EX FCB field index */
#define F6_FIELD 6 /* F6' attribute (READ ONLY) */
/*----------------------------------------------------------------------*\
| Misc. defines |
\*----------------------------------------------------------------------*/
#define CR '\015' /* carriage return */
#define LF '\012' /* line feed */
#define FF '\014' /* form feed */
#define SP '\040' /* space */
#define HT '\011' /* horizontal tab */
#define ERROR -1 /* error found return code */
#define MATCH 0 /* sting compare match code */
#define YES 1 /* condition met */
#define NO 0 /* condition not met */
#define OK 1 /* boolean truth */
#define NOT_OK 0 /* boolen false */
#define INVALID_FILE -2 /* invalid filespec */
/*----------------------------------------------------------------------*\
| Macro definitions |
\*----------------------------------------------------------------------*/
#define islower(c) ('a' <= (c) && (c) <= 'z')
#define isupper(c) ('A' <= (c) && (c) <= 'Z')
#define isdigit(c) ('0' <= (c) && (c) <= '9')
#define isalpha(c) (islower(c) | isupper(c))
#define tolower(c) (isupper(c) ? ((c)+0x20):(c))
#define toupper(c) (islower(c) ? ((c)-0x20):(c))
/*----------------------------------------------------------------------*\
| Valid Command Line Options |
\*----------------------------------------------------------------------*/
#define OP_GROUP "GROUP" /* User group/number option */
#define OP_PAGE "PAGE" /* Page mode/length option */
#define OP_NOPAGE "NOPAGE" /* No page mode option */
#define OP_SYSTEM "SYSTEM" /* System files option */
#define OP_DIRECTORY "DIRECTORY" /* Directory files option */
#define OP_XFCB "XFCB" /* XFCB only option */
#define OP_CONFIRM "CONFIRM" /* Confirm option */
#define OP_GET "GET" /* Get information option */
#define OP_FILE "FILE" /* FILE option (not) XFCB */
#define OP_NOCONFIRM "NOCONFIRM" /* No confirm option */
#define OP_TAB "TAB" /* Expand tabs option */
/*----------------------------------------------------------------------*\
| Global structure definitions |
\*----------------------------------------------------------------------*/
struct _cbuf /* BDOS c_readstr buffer */
{
BYTE max_char; /* max. char. to read */
BYTE nchar; /* actual # char. read */
BYTE buffer[DMA_LEN+2]; /* line buffer */
};
struct _pfcb /* BDOS F_PARSE file cont. blk */
{
BYTE *fname; /* ASCII file spec. */
BYTE *fcbaddr; /* FCB address */
};
struct _fcblst /* expfcb link list entry of FCB's */
{
BYTE fcb_buff[FCB_LEN]; /* FCB buffer */
struct _fcblst *next_fcb; /* ptr to next entry */
};
struct _oplist
{
BYTE opname[14]; /* command option name */
WORD max_num; /* max. number spec. */
};
/*----------------------------------------------------------------------*\
| External Variables |
\*----------------------------------------------------------------------*/
EXTERN WORD _EXTERR; /* AX save area; kludge to get all of AX */
EXTERN WORD _SYSERR; /* CX save area; kludge to get CX error codes */


View File

@@ -0,0 +1,73 @@
/*----------------------------------------------------------------------*\
| NAME : valid LAST MODIFIED: 16-October-83 |
| FUNCTION: Valid compares the "opt" string against a list of |
| valid option names in "oplist" and all abbreviations |
| thereof (i.e P PA PAG PAGE matches "PAGE"). |
| Limits options to unique first letters. |
| INPUT : opt -- ptr to string to validate as an option |
| oplist -- ptr to struct array containing the valid |
| options |
| OUTPUT : Returns 0 if valid, 1 or 2 if invalid (maybe changed)|
\*----------------------------------------------------------------------*/
#include <portab.h>
#include "utildef.h"
WORD valid( opt,oplist )
BYTE *opt; /* option to validate */
struct _oplist oplist[]; /* list of valid options */
{
WORD num; /* number on option,i.e. PAGE10 */
WORD found; /* option matched entry */
WORD op_err; /* option error return */
WORD op_size; /* length of option name */
WORD save_bi; /* save area for buffer index */
WORD bi,i,j,k; /* various loop control vars. */
BYTE op_tbl[10][11]; /* valid options table */
BYTE buff[128]; /* option buffer */
strcpy( buff,opt ); /* save option that was passed */
op_err = 0; /* assume valid option */
found = 0; /* assume option not found yet */
/* stip off number if found */
for( bi=0; !(isdigit( buff[bi] )) && buff[bi]; bi++ )
;
buff[bi] = NULL;
i = 0;
while( *oplist[i].opname && !found ) /* search until end of */
{ /* the option table or */
op_size = strlen( oplist[i].opname ); /* build abbrev. table */
for( k=0; k < op_size; k++ )
{
for( j=0; j <= k; j++ )
op_tbl[k][j] = oplist[i].opname[j];
op_tbl[k][j] = NULL;
}
op_tbl[k][0] = NULL; /* table sentinel */
k = 0;
while( *op_tbl[k] && !found ) /* scan for option */
{
if( strcmp( buff,op_tbl[k] ) == 0 )
found = 1;
else
k++;
}
i++;
}
if( found ) /* if found check for */
{ /* number */
if( oplist[--i].max_num > 0 )
{
if( (num = get_num( opt,0 )) > oplist[i].max_num )
op_err = 1; /* number > max_num */
}
}
else
op_err = 2;
return( op_err );
}


View File

@@ -0,0 +1,21 @@
/**** VAX commands for generation - read the name of this program
for PROGNAME below.
$ util := PROGNAME
$ ccpmsetup ! set up environment
$ assign 'f$directory()' f1: ! use local dir for temp files
$ plm86 'util'.plm xref 'p1' optimize(3) debug
$ link86 f2:scd.obj, 'util'.obj to 'util'.lnk
$ loc86 'util'.lnk od(sm(code,dats,data,stack,const)) -
ad(sm(code(0),dats(10000h))) ss(stack(+32)) to 'util'.
$ h86 'util'
***** Then, on a micro:
A>vax progname.h86 $fans
A>gencmd progname data[b1000]
***** Notes: Stack is increased for interrupts. Const(ants) are last
to force hex generation.
****/


View File

@@ -0,0 +1,82 @@
/* Concurrent CP/M Character Control Block Structure */
/* +---------+---------+---------+---------+
00 | attach | queue |
+---------+---------+---------+---------+
04 | flag | startcol| column | nchar |
+---------+---------+---------+---------+
08 | mimic | msource | pc | vc |
+---------+---------+---------+---------+
0C | btmp | rsvd | state |
+---------+---------+---------+---------+
10 | maxbufsiz | vinq |
+---------+---------+---------+---------+
14 | voutq | vcmxq |
+---------+---------+---------+---------+
18 | qpbflgs | qpbfill | qpbqaddr |
+---------+---------+---------+---------+
1C | qpbnmsgs | qpbbuffptr |
+---------+---------+---------+---------+
20 | qbuff | cosleep |
+---------+---------+---------+---------+
24 | usleep | vsleep |
+---------+---------+---------+---------+
28 | ... reserved ... |
+---------+---------+---------+---------+
*/
dcl ccb$structure lit 'structure (attach address, queue address,
flag byte, startcol byte, column byte, nchar byte, mimic byte, msource byte,
ccb$tail1';
dcl ccb$tail1 lit
'pc byte, vc byte, btmp byte, rsvd byte, state word, maxbufsiz word,
ccb$tail2';
dcl ccb$tail2 lit
'vinq address, voutq address, vcmxq address,
qpbflags byte, qpbresrvd byte, qpbqaddr address,
qpbnmsgs address, qpbbuffptr address, qbuff address, cosleep word,
usleep word, vsleep word, r1 word, r2 word)';
declare /* flag values */
cf$listcp lit '001h', /* control P toggle */
cf$compc lit '002h', /* suppress output */
cf$switchs lit '004h', /* XIOS supports switch screening */
cf$conout lit '008h', /* XIOS console output ownership */
cf$vout lit '010h'; /* process writing to VOUTQ */
/* values of state byte */
/* conout goes to XIOS */
/* state word flags */
dcl
csm$buffered lit '0001h',
csm$background lit '0002h',
csm$purging lit '0004h',
csm$noswitch lit '0008h',
csm$suspend lit '0010h',
csm$abort lit '0020h',
csm$filefull lit '0040h',
csm$ctrlS lit '0080h',
csm$ctrlO lit '0100h',
csm$ctrlP lit '0200h';
dcl x$init$offset lit '0Ch',
x$init$pointer pointer,
x$init$ptr structure (offset word, segment word) at (@x$init$pointer),
x$init based x$init$pointer structure
(tick byte, ticks$sec byte, door byte, resrvd1 (2) byte,
nvcns byte, nccb byte, nlst byte, ccb word, lcb word);
dcl lcb$structure lit 'structure (attach address, queue address,
flag byte, startcol byte, column byte, nchar byte,
mimic byte, msource byte)';
dcl vccb$len lit '02ch';


View File

@@ -0,0 +1,295 @@
$title('VCMODE.CMD - Set Virtual Console Background Mode')
$compact
vcmode:
do;
$include (:f2:copyrt.lit)
$include (:f2:vaxcmd.lit)
$include (:f2:comlit.lit)
$include (:f2:mfunc.lit)
$include (:f2:fcb.lit)
dcl fcb (1) byte external;
dcl buff (1) byte external;
$include (:f2:sd.lit)
dcl ccb$pointer pointer;
dcl ccb$ptr structure ( offset address, segment address) at
(@ccb$pointer);
$include (:f2:vccb.lit)
dcl ccb based ccb$pointer ccb$structure;
dcl ccpmproduct lit '14h';
dcl bdosversion lit '31h';
mon1: procedure (func,info) external;
declare func byte;
declare info address;
end mon1;
mon2: procedure (func,info) byte external;
declare func byte;
declare info address;
end mon2;
mon3: procedure (func,info) address external;
dcl func byte, info address;
end mon3;
mon4: procedure (func,info) pointer external;
dcl func byte, info address;
end mon4;
/**************************************
* *
* B D O S Externals *
* *
**************************************/
print$char: procedure(char);
declare char byte;
call mon1(2,char);
end print$char;
print$console$buffer: procedure (buffer$address);
declare buffer$address address;
call mon1 (9,buffer$address);
end print$console$buffer;
version: procedure address;
return mon3(12,0);
end version;
/**************************************
* *
* X D O S Externals *
* *
**************************************/
terminate: procedure;
call mon1 (143,0);
end terminate;
get$console$number: procedure byte;
return mon2 (153,0);
end get$console$number;
printb: procedure public;
call print$char(' ');
end printb;
pdecimal: procedure(v,prec,zerosup) public;
/* print value v, field size = (log10 prec) + 1 */
/* with leading zero suppression if zerosup = true */
declare v address, /* value to print */
prec address, /* precision */
zerosup boolean, /* zero suppression flag */
d byte; /* current decimal digit */
do while prec <> 0;
d = v / prec; /* get next digit */
v = v mod prec; /* get remainder back to v */
prec = prec / 10; /* ready for next digit */
if prec <> 0 and zerosup and d = 0 then
call printb;
else
do;
zerosup = false;
call printchar('0'+d);
end;
end;
end pdecimal;
/*lbracket: procedure byte; /* find left bracket in command tail return */
/* dcl i byte; /* its index. if not found ret 0 */
/* i = 1;
do while i <= buff(0) and (buff(i) = ' ' or buff(i) = tab);
i = i + 1;
end;
if buff(i) = '[' then
return(i);
return(0);
end lbracket;
*/
help: procedure;
call mon1(m$prt$buf, .(cr, lf, tab, tab, tab ,'VCMODE EXAMPLES$'));
call mon1(m$prt$buf, .(cr, lf, lf, 'vcmode', tab, tab, tab, tab, tab,
'(show background mode)$'));
call mon1(m$prt$buf, .(cr, lf, 'vcmode dynamic', tab, tab, tab, tab,
'(sets background mode)$'));
call mon1(m$prt$buf, .(cr, lf, 'vcmode buffered', tab, tab, tab, tab,
tab, '"$'));
/* call mon1(m$prt$buf, .(cr, lf, 'vcmode suspend', tab, tab, tab, tab,
tab, '"$'));*/
call mon1(m$prt$buf, .(cr, lf, 'vcmode size = 5', tab, tab, tab, tab,
'(sets buffered mode max file size in)$'));
call mon1(m$prt$buf, .(cr, lf, tab, tab, tab, tab, tab,
'(kilobytes, legal range is 1 to 8191)$'));
call mon1(m$prt$buf, .(cr, lf, tab, tab, tab, tab, tab,
'(also sets background mode to buffered)$'));
/* call mon1(m$prt$buf, .(cr, lf, 'vcmode size = 100H', tab, tab, tab,
'(legal range in HEX is 1H to 1FFFFH)$'));*/
call mon1(m$prt$buf, .(cr, lf, 'vcmode help', tab, tab, tab, tab,
'(prints this message)$'));
call mon1(m$prt$buf, .(cr, lf, '$'));
call terminate;
end help;
showstate: procedure (verb);
dcl (verb,state) address;
call mon1(m$prt$buf, .(cr,lf,'Background Mode For Virtual Console$'));
call pdecimal (console, 100, true);
call printb;
call mon1(m$prt$buf, verb);
state = ccb.state and csm$buffered;
if state = 0 then
call mon1(m$prt$buf, .(' Dynamic$'));
else
do;
call mon1(m$prt$buf, .(' Buffered', cr, lf, 'Maximum file size = $'));
call pdecimal(ccb.maxbufsiz, 10000, true);
call mon1(m$prt$buf, .('K$'));
end;
call mon1(m$prt$buf, .(cr, lf, '$'));
end show$state;
$include (:f2:qd.lit)
dcl qpb qpb$structure;
read$change$mxq: procedure;
qpb.qaddr = ccb.vcmxq;
call mon1 (m$readq, .qpb);
end read$change$mxq;
write$change$mxq: procedure;
qpb.qaddr = ccb.vcmxq;
call mon1 (m$writeq, .qpb);
end write$change$mxq;
atohb: procedure (char) byte public; /* convert ascii hex to nibble value */
declare char byte;
if char >= '0' and char <= '9' then
char = char - '0';
else if char >= 'A' and char <= 'F' then
char = char - 'A' + 10;
else
char = 255;
return(char);
end atohb;
atodb: procedure (char) byte public;/* convert ascii decimal to nibble value */
declare char byte;
if char >= '0' and char <= '9' then
char = char - '0';
else
char = 255;
return(char);
end atodb;
atoi: procedure(str) word; /* convert ascii to 16 bit unsigned value */
dcl str pointer;
dcl (accum, temp) word;
dcl (val, i, len) byte;
dcl string based str (1) byte;
i, accum = 0;
if (len := findb(str, 'H', 5)) <> 0ffffh then /* hex conversion */
do while (val := atohb(string(i))) <> 0ffh and i < len;
accum = shl(accum, 4) + val;
i = i + 1;
end;
else /* decimal is default base */
do while (val := atodb(string(i))) <> 0ffh and i < 5;
accum = 10 * accum + val;
if i = 4 then
temp = accum;
i = i + 1;
end;
if temp > accum then /* overflow */
accum = 0ffffh;
return(accum);
end atoi;
compare: procedure(ustr, ostr, minlen, maxlen) boolean;
dcl (ustr, ostr) pointer; /* user string, option string */
dcl user$string based ustr (1) byte;
dcl (minlen, maxlen) byte;
dcl cmplen word;
cmplen = cmpb(ustr, ostr, maxlen);
if cmplen = 0ffffh or (user$string(cmplen) = ' ' and cmplen >= minlen) then
return(true);
if user$string(cmplen) = ' ' then
do;
call mon1(m$prt$buf, .(cr,lf,'Invalid Command Option.', cr ,lf, '$'));
call help;
end;
return(false);
end compare;
dcl vers address initial (0);
dcl no$state lit '0ffh';
dcl console byte;
/*
Main Program
*/
plmstart: procedure public;
dcl option$ptr byte;
dcl num word;
vers = version;
if (high(vers) <> ccpmproduct) then
do;
call print$console$buffer(.(cr,lf,'Requires Concurrent CP/M-86', cr, lf,
'$'));
call mon1(0,0);
end;
sysdat$pointer, ccb$pointer = mon4(m$sysdat, 0); /* system data segment */
ccb$ptr.offset = sd.ccb + (console := mon2(m$getcns, 0)) * size(ccb);
call read$change$mxq; /* MXQ is written in kernel terminate code */
if (ccb.state and csm$background) <> 0 then
call mon1(m$prt$buf, .(cr,lf,'Virtual Console not in foreground', cr, lf,
'$'));
else if buff(0) = 0 then
call show$state(.('is$')); /* show current state */
else /* try to set state or show help message */
do;
fcb(f$type) = ' ';
if compare(@fcb(f$name), @('BUFFERED'), 1, 8) then
ccb.state = ccb.state or csm$buffered;
else if compare(@fcb(f$name), @('DYNAMIC'), 1, 7) then
ccb.state = ccb.state and not double(csm$buffered);
else if compare(@fcb(f$name), @('HELP'), 1, 4) then
call help;
else if compare(@fcb(f$name), @('SIZE'), 1, 4) then /* change to 2,4 */
do; /* when suspend is put back in */
num = atoi(@fcb(f$name2));
if num > 0 and num < 2000H then
ccb.maxbufsiz = num; /* limit size to 16 bit record count */
else
do;
call mon1(m$prt$buf, .(cr,lf,'File size out of range', cr ,lf, '$'));
call help;
end;
ccb.state = ccb.state or csm$buffered;
/* automatically sets to buffered */
end;
else
do;
call mon1(m$prt$buf, .(cr,lf,'Invalid Command Option.', cr ,lf, '$'));
call help;
end;
call show$state(.('set to$'));
end;
call terminate;
end plmstart;
end vcmode;


View File

@@ -0,0 +1,17 @@
/* This utility requires MP/M or Concurrent function calls */
/****** commented out for CCP/M-86 :
declare Ver$OS literally '11h',
Ver$Needs$OS literally '''Requires MP/M-86''';
******/
declare Ver$OS literally '14h',
Ver$Needs$OS literally '''Requires Concurrent CP/M-86''';
declare Ver$Mask literally '0fdh'; /* mask out Is_network bit */
declare Ver$BDOS literally '30h'; /* minimal BDOS version rqd */