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

View File

@@ -0,0 +1,675 @@
/*----------------------------------------------------------------------*\
| |
| DISK COPY PROGRAM |
| ================= |
| |
| Created: November 4,1982 |
| ------- |
| |
| Last Modified: January 15,1982 |
| ------------- |
| |
| Description: |
| ----------- This program will copy all or portions of |
| one disk to another compatible disk. |
| |
| Needed Files: |
| ------------ <STDIO.H>,<PORTAB.H> |
| |
| Must be linked to the 'C' runtime library. |
| ------------------------------------------ |
| |
| (c) COPYRIGHT DIGITAL RESEARCH 1983 |
| ALL RIGHTS RESERVED |
| |
\*----------------------------------------------------------------------*/
char *copyrt="CP/M-68K(tm), Version 1.1, Copyright 1983, Digital Research";
char *serial="XXXX-0000-654321";
/************************************************************************\
* Here are the Include Files *
\************************************************************************/
/********************************/
#include <stdio.h> /* Standard I/O library */
/********************************/
/************************************************************************\
* DEFINES for Copy.c *
\************************************************************************/
/********************************/
#define ON 1 /* Option is valid for this copy*/
#define OFF 0 /* Option is not valid */
#define BAD 0 /* Illegal mode flag */
#define MATCH 0 /* used by strcmp */
#define SDRIVE 1 /* source drive */
#define DDRIVE 2 /* destination drive */
#define _ALL 0 /* copy whole disk */
#define _BOOT 1 /* copy boot tracks */
#define _FILES 2 /* copy non-boot tracks */
#define _END 3 /* end this program */
#define RDERR 0 /* read error flag */
#define WRERR 1 /* write error flag */
#define NULLB '\0' /* NULL byte */
#define isupper(c) ('A' <= (c) && (c) <= 'Z')/*upper case */
#define islower(c) ('a' <= (c) && (c) <= 'z')/*lower case */
#define tolower(c) (isupper(c) ? ((c)+040):(c))/* */
#define toupper(c) (islower(c) ? ((c)-040):(c))/* */
/********************************/
/************************************************************************\
* GLOBAL definitions *
\************************************************************************/
/********************************/
GLOBAL BYTE *choice[] = /* Copy Modes available */
{"all","boot","files","end"}; /* ---------------------- */
/********************************/
GLOBAL BYTE mode; /* Hold the current copy mode */
/********************************/
/* ------- OPTIONS ------- */
GLOBAL BYTE verbose = ON; /* Prompt the user if ON */
GLOBAL BYTE verify = OFF; /* Check newly written track */
/* againist source track. */
/********************************/
/* Prompts........... */
GLOBAL BYTE *msg1 = "Enter SOURCE drive: "; /* SDRIVE */
GLOBAL BYTE *msg2 = "Enter DESTINATION drive: "; /* DDRIVE */
GLOBAL BYTE *msg3 = "READ error ----> "; /* Read error */
GLOBAL BYTE *msg4 = "WRITE error ----> "; /* Write error */
/********************************/
/********************************/
GLOBAL BYTE *bracket = "["; /* Marks beginning of option */
/* indicators on the cmd line */
/********************************/
GLOBAL struct _dpb /* Define disk parm block */
{ /*------------------------------*/
WORD spt; /* Logical sectors per track */
BYTE bsh; /* Allocation block shift factor*/
BYTE blm; /* Block mask */
BYTE exm; /* Extent mask */
BYTE dpbjunk; /* Alignment byte */
WORD dsm; /* Total storage of the disk */
WORD drm; /* Total directory entries */
BYTE al0; /* Flag reserved for dir blocks */
BYTE al1; /* Flag reserved for dir blocks */
WORD cks; /* Directory check vector size */
WORD off; /* The number of reserved tracks*/
}; /* */
/********************************/
GLOBAL struct _dph /* Define disk parm header */
{ /*------------------------------*/
BYTE *xltp; /* Pointer to sector trans table*/
WORD dphscr[3]; /* Scratchpad values for BDOS */
BYTE *dirbufp; /* Pointer to dir scratchpad */
struct _dpb *dpbp; /* Pointer to disk parm block */
BYTE *csvp; /* Pointer to scratchpad area */
BYTE *alvp; /* Pointer to scratchpad area */
}; /********************************/
EXTERN LONG __BDOS(); /* BDOS Caller in CLIB */
#define bdos(a,b) (struct _dph*)__BDOS(a,b) /* Declare a bogus function */
/********************************/
GLOBAL struct _biospb /* Bios Pararmeter Block */
{ /*------------------------------*/
UWORD funcnum; /* Bios function number */
LONG parm1; /* Bios parameter 1 */
LONG parm2; /* Bios parameter 2 */
}; /* */
GLOBAL struct _biospb biospb; /* Define it */
/********************************/
GLOBAL BYTE trkbuf[128*26*6]; /* buffer big enough to hold 6 */
/* tracks of bytes */
GLOBAL BYTE verbuf[128*26*6]; /* buffer for verification opt */
/********************************/
/************************************************************************\
* FUNCTION definitions *
\************************************************************************/
/********************************/
UWORD illegal(); /* Decides if the mode is a */
/* legal one. */
/*------------------------------*/
VOID get_mode(); /* If the mode was not there */
/* or an illegal one,get_mode */
/* will print a menu and keep */
/* prompting the user for a */
/* legal mode. */
/*------------------------------*/
BYTE get_drive(); /* Reads in a drive character */
/* from the console. If the */
/* drive is in the range(A-P), */
/* the drive is returned. If */
/* not,the value BAD is returned*/
/*------------------------------*/
VOID wait_for(); /* Holds the copy program in a */
/* wait state so the user can */
/* make sure his or her disk is */
/* in the proper drive. */
/*------------------------------*/
BYTE scan(); /* Picks off the source and */
/* destination drives from the */
/* command line. If they do */
/* not exist,or the specified */
/* drives are illegal,scan */
/* prompts the user. */
/*------------------------------*/
VOID get_options(); /* Scans the command line until */
/* a '[' is found. A list of */
/* of options is checked. Flags */
/* are turned on by the option */
/* indicators found after the */
/* square bracket. */
/*------------------------------*/
VOID copy(); /* If the two disk parameter */
/* blocks are identical,a track */
/* for track copy is made. */
/* If an serious error occurs, */
/* the copy is aborted and the */
/* program ends. */
/********************************/
VOID read_wr(); /* This routine does the actual */
/* reading and writing of the */
/* compatible disks. */
/********************************/
/************************************************************************/
/************************************************************************\
* *
* BEGIN MAIN PROGRAM *
* *
\************************************************************************/
main(argc,argv)
WORD argc;
BYTE *argv[];
{
BYTE answer,source,dest,optfound;
optfound = FALSE;
printf("Copy Ver 1.1\n"); /* Copy version message */
/*------------------------------*\
| If there is an mode on |
| on the command line or the |
| command line mode is not |
| recognized,print a menu |
| and have the user input a |
| a legal copy mode. |
\*------------------------------*/
argc--; argv++; /* point to first arg after cmd */
if(illegal(*argv))
get_mode();
else /* point to 2nd arg past cmd */
{
argv++;
argc--;
}
if(mode == _END)
cpyexit();
/*------------------------------*\
| Look for the '[' as the |
| start of the options. |
| This allows the following |
| |
| copy <mode> [options |
| ==================== |
| or |
| copy [options |
| ============= |
| |
| I will not allow the drives|
| to be specified after the |
| options though!!!!! |
\*------------------------------*/
if(strncmp(bracket,*argv,1) == MATCH)
{
argc = 0;
get_options(*argv++);
source = scan(argc,*argv++,SDRIVE);
dest = scan(argc,*argv,DDRIVE);
}
else
/*------------------------------*\
| Otherwise I assume that the |
| command line looks like |
| this: |
| |
| copy <mode> <sd> <dd> [opt |
| ========================== |
\*------------------------------*/
{
source = scan(argc--,*argv++,SDRIVE);
dest = scan(argc--,*argv,DDRIVE);
if(strncmp(bracket,*argv,1) == MATCH)
{
optfound = TRUE;
get_options(*argv);
}
while(argc-- > 0)
/* scan cmd line to find a '[' */
if(strncmp(bracket,*++argv,1) == MATCH &&
(!optfound))
{
get_options(*argv);
break;
}
else
printf("\nExtraneous argument ignored: %s",*argv);
}
if(source == dest)
{
printf("\nSource and Destination must be different");
cpyexit();
}
/*------------------------------*\
| REPEAT the copy as many |
| times as the user wishes |
\*------------------------------*/
while(TRUE)
{
if(verbose)
wait_for(source,dest);
copy((toupper(source) - 'A'),(toupper(dest) - 'A'));
printf("\nCopy complete");
if(verbose)
printf("\nDo you wish to repeat the copy? ");
else
break;
answer = __BDOS(1,(long)0);
if(toupper(answer) != 'Y')
break;
}
}
/************************/
UWORD illegal(_mode) /* Check command line */
/* aganist mode table */
/* Return mode code if */
/* found,return false */
/* if the mode is not */
/* found in the table */
/************************/
BYTE *_mode;
{
REG UWORD i;
for(i = 0;i <= 3;i++)
if(strcmp(_mode,choice[i]) == MATCH)
{
mode = i;
return(FALSE);
}
mode = -1;
return(TRUE);
}
/************************/
VOID get_mode() /* Prompt the user for */
/* a legal mode. Keep */
/* prompting until you */
/* get one. */
/************************/
{
REG UWORD i;
BYTE buf[256];
printf("\nMODE\tFUNCTION\n");
printf("\nALL\tCopy the whole disk");
printf("\nBOOT\tCopy the boot tracks");
printf("\nFILES\tCopy the non-boot tracks");
printf("\nEND\tEnd this program\n");
do
{
printf("\nEnter your copy mode: ");
gets(buf);
for(i = 0;buf[i] != NULLB;i++)
buf[i] = tolower(buf[i]);
}
while(illegal(buf));
}
/************************/
BYTE get_drive() /* Read in a drive. */
/************************/
{
BYTE drive[10];
gets(drive);
if(strlen(drive) > 1)
return(BAD);
drive[0] = toupper(drive[0]);
if(drive[0] < 'A' || drive[0] > 'P')
return(BAD);
else
return(drive[0]);
}
/************************/
VOID wait_for(source,dest) /* Wait for the user */
/* to put the disks */
/* in the proper drives*/
/************************/
BYTE source;
BYTE dest;
{
BYTE wait_buf[5];
BYTE *upchoice[3];
upchoice[0] = "ALL";
upchoice[1] = "BOOT";
upchoice[2] = "FILES";
wait_buf[0] = 3;
do
{
printf("\n(^C to ABORT)");
printf("\nRETURN to copy %s",upchoice[mode]);
printf(" from %c to %c",source,dest);
__BDOS(10,&wait_buf[0]);
}
while(wait_buf[1] != 0);
}
/************************/
BYTE scan(argc,argv,which_drive) /* Scan the command */
/* for the drives. */
/* If I can't find them*/
/* or they are illegal */
/* keep prompting the */
/* user for them. */
/************************/
WORD argc;
BYTE *argv;
UWORD which_drive;
{
BYTE *prompt,drive;
if(argc > 0 && strlen(argv) == 1)
{
sscanf(argv,"%c",&drive);
drive = toupper(drive);
if(drive >= 'A' && drive <= 'P')
return(drive);
}
switch(which_drive)
{
case SDRIVE : prompt = &msg1[0];
break;
case DDRIVE : prompt = &msg2[0];
}
printf("\n");
do
{
printf("%s",prompt);
}
while((drive = get_drive()) == BAD);
return(drive);
}
/************************/
VOID get_options(argv) /* Scan cmd line for */
/* supported options */
/************************/
BYTE *argv;
{
argv++; /* skip the square bracket */
while(*argv != NULLB)
{
switch(*argv)
{
case 'A' :
case 'a' :
verbose = OFF;
break;
case 'v' :
case 'V' : verify = ON;
break;
case ']' : return(0);
default : printf("\nUndefined option: %c",*argv);
}
argv++;
}
}
/************************/
VOID copy(source,dest) /* Select the disks. */
/* If I can't select or*/
/* the disk have diff- */
/* erent parameter blks*/
/* then print error msg*/
/************************/
BYTE source;
BYTE dest;
{
REG struct _dpb *dskpblk;
REG struct _dph *h1,*h2;
REG LONG *ptr1,*ptr2;
REG LONG endtrk,begtrk;
LONG numtrks,temp;
BYTE *sectran;
REG UWORD i;
biospb.funcnum = 9; /* Select the disks */
biospb.parm1 = (long)source; /* first the source disk */
biospb.parm2 = (long)0; /* set least sig bit to 0 */
if((h1 = bdos(50,&biospb))!= NULL)
{
biospb.parm1 = (long)dest;
if((h2 = bdos(50,&biospb))!= NULL)
{ /*----------------------------------------------*/
/* check the parameter blocks(must be identical)*/
/*----------------------------------------------*/
dskpblk = (*h1).dpbp; /* pointer to dpb */
sectran = (*h1).xltp; /* pointer to sect tran tb*/
h1 = (*h1).dpbp; /* h1 points to dpb */
ptr1 = (long)h1; /* compare long words */
h2 = (*h2).dpbp; /* h2 points to dpb */
ptr2 = (long)h2; /* compare long words */
for(i = 0;i <= 3;i++)
{
if(*ptr1 != *ptr2)
{
printf("\nIncompatible disks");
cpyexit();
}
ptr1++;
ptr2++;
}
}
else
{
printf("\nDisk select error on Destination");
cpyexit();
}
}
else
{
printf("\nDisk select error on Source");
cpyexit();
}
/*------------------------------------------------------*\
| |
| Compute beginning and ending track |
| |
\*------------------------------------------------------*/
temp = (((*dskpblk).dsm + 1)*((*dskpblk).blm + 1));
numtrks = temp/(*dskpblk).spt;
if((numtrks*(*dskpblk).spt) < temp)
numtrks++;
numtrks += (*dskpblk).off;
switch(mode)
{
case _ALL : begtrk = 0;
endtrk = numtrks - 1;
break;
case _BOOT: begtrk = 0;
endtrk = (*dskpblk).off - 1;
break;
case _FILES: begtrk = (*dskpblk).off;
endtrk = numtrks - 1;
}
read_wr(source,dest,begtrk,endtrk,sectran,dskpblk);
}
/************************************************************************/
/* */
/* Do the actual read write operations */
/* =================================== */
/* */
/************************************************************************/
VOID read_wr(source,dest,begtrk,endtrk,sectran,dskpblk)
/********************************/
BYTE source; /* source disk */
BYTE dest; /* destination disk */
REG LONG begtrk; /* beginning track to copy */
REG LONG endtrk; /* ending track to copy */
REG BYTE *sectran; /* sector translate table */
struct _dpb *dskpblk; /* ptr to disk parameter block */
/********************************/
{
REG BYTE *dma;
REG UWORD i,k;
printf("\n***Copying Tracks***\n");
for(i = begtrk;i <= endtrk;i++)
{
dma = &trkbuf;
biospb.funcnum = 12; /* set the dma address */
biospb.parm1 = dma; /* set it to beginning of trkbuf*/
biospb.parm2 = 0;
__BDOS(50,&biospb); /* call the bios via the bdos */
biospb.funcnum = 9; /* select the source diskette */
biospb.parm1 = (long)source;
biospb.parm2 = (long)0xFFFFFFFF;
__BDOS(50,&biospb); /* call the bios via the bdos */
biospb.funcnum = 10; /* set the track */
biospb.parm1 = (long)(i);
biospb.parm2 = 0;
__BDOS(50,&biospb); /* call bios via bdos */
/*----------------------------------------------*\
| Read a track's worth of sectors |
\*----------------------------------------------*/
for(k = 0;k < (*dskpblk).spt;k++)
{
biospb.funcnum = 16; /* translate sector*/
biospb.parm1 = (long)k; /* logical sect */
biospb.parm2 = sectran;
biospb.parm1 = __BDOS(50,&biospb);
biospb.funcnum = 11; /* set physical sec*/
biospb.parm2 = 0;
__BDOS(50,&biospb); /* call the bios */
/*--------------------------------------*\
| READ a sector |
\*--------------------------------------*/
biospb.funcnum = 13;
if(__BDOS(50,&biospb) != 0)
error(i,k,RDERR);
dma += 128;
biospb.funcnum = 12;
biospb.parm1 = dma;
__BDOS(50,&biospb);
}
dma = &trkbuf;
biospb.funcnum = 12; /* reset the dma addr to trkbuf */
biospb.parm1 = dma;
biospb.parm2 = 0;
__BDOS(50,&biospb); /* call the bios */
biospb.funcnum = 9; /* select the destination disk */
biospb.parm1 = (long)dest;
biospb.parm2 = (long)0xFFFFFFFF;
__BDOS(50,&biospb); /* call the bios */
/*----------------------------------------------*\
| Write out a Track's worth of Sectors |
\*----------------------------------------------*/
for(k = 0;k < (*dskpblk).spt;k++)
{
biospb.funcnum = 16;
biospb.parm1 = (long)k;
biospb.parm2 = sectran;
biospb.parm1 = __BDOS(50,&biospb);
biospb.funcnum = 11;
biospb.parm2 = 0;
__BDOS(50,&biospb);
/*--------------------------------------*\
| Write a Sector |
\*--------------------------------------*/
biospb.funcnum = 14;
biospb.parm1 = (long)2;
if(__BDOS(50,&biospb) != 0)
error(i,k,WRERR);
dma += 128;
biospb.funcnum = 12;
biospb.parm1 = dma;
__BDOS(50,&biospb);
}
if(verify)
{
dma = &verbuf;
biospb.funcnum = 12;
biospb.parm1 = dma;
__BDOS(50,&biospb); /* reset dma addr */
for(k = 0;k < (*dskpblk).spt;k++)
{
biospb.funcnum = 16;
biospb.parm1 = (long)k;
biospb.parm2 = sectran;
biospb.parm1 = __BDOS(50,&biospb);
biospb.funcnum = 11;
biospb.parm2 = 0;
__BDOS(50,&biospb);
/*------------------------------*\
| Read a sector |
\*------------------------------*/
biospb.funcnum = 13;
if(__BDOS(50,&biospb) != 0)
error(i,k,RDERR);
dma += 128;
biospb.funcnum = 12;
biospb.parm1 = dma;
__BDOS(50,&biospb);
}
/*--------------------------------------*\
| Verify the TRACK write |
\*--------------------------------------*/
for(k = 0;k < (((*dskpblk).spt)*128);k++)
if(trkbuf[k] != verbuf[k])
error(i,(k/128),WRERR);
}
printf("\r %d",i);
}
}
/************************/
error(track,sector,phase) /* Read/Write Error */
/* handler */
/************************/
UWORD track;
UWORD sector;
BYTE phase;
{
REG BYTE *addr;
if(phase == RDERR)
addr = &msg3[0];
else
addr = &msg4[0];
printf("\n\n\n%s",addr);
printf("Track: %d Sector: %d",track,sector);
cpyexit();
}
cpyexit() /* bios select what the bdos thinks is the default disk */
{
biospb.funcnum = 9;
biospb.parm1 = __BDOS(25,(long)0);
biospb.parm2 = 0;
bdos(50,&biospb);
exit(0);
}

