Popmon

Some distant time in the past I replaced the two original monitor PROMs by a set of six PROMs. The labels on the chips read “Popmon”. The software itself seems to be incomplete.

Only later I obtained a printed listing that appears to be complete. I now know that this monitor was written by a Dutch author who goes by the name PA0POP. It is probably created as an extended version of the Central Data monitor.

Certain subroutines are kept at the same address as in the Central Data board for binary compatibility.

Popmon contains some nice additions over the standard monitor. I probably never finished it because I upgraded the system with floppy drives and a Disk Operating System. The monitor was not needed anymore.

I also have a single PROM marked “IPL” (Initial Program Load?), that contains code to read an OS from a floppy diskette. This is the only PROM that was on the board when I retrieved it out of storage.

  • Popmon 000 – 1FF
  • Popmon 200 – 3FF
  • Popmon 400 – 5FF (missing!)
  • Popmon 600 – 7FF
  • Popmon 800 – 9FF
  • Popmon A00 – 1FF

The missing chip mostly contains code to drive a printer.

File popmon.bin contains corrections to the faulty bits. It does not contain a replacement for the missing data between 0400 and 05FF. The source (popmon_annotated.2650) and assembly listing (popmon_annotated.lst) can also be downloaded here. These last two files have been reverse engineered by me, before I recovered the original sources.

Popmon accepts the following commands.

A – Alter Memory (01ce)
Enter memory address, then Space to display next address , or ^ Caret to display previous address. Hex values replace the memory contents.

B – Breakpoint (00f8)
Enter memory address. This location and the next are replaced by 9b a2, an indirect jump to 0x0022.

C – Clear breakpoint (00bb)
Displays address of breakpoint and restores memory contents.

D – Dump to tape (03FA)
Enter start address, then enter end address. Data is written to tape (see below).

E – Execute (027f)
Enter memory address, press Enter Jumps to that location.

F..H – unused

I – Inspect Registers (0122)
Enter number of the register, then C to change that value (enter the new value), or any other character to prompt again.
0 1,2,3 = bank 0
4,5,6 = bank 1
7,8 = PSW

J..K – unused

L – Load from tape (0328)
Read valid data from tape. Press Escape to cancel.

M – Execute ROM at 0x0600
(to be recovered from popmon sources).

N..O – Unused

P – Execute ROM at 0x0400
Is missing. Possibly for printer commands. To be recovered from sources.

Q – Unused

R – Run tape (00f0)
Enable tape-start relay. Press Escape to stop.

S..U = unused

V – Verify from tape (02a0)
Enter an address. Contents of the tape are compared against that memory location. Press Escape to cancel.

W – Erase screen (021c)

X – Execute RAM at 0x2000

Y – Execute RAM at 0x1510

Z – Extended commands:

ZS – Move Memory Contents (07aa)
Enter from, until, destination addresses. Copy the block «from,until» to the location starting at «destination».

ZG – Compare Memory Contents (080C)
Enter from, until, reference addresses. Compare the locations «from,until» to the locations starting at «reference».

ZH – Display Memory (071f)
Enter address, a screenful of memory contents are shown (hex and ascii). Press space to continue, or Return to stop.

ZTR – Disassembler (088e)
Clears the screen, then presents an @-prompt. Read one character (either a P or not a P), then read a starting address. A page of disassembled instructions at that address is shown. Press Return to enter a new address. Press Escape to return to the commandline. Or press any other key to continue.

ZTX – Missing (0b8e)
There are no instructions in ROM at this address (0x0b8e).

ZJ – Show text from cassette (086c)
Read from the serial input (cassette interface) and echo to the screen. Press any key to stop.

Tape format

bit 0 = 2400 Hz
bit 1 = 1200 Hz
This is normally the other way around. The FLAG signal from the CPU is inverted.

Byte written with one startbit (0) and 3 stopbits (1s). Least significant bit is written first. Eg: 3A is written as 0 0 1 0 1 1 1 0 0 1 1 1

Bytes are written in blocks. Each block starts with a header:

  • Colon: byte 3A, ascii ‘:’
  • Addr hi: address in which to load the block
  • Addr lo: Length length of the block (length – 1, e.g. FF for a full 256-byte block)
  • Sumcheck: sumcheck over the header, including colon three bit delay
  • data…: data contents of the block
  • Sumcheck: sumcheck over the data

Sumcheck is computed by EXOR followed by Rotate Left.