CCDP - Nakazoto/CenturionComputer GitHub Wiki

What is CCDP?

First things first, click here to go to Tergav's Github for CCDP!

CCDP, or the Centurion Computer Diagnostic Package, is a collection of software routines that allow for easier diagnostic program creation, execution, and data collection. The design philosophy of CCDP is based off of the similarly named XXDP for the PDP-11. Like its namesake, it is designed to be able to run on a minimally equipped or partially nonfunctional system. To reduce technical complexity, the CCDP kernel only makes use of instructions found in the original EE200. The minimum that CCDP needs to be able to run in its current configuration is about 8K of unbanked RAM and 2 functional serial ports. CCDP was written in assembly using Alan Cox’s Centurion build tools. SerialDir is written in .NET CORE C#.

On a technical level, CCDP is loosely based on the CP/M operating system. While significant differences exist, the memory setup, file I/O, and terminal communication methods share close similarities. Like CP/M, CCDP only supports block operations on files, meaning that files are broken up into a series of 256 byte blocks, which can only be operated on one at a time. The way that programs are run is also very similar, with the executable format simply being a binary image that is loaded verbatim into a specific space in memory. For those familiar with CP/M, it can help to think of CCDP as simply a very cut down version of it.

One of the helpful features of CCDP is that it allows for a layer of abstraction between the diagnostic programs and the actual support hardware. This allows for the same tests to be run on many different system configurations, if that becomes necessary. At the current moment, the only devices that CCDP is aware of are the terminal I/O device, and the file system device. The current version of CCDP does not support more than one file system, though this may change in the future if there is any desire to turn CCDP into a “real” operating system. The current design goals for CCDP is to simply have a way to run programs for diagnostic, reverse engineering, and data archival purposes.

The Memory Map

For those who are familiar with the CP/M operating system, this part is about to be very familiar. This is because CCDP and CP/M share almost the same memory map, with some minor differences for simplicity and the unique memory layout of the EE200 derivative machines.

The utilized memory is divided up into the following regions:

High Memory High Memory
Kernel BASE - TOP
TPA 0x0200 - BASE
Low Memory 0x0100 - 0x01FF
Register File 0x0000 - 0x00FF
Low Memory Low Memory
  • Kernel: This is the area the command monitor and CCDP routines are stored in. It is responsible for loading programs into the TPA, and providing system calls to that program as it runs. The programs do not interface with the kernel directly, but are instead routed through the syscall jump table in low memory to their respective vectors.
  • TPA: The TPA (Transient Program Area) is where all program images are loaded and executed in. This can be an arbitrary size, depending on where the kernel was loaded during bootstrap. For example, 32K.SYS will result in a TPA that is slightly less than 32K in size. This stack pointer also starts at the very top of the TPA when a program first starts execution.
  • Low Memory: This is the area of memory that is used to interface the program in the TPA with the kernel. It contains the syscall jump table, and also internal variables to the kernel that need to be passed to the program, such as the command arguments. This area should not be written to by use programs unless explicitly allowed.
  • Register File: This is where all the registers live on a EE200 derivative machine.

In addition, here is a memory map of the low memory area:

High Memory High Memory
Command Buffer 0xC0 - 0xFF
Unused Space 0x80 - 0cBF
Syscall Table 0x00 - 0x7F
Low Memory Low Memory

Devices

As previously mentioned, CCDP only really knows about 2 devices. The first device is a simple terminal I/O device. This is how CCDP communicates with the system user. The second device is an interface to a file system. CCDP doesn’t really care how the files are stored, all it cares about is if the files can be accessed in such a way that it is consistent with specifications. This allows for CCDP to use file systems that don’t even exist on a native Centurion device, as long as there is some sort of interface. This mechanism is how SerialDir is made to work with CCDP.

The terminal I/O device is pretty easy to understand. There are only 3 necessary routines that need to be implemented for a terminal I/O device to work. The first is a command to write a character to the terminal. This uses 7 bit ascii, with the 8th bit being a zero. The second routine reads a single character from the terminal. If there is no character to be read, the routine stalls till one is found. The last routine checks if there is a character to be read. If there is no character, a zero is returned.

The file system device is a bit more complicated. For a file system driver to function, the following commands need to be implemented:

  • OPEN: Closes the current file and opens a new one
  • CLOSE: Closes the current file (and writes back the buffer if needed)
  • MAKE: Makes a new file given a file name
  • DELETE: Deletes an existing file given a file name
  • LIST: Returns a file name in the directory given an index
  • READ: Reads a 256 byte block from the currently open file
  • WRITE: Writes a 256 byte block to the currently open file

There is more information about the specifics about these system calls in the programming documentation on the github. The maximum length for a filename is 13 characters.

SerialDir

While CCDP can technically boot from any data storage device given the correct driver, the Centurion is in a state where no suitable media storage devices exist that would be easy to transfer data onto from a modern computer. To resolve this issue, SerialDir can be used to abstract the native file system of the host computer into something that the Centurion, and therefore CCDP, and interface to. It translates commands sent to it over a serial line into actual file I/O commands a contemporary operating system like Windows or Linux can understand.

