C or other high level language compiler suitable for ROM code?

262 views
Skip to first unread message

John Kennedy

unread,
Feb 14, 2021, 3:49:43 PM2/14/21
to RC2014-Z80
I know the Z80 is not optimized for a C type language, but has anyone had success with a higher-than-machine level development tool for providing code that can be burned to ROM and drive an RC2014 system?


Patrick Jackson

unread,
Feb 14, 2021, 4:02:15 PM2/14/21
to RC2014-Z80
I've used Aztec C to great effect for games, but it only generates 8080 op codes so it would not be ideal for z80 specific code. There is a github project out there that aims to resurrect HI-TECH C for the Z80, and it adds a TON of bugfixes and feature upgrades (string.h comes to mind!)
https://github.com/agn453/HI-TECH-Z80-C

I've had great success with z88dk for small games for the ti 84+, and it has a very very robust random number generator (for which I like). However, even though its SUPPOSED to support cp/m, others have had issues with such.

Nothing beats good quality assembly, but you do have options for C or even Pascal if you are into that. Just make sure the compiler you use can output z80 code, not just 8080.

Phillip Stevens

unread,
Feb 14, 2021, 7:10:12 PM2/14/21
to RC2014-Z80
John wrote:
I know the Z80 is not optimized for a C type language, but has anyone had success with a higher-than-machine level development tool for providing code that can be burned to ROM and drive an RC2014 system?

The easiest example for me to provide for mixed C and Z80 assembly is the CP/M-IDE in the RC2014 repository. This CP/M implementation is built off the (almost completely pure) DRI assembly code for CCP/BDOS and BIOS, yet has a console / shell built in C; and the FatFS file system is written C, but IDE disk interfaces are written in assembly.

This is built by z88dk with as single command line. Using a list of the sources of mixed C and assembly, no matter, the zcc pre/postprocessor works out what to do, which other additional tools are needed, and then at the end links all the binaries together, compresses them were desired, and produces a single ROM / HEX. output.

z88dk uses assembly libraries exclusively (for performance), and the entire C library is available in the classic libraries. The new library (DEVELOPMENT) in development is mostly complete, and is where the RC2014 and other recent platforms are supported. The only thing missing from the new library is disk management, but there are other solutions for that. CP/M builds are supported in both of the classic and new libraries.

z88dk also allows you to build 3rd party libraries (from C or assembly) and then automatically integrate them into the build process. So high quality C libraries can be simply added to your build if you see a gap. My best examples of that are the ChaN FatFS library for disk management, and the FreeRTOS. Both of these are in C, so wouldn't (by strategy / design) be integrated into z88dk, but it is really easy to just compile up someone else's C into a library, and add it to your C or assembly program.


End of advert.
Cheers, Phillip
 

John Kennedy

unread,
Feb 15, 2021, 12:26:17 AM2/15/21
to RC2014-Z80
Thanks all. I’m looking at z88dk. It’s been a long, long process getting it running on a Raspberry Pi - maybe it’ll be done by tomorrow ;-)
Definitely need a nice by-the-hand YouTube video or something as it’s quite intimidating. 

Phillip Stevens

unread,
Feb 15, 2021, 1:27:09 AM2/15/21
to RC2014-Z80
John wrote:
Thanks all. I’m looking at z88dk. It’s been a long, long process getting it running on a Raspberry Pi - maybe it’ll be done by tomorrow ;-)

Going for expert level straight off the bat... Respect.
Perhaps, try with the standard x86, MacOS or Windows packaged installation first?

I don't know of anyone who uses it on RasPi (not to say it won't work).
Mainly because sdcc is so resource intensive that you want every processor cycle you can get when you do large compiles. 

Definitely need a nice by-the-hand YouTube video or something as it’s quite intimidating.

Good idea. If you can get it going on RasPi, you should do a video to help others.

Cheers Phillip

John Kennedy

unread,
Feb 15, 2021, 4:29:06 PM2/15/21
to RC2014-Z80
So far so good - all I need now is the correct C way to read/write to the Z80’s I/O ports..

Phillip Stevens

unread,
Feb 15, 2021, 11:00:53 PM2/15/21
to RC2014-Z80
John wrote:
So far so good - all I need now is the correct C way to read/write to the Z80’s I/O ports.

You've probably already worked it out, but for the record.
Have a read of the SDCC manual, specifically the sections in 3.5.2 on the Z80.
There are some examples here, for the well known RC2014 ports.
P.

John Kennedy

