21

I am looking for a native C compiler for the Spectrum 128. I would like one which:

  • Has good support for the latest C standard at the time.
  • Is not limited to compiling ridiculously short source code.
  • Produces decently-optimized machine code*, especially for bitwise operations.
  • Has an English interface.

Features that would be nice, but are not required:

  • Has a basic C library (for things such as strcmp).
  • Can run with 48K memory.
  • Supports assembly as well for manual optimization.

What native C compiler fits these requirements?

* I'll mostly be doing add, rotate, and XOR on arrays, and possibly finite field arithmetic (cryptographic stuff).

forest
  • 2,029
  • 12
  • 36
  • 3
    I looked through much of World of Spectrum's compiler section, but I couldn't find anything which was specifically advertised as producing well-optimized code. – forest Mar 24 '18 at 22:53
  • Presumably CP/M options, even though the +2A and +3 memory map allows a CP/M BIOS to be loaded and one was available for the +3, don't count as native? By 'Spectrum 128' you mean including the Sinclair models? Just asking in case the actual motivation is that you have a +3 and would like to use it for development. – Tommy Mar 25 '18 at 18:03
  • I have the +3 model as well. – forest Mar 25 '18 at 21:19
  • 6
    At the time of the Spectrum, there was no latest C standard. The closest you could come to it was The C Programming Language, 1st Edition. Also, by modern standards, no compiler produced decently optimised machine code. – JeremyP Mar 26 '18 at 08:43
  • For the record, I've decided against CP/M recommendations — though there are many, many of them http://www.z80.eu/c-compiler.html — because any use of the standard libraries would mean that you'd produced a CP/M application rather than a Spectrum one. So even though you're running it natively on hardware, nativeness is questionable. – Tommy Mar 27 '18 at 17:26
  • 4
    @JeremyP the Spectrum had a ten-year retail run, not being discontinued until 1992. So they were in shops for a couple of years after publication of the C89/C90 standards. But fudging "at the time of the Spectrum" to "at the time that a compiler author might expect to obtain anything by targetting the Spectrum" suits me fine. – Tommy Mar 27 '18 at 17:33
  • Not to mention Spectrum clones in Russia and Eastern Europe being made up until the end of the '90s. – hippietrail May 01 '20 at 02:38

3 Answers3

27

If you want it contemporary, use HiSoft C. Back then the standard compiler and compatible with other HiSoft Tools.

For a more up to date and rather comfortable (cross) compiler Z88dk with its Spectrum target might be a good choice. The detailed documentation is a great plus.

