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

View File

@@ -0,0 +1,15 @@
********************************************************************
*
* CP/M abort function for C Run Time Library
*
* "abort" generates an Illegal Instruction Trap to recall DDT
* (if it is loaded).
*
*********************************************************************
illegal = $4AFC
.globl _abort
.text
_abort:
move.w 4(sp),d0
a: .dc.w illegal
bra.b a * For Wise Guys

View File

@@ -0,0 +1,44 @@
/*************************************************************************
*
* a c c e s s F u n c t i o n
* -----------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "access" returns 0 if access to a file is allowed, -1 o.w.
* Under CP/M, this just tests for existence.
*
* Calling sequence:
* ret = access(fname,mode)
* Where:
* ret = 0 if accessable, -1 o.w.
* fname -> file's name, NULL terminated string
* mode = test for read, write, exec, dir path access
* (ignored by CP/M)
*
**************************************************************************/
#include <portab.h>
#include <cpm.h>
#include <errno.h>
WORD access(fname,mode)
REG BYTE *fname;
REG WORD mode;
{
REG WORD ich;
REG WORD rval;
REG FD *fp;
rval = FAILURE;
if( (ich=allocc()) < 0)
return(FAILURE); /* can't access anything */
__chinit(ich);
fp = _getccb(ich);
if(__open(ich,fname,OPEN) == SUCCESS )
{
rval = SUCCESS;
__BDOS(CLOSE,&(fp->fcb));
}
freec(ich);
if( rval == SUCCESS )
return(SUCCESS);
else RETERR(FAILURE,ENOENT);
}

View File

@@ -0,0 +1,20 @@
.globl _ldiv
.globl _aldiv
.globl aldiv
.text
_aldiv:
aldiv:
~~aldiv:
~l2=12
~al1=8
link R14,#-2
move.l 12(R14),-(sp)
move.l 8(R14),R8
move.l (R8),-(sp)
jsr _ldiv
cmpm.l (sp)+,(sp)+
move.l 8(R14),R9
move.l R0,(R9)
L1:
unlk R14
rts

View File

@@ -0,0 +1,49 @@
/*****************************************************************************
*
* A L L O C C / F R E E C R O U T I N E S
* ---------------------------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* Routines "allocc" and "freec" are used to allocate / deallocate a
* channel number so that the user may do I/O directly without the OTS
* getting in the way.
* Note that this scheme preserves compatibility with OS's that really
* truly use channels, and allows users to inform the C Run Time Library
* routines that they are using the channel.
* It's not important to use these routines under CP/M, since CP/M
* allows you to have as many FCBs as you wish.
*
* Calling Sequence:
*
* i = allocc();
* freec(i);
*
*****************************************************************************/
#include <portab.h> /* Include std definitions */
#include <cpm.h> /* Also CP/M ones */
#include <errno.h> /* for error returns */
LONG _chvec ={0}; /* Allocate storage */
WORD allocc() /****************************/
{ /* */
REG WORD i; /* Define 2 temporaries */
REG LONG j; /* */
/* */
j = 1; /* Start with channel 0 */
for(i=0;i<MAXCCBS;i++) /* Look at the bits */
{ /* */
if((j & _chvec) == 0) /* If 0, then channel free */
{ /* */
_chvec |= j; /* set allocated bit */
return(i); /* and return the channel # */
} /* */
j = j << 1; /* Up to next bit */
} /* End FOR loop */
RETERR(FAILURE,EMFILE); /* All channels in use! */
} /****************************/
WORD freec(ch) /****************************/
REG WORD ch; /* Channel number to free */
{ /* */
_chvec &= ~(1 << ch); /* Clear appropriate bit */
return(SUCCESS); /* Return OK */
} /****************************/

View File

@@ -0,0 +1,19 @@
.text
.globl almul
.globl lmul
*
* / this routine multiplies together two 32 bit signed long integers.
* / the first arg is a pointer to the long, which is multiplied by the
* / second arg, with the result being stored at the firstarg.
* / lmul.s does the meat of the work
*
almul:
move.l A5,-(sp)
move.l 8(sp),A5
move.l 12(sp),-(sp)
move.l (A5),-(sp)
jsr lmul
add #8,sp
move.l R0,(A5)
move.l (sp)+,A5
rts

View File

@@ -0,0 +1,22 @@
.globl _ldiv
.globl _ldivr
.comm _ldivr,4
.globl _alrem
.globl alrem
.text
_alrem:
alrem:
~~alrem:
~l2=12
~al1=8
link R14,#-2
move.l 12(R14),-(sp)
move.l 8(R14),R8
move.l (R8),-(sp)
jsr _ldiv
cmpm.l (sp)+,(sp)+
move.l _ldivr,R0
move.l 8(R14),R9
move.l R0,(R9)
unlk R14
rts

View File

@@ -0,0 +1,26 @@
/* atoi - convert decimal number in ascii to integer */
#include <portab.h>
#include <ctype.h>
WORD atoi(s)
REG BYTE *s;
{
REG WORD val;
REG WORD isneg;
val = 0;
isneg = FALSE;
while( isspace(*s) )
s++;
if( *s == '+' )
s++;
else if( *s == '-' ) {
s++;
isneg++;
}
while( *s >= '0' && *s <= '9' )
val = 10 * val + ( *s++ - '0' );
if( isneg )
val = -val;
return( val );
}

View File

@@ -0,0 +1,26 @@
/* atol - convert decimal number in ascii to long integer */
#include <portab.h>
#include <ctype.h>
LONG atol(s)
REG BYTE *s;
{
REG LONG val;
REG WORD isneg;
val = 0L;
isneg = FALSE;
while( isspace(*s) )
s++;
if( *s == '+' )
s++;
else if( *s == '-' ) {
s++;
isneg++;
}
while( *s >= '0' && *s <= '9' )
val = 10 * val + ( *s++ - '0' );
if( isneg )
val = -val;
return( val );
}

View File

@@ -0,0 +1,39 @@
/****************************************************************************/
/* */
/* 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. */
/* */
/* "cpm.h" MUST be '#include'd before this file */
/* */
/****************************************************************************/
struct b_page
{
BYTE *ltpa; /* Low TPA address */
BYTE *htpa; /* High TPA address */
BYTE *lcode; /* Start address of code seg*/
LONG codelen; /* Code segment length */
BYTE *ldata; /* Start address of data seg*/
LONG datalen; /* Data segment length */
BYTE *lbss; /* Start address of bss seg */
LONG bsslen; /* Bss segment length */
LONG freelen; /* Free segment length */
BYTE resvd1[20]; /* Reserved area */
struct fcb fcb2; /* Second basepage FCB */
struct fcb fcb1; /* First basepage FCB */
BYTE buff[128]; /* Default DMA buffer, */
/* command line tail */
};
extern struct b_page *_base;

View File

@@ -0,0 +1,367 @@
/****************************************************************************/
/* */
/* B D O S . H */
/* ----------- */
/* */
/* Copyright (c) 1982, Zilog Incorporated */
/* */
/* Macros defining the direct BDOS calls used by the standard CP/M */
/* utilities (ED, PIP, STAT, SET, SHOW.) Some necessary data */
/* data structures are also defined. */
/* */
/* All macros return a long value, even when the BDOS function they */
/* call does produce a return parameter. */
/* */
/* This header file can be used applications which do not require */
/* to use the C standard I/O library functions. For applications */
/* which require the library, but which wish to make use of the */
/* additional information in this file, cpm.h should be included in */
/* the source ahead of this file. The compiler flags multiple */
/* definition errors if this ordering is not observed. */
/* */
/* portab.h must always be included ahead of this file. */
/* */
/****************************************************************************/
extern long __BDOS(); /* BDOS entry point */
#define XADDR long /* 32-bit address data type */
/****************************************************************************/
/* The following BDOS calls are defined in cpm.h. Define them only if they */
/* are not defined already. */
/****************************************************************************/
#ifndef EXIT /* Find out where we stand */
/* Define if necessary */
#define EXIT 0 /* Exit to BDOS */
#define CONOUT 2 /* Direct console output */
#define LSTOUT 5 /* Direct list device output*/
#define CONIO 6 /* Direct console I/O */
#define CONBUF 10 /* Read console buffer */
#define OPEN 15 /* OPEN a disk file */
#define CLOSE 16 /* Close a disk file */
#define DELETE 19 /* Delete a disk file */
#define CREATE 22 /* Create a disk file */
#define SETDMA 26 /* Set DMA address */
#define B_READ 33 /* Read Random record */
#define B_WRITE 34 /* Write Random record */
#define FILSIZ 35 /* Compute File Size */
#define SETMSC 44 /* Set Multi-Sector Count */
#endif
/****************************************************************************/
/* The following BDOS calls are not defined in cpm.h */
/****************************************************************************/
#define CONIN 1 /* Single char I/P with echo*/
#define READER 3 /* Paper tape input */
#define PUNCH 4 /* Paper tape output */
#define GET_IOB 7 /* Get I/O byte */
#define SET_IOB 8 /* Set I/O byte */
#define PRINT 9 /* Print $-terminated line */
#define CONSTAT 11 /* Check if I/P char waiting*/
#define VERSION 12 /* Return version number */
#define RS_DISK 13 /* Reset disk system */
#define SEL_DISK 14 /* Select disk */
#define SRCH_1ST 17 /* Search 1st filename match*/
#define SRCH_NEXT 18 /* Search next match */
#define S_READ 20 /* Sequential read from file*/
#define S_WRITE 21 /* Sequential write to file */
#define RENAME 23 /* Rename a file */
#define RET_LOGIN 24 /* Return login vector */
#define RET_CDISK 25 /* Return current disk */
#define GET_ALLOC 27 /* Get allocation vector */
#define WR_PROTD 28 /* Write protect disk */
#define GET_RO 29 /* Get read-only vector */
#define SET_ATT 30 /* Set file attributes */
#define GET_DPB 31 /* Get disk parameters */
#define GSET_UCODE 32 /* Get/set user code */
#define SET_RAND 36 /* Set random record */
#define RS_DRIVE 37 /* Reset disk specified drv */
/* 38, 39 not used */
#define B_WRZF 40 /* Write random, zero fill */
/* 41 - 43 not used */
#define RET_ERRORS 45 /* Set error return mode */
#define GET_DFS 46 /* Get free disk space */
#define CHAIN 47 /* Chain to program via CCP */
#define FLUSH 48 /* Flush buffers to disk */
#define GSET_SCB 49 /* Get/set system control bk*/
#define BIOS_CALL 50 /* Direct call to BIOS */
/* 51 - 58 not used */
#define PROG_LOAD 59 /* Program load */
/* 60 unused */
#define SET_EXV 61 /* Set exception vector */
#define SET_SUP 62 /* Set supervisor state */
#define SET_LABEL 100 /* Set directory label */
#define GET_LABEL 101 /* Get directory label */
#define GET_XFCB 102 /* Get extended FCB */
#define SET_XFCB 103 /* Set extended FCB */
#define COND_LST 161 /* Conditionally attach LST:*/
/****************************************************************************/
/* The macros themselves... */
/****************************************************************************/
#define _conin() (__BDOS(CONIN, (long) 0))
#define _conout(a) (__BDOS(CONOUT, (long) (a)))
#define _reader() (__BDOS(READER, (long) 0))
#define _punch(a) (__BDOS(PUNCH, (long) (a)))
#define _lstout(a) (__BDOS(LSTOUT, (long) (a)))
#define _conio(a) (__BDOS(CONIO, (long) (a)))
#define _get_iob() (__BDOS(GET_IOB, (long) 0))
#define _set_iob(a) (__BDOS(SET_IOB, (long) (a)))
#define _print(a) (__BDOS(PRINT, (long) (a)))
#define _conbuf(a) (__BDOS(CONBUF, (long) (a)))
#define _constat() (__BDOS(CONSTAT, (long) 0))
#define _version() (__BDOS(VERSION, (long) 0))
#define _rs_disk(a) (__BDOS(RS_DISK, (long) (a)))
#define _sel_disk(a) (__BDOS(SEL_DISK, (long) (a)))
#define _open(a) (__BDOS(OPEN, (long) (a)))
#define _close(a) (__BDOS(CLOSE, (long) (a)))
#define _srch_1st(a) (__BDOS(SRCH_1ST, (long) (a)))
#define _srch_next() (__BDOS(SRCH_NEXT, (long) 0))
#define _delete(a) (__BDOS(DELETE, (long) (a)))
#define _s_read(a) (__BDOS(S_READ, (long) (a)))
#define _s_write(a) (__BDOS(S_WRITE, (long) (a)))
#define _create(a) (__BDOS(CREATE, (long) (a)))
#define _rename(a) (__BDOS(RENAME, (long) (a)))
#define _ret_login() (__BDOS(RET_LOGIN, (long) 0))
#define _ret_cdisk() (__BDOS(RET_CDISK, (long) 0))
#define _setdma(a) (__BDOS(SETDMA, (long) (a)))
#define _get_alloc() (__BDOS(GET_ALLOC, (long) 0))
#define _wr_protd() (__BDOS(WR_PROTD, (long) 0))
#define _get_ro() (__BDOS(GET_RO, (long) 0))
#define _set_att(a) (__BDOS(SET_ATT, (long) (a)))
/* _get_dpb has parameter in*/
/* some implementations */
/* of CP/M but not others */
/* This macro suitable only */
/* for former */
#define _get_dpb(a) (__BDOS(GET_DPB, (long) (a)))
/* This one handles latter */
#define _get_dpa() (__BDOS(GET_DPB, (long) 0))
#define _gset_ucode(a) (__BDOS(GSET_UCODE, (long) (a)))
#define _b_read(a) (__BDOS(B_READ, (long) (a)))
#define _b_write(a) (__BDOS(B_WRITE, (long) (a)))
#define _filsiz(a) (__BDOS(FILSIZ, (long) (a)))
#define _set_rand(a) (__BDOS(SET_RAND, (long) (a)))
#define _rs_drive(a) (__BDOS(RS_DRIVE, (long) (a)))
#define _b_wrzf(a) (__BDOS(B_WRZF, (long) (a)))
#define _setmsc(a) (__BDOS(SETMSC, (long) (a)))
#define _ret_errors(a) (__BDOS(RET_ERRORS, (long) (a)))
#define _get_dfs(a) (__BDOS(GET_DFS, (long) (a)))
#define _chain() (__BDOS(CHAIN, (long) 0))
#define _flush() (__BDOS(FLUSH, (long) 0))
#define _gset_scb(a) (__BDOS(GSET_SCB, (long) (a)))
#define _bios_call(a) (__BDOS(BIOS_CALL, (long) (a)))
#define _prog_load(a) (__BDOS(PROG_LOAD, (long) (a)))
#define _set_exv(a) (__BDOS(SET_EXV, (long) (a)))
#define _set_sup(a) (__BDOS(SET_SUP, (long) 0))
#define _get_label(a) (__BDOS(GET_LABEL, (long) (a)))
#define _set_label(a) (__BDOS(SET_LABEL, (long) (a)))
#define _get_xfcb(a) (__BDOS(GET_XFCB, (long) (a)))
#define _set_xfcb(a) (__BDOS(SET_XFCB, (long) (a)))
#define _cond_lst() (__BDOS(COND_LST, (long) 0))
/****************************************************************************/
/* BIOS calls, for use in conjunction with BDOS call 50 & struct bios_parms */
/****************************************************************************/
#define _INIT 0 /* Cold start */
#define _WARM 1 /* Warm start */
#define _CONST 2 /* Console status */
#define _CONIN 3 /* Read console character */
#define _CONOUT 4 /* Write console character */
#define _LIST 5 /* Write listing character */
#define _PUNCH 6 /* Write punch character */
#define _READER 7 /* Read tape character */
#define _HOME 8 /* Move to track 0 */
#define _SELDSK 9 /* Select disk drive */
#define _SETTRK 10 /* Set track number */
#define _SETSEC 11 /* Set sector number */
#define _SETDMA 12 /* Set DMA address */
#define _READ 13 /* Read selected sector */
#define _WRITE 14 /* Write selected sector */
#define _LISTST 15 /* Return list status */
#define _GETMRT 16 /* Get memory region table */
/* address */
#define _GETIOB 17 /* Get IOBYTE value */
#define _SETIOB 18 /* Set IOBYTE value */
#define _FLUSH 19 /* Flush buffers */
#define _SETEXC 20 /* Set exception vector */
/****************************************************************************/
/* FCB structure is defined in cpm.h. Define it here only if it is not */
/* defined already. Declare some useful values at the same time. */
/****************************************************************************/
#ifndef SECSIZ /* Not already declared? */
struct fcbtab /* File control block */
{ /* */
BYTE drive; /* Disk drive field */
BYTE fname[8]; /* File name */
BYTE ftype[3]; /* File type */
BYTE extent; /* Current extent number */
BYTE s1,s2; /* "system reserved" */
BYTE reccnt; /* Record counter */
BYTE resvd[16]; /* More "system reserved" */
LONG record; /* Note -- we overlap the */
/* current record field to */
/* make this useful. */
};
#define fcb fcbtab /* A useful synonym */
#define SECSIZ 128 /* size of CP/M sector */
#define _MAXSXFR 1 /* max # sectors xferrable */
#define _MAXSHFT 12 /* shift right BDOS rtn val */
#endif
/****************************************************************************/
/* Data structures not defined in cpm.h */
/****************************************************************************/
struct dpbs /* Disk parameter block */
{
UWORD spt; /* Sectors per track */
BYTE bls; /* Block shift factor */
BYTE bms; /* Block mask */
BYTE exm; /* Extent mark */
/* BYTE filler; *** Pad to align words ***/
UWORD mxa; /* Maximum allocation (blks)*/
UWORD dmx; /* Max directory entries */
UWORD dbl; /* Directory alloc. map */
UWORD cks; /* Directory checksum */
UWORD ofs; /* Track offset from track 0*/
};
struct bios_parm /* BIOS parameters for BDOS */
{ /* call 50 */
UWORD req; /* BIOS request code */
LONG p1; /* First parameter */
LONG p2; /* Second parameter */
};
struct scbs /* System control block */
{
BYTE resvd_1[6]; /* Reserved for system use */
BYTE u_flags[4]; /* Utility flags */
BYTE d_flags[4]; /* Display flags */
BYTE clp_flags[2]; /* Command Line Proc flags */
UWORD p_error; /* Program error return code*/
BYTE resvd_2[8]; /* Reserved for system use */
BYTE con_w; /* Console width */
BYTE con_c; /* Console column */
BYTE con_l; /* Console page length */
BYTE resvd_3[5]; /* Reserved for system use */
UWORD conin_r; /* CONIN redirection flag */
UWORD conout_r; /* CONOUT redirection flag */
UWORD auxin_r; /* AUXIN redirection flag */
UWORD auxout_r; /* AUXOUT redirection flag */
UWORD lstout_r; /* LSTOUT redirection flag */
BYTE resvd_4[2]; /* Reserved for system use */
BOOLEAN ctl_h_a; /* Backspace active */
BOOLEAN rubout_a; /* Rubout active */
BYTE resvd_5[2]; /* Reserved for system use */
UWORD c_xlate; /* Console translate func. */
UWORD con_m; /* Console mode (raw/cooked)*/
UWORD buff_a; /* 128 byte buffer available*/
BYTE o_delim; /* Output delimiter */
BOOLEAN lo_flag; /* List output flag */
BYTE resvd_6[2]; /* Reserved for system use */
UWORD d_m_a; /* Current DMA address */
BYTE disk_no; /* Current disk */
BYTE bdos_info[2]; /* BDOS variable info */
BYTE resvd_7[3]; /* Reserved for system use */
BYTE user_no; /* Current user number */
BYTE resvd_8[6]; /* Reserved for system use */
BYTE bdos_mode; /* BDOS error mode */
BYTE c_chain[4]; /* Current search chain */
BYTE tmp_drv; /* Drive for temporary files*/
BYTE resvd_9[7]; /* Reserved for system use */
BYTE date_s[5]; /* Date stamp */
BYTE error_jmp[3]; /* Error jump */
UWORD cmb_a; /* Common memory base addr */
UWORD bdos_ent; /* BDOS entry point */
};
struct scbpb /* SCB parameter block */
{
BYTE off; /* Index to data in SCB */
BYTE op; /* Operation: 0xff Set byte */
/* 0xfe Set word */
/* else Get word */
UWORD val; /* Byte/word value to be set*/
};
#define SET_BYTE 0xff
#define SET_WORD 0xfe
#define GET 0
/****************************************************************************/
/* HILO must be defined for the Z8000. Undefine it first, in case cpm.h */
/* has already defined it. The tagless structures defining byte ordering */
/* which are declared in cpm.h are not redeclared here (the use of members */
/* of tagless structures to define offsets is an obsolete feature of the C */
/* language.) */
/****************************************************************************/
#undef HILO
#define HILO

View File

@@ -0,0 +1,21 @@
.globl _sw
_sw:
.text
tst.l d5
beq ok
move.l #-1,(sp) * Destroy the evidence
divs #$0,d5
ok: rts
*********************************************************
* *
* Copyright Notice Module *
* *
*********************************************************
.data
___cpyrt: .dc.b 'CP/M-68K(tm), Version 1.2, '
.dc.b 'Copyright (c) 1983, Digital Research '
serial: .dc.b 'XXXX-0000-654321'
.dc.w 0
.end

View File

@@ -0,0 +1,88 @@
/****************************************************************************/
/* */
/* _ b l k i o F u n c t i o n */
/* ----------------------------- */
/* Copyright 1982 by Digital Research Inc. All rights reserved. */
/* */
/* The _blkio function is used to read / write a set of contiguous */
/* sectors in an open file. */
/* Note: it will use CP/M function 44 (Set Multi-Sector Count) if */
/* MAXSXFR > 1. This is for BDOS version 3.0 or greater. */
/* */
/* Calling Sequence: */
/* */
/* ret = _blkio(ccb,sector,buffer,count,bdosfunc); */
/* */
/* Where: */
/* ret = sectors actually read/written */
/* ccb -> the open file channel control block */
/* sector = The desired starting sector number */
/* buffer = The memory address to begin transfer */
/* count = the number of sectors to read/write */
/* bdosfunc= The BDOS function number (B_READ / B_WRITE) */
/* */
/* */
/****************************************************************************/
#include <portab.h>
#include <cpm.h>
LONG
_blkio(ccb,sector,buffer,count,bdosfunc)
/****************************/
REG FD *ccb; /* open file pointer */
REG LONG sector; /* Sector number */
REG BYTE *buffer; /* User's buffer area */
REG LONG count; /* # of sectors to do */
REG int bdosfunc; /* BDOS function to use */
/****************************/
{ /****************************/
REG WORD nsecs; /* # secs to xfer each time */
REG LONG seccnt; /* # sectors processed */
REG WORD xuser; /* old user number */
/****************************/
seccnt = 0; /* Zero count initally */
xuser = __BDOS(USER,0xFFL); /* Get current user # */
if(xuser != ccb->user) /* File have a different 1? */
__BDOS(USER,(LONG)ccb->user); /* Yes, set to that */
/* */
while (count > 0) /* Until all sectors xferred*/
{ /* */
__BDOS(SETDMA,buffer); /* Set new DMA address */
ccb->fcb.record = sector; /* Set new record number */
#if _MAXSXFR > 1 /* Can we xfer multi-secs? */
nsecs = min(_MAXSXFR,count); /* Ifso, xfer many */
__BDOS(SETMSC,nsecs); /* Always set before r/w */
#else /* if possible */
nsecs = 1; /* o.w. xfer singly */
#endif /* */
if(__BDOS(bdosfunc,&(ccb->fcb)) /* do the read */
!= 0) /* Check for errors */
{ /****************************/
/*** WE SHOULD CHECK FOR SPARSE FILES HERE... ***/
if(nsecs>1) /* were we trying multi-sec?*/
nsecs = __cpmrv >>_MAXSHFT; /* adjust nsecs read ifso */
else nsecs=0; /* ow. assume 0 secs read */
return(seccnt+nsecs); /* Return nfg */
} /****************************/
/* */
sector += nsecs; /* Increment sector number */
count -= nsecs; /* Down count */
seccnt += nsecs; /* Bump sector count */
buffer += nsecs*SECSIZ; /* Increment address */
} /****************************/
if(ccb->user != xuser) /* Different user #'s?? */
__BDOS(USER,(LONG)xuser); /* Yes, reset to original */
return(seccnt); /* All is OK */
} /****************************/

