mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 08:24:18 +00:00
Upload
Digital Research
This commit is contained in:
55
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/blkio.c
Normal file
55
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/blkio.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* _ b l k i o F u n c t i o n */
|
||||
/* ----------------------------- */
|
||||
/* */
|
||||
/* The _blkio function is used to read / write a set of contiguous */
|
||||
/* sectors in an open file. */
|
||||
/* */
|
||||
/* Calling Sequence: */
|
||||
/* */
|
||||
/* ret = _blkio(ccb,sector,buffer,count,bdosfunc); */
|
||||
/* */
|
||||
/* Where: */
|
||||
/* 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 "stdio.h"
|
||||
#include "cpm.h"
|
||||
LONG _blkio(ccb,sector,buffer,count,bdosfunc)
|
||||
/****************************/
|
||||
REG FILE *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 temp; /* Temp return from BDOS */
|
||||
REG LONG seccnt; /* # sectors processed */
|
||||
/****************************/
|
||||
seccnt = 0; /* Zero count initally */
|
||||
/* */
|
||||
while (count > 0) /* Until all sectors xferred*/
|
||||
{ /* */
|
||||
__BDOS(SETDMA,buffer); /* Set new DMA address */
|
||||
ccb->fcb.record = sector; /* Set new record number */
|
||||
temp=__BDOS(bdosfunc,&(ccb->fcb));/* do the read */
|
||||
if(temp != 0) /* Check for errors */
|
||||
{ /****************************/
|
||||
return(seccnt); /* Return nfg */
|
||||
} /****************************/
|
||||
/* */
|
||||
sector++; /* Increment sector number */
|
||||
count--; /* Down count */
|
||||
buffer += SECSIZ; /* Increment address */
|
||||
seccnt++; /* Bump sector count */
|
||||
} /****************************/
|
||||
return(seccnt); /* All is OK */
|
||||
} /****************************/
|
@@ -0,0 +1,60 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* C C B I N I T I A L I Z A T I O N
|
||||
* -----------------------------------
|
||||
*
|
||||
* Routine "_chinit" is called from the run-time initialization to clear
|
||||
* out all the CCB storage.
|
||||
*
|
||||
* Calling sequence:
|
||||
*
|
||||
* _chinit();
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include "stdio.h" /* Include std definitions */
|
||||
#include "cpm.h" /* Include CP/M definitions */
|
||||
FILE _iob[16]; /* Allocate CCB storage */
|
||||
_chinit() /****************************/
|
||||
{ /* */
|
||||
REG WORD i; /* Index */
|
||||
for(i=0;i<MAXFILE;i++) /* For all channels */
|
||||
__chinit(i); /* Init iob(i); */
|
||||
} /****************************/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* The __chinit routine initializes only 1 channel.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
__chinit(i)
|
||||
{ /****************************/
|
||||
REG FILE *ch; /* -> CCB */
|
||||
REG BYTE *p; /* Byte pointer temporary */
|
||||
EXTERN FILE *_getc(); /* Converts fd to fp */
|
||||
ch = _getc(i); /* Load address */
|
||||
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; /* Clear drive code */
|
||||
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 */
|
||||
} /****************************/
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* The _getc routine returns the address of a particular ccb.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
FILE *_getc(i) /***************************/
|
||||
REG WORD i; /* input channel number */
|
||||
{ /***************************/
|
||||
extern FILE _iob[]; /* Declare external */
|
||||
return(&_iob[i]); /* Load addr, return */
|
||||
} /***************************/
|
34
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/chkc.c
Normal file
34
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/chkc.c
Normal file
@@ -0,0 +1,34 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* C H A N N E L N U M B E R V A L I D A T I O N
|
||||
* -------------------------------------------------
|
||||
*
|
||||
* 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 "stdio.h" /* Include std definitions */
|
||||
#include "cpm.h" /* and CP/M definitions */
|
||||
FILE *_chkc(ch) /****************************/
|
||||
UWORD ch; /* Facilitate error check */
|
||||
{ /* */
|
||||
REG FILE *xcb; /* -> CCB */
|
||||
EXTERN FILE *_getc(); /* converts fd to fp */
|
||||
/****************************/
|
||||
if(ch >= MAXFILE) /* Is channel in range? */
|
||||
return(FAILURE); /* No, quit now. */
|
||||
/* */
|
||||
xcb = _getc(ch); /* xcb -> ccb for channel */
|
||||
if((xcb->flags & OPENED) == 0) /* Is channel OPEN? */
|
||||
return (FAILURE); /* Noooooooo!! */
|
||||
return(xcb); /* Else, return pointer */
|
||||
} /****************************/
|
@@ -0,0 +1,6 @@
|
||||
_clenf (s) /* counts length of string */
|
||||
register char *s;
|
||||
{
|
||||
register int n;
|
||||
for (n=0; *s++ != '\0'; n++);
|
||||
return (n);}
|
53
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/close.c
Normal file
53
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/close.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* C l o s e F u n c t i o n */
|
||||
/* --------------------------- */
|
||||
/* */
|
||||
/* 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 "stdio.h"
|
||||
#include "cpm.h"
|
||||
/****************************/
|
||||
EXTERN BYTE __xeof; /* End of file for ASCII */
|
||||
WORD close(fd) /****************************/
|
||||
/* */
|
||||
WORD fd; /* File descriptor to close */
|
||||
/* */
|
||||
{ /****************************/
|
||||
EXTERN LONG _chkc(); /* fd -> fp conversion */
|
||||
REG FILE *fp; /* file pointer Temporary */
|
||||
/* */
|
||||
if((LONG)(fp=_chkc(fd)) == FAILURE) /* 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 */
|
||||
{ /* */
|
||||
lseek(fd,0L,2); /* Seek to EOF */
|
||||
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 */
|
||||
return(FAILURE); /* can't */
|
||||
} /****************************/
|
||||
__BDOS(CLOSE,&(fp->fcb)); /* Close the fcb */
|
||||
__chinit(fd); /* Release the space */
|
||||
freec(fd); /* Release the channel */
|
||||
return(SUCCESS); /* Done */
|
||||
} /****************************/
|
@@ -0,0 +1,17 @@
|
||||
.globl _sw
|
||||
_sw:
|
||||
rts
|
||||
|
||||
*********************************************************
|
||||
* *
|
||||
* Copyright Notice Module *
|
||||
* *
|
||||
*********************************************************
|
||||
|
||||
.globl ___cpyrt
|
||||
.text
|
||||
___cpyrt: .dc.b 'CP/M-68K(tm), Version 1.1, '
|
||||
.dc.b 'Copyright (c) 1983, Digital Research'
|
||||
.dc.b 'XXXX-0000-654321'
|
||||
.dc.w 0
|
||||
.end
|
13
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/cout.h
Normal file
13
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/cout.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#define HDSIZE (sizeof couthd) /**.o file header size*/
|
||||
struct hdr {
|
||||
short ch_magic; /*c.out magic number 060016 = $600E*/
|
||||
long ch_tsize; /*text size*/
|
||||
long ch_dsize; /*data size*/
|
||||
long ch_bsize; /*bss size*/
|
||||
long ch_ssize; /*symbol table size*/
|
||||
long ch_stksize; /*stack size*/
|
||||
long ch_entry; /*entry point*/
|
||||
short ch_rlbflg; /*relocation bits suppressed flag*/
|
||||
} couthd;
|
||||
|
||||
#define MAGIC 0x601a /* bra .+26 instruction*/
|
101
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/cpm.h
Normal file
101
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/cpm.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* C P M . H */
|
||||
/* --------- */
|
||||
/* */
|
||||
/* This file contains CP/M specific definitions for the v6 library */
|
||||
/* for the Alcyon assembler / linker. */
|
||||
/* */
|
||||
/* "stdio.h" must be included BEFORE this file. */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
/*
|
||||
* Cp/m FCB definition
|
||||
*/
|
||||
|
||||
struct xfcb /****************************/
|
||||
{ /* */
|
||||
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 /* # bytes / CP/M sector */
|
||||
/****************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* 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 /************************************/
|
||||
{ /* */
|
||||
BYTE flags; /* Flags byte */
|
||||
BYTE chan; /* Channel number being used */
|
||||
LONG offset; /* File offset word (bytes) */
|
||||
LONG sector; /* Sector currently in buffer */
|
||||
LONG hiwater; /* High water mark */
|
||||
struct xfcb fcb; /* File FCB */
|
||||
BYTE buffer[SECSIZ]; /* Read / write buffer */
|
||||
}; /************************************/
|
||||
|
||||
#define MAXFILE 16 /* Maximum # files */
|
||||
extern struct ccb _iob[MAXFILE]; /* Declare storage */
|
||||
|
||||
/* Flags word bit definitions */
|
||||
/************************************/
|
||||
#define OPENED 1 /* Channel is OPEN */
|
||||
#define ISTTY 2 /* Channel open to TTT */
|
||||
#define ISLPT 4 /* Channel open to LPT */
|
||||
#define ISREAD 8 /* Channel open readonly */
|
||||
#define ISASCII 16 /* ASCII file attached */
|
||||
#define ATEOF 32 /* End of file encountered */
|
||||
#define DIRTY 64 /* Buffer needs writing */
|
||||
/************************************/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* 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 B_READ 33 /* Read Random record */
|
||||
#define B_WRITE 34 /* Write Random record */
|
||||
/****************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/* 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 */
|
||||
/****************************/
|
14
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/cputc.c
Normal file
14
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/cputc.c
Normal file
@@ -0,0 +1,14 @@
|
||||
# include "iodec.h"
|
||||
|
||||
/**
|
||||
** put a single character
|
||||
**/
|
||||
|
||||
int f_log 0;
|
||||
|
||||
cputc(c, fn)
|
||||
char c;
|
||||
int fn;
|
||||
{
|
||||
write(fn,&c,1);
|
||||
}
|
57
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/creat.c
Normal file
57
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/creat.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* C F I L E C R E A T E R O U T I N E
|
||||
* -----------------------------------------
|
||||
*
|
||||
* The "creat" routine opens a new "C" file and returns a file id.
|
||||
*
|
||||
* Calling Sequence:
|
||||
*
|
||||
* 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 "stdio.h" /* Include std definitions */
|
||||
#include "cpm.h" /* Include CP/M definitions */
|
||||
extern char __tname[]; /* -> CON: */
|
||||
extern char __lname[]; /* -> LST: */
|
||||
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 */
|
||||
REG FILE *ch; /* -> CCB for channel */
|
||||
EXTERN FILE *_getc(); /* Converts fd to fp */
|
||||
/* */
|
||||
if((ich = igetc()) < 0) /* Allocate a channel */
|
||||
return (FAILURE); /* Can't */
|
||||
/* */
|
||||
__chinit(ich); /* Clear out channel's ccb */
|
||||
ch = _getc(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 */
|
||||
return(FAILURE); /* If return <> 0, NFG. */
|
||||
/* Else: */
|
||||
ch -> flags |= OPENED; /* Set OPEN bit */
|
||||
return(ich); /* Return Channel # */
|
||||
} /****************************/
|
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* El-Kludg-o Dup routine. Takes advantage of the fact that
|
||||
* stdout is not closed by Bill Allen's stuff.
|
||||
*/
|
||||
dup(n)
|
||||
register int n;
|
||||
{
|
||||
return(n);
|
||||
}
|
35
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/exit.c
Normal file
35
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/exit.c
Normal file
@@ -0,0 +1,35 @@
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* E x i t F u n c t i o n */
|
||||
/* ------------------------- */
|
||||
/* */
|
||||
/* The exit function is called from anywhere to pass control back to */
|
||||
/* the CCP from the executing C program. */
|
||||
/* */
|
||||
/* Calling Sequence: */
|
||||
/* */
|
||||
/* exit(code); */
|
||||
/* */
|
||||
/* Where: */
|
||||
/* code Is the exit status (ignored) */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
#include "stdio.h"
|
||||
#include "cpm.h"
|
||||
|
||||
exit(code) /***************************/
|
||||
/* */
|
||||
WORD code; /* Exit status */
|
||||
{ /* */
|
||||
REG WORD i; /* Counter */
|
||||
/* */
|
||||
for(i=0; i<MAXFILE; i++) /* Close all */
|
||||
close(i); /* Open files */
|
||||
/***************************/
|
||||
_exit(code); /* Do the exit now */
|
||||
} /***************************/
|
||||
_exit(code) /* */
|
||||
WORD code; /***************************/
|
||||
{ /* */
|
||||
__BDOS(EXIT,0L); /* Exit to BDOS */
|
||||
} /***************************/
|
52
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/getc.c
Normal file
52
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/getc.c
Normal file
@@ -0,0 +1,52 @@
|
||||
#define BLEN 512
|
||||
|
||||
struct iob {
|
||||
int fd; /*file descriptor*/
|
||||
int cc; /*char count*/
|
||||
char *cp; /*ptr to next char*/
|
||||
char cbuf[BLEN]; /*char buffer*/
|
||||
};
|
||||
|
||||
fopen(fname,ibuf,x)
|
||||
char *fname;
|
||||
register struct iob *ibuf;
|
||||
int x;
|
||||
{
|
||||
|
||||
ibuf->cc = 0; /*no chars*/
|
||||
x = (x == 0) ? 0 : 1;
|
||||
return(ibuf->fd=open(fname,0,x));
|
||||
}
|
||||
|
||||
getc(ibuf)
|
||||
register struct iob *ibuf;
|
||||
{
|
||||
|
||||
if(ibuf->cc<=0) {
|
||||
ibuf->cp = &(ibuf->cbuf[0]);
|
||||
ibuf->cc = read(ibuf->fd,ibuf->cp,BLEN);
|
||||
}
|
||||
if(ibuf->cc <= 0) {
|
||||
return(-1);
|
||||
}
|
||||
ibuf->cc--;
|
||||
return((int)(*(ibuf->cp)++)&0xff);
|
||||
}
|
||||
|
||||
getw(ibuf)
|
||||
register struct iob *ibuf;
|
||||
{
|
||||
|
||||
register int j;
|
||||
register int i;
|
||||
|
||||
if((j=getc(ibuf)) == -1)
|
||||
return(-1);
|
||||
i = (j&0377) << 8;
|
||||
if((j=getc(ibuf)) == -1)
|
||||
return(-1);
|
||||
i =| (j&0377);
|
||||
if(i&0100000)
|
||||
i =| 0xffff0000; /* make it negative */
|
||||
return(i);
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
#define BLEN 512
|
||||
|
||||
struct iob {
|
||||
int fd; /*file descriptor*/
|
||||
int cc; /*char count*/
|
||||
char *cp; /*ptr to next char*/
|
||||
char cbuf[BLEN]; /*char buffer*/
|
||||
} fin;
|
||||
|
||||
getchar()
|
||||
{
|
||||
char c;
|
||||
register int i;
|
||||
|
||||
if(fin.fd==0) {
|
||||
if(read(0,&c,1)<=0 || c==4)
|
||||
return(0);
|
||||
i = c;
|
||||
return(i&0xff);
|
||||
}
|
||||
if(fin.cc<=0) {
|
||||
fin.cp = &(fin.cbuf[0]);
|
||||
fin.cc = read(fin.fd,fin.cp,BLEN);
|
||||
}
|
||||
if(fin.cc <= 0) {
|
||||
return(0);
|
||||
}
|
||||
fin.cc--;
|
||||
i = *(fin.cp)++;
|
||||
return(i&0xff);
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
/*
|
||||
* Getpid.c -- Whitesmith's version of UNIX getpid function
|
||||
*/
|
||||
getpid()
|
||||
{
|
||||
return(1);
|
||||
}
|
45
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/igetc.c
Normal file
45
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/igetc.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* I G E T C / F R E E C R O U T I N E S
|
||||
* -------------------------------------------
|
||||
*
|
||||
* Routines "igetc" 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.
|
||||
*
|
||||
* Calling Sequence:
|
||||
*
|
||||
* i = getc();
|
||||
* freec(i);
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include "stdio.h" /* Include std definitions */
|
||||
#include "cpm.h" /* Also CP/M ones */
|
||||
WORD chmask = 0; /* Allocate storage */
|
||||
WORD igetc() /****************************/
|
||||
{ /* */
|
||||
REG i,j; /* Define 2 temporaries */
|
||||
/* */
|
||||
j = 1; /* Start with channel 0 */
|
||||
for(i=0;i<MAXFILE;i++) /* Look at all 16 bits */
|
||||
{ /* */
|
||||
if((j & chmask) == 0) /* If 0, then channel free */
|
||||
{ /* */
|
||||
chmask |= j; /* set allocated bit */
|
||||
return(i); /* and return the channel # */
|
||||
} /* */
|
||||
j = j << 1; /* Up to next bit */
|
||||
} /* End FOR loop */
|
||||
return(FAILURE); /* All channels in use! */
|
||||
} /****************************/
|
||||
|
||||
WORD freec(ch) /****************************/
|
||||
{ /* */
|
||||
REG i,j; /* Define 2 temporaries */
|
||||
/* */
|
||||
j = 1; /* Start with channel 0 */
|
||||
for (i=0; i<ch; i++) /* Compute */
|
||||
j = j << 1; /* bit mask */
|
||||
chmask &= (~j); /* clear allocation bit */
|
||||
return(SUCCESS); /* Return OK */
|
||||
} /****************************/
|
24
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/iodec.h
Normal file
24
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/iodec.h
Normal file
@@ -0,0 +1,24 @@
|
||||
# define MAXFILES 15
|
||||
|
||||
struct fileps
|
||||
{
|
||||
char *buff; /* beginning of buffer */
|
||||
char *bptr; /* current position */
|
||||
int nchars; /* number of characters internal */
|
||||
int bsize; /* size of buffer */
|
||||
char eoferr; /* end of file flag */
|
||||
char wrflag; /* mode flag */
|
||||
char *pbuff; /* bottom of peek buffer */
|
||||
};
|
||||
|
||||
struct fileps __filehdr[MAXFILES];
|
||||
|
||||
struct param
|
||||
{
|
||||
int bufsize; /* initial buffer size */
|
||||
int peeksize; /* initial peek size */
|
||||
};
|
||||
|
||||
extern struct param __param;
|
||||
|
||||
int __statbuf[MAXFILES];
|
84
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/ldiv.s
Normal file
84
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/ldiv.s
Normal 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
|
@@ -0,0 +1,12 @@
|
||||
__length(s)
|
||||
char *s;
|
||||
{
|
||||
register int l;
|
||||
register char *p;
|
||||
|
||||
p = s;
|
||||
l = 0;
|
||||
while (*p++)
|
||||
l++;
|
||||
return(l);
|
||||
}
|
123
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/list.com
Normal file
123
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/list.com
Normal file
@@ -0,0 +1,123 @@
|
||||
$ set noon
|
||||
$ num
|
||||
BLKIO.C
|
||||
BLKIO.lis
|
||||
$ num
|
||||
CHINIT.C
|
||||
CHINIT.lis
|
||||
$ num
|
||||
CHKC.C
|
||||
CHKC.lis
|
||||
$ num
|
||||
CLENF.C
|
||||
CLENF.lis
|
||||
$ num
|
||||
CLOSE.C
|
||||
CLOSE.lis
|
||||
$ num
|
||||
CPUTC.C
|
||||
CPUTC.lis
|
||||
$ num
|
||||
CREAT.C
|
||||
CREAT.lis
|
||||
$ num
|
||||
DUP.C
|
||||
DUP.lis
|
||||
$ num
|
||||
EXIT.C
|
||||
EXIT.lis
|
||||
$ num
|
||||
GETC.C
|
||||
GETC.lis
|
||||
$ num
|
||||
GETCHAR.C
|
||||
GETCHAR.lis
|
||||
$ num
|
||||
GETPID.C
|
||||
GETPID.lis
|
||||
$ num
|
||||
IGETC.C
|
||||
IGETC.lis
|
||||
$ num
|
||||
LENGTH.C
|
||||
LENGTH.lis
|
||||
$ num
|
||||
LSEEK.C
|
||||
LSEEK.lis
|
||||
$ num
|
||||
MAIN.C
|
||||
MAIN.lis
|
||||
$ num
|
||||
OPEN.C
|
||||
OPEN.lis
|
||||
$ num
|
||||
PRINTF.C
|
||||
PRINTF.lis
|
||||
$ num
|
||||
PRTINT.C
|
||||
PRTINT.lis
|
||||
$ num
|
||||
PUTC.C
|
||||
PUTC.lis
|
||||
$ num
|
||||
PUTCHAR.C
|
||||
PUTCHAR.lis
|
||||
$ num
|
||||
READ.C
|
||||
READ.lis
|
||||
$ num
|
||||
SBRK.C
|
||||
SBRK.lis
|
||||
$ num
|
||||
SEEK.C
|
||||
SEEK.lis
|
||||
$ num
|
||||
STRCAT.C
|
||||
STRCAT.lis
|
||||
$ num
|
||||
STRCMP.C
|
||||
STRCMP.lis
|
||||
$ num
|
||||
STRLEN.C
|
||||
STRLEN.lis
|
||||
$ num
|
||||
TTYIN.C
|
||||
TTYIN.lis
|
||||
$ num
|
||||
UNLINK.C
|
||||
UNLINK.lis
|
||||
$ num
|
||||
WRITE.C
|
||||
WRITE.lis
|
||||
$ num
|
||||
XOPEN.C
|
||||
XOPEN.lis
|
||||
$ num
|
||||
XSTRCMP.C
|
||||
XSTRCMP.lis
|
||||
$ num
|
||||
XTTYIN.C
|
||||
XTTYIN.lis
|
||||
$ num
|
||||
COUT.H
|
||||
COUT.lst
|
||||
$ num
|
||||
CPM.H
|
||||
CPM.lst
|
||||
$ num
|
||||
IODEC.H
|
||||
IODEC.lst
|
||||
$ num
|
||||
PORTAB.H
|
||||
PORTAB.lst
|
||||
$ num
|
||||
SENDC68.H
|
||||
SENDC68.lst
|
||||
$ num
|
||||
STDIO.H
|
||||
STDIO.lst
|
||||
$ as68 -l -u -p COPYRT.S >COPYRT.lis
|
||||
$ as68 -l -u -p LDIV.S >LDIV.lis
|
||||
$ as68 -l -u -p LMUL.S >LMUL.lis
|
||||
$ as68 -l -u -p LREM.S >LREM.lis
|
||||
$ as68 -l -u -p STARTUP.S >STARTUP.lis
|
74
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/lmul.s
Normal file
74
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/lmul.s
Normal file
@@ -0,0 +1,74 @@
|
||||
*// 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:
|
||||
~~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
|
19
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/lrem.s
Normal file
19
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/lrem.s
Normal file
@@ -0,0 +1,19 @@
|
||||
.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
|
61
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/lseek.c
Normal file
61
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/lseek.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* L s e e k F u n c t i o n */
|
||||
/* --------------------------- */
|
||||
/* */
|
||||
/* The lseek function simulates the UNIX lseek system call. */
|
||||
/* */
|
||||
/* Calling sequence: */
|
||||
/* */
|
||||
/* ret = lseek(fd,offset,sense); */
|
||||
/* */
|
||||
/* 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 "stdio.h"
|
||||
#include "cpm.h"
|
||||
LONG lseek(fd,offs,sense) /****************************/
|
||||
/* */
|
||||
WORD fd; /* Open file descriptor */
|
||||
LONG offs; /* File offset */
|
||||
WORD sense; /* Sense of offset */
|
||||
/* */
|
||||
/****************************/
|
||||
{
|
||||
/****************************/
|
||||
REG FILE *fp; /* File pointer */
|
||||
EXTERN LONG _chkc(); /* fd to fp translation */
|
||||
/* */
|
||||
if((LONG)(fp = _chkc(fd)) == FAILURE) /* 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->offset = fp->hiwater + offs;/* compute end of file */
|
||||
break; /* */
|
||||
/****************************/
|
||||
default: /* All others NFG */
|
||||
return(FAILURE); /* */
|
||||
} /****************************/
|
||||
fp->flags &= ~ATEOF; /* any seek clears EOF */
|
||||
return(fp->offset); /* Return resultant offset */
|
||||
} /****************************/
|
79
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/main.c
Normal file
79
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/main.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* R U N T I M E S T A R T O F F R O U T I N E
|
||||
* -----------------------------------------------
|
||||
*
|
||||
* Routine "_main" is entered from the C header routine to start a C
|
||||
* program. The command string from CP/M is parsed into
|
||||
* a UNIX-like "argc/argv" setup, including simple I/O redirection.
|
||||
*
|
||||
* Calling Sequence:
|
||||
*
|
||||
* return = _main(command,length);
|
||||
*
|
||||
* Where:
|
||||
*
|
||||
* command Is the address of the command line from CP/M
|
||||
* length Is the number of characters in the line,
|
||||
* excluding the termination character (CR/LF).
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include "stdio.h" /* Include std definitions */
|
||||
#include "cpm.h" /* Include CP/M Definitions */
|
||||
extern char __tname[]; /* -> terminal name */
|
||||
extern char __pname[]; /* -> Program name */
|
||||
_main(com, len) /****************************/
|
||||
char *com; /* Command address */
|
||||
int len; /* Command length */
|
||||
{ /****************************/
|
||||
char *av[30]; /* Unix's "ARGV" for main */
|
||||
register i; /* Define a count var. */
|
||||
register char *s; /* Temp byte pointer */
|
||||
int ac; /* Number of args we find */
|
||||
/****************************/
|
||||
_chinit(); /* Initialize channels */
|
||||
open(__tname,READ); /* Open STDIN */
|
||||
open(__tname,WRITE); /* Open STDOUT */
|
||||
open(__tname,WRITE); /* Open STDERR */
|
||||
av[0] = __pname; /* */
|
||||
com[len] = '\0'; /* Insure null at line end */
|
||||
ac = 1; /* Initialize count */
|
||||
for (s = com; *s; s =+ i) /* One arg at a time */
|
||||
{ /* */
|
||||
while (*s && iswhite(*s)) /* Skip leading spaces */
|
||||
++s; /* */
|
||||
if (!*s) /* End of line? */
|
||||
break; /* Yes, don't continue */
|
||||
for (i = 0; !iswhite(s[i]); ++i)/* How many characters? */
|
||||
s[i] = tolower(s[i]); /* lower case please ... */
|
||||
if (s[i]) /* If last is space, etc... */
|
||||
s[i++] = '\0'; /* Make it a null for C */
|
||||
/****************************/
|
||||
if (*s == '<') /* Redirecting input?? */
|
||||
{ /* */
|
||||
close(STDIN); /* Yes, close TTY */
|
||||
if (open(s + 1, READ,0) != STDIN) /* Open New */
|
||||
_err("Cannot open ", s + 1) ;/* Can't ... */
|
||||
} /****************************/
|
||||
else if (*s == '>') /* Redirecting output?? */
|
||||
{ /* */
|
||||
close(STDOUT); /* Close output */
|
||||
if (creat(s+1,0,0)!=STDOUT) /* Try to open new */
|
||||
_err("Cannot create ", s + 1);/* Can't */
|
||||
} /****************************/
|
||||
else /* Just a regular arg */
|
||||
av[ac++] = s; /* save in argv */
|
||||
} /****************************/
|
||||
av[ac] = NULL; /* Insure terminator */
|
||||
return (main(ac, av)); /* Invoke C program */
|
||||
} /****************************/
|
||||
|
||||
_err(s1,s2) /* Error routine */
|
||||
char *s1; /* Message text */
|
||||
char *s2; /* Filename */
|
||||
{ /****************************/
|
||||
write(STDERR,s1,_clenf(s1)); /* Output error message */
|
||||
write(STDERR,s2,_clenf(s2)); /* And filename */
|
||||
write(STDERR,"\n",1); /* + Newline */
|
||||
exit(-1); /* And fail hard */
|
||||
} /****************************/
|
@@ -0,0 +1,38 @@
|
||||
$ set noon
|
||||
$ set def drb0:[steve.cpm68k.klib]
|
||||
$ delete *.o;*,lib6.a;*,*.ic;*,*.st;*,*.i;*
|
||||
$ cc68 BLKIO
|
||||
$ cc68 CHINIT
|
||||
$ cc68 CHKC
|
||||
$ cc68 CLENF
|
||||
$ cc68 CLOSE
|
||||
$ cc68 cputc
|
||||
$ cc68 CREAT
|
||||
$ cc68 dup
|
||||
$ cc68 EXIT
|
||||
$ cc68 getc
|
||||
$ cc68 getchar
|
||||
$ cc68 getpid
|
||||
$ cc68 IGETC
|
||||
$ cc68 length
|
||||
$ cc68 LSEEK
|
||||
$ cc68 MAIN
|
||||
$ cc68 OPEN
|
||||
$ cc68 printf
|
||||
$ cc68 prtint
|
||||
$ cc68 putc
|
||||
$ cc68 putchar
|
||||
$ cc68 READ
|
||||
$ cc68 SBRK
|
||||
$ cc68 seek
|
||||
$ cc68 xSTRCMP
|
||||
$ cc68 strlen
|
||||
$ cc68 strcat
|
||||
$ cc68 UNLINK
|
||||
$ cc68 WRITE
|
||||
$ cc68 XOPEN
|
||||
$ as68 -l startup.s
|
||||
$ as68 -l lmul.s
|
||||
$ as68 -l ldiv.s
|
||||
$ as68 -l lrem.s
|
||||
$ @rear
|
312
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/make.sub
Normal file
312
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/make.sub
Normal file
@@ -0,0 +1,312 @@
|
||||
$1pip d:=$1as68symb.dat[g0
|
||||
|
||||
$1cp68 BLKIO.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic BLKIO.s -l
|
||||
$1as68 -f $1 -l -u BLKIO.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era BLKIO.s
|
||||
|
||||
$1cp68 CHINIT.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic CHINIT.s -l
|
||||
$1as68 -f $1 -l -u CHINIT.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era CHINIT.s
|
||||
|
||||
$1cp68 CHKC.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic CHKC.s -l
|
||||
$1as68 -f $1 -l -u CHKC.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era CHKC.s
|
||||
|
||||
$1cp68 CLENF.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic CLENF.s -l
|
||||
$1as68 -f $1 -l -u CLENF.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era CLENF.s
|
||||
|
||||
$1cp68 CLOSE.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic CLOSE.s -l
|
||||
$1as68 -f $1 -l -u CLOSE.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era CLOSE.s
|
||||
|
||||
$1cp68 cputc.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic cputc.s -l
|
||||
$1as68 -f $1 -l -u cputc.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era cputc.s
|
||||
|
||||
$1cp68 CREAT.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic CREAT.s -l
|
||||
$1as68 -f $1 -l -u CREAT.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era CREAT.s
|
||||
|
||||
$1cp68 dup.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic dup.s -l
|
||||
$1as68 -f $1 -l -u dup.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era dup.s
|
||||
|
||||
$1cp68 EXIT.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic EXIT.s -l
|
||||
$1as68 -f $1 -l -u EXIT.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era EXIT.s
|
||||
|
||||
$1cp68 getc.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic getc.s -l
|
||||
$1as68 -f $1 -l -u getc.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era getc.s
|
||||
|
||||
$1cp68 getchar.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic getchar.s -l
|
||||
$1as68 -f $1 -l -u getchar.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era getchar.s
|
||||
|
||||
$1cp68 getpid.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic getpid.s -l
|
||||
$1as68 -f $1 -l -u getpid.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era getpid.s
|
||||
|
||||
$1cp68 IGETC.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic IGETC.s -l
|
||||
$1as68 -f $1 -l -u IGETC.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era IGETC.s
|
||||
|
||||
$1cp68 length.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic length.s -l
|
||||
$1as68 -f $1 -l -u length.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era length.s
|
||||
|
||||
$1cp68 LSEEK.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic LSEEK.s -l
|
||||
$1as68 -f $1 -l -u LSEEK.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era LSEEK.s
|
||||
|
||||
$1cp68 MAIN.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic MAIN.s -l
|
||||
$1as68 -f $1 -l -u MAIN.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era MAIN.s
|
||||
|
||||
$1cp68 OPEN.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic OPEN.s -l
|
||||
$1as68 -f $1 -l -u OPEN.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era OPEN.s
|
||||
|
||||
$1cp68 printf.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic printf.s -l
|
||||
$1as68 -f $1 -l -u printf.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era printf.s
|
||||
|
||||
$1cp68 prtint.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic prtint.s -l
|
||||
$1as68 -f $1 -l -u prtint.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era prtint.s
|
||||
|
||||
$1cp68 putc.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic putc.s -l
|
||||
$1as68 -f $1 -l -u putc.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era putc.s
|
||||
|
||||
$1cp68 putchar.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic putchar.s -l
|
||||
$1as68 -f $1 -l -u putchar.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era putchar.s
|
||||
|
||||
$1cp68 READ.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic READ.s -l
|
||||
$1as68 -f $1 -l -u READ.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era READ.s
|
||||
|
||||
$1cp68 SBRK.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic SBRK.s -l
|
||||
$1as68 -f $1 -l -u SBRK.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era SBRK.s
|
||||
|
||||
$1cp68 seek.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic seek.s -l
|
||||
$1as68 -f $1 -l -u seek.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era seek.s
|
||||
|
||||
$1cp68 STRCMP.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic STRCMP.s -l
|
||||
$1as68 -f $1 -l -u STRCMP.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era STRCMP.s
|
||||
|
||||
$1cp68 strlen.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic strlen.s -l
|
||||
$1as68 -f $1 -l -u strlen.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era strlen.s
|
||||
|
||||
$1cp68 strcat.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic strcat.s -l
|
||||
$1as68 -f $1 -l -u strcat.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era strcat.s
|
||||
|
||||
$1cp68 UNLINK.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic UNLINK.s -l
|
||||
$1as68 -f $1 -l -u UNLINK.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era UNLINK.s
|
||||
|
||||
$1cp68 WRITE.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic WRITE.s -l
|
||||
$1as68 -f $1 -l -u WRITE.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era WRITE.s
|
||||
|
||||
$1cp68 XOPEN.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic XOPEN.s -l
|
||||
$1as68 -f $1 -l -u XOPEN.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era XOPEN.s
|
||||
|
||||
$1cp68 XSTRCMP.c $1x.i
|
||||
$1c068 $1x.i $1x.ic $1x.st
|
||||
$1c168 $1x.ic XSTRCMP.s -l
|
||||
$1as68 -f $1 -l -u XSTRCMP.s
|
||||
era $1x.i
|
||||
era $1x.ic
|
||||
era $1x.st
|
||||
era XSTRCMP.s
|
||||
|
||||
$1as68 -f $1 -l startup.s
|
||||
$1as68 -f $1 -l ldiv.s
|
||||
$1as68 -f $1 -l lmul.s
|
||||
$1as68 -f $1 -l lrem.s
|
||||
$1as68 -f $1 -l copyrt.s
|
||||
|
||||
era lib6.a
|
||||
$1ar68 rf $1 lib6.a main.o printf.o prtint.o cputc.o putchar.o putc.o getchar.o
|
||||
$1ar68 rf $1 lib6.a getc.o exit.o close.o open.o creat.o read.o write.o seek.o
|
||||
$1ar68 rf $1 lib6.a lseek.o xopen.o unlink.o blkio.o chinit.o chkc.o igetc.o
|
||||
$1ar68 rf $1 lib6.a strcmp.o sbrk.o xstrcmp.o length.o clenf.o lrem.o ldiv.o
|
||||
$1ar68 rf $1 lib6.a lmul.o dup.o strlen.o strcat.o copyrt.o
|
||||
|
||||
era as68symb.dat
|
||||
|
||||
user 6!make e:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -0,0 +1 @@
|
||||
user 7 ! make
|
64
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/open.c
Normal file
64
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/open.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* C F I L E O P E N R O U T I N E
|
||||
* -------------------------------------
|
||||
*
|
||||
* The "open" routine opens a "C" file and returns a file id.
|
||||
*
|
||||
* Calling Sequence:
|
||||
*
|
||||
* 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 "stdio.h" /* Include Whitesmith's */
|
||||
#include "cpm.h" /* + CP/M */
|
||||
EXTERN BYTE __tname[]; /* -> CON: */
|
||||
EXTERN BYTE __lname[]; /* -> LST: */
|
||||
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 FILE *ch; /* -> CCB for channel */
|
||||
EXTERN FILE *_getc(); /* fd to fp converter */
|
||||
/* */
|
||||
if((ich = igetc()) < 0) /* Allocate a channel */
|
||||
return (FAILURE); /* Can't */
|
||||
/* */
|
||||
__chinit(ich); /* Clear out channel's ccb */
|
||||
ch = _getc(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 */
|
||||
return(FAILURE); /* If return <> 0, NFG. */
|
||||
/* Else: */
|
||||
ch -> flags |= OPENED; /* Set OPEN bit */
|
||||
return(ich); /* Return Channel # */
|
||||
} /****************************/
|
@@ -0,0 +1,51 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* 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 */
|
||||
/***************************/
|
||||
#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 (BYTE *)0 /* Null pointer value */
|
||||
#define EOF (-1) /* EOF Value */
|
||||
#define TRUE (1) /* Function TRUE value */
|
||||
#define FALSE (0) /* Function FALSE value */
|
||||
|
||||
/*************************** end of portab.h ********************************/
|
275
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/printf.c
Normal file
275
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/printf.c
Normal file
@@ -0,0 +1,275 @@
|
||||
# include "iodec.h"
|
||||
# define BUFSIZ 80
|
||||
|
||||
/**
|
||||
** formated print
|
||||
**/
|
||||
|
||||
printf(parlist)
|
||||
char *parlist;
|
||||
{
|
||||
register char *fmt, c;
|
||||
char buf[BUFSIZ];
|
||||
extern char *__prtshort(), *__prtld(), *__prtld();
|
||||
// double *dblptr;
|
||||
int mode;
|
||||
char *fd;
|
||||
register char **p;
|
||||
register int *pi;
|
||||
int width, prec;
|
||||
int left, longf;
|
||||
char padchar;
|
||||
char *s;
|
||||
int n;
|
||||
auto (*fn)();
|
||||
int len;
|
||||
|
||||
p = &parlist;
|
||||
fd = 0;
|
||||
mode = 0; /* mode zero, putchar */
|
||||
if (parlist + 1 < MAXFILES + 1)
|
||||
{
|
||||
mode++; /* mode one, cputc */
|
||||
fd = *p++;
|
||||
}
|
||||
if (fd == -1)
|
||||
{
|
||||
mode++; /* mode two, string */
|
||||
fd = *p++;
|
||||
}
|
||||
fmt = *p++;
|
||||
|
||||
pi = p;
|
||||
while (c = *fmt++)
|
||||
{
|
||||
p = pi;
|
||||
if (c != '%')
|
||||
{
|
||||
__putch(mode, &fd, c);
|
||||
continue;
|
||||
}
|
||||
left = 0;
|
||||
if ((c = *fmt++) == '-')
|
||||
{
|
||||
c = *fmt++;
|
||||
left++;
|
||||
}
|
||||
padchar = ' ';
|
||||
if (c == '0')
|
||||
{
|
||||
padchar = c;
|
||||
c = *fmt++;
|
||||
}
|
||||
width = -1;
|
||||
while (c >= '0' && c <= '9')
|
||||
{
|
||||
if (width < 0)
|
||||
width = 0;
|
||||
width = width * 10 + (c - '0');
|
||||
c = *fmt++;
|
||||
}
|
||||
prec = -1;
|
||||
if (c == '.')
|
||||
{
|
||||
prec = 0;
|
||||
c = *fmt++;
|
||||
}
|
||||
while (c >= '0' && c <= '9')
|
||||
{
|
||||
prec = prec * 10 + (c - '0');
|
||||
c = *fmt++;
|
||||
}
|
||||
longf = 0;
|
||||
if (c == 'l')
|
||||
{
|
||||
longf++;
|
||||
c = *fmt++;
|
||||
}
|
||||
/* we now have all the prelims out of the way;
|
||||
let's see what we want to print */
|
||||
|
||||
s = buf;
|
||||
switch (c)
|
||||
{
|
||||
|
||||
case 'd': /* decimal signed */
|
||||
case 'D':
|
||||
if (longf)
|
||||
fn = __prtld;
|
||||
else
|
||||
fn = __prtshort;
|
||||
__prtint(pi++, buf, 10, 1, fn, 0);
|
||||
if (longf)
|
||||
pi++;
|
||||
break;
|
||||
|
||||
case 'u': /* decimal unsigned */
|
||||
case 'U':
|
||||
__prtint(pi++, buf, 10, 0, __prtshort, 0);
|
||||
break;
|
||||
|
||||
case 'o': /* octal unsigned */
|
||||
case 'O':
|
||||
if (longf)
|
||||
fn = __prtld;
|
||||
else
|
||||
fn = __prtshort;
|
||||
__prtint(pi++, buf, 8, 0, fn, 0);
|
||||
if (longf)
|
||||
pi++;
|
||||
break;
|
||||
|
||||
case 'x': /* hexadecimal unsigned */
|
||||
case 'X':
|
||||
if (longf)
|
||||
fn = __prtld;
|
||||
else
|
||||
fn = __prtshort;
|
||||
__prtint(pi++, buf, 16, 0, fn, c == 'X');
|
||||
if (longf)
|
||||
pi++;
|
||||
break;
|
||||
|
||||
case 's': /* string */
|
||||
case 'S':
|
||||
s = *p++;
|
||||
pi = p;
|
||||
break;
|
||||
|
||||
case 'c': /* character */
|
||||
case 'C':
|
||||
n = *pi++;
|
||||
buf[0] = n;
|
||||
buf[1] = '\0';
|
||||
break;
|
||||
|
||||
// case 'e': /* exponential */
|
||||
// case 'E':
|
||||
// case 'f': /* floating */
|
||||
// case 'F':
|
||||
// case 'g': /* e or f */
|
||||
// case 'G':
|
||||
// case 'n':
|
||||
// case 'N':
|
||||
// dblptr = p;
|
||||
// if (prec < 0)
|
||||
// prec = 7;
|
||||
// ftoa(*dblptr, buf, sizeof buf - 1, prec, c);
|
||||
// while (*s == ' ')
|
||||
// s++;
|
||||
// p =+ 4;
|
||||
// prec = -1;
|
||||
// break;
|
||||
|
||||
default: /* just print the character */
|
||||
__putch(mode, &fd, c);
|
||||
continue;
|
||||
|
||||
}
|
||||
len = __length(s);
|
||||
if (prec < len && prec >= 0)
|
||||
len = prec;
|
||||
n = width - len;
|
||||
if (!left)
|
||||
{
|
||||
if (padchar != ' ' && *s == '-')
|
||||
{
|
||||
len--;
|
||||
__putch(mode, &fd, *s++);
|
||||
}
|
||||
while (n-- > 0)
|
||||
__putch(mode, &fd, padchar);
|
||||
}
|
||||
while (len--)
|
||||
__putch(mode, &fd, *s++);
|
||||
while (n-- > 0)
|
||||
__putch(mode, &fd, padchar);
|
||||
}
|
||||
if (mode == 2)
|
||||
*fd = '\0';
|
||||
}
|
||||
|
||||
|
||||
__putch(mode, pfd, c)
|
||||
int mode;
|
||||
char c;
|
||||
char **pfd;
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
|
||||
case 0:
|
||||
putchar(c);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
cputc(c, *pfd);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
*(*pfd)++ = c;
|
||||
break;
|
||||
|
||||
}
|
||||
return (c);
|
||||
}
|
||||
|
||||
|
||||
char *__prtld(pobj, pbuf, base, signed, digs)
|
||||
long *pobj;
|
||||
char **pbuf;
|
||||
int base;
|
||||
int signed;
|
||||
char *digs;
|
||||
{
|
||||
register long n;
|
||||
register long b;
|
||||
register char *p;
|
||||
struct {
|
||||
char cbyte0;
|
||||
char cbyte1;
|
||||
char cbyte2;
|
||||
char cbyte3;
|
||||
};
|
||||
extern long ldiv();
|
||||
extern long ldivr;
|
||||
register i;
|
||||
struct {
|
||||
int wd1;
|
||||
int wd2;
|
||||
};
|
||||
|
||||
p = digs;
|
||||
b = base;
|
||||
n = *pobj;
|
||||
if(base == 16) { //special because of negatives
|
||||
i = 8;
|
||||
while(n && i) {
|
||||
*p++ = n & 0xf;
|
||||
n =>> 4;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
else if(base == 8) {
|
||||
i = 11;
|
||||
while(n && i) {
|
||||
*p++ = n & 7;
|
||||
n =>> 3;
|
||||
i--;
|
||||
}
|
||||
if(i==0) {
|
||||
*(p-1) =& 3; //only 2 bits in upper octal digit
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (signed && n < 0) {
|
||||
*(*pbuf)++ = '-';
|
||||
n = -n;
|
||||
}
|
||||
while(n) {
|
||||
n = ldiv(n,b);
|
||||
*p++ = ldivr.cbyte3;
|
||||
}
|
||||
}
|
||||
return (p);
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
char *__prtint(pobj, buf, base, signed, f, upper)
|
||||
int *pobj;
|
||||
char *buf;
|
||||
int base;
|
||||
int signed;
|
||||
int upper;
|
||||
char *(*f)();
|
||||
{
|
||||
char digs[15];
|
||||
register char *dp;
|
||||
register int k;
|
||||
register char *p;
|
||||
|
||||
dp = (*f)(pobj, &buf, base, signed, digs);
|
||||
|
||||
if (dp == digs)
|
||||
*dp++ = 0;
|
||||
p = buf;
|
||||
while (dp != digs)
|
||||
{
|
||||
k = *--dp;
|
||||
if (k < 10)
|
||||
k =+ '0';
|
||||
else
|
||||
k =+ upper ? 'A'-10 : 'a'-10;
|
||||
*p++ = k;
|
||||
}
|
||||
*p = 0;
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
||||
char *__prtshort(pobj, pbuf, base, signed, digs)
|
||||
int *pobj;
|
||||
char **pbuf;
|
||||
int base;
|
||||
int signed;
|
||||
char *digs;
|
||||
{
|
||||
extern long ldivr;
|
||||
register long n;
|
||||
register char *p;
|
||||
register long b;
|
||||
|
||||
p = digs;
|
||||
b = base;
|
||||
n = *pobj;
|
||||
if (signed && n < 0)
|
||||
{
|
||||
n = -n;
|
||||
*(*pbuf)++ = '-';
|
||||
}
|
||||
else {
|
||||
n =& 0xffffL; //clear upper half
|
||||
}
|
||||
while (n != 0)
|
||||
{
|
||||
n = ldiv(n,b);
|
||||
*p++ = ldivr;
|
||||
}
|
||||
return (p);
|
||||
}
|
63
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/putc.c
Normal file
63
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/putc.c
Normal file
@@ -0,0 +1,63 @@
|
||||
#define BLEN 512
|
||||
|
||||
struct iob {
|
||||
int fd; /*file descriptor*/
|
||||
int cc; /*char count*/
|
||||
char *cp; /*ptr to next char*/
|
||||
char cbuf[BLEN]; /*char buffer*/
|
||||
};
|
||||
|
||||
fcreat(fname,ibuf,x)
|
||||
char *fname;
|
||||
int x;
|
||||
register struct iob *ibuf;
|
||||
{
|
||||
|
||||
ibuf->cc = BLEN; /*no chars*/
|
||||
ibuf->cp = &(ibuf->cbuf[0]);
|
||||
x = (x == 0) ? 0 : 1;
|
||||
return(ibuf->fd=creat(fname,2,x));
|
||||
}
|
||||
|
||||
putc(c,ibuf)
|
||||
char c;
|
||||
register struct iob *ibuf;
|
||||
{
|
||||
|
||||
if(ibuf->cc<=0) {
|
||||
ibuf->cp = &(ibuf->cbuf[0]);
|
||||
if(write(ibuf->fd,ibuf->cp,BLEN) != BLEN)
|
||||
return(-1);
|
||||
ibuf->cc = BLEN;
|
||||
}
|
||||
*(ibuf->cp)++ = c;
|
||||
ibuf->cc--;
|
||||
return(c);
|
||||
}
|
||||
|
||||
putw(w,ibuf)
|
||||
int w;
|
||||
register struct iob *ibuf;
|
||||
{
|
||||
|
||||
register j;
|
||||
int i;
|
||||
|
||||
putc((w>>8)&0xff,ibuf);
|
||||
putc(w&0xff,ibuf);
|
||||
return(w);
|
||||
}
|
||||
|
||||
myfflush(ibuf)
|
||||
register struct iob *ibuf;
|
||||
{
|
||||
|
||||
register i;
|
||||
|
||||
i = BLEN - ibuf->cc;
|
||||
ibuf->cc = BLEN;
|
||||
ibuf->cp = &(ibuf->cbuf[0]);
|
||||
if(write(ibuf->fd,ibuf->cp,i) != i)
|
||||
return(-1);
|
||||
return(0);
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
#define BLEN 512
|
||||
|
||||
struct iob {
|
||||
int fd; /*file descriptor*/
|
||||
int cc; /*char count*/
|
||||
char *cp; /*ptr to next char*/
|
||||
char cbuf[BLEN]; /*char buffer*/
|
||||
} fout = {0,BLEN,&fout.cbuf[0]};
|
||||
|
||||
putchar(cc)
|
||||
char cc;
|
||||
{
|
||||
|
||||
if(fout.fd <= 1) {
|
||||
if(write(1,&cc,1) != 1)
|
||||
return(-1);
|
||||
return(cc);
|
||||
}
|
||||
/* buffered output*/
|
||||
if(fout.cc<=0) {
|
||||
fout.cp = &(fout.cbuf[0]);
|
||||
if(write(fout.fd,fout.cp,BLEN) != BLEN)
|
||||
return(-1);
|
||||
fout.cc = BLEN;
|
||||
}
|
||||
*(fout.cp)++ = cc;
|
||||
fout.cc--;
|
||||
return(cc);
|
||||
}
|
||||
|
||||
myflush()
|
||||
{
|
||||
|
||||
register i;
|
||||
|
||||
i = BLEN - fout.cc;
|
||||
fout.cc = BLEN;
|
||||
fout.cp = &(fout.cbuf[0]);
|
||||
if(write(fout.fd,fout.cp,i) != i)
|
||||
return(-1);
|
||||
return(0);
|
||||
}
|
280
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/read.c
Normal file
280
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/read.c
Normal file
@@ -0,0 +1,280 @@
|
||||
#define RETERR(x,y) return(x)
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* 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 "stdio.h"
|
||||
#include "cpm.h"
|
||||
|
||||
WORD read(fd,buff,pbytes) /****************************/
|
||||
WORD fd; /* File descriptor */
|
||||
REG BYTE *buff; /* -> buffer start */
|
||||
WORD pbytes; /* = byte count to read */
|
||||
{ /****************************/
|
||||
REG FILE *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 FILE *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->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 */
|
||||
} /****************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* _ t t y i n F u n c t i o n */
|
||||
/* ----------------------------- */
|
||||
/* */
|
||||
/* Function "_ttyin" is used to read a line from the terminal. */
|
||||
/* */
|
||||
/* Calling Sequence: */
|
||||
/* */
|
||||
/* ret = _ttyin(buffer,bytes); */
|
||||
/* */
|
||||
/* Where: */
|
||||
/* */
|
||||
/* buffer -> the user's input buffer */
|
||||
/* bytes = the (maximum) number of bytes to read */
|
||||
/* */
|
||||
/* ret = the number of bytes actually read */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
WORD _ttyin(buff,bytes) /****************************/
|
||||
/* */
|
||||
REG BYTE *buff; /* -> user's buffer */
|
||||
REG LONG bytes; /* = requested byte count */
|
||||
/* */
|
||||
{ /****************************/
|
||||
LOCAL BYTE ttybuf[257]; /* Biggest line from tty */
|
||||
REG LONG xbytes; /* Returned byte count */
|
||||
REG BYTE *p; /* Temp pointer */
|
||||
/* */
|
||||
ttybuf[0] = 255; /* Max # bytes */
|
||||
__BDOS(CONBUF,&ttybuf[0]); /* Read line from BDOS */
|
||||
__BDOS(CONOUT,(LONG)'\n'); /* Pop a line feed */
|
||||
/****************************/
|
||||
xbytes = ttybuf[1] & 0xffL; /* # characters read */
|
||||
p = &ttybuf[2]; /* p -> First character */
|
||||
while( bytes > 0 && xbytes > 0) /* */
|
||||
{ /* Copy 1 byte / time */
|
||||
*buff++ = *p++; /* */
|
||||
bytes--; /* Decrement request */
|
||||
xbytes--; /* Decrement bytes in buff */
|
||||
} /****************************/
|
||||
if(bytes > 0) /* Terminate on count? */
|
||||
{ /* */
|
||||
*buff++ = '\n'; /* No, plug in newline */
|
||||
p++; /* Bump pointer */
|
||||
} /****************************/
|
||||
return(p-&ttybuf[2]); /* Return # bytes moved */
|
||||
} /****************************/
|
@@ -0,0 +1,9 @@
|
||||
$ set noon
|
||||
$ delete lib6.a;*
|
||||
$ ar68 r lib6.a main.o printf.o prtint.o cputc.o putchar.o putc.o getchar.o -
|
||||
getc.o exit.o close.o open.o creat.o read.o write.o seek.o lseek.o -
|
||||
xopen.o unlink.o blkio.o chinit.o chkc.o igetc.o sbrk.o xstrcmp.o
|
||||
$ ar68 r lib6.a length.o clenf.o lrem.o ldiv.o lmul.o lrem.o -
|
||||
dup.o strlen.o strcat.o
|
||||
$ copy lib6.a lib:
|
||||
$ purge lib:
|
40
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/sbrk.c
Normal file
40
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/sbrk.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* s b r k F u n c t i o n */
|
||||
/* ------------------------- */
|
||||
/* */
|
||||
/* 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 "stdio.h"
|
||||
#include "cpm.h"
|
||||
EXTERN BYTE *_break; /* Old break address */
|
||||
/****************************/
|
||||
BYTE *sbrk(incr) /* */
|
||||
WORD incr; /* Incremental storage */
|
||||
/* */
|
||||
{ /****************************/
|
||||
REG BYTE *t1; /* Temporary */
|
||||
if(incr & 1) /* Disallow odd incr's */
|
||||
incr++; /* Round up to next */
|
||||
/* */
|
||||
t1 = _break + incr; /* New break value */
|
||||
/****************************/
|
||||
if(brk(t1) == FAILURE) /* Allocate */
|
||||
return(FAILURE); /* Can't */
|
||||
/****************************/
|
||||
t1 = _break; /* Save old break */
|
||||
_break += incr; /* Set new break */
|
||||
return(t1); /* And return */
|
||||
} /****************************/
|
18
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/seek.c
Normal file
18
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/seek.c
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Seek.c -- Whitesmith's equivalent of V6 seek
|
||||
*/
|
||||
long lseek();
|
||||
|
||||
seek(fildes,offset,ptrname)
|
||||
int fildes; /* UNIX / WS file descriptor */
|
||||
int offset; /* File offset, bytes */
|
||||
int ptrname; /* Sense variable */
|
||||
{
|
||||
offset &= 0xffff; /* Clear sign extension problems*/
|
||||
if(ptrname > 2) /* Not byte sense seek */
|
||||
{ /* */
|
||||
offset = offset << 9; /* Multiply by 512 */
|
||||
ptrname -= 3; /* reset to range 0 .. 2 */
|
||||
} /********************************/
|
||||
return(lseek(fildes,(long)offset,ptrname));
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
$ set noon
|
||||
$ vsend BLKIO.C
|
||||
$ vsend CHINIT.C
|
||||
$ vsend CHKC.C
|
||||
$ vsend CLENF.C
|
||||
$ vsend CLOSE.C
|
||||
$ vsend CPUTC.C
|
||||
$ vsend CREAT.C
|
||||
$ vsend DUP.C
|
||||
$ vsend EXIT.C
|
||||
$ vsend GETC.C
|
||||
$ vsend GETCHAR.C
|
||||
$ vsend GETPID.C
|
||||
$ vsend IGETC.C
|
||||
$ vsend LDIV.C
|
||||
$ vsend LENGTH.C
|
||||
$ vsend LSEEK.C
|
||||
$ vsend MAIN.C
|
||||
$ vsend OPEN.C
|
||||
$ vsend PRINTF.C
|
||||
$ vsend PRTINT.C
|
||||
$ vsend PUTC.C
|
||||
$ vsend PUTCHAR.C
|
||||
$ vsend READ.C
|
||||
$ vsend SBRK.C
|
||||
$ vsend SEEK.C
|
||||
$ vsend STRCAT.C
|
||||
$ vsend STRCMP.C
|
||||
$ vsend STRLEN.C
|
||||
$ vsend TTYIN.C
|
||||
$ vsend UNLINK.C
|
||||
$ vsend WRITE.C
|
||||
$ vsend XOPEN.C
|
||||
$ vsend XSTRCMP.C
|
||||
$ vsend XTTYIN.C
|
||||
$ vsend ALDIV.S
|
||||
$ vsend ALMUL.S
|
||||
$ vsend ALREM.S
|
||||
$ vsend COPYRT.S
|
||||
$ vsend LDIV.S
|
||||
$ vsend LMUL.S
|
||||
$ vsend LREM.S
|
||||
$ vsend STARTUP.S
|
||||
$ vsend COUT.H
|
||||
$ vsend CPM.H
|
||||
$ vsend IODEC.H
|
||||
$ vsend PORTAB.H
|
||||
$ vsend SENDC68.H
|
||||
$ vsend STDIO.H
|
||||
$ vsend DOWNLOAD.SUB
|
||||
$ vsend MAKE.SUB
|
||||
$ vsend NEXT.SUB
|
@@ -0,0 +1,72 @@
|
||||
#
|
||||
/* format of a symbol entry in the main table*/
|
||||
|
||||
#define SEEKREL 1 /*relative seek flag*/
|
||||
|
||||
#define OSTSIZE 14 /*symbol table entry length on object file*/
|
||||
/* without table link*/
|
||||
# define STESIZE 18 /*byte length of symbol table entry*/
|
||||
struct symtab {
|
||||
char name[8]; /*symbol name*/
|
||||
short flags; /*bit flags*/
|
||||
long vl1; /*symbol value*/
|
||||
char *tlnk; /*table link*/
|
||||
};
|
||||
|
||||
struct symtab *symptr;
|
||||
|
||||
/* flags for symbols*/
|
||||
# define SYDF 0100000 /*defined*/
|
||||
# define SYEQ 0040000 /*equated*/
|
||||
# define SYGL 0020000 /*global - entry or external*/
|
||||
# define SYER 0010000 /*equated register*/
|
||||
# define SYXR 0004000 /*external reference*/
|
||||
# define SYDA 0002000 /*DATA based relocatable*/
|
||||
# define SYTX 0001000 /*TEXT based relocatable*/
|
||||
# define SYBS 0000400 /*BSS based relocatable*/
|
||||
|
||||
struct irts {
|
||||
char *irle; /*ptr to last entry in chain*/
|
||||
char *irfe; /*ptr to first entry in chain*/
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
struct {
|
||||
short loword;
|
||||
short hiword;
|
||||
};
|
||||
*/
|
||||
struct {
|
||||
short hiword;
|
||||
short loword;
|
||||
};
|
||||
/*
|
||||
struct {
|
||||
char lobyte;
|
||||
char hibyte;
|
||||
};
|
||||
*/
|
||||
struct {
|
||||
char hibyte;
|
||||
char lobyte;
|
||||
};
|
||||
/* relocation bit definitions:*/
|
||||
#define RBMASK 07 /*tells type of relocation*/
|
||||
#define INSABS 7 /*first word of instr -- absolute*/
|
||||
#define DABS 0 /*data word absolute*/
|
||||
#define TRELOC 2 /* TEXT relocatable*/
|
||||
#define DRELOC 1 /* DATA relocatable*/
|
||||
#define BRELOC 3 /* BSS relocatable*/
|
||||
#define EXTVAR 4 /* ref to external variable*/
|
||||
#define LUPPER 5 /* upper word of long*/
|
||||
|
||||
struct buf{
|
||||
int fildes;
|
||||
int nunused;
|
||||
char *xfree;
|
||||
char buff[512];
|
||||
};
|
||||
|
||||
struct buf ibuf;
|
||||
char *ifilname=0;
|
@@ -0,0 +1,99 @@
|
||||
******************************************************************************
|
||||
*
|
||||
* 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 ___cpyrt
|
||||
.text
|
||||
__start: bra start1 * jump around copyright
|
||||
*
|
||||
.dc.b 'CP/M-68K(tm), Version 1.1, Copyright (c) 1983, '
|
||||
.dc.b 'Digital Research' * copyright notice
|
||||
.dc.b 'XXXX-0000-654321' * serial number
|
||||
*
|
||||
.even
|
||||
start1: move.l 4(a7),a0 * a0 -> Base page
|
||||
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
|
||||
jsr _exit * call "exit"
|
||||
*
|
||||
*
|
||||
.bss
|
||||
__break: .ds.l 1 * Break function
|
||||
*
|
||||
*
|
||||
.globl _brk
|
||||
.text
|
||||
_brk: link a6,#0 * preserve conventions
|
||||
clr.l d0 * clear return
|
||||
movea.l 8(sp),a0 * New break?
|
||||
adda.l #$100,a0 * Chicken factor
|
||||
cmpa.l a0,sp * Compare
|
||||
bhis brkok * OK, continue
|
||||
move.l #-1,d0 * Load return reg
|
||||
brkok:
|
||||
unlk a6 * Unlink
|
||||
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
|
||||
*
|
||||
* 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
|
80
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/stdio.h
Normal file
80
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/stdio.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* C P / M C H E A D E R F I L E
|
||||
* -----------------------------------
|
||||
*
|
||||
* This is the standard include file for the CP/M-68K assembler / linker
|
||||
* kludge package.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Standard type definitions
|
||||
*/
|
||||
/***************************/
|
||||
#define BYTE char /* Signed byte */
|
||||
#define UBYTE unsigned char /* Unsigned byte */
|
||||
#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 */
|
||||
/***************************/
|
||||
|
||||
/* Open Mode Definitions */
|
||||
|
||||
/************************************/
|
||||
#define READ 0 /* Open for READ only */
|
||||
#define WRITE 1 /* Open for WRITE only */
|
||||
#define IO 2 /* Open for READ and WRITE */
|
||||
#define UPDATE 2 /* Same as IO */
|
||||
/************************************/
|
||||
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* Miscellaneous Definitions: */
|
||||
/****************************************************************************/
|
||||
#define FILE struct ccb /* Define FILE pointer */
|
||||
#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 EOF (-1) /* EOF Value */
|
||||
#define TRUE (1) /* Function TRUE value */
|
||||
#define FALSE (0) /* Function FALSE value */
|
||||
#define STDIN 0 /* File */
|
||||
#define STDOUT 1 /* numbers */
|
||||
#define STDERR 2 /* for std i/o */
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* M A C R O S */
|
||||
/* ----------- */
|
||||
/* */
|
||||
/* Define some stuff as macros .... */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
#define stdin (&_iob[0]) /* Standard input channel */
|
||||
#define stdout (&_iob[1]) /* Standard output channel */
|
||||
#define stderr (&_iob[2]) /* Standard error channel */
|
||||
#define fileno(p) p->chan /* File # of a channel */
|
||||
#define abs(x) ((x) < 0 ? -(x) : (x)) /* Absolute value function */
|
||||
|
||||
#define isalpha(c) (islower(c)||isupper(c)) /* true if "c" a letter */
|
||||
#define isdigit(c) ('0' <= (c) && (c) <= '9') /* Ascii only!! */
|
||||
#define islower(c) ('a' <= (c) && (c) <= 'z') /* Ascii only!! */
|
||||
#define isupper(c) ('A' <= (c) && (c) <= 'Z') /* Ascii only!! */
|
||||
#define iswhite(c) ((c) <= ' ' || 0177<= (c)) /* Is control / funny char */
|
||||
#define max(x,y) (((x) > (y)) ? (x) : (y)) /* Max function */
|
||||
#define min(x,y) (((x) < (y)) ? (x) : (y)) /* Min function */
|
||||
#define tolower(c) (isupper(c) ? ((c)+040):(c)) /* translate to lower case */
|
||||
#define toupper(c) (islower(c) ? ((c)-040):(c)) /* translate to upper case */
|
@@ -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);
|
||||
}
|
||||
|
@@ -0,0 +1,37 @@
|
||||
/*********************************************************************
|
||||
* STRCMP - compares strings
|
||||
*
|
||||
* Special version which is case - insensitive.
|
||||
*
|
||||
* 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 = _toupper(*s1++);
|
||||
b = _toupper(*s2++);
|
||||
if (a > b) return (1);
|
||||
if (a < b) return (-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
MLOCAL BYTE _toupper(c)
|
||||
REG BYTE c;
|
||||
{
|
||||
if(c >= 'a' && c <= 'z')
|
||||
c -= 'a' - 'A';
|
||||
return(c);
|
||||
}
|
@@ -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);
|
||||
}
|
||||
|
288
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/ttyin.c
Normal file
288
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/ttyin.c
Normal file
@@ -0,0 +1,288 @@
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* R e a d F u n c t i o n */
|
||||
/* ------------------------- */
|
||||
/* */
|
||||
/* The read function simulates the UNIX read system call. Any */
|
||||
/* arbitrary number of bytes may be read at any arbitrary offset in */
|
||||
/* the file. */
|
||||
/* */
|
||||
/* Calling Sequence: */
|
||||
/* */
|
||||
/* ret = read(fd,buffer,bytes); */
|
||||
/* */
|
||||
/* Where: */
|
||||
/* */
|
||||
/* fd Is an open file descriptor */
|
||||
/* buffer Is the buffer address */
|
||||
/* bytes Is the number of bytes to read */
|
||||
/* */
|
||||
/* ret Is the number of bytes which were actually read */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
#include "stdio.h"
|
||||
#include "cpm.h"
|
||||
|
||||
WORD read(fd,buff,pbytes) /****************************/
|
||||
/* */
|
||||
WORD fd; /* File descriptor */
|
||||
REG BYTE *buff; /* -> buffer start */
|
||||
WORD pbytes; /* = byte count to read */
|
||||
/* */
|
||||
/****************************/
|
||||
{
|
||||
/****************************/
|
||||
REG FILE *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?? */
|
||||
return(FAILURE); /* A wise guy!! */
|
||||
/****************************/
|
||||
if((fp->flags & ISTTY) != 0) /* TTY? */
|
||||
return(_ttyin(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) /* */
|
||||
return(FAILURE); /* Unable to write, quit */
|
||||
fp->flags &= ~DIRTY; /* Wipe dirty bit */
|
||||
} /****************************/
|
||||
if(_blkio(fp,xsector,fp->buffer,1L, /* Read proper sector */
|
||||
B_READ) != 1) /* */
|
||||
{ /* */
|
||||
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 */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
_rdbin(fp,buff,bytes) /****************************/
|
||||
/* */
|
||||
REG FILE *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 */
|
||||
return(FAILURE); /* Can't; just quit. */
|
||||
fp->flags &= ~DIRTY; /* Buffer now clean */
|
||||
} /****************************/
|
||||
if(_blkio(fp,xsector,fp->buffer, /* Now read the */
|
||||
1L,B_READ) != 1) /* next sector */
|
||||
return(FAILURE); /* Can't */
|
||||
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? */
|
||||
{ /* */
|
||||
if(_blkio(fp,fp->sector, /* */
|
||||
fp->buffer,1L,B_WRITE) != 1) /* Try to write old buffer */
|
||||
return(FAILURE); /* Can't; just quit. */
|
||||
fp->flags &= ~DIRTY; /* Clear dirty bit */
|
||||
} /****************************/
|
||||
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->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 */
|
||||
} /****************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* _ t t y i n F u n c t i o n */
|
||||
/* ----------------------------- */
|
||||
/* */
|
||||
/* Function "_ttyin" is used to read a line from the terminal. */
|
||||
/* */
|
||||
/* Calling Sequence: */
|
||||
/* */
|
||||
/* ret = _ttyin(buffer,bytes); */
|
||||
/* */
|
||||
/* Where: */
|
||||
/* */
|
||||
/* buffer -> the user's input buffer */
|
||||
/* bytes = the (maximum) number of bytes to read */
|
||||
/* */
|
||||
/* ret = the number of bytes actually read */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
WORD _ttyin(buff,bytes) /****************************/
|
||||
/* */
|
||||
REG BYTE *buff; /* -> user's buffer */
|
||||
REG LONG bytes; /* = requested byte count */
|
||||
/* */
|
||||
{ /****************************/
|
||||
LOCAL BYTE ttybuf[257]; /* Biggest line from tty */
|
||||
REG LONG xbytes; /* Returned byte count */
|
||||
REG BYTE *p; /* Temp pointer */
|
||||
/* */
|
||||
ttybuf[0] = 255; /* Max # bytes */
|
||||
__BDOS(CONBUF,&ttybuf[0]); /* Read line from BDOS */
|
||||
__BDOS(CONOUT,(LONG)'\n'); /* Pop a line feed */
|
||||
/****************************/
|
||||
xbytes = ttybuf[1] & 0xffL; /* # characters read */
|
||||
p = &ttybuf[2]; /* p -> First character */
|
||||
while( bytes > 0 && xbytes > 0) /* */
|
||||
{ /* Copy 1 byte / time */
|
||||
*buff++ = *p++; /* */
|
||||
bytes--; /* Decrement request */
|
||||
xbytes--; /* Decrement bytes in buff */
|
||||
} /****************************/
|
||||
if(bytes > 0) /* Terminate on count? */
|
||||
{ /* */
|
||||
*buff++ = '\n'; /* No, plug in newline */
|
||||
p++; /* Bump pointer */
|
||||
} /****************************/
|
||||
return(p-&ttybuf[2]); /* Return # bytes moved */
|
||||
} /****************************/
|
@@ -0,0 +1,35 @@
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* U n l i n k F u n c t i o n */
|
||||
/* ----------------------------- */
|
||||
/* */
|
||||
/* The unlink function is used to delete a CP/M file by name. */
|
||||
/* */
|
||||
/* Calling Sequence: */
|
||||
/* */
|
||||
/* ret = unlink(filename); */
|
||||
/* */
|
||||
/* Where: */
|
||||
/* filename Is the null-terminated name of the file */
|
||||
/* */
|
||||
/* ret Is 0 for success, -1 for failure */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
#include "stdio.h"
|
||||
#include "cpm.h"
|
||||
WORD unlink(filename)
|
||||
/****************************/
|
||||
BYTE *filename; /* -> filename */
|
||||
{ /****************************/
|
||||
REG WORD ch; /* Channel number */
|
||||
REG WORD ret; /* Temp return value */
|
||||
/****************************/
|
||||
if((ch=igetc()) < 0) /* Allocate a channel */
|
||||
return(FAILURE); /* Can't */
|
||||
/* */
|
||||
__chinit(ch); /* Init fcb and ccb */
|
||||
ret = _open(ch,filename,DELETE); /* Delete the file */
|
||||
freec(ch); /* Free the channel */
|
||||
return(ret); /* Return result of DELETE */
|
||||
} /****************************/
|
||||
|
315
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/write.c
Normal file
315
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/write.c
Normal file
@@ -0,0 +1,315 @@
|
||||
#define RETERR(x,y) return(x)
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* W r i t e F u n c t i o n */
|
||||
/* --------------------------- */
|
||||
/* Copyright 1982 by Digital Research Inc. All rights reserved. */
|
||||
/* */
|
||||
/* Function "write" simulates the UNIX write system call. Any */
|
||||
/* arbitrary number of bytes are written to the file specified by */
|
||||
/* file descriptor. No special alignment of file or buffer is */
|
||||
/* required. */
|
||||
/* */
|
||||
/* Calling Sequence: */
|
||||
/* */
|
||||
/* ret = write(fd,buffer,bytes); */
|
||||
/* */
|
||||
/* Where: */
|
||||
/* */
|
||||
/* fd is an open file descriptor */
|
||||
/* buffer is the buffer address */
|
||||
/* bytes is the number of bytes to be written */
|
||||
/* */
|
||||
/* ret is the number of bytes actually written */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
#include "stdio.h"
|
||||
#include "cpm.h"
|
||||
WORD write(fd,buff,pbytes) /****************************/
|
||||
/* */
|
||||
WORD fd; /* File descriptor */
|
||||
REG BYTE *buff; /* Buffer address */
|
||||
WORD pbytes; /* Number of bytes to xfer */
|
||||
/* */
|
||||
{ /****************************/
|
||||
REG FILE *fp; /* File (ccb) pointer */
|
||||
EXTERN LONG _chkc(); /* fd -> fp Convertor */
|
||||
LOCAL LONG ofs; /* Buffer offset */
|
||||
LOCAL LONG written; /* Number of bytes written */
|
||||
LOCAL LONG xsector; /* Sector number temporary */
|
||||
REG BYTE *p1; /* Move loop pointers */
|
||||
REG BYTE c; /* Character temp */
|
||||
REG LONG xbytes; /* Saved bytes */
|
||||
REG LONG bytes; /* Bytes for everyone else */
|
||||
/****************************/
|
||||
/* */
|
||||
bytes = (LONG)pbytes; /* Convert to long */
|
||||
/****************************/
|
||||
if((LONG)(fp=_chkc(fd)) == FAILURE) /* Get CCB address */
|
||||
return(FAILURE); /* Can't */
|
||||
/* */
|
||||
if(bytes <= 0) /* Trying to write 0 or less*/
|
||||
return(0); /* Yes, a wise guy! */
|
||||
/* */
|
||||
if((fp->flags & ISREAD) != 0) /* Check for readonly file */
|
||||
RETERR(FAILURE,EBADF); /* Barf if so */
|
||||
/* */
|
||||
if((fp->flags & ISTTY) != 0) /* TTY File? */
|
||||
return(_chrout(buff,bytes,CONOUT));/* Yes, out to TTY */
|
||||
/* */
|
||||
if((fp->flags & ISLPT) != 0) /* LIST file? */
|
||||
return(_chrout(buff,bytes,LSTOUT));/* Yes, out to LST: */
|
||||
/****************************/
|
||||
if((fp->flags & ISASCII) == 0) /* If binary file */
|
||||
return(_wrtbin(fp,buff,bytes)); /* do binary style */
|
||||
/****************************/
|
||||
written = bytes; /* Remember original request*/
|
||||
/****************************/
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
/* Here begins the actual write loop */
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
c = 0; /* Init to garbage value */
|
||||
/* */
|
||||
while(bytes >0) /* While more bytes to write*/
|
||||
{ /* */
|
||||
xsector = fp->offset >> 7; /* Compute beginning sector */
|
||||
ofs = 0; /* start on sector boundary */
|
||||
/* */
|
||||
if(xsector != fp -> sector) /* Have to read it first */
|
||||
{ /* */
|
||||
if((fp->flags & DIRTY) != 0) /* Buffer has data? */
|
||||
{ /* Yes */
|
||||
if(_blkio(fp,fp->sector, /* */
|
||||
fp->buffer,1L,B_WRITE) != 1) /* Try to write */
|
||||
RETERR(FAILURE,EIO); /* Couldn't */
|
||||
fp->flags &= ~DIRTY; /* Nice clean buffer now */
|
||||
} /****************************/
|
||||
} /* */
|
||||
/* */
|
||||
if((fp-> offset & (SECSIZ-1)) != 0 /* Beginning on crazy offset*/
|
||||
&& (fp -> offset < fp -> hiwater)) /* and below hiwater mark */
|
||||
{ /* */
|
||||
if(_blkio(fp,xsector,fp->buffer, /* */
|
||||
1L,B_READ) != 1) /* Now read the correct sec */
|
||||
RETERR(FAILURE,EIO); /* Couldn't */
|
||||
} /****************************/
|
||||
fp->sector = xsector; /* Mark buffer correctly */
|
||||
ofs = fp->offset & (SECSIZ-1); /* Compute 1st char offset */
|
||||
/* */
|
||||
p1 = &(fp->buffer[ofs]); /* first char to write */
|
||||
/* */
|
||||
xbytes = bytes; /* Save byte count remaining*/
|
||||
while (p1 < &(fp->buffer[SECSIZ]) /* Until buffer is full */
|
||||
&& (bytes > 0)) /* or until request done */
|
||||
{ /****************************/
|
||||
if(*buff == '\n' && c != '\r') /* need to insert C/R */
|
||||
c = '\r'; /* */
|
||||
else /* Don't need to */
|
||||
{ /* */
|
||||
c = *buff++; /* */
|
||||
bytes--; /* */
|
||||
} /****************************/
|
||||
*p1++ = c; /* Put char in buffer */
|
||||
fp->offset++; /* Increment file offset */
|
||||
} /****************************/
|
||||
if(p1 >= &(fp->buffer[SECSIZ])) /* Need to write buffer */
|
||||
{ /* */
|
||||
if(_blkio(fp,xsector,fp->buffer, /* */
|
||||
1L,B_WRITE) !=1) /* Try the write */
|
||||
return(written-xbytes); /* return # actually written*/
|
||||
} /****************************/
|
||||
else /* */
|
||||
fp -> flags |= DIRTY; /* Buffer dirty again */
|
||||
if(bytes == 0) /* If done, */
|
||||
{ /* Check offset here */
|
||||
if(fp->offset > fp->hiwater) /* */
|
||||
fp->hiwater = fp->offset; /* Fix hiwater if necessary */
|
||||
return(written); /* return */
|
||||
} /* */
|
||||
} /****************************/
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* W r t b i n F u n c t i o n */
|
||||
/* ------------------------------ */
|
||||
/* */
|
||||
/* Function "wrtbin" is called from "write" to take advantage of a */
|
||||
/* potential multi-sector transfer for binary files. */
|
||||
/* */
|
||||
/* Calling sequence: */
|
||||
/* */
|
||||
/* ret = _wrtbin(fp,buffer,bytes); */
|
||||
/* */
|
||||
/* Where: */
|
||||
/* */
|
||||
/* fp Points to the affected ccb. */
|
||||
/* buffer Is the buffer address */
|
||||
/* bytes Is the number of bytes to write */
|
||||
/* */
|
||||
/* ret Is the number of bytes actually written */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
LONG _wrtbin(fp,buff,bytes) /****************************/
|
||||
/* */
|
||||
REG FILE *fp; /* -> CCB */
|
||||
REG BYTE *buff; /* -> User's buffer */
|
||||
REG LONG bytes; /* # bytes to write */
|
||||
{ /****************************/
|
||||
LOCAL LONG xsector; /* Sector temp */
|
||||
LOCAL LONG nsector; /* Multi-sector count */
|
||||
LOCAL LONG written; /* # bytes to write */
|
||||
REG BYTE *p1; /* Temp buffer pointer */
|
||||
/****************************/
|
||||
written = bytes; /* Remember request length */
|
||||
xsector = fp->offset >> 7; /* Calculate present sector */
|
||||
/****************************/
|
||||
if((fp -> offset & (SECSIZ-1)) != 0) /* Are we at a boundary? */
|
||||
{ /* */
|
||||
if(xsector != fp->sector) /* No, do sectors match? */
|
||||
{ /* */
|
||||
if((fp->flags & DIRTY) != 0) /* No, is buffer dirty? */
|
||||
{ /* */
|
||||
if(_blkio(fp,fp->sector, /* */
|
||||
fp->buffer,1L,B_WRITE) != 1) /* Yes, write it */
|
||||
RETERR(FAILURE,EIO); /* Couldn't write buffer */
|
||||
fp->flags &= ~DIRTY; /* Clear dirty bit */
|
||||
} /****************************/
|
||||
/* */
|
||||
if(fp->offset < fp->hiwater) /* Within the hiwater area? */
|
||||
{ /* If yes, then read it */
|
||||
if(_blkio(fp,xsector,fp->buffer, /* */
|
||||
1L,B_READ) != 1) /* Try to read the correct */
|
||||
RETERR(FAILURE,EIO); /* Can't */
|
||||
} /****************************/
|
||||
else _clear(fp->buffer,SECSIZ); /* Zero out the buffer */
|
||||
/* */
|
||||
/* */
|
||||
fp->sector = xsector; /* Label buffer */
|
||||
/* */
|
||||
} /****************************/
|
||||
p1 = &fp->buffer[fp->offset&(SECSIZ-1)];/* p1->1st loc in buffer */
|
||||
/* */
|
||||
while (p1 < &(fp->buffer[SECSIZ]) && /* while still in buffer */
|
||||
bytes > 0) /* And still writing */
|
||||
{ /* */
|
||||
*p1++ = *buff++; /* Move a byte */
|
||||
bytes--; /* Decrement counter */
|
||||
} /****************************/
|
||||
if (bytes <= 0) /* Byte count exhausted?? */
|
||||
{ /* */
|
||||
fp->flags |= DIRTY; /* Yes, buffer is now dirty */
|
||||
fp->offset += written; /* fix offset */
|
||||
if(fp->offset > fp->hiwater) /* See if above hiwater mark*/
|
||||
fp->hiwater = fp->offset; /* Fix if necessary */
|
||||
return(written); /* Return original byte cnt */
|
||||
} /****************************/
|
||||
if(_blkio(fp,xsector,fp->buffer,1L, /* Write full buffer */
|
||||
B_WRITE) != 1) /* */
|
||||
RETERR(FAILURE,EIO); /* Couldn't */
|
||||
xsector++; /* Bump sector counter */
|
||||
} /* End boundary problem code*/
|
||||
/****************************/
|
||||
/* */
|
||||
/************************************************* */
|
||||
/* The observant reader will note that after the above malarkey, we are now */
|
||||
/* aligned on a sector boundary. The following code exploits the oppor- */
|
||||
/* tunity to do a multi-sector write. */
|
||||
/************************************************* */
|
||||
/* */
|
||||
nsector = bytes >> 7; /* divide by 128 for sectors*/
|
||||
if(nsector > 0) /* Check for no more left */
|
||||
if(_blkio(fp,xsector,buff, /* */
|
||||
nsector,B_WRITE) != nsector) /* Multi-sector xfer */
|
||||
RETERR(FAILURE,EIO); /* Just quit on error */
|
||||
/****************************/
|
||||
bytes -= (nsector << 7); /* Subtract multi-sector */
|
||||
/* Byte count */
|
||||
buff += (nsector << 7); /* Update address */
|
||||
fp->offset += written; /* Update offset now */
|
||||
/* (All I/O is complete) */
|
||||
if(fp->offset > fp->hiwater) /* Fix up hiwater mark */
|
||||
fp->hiwater = fp->offset; /* */
|
||||
if(bytes == 0) /* If done, */
|
||||
return(written); /* return success */
|
||||
/****************************/
|
||||
if((fp->flags & DIRTY) != 0) /* Is buffer dirty? */
|
||||
{ /* Test (again) here in case*/
|
||||
if(_blkio(fp,fp->sector, /* of boundary condition */
|
||||
fp->buffer,1L,B_WRITE) != 1) /* Yes, write it */
|
||||
RETERR(FAILURE,EIO); /* Couldn't write buffer */
|
||||
} /****************************/
|
||||
fp -> flags |= DIRTY; /* Let's dirty the buffer */
|
||||
fp -> sector = fp -> offset >> 7; /* Mark sector number */
|
||||
/****************************/
|
||||
if(fp->offset < fp->hiwater) /* Sector in high water area*/
|
||||
_blkio(fp,fp->sector,fp->buffer,1L, /* Read sector */
|
||||
B_READ); /* */
|
||||
else _clear(fp->buffer,SECSIZ); /* Or clear it */
|
||||
/****************************/
|
||||
p1 = &(fp->buffer[0]); /* p1 -> address */
|
||||
while(bytes > 0) /* Move the bytes */
|
||||
{ /* */
|
||||
*p1++ = *buff++; /* One at a time */
|
||||
bytes--; /* Decrement count */
|
||||
} /****************************/
|
||||
/* */
|
||||
return(written); /* Return requested # */
|
||||
} /****************************/
|
||||
|
||||
_clear(ptr,bytes) /****************************/
|
||||
/* Clear a memory area */
|
||||
REG BYTE *ptr; /* -> area to be cleared */
|
||||
REG WORD bytes; /* # of bytes to zero */
|
||||
{ /****************************/
|
||||
while (bytes-- > 0) /* Until all exhausted */
|
||||
*ptr++ = 0; /* Clear 1 byte */
|
||||
} /****************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* _ c h r o u t F u n c t i o n */
|
||||
/* ------------------------------- */
|
||||
/* */
|
||||
/* Function "_chrout" is called to perform "write" operations to the */
|
||||
/* console or list device. */
|
||||
/* */
|
||||
/* Calling Sequence: */
|
||||
/* */
|
||||
/* ret = _chrout(buffer,count,func); */
|
||||
/* */
|
||||
/* Where: */
|
||||
/* */
|
||||
/* buffer -> the output buffer */
|
||||
/* count = the number of bytes to output */
|
||||
/* func = BDOS function to use */
|
||||
/* */
|
||||
/* ret = count on return */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
_chrout(buffer,count,func) /***************************/
|
||||
/* */
|
||||
REG BYTE *buffer; /* -> 1st char output */
|
||||
REG LONG count; /* = # bytes to xfer */
|
||||
REG WORD func; /* BDOS Function */
|
||||
/* */
|
||||
{ /***************************/
|
||||
LONG xcount; /* save area for count */
|
||||
/* */
|
||||
xcount = count; /* Copy for later */
|
||||
/* */
|
||||
while(count > 0) /* Until all written */
|
||||
{ /* */
|
||||
if(*buffer == '\n') /* New line char?? */
|
||||
{ /* */
|
||||
__BDOS(func,(LONG)'\r'); /* Output carriage return */
|
||||
} /* */
|
||||
__BDOS(func,(LONG)*buffer++); /* Output next character */
|
||||
count--; /* Decrement count */
|
||||
} /* */
|
||||
return(xcount); /* return original count */
|
||||
} /***************************/
|
73
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/xopen.c
Normal file
73
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/klib/xopen.c
Normal file
@@ -0,0 +1,73 @@
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* _ o p e n F u n c t i o n */
|
||||
/* --------------------------- */
|
||||
/* */
|
||||
/* Function "_open" is used to parse the CP/M fcb and open or create */
|
||||
/* the requested file. Created files are deleted first, to avoid */
|
||||
/* directory problems. */
|
||||
/* */
|
||||
/* Calling Sequence: */
|
||||
/* */
|
||||
/* ret = _open(ch,filnam,bdosfunc); */
|
||||
/* */
|
||||
/* Where: */
|
||||
/* ch Is a vacant channel number */
|
||||
/* filnam Is a null-terminated CP/M filename */
|
||||
/* bdosfunc Is the desired BDOS function to perform */
|
||||
/* */
|
||||
/* This routine may also be used to delete files as well. */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
#include "stdio.h"
|
||||
#include "cpm.h"
|
||||
WORD _open(ch,filnam,bdosfunc) /****************************/
|
||||
/* */
|
||||
WORD ch; /* Channel number */
|
||||
REG BYTE *filnam; /* -> filename */
|
||||
WORD bdosfunc; /* BDOS Function */
|
||||
{ /****************************/
|
||||
EXTERN FILE *_getc(); /* fd -> fp xlate routine */
|
||||
REG FILE *fp; /* -> ccb area */
|
||||
REG struct xfcb *fcbp; /* -> FCB area in ccb */
|
||||
REG BYTE *p; /* Temp character pointer */
|
||||
REG WORD i; /* Character index */
|
||||
/****************************/
|
||||
fp = _getc(ch); /* Fetch ccb pointer */
|
||||
fcbp = &(fp ->fcb); /* Fetch fcb pointer */
|
||||
/****************************/
|
||||
if(*(filnam+1) == ':') /* Drive ID present? */
|
||||
{ /* If here, yes */
|
||||
fcbp->drive = toupper(*filnam) /* Load drive ID */
|
||||
- 'A' + 1; /* 1 for a:, 2 for b:, ... */
|
||||
filnam += 2; /* Bump past ':' */
|
||||
} /****************************/
|
||||
/* */
|
||||
i = 0; /* index */
|
||||
/****************************/
|
||||
while (*filnam > ' ' && i < 8 && /* */
|
||||
*filnam != '.') /* Terminate on ext. */
|
||||
{ /* */
|
||||
fcbp -> fname[i++] = /* Load next character */
|
||||
toupper(*filnam); /* */
|
||||
filnam++; /* Increment */
|
||||
} /* */
|
||||
/****************************/
|
||||
if (*filnam == '.') /* Extension specified? */
|
||||
{ /* Yes */
|
||||
filnam++; /* Bump past '.' */
|
||||
i = 0; /* set index to 0 */
|
||||
while(*filnam > ' ' && i < 3) /* copy */
|
||||
{ /* */
|
||||
fcbp -> ftype[i++] = /* */
|
||||
toupper(*filnam); /* file type */
|
||||
filnam++; /* */
|
||||
} /* */
|
||||
} /****************************/
|
||||
/* */
|
||||
if(bdosfunc == CREATE) /* Creating file? */
|
||||
__BDOS(DELETE,fcbp); /* Yes, delete it first */
|
||||
/****************************/
|
||||
i = __BDOS(bdosfunc,fcbp); /* Do requested operation */
|
||||
return((i<=3) ? SUCCESS : FAILURE); /* Binary return code */
|
||||
} /****************************/
|
@@ -0,0 +1,37 @@
|
||||
/*********************************************************************
|
||||
* STRCMP - compares strings
|
||||
*
|
||||
* Special version which is case - insensitive.
|
||||
*
|
||||
* 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 = _toupper(*s1++);
|
||||
b = _toupper(*s2++);
|
||||
if (a > b) return (1);
|
||||
if (a < b) return (-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
MLOCAL BYTE _toupper(c)
|
||||
REG BYTE c;
|
||||
{
|
||||
if(c >= 'a' && c <= 'z')
|
||||
c -= 'a' - 'A';
|
||||
return(c);
|
||||
}
|
@@ -0,0 +1,89 @@
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* _ t t y i n F u n c t i o n */
|
||||
/* ----------------------------- */
|
||||
/* Copyright 1982 by Digital Research Inc. All rights reserved. */
|
||||
/* */
|
||||
/* Function "_ttyin" is used to read a line from the terminal. */
|
||||
/* It looks for the ISSPTTY flag set in the ccb: if set, it assumes */
|
||||
/* the fcb really contains sgttyb information (see <sgtty.h>), and */
|
||||
/* behaves accordingly. */
|
||||
/* Otherwise, it grabs a line at a time from the BDOS. */
|
||||
/* */
|
||||
/* Calling Sequence: */
|
||||
/* ret = _ttyin(fp,buffer,bytes); */
|
||||
/* Where: */
|
||||
/* fp -> ccb pointer & channel info */
|
||||
/* buffer -> the user's input buffer */
|
||||
/* bytes = the (maximum) number of bytes to read */
|
||||
/* ret = the number of bytes actually read */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
#include <portab.h>
|
||||
#include <cpm.h>
|
||||
#include <sgtty.h>
|
||||
#define Conin 0xFFL
|
||||
#define Constat 0xFEL
|
||||
|
||||
WORD _ttyin(fp,buff,bytes) /****************************/
|
||||
REG FD *fp; /* -> filedes */
|
||||
REG BYTE *buff; /* -> user's buffer */
|
||||
REG LONG bytes; /* = requested byte count */
|
||||
{ /****************************/
|
||||
LOCAL BYTE ttybuf[257]; /* Biggest line from tty */
|
||||
REG LONG xbytes, /* Returned byte count */
|
||||
nbs; /* Number to read */
|
||||
REG BYTE *p; /* Temp pointer */
|
||||
LOCAL struct sgttyb *tyb; /* TTY info ptr (at fp->fcb)*/
|
||||
/* */
|
||||
if(fp->flags & ISSPTTY) /* is this a special tty? */
|
||||
{ /****************************/
|
||||
tyb = &(fp->fcb); /* assume info stored here */
|
||||
if(tyb->sg_flags & RAW) /* are we in raw mode? */
|
||||
{ /* */
|
||||
*buff = __BDOS(CONIO,Conin);/* grab a char */
|
||||
return(1); /* return number bytes read */
|
||||
} /* ************************/
|
||||
if(tyb->sg_flags & CBREAK) /* are we half baked? */
|
||||
{ /* */
|
||||
p = buff; /* use ptr */
|
||||
*p = __BDOS(CONIO,Conin); /* get char */
|
||||
if( *p == tyb->sg_kill ) /* kill char typed? */
|
||||
exit(1); /* yes: DIE, PROGRAM! */
|
||||
if(tyb->sg_flags & LCASE) /* they want lower case? */
|
||||
*p = (*p>='A'&& *p<='Z' /* */
|
||||
? *p-'A'+'a' : *p); /* give them lower case */
|
||||
if((tyb->sg_flags & CRMOD) /* xlate returns? */
|
||||
&& *p == '\r' ) /* */
|
||||
{ /* */
|
||||
if(tyb->sg_flags & ECHO) /* */
|
||||
__BDOS(CONIO,(LONG)*p); /* out before xlate */
|
||||
*p = '\n'; /* yes, do xlation */
|
||||
} /* */
|
||||
if(tyb->sg_flags & ECHO) /* echo chars? */
|
||||
__BDOS(CONIO,(LONG)*p); /* */
|
||||
return(1); /* return number read */
|
||||
} /* ************************/
|
||||
/* nothing really special...*/
|
||||
} /****************************/
|
||||
nbs = bytes < 255 ? bytes : 255; /* don't read more than they*/
|
||||
ttybuf[0] = nbs; /* asked for/we have room fr*/
|
||||
__BDOS(CONBUF,&ttybuf[0]); /* Read line from BDOS */
|
||||
/****************************/
|
||||
xbytes = ttybuf[1] & 0xffL; /* # characters read */
|
||||
if( xbytes<nbs ) /* # read < #asked for,assum*/
|
||||
__BDOS(CONOUT,(LONG)'\n'); /* CR/LF line terminated */
|
||||
p = &ttybuf[2]; /* p -> First character */
|
||||
while( bytes > 0 && xbytes > 0) /* */
|
||||
{ /* Copy 1 byte / time */
|
||||
*buff++ = *p++; /* */
|
||||
bytes--; /* Decrement request */
|
||||
xbytes--; /* Decrement bytes in buff */
|
||||
} /****************************/
|
||||
if(bytes > 0) /* Terminate on count? */
|
||||
{ /* */
|
||||
*buff++ = '\n'; /* No, plug in newline */
|
||||
p++; /* Bump pointer */
|
||||
} /****************************/
|
||||
return((WORD)(p-&ttybuf[2])); /* Return # bytes moved */
|
||||
} /****************************/
|
Reference in New Issue
Block a user