Raffzahn
  • 222,541
  • 22
  • 631
  • 918
  • 6
    Definitely second z88dk. While I can see the attraction of doing things as they were, you can do so much more with a modern compiler that runs on a PC than you can running on the target: no memory worries, plus a modern optimizer is so much better than old ones that you can actually fit noticeably more in memory. On one of their benchmark programs, their compiler produces an output that's literally half the size of HiSoft C's result. – Jules Mar 25 '18 at 08:43
  • z88dk is indeed a well-known environment. Be aware that its spirit is to provide a kind-of "multi-target"/"platform-agnostic" environment that allows to compile "portable" C source code to many 8-bit platforms, at the cost of some sort of "race for the bottom" API. That mostly does not prevent to adjust things to benefit platform-specific features, it's just that it's better to know the spirit of the tool. – Stéphane Gourichon Mar 25 '18 at 17:56
  • Kudos for the cross-compiler route, almost any modern-ish compiler on decent hardware is going to outperform what was available at the time. –  Mar 29 '18 at 05:51
  • 1
    BTW, it looks like latest versions of z88dk has two compilers: sccz80 (original z88dk's compiler) and sdcc. – kolen Mar 29 '18 at 19:55
  • 1
    @StéphaneGourichon While there is some cross-platform functionality, this is not entirely true. There are specialized libraries for specific machines that take advantage of specific hardware. Some examples are sp1 for the spectrum and devkitsms for the sega master system which are both integrated into the library. – aralbrec Mar 30 '18 at 19:21
  • 1
    @kolen I've used sdcc before to generate MCS-51 code, but it was quite inefficient. – forest Sep 22 '18 at 07:43
  • Would you happen to know where a (non-OCRed) manual for HiSoft C would be in a format available for download? The only ones I can find are either scanned with OCR (not good for manuals related to programming), or specific for the CPC (meaning the command keys are quite different). – forest Apr 16 '19 at 01:49
6

There is one native z80 c compiler that I've found performs surprisingly well in benchmarks, and that's Hitech C v309 for CP/M. Unfortunately it's for CP/M as the name suggests, but it's worth a mention because it is steps above the others.

It is (nearly?) C90. But you do have to be careful to split really large programs into several source files to avoid running out of memory during compilation.

But today there's no reason except nostalgia to run a compiler on the native machine I don't think?

Omar and Lorraine
  • 38,883
  • 14
  • 134
  • 274
aralbrec
  • 1,156
  • 1
  • 7
  • 5
  • 1
    Sorry, the vast majority of your writing is not an answerrelated to the question asked. I'ts all about comments on other questions. If you want to relate to these, then do so in comments - but avoide lengthy discusions. Stackexchange is a Q&A site, not a forum. – Raffzahn Mar 30 '18 at 19:31
  • Also, the first paragraph isn't quite an answer, as the question is looking for a C compiler that runs on the target machine; this compiler isn't native as it runs on CPM. – wizzwizz4 Mar 31 '18 at 08:07
5

I'm afraid that with this: "Produces decently-optimized machine code" there will be no answer. Even contemporary cross-compilers (i.e. pc hosted) like sdcc or iar C produce miserably slow code for Z80 target.

lvd
  • 10,382
  • 24
  • 62
  • 2
    I'm afraid that is no answer to the question. – tofro Mar 27 '18 at 12:51
  • 6
    Yes, there are questions with no answer. – lvd Mar 27 '18 at 14:21
  • "Decent" is relative. If uint32_t a = b >> c; can be done in just a couple instructions, it's optimized enough. I certainly don't mean to get anywhere near the kind of optimized code that a modern GCC or Clang with LTO could produce on its highest settings. – forest Mar 28 '18 at 01:58
  • In my experience, z88dk is not a bad compiler, probably the best you can get for the Spectrum, and can create fast programs. It's not hand-optimized assembler, though. – tofro Mar 28 '18 at 07:31
  • 1
    "Decent" for me using all 'latest' Z80 optimization tricks. For example, what would be generated for (uint8_t a)(uint8_t b)? Even with no tables, there is tightly optimized unrolled multiplication loop like this: ADD HL,HL:JR C,$+3:ADD HL,DE, will any of Z80 C compilers ever generate it? Another example is stack arguments pushing and then retrieving arguments (and local variables) back, like LD IX,0:ADD IX,SP:LD r,[IX+]. Blind addressing of everything with [IX+*] is alarmingly slow in Z80. – lvd Mar 28 '18 at 09:33
  • Related: https://retrocomputing.stackexchange.com/questions/6095/why-do-c-to-z80-compilers-produce-poor-code – Steve Smith Mar 29 '18 at 10:58
  • @tofro I guess you're right, it's not realy an answer, then again, it touches the right button by pointing out the request of opinions of teh original post. Lets keep it for the whole picture. – Raffzahn Mar 29 '18 at 20:00
  • 1
    @lvd If there are constants involved, sdcc/zsdcc/sccz80 (the latter two in z88dk) will perform additions instead. // In z88dk you can choose to enable the fast integer library that includes options for unrolling and leading zero elimination all the way up to 64x64 multiply and divide (though the optimizations are far less after 32-bit). The code can be considerably faster but it is via calls and not inlined. I'm not sure you want inlined unrolled code everywhere as that's a fast way to run out of memory. If you really need that someplace, I'd just write that part in asm in the first place. – aralbrec Mar 30 '18 at 19:21
  • 1
    @lvd Both sdcc and zsdcc try to keep a working set in registers so that they don't have to go back and forth to memory. But their degree of success will depend on how tightly written the original c code is. One thing people tend to do in c that they don't in asm is write very complicated functions and that contributes to poorer code quality. – aralbrec Mar 30 '18 at 19:21