Z80 HiTech C Compiler - improved

  • The HiTech C Compiler v3.09 is one of the best available C compilers that can be used on 8-bit CP/M 2.2 systems.

    However, the high quality of this toolset is critically affected by the available 64KB RAM memory constraints.

    It is very frequent that the compiler reports “out-of-memory” error messages for C source files enough small (some hundreds code lines…).

    In the same time, currently there are available a lot of Z80 based hardware configurations provided with 128 KB RAM or 512KB RAM banked memory; of course, Z80 may use only a 64KB address space, but in these hardware configurations, the available extra RAM banks can be selected using I/O ports.

    This opens the possibility to “enhance” the capabilities of the C compiler, by allowing him to allocate memory in the extra RAM banks.

    Benefiting from the high quality work of Andrey Nikitin and Mark Ogden, who published the decompiled C sources on GitHub, I modified these source files to implement this idea of a enhanced C compiler.

    I published on GitHub the solution: an enhanced HiTech C Compiler, for 128KB/512KB RAM Z80 computers, able to compile large C source files ( https://github.com/Laci1953/HiTech-C-compiler-enhanced )

    The following HiTech components were modified:

    • P1.COM
    • CGEN.COM
    • OPTIM.COM
    • ZAS.COM (starting from the Hector Peraza’s ZSM4 published on GitHub)

    The included files are built to be used on Z80 systems provided with 128KB RAM or 512KB RAM modules hardware configuration.

    The resulting C toolset can be customized to be used on any available 128KB RAM / 512KB RAM Z80 hardware system configuration (for example, it works on any RC2014 provided with SC108, SC114, SC118, SC150, SC152 or the Phillip Stevens memory module, or the 512KB RAM + 512KB ROM module).


    Waiting for your feedback,


    Ladislau

  • No, I did not, because my only target was to provide, for Z80 computers, the capability to compile larger C files.

    So, now, with my humble RC2014 provided with 512KB RAM memory module, I can compile large C files that failed to compile before...

    See some examples of files that can now be compiled, but fail to compile in the original HiTech C compiler, here: https://github.com/Laci1953/Hi…-enhanced/tree/main/TESTS

    It's normal that larger C files are now compiled, given the extra RAM space provided for memory allocation (and the C compiler allocates heavily...)


    Ladislau

  • I will try to compare it by myself, your also published StarTrek-Source is perfect for that ;)

    Also, I thought your newly build version of the HiTech C Compiler does only work on your RC2014 with more than 64K, because as far as I remember you're not using a generic approach to use the additional RAM, instead, it's only adapted for the RC2014 build. Is that true?

    "The biggest communication problem is we do not listen to understand. We listen to reply." - Stephen Covey


    Webseite und Blog ist immer noch - seit fast 20 Jahren - online.

  • Yes, this version works only for computers with their hardware containing more that 64KB RAM.


    Yes, you can say that it's adapted for the RC2014, but, given the fact that all the sources are available, including the memory management routines, it's easy to adapt the package for other hardware environments (changing the value of some I/O ports via EQU assembler statements).


    Until now, two "memory models" are covered:

    1. 128KB RAM, practically 2 banks x 64KB + 32KB EPROM

    2. 512KB RAM, practically 32 banks x 16KB + 512KB EPROM


    I'm just starting the design for a new "memory model", with 128KB RAM but 4 banks x 32KB.


    So, as you see, I will cover some very popular Z80 hardware environments.


    That was the target, in fact.


    Ladislau

  • Zitat

    128KB RAM, practically 2 banks x 64KB + 32KB EPROM

    That makes me wonder if an Apple //e with a Microsoft Z-80 SoftCard (and an extended 80 col. board) could be a potential target system.

  • If ( the Z-80 SoftCard and the Extended 80-Column text card are compatible,

    and the extra 64 KB RAM can be addressed via a port to switch the current RAM bank,

    and if you can move bytes to the extra 64 KB RAM to inject at the top of both 64KB banks, at exactly the same address, some small routines),

    then ... yes, can be done.


    The most difficult task is to move bytes from the "base" 64KB RAM bank to the "extra" 64KB RAM bank...


    Example


    In the particular case of RC2014 provided with the SC108 module (128KB RAM + 32KB EPROM), the trick that helped me fulfill this task was a small function present in the 32KB EPROM's monitor, which allowed to move one byte from the 8000-FFFF area of the "lower" 64KB RAM to the 8000-FFFF area of the "upper" 64KB RAM; practically, the procedure is the following:


    from a routine located somewhere in the 8000-FFFF area of the "lower" 64KB RAM, execute:


    1. page-in the 32KB EPROM at 0000-7FFF

    2. call a routine located in the EPROM, passing-it the byte and and address (where the byte will be stored...)

    3. that routine page-out the "lower" 64KB RAM and page-in the "upper" 64KB RAM

    4. then store the byte at the specified address

    5.the page-in the "lower" 64KB RAM and return


    This "trick" helped me to move at the top of the "upper" 64KB RAM an exact copy of the "shadow" routines ; these "shadow" routines were then stored, at exactly the same address, in the "lower" 64KB RAM, and all is ready to move bytes between these two 64 KB RAM banks.


    The "shadow" routines contain the following:


    - get byte (from low64 to up64)

    - put byte (from low64 to up64)

    - get word

    - put word

    - get string

    - put string


    Of course, there are also custom "malloc" and "free" routines that allocate/free memory in the "upper" 64KB RAM.


    For the Z80 computers provided with 512KB RAM + 512KB EPROM, there is another, completely different mechanism.


    The 512KB (RAM or EPROM) contains 32 x 16KB logical banks, selected via ports, mapped to the following physical memory areas: 0000-3FFF, 4000-7FFF, 8000-BFFF, C000-FFFF; so, you can map any 16KB (RAM or EPROM) bank to any of those memory areas.


    I wrote a memory allocator (using Donald Knuth's "buddy system" algorithm) that can allocate / free buffers located at 8000-BFFF, mapping there 28 16KB RAM logical banks (the rest of 4 16KB RAM banks are used to hold the program + CP/M).


    Ok, that's the story... I hope it was not too boring...


    Ladislau

  • Without going into details I'm pretty sure that your ideas fit to the hardware in question.


    There's even a "EPROM routine" to memcpy() a whole block from "low64" to "up64" (and vice versa). So maybe your "shadow" routines aren't necessary at all.


    But apart from that, your "shadow" routines are what others name "trampoline". They are a usual pattern on the hardware in question.


    So, I believe this could work - however I'm personally not interested in working on it ;)