mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 00:14:25 +00:00
328 lines
6.7 KiB
C
328 lines
6.7 KiB
C
|
||
/****************************************************************
|
||
* *
|
||
* P-CP/M BDOS Miscellaneous Module *
|
||
* *
|
||
* This module contains miscellaneous loose ends for *
|
||
* P-CP/M. Included are: *
|
||
* *
|
||
* bdosinit() - BDOS initialization routine *
|
||
* called from CCP for system init *
|
||
* warmboot() - BDOS warm boot exit routine *
|
||
* error() - BDOS error printing routine *
|
||
* setexc() - BDOS set exception vector *
|
||
* set_tpa() - BDOS get/set TPA limits *
|
||
* cpy_bi() - copy byte in *
|
||
* *
|
||
* *
|
||
* Modified for memory management on the Z8000 *
|
||
* *
|
||
****************************************************************/
|
||
|
||
#include "stdio.h" /* Standard I/O declarations */
|
||
|
||
#include "bdosdef.h" /* Type and structure declarations for BDOS */
|
||
|
||
#include "biosdef.h" /* BIOS definitions, needed for bios wboot */
|
||
|
||
|
||
/* Declare external functions */
|
||
EXTERN conout(); /* Console Output function */
|
||
EXTERN UBYTE conin(); /* Console Input function */
|
||
EXTERN prt_line(); /* Print String function */
|
||
EXTERN UWORD _bdos(); /* BDOS main routine */
|
||
EXTERN UBYTE *traphnd(); /* assembly language trap handler */
|
||
EXTERN initexc(); /* init the exception handler in */
|
||
/* exceptn.s */
|
||
EXTERN UWORD dirscan(); /* Directory scanning routine */
|
||
EXTERN BOOLEAN set_attr(); /* Set File attributes function */
|
||
|
||
/* Declare external variables */
|
||
EXTERN UWORD log_dsk; /* logged-on disk vector */
|
||
EXTERN UWORD ro_dsk; /* read-only disk vector */
|
||
EXTERN UWORD crit_dsk; /* vector of critical disks */
|
||
EXTERN XADDR tpa_lt; /* TPA lower limit (temporary) */
|
||
EXTERN XADDR tpa_lp; /* TPA lower limit (permanent) */
|
||
EXTERN XADDR tpa_ht; /* TPA upper limit (temporary) */
|
||
EXTERN XADDR tpa_hp; /* TPA upper limit (permanent) */
|
||
EXTERN BOOLEAN submit; /* external variables from CCP */
|
||
EXTERN BOOLEAN morecmds;
|
||
|
||
|
||
#define trap2v 34 /* trap 2 vector number */
|
||
#define ctrlc 3 /* control-c */
|
||
|
||
|
||
/********************************
|
||
* bdos initialization routine *
|
||
********************************/
|
||
|
||
bdosinit()
|
||
/* Initialize the File System */
|
||
{
|
||
REG struct
|
||
{
|
||
WORD nmbr;
|
||
XADDR low;
|
||
LONG length;
|
||
} *segp;
|
||
BSETUP
|
||
|
||
bsetvec(trap2v, map_adr((long)traphnd, 257)); /* set up trap vector */
|
||
/* (inst. space addr) */
|
||
GBL.kbchar = 0; /* initialize the "global" variables */
|
||
GBL.delim = '$';
|
||
GBL.lstecho = FALSE;
|
||
GBL.echodel = TRUE;
|
||
GBL.chainp = XNULL;
|
||
GBL.user = 0;
|
||
_bdos(13,0, XNULL); /* reset disk system function */
|
||
prt_line("
|
||
\r\nCPM-Z8000 Version 1.3 06/14/83$");
|
||
prt_line("\r\nCopyright 1982 Digital Research Inc., Zilog Inc.$");
|
||
segp = bgetseg(); /* get pointer to memory segment table */
|
||
tpa_lt = tpa_lp = segp->low;
|
||
tpa_ht = tpa_hp = tpa_lp + segp->length;
|
||
initexc( &(GBL.excvec[0]) );
|
||
}
|
||
|
||
|
||
/************************
|
||
* warmboot entry point *
|
||
************************/
|
||
|
||
warmboot(parm)
|
||
/* Warm Boot the system */
|
||
WORD parm; /* 1 to reset submit flag */
|
||
{
|
||
BSETUP
|
||
|
||
log_dsk &= ~ro_dsk; /* log off any disk marked read-only */
|
||
/* note that this code is specifically for a single-
|
||
thread system. It won't work in a multi-task sys */
|
||
ro_dsk = 0;
|
||
crit_dsk = 0;
|
||
if (parm)
|
||
submit = morecmds = FALSE;
|
||
tpa_lt = tpa_lp;
|
||
tpa_ht = tpa_hp;
|
||
initexc( &(GBL.excvec[0]) );
|
||
bwboot();
|
||
}
|
||
|
||
|
||
/*************************/
|
||
/* disk error handlers */
|
||
/*************************/
|
||
|
||
prt_err(p)
|
||
/* print the error message */
|
||
|
||
BYTE *p;
|
||
{
|
||
BSETUP
|
||
|
||
prt_line(p);
|
||
prt_line(" error on drive $");
|
||
conout(GBL.curdsk + 'A');
|
||
}
|
||
|
||
|
||
abrt_err(p)
|
||
/* print the error message and always abort */
|
||
|
||
BYTE *p;
|
||
{
|
||
prt_err(p);
|
||
warmboot(1);
|
||
}
|
||
|
||
|
||
ext_err(p)
|
||
/* print the error message, and allow for retry, abort, or ignore */
|
||
|
||
BYTE *p;
|
||
{
|
||
REG UBYTE ch;
|
||
|
||
prt_err(p);
|
||
do
|
||
{
|
||
prt_line("\n\rDo you want to: Abort (A), Retry (R),$");
|
||
prt_line(" or Continue with bad data (C)? $");
|
||
ch = conin() & 0x5f;
|
||
prt_line("\r\n$");
|
||
|
||
switch ( ch )
|
||
{
|
||
case ctrlc: warmboot(1);
|
||
case 'A': warmboot(1);
|
||
case 'C': return(1);
|
||
case 'R': return(0);
|
||
}
|
||
} while (TRUE);
|
||
}
|
||
|
||
|
||
filero(fcbp)
|
||
/* File R/O error */
|
||
|
||
REG struct fcb *fcbp;
|
||
{
|
||
REG BYTE *p;
|
||
REG UWORD i;
|
||
REG UBYTE ch;
|
||
|
||
p = (BYTE *)fcbp;
|
||
prt_line("file error: $");
|
||
i = 8;
|
||
do conout(*++p); while (--i);
|
||
conout('.');
|
||
i = 3;
|
||
do conout(*++p); while (--i);
|
||
prt_line(" is read-only.$");
|
||
do
|
||
{
|
||
prt_line("\r\nDo you want to: Change it to read/write (C), or Abort (A)? $");
|
||
ch = conin() & 0x5f;
|
||
prt_line("\r\n$");
|
||
|
||
switch ( ch )
|
||
{
|
||
case ctrlc: warmboot(1);
|
||
case 'A': warmboot(1);
|
||
case 'C': fcbp->ftype[robit] &= 0x7f;
|
||
return( dirscan(set_attr, fcbp, 2) );
|
||
}
|
||
} while (TRUE);
|
||
}
|
||
|
||
|
||
/************************
|
||
* error entry point *
|
||
************************/
|
||
|
||
error(errnum, fcbp) /* VARARGS */
|
||
/* Print error message, do appropriate response */
|
||
|
||
UWORD errnum; /* error number */
|
||
struct fcb *fcbp; /* pointer to fcb */
|
||
{
|
||
BSETUP
|
||
|
||
prt_line("\r\nCP/M Disk $");
|
||
switch (errnum)
|
||
{
|
||
case 0: return( ext_err("read$") );
|
||
/* break; */
|
||
|
||
case 1: return( ext_err("write$") );
|
||
/* break; */
|
||
|
||
case 2: abrt_err("select$");
|
||
/* break; */
|
||
|
||
case 3: return( ext_err("select$") );
|
||
/* break; */
|
||
|
||
case 4: abrt_err("change$");
|
||
/* break; */
|
||
|
||
case 5: return filero(fcbp);
|
||
/* break; */
|
||
|
||
}
|
||
}
|
||
|
||
|
||
/*****************************
|
||
* set exception entry point *
|
||
*****************************/
|
||
|
||
setexc(xepbp)
|
||
/* Set Exception Vector */
|
||
REG XADDR xepbp;
|
||
{
|
||
REG WORD i;
|
||
REG struct
|
||
{
|
||
WORD vecnum;
|
||
UBYTE *newvec;
|
||
UBYTE *oldvec;
|
||
} epb;
|
||
|
||
BSETUP
|
||
|
||
cpy_in(xepbp, &epb, sizeof epb); /* copy in param block */
|
||
|
||
i = epb.vecnum-2;
|
||
if ( i==32 || i==33) return(-1);
|
||
if ( (30 <= i) && (i <= 37) ) i -= 20;
|
||
else if ( (i < 0) || (i > 9) ) return(-1);
|
||
epb.oldvec = GBL.excvec[i];
|
||
GBL.excvec[i] = epb.newvec;
|
||
|
||
cpy_out(&epb, xepbp, sizeof epb); /* copy out param block */
|
||
|
||
return(0);
|
||
}
|
||
|
||
|
||
/*****************************
|
||
* get/set TPA entry point *
|
||
*****************************/
|
||
|
||
set_tpa(xp)
|
||
/* Get/Set TPA Limits */
|
||
REG XADDR xp;
|
||
|
||
#define set 1
|
||
#define sticky 2
|
||
|
||
{
|
||
struct
|
||
{
|
||
UWORD parms;
|
||
XADDR low;
|
||
XADDR high;
|
||
} p;
|
||
|
||
cpy_in(xp, &p, sizeof p); /* copy in param block */
|
||
|
||
if (p.parms & set)
|
||
{
|
||
tpa_lt = p.low;
|
||
tpa_ht = p.high;
|
||
if (p.parms & sticky)
|
||
{
|
||
tpa_lp = tpa_lt;
|
||
tpa_hp = tpa_ht;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
p.low = tpa_lt;
|
||
p.high = tpa_ht;
|
||
}
|
||
|
||
cpy_out(&p, xp, sizeof p); /* copy out param block */
|
||
|
||
}
|
||
|
||
|
||
/*****************************************************
|
||
**
|
||
** ubyte = cpy_bi(xaddr)-- copy byte in
|
||
**
|
||
*****************************************************/
|
||
|
||
UBYTE cpy_bi(addr)
|
||
XADDR addr;
|
||
{
|
||
UBYTE b;
|
||
|
||
cpy_in(addr, &b, 1);
|
||
return b;
|
||
}
|
||
|