Serial communication with the Philips P2000C#
The Philips P2000C hosts a DB25 serial interface connector on its back side which can be used for serial communication according to the RS-232 protocol. This blog post will look into more detail how this protocol works and how we can drive the serial interface port using MS-DOS interrupt routines.
Wiring#
To read the raw signals, an oscilloscope is hooked up to the transmit, receive and ground pins of the serial port. As can be seen in the image below, we also use a DB25 to DB9 converter adapter.

The female DB9 end of this adapter exposes the RxD (read), TxD (transmit) and ground signals on pins 2, 3 and 5, respectively. Although the port exposes more signals, we can ignore these for the purposes of this blog post. The RxD signal is wired to channel 1 and the TxD signal to channel 2 on the oscilloscope. In other words, an outgoing signal is monitored on the first channel of the oscilloscope and an incoming signal on the second.
Via a breadboard, the RxD, TxD and GND signals are further routed to a USB-to-serial cable such that we can also read out the signals on a modern computer. For this purpose, we use the program PuTTy which can be obtained for free.
Important
Connecting two serial ports requires using a so-called null-modem cable. Such a cable swaps the TxD and RxD lines between its two ends.
To mimic a null-modem cable, the RxD (pin 2) line on the P2000C side is hooked up to pin 3 on the USB-to-serial cable. Vice-versa, the TxD (pin 3) line is connected to pin 2. In other words, the TxD and RxD signals are swapped via the breadboard, corresponding to a null-modem configuration. Finally, all ground signals are connected (including the ones on the osscilloscope) to ensure there is a common ground.
Interrupt routines#
According to the 8088 CoPower board manual (page 502), serial communication
proceeds by making calls to interrupt 0x14
. Interrupt 14,0
is
used to set the communication parameters and interrupt 14,1
can be used
to send a single byte. Although the manual does not specify this, the default
settings correspond to a baud rate of 1200, a single stop bit, a bytesize of 8
and no parity checking.

As shown in the previous post, we can use
the MS-DOS debug program to
write small snippets of assembly code. The following snippet sends 0x55
and 0xAA
over the serial port.
mov ah,1
mov al,55
int 14
mov ah,1
mov al,aa
int 14
int 20
Important
According to the RS-232 standard, a logic 1 gives a low signal and a logic 0 gives a high signal. Furthermore, bytes are sent with their least-significant-bit (LSB) first. Every byte is preceded by a start bit (high signal) and ends with a stop bit (low signal).
On the oscilloscope, we see the result as shown in the image below upon running
the program. First, a high start bit is seen. Next, the bits corresponding to
0x55
are received LSB-first and in inverted fashion. That means, a low
signal corresponds to a binary 1 and a high signal corresponds to a binary 0.
Since 0x55
corresponds to 0b01010101
, the signals after the
start bit correspond to low-high-low-high-low-high-low-high. Finally, a stop
bit (low) is received.

The next byte, 0xAA
shows a very similar pattern. A single high start
bit, the byte encoded as high-low-high-low-high-low-high-low and finally a low
stop bit. From the figure, we also observe two dashed lines which show the time
interval of two consecutive pulses (one high, one low). On the basis of the this
time interval, we can determine that 1200 bits per second are sent,
corresponding to the default baud rate.
Saying hello to the world#
Let us try something somewhat more exciting and send over a sentence. We write
the following snippet of assembly code as can be seen in the image below. What
this code does is basically loop 12 times over the characters in a string stored
at location 0x110
. Every character is sent to the serial port after
which the program terminates.

Upon execution of this snippet, the osscilloscope indeed confirms that we were able to send “Hello World!” over the serial port. Although not explicitly shown, on the laptop end, also the string “Hello World!” is received.

Changing the parameters#
As eluded to earlier, we can also change the serial communication parameters via
interrupt 14,0
. Instead of the default baudrate of 1200, we want to set
it to 9600. We also would like to enable parity checking by enforcing odd parity
via the parity bit. From the manual, it can be determined that this corresponds
to setting 0xEB
. To see the effect of parity checking, we will be
sending the bytes 0x40
and 0x41
, corresponding to the characters
@
and A
in ASCII. The complete snippet of code can be seen from
the image below.

Upon execution of the program, we see the result as shown in the image below on
the oscilloscope. The start bit is indicated by the dashed lines. From its time
interval it can be confirmed that the protocol indeed operates at a baud rate of
9600. Following the start bit, we see 6 consecutive high signals, then a low
signal, then two high signals and finally a low signal, the latter corresponding
to the stop bit. As 0x40
is encoded as 0b01000000
and is
transmitted LSB-first, we would indeed expect 6 consecutive high signals. The
binary 1 corresponds to a low signal and the final binary 0, the MSB, yields a
high signal. In total, the value 0x40
contains a single binary one, thus
the number of binary 1’s equals an odd number. The parity bit is set such that
odd parity is ensured, which corresponds to sending another 0 (high signal).
The next byte corresponds to the number 0x41
which is encoded as
0b01000001
. In contrast to 0x40
, directly after the start bit, a
low signal is seen, then 5 consecutive high signals, followed by another low and
then another high signal. At this point, the parity bit must ensure the odd
parity. Since the number 0x41
contains two 1’s, the parity bit must also
be set to 1 to ensure that there remains an odd number of 1’s in the signal.
Thus, a low signal is received followed by another low signal which is the stop
bit.

Outlook: File transfer#
By means of the serial port, we are able to transmit data between the P2000C and a modern computer. This allows us to transfer files. By writing a small assembly program on the P2000C side, we can read a number of bytes from the serial port, store these in memory and finally write these to a file on a floppy. Since the highest accepted baud rate corresponds to 9600, this will place an upper limit on the transfer speed. Assuming we can store the bytes received from the serial port into memory at maximum efficiency, a baud rate of 9600 would correspond to a transfer rate of approximately 0.94 KiB/s, 0.85 KiB/s if we would turn on parity checking. A complete floppy disk, corresponding to 720 KiB, would thus take almost 13 minutes to transfer.