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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,93 @@
PL/M is a high-level programming language especially designed to
simplify the task of system programming for the Intel 8-bit family
of microcomputers--the 8008 and the 8080. The files provided in
this archive contain version 2.0 of Intel's PL/M cross compiler
for the 8080. The PL/M programming langauge is described in the
Intel publication, 8008 and 8080 PL/M Programming Manual. A second
Intel publication, 8080 PL/M Compiler Operators Manual, describes
the operation of the PL/M cross compiler.
The Intel 8080 PL/M Cross Compiler is a two pass compiler written
in ANSI FORTRAN. PASS 1 reads a PL/M source program and converts
it to an intermediate form on work files. Optionally, a listing of
the input source program may be obtained during this pass. Errors
in program syntax are detected at this stage, and appropriate error
messages are sent to the list file. PASS 2 processes the work files
produced by PASS 1, and generates machine code for the MCS-80 CPU.
This machine code, which may be in either BNPF or Hex format, may be
loaded and executed directly on an INTELLEC 8/Mod 80 Microcomputer
Development System, simulated using INTERP/80, a cross-simulator of
the 8080 CPU, or used to program ROMs. PASS 2 will optionally
produce a symbol table and a mnemonic listing of the generated
machine code. Certain errors may be detected during PASS 2 and are
reported in the list file.
The operation of each pass of the PL/M compiler is governed by a set
of parameters know as compiler controls, each control is identified
by a unique letter of the alphabet. Each compiler control is provided
with a default value which is used throughout the compilation unless
explicitly altered by the user. The commonly used compiler controls
are described below and a complete list of compiler controls is given
in Intel's 8080 PL/M Compiler Operators Manual.
The value of the compiler controls may be changed at any time during
PASS 1 or at the beginning of PASS 2 by entering a control record.
Control records must begin with a dollar sign ($) and have the
following form:
$<id>=<value> [ $<id>=<value> ] ...
where <id> is the unique letter assigned to the compiler control
that is to be changed and <value> is the new value. Blanks may be
included on either side of the equal sign (=) but not within the
$<id> or <value>. Two special control record formats are available
to interrogate the current values of the compiler controls. A
specification like the following:
$$<id>
will cause the current value of the compiler control represented
by <id> to be listed, while a specification that consists of just
two dollar signs will cause the values of all compiler controls to
be listed.
Control records may be included anywhere within the source input read
by PASS 1 or in one or more input lines terminated with an all blank
or null line to be read at the start of PASS 2.
PASS 1 Compiler Controls
CONTROL VALUES DEFAULT USE
L 1-79 1 Leftmargin. Specifies the first
character position processed on each
input line. All leading characters are
ignored.
P 0,1 1 Echo input if 1, suppress echo if 0.
R 1-80 80 Rightmargin, ignore trailing characters
on each input record.
W 1-120 120 Maximun number of characters per output
line.
PASS 2 Compiler Controls
CONTROL VALUES DEFAULT USE
F 0,1 1 Display decoded memory initialization.
T 0,1 1 Display cross-reference table of
approximate memory address versus
source line number.
H 0 Header. Decimal address at which
generated code should start. I.e.,
the start of the program's ISA.
M 0,1 1 Display symbol table.
Q 0,1 1 If 1 then object file is written in
BNPF, otherwise the object file is
written in Hex format.
V 0 Page number of first page of the VSA.
I.e., variable storage, stack, etc.
If set to zero the first availabe page
above the ISA is used.


View File