unread,
Feb 15, 2021, 11:20:57 PM2/15/21
to RC2014-Z80
Thank you! I hadn’t managed to find that, and instead I was using #asm / #endasm; with some out (port), a in between.
This will be a lot more convenient.

I found a few things:

* I couldn’t get code compiled on the Raspberry Pi to run on my RC2014 set-up.
* The same code compiled on the Mac using the precompiled files DID work.  (I will compare it and see what’s up)

Now, what I really want is to compile some C code not for an RC2014 but for some Frankenstein’s monster system I’ve made.
This system which has a ROM at 0  and RAM from 2000 to 2fff.
I’ve tweaked the crt_config a bit, but no luck. I feel like I’m close though.

Phillip Stevens

unread,
Feb 15, 2021, 11:46:13 PM2/15/21
to RC2014-Z80
John wrote:
This system which has a ROM at 0  and RAM from 2000 to 2fff.
I’ve tweaked the crt_config a bit, but no luck. I feel like I’m close though.

You just need to change the org_DATA location, and the register_sp location, using pragmas, or change the config file as you noted.

The SCM reference is relevant, but for you these pragmas go in your C file.

#pragma output CRT_ORG_DATA = 0x2000
#pragma output CRT_REGISTER_SP = 0x3000

 

Phillip Stevens

unread,
Feb 15, 2021, 11:50:18 PM2/15/21
to RC2014-Z80
John wrote:
Now, what I really want is to compile some C code not for an RC2014 but for some Frankenstein’s monster system I’ve made.

You can also use the +z80 target, which used to be called Embedded, as a blank slate with no drivers for Frankenstein's monster.

John Kennedy

unread,
Feb 16, 2021, 11:53:25 PM2/16/21
to RC2014-Z80
Thanks again Phillip. I’m still fighting it, but I’ll work it out. 
My compiled program works on the RC2014, and a pure assembler app is working so the test hardware (an EPROM emu) is working.
I’ll have to make a very simple C app, compile it, and disassemble it to see exactly what is going wrong.

Phillip Stevens

unread,
Feb 17, 2021, 12:01:59 AM2/17/21
to RC2014-Z80
John wrote:
I’m still fighting it, but I’ll work it out. 
My compiled program works on the RC2014, and a pure assembler app is working so the test hardware (an EPROM emu) is working.
I’ll have to make a very simple C app, compile it, and disassemble it to see exactly what is going wrong.

There are some compile options that I always use to help when in your situation.
-m - generate a map file to point out where every function is located, and what every define is equal to.
--list - generate assembly listings from all the C files (and assembly files), including the CRT0 file.
--c-code-in-asm - puts the C line into assembly listing as a comment.
--verbose-asm - writes comments on which peephole optimisations have been applied (useful if worried an optimisation may be borked). 

Good luck!
P.

John Kennedy

unread,
Feb 17, 2021, 12:04:24 AM2/17/21
to RC2014-Z80

Cheers!
A cursory glance at the disassembled bin implies the SP is set to 0, which isn’t going work.
I did use the CRT_REGISTER_SP #pragma, I wonder if it’s being overridden.

Phillip Stevens

unread,
Feb 17, 2021, 12:10:00 AM2/17/21
to RC2014-Z80
John wrote:
A cursory glance at the disassembled bin implies the SP is set to 0, which isn’t going work.
I did use the CRT_REGISTER_SP #pragma, I wonder if it’s being overridden.

Check the map file to ensure that your #pragma is being applied correctly.
Check the crt0 listing to make sure that your return code isn't causing the issue, at it may be writing SP to zero on exit, or something weird like that.

I usually find close examination of the listings (with all the comments and symbols included) is much easier to understand than a disassembled binary. Check what your crt0 is doing with the stack pointer on entry and exit, as there are lots of options available. You can see the decision flow from the listing.

Cheers, P.

John Kennedy

unread,
Feb 17, 2021, 12:53:44 AM2/17/21
to RC2014-Z80

Getting warmer..

#pragma output REGISTER_SP = 0x3000

Rather than

#program output CRT_REGISTER_SP = 0x3000

Fixes the SP. Looks like the DATA section is still wonky. Progress!

Phillip Stevens

unread,
Feb 17, 2021, 1:54:15 AM2/17/21
to RC2014-Z80
#pragma output REGISTER_SP = 0x3000
Rather than
#program output CRT_REGISTER_SP = 0x3000

Reply all
Reply to author
Forward
0 new messages