mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-26 18:04:07 +00:00
Upload
Digital Research
This commit is contained in:
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
;
|
||||
;
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
/*
|
||||
Copyright (C) 1983
|
||||
Digital Research
|
||||
P.O. Box 579
|
||||
Pacific Grove, CA 93950
|
||||
*/
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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' );
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
/* Flag Format */
|
||||
|
||||
dcl flag$structure lit 'structure(
|
||||
pd word,
|
||||
ignore byte)';
|
||||
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "portab.h"
|
||||
#include "cpmfunc.h"
|
||||
|
||||
_main()
|
||||
{
|
||||
main();
|
||||
p_termcpm();
|
||||
}
|
||||
|
||||
@@ -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)';
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
@@ -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 ********************************/
|
||||
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 )';
|
||||
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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]
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
sqlib=
|
||||
cpyucase,
|
||||
cpmerr,
|
||||
crlf,
|
||||
fileopen,
|
||||
firstch,
|
||||
getdrv,
|
||||
getnum,
|
||||
gettail,
|
||||
issysfil,
|
||||
itoa,
|
||||
nextfcb,
|
||||
okver,
|
||||
parse,
|
||||
putfname,
|
||||
readsect,
|
||||
reverse,
|
||||
tlex,
|
||||
valid
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)';
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
****/
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user