@@ -0,0 +1,352 @@
PL/M-80 Language Summary
PL/M-80 is a programming language for i8080 systems. It is based most
notable on PL/I. It has the type of block structure and scope rules
most programmers now expect despite the fact it is a fairly small
language.
The one thing that may "trip-up" may Pascal programmers is that PL/M
(and its PL/I big brother) use semicolon as a terminator, not as a
statement separator. Semicolons mark the end of every statement.
The remainder of this file summarizes the PL/M-80 language and its
features. It is only a summary; no attempt is made to provide a
complete and unambiguous description.
PL/M Character Set
==================
Alphabetics: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Numerics: 0 1 2 3 4 5 6 7 8 9
Specials: $ = . / ( ) + - ' * , < > : ; and space
All other characters are unrecognized by PL/M in the sense that they
are regarded as equivalent to the space character.
PL/M Identifiers
================
Identifiers may be from 1 to 31 characters in length. An alphabetic
must be the first character in an identifer name; the remainder may
be alphabetic or numeric. In addition, dollar signs may be imbedded
within a variable name to improve readability. They are ignored by
PL/M. (The identifiers LINE$COUNT and LINECOUNT are interpreted
as identical names.)
The following are all reserved words, and may not be used as
identifier names:
ADDRESS DATA EOF LABEL PROCEDURE
AND DECLARE GO LITERALLY RETURN
BASED DISABLE GOTO MINUS THEN
BY DO HALT MOD TO
BYTE ELSE IF NOT WHILE
CALL ENABLE INITIAL OR XOR
CASE END INTERRUPT PLUS
PL/M Data Types
===============
There are two data types in PL/M. The data type BYTE refers to
8-bit data; ADDRESS, to 16. It is also possible to construct
arrays of either type and pointers to either type.
PL/M Constants
================
Numeric constants may be expressed as binary, octal, decimal, and
hexadecimal numbers. The radix for the number is specified by a
letter appended to the number: B for binary, O and Q for octal,
D for decimal, and H for hexadecimal. If the letter suffix is
omitted, the number is treated as decimal. Hexadecimal constants
must begin with a numeric to avoid confusion with identifier names.
As with identifiers, dollar signs may be imbedded in numeric constants
to improve readability. However a number is expressed, it must be
representable in 16 bits.
Character string constants are enclosed in apostrophes. An apostrophe
within the string must be doubled. Character strings are represented
using 7-bit ASCII codes. Character strings constants of length 1 are
treated as BYTE values; length 2 as ADDRESS values. Longer strings
are only useful with the "dot" operator.
PL/M Expressions
================
There are seven arithmetic operators in PL/M. All perform unsigned
arithmetic operations on either BYTE or ADDRESS values.
+ Binary addition operator.
- Binary subtraction operator, or unary negation.
PLUS Binary addition-with-carry operator.
MINUS Binary subtraction-with-carry operator.
* Binary multiplication operator.
/ Binary division operator.
MOD Binary remainder operator.
Multiply and divide always produce ADDRESS results. The others
produce BYTE results if both operands are BYTE values; ADDRESS,
otherwise.
There are four boolean operators in PL/M. All perform either 8-bit
or 16-bit boolean operations of their operands.
NOT Unary complement operator.
AND Binary conjunction operator.
OR Binary disjunction operator.
XOR Binary exclusive-disjunction operator.
The operators produce BYTE results if both operands are BYTE values.
If at least one is of type ADDRESS, the other is extended with
high-order zeroes if necessary, and the result is type ADDRESS.
There are six relational operators. All return a true/false result
with 0FFH representing "true" and 00H, "false".
< Binary less-than operator.
<= Binary less-than-or-equal operator.
= Binary equal operator.
>= Binary greater-than-or-equal operator.
> Binary greater-than operator.
<> Binary not-equal operator.
There is one other PL/M operator, the so-called "dot" operator. It
is a unary operator that returns the memory address of its operand.
The operator may be used in the following forms:
.variable
.constant
.(constant)
.(constant, ...)
The construction " .(08H, 'Message', 0DH) " might best be considered
as the address of a nine-element BYTE array.
Expression evaluation obeys operator precedence unless modified by
parenthesis. The following lists the operators in order of precedence:
Highest: .
* / MOD
+ - PLUS MINUS
< <= = => > <>
NOT
AND
Lowest: OR XOR
PL/M Executable Statements
==========================
Commentary.
/* Not really an executable statement, but... */
Assignment.
variable = expression ;
-or- variable, variable, ... = expression ;
Imbedded assignment. (May be used within an expression.)
(variable := expression)
Do-End. (Simple statement grouping.)
DO;
statement; ...;
END;
Do-While. (Loop while rightmost bit of expression = 1.)
DO WHILE expression;
statement; ...;
END;
Iterative Do.
DO variable = expression1 to expression2;
statement; ...;
END;
Do-Case. (Execute i-th statement, numbered from 0.)
DO CASE expression;
statement0;
statement1;
...;
END;
If-Then.
IF expression THEN statement;
If-Then-Else.
IF expression THEN statement; ELSE statement;
Go To. (GO TO and GOTO are synonomous.)
GO TO label;
-or- GO TO number;
-or- GO TO variable;
The first form causes a GOTO the statement prefixed with 'label:'.
The latter two forms cause a GOTO an absolute storage location.
Disable interrupts.
DISABLE;
Enable interrupts.
ENABLE;
PL/M Variable Declarations
==========================
Identifiers are defined with the DECLARE statement. The following
are typical forms for the DECLARE statement.
Single identifier: DECLARE identifier type;
Group of identifiers: DECLARE (identifier, ...) type;
Array: DECLARE identifier (constant) type;
Multiple: DECLARE id type, id type, ...;
Array subscripts start at 0. Thus, DECLARE A(10) BYTE; defines the
array of elements A(0)...A(9).
Declared variables may have initial values specified by including
the INITIAL attribute after the type on the DECLARE statement:
DECLARE A(10) BYTE INITIAL(10,11,12,13,14,15,16,17,18,19);
Variables declared with the INITIAL attribute are preset at program
load time. They are not reset at procedure invocation or anywhere
else. The INITIAL attribute may specify fewer values then would
be needed for the declared variables.
A DATA attribute is available for declaring storage constants. No
type or array sizes are specified; BYTE is assumed and the array
size is implicitly determined from the DATA value. The values of
identifiers declared as DATA must not be changed during program
execution.
DECLARE GREETINGS DATA ('Hello, world.');
PL/M also supports a limited macro facility. Identifiers may be
declared with the LITERALLY attribute. The literal value is
substituted in the program source text where ever the identifier is
used.
DECLARE FOREVER LITERALLY 'WHILE TRUE';
. . .
DO FOREVER;
Variables may be declared as BASED, as in
DECLARE A$PTR ADDRESS,
A BASED A$PTR BYTE;
In this example, the memory location associated with variable A is
determined by the address stored in variable A$PTR.
Labels are declared using LABEL for the type. An identifier so
declared should also appear before an executable statement, separated
from the statement by a colon. (It is often not strictly necessary
to declare all labels. An implicit DECLARE results when an otherwise
undeclared label is encountered in the program. That is,
COME$HERE: CALL PRT$MESSAGE(3);
is equivalent to
DECLARE COME$HERE LABEL;
COME$HERE: CALL PRT$MESSAGE(3);
However, due to scope rules, a earlier reference to the label (in a
GOTO statement) may be flagged in error, because the implicit DECLARE
is physically latter in the program.
PL/M Procedure Declarations
===========================
Procedures must be defined before they are used. This declaration
form is:
identifier: PROCEDURE (arg, ...) type;
statement; ...;
END identifier;
The 'identifier' (which appears in two places) specifies the name for
the procedure. If no result is returned, the 'type' is omitted from
the PROCEDURE statement.
Return from a procedure is implicit after the last statement of the
procedure, although no value is returned in this case. Return may be
explicitly specified with the RETURN statement:
No value: RETURN ;
Value: RETURN expression ;
Procedures may be declared with the special type INTERRUPT followed
by a number in the range 0 through 7. Such a procedure will be used
as an interrupt handler for the corresponding RST instruction.
Interrupts are re-enabled on return from an interrupt procedure.
Procedures may not be recursive. Procedures are invoked either with
the CALL statement, or within an expression.
Stand-alone: CALL identifier (arg, ...);
Within expressions: identifier (arg, ...)
Built-in Procedures
===================
INPUT(number)
Returns a BYTE value from the I/O port specified by 'number'.
OUTPUT(number) = expression;
Sends the BYTE value of 'expression' to the I/O port specified
by 'number'.
LENGTH(identifier)
Returns the number of elements in the array 'identifier'.
LAST(identifier)
Returns the highest subscript for array 'identifier'. Note that
LAST = LENGTH - 1.
LOW(expression)
Returns the low-order byte of 'expression'.
HIGH(expression)
Returns the high-order byte of 'expression'.
DOUBLE(expression)
Returns an ADDRESS value equivalent to 'expression'. High-order
zeroes are used to pad BYTE expressions.
ROL(expr1, expr2) and ROR(expr1, expr2)
Returns the value of 'expr1' rotated left/right the number of bits
specified by 'expr2'. Both expressions must be BYTE values. The
value of 'expr2' must not be zero.
SCL(expr1, expr2) and SCR(expr1, expr2)
Returns the value of 'expr1' rotated left/right the number of bits
specified by 'expr2'. The carry flag participates in the rotate.
'expr2' must be a BYTE value; 'expr1' may be BYTE or ADDRESS. The
value returned is of the same type as 'expr1'. The value of
'expr2' must not be zero.
SHL(expr1, expr2) and SHR(expr1, expr2)
Returns the value of 'expr1' shifted left/right the number of bits
specified by 'expr2'. The last bit shifted out ends up in the
carry flag. 'expr2' must be a BYTE value; 'expr1' may be BYTE or
ADDRESS. The value returned is of the same type as 'expr1'. The
value of 'expr2' must not be zero.
CALL TIME(expression)
The expression is evaluated as a BYTE value. The TIME procedure
delays 100 microseconds times the value. (Timing is based on
instruction execution times for the standard i8080 cpu.)
DEC(expr1 + expr2) and DEC(expr1 PLUS expr2)
The two expressions must be unsubscripted variables, constants,
or expressions that represent BCD values. The DEC function does
the necessary decimal adjustment to produce the BCD result from
the addition.
Pre-defined Variables
=====================
CARRY, ZERO, SIGN, PARITY
The values of these variables reflect the current values of the
cpu flags.
MEMORY
The MEMORY variable is assigned the to the first memory location
following the PL/M program. It is useful for determining where
free memory begins.
STACKPTR
The STACKPTR variable's value reflects the current value of the
SP register. The variable may be assigned a new value to alter
the stack register.


View File

@@ -0,0 +1,67 @@
5 MEMORY 00300H
25 SQUAREROOT 00016H
26 X 002DAH
28 Y 002DCH
29 Z 002DEH
33 PRINTCHAR 000A7H
34 CHAR 002E1H
37 PRINTSTRING 000AFH
38 NAME 002E2H
39 LENGTH 002E4H
41 I 002E5H
46 PRINTNUMBER 000D9H
47 NUMBER 002E6H
48 BASE 002E9H
49 CHARS 002EAH
50 ZEROSUPPRESS 002EBH
52 I 002ECH
53 J 002EDH
54 TEMP 002EEH
64 I 002FEH
66 HEADING 00182H
$
****************************************
:1000100031DA02C3F50121DA027123702D4E2C462C
:100020002C7123702ADA0223EB7AB71F577B1F212A
:10003000DE0277237221DC027E2C462C962C4F7830
:100040009EB1CAA1002D4E2C462EDC71237021DCFE
:10005000025E2C562EDA4E2C46C389007A2F577B2F
:100060002F5F132100003E11E519D26E00E3E1F588
:1000700079174F7817477D176F7C1767F13DC26876
:1000800000B77C1F577D1F5FC9CD5C002ADC0209C9
:1000900023EB7AB71F577B1F21DE02772372C3350C
:1000A000002EDC7E2C46C921E10271C30938C9212A
:1000B000E2027123702C732C360021E4024E0D797C
:1000C0002C96DAD8004E06002AE202097E4FCDA710
:1000D0000021E50234C2BA00C921EA02712C733E44
:1000E0000F2D96D2E800360F2EEC360121EA027E63
:1000F0002EEC96DA680121E9025E16002EE64E2CFF
:1001000046CD5C00013000EB09EB21ED02733E3976
:1001100096D218017EC607772D4E0D3EFFC22101F3
:10012000AF2DA62EE64F7E2C56D6005F7ADE00B3AA
:10013000D6019FA10FD23C012EED36203E102EECB1
:10014000964F06002EEE09EB21ED024E791221E9C1
:10015000025E16002EE64E2C46CD5C0021E60271B2
:1001600023702EEC34C2EC0001EE02111000696025
:1001700019EB7B21EA02965F7ADE004B475ECDAF3A
:1001800000C90D0A0A0A202020202020202020203B
:10019000202020202020202020202020202054410A
:1001A000424C45204F462053515541524520524F15
:1001B0004F54530D0A0A2056414C55452020524FAA
:1001C0004F542056414C55452020524F4F542056F5
:1001D000414C55452020524F4F542056414C5545D7
:1001E0002020524F4F542056414C55452020524F0D
:1001F0004F540D0A0A21FE0236012336003EE8065E
:100200000321FE02962C4F789EDA90021E051600FE
:1002100021FE024E2C46CD5C007BD6015F7ADE00CB
:10022000B3C251021EFA160021FE024E2C46CD5CCE
:10023000007BD6015F7ADE00B3C249020182011E53
:1002400073CDAF00C351020D0A0147021E02CDAFAC
:100250000021FE024E2C462EE67123702EE9360A4E
:100260000E061E01CDD9002EFE4E2C46CD160021C5
:10027000E602772336002EE9360A0E061E01CDD996
:10028000002EFE4E2C462101000922FE02C3FD0174
:02029000FB76FB
:0000000000
****************************************
$

View File

@@ -0,0 +1,70 @@
/*
SAMPLE PL/M PROGRAM
THIS PROGRAM CALCULATES AND PRINTS OUT THE SQUARE ROOTS OF
ALL INTEGERS BETWEEN 1 AND 1000.
*/
DECLARE CR LITERALLY '0DH', LF LITERALLY '0AH', TRUE LITERALLY '1',
FALSE LITERALLY '0';
10H: /* IS THE ORIGIN OF THIS PROGRAM */
SQUARE$ROOT: PROCEDURE(X) BYTE;
DECLARE (X,Y,Z) ADDRESS;
Y=X; Z=SHR(X+1,1);
DO WHILE Y<>Z;
Y=Z; Z=SHR(X/Y + Y + 1, 1);
END;
RETURN Y;
END SQUAREROOT;
/* PRINT USING INTELLEC MONITOR */
PRINT$CHAR: PROCEDURE (CHAR);
DECLARE CHAR BYTE;
DECLARE IOCO LITERALLY '3809H';
GO TO IOCO;
END PRINT$CHAR;
PRINT$STRING: PROCEDURE(NAME,LENGTH);
DECLARE NAME ADDRESS,
(LENGTH,I,CHAR BASED NAME) BYTE;
DO I = 0 TO LENGTH-1;
CALL PRINT$CHAR(CHAR(I));
END;
END PRINT$STRING;
PRINT$NUMBER: PROCEDURE(NUMBER,BASE,CHARS,ZERO$SUPPRESS);
DECLARE NUMBER ADDRESS, (BASE,CHARS,ZERO$SUPPRESS,I,J) BYTE;
DECLARE TEMP(16) BYTE;
IF CHARS > LAST(TEMP) THEN CHARS = LAST(TEMP);
DO I = 1 TO CHARS;
J=NUMBER MOD BASE + '0';
IF J > '9' THEN J = J + 7;
IF ZERO$SUPPRESS AND I <> 1 AND NUMBER = 0 THEN
J = ' ';
TEMP(LENGTH(TEMP)-I) = J;
NUMBER = NUMBER / BASE;
END;
CALL PRINT$STRING(.TEMP + LENGTH(TEMP) - CHARS,CHARS);
END PRINT$NUMBER;
DECLARE I ADDRESS,
CRLF LITERALLY 'CR,LF',
HEADING DATA (CRLF,LF,LF,
' TABLE OF SQUARE ROOTS', CRLF,LF,
' VALUE ROOT VALUE ROOT VALUE ROOT VALUE ROOT VALUE ROOT',
CRLF,LF);
/* SILENCE TTY AND PRINT COMPUTED VALUES */
DO I = 1 TO 1000;
IF I MOD 5 = 1 THEN
DO; IF I MOD 250 = 1 THEN
CALL PRINT$STRING(.HEADING,LENGTH(HEADING));
ELSE
CALL PRINT$STRING(.(CR,LF),2);
END;
CALL PRINT$NUMBER(I,10,6,TRUE /* TRUE SUPPRESSES LEADING ZEROES */);
CALL PRINT$NUMBER(SQUARE$ROOT(I), 10,6, TRUE);
END;
EOF

View File

@@ -0,0 +1,147 @@
8080 PLM1 VERS 2.0
00001 1 /*
00002 1 SAMPLE PL/M PROGRAM
00003 1
00004 1 THIS PROGRAM CALCULATES AND PRINTS OUT THE SQUARE ROOTS OF
00005 1 ALL INTEGERS BETWEEN 1 AND 1000.
00006 1 */
00007 1 DECLARE CR LITERALLY '0DH', LF LITERALLY '0AH', TRUE LITERALLY '1',
00008 1 FALSE LITERALLY '0';
00009 1
00010 1 10H: /* IS THE ORIGIN OF THIS PROGRAM */
00011 1
00012 1 SQUARE$ROOT: PROCEDURE(X) BYTE;
00013 2 DECLARE (X,Y,Z) ADDRESS;
00014 2 Y=X; Z=SHR(X+1,1);
00015 2 DO WHILE Y<>Z;
00016 2 Y=Z; Z=SHR(X/Y + Y + 1, 1);
00017 3 END;
00018 2 RETURN Y;
00019 2 END SQUAREROOT;
00020 1
00021 1 /* PRINT USING INTELLEC MONITOR */
00022 1 PRINT$CHAR: PROCEDURE (CHAR);
00023 2 DECLARE CHAR BYTE;
00024 2 DECLARE IOCO LITERALLY '3809H';
00025 2 GO TO IOCO;
00026 2 END PRINT$CHAR;
00027 1
00028 1 PRINT$STRING: PROCEDURE(NAME,LENGTH);
00029 2 DECLARE NAME ADDRESS,
00030 2 (LENGTH,I,CHAR BASED NAME) BYTE;
00031 2 DO I = 0 TO LENGTH-1;
00032 2 CALL PRINT$CHAR(CHAR(I));
00033 3 END;
00034 2 END PRINT$STRING;
00035 1
00036 1 PRINT$NUMBER: PROCEDURE(NUMBER,BASE,CHARS,ZERO$SUPPRESS);
00037 2 DECLARE NUMBER ADDRESS, (BASE,CHARS,ZERO$SUPPRESS,I,J) BYTE;
00038 2 DECLARE TEMP(16) BYTE;
00039 2 IF CHARS > LAST(TEMP) THEN CHARS = LAST(TEMP);
00040 2 DO I = 1 TO CHARS;
00041 2 J=NUMBER MOD BASE + '0';
00042 3 IF J > '9' THEN J = J + 7;
00043 3 IF ZERO$SUPPRESS AND I <> 1 AND NUMBER = 0 THEN
00044 3 J = ' ';
00045 3 TEMP(LENGTH(TEMP)-I) = J;
00046 3 NUMBER = NUMBER / BASE;
00047 3 END;
00048 2 CALL PRINT$STRING(.TEMP + LENGTH(TEMP) - CHARS,CHARS);
00049 2 END PRINT$NUMBER;
00050 1
00051 1 DECLARE I ADDRESS,
00052 1 CRLF LITERALLY 'CR,LF',
00053 1 HEADING DATA (CRLF,LF,LF,
00054 1 ' TABLE OF SQUARE ROOTS', CRLF,LF,
00055 1 ' VALUE ROOT VALUE ROOT VALUE ROOT VALUE ROOT VALUE ROOT',
00056 1 CRLF,LF);
00057 1
00058 1 /* SILENCE TTY AND PRINT COMPUTED VALUES */
00059 1 DO I = 1 TO 1000;
00060 1 IF I MOD 5 = 1 THEN
00061 2 DO; IF I MOD 250 = 1 THEN
00062 3 CALL PRINT$STRING(.HEADING,LENGTH(HEADING));
00063 3 ELSE
00064 3 CALL PRINT$STRING(.(CR,LF),2);
00065 3 END;
00066 2 CALL PRINT$NUMBER(I,10,6,TRUE /* TRUE SUPPRESSES LEADING ZEROES */);
00067 2 CALL PRINT$NUMBER(SQUARE$ROOT(I), 10,6, TRUE);
00068 2 END;
00069 1
00070 1 EOF
NO PROGRAM ERRORS
8080 PLM2 VERS 2.0
1=0003H 12=0013H 13=0016H 14=001CH 15=002FH 16=0045H 17=0098H 18=00A1H 19=00A7H 23=00ABH
25=00AEH 26=00AFH 29=00B7H 31=00BAH 32=00C5H 33=00D1H 34=00D8H 35=00D9H 37=00DFH 39=00E3H
40=00E6H 41=00F6H 42=010AH 43=0117H 44=0134H 45=0138H 46=0148H 47=015CH 48=0168H 49=0181H
50=0182H 56=01F5H 59=01FDH 60=020CH 61=0221H 62=0239H 63=0244H 64=0247H 65=0251H 66=025CH
67=0267H 68=0281H 69=0290H
STACK SIZE = 6 BYTES
MEMORY..........................0300H
SQUAREROOT......................0016H
X...............................02DAH
Y...............................02DCH
Z...............................02DEH
PRINTCHAR.......................00A7H
CHAR............................02E1H
PRINTSTRING.....................00AFH
NAME............................02E2H
LENGTH..........................02E4H
I...............................02E5H
PRINTNUMBER.....................00D9H
NUMBER..........................02E6H
BASE............................02E9H
CHARS...........................02EAH
ZEROSUPPRESS....................02EBH
I...............................02ECH
J...............................02EDH
TEMP............................02EEH
I...............................02FEH
HEADING.........................0182H
0010H LXI SP DAH 02H JMP F5H 01H LXI H DAH 02H MOV MC INX H MOV MB DCR L MOV CM INR L MOV BM
0020H INR L MOV MC INX H MOV MB LHLD DAH 02H INX H XCHG MOV AD ORA A RAR MOV DA MOV AE RAR LXI H
0030H DEH 02H MOV MA INX H MOV MD LXI H DCH 02H MOV AM INR L MOV BM INR L SUB M INR L MOV CA MOV AB
0040H SBC M ORA C JZ A1H 00H DCR L MOV CM INR L MOV BM MOV LI DCH MOV MC INX H MOV MB LXI H DCH
0050H 02H MOV EM INR L MOV DM MOV LI DAH MOV CM INR L MOV BM JMP 89H 00H MOV AD CMA MOV DA MOV AE
0060H CMA MOV EA INX D LXI H 00H 00H MOV AI 11H PUSH H DAD D JNC 6EH 00H XTHL POP H PUSH A
0070H MOV AC RAL MOV CA MOV AB RAL MOV BA MOV AL RAL MOV LA MOV AH RAL MOV HA POP A DCR A JNZ 68H
0080H 00H ORA A MOV AH RAR MOV DA MOV AL RAR MOV EA RET CALL 5CH 00H LHLD DCH 02H DAD B
0090H INX H XCHG MOV AD ORA A RAR MOV DA MOV AE RAR LXI H DEH 02H MOV MA INX H MOV MD JMP 35H
00A0H 00H MOV LI DCH MOV AM INR L MOV BM RET LXI H E1H 02H MOV MC JMP 09H 38H RET LXI H
00B0H E2H 02H MOV MC INX H MOV MB INR L MOV ME INR L MOV MI 00H LXI H E4H 02H MOV CM DCR C MOV AC
00C0H INR L SUB M JC D8H 00H MOV CM MOV BI 00H LHLD E2H 02H DAD B MOV AM MOV CA CALL A7H
00D0H 00H LXI H E5H 02H INR M JNZ BAH 00H RET LXI H EAH 02H MOV MC INR L MOV ME MOV AI
00E0H 0FH DCR L SUB M JNC E8H 00H MOV MI 0FH MOV LI ECH MOV MI 01H LXI H EAH 02H MOV AM
00F0H MOV LI ECH SUB M JC 68H 01H LXI H E9H 02H MOV EM MOV DI 00H MOV LI E6H MOV CM INR L
0100H MOV BM CALL 5CH 00H LXI B 30H 00H XCHG DAD B XCHG LXI H EDH 02H MOV ME MOV AI 39H
0110H SUB M JNC 18H 01H MOV AM ADD I 07H MOV MA DCR L MOV CM DCR C MOV AI FFH JNZ 21H 01H
0120H XRA A DCR L ANA M MOV LI E6H MOV CA MOV AM INR L MOV DM SUB I 00H MOV EA MOV AD SBC I 00H ORA E
0130H SUB I 01H SBC A ANA C RRC JNC 3CH 01H MOV LI EDH MOV MI 20H MOV AI 10H MOV LI ECH
0140H SUB M MOV CA MOV BI 00H MOV LI EEH DAD B XCHG LXI H EDH 02H MOV CM MOV AC STAX D LXI H E9H
0150H 02H MOV EM MOV DI 00H MOV LI E6H MOV CM INR L MOV BM CALL 5CH 00H LXI H E6H 02H MOV MC
0160H INX H MOV MB MOV LI ECH INR M JNZ ECH 00H LXI B EEH 02H LXI D 10H 00H MOV LC MOV HB
0170H DAD D XCHG MOV AE LXI H EAH 02H SUB M MOV EA MOV AD SBC I 00H MOV CE MOV BA MOV EM CALL AFH
0180H 00H RET
0182H 0DH 0AH 0AH 0AH 20H 20H 20H 20H 20H 20H 20H 20H 20H 20H 20H 20H 20H 20H 20H 20H 20H 20H 20H 20H 20H 20H 20H 20H
019EH 54H 41H 42H 4CH 45H 20H 4FH 46H 20H 53H 51H 55H 41H 52H 45H 20H 52H 4FH 4FH 54H 53H 0DH 0AH 0AH 20H 56H 41H 4CH
01BAH 55H 45H 20H 20H 52H 4FH 4FH 54H 20H 56H 41H 4CH 55H 45H 20H 20H 52H 4FH 4FH 54H 20H 56H 41H 4CH 55H 45H 20H 20H
01D6H 52H 4FH 4FH 54H 20H 56H 41H 4CH 55H 45H 20H 20H 52H 4FH 4FH 54H 20H 56H 41H 4CH 55H 45H 20H 20H 52H 4FH 4FH 54H
01F2H 0DH 0AH 0AH
01F5H LXI H FEH 02H MOV MI 01H INX H MOV MI 00H MOV AI E8H MOV BI 03H LXI H FEH 02H SUB M
0205H INR L MOV CA MOV AB SBC M JC 90H 02H MOV EI 05H MOV DI 00H LXI H FEH 02H MOV CM INR L
0215H MOV BM CALL 5CH 00H MOV AE SUB I 01H MOV EA MOV AD SBC I 00H ORA E JNZ 51H 02H MOV EI
0225H FAH MOV DI 00H LXI H FEH 02H MOV CM INR L MOV BM CALL 5CH 00H MOV AE SUB I 01H MOV EA
0235H MOV AD SBC I 00H ORA E JNZ 49H 02H LXI B 82H 01H MOV EI 73H CALL AFH 00H JMP
0245H 51H 02H
0247H 0DH 0AH
0249H LXI B 47H 02H MOV EI 02H CALL AFH 00H LXI H FEH 02H MOV CM INR L MOV BM MOV LI E6H
0259H MOV MC INX H MOV MB MOV LI E9H MOV MI 0AH MOV CI 06H MOV EI 01H CALL D9H 00H MOV LI FEH
0269H MOV CM INR L MOV BM CALL 16H 00H LXI H E6H 02H MOV MA INX H MOV MI 00H MOV LI E9H MOV MI
0279H 0AH MOV CI 06H MOV EI 01H CALL D9H 00H MOV LI FEH MOV CM INR L MOV BM LXI H 01H 00H
0289H DAD B SHLD FEH 02H JMP FDH 01H EI HLT
NO PROGRAM ERRORS

View File

@@ -0,0 +1,63 @@
\README.PLM = Original
Here is the source to the Intel PLM compiler. It is written in Fortran (66), and is supposed to be pretty clean.
It compiles correctly with gcc's g77 on Linux. However, it is not the version required to compile CP/M 2.2 or 3.0. It works well, but lacks support for external definitions and some PLM constructs, as required by the DR source.
--
This archive contains the FORTRAN IV source code for the PL/M-80
cross compiler. It bears the Intel's copyright, but at some time
in the late 1970's the code was made available by Intel. The
history of all of this, and the conditions behind it, have become
a bit merky over the years; however, to the best of my knowledge,
you are free to use it for personal and educational applications.
The copy provided in this package was extracted from the standard
distribution tapes for the Michigan Terminal System, an operating
system for IBM mainframe hardware used by about six universities
around the world.
The compiler has been successfully installed on an IBM mainframe
running both the MTS operating system and the more common VM/CMS.
The source code has been compiled by the FORTRAN-G1, FORTRAN-HX,
and VS/FORTRAN compilers. It should be compilable by any other
FORTRAN compilers that accept the 1966 (FORTRAN IV) standard
since the code seems to confirm rather well to that standard.
Getting a working version on an 8080 or Z80 micro computer may
be a problem, though, but only because of the size of the two
modules. I have not tried this, but I suspect MicroSoft's
FORTRAN product for MSDOS systems should be able to handle it.
Alas, machine-readable documentation for the langauge and for
installing the compiler is not available. I have tried to give
a capsule summary of the langauge in PLMLANG.DOC, but it in no
way constitutes a complete description. PLMCOMP.DOC describes
the compiler options.
The following files are provided.
-README PLM You are reading it now.
PLM81 FOR Source for Pass 1 of the compiler.
PLM82 FOR Source for Pass 2 of the compiler.
PLMLANG DOC Summary of the PL/M language.
PLMCOMP DOC Description of compiler switches.
PLMSAMP PLM Sample PL/M program.
PLMSAMP HEX Compiler output for the sample.
PLMSAMP PRN Compiler listing for the sample.
The package is made available under the "Care-Ware" philosophy.
This is really quite simple: If you are just so pleased to
finally have something like this in you possession that you
feel duty-bound to send a check for some amount to somewhere,
may I suggest you send it to:
CARE
Post Office Box 13140
Philadelphia, Pennsylvania 19101-9903
(Who knows, maybe this will catch on :-) Contributions to CARE
should be made in your name, not mine.
John Fisher
INTERNET: FISHER@VM.ECS.RPI.EDU
BITNET: FISHER@RPIECS


View File

@@ -0,0 +1,56 @@
This archive contains the FORTRAN IV source code for the PL/M-80
cross compiler. It bears the Intel's copyright, but at some time
in the late 1970's the code was made available by Intel. The
history of all of this, and the conditions behind it, have become
a bit merky over the years; however, to the best of my knowledge,
you are free to use it for personal and educational applications.
The copy provided in this package was extracted from the standard
distribution tapes for the Michigan Terminal System, an operating
system for IBM mainframe hardware used by about six universities
around the world.
The compiler has been successfully installed on an IBM mainframe
running both the MTS operating system and the more common VM/CMS.
The source code has been compiled by the FORTRAN-G1, FORTRAN-HX,
and VS/FORTRAN compilers. It should be compilable by any other
FORTRAN compilers that accept the 1966 (FORTRAN IV) standard
since the code seems to confirm rather well to that standard.
Getting a working version on an 8080 or Z80 micro computer may
be a problem, though, but only because of the size of the two
modules. I have not tried this, but I suspect MicroSoft's
FORTRAN product for MSDOS systems should be able to handle it.
Alas, machine-readable documentation for the langauge and for
installing the compiler is not available. I have tried to give
a capsule summary of the langauge in PLMLANG.DOC, but it in no
way constitutes a complete description. PLMCOMP.DOC describes
the compiler options.
The following files are provided.
-README PLM You are reading it now.
PLM81 FOR Source for Pass 1 of the compiler.
PLM82 FOR Source for Pass 2 of the compiler.
PLMLANG DOC Summary of the PL/M language.
PLMCOMP DOC Description of compiler switches.
PLMSAMP PLM Sample PL/M program.
PLMSAMP HEX Compiler output for the sample.
PLMSAMP PRN Compiler listing for the sample.
The package is made available under the "Care-Ware" philosophy.
This is really quite simple: If you are just so pleased to
finally have something like this in you possession that you
feel duty-bound to send a check for some amount to somewhere,
may I suggest you send it to:
CARE
Post Office Box 13140
Philadelphia, Pennsylvania 19101-9903
(Who knows, maybe this will catch on :-) Contributions to CARE
should be made in your name, not mine.
John Fisher
INTERNET: FISHER@VM.ECS.RPI.EDU
BITNET: FISHER@RPIECS