Pep/8 Reference

The Pep/8 computer is a 16-bit complex instruction set computer (CISC). It is designed to teach computer architecture and assembly language programming principles. Its 39 instructions are based on an expanding opcode and are either unary (one byte) or nonunary (three bytes). The eight addressing modes are designed for straighforward translation between C/C++ and assembly language.

Topics: Instruction set, Setting the C bit on subtraction, Setting the N bit on CPr, Dot commands, Addressing modes, Register field, Trace tags, Assembly language syntax summary.

Instruction set

Instruction Specifier Mnemonic Instruction Addressing Modes Status Bits
0000 0000 STOP Stop execution U
0000 0001 RETTR Return from trap U
0000 0010 MOVSPA Move SP to A U
0000 0011 MOVFLGA Move NZVC flags to A U
0000 010a BR Branch unconditional i, x
0000 011a BRLE Branch if less than or equal to i, x
0000 100a BRLT Branch if less than i, x
0000 101a BREQ Branch if equal to i, x
0000 110a BRNE Branch if not equal to i, x
0000 111a BRGE Branch if greater than or equal to i, x
0001 000a BRGT Branch if greater than i, x
0001 001a BRV Branch if V i, x
0001 010a BRC Branch if C i, x
0001 011a CALL Call subroutine i, x
0001 100r NOTr Bitwise invert r U N Z
0001 101r NEGr Negate r U N Z V
0001 110r ASLr Arithmetic shift left r U N Z V C
0001 111r ASRr Arithmetic shift right r U N Z C
0010 000r ROLr Rotate left r U C
0010 001r RORr Rotate right r U C
0010 01nn NOPn Unary no operation trap U
0010 1aaa NOP Nonunary no operation trap i
0011 0aaa DECI Decimal input trap d, n, s, sf, x, sx, sxf N Z V
0011 1aaa DECO Decimal output trap i, d, n, s, sf, x, sx, sxf
0100 0aaa STRO String output trap d, n, sf
0100 1aaa CHARI Character input d, n, s, sf, x, sx, sxf
0101 0aaa CHARO Character output i, d, n, s, sf, x, sx, sxf
0101 1nnn RETn Return from call with n local bytes U
0110 0aaa ADDSP Add to stack pointer (SP) i, d, n, s, sf, x, sx, sxf N Z V C
0110 1aaa SUBSP Subtract from stack pointer (SP) i, d, n, s, sf, x, sx, sxf N Z V C
0111 raaa ADDr Add to r i, d, n, s, sf, x, sx, sxf N Z V C
1000 raaa SUBr Subtract from r i, d, n, s, sf, x, sx, sxf N Z V C
1001 raaa ANDr Bitwise AND to r i, d, n, s, sf, x, sx, sxf N Z
1010 raaa ORr Bitwise OR to r i, d, n, s, sf, x, sx, sxf N Z
1011 raaa CPr Compare r i, d, n, s, sf, x, sx, sxf N Z V C
1100 raaa LDr Load r from memory i, d, n, s, sf, x, sx, sxf N Z
1101 raaa LDBYTEr Load byte r from memory i, d, n, s, sf, x, sx, sxf N Z
1110 raaa STr Store r to memory d, n, s, sf, x, sx, sxf
1111 raaa STBYTEr Store byte r to memory d, n, s, sf, x, sx, sxf

Scroll to topics.

Setting the C bit on subtraction

There are two different philosophies for setting the carry bit after subtraction.

Z80, x86, and SPARC treat the carry flag as a "borrow flag" when doing a subtraction. When subtracting x - y, if x is less than y (treating both operands as unsigned), the carry flag is set because there is a borrow. A BRC after a SUBr or CPr instruction is equivalent to "branch if unsigned overflow" in this case.

On other processor families, such as ARM and PowerPC, the carry flag after a subtraction is set to the adder carry output after computing (x + ~y + 1). When subtracting x - y, if x is greater than or equal to y (treating both operands as unsigned), the carry flag is set. A BRC after a SUBr or CPr instruction is equivalent to "branch if not unsigned overflow" in this case.