View File

@@ -0,0 +1,4 @@
vax b:readme.doc $$frants
vax b:serial.c $$frants
vax b:serial.dat $$frants
vax b:sernotes.doc $$frants

View File

@@ -0,0 +1,24 @@
Commands to build the ED utility on the EXORmacs
================================================
================================================
1. Boot up Versados.
2. Use the vax utility to log on to the VAX.
3. Choose a suitable directory on the VAX for ED68K.OC
4. =CHAIN ED
The submit file ED.CF will compile ed and put the
resulting file (ED68K.OC) on the VAX.
5. Download ED68K.OC from the VAX to an ALTOS.
6. Use the RECONV.COM program to reconvert ED68K.OC to ED.68K
7. Port to the EXORmacs by floppy and test under CP/M-68K.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,410 @@
/*SPLH*/ /*$TITLE='CP/M-86 2.0 --- ED' */
ED:
DO;
/* MODIFIED FOR .PRL OPERATION MAY, 1979 */
/* MODIFIED FOR OPERATION WITH CP/M 2.0 AUGUST 1979 */
/* MODIFIED FOR MP/M 2.0 JUNE 1981 */
/* MODIFIED FOR CP/M 1.1 OCT 1981 */
/* MODIFIED FOR CP/M-68K JULY 1982 BY H.CHAKI */
DECLARE
MPMPRODUCT LITERALLY '01H', /* REQUIRES MP/M */
CPM3 LITERALLY '30H'; /* REQUIRES 3.0 CP/M */
/* DECLARE 8080 INTERFACE
JMP EDCOMMAND - 3 (TO ADDRESS LXI SP)
EDJMP BYTE DATA(0C3H),
EDADR ADDRESS DATA(.EDCOMMAND-3); */
/**************************************
* *
* B D O S INTERFACE *
* *
**************************************/
MON1:
PROCEDURE (FUNC,INFO) EXTERNAL;
DECLARE FUNC BYTE;
DECLARE INFO ADDRESS;
END MON1;
MON2:
PROCEDURE (FUNC,INFO) BYTE EXTERNAL;
DECLARE FUNC BYTE;
DECLARE INFO ADDRESS;
END MON2;
MON3:
PROCEDURE (FUNC,INFO) ADDRESS EXTERNAL;
DECLARE FUNC BYTE;
DECLARE INFO ADDRESS;
END MON3;
MON5 : PROC(FN,IN) EXT ;
DCL FN BYTE;
DCL IN POINTER ;
END;
MON6 : PROC(FN,IN) BYTE EXT ;
DCL FN BYTE;
DCL IN POINTER ;
END ;
MON7 : PROC(FN,IN) ADDR EXT;
DCL FN BYTE ;
DCL IN POINTER;
END ;
/* DECLARE CMDRV BYTE EXTERNAL; /* COMMAND DRIVE */
DECLARE FCB (128) BYTE EXTERNAL; /* 1ST DEFAULT FCB */
DECLARE FCB16 (128) BYTE EXTERNAL; /* 2ND DEFAULT FCB */
/* DECLARE PASS0 ADDRESS EXTERNAL; /* 1ST PASSWORD PTR */
/* DECLARE LEN0 BYTE EXTERNAL; /* 1ST PASSWD LENGTH */
/* DECLARE PASS1 ADDRESS EXTERNAL; /* 2ND PASSWORD PTR */
/* DECLARE LEN1 BYTE EXTERNAL; /* 2ND PASSWD LENGTH */
DECLARE TBUFF (128) BYTE EXTERNAL; /* DEFAULT DMA BUFFER */
DECLARE
/* BDISK BYTE EXTERNAL, /* BOOT DISK 0004H */
MAXB ADDRESS EXTERNAL, /* MAX BASE 0006H */
BUFF (128)BYTE EXTERNAL, /* BUFFER 0080H */
SECTSHF LITERALLY '7', /* SHL(1,SECTSHF) = SECTSIZE */
SECTSIZE LITERALLY '80H'; /* SECTOR SIZE */
/* 68K */ DCL DUM1P POINTER,DUM1L LONG AT(@DUM1P);
/* 68K */ DCL DUM2P POINTER,DUM2L LONG AT(@DUM2P);
BOOT: PROCEDURE PUBLIC;
CALL MON1(0,0); /* CHANGED FOR MP/M-86 VERSION */
/* SYSTEM REBOOT */
END BOOT;
/*SPLH*/ /*$EJECT */
/* E D : T H E C P / M C O N T E X T E D I T O R */
/* COPYRIGHT (C) 1976, 1977, 1978, 1979, 1980, 1981
DIGITAL RESEARCH
BOX 579 PACIFIC GROVE
CALIFORNIA 93950
REVISED:
07 APRIL 81 BY THOMAS ROLANDER
21 JULY 81 BY DOUG HUSKEY
29 OCT 81 BY DOUG HUSKEY
10 NOV 81 BY DOUG HUSKEY
31 JULY 81 BY H.CHAKI
*/
/*SPLH*/ /*$EJECT */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * GLOBAL VARIABLES * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
DECLARE /* LIT LITERALLY 'LITERALLY',
DCL LIT 'DECLARE',
PROC LIT 'PROCEDURE',
ADDR LIT 'ADDRESS', */
CTLL LIT '0CH',
CTLR LIT '12H', /* REPEAT LINE IN INSERT MODE */
CTLU LIT '15H', /* LINE DELETE IN INSERT MODE */
CTLX LIT '18H', /* EQUIVALENT TO CTLU */
CTLH LIT '08H', /* BACKSPACE */
TAB LIT '09H', /* TAB CHARACTER */
LCA LIT '110$0001B', /* LOWER CASE A */
LCZ LIT '111$1010B', /* LOWER CASE Z */
ESC LIT '1BH', /* ESCAPE CHARACTER */
ENDFILE LIT '1AH'; /* CP/M END OF FILE */
DECLARE
TRUE LITERALLY '1',
FALSE LITERALLY '0',
FOREVER LITERALLY 'WHILE TRUE',
CTRL$C LITERALLY '3',
CR LITERALLY '13',
LF LITERALLY '10',
WHAT LITERALLY '63';
DECLARE
US LITERALLY '8', /* FILE FROM USER 0 */
RO LITERALLY '9', /* R/O FILE INDICATOR */
SY LITERALLY '10', /* SYSTEM FILE ATTRIBUTE */
EX LITERALLY '12', /* EXTENT NUMBER POSITION */
UB LITERALLY '13', /* UNFILLED BYTES */
CK LITERALLY '13', /* CHECKSUM */
MD LITERALLY '14', /* MODULE NUMBER POSITION */
NR LITERALLY '32', /* NEXT RECORD FIELD */
FS LITERALLY '33', /* FCB SIZE */
XFERON BYTE EXT INIT, /* TRUE IF XFER ACTIVE */
PASSWORD (16) BYTE EXT INIT; /* SOURCE PASSWORD */
DECLARE
LIBFCB (12) BYTE EXT DATA ;/* DEFAULT LIB NAME */
DECLARE
PRINTSUPPR BYTE EXT INIT; /* TRUE IF PRINT SUPPRESSED */
DECLARE
COLUMN BYTE EXT; /* CONSOLE COLUMN POSITION */
/* COMMAND BUFFER */
DCL DCNT BYTE EXT ;
DECLARE (MAXLEN,COMLEN) BYTE EXT, COMBUFF(128) BYTE EXT,
(TCBP,CBP) BYTE EXT ;
/* MP/M PARSE FUNCTION CALL */
DECLARE
PARSE$FN STRUCTURE(
BUFF$ADR POINTER,
FCB$ADR POINTER);
DECLARE
LPP LIT '23', /* LINES PER PAGE */
FORWARD LIT '1',
BACKWARD LIT '0',
RUBOUT LIT '07FH',
POUND LIT '23H',
MACSIZE LIT '128', /* MAX MACRO SIZE */
SCRSIZE LIT '100', /* SCRATCH BUFFER SIZE */
COMSIZE LIT 'ADDRESS'; /* DETERMINES MAX COMMAND NUMBER*/
DCL FLAG BYTE EXT;
DCL RESET LABEL EXT;
DECLARE
EOS LITERALLY '0FFH';
/*SPLH*/ /*$EJECT */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * CP/M INTERFACE ROUTINES * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* IO SECTION */
READCHAR: PROCEDURE BYTE PUBLIC; RETURN MON2(1,0);
END READCHAR;
CONIN:
PROCEDURE BYTE PUBLIC;
RETURN MON2(6,0FDH);
END CONIN;
PRINTCHAR: PROCEDURE(CHAR) PUBLIC;
DECLARE CHAR BYTE;
IF PRINTSUPPR THEN RETURN;
CALL MON1(2,CHAR);
END PRINTCHAR;
TTYCHAR: PROCEDURE(CHAR) PUBLIC;
DECLARE CHAR BYTE;
IF CHAR >= ' ' THEN COLUMN = COLUMN + 1;
IF CHAR = LF THEN COLUMN = 0;
CALL PRINTCHAR(CHAR);
END TTYCHAR;
BACKSPACE: PROCEDURE PUBLIC;
/* MOVE BACK ONE POSITION */
IF COLUMN = 0 THEN RETURN;
CALL TTYCHAR(CTLH); /* COLUMN = COLUMN - 1 */
CALL TTYCHAR(' ' ); /* COLUMN = COLUMN + 1 */
CALL TTYCHAR(CTLH); /* COLUMN = COLUMN - 1 */
COLUMN = COLUMN - 2;
END BACKSPACE;
PRINTABS: PROCEDURE(CHAR) PUBLIC ;
DECLARE (CHAR,I,J) BYTE;
I = CHAR = TAB AND 7 - (COLUMN AND 7);
IF CHAR = TAB THEN CHAR = ' ';
DO J = 0 TO I;
CALL TTYCHAR(CHAR);
END;
END PRINTABS;
GRAPHIC: PROCEDURE(C) BYTE PUBLIC;
DECLARE C BYTE;
/* RETURN TRUE IF GRAPHIC CHARACTER */
IF C >= ' ' THEN RETURN TRUE;
RETURN C = CR OR C = LF OR C = TAB;
END GRAPHIC;
PRINTC: PROCEDURE(C) PUBLIC;
DECLARE C BYTE;
IF NOT GRAPHIC(C) THEN
DO; CALL PRINTABS('^');
C = C + '@';
END;
CALL PRINTABS(C);
END PRINTC;
CRLF: PROCEDURE PUBLIC;
CALL PRINTC(CR); CALL PRINTC(LF);
END CRLF;
PRINTM: PROCEDURE(A) PUBLIC;
DECLARE A POINTER;
CALL MON5(9,A);
END PRINTM;
PRINT: PROCEDURE(A) PUBLIC;
DECLARE A POINTER;
CALL CRLF;
CALL PRINTM(A);
END PRINT;
READ: PROCEDURE(A) PUBLIC;
DECLARE A POINTER;
CALL MON5(10,A);
END READ;
/* USED FOR LIBRARY FILES */
OPEN: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
IF MON6(15,FCB) = 255 THEN DO;
FLAG = 'O';
GO TO RESET;
END;
END OPEN;
/* USED FOR MAIN SOURCE FILE */
OPEN$FILE: PROCEDURE(FCB) ADDRESS PUBLIC;
DECLARE FCB POINTER;
RETURN MON7(15,FCB);
END OPEN$FILE;
CLOSE: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
DCNT = MON6(16,FCB);
END CLOSE;
SEARCH: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
DCNT = MON6(17,FCB);
END SEARCH;
DELETE: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
DCNT = MON6(19,FCB);
END DELETE;
DISKREAD: PROCEDURE(FCB) BYTE PUBLIC ;
DECLARE FCB POINTER;
RETURN MON6(20,FCB);
END DISKREAD;
DISKWRITE: PROCEDURE(FCB) BYTE PUBLIC;
DECLARE FCB POINTER;
RETURN MON6(21,FCB);
END DISKWRITE;
MAKE: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
DCNT = MON6(22,FCB);
END MAKE;
RENAME: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
CALL MON5(23,FCB);
END RENAME;
READCOM: PROCEDURE PUBLIC;
MAXLEN = 128; CALL READ(@MAXLEN);
END READCOM;
BREAK$KEY: PROCEDURE BYTE PUBLIC;
IF MON2(11,0) THEN
DO; /* CLEAR CHAR */
IF MON2(1,0) = CTRL$C THEN
RETURN TRUE;
END;
RETURN FALSE;
END BREAK$KEY;
CSELECT: PROCEDURE BYTE PUBLIC;
/* RETURN CURRENT DRIVE NUMBER */
RETURN MON2(25,0);
END CSELECT;
SELECT: PROCEDURE(DISK) PUBLIC;
DECLARE DISK BYTE;
/* SET DRIVE NUMBER */
CALL MON1(14,DISK);
END SELECT;
SETDMA: PROCEDURE(A) PUBLIC;
DECLARE A POINTER;
/* SET DMA ADDRESS */
CALL MON5(26,A);
END SETDMA;
SET$ATTRIBU: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
CALL MON5(30,FCB);
END SET$ATTRIBU;
/* THIS ROUTINE IS INCLUDED SOLELY FOR
ENCONOMY OF SPACE OVER THE USE OF THE
EQUIVALENT (IN-LINE) CODE GENERATED BY
THE BUILT-IN FUNCTION */
MOVE: PROC(C,S,D) PUBLIC;
DCL (S,D) POINTER, C BYTE;
DCL A BASED DUM1P BYTE, B BASED DUM2P BYTE;
DUM1P=S;DUM2P=D;
DO WHILE (C:=C-1)<>255;
B=A; DUM1L=DUM1L+1;DUM2L=DUM2L+1;
END;
END MOVE;
WRITE$XFCB: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
CALL MOVE(8,@PASSWORD,@PASSWORD(8));
IF MON6(103,FCB)= 0FFH THEN
CALL PRINT(@('ERROR CREATING PASSWORD$'));
END WRITE$XFCB;
READ$XFCB: PROCEDURE(FCB) PUBLIC;
DECLARE FCB POINTER;
CALL MON5(102,FCB);
END READ$XFCB;
/* 0FF => RETURN BDOS ERRORS */
RETURN$ERRO:
PROCEDURE(MODE) PUBLIC;
DECLARE MODE BYTE;
CALL MON1 (45,MODE);
END RETURN$ERRO;
REBOOT: PROCEDURE PUBLIC;
IF XFERON THEN
CALL DELETE(@LIBFCB);
CALL BOOT;
END REBOOT;
VERSION: PROCEDURE ADDRESS PUBLIC;
/* RETURNS CURRENT CP/M VERSION # */
RETURN MON7(12,0);
END VERSION;
PARSE: PROCEDURE PUBLIC;
CALL MON5(152,@PARSE$FN);
END PARSE;
END;