View File

@@ -0,0 +1,8 @@
cp68 $1.c $1.i
c068 $1.i $1.ic $1.st
era $1.i
era $1.st
c168 $1.ic $1.s -L
era $1.ic
as68 -l -u $1.s
era $1.s

View File

@@ -0,0 +1,30 @@
/********************************************************************
*
* calloc.c - memory allocator for sets of elements
*
* BYTE *calloc(nelem,sizelem)
* WORD nelem, sizelem
*
* Returns a pointer to a region of (zero filled) memory large
* enough to hold 'nelem' items each of size 'sizelem'.
* Returns NULL if not enough memory.
*
*********************************************************************/
#include <portab.h>
#include <cpm.h>
BYTE *calloc(ne,se)
REG WORD ne, /* number of elements */
se; /* size of element */
{
REG WORD rs; /* region size to be allocated */
REG BYTE *rp; /* pointer to region */
BYTE *malloc();
if( (rp=malloc(rs =(se*ne))) == NULL)
return(NULL);
for( ; rs > 0; )
rp[--rs]=ZERO;
return(rp);
}

View File

@@ -0,0 +1,53 @@
/*****************************************************************************
*
* C C B I N I T I A L I Z A T I O N
* -----------------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* Routine "_chinit" is called from the run-time initialization to clear
* out all the CCB storage.
* Calling sequence:
* _chinit();
*
* Routine "__chinit(fd)" is called from other low-level routines
* for single channel initialization.
* Calling sequence:
* __chinit(fd)
* where: fd = file descriptor #
*
*****************************************************************************/
#include <portab.h> /* Include std definitions */
#include <cpm.h> /* Include CP/M definitions */
FD _fds[MAXCCBS]; /* Allocate CCB storage */
_chinit() /****************************/
{ /* */
REG WORD i; /* Index */
for(i=0;i<MAXCCBS;i++) /* For all channels */
__chinit(i); /* Init fds(i); */
} /****************************/
/*****************************************************************************
* The __chinit routine initializes only 1 channel.
*****************************************************************************/
__chinit(i)
{ /****************************/
REG FD *ch; /* -> CCB */
REG BYTE *p; /* Byte pointer temporary */
ch = _getccb(i); /* convert fd to CCB */
ch -> chan = i; /* Load channel byte */
ch -> flags = 0; /* clear flag word */
ch -> sector = -1; /* Set no sector in buff */
ch -> offset = 0; /* Clear file offset word */
ch -> hiwater = 0; /* Init hiwater mark */
ch -> fcb.drive = 0; /* Init drive field of fcb */
p = &ch->fcb.fname[0]; /* Set to file var */
while (p< &ch->fcb.ftype[3]) /* Init file name fields */
*p++ = ' '; /* To spaces */
while (p < &ch->fcb.record) /* Init rest of fcb */
*p++ = 0; /* To zeros */
} /****************************/

View File

@@ -0,0 +1,35 @@
/*****************************************************************************
*
* C H A N N E L N U M B E R V A L I D A T I O N
* -------------------------------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* This routine is used to validate a channel number and return the
* pointer to the ccb area. The channel must be in range and open.
*
* Calling Sequence:
*
* ccbptr = _chkc(ch);
*
* Where:
*
* ch Is the channel number
* ccbptr Is the returned ccb address
*
*****************************************************************************/
#include <portab.h> /* Include std definitions */
#include <cpm.h> /* and CP/M definitions */
#include <errno.h>
FD *_chkc(ch) /****************************/
REG UWORD ch; /* Facilitate error check */
{ /* */
REG FD *xcb; /* -> CCB */
/****************************/
if(ch >= MAXCCBS) /* Is channel in range? */
RETERR(NULL,EBADF); /* No, quit now. */
/* */
xcb = _getccb(ch); /* xcb -> ccb for channel */
if((xcb->flags & OPENED) == 0) /* Is channel OPEN? */
RETERR(NULL,EBADF); /* Noooooooo!! */
return(xcb); /* Else, return pointer */
} /****************************/

View File

@@ -0,0 +1,8 @@
/* chmod - change mode: NOP under CP/M */
#include <portab.h>
WORD chmod(name,mode)
BYTE *name;
WORD mode;
{
return(access(name,mode));
}

View File

@@ -0,0 +1,9 @@
/* chown - change owner: like access() under CP/M */
#include <portab.h>
WORD chown(name,owner,group)
BYTE *name;
WORD owner;
WORD group;
{
return(access(name,0));
}

View File

@@ -0,0 +1,20 @@
/**********************************************************************
*
* _ c l e a n u p F u n c t i o n
* ---------------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "_cleanup" closes all buffered files
*
* Calling sequence:
* _cleanup()
*
***************************************************************************/
#include <stdio.h>
_cleanup()
{
REG WORD ii;
for( ii=0; ii<MAXFILES; ii++ )
fclose(&_iob[ii]);
}

View File

@@ -0,0 +1 @@
lo68 -r -unofloat -o $1.68k s.o $1.o $2.o $3.o $4.o $5.o $6.o $7.o $8.o $9.o clib

View File

@@ -0,0 +1,56 @@
/****************************************************************************/
/* */
/* C l o s e F u n c t i o n */
/* --------------------------- */
/* Copyright 1982 by Digital Research Inc. All rights reserved. */
/* */
/* The close function is used to terminate access to a file / device. */
/* */
/* Calling Sequence: */
/* */
/* ret = close(fd); */
/* */
/* Where "fd" is an open file descriptor to be CLOSEd. */
/* */
/****************************************************************************/
#include <portab.h>
#include <cpm.h>
#include <errno.h>
/****************************/
EXTERN BYTE __xeof; /* End of file for ASCII */
WORD close(fd) /****************************/
/* */
WORD fd; /* File descriptor to close */
/* */
{ /****************************/
EXTERN FD *_chkc(); /* fd -> fp conversion MGL */
REG FD *fp; /* file pointer Temporary */
/* */
if((fp=_chkc(fd)) == NULL) /* File Open? */
return(FAILURE); /* no, quit */
/* */
if ((fp->flags & (ISTTY|ISLPT)) != 0) /* Character device? */
{ /* */
__chinit(fd); /* Clean the channel again */
freec(fd); /* Release the channel */
return(SUCCESS); /* All done */
} /****************************/
if((fp->flags & ISASCII) != 0 && /* ASCII file? */
(fp->flags & ISREAD) == 0) /* and not read-only */
{ /* */
if( fp->offset < fp->hiwater ) /* Have we been seeking? */
lseek(fd,0L,2); /* Seek to EOF ifso */
write(fd,&__xeof,1); /* Write a ^Z character */
} /****************************/
if((fp->flags & DIRTY) != 0) /* Buffer dirty? */
{ /* */
if(_blkio(fp,fp->sector,fp->buffer, /* Write out */
1L,B_WRITE) != 1) /* buffer */
RETERR(FAILURE,EIO); /* can't */
} /****************************/
if(__BDOS(CLOSE,&(fp->fcb))==0xFF) /* Close the fcb */
RETERR(FAILURE,EIO); /* */
__chinit(fd); /* Release the space */
freec(fd); /* Release the channel */
return(SUCCESS); /* Done */
} /****************************/

View File

@@ -0,0 +1,179 @@
/****************************************************************************/
/* */
/* C P M . H */
/* --------- */
/* Copyright 1982 by Digital Research Inc. All rights reserved. */
/* */
/* Edits: */
/* */
/* 25-June-83 sw Add user number to file "fd" structure. */
/* */
/* This file contains CP/M specific definitions for the CP/M */
/* C Run Time Library. */
/* This file is intended only for inclusion with those functions */
/* dealing directly with the BDOS, as well as any function which */
/* has hardware dependent code (byte storage order, for instance). */
/* */
/* <portab.h> must be included BEFORE this file. */
/* */
/****************************************************************************/
/*
* CP/M FCB definition
*/
struct fcbtab /****************************/
{ /* */
BYTE drive; /* Disk drive field */
BYTE fname[8]; /* File name */
BYTE ftype[3]; /* File type */
BYTE extent; /* Current extent number */
BYTE s1,s2; /* "system reserved" */
BYTE reccnt; /* Record counter */
BYTE resvd[16]; /* More "system reserved" */
LONG record; /* Note -- we overlap the */
/* current record field to */
/* make this useful. */
}; /****************************/
#define SECSIZ 128 /* size of CP/M sector */
#define _MAXSXFR 1 /* max # sectors xferrable */
#define _MAXSHFT 12 /* shift right BDOS rtn val */
/* to obtain nsecs on err */
/****************************/
/****************************************************************************/
/* */
/* Channel Control Block (CCB) */
/* */
/* One CCB is allocated (statically) for each of the 16 possible open */
/* files under C (including STDIN, STDOUT, STDERR). Permanent data */
/* regarding the channel is kept here. */
/* */
/* */
/****************************************************************************/
struct ccb /************************************/
{ /* */
WORD flags; /*sw Flags byte */
BYTE user; /*sw User # */
BYTE chan; /* Channel number being used */
LONG offset; /* File offset word (bytes) */
LONG sector; /* Sector currently in buffer */
LONG hiwater; /* High water mark */
struct fcbtab fcb; /* File FCB (may have TTY info)*/
BYTE buffer[SECSIZ]; /* Read/write buffer */
}; /************************************/
#define MAXCCBS 16 /* Maximum # CC Blocks */
extern struct ccb _fds[MAXCCBS]; /* Declare storage */
#define FD struct ccb /* FD Type definition */
/************************************/
/* Flags word bit definitions */
/************************************/
#define OPENED 0x01 /* Channel is OPEN */
#define ISTTY 0x02 /* Channel open to TTT */
#define ISLPT 0x04 /* Channel open to LPT */
#define ISREAD 0x08 /* Channel open readonly */
#define ISASCII 0x10 /* ASCII file attached */
#define ATEOF 0x20 /* End of file encountered */
#define DIRTY 0x40 /* Buffer needs writing */
#define ISSPTTY 0x80 /* Special tty info */
#define ISAUX 0x100 /*sw Auxiliary device */
/************************************/
#define READ 0 /* Read mode parameter for open */
#define WRITE 1 /* Write mode */
/* CCB manipulation macros *************************************/
#define _getccb(i) (&_fds[i]) /* Get CCB addr */
/* Error handling *************************************/
EXTERN WORD errno; /* error place for assigning */
EXTERN WORD __cpmrv; /* the last BDOS return value */
EXTERN WORD _errcpm; /* place to save __cpmrv */
#define RETERR(val,err) {errno=(err);_errcpm=__cpmrv;return(val);}
/************************************/
/****************************************************************************/
/* */
/* B D O S F u n c t i o n D e f i n i t i o n s */
/* ------------------------------------------------- */
/* */
/* Following are BDOS function definitions used by the C runtime */
/* library. */
/* */
/****************************************************************************/
/****************************/
#define EXIT 0 /* Exit to BDOS */
#define CONOUT 2 /* Direct console output */
#define LSTOUT 5 /* Direct list device output*/
#define CONIO 6 /* Direct console I/O */
#define CONBUF 10 /* Read console buffer */
#define OPEN 15 /* OPEN a disk file */
#define CLOSE 16 /* Close a disk file */
#define DELETE 19 /* Delete a disk file */
#define CREATE 22 /* Create a disk file */
#define SETDMA 26 /* Set DMA address */
#define USER 32 /*sw Get / set user number */
#define B_READ 33 /* Read Random record */
#define B_WRITE 34 /* Write Random record */
#define FILSIZ 35 /* Compute File Size */
#define SETMSC 44 /* Set Multi-Sector Count */
#define SETVEC 61 /* Set exception vector */
/****************************/
/****************************************************************************/
/* Other CP/M definitions */
/****************************************************************************/
#define TERM "CON:" /* Console file name */
#define LIST "LST:" /* List device file name */
#define EOFCHAR 0x1a /* End of file character-^Z */
/****************************/
/****************************************************************************/
/* Hardware dependencies */
/****************************************************************************/
#define HILO /* used when bytes stored */
/* Hi,Lo */
/****************************/
#ifdef HILO /* Hi/Lo storage used in */
struct { /* 68K */
BYTE lbhihi; /* Use this for accessing */
BYTE lbhilo; /* ordered bytes in 32 bit*/
BYTE lblohi; /* LONG qtys. */
BYTE lblolo; /* */
}; /* */
struct { /* Use this for accessing */
WORD lwhi; /* ordered words in 32 bit*/
WORD lwlo; /* LONG qtys. */
}; /* */
#else /****************************/
struct { /* Lo/Hi storage use on */
BYTE lblolo; /* PDP-11, VAX, 8086,... */
BYTE lblohi; /* */
BYTE lbhilo; /* */
BYTE lbhihi; /* */
}; /* */
struct { /* */
WORD lwlo; /* */
WORD lwhi; /* */
}; /* */
#endif /****************************/
/*************************** end of cpm.h ***********************************/

View File

@@ -0,0 +1,79 @@
/****************************************************************************
*
* C F I L E C R E A T E R O U T I N E
* -----------------------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* The "creat" routine opens a new "C" file and returns a file id.
* Comes in 3 flavors: ascii (CP/M text files), binary, and default
* (currently ascii).
*
* Calling Sequence:
* fid = creat(fname,prot)
* fid = creata(fname,prot)
* fid = creatb(fname,prot)
* fid = _creat(fname,prot,type);
*
* Where:
*
* fname is the address of a null terminated file name.
* prot is the UNIX file protection
* type is 0 for ASCII, 1 for BINARY
*
*****************************************************************************/
#include <portab.h> /* Include std definitions */
#include <cpm.h> /* Include CP/M definitions */
#include <errno.h> /* Error codes */
EXTERN BYTE __tname[]; /* Terminal name */
EXTERN BYTE __lname[]; /* List device name */
/****************************/
WORD creat (f,p)
BYTE *f; WORD p;
{ return(_creat(f,p,0)); } /* default to ascii */
WORD creata (f,p)
BYTE *f; WORD p;
{ return(_creat(f,p,0)); } /* ascii file open */
WORD creatb (f,p)
BYTE *f; WORD p;
{ return(_creat(f,p,1)); } /* binary file open */
WORD _creat (fname,prot,type) /****************************/
BYTE *fname; /* -> File name */
WORD prot; /* Open mode */
WORD type; /* ASCII/BINARY flag */
{ /****************************/
REG WORD ich; /* Channel number for open */
WORD allocc(); /* gets a channel */
REG FD *ch; /* -> CCB for channel */
/* */
if((ich = allocc()) < 0) /* Allocate a channel */
return (FAILURE); /* Can't */
/* */
__chinit(ich); /* Clear out channel's ccb */
ch = _getccb(ich); /* Get address of ccb */
/* */
if(type==0) /* ASCII file? */
ch -> flags |= ISASCII; /* Yes, mark it. */
/****************************/
if(_strcmp(fname,__tname) == 0) /* Terminal file? */
{ /* */
ch -> flags |= ISTTY|OPENED; /* Set flag */
return(ich); /* Return file descriptor */
} /****************************/
else if(_strcmp(fname,__lname) == 0) /* List device? */
{ /* */
ch -> flags |= ISLPT|OPENED; /* set flag */
return(ich); /* */
} /* */
/****************************/
if(__open(ich,fname,CREATE) != 0) /* Use BDOS interface */
{ /* */
freec(ich); /* Release channel */
RETERR(FAILURE,ENODSPC); /* Oops, No dir space. */
} /****************************/
/* Else: */
ch -> flags |= OPENED; /* Set OPEN bit */
return(ich); /* Return Channel # */
} /****************************/

View File

@@ -0,0 +1,67 @@
/**************************************************************************
* CTYPE.C - provides static tables for 'ctype.h' extern defs.
*
***************************************************************************/
#include <portab.h>
#define CTYPE /* tells ctype.h who's boss */
#include <ctype.h>
GLOBAL UBYTE __atab[] = { /* table of ascii char types */
/********************************************************************/
/* nn0 nn1 nn2 nn3 nn4 nn5 nn6 nn7 */
/* nul soh stx etx eot enq ack bel */
/*00m*/ __c, __c, __c, __c, __c, __c, __c, __c,
/* bs ht nl vt np cr so si */
/*01m*/ __c, __cs, __cs, __c, __cs, __cs, __c, __c,
/* dle dc1 dc2 dc3 dc4 nak syn etb */
/*02m*/ __c, __c, __c, __c, __c, __c, __c, __c,
/* can em sub esc fs gs rs us */
/*03m*/ __c, __c, __c, __c, __c, __c, __c, __c,
/* sp ! " # $ % & ' */
/*04m*/ __ps, __p, __p, __p, __p, __p, __p, __p,
/* ( ) * + , - . / */
/*05m*/ __p, __p, __p, __p, __p, __p, __p, __p,
/* 0 1 2 3 4 5 6 7 */
/*06m*/ __d, __d, __d, __d, __d, __d, __d, __d,
/* 8 9 : ; < = > ? */
/*07m*/ __d, __d, __p, __p, __p, __p, __p, __p,
/* @ A B C D E F G */
/*10m*/ __p, __u, __u, __u, __u, __u, __u, __u,
/* H I J K L M N O */
/*11m*/ __u, __u, __u, __u, __u, __u, __u, __u,
/* P Q R S T U V W */
/*12m*/ __u, __u, __u, __u, __u, __u, __u, __u,
/* X Y Z [ \ ] ^ _ */
/*13m*/ __u, __u, __u, __p, __p, __p, __p, __p,
/* ` a b c d e f g */
/*14m*/ __p, __l, __l, __l, __l, __l, __l, __l,
/* h i j k l m n o */
/*15m*/ __l, __l, __l, __l, __l, __l, __l, __l,
/* p q r s t u v w */
/*16m*/ __l, __l, __l, __l, __l, __l, __l, __l,
/* x y z { | } ~ del */
/*17m*/ __l, __l, __l, __p, __p, __p, __p, __c
};

View File

@@ -0,0 +1,39 @@
/**************************************************************************
* CTYPE.H - macros to classify ASCII-coded integers by table lookup.
*
*
* Note: Integer args are undefined for all int values > 127,
* except for macro 'isascii()'.
* Assumes:
* User will link with standard library functions.
* Compiler can handle declarator initializers and
* '#defines' with parameters.
***************************************************************************/
/* Define bit patterns for character classes */
#define __c 01
#define __p 02
#define __d 04
#define __u 010
#define __l 020
#define __s 040
#define __cs 041
#define __ps 042
#ifndef CTYPE
extern char __atab[];
#endif
#define isascii(ch) ((ch) < 0200)
#define isalpha(ch) (__atab[ch] & (__u | __l))
#define isupper(ch) (__atab[ch] & __u)
#define islower(ch) (__atab[ch] & __l)
#define isdigit(ch) (__atab[ch] & __d)
#define isalnum(ch) (__atab[ch] & (__u | __l | __d))
#define isspace(ch) (__atab[ch] & __s)
#define ispunct(ch) (__atab[ch] & __p)
#define isprint(ch) (__atab[ch] & (__u | __l | __d | __p))
#define iscntrl(ch) (__atab[ch] & __c)
#define tolower(ch) (isupper(ch) ? (ch)-'A'+'a' : (ch) )
#define toupper(ch) (islower(ch) ? (ch)-'a'+'A' : (ch) )
#define toascii(ch) ((ch) & 0177)

View File