Previous versions of Pep/8 set the C bit on subtraction according to the first philosophy. However, starting with version 8.1.0, the C bit on subtraction is set according to the second philosophy. This is consistent with the section "The Carry Bit" in Chapter 3, and the adder/subtracter circuit in Figure 10.53 in the text.

Scroll to topics.

Setting the N bit on CPr

Normally, the N bit duplicates the sign bit, so that N is 1 when the result of the operation is negative. The compare instruction CPr subtracts the operand from the register and sets the status bits without storing the result of the subtraction.

As long as there is no overflow when the operands are interpreted as signed integers, the N bit is set appropriately for a subsequent conditional branch instruction. If the result of the subtraction yields an overflow and the N bit were set as usual, the subsequent conditional branch instruction might execute an erroneous branch. Consequently, if the CPr subtraction operation overflows and sets the V bit, then the N bit is inverted from its normal value and does not duplicate the sign bit.

With this adjustment, the compare operation extends the range of valid comparisons. Even though there is an overflow, the N bit is set as if there were no overflow so that a subsequent conditional branch will operate as expected.

Scroll to topics.

Dot commands

Dot Command Description
.ADDRSS symbol The address of a symbol (two bytes)
.ASCII "string" A string of ASCII bytes
.BLOCK n A block of n bytes
.BURN 0xFFFF Initiate ROM burn ending at 0xFFFF
.BYTE constant A byte value (one byte)
.END The sentinel for the assembler
.EQUATE constant Equate a symbol to a constant value
.WORD constant A word value (two bytes)

Scroll to topics.

Addressing modes

Addressing Mode aaa-field Letters Operand
Immediate 000 i OprndSpec
Direct 001 d Mem [OprndSpec ]
Indirect 010 n Mem [Mem [OprndSpec ] ]
Stack-relative 011 s Mem [SP + OprndSpec ]
Stack-relative deferred 100 sf Mem [Mem [SP + OprndSpec ] ]
Indexed 101 x Mem [OprndSpec + X ]
Stack-indexed 110 sx Mem [SP + OprndSpec + X ]
Stack-indexed deferred 111 sxf Mem [Mem [SP + OprndSpec ] + X ]

Scroll to topics.

Addressing Mode a-field Letters Operand
Immediate 0 i OprndSpec
Indexed 1 x Mem [OprndSpec + X ]

Scroll to topics.

Register field

r-field Register
0 Accumulator, A
1 Index register, X

Scroll to topics.

Trace tags

Trace tag Format
#1c One-byte character
#1d One-byte decimal
#2d Two-byte decimal
#1h One-byte hexadecimal
#2h Two-byte hexadecimal
#2d4a Two-byte decimal, four-cell array (example)

Scroll to topics.

Assembly language syntax summary

A decimal integer starts with an optional + or -, followed by a decimal digit followed by zero or more digits.

A decimal integer used with .BYTE ranges from -128 to 255, otherwise from -32768 to 65535.

A hex integer starts with 0x or 0X followed by one or more hex digits (upper- or lower-case).

A hex integer used with .BYTE ranges from 0 to FF, otherwise from 0 to FFFF.

A single character is enclosed in single quotes, as in 't'.

An ASCII string is enclosed in double quotes, as in "My string.".

An arbitrary byte can be included in a string or a character by prefixing exactly two hex digits with \x or \X, as in "Null terminated\x00".

A double quote is included in a string by prefixing it with \, as in "She said, \"Hello\".".

A single quote is included in a character by prefixing it with \, as in '\''.

A backslash character is included in a string or character by prefixing it with \, as in "My bash is \\." and '\\'.

The following letters, when preceded by \, generate non printable characters—b backspace, f form feed, n line feed (new line), r carriage return, t horizontal tab, v vertical tab—in string and character constants, as in "\n Starts on a new line." and '\n'.

A backslash character followed by any character other than b, f, n, r, t, v, x, X, ", ', or \ (except for the second of a pair of \’s) is an error.

A double quote preceded by a backslash in a character is not necessary but is valid and represents one double quote.

A single quote preceded by a backslash in a string is not necessary but is valid and represents one single quote.

A constant used as an operand specifier that occupies less than two bytes is right justified in the two-byte field.

A constant used as an operand specifier that occupies more than two bytes is an error.

Scroll to topics.