View File

@@ -0,0 +1,158 @@
*********************************************************
* *
* Disk Formatting Program for CP/M-68K (tm) *
* *
* Copyright Digital Research 1982 *
* *
*********************************************************
*
*
*
prntstr = 9
readbuf = 10
*
seldsk = 9
settrk = 10
setsec = 11
setdma = 12
write = 14
sectran = 16
flush = 21
format = 63
*
.text
*
start: link a6,#0
move.l 8(a6),a0
add #$81,a0
scan: cmpi.b #$20,(a0)+
beq scan
cmpi.b #$61,-(a0)
blt upper
sub #$20,(a0)
upper: cmpi.b #$41,(a0)
blt erxit
cmpi.b #$50,(a0)
bgt erxit
query: move.b (a0),d0
move.b d0,msgdskx
ext.w d0
sub.w #$41,d0
move.w d0,dsk
move.w #prntstr,d0
move.l #msgdsk,d1
trap #2
move.w #readbuf,d0
move.l #buf,d1
trap #2
move.b buf+2,d0
cmpi.b #$59,d0
beq doit
cmpi.b #$79,d0
bne exit
*
doit: clr.l d0
clr.l d1
*
* Select the disk to format
*
move.w #seldsk,d0
move.w dsk,d1
clr.b d2
trap #3
tst.l d0
beq selerx
move.l d0,a0
move.l (a0),xlt
move.l 14(a0),a0
move.w (a0),spt
move.w 8(a0),drm
move.w 14(a0),trk
clr.w sect
clr.w count
*
* Call the format function
*
move.w #format,d0
move.w dsk,d1
trap #3
tst.w d0
bne fmterx
lea buf,a0
move.l #$e5e5e5e5,d0
move.w #31,d1
bloop: move.l d0,(a0)+
dbf d1,bloop
move.w #setdma,d0
move.l #buf,d1
trap #3
*
dloop: move.w count,d0
cmp.w drm,d0
bgt exit
move.w sect,d1
cmp.w spt,d1
blt sok
clr.w sect
add.w #1,trk
sok: move.w #settrk,d0
move.w trk,d1
trap #3
move.w #sectran,d0
move.w sect,d1
move.l xlt,d2
trap #3
move.w d0,d1
move.w #setsec,d0
trap #3
move.w #write,d0
clr.w d1
trap #3
tst.w d0
bne wrterx
add #1,sect
add #1,count
bra dloop
*
exit: move.w #flush,d0
trap #3
unlk a6
rts
*
erxit: move.l #erstr,d1
erx: move.w #prntstr,d0
trap #2
bra exit
*
fmterx: move.l #fmtstr,d1
bra erx
selerx: move.l #selstr,d1
bra erx
wrterx: move.l #wrtstr,d1
bra erx
*
.data
msgdsk: .dc.b 'Do you really want to format disk '
msgdskx:.dc.b 'x ? $'
*
.even
buf: .dc.b 126,0
.ds.b 126
*
xlt: .ds.l 1
spt: .ds.w 1
drm: .ds.w 1
sect: .ds.w 1
trk: .ds.w 1
dsk: .ds.w 1
count: .ds.w 1
*
fmtstr: .dc.b 'Formatting Error',13,10,'$'
erstr: .dc.b 'Error',13,10,'$'
selstr: .dc.b 'Select Error',13,10,'$'
wrtstr: .dc.b 'Write Error',13,10,'$'
*
copyrt: .dc.b 'CP/M-68K(tm), Version 1.1, Copyright 1983, Digital Research'
serial: .dc.b 'XXXX-0000-654321'
*
.end