@@ -0,0 +1,122 @@
$ set noon
$ diff ACCESS.C drb1:[cpm68k.beta2.clib]ACCESS.C
$ diff ALLOCC.C drb1:[cpm68k.beta2.clib]ALLOCC.C
$ diff ATOI.C drb1:[cpm68k.beta2.clib]ATOI.C
$ diff ATOL.C drb1:[cpm68k.beta2.clib]ATOL.C
$ diff BLKIO.C drb1:[cpm68k.beta2.clib]BLKIO.C
$ diff CALLOC.C drb1:[cpm68k.beta2.clib]CALLOC.C
$ diff CHINIT.C drb1:[cpm68k.beta2.clib]CHINIT.C
$ diff CHKC.C drb1:[cpm68k.beta2.clib]CHKC.C
$ diff CHMOD.C drb1:[cpm68k.beta2.clib]CHMOD.C
$ diff CHOWN.C drb1:[cpm68k.beta2.clib]CHOWN.C
$ diff CLEANUP.C drb1:[cpm68k.beta2.clib]CLEANUP.C
$ diff CLOSE.C drb1:[cpm68k.beta2.clib]CLOSE.C
$ diff CREAT.C drb1:[cpm68k.beta2.clib]CREAT.C
$ diff CTYPE.C drb1:[cpm68k.beta2.clib]CTYPE.C
$ diff ERRNO.C drb1:[cpm68k.beta2.clib]ERRNO.C
$ diff EXEC.C drb1:[cpm68k.beta2.clib]EXEC.C
$ diff EXIT.C drb1:[cpm68k.beta2.clib]EXIT.C
$ diff FCLOSE.C drb1:[cpm68k.beta2.clib]FCLOSE.C
$ diff FDOPEN.C drb1:[cpm68k.beta2.clib]FDOPEN.C
$ diff FFLUSH.C drb1:[cpm68k.beta2.clib]FFLUSH.C
$ diff FGETC.C drb1:[cpm68k.beta2.clib]FGETC.C
$ diff FGETC.C drb1:[cpm68k.beta2.clib]FGETC.C
$ diff FGETS.C drb1:[cpm68k.beta2.clib]FGETS.C
$ diff FOPEN.C drb1:[cpm68k.beta2.clib]FOPEN.C
$ diff FPRINTF.C drb1:[cpm68k.beta2.clib]FPRINTF.C
$ diff FPUTC.C drb1:[cpm68k.beta2.clib]FPUTC.C
$ diff FPUTC.C drb1:[cpm68k.beta2.clib]FPUTC.C
$ diff FPUTC.C drb1:[cpm68k.beta2.clib]FPUTC.C
$ diff FPUTS.C drb1:[cpm68k.beta2.clib]FPUTS.C
$ diff FREAD.C drb1:[cpm68k.beta2.clib]FREAD.C
$ diff FREOPEN.C drb1:[cpm68k.beta2.clib]FREOPEN.C
$ diff FSCANF.C drb1:[cpm68k.beta2.clib]FSCANF.C
$ diff FSEEK.C drb1:[cpm68k.beta2.clib]FSEEK.C
$ diff FTELL.C drb1:[cpm68k.beta2.clib]FTELL.C
$ diff FWRITE.C drb1:[cpm68k.beta2.clib]FWRITE.C
$ diff GETL.C drb1:[cpm68k.beta2.clib]GETL.C
$ diff GETPASS.C drb1:[cpm68k.beta2.clib]GETPASS.C
$ diff GETPID.C drb1:[cpm68k.beta2.clib]GETPID.C
$ diff GETS.C drb1:[cpm68k.beta2.clib]GETS.C
$ diff GETW.C drb1:[cpm68k.beta2.clib]GETW.C
$ diff GETW.C drb1:[cpm68k.beta2.clib]GETW.C
$ diff INDEX.C drb1:[cpm68k.beta2.clib]INDEX.C
$ diff ISATTY.C drb1:[cpm68k.beta2.clib]ISATTY.C
$ diff LDIV.C drb1:[cpm68k.beta2.clib]LDIV.C
$ diff LSEEK.C drb1:[cpm68k.beta2.clib]LSEEK.C
$ diff MALLOC.C drb1:[cpm68k.beta2.clib]MALLOC.C
$ diff MKTEMP.C drb1:[cpm68k.beta2.clib]MKTEMP.C
$ diff OPEN.C drb1:[cpm68k.beta2.clib]OPEN.C
$ diff PERROR.C drb1:[cpm68k.beta2.clib]PERROR.C
$ diff PRINTF.C drb1:[cpm68k.beta2.clib]PRINTF.C
$ diff PUTL.C drb1:[cpm68k.beta2.clib]PUTL.C
$ diff PUTS.C drb1:[cpm68k.beta2.clib]PUTS.C
$ diff PUTW.C drb1:[cpm68k.beta2.clib]PUTW.C
$ diff QSORT.C drb1:[cpm68k.beta2.clib]QSORT.C
$ diff RAND.C drb1:[cpm68k.beta2.clib]RAND.C
$ diff READ.C drb1:[cpm68k.beta2.clib]READ.C
$ diff REWIND.C drb1:[cpm68k.beta2.clib]REWIND.C
$ diff RINDEX.C drb1:[cpm68k.beta2.clib]RINDEX.C
$ diff SBRK.C drb1:[cpm68k.beta2.clib]SBRK.C
$ diff SCANF.C drb1:[cpm68k.beta2.clib]SCANF.C
$ diff SETBUF.C drb1:[cpm68k.beta2.clib]SETBUF.C
$ diff SIGNAL.C drb1:[cpm68k.beta2.clib]SIGNAL.C
$ diff SPRINTF.C drb1:[cpm68k.beta2.clib]SPRINTF.C
$ diff SSCANF.C drb1:[cpm68k.beta2.clib]SSCANF.C
$ diff STRCAT.C drb1:[cpm68k.beta2.clib]STRCAT.C
$ diff STRCMP.C drb1:[cpm68k.beta2.clib]STRCMP.C
$ diff STRCPY.C drb1:[cpm68k.beta2.clib]STRCPY.C
$ diff STRINS.C drb1:[cpm68k.beta2.clib]STRINS.C
$ diff STRLEN.C drb1:[cpm68k.beta2.clib]STRLEN.C
$ diff STRNCAT.C drb1:[cpm68k.beta2.clib]STRNCAT.C
$ diff STRNCMP.C drb1:[cpm68k.beta2.clib]STRNCMP.C
$ diff STRNCPY.C drb1:[cpm68k.beta2.clib]STRNCPY.C
$ diff SWAB.C drb1:[cpm68k.beta2.clib]SWAB.C
$ diff TTYNAME.C drb1:[cpm68k.beta2.clib]TTYNAME.C
$ diff UNGETC.C drb1:[cpm68k.beta2.clib]UNGETC.C
$ diff UNLINK.C drb1:[cpm68k.beta2.clib]UNLINK.C
$ diff WRITE.C drb1:[cpm68k.beta2.clib]WRITE.C
$ diff XDOPRT.C drb1:[cpm68k.beta2.clib]XDOPRT.C
$ diff XDOPRTFP.C drb1:[cpm68k.beta2.clib]XDOPRTFP.C
$ diff XDOSCAN.C drb1:[cpm68k.beta2.clib]XDOSCAN.C
$ diff XEXIT.C drb1:[cpm68k.beta2.clib]XEXIT.C
$ diff XFDECLS.C drb1:[cpm68k.beta2.clib]XFDECLS.C
$ diff XFILBUF.C drb1:[cpm68k.beta2.clib]XFILBUF.C
$ diff XFILBUF.C drb1:[cpm68k.beta2.clib]XFILBUF.C
$ diff XFILESZ.C drb1:[cpm68k.beta2.clib]XFILESZ.C
$ diff XFLSBUF.C drb1:[cpm68k.beta2.clib]XFLSBUF.C
$ diff XFLSBUF.C drb1:[cpm68k.beta2.clib]XFLSBUF.C
$ diff XFPRINTF.C drb1:[cpm68k.beta2.clib]XFPRINTF.C
$ diff XMAIN.C drb1:[cpm68k.beta2.clib]XMAIN.C
$ diff XOPEN.C drb1:[cpm68k.beta2.clib]XOPEN.C
$ diff XPRTINT.C drb1:[cpm68k.beta2.clib]XPRTINT.C
$ diff XPRTLD.C drb1:[cpm68k.beta2.clib]XPRTLD.C
$ diff XPRTSHRT.C drb1:[cpm68k.beta2.clib]XPRTSHRT.C
$ diff XSTRCMP.C drb1:[cpm68k.beta2.clib]XSTRCMP.C
$ diff XTTYIN.C drb1:[cpm68k.beta2.clib]XTTYIN.C
$ diff XWMAIN.C drb1:[cpm68k.beta2.clib]XWMAIN.C
$ diff ABORT.S drb1:[cpm68k.beta2.clib]ABORT.S
$ diff ALDIV.S drb1:[cpm68k.beta2.clib]ALDIV.S
$ diff ALMUL.S drb1:[cpm68k.beta2.clib]ALMUL.S
$ diff ALREM.S drb1:[cpm68k.beta2.clib]ALREM.S
$ diff BLIVOT.S drb1:[cpm68k.beta2.clib]BLIVOT.S
$ diff LDIV.S drb1:[cpm68k.beta2.clib]LDIV.S
$ diff LMUL.S drb1:[cpm68k.beta2.clib]LMUL.S
$ diff LREM.S drb1:[cpm68k.beta2.clib]LREM.S
$ diff NOFLOAT.S drb1:[cpm68k.beta2.clib]NOFLOAT.S
$ diff S.S drb1:[cpm68k.beta2.clib]S.S
$ diff SETJMP.S drb1:[cpm68k.beta2.clib]SETJMP.S
$ diff STKCPY.S drb1:[cpm68k.beta2.clib]STKCPY.S
$ diff ULDIV.S drb1:[cpm68k.beta2.clib]ULDIV.S
$ diff W.S drb1:[cpm68k.beta2.clib]W.S
$ diff XSIGNAL.S drb1:[cpm68k.beta2.clib]XSIGNAL.S
$ diff BASEPAGE.H drb1:[cpm68k.beta2.clib]BASEPAGE.H
$ diff BDOS.H drb1:[cpm68k.beta2.clib]BDOS.H
$ diff CPM.H drb1:[cpm68k.beta2.clib]CPM.H
$ diff CTYPE.H drb1:[cpm68k.beta2.clib]CTYPE.H
$ diff ERRNO.H drb1:[cpm68k.beta2.clib]ERRNO.H
$ diff PORTAB.H drb1:[cpm68k.beta2.clib]PORTAB.H
$ diff SETJMP.H drb1:[cpm68k.beta2.clib]SETJMP.H
$ diff SGTTY.H drb1:[cpm68k.beta2.clib]SGTTY.H
$ diff SIGNAL.H drb1:[cpm68k.beta2.clib]SIGNAL.H
$ diff STDIO.H drb1:[cpm68k.beta2.clib]STDIO.H

View File

@@ -0,0 +1,8 @@
/*
* errno.c : declares storage for errno, a variable containing the last
* system error.
*/
#include <portab.h>
WORD errno = 0; /* set by low level i/o, unset by user (if at all) */
WORD _errcpm = 0; /* assign BDOS return val when assigning errno */

View File

@@ -0,0 +1,45 @@
/*
* errno.h - error codes
*/
#define EPERM 1
#define ENOENT 2
#define ESRCH 3
#define EINTR 4
#define EIO 5
#define ENXIO 6
#define E2BIG 7
#define ENOEXEC 8
#define EBADF 9
#define ECHILD 10
#define EAGAIN 11
#define ENOMEM 12
#define EACCES 13
#define EFAULT 14
#define ENOTBLK 15
#define EBUSY 16
#define EEXIST 17
#define EXDEV 18
#define ENODEV 19
#define ENOTDIR 20
#define EISDIR 21
#define EINVAL 22
#define ENFILE 23
#define EMFILE 24
#define ENOTTY 25
#define ETXTBSY 26
#define EFBIG 27
#define ENOSPC 28
#define ESPIPE 29
#define EROFS 30
#define EMLINK 31
#define EPIPE 32
/* math software */
#define EDOM 33
#define ERANGE 34
/* hereafter is available to CP/M specials */
#define ENODSPC 35
/****** end of errno.h ******/

View File

@@ -0,0 +1,47 @@
/****************************************************************************/
/* */
/* E x e c F u n c t i o n */
/* ------------------------- */
/* Copyright 1982 by Digital Research Inc. All rights reserved. */
/* */
/* The execl function is called from anywhere to pass control to */
/* another program from the the executing C program. */
/* Note that the stream files are closed via '_cleanup()'. */
/* */
/* Calling Sequence: */
/* */
/* execl(name,arg0,arg1,...,argn,NULLPTR); */
/* */
/* Where: */
/* name, arg0, arg1...argn are pointers to character strings */
/* */
/****************************************************************************/
#include <stdio.h>
#include <cpm.h>
#include <ctype.h>
execl(name,arg0) /***************************/
UBYTE *name,*arg0; /* pointers arguments */
{ /* */
UBYTE **args; /* used to index into args */
UBYTE cmdline[128]; /* CP/M command line area */
WORD i; /***************************/
/* */
_cleanup(); /* Close all (stream) files*/
__BDOS(26,&cmdline[0]); /* DMA -> Command line */
/* now build cmdline */
strcpy(cmdline,name); /* Copy name portion */
for(i=0; i < strlen(cmdline); i++) /* uppercase command name */
if (islower(cmdline[i])) /***************************/
cmdline[i] = toupper(cmdline[i]); /* */
/* */
args = &arg0; /* Copy args */
args++; /* arg0 is a dup of the */
/* command name */
while(*args != NULL) /***************************/
{ /* */
strcat(cmdline," "); /* Add a blank */
strcat(cmdline,*args++); /* Add next arg */
} /***************************/
cmdline[0] = strlen(&cmdline[1]); /* Set commmand length */
__BDOS(47,0L); /* chain to program */
} /***************************/

View File

@@ -0,0 +1,27 @@
/****************************************************************************/
/* */
/* E x i t F u n c t i o n */
/* ------------------------- */
/* Copyright 1982 by Digital Research Inc. All rights reserved. */
/* */
/* The exit function is called from anywhere to pass control back to */
/* the CCP from the executing C program. */
/* Note that the stream files are closed via '_cleanup()'. */
/* */
/* Calling Sequence: */
/* */
/* exit(code); */
/* */
/* Where: */
/* code Is the exit status (ignored) */
/* */
/****************************************************************************/
#include <stdio.h>
#include <cpm.h>
exit(code) /***************************/
WORD code; /* Exit status */
{ /* */
_cleanup(); /* Close all (stream) files*/
_exit(code); /* return to O.S. */
} /***************************/

View File

@@ -0,0 +1,32 @@
/*********************************************************************
*
* f c l o s e F u n c t i o n
* -----------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "fclose" flushes a stream (buffered file) and releases the
* channel and any allocated buffers.
*
* Calling sequence:
* ret = fclose(stream)
* Where:
* stream -> file to be closed (FILE *)
* ret = SUCCESS or FAILURE (if IO error)
*
*****************************************************************************/
#include <stdio.h>
WORD fclose(sp) /****************************/
REG FILE *sp; /* stream to close */
{ /* */
/****************************/
if( sp->_flag & (_IOREAD|_IOWRT) ) /* is it closeable? */
{ /* yup... */
fflush(sp); /* do the flush */
if( sp->_flag & _IOABUF ) /* was buf alloc'd? */
free(sp->_base); /* free it ifso */
sp->_base = sp->_ptr = NULL; /* reset these */
sp->_cnt = 0; /* */
} /* reset all flags */
sp->_flag &= ~(_IOREAD|_IOWRT|_IOABUF|_IONBUF|_IOERR|_IOEOF|_IOLBUF);
return(close(sp->_fd)); /* and return */
} /****************************/

View File

@@ -0,0 +1,49 @@
/***************************************************************************
*
* f d o p e n F u n c t i o n
* -----------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "fdopen" associates a file which was opened by a file descriptor
* (using "open" or "creat") with a stream.
*
* Calling sequence:
* stream = fdopen( fd, mode )
* Where:
* stream -> stream info (FILE *) (NULL returned on fail)
* fd = small int returned by open or creat
* mode = "r" for read-only, "w" for write, "a" for append
*
*****************************************************************************/
#include <stdio.h>
FILE *fdopen( fd, mode )
REG WORD fd;
REG BYTE *mode;
{
REG FILE *sp;
REG WORD ii;
/****************************/
if( fd<0 || lseek(fd,0L,1)==FAILURE ) /* is fd valid? */
return(NULL); /* no, oh well */
for( ii=0; /* look at _iob table */
(sp=(&_iob[ii]))->_flag&(_IOREAD|_IOWRT); /* not marked rd/wrt */
ii++ ) /* */
if( ii >= MAXFILES ) /* if off end of table */
break; /* */
if( ii >= MAXFILES ) /* */
return(NULL); /* fail */
if( *mode != 'r' && *mode != 'R') /* not 'r'ead mode? */
{ /* */
sp->_flag |= _IOWRT; /* set this flag */
if( *mode == 'a' || /* 'a'ppend mode? */
*mode == 'A' ) /* */
lseek(fd,0L,2); /* its out there, seef EOF */
} /* ************************/
else sp->_flag |= _IOREAD; /* 'r'ead mode */
/****************************/
sp->_cnt = 0; /* init count */
sp->_fd = fd; /* and file des */
sp->_base = sp->_ptr = NULL; /* and buffer pointers */
/****************************/
return(sp); /* return the stream ptr */
} /****************************/

View File

@@ -0,0 +1,42 @@
/****************************************************************************
*
* f f l u s h F u n c t i o n
* -----------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* 'fflush' causes any buffered data in a stream to be written out
* to the file. The stream remains open.
*
* Calling sequence:
* ret = fflush(stream)
* Where:
* stream is a (FILE *)
* ret = SUCCESS or FAILURE (I/O error)
*
*****************************************************************************/
#include <stdio.h>
WORD fflush(sp)
REG FILE *sp; /* stream to flush */
{ /****************************/
REG WORD n, /* num written */
ns; /* num sposed to be written */
/****************************/
if((sp->_flag&(_IONBUF|_IOWRT))==_IOWRT /* does it have a wrt buf? */
&& (ns=sp->_ptr-sp->_base) > 0 ) /* and does buf need wrt? */
{ /* yes! */
n=write(sp->_fd,sp->_base,ns); /* do it */
if(ns!=n) /* did they all git writ? */
{ /* oooops */
sp->_flag |= _IOERR; /* this stream no good */
return(FAILURE); /* let em know */
} /* */
} /****************************/
if((sp->_flag&_IOWRT)!=0 && sp->_base!=NULL)/* written to already? */
{ /* */
if(sp->_flag&_IONBUF) /* is this a nobuf stream? */
sp->_cnt = 1; /* yes */
else sp->_cnt = BUFSIZ-1; /* standard size */
} else sp->_cnt = 0; /* ow. zap out count */
sp->_ptr=sp->_base; /* reset buf */
return(SUCCESS); /* */
} /****************************/

View File

@@ -0,0 +1,25 @@
/**************************************************************************
*
* f g e t c F u n c t i o n
* ---------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* Function "fgetc" does the yanking of a char out of the stream.
*
* Calling sequence:
* ch = fgetc(s)
* Where:
* ch = a (WORD) character (-1 on EOF)
* s -> a stream file (FILE *)
*
*****************************************************************************/
#include <stdio.h>
WORD fgetc(s) /****************************/
REG FILE *s; /* stream pointer */
{ /****************************/
EXTERN WORD _filbuf(); /* use this when we run shrt*/
if( --s->_cnt >= 0 ) /* any chars left in buf? */
return(((WORD) *s->_ptr++) & 0377); /* return & advance ptr ifso*/
else /* */
return( _filbuf(s) ); /* o.w. whatever happens */
} /****************************/

View File

@@ -0,0 +1,42 @@
/***********************************************************************
*
* f g e t s F u n c t i o n
* ---------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "fgets" reads a string from a stream file (up to n-1 chars), and
* returns pointer s (NULL on end of file). The newline at the
* end of line is included, NOT replaced, and the string is terminated
* by a NULL.
*
* Calling sequence:
* addr = fgets(saddr,n,stream)
* Where:
* saddr -> where the string is to go (no bounds check)
* n = max # chars (inc. NULL) for saddr (assumed > 0)
* stream-> where to get from
* addr = saddr if all ok, NULL o.w.
*
*****************************************************************************/
#include <stdio.h>
BYTE *fgets(s,n,f) /****************************/
REG BYTE *s; /* string save area */
REG WORD n; /* max size of string */
REG FILE *f; /* where to get from */
{ /****************************/
REG WORD c; /* char to test for eof */
REG BYTE *sav; /* sav pointer for return */
sav = s; /* remember this */
while( --n > 0 && /* while there's still room */
/* for getc and NULL */
(c=getc(f)) != FAILURE ) /* and read_char ok */
{ /* */
*s++ = c; /* store it */
if( c == '\n' ) /* if end of line */
break; /* stop the presses */
} /* */
*s = ZERO; /* clean up string */
if( c== FAILURE ) /* if not cool */
return(NULL); /* then tell them so */
else return(sav); /* tell them is cool */
} /****************************/

View File

@@ -0,0 +1,92 @@
/**************************************************************************
*
* f o p e n F u n c t i o n
* ---------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "fopen" opens a buffered stream file, either on disk, console, or
* line printer.
* Note that "fopen" comes in three (3) flavors, one for ascii CP/M
* files, another for binary files, and the default (presently to
* ascii files).
*
* Calling sequence:
* stream = fopena(name,mode) (ascii files)
* stream = fopenb(name,mode) (binary files)
* stream = fopen(name,mode) (default-ascii files)
* stream = _fopen(name,mode,ascii)
* Where:
* stream -> file opened (FILE *), NULL if failure
* name -> null terminated string containing filename,
* name="CON:" means the console,
* name="LST:" goes to the line printer, and
* otherwise a disk file is assumed.
* mode -> "r" for read only,
* "w" for write only,
* "a" to append (write only) to end of file.
* ascii = 0 if the file is handled as a CP/M text file
* (newline -> CRLF xlation, ^Z EOF convention).
* Otherwise, file is treated as a binary file.
*
*****************************************************************************/
#include <stdio.h> /****************************/
#define READ 0 /* read mode val */
#define WRITE 1 /* write mode val */
#define CREATMODE 1 /* mode to use for 'creat' */
/****************************/
FILE *fopen(name,mode) /* */
BYTE *name, *mode; /* */
{ FILE *_fopen(); /* */
return(_fopen(name,mode,0)); } /* ascii file open */
/****************************/
FILE *fopena(name,mode) /* */
BYTE *name,*mode; /* */
{ FILE *_fopen(); /* */
return(_fopen(name,mode,0)); } /* ascii file open */
/****************************/
FILE *fopenb(name,mode) /* */
BYTE *name, *mode; /* */
{ FILE *_fopen(); /* */
return(_fopen(name,mode,1)); } /* binary file open */
/****************************/
FILE *_fopen(name,mode,ascii) /* */
REG BYTE *name, /* file name */
*mode; /* "r","w", or "a" */
BOOLEAN ascii; /* CP/M text file */
{ /****************************/
REG FILE *sp; /* stream pointer */
REG WORD ii, /* index into _iob */
fd; /* file descriptor */
/****************************/
for( ii=0; /* look at _iob table */
(sp=(&_iob[ii]))->_flag&(_IOREAD|_IOWRT); /* not marked rd/wrt */
ii++ ) /* */
if( ii >= MAXFILES ) /* if off end of table */
break; /* */
if( ii >= MAXFILES ) /* */
return(NULL); /* fail */
if( *mode == 'w' || *mode == 'W' ) /* 'w'rite mode? */
fd=_creat(name,CREATMODE,ascii);/* create file *********/
else if( *mode == 'a' || *mode == 'A' ) /* 'a'ppend mode? */
{ /* */
if( (fd=_open(name,WRITE,ascii)) < 0 ) /* try open */
fd=_creat(name,CREATMODE,ascii);/* ow. do create */
else lseek(fd,0L,2); /* its out there, seef EOF */
} /* ************************/
else if( *mode == 'r' || *mode == 'R' ) /* 'r'ead mode? */
fd=_open(name,READ,ascii); /* try open ************/
else return(NULL); /* bad mode barf... */
/****************************/
if(fd<0) /* did one of those work? */
return(NULL); /* no, oh well */
sp->_cnt = 0; /* init count */
sp->_fd = fd; /* and file des */
sp->_base = sp->_ptr = NULL; /* and buffer pointers */
if( *mode == 'r' || *mode == 'R' ) /* 'r'ead mode? */
sp->_flag = _IOREAD; /* say so */
else sp->_flag = _IOWRT; /* else 'w'rite mode */
if( ascii == 0 ) /* ascii mode? */
sp->_flag |= _IOASCI; /* */
/****************************/
return(sp); /* return the stream ptr */
} /****************************/

View File

@@ -0,0 +1,23 @@
/************************************************************************
*
* f p r i n t f F u n c t i o n
* -------------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "fprintf" prints args specified in format string to a stream file.
*
* Calling sequence:
* nchrs = fprintf(fmt,arg1,arg2,...argn);
* Where:
* nchrs = number of chars output
* fmt -> a string specifying how arg1-n are to be printed.
*
**************************************************************************/
#include <stdio.h>
WORD fprintf(stream,fmt,args)
FILE *stream;
BYTE *fmt,
*args;
{
return(_doprt(stream,fmt,&args));
}

View File

@@ -0,0 +1,28 @@
/*****************************************************************************
*
* f p u t c F u n c t i o n
* ---------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "fputc" does the inserting of a char into a stream buffer,
* calling _flsbuf when the buffer fills up.
* Returns the character put, or FAILURE (-1) if any errors.
*
* Calling sequence:
* ret=fputc(ch,s)
* Where:
* ch = the char to put
* s -> the stream (FILE *)
* ret= ch or FAILURE
*
*****************************************************************************/
#include <stdio.h>
WORD fputc(ch,s) /* */
REG BYTE ch; /* char to put */
REG FILE *s; /* stream to put it to */
{ /****************************/
if( --(s->_cnt) >= 0 ) /* if there's room in buf */
return(((WORD)(*s->_ptr++ = ch)) & 0377);/* put it! */
else return(_flsbuf(ch,s)); /* o.w. flush & put */
/****************************/
}

View File

