Installing the HI-TECH Z80 C Compiler for CP/M
Written by Lawrence Woodman on 22nd October 2008     [6 Comments]
Tags: C, CP/M, Programming, Retro, Tutorials, Z80

My language of choice is C and I am currently getting more involved with the CP/M operating system.  I have therefore decided that it would be nice to have a C compiler working under CP/M.  There are a number of options available in the archives, but I have found that HI-TECH are allowing their CP/M C compiler to be downloaded for free.  This is a very good product, has good documentation, is almost ANSI C compliant and can be used for commercial and non-commercial use.  This, therefore, is the one I have chosen.

Downloading the HI-TECH Z80 CP/M C Compiler

This can be downloaded from their site, here.  You do need to register, but it is a simple process and doesn't take long.

The files are self-extracting lharc'ed archives so I installed lha, which is part of my Debian distro.  To extract the contents of the main compiler archive, I created a subdirectory called z80v309.  I entered it and ran:
$ lha e ../z80v309.exe

The extracted contents comes to 413k which is too large for the 8" SD disks that my emulator supports, so I used Cpmtools to create a 4Mb HDD image to put the files on.  Hopefully however, this should fit on your disks. 

Using the C compiler

To test the C compiler I went to the B: drive, where I'm storing my development work, and created a file called hello.c containing the classic "hello, world" source code:

void main(void)
{
   printf("hello, world\n");
}

To compile the source (hello.c on my B: drive) in verbose mode, using the compiler on my I: drive, I run the following:
I> c -v b:hello.c

This leaves the executable hello.com on the I: drive.  Now all we need to do is run it to ensure that it has compiled properly:
I> hello

Which gives the correct output as below:

I>hello
hello, world

Where Now?

The next step, if you haven't already done it, is to extract the documentation file, z80doc.exe.  This is an extensive document that should really help you get to grips with using the compiler.  Now all you have to do is start tinkering and see what you can create. 




Creative Commons License
Installing the HI-TECH Z80 C Compiler for CP/M
by TechTinkering is licensed under a Creative Commons Attribution 2.0 UK: England & Wales License.
Comments


Jon Saxton   (18 April 2010 17:08)
I just used Hi-Tech C to build a recoded version of John Hastwell-Batten's IZ program (originally in Pascal) and found a pretty savage bug in memset().  I have not yet rebuilt the library to fix the bug (I worked around the issue with a custom routine) but be aware that in the copy of 3.0.9 memset() should be avoided. It just does not produce the results you would expect.



Lawrence Woodman   (19 April 2010 01:58)
Jon‚

Thanks for the warning about memset().  I haven't come across any problem as yet‚ but then I haven't used that function much.  It must have been a real pain to narrow down the problem you were having to memset().



pullmoll   (26 April 2010 07:36)
memset(p‚ n‚ c)
register char * p;
register int    n;
char            c;
{
        while(n--)
                *p++ = c;
}

The bug here is the order of parameters. According to e.g. Linux man page for memset it should be memset(void *s‚ int c‚ size_t n). It should be possible to patch the libc.lib file‚ if you can find the code that reads the parameters from the stack.



pullmoll   (26 April 2010 18:07)
I found the code of memset() in the libc.lib file by extracting memset.obj:
B> libr x libc.lib memset.obj
B> ddtz memset.obj
>l 11c
011C  LD   L‚(IX+06)   ; this is the first parameter
011F  LD   H‚(IX+07)
0122  PUSH HL
0123  POP  IY
0125  JR   012F       
0127  LD   A‚(IX+0A)   ; this is the third parameter (which should be 2nd)
012A  LD   (IY+00)‚A
012D  INC  IY
012F  LD   L‚(IX+08)   ; this is the second parameter (which should be 3rd)
0132  LD   H‚(IX+09)
0135  DEC  HL
0136  LD   (IX+08)‚L   ; 2nd parameter again
0139  LD   (IX+09)‚H
013C  INC  HL
013D  LD   A‚L
013E  OR   H
013F  JR   NZ‚0127    

So it's sufficient to swap the IX+0A and the IX+08/09 offsets. The patch addresses in the libc.lib file as found in the archive are:
B66E 0A => 08
B676 08 => 0A
B679 09 => 0B
B67D 08 => 0A
B680 09 => 0B



Lawrence Woodman   (27 April 2010 03:08)
pullmoll‚

I have just had a quick look over the patch and it looks like that should fix the problem.  It really is incredible that this bug got into a production release.  We have to assume that when HI-TECH C was being developed‚ that they had virtually no testbed.  Something unthinkable in a compiler today.



Serge   (31 August 2010 12:13)
Hello!

Thanks for memset patch‚ I used it in my CP/M program written in Hitech C.

BTW‚ are anybody has such problems with HTC too (and may be have a solution?) :
- compiler can not use long (32bit int) and char (8 bit int) together in the same arithmetic equation because char allways interpreting as 0 then. :)  It is needed to typecast char to short (16bit).  
- lowlevel IO (unixio.h: creat‚ open‚ close‚ write‚ read) is erroneous‚ while highlevel IO is working OK (stdio.h: fopen‚ fclose‚ fwrite‚ fread). 
- including of conio.h hangs compiler off

First feature (32bit int and 8 bit int operations) is very interesting and important because HTC is really single CP/M C-compiler natively operating with long (32bit int).


Add a Comment

Please leave a comment.  I would love to hear what you think.
All comments are checked before displaying to prevent SPAM.

Your Name (Optional)

Your Email (Optional)
Not displayed, just used to pickup a Gravatar

Your Website (Optional)

Comment

All comments preformatted i.e. newlines and spaces display properly.
All HTML will be displayed literally e.g. <br /> will not create a line break.
URLs beginning with http:// or ftp:// will be converted to links.

        Privacy Policy

Contact Details

I would love to hear from you and welcome your feedback on the site.

You can keep in contact with me through the following services:
Click to get email address
GitHub
Linkedin
Twitter
Delicious
StumbleUpon
YouTube
Technorati
FriendFeed
MyBlogLog