View File

@@ -0,0 +1,141 @@
*********************************************************
* *
* Disk Initialization Program for CP/M-68K (tm) *
* *
* Copyright Digital Research 1983 *
* *
*********************************************************
*
*
*
prntstr = 9 BDOS Functions
readbuf = 10
*
seldsk = 9 BIOS Functions
settrk = 10
setsec = 11
setdma = 12
write = 14
sectran = 16
flush = 21
*
.text
*
start: link a6,#0
move.l 8(a6),a0 base page address
add #$81,a0 first character of command tail
scan: cmpi.b #$20,(a0)+ skip over blanks
beq scan
cmpi.b #$61,-(a0) get disk letter
blt upper upshift
sub #$20,(a0)
upper: cmpi.b #$41,(a0) compare with range A - P
blt erxit
cmpi.b #$50,(a0)
bgt erxit
query: move.b (a0),d0 put disk letter in message
move.b d0,msgdskx
ext.w d0 put disk letter into range 0 - 15
sub.w #$41,d0
move.w d0,dsk
move.w #prntstr,d0 ask whether it's really ok to init
move.l #msgdsk,d1
trap #2
move.w #readbuf,d0 read reply
move.l #buf,d1
trap #2
move.b buf+2,d0 if answer isn't Y then exit
cmpi.b #$59,d0
beq doit
cmpi.b #$79,d0
bne exit
*
doit: lea buf,a0 init disk buffer to empty directory entries
move.l #$e5e5e5e5,d0
move.w #31,d1
bloop: move.l d0,(a0)+
dbf d1,bloop
move.w #setdma,d0 set up dma address for write
move.l #buf,d1
trap #3
move.w #seldsk,d0 select the disk
move.w dsk,d1
clr.b d2
trap #3
tst.l d0 check for select error
beq selerx
move.l d0,a0 get translate table address for sectran
move.l (a0),xlt
move.l 14(a0),a0 get DPB address
move.w (a0),spt get sectors per track
move.w 8(a0),drm get directory entry count - 1
move.w 14(a0),trk get starting track (=offset)
clr.w sect start at sector 0
clr.w count count of initialized sectors
*
dloop: move.w count,d0 while count <= drm ...
cmp.w drm,d0
bgt exit
move.w sect,d1 check for end-of-track
cmp.w spt,d1
blt sok
clr.w sect advance to new track
add.w #1,trk
sok: move.w #settrk,d0 set the track
move.w trk,d1
trap #3
move.w #sectran,d0 do sector translate
move.w sect,d1
move.l xlt,d2
trap #3
move.w d0,d1 set sector
move.w #setsec,d0
trap #3
move.w #write,d0 and write
clr.w d1
trap #3
tst.w d0 check for write error
bne wrterx
add #1,sect increment sector number
add #4,count increment count of directory entries
bra dloop and loop
*
exit: move.w #flush,d0 exit location - flush bios buffers
trap #3
unlk a6
rts and exit to CCP
*
erxit: move.l #erstr,d1 miscellaneous errors
erx: move.w #prntstr,d0 print error message and exit
trap #2
bra exit
*
selerx: move.l #selstr,d1 disk select error
bra erx
wrterx: move.l #wrtstr,d1 disk write error
bra erx
*
.data
msgdsk: .dc.b 'Do you really want to init disk '
msgdskx:.dc.b 'x ? $'
*
.even
buf: .dc.b 126,0 dual use buffer -- console input & dsk output
.ds.b 126
*
xlt: .ds.l 1 translate table address
spt: .ds.w 1 sectors per track
drm: .ds.w 1 maximum directory entry number
sect: .ds.w 1 current sector
trk: .ds.w 1 current track
dsk: .ds.w 1 selected disk
count: .ds.w 1 number of directory entries written so far
*
erstr: .dc.b 'Error',13,10,'$'
selstr: .dc.b 'Select Error',13,10,'$'
wrtstr: .dc.b 'Write Error',13,10,'$'
*
copyrt: .dc.b 'CP/M-68K(tm), Version 1.1, Copyright 1983, Digital Research'
serial: .dc.b 'XXXX-0000-654321'
*
.end