@@ -0,0 +1,29 @@
/**************************************************************************
*
* f p u t s F u n c t i o n
* ---------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "fputs" copies a null terminated string to a stream file.
* To be compatible with Unix, it does NOT append a newline.
*
* Calling sequence:
* ret = fputs(s,stream)
* Where:
* ret = last char out, on error FAILURE
* s = string to put
* stream -> stream (FILE *)
*
*****************************************************************************/
#include <stdio.h>
WORD fputs(s,f) /****************************/
REG BYTE *s; /* null term string */
REG FILE *f; /* stream file pointer */
{ /****************************/
REG WORD rv; /* return val */
rv = ZERO; /* init for *s==NULL */
while(*s) /* for all chars in s */
if((rv=putc(*s++,f)) == FAILURE) /* if putc fouls up */
return(FAILURE); /* give up */
return(rv); /* it worked */
} /****************************/

View File

@@ -0,0 +1,38 @@
/**************************************************************************
*
* f r e a d F u n c t i o n
* ---------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "fread" reads NI items of size SZ from stream SP and deposits them
* at BUFF.
*
* Calling sequence:
* nitems = fread(buff,size,nitems,stream)
* Where:
* buff -> where to read to
* size = number bytes in each item
* nitems = number bytes read/to read
* stream -> file
*
* nitems is set to 0 if an error occurs (including EOF).
*
*****************************************************************************/
#include <stdio.h>
WORD fread(buff,sz,ni,sp)
REG BYTE *buff;
WORD sz,
ni;
REG FILE *sp;
{
REG WORD jj, kk, ch;
for( jj=0; jj<ni; jj++ )
for( kk=0; kk<sz; kk++ )
{
if( (ch = getc(sp)) == FAILURE )
return(ZERO);
else *buff++ = ch & 0377;
}
return(ni);
}

View File

@@ -0,0 +1,81 @@
/*****************************************************************************
*
* f r e o p e n F u n c t i o n
* -------------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "freopen" opens a buffered stream file, either on disk, console, or
* line printer. It first closes the given stream, and reuses that slot.
* Comes in 3 flavors, like "fopen".
*
* Calling sequence:
* stream = freopen(name,mode,stream)
* stream = freopa(name,mode,stream)
* stream = freopb(name,mode,stream)
* stream = _freopen(name,mode,stream,ascii)
* Where:
* stream -> file reopened (FILE *), NULL if failure
* name -> null terminated string containing filename,
* name="CON:" means the console,
* name="LST:" goes to the line printer, and
* otherwise a disk file is assumed.
* mode -> "r" for read only,
* "w" for write only,
* "a" to append (write only) to end of file.
* ascii = 0 if the file is handled as a CP/M text file
* (newline -> CRLF xlation, ^Z EOF convention).
* Otherwise, file is treated as a binary file.
*
*****************************************************************************/
#include <stdio.h> /****************************/
#define READ 0 /* read mode val */
#define WRITE 1 /* write mode val */
FILE *_freope(name,mode,sp,ascii) /****************************/
REG BYTE *name, /* file name */
*mode; /* "r","w", or "a" */
REG FILE *sp; /* stream pointer */
BOOLEAN ascii; /* CP/M text file */
{ /****************************/
REG WORD ii, /* index into _iob */
fd; /* file descriptor */
/****************************/
if( fclose(sp) == FAILURE ) /* try closing the file 1st */
return(NULL); /* oops, it failed */
if( *mode == 'w' || *mode == 'W' ) /* 'w'rite mode? */
fd=_creat(name,0,ascii); /* create file *********/
else if( *mode == 'a' || *mode == 'A' ) /* 'a'ppend mode? */
{ /* */
if( (fd=_open(name,WRITE,ascii)) < 0 ) /* try open */
fd=_creat(name,0,ascii);/* do create if needed */
else lseek(fd,0L,2); /* its out there, seef EOF */
} /* ************************/
else if( *mode == 'r' || *mode == 'R' ) /* 'r'ead mode? */
fd=_open(name,READ,ascii); /* try open ************/
else return(NULL); /* bad mode barf... */
/****************************/
if(fd<0) /* did one of those work? */
return(NULL); /* no, oh well */
sp->_cnt = 0; /* init count */
sp->_fd = fd; /* and file des */
sp->_base = sp->_ptr = NULL; /* and buffer pointers */
if( *mode == 'r' || *mode == 'R' ) /* 'r'ead mode? */
sp->_flag = _IOREAD; /* say so */
else sp->_flag = _IOWRT; /* else 'w'rite mode */
if( ascii == 0 ) /* ascii file? */
sp->_flag |= _IOASCI; /* */
/****************************/
return(sp); /* return the stream ptr */
} /****************************/
FILE *freopen(n,m,s)
BYTE *n, *m; FILE *s;
{ return(_freope(n,m,s,0)); } /* reopen ascii file */
FILE *freopa(n,m,s)
BYTE *n, *m; FILE *s;
{ return(_freope(n,m,s,0)); } /* reopen ascii file */
FILE *freopb(n,m,s)
BYTE *n, *m; FILE *s;
{ return(_freope(n,m,s,1)); } /* reopen binary file */

View File

@@ -0,0 +1,27 @@
/**************************************************************************
*
* f s c a n f F u n c t i o n
* -----------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "fscanf" scans the given stream for items specified, and assigns
* them to user supplied variables (via pointers to these vars).
*
* Calling sequence:
* ret = fscanf(sp,fmt,p1,p2,...)
* Where:
* ret = the number of items successfully matched & assigned
* EOF returned if encountered on input
* sp -> (FILE *) stream pointer
* fmt -> a string specifying how to parse the input
* p1,p2,... -> where matched items get stored
*
*****************************************************************************/
#include <stdio.h>
WORD fscanf(sp,fmt,ptrs)
FILE *sp;
BYTE *fmt;
BYTE *ptrs;
{
return(_doscan(sp,fmt,&ptrs));
}

View File

@@ -0,0 +1,35 @@
/**************************************************************************
*
* f s e e k F u n c t i o n
* ---------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "fseek" sets the read/write pointer of a stream to an arbitrary
* offset.
*
* Calling sequence:
* ret = fseek(sp,offset,sense)
* Where:
* sp -> (FILE *) stream to seek on
* offset = signed number of bytes
* sense = 0 => offset from beginning of file
* 1 => offset from current position
* 2 => from end of file
* ret = 0 for success, -1 for failure
*
*****************************************************************************/
#include <stdio.h>
WORD fseek(sp,offs,sense)
FILE *sp;
LONG offs;
WORD sense;
{
LONG p, lseek();
if(sp->_flag & _IOWRT) /* Only if file writable */
{
if( fflush(sp) == FAILURE )
return( FAILURE );
}
p = lseek(fileno(sp),offs,sense);
return( p==(LONG) FAILURE ? FAILURE : SUCCESS);
}

View File

@@ -0,0 +1,57 @@
/***********************************************************************
*
* f t e l l F u n c t i o n
* ---------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "ftell" returns the present value of the read/write pointer
* within the stream. This is a meaningless number for console
* and list devices.
*
* Calling sequence:
* offset = ftell(sp)
* Where:
* sp -> (FILE *) stream
* offset = (LONG) where stream is reading from/writing to
*
******************************************************************************/
#include <stdio.h>
LONG ftell(sp)
REG FILE *sp; /* stream pointer */
{ /* */
REG LONG filepos; /* file position */
REG BYTE *bp; /* Buffer ptr */
LONG lseek(); /* byte offset into file */
/* */
if( isatty(fileno(sp)) ) /* are we talking to a tty? */
return(0); /* quit now if so */
filepos = FAILURE; /* default return value */
if( sp->_flag & (_IOREAD|_IOWRT) ) /* if file is open */
{ /* */
if((filepos=lseek(fileno(sp),0L,1)) /* get where next byte read */
== FAILURE ) /* from or written to */
return(FAILURE); /* quit if bad lseek */
filepos += sp->_ptr - sp->_base; /* correct for # read/wrtn */
if( sp->_flag & _IOREAD ) /* if reading from file */
if( filepos > 0 ) /* and we've read from file*/
filepos -= sp->_ptr - sp->_base + sp->_cnt; /* */
/* adjust file position */
/* to reflect read ahead */
if( sp->_flag & _IOASCI ) /* ascii file? **************/
{ /* count the newlines */
if( sp->_flag & _IOWRT ) /* add in newline's cr's */
{ /* */
for( bp=sp->_base; bp < sp->_ptr; bp++ ) /* */
if( *bp == '\n' ) /* count newlines in stuff */
filepos++; /* written/read so far */
} else { /* we're reading... */
if( filepos > 0 ) /* check to see we've read */
for(bp= &(sp->_ptr[sp->_cnt-1]);/* start at end of buffer */
bp >= sp->_ptr; bp-- ) /* back up to next read char*/
if( *bp == '\n' ) /* count off for newlines */
filepos--; /* */
} /* */
} /* fini ascii ***************/
} /****************************/
return(filepos); /* */
} /****************************/

View File

@@ -0,0 +1,35 @@
/**************************************************************************
*
* f w r i t e F u n c t i o n
* -----------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "fwrite" writes NI items of size SZ from memory at BUFF into stream
* SP.
*
* Calling sequence:
* nitems = fwrite(buff,size,nitems,stream)
* Where:
* buff -> where to write from
* size = number bytes in each item
* nitems = number bytes written/to write
* stream -> file
*
* nitems is set to 0 if an error occurs (including EOF).
*
*****************************************************************************/
#include <stdio.h>
WORD fwrite(buff,sz,ni,sp)
REG BYTE *buff;
WORD sz,
ni;
REG FILE *sp;
{
REG WORD jj, kk;
for( jj=0; jj<ni; jj++ )
for( kk=0; kk<sz; kk++ )
if( fputc(*buff++,sp) == FAILURE ) /* used for side effects */
return(ZERO);
return(ni);
}

View File

@@ -0,0 +1,32 @@
/**************************************************************************
*
* g e t l F u n c t i o n
* -------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "getl" gets an LONG (4 byte) value from the input stream.
* Note that what's written (binary) by a PDP 11 (UNIX: lo byte, hi byte)
* system will NOT be compatible with what's written by a
* 68K (NUXI: hi byte, lo byte) system.
*
* Calling sequence:
* l = getl(stream)
* Where:
* l = a 32-bit long value
* stream-> a (FILE *) input stream
*
*****************************************************************************/
#include <stdio.h>
LONG getl(sp)
REG FILE *sp; /* the stream to get from */
{ /* */
LONG l; /* place to get to */
REG BYTE *p; /* make ptr to l */
/****************************/
p = (char *)&l; /* point to l */
*p++ = getc(sp); /* no way to distinguish */
*p++ = getc(sp); /* twixt EOF & -1 */
*p++ = getc(sp); /* */
*p++ = getc(sp); /* */
return(l); /* there it is */
} /****************************/

View File

@@ -0,0 +1,71 @@
/***********************************************************************
*
* g e t p a s s F u n c t i o n
* -------------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "getpass" writes a prompt to the console (NOT stdout) and accepts
* a string of 1-8 chars from the console (NOT stdin) without
* echoing the input to the terminal. Only limited CP/M line edit
* commands are available (CTL H, DEL, CTL X) on input.
*
* Calling sequence:
* pret = getpass(prompt)
* Where:
* pret -> ptr to 1-8 chars of null terminated password
* prompt -> null teminated console out msg.
*
**************************************************************************/
#include <portab.h>
#include <cpm.h>
BYTE *getpass(prompt)
BYTE *prompt;
{
MLOCAL ibuf[9];
_chrout(prompt,(LONG)strlen(prompt),CONOUT);/* same fn write uses */
_noecho(ibuf,9);
return(ibuf);
}
#define INCHAR 0xFFL
#define DEL 0177
#define CTRLX 030
#define CTRLC 003
VOID _noecho(bf,ln)
BYTE *bf;
WORD ln;
{
WORD cur;
WORD ch;
cur = 0;
FOREVER {
switch( ch = __BDOS(CONIO,INCHAR) & 0177 ) {
case '\b':
case DEL:
if( cur>0 ) {
cur--;
bf--;
}
break;
case CTRLX:
bf -= cur;
cur = 0;
break;
case '\r':
case '\n':
*bf = ZERO;
return;
case CTRLC:
exit(1);
default:
*bf++ = ch;
cur++;
if( cur+1 >= ln ) {
*bf = ZERO;
return;
}
}
}
}

View File

@@ -0,0 +1,8 @@
/* getpid - return process ID */
/* returns phony number under CP/M */
#include <portab.h>
#define PHONYPID 222
WORD getpid()
{
return(PHONYPID);
}

View File

@@ -0,0 +1,32 @@
/***********************************************************************
*
* g e t s F u n c t i o n
* -------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "gets" reads a string from the standard input, and returns
* its argument (NULL on end of file). The newline at the
* end of the string is replaced by a NULL.
*
* Calling sequence:
* addr = gets(saddr)
* Where:
* saddr -> where the string is to go (no bounds check)
* addr = saddr if all ok, NULL o.w.
*
*****************************************************************************/
#include <stdio.h>
BYTE *gets(s) /****************************/
BYTE *s; /* string save area */
{ /****************************/
REG WORD c; /* char to test for eof */
BYTE *sav; /* sav pointer for return */
sav = s; /* remember this */
while( (c=getc(stdin)) != FAILURE && /* while everything ok */
c != '\n' ) /* and not end of line */
*s++ = c; /* store it */
*s = ZERO; /* clean up string */
if( c == FAILURE ) /* if not cool */
return(NULL); /* then tell them so */
else return(sav); /* tell them is cool */
} /****************************/

View File

@@ -0,0 +1,30 @@
/**************************************************************************
*
* g e t w F u n c t i o n
* -------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "getw" gets an WORD (2 byte) value from the input stream.
* Note that what's written (binary) by a PDP 11 (UNIX: lo byte, hi byte)
* system will NOT be compatible with what's written by a
* 68K (NUXI: hi byte, lo byte) system.
*
* Calling sequence:
* w = getw(stream)
* Where:
* w = a 16-bit word value
* stream-> a (FILE *) input stream
*
*****************************************************************************/
#include <stdio.h>
WORD getw(sp)
REG FILE *sp; /* the stream to get from */
{ /* */
WORD w; /* place to get to */
REG BYTE *p; /* make ptr to w */
/****************************/
p = (char *)&w; /* point to w */
*p++ = getc(sp); /* no way to distinguish */
*p++ = getc(sp); /* twixt EOF & -1 */
return(w); /* there it is */
} /****************************/

View File

@@ -0,0 +1,21 @@
/*********************************************************************
* INDEX - returns a pointer to first occurrence of char in string.
*
* BYTE *index(s,c)
* BYTE *s, c;
*
* Returns pointer to first c in s, or zero if c not in s.
**********************************************************************/
#include <portab.h>
BYTE *index(s,c)
BYTE *s, c;
{
for( ; c != *s ; s++ ) /* look for c in s. */
if( *s == NULL ) /* if we get to eos, we've gone */
return(0); /* too far. */
return(s); /* found c. note that 'index' */
/* works to find NULL, (ie. */
/* eos), if c==NULL. */
}

View File

@@ -0,0 +1,26 @@
/*************************************************************************
*
* i s a t t y F u n c t i o n
* -----------------------------
* Copyright 1982 by Digital Reserach Inc. All rights reserved.
*
* "isatty" returns TRUE iff the file on channel fd is a 'CON:'
* device.
* Calling sequence:
* ret = isatty(fd)
* Where:
* fd = file descriptor returned by 'open'
* ret = TRUE iff the file is a 'CON:'
*
**************************************************************************/
#include <portab.h>
#include <cpm.h>
BOOLEAN isatty(fd) /****************************/
WORD fd; /* file des returned by open*/
{ /****************************/
REG FD *fp; /* ptr to ccb */
FD *_chkc(); /* validates fd, cvt to fp */
if((fp=_chkc(fd)) == NULL) /* make sure its open MGL */
return(FALSE); /* isno TTY ifnot open */
return( (fp->flags & ISTTY) != 0 ); /* test this flag */
} /****************************/

View File

@@ -0,0 +1,56 @@
long ldivr = 0;
long ldiv(al1,al2)
long al1,al2;
{
register long l1,l2,q,b;
register int sign;
sign = 0;
l1 = al1;
l2 = al2;
if(l2==0) {
ldivr = 0x80000000;
return(0x80000000);
}
if(l2 > l1) {
ldivr = l1;
return(0);
}
if(l1<0) {
l1 = -l1;
sign++;
}
if(l2<0) {
l2 = -l2;
sign++;
}
if(l1==l2) {
q = 1;
l1 = 0;
goto doret;
}
b = 1; /* bit value */
while(l1>=l2) {
l2 =<< 1;
b =<< 1;
}
q = 0;
while(b) { /* now do shifts and subtracts */
if(l1>=l2) {
q =| b;
l1 =- l2;
}
b =>> 1;
l2 =>> 1;
}
doret:
if(sign==1) {
ldivr = -l1;
return(-q);
}
ldivr = l1;
return(q);
}

View File

@@ -0,0 +1,57 @@
1File: LDIV.C Page 1
1 long ldivr = 0;
2
3 long ldiv(al1,al2)
4 long al1,al2;
5 {
6
7 register long l1,l2,q,b;
8 register int sign;
9
10 sign = 0;
11 l1 = al1;
12 l2 = al2;
13 if(l2==0) {
14 ldivr = 0x80000000;
15 return(0x80000000);
16 }
17 if(l2 > l1) {
18 ldivr = l1;
19 return(0);
20 }
21 if(l1<0) {
22 l1 = -l1;
23 sign++;
24 }
25 if(l2<0) {
26 l2 = -l2;
27 sign++;
28 }
29 if(l1==l2) {
30 q = 1;
31 l1 = 0;
32 goto doret;
33 }
34 b = 1; /* bit value */
35 while(l1>=l2) {
36 l2 =<< 1;
37 b =<< 1;
38 }
39 q = 0;
40 while(b) { /* now do shifts and subtracts */
41 if(l1>=l2) {
42 q =| b;
43 l1 =- l2;
44 }
45 b =>> 1;
46 l2 =>> 1;
47 }
48 doret:
49 if(sign==1) {
50 ldivr = -l1;
51 return(-q);
52 }
53 ldivr = l1;
54 return(q);
55 }
56

View File

@@ -0,0 +1,84 @@
.globl _ldivr
.comm _ldivr,4
.globl _ldiv
.globl ldiv
.text
_ldiv:
ldiv:
~~ldiv:
~b=R4
~q=R5
~l1=R7
~l2=R6
~al1=8
~al2=12
~sign=R3
link R14,#-2
movem.l R2-R7,-(sp)
clr R3
clr.l R5
move.l 8(R14),R7
move.l 12(R14),R6
bne L2
move.l #$80000000,_ldivr
move.l #$80000000,R0
bra L1
L2:
bge L3
neg.l R6
add #1,R3
L3:
tst.l R7
bge L4
neg.l R7
add #1,R3
L4:
cmp.l R7,R6
bgt L6
bne L7
move.l #1,R5
clr.l R7
bra L6
L7:
cmp.l #$10000,R7
bge L9
divu R6,R7
move R7,R5
swap R7
ext.l R7
bra L6
L9:
move.l #1,R4
L12:
cmp.l R6,R7
blo L11
asl.l #1,R6
asl.l #1,R4
bra L12
L11:
tst.l R4
beq L6
cmp.l R6,R7
blo L15
or.l R4,R5
sub.l R6,R7
L15:
lsr.l #1,R4
lsr.l #1,R6
bra L11
L6:
cmp #1,R3
bne L16
neg.l R7
move.l R7,_ldivr
move.l R5,R0
neg.l R0
bra L1
L16:
move.l R7,_ldivr
move.l R5,R0
L1:
tst.l (sp)+
movem.l (sp)+,R3-R7
unlk R14
rts

View File

@@ -0,0 +1,345 @@
$ num
ACCESS.C
ACCESS.lis
$ num
ALLOCC.C
ALLOCC.lis
$ num
ATOI.C
ATOI.lis
$ num
ATOL.C
ATOL.lis
$ num
BLKIO.C
BLKIO.lis
$ num
CALLOC.C
CALLOC.lis
$ num
CHINIT.C
CHINIT.lis
$ num
CHKC.C
CHKC.lis
$ num
CHMOD.C
CHMOD.lis
$ num
CHOWN.C
CHOWN.lis
$ num
CLEANUP.C
CLEANUP.lis
$ num
CLOSE.C
CLOSE.lis
$ num
CREAT.C
CREAT.lis
$ num
CTYPE.C
CTYPE.lis
$ num
ERRNO.C
ERRNO.lis
$ num
EXEC.C
EXEC.lis
$ num
EXIT.C
EXIT.lis
$ num
FCLOSE.C
FCLOSE.lis
$ num
FDOPEN.C
FDOPEN.lis
$ num
FFLUSH.C
FFLUSH.lis
$ num
FGETC.C
FGETC.lis
$ num
FGETS.C
FGETS.lis
$ num
FOPEN.C
FOPEN.lis
$ num
FPRINTF.C
FPRINTF.lis
$ num
FPUTC.C
FPUTC.lis
$ num
FPUTS.C
FPUTS.lis
$ num
FREAD.C
FREAD.lis
$ num
FREOPEN.C
FREOPEN.lis
$ num
FSCANF.C
FSCANF.lis
$ num
FSEEK.C
FSEEK.lis
$ num
FTELL.C
FTELL.lis
$ num
FWRITE.C
FWRITE.lis
$ num
GETL.C
GETL.lis
$ num
GETPASS.C
GETPASS.lis
$ num
GETPID.C
GETPID.lis
$ num
GETS.C
GETS.lis
$ num
GETW.C
GETW.lis
$ num
INDEX.C
INDEX.lis
$ num
ISATTY.C
ISATTY.lis
$ num
LDIV.C
LDIV.lis
$ num
LSEEK.C
LSEEK.lis
$ num
MALLOC.C
MALLOC.lis
$ num
MKTEMP.C
MKTEMP.lis
$ num
OPEN.C
OPEN.lis
$ num
PERROR.C
PERROR.lis
$ num
PRINTF.C
PRINTF.lis
$ num
PUTL.C
PUTL.lis
$ num
PUTS.C
PUTS.lis
$ num
PUTW.C
PUTW.lis
$ num
QSORT.C
QSORT.lis
$ num
RAND.C
RAND.lis
$ num
READ.C
READ.lis
$ num
REWIND.C
REWIND.lis
$ num
RINDEX.C
RINDEX.lis
$ num
SBRK.C
SBRK.lis
$ num
SCANF.C
SCANF.lis
$ num
SETBUF.C
SETBUF.lis
$ num
SIGNAL.C
SIGNAL.lis
$ num
SPRINTF.C
SPRINTF.lis
$ num
SSCANF.C
SSCANF.lis
$ num
STRCAT.C
STRCAT.lis
$ num
STRCMP.C
STRCMP.lis
$ num
STRCPY.C
STRCPY.lis
$ num
STRINS.C
STRINS.lis
$ num
STRLEN.C
STRLEN.lis
$ num
STRNCAT.C
STRNCAT.lis
$ num
STRNCMP.C
STRNCMP.lis
$ num
STRNCPY.C
STRNCPY.lis
$ num
SWAB.C
SWAB.lis
$ num
TTYNAME.C
TTYNAME.lis
$ num
UNGETC.C
UNGETC.lis
$ num
UNLINK.C
UNLINK.lis
$ num
WRITE.C
WRITE.lis
$ num
XDOPRT.C
XDOPRT.lis
$ num
XDOPRTFP.C
XDOPRTFP.lis
$ num
XDOSCAN.C
XDOSCAN.lis
$ num
XEXIT.C
XEXIT.lis
$ num
XFDECLS.C
XFDECLS.lis
$ num
XFILBUF.C
XFILBUF.lis
$ num
XFILESZ.C
XFILESZ.lis
$ num
XFLSBUF.C
XFLSBUF.lis
$ num
XFPRINTF.C
XFPRINTF.lis
$ num
XMAIN.C
XMAIN.lis
$ num
XOPEN.C
XOPEN.lis
$ num
XPRTINT.C
XPRTINT.lis
$ num
XPRTLD.C
XPRTLD.lis
$ num
XPRTSHRT.C
XPRTSHRT.lis
$ num
XSTRCMP.C
XSTRCMP.lis
$ num
XTTYIN.C
XTTYIN.lis
$ num
XWMAIN.C
XWMAIN.lis
$ num
ABORT.S
ABORT.lis
$ num
ALDIV.S
ALDIV.lis
$ num
ALMUL.S
ALMUL.lis
$ num
ALREM.S
ALREM.lis
$ num
BLIVOT.S
BLIVOT.lis
$ num
LDIV.S
LDIV.lis
$ num
LMUL.S
LMUL.lis
$ num
LREM.S
LREM.lis
$ num
NOFLOAT.S
NOFLOAT.lis
$ num
S.S
S.lis
$ num
SETJMP.S
SETJMP.lis
$ num
STKCPY.S
STKCPY.lis
$ num
ULDIV.S
ULDIV.lis
$ num
W.S
W.lis
$ num
XSIGNAL.S
XSIGNAL.lis
$ num
BASEPAGE.H
BASEPAGE.lst
$ num
BDOS.H
BDOS.lst
$ num
CPM.H
CPM.lst
$ num
CTYPE.H
CTYPE.lst
$ num
ERRNO.H
ERRNO.lst
$ num
PORTAB.H
PORTAB.lst
$ num
SETJMP.H
SETJMP.lst
$ num
SGTTY.H
SGTTY.lst
$ num
SIGNAL.H
SIGNAL.lst
$ num
STDIO.H
STDIO.lst