Communication occurs via the client and the server sending packets to each other. In any exchange, it will begin with the client sending a packet to the server, and then the server responding with a single response packet. All information sent or received in this exchange will be found within these two packets. In an exchange, there will only ever be two packets involved. A sent packet will contain a command for the server to execute. The first two "commands" do not need to be sent as proper packetsThese are as follows:

  • {N}o command, do not send a response
  • {B}ootstrap, return the first 256 bytes of BOOT.BIN with no formatting, or all zeros if not found
  • {O}pen file, file name is sent to be opened, status is returned
  • {C}lose file, currently open file is closed, status is returned
  • {M}ake file, a new file name is sent and created on the server, status is returned
  • {D}elete file, a filename to delete is sent, status is returned
  • {L}ist directory, a number is sent in the block # field, and a filename + status is returned.
  • {R}ead block, a block # to read is sent, and the block + status is returned
  • {W}rite block, a block # + block data is sent, and a status is returned

For most packets, an 8 bit CRC will be used to sign the data blocks coming to or returning from the server. This will ensure that corrupt information cannot make its way over the connection and be written to or read from a file.

As mentioned before, all communication between the server and client is done through packets. The format of a command packet sent from the client to the server is as follows:

  • {0}: Commands code (If command 0,1, omit rest of packet)
  • {1}: Block # (High byte)
  • {2}: Block # (Low byte)
  • {3 - ?}: Data field
  • {? + 1}: 8 Bit CRC

All values are included in the CRC, the length of the data field is dependent on what command is executed:

  • {N},{B}: Non-applicable
  • {C},{L},{R}: 0 Bytes
  • {O},{M},{D}: 16 bytes
  • {W}: 256 bytes

As with the command packet, the response packet also has a set format. The format of the response packet sent from the server to the client is as follows:

  • {0}: Status
  • {1 - ?}: Data field
  • {? + 1}: 8 Bit CRC

All values are included in the CRC, the length of the data field is dependent on the returned status. A return value that is above 127 indicates an error has occurred. These lengths are the following:

  • 0: Successful, 0 bytes returned
  • 1: Successful, 16 bytes returned
  • 2: Successful, 256 bytes returned
  • 254: Execution Failure, 0 bytes returned
  • 255: Communication Failure, 0 bytes returned

Bootstrapping

Part 1, Setup

When booting CCDP, the first thing that needs to be set up is the communication line between the host computer and the client computer. This will involve 2 serial connections on the Centurion, one for terminal I/O, and one for data I/O. The MUX0 port will be connected to the terminal like normal, and MUX3 (the port 2 lines under MUX0) will be connected to the host computer.

ADDS 200       Centurion     Host Computer
TERMINAL <--> MUX0 | MUX3 <--> SERIALDIR

After this systems have been connected, the SerialDir program needs to be setup and ran. This can be most easily done by just downloading and extracting Setup.zip, which contains a up-to-date SerialDir executatble and file system. SerialDir.exe must be run on the command line with the arguments for COM port and baud rate:

Usage: SerialDir [Port] [Baudrate]

for example...
./SerialDir COM3 19200

If CCDP is to be booted up inside of an emulator, SerialDir can be configured to to work on a TCP socket connection instead of a serial line connection:

Usage: SerialDir -s [IP Address] [Port]

for example...
./SerialDir -s 192.168.0.1 2048

Part 2, Stage 1 Bootstrap

Booting up CCDP happens in 2 stages. The first stage involves using a bootstrap to load a 256 byte bootloader program into memory. This will be done with a short 24 byte TOS type-in program, as there currently are no boot ROMs on the real system for booting serial.

Before serial communication can happen, the MUX1 serial terminal needs to be configured to run at 19200 baud, 8N1. This will be done in TOS for simplicites sake. Once we know how to set up the serial ports for other speeds, this step can be changed to allow for CCDP to run at higher speeds.

By loading 0xF6 into 0xF206, this will set the serial port to the correct baud rate.

/MF206 F6

It may also be useful to examine 0xF207 to ensure that the serial input register is cleared. If 0xF206 examines to an odd number, then 0xF207 NEEDS to be examined before the bootstrap process can start.

Start by booting the the Centurion into TOS, then type in the following program.

/M01E8 C0 01 E1 F2 07 D0 02 00 55 2A 81 F2 06 2C 11 FA 81 F2 07 A9 20 30 15 F2
/G01E8

It is important to place the bootstrap program at 0x01E8 in memory.

Included below is the listing for bootstrap.asm, this may be easier to read while typing in:

1 0000 :                         ; --- BOOTSTRAP ---
1 0000 :                         
1 0000 : C0 01                   	ld		bl,01
1 0002 : E1 F2 07                	st		bl,(0xF207)
1 0005 : D0 02 00                	ld		b,0x0200
1 0008 : 55 2A                   	xfr		b,s
1 000A :                         loop:
1 000A : 81 F2 06                	ld		al,(0xF206)
1 000D : 2C                      	srr		al
1 000E : 11 FA                   	bnl		loop
1 0010 : 81 F2 07                	ld		al,(0xF207)
1 0013 : A9                      	st		al,(b)
1 0014 : 20 30                   	inr		bl
1 0016 : 15 F2                   	bnz		loop
1 0018 :                       	

Part 3, Stage 2 Bootstrap

If all has gone well in the last part, you should be greeted with the following prompt:

/G01E8

@

This means that the stage 1 bootstrap has successfully completed, and the computer is ready to do stage 2. In this stage, a .SYS file will be loaded somewhere into memory, and executed. This should end the bootstrap process, and starting running CCDP. To do this, simply type in the filename for the .SYS file you want to boot in upper case, and hit enter. Right now the only bootable files in Setup.zip are 32K.SYS and 16K.SYS. 16K.SYS uses less memory, but may be useful if there are RAM errors in upper memory.

@32K.SYS

After this is done, the system should fully come up in a few moments.