View File

@@ -0,0 +1,22 @@
pip d:=*.h[g7
pip d:=as68symb.dat[g0
pip d:=s.o[g7
pip d:=clib[g7
cp68 copy.c copy.i
c068 copy.i copy.ic copy.st
c168 copy.ic copy.s -LD
as68 -l -u copy.s
era copy.i*
era copy.s*
as68 -l -u format.s
as68 -l -u init.s
lo68 -r -s -o copy.rel s.o copy.o clib
lo68 -r -s -o format.rel format.o
lo68 -r -s -o init.rel init.o
pip d:[g0]=relochd.sub
submit next

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,22 @@
Commands to build the PIP utility on the EXORmacs
=================================================
=================================================
1. Boot up VERSADOS
2. Logon to the VAX using the VAX utility.
3. =CHAIN PIP
The submit file PIP.CF will compile PIP and send the
resulting output file (PIP68K.OC) to the VAX.
4. Download PIP68K.OC to an ALTOS
5. Use the RECONV.COM program to reconvert PIP68K.OC to PIP.68K
6. Port to the EXORmacs via a floppy and test under CP/M-68K.

View File

@@ -0,0 +1,24 @@
*
* SUBROUTINE FOR CP/M68K PIP UTILITY
*
SECTION 9
XDEF INPLOC,OUTPLOC,INPD,OUTD
*
INPLOC EQU *
NOP
RTS
*
OUTPLOC EQU *
NOP
RTS
*
INPD EQU *
NOP
RTS
*
OUTD EQU *
NOP
MOVE.L (A7)+,A0
LEA 2(A7),A7
JMP (A0)
END

View File

@@ -0,0 +1,194 @@
*********************************************************
* *
* Program to Write Boot Tracks for CP/M-68K (tm) *
* *
* Copyright Digital Research 1982 *
* *
*********************************************************
*
*
*
prntstr = 9 BDOS Functions
dseldsk = 14
open = 15
readseq = 20
dsetdma = 26
*
seldsk = 9 BIOS Functions
settrk = 10
setsec = 11
isetdma = 12
write = 14
sectran = 16
flush = 21
*
bufcnt = $80
bufsize = $80*bufcnt
*
.text
*
start: link a6,#0
move.l 8(a6),a0 base page address
lea $5c(a0),a1
move.l a1,fcb
clr.b hflag
add #$81,a0 first character of command tail
scan: cmpi.b #$20,(a0)+ skip over blanks
beq scan
sub.l #1,a0
scan1: tst.b (a0)
beq erxit
cmpi.b #$2d,(a0)+ check for -H flag
bne nohyph
cmpi.b #$48,(a0)+
bne erxit
tst.b hflag
bne erxit
move.b #$ff,hflag
sub.l #$24,fcb change to 2nd default fcb
bra scan
nohyph: cmpi.b #$20,(a0)
bne scan1
scan2: cmpi.b #$20,(a0)+
beq scan2
cmpi.b #$61,-(a0) get disk letter
blt upper upshift
sub #$20,(a0)
upper: cmpi.b #$41,(a0) compare with range A - P
blt erxit
cmpi.b #$50,(a0)
bgt erxit
move.b (a0),d0
ext.w d0 put disk letter into range 0 - 15
sub.w #$41,d0
move.w d0,dsk
*
* open file to copy
*
move.w #open,d0
move.l fcb,d1
trap #2
cmpi.w #$00ff,d0
bne openok
move.l #opnfl,d1
jmp erx
openok: move.l fcb,a0
clr.b 32(a0)
*
* read
*
move.l #buf,d2
clr.w count
rloop: move.w #dsetdma,d0
move.l d2,d1
trap #2
move.w #readseq,d0
move.l fcb,d1
trap #2
tst.w d0
bne wrtout
add.l #128,d2
add.w #1,count
cmpi.w #bufcnt,count
bgt bufoflx
bra rloop
*
* write
*
wrtout: move.w #seldsk,d0 select the disk
move.w dsk,d1
clr.b d2
trap #3
tst.l d0 check for select error
beq selerx
move.l d0,a0
move.l 14(a0),a0 get DPB address
move.w (a0),spt get sectors per track
move.w 14(a0),off get offset
clr.w trk start at trk 0
clr.w sect start at sector 0
lea buf,a0
tst.b hflag
bne wrt1
cmpi.w #$601a,(a0)
bne wrt1
add.l #28,a0
wrt1: move.l a0,bufp
*
wloop: tst.w count
beq exit
move.w sect,d1 check for end-of-track
cmp.w spt,d1
blt sok
clr.w sect advance to new track
move.w trk,d0
add.w #1,d0
move.w d0,trk
cmp.w off,d0
bge oflex
sok: move.w #settrk,d0 set the track
move.w trk,d1
trap #3
move.w sect,d1 set sector
move.w #setsec,d0
trap #3
move.w #isetdma,d0 set up dma address for write
move.l bufp,d1
trap #3
move.w #write,d0 and write
clr.w d1
trap #3
tst.w d0 check for write error
bne wrterx
add #1,sect increment sector number
sub #1,count
add.l #128,bufp
bra wloop
*
exit: move.w #flush,d0 exit location - flush bios buffers
trap #3
unlk a6
rts and exit to CCP
*
erxit: move.l #erstr,d1 miscellaneous errors
erx: move.w #prntstr,d0 print error message and exit
trap #2
bra exit
*
selerx: move.l #selstr,d1 disk select error
bra erx
wrterx: move.l #wrtstr,d1 disk write error
bra erx
bufoflx: move.l #bufofl,d1 buffer overflow
bra erx
oflex: move.l #trkofl,d1
bra erx
*
*
.bss
*
.even
*
buf: .ds.b bufsize+128
*
fcb: .ds.l 1 fcb address
spt: .ds.w 1 sectors per track
sect: .ds.w 1 current sector
trk: .ds.w 1 current track
dsk: .ds.w 1 selected disk
off: .ds.w 1 1st track of non-boot area
count: .ds.w 1
bufp: .ds.l 1
hflag: .ds.b 1
*
.data
*
erstr: .dc.b 'Invalid Command Line',13,10,'$'
selstr: .dc.b 'Select Error',13,10,'$'
wrtstr: .dc.b 'Write Error',13,10,'$'
opnfl: .dc.b 'Cannot Open Source File',13,10,'$'
bufofl: .dc.b 'Buffer Overflow',13,10,'$'
trkofl: .dc.b 'Too Much Data for System Tracks',13,10,'$'
*
*
.end

View File

@@ -0,0 +1,34 @@
The serialization program needs the following function in CLIB:
alrem
The compiler generates jsr alrem instead of jsr _alrem.
Solution -----> add another label to CLIB called alrem: pointing
to _alrem.
A>c serial
A>clink serial
A>serial 1 10000
Put files to serialize in a file called : SERIAL.DAT.
EX> pip.rel
stat.rel
ed.rel
nm68.rel
.
.
.
cpm.rel

View File

@@ -0,0 +1,33 @@
pip d:=*.rel[g1
pip d:=as68init[g1
pip d:=*.rel[g6
pip d:=s.o[g7
pip d:=clib[g7
pip d:=*.h[g7
pip d:=*.rel[g8
pip d:=*.rel[g10
pip d:=*.rel[g11
pip d:=*.rel[g12
pip d:=*.rel[g13
reloc.rel reloc.rel reloc.68k
reloc ar68.rel ar68.68k
reloc as68.rel as68.68k
reloc c068.rel c068.68k
reloc c168.rel c168.68k
reloc cp68.rel cp68.68k
reloc copy.rel copy.68k
reloc ddt.rel ddt.68k
reloc dump.rel dump.68k
reloc format.rel format.68k
reloc init.rel init.68k
reloc lo68.rel lo68.68k
reloc nm68.rel nm68.68k
reloc prtobj.rel prtobj.68k
reloc sendc68.rel sendc68.68k
reloc size68.rel size68.68k
pip ddt1.68k=ddt1.rel
as68 -i as68init
user 8 ! make

View File

@@ -0,0 +1,269 @@
/*----------------------------------------------------------------------*\
| serial.c v1.0 |
| SERIALIZATION PROGRAM FOR CP/M-68K |
| ================================== |
| |
| date: 1/3/83 |
| ---- |
| |
| last modified: 2/3/83 |
| ------------- |
| |
| description: |
| ----------- This program replaces up to 20 occurances |
| of "654321" in all files found in "SERIAL.DAT". |
| The string "654321" is replaced by a serial |
| number. Leading zeros will be filled in by |
| the program. The starting and ending serial |
| number's are read in from the command line. |
| The user is prompted for the serialization |
| drive. |
| |
| |
| COPYRIGHT (C) 1983 |
| DIGITAL RESEARCH |
| BOX 579 |
| PACIFIC GROVE, CA. 93950 |
| |
\*----------------------------------------------------------------------*/
#include "stdio.h" /* standard I/O library */
#define islower(c) ('a' <= (c) && (c) <= 'z')
#define toupper(c) (islower(c) ? ((c)-040) : (c))
#define RESET 13
#define SELECT 14
/********************************/
/* GLOBAL VARIABLES */
struct _serial /********************************/
{ /* */
BYTE filename[13]; /* file to serialize */
}; /* */
struct _serial serial[150]; /* array of structures */
/* */
BYTE enddata[] = "xxxxxxxxxxxx"; /* end of filenames marker */
BYTE marker[] = "654321"; /* place in file to sub serial #*/
BYTE snum[] = "000000"; /* serial number */
BYTE drive = 0; /* serialization drive */
BYTE chtab[] = "0123456789"; /* table of digits */
FILE *stream; /* pointer to a stream file */
/********************************/
/********************************/
/* FUNCTIONS */
/********************************/
FILE *fopen(); /* returns a stream I/O pointer */
FILE *fopenb(); /* returns a stream I/O pointer */
BYTE *trans(); /* returns a pointer to a string*/
LONG atol(); /* returns a long number */
LONG ftell(); /* returns a long number */
/********************************/
main(argc,argv)
WORD argc;
BYTE *argv[];
{
REG LONG start_num; /* starting serial number */
REG LONG final_num; /* final serial number */
REG LONG num; /* current serial number */
BYTE buffer[32]; /* read buffer */
BYTE boot; /* y or n to system tracks */
if(argc != 3)
{
printf("\nUsage: A>serial starting ending");
exit(0);
}
printf("Serial.68K V1.0");
init(); /* try to open data file */
boot = 'N'; /* no serializing of system trks*/
/* check range of serial number's */
if(atol(argv[1]) > 999999L || atol(argv[2]) > 999999L ||
atol(argv[1]) < 0L || atol(argv[2]) < 0L)
{
printf("\nERROR: Serial # out of range: [0-999999]");
exit(0);
}
printf("\nSerialization drive ? "); gets(buffer);
drive = toupper(buffer[0]);
/* verify to user the serial number range */
printf("\nSTARTING serial number is: %s",argv[1]);
printf("\nFINAL serial number is : %s",argv[2]);
if(boot == 'Y')
printf("\nSystem tracks will be serialized");
printf("\n\n");
/************************************************/
/* */
/* MAIN SERIALIZATION LOOP */
/* ----------------------- */
/* */
/************************************************/
for(num = atol(argv[1]); num <= atol(argv[2]); num++)
{
__BDOS(RESET,(long)0);
printf("\n\nInsert new diskette in drive %c and type RETURN",drive);
getchar();
printf("\nCURRENT serial number is: %LD\n",num);
if(boot == 'Y')
boottrk(num);
patch(num);
}
}
/************************/
VOID init() /* Open SERIAL.DAT */
/* Read SERIAL.DAT */
/************************/
{
BYTE buf[40];
REG UWORD j;
REG struct _serial *p;
if((stream = fopen("SERIAL.DAT","r")) == NULL)
{
printf("\nUnable to open SERIAL.DAT");
exit(0);
}
/* read in the data line by line */
/* and fill the structure serial */
fgets(buf,40,stream);
p = &serial;
do
{
j = 0;
while((p->filename[j] = buf[j++]) != '\n');
p->filename[j-1] = '\0';
p++;
fgets(buf,40,stream);
}
while(!(feof(stream)));
for(j = 0;j < 12;j++)
p->filename[j] = 'x';
p->filename[12] = '\0';
fclose(stream);
}
/************************/
VOID patch(num) /* Plug Serialization */
/* bytes into file */
/************************/
LONG num;
{
REG struct _serial *p;
REG UWORD i,j;
LONG offset[21];
REG BYTE *pp;
REG UWORD ch;
REG WORD fd;
__BDOS(SELECT,(long)drive-'A');
p = &serial;
while(strcmp(p,enddata))
{
printf("\nSerializing: %s ",p);
for(i = 1;i <= (12 - strlen(p));i++)
printf(" ");
if((stream = fopenb(p,"r")) == NULL)
printf("Unable to open file: %s",p);
else
{
for(j = 0;j < 21;j++)
offset[j] = -1L;
i = j = 0;
pp = marker;
rewind(stream);
while(1)
{
ch = fgetc(stream);
if(feof(stream))
break;
if(ch == *pp)
{
i++;
if(pp == marker)
offset[j] = ftell(stream);
pp++;
}
else
{
pp = marker;
offset[j] = -1L;
i = 0;
}
if(i == 6)
{
j++;
if(j == 20)
break;
i = 0;
pp = marker;
}
}
fclose(stream);
if(offset[0] == -1L)
printf("file cannot be serialized");
else
{
fd = openb(p, 2);
if ( fd == -1 ) printf("cannot write to file");
else
{
j = 0;
while(offset[j] != -1L)
{
lseek(fd, --offset[j++], 0);
write(fd, trans(num), 6);
}
printf("Serialization complete %d",j);
close(fd);
}
}
}
p++;
}
}
VOID boottrk(num)
LONG num;
{
printf("\nSerializing Boot tracks");
}
BYTE *trans(num)
LONG num;
{
REG BYTE *p;
LONG x;
p = snum;
x = 100000;
while(x)
{
*p++ = chtab[num/x];
num %= x;
x /= 10;
}
return(snum);
}

View File

@@ -0,0 +1,8 @@
ed.68k
pip.68k
stat.68k
clib
nm68.68k
sendc68.68k
cpmlib

View File

@@ -0,0 +1,53 @@
CP/M-68K RELEASE SOFTWARE
========================= 1/19/83
DIRECTORY FILES THAT HAVE XXXX-0000-654321
========= ================================
AS68.DIR MAIN.C
CCP.DIR NONE
DOCS.DIR NONE
PIPEDSTAT.DIR UT68K.SA
TOOLS.DIR COPY.C
INIT.S
FORMAT.S
BDOS.DIR BDOSMISC.C
CGEN.DIR MAIN.C
KLIB.DIR NONE
PREPROC.DIR MAIN.C
BIOS.DIR NONE
CLIB.DIR COPYRT.S
LINK.DIR RELOC.C
SIZE68.C
AR68.C
LO68.C
DUMP.C
SENDC68.C
NM68.C
RELNOTES.DIR NONE
VMSLIB.DIR NONE
BOOT.DIR BDOSMAIN.C
DDT.DIR DDT1.C
DDTLOAD.S
PARSER.DIR MAIN.C
SERIAL.DIR NONE

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
Commands to build the STAT utility on the EXORmacs
==================================================
==================================================
1. Boot up VERSADOS
2. Use the VAX utility to logon to the VAX
3. =CHAIN STAT
The submit file STAT.CF will compile stat and place
the resulting output file (STAT68K.OC) on the VAX.
4. Download STAT68K.OC to an ALTOS.
5. Use the RECONV.COM program to reconvert STAT68K.OC to STAT.68K.
6. Port STAT.68K to the EXORmacs and test under CP/M-68K.

View File

@@ -0,0 +1,114 @@
DPB86:
DO;
/* THE PURPOSE OF THIS MODULE IS TO ALLOW INDEPENDENCE */
/* OF PROCESSOR, I.E., 8080 OR 8086 */
DECLARE
/*SPLH*/ /* LIT LITERALLY 'LITERALLY',
DCL LIT 'DECLARE',
PROC LIT 'PROCEDURE',
ADDR LIT 'ADDRESS', */
TRUE LIT '0FFH',
FALSE LIT '0',
/* BOOLEAN LIT 'BYTE', */
FOREVER LIT 'WHILE TRUE',
CR LIT '13',
LF LIT '10',
TAB LIT '9',
FF LIT '12',
SECTORLEN LIT '128';
/* FUNCTION CALL 32 IN 2.0 OR LATER BDOS, RETURNS THE ADDRESS OF THE DISK
PARAMETER BLOCK FOR THE CURRENTLY SELECTED DISK, WHICH CONSISTS OF:
SPT (2 BYTES) NUMBER OF SECTORS PER TRACK
BLKSHF (1 BYTE) BLOCK SIZE = SHL(DOUBLE(128),BLKSHF)
BLKMSK (1 BYTE) SECTOR# AND BLKMSK = BLOCK NUMBER
EXTMSK (1 BYTE) LOGICAL/PHYSICAL EXTENTS
BLKMAX (2 BYTES) MAX ALLOC NUMBER
DIRMAX (2 BYTES) SIZE OF DIRECTORY-1
DIRBLK (2 BYTES) RESERVATION BITS FOR DIRECTORY
CHKSIZ (2 BYTES) SIZE OF CHECKSUM VECTOR
OFFSET (2 BYTES) OFFSET FOR OPERATING SYSTEM
*/
/* INDICES INTO DISK PARAMETER BLOCK, USED AS PARAMETERS TO DPB PROCEDURE */
DCL SPT$W LIT '0',
BLKSHF$B LIT '2',
BLKMSK$B LIT '3',
EXTMSK$B LIT '4', /* 68K*/
BLKMAX$W LIT /*'5', */ '6',
DIRMAX$W LIT /*'7', */ '8',
DIRBLK$W LIT /*'9', */ '10',
CHKSIZ$W LIT /*'11',*/ '12',
OFFSET$W LIT /*'13';*/ '14';
DECLARE K$PER$BLOCK BYTE PUBLIC;
DECLARE DPB$BASE POINTER;/*SPLH*/
DECLARE DPB$ARRAY (16) BYTE; /*SPLH */
MON4: PROCEDURE (F,A) EXTERNAL;
DCL F BYTE, A ADDRESS;
END MON4;
MON5: PROC(F,A) EXT;
DCL F BYTE,A POINTER;
END MON5;
DCL GET$DPB LIT '31';
/* MERGE SYS:3.CHRSYN.STATSUB1.SA = [SOURCE.CPM86.CPM11.STAT]CON86.PLM*/
/* $COMPACT */
/* $TITLE ('CONSOLE 8086 - GET CONSOLE WIDTH') */
/* THE PURPOSE OF THIS MODULE IS TO ALLOW INDEPENDENCE */
/* OF PROCESSOR, I.E., 8080 OR 8086 */
/* IT WILL RETURN A WORD VALUE EQUAL TO THE CONSOLE WIDTH FROM
THE SYSTEM DATA PAGE. */
GET$SYSDAT:
PROCEDURE POINTER;
RETURN /* (MON4(49,0)); */ 10; /*SPLH*/
END GET$SYSDAT;
DECLARE CONWIDTH$POINTER POINTER;
DECLARE CONWIDTH$PTR STRUCTURE (
OFFSET WORD,
SEGMENT WORD) AT (@CONWIDTH$POINTER);
DECLARE WIDTH BASED CONWIDTH$POINTER BYTE;
DECLARE CONWIDTH$OFFSET LIT '0040H';
COLUMNS: PROCEDURE BYTE PUBLIC;
/* CONWIDTH$POINTER = GET$SYSDAT;
CONWIDTH$PTR.OFFSET = CONWIDTH$PTR.OFFSET + CONWIDTH$OFFSET;
IF WIDTH = 0 THEN
RETURN 80;
RETURN WIDTH; */ RETURN 80 ; /*SPLH*/
END COLUMNS;
/* MERGE END */
DPB$BYTE: PROCEDURE(PARAM) BYTE PUBLIC;
DCL PARAM BYTE;
RETURN(DPB$ARRAY(PARAM)); /* S-PL/H */
END DPB$BYTE;
DPB$WORD: PROCEDURE(PARAM) ADDRESS PUBLIC; /* S-PL/H */
DCL PARAM BYTE;
RETURN(DPB$ARRAY(PARAM+1) + SHL(DOUBLE(DPB$ARRAY(PARAM)),8));
END DPB$WORD;
BASE$DPB: PROCEDURE PUBLIC; /* S-PL/H */
/* 68K*/ DPB$BASE=@DPB$ARRAY;
/* DPB$BASE = MON4(GET$DPB,0); */ CALL MON5(GET$DPB,DPB$BASE);
K$PER$BLOCK = SHR(DPB$BYTE(BLKMSK$B)+1 ,3);
END BASE$DPB;
END DPB86;

View File

@@ -0,0 +1,43 @@
Commands to build the COPY utility on the EXORmacs
==================================================
==================================================
D>c copy
*****INCLUDE FILES*****
stdio.h
portab.h
*****OUTPUT FILES*****
copy.o
*****LINK STEP*****
D>clink copy ccpbdos
Submit file yields: lo68 -r -o copy.68k s.o copy.o ccpbdos.o clib
*****OUTPUT FILES*****
copy.68k
-------------------------------------------------------------------
FORMAT and INIT utilities:
==========================
D>as68 -l -u format.s
D>lo68 -r -o format.68k format.o
D>as68 -l -u init.s
D>lo68 -r -o init.68k init.o

View File

@@ -0,0 +1,133 @@
*******************************************************************************
*
* STANDARD INTERFACE ROUTINE FOR CP/M68K UTILITY PROGRAM
* (OVER 64K MODEL)
*
* (1) SET THE ENVIRONMENT FOR S-PL/H OBJECT
* (2) DECLARE THE PUBLIC PROCEDURE FOR BDOS CALL
* (3) SET THE BASE PAGE VARIABLES
* (4) DECLARE PATCH AREA
*
*******************************************************************************
SECTION 8
*******************************************************************************
********* EXTERNAL DEFINITION
*******************************************************************************
XDEF .SMAIN
XDEF ENTRYC
XDEF MON1,MON2,MON3,MON4,XDOS
XDEF MON5,MON6,MON7
XDEF MAXB,MEMSIZE
XDEF FCB,FCB16,BUFF,TBUFF
XDEF PATCH1,PATCH2
XDEF MEMORY
*******************************************************************************
********* EXTERNAL REFERENCE DIFINITION
*******************************************************************************
XREF .SPSCT
XREF .SDSCT
*******************************************************************************
********* CONSTANT EQUATION DEFINITION
*******************************************************************************
OMAXB EQU 4 /* OFFSET OF MAXB FROM BASE
OFCB16 EQU $38 /* OFFSET OF FCB16 FROM BASE
OFCB EQU $5C /* OFFSET OF FCB FROM BASE
OBUFF EQU $80 /* OFFSET OF BUFF FROM BASE
FCBSZ EQU 72 /* (FCB16 + FCB) AREA SIZE
BUFFSZ EQU 128 /* BUFF AREA SIZE
*
*******************************************************************************
*
ENTRYC EQU * /* ENTRY POINT FROM CCP
.SMAIN EQU * /* REFER FROM .SINIT ROUTINE
*******************************************************************************
********* SET THE BASE PAGE VARIABLES
*******************************************************************************
MOVE.L (A7)+,RTNCCP /* STORE RETURN ADDR OF CCP
MOVE.L (A7)+,SBASEP /* STORE POINTER OF BASE PAGE
*
MOVEA.L SBASEP,A0 /* GET THE BASE ADDR OF BASE PAGE
MOVE.W OMAXB(A0),MAXB /* SET MAXB
*
LEA OFCB16(A0),A0 /* GET THE SOURCE ADDR OF FCB16
LEA FCB16,A1 /* GET THE DESTINATION ADDR OF FCB16
MOVE.W #(FCBSZ-1),D0 /* SET LOOP NUMBER
LOP1 MOVE.B (A0)+,(A1)+ /* SET FCB16 AND FCB
DBF D0,LOP1
*
MOVEA.L SBASEP,A0
LEA OBUFF(A0),A0 /* GET THE SOURCE ADDR OF BUFF
LEA BUFF,A1 /* GET THE DESTINATION ADDR OF BUFF
MOVE.W #(BUFFSZ-1),D0 /* SET LOOP NUMBER
LOP2 MOVE.B (A0)+,(A1)+ /* SET BUFF AND TBUFF
DBF D0,LOP2
*
********* END BASE PAGE SET
*******************************************************************************
********* INIT FOR S-PL/H
*******************************************************************************
LEA RMA,A5 /* SET RMA BASE
LEA RMA,A6
LEA RMA,A7 /* SET STACK POINTER
SUBA.L #4,A6 /* SET FRAME POINTER
LEA .SPSCT,A4 /* S-PL/H OBJECT AREA
LEA .SDSCT,A2 /* S-PL/H DATA AREA
JSR (A4) /* GO TO S-PL/H
*******************************************************************************
********* PUBLIC SUBROUTINE FOR BDOS CALL
*******************************************************************************
MON1 EQU *
MON2 EQU *
MON3 EQU *
MON4 EQU *
XDOS EQU *
CLR.L D0
CLR.L D1
MOVE.W 4(A7),D1
MOVE.B 6(A7),D0
TRAP #2 /* BDOS CALL
MOVEA.L (A7)+,A0
LEA 4(A7),A7
JMP (A0) /* RETURN TO MAINROUTINE
MON5 EQU *
MON6 EQU *
MON7 EQU *
CLR.L D0
MOVE.L 4(A7),D1
MOVE.B 8(A7),D0
TRAP #2 /* BDOS CALL
MOVEA.L (A7)+,A0
LEA 6(A7),A7
JMP (A0)
*******************************************************************************
********* PATCH AREA
*******************************************************************************
PATCH1 DC.B 'COPYRIGHT 1983'
DC.B 'DIGITAL RESEARCH'
PATCH2 DC.B '010282'
DC.B 'XXXX-'
DC.B '0000-'
DC.B '654321'
*
*******************************************************************************
*******************************************************************************
* DEFINITION OF DATA AREA
*******************************************************************************
SECTION 7
STACK DS.L 300 /* STACK AREA OF S-PL/H
RMA DS.B 144 /* S-PL/H RUN TIME MAINTENANCE AREA
*******************************************************************************
MAXB DS.L 1 /* TOP ADDR OF TPA
MEMSIZE EQU MAXB /* SAME AS MAXB
FCB16 DS.B 36 /* 2-nd PARSED FCB OF COMMAND LINE
FCB DS.B 36 /* 1-st PARSED FCB OF COMMAND LINE
BUFF DS.B 128 /* COMMAND LINE TAIL AND DMA BUFF
TBUFF EQU BUFF /* SAME AS BUFF
RTNCCP DS.L 1 /* RETURN ADDR TO CCP
SBASEP DS.L 1 /* POINTER TO BASE PASE
MEMORY DS.L 1 /* MEMORY ARRAY
*
*******************************************************************************
*
END .SMAIN