View File

@@ -0,0 +1,73 @@
*// long multiply routine without floating point
*// call with:
*// two long values on stack
*// returns:
*// long value in R0 and R1
*//
*// warning: no overflow checking or indication!!!!
*struct {
* int hiword;
* int loword;
*};
*long lmul(l1,l2)
*long l1,l2;
*{
*
* long t1;
* register int sign;
* register int t2;
*
* sign = 0;
* if(l1 < 0) {
* l1 = -l1; //make it positive
* sign++;
* }
* if(l2 < 0) {
* l2 = -l2; //make it positive
* sign++;
* }
* t1 = l1.loword*l2.loword;
* t2 = l1.hiword*l2.loword + l2.hiword*l1.loword;
* t1.hiword = t1.hiword + t2;
* if(sign&1)
* t1 = -t1; //negate results
* return(t1);
*}
*
*
.globl lmul
.text
lmul:
~~lmul:
~sign=R2
~l1=8
~l2=12
~t1=-4
~t2=R6
link R14,#-4
clr R2
tst.l 8(R14) //is first arg negative?
bge L2
neg.l 8(R14) //yes, negate it
inc R2 // increment sign flag
L2:tst.l 12(R14) //is second arg negative?
bge L3
neg.l 12(R14) //yes, make it positive
inc R2 //increment sign flag
L3:move 10(R14),R0 //arg1.loword
mulu 14(R14),R0 //arg2.loword
move.l R0,-4(R14) //save in temp
move 8(R14),R0 //arg1.hiword
mulu 14(R14),R0 //arg2.loword
move 12(R14),R1 //arg2.hiword
mulu 10(R14),R1 //arg1.loword
add R1,R0 //form the sum of 2 lo-hi products
add -4(R14),R0 //add to temp hiword
move R0,-4(R14) //store back in temp hiword
move.l -4(R14),R0 //long results
btst #0,R2 //test sign flag
beq L4
neg.l R0 //complement the results
L4:
unlk R14
rts

View File

@@ -0,0 +1,21 @@
.globl _ldiv
.globl _ldivr
.comm _ldivr,4
.globl _lrem
.globl lrem
.text
_lrem:
lrem:
~~lrem:
~l2=12
~al1=8
link R14,#-2
move.l 12(R14),-(sp)
move.l 8(R14),-(sp)
jsr _ldiv
cmpm.l (sp)+,(sp)+
move.l _ldivr,R0
unlk R14
rts

View File

@@ -0,0 +1,75 @@
/****************************************************************************/
/* */
/* L s e e k F u n c t i o n */
/* --------------------------- */
/* Copyright 1982 by Digital Research Inc. All rights reserved. */
/* */
/* The lseek function changes the present position of reading */
/* to or writing from a file. */
/* The tell function returns the present position in a file. */
/* */
/* Calling sequence: */
/* */
/* ret = lseek(fd,offset,sense); */
/* or ret = tell(fd); */
/* */
/* Where: */
/* */
/* fd Is an open file descriptor */
/* offset Is the (long) file offset */
/* sense Is the meaning of offset */
/* 0 => From the beginning of the file */
/* 1 => From the present file position */
/* 2 => From the end of the file */
/* */
/* ret Is the resulting absolute file offset */
/* -1 indicates failure */
/* */
/****************************************************************************/
#include <portab.h>
#include <cpm.h>
EXTERN LONG _filesz();
LONG lseek(fd,offs,sense) /****************************/
/* */
WORD fd; /* Open file descriptor */
LONG offs; /* File offset */
WORD sense; /* Sense of offset */
/* */
/****************************/
{
/****************************/
REG FD *fp; /* File pointer */
EXTERN FD *_chkc(); /* fd to fp translation */
/* */
if((fp = _chkc(fd)) == NULL) /* Convert to pointer */
return(FAILURE); /* Can't */
switch(sense) /****************************/
{ /* */
case 0: /* From beginning of file */
fp->offset = offs; /* Just set to offset */
break; /* Then quit */
/****************************/
case 1: /* From present position */
fp->offset += offs; /* */
break; /* */
/****************************/
case 2: /* From end of file */
fp->hiwater = _filesz(fd); /* go find the end of file */
fp->offset = fp->hiwater + offs;/* compute from end of file */
break; /* */
/****************************/
default: /* All others NFG */
return(FAILURE); /* */
} /****************************/
fp->flags &= ~ATEOF; /* any seek clears EOF */
if( fp->offset < 0 ) /* bad seek call? */
fp->offset = -1; /* set to uniform value */
return(fp->offset); /* Return resultant offset */
} /****************************/
/****************************/
LONG tell(fd) /* tell a file's offset */
WORD fd; /* this file here */
{ /* */
return(lseek(fd,0L,1)); /* is that all? */
} /****************************/

View File

@@ -0,0 +1,102 @@
$ set noon
$ clib
$ cc68 XMAIN
$ cc68 XWMAIN
$ cc68 PERROR
$ cc68 MKTEMP
$ cc68 CHMOD
$ cc68 CHOWN
$ cc68 FPRINTF
$ cc68 PRINTF
$ cc68 SPRINTF
$ cc68 XDOPRT
$ cc68 XPRTINT
$ cc68 XPRTLD
$ cc68 XPRTSHRT
$ cc68 FSCANF
$ cc68 SCANF
$ cc68 SSCANF
$ cc68 XDOSCAN
$ cc68 FDOPEN
$ cc68 FOPEN
$ cc68 FREOPEN
$ cc68 FTELL
$ cc68 REWIND
$ cc68 FSEEK
$ cc68 EXIT
$ cc68 CLEANUP
$ cc68 FCLOSE
$ cc68 FFLUSH
$ cc68 FREAD
$ cc68 FWRITE
$ cc68 FGETS
$ cc68 GETS
$ cc68 FPUTS
$ cc68 PUTS
$ cc68 GETL
$ cc68 GETW
$ cc68 PUTL
$ cc68 PUTW
$ cc68 UNGETC
$ cc68 SETBUF
$ cc68 FGETC
$ cc68 FPUTC
$ cc68 XFILBUF
$ cc68 XFLSBUF
$ cc68 XFDECLS
$ cc68 CLOSE
$ cc68 CREAT
$ cc68 XEXIT
$ cc68 LSEEK
$ cc68 XFILESZ
$ cc68 OPEN
$ cc68 READ
$ cc68 XTTYIN
$ cc68 UNLINK
$ cc68 WRITE
$ cc68 XOPEN
$ cc68 ACCESS
$ cc68 GETPASS
$ cc68 TTYNAME
$ cc68 ISATTY
$ cc68 CHINIT
$ cc68 CHKC
$ cc68 BLKIO
$ cc68 ALLOCC
$ cc68 ATOI
$ cc68 ATOL
$ cc68 SWAB
$ cc68 GETPID
$ cc68 RAND
$ cc68 QSORT
$ cc68 CALLOC
$ cc68 MALLOC
$ cc68 SBRK
$ cc68 ERRNO
$ cc68 CTYPE
$ cc68 INDEX
$ cc68 RINDEX
$ cc68 STRCAT
$ cc68 STRCMP
$ cc68 STRCPY
$ cc68 STRLEN
$ cc68 STRNCAT
$ cc68 STRNCMP
$ cc68 STRNCPY
$ cc68 signal
$ cc68 xstrcmp
$ as68 -l -u ABORT.s
$ as68 -l -u ALDIV.s
$ as68 -l -u ALMUL.s
$ as68 -l -u ALREM.s
$ as68 -l -u LMUL.s
$ as68 -l -u LDIV.s
$ as68 -l -u LREM.s
$ as68 -l -u ULDIV.s
$ as68 -l -u setjmp.s
$ as68 -l -u s.s
$ as68 -l -u w.s
$ as68 -l -u nofloat.s
$ as68 -l -u blivot.s
$ as68 -l -u xsignal.s
$ @rear

View File

