Version I.5, September 1978
The UCSD Pascal P-machine, designed specifically for the execution of Pascal programs on small machines, is an extensively modified descendant of the P-2 pseudo-machine from Zurich. It supports variable addressing, including strings, byte arrays, packed fields, and dynamic variables; logical, integer, real, and set top-of- stack arithmetic and comparisons; multi-element structure comparisons; several types of branches; procedure/function calls and returns, including overlayable procedures; miscellaneous procedures used by systems programs; and basic I/O subsystem.
This Section, to be used in conjunction with Section 3.5, describes the P-machine "hardware," communication with the operating system, exceptional condition handling, the instruction set, the I/O system, and the boot-loading process.
SP | Stack Pointer is a pointer to the top of the execution stack. The stack starts in high memory and grows toward low memory. It contains code segments and activation records, and is used to pass parameters, return function values, and as an operand source for many instructions. The stack is extended by loads and procedure calls, and is cut back by stores, procedure returns, and arithmetic operations. |
NP | New Pointer is a pointer to the top of the dynamic heap. The heap starts in low memory and grows upward toward the stack. It contains all dynamic variables (see Jensen and Wirth, Chapter 10). It is extended by the standard procedure 'new', and is cut back by the standard procedure 'release'. |
JTAB | Jump TABle pointer is a pointer to the procedure attribute table of the currently executing procedure. (See Section 3.5, figure 5.) |
SEG | Segment Pointer points to the procedure dictionary of the segment to which the currently executing procedure belongs. (See Section 3.5, figure 6.) |
MP | Most recent Procedure is a pointer to the activation record of the currently executing procedure (see Section 3.5, figure 7). Variables local to the current procedure are accessed by indexing off MP. |
BASE | BASE Procedure is a pointer to the activation record of the most recently invoked base procedure (lex level 0). Global (lex level 0) variables are accessed by indexing off BASE. |
PDP11:
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Word 1: | low mantissa | |||||||||||||||
Word 0: | s | exponent | high mantissa |
Z80/8080:
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Word 1: | low mantissa | middle mantissa | ||||||||||||||
Word 0: | s | high mantissa | exponent |
Both representations have an excess-128 exponent, a fractional mantissa that is always normalized, exponent base 2, an implicit 24th mantissa bit, and zero represented by a zero exponent. (See PDP11 processor manual or Z80/8080 interpreter listing for greater detail.)
word 2: | word pointer to word field is in. | |
word 1: | field-width (in bits). | |
word 0: | right-bit-number of field. |
When a set is on the stack, it is represented by a word containing the length, and then that number of words, all of which contain valid information. All elements past the last word of a set are assumed not to be elements of the set. Before being stored back in the data segment, a set must be forced back to the size allocated to it, and so an ADJ instruction must be issued.
Any exceptions to these formats are noted in the instructions where they occur.
Abbreviations are used widely, but use fairly simple conventions. Parameters are written as X or Xn, where X is UB, SB, DB, B or W, and n is an integer indicating the parameter position in the instruction. Tos means the operand on the top of stack, tos-1 the next operand, etc. Mark Stack Control Word is abbreviated to MSCW.
Many instructions refer to the activation record of a procedure, and this document assumes the reader has a general knowledge of procedure calling in stack machines, and the concept of stack frames. An activation record as defined in this document specifically consists of:
The dynamic chain refers to the calling chain, traversed using the MSCW.MSDYN links. The static chain refers to the lexical or ancestor chain, traversed using the MSCW.MSSTAT links.
5.A. Variable Fetching, Indexing, Storing, and Transferring | |||
5.A.1. One Word Loads and Stores | |||
5.A.1.a. Constant One Word Loads | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
---|---|---|---|
SLDC | 0..127 | Short load word constant. Pushes the opcode, with high byte zero, onto stack. | |
LDCN | 159 | Load constant nil. Pushes the implementation-dependent value of nil. | |
LDCI | 199 | W | Load constant word. Pushes W. |
5.A.1.b Local One Word Loads and Store | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
SLDL1 ... SLDL16 | 216 ... 231 | Short load local word. SLDLx fetches the word with offset x in MP activation record and pushes it. | |
LDL | 202 | Big | Load local word. Fetches the word with offset B in MP activation record and pushes it. |
LLA | 198 | Big | Load local address. Fetches address of the word with offset B in MP activation record and pushes it. |
STL | 204 | Big | Store local word. Stores tos into word with offset B in MP activation record. |
5.A.1.c. Global One Word Loads and Store | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
SLDO1 ... SLDO16 | 232 ... 247 | Short load global word. SLDOx fetches the word with offset x in BASE activation record and pushes it. | |
LDO | 167 | Big | Load global word. Fetches the word with offset B in BASE activation record and pushes it. |
LAO | 165 | Big | Load global address. Pushes the word address of the word with offset B in BASE activation record. |
SRO | 171 | Big | Store global word. Stores tos into the word with offset B in BASE activation record. |
5.A.1.d. Intermediate One-Word Loads and Store | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
LOD | 182 | DB, Big | Load intermediate word. DB indicates the number of static links to traverse to find the activation record to use. B is the offset within the activation record. |
LDA | 178 | DB, Big | Load intermediate address. |
STR | 184 | DB, Big | Store intermediate word. |
5.A.1.e. Indirect One-Word Loads and Store | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
STO | 154 | Store indirect. Tos is stored into the word pointed to by tos-1. | |
SIND0 | 248 | Load indirect. | |
5.A.2. Multiple Word Loads and Stores (Sets and Reals) | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
LDC | 179 | UB, block | Load multiple word constant. UB is the number of words to load, and <block> is a word aligned block of UB words in reverse word order. Load the block onto the stack. |
LDM | 188 | UB | Load multiple words. Tos is a pointer to the beginning of a block of UB words. Push the block onto the stack. |
STM | 189 | UB | Store multiple words. Tos is a block of UB words, tos-1 is a word pointer to a similar block. Transfer the block from the stack to the destination block. |
5.A.3. Byte Arrays | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
BYT | 210 | Byte conversion. Convert word pointer tos to a byte pointer. (NOP in the PDP11 and Z80/8080 implementations.) | |
LDB | 190 | Load byte. Push the byte (after zeroing high byte) pointed to by byte pointer tos. | |
STB | 191 | Store byte. Store byte tos into the location specified by byte pointer tos-1. | |
MVB | 169 | Big | Move bytes. Tos is a byte source pointer to a block of B bytes, tos-1 is byte destination pointer to a similar block. Transfer the source block to the destination block (This instruction is redundant due to word alignment, and will be replaced by MOV in the future.) |
IXB | 209 | Index byte array. Push a byte pointer formed from the integer index tos and the byte pointer tos-1. | |
5.A.4. Strings | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
LCA | 166 | UB, chars | Load constant string address. Push a byte pointer to the location UB is contained in, and skip IPC past <chars>. |
SAS | 170 | UB | String assign. Tos is either a source byte pointer or a character. (Characters always have a high byte of zero, while pointers never do.) Tos-1 is a destination byte pointer. UB is the declared size of the destination string. If the declared size is less than the current size of the source string, a run-time error occurs; otherwise all bytes of source containing valid information are transferred to the destination string. |
S1P | 208 | String to packed conversion on tos. Tos is a byte pointer to a string, and is incremented by one byte in order to point to the first character of the string. | |
S2P | 157 | String to packed conversion on tos-1. Tos and tos-1 are byte pointers, and tos-1 is incremented by one byte. | |
IXS | 155 | Index string array. Performs the same operation as IXB, except before indexing the index is checked to see if it is in the range 1..current length. If not, a run-time error occurs. | |
5.A.5. Record and Array Indexing and Assignment | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
MOV | 168 | Big | Move words. Tos is a source pointer to a block of B words, tos-1 is a destination pointer to a similar block. Transfer the block from the source to the destination. |
SIND0 ... SIND7 | 248 ... 255 | Short index and load word. SINDx indexes the word pointer tos by x words, and pushes the word pointed to by the result. | |
IND | 163 | Big | Static index and load word. Indexes the word pointer tos by B words, and pushes the word pointed to. |
INC | 162 | Big | Increment field pointer. The word pointer tos is indexed by B words and the resultant pointer is pushed. |
IXA | 164 | Big | Index array. Tos is an integer index, tos-1 is the array base word pointer, and B is the size (in words) of an array element. A word pointer to the indexed element is pushed. |
IXP | 192 | UB1, UB2 | Index packed array. Tos is an integer index, tos-1 is the array base word pointer. UB_1 is the number of elements per word, and UB_2 is the field width (in bits). Compute and push a packed field pointer. |
LDP | 186 | Load a packed field. Push the element described by the packed field pointer tos. | |
STP | 187 | Store into a packed field. Tos is the data, tos-1 is a packed field pointer. Store tos into the field described by tos-1. | |
5.A.6. Dynamic Variable Allocation and De-allocation | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
NEW | 158 1 | New variable allocation. Tos is the size (in words) to allocate the variable, and tos-2 is a word pointer to a dynamic variable. If GDIRP is non-nil, cut NP back to GDIRP and set GDIRP to nil. Store NP into word pointed to by tos-1, and increment NP by tos words. | |
MRK | 158 31 | Mark heap. Release GDIRP and set to nil if necessary, then store NP into word pointed to by tos. | |
RLS | 158 32 | Release heap. Set GDIRP to nil, then store word pointed to by tos into NP. | |
5.B. Top of Stack Arithmetic and Comparisons | |||
5.B.1. Logical | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
LAND | 132 | Logical and. And tos into tos-1. | |
LOR | 141 | Logical or. Or tos into tos-1. | |
LNOT | 147 | Logical not. Take one's compliment of tos | |
EQUBOOL | 175 6 | Boolean = comparison. Compare bit_0 of tos-1 to bit_0 of tos and push true or false. | |
NEQBOOL | 183 6 | Boolean <> comparison. Compare bit_0 of tos-1 to bit_0 of tos and push true or false. | |
LEQBOOL | 180 6 | Boolean <= comparison. Compare bit_0 of tos-1 to bit_0 of tos and push true or false. | |
LESBOOL | 181 6 | Boolean < comparison. Compare bit_0 of tos-1 to bit_0 of tos and push true or false. | |
GEQBOOL | 176 6 | Boolean >= comparison. Compare bit_0 of tos-1 to bit_0 of tos and push true or false. | |
GTRBOOL | 177 6 | Boolean > comparison. Compare bit_0 of tos-1 to bit_0 of tos and push true or false. | |
5.B.2. Integer | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
ABI | 128 | Absolute value of integer. Take absolute value of integer tos. Result is undefined if tos is initially -32768. | |
ADI | 130 | Add integers. Add tos and tos-1. | |
NGI | 145 | Negate integer. Take the two's compliment of tos. | |
SBI | 149 | Subtract integers. Subtract tos from tos-1. | |
MPI | 143 | Multiply integers. Multiply tos and tos-1. This instruction may cause overflow if result is larger than 16 bits. | |
SQI | 152 | Square integer. Square tos. May cause overflow. | |
DVI | 134 | Divide integers. Divide tos-1 by tos and push quotient. (PDP11 quotient defined as in Jensen and Wirth; Z80/8080 quotient defined by floor(tos-1/tos).) | |
MODI | 142 | Modulo integers. Divide tos-1 by tos and push the remainder (as defined in Jensen and Wirth). | |
CHK | 136 | Check against subrange bounds. Insure that tos-1 <= tos-2 <= tos, leaving tos-2 on the stack. If conditions are not satisfied a run-time error occurs. | |
EQUI | 195 | Integer = comparison. Compare tos-1 to tos and push true or false. | |
NEQI | 203 | Integer <> comparison. Compare tos-1 to tos and push true or false. | |
LEQI | 200 | Integer <= comparison. Compare tos-1 to tos and push true or false. | |
LESI | 201 | Integer < comparison. Compare tos-1 to tos and push true or false. | |
GEQI | 196 | Integer >= comparison. Compare tos-1 to tos and push true or false. | |
GTRI | 197 | Integer > comparisons. Compare tos-1 to tos and push true or false. | |
5.B.3. RealsAll over/underflows cause a run-time error. | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
FLT | 138 | Float top-of-stack. The integer tos is converted to a floating point number. | |
FLU | 137 | Float next to top-of-stack. Tos is a real, tos-1 is an integer. Convert tos-1 to a real number. | |
TNC | 158 22 | Truncate real. The real tos is truncated (as defined in Jensen and Wirth) and converted to an integer. | |
RND | 158 23 | Round real. The real tos is rounded (as defined in Jensen aid Wirth), then truncated and converted to an integer. | |
ABR | 129 | Abs reals. Take the absolute value of the real tos. | |
ADR | 131 | Add reals. Add tos and tos-1. | |
NGR | 146 | Negate real. Negate the real tos. | |
SBR | 150 | Subtract reals. Subtract tos from tos-1. | |
MPR | 144 | Multiply reals. Multiply tos and tos-1. | |
SQR | 153 | Square real. | |
DVR | 135 | Divide reals. Divide tos-1 by tos. | |
POT | 158 35 | Power of ten. The integer tos is checked for 0 <= tos <= 38, a run-time error occurring if the conditions aren't satisfied. The implementation dependent value 10tos is pushed. This facility allows the rest of the system to be independent of floating point format. | |
SIN | 158 24 | Sine. Take the sine of the real tos. | |
COS | 158 25 | Cosine. Take the cosine of the real tos. | |
ATAN | 158 27 | Arctangent. Take the arctangent of the real tos. | |
EXP | 158 29 | Exponential. Calculate etos and push result. | |
LN | 158 28 | Natural logarithm. | |
LOG | 158 26 | Log base 10. | |
SQT | 158 30 | Square root. | |
EQUREAL | 175 2 | Real = comparison. Push true or false. | |
NEQREAL | 183 2 | Real <> comparison. Push true or false. | |
LEQREAL | 180 2 | Real <= comparison. Push true or false. | |
LESREAL | 181 2 | Real < comparison. Push true or false. | |
GEQREAL | 176 2 | Real >= comparison. Push true or false. | |
GTRREAL | 177 2 | Real > comparison. Push TRUE or FALSE. | |
5.B.4. Sets | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
ADJ | 160 | UB | Adjust set. The set tos is forced to occupy UB words, either by expansion (putting zeroes “between” tos and tos-1) or compression (chopping off high words of set), and its length word is discarded. |
SGS | 151 | Build a singleton set. The integer tos is checked to ensure that 0 <= tos <= 4079, a run-time error occurring if not. The set [tos] is pushed. | |
SRS | 148 | Build a subrange set. The integers tos and tos-1 are checked as in SGS, and the set [tos-1..tos] is pushed. (The set [] is pushed if tos-1 > tos.) | |
INN | 139 | Set membership. See if integer tos-1 is in set tos, pushing TRUE or FALSE. | |
UNI | 156 | Set union. The union of sets tos and tos-1 is pushed. (Tos or tos-1.) | |
INT | 140 | Set intersection. The intersection of sets tos and tos-1 is pushed. (Tos and tos-1.) | |
DIF | 133 | Set difference. The difference of sets tos-1 and tos is pushed. (tos-1 and not tos.) | |
EQUPOWR | 175 8 | Set = comparison. Push true or false. | |
NEQPOWR | 183 8 | Set <> comparison. Push true or false. | |
LEQPOWR | 180 8 | Set <= (subset of) comparison. Push true or false. | |
GEQPOWR | 176 8 | Set >= (superset of) comparison. Push true or false. | |
5.B.5. Strings | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
EQUSTR | 175 4 | String = comparison. Push true or false. | |
NEQSTR | 183 4 | String <> comparison. Push true or false. | |
LEQSTR | 180 4 | String <= comparison. Push true or false. | |
LESSTR | 181 4 | String < comparison. Push true or false. | |
GEQSTR | 176 4 | String >= comparison. Push true or false. | |
GTRSTR | 177 4 | String > comparison. The string pointed to by word pointer tos-1 is lexicographically compared to the string pointed at by tos. Push true or false. | |
5.B.6. Byte ArraysThe <=, <, >=, and > are only emitted for packed arrays of char. | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
EQUBYT | 175 10 | Byte array = comparison. Push true or false. | |
NEQBYT | 183 10 | Byte array <> comparison. Push true or false. | |
LEQBYT | 180 10 | Byte array <= comparison. Push true or false. | |
LESBYT | 181 10 | Byte array < comparison. Push true or false. | |
GEQBYT | 176 10 | Byte array >= comparison. Push true or false. | |
GTRBYT | 177 10 | Byte array > comparison. Push true or false. | |
5.B.7. Array and Record Comparisons | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
EQUWORD | 175 12 | Word or multi-word structure = comparison. Push true or false. | |
NEQWORD | 183 12 | Word or multi-word structure <> comparison. Push true or false. | |
5.C. JumpsSimple (non-case statement) jumps are all two bytes long. The first byte is the op-code, the second is a SB jump offset. If this offset is non-negative, it is simply added to IPC. (A value of zero for the jump offset will make any jump a two-byte nop.) If SB is negative, then SB div 2 is used as a word offset into JTAB, and IPC is set to the byte address(JTAB^[SB div 2]) - JTAB[SB div 2]. | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
UJP | 185 | SB | Unconditional jump. Jump as described above. |
FJP | 161 | SB | False jump. Jump if tos is false. |
EFJ | 211 | SB | Equal false jump. Jump if integer tos <> tos-1. Not implemented in I.4. |
NFJ | 212 | SB | Not equal false jump. Jump if integer tos = tos-1. Not implemented in I.4. |
XJP | 172 | W_1, W_2, W_3, <case table> |
Case jump. W_1 is word-aligned, and is
the minimum index of the table. W_2 is the
maximum index. W_3 is an unconditional
jump instruction past the table. The case
table is W_2-W_1+1 words long, and contains
self-relative locations.
If tos, the actual index, is not in the range W_1..W_2, then IPC is pointed at W3. Otherwise, tos-W1 is used as an index into the table, and IPC is set to byte address(casetable[index-min_index])- casetable[index-min_index]. |
5.D. Procedure and Function Calls and ReturnsThe general scheme used in procedure/function invocation is
| |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
CLP | 206 | UB | Call local procedure. Call procedure UB, which is an immediate child of the currently executing procedure and in the same segment. Static link of MSCW is set to old NP. |
CGP | 207 | UB | Call global procedure. Call procedure UB, which is at lex level 1 and in same segment. The static link of the MSCW is set to BASE. |
CIP | 174 | UB | Call intermediate procedure. Call procedure UB in same segment as the currently executing procedure. The static link of the MSCW is set by looking up the call chain until an activation record is found whose caller had a lex level one 1 less than the procedure being called. Use that activation record's static link as the static link of the new MSCW. |
CBP | 194 | UB | Call base procedure. Call procedure UB, which is at lex level -1 or 0. The static link of the MSCW is set to the static link in BASE's activation record. The BASE is saved, after which it is pointed at the activation record just created. |
CXP | 205 | DB_1, UB_2 |
Call external procedure. Used to call
any procedure not in the same segment as
the calling procedure, including procedures
at lex level -1 or 0. It works as follows:
|
CSP | 158 | UB | Call Standard Procedure. Scan this document for an opcode of 158. |
RNP | 173 | DB | Return from non-base procedure. DB is the number of words that should be returned as a function value (0 for procedures, 1 for non-real functions, and 2 for real functions). DB words are copied from the bottom of the data segment and "pushed" onto one caller's top-of-stack. The information in the MSCW is then used to restore the caller's correct environment. |
RBP | 193 | Return from base procedure. The saved base is moved into BASE, after which things proceed as in the RNP instruction. | |
EXIT | 158 4 |
Exit from procedure. Tos is the
procedure number, tos-1 is the segment
number. This operator sets IPC to point to
the exit code of the currently executing
procedure, then sees if the current
procedure is the one to exit from. If it
is, control returns to the instruction
fetch loop.
Otherwise, each MSCW has its saved IPC changed to point to the exit code of the procedure that invoked it, until the desired procedure is found. If at any time the saved IPC of main body of the operating system is about to be changed, a run-time error occurs. | |
5.E. System Programs Support ProceduresSee Section 2.1 for description of these procedures.
Byte Array Procedures | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
FLC | 155 10 | Fillchar(dst, len, char). | |
SCN | 158 11 | Scan(maxdisp, start, forpast, char, masx). | |
MVL | 158 02 | Moveleft(src, dst, numbytes). | |
MVR | 158 03 | Moveright(src, dst, numbytes). | |
Compiler ProceduresStill undocumented. | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
TRS | 158 08 | Treesearch. | |
IDS | 158 07 | Idsearch. | |
Debugger | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
BPT | 213 | UB | Breakpoint (conditional HALT). The UB is the line number in the source file. |
Miscellaneous | |||
Mnemonic | Opcode | Parameters | Full Name and Operation |
TIM | 158 09 | Time(var high, low: integer) | |
XIT | 214 | Exit. The p-Machine halts immediately. (Not to be confused with the EXIT opcode.) | |
NOP | 215 | No operation. |