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,37 @@
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* B A S E P A G E . H */
|
||||
/* ------------------- */
|
||||
/* */
|
||||
/* This file contains a definition of the CP/M basepage structure, */
|
||||
/* b_page. */
|
||||
/* */
|
||||
/* NOTE: In the portable CP/M environment, it is NOT guaranteed */
|
||||
/* that the location of the base page is known at link-edit time */
|
||||
/* (as it is, for example, in CP/M-80 and CP/M-86.) Instead, a */
|
||||
/* pointer to the current basepage is delivered by the BDOS */
|
||||
/* to each new program which is run. This pointer, _base, is */
|
||||
/* initialized by the C startup function (startup.s) and is */
|
||||
/* available to C programs as an external. */
|
||||
/* */
|
||||
/* This file has been modified to live with the BDOS definitions. */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
struct b_page
|
||||
{
|
||||
XADDR ltpa; /* Low TPA address */
|
||||
XADDR htpa; /* High TPA address */
|
||||
XADDR lcode; /* Start address of code seg*/
|
||||
long codelen; /* Code segment length */
|
||||
XADDR ldata; /* Start address of data seg*/
|
||||
long datalen; /* Data segment length */
|
||||
XADDR lbss; /* Start address of bss seg */
|
||||
long bsslen; /* Bss segment length */
|
||||
long freelen; /* Free segment length */
|
||||
char resvd1[20]; /* Reserved area */
|
||||
struct fcb fcb2; /* Second basepage FCB */
|
||||
struct fcb fcb1; /* First basepage FCB */
|
||||
char buff[128]; /* Default DMA buffer, */
|
||||
/* command line tail */
|
||||
};
|
||||
@@ -0,0 +1,170 @@
|
||||
|
||||
/********************************************************
|
||||
* *
|
||||
* P-CP/M header file *
|
||||
* Copyright (c) 1982 by Digital Research, Inc. *
|
||||
* Structure definitions for BDOS globals *
|
||||
* and BDOS data structures *
|
||||
* *
|
||||
********************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
The BDOS data structures, especially those relating to global variables,
|
||||
are structured in a way that hopefully will enable this BDOS, in the future,
|
||||
to easily become a re-entrant multi-tasking file system. Consequently,
|
||||
the BDOS global variables are divided into two classes. Those that are
|
||||
truly global, even in the case of multiple tasks using the file system
|
||||
concurrently, are simply declared as global variables in bdosmain.c.
|
||||
Only a few "globals" are really global in this sense.
|
||||
|
||||
The majority of the "global" variables are actually state variables that
|
||||
relate to the state of the task using the file system. In CP/M-68K, these
|
||||
are "global", since there's only one task, but in a multi-thread model they're
|
||||
not. These type of variables are put into a data structure, with the
|
||||
intention that in the multi-task environment this structure will be based.
|
||||
|
||||
The following declarations take this philosophy into account, and define
|
||||
a simple structure for the single thread environment while leaving the
|
||||
possibilities open for the multi-thread environment.
|
||||
****************************************************************************/
|
||||
|
||||
#define snglthrd TRUE
|
||||
/* TRUE for single-thread environment
|
||||
undefined to create based structure for re-entrant model */
|
||||
#ifdef snglthrd
|
||||
#define GBL gbls
|
||||
/* In single thread case, GBL just names
|
||||
the structure */
|
||||
#define BSETUP EXTERN struct stvars gbls;
|
||||
/* and BSETUP defines the extern structure */
|
||||
#else
|
||||
|
||||
#define GBL (*statep)
|
||||
/* If multi-task, state vars are based */
|
||||
#define BSETUP REG struct stvars *statep; \
|
||||
statep = &gbls;
|
||||
/* set up pointer to state variables */
|
||||
/* This is intended as an example to show the intent */
|
||||
#endif
|
||||
|
||||
|
||||
/* Note that there are a few critical regions in the file system that must
|
||||
execute without interruption. They pertain mostly to the manipulation of
|
||||
the allocation vector. This isn't a problem in a single-thread model, but
|
||||
must be provided for in a multi-tasking file system. Consequently, the
|
||||
primitives LOCK and UNLOCK are defined and used where necessary in the
|
||||
file system. For the single thread model, they are null routines */
|
||||
|
||||
#define LOCK /**/
|
||||
#define UNLOCK /**/
|
||||
/* Be sure LOCK and UNLOCK are implemented to allow recursive calls to LOCK.
|
||||
That is, if a process that calls LOCK already owns the lock, let it proceed,
|
||||
but remember that only the outer-most call to UNLOCK really releases the
|
||||
file system. */
|
||||
|
||||
|
||||
#define VERSION 0x2022 /* Version number for CP/M-68K */
|
||||
#define robit 0 /* read-only bit in file type field of fcb */
|
||||
#define SECLEN 128 /* length of a CP/M sector */
|
||||
|
||||
|
||||
union smallbig
|
||||
{
|
||||
UBYTE small[16]; /* 16 block numbers of 1 byte */
|
||||
WORD big[8]; /* or 8 block numbers of 1 word */
|
||||
};
|
||||
|
||||
/* File Control Block definition */
|
||||
struct fcb
|
||||
{
|
||||
UBYTE drvcode; /* 0 = default drive, 1..16 are drives A..P */
|
||||
UBYTE fname[8]; /* File name (ASCII) */
|
||||
UBYTE ftype[3]; /* File type (ASCII) */
|
||||
UBYTE extent; /* Extent number (bits 0..4 used) */
|
||||
UBYTE s1; /* Reserved */
|
||||
UBYTE s2; /* Module field (bits 0..5), write flag (7) */
|
||||
UBYTE rcdcnt; /* Nmbr rcrds in last block, 0..128 */
|
||||
union smallbig dskmap;
|
||||
UBYTE cur_rec; /* current record field */
|
||||
UBYTE ran0; /* random record field (3 bytes) */
|
||||
UBYTE ran1;
|
||||
UBYTE ran2;
|
||||
};
|
||||
|
||||
|
||||
/* Declaration of directory entry */
|
||||
struct dirent
|
||||
{
|
||||
UBYTE entry; /* 0 - 15 for user numbers, E5 for empty */
|
||||
/* the rest are reserved */
|
||||
UBYTE fname[8]; /* File name (ASCII) */
|
||||
UBYTE ftype[3]; /* File type (ASCII) */
|
||||
UBYTE extent; /* Extent number (bits 0..4 used) */
|
||||
UBYTE s1; /* Reserved */
|
||||
UBYTE s2; /* Module field (bits 0..5), write flag (7) */
|
||||
UBYTE rcdcnt; /* Nmbr rcrds in last block, 0..128 */
|
||||
union smallbig dskmap;
|
||||
};
|
||||
|
||||
|
||||
/* Declaration of disk parameter tables */
|
||||
struct dpb /* disk parameter table */
|
||||
{
|
||||
UWORD spt; /* sectors per track */
|
||||
UBYTE bsh; /* block shift factor */
|
||||
UBYTE blm; /* block mask */
|
||||
UBYTE exm; /* extent mask */
|
||||
UBYTE dpbdum; /* dummy byte for fill */
|
||||
UWORD dsm; /* max disk size in blocks */
|
||||
UWORD drm; /* max directory entries */
|
||||
UWORD dir_al; /* initial allocation for dir */
|
||||
UWORD cks; /* number dir sectors to checksum */
|
||||
UWORD trk_off; /* track offset */
|
||||
};
|
||||
|
||||
struct dph /* disk parameter header */
|
||||
{
|
||||
UBYTE *xlt; /* pointer to sector translate table */
|
||||
UWORD hiwater; /* high water mark for this disk */
|
||||
UWORD dum1; /* dummy (unused) */
|
||||
UWORD dum2;
|
||||
UBYTE *dbufp; /* pointer to 128 byte directory buffer */
|
||||
struct dpb *dpbp; /* pointer to disk parameter block */
|
||||
UBYTE *csv; /* pointer to check vector */
|
||||
UBYTE *alv; /* pointer to allocation vector */
|
||||
};
|
||||
|
||||
|
||||
/* Declaration of structure containing "global" state variables */
|
||||
struct stvars
|
||||
{
|
||||
UBYTE kbchar; /* One byte keyboard type-ahead buffer */
|
||||
UBYTE delim; /* Delimiter for function 9 */
|
||||
BOOLEAN lstecho; /* True if echoing console output to lst: */
|
||||
BOOLEAN echodel; /* Echo char when getting <del> ? */
|
||||
UWORD column; /* CRT column number for expanding tabs */
|
||||
XADDR chainp; /* Used for chain to program call */
|
||||
UBYTE curdsk; /* Currently selected disk */
|
||||
UBYTE dfltdsk; /* Default disk (last selected by fcn 14) */
|
||||
UBYTE user; /* Current user number */
|
||||
struct dph *dphp; /* pointer to disk parm hdr for cur disk */
|
||||
struct dirent *dirbufp; /* pointer for directory buff for process */
|
||||
/* stored here so that each process can */
|
||||
/* have a separate dirbuf. */
|
||||
struct dpb *parmp; /* pointer to disk parameter block for cur */
|
||||
/* disk. Stored here to save ref calc */
|
||||
UWORD srchpos; /* position in directory for search next */
|
||||
XADDR dmaadr; /* Disk dma address */
|
||||
XADDR srchp; /* Pointer to search FCB for function 17 */
|
||||
UBYTE *excvec[14]; /* Array of exception vectors */
|
||||
};
|
||||
|
||||
|
||||
/* Console buffer structure declaration */
|
||||
struct conbuf
|
||||
{
|
||||
UBYTE maxlen; /* Maximum length from calling routine */
|
||||
UBYTE retlen; /* Length actually found by BDOS */
|
||||
UBYTE cbuf[1]; /* Console data */
|
||||
};
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
|
||||
/********************************************************
|
||||
* *
|
||||
* BIOS definitions for P-CP/M *
|
||||
* *
|
||||
* Copyright (c) 1982 Digital Research, Inc. *
|
||||
* *
|
||||
* This include file simply defines the BIOS calls *
|
||||
* *
|
||||
* Memory management added 821018 by SS at Zilog *
|
||||
* *
|
||||
********************************************************/
|
||||
|
||||
EXTERN UBYTE bios1(); /* used for character I/O functions */
|
||||
EXTERN bios2(); /* parm1 is word, no return value */
|
||||
EXTERN bios3(); /* used for set dma only */
|
||||
/* parm1 is a pointer, no return */
|
||||
EXTERN UBYTE *bios4(); /* seldsk only, parm1 and parm2 are */
|
||||
/* words, returns a pointer to dph */
|
||||
EXTERN UWORD bios5(); /* for sectran and set exception */
|
||||
|
||||
|
||||
#define bwboot() bios1(1) /* warm boot */
|
||||
#define bconstat() bios1(2) /* console status */
|
||||
#define bconin() bios1(3) /* console input */
|
||||
#define bconout(parm) bios2(4,parm) /* console output parm */
|
||||
#define blstout(parm) bios2(5,parm) /* list device output */
|
||||
#define bpun(parm) bios2(6,parm) /* punch char output */
|
||||
#define brdr() bios1(7) /* reader input */
|
||||
#define bhome() bios1(8) /* recalibrate drive */
|
||||
#define bseldsk(parm1,parm2) bios4(9,parm1,parm2)
|
||||
/* select disk and return info */
|
||||
#define bsettrk(parm) bios2(10,parm) /* set track on disk */
|
||||
#define bsetsec(parm) bios2(11,parm) /* set sector for disk */
|
||||
#define bsetdma(parm) bios3(12,parm) /* set dma address */
|
||||
#define bread() bios1(13) /* read sector from disk */
|
||||
#define bwrite(parm) bios2(14,parm) /* write sector to disk */
|
||||
#define blistst() bios1(15) /* list device status */
|
||||
#define bsectrn(parm1,parm2) bios5(16,parm1,(XADDR)parm2)
|
||||
/* sector translate */
|
||||
#define bgetseg() bios1(18) /* get memory segment tbl */
|
||||
#define bgetiob() bios1(19) /* get I/O byte */
|
||||
#define bsetiob(parm) bios2(20,parm) /* set I/O byte */
|
||||
#define bflush() bios1(21) /* flush buffers */
|
||||
#define bsetvec(parm1,parm2) bios5(22,parm1,(XADDR)parm2)
|
||||
/* set exception vector */
|
||||
|
||||
|
||||
/************************/
|
||||
/* MEMORY MANAGEMENT */
|
||||
/*----------------------*/
|
||||
EXTERN XADDR map_adr(); /*(laddr, space)->paddr */
|
||||
EXTERN VOID mem_cpy(); /*(src, dst, len) */
|
||||
/*----------------------*/
|
||||
/* copy in, out (s,d,l) */
|
||||
/* */
|
||||
#define cpy_in(s,d,l) mem_cpy((XADDR)s, map_adr((XADDR)d, 0), (long)l)
|
||||
#define cpy_out(s,d,l) mem_cpy(map_adr((XADDR)s, 0), (XADDR)d, (long)l)
|
||||
/* */
|
||||
/************************/
|
||||
|
||||
|
||||
1505
CPM OPERATING SYSTEMS/CPM 8000 (CPM8K)/P-CP M-Z8K SOURCES/ccp/ccp.c
Normal file
1505
CPM OPERATING SYSTEMS/CPM 8000 (CPM8K)/P-CP M-Z8K SOURCES/ccp/ccp.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,158 @@
|
||||
/*--------------------------------------------------------------*\
|
||||
| ccp_def.c DEFINES v1.0 |
|
||||
| ======= |
|
||||
| |
|
||||
| P-CP/M: A CP/M derived operating system |
|
||||
| |
|
||||
| File contents: |
|
||||
| ------------- |
|
||||
| This file contains all of the #defines |
|
||||
| used by the console command processor. |
|
||||
| |
|
||||
| created by : Tom Saulpaugh Date: 7/13/82 |
|
||||
| ---------- |
|
||||
| last modified: 12/20/82 |
|
||||
| ------------- |
|
||||
| |
|
||||
| (c) COPYRIGHT Digital Research 1982 |
|
||||
| all rights reserved |
|
||||
| |
|
||||
\*--------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*-------------------------------------------*\
|
||||
| CP/M Transient Commands |
|
||||
\*-------------------------------------------*/
|
||||
|
||||
#define DIRCMD 0
|
||||
#define TYPECMD 1
|
||||
#define RENCMD 2
|
||||
#define ERACMD 3
|
||||
#define UCMD 4
|
||||
#define CH_DISK 5
|
||||
#define SUBCMD 6
|
||||
#define SUB_FILE 7
|
||||
#define FILE 8
|
||||
#define DIRSCMD 9
|
||||
#define SEARCH 10
|
||||
|
||||
/*-------------------------------------------*\
|
||||
| Modes and Flags |
|
||||
\*-------------------------------------------*/
|
||||
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
#define MATCH 0
|
||||
#define GOOD 1
|
||||
#define BAD 0
|
||||
#define FILL 1
|
||||
#define NOFILL 0
|
||||
#define VOID /*no return value*/
|
||||
#define NO_FILE 98
|
||||
#define STOP 99
|
||||
#define USER_ZERO 0
|
||||
#define DISK_A 1
|
||||
#define SOURCEDRIVE 88
|
||||
#define DESTDRIVE 99
|
||||
#define BYTE char
|
||||
#define REG register
|
||||
#define WORD short
|
||||
#define UWORD unsigned int
|
||||
#define LONG long
|
||||
#define ULONG unsigned long
|
||||
#define GET_MEM_REG 18
|
||||
#define ZERO 0
|
||||
#define NULL '\0'
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define NO_READ 255
|
||||
#define BLANK ' '
|
||||
#define BACKSLH '\\'
|
||||
#define EXLIMPT '!'
|
||||
#define CMASK 0177
|
||||
#define ONE (long)49
|
||||
#define TAB 9
|
||||
#define Cr 13
|
||||
#define Lf 10
|
||||
#define CR (long)13
|
||||
#define LF (long)10
|
||||
#define EOF 26
|
||||
#define BLANKS (long)32
|
||||
#define PERIOD (long)46
|
||||
#define COLON (long)58
|
||||
#define ARROW (long)62
|
||||
|
||||
/*-------------------------------------------*\
|
||||
| Data Structure Size Constants |
|
||||
\*-------------------------------------------*/
|
||||
|
||||
#define CMD_LEN 128
|
||||
#define BIG_CMD_LEN 255
|
||||
#define MAX_ARGS 4
|
||||
#define ARG_LEN 26
|
||||
#define NO_OF_DRIVES 16
|
||||
#define NUMDELS 16
|
||||
#define FCB_LEN 36
|
||||
#define DMA_LEN 128
|
||||
#define FILES_PER_LINE 4 /* Zilog */
|
||||
#define SCR_HEIGHT 23
|
||||
#define BIG_WIDTH 80
|
||||
#define SMALL_WIDTH 40
|
||||
|
||||
/*-------------------------------------------*\
|
||||
| BDOS Function Calls |
|
||||
\*-------------------------------------------*/
|
||||
|
||||
#define WARMBOOT 0
|
||||
#define CONIN 1
|
||||
#define CONSOLE_OUTPUT 2
|
||||
#define READER_INPUT 3
|
||||
#define PUNCH_OUTPUT 4
|
||||
#define LIST_OUTPUT 5
|
||||
#define DIR_CONS_I/O 6
|
||||
#define GET_I/O_BYTE 7
|
||||
#define SET_I/O_BYTE 8
|
||||
#define PRINT_STRING 9
|
||||
#define READ_CONS_BUF 10
|
||||
#define GET_CONS_STAT 11
|
||||
#define RET_VERSION_NO 12
|
||||
#define RESET_DISK_SYS 13
|
||||
#define SELECT_DISK 14
|
||||
#define OPEN_FILE 15
|
||||
#define CLOSE_FILE 16
|
||||
#define SEARCH_FIRST 17
|
||||
#define SEARCH_NEXT 18
|
||||
#define DELETE_FILE 19
|
||||
#define READ_SEQ 20
|
||||
#define WRITE_SEQ 21
|
||||
#define MAKE_FILE 22
|
||||
#define RENAME_FILE 23
|
||||
#define RET_LOGIN_VEC 24
|
||||
#define RET_CUR_DISK 25
|
||||
#define SET_DMA_ADDR 26
|
||||
/* #define GET_ADDR(ALLOC) 27 */
|
||||
#define WRITE_PROT_DISK 28
|
||||
#define GET_READ/O_VEC 29
|
||||
#define SET_FILE_ATTRIB 30
|
||||
#define GET_ADDR_D_PARM 31
|
||||
#define GET_USER_NO 32
|
||||
#define READ_RANDOM 33
|
||||
#define WRITE_RANDOM 34
|
||||
#define COMP_FILE-SIZE 35
|
||||
#define SET_RANDOM_REC 36
|
||||
#define RESET_DRIVE 37
|
||||
/* #define WRITE_RAN_ZERO 40 */
|
||||
#define BIOS_CALL 50
|
||||
#define LOAD_PROGRAM 59
|
||||
|
||||
/*----------------------------------------------*\
|
||||
| MACROS |
|
||||
\*----------------------------------------------*/
|
||||
|
||||
#define isalpha(c) (islower(c) || isupper(c))
|
||||
#define islower(c) ('a' <= (c) && (c) <= 'z')
|
||||
#define isupper(c) ('A' <= (c) && (c) <= 'Z')
|
||||
#define tolower(c) (isupper(c) ? ((c)+040):(c))
|
||||
#define toupper(c) (islower(c) ? ((c)-040):(c))
|
||||
#define isdigit(c) ('0' <= (c) && (c) <= '9')
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
;******* ccpif.z8k -- CCP interface *****************
|
||||
;*
|
||||
;* 821015 S. Savitzky (Zilog) derived from 68K version
|
||||
;*
|
||||
;****************************************************
|
||||
|
||||
__text: .sect
|
||||
|
||||
;****************************************************
|
||||
;*
|
||||
;* EXTERNALS
|
||||
;*
|
||||
;****************************************************
|
||||
|
||||
.global _bdosinit
|
||||
.global _main
|
||||
|
||||
;****************************************************
|
||||
;*
|
||||
;* GLOBALS
|
||||
;*
|
||||
;****************************************************
|
||||
|
||||
.global ccp ; main entry point
|
||||
.global _autost
|
||||
.global _usercmd
|
||||
.global _submit
|
||||
.global _morecmds
|
||||
|
||||
;****************************************************
|
||||
;*
|
||||
;* JUMP VECTOR
|
||||
;*
|
||||
;****************************************************
|
||||
|
||||
ccp: jr ccpstart ; start ccp with possible
|
||||
; initial command
|
||||
jp ccpclear ; clear autostart flag
|
||||
|
||||
|
||||
|
||||
;****************************************************
|
||||
;*
|
||||
;* DATA
|
||||
;*
|
||||
;****************************************************
|
||||
|
||||
__data: .sect
|
||||
|
||||
copy: .byte " COPYRIGHT (C) 1982, Digital Research "
|
||||
|
||||
_autost: ; autostart command flag
|
||||
.byte 0
|
||||
sysinit: ; set if system initialized
|
||||
.byte 0
|
||||
_submit:
|
||||
.byte 0
|
||||
_morecmds:
|
||||
.byte 0
|
||||
|
||||
__bss: .sect
|
||||
|
||||
_usercmd: ; user command buffer
|
||||
.block 130
|
||||
stackp: ; saved stack pointer
|
||||
.block 2
|
||||
|
||||
|
||||
|
||||
;****************************************************
|
||||
;*
|
||||
;* PROGRAM INTERFACE
|
||||
;*
|
||||
;* ccpclear -- clear autostart flag
|
||||
;* ccpstart -- normal entry from boot
|
||||
;* jumped to with valid stack ptr.
|
||||
;* ccploop -- main loop (internal)
|
||||
;*
|
||||
;****************************************************
|
||||
|
||||
__text: .sect
|
||||
|
||||
ccpclear:
|
||||
clrb _autost ; clear the autostart flag
|
||||
|
||||
ccpstart:
|
||||
ld stackp,r15 ; save stack pointer
|
||||
tsetb sysinit ; system initialized?
|
||||
jr mi ccploop ; yes
|
||||
; no: init flag now set
|
||||
call _bdosinit ; init bdos
|
||||
|
||||
ccploop:
|
||||
ld r15,stackp ; reset stack pointer
|
||||
call _main ; call the CCP
|
||||
jr ccploop ; loop forever
|
||||
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
/************************************************************************
|
||||
* *
|
||||
* CP/M-8000 CCP Program Loader (__LOAD) *
|
||||
* *
|
||||
* Copyright (c) 1982 Zilog Incorporated *
|
||||
* *
|
||||
* This function arranges for the BDOS program loader to be *
|
||||
* invoked in a suitable environment. Suitable means that it *
|
||||
* fills in whatever is expected in the LPB, gets the rest back *
|
||||
* from the BDOS, and then completes the basepage and resets the *
|
||||
* dma buffer. *
|
||||
* *
|
||||
* The loading of segmented programs is not currently supported *
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
#include "stdio.h" /* Standard declarations for BDOS, BIOS */
|
||||
|
||||
#include "bdosdef.h" /* BDOS type and structure declarations */
|
||||
|
||||
#include "biosdef.h" /* Declarations of BIOS functions */
|
||||
|
||||
#include "basepage.h" /* Base page structure */
|
||||
|
||||
#define SEP_ID 0x4000 /* Separate I/D flag */
|
||||
#define SEG 0x2000 /* Segmented load module */
|
||||
|
||||
#define NREGIONS 2 /* Number of MRT regions */
|
||||
|
||||
/* Return values: indexes into msgs (included here for documentation */
|
||||
/* purposes - only GOOD is used in this module */
|
||||
|
||||
#define GOOD 0 /* good return value */
|
||||
#define BADHDR 1 /* bad header */
|
||||
#define NOMEM 2 /* not enough memory */
|
||||
#define READERR 3 /* read error */
|
||||
|
||||
#define WARMBOOT 0 /* Warm reboot BDOS call */
|
||||
#define PRNTSTR 9 /* Print String BDOS call */
|
||||
#define SETDMA 26 /* Set DMA Address BDOS call */
|
||||
#define PGLOAD 59 /* Program Load BDOS call */
|
||||
|
||||
#define MYDATA 0 /* Argument for map_adr */
|
||||
#define TPADATA 4 /* Argument for map_adr */
|
||||
#define TPAPROG 5 /* Argument for map_adr */
|
||||
/* Get actual code segment (as opposed */
|
||||
/* to segment where it can be accessed*/
|
||||
/* as data) */
|
||||
#define TRUE_TPAPROG (TPAPROG | 0x100)
|
||||
|
||||
#define BGETMRT 18 /* Number of the BIOS call */
|
||||
|
||||
extern char cmdfcb[]; /* the FCB for everything */
|
||||
extern char *tail; /* where the command tail is */
|
||||
|
||||
extern UWORD bdos(); /* To do I/O into myself */
|
||||
extern XADDR bios(); /* To get MRT pointer */
|
||||
extern VOID fill_fcb(); /* Parse filename into fcb */
|
||||
extern VOID xfer(); /* Transfer control to user program */
|
||||
|
||||
struct lpb {
|
||||
XADDR fcbaddr; /* Address of fcb of opened file */
|
||||
XADDR pgldaddr; /* Low address of prog load area */
|
||||
XADDR pgtop; /* High address of prog load area, +1 */
|
||||
XADDR bpaddr; /* Address of basepage; return value */
|
||||
XADDR stackptr; /* Stack ptr of user; return value */
|
||||
short flags; /* Loader control flags; return value */
|
||||
} LPB;
|
||||
|
||||
struct m_rt { /* The Memory Region Table */
|
||||
int entries;
|
||||
struct {
|
||||
XADDR m_low;
|
||||
XADDR m_len;
|
||||
} m_reg[NREGIONS];
|
||||
};
|
||||
|
||||
struct ustack /* User's initial stack (nonsegmented) */
|
||||
{
|
||||
short two; /* "Return address" (actually a call to */
|
||||
/* BDOS warm boot in runtime startup) */
|
||||
short bpgaddr;/* Input parameter: pointer to basepage */
|
||||
} stack =
|
||||
{
|
||||
0x0002 /* bpgaddr initialized at runtime */
|
||||
};
|
||||
|
||||
struct sstack /* User's initial stack (segmented) */
|
||||
{
|
||||
XADDR stwo; /* "Return address" (actually a call to */
|
||||
/* BDOS warm boot in runtime startup) */
|
||||
XADDR sbpgadr;/* Input parameter: pointer to basepage */
|
||||
} sstack;
|
||||
|
||||
|
||||
/* Error messages for bad loads */
|
||||
|
||||
static char *msgs[] =
|
||||
{
|
||||
"",
|
||||
"File is not executable$",
|
||||
"Insufficient memory$",
|
||||
"Read error on program load$",
|
||||
"Program Load Error$"
|
||||
};
|
||||
|
||||
struct context /* Startup context for user's program */
|
||||
{
|
||||
short regs[16];
|
||||
short ignore;
|
||||
short FCW;
|
||||
XADDR PC;
|
||||
} context =
|
||||
|
||||
{ /* Regs 0-14 cleared, 15 set up below */
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
0, /* Ignore: value is zero */
|
||||
0x1800 /* FCW: nonsegmented normal, VI, NVI set*/
|
||||
}; /* PC initialized below */
|
||||
|
||||
|
||||
/********************************/
|
||||
/* */
|
||||
/* _ _ L O A D */
|
||||
/* */
|
||||
/********************************/
|
||||
|
||||
|
||||
VOID /* Load a program from */
|
||||
__LOAD() /* info in cmdfcb */
|
||||
{
|
||||
register short k;
|
||||
struct m_rt *mpr;
|
||||
register XADDR physaddr;
|
||||
BYTE tlen; /* length of cmd tail */
|
||||
register char *tp;
|
||||
|
||||
mpr = (struct m_rt *) bios(BGETMRT);
|
||||
|
||||
/* Set up the Load Parameter Block */
|
||||
/* Strictly speaking we should look at magic number to find out */
|
||||
/* which segment(s) the program needs. */
|
||||
|
||||
LPB.pgldaddr = mpr->m_reg[0].m_low;
|
||||
LPB.pgtop = mpr->m_reg[0].m_len;
|
||||
LPB.fcbaddr = map_adr((XADDR) cmdfcb, MYDATA);
|
||||
|
||||
/* Try loading the program. Print message and reboot if load fails */
|
||||
|
||||
if ((k = bdos(PGLOAD, map_adr((XADDR) &LPB, MYDATA))) != GOOD)
|
||||
{
|
||||
bdos(PRNTSTR, map_adr((XADDR) msgs[min(4, k)], MYDATA));
|
||||
bdos(WARMBOOT, 0L);
|
||||
}
|
||||
|
||||
/* Move command tail to basepage buffer; reset DMA address to that buffer. */
|
||||
/* Due to difficulty of adding structure member offset to something */
|
||||
/* which is not a structure pointer, we use a kludge to get physical */
|
||||
/* DMA buffer address: buffer is at last thing on basepage and has a */
|
||||
/* length of one sector. */
|
||||
|
||||
/* Compute length of tail, since CCP does not supply it */
|
||||
|
||||
for (tlen=0, tp=tail; *tp++ != NULL; tlen++) ;
|
||||
|
||||
/* Next expression written in strange way to overcome compiler bug */
|
||||
|
||||
physaddr = LPB.bpaddr - (SECLEN - sizeof (struct b_page));
|
||||
bdos(SETDMA, physaddr);
|
||||
cpy_out(&tlen, physaddr, 1L); /* tail length */
|
||||
cpy_out(tail, physaddr+1, (long) SECLEN-1); /* and cmd tail */
|
||||
|
||||
/* Fill base page fcb's */
|
||||
|
||||
fill_fcb(1, cmdfcb);
|
||||
physaddr -= sizeof (struct fcb); /* Another kludge */
|
||||
cpy_out(cmdfcb, physaddr, sizeof (struct fcb));
|
||||
|
||||
fill_fcb(2, cmdfcb);
|
||||
physaddr -= sizeof (struct fcb); /* Yet a third kludge */
|
||||
cpy_out(cmdfcb, physaddr, sizeof(struct fcb));
|
||||
|
||||
/* Now build a user stack which looks like:
|
||||
* ----------------- ^ ^
|
||||
* word/long | Base page addr| ^ High address ^
|
||||
* ----------------- ^ ^
|
||||
* word/long | 2 | <-- Stack pointer points here
|
||||
* -----------------
|
||||
*/
|
||||
if (LPB.flags & SEG) { /* Segmented */
|
||||
sstack.sbpgadr = LPB.bpaddr;
|
||||
sstack.stwo = LPB.pgldaddr + 2;
|
||||
cpy_out(&sstack, LPB.bpaddr - sizeof sstack, sizeof sstack);
|
||||
} else { /* Nonsegmented */
|
||||
stack.bpgaddr = (short) LPB.bpaddr;
|
||||
cpy_out(&stack, LPB.bpaddr - sizeof stack, sizeof stack);
|
||||
}
|
||||
|
||||
/* Finally, ready to transfer control. Must complete context first. */
|
||||
|
||||
if (LPB.flags & SEG) { /* Segmented */
|
||||
context.regs[14] = (short)(LPB.stackptr >> 16);
|
||||
context.regs[15] = (short)LPB.stackptr;
|
||||
context.PC = LPB.pgldaddr;
|
||||
context.FCW= 0x9800;
|
||||
} else { /* Nonsegmented!*/
|
||||
context.regs[15] = (short) LPB.stackptr;
|
||||
context.PC = map_adr(LPB.pgldaddr, TRUE_TPAPROG);
|
||||
context.FCW= 0x1800;
|
||||
}
|
||||
xfer(map_adr((XADDR) &context, MYDATA)); /* Go for it! */
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/********************************************************
|
||||
* *
|
||||
* P-CP/M header file *
|
||||
* Copyright (c) 1982 by Digital Research, Inc. *
|
||||
* Structure definitions for doing I/O in packets *
|
||||
* *
|
||||
* Modified for data in other address space *
|
||||
* *
|
||||
********************************************************/
|
||||
|
||||
/* May use this information structure instead of disk parameter header and
|
||||
disk parameter block in future, but for now it's unused
|
||||
struct dskinfo
|
||||
{
|
||||
UBYTE *dbuffp;
|
||||
UBYTE *csv;
|
||||
UBYTE *alv;
|
||||
UBYTE blksize;
|
||||
UBYTE didummy;
|
||||
UWORD dskmax;
|
||||
UWORD dirmax;
|
||||
UWORD chksize;
|
||||
};
|
||||
*/
|
||||
|
||||
struct iopb
|
||||
{
|
||||
UBYTE iofcn; /* function number, see defines below */
|
||||
UBYTE ioflags; /* used for login flag and write flag */
|
||||
UBYTE devtype; /* device type, see defines below */
|
||||
/* currently unused */
|
||||
UBYTE devnum; /* device number, or, devtype and devnum
|
||||
taken together form int device number */
|
||||
LONG devadr; /* item nmbr on device to start xfer at */
|
||||
/* note -- item is sector for disks, byte for char devs */
|
||||
UWORD xferlen; /* number items to transfer */
|
||||
XADDR xferadr; /* memory address to xfer to/from */
|
||||
struct dph *infop; /* pointer to disk parameter header */
|
||||
/* return parm for fcn 0, input for rest */
|
||||
};
|
||||
|
||||
|
||||
/* Definitions for iofcn, the function number */
|
||||
#define sel_info 0 /* select and return info on device */
|
||||
#define read 1
|
||||
#define write 2
|
||||
#define flush 3
|
||||
#define status 4 /* not currently used */
|
||||
|
||||
|
||||
/* Definitions for devtype, the device type */
|
||||
/* This field not currently used */
|
||||
#define console 0
|
||||
#define printer 1
|
||||
#define disk 2
|
||||
#define memory 3 /* gets TPA boundaries */
|
||||
#define redir 4 /* read/write IOByte */
|
||||
#define exc_vec 5 /* set exception vector */
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* C P / M C 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 ALCYON 1 /* NOT using Alcyon compiler*/
|
||||
/* but Zilog has similar bug*/
|
||||
|
||||
/*
|
||||
* Standard type definitions
|
||||
*/
|
||||
/***************************/
|
||||
#define BYTE char /* Signed byte */
|
||||
#define BOOLEAN char /* 2 valued (true/false) */
|
||||
#define WORD short /* Signed word (16 bits) */
|
||||
#define UWORD unsigned int /* unsigned word */
|
||||
#define LONG long /* signed long (32 bits) */
|
||||
#define ULONG unsigned 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 XADDR long /* Extended (SEG) address */
|
||||
/***************************/
|
||||
#ifdef ALCYON
|
||||
#define UBYTE char
|
||||
#define UBWORD(a) ((UWORD)a & 0xff)
|
||||
/* Unsigned byte to word cast */
|
||||
#else
|
||||
#define UBYTE unsigned char /* Unsigned byte */
|
||||
#define UBWORD(a) (UWORD)a
|
||||
#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 (BYTE *)0 /* Null pointer value */
|
||||
#define XNULL 0L /* Null XADDR */
|
||||
#define EOF (-1) /* EOF Value */
|
||||
#define TRUE (1)
|
||||
/* Function TRUE value */
|
||||
#define FALSE (0)
|
||||
/* Function FALSE value */
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* M A C R O S */
|
||||
/* ----------- */
|
||||
/* */
|
||||
/* Define some stuff as macros .... */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
#define abs(x) ((x) < 0 ? -(xIq
|
||||
This directory contains the source, object, and archived object ("libcpm.a")
|
||||
of the Non-segmented version of the Z8000 C runtime library. The segmented
|
||||
Reference in New Issue
Block a user