@@ -0,0 +1,791 @@
$1pip d:=e:as68symb.dat[g0
$1cp68 XMAIN.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic XMAIN.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u XMAIN.s
era XMAIN.s
$1cp68 XWMAIN.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic XWMAIN.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u XWMAIN.s
era XWMAIN.s
$1cp68 PERROR.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic PERROR.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u PERROR.s
era PERROR.s
$1cp68 MKTEMP.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic MKTEMP.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u MKTEMP.s
era MKTEMP.s
$1cp68 CHMOD.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic CHMOD.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u CHMOD.s
era CHMOD.s
$1cp68 CHOWN.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic CHOWN.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u CHOWN.s
era CHOWN.s
$1cp68 FPRINTF.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic FPRINTF.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u FPRINTF.s
era FPRINTF.s
$1cp68 PRINTF.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic PRINTF.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u PRINTF.s
era PRINTF.s
$1cp68 SPRINTF.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic SPRINTF.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u SPRINTF.s
era SPRINTF.s
$1cp68 XDOPRT.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic XDOPRT.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u XDOPRT.s
era XDOPRT.s
$1cp68 XPRTINT.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic XPRTINT.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u XPRTINT.s
era XPRTINT.s
$1cp68 XPRTLD.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic XPRTLD.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u XPRTLD.s
era XPRTLD.s
$1cp68 XPRTSHRT.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic XPRTSHRT.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u XPRTSHRT.s
era XPRTSHRT.s
$1cp68 FSCANF.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic FSCANF.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u FSCANF.s
era FSCANF.s
$1cp68 SCANF.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic SCANF.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u SCANF.s
era SCANF.s
$1cp68 SSCANF.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic SSCANF.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u SSCANF.s
era SSCANF.s
$1cp68 XDOSCAN.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic XDOSCAN.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u XDOSCAN.s
era XDOSCAN.s
$1cp68 FDOPEN.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic FDOPEN.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u FDOPEN.s
era FDOPEN.s
$1cp68 FOPEN.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic FOPEN.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u FOPEN.s
era FOPEN.s
$1cp68 FREOPEN.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic FREOPEN.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u FREOPEN.s
era FREOPEN.s
$1cp68 FTELL.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic FTELL.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u FTELL.s
era FTELL.s
$1cp68 REWIND.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic REWIND.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u REWIND.s
era REWIND.s
$1cp68 FSEEK.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic FSEEK.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u FSEEK.s
era FSEEK.s
$1cp68 EXIT.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic EXIT.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u EXIT.s
era EXIT.s
$1cp68 CLEANUP.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic CLEANUP.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u CLEANUP.s
era CLEANUP.s
$1cp68 FCLOSE.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic FCLOSE.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u FCLOSE.s
era FCLOSE.s
$1cp68 FFLUSH.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic FFLUSH.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u FFLUSH.s
era FFLUSH.s
$1cp68 FREAD.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic FREAD.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u FREAD.s
era FREAD.s
$1cp68 FWRITE.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic FWRITE.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u FWRITE.s
era FWRITE.s
$1cp68 FGETS.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic FGETS.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u FGETS.s
era FGETS.s
$1cp68 GETS.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic GETS.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u GETS.s
era GETS.s
$1cp68 FPUTS.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic FPUTS.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u FPUTS.s
era FPUTS.s
$1cp68 PUTS.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic PUTS.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u PUTS.s
era PUTS.s
$1cp68 GETL.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic GETL.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u GETL.s
era GETL.s
$1cp68 GETW.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic GETW.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u GETW.s
era GETW.s
$1cp68 PUTL.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic PUTL.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u PUTL.s
era PUTL.s
$1cp68 PUTW.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic PUTW.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u PUTW.s
era PUTW.s
$1cp68 UNGETC.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic UNGETC.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u UNGETC.s
era UNGETC.s
$1cp68 SETBUF.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic SETBUF.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u SETBUF.s
era SETBUF.s
$1cp68 FGETC.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic FGETC.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u FGETC.s
era FGETC.s
$1cp68 FPUTC.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic FPUTC.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u FPUTC.s
era FPUTC.s
$1cp68 XFILBUF.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic XFILBUF.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u XFILBUF.s
era XFILBUF.s
$1cp68 XFLSBUF.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic XFLSBUF.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u XFLSBUF.s
era XFLSBUF.s
$1cp68 XFDECLS.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic XFDECLS.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u XFDECLS.s
era XFDECLS.s
$1cp68 CLOSE.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic CLOSE.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u CLOSE.s
era CLOSE.s
$1cp68 CREAT.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic CREAT.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u CREAT.s
era CREAT.s
$1cp68 XEXIT.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic XEXIT.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u XEXIT.s
era XEXIT.s
$1cp68 LSEEK.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic LSEEK.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u LSEEK.s
era LSEEK.s
$1cp68 XFILESZ.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic XFILESZ.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u XFILESZ.s
era XFILESZ.s
$1cp68 OPEN.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic OPEN.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u OPEN.s
era OPEN.s
$1cp68 READ.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic READ.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u READ.s
era READ.s
$1cp68 XTTYIN.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic XTTYIN.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u XTTYIN.s
era XTTYIN.s
$1cp68 UNLINK.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic UNLINK.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u UNLINK.s
era UNLINK.s
$1cp68 WRITE.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic WRITE.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u WRITE.s
era WRITE.s
$1cp68 XOPEN.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic XOPEN.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u XOPEN.s
era XOPEN.s
$1cp68 ACCESS.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic ACCESS.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u ACCESS.s
era ACCESS.s
$1cp68 GETPASS.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic GETPASS.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u GETPASS.s
era GETPASS.s
$1cp68 TTYNAME.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic TTYNAME.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u TTYNAME.s
era TTYNAME.s
$1cp68 ISATTY.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic ISATTY.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u ISATTY.s
era ISATTY.s
$1cp68 CHINIT.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic CHINIT.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u CHINIT.s
era CHINIT.s
$1cp68 CHKC.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic CHKC.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u CHKC.s
era CHKC.s
$1cp68 BLKIO.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic BLKIO.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u BLKIO.s
era BLKIO.s
$1cp68 ALLOCC.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic ALLOCC.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u ALLOCC.s
era ALLOCC.s
$1cp68 ATOI.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic ATOI.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u ATOI.s
era ATOI.s
$1cp68 ATOL.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic ATOL.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u ATOL.s
era ATOL.s
$1cp68 SWAB.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic SWAB.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u SWAB.s
era SWAB.s
$1cp68 GETPID.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic GETPID.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u GETPID.s
era GETPID.s
$1cp68 RAND.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic RAND.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u RAND.s
era RAND.s
$1cp68 QSORT.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic QSORT.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u QSORT.s
era QSORT.s
$1cp68 CALLOC.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic CALLOC.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u CALLOC.s
era CALLOC.s
$1cp68 MALLOC.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic MALLOC.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u MALLOC.s
era MALLOC.s
$1cp68 SBRK.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic SBRK.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u SBRK.s
era SBRK.s
$1cp68 ERRNO.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic ERRNO.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u ERRNO.s
era ERRNO.s
$1cp68 exec.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic exec.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u exec.s
era exec.s
$1cp68 CTYPE.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic CTYPE.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u CTYPE.s
era CTYPE.s
$1cp68 INDEX.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic INDEX.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u INDEX.s
era INDEX.s
$1cp68 RINDEX.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic RINDEX.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u RINDEX.s
era RINDEX.s
$1cp68 STRCAT.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic STRCAT.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u STRCAT.s
era STRCAT.s
$1cp68 STRCMP.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic STRCMP.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u STRCMP.s
era STRCMP.s
$1cp68 STRCPY.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic STRCPY.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u STRCPY.s
era STRCPY.s
$1cp68 STRLEN.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic STRLEN.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u STRLEN.s
era STRLEN.s
$1cp68 STRNCAT.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic STRNCAT.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u STRNCAT.s
era STRNCAT.s
$1cp68 STRNCMP.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic STRNCMP.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u STRNCMP.s
era STRNCMP.s
$1cp68 STRNCPY.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic STRNCPY.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u STRNCPY.s
era STRNCPY.s
$1cp68 signal.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic signal.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u signal.s
era signal.s
$1cp68 xstrcmp.c $1x.i
$1c068 $1x.i $1x.ic $1x.st
$1c168 $1x.ic xstrcmp.s -LD
era $1x.i
era $1x.ic
era $1x.st
$1as68 -f $1 -l -u xstrcmp.s
era xstrcmp.s
$1as68 -f $1 -l -u ABORT.s
$1as68 -f $1 -l -u ALDIV.s
$1as68 -f $1 -l -u ALMUL.s
$1as68 -f $1 -l -u ALREM.s
$1as68 -f $1 -l -u LMUL.s
$1as68 -f $1 -l -u LDIV.s
$1as68 -f $1 -l -u LREM.s
$1as68 -f $1 -l -u ULDIV.s
$1as68 -f $1 -l -u setjmp.s
$1as68 -f $1 -l -u s.s
$1as68 -f $1 -l -u w.s
$1as68 -f $1 -l -u nofloat.s
$1as68 -f $1 -l -u blivot.s
$1as68 -f $1 -l -u xsignal.s
rear $1

View File

@@ -0,0 +1,257 @@
/********************************************************************
* malloc, free - memory allocator mechanism
*
* BYTE *malloc(numbytes)
* WORD numbytes
* Returns a pointer to an area of memory at least 'numbytes'
* in length.
* Warning: the size of the area is right below the region:
* do not overwrite!
* Returns NULL if not enough memory.
*
* free(mptr)
* BYTE *mptr
* Frees the region pointed to by 'mptr'.
* Warning: if mptr does not contain a pointer previously
* obtained from malloc, the memory structure will probably
* get corrupted!
*
* BYTE *realloc(mptr,numbytes)
* BYTE *mptr
* WORD numbytes
* Returns a pointer to a (probably different) region of memory
* (numbytes long) containing the same data as the old region
* pointed to by mptr.
* Returns NULL if not enough memory.
*
********************************************************************/
#include <portab.h>
/* malloc - general purpose memory allocator
* This function allocates the requested number of bytes (nbytes) and returns
* a pointer to this space to the calling function.
* The memory is requested from the O.S. in larger chunks, and
* free space is managed as a ring of free blocks. Each block
* contains a pointer to the next block (s.ptr), a block size (s.size),
* and the space itself.
* Alignment is handled by assuming that sizeof(FB_HDR) is an aligned
* quantity, and allocating in multiples of that size.
*/
struct hdr {
struct hdr *ptr;
UWORD size;
};
typedef struct hdr FB_HDR; /* free block header type */
MLOCAL FB_HDR _afreebase = { &_afreebase, 0 }; /* initial (empty) block */
MLOCAL FB_HDR *_aflistptr = NULL; /* ring pointer */
#define AOFFS 1 /* alignment offset: 0=byte, 1=word, 3=quad */
#define AMASK(c) ((char *)((long)(c) & (long)~AOFFS)) /* mask alignment bits */
#define AFUDGE 4 /* number multiples leeway for passing block as is */
BYTE *
malloc(nbytes)
UWORD nbytes; /* number bytes requested */
{
FB_HDR *getmemory(); /* local fn, gets from O.S. */
REG FB_HDR *cp, /* current freeblock ptr */
*pp, /* previous freeblock ptr */
*np; /* new freeblock ptr */
REG UWORD nmults; /* multiples of FB_HDR size */
nmults = 1+(nbytes+sizeof(FB_HDR)-1)/sizeof(FB_HDR);
#ifdef DEBUG4
TRACE("malloc(%ui) = %ui units\n",nbytes,nmults);
if( sizeof(FB_HDR) != AMASK(sizeof(FB_HDR)) )
TRACE("bad alignment\n");
#endif
if( _aflistptr == NULL ) { /* initialize list if needed */
_afreebase.ptr = _aflistptr = &_afreebase;
_afreebase.size = 0;
}
pp = _aflistptr; /* init prev freeblock ptr */
for( cp=pp->ptr; ; cp=(pp=cp)->ptr ) {
if( cp->size >= nmults ) {
if( cp->size <= nmults + AFUDGE) /* if size is close */
pp->ptr = cp->ptr; /* use block as is */
else { /* cut up this freeblock */
np = cp + nmults;
np->size = cp->size - nmults;
np->ptr = cp->ptr;
pp->ptr = np;
cp->size = nmults;
}
_aflistptr = pp; /* start search here next time */
return( (BYTE *)(cp+1) );
}
if( cp==_aflistptr ) /* wrapped around ring: need space */
if( (cp=getmemory(nmults)) == NULL )
return( NULL );
}
}
/* getmemory - gets memory from O.S.
* This function requests memory from the O.S. in multiples (ACHUNKS)
* of the requested number of units (numu), in order to minimize
* the number of calls to the O.S.
* Function cleans up pointer alignment and adds to free list.
*/
#define ACHUNKS 64 /* chunks to alloc from O.S.*/
MLOCAL FB_HDR *
getmemory(numu)
UWORD numu; /* number of units */
{
BYTE *sbrk(); /* obtain memory from O.S. */
REG BYTE *mmp; /* more memory pointer */
REG FB_HDR *fbp; /* free block pointer */
REG WORD utg; /* units to get */
#ifdef DEBUG4
TRACE(" getmemory ");
#endif
utg = ACHUNKS * ((numu+ACHUNKS-1) / ACHUNKS);
mmp = sbrk(utg * sizeof(FB_HDR)); /* sbrk wants number of bytes */
if( mmp == (char *)-1 ) /* sbrk = -1 means no memory available */
return( NULL );
mmp = AMASK(mmp + AOFFS); /* alignment handling: nop if good sbrk */
fbp = (FB_HDR *)mmp;
fbp->size = utg;
free( (BYTE *)(fbp+1) ); /* add to free list */
return(_aflistptr); /* set in 'free' */
}
/* free - adds memory back to free block list.
* This function assumes freed memory pointer (fmp) points to free space
* preceeded by a FB_HDR structure.
* Note that free block is inserted in memory address order,
* to facilitate compaction.
* Disaster if random pointer is linked into this list.
*/
VOID
free(fmp)
BYTE *fmp;
{
REG FB_HDR *cp, /* current freeblk ptr */
*pp; /* previous freeblk ptr */
cp = (FB_HDR *)fmp - 1; /* backup pointer to before struct */
#ifdef DEBUG4
TRACE("free, size=%ui ",cp->size);
#endif
for( pp=_aflistptr; /* start where we left off before */
!( cp>pp && cp < pp->ptr ); /*break if right place */
pp=pp->ptr ) {
if( pp >= pp->ptr && (cp < pp->ptr || cp>pp) )
break; /* break also if either end of list */
if( cp==pp ) { /* block has already been freed */
_aflistptr = pp; /* that's okay */
return;
}
}
#ifdef DEBUG4
if( cp>pp && cp < pp->ptr ) { /* if cp is within the list */
if( cp+cp->size > pp->ptr ) /* ASSERT */
TRACE("\t*** OVERLAPPING HI BLK ***\n");
if( pp+pp->size > cp ) /* ASSERT */
TRACE("\t*** OVERLAPPING LO BLK\n");
}
#endif
if( cp+cp->size == pp->ptr ) { /* check if we can merge w. next blk */
cp->size += pp->ptr->size;
cp->ptr = pp->ptr->ptr;
#ifdef DEBUG4
TRACE("++free merge hi(%ui)++",cp->size);
#endif
} else
cp->ptr = pp->ptr;
if( pp+pp->size == cp ){ /* check if we can merge w. prev blk */
pp->size += cp->size;
pp->ptr = cp->ptr;
#ifdef DEBUG4
TRACE("--free merge lo(%ui)-- ",pp->size);
#endif
} else
pp->ptr = cp;
#ifdef DEBUG4
TRACE("\n");
#endif
_aflistptr = pp; /* search from here next time */
}
BYTE *
realloc(ptr,siz)
BYTE *ptr;
UWORD siz;
{
BYTE *np, *np2;
FB_HDR *fp;
UWORD ss;
#ifdef DEBUG4
TRACE("realloc(,%ui)",siz);
#endif
fp = ((FB_HDR *)ptr) - 1;
ss = sizeof(FB_HDR) * fp->size; /* get size of old (in bytes) */
if( (np=malloc(siz)) == NULL)
return( NULL );
free(ptr); /* this would be nicer before the malloc... */
#ifdef DEBUG4
TRACE(" moved %i bytes\n",np-ptr);
#endif
if( ptr != np ) { /* don't copy if hasn't changed */
if( siz < ss )
ss = siz; /* ss = min(ss,siz) */
if( np < ptr )
for( np2=np; ss; ss-- )
*np2++ = *ptr++; /* copy up */
else
for( np2=np+ss, ptr+=ss; ss; ss-- )
*--np2 = *--ptr; /* copy down */
}
return( np );
}
#ifdef DEBUG
VOID
printstats()
{
FB_HDR *fp;
UWORD nblk=0, nbyt=0;
double abyt;
if( (fp=_aflistptr) != NULL ) {
nblk++;
nbyt += fp->size;
for( fp=fp->ptr; fp != _aflistptr; fp = fp->ptr ){
nblk++;
nbyt += fp->size;
}
}
nbyt *= sizeof(FB_HDR);
abyt = 0;
if( nblk>1 )
abyt = nbyt / (nblk-1); /* avg blk size */
TRACE("\n\tmalloc free blocks=%ui bytes=%ui Avg size=%4.2f\n",
nblk,nbyt,abyt);
}
#endif

View File

@@ -0,0 +1,38 @@
/***********************************************************************
*
* m k t e m p F u n c t i o n
* -----------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "mktemp" assumes it is called with a string ending in 6 X's.
* It will replace the last 6 chars with the process id
* and a letter (different on each invocation).
* REALLY "mktemp" replaces everything after the 1st x...
* this is a feature...
* Note that the process id does not change under CP/M,
* therefore the name itself will not be very unique...
*
* Calling sequence:
* string = mktemp(string)
* Where:
* string -> null terminated string with 6 x's
*
*************************************************************************/
#include <stdio.h>
MLOCAL BYTE _mktchar = { 'A' };
BYTE *mktemp(st)
BYTE *st;
{
BYTE *ss;
for( ss=st; *ss != 'x' && *ss != 'X'; ss++)
if(*ss == NULL)
return(st); /* resign */
if( _mktchar < 'A' || _mktchar >'Z' )
_mktchar = 'A';
sprintf(ss,"X%04.4d%c",getpid(),_mktchar);
_mktchar++;
return(st);
}

View File

@@ -0,0 +1 @@
user 12 ! make

View File

@@ -0,0 +1,21 @@
*
* This module is designed to allow the use of "printf" without
* dragging in the entire floating point RTL.
*
.globl nofloat
.globl _petoa * Called from "_doprt"
.globl _pftoa * Called from "_doprt"
nofloat:
_petoa:
_pftoa:
move.l #9,d0 * Print string BDOS Call
move.l #fpstring,d1 * d1 -> string to print
trap #2 * Print the error
clr.l d0 * Now
trap #2 * exit
.data *
fpstring:
.dc.b 'C RTL -- Program not linked for floating point'
.dc.b $0d,$0a,'$'
.even

View File

@@ -0,0 +1,84 @@
/****************************************************************************
*
* C F I L E O P E N R O U T I N E
* -------------------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* The "open" routine opens a "C" file and returns a file id.
* Comes in 3 flavors, one for ascii, one for binary, and the default
* (currently to ascii).
*
* Calling Sequence:
* fid = open(fname,mode)
* fid = opena(fname,mode)
* fid = openb(fname,mode)
* fid = _open(fname,mode,type);
*
* Where:
* fname is the address of a null terminated file name.
* mode is the open mode:
* 0 => READ access only
* 1 => WRITE access only
* 2 => Both READ and WRITE
* type is 0 for ASCII files, 1 for BINARY
*
*****************************************************************************/
#include <portab.h> /* */
#include <cpm.h> /* */
#include <errno.h> /* */
EXTERN BYTE __tname[]; /* -> Terminal name */
EXTERN BYTE __lname[]; /* -> List device name */
WORD open (f,m)
BYTE *f; WORD m;
{ return(_open(f,m,0)); } /* default to ascii */
WORD opena (f,m)
BYTE *f; WORD m;
{ return(_open(f,m,0)); } /* open ascii file */
WORD openb (f,m)
BYTE *f; WORD m;
{ return(_open(f,m,1)); } /* open binary file */
WORD _open (fname,mode,xtype) /****************************/
BYTE *fname; /* -> File name */
WORD mode; /* Open mode */
WORD xtype; /* File type */
{ /****************************/
REG WORD ich; /* Channel number for open */
REG FD *ch; /* -> CCB for channel */
/* */
if((ich = allocc()) < 0) /* Allocate a channel */
return (FAILURE); /* Can't */
/* */
__chinit(ich); /* Clear out channel's ccb */
ch = _getccb(ich); /* Get address of ccb */
/* */
if(mode == READ) /* If read only, */
ch -> flags |= ISREAD; /* set READONLY bit*/
if(xtype == 0) /* Is ASCII file? */
ch -> flags |= ISASCII; /* Yes, mark it */
/* */
if(_strcmp(fname,__tname) == 0) /* if a terminal */
{ /* */
ch->flags |= ISTTY|OPENED; /* mark as tty */
return(ich); /* Return file descriptor */
} /****************************/
else if(_strcmp(fname,__lname) == 0) /* List device? */
{ /* */
ch->flags |= ISLPT|OPENED; /* Mark as printer */
return(ich); /* Return file descriptor */
} /* */
/****************************/
if(__open(ich,fname,OPEN) != 0) /* Use POS SVC interface */
{ /* */
freec(ich); /* deallocate channel */
RETERR(FAILURE,ENOENT); /* If return <> 0, NFG. */
} /****************************/
/* Else: */
ch -> flags |= OPENED; /* Set OPEN bit */
lseek(ch->chan, 0L, 2); /* Kludge to set */
lseek(ch->chan, 0L, 0); /* hiwater mark */
return(ich); /* Return Channel # */
} /****************************/

View File

@@ -0,0 +1,106 @@
/***********************************************************************
*
* p e r r o r F u n c t i o n
* -----------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "perror" produces a short error message on stderr describing
* the last error encountered during a call to the system.
* It assumes the variable "errno" contains this error.
* Note: "errno" is set when errors occur, but is not cleared.
* Note also that some of the UNIX errors are meaningless under
* CP/M, and will print an undefined message (defined below).
* Finally, note that the defines in """errno.h""" will index
* appropriately into the sys_errlist table, below.
*
* Calling sequence:
* ret = perror(s)
* Where:
* ret = errno
* s -> a string containing a message printed with
* the explanatory error message.
*
**************************************************************************/
#include <stdio.h>
#include <cpm.h>
#define NUMERRS 36
#define STDERR 2
MLOCAL BYTE _undeferr[] = "Error undefined on CP/M" ;
WORD sys_nerr = NUMERRS;
perror(s)
BYTE *s;
{
BYTE *err;
BYTE lbuf[20], *buf, *_itoa();
EXTERN BYTE *sys_errlist[];
if( errno<0 || errno>=sys_nerr )
err = _undeferr;
else err = sys_errlist[errno];
write(STDERR,s,strlen(s));
write(STDERR,": ",2);
write(STDERR,err,strlen(err));
write(STDERR," (",2);
buf = _itoa(errno,lbuf);
if( _errcpm != 0 ) /* assume this had something to do */
{
*buf++ = '.';
buf = _itoa(_errcpm,buf);
}
*buf++ = ')'; *buf++ = '\n'; *buf = ZERO;
write(STDERR,lbuf,strlen(lbuf));
return(errno);
}
MLOCAL BYTE *_itoa(nm,bp)
WORD nm;
BYTE *bp;
{
/* temporary... */
sprintf(bp,"%d",nm);
while(*bp) bp++;
return(bp);
}
BYTE *sys_errlist[NUMERRS] = {
_undeferr, /* 0 */
_undeferr, /* 1 */
"ENOENT No such file", /* 2 */
_undeferr, /* 3 */
_undeferr, /* 4 */
"EIO I/O error", /* 5 */
_undeferr, /* 6 */
"E2BIG Arg list too long", /* 7 */
_undeferr, /* 8 */
"EBADF Bad file number", /* 9 */
_undeferr, /* 10 */
_undeferr, /* 11 */
"ENOMEM Not enough core", /* 12 */
"EACCES Permission denied", /* 13 */
_undeferr, /* 14 */
_undeferr, /* 15 */
_undeferr, /* 16 */
_undeferr, /* 17 */
_undeferr, /* 18 */
_undeferr, /* 19 */
_undeferr, /* 20 */
_undeferr, /* 21 */
"EINVAL Invalid argument", /* 22 */
"ENFILE File table overflow", /* 23 */
"EMFILE Too many open files", /* 24 */
"ENOTTY Not a typewriter", /* 25 */
_undeferr, /* 26 */
"EFBIG File too big", /* 27 */
"ENOSPC No space left on device",/* 28 */
_undeferr, /* 29 */
"EROFS Read-only file system", /* 30 */
_undeferr, /* 31 */
_undeferr, /* 32 */
_undeferr, /* 33 */
_undeferr, /* 34 */
/* end of UNIX v7, start of CPM specific */
"ENODSPC No directory space" /* 35 */
};

View File

@@ -0,0 +1,54 @@
/*****************************************************************************
*
* 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 ALCYON 1 /* using Alcyon compiler */
/*
* 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 DEFAULT int /* Default size */
#define FLOAT float /* Floating point */
#define DOUBLE double /* Double precision */
/***************************/
#ifdef ALCYON
#define UBYTE char
#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 ZERO 0 /* Zero value */
#define EOF (-1) /* EOF Value */
#define TRUE (1) /* Function TRUE value */
#define FALSE (0) /* Function FALSE value */
/*************************** end of portab.h ********************************/

View File

@@ -0,0 +1,24 @@
/************************************************************************
*
* p r i n t f F u n c t i o n
* -----------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "printf" prints args specified in format string to stdout.
*
* Calling sequence:
* nchrs = printf(fmt,arg1,arg2,...argn);
* Where:
* nchrs = # chars output by printf
* fmt -> a string specifying how arg1-n are to be printed.
*
**************************************************************************/
#include <stdio.h>
WORD printf(fmt,args)
BYTE *fmt,
*args;
{
return(_doprt(stdout,fmt,&args));
}

View File

@@ -0,0 +1,33 @@
/**************************************************************************
*
* p u t l F u n c t i o n
* -------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "putl" puts a LONG (4 byte) value into the output stream.
* Note that what's written (binary) by a UNIX (lo byte, hi byte)
* system (PDP 11) will NOT be compatible with what's written by a
* NUXI (hi byte, lo byte) system (68K).
*
* Calling sequence:
* ret = putl(l, stream)
* Where:
* ret = l or FAILURE on error
* l = an LONG value
* stream-> a (FILE *) output stream
*
*****************************************************************************/
#include <stdio.h>
LONG putl(l,sp) /****************************/
LONG l; /* the LONG to be put */
FILE *sp; /* the stream to put to */
{ /* */
WORD i; /* index */
BYTE *p; /* make ptr to w */
/****************************/
p = (char *)&l; /* point to l */
for( i=0; i<4; i++ ) /* for all the 4 bytes in l */
if( putc((*p++)&0xff,sp)== FAILURE )/* put dem */
return(FAILURE); /* */
return(l); /* it worked */
} /****************************/

View File

@@ -0,0 +1,25 @@
/**************************************************************************
*
* p u t s F u n c t i o n
* -------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "puts" copies a null terminated string to the standard output.
* It copies a newline char after the end of the string.
*
* Calling sequence:
* ret = puts(s)
* Where:
* s = string to put
* ret = last char output
*
*****************************************************************************/
#include <stdio.h>
WORD puts(s) /****************************/
BYTE *s; /* null term string */
{ /****************************/
while(*s) /* for all chars in s */
if(putc(*s++,stdout) == FAILURE) /* if putc fouls up */
return(FAILURE); /* give up */
return( putc('\n',stdout) ); /* append newline & return */
} /****************************/

View File

@@ -0,0 +1,33 @@
/**************************************************************************
*
* p u t w F u n c t i o n
* -------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "putw" puts a word (2 byte) value into the output stream.
* Note that what's written (binary) by a UNIX (lo byte, hi byte)
* system (PDP 11) will NOT be compatible with what's written by a
* NUXI (hi byte, lo byte) system (68K).
*
* Calling sequence:
* ret = putw(w, stream)
* Where:
* ret = w or FAILURE on error
* w = an int word value
* stream-> a (FILE *) output stream
*
******************************************************************************/
#include <stdio.h>
WORD putw(w,sp) /****************************/
int w; /* the word to be put */
FILE *sp; /* the stream to put to */
{ /* */
WORD i; /* index */
BYTE *p; /* make ptr to w */
/****************************/
p = (char *)&w; /* point to w */
for( i=0; i<2; i++ ) /* for all the 2 bytes in w */
if( putc((*p++)&0xff,sp)==FAILURE ) /* put dem */
return(FAILURE); /* */
return(w); /* it worked */
} /****************************/

View File

@@ -0,0 +1,80 @@
/**************************************************************************
*
* q s o r t F u n c t i o n
* ---------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "qsort" sorts the "number" of items, each of length "size", starting
* at "base", using function "compare" to compare 2 items in the vector.
*
* Calling sequence:
* ret = qsort(base,number,size,compar)
* Where:
* ret = always 0
* base -> start of items vector
* number = number of elements in vector
* size = number of bytes per item in vector
* compar -> comparator function, taking ptrs to items,
* returning WORD:
* compar(a,b) < 0 if *a < *b
* compar(a,b) == 0 if *a == *b
* compar(a,b) > 0 if *a > *b
*
* "qsort" uses the quicksort algorithm by C.A.R. Hoare.
* Ref: "Software Tools in Pascal" by Kernighan & Plauger.
*****************************************************************************/
#include <portab.h>
#define LINEPOS(nn) ((nn)*siz + bas)
#define EXCHANGE(aa,bb) _swap(aa,bb,siz)
WORD qsort(bas,num,siz,cmp)
BYTE *bas;
WORD num;
WORD siz;
WORD (*cmp)();
{
REG WORD i,j;
REG BYTE *pivline;
if( num > 1 )
{
i = 0;
j = num-1;
pivline = LINEPOS(j); /* choose last line for pvt */
do{
while( i<j && (*cmp)(LINEPOS(i),pivline) <= 0 )
i++;
while( j>i && (*cmp)(LINEPOS(j),pivline) >= 0 )
j--;
if( i<j ) /* out of order pair */
EXCHANGE(LINEPOS(i),LINEPOS(j));
}while( i<j );
EXCHANGE(LINEPOS(i),pivline);
if( i < num-1-i ) /* sort shorter subset 1st */
{
qsort( bas, i, siz, cmp);
qsort( LINEPOS(i+1), num-1-i, siz, cmp);
} else
{
qsort( LINEPOS(i+1), num-1-i, siz, cmp);
qsort( bas, i, siz, cmp);
}
}
return(0);
}
VOID _swap(a,b,wid)
REG BYTE *a;
REG BYTE *b;
REG WORD wid;
{
REG BYTE tmp;
if( a != b )
for( ; wid-- > 0; a++, b++ )
{
tmp = *a;
*a = *b;
*b = tmp;
}
}

View File

@@ -0,0 +1,35 @@
/* rand.c - kluges a random number generator with addition & overflow */
#include <portab.h>
#define NSEEDS 7
MLOCAL UWORD _seeds[NSEEDS] =
{ 0, 24213, 12345, 4622, 2143, 32010, 7942 };
MLOCAL WORD _seedptr=0;
WORD srand(seed1)
int seed1;
{
WORD ncs;
_seeds[0] = seed1;
for( ncs = seed1&077; ncs; ncs-- )
rand();
return(rand());
}
WORD rand()
{
UWORD tot, ii;
for( tot=0, ii=0; ii<NSEEDS; ii++)
tot += _seeds[ii]; /* ignore overflow */
if( ++_seedptr >= NSEEDS )
_seedptr = 0;
_seeds[_seedptr] = tot;
return( tot >> 1 ); /* ignore lo bit because of addition */
}

View File

@@ -0,0 +1,231 @@
/****************************************************************************/
/* */
/* R e a d F u n c t i o n */
/* ------------------------- */
/* Copyright 1982 by Digital Research Inc. All rights reserved. */
/* */
/* The read function simulates the UNIX read system call. Any */
/* arbitrary number of bytes may be read at any arbitrary offset in */
/* the file. */
/* The terminal handler for read has been set up to simulate some of */
/* the functions provided by "ioctl". */
/* */
/* Calling Sequence: */
/* ret = read(fd,buffer,bytes); */
/* Where: */
/* ret Is the number of bytes which were actually read */
/* fd Is an open file descriptor */
/* buffer Is the buffer address */
/* bytes Is the number of bytes to read */
/* */
/****************************************************************************/
#include <portab.h>
#include <cpm.h>
#include <errno.h>
WORD read(fd,buff,pbytes) /****************************/
WORD fd; /* File descriptor */
REG BYTE *buff; /* -> buffer start */
UWORD pbytes; /* = byte count to read */
{ /****************************/
REG FD *fp; /* -> ccb to read from */
EXTERN FD *_chkc(); /* Converts fd to fp */
LOCAL LONG ofs; /* Offset temporary */
LOCAL LONG xbytes; /* Bytes temporary */
REG LONG xsector; /* Sector temporary */
REG BYTE c; /* Character temporary */
REG BYTE *p1; /* Char pointer temporary */
REG LONG bytes; /* Byte convertor */
/****************************/
bytes = (LONG) pbytes; /* Convert to long */
/* */
if((fp=_chkc(fd)) == NULL) /* File open & OK?? */
return(FAILURE); /* */
if((fp->flags & ATEOF) != 0) /* End of file already? */
return(0); /* Yes, quit now */
if((fp->flags & ISLPT) != 0) /* A wise guy?? */
RETERR(FAILURE,EBADF); /* A wise guy!! */
/****************************/
if((fp->flags & ISTTY) != 0) /* TTY? */
return(_ttyin(fp,buff,bytes)); /* Yes, read 1 line */
/****************************/
if((fp->flags & ISASCII) == 0) /* ASCII?? */
return(_rdbin(fp,buff,bytes)); /* No, read binary */
/****************************/
/****************************************************************************/
/* Read loop for ASCII data ... */
/****************************************************************************/
xbytes = bytes; /* Remember org. request */
while(bytes > 0) /* Until read is satisfied */
{ /****************************/
xsector = fp->offset >> 7; /* Calc starting sector */
if(xsector != fp->sector) /* Match sector in buffer?? */
{ /* No, must read first */
/****************************/
if((fp->flags & DIRTY) != 0) /* Buffer dirty?? */
{ /* Yes, must write it */
if(_blkio(fp,fp->sector,fp->buffer, /* Try to write buffer */
1L,B_WRITE) != 1) /* */
RETERR(FAILURE,EIO); /* Unable to write, quit */
fp->flags &= ~DIRTY; /* Wipe dirty bit */
} /****************************/
if(_blkio(fp,xsector,fp->buffer,1L, /* Read proper sector */
B_READ) != 1) /* */
{ /* Assume no sparse ascii fs*/
fp->flags |= ATEOF; /* Set EOF flag */
return(xbytes-bytes); /* Do partial read */
}
fp->sector = xsector; /* Mark buffer correctly */
} /****************************/
ofs = fp->offset & (SECSIZ-1); /* correct buffer offset */
p1 = &(fp->buffer[ofs]); /* Load byte pointer */
/* */
while(p1 < &(fp->buffer[SECSIZ]) && /* Ie, more data in buffer */
bytes > 0) /* And request not satisfied*/
{ /* */
c = *p1; /* Pick up next character */
if(c==EOFCHAR) /* ^Z?? */
{ /* Yes, */
fp->flags |= ATEOF; /* Set EOF flag */
if(fp->offset > fp->hiwater) /* set hiwater mark */
fp->hiwater = fp->offset; /* if necessary */
return(xbytes-bytes); /* Return number read */
} /****************************/
else if (c == '\r') /* Carriage return? */
{ /* */
p1++; /* Yes, just ignore that */
fp->offset++; /* Increment file offset */
} /* */
else /****************************/
{ /* Regular character */
*buff++ = c; /* Load buffer with byte */
bytes--; /* Decrement count */
p1++; /* increment counter */
fp->offset++; /* Increment file offset */
} /****************************/
} /* */
} /* While bytes > 0 */
if(fp->offset > fp->hiwater) /* Fix up hiwater mark */
fp->hiwater = fp->offset; /* */
return(xbytes); /* Read fully satisfied */
} /****************************/
/****************************************************************************/
/* */
/* R d b i n F u n c t i o n */
/* --------------------------- */
/* */
/* The "_rdbin" function performs a read operation for binary files. */
/* */
/* Calling Sequence: */
/* ret = _rdbin(fp,buffer,bytes); */
/* Where: */
/* fp -> to the open CCB */
/* buffer -> the user's buffer */
/* bytes = the number of bytes to be read */
/* */
/* ret = the number of bytes actually read */
/* */
/****************************************************************************/
WORD _rdbin(fp,buff,bytes) /****************************/
/* */
REG FD *fp; /* -> ccb for the file */
REG BYTE *buff; /* -> buffer to receive data*/
REG LONG bytes; /* = # bytes to xfer */
{ /****************************/
REG BYTE *p; /* Temp byte pointer */
LOCAL LONG xsector; /* Temp sector number */
LOCAL LONG nsector; /* Multi-sector count */
LOCAL LONG xbytes; /* byte count temp */
REG LONG i; /* Temp index */
/****************************/
xbytes = bytes; /* Preserve org byte cnt */
xsector = fp->offset >> 7; /* Calculate starting sector*/
/* */
if((fp->offset & (SECSIZ-1)) != 0) /* If not on boundary, */
{ /* must buffer */
if(fp->sector != xsector) /* Do sectors match? */
{ /* */
if((fp->flags & DIRTY) != 0) /* Buffer dirty? */
{ /* */
if(_blkio(fp,fp->sector, /* */
fp->buffer,1L,B_WRITE) != 1) /* Try to write old buffer */
RETERR(FAILURE,EIO); /* Can't; just quit. */
fp->flags &= ~DIRTY; /* not dirty anymore */
} /****************************/
if(_blkio(fp,xsector,fp->buffer, /* Now read the */
1L,B_READ) != 1) /* next sector */
RETERR(FAILURE,EIO); /* Must be EOF */
fp->sector = xsector; /* Mark buffer */
} /****************************/
p = &fp->buffer[fp->offset&(SECSIZ-1)];/* Compute buffer offset */
/* */
while(p < &(fp->buffer[SECSIZ]) && /* Move the bytes */
bytes > 0) /* */
{ /* */
*buff++ = *p++; /* Copy data byte */
bytes--; /* Decrement byte counter */
fp->offset++; /* Increment offset */
} /****************************/
if(bytes == 0) /* Zero byte count now? */
{ /* */
if(fp->offset > fp->hiwater) /* Adjust hiwater if */
fp->hiwater=fp->offset; /* necessary */
return(xbytes); /* Yes, just return */
} /* */
xsector++; /* Bump sector pointer */
} /****************************/
/****************************************************************************/
/* At this point, a multi-sector transfer may be accomplished. */
/****************************************************************************/
/* */
i = 0; /* In case no xfer */
nsector = bytes >> 7; /* Compute number of sectors*/
if(nsector > 0) /* need to transfer?? */
i=_blkio(fp,xsector,buff,nsector, /* Do the */
B_READ); /* transfer */
/* */
xsector += i; /* Update sector counter */
fp->offset += i*SECSIZ; /* Update offset */
bytes -= i*SECSIZ; /* Update byte count */
buff += i*SECSIZ; /* Update buffer address */
/* */
if(fp->offset > fp->hiwater) /* Adjust hiwater */
fp->hiwater = fp->offset; /* if needed */
if (i != nsector) /* Short read?? */
{ /* */
fp->flags |= ATEOF; /* set EOF Flag */
return(xbytes - bytes); /* Return actual read count */
} /****************************/
if(bytes == 0) /* Done? */
return(xbytes); /* Yes, return */
/****************************/
if((fp->flags & DIRTY) != 0) /* Buffer dirty? */
{ /* This can be true for */
if(_blkio(fp,fp->sector, /* boundary conditions */
fp->buffer,1L,B_WRITE) != 1) /* Try to write old buffer */
RETERR(FAILURE,EIO); /* Can't; just quit. */
fp->flags &= ~DIRTY; /* not dirty anymore */
} /****************************/
if(_blkio(fp,xsector,fp->buffer,1L, /* Read into buffer */
B_READ) != 1) /* */
{ /* */
fp->flags |= ATEOF; /* End of file */
return(xbytes-bytes); /* return corrected count */
} /****************************/
/* */
fp->sector = xsector; /* Update data area */
fp->offset += bytes; /* Increment offset */
if(fp->offset > fp->hiwater) /* Adjust high water mark */
fp->hiwater = fp->offset; /* if necessary */
p = &fp->buffer[0]; /* Start with 1st byte */
while (bytes > 0) /* Count down */
{ /* bytes */
*buff++ = *p++; /* Move a byte */
bytes--; /* Down count */
} /****************************/
return(xbytes); /* Return requested length */
} /****************************/

View File

@@ -0,0 +1,231 @@
/****************************************************************************/
/* */
/* R e a d F u n c t i o n */
/* ------------------------- */
/* Copyright 1982 by Digital Research Inc. All rights reserved. */
/* */
/* The read function simulates the UNIX read system call. Any */
/* arbitrary number of bytes may be read at any arbitrary offset in */
/* the file. */
/* The terminal handler for read has been set up to simulate some of */
/* the functions provided by "ioctl". */
/* */
/* Calling Sequence: */
/* ret = read(fd,buffer,bytes); */
/* Where: */
/* ret Is the number of bytes which were actually read */
/* fd Is an open file descriptor */
/* buffer Is the buffer address */
/* bytes Is the number of bytes to read */
/* */
/****************************************************************************/
#include <portab.h>
#include <cpm.h>
#include <errno.h>
WORD read(fd,buff,pbytes) /****************************/
WORD fd; /* File descriptor */
REG BYTE *buff; /* -> buffer start */
WORD pbytes; /* = byte count to read */
{ /****************************/
REG FD *fp; /* -> ccb to read from */
EXTERN LONG _chkc(); /* Converts fd to fp */
LOCAL LONG ofs; /* Offset temporary */
LOCAL LONG xbytes; /* Bytes temporary */
REG LONG xsector; /* Sector temporary */
REG BYTE c; /* Character temporary */
REG BYTE *p1; /* Char pointer temporary */
REG LONG bytes; /* Byte convertor */
/****************************/
bytes = (LONG) pbytes; /* Convert to long */
/* */
if((LONG)(fp=_chkc(fd)) == FAILURE) /* File open & OK?? */
return(FAILURE); /* */
if((fp->flags & ATEOF) != 0) /* End of file already? */
return(0); /* Yes, quit now */
if((fp->flags & ISLPT) != 0) /* A wise guy?? */
RETERR(FAILURE,EBADF); /* A wise guy!! */
/****************************/
if((fp->flags & ISTTY) != 0) /* TTY? */
return(_ttyin(fp,buff,bytes)); /* Yes, read 1 line */
/****************************/
if((fp->flags & ISASCII) == 0) /* ASCII?? */
return(_rdbin(fp,buff,bytes)); /* No, read binary */
/****************************/
/****************************************************************************/
/* Read loop for ASCII data ... */
/****************************************************************************/
xbytes = bytes; /* Remember org. request */
while(bytes > 0) /* Until read is satisfied */
{ /****************************/
xsector = fp->offset >> 7; /* Calc starting sector */
if(xsector != fp->sector) /* Match sector in buffer?? */
{ /* No, must read first */
/****************************/
if((fp->flags & DIRTY) != 0) /* Buffer dirty?? */
{ /* Yes, must write it */
if(_blkio(fp,fp->sector,fp->buffer, /* Try to write buffer */
1L,B_WRITE) != 1) /* */
RETERR(FAILURE,EIO); /* Unable to write, quit */
fp->flags &= ~DIRTY; /* Wipe dirty bit */
} /****************************/
if(_blkio(fp,xsector,fp->buffer,1L, /* Read proper sector */
B_READ) != 1) /* */
{ /* Assume no sparse ascii fs*/
fp->flags |= ATEOF; /* Set EOF flag */
return(xbytes-bytes); /* Do partial read */
}
fp->sector = xsector; /* Mark buffer correctly */
} /****************************/
ofs = fp->offset & (SECSIZ-1); /* correct buffer offset */
p1 = &(fp->buffer[ofs]); /* Load byte pointer */
/* */
while(p1 < &(fp->buffer[SECSIZ]) && /* Ie, more data in buffer */
bytes > 0) /* And request not satisfied*/
{ /* */
c = *p1; /* Pick up next character */
if(c==EOFCHAR) /* ^Z?? */
{ /* Yes, */
fp->flags |= ATEOF; /* Set EOF flag */
if(fp->offset > fp->hiwater) /* set hiwater mark */
fp->hiwater = fp->offset; /* if necessary */
return(xbytes-bytes); /* Return number read */
} /****************************/
else if (c == '\r') /* Carriage return? */
{ /* */
p1++; /* Yes, just ignore that */
fp->offset++; /* Increment file offset */
} /* */
else /****************************/
{ /* Regular character */
*buff++ = c; /* Load buffer with byte */
bytes--; /* Decrement count */
p1++; /* increment counter */
fp->offset++; /* Increment file offset */
} /****************************/
} /* */
} /* While bytes > 0 */
if(fp->offset > fp->hiwater) /* Fix up hiwater mark */
fp->hiwater = fp->offset; /* */
return(xbytes); /* Read fully satisfied */
} /****************************/
/****************************************************************************/
/* */
/* R d b i n F u n c t i o n */
/* --------------------------- */
/* */
/* The "_rdbin" function performs a read operation for binary files. */
/* */
/* Calling Sequence: */
/* ret = _rdbin(fp,buffer,bytes); */
/* Where: */
/* fp -> to the open CCB */
/* buffer -> the user's buffer */
/* bytes = the number of bytes to be read */
/* */
/* ret = the number of bytes actually read */
/* */
/****************************************************************************/
WORD _rdbin(fp,buff,bytes) /****************************/
/* */
REG FD *fp; /* -> ccb for the file */
REG BYTE *buff; /* -> buffer to receive data*/
REG LONG bytes; /* = # bytes to xfer */
{ /****************************/
REG BYTE *p; /* Temp byte pointer */
LOCAL LONG xsector; /* Temp sector number */
LOCAL LONG nsector; /* Multi-sector count */
LOCAL LONG xbytes; /* byte count temp */
REG LONG i; /* Temp index */
/****************************/
xbytes = bytes; /* Preserve org byte cnt */
xsector = fp->offset >> 7; /* Calculate starting sector*/
/* */
if((fp->offset & (SECSIZ-1)) != 0) /* If not on boundary, */
{ /* must buffer */
if(fp->sector != xsector) /* Do sectors match? */
{ /* */
if((fp->flags & DIRTY) != 0) /* Buffer dirty? */
{ /* */
if(_blkio(fp,fp->sector, /* */
fp->buffer,1L,B_WRITE) != 1) /* Try to write old buffer */
RETERR(FAILURE,EIO); /* Can't; just quit. */
fp->flags &= ~DIRTY; /* not dirty anymore */
} /****************************/
if(_blkio(fp,xsector,fp->buffer, /* Now read the */
1L,B_READ) != 1) /* next sector */
RETERR(FAILURE,EIO); /* Must be EOF */
fp->sector = xsector; /* Mark buffer */
} /****************************/
p = &fp->buffer[fp->offset&(SECSIZ-1)];/* Compute buffer offset */
/* */
while(p < &(fp->buffer[SECSIZ]) && /* Move the bytes */
bytes > 0) /* */
{ /* */
*buff++ = *p++; /* Copy data byte */
bytes--; /* Decrement byte counter */
fp->offset++; /* Increment offset */
} /****************************/
if(bytes == 0) /* Zero byte count now? */
{ /* */
if(fp->offset > fp->hiwater) /* Adjust hiwater if */
fp->hiwater=fp->offset; /* necessary */
return(xbytes); /* Yes, just return */
} /* */
xsector++; /* Bump sector pointer */
} /****************************/
/****************************************************************************/
/* At this point, a multi-sector transfer may be accomplished. */
/****************************************************************************/
/* */
i = 0; /* In case no xfer */
nsector = bytes >> 7; /* Compute number of sectors*/
if(nsector > 0) /* need to transfer?? */
i=_blkio(fp,xsector,buff,nsector, /* Do the */
B_READ); /* transfer */
/* */
xsector += i; /* Update sector counter */
fp->offset += i*SECSIZ; /* Update offset */
bytes -= i*SECSIZ; /* Update byte count */
buff += i*SECSIZ; /* Update buffer address */
/* */
if(fp->offset > fp->hiwater) /* Adjust hiwater */
fp->hiwater = fp->offset; /* if needed */
if (i != nsector) /* Short read?? */
{ /* */
fp->flags |= ATEOF; /* set EOF Flag */
return(xbytes - bytes); /* Return actual read count */
} /****************************/
if(bytes == 0) /* Done? */
return(xbytes); /* Yes, return */
/****************************/
if((fp->flags & DIRTY) != 0) /* Buffer dirty? */
{ /* This can be true for */
if(_blkio(fp,fp->sector, /* boundary conditions */
fp->buffer,1L,B_WRITE) != 1) /* Try to write old buffer */
RETERR(FAILURE,EIO); /* Can't; just quit. */
fp->flags &= ~DIRTY; /* not dirty anymore */
} /****************************/
if(_blkio(fp,xsector,fp->buffer,1L, /* Read into buffer */
B_READ) != 1) /* */
{ /* */
fp->flags |= ATEOF; /* End of file */
return(xbytes-bytes); /* return corrected count */
} /****************************/
fp->sector = xsector; /* Mark buffer (MDF) */
/* */
fp->offset += bytes; /* Increment offset */
if(fp->offset > fp->hiwater) /* Adjust high water mark */
fp->hiwater = fp->offset; /* if necessary */
p = &fp->buffer[0]; /* Start with 1st byte */
while (bytes > 0) /* Count down */
{ /* bytes */
*buff++ = *p++; /* Move a byte */
bytes--; /* Down count */
} /****************************/
return(xbytes); /* Return requested length */

View File

@@ -0,0 +1,22 @@
$ set noon
$ clib
$ !
$ ! Re-archive the stuff ...
$ !
$ delete clib68.a;*
$ ar68 r clib68.a NOFLOAT.O XMAIN.O XWMAIN.O PERROR.O MKTEMP.O CHMOD.O CHOWN.O
$ ar68 r clib68.a FPRINTF.O PRINTF.O SPRINTF.O XDOPRT.O XPRTINT.O XPRTLD.O
$ ar68 r clib68.a XPRTSHRT.O FSCANF.O SCANF.O SSCANF.O XDOSCAN.O FDOPEN.O
$ ar68 r clib68.a FOPEN.O FREOPEN.O FTELL.O REWIND.O FSEEK.O EXIT.O
$ ar68 r clib68.a CLEANUP.O FCLOSE.O FFLUSH.O FREAD.O FWRITE.O FGETS.O
$ ar68 r clib68.a GETS.O FPUTS.O PUTS.O GETL.O GETW.O PUTL.O PUTW.O
$ ar68 r clib68.a UNGETC.O SETBUF.O FGETC.O FPUTC.O XFILBUF.O XFLSBUF.O
$ ar68 r clib68.a XFDECLS.O CLOSE.O CREAT.O XEXIT.O LSEEK.O XFILESZ.O
$ ar68 r clib68.a OPEN.O READ.O XTTYIN.O UNLINK.O WRITE.O XOPEN.O ACCESS.O
$ ar68 r clib68.a GETPASS.O TTYNAME.O ISATTY.O CHINIT.O CHKC.O BLKIO.O
$ ar68 r clib68.a ALLOCC.O ATOI.O ATOL.O SWAB.O GETPID.O RAND.O QSORT.O
$ ar68 r clib68.a CALLOC.O MALLOC.O SBRK.O ERRNO.O CTYPE.O INDEX.O
$ ar68 r clib68.a RINDEX.O STRCAT.O STRCMP.O STRCPY.O STRLEN.O STRNCAT.O
$ ar68 r clib68.a STRNCMP.O STRNCPY.O
$ ar68 r clib68.a ABORT.O ALDIV.O ALMUL.O ALREM.O LMUL.O LREM.O ULDIV.O
$ ar68 r clib68.a setjmp.o signal.o xsignal.o xstrcmp.o ldiv.o blivot.o

View File

@@ -0,0 +1,41 @@
era clib
$1ar68 rf $1 clib NOFLOAT.O XMAIN.O XWMAIN.O PERROR.O MKTEMP.O CHMOD.O CHOWN.O
$1ar68 rf $1 clib FPRINTF.O PRINTF.O SPRINTF.O XDOPRT.O XPRTINT.O XPRTLD.O
$1ar68 rf $1 clib XPRTSHRT.O FSCANF.O SCANF.O SSCANF.O XDOSCAN.O FDOPEN.O
$1ar68 rf $1 clib FOPEN.O FREOPEN.O FTELL.O REWIND.O FSEEK.O EXIT.O
$1ar68 rf $1 clib CLEANUP.O FCLOSE.O FFLUSH.O FREAD.O FWRITE.O FGETS.O
$1ar68 rf $1 clib GETS.O FPUTS.O PUTS.O GETL.O GETW.O PUTL.O PUTW.O
$1ar68 rf $1 clib UNGETC.O SETBUF.O FGETC.O FPUTC.O XFILBUF.O XFLSBUF.O
$1ar68 rf $1 clib XFDECLS.O CLOSE.O CREAT.O XEXIT.O LSEEK.O XFILESZ.O
$1ar68 rf $1 clib OPEN.O READ.O XTTYIN.O UNLINK.O WRITE.O XOPEN.O ACCESS.O
$1ar68 rf $1 clib GETPASS.O TTYNAME.O ISATTY.O CHINIT.O CHKC.O BLKIO.O
$1ar68 rf $1 clib ALLOCC.O ATOI.O ATOL.O SWAB.O GETPID.O RAND.O QSORT.O
$1ar68 rf $1 clib CALLOC.O MALLOC.O SBRK.O ERRNO.O CTYPE.O INDEX.O
$1ar68 rf $1 clib RINDEX.O STRCAT.O STRCMP.O STRCPY.O STRLEN.O STRNCAT.O
$1ar68 rf $1 clib STRNCMP.O STRNCPY.O
$1ar68 rf $1 clib ABORT.O ALDIV.O ALMUL.O ALREM.O LMUL.O LREM.O ULDIV.O
$1ar68 rf $1 clib setjmp.o signal.o xsignal.o xstrcmp.o ldiv.o blivot.o
era as68symb.dat
ren s.x=s.o
ren w.x=w.o
era *.o
ren s.o=s.x
ren w.o=w.x
user 7!make e:

View File

@@ -0,0 +1,27 @@
/************************************************************************
*
* r e w i n d F u n c t i o n
* -----------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "rewind" sets the read/write pointer of a stream file to the
* beginning of the stream.
*
* Calling sequence:
* ret = rewind(sp)
* Where:
* sp -> a stream file (FILE *)
* ret = 0 for success, -1 for failure
*
*************************************************************************/
#include <stdio.h>
WORD rewind(sp)
FILE *sp;
{
return(fseek(sp,0L,0));
}

View File

@@ -0,0 +1,25 @@
/*********************************************************************
* RINDEX - returns a pointer to last occurrence of char in string.
*
* BYTE *rindex(s,c)
* BYTE *s, c;
*
* Like 'index', only returns pointer to last c in s (instead of first),
* or zero if c not in s.
**********************************************************************/
#include <portab.h>
BYTE *rindex(s,c)
BYTE *s, c;
{ REG BYTE *t;
for( t=s; *t; t++ ) /* look for eos. */
;
for( ; c != *t ; t-- ) /* look for c in s. */
if( t==s ) /* if we get to start of string,*/
return(0); /* too far. */
return(t); /* found c. note that 'rindex' */
/* works (ie. returns eos) */
/* if c==NULL. */
}

View File

@@ -0,0 +1,144 @@
******************************************************************************
*
* C runtime startup for CP/M-68k.
*
******************************************************************************
*
ltpa=0 * Low TPA address
htpa=4 * High TPA address
lcode=8 * Code segment start
codelen=12 * Code segment length
ldata=16 * Data segment start
datalen=20 * Data segment length
lbss=24 * Bss segment start
bsslen=28 * Bss segment length
freelen=32 * free segment length
resvd=36 * Reserved
fcb2=56 * 2nd parsed fcb
fcb1=92 * 1st parsed fcb
command=128 * Command tail
prtstr=9 * Print string BDOS Call
exit=0 * BDOS exit call
.globl __main
.globl __exit
.globl __break
.globl __start
.globl ___cpmrv
.globl __base
.globl _sw
.text
__start: clr.l d5 * clear a register
jsr _sw * security reasons
bra start * Branch around ID
.dc.b 'C Runtime V01.10, Copyright(c) 1983, Digital Research '
serial: .dc.b 'XXXX-0000-654321' * serial number
.even
start: move.l 4(a7),a0 * a0 -> Base page
move.l a0,__base * Load C external
move.l lbss(a0),a1 * a1 -> bss region
move.l a1,a3 * Save this
adda.l bsslen(a0),a1 * a1 -> 1st heap loc
xclear: * Clear heap area
clr.w (a3)+ * clear a word
cmpa.l a3,sp * See if done
bhi xclear * Not yet, continue
move.l a1,__break * Put in "break" loc
lea.l command(a0),a2 * a2 -> command line
move.b (a2)+,d0 * d0 = byte count
andi.l #$ff,d0 * clear junk
move.w d0,-(a7) * push length
move.l a2,-(a7) * Push commnd
clr.l a6 * Clear frame pointer
jsr __main * call main routine
jmp __exit * call "exit"
*
*
.bss
__base: .ds.l 1 * -> Base Page
__break: .ds.l 1 * Break function
___cpmrv: .ds.w 1 * Last CP/M return val
*
*
.globl _brk
.text
_brk:
movea.l 4(sp),a0 * New break?
move.l a0,d0
lea $100(a0),a0 * Chicken factor
cmpa.l a0,sp * Compare
bhis brkok * OK, continue
move.l #-1,d0 * Load return reg
rts * Return
brkok:
move.l d0,__break * Save the break
clr.l d0 * Set OK return
rts * return
.globl ___BDOS
___BDOS: link a6,#0 * link
move.w 8(sp),d0 * Load func code
move.l 10(sp),d1 * Load Paramter
trap #2 * Enter BDOS
cmpa.l __break,sp * Check for stack ovf
bhis noovf * NO overflow, continue
move.w #prtstr,d0 * String print
lea ovf,a0 * a0-> message
move.l a0,d1 * load proper reg
trap #2 * Issue message
move.w #exit,d0 * Exit
trap #2 * now
noovf: * Here if all OK
unlk a6 *
rts * Back to caller
*
* Fill function:
*
* fill(dest,char,cnt);
*
* BYTE *dest; /* -> area to be filled */
* BYTE char; /* = char to fill */
* WORD cnt; /* = # bytes to fill */
*
.globl _fill
_fill:
move.l 4(a7),a0 * -> Output area
move.w 8(a7),d1 * = output char
move.w 10(a7),d0 * = output count
ext.l d0 * make it long
subq.l #1,d0 * decrement
ble filldone * Done if le
fillit: move.b d1,(a0)+ * move a byte
dbra d0,fillit * Continue
filldone: clr.l d0 * always return 0
rts *
*
* Data area
*
.data
.globl ___pname * Program Name
.globl ___tname * Terminal Name
.globl ___lname * List device name
.globl ___xeof * ^Z byte
ovf: .dc.b 'Stack Overflow$' * Error message
___pname: .dc.b 'C runtime',0 * Program name
___tname: .dc.b 'CON:',0 * Console name
___lname: .dc.b 'LST:',0 * List device name
___xeof: .dc.b $1a * Control-Z
.end

View File

@@ -0,0 +1,41 @@
/****************************************************************************/
/* */
/* s b r k F u n c t i o n */
/* ------------------------- */
/* Copyright 1982 by Digital Research Inc. All rights reserved. */
/* */
/* The "sbrk" function is used to allocate memory dynamically. */
/* */
/* Calling Sequence: */
/* */
/* addr = sbrk(incr); */
/* */
/* Where: */
/* incr Is the incremental number of bytes to be added to */
/* the program heap area. */
/* */
/* addr Is the beginning address of the allocated area. */
/* -1 is returned if allocation failed */
/* */
/****************************************************************************/
#include <portab.h>
EXTERN BYTE *_break; /* Old break address */
/****************************/
BYTE *sbrk(incr) /* */
WORD incr; /* Incremental storage */
/* */
{ /****************************/
REG BYTE *t1,*t2; /* Temporary */
REG LONG inc; /* Temp size increment */
inc = ((LONG)incr) & 0xffffL; /* Un sign-extend */
if(inc & 1) /* Disallow odd incr's */
inc++; /* Round up to next */
/* */
t1 = _break; /* Save the old break */
t2 = _break + inc; /* New break value */
/****************************/
if(brk(t2) == FAILURE) /* Allocate */
return(FAILURE); /* Can't */
/****************************/
return(t1); /* And return */
} /****************************/

View File

@@ -0,0 +1,25 @@
/**************************************************************************
*
* s c a n f F u n c t i o n
* ---------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "scanf" scans the standard input for items specified, and assigns
* them to user supplied variables (via pointers to these vars).
*
* Calling sequence:
* ret = scanf(fmt,p1,p2,...)
* Where:
* ret = the number of items successfully matched & assigned
* EOF returned if encountered on input
* fmt -> a string specifying how to parse the input
* p1,p2,... -> where matched items get stored
*
*****************************************************************************/
#include <stdio.h>
WORD scanf(fmt,ptrs)
BYTE *fmt;
BYTE *ptrs;
{
return(_doscan(stdin,fmt,&ptrs));
}

View File

@@ -0,0 +1,121 @@
$ set noon
$ vsend ACCESS.C
$ vsend ALLOCC.C
$ vsend ATOI.C
$ vsend ATOL.C
$ vsend BLKIO.C
$ vsend CALLOC.C
$ vsend CHINIT.C
$ vsend CHKC.C
$ vsend CHMOD.C
$ vsend CHOWN.C
$ vsend CLEANUP.C
$ vsend CLOSE.C
$ vsend CREAT.C
$ vsend CTYPE.C
$ vsend ERRNO.C
$ vsend EXEC.C
$ vsend EXIT.C
$ vsend FCLOSE.C
$ vsend FDOPEN.C
$ vsend FFLUSH.C
$ vsend FGETC.C
$ vsend FGETS.C
$ vsend FOPEN.C
$ vsend FPRINTF.C
$ vsend FPUTC.C
$ vsend FPUTS.C
$ vsend FREAD.C
$ vsend FREOPEN.C
$ vsend FSCANF.C
$ vsend FSEEK.C
$ vsend FTELL.C
$ vsend FWRITE.C
$ vsend GETL.C
$ vsend GETPASS.C
$ vsend GETPID.C
$ vsend GETS.C
$ vsend GETW.C
$ vsend INDEX.C
$ vsend ISATTY.C
$ vsend LDIV.C
$ vsend LSEEK.C
$ vsend MALLOC.C
$ vsend MKTEMP.C
$ vsend OPEN.C
$ vsend PERROR.C
$ vsend PRINTF.C
$ vsend PUTL.C
$ vsend PUTS.C
$ vsend PUTW.C
$ vsend QSORT.C
$ vsend RAND.C
$ vsend READ.C
$ vsend REWIND.C
$ vsend RINDEX.C
$ vsend SBRK.C
$ vsend SCANF.C
$ vsend SETBUF.C
$ vsend SIGNAL.C
$ vsend SPRINTF.C
$ vsend SSCANF.C
$ vsend STRCAT.C
$ vsend STRCMP.C
$ vsend STRCPY.C
$ vsend STRINS.C
$ vsend STRLEN.C
$ vsend STRNCAT.C
$ vsend STRNCMP.C
$ vsend STRNCPY.C
$ vsend SWAB.C
$ vsend TTYNAME.C
$ vsend UNGETC.C
$ vsend UNLINK.C
$ vsend WRITE.C
$ vsend XDOPRT.C
$ vsend XDOPRTFP.C
$ vsend XDOSCAN.C
$ vsend XEXIT.C
$ vsend XFDECLS.C
$ vsend XFILBUF.C
$ vsend XFILESZ.C
$ vsend XFLSBUF.C
$ vsend XFPRINTF.C
$ vsend XMAIN.C
$ vsend XOPEN.C
$ vsend XPRTINT.C
$ vsend XPRTLD.C
$ vsend XPRTSHRT.C
$ vsend XSTRCMP.C
$ vsend XTTYIN.C
$ vsend XWMAIN.C
$ vsend ABORT.S
$ vsend ALDIV.S
$ vsend ALMUL.S
$ vsend ALREM.S
$ vsend BLIVOT.S
$ vsend LDIV.S
$ vsend LMUL.S
$ vsend LREM.S
$ vsend NOFLOAT.S
$ vsend S.S
$ vsend SETJMP.S
$ vsend STKCPY.S
$ vsend ULDIV.S
$ vsend W.S
$ vsend XSIGNAL.S
$ vsend BASEPAGE.H
$ vsend BDOS.H
$ vsend CPM.H
$ vsend CTYPE.H
$ vsend ERRNO.H
$ vsend PORTAB.H
$ vsend SETJMP.H
$ vsend SGTTY.H
$ vsend SIGNAL.H
$ vsend STDIO.H
$ vsend C.SUB
$ vsend CLINK.SUB
$ vsend MAKE.SUB
$ vsend NEXT.SUB
$ vsend REAR.SUB

View File

@@ -0,0 +1,17 @@
/* setbuf - assign a buffer to a stream, after open but
before any i/o.
Returns SUCCESS if ok, FAILURE o.w. */
#include <stdio.h>
WORD setbuf(sp,buf)
REG FILE *sp;
REG BYTE *buf;
{
if( sp->_base != NULL )
return(FAILURE);
sp->_base = sp->_ptr = buf;
if( buf == NULL )
sp->_flag |= _IONBUF;
else sp->_flag &= ~_IONBUF;
return(SUCCESS);
}

View File

@@ -0,0 +1,35 @@
/****************************************************************************/
/* */
/* L o n g j u m p H e a d e r F i l e */
/* --------------------------------------- */
/* */
/* Copyright 1982 by Digital Research. All rights reserved. */
/* */
/* Long jumps on the 68K are implemented as follows: */
/* */
/* 1). Routine "setjmp" is called to setup a special */
/* buffer for return. The return address, stack */
/* pointer and frame pointer are saved. This allows */
/* the calling program to do the proper number of */
/* "pops". */
/* */
/* 2). At some later time, the procedure "longjmp" is */
/* called. The programmer sees a return from the */
/* previous "setjmp" as the result. */
/* */
/* Calling sequence: */
/* */
/* #include <setjmp.h> (definitions) */
/* jmp_buf env; (define a buffer for saved stuff) */
/* */
/* setjmp(env); */
/* a: */
/* */
/* longjmp(env,val); */
/* */
/* Setjmp returns a WORD of 0 on first call, and "val" on the */
/* subsequent "longjmp" call. The longjmp call causes execution to */
/* resume at "a:" above. */
/* */
/****************************************************************************/
typedef LONG jmp_buf[3];

View File

@@ -0,0 +1,22 @@
*
* Setjmp / longjmp implementation. See file "setjmp.h" for details.
*
.globl _setjmp * Set up longjump
.globl _longjmp * do longjump
*
_setjmp: * Save environment
movea.l 4(a7),a0 * a0 -> Environment buffer
move.l a7,(a0)+ * Stack pointer to first long
move.l a6,(a0)+ * Frame pointer to second long
move.l (a7),(a0) * Return address to third long
clr.l d0 * Return 0 value
rts * Return to caller
*
_longjmp: * Return to saved point
movea.l 4(a7),a0 * a0 -> Environment buffer
move.w 8(a7),d0 * Load return value
ext.l d0 * just in case ...
movea.l (a0)+,a7 * Reset stack
movea.l (a0)+,a6 * Reset frame
move.l (a0),(a7) * Load TOS with return addr
rts * and return

View File

@@ -0,0 +1,14 @@
/* sgtty.h - tty control information */
/* Note reduced contents for CP/M implementation... */
struct sgttyb{
char sg_ispeed; /* ignored */
char sg_ospeed; /* ignored */
char sg_erase; /* ignored */
char sg_kill; /* ignored */
int sg_flags;
};
#define RAW 0000040
#define CRMOD 0000020
#define ECHO 0000010
#define LCASE 0000004
#define CBREAK 0000002

View File

@@ -0,0 +1,87 @@
/****************************************************************************/
/* */
/* S i g n a l F u n c t i o n */
/* ----------------------------- */
/* */
/* The "signal" function allows a routine in C to catch a 68000 */
/* interrupt, and service it with a C function. */
/* */
/* Calling Sequence: */
/* */
/* ret = signal(sig,func); */
/* */
/* Where: */
/* ret Is always 0 under CP/M. */
/* sig Is the UNIX signal number */
/* func -> the function to service the exception */
/* */
/****************************************************************************/
#include <stdio.h> /* Include standard stuff */
#include <signal.h> /* Include definitions */
#include <cpm.h> /* Include BDOS Functions */
/****************************/
EXTERN WORD *_illinst(); /* -> Illegal instruction ep*/
EXTERN WORD *_trace(); /* -> Trace trap epa */
EXTERN WORD *_trap(); /* -> TRAP instruction epa */
EXTERN WORD *_buserr(); /* -> BUSERR epa */
EXTERN WORD *_arith(); /* -> Arithmetic traps epa */
EXTERN BYTE *__signal[NSIG]; /* Holds user func addresses*/
/* */
LONG signal(sig,func) /****************************/
REG DEFAULT sig; /* Signal number */
REG DEFAULT (*func)(); /* Function address */
{ /* */
REG WORD i; /* Temp */
/* */
if(sig >= NSIG || sig < 0) /* Too big? */
return(BADSIG); /* Yes, return UNIX NFG code*/
/****************************/
__signal[sig] = func; /* Save the function addr */
/* */
switch(sig) /* Do signal processing */
{ /* */
case SIGILL: /* Illegal instruction */
_setvec( 4,&_illinst); /* Set vector #4 */
_setvec( 8,&_illinst); /* Privilege violation */
_setvec(10,&_illinst); /* Set vector #10 (line A) */
_setvec(11,&_illinst); /* Set vector #11 (line F) */
break; /****************************/
/* */
case SIGTRAP: /* Trace trap */
_setvec(9,&_trace); /* Set vector #9 */
break; /****************************/
/* */
case SIGIOT: /* Bad TRAP instruction */
_setvec(32,&_trap); /* Trap 0 */
for(i=35; i<48; i++) /* Traps 4 - 15 */
_setvec(i,&_trap); /* */
break; /****************************/
/* */
case SIGBUS: /* BUSERR PDP-11 trap 4 & 10*/
_setvec(2,&_buserr); /* Set nxm vector */
_setvec(3,&_buserr); /* Set addressing vector */
break; /****************************/
/* */
case SIGFPE: /* Arithmetic section */
for(i=5; i<8; i++) /* Set all misc vectors */
_setvec(i,&_arith); /* */
break; /****************************/
/* */
} /* */
return(0L); /* Return OK */
} /****************************/
VOID _setvec(vector,func) /****************************/
WORD vector; /* Vector # */
BYTE *func; /* Function address */
{ /****************************/
struct { /* A CP/M EPB structure */
WORD vec; /* Vector number */
BYTE *userepa; /* User's epa */
BYTE *bdosepa; /* BDOS's epa */
} epb; /****************************/
epb.vec = vector; /* Set up vector */
epb.userepa = func; /* and function */
epb.bdosepa = 0L; /* Clear return word */
__BDOS(SETVEC,&epb); /* Do it. */
} /****************************/

View File

@@ -0,0 +1,32 @@
/****************************************************************************/
/* */
/* S i g n a l H e a d e r F i l e */
/* ----------------------------------- */
/* */
/* Copyright 1982 by Digital Research, Inc. All rights reserved. */
/* */
/* Define the "signal" arguments, so anyone using the function will */
/* not get compile-time errors. Some functions are not implemented. */
/* */
/****************************************************************************/
#define NSIG 16 /* 16 simulated signals */
#define SIGHUP 1 /* Hangup */
#define SIGINT 2 /* Interrupt (^C) */
#define SIGQUIT 3 /* Quit signal */
#define SIGILL 4 /* Illegal Instruction trap */
#define SIGTRAP 5 /* Trace Trap */
#define SIGIOT 6 /* IOT instruction (on PDP-11) */
#define SIGEMT 7 /* EMT instruction (TRAP on 68k) */
#define SIGFPE 8 /* Floating point exception */
#define SIGKILL 9 /* Kill (cannot be intercepted) */
#define SIGBUS 10 /* BUSERR (non-ex memory reference) */
#define SIGSEGV 11 /* Segmentation (MMU) violation */
#define SIGSYS 12 /* Bad argument to system call */
#define SIGPIPE 13 /* Write on a broken pipe */
#define SIGALRM 14 /* Alarm clock (what a name!) */
#define SIGTERM 15 /* Software termination signal */
/************************************/
#define BADSIG (-1L) /* Error return */
#define SIG_DFL (0L) /* Default action on signal call */
#define SIG_IGN (1L) /* Ignore */
/************************************/

View File

@@ -0,0 +1,36 @@
/************************************************************************
*
* s p r i n t f F u n c t i o n
* -------------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "sprintf" prints args specified in format string to a string
* pointed to by str. No checks for str overflow are possible.
* sprintf returns str.
*
* Calling sequence:
* s = sprintf(string,fmt,arg1,arg2,...argn);
* Where:
* s = string = place to put info
* fmt -> a string specifying how arg1-n are to be printed.
*
**************************************************************************/
#include <stdio.h>
BYTE *sprintf(string,fmt,args)
BYTE *string,
*fmt,
*args;
{
FILE stream; /* pseudo stream tab */
REG FILE *sp; /* ptr thereto */
WORD rv; /* return val from _doprt */
/* */
sp = &stream; /* point to pseudo stream */
sp->_cnt = 32767; /* assume 'infinite' buf */
sp->_ptr = sp->_base = string; /* stream buf -> string */
sp->_flag = _IOWRT | _IOSTRI; /* writeable string */
sp->_fd = -1; /* insure no real i/o */
rv = _doprt(sp,fmt,&args); /* do the print */
putc(NULL,sp); /* NULL terminate string */
return(rv==FAILURE ? NULL : string); /* tell user what happened */
}

View File

@@ -0,0 +1,36 @@
/**************************************************************************
*
* s s c a n f F u n c t i o n
* -----------------------------
* Copyright 1982 by Digital Research Inc. All rights reserved.
*
* "sscanf" scans the given string for items specified, and assigns
* them to user supplied variables (via pointers to these vars).
*
* Calling sequence:
* ret = sscanf(str,fmt,p1,p2,...)
* Where:
* ret = the number of items successfully matched & assigned
* EOF returned if encountered on input
* str -> a (null terminated) string to scan
* fmt -> a string specifying how to parse the input
* p1,p2,... -> where matched items get stored
*
*****************************************************************************/
#include <stdio.h>
WORD sscanf(str,fmt,ptrs)
BYTE *str;
BYTE *fmt;
BYTE *ptrs;
{
FILE spbuf, *sp;
BYTE locbuf[BUFSIZ]; /* set up a local buffer */
sp = &spbuf; /* set up a pseudo stream */
sp->_fd = -1;
sp->_flag = _IOREAD | _IOSTRI; /* readable string */
sp->_cnt = strlen(str) + 1; /* allow doscan to read NULL*/
strcpy(locbuf,str); /* copy to safe place */
sp->_base = sp->_ptr = locbuf;
return(_doscan(sp,fmt,&ptrs));
}

View File

@@ -0,0 +1,68 @@
/*****************************************************************************
*
* 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 the standard include file for the CP/M C Run Time Library.
*
*****************************************************************************/
/* */
#include <portab.h> /* Portability Definitions */
/* */
/****************************************************************************
* Stream I/O File Definitions
*****************************************************************************/
#define BUFSIZ 512 /* Standard (ascii) buf size */
#define MAXFILES 16 /* Max # open files ( < 32 ) */
struct _iobuf { /* */
WORD _fd; /* file descriptor for low level io */
WORD _flag; /* stream info flags */
BYTE *_base; /* base of buffer */
BYTE *_ptr; /* current r/w pointer */
WORD _cnt; /* # chars to be read/have been wrt */
}; /* */
#ifndef FILE /* conditionally include: */
extern struct _iobuf _iob[MAXFILES]; /* an array of this info */
#define FILE struct _iobuf /* stream definition */
#endif /************************************/
/* flag byte definition */
#define _IOREAD 0x01 /* readable file */
#define _IOWRT 0x02 /* writeable file */
#define _IOABUF 0x04 /* alloc'd buffer */
#define _IONBUF 0x08 /* no buffer */
#define _IOERR 0x10 /* error has occurred */
#define _IOEOF 0x20 /* EOF has occurred */
#define _IOLBUF 0x40 /* handle as line buffer */
#define _IOSTRI 0x80 /* this stream is really a string */
#define _IOASCI 0x100 /* this was opened as an ascii file */
/************************************/
#define stdin (&_iob[0]) /* standard input stream */
#define stdout (&_iob[1]) /* " output " */
#define stderr (&_iob[2]) /* " error " */
/************************************/
#define clearerr(p) ((p)->_flag & ~_IOERR) /* clear error flag */
#define feof(p) ((p)->_flag & _IOEOF) /* EOF encountered on stream */
#define ferror(p) ((p)->_flag & _IOERR) /* error encountered on stream */
#define fileno(p) ((p)->_fd) /* get stream's file descriptor */
#define getchar() getc(stdin) /* get char from stdin */
#define putchar(c) putc(c,stdout) /* put char to stdout */
#define putc fputc
#define getc fgetc
/****************************************************************************/
/* */
/* M A C R O S */
/* ----------- */
/* */
/* Define some stuff as macros .... */
/* */
/****************************************************************************/
#define abs(x) ((x) < 0 ? -(x) : (x)) /* Absolute value function */
#define max(x,y) (((x) > (y)) ? (x) : (y)) /* Max function */
#define min(x,y) (((x) < (y)) ? (x) : (y)) /* Min function */
/*************************** end of stdio.h *********************************/

View File

@@ -0,0 +1,13 @@
*********************************************************
* *
* Copyright Notice Module *
* *
*********************************************************
.globl ___cpyrt
.text
___cpyrt: .dc.b 'CP/M-68K(tm), Version 1.1, '
.dc.b 'Copyright (c) 1983, Digital Research'
serial: .dc.b 'XXXX-0000-654321'
.dc.w 0
.end

View File

@@ -0,0 +1,24 @@
/****************************************************************************
* STRCAT - concatenate strings
*
* BYTE *strcat(s1,s2) copies s2 to end of s1
* BYTE *s1, *s2;
*
* Assumes null terminated strings. No check is made for string area
* overflow.
****************************************************************************/
#include <portab.h>
BYTE *strcat(s1,s2)
REG BYTE *s1, *s2;
{
REG BYTE *cp;
for( cp=s1; *cp; cp++ ) /* save s1 for return. */
;
while( (*cp++ = *s2++) ) /* copy until eos(s2). */
;
return(s1);
}

View File

@@ -0,0 +1,30 @@
/*********************************************************************
* STRCMP - compares strings
*
*
* WORD strcmp(s1,s2)
* BYTE *s1, *s2;
*
* 'strcmp' compares null terminated strings s1 and s2.
* Returns:
* strcmp < 0 if s1<s2
* strcmp = 0 if s1=s2
* strcmp > 0 if s1>s2
*********************************************************************/
#include <portab.h>
WORD strcmp(s1,s2)
REG BYTE *s1, *s2;
{
REG BYTE a,b;
while (*s1 && *s2)
{
a = (*s1++);
b = (*s2++);
if (a > b) return (1);
if (a < b) return (-1);
}
return(*s1 - *s2);
}

View File

@@ -0,0 +1,23 @@
/**********************************************************************
* STRCPY - copies from one string to another
*
* BYTE *strcpy(s1,s2)
* BYTE *s1, *s2;
*
* Copies bytes from s2 to s1, stopping after null has been moved.
* Returns s1.
* No check for overflow of s1.
***********************************************************************/
#include <portab.h>
BYTE *strcpy(s1,s2)
REG BYTE *s1, *s2;
{ REG BYTE *cp;
cp = s1; /* save for return. */
while( *cp++ = *s2++ ) /* isn't C fun? */
;
return(s1);
}

View File

@@ -0,0 +1,63 @@
#define begin {
#define end }
/********************************************************/
/* */
/* strins(s1,s2,pos) */
/* insert s1 into s2 at pos */
/* (pos starts at 0) */
/* */
/********************************************************/
strins(s1,s2,pos)
char s1[],s2[];
int pos;
begin
/*
PROCEDURE INSERT(SOURCE:STRING; VAR DEST:STRING; INDEX:INTEGER);
BEGIN
MOVERIGHT(DEST[INDEX],DEST[INDEX+LENGTH(SOURCE)],LENGTH(DEST)-INDEX+1);
MOVE(SOURCE[1],DEST[INDEX],LENGTH(SOURCE));
DEST[0] := CHR(LENGTH(DEST) + LENGTH(SOURCE))
END;
*/
int ls1, ls2, lm; /* length s1, length s2, length to move */
int mp1, mp2; /* move "pointers" (indexes) */
int i,j,k;
ls1 = strlen(s1);
ls2 = strlen(s2);
lm = ls2 - pos;
mp1 = pos + lm;
mp2 = pos + ls1 + lm;
s2[mp2] = '\0';
for(i=0; i < lm; i++)
s2[--mp2] = s2[--mp1];
for(i=0; i < ls1; i++)
s2[pos+i] = s1[i];
end /* strins */
/****************************************************************
*
* strdel(sp,len)
* remove len characters from string pointed to by sp
*
***************************************************************/
strdel(sp,len)
register char *sp;
register int len;
begin
register char *ssp;
ssp = sp + len;
while ((*sp++ = *ssp++) != 0)
;
end

View File

@@ -0,0 +1,18 @@
/**********************************************************************
* STRLEN - finds the number of non-null characters in s.
*
* WORD strlen(s)
* BYTE *s;
**********************************************************************/
#include <portab.h>
WORD strlen(s)
REG BYTE *s;
{
REG BYTE *p;
for( p = s; *p; p++ ) /* advance *p until NULL. */
;
return(p-s);
}

Some files were not shown because too many files have changed in this diff Show More