CP/M Version Numbers

This is a continuation of my series of articles on CP/M. It follows my third CP/M article.

The series starts with my first CP/M article. If you have not read the previous articles, I recommend that you read them first.

Getting a version number from the OS…

CP/M was first released in 1974 to run on Intel's new 8080 8 bit CPU and ultimately evolved into DR DOS, an MS-DOS clone. MS-DOS was itself a clone of CP/M.

The most common versions of CP/M, as far as I can tell, were CP/M 1.3, 2.2, 3.0 and 3.1 on 8 bit machines and 2.2 and 3.1 on 16 bit (8086-based) machines. CP/M versions for Z8000 (16 bit Zilog) and 68000 (32 bit Motorola) used the same version numbers as far as I can tell.

Here is how you can tell the version number of your CP/M system.

First we need the BDOS system call that returns the version number.

In case you can't read this (I noticed single lines are more difficult to read than a number of lines), it defines a string "bdosver" to represent BDOS function 0Ch which returns the system type in B and the version number in A. We'll ignore the system type. It will be  zero for 8 bit CP/M anyway.

Then we need to find a way to convert a byte into a bunch of ASCII characters.

The conv: routine is defined at the end of the source file, just before the END assembler directive.

The BDOS system call to get the version number is called before the conv: routine.

This is the actual program. It does the following:

  1. Loads the number representing the bdosver system call into C.
  2. Calls the BDOS.
  3. Calls the conversion routine to convert the number in A into an ASCII string.
  4. Loads the number representing the cwrites system call into C.
  5. Loads the address of the ASCII string at osname into DE.
  6. Calls the BDOS to display the ASCII string from osname via number to the "$" sign.
  7. Exits the program.

You can find the source file in copy-and-pastable form here.

As for the results of running the program, it is important to know how to read the version number.

The human-readable version number X.Y corresponds to the hexadecimal number XYh.

The version byte contained 22h (34 in decimal).

The version byte contained 31h (49 in decimal). (I don't know why the system boot screen claims version 3.0.)

New instructions used in ver.mac:

SUB immediate
subtracts the immediate from A
JP P,address
jumps to address if signed flag is set (i.e. if A is positive)
increments the byte located at address stored in HL
jumps to last address stored in call stack (i.e. returns to calling routine)

To be continued...

 © Andrew Brehm 2016