Take the 2-minute tour ×

I seem to be losing the battle against my stupidity.

This site explains the system calls under various versions of CP/M.

However, when I try to use call 2 (C_WRITE, console output), nothing much happens.

I have the following code.

ORG 100h
LD E,'a'
LD C,2

I recite this here from memory. If there are typos, rest assured they were not in the original since the file did compile and I had a COM file to start.

I am thinking the lines mean the following:

  1. Make sure this gets loaded at address 100h (0h to FFh being the zero page).
  2. Load ASCII 'a' into E register for system call 2.
  3. Load integer 2 into C register for system call 2.
  4. Make system call (JMP to system call is at address 5 in zero page).
  5. End program (Exit command is at address 0 in zero page).

The program starts and exits with no problems. If I remove the last command, it hangs the computer (which I guess is also expected and shows that CALL 0 works).

However, it does not print the ASCII character. (But it does print an extra new line, but the system might have done that.)

How can I get my CP/M program to do what the system call is supposed to do? What am I doing wrong?

UPDATE: The problem was that all assemblers I tried expected a certain format of the source file. This file worked with Microsoft's macro assembler:

START:  LD      E,'a'
        LD      C,2
        CALL    5
        JP      0

I think (I am guessing) that asm.com (DR's assembler) and m80.com (Microsoft's macro assembler) are expecting Intel 8080 mnemonics and have to be told when they have to expect z80 mnemonics, which are apparently different.

I'll accept the answer below anyway because it is also correct since it suggests simply writing the image itself without worrying about asm.com.

share|improve this question
You're correct that CP/M itself will print an extra new line. Take out everything but the CALL 0 and see for yourself. –  Mark Ransom Sep 11 '12 at 21:02
Incidentally --- and I'm aware this is a bit of a necrocomment, but hey, CP/M, it's appropriate --- you don't have to JP 0 to exit your program. If you take care to save your original stack pointer and not overwrite any of the CCP's storage you can just RET back to the shell. That's much more user-friendly as the CCP doesn't need to be reloaded. –  David Given Feb 22 '13 at 11:09
Thanks. That's a good tip. I am not done with this yet. –  Andrew J. Brehm Feb 23 '13 at 0:20

1 Answer 1

up vote 2 down vote accepted

Obvious possibility: is your assembler taking 'a' to be a hexadecimal rather than an ASCII character? 0xa is ASCII for new line. Maybe try 'g' or inspect a hex dump of your assembler output?

Other than that your code looks fine, though an RST 0 would save a few bytes.


I hand assembled your code to:

1e 61
0e 02 
cd 05 00
cd 00 00

I saved that to disk as mytest.com. I then launched this CP/M emulator (warning: that's a direct file download link; the emulator appears to be titled Joan Riff's "Z80MU PROFESSIONAL" Z80 and CP/M 2.2 Emulator and is itself more than twenty years old so doesn't seem to have a web page) for DOS inside DOSBox and ran mytest.com. It output the letter 'a'. So either your toolchain or your CP/M is at fault.

A picture because it really did happen:

enter image description here

share|improve this answer
I tried giving it a 64 for an at-sign. It still doesn't print anything. But I'll look into the possibility. It's the mac.com assembler that comes with CP/M 3.x. –  Andrew J. Brehm Sep 4 '12 at 7:45
To follow the same line of thought, if you make two calls, ostensibly to print two things, does the output change at all? –  Tommy Sep 4 '12 at 21:26
I haven't looked at this last night, but that's a good idea. I'll try tonight. Ta. –  Andrew J. Brehm Sep 5 '12 at 7:16
With two call 5 (and a new character in E) it does exactly the same –  Andrew J. Brehm Sep 7 '12 at 9:00
One more question — have you tried calling the BIOS function CONOUT directly rather than going through BDOS? –  Tommy Sep 11 '12 at 19:23

Your Answer


