Improving the HiTech C compiler

1,549 views
Skip to first unread message

ladislau szilagyi

unread,
Apr 13, 2022, 3:32:02 PM4/13/22
to RC2014-Z80
Hi,

as many of you already know, the HiTech C compiler fails often to compile large C source files.

In such cases, one of the compiler components : P1, CGEN, OPTIM or ZAS issues the infamous "out-of-memory" error message.

I've been trying to find a solution for a few months.

I focused first ZAS, and I have now my Z80AS, capable of assembling much larger files than ZAS.

I'm now trying to fix the OPTIM.COM issue, and it seems I have an answer, but only for RC2014 configurations provided with 128KB RAM (SC108, SC114, SC118 or Phillip Stevens memory module).

For such RC2014 computers, I built a modified OPTIM.COM that can use also the upper 64KB RAM as a storage area for the objects allocated by OPTIM.

I'm still testing it, but the results so far are promising.

An example of such a test:

D>c -v -c -o teedit.c
HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I TEEDIT.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
optim: Out of memory in _BfEdit
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>CPP -DCPM -DHI_TECH_C -Dz80 -I TEEDIT.C $CTMP1.$$$

D>P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$

D>CGEN $CTMP2.$$$ temp.as

D>optim1 temp.as teedit.as

D>sdir teedit.as

Directory For Drive D:  User  0

    Name     Bytes   Recs   Attributes
------------ ------ ------ ------------
TEEDIT   AS     16k    100 Dir RW

D>z80as -j -n teedit.as
Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 69
Finished.

D>

I will keep you informed on the progress of this experiment...

Ladislau

ladislau szilagyi

unread,
Apr 21, 2022, 4:55:02 AM4/21/22
to RC2014-Z80
Hi,

has anyone tried to decompile the P1.COM from HiTech ?

It seems to me that this one is missing, all the rest (C,CPP, CGEN, OPTIM) are available on GitHub, and it would be really unfortunate not to have access to the "missing link".

Why is this P1.COM important?

Because, for owners of 128KB RAM RC2014's , it could remove the constraint of "compile only small C sources" on the RC2014's CP/M. 

In practice, twice as large files will be compiled.

Until now, I have removed part of the constraint (related to ZAS & OPTIM), I'm starting now to work on optimising CGEN.COM, but enhancing P1.COM still remains unsolved.

To give you an ideea about how the enhanced compiler will behave on the RC2014's provided with 128KB RAM, I can give you one example: a 22KB C source file was processed by the "original" OPTIM.COM in 45 secs, compared to 55 secs while running my custom OPTIM. However, that file is the "upper limit" that the original HiTech C compiler is capable of handling; if you add a dozen of lines to that file, you will get the "out-of-memory" error with the "original" OPTIM.COM,. while my custom OPTIM runs-it without any problem ( it uses around 20KB of allocated memory on the upper 64KB RAM).

I'm waiting for your thoughts on this topic...

Ladislau

ladislau szilagyi

unread,
Apr 23, 2022, 12:42:37 AM4/23/22
to RC2014-Z80
Hi,

to get an idea of how much could be gained with this enhanced OPTIM.COM, here are some more samples:


CASE 1
------------
part21.c 48KB

( on ZXCC, using the command zxc -c -s part21.c , P1,CGEN produced the (un-optimized) output part21.as ...)

( now on RC2014 + SC108)

D>optim1 -n part21.as test.as
15K, 2 iterations
102 Redundant labels
149 Jumps to jumps
145 Stack adjustments
291 Temporary labels
224 Unref'ed labels
238 Unreachable code
21 Jumps to .+1
53 Skips over jumps
56 Common code seq's
4 Ex (sp),hl's used
35 Redundant operations
192 Redundant loads/stores
26 Simplified addresses
1 Xor a's used
5 Redundant ex de,hl's
19 Code motions
47 KB used from the upper 64KB RAM


CASE 2
------------
part31.c 40KB

( on ZXCC, using the command zxc -c -s part31.c , P1,CGEN produced the (un-optimized) output part31.as ...)

( now on RC2014 + SC108)

D>optim1 -n part31.as test.as
15K, 3 iterations
163 Redundant labels
225 Jumps to jumps
151 Stack adjustments
197 Temporary labels
254 Unref'ed labels
163 Unreachable code
16 Jumps to .+1
48 Skips over jumps
69 Common code seq's
6 Ex (sp),hl's used
8 Redundant operations
161 Redundant loads/stores
15 Simplified addresses
16 Code motions
33 KB used from the upper 64KB RAM


Those 2 files (part21.c, part31.c) are parts of the OPTIM.COM's source code.

Of course, if compiled on RC2014 with the "standard" HiTech's C, you get the "out of memory" error, directly from P1.COM.

If you try to "fool" the compiler, by obtaining first the "un optimized" assembler source in ZXCC, and then run OPTIM, you get also the "out of memory" error...

Or, as I witnessed in some occasions, ZAS will issue the "out of memory", exactly at the end of the process...

The only way out seems to be "enhancing" all the critical components of the C compiler (P1, CGEN, OPTIM, ZAS).

Status:

For RC2014's with 128KB RAM, I have solved the OPTIM's issue.
For all RC2014's, I have solved the ZAS's issue.

I'm working on CGEN now...

The missing link is P1.

Can I get a little help ?

Or anyone considers this topic as being irrelevant ?

Can I get at least a feedback on this ?

thanks,
Ladislau



ladislau szilagyi

unread,
Apr 23, 2022, 8:11:37 AM4/23/22
to RC2014-Z80
Hi,

a practical example of using the enhanced OPTIM.COM follows.

Remember the TE editor that I customized for RC2104 systems provided with 128KB RAM?

I use-it frequently to edit large source files.

But, I remember than, some months ago, while building-it, I was "forced" to compile on my RC2014 the TE source files without the "code optimization" option, because of the OPTIM.COM "out-of-memory" issue. 
 
I now modified the make file, adding the code optimization option ( -o )

Now, it works ! (I substituted the "original" OPTIM.COM with my new, enhanced OPTIM)

Here is the execution log, on a SC108 based RC2014:
 
------------------------------------------------------------------------------------------------------------------
D>submit makete

D>c -v -c -o te.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I TE.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oTE.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 68
Finished.

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c teconf.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I TECONF.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:ZAS -N -oTECONF.OBJ $CTMP1.$$$

Z80AS Macro-Assembler V4.7

Errors: 0
Finished.

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o teedit.c
HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I TEEDIT.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oTEEDIT.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 55
Finished.

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o teerror.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I TEERROR.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oTEERROR.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0
Finished.

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o tefile.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I TEFILE.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oTEFILE.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 14
Finished.

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o tekeys.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I TEKEYS.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oTEKEYS.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 19
Finished.

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o telines.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I TELINES.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oTELINES.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 26
Finished.

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o temisc.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I TEMISC.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oTEMISC.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 3
Finished.

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c teui.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I TEUI.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
TEUI.C:497:     constant relational expression (warning)
0:ZAS -N -oTEUI.OBJ $CTMP1.$$$

Z80AS Macro-Assembler V4.7

Errors: 0
Finished.

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c tews100.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I TEWS100.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:ZAS -N -oTEWS100.OBJ $CTMP1.$$$

Z80AS Macro-Assembler V4.7

Errors: 0
Finished.

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>z80as -j dynm128

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 5
Finished.

D>z80as -j tabs

Z80AS Macro-Assembler V4.7

Errors: 0
Finished.

D>z80as -j mycrtcpm

Z80AS Macro-Assembler V4.7

Errors: 0
Finished.

D>submit linkte

D>xsub

D>link
link> -Z -Dte128.sym -N -C -Mte128.map -Ptext=0,data,bss -C100H -Ote128.COM mycrtcpm.obj \

link> te.obj teconf.obj teedit.obj teerror.obj tefile.obj tekeys.obj telines.obj \

link> temisc.obj teui.obj tews100.obj tabs.obj dynm128.obj LIBC.LIB


(xsub active)
D>sdir te.com


Directory For Drive D:  User  0

    Name     Bytes   Recs   Attributes
------------ ------ ------ ------------
TE       COM    32k    235 Dir RW

D>sdir te128.com


Directory For Drive D:  User  0

    Name     Bytes   Recs   Attributes
------------ ------ ------ ------------
TE128    COM    24k    192 Dir RW

D>
------------------------------------------------------------------------------------------

Take a look at the size of the editor: (TE.COM is the old one) 

I gained 8KB just by applying code optimization !!!

I do not think I need to comment further on the advantage to have an enhanced C compiler. The previous example is self-explanatory.

If, however, you decide to ignore this option, it's ok for me, and I will not insist any more on this topic.  

I personally prefer always to fully use the capabilities of my hardware, and if I can use the full power of the 128KB RAM, I will do-it without any hesitation.

Consider please this topic closed.

regards,
Ladislau

Fred Weigel

unread,
Apr 23, 2022, 12:26:16 PM4/23/22
to RC2014-Z80
Ladislau

So, the new OPTIM.COM works on 64K CP/M? If so, I will start using it. I am using your ZAS.COM upgrade, and
I wish o report that (so far) it has worked flawlessly. I will be needing the new float capabilities soon... (compiling
MATLAB for CP/M).

FredW

ladislau szilagyi

unread,
Apr 23, 2022, 10:28:01 PM4/23/22
to RC2014-Z80
Hi Fred,

1. glad to hear that you use Z80AS; please let me know any problem you might have...
2. my new OPTIM was designed to work only on 128KB RAM RC2014's (provided with one of SC108,SC114,SC118 or Phillip Stevens memory module); the idea is to "extend" the malloc reach to the extra 64KB RAM, in order to allow larger source files to be compiled

Ladislau

Aaron

unread,
May 5, 2022, 12:43:29 PM5/5/22
to RC2014-Z80
Hi Ladislau,

I have to thank you for all of your time and work on Z80AS! I am also enthusiastic about an open-source Z80-native compiler toolchain. Your post about decompiling P1.COM is a coincidence, because I have been thinking about the same thing. But before trying to work on P1.COM, I am building the other parts that have been restored, including: C.COM, CPP.COM, OPTIM.COM, CGEN.COM, $EXEC.COM, and DUMP.COM. It has been mostly successful and I would be happy to share my build script, even though the work is not finished yet and some of these components will need modification before self-hosting can be achieved.

Aaron

Alan Cox

unread,
May 5, 2022, 2:22:35 PM5/5/22
to rc201...@googlegroups.com


On Thu, 5 May 2022 at 17:43, Aaron <aarons...@gmail.com> wrote:
Hi Ladislau,

I have to thank you for all of your time and work on Z80AS! I am also enthusiastic about an open-source Z80-native compiler toolchain. Your post about decompiling P1.COM is a coincidence, because I have been thinking about the same thing. But before trying to work on P1.COM, I am building the other parts that have been restored, including: C.COM, CPP.COM, OPTIM.COM, CGEN.COM, $EXEC.COM, and DUMP.COM. It has been mostly successful and I would be happy to share my build script, even though the work is not finished yet and some of these components will need modification before self-hosting can be achieved.

I will be very interested to see what comes of this. I've started on a slightly different tack trying to build a new native ANSI(ish) compiler that will run in 48K of RAM but whilst a lot of CPU code generation is easy, Z80 is going to be tricky, so it will be really interesting to see how they have approached it.


There is still a lot to do, but I can feed it fairly simple code, or some quite complex stuff and get stuff that's right for a backend. I don't have an actual backend (expression -> native CPU) yet, just some test code that spits out diabolically bad 8080. There are also some gaps in it so far (notably goto/labels and proper handling of comma in type declarations).

The nice thing about C is that (if you ignore all the modern nonsense) it's actually a very simple language with only a couple of deeply weird syntactical funnies (notably that functions are not  int foo(int bar) = { blah; }; )

My main target if Fuzix but I'd like to get it to work with CP/M as well.

Alan

ladislau szilagyi

unread,
May 6, 2022, 1:35:57 AM5/6/22
to RC2014-Z80
Hi, I'm back...

I made some small progress on optimizing P1.COM

Some test samples: (p1new.com is the modified p1.com)
------------------------------------------------
(on RC2014)

D>c -v -c -o part21c.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21C.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
PART21C.C: sub_24c0()
   105:             ReadMem((char*)&regValues[auxR], (char*)poL, sizeof(operand_t));
                                     Out of memory ^

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>CPP -DCPM -DHI_TECH_C -Dz80 -I PART21C.C $CTMP1.$$$

D>p1new $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$

D>

(on Udo Munk's Z80SIM)

I>c -v -c part21b.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21B.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
PART21B.C: sub_1ec1()
   110:                           GetByte((char*)(gPi->     u.o.lhs     )+              1)  (uint8_t) 0x0A) ||
                                                                           Out of memory ^

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

I>CPP -DCPM -DHI_TECH_C -Dz80 -I PART21B.C $CTMP1.$$$

I>p1new $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$

I>
------------------------------------

The good news: P1 was slightly enhanced for all sorts of hardware/simulators (RC2014, Z80SIM, etc.) running CP/M.  Until now, the gain is only 600H (1 and half KB) RAM, allowing P1 to allocate more space for its needs. It's a small gain, but as you see, it works in some cases.

The bad news: P1 might be greatly enhanced for RC2014's provided with 128KB RAM, but this will take some time.

Status of P1 optimization: 

Until now, I managed to disassemble P1, identify the LIBC routines, and optimize some code, directly in the assembler source. I gained by this 600H RAM space. I started also decompiling P1 but until now I was been able to produce only a small number (~10) of (small) C routines from the grand total of 150 (not including the LIBC part). If I will have a complete collection of P1 C sources, I might apply the same trick as in the case of OPTIM.COM (allocate some of the requested space also in the upper 64KB RAM) and only then the optimization will be complete (of course, only for the RC2104's provided with 128KB RAM)

So, eventually, the whole HiTech tool chain will be completely optimized.

Until now:

- CPP is enhanced, accepting also // comments (see https://github.com/nikitinprior/dcpp )
- P1 is in alpha testing (with small improvements over the original)
- OPTIM is in alpha testing (with significant improvements for RC2014's provided with 128KB RAM)
- ZAS may be substituted with Z80AS (still in alpha testing, last version published on 3 May 2022), offering huge improvements over ZAS

By the way, I noticed that CGEN has no issues related to the RAM space available...no "out-of-memory" errors...

The most visible effect for me is that I currently use this new toolchain on my RC2014 (with an SC108 board, provided with 128KB RAM), being able to compile more and more of the old C projects that were impossible to compile on RC2014 due to "out-of-memory" errors... More than that, I am able to compile now on RC2014 some C sources that are impossible to compile on Z80SIM or ZXCC...because of OPTIM that can use 128KB RAM.

Once again, passing to beta testing stage will need some time, it all depends on how many of you will frequently use these tools in order to discover bugs. 
To give you an example, because I currently use each time Z80AS instead of ZAS, I was able to found & fix a number of bugs.

If someone wants to give the 'new' OPTIM and/or P1 a try, please let me know...

I will publish shortly OPTIM on GitHub, it is enough stable to be used (again... only for RC2014's provided with 128 KB RAM hardware)

P1 needs some more internal (alpha) testing, then I will publish-it too...

Ladislau

ladislau szilagyi

unread,
May 6, 2022, 3:14:46 AM5/6/22
to RC2014-Z80
I just published the new OPTIM.COM on GitHub ( https://github.com/Laci1953/RC2014-CPM folder  HiTech C compiler optimization /OPTIM  )

Ladislau

nikitin

unread,
May 6, 2022, 3:54:20 AM5/6/22
to rc201...@googlegroups.com
Hi Ladislau,

I started code recovery P1.COM , but has not yet completed it. The attachment contains disassembled assembly language code and some functions recreated in C. Perhaps this information will be useful to you. I planned to restore this code of the first pass of the compiler and post it on my github. I will be glad if you continue this work and I will be able to fulfill my dream.

Regards
Andrey


6 мая 2022 г., в 08:35, ladislau szilagyi <ladislau...@euroqst.ro> написал(а):

--
You received this message because you are subscribed to the Google Groups "RC2014-Z80" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rc2014-z80+...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/rc2014-z80/0a23bcb2-9999-4a0d-97f4-60c8d0f145b8n%40googlegroups.com.
p1.txt
p1_new.c

ladislau szilagyi

unread,
May 6, 2022, 5:56:09 AM5/6/22
to RC2014-Z80
Thanks Andrey,

I will surely use your files... I'm beginning the design of the P1 for 128KB RAM...

and... I made some progress for the ''normal' P1, now the gain is 700H ...

regards,
Ladislau

ladislau szilagyi

unread,
May 17, 2022, 3:17:38 AM5/17/22
to RC2014-Z80
Hi all,

I have some good news: I managed to optimize P1.COM ( the executable is 4KB smaller compared with the original ).

Some tests:

(ZXCC on CygWin - as expected, all files are compiled ok...)

$ make
zxc -c -o  optim1.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE

zxc -c -o  part21a.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE

zxc -c -o  part21b.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE

zxc -c -o  part21c.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE

zxc -c -o  part21c2.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE

zxc -c -o  part21d.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE

zxc -c -o  part31a.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE

zxc -c -o  part31b.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE

zxc -c -o  part31c.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE

zxc -c -o  part41a.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE

zxc -c -o  part41b.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE

zxc -c -o  ctype1.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE

zxc -c -o  initvar1.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE

zxas -n mylibc.as

zxas -n mycrtcpm.as

zxas -n myalloc.as

zxlink <lkoptim
link> -Z -Doptim1.sym -N -C -Moptim1.map -Ptext=0,data,bss -C100H -Ooptim1.COM mycrtcpm.obj \
link> optim1.obj part21a.obj part21b.obj part21c.obj part21c2.obj part21d.obj  \
link> part31a.obj part31b.obj part31c.obj part41a.obj part41b.obj ctype1.obj initvar1.obj \
link> myalloc.obj mylibc.obj LIBC.LIB

sort <optim1.sym | uniq > optim1.sym.sorted

------------------------------------------------------------------------------

(CP/M on RC2014/SC108/CF64MB with the original HiTech C toolchain - same files... P1 fails again and again... )

D>c -v -c -o part21a.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21A.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
PART21A.C:
    21:     int val_1795;
                        ^ val_1795: storage class redeclared
PART21A.C: sub_1795()
    24: register     inst_t *pi_1795;
                                    ^ identifier redefined: pi_1795
    65:     for (; pi_1795->type !=  0xB   && pi_1795->type !=    8   && pi_1795->type != 0x10   && (pi_1795->type != 0x11   ||
                                                                     simple type required for != ^
                                                                           logical type required ^
    66:           GetByte((char*)(pi_1795->     u.o.lhs )+              1) != (uint8_t) 0x0D);

                  Out of memory ^
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part21c.c
HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21C.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
PART21C.C: sub_24c0()
   183:             aux = (uint8_t)GetByte((char*)op+           1);
                      : storage class redeclared ^
                        illegal conversion of integer to pointer ^  (warning)
   186:                 typ == (uint8_t) 0x46  &&
            : storage class redeclared ^
   188:                !sub_47e0( aux, gPi->pNext, ip) &&
                                 logical type required ^
   194:                 PutByte((char*)op+              1, (char)auxL);
           : storage class redeclared ^
                illegal conversion of integer to pointer ^  (warning)
                                     : storage class redeclared ^

                                                  Out of memory ^
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>

-------------------------------------------------------------------------
(CP/M on RC2014/SC108/CF64MB with the improved HiTech C toolchain - P1 works ok , but now CGEN fails sometimes...)

D>pip cpp.com=newcpp.com
D>pip p1.com=newp1.com
D>pip optim.com=newoptim.com
D>pip zas.com=z80as.com

D>c -v -c -o part21a.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21A.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
PART21A.C:68:   No room

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part31a.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART31A.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oPART31A.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 15
Finished.

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part41b.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART41B.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oPART41B.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 62
Finished.

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>

-------------------------------------------------------------------------------------------------------------------------------

Now, I will try to work on CGEN...

A short status report on the HiTech C toolchain optimization:

- CCP is OK (thanks Andrey Nikitin ...), works on all RC2014 hardware configurations (the nice thing is that it accepts also //comments )
- P1 is OK , works on all RC2014 hardware configurations 
- CGEN - last weak point, working on it...
- OPTIM is OK for all RC2104 128KB RAM hardware
- ZAS is OK (substituted with Z80AS), works on all RC2014 hardware configurations 

Some comments about the optimized P1: I worked directly on the assembler sources (identified unused code, duplicate code, not optimal code).
I gained 4KB RAM, which is good enough for most cases of C sources passing compile under ZXCC, but failing with the "original" P1.COM on RC2014.
So, now the P1 optimization is complete.
Unfortunately, the goal to obtain the C source code for P1 is still far away, there is a lot of work to be done...

Now, I'm focusing CGEN.COM.

I will try to obtain a smaller CGEN.COM, but I'm working also to make-it allocate on the upper 64KB RAM (for RC2014's provided with 128KB RAM), which will practically solve the problem.

Ladislau
PS. I will soon publish the new P1.COM, I'm still testing it...

ladislau szilagyi

unread,
May 17, 2022, 3:45:12 PM5/17/22
to RC2014-Z80
Hi,

As promised, I started working on CGEN.COM.

My first problem was that some of the source files from Andrey's CGEN GitHub directory fail to compile on ZXCC, because OPTIM reports "out-of-memory".

Do you now how I solved this issue?

Well, I used my small and humble RC2014 to run my enhanced OPTIM.COM on those files... and it worked perfectly.

Now, I have a fully functional clone of CGEN.COM and I'm starting optimizing it...

Ladislau

ladislau szilagyi

unread,
May 25, 2022, 2:47:05 AM5/25/22
to RC2014-Z80
Hi,

first of all, I want to thank Andrey Nikitin and Mark Ogden for their outstanding quality work on decompiling CGEN.

Thanks to them, I had a very good starting point for the optimization of the CGEN.COM for the RC2014's provided with 128KB RAM.

And, it seems I am on the good path...the first tests of the "new" CGEN are a success!

Here are some samples, obtained by running the 'submit' file that I use to build the "optimized" OPTIM:

(this was run on an RC2014 with SC108 - 128KB RAM)

(first, try with the "old" set of HiTech tools)

(comments marked with ***)

-----------------------------------------------
D>type makeopt.sub
c -v -c -o ctype1.c
c -v -c -o initvar1.c
c -v -c -o optim1.c

c -v -c -o part21a.c
c -v -c -o part21b.c

c -v -c -o part21c.c
c -v -c -o part21c2.c
c -v -c -o part21d.c

c -v -c -o part31a.c
c -v -c -o part31b.c
c -v -c -o part31c.c
c -v -c -o part41a.c

c -v -c -o part41b.c

D>submit makeopt

D>c -v -c -o ctype1.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I CTYPE1.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oCTYPE1.OBJ $CTMP2.$$$

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o initvar1.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I INITVAR1.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oINITVAR1.OBJ $CTMP2.$$$

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o optim1.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I OPTIM1.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
OPTIM1.C:
   318: int strtoi(char  *s, int base) {
                           ^ s: storage class redeclared
OPTIM1.C: strtoi()
   319:     int val;
                   ^ val: storage class redeclared
   320:     int digit;
                     ^ digit: storage class redeclared
   322:     val = 0;
            ^ not a variable identifier: val
                   ^ only lvalues may be assigned to or modified
   324:         val *= base;
                ^ not a variable identifier: val
                           ^ only lvalues may be assigned to or modified
             type conflict ^
                           ^ illegal conversion
   326:             digit = *(s++) - '0';
                    ^ not a variable identifier: digit
                                        ^ only lvalues may be assigned to or modified
                     illegal conversion ^
   329:                 digit = (     ( ccClass[*s] &  1         ) ? (char)(*s | 0x20) : (char) * s) - ('a' - 10);
                        ^ not a variable identifier: digit
                                                                     only lvalues may be assigned to or modified ^
                                                                                              illegal conversion ^
   333:         if (digit >= base) {
                    ^ not a variable identifier: digit
                                 ^ illegal use of void expression
   337:         val += digit;
                ^ not a variable identifier: val
                       ^ not a variable identifier: digit
                            ^ only lvalues may be assigned to or modified
              type conflict ^
   339:     return val;
                   ^ not a variable identifier: val
                      ^ illegal conversion

(***OPTIM crashes, so I rebooted...)

Small Computer Monitor - S3
*cpm
RC2014 CP/M BIOS 1.2 by G. Searle 2007-18

CP/M 2.2 Copyright 1979 (c) by Digital Research

A>c -v -c -o part21a.c
C?

A>d:

(***let's continue, file by file, by manual compile commands...)

D>c -v -c -o part21a.c
HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21A.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
PART21A.C:
    21:     int val_1795;
                        ^ val_1795: storage class redeclared
PART21A.C: sub_1795()
    24: register     inst_t *pi_1795;
                                    ^ identifier redefined: pi_1795
    65:     for (; pi_1795->type !=  0xB   && pi_1795->type !=    8   && pi_1795->type != 0x10   && (pi_1795->type != 0x11   ||
                                                                     simple type required for != ^
                                                                           logical type required ^
    66:           GetByte((char*)(pi_1795->     u.o.lhs )+              1) != (uint8_t) 0x0D);
                  Out of memory ^
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part21b.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21B.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
PART21B.C: sub_1ec1()
    43:                          GetByte((char*)(gPi->     u.o.lhs      )+              1) == (uint8_t) 0x07 &&
D>c -v -c -o part21c2.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21C2.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oPART21C2.OBJ $CTMP2.$$$

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part21d.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21D.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
PART21D.C: sub_2ef8()
    37:                  regValues[     0x05].aux == regValues[ 0x04].aux && regValues[ 0x05].     term.val + 1 == regValues[   0x04].     ter 
                                                     Out of memory ^
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part31a.c
HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART31A.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
PART31A.C:
    17:     0x01,
                ^ simple type required for @
                ^ illegal conversion
    49:     int valO;
                    ^ valO: storage class redeclared
PART31A.C: evalOperand()
    52: register     operand_t *operO;
                                     ^ operO: storage class redeclared
    58:     operO = allocOperand();
                                  ^ only lvalues may be assigned to or modified
               illegal conversion ^
    63:             PutByte((char*)operO+       0, (uint8_t) 0);
                                  ^ : storage class redeclared

                          Out of memory ^
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

>c -v -c -o part31b.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART31B.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
PART31B.C: loadFunction()
   120:                         if (psF->label[0] != 'f')
                                  type conflict ^
   128:                         if ( GetByte((char*)(piF->     u.o.lhs  )+      0) != (uint8_t)0x32   ||
                                                                   : storage class redeclared ^
   129:                              GetWord((char*)(piF->     u.o.lhs  )+      4       ) )
                                                                    logical type required ^
                                                                    logical type required ^
                                                                    logical type required ^
   132:                         fpBase    =  GetWord((char*)(piF->     u.o.lhs  )+      2       );

                                                                                  Out of memory ^
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part31c.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART31C.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
PART31C.C: sub_404d()
   166:                     valid = IsValid((char*)pop);

                       : storage class redeclared ^
             illegal conversion of integer to pointer ^  (warning)
   175:                     v = GetWord((char*)pop+     2       );
                   : storage class redeclared ^
                                                  type conflict ^
                                             illegal conversion ^
   204:             else if (valid && !usesIXorIY && pi->type ==  0xB   && pi->aux == 0 && pi->pNext->aux == 0 &&
                                                            simple type required for == ^
                                                                  logical type required ^
                                                                                         logical type required ^
   205:                        sub_4000(pi->pNext) &&  ps->label[0] == '_')
                                                    logical type required ^
                                                    logical type required ^
                                                    logical type required ^
PART31C.C: pr_instruction()
   248:         ps_i = (sym_t*)GetWord((char*)po_i+     4       );
                  : storage class redeclared ^
                                                  type conflict ^
                                             illegal conversion ^
   264:                strcmp( ps_i->label, "csv") == 0)
                                 logical type required ^
   273:         if (pi->type ==    8   || pi->type ==  0xB   || pi->type ==  0xC  )
                                                      simple type required for == ^
                                                             too much indirection ^
                                                            logical type required ^
   277:             if (pi->aux != 0)
               pointer required ^

(***P1 crashes, so I rebooted...continuing compile file by file...)

Small Computer Monitor - S3
*cpm
RC2014 CP/M BIOS 1.2 by G. Searle 2007-18

CP/M 2.2 Copyright 1979 (c) by Digital Research

A>d:
D>c -v -c -o part41a.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART41A.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
PART41A.C: sub_436e()
    14:     operand_t local_pi;
                              ^ local_pi: storage class redeclared
    15:     operand_t *pi = &local_pi;
                          ^ pi: storage class redeclared
                          ^ can't initialise auto aggregates
    21:     ReadMem((char*)&local_pi, (char*)pi_arg, sizeof(operand_t));
                          ^ : storage class redeclared
                                    ^ can't take address of register variable
            can't take this address ^
                 illegal conversion ^
    24:     switch (pi->type) {
           pointer required ^
                            ^ struct/union required
    27:             fputc('(',  (&_iob[1]));

                           Out of memory ^
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part41b.c
HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART41B.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
PART41B.C: sub_47e0()
    42:         fprintf(        (&_iob[2]), "%d\n", reg);
         illegal conversion between pointer types ^  (warning)
    50:         if (IsValid((char*)pi1->     u.o.lhs    ))
                                  ^ : storage class redeclared
               illegal conversion between pointer types ^  (warning)
    53:             ps = (sym_t*)GetWord((char*)po+     4       );
                                ^ : storage class redeclared
                                              illegal conversion ^
    75:                      ps->label[0] == '_')

                                  Out of memory ^
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$


------------------------------------------

(and now, with the new set of HiTech tools : ZAS, CPP,  P1, CGEN, OPTIM are all substituted with the "new" optimized variants...)

D>submit makeopt

D>c -v -c -o ctype1.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I CTYPE1.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oCTYPE1.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0
Finished.
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o initvar1.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I INITVAR1.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oINITVAR1.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0
Finished.
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o optim1.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I OPTIM1.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
OPTIM1.C:1017:  No room

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part21a.c
HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21A.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oPART21A.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 47

Finished.
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part21b.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21B.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
PART21B.C: sub_1ec1()
   197:                              GetByte((char*)(gPi->pNext->     u.o.lhs   )+              1) == (uint8_t) 0x11) {

                                                                                   Out of memory ^
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part21c.c
HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21C.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
PART21C.C:123:  No room

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part21c2.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21C2.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oPART21C2.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 10

Finished.
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part21d.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21D.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$

(***P1 crashes, so I rebooted...continuing compile file by file...)

Small Computer Monitor - S3
*cpm
RC2014 CP/M BIOS 1.2 by G. Searle 2007-18

CP/M 2.2 Copyright 1979 (c) by Digital Research
A>d:
D>c -v -c -o part31a.c
HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART31A.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oPART31A.OBJ $CTMP2.$$$
Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 15
Finished.
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part31b.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART31B.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oPART31B.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 43

Finished.
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part31c.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART31C.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oPART31C.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 48

Finished.
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part41a.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART41A.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oPART41A.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 54

Finished.
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part41b.c
HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART41B.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oPART41B.OBJ $CTMP2.$$$
Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 62
Finished.
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>
----------------------------------------------------

Summary of results:

File                   Size(KB)                 Old HiTech tools                                           New HiTech tools

ctype1.c          2                              ok                                                                     ok
initvar.c           4                              ok                                                                     ok
optim1.c         50                            OPTIM crashes                                              OPTIM: no room
part21a.c        10                            P1: out of memory                                        ok
part21b.c        19                            P1: out of memory                                        P1: out of memory
part21c.c        12                            P1: out of memory                                        CGEN: no room
part21c2.c      4                              ok                                                                     ok
part21d.c        14                            P1: out of memory                                        P1 crashes
part31a.c         7                             P1: out of memory                                        ok
part31b.c        11                            P1: out of memory                                        ok
part31c.c         8                             P1 crashes                                                      ok
part41a.c         9                             P1: out of memory                                         ok
part41b.c         14                          P1: out of memory                                         ok


There is an obvious progress,  but there is still room for improvement...

I will soon publish the new P1, I'm done with the tests.

I'm still working and testing the "optimised" GGEN, on both versions:
- for "usual" RC2014
- for RC2014's with 128 KB RAM

Ladislau

Phillip Stevens

unread,
May 26, 2022, 12:05:07 AM5/26/22
to RC2014-Z80
Ladislau wrote:

Summary of results:

File                   Size(KB)                 Old HiTech tools                                           New HiTech tools

ctype1.c          2                              ok                                                                     ok
initvar.c           4                              ok                                                                     ok
optim1.c         50                            OPTIM crashes                                              OPTIM: no room
part21a.c        10                            P1: out of memory                                        ok
part21b.c        19                            P1: out of memory                                        P1: out of memory
part21c.c        12                            P1: out of memory                                        CGEN: no room
part21c2.c      4                              ok                                                                     ok
part21d.c        14                            P1: out of memory                                        P1 crashes
part31a.c         7                             P1: out of memory                                        ok
part31b.c        11                            P1: out of memory                                        ok
part31c.c         8                             P1 crashes                                                      ok
part41a.c         9                             P1: out of memory                                         ok
part41b.c         14                          P1: out of memory                                         ok

There is an obvious progress,  but there is still room for improvement...
I will soon publish the new P1, I'm done with the tests.

It is an obvious, but very rhetorical, question but, if the original P1 and OPTIM can't compile CGEN, then the how did Hi-Tech build their compiler release files in the first place?

I guess they must have had some other cross compile tools, or something else of that nature.
I'm interested to know if anyone has any background or thoughts on how it was done.

P.

Alan Cox

unread,
May 26, 2022, 8:06:39 AM5/26/22
to rc201...@googlegroups.com

I guess they must have had some other cross compile tools, or something else of that nature.
I'm interested to know if anyone has any background or thoughts on how it was done.

They offered Z80 cross compilers on PC, in fact they had a whole family of compiler products. The CP/M Z80 one was given to the community as a nice gesture when it ceased to be relevant. I'd imagine by then they were not compiling anything on 8bit micros.

Hi-tech were eventually bought by Microchip, although I think all the products are now discontinued in favour of MPLAB.

Alan

Phillip Stevens

unread,
May 26, 2022, 9:01:39 PM5/26/22
to RC2014-Z80
Alan wrote:

I guess they must have had some other cross compile tools, or something else of that nature.
I'm interested to know if anyone has any background or thoughts on how it was done.

They offered Z80 cross compilers on PC, in fact they had a whole family of compiler products. The CP/M Z80 one was given to the community as a nice gesture when it ceased to be relevant.

Just thinking. I’ve a copy of the MS-DOS v7.80 Version. That should be able to ingest the sources without a hiccup, and would be a good comparison point for Ladislau’s work.

But it wouldn’t really answer the question of what was used to compile v3.09. Because, time travel.

P.

Bill Shen

unread,
May 26, 2022, 10:10:55 PM5/26/22
to RC2014-Z80
Ladislau is doing wonderful work but I've been wondering if another approach is to develop a loadable barebone CP/M that maximize the available TPA.  Use the barebone CP/M to compile code and then boot up the original CP/M to execute.  Perhaps this is how HiTech was able to compile its own C executables?

Too bad I don't have much time in the summer, I really would love to try the many improvements in HiTech C.
  Bill

Alan Cox

unread,
May 26, 2022, 10:15:09 PM5/26/22
to rc201...@googlegroups.com
On Fri, 27 May 2022 at 03:10, Bill Shen <coinst...@gmail.com> wrote:
Ladislau is doing wonderful work but I've been wondering if another approach is to develop a loadable barebone CP/M that maximize the available TPA.  Use the barebone CP/M to compile code and then boot up the original CP/M to execute.  Perhaps this is how HiTech was able to compile its own C executables?

There were several commercial high end CP/M and MP/M compatible OS with a 62-63K or so TPA. It probably wouldn't be too hard to modify ZSDOS to work this way. Basically nothing was in the TPA but jump tables, required data, and some stubs that paged in the OS.   The only tricky bit is managing the copies to/from the OS and also direct disk I/O efficiently

Fred Weigel

unread,
May 26, 2022, 11:19:31 PM5/26/22
to RC2014-Z80
You don't know the original source... It may have been one function per file! You also presume that 3.09 was
used to compile itself... I would think that is a very nice goal for the reconstruction. Back then Whitesmiths C
was available in native and cross versions... I used the 8080 native (CP/M) and VAX cross Z80 versions. As I
think HiTech was to compete with Whitesmiths C (and not BDS C), it may have been the same...

FredW

ladislau szilagyi

unread,
May 27, 2022, 3:39:49 AM5/27/22
to RC2014-Z80
Hi,

About the "minimal CP/M": I actually use "my custom" CP/M, with the smallest possible BIOS, tailored for 64MB CF's, and without using SIO/ACIA interrupts (to gain space).
My CCP+BDOS starts at 0BA00H ( CCP ends at ~ 0C200H), BIOS starts at 0F000H.
Therefore, I have a TPA larger with 2 and half KB, compared with the "classic" RC2014 CP/M (where CCP+BDOS starts at 0B000H).

About compiling HiTech toolchain on HiTech under CP/M: there are some C source files that cannot be processed on CP/M, even it the TPA has 64KB. 

Example: I was able to use OPTIM on some CGEN C sources ONLY on a RC2014 with 128KB RAM ( my statistics proved that 40 to 50KB were used on the "upper" 64KB RAM by OPTIM to allocate stuff... so, on a 64KB system, this is "mission impossible" - this fact was noticed also by Mark Ogden, while trying-and failing- to compile CGEN on ZXCC, without an "external" optimizer).

So, I was lucky to have first my OPTIM already working on a 128KB RAM machine, otherwise I would have failed to build the CGEN starting from the C sources published by Andrey Nikitin & Mark Ogden.

Now, I'm working on CGEN (on both versions : 64KB & 128KB RAM - they are already functional...), trying to gain some space by code optimization at the assembler level.

I still have to publish the optimized P1... I just have too much work to do... but I hope I will publish-it this weekend.

Ladislau

ladislau szilagyi

unread,
May 27, 2022, 9:56:01 AM5/27/22
to RC2014-Z80
Hi,


It works on any Z80-based computer running CP/M. 
 Compared to the original HiTech P1.COM, it is smaller by 4KB (the RAM space available to be allocated is larger with 4KB). 
 The immediate advantage is to being capable to compile larger C source files... 

 Here is the original P1.COM map: 
TOTAL           Name         Link     Load   Length
                (abs)           0        0        0
                text          100      100     89B4
                data         8AB4     8AB4     11FB
                bss          9CAF     9CAF      801    end at 0A4B0H

Here is the new P1 map:
TOTAL           Name         Link     Load   Length
                (abs)           0        0        0
                text          100      100     8440
                data         8540     8540      8E8
                bss          8E28     8E28      681    end at 094A9 ( 1007H = 4KB less !!! )
                top          94A9     94A9       F5

To obtain this, I followed a less-used path... because I did not had the C sources, I started working directly on the disassembled source file. 
 So, all the work was done on Z80 assembler sources. 

 What I did: 
- eliminated duplicated (yes, I found 2 routines with exactly the same content...) or unused code (mostly, from the parts belonging to the C library) 
- changed the size of buffer used for file input (from 512 to 128) 
- optimized frequent used parts of code (compares - instead of word compares using SBB HL,RR I opted for a simple CP R, returns from C functions containg the same sequences of code, replaced with a jump to the "common" sequence,... ) 
- placed the initialization-related code (the "top" PSECT) after the bss segment (once executed, that code can be dumped...) 
- changed a lot of warning/error message calls, using a simpler (and shorter...) message containing only an error index instead of the original error/warning text (of course, a numbered list of error/warning messages is provided) ; I kept all fatal error messages untouched... 

 The P1 source files (in the folder SOURCES) must be assembled using Z80AS; submit files to assemble and link are provided.

Ladislau

Bill Shen

unread,
May 27, 2022, 4:00:04 PM5/27/22
to RC2014-Z80
Ladislau,
Something is not right with your minimal CP/M CCP/BDOS/BIOS addresses.  I have a CP/M2.2 design that I used successfully for many Z80/Z180/Z280 boards where the CCP starting address is $DC00, BDOS starts at $E400 and BIOS starts at $F200.  There are plenty of unused space in the my BIOS, about 1.7K.

I think it is possible to move your CCP start address from $BA00 to $DA00 and gain 8K more space.  With further minimization it should be possible to move CCP up to $E000
  Bill

ladislau szilagyi

unread,
May 27, 2022, 11:45:55 PM5/27/22
to RC2014-Z80
Hi Bill,

Yes, you're right, my mistake...sorry! 

The correct numbers are: "classic RC2014 CP/M" BDOS starts at 0D000H, my enhanced CP/M BDOS starts at 0DA00H.

Ladislau

ladislau szilagyi

unread,
May 28, 2022, 11:35:39 AM5/28/22
to RC2014-Z80
Hi,

I finally finished the work on the HiTech toochain.

Today, I tested the enhanced CGEN.COM on my RC2014 provided with 128KB RAM.

The results:

--------------------------------------------------
Jump optimizations done: 46

Finished.
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part21b.c
HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21B.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
PART21B.C: sub_1ec1()
   199:                             PutByte((char*)(gPi->pNext->     u.o.lhs    )+              1, GetByte((char*)(gPi->pAlt->     u.o.lhs      )+              1));

                                                                                                                      Out of memory ^
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part21c.c
HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21C.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oPART21C.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 64

Finished.
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part21c2.c
HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21C2.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oPART21C2.OBJ $CTMP2.$$$
Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 10
Finished.
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part21d.c
HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART21D.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
PART21D.C:38:   No room

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o part31a.c
HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I PART31A.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oPART31A.OBJ $CTMP2.$$$
Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 15
Finished.
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>z80as mylibc

Z80AS Macro-Assembler V4.7

Errors: 0
Finished.

D>z80as mycrtcpm

Z80AS Macro-Assembler V4.7

Errors: 0
Finished.

D>z80as -j myalloc

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 2
Finished.

------------------------------------------------------------

As you see, no more crashes!

The comparison with the "original" HiTech toochain:

Summary of results:

File                   Size(KB)                 Old HiTech tools                                           New HiTech tools

ctype1.c          2                              ok                                                                     ok
initvar.c           4                              ok                                                                     ok
optim1.c         50                            P1 crashes                                                     P1: no room

part21a.c        10                            P1: out of memory                                        ok
part21b.c        19                            P1: out of memory                                        P1: out of memory
part21c.c        12                            P1: out of memory                                        ok
part21c2.c      4                              ok                                                                     ok
part21d.c        14                            P1: out of memory                                        GCEN : no room

part31a.c         7                             P1: out of memory                                        ok
part31b.c        11                            P1: out of memory                                        ok
part31c.c         8                             P1 crashes                                                      ok
part41a.c         9                             P1: out of memory                                         ok
part41b.c         14                          P1: out of memory                                         ok

----------------------------------------------------------

I consider now the job done.

The new HiTech tools clearly outperform  the old tools, when executed on a computer with 128KB RAM.
Clearly, the best improvement was obtained on OPTIM, the version for 128KB RAM.

Even on a 64KB RAM computer, the P1 and CGEN give better results.

I will publish tomorrow the enhanced CGEN.COM, both versions: for 64KB RAM and for 128KB RAM computers.

Of course, the 128KB RAM version is better: for the 64KB RAM version, I gained only a half KB of RAM, while for the 128KB version,  all the allocated strings are now stored on the upper 64KB RAM, offering a lot of more free RAM for other objects to be allocated.

I am waiting for your feedback about the practical use of these new HiTech tools...

Ladislau

ladislau szilagyi

unread,
May 29, 2022, 2:43:34 AM5/29/22
to RC2014-Z80
Hi,

I added CGEN to my GitHub folder ( https://github.com/Laci1953/RC2014-CPM/tree/main/HiTech%20C%20compiler%20optimization ) containing the enhanced HiTech tools.

Now, the list is complete: CPP, P1, CGEN, OPTIM, Z80AS.

This work was based on the decompiled HiTech tools found at https://github.com/nikitinprior

Thanks to the excellent work of Andrey Nikitin and Mark Ogden, I was able to have a very solid foundation to build on.

The main goal of this project was to obtain an enhanced HiTech C compiler toolchain, to be used in two environments:

1 : generic, for all Z80 computers running CP/M 2.2
2 : specific, only for RC2014's provided with 128 KB RAM (SC108, SC114, SC118 or Phillip Stevens memory module) running CP/M 2.2

For the second (specific) environment, the basic idea was to use the upper 64KB RAM to extend the RAM space available for the HiTech tools.
This was done by intercepting (part of) the malloc/free calls used by a tool, by using some extra assembler code, to return pointers not from the "usual" lower 64KB RAM, but from the upper 64 KB RAM.
Practically, a new "memory allocator" was written, to handle the upper 64KB RAM space.
Of course, all the references to those pointers, in the C sources, must be handled by special routines, to move bytes from/to the upper 64KB RAM to the lower 64KB RAM.

Obviously, this means some extra code is executed, compared to the "original" HiTech tools, resulting in a longer execution time.

However, this loss of speed ( 10 to 15% ) is largely compensated by the big advantage obtained: to be able to compile larger C source files.

The results:

For the generic environment (all Z80 computers running CP/M 2.2) some limited improvements were obtained, mainly for P1 (4KB more RAM available)

For RC2014's provided with 128 KB RAM (SC108, SC114, SC118 or Phillip Stevens memory module) and 64MB CF,
some significant improvements were obtained, listed below:

- P1 (4KB more RAM available)
- CGEN (using the upper 64KB RAM for some of the malloc's)
- OPTIM (using the upper 64KB RAM for some of the malloc's)

The most significant improvement for this second environment (128KB RAM computers), is that OPTIM can handle now files that cannot be compiled on any available Z80 computer, including here also the emulators/simulators (Z80SIM, ZXCC).

For example, I was able to compile some of the CGEN files ONLY on my SC108 based RC2014. 
Z80SIM and ZXCC failed to run OPTIM on those files ("no room"), while the enhanced OPTIM, executed on my SC108 based RC2014, finished the job without any problem.

Also, do not forget my Z80AS, it must be added to this new toolset, to eliminate all the worries related to the size of files to be assembled.

As a conclusion, I consider this new HiTech tools as an improvement over the "classic" HiTech tools. 

Mainly, the RC2014's provided with 128 KB RAM can now take full advantage of having more memory space, while working with the HiTech C tools.

Ladislau

PS. I'm waiting for your feedback related to the use of this new HiTech toolchain...

ladislau szilagyi

unread,
Jun 1, 2022, 10:52:12 AM6/1/22
to RC2014-Z80
Hi,

I'm still polishing the new CGEN...

Now the CGEN.COM is 1KB smaller compared with the original.

Just updated the executable for 64KB RAM RC2014's on GitHub.

Ladislau

ladislau szilagyi

unread,
Jun 6, 2022, 9:37:21 AM6/6/22
to RC2014-Z80
Hi,

these days I intend to try to optimize the OPTIM.COM, for the generic case of 64KB RAM computers (remember, I already have solved the issue for the 128KB RAM computers...).

I will work on the assembler sources, not on the C sources.

The big question is: how much will I be able to reduce the size of the code, compared to the "original" OPTIM.COM ? Do you think it's worth the effort?

What's your opinion?

Ladislau

Fred Weigel

unread,
Jun 9, 2022, 8:59:35 AM6/9/22
to RC2014-Z80
Ladislau

I use this compiler on an Altair-Duino, so *I* think it would be a very good thing.

Fred Weigel

Phillip Stevens

unread,
Jun 12, 2022, 9:03:28 AM6/12/22
to RC2014-Z80
these days I intend to try to optimize the OPTIM.COM, for the generic case of 64KB RAM computers (remember, I already have solved the issue for the 128KB RAM computers...).
I will work on the assembler sources, not on the C sources.

The big question is: how much will I be able to reduce the size of the code, compared to the "original" OPTIM.COM ? Do you think it's worth the effort?

Ladislau,

for interest, I've just gone through all of the z88dk benchmarks and redone them against Tony's v309-15 Release.
This "standard" code was able to handle everything except the whetstone benchmark verification, with printf() enabled, where optim failed out of memory.

Anyway, you can see the resulting code sizes, and timings done with z88dk-ticks.
The benchmarks are some relatively complex examples that you might find useful for testing or reference.

Cheers, Phillip

ladislau szilagyi

unread,
Dec 6, 2022, 11:46:54 AM12/6/22
to RC2014-Z80
Hi all,

I just published on GitHub ( https://github.com/Laci1953/RC2014-CPM/tree/main/HiTech%20C%20compiler%20optimization/P1/128 ) an improved version of the P1.com, intended to be used on all 128KB RAM RC2014 configurations.
It enables the C compiler to process larger files, compared to the original version. 
It uses the upper 64 KB RAM to store data (instead of using malloc). 
Works ONLY for systems provided with both: 
 - 128 KB RAM (SC108, SC114, SC118 or Phillip Stevens memory module) 
 - CP/M from the folder PutSys ( https://github.com/Laci1953/RC2014-CPM/tree/main/PutSys )
 Best results are obtained with RC2014's provided with 64MB CF, due to larger TPA.

Now, for the 128KB RAM RC2014 configurations, all the HiTech tools (CPP, P1, CGEN, OPTIM, ZAS) are optimized, allowing to process larger C files.

Ladislau

ladislau szilagyi

unread,
Dec 8, 2022, 1:59:10 PM12/8/22
to RC2014-Z80
Hi,

to get an idea about the capabilities of this new version of P1, I made an experiment.

I took the source for OPTIM, optim.c , published on https://github.com/nikitinprior/doptim

It's size: 135KB.

First, I obtained the CPP output for this file:

D>c -v -c optim.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I OPTIM.C $CTMP1.$$$
^C
...

I used the command:
D>CPP -DCPM -DHI_TECH_C -Dz80 -I OPTIM.C optim.p1

...to obtain the CPP output.

Then, I tried my new P1:

D>p1new -n optim.p1 x y
25 KB used from the upper 64KB RAM

D>

...and, as you noticed, it worked!

(useless to say, the old P1 fails miserably...)

D>p1 optim.p1 x y
OPTIM.C: get_token()
   944:                     *pc++ =         (--charsLeft >= 0 ? *ptr_inbuf++ : get_line());
                    Out of memory ^

D>

The good news is that even larger files can be processed by the new P1 ( optim.c "consumed" only 25KB from 64KB)

Ladislau

Bill Shen

unread,
Dec 8, 2022, 8:34:37 PM12/8/22
to RC2014-Z80
Impressive.  I have a barebone CP/M with 59K of TPA which was sufficient to compile 'te' editor with the original HiTech v3.09.  I downloaded optim.c and followed your instruction and tried "p1 optim.p1 x y" and it ran out of memory as well.  Now I need to figure out how to configure SC108 to run your p1new.
  Bill

a>p1 optim.p1 x y
OPTIM.C: ÉH()
   782: int sub_47a2(operand_t  *, int);
                        Out of memory ^

ladislau szilagyi

unread,
Dec 9, 2022, 1:30:38 AM12/9/22
to RC2014-Z80
Hi Bill,

I omitted to mention that during my "experiment" using optim.c I encountered an unexpected issue.

While trying to obtain the output from CCP ...

CPP -DCPM -DHI_TECH_C -Dz80 -I OPTIM.C OPTIM.P1

... and using-it to test my new P1, I noticed that I kept receiving some strange error messages from my new P1, like the following one:

D>p1new optimold.p1 x y
OPTIM.C: sub_15ad()
  1697:                         logOptimiseEACH_LAB);
                                ^ Error #72 logOptimiseEACH_LAB
                                        ; expected ^

Investigating the case, I discovered that the problem was related to the OPTIM.P1 file, which effectively contained that strange line: 

 logOptimiseEACH_LAB);

instead of the correct one:

logOptimise(O_UNREACH_LAB);

It turned out that the source file OPTIM.C contained some unusual long lines ( > 120 chars), and I was constrained to "fix" by hand the OPTIM.P1 , in order to continue the experiment.

The issue is present with both the "old" original CPP and the "new" CPP published by Andrey Nikitin & Mark Ogden...

LESSON: keep the C source lines as short as you can (max. 100 chars seems to be a good choice)

Now, about how to configure an RC2014 using SC108 to be able to use my "new" HiTech toolset, it's simple.

You must install the CPM from my PutSys folder ( https://github.com/Laci1953/RC2014-CPM/tree/main/PutSys ) , according to the hardware you have ( serial & CF size), then you must replace the "old" HiTech .COM files (CPP, P1, CGEN, OPTIM, ZAS) with my version of these files.

You will get a CP/M system able to compile quite large C sources...and of course, you may use also my version of the TE editor to edit large source files. 

The only drawback of this configuration is that my BIOS does NOT use interrupts, therefore DOWNLOAD.COM will fail.
Instead, I built my own "download" ( https://github.com/Laci1953/RC2014-CPM/tree/main/DOWNLOAD ), also able to handle larger files.

I hope these clarifications will help anyone willing to test my "custom" CP/M built specially for RC2014's provided with SC108 boards...

regards,
Ladislau

Bill Shen

unread,
Dec 9, 2022, 10:11:30 AM12/9/22
to RC2014-Z80
I set up a SC114 with KIO and CF board.  Install your "KIO_PutSys_CF64_CPM_DA00H.hex" and use XMODEM to bring in original HiTech files.  SC114 is running 20MHz.  Did a test run making TE with "submit makete.sub" and see everything compiled except "out of memory" with TEEDIT.C which is expected.  Now I bring in Z80AS, P1NEW, OPTIMNEW, CPPNEW, and CGEN128 and renamed them to replace the original HiTech files.  Ran makete.sub again but the program hung at cgen.  Hmmm...

Try another angle, reload P1NEW.COM and run optim.c like you did yesterday, I got "out of memory" again.  Slow down the clock to 7.37MHz didn't make any difference.  So...

Comparing SC108 to SC114/SC118/feilipu memory module, I see the bank switching logic is different.  For SC108 it is data 7 on I/O address 0x38, for SC114 etc it is data 0 on I/O address 0x30.  Perhaps the bank switching implementation for SC114 is not working?

I'll try this again on a SC108
  Bill
-----------------------------------------
A>xmodem optim.c /r/z1

File created
Receiving via CON with CRCsC
OK
Received 1021 blocks
A>c -v -c optim.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I OPTIM.C $CTMP1.$$$
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

A>CPP -DCPM -DHI_TECH_C -DZ80 -I OPTIM.C OPTIM.P1

A>P1NEW -N OPTIM.P1 X Y
OPTIM.C: get_token()
   927:                 *pc++ =         (--charsLeft >= 0 ? *ptr_inbuf++ : get_line());
                Out of memory ^

ladislau szilagyi

unread,
Dec 10, 2022, 1:00:44 AM12/10/22
to RC2014-Z80
Hi Bill,

the problem is the different ports used by SC108 and SC114 to select the 64KB RAM banks.

The solution is to re-compile CGEN, P1, OPTIM starting from the sources, but modifying first alloc128.as (in case of CGEN), p1alloc.as (in case of P1) and myalloc.as (in case of OPTIM), by changing the SC108 setting to 0. Z80AS must be used as assembler.

Then, it will work as designed.

Ladislau

Bill Shen

unread,
Dec 10, 2022, 7:45:21 AM12/10/22
to RC2014-Z80
Thank you for your help.  I visited your GitHub site just now and downloaded HiTechC software and updated my existing HiTechC.  The new files are: Z80AS, P1V128, OPTIMNEW, CPPNEW, and CGEN128.  I noticed P1V128 was updated just today.

My setup are KIO, SC108, and CF boards.  I did a test run by compiling TE using makete.sub.  I'm not successful; the new P1 hung indefinitely.  I notice SC108's ROM LED will turn on (RAM paged out and ROM paged in) as soon as P1 starts executing.  I've updated CP/M with your "KIO_PutSys_CF64_CPM_DA00H.hex".

I will go back to the baseline RC2014Pro by replacing KIO board with SIO board and try again.
  Bill
PS, I'm please to know that memory management routines are localized and can be modified.  I would like to try 512K RAM/ROM board and other banked memory designs.
------------------------------------
A>C -V -C TECONF.C

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I TECONF.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$  <--program hang here

Press [SPACE] to activate console

Bill Shen

unread,
Dec 10, 2022, 8:20:20 AM12/10/22
to RC2014-Z80
Oh, I think I see the problem.  In p1alloc.as you page in the ROM and search for a "mover" routine at top of ROM memory, but I'm using the original RC2014 ROM monitor, not SCMonitor, so there are no "mover" located at the top of ROM memory.  I'll see what I can do to install SCMonitor to run on my hardware setup...
  BIll

Bill Shen

unread,
Dec 10, 2022, 9:52:08 AM12/10/22
to RC2014-Z80
I hunted around for the "mover" routine but couldn't find it in SCMonitor.  You've made reference about it being an API call in SCMonitor, but I don't see it in the .hex output of SCMonitor.  I did find the routine in your GitHub RC2014-CPM/BOOT/CMP_boot_SC108_SIO_CF128.hex, so I patch that into the original RC2014 ROM monitor at location 0x7F00.  Now it will run P1, but unfortunately hung at OPTIM
-----------------------------------
A>b:submit makete.sub

A>C -V -C -O TE.C

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I TE.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$  <--program hung here


Press [SPACE] to activate console


ladislau szilagyi

unread,
Dec 10, 2022, 1:14:16 PM12/10/22
to RC2014-Z80
Hi Bill,

my version of SCM contains the API functions $2A  and $2B, to move a byte from/to the upper 64KB RAM. 
But, these API calls are not documented in my SCM manual, I have found them by digging into the SCM sources... I suspect that older versions of SCM have not these APIs implemented.
Sorry, I have no solution to overcome this issue, other that using my custom CPM_BOOT code... but, you must choose the correct version.
In your case, if running on SC114, unfortunately I did not included this configuration on GitHub, so you must edit ROM_CPM_boot.as, and select :

(... I suppose you have SC114, 64MB CF, KIO)
 
M512        equ    0    ;1=512KB.ROM + 512KB.RAM, 0=SC108 or MM

SC108        equ    0    ;1=SC108, 0=32KBROM+128KBRAM Memory Module

LARGE_TPA    equ    1    ;1=BDOS starts at DA00H, 0=BDOS starts at D000H               ;set it to 1 ONLY for 64MB CFs !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

ACIA        equ    0    ;1=ACIA,0=KIO or SIO

KIO        equ    1    ;1=KIO's SIO, 0=SC110's SIO

then, assemble-it, burn the booter, and it will solve the problem.

Ladislau

Bill Shen

unread,
Dec 10, 2022, 2:06:39 PM12/10/22
to RC2014-Z80
Thank you,  you’ve given me many good hints and pointed the right direction.  I should be able to fill in the details tonight.
  Bill

ladislau szilagyi

unread,
Dec 11, 2022, 2:11:02 AM12/11/22
to RC2014-Z80
Hi all,

improving a large software toolset, such as the HiTech C compiler, is a huge and difficult task.

I had two targets: 

- the "classic 64 KB RAM" RC2014 configurations
- the "128KB RAM" RC2014 configurations

I was lucky to have at disposal the decompiled set of HiTech C sources (I must thank again Mark Ogden , Andrey Nikitin, and Hector Peraza for his outstanding ZSM4...).

Looking back, but also trying to look forward, I must confess that the first target was only partly achieved (Z80AS is the main asset, with P1 as a small improvement...)

Now, for the second target, the outcome is better and progress can be still made...

Z80AS is clearly the best improvement.

Next, I consider P1 as the second best one (and there is room for improvement...)

Then, OPTIM is good enough ( but I recently discovered that it misses some code optimizations - some few missed from dozens - but still missed...) , but here also there is room for improvement.

The last and most sensitive topic - CGEN. 
It is now the weak point (trying to work extensively on my SC108-based RC2014 pays off... in most cases, CGEN is now the "out-of-memory" stopper).

But, I just discovered a simple way to "pack" into the Upper 64 KB RAM both Strings and Object Structures, and I think I can solve also this last weak point.

One last thing.

I must ask for help from you, the RC2014 owners community, to test the results.

It is not easy to test alone such a complex toolset...help is always welcomed in such circumstances...

regards,
Ladislau

Bill Shen

unread,
Dec 11, 2022, 9:32:52 AM12/11/22
to RC2014-Z80
More efficient use of TPA can be somewhat helpful so can banked CP/M3, but I agree that using 2nd bank of memory for data structures really improve HiTechC in very significant way.  I congratulate you on finding a way to significantly improve HiTechC!  

Downside to larger programs is the compilation time is getting quite long.  RC2014's 7.37MHz baseline clock is quite conservative.  It can easily double to 14.7MHz with an oscillator change.  More integrated Z80 platform can double the clock again to 29.5MHz.  Z180 can go to 36MHz, beyond that is eZ80 but compatibility to Z80 is questionable.  You are probably doing most your works in Z80 simulator, but I do want to mention doing compilation in native Z80 hardware is realistic with faster hardware.

Back to minutiae of the compiler, I still unable to solve the program hanging with OPTIM.  My hardware setup is SC108, KIO, CF.  I now have your custom CPM_BOOT with API $2A and $2B installed.  It boots straight into CP/M and the improved P1 work just fine;  it clearly is using the 2nd bank of memory:

A>c -v -c te.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I TE.C $CTMP1.$$$
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

A>cpp -dcpm -dh1_tech_c -dz80 -i te.c te.p1

A>p1 -n te.p1 x y
13 KB used from the upper 64KB RAM

But OPTIM still hung like before.  By "hung" I mean the ROM was paged in and I assume OPTIM was searching for 'mover' routine but failed somehow.  I've tried several ways to compile OPTIM source codes provided in your GitHub page but kept running into "no room" or "out of memory" issues.  Could you check the new OPTIM published on your GitHub on your SC108 hardware to make sure it is working properly?
  Bill

ladislau szilagyi

unread,
Dec 11, 2022, 10:18:09 AM12/11/22
to RC2014-Z80
Hi Bill,

I just published a new version of OPTIM, for SC108.

I managed to solve the strange case of those few missing optimizations in the past version; now, the statistics obtained using -n show that the output is identical to the old HiTech OPTIM.

I published the new COM and sources.

For all of you who want to build these tools from the sources, be aware that you MUST use a 128KB RAM RC2014 configuration (e.g. SC128) with my HiTech toolset, including Z80AS,  replacing the "classic'' HiTech toolset, otherwise, as Bill noticed, you will get only "out-of-memory" errors...

Ladislau

Bill Shen

unread,
Dec 11, 2022, 12:13:07 PM12/11/22
to RC2014-Z80
Ladislau,
Thank you for the updated OPTIM.  It all works now.  My hardware setup is SC108, KIO, CF with CPM_BOOT installed in EPROM.  Clock is 20MHz.  CP/M is KIO_PutSys_CF64_CPM_DA00H.hex test case is TE128.  It took 200 seconds to compile the C program, another 22 seconds to link.  The resulting TE128 works wonderfully.

I should mention that for both TE128 and TE512 repositories that "makete.sub" has a blank line at the end.  submit.com does not like blank line in .sub file and will exit immediately.  So I have to edit out the blank line to run the batch file.
  Bill

Bill Shen

unread,
Dec 12, 2022, 7:37:48 AM12/12/22
to RC2014-Z80
I like the improved HiTechC a lot.  The TE editor is very nice as well, so I modified a K80 to emulate SC108+KIO+CF but ran at 29.5MHz.  This way the same software that ran in SC108 will run in K80 emulation but faster.  Compiling TE128 is now 128 seconds + 15 seconds to link.  TE128 is very responsive. 
  Bill
K80_emulate_SC108.jpg

ladislau szilagyi

unread,
Dec 26, 2022, 2:43:51 AM12/26/22
to RC2014-Z80
Hi all,

I just published a new (final) version of the improved HiTech C toolchain ( CPP, P1, CGEN, OPTIM, Z80AS) ( https://github.com/Laci1953/RC2014-CPM/tree/main/HiTech%20C%20compiler%20optimization )

I included also folders containing some tests involving large C files.

I listed below the results of a significant test using the OPTIM.COM C source files:

I took the optim.c source containing ALL the OPTIM source, sliced-it in 3 parts:

optima.c 128KB
optimb.c 68KB
optimc.c 48KB

...then attempted to compile these files.

Here are the results:
....

D>sdir optim?.c

Directory For Drive D:  User  0

    Name     Bytes   Recs   Attributes      Name     Bytes   Recs   Attributes
------------ ------ ------ ------------ ------------ ------ ------ ------------
OPTIMA   C     128k   1007 Dir RW       OPTIMB   C      68k    529 Dir RW
OPTIMC   C      48k    363 Dir RW

Total Bytes     =    244k  Total Records =    1899  Files Found =    3
Total 1k Blocks =    239   Used/Max Dir Entries For Drive D:  484/ 512

OPTIMA

D>c -v -c -o optima.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE

(entering C tools execution step-by step...including also statistics)

D>CPP -DCPM -DHI_TECH_C -Dz80 -I OPTIMA.C $CTMP1.$$$

D>p1 -n $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
20 KB used from the upper 64KB RAM

D>cgen -n $CTMP2.$$$ $CTMP1.$$$
9 KB used from the upper 64KB RAM

D>optim -n $CTMP1.$$$ optima.as
10K, 3 iterations
105 Redundant labels
132 Jumps to jumps
122 Stack adjustments
312 Temporary labels
240 Unref'ed labels
78 Unreachable code
11 Jumps to .+1
58 Skips over jumps
33 Common code seq's
8 Ex (sp),hl's used
59 Redundant operations
164 Redundant loads/stores
37 Simplified addresses
4 Xor a's used
3 Redundant ex de,hl's
10 Code motions
42 KB used from the upper 64KB RAM

D>z80as -j optima

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 128
Finished.

OPTIMB

D>c -v -c -o optimb.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE

D>CPP -DCPM -DHI_TECH_C -Dz80 -I OPTIMB.C $CTMP1.$$$

D>p1 -n $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
19 KB used from the upper 64KB RAM

D>cgen -n $CTMP2.$$$ $CTMP1.$$$
8 KB used from the upper 64KB RAM

D>optim -n $CTMP1.$$$ optimb.as
16K, 3 iterations
109 Redundant labels
170 Jumps to jumps
165 Stack adjustments
293 Temporary labels
232 Unref'ed labels
245 Unreachable code
27 Jumps to .+1
53 Skips over jumps
77 Common code seq's
5 Ex (sp),hl's used
21 Redundant operations
248 Redundant loads/stores
26 Simplified addresses
1 Xor a's used
2 Redundant ex de,hl's
25 Code motions
46 KB used from the upper 64KB RAM

D>z80as -j optimb

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 128
Finished.

OPTIMC

D>c -v -c -o optimc.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE

D>CPP -DCPM -DHI_TECH_C -Dz80 -I OPTIMC.C $CTMP1.$$$

D>p1 -n $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
19 KB used from the upper 64KB RAM

D>cgen -n $CTMP2.$$$ $CTMP1.$$$
8 KB used from the upper 64KB RAM

D>optim -n $CTMP1.$$$ optimc.as
15K, 3 iterations
156 Redundant labels
197 Jumps to jumps
80 Stack adjustments
126 Temporary labels
211 Unref'ed labels
164 Unreachable code
11 Jumps to .+1
37 Skips over jumps
73 Common code seq's
2 Ex (sp),hl's used
7 Redundant operations
76 Redundant loads/stores
8 Simplified addresses
11 Code motions
19 KB used from the upper 64KB RAM

D>z80as -j optimc

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 128
Finished.

-----------------------------

Therefore, all the 3 files compiled OK, including code optimization.

Needles to say, if you attempt to use the old HiTech C toolchain, you will get a complete failure:

D>CPP -DCPM -DHI_TECH_C -Dz80 -I OPTIMA.C $CTMP1.$$$

D>oldp1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
   776: void           uconv(int, term_t *);
                  Out of memory ^

IMPORTANT NOTICE
---------------------------------

To use this new HiTech C toolchain, you must use my "custom" CP/M PutSys ( https://github.com/Laci1953/RC2014-CPM/tree/main/PutSys )
...

Happy compiling & Merry XMAS to all!

Ladislau

ladislau szilagyi

unread,
Dec 26, 2022, 6:59:55 AM12/26/22
to RC2014-Z80
Hi,

I published also a C.COM clone, with an extra -% switch added, to provide memory usage statistics for P1, CGEN, OPTIM.

example:

D>c -v -c -o -% te.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I TE.C $CTMP1.$$$
0:P1 -N $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$

13 KB used from the upper 64KB RAM
0:CGEN -N $CTMP2.$$$ $CTMP1.$$$
6 KB used from the upper 64KB RAM
0:OPTIM -N $CTMP1.$$$ $CTMP2.$$$
5K, 3 iterations
36 Redundant labels
33 Jumps to jumps
113 Stack adjustments
25 Temporary labels
84 Unref'ed labels
24 Unreachable code
2 Jumps to .+1
7 Skips over jumps
12 Common code seq's
4 Ex (sp),hl's used
1 Redundant operations
90 Redundant loads/stores
15 Simplified addresses
2 Xor a's used
2 Code motions
14 KB used from the upper 64KB RAM
0:ZAS -J -N -oTE.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 68
Finished.

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$
D>

regards,
Ladislau

ladislau szilagyi

unread,
Jan 3, 2023, 5:24:05 AM1/3/23
to RC2014-Z80
Hi,

now, with the improved HiTech C compiler, it's easy to play with all kind of large C source files...

For example, the famous game STAR TREK.

First, I wanted only to test my new HiTech C compiler... but then I decided to (re)build this old game. 

Thanks to Alan Cox ( https://github.com/EtchedPixels/FUZIX/tree/master/Applications/games ), I had a very good starting source file, I split-it in two, modified-it a little, compiled, linked... and ... it works. 


The files st.doc, st.int, st.fat, st.log must be copied to the drive containing the STARTREK.COM file 

 Enjoy! 

ladislau szilagyi

unread,
Jan 3, 2023, 7:11:31 AM1/3/23
to RC2014-Z80
I forgot to include the log :

D>sdir st?.c


Directory For Drive D:  User  0

    Name     Bytes   Recs   Attributes      Name     Bytes   Recs   Attributes
------------ ------ ------ ------------ ------------ ------ ------ ------------
ST1      C      24k    162 Dir RW       ST2      C      24k    167 Dir RW

Total Bytes     =     48k  Total Records =     329  Files Found =    2
Total 1k Blocks =     42   Used/Max Dir Entries For Drive D:  475/ 512

D>

 ( st1.c has 907 lines, st2.c has 965 lines )

D>c -v -c -o -% st1.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I ST1.C $CTMP1.$$$

0:P1 -N $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
13 KB used from the upper 64KB RAM
0:CGEN -N $CTMP2.$$$ $CTMP1.$$$
ST1.C:372:      constant relational expression

6 KB used from the upper 64KB RAM
0:OPTIM -N $CTMP1.$$$ $CTMP2.$$$
11K, 3 iterations
27 Redundant labels
38 Jumps to jumps
141 Stack adjustments
51 Temporary labels
95 Unref'ed labels
34 Unreachable code
16 Skips over jumps
18 Common code seq's
22 Ex (sp),hl's used
7 Redundant operations
79 Redundant loads/stores
17 Simplified addresses

4 Xor a's used
18 Redundant ex de,hl's
27 KB used from the upper 64KB RAM
0:ZAS -J -N -oST1.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 60

Finished.
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>c -v -c -o -% st2.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I ST2.C $CTMP1.$$$

0:P1 -N $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
14 KB used from the upper 64KB RAM
0:CGEN -N $CTMP2.$$$ $CTMP1.$$$
7 KB used from the upper 64KB RAM

0:OPTIM -N $CTMP1.$$$ $CTMP2.$$$
7K, 3 iterations
20 Redundant labels
63 Jumps to jumps
174 Stack adjustments
57 Temporary labels
135 Unref'ed labels
35 Unreachable code
4 Jumps to .+1
30 Skips over jumps
16 Common code seq's
25 Ex (sp),hl's used
2 Redundant operations
93 Redundant loads/stores
36 Simplified addresses

2 Xor a's used
18 Redundant ex de,hl's
4 Code motions
34 KB used from the upper 64KB RAM
0:ZAS -J -N -oST2.OBJ $CTMP2.$$$

Z80AS Macro-Assembler V4.7

Errors: 0

Jump optimizations done: 64

Finished.
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

D>

PS. Do not try to compile these source files using the "old" HiTech C compiler, it will be a complete failure...

ladislau szilagyi

unread,
Jan 31, 2023, 8:30:31 AM1/31/23
to RC2014-Z80
Hi,

Besides my basic RC2014 configuration (SC112+SC108+SC110) I have also another RC2014(SC112+512KB RAM/512KB ROM + ACIA serial).

Until now, I used only my first configuration to compile my various C source files, benefiting from my customized HiTech C compiler.

Recently, I begun working to customize the HiTech C toolset in order to make-it run better also on RC2014's provided with 512KB RAM + 512KB ROM memory board.

The basic idea is to modify P1, CGEN & OPTIM in order to allow them to process larger C files, when executed on the already mentioned hardware.

I started with P1.COM

My first option was to use code overlays, in order to gain some RAM space. 

What I obtained is a rather strange P1 ( a combination between a .COM and three overlays) containing:
- a "root" code segment, located in the memory space below 4000H; this is loaded as a .COM file
- 3 code "overlays", that execute in the area 4000H - 8000H; these are stored either in EPROM ( in the 512KB ROM) or as disk files, and are loaded at P1 start (from EPROM or disk) in three 16KB RAM banks stored on the 512KB RAM.

Therefore, these overlays are loaded at run-time, as needed, on the physical space 4000-8000H, and executed.

Because loading of these "overlays" is very fast (just an OUT port...) the overall execution speed is not affected.

The rest of RAM space (from 8000H ...) is used to store objects allocated by P1. 

The result: my "custom" P1 can now process files that were impossible to compile using the original HiTech C compiler...

Now, I'm focusing on CGEN...

After finishing also OPTIM, I will publish on GitHub also this customized version of HiTech C compiler.

Ladislau

Bill Shen

unread,
Jan 31, 2023, 9:44:51 AM1/31/23
to RC2014-Z80
Excellent.  128K RAM is very common and cheap.  Hardware to split 128K RAM into two 64K banks are easy to do, but software to utilize the two banks are tricky.  Splitting 128K into four 32K banks are relatively simple, but split 128K into eight 16K banks become complicated (hardware-wise) again.  Because of your works in RTM/Z80 I've changed several of my designs to have 16K banks rather than 32K banks with added cost to hardware complexity, but what's hardware if there are no software for it?  Thank you for your continuing works advancing Z80 technology.
  Bill

ladislau szilagyi

unread,
Feb 17, 2023, 12:47:53 PM2/17/23
to RC2014-Z80
Hi,

I finished testing P1.COM for Z80 systems provided with 512KB RAM + 512KB EPROM memory board. 

The memory map of this custom P1:

0000 - 4000H    Base code partition ( Code,  Data, BSS, File buffers (2 x 200H) )
4000 - 8000H    Overlays code partition (code, data) - there are 3 partitions, stored in 3 files, loaded at run-time in three16KB memory banks 
8000 - C000H    Dynamic memory buffer (maps one of the 16KB memory banks from the 512KB RAM)
C000 -                 Available for malloc
        - to BDOS    Stack

Some comments:
- I'm using the classic simple, plain CP/M, booted from the EPROM
- In my custom implementation of the HiTech C compiler, all the components (P1, CGEN, OPTIM) will be executed using a base + overlays architecture; base is a COM file, the overlays will be loaded from files to RAM banks at start time, while the rest of 16 RAM banks will be used for dynamic memory; this makes overlay calling super-fast (just switching the 4000-8000 RAM bank)
- Some of the objects allocated by a component will be placed into this 256KB dynamic memory, while other (few) will be handled by the usual malloc/free mechanism
- The HiTech's batch processor (EXEC), which under normal conditions is resident in RAM, just below BDOS, will be "moved" - out at the component start-up to a dedicated RAM bank, to gain some extra space (1KB) for the stack and malloc's, to be "moved" - back below BDOS when the component finishes its job

Using these "tricks", it will be possible to compile huge C files ( P1 was tested for some 30-40 KB C source files, of thousands of lines each...)

Next target : CGEN

Ladislau


ladislau szilagyi

unread,
Feb 28, 2023, 2:04:33 AM2/28/23
to RC2014-Z80
Hi,

I just finished testing CGEN.COM for Z80 systems provided with 512KB RAM + 512KB EPROM memory board. 

The memory map of this custom CGEN:

0000 - 4000H    Base code partition ( Code,  Data, BSS, File buffers (2 x 200H) )
4000 - 8000H    Overlays code partition (code, data) - there are 3 partitions, stored in 3 files, loaded at run-time in three16KB memory banks 
8000 - C000H    Dynamic memory buffer (maps one of the 16KB memory banks from the 512KB RAM)
C000 -                 Available for malloc
        - to BDOS    Stack

Some comments:
- I'm using the classic simple, plain CP/M, booted from the EPROM
- In my custom implementation of the HiTech C compiler, all the components (P1, CGEN, OPTIM) will be executed using a base + overlays architecture; base is a COM file, the overlays will be loaded from files to RAM banks at start time, while the rest of 16 RAM banks will be used for dynamic memory; this makes overlay calling super-fast (just switching the 4000-8000 RAM bank)
- Some of the objects allocated by a component will be placed into this 256KB dynamic memory, while other (few) will be handled by the usual malloc/free mechanism
- The HiTech's batch processor (EXEC), which under normal conditions is resident in RAM, just below BDOS, will be "moved" - out at the component start-up to a dedicated RAM bank, to gain some extra space (1KB) for the stack and malloc's, to be "moved" - back below BDOS when the component finishes its job

Using these "tricks", it will be possible to compile huge C files ( CGEN was tested for some 30-40 KB C source files, of thousands of lines each...)

Next (and final) target : OPTIM

I will publish on GitHub this "C-512" version of HiTech C Compiler tools after finishing to test the OPTIM component.

I really hope it will be of great help for those who want to develop big C projects on Z80 systems provided with 512KB RAM + 512KB EPROM memory board.

Ladislau

Fred Weigel

unread,
Mar 2, 2023, 11:35:25 AM3/2/23
to RC2014-Z80
Ladislau

I am very interested -- this seems like classic overlays. How many inter-bank calls are there? If the answer is: very few, then can we replace the memory banks with an overlay loader? If that is the case, then this could be run on a 64K RAM CP/M machine, yes? Do you compile the "overlays" and link separately? As I will never have a 512KB + 512KB system. But, I can do the overlay loader work (I have converted HiTech to use REL format... as on my Github -- and that can then use the PLINK-II linker with overlays).

I am interested in taking your work in that direction - if that is something you are interested in supporting.

Fred Weigel

ladislau szilagyi

unread,
Mar 2, 2023, 3:03:09 PM3/2/23
to RC2014-Z80
Hi Fred,

my "overlays" architecture is based on :
- a "common" set of routines, resident in the "base" 16KB RAM bank (0000-4000H)
- an "overlay" 16KB area ( 4000H - 8000H) 
- the stack to handle the call/return functions

The "base" and the "overlays" are compiled & linked separately.

In both P1 & CGEN implementations, there are a lot of inter-overlay calls, not only base-overlay calls, but every call / return comes with a very small overhead, because I'm actually switching the overlays by selecting the appropriate physical 16KB RAM bank to the 4000H-8000H area by using an OUT instruction. If these overlays will need to be loaded from disk, then the overhead will be significant...

I will publish shortly (after finishing to adapt also OPTIM) the HiTech C toolset for 512 RAM Z80 systems... including the overlay support routines.

Ladislau

Fred Weigel

unread,
Mar 2, 2023, 6:31:43 PM3/2/23
to RC2014-Z80
Thanks!

I am still interested -- will wait until you publish -- then attempt a routine map to see if it can be broken into conventional overlays. Remember -- the overlays are not at a 16k granualarity... They can be as little as 128 bytes! So fairly complex
overlay structures can be built.

Fred

ladislau szilagyi

unread,
Mar 10, 2023, 5:25:29 AM3/10/23
to RC2014-Z80
Hi,

while working to finish the 512KB RAM version of HiTech C toolset, I found some problems (bugs?) in the original HiTech C Compiler v.3.09.

The issue is not a new one, because I suspect there are a lot of such bugs, and perhaps it's worth fixing them...

I found, in the documents published by Microchip Technology Inc. (who acquired HiTech Software in 2009), the following:

(On the Facebook Zilog Z80 DIY group, Chris A Hills requested
and was granted permission from Microchip Technology Inc. to
release this software for cross-compiling CP/M Z80 programs
under MS-DOS.)

(Release Notes for HI-TECH C Compiler v.4.11, MS_DOS, october 1989)
...
Version 4.11 of the HI_TECH C Z80 compiler has some bug fixes and new features from version 4.0x
...
The OPTIM had a bug which caused it to hang or crash on certain unusual code sequences.
...
The CGEN contained a serious bug which caused bad stack adjustment code to be generated for functions containing more than 12 bytes of local variables. 
The stack pointer was added to instead of subtracting, causing corruption of the stack.

--------------------------------

I wonder if these issues were also present in the (current) 3.09 version ?

For the CGEN related bug, I think it was "injected" only in the v.4 of the compiler... in my v.3.09 compiler, this never happens.

About OPTIM, I'm not convinced that the bug is not present also in the v.3.09

In OPTIM, I found also another couple of bugs:

1. In certain cases when #asm ... #endasm is used, the optimised code contains some strange (and incorrect...) statements.

Example (found while compiling part of the TE editor)

I>c -v -c -o teui.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I TEUI.C $CTMP1.$$$

0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
TEUI.C:498:     constant relational expression (warning)
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
0:ZAS -J -N -oTEUI.OBJ $CTMP2.$$$
Z80AS Macro-Assembler V4.7
O                               z
E 0022' C3 0000                 jp      af',L1

Errors: 2

Jump optimizations done: 71

Finished.
ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

I>

Contents of $CTMP1.$$$

...
psect text
_putstr:
        ld      hl,2
        add     hl,sp
        ld      e,(hl)
        inc     hl
        ld      d,(hl)
        ex      de,hl
1:      ld      a,(hl)
        or      a
        ret     z
        inc     hl
        ld      c,a
        push    hl
        push    bc
        call    _CrtOut
        pop     bc
        pop     hl
        jr      1b
...

Contents of $CTMP2.$$$

...
psect   text
_putstr:
ld      hl,2
add     hl,sp
ld      e,(hl)
inc     hl
ld      d,(hl)
ex      de,hl
L1:
ld      a,(hl)
or      a
z
inc     hl
ld      c,a
push    hl
push    bc
call    _CrtOut
pop     bc
pop     hl
jp      af',L1
...

Notice the strange z and jp      af',L1 statements... clearly a bug.

2. If you try to compile a very large C procedure (resulting in more than 311 jump labels being generated by CGEN), the OPTIM will be "blocked" (it hangs in an infinite loop, because the table containing labels has only 311 places available...)

Maybe there are other bugs too ... (the  Microchip document mentioned also a problem related to ZAS - but I actually dropped ZAS, using my Z80AS instead...).

If anyone knows about such bugs, please let me know.

Once again, it's ONLY about bugs related to the C compiler, NOT about the C library (here, Tony Nicholson is doing a great job, thanks Tony!)

thanks,
Ladislau

Fred Weigel

unread,
Mar 10, 2023, 7:43:14 PM3/10/23
to RC2014-Z80
Yes, the assembler production issue is why I wrote OBJ2MAC -- I used to convert AS to MAC, but noted that the compiler would produce "bad" sequences on occasion. There are also bad code generation when dealing with "long". Its not a perfect compiler. Good, but not great... See my am9511 emulator for some of the code generation issues.

ladislau szilagyi

unread,
Mar 15, 2023, 6:26:09 AM3/15/23
to RC2014-Z80
Hi,

I just published the new, improved, Hi Tech C compiler toolchain , for the 128KB / 512KB RAM Z80 systems.


The novelty is that if you have a 512KB RAM + 512KB ROM module, you can now compile larger C source files.

For this new 512KB RAM version, all the C compiler components ( P1, CGEN and OPTIM) use code overlay files, being loaded at start-up in separate 16KB RAM banks and executed there.

This keeps the code overlay loading/changing at a very low overhead, resulting in fast execution time (comparable with the 128KB RAM version).

Now, for all of you who own Z80 systems provided with 128KB RAM or 512KB RAM modules, developing C language based projects is becoming easier.

So, if you own any of the following modules ( SC108, SC114, SC118, SC150, SC152 or the Phillip Stevens memory module, or the 512KB RAM + 512KB ROM module), please give-it a try...

Ladislau

ladislau szilagyi

unread,
Mar 16, 2023, 6:30:23 AM3/16/23
to RC2014-Z80
Implementation details: (this is published also on GitHub)

Hardware requirements
-------------------------------

The improved HiTech C compiler works on any Z80-based system provided with one of the following RAM modules:

- 128 KB RAM (SC108, SC114, SC118, SC150, SC152 or the Phillip Stevens’s memory module)

- 512 KB RAM (512 KB RAM + 512 KB ROM Spencer Owen’s module)

Software requirements
------------------------------

For the 128KB version, a customised CP/M is needed (one with a smaller BIOS).

Why is this a mandatory constraint?
Because it is vital for the C compiler to access the upper 64KB RAM in order to “gain” more available memory where to store its various data structures used by its routines.
But, in order to access the upper 64KB RAM, a small piece of code must be stored in memory as high as possible, in both the lower and the upper 64KB RAM, at exactly the same address.
This “shadow” code will be responsible to move bytes between these two 64KB RAM partitions.
Unfortunately, the “official” BIOS delivered with the RC2014 is too big, “eating” all the available RAM space until the end of the physical 64K memory space.
Thus, no space is left for the “shadow” code.
The only possible solution was to build a custom, smaller BIOS.

You can find the customised CP/M’s here: https://github.com/Laci1953/HiTech-C-compiler-enhanced/tree/main/PutSys - the folder contains all the possible CP/M variants according to the needed serial type (SIO, KIO, ACIA) and CF size (64MB or 128MB).

For the 512KB version, no CP/M customization is needed.

One last remark: the 64MB CF’s CP/M is preferable because it allows a larger TPA ( 2 and half KB larger compared to the 128MB CF version, who “eats” more buffer space needed by the extra disk drives ... ) ;

Design details
-------------------

The customised HiTech C compiler components (P1, CGEN, OPTIM) use now two kinds of memory allocation routines:
- the classical “malloc”
- the new memory allocation routine, allowing access to the extra RAM provided by the hadware

For the 128KB version, a custom memory allocator was built (assembler). This made possible accessing an extra 64KB RAM area, compared to the “classic” TPA area.

For the 512KB version, another memory allocator was built (assembler), allowing access to at least extra 256 KB RAM.
For the 512KB version also a code overlay support module was built (assembler). The code overlays are stored on disk files, being read at start time and stored on specific 16KB RAM partitions; when called, the requested code overlay is loaded from its 16KB RAM partition to a fixed 16KB RAM internal buffer and executed there. This makes the overlay mechanism very efficient.

Thus, the 512KB RAM space 16KB partitions are used to store allocated memory and code overlays.

The 512KB version uses the following memory map model:

0000H – 4000H Base partition (code, data, bss + first memory heap area)
4000H – 8000H Overlay partition (code, data)
8000H – C000H Dynamic memory buffer (loaded with a 16KB RAM memory partition)
C000H – FFFFH Secondary memory heap area + stack + BDOS, BIOS

Also, for the 512KB version, because it was important to gain as much free RAM as possible in TPA, a mechanism for “hiding” and “restoring” the HiTech $EXEC batch processor was implemented, gaining an extra 1 KB of memory.

For both 128KB and 512KB versions, code was kept small also by using a special psect, named “top”, placed after the BSS psect; this “top” psect contains code that is executed only once, at initialization time, and then can be “dropped”, the “top” psect practically is being overwritten by subsequent malloc’s.

Practical results
---------------------

Both the 128KB and 512KB HiTech C compiler custom versions outperform the old 64KB version, allowing to compile quite large C source files.

See the TESTS folder for examples of large C source files that can now be compiled, but will fail with the old HiTech C compiler.

---------------------------

regards,
Ladislau

Bill Shen

unread,
Mar 17, 2023, 11:47:29 AM3/17/23
to RC2014-Z80
Ladislau,
Great work!  I'm currently preoccupied with software for VGARC, but I will soon try out your 512K version on RC2014Zed, K80, and Micro80 which all have 512K RAM/ROM.
  Bill

ladislau szilagyi

unread,
Apr 20, 2023, 6:43:32 AM4/20/23
to RC2014-Z80
Hi,

I just published a new version of the enhanced HiTech C toolsets, including now also support for Bill Shen's Z80ALL, here: https://github.com/Laci1953/HiTech-C-compiler-enhanced

The old version contained different sets of source files for different hardware platforms (one for 128KB RAM systems, one for 512KB RAM systems), now there is only one set for each of P1, CGEN, OPTIM.

Ladislau

Bill Shen

unread,
Apr 20, 2023, 10:44:56 AM4/20/23
to RC2014-Z80
Ladislau,
Thanks for the HiTech C update for Z80all.  I updated the HiTech C with your P1, CGEN, OPTIM, CPP, then tried compiling the startrek program in your test folder.  I received this error message for st2.c:
  Bill
---------------------------------------------

a>c -v -c -o st2.c

HI-TECH C COMPILER (CP/M-80) V3.09
Copyright (C) 1984-87 HI-TECH SOFTWARE
0:CPP -DCPM -DHI_TECH_C -Dz80 -I ST2.C $CTMP1.$$$
0:P1 $CTMP1.$$$ $CTMP2.$$$ $CTMP3.$$$
0:CGEN $CTMP2.$$$ $CTMP1.$$$
0:OPTIM $CTMP1.$$$ $CTMP2.$$$
Out of Upper RAM memory in _klingons_shoot

ERA $CTMP1.$$$
ERA $CTMP2.$$$
ERA $CTMP3.$$$
ERA $$EXEC.$$$

ladislau szilagyi

unread,
Apr 20, 2023, 11:35:43 AM4/20/23
to RC2014-Z80
Hi Bill,

you're right, I have still to do some improvements on the "efficiency" of the dynamic storage algorithm , for the 4 X 32KB RAM systems.

This is only the first Z80ALL enhanced HiTech C version :)

On 2 X 64KB and 512KB RAM systems, it works ok. It will work also for Z80ALL...

Ladislau

ladislau szilagyi

unread,
Apr 22, 2023, 12:22:33 PM4/22/23
to RC2014-Z80
Hi Bill,

I solved the Z80ALL OPTIM's problem, and published the new version (including also new, updated & improved 128KB & 512KB versions).

Ladislau

ladislau szilagyi

unread,
Oct 22, 2023, 3:15:44 AM10/22/23
to RC2014-Z80
Hi,

I published a guide for those of you who have Z80 computers with more than 64KB RAM and who want to use the enhanced HiTech C compiler toolset , to help adapting the toolset to some rarer / non-standard hardware configurations.

The enhanced HiTech C compiler toolset allows compiling larger C source files.

It works for Z80 computers with more than 64KB RAM.

I tested it on the following hardware configurations:

- SC108
- 512KB RAM + 512KB ROM
- Z80ALL

The guide to modify/adapt the toolset for other hardware configurations is here: 

Ladislau

Bill Shen

unread,
Oct 22, 2023, 10:33:24 AM10/22/23
to RC2014-Z80
Ladislau,
Thank you for providing a guide to adapt to other Z80 system with larger memory than 64K.  I have several Z80 designs that all used 128K memory or more so I clearly can benefit from your guide.  The one specific Z80 design I'm interested having improved HiTechC and possibly TE editor is Simple80.  It is a Z80 SBC without glue logic and used SIO's discrete outputs to switch banks.  It has 128K RAM arranged in 2x64K banks.  Below is the code fragment extracted from Simple80 monitor that moves data to/from banks of 64K memories.  In the comment section I've added SC108 shadow mover as reference.

Simple80 has its own CP/M implementations that are smaller than RC2014's CP/M so I believe the code moving program can fit in Simple80's CP/M.

I'm thinking about another version of Simple80 that uses KIO instead of SIO so it can run faster and have bigger memory so a method of utilizing banks of 64K memories is very useful.  --Bill
***********************************
org 0ff00h
;shadow mover of SC108 is re-implemented here
;; jp 07f06h
;; jp 07f12h
;7f06h:
;get high RAM pointed by (DE) into regA
;; ld a,80h
;; out (38h),a
;; ld a,(de)
;; ld c,a
;; ld a,0
;; out (38h),a
;; ld a,c
;; ret
;7f12h:
;put reg A into high RAM pointed by (DE)
;; ld c,a
;; ld a,80h
;; out (38h),a
;; ld a,c
;; ld (de),a
;; ld a,0
;; out (38h),a
;; ret

jp getHiRAM
putHiRAM:
;put regA into high RAM pointed by (DE)
ld c,a ;save regA
ld a,11h ;Wr0 points to reg1 + reset ex st int
out (SIOBCmd),a
ld a,40h ;Wr1 No Tx interrupts, set READY high
out (SIOBCmd),a
ld a,c
ld (de),a
ld a,11h ;Wr0 points to reg 1 + reset ex st int
out (SIOBCmd),a
ld a,0 ;Wr1 No Tx interrupts, set READY low
out (SIOBCmd),a
ret
getHiRAM:
;get high RAM pointed by (DE) into regA
ld a,11h ;Wr0 points to reg1 + reset ex st int
out (SIOBCmd),a
ld a,40h ;Wr1 No Tx interrupts, set READY high
out (SIOBCmd),a
ld a,(de)
ld c,a
ld a,11h ;Wr0 points to reg 1 + reset ex st int
out (SIOBCmd),a
ld a,0 ;Wr1 No Tx interrupts, set READY low
out (SIOBCmd),a
ld a,c
ret

ladislau szilagyi

unread,
Oct 23, 2023, 12:17:44 AM10/23/23
to RC2014-Z80
HI Bill,

yes, Simple80 is a good example of a Z80-based computer where the advantages of having more than 64KB RAM can be harnessed easily.

More implementation details could be useful:

In my assembler source files that handle alloc/dealloc, for the 2 x 64KB RAM configurations, when I search at start for the routine to move bytes to the 'second' 64KB bank, I used the following code:

;
; Store shared code to Upper & Lower RAM
;
; SP must be set at top of TPA
;
StoreShared:
;move shared code to Lower RAM
ld de,SHARED ;to
ld hl,SHARED_START ;from
ld bc,SHARED_END - SHARED_START
ldir
;move "mover" to 0A000H
ld de,0A000H ;to
ld hl,mover_start ;from
ld bc,mover_end - mover_start
ldir
jp 0A000H ;call "mover" to store shared code to Upper RAM and return
;
mover_start:
;move shared code to Upper RAM
ROM_IN
;first search at 7F00H
ld hl,7F00H
ld a,(hl)
cp 0c3H
jr nz,searchscm
inc hl
inc hl
inc hl
ld a,(hl)
cp 0c3H
jr nz,searchscm
;found "mover" in CPM BOOT EPROM
inc hl
ld a,(hl)
inc hl
ld h,(hl)
ld l,a ;HL=address of "move 1 byte to upper RAM" routine
jp moveit
 ;
searchscm:
;search "move 1 byte to upper RAM" routine in SCM
ld hl,69H
searchjp:
ld a,(hl)
cp 0c3H
jr z,jpfound
inc hl
jr searchjp
jpfound:
ld b,6
searchj7thjp:
inc hl
inc hl
inc hl
ld a,(hl)
cp 0c3H
jr nz,searchjp
djnz searchj7thjp
inc hl

ld e,(hl)
inc hl
ld d,(hl)
ex de,hl
inc hl

ld e,(hl)
inc hl
ld d,(hl)
ex de,hl
ld bc,2bH
add hl,bc
add hl,bc

ld e,(hl)
inc hl
ld d,(hl)
ex de,hl ;HL=LTOUP_SCM
moveit:
push hl
pop iy ;IY=SCM function to move A --> UpperRAM in (DE)
ld ix,SHARED ;from
ld de,SHARED ;to
ld a,SHARED_END - SHARED_START
looptoup:
push af
ld a,(ix+0)
ld hl,retadr - mover_start + 0A000H
push hl
jp (iy)
retadr: inc ix
inc de
pop af
dec a
jr nz,looptoup
ROM_OUT
ret
;
mover_end:

;-----------------------
; stored at 0FF63H in both Lower & Upper RAM
;
SHARED equ 0FF63H

SHARED_START:
; code to ...
; Read one byte from Upper 64KB RAM
; Write one byte to Upper 64KB RAM
; Read one word from Upper 64KB RAM
; Write one word to Upper 64KB RAM
; Write String to Upper 64KB RAM
; Read String from Upper 64KB RAM
; get String Len from Upper 64KB RAM
; Read up to 256 bytes from the Upper 64KB RAM
; Write up to 256 bytes to the Upper 64KB RAM
;       Zero Fill a buffer

SHARED_END: ;at 0FFF6H

$ReadByte equ 0FF63H
$WriteByte equ 0FF6DH
$ReadWord equ 0FF77H
$WriteWord equ 0FF83H
$WriteString equ 0FF8FH
$ReadString equ 0FFA1H
$StringLen equ 0FFB2H
$ReadMem equ 0FFC7H
$WriteMem equ 0FFD7H
$FillZero equ 0FFE7H
--------------------

Therefore, the "mover_start" routine executes at an address >= 8000H, then it calls the ROM_IN macro to "load" the ROM at 0000 - 7FFFH, (code in ROM_IN must be changed, by the way... ), 
then notice that I search at 7F00H for as series of two JP's:

JP getHiRam ;  load A <-- UpperRAM from (DE)
JP putHiRam ;  move A --> UpperRAM to (DE)

if these 2 JP's are not found, I search in SCM for the "putHiRam" routine (Steve Cousins told me the 'trick' about the 7'th JP :).

The macros: (here is the version for SC108)

MEMP_PORT       equ     38H

;       ROM     0000 to 8000H
;
ROM_OUT_CMD     equ     00000001B
ROM_IN_CMD      equ     00000000B
LOWER_64RAM     equ     00000000B
UPPER_64RAM     equ     10000000B
;
MACRO LOW_RAM
ld a,LOWER_64RAM .or. ROM_OUT_CMD
out (MEMP_PORT),a
ENDM

MACRO UP_RAM
ld a,UPPER_64RAM .or. ROM_OUT_CMD
out (MEMP_PORT),a
ENDM

MACRO ROM_IN
ld a,LOWER_64RAM .or. ROM_IN_CMD
out (MEMP_PORT),a
ENDM

MACRO ROM_OUT
ld a,LOWER_64RAM .or. ROM_OUT_CMD
out (MEMP_PORT),a
ENDM

... should be also modified for Simple80 to set/reset SIO READY accordingly...

For SC108, the "shadow" routines are stored, in both 64KB RAM banks, at top (0FF63H to 0FFF6H), and the remaining area in the second RAM bank (0000 to 0FF63H) is the area used to alloc/dealloc.

So, for SC108, the CP/M code should "stop" before 0FF63H (that's why I use a "custom" CP/M, smaller than the original RC2014 CP/M, which used all the space till 0FFFFH).

In case of Simple80, it appears that the "shadow" routines size will be larger, but I estimate that the buffer (0FF00H to FFFFH) will be good enough to hold these routines...therefore the Simple80 CP/M code should "stop" before 0FF00H.

Bill, please let me know if you need more details, I hope the Simple80 implementation of the enhanced HiTech C compiler & TE editor will work OK.

I hope these implementation details will be useful also for other Z80 retro-computer owners with configurations including more than 64KB RAM , to harness the full advantages of such hardware.

regards,
Ladislau

ladislau szilagyi

unread,
Oct 27, 2023, 12:48:32 AM10/27/23
to RC2014-Z80
Hi all,

I added to https://github.com/Laci1953/HiTech-C-compiler-enhanced ,

the file "How to install" ,

containing the following text:

---------------------------

Here are the necessary 3 steps, depending on your specific Z80 computer's hardware:

1. The boot (E)EPROM

This is a mandatory step only for computers provided with the 512KB ROM + 512KB RAM board.
(For computers provided with Steve Cousins SCM, e.g. SC108, this step is not mandatory, you can boot CP/M from SCM, so go to step 2)

For computers provided with 512KB RAM, you need to boot CP/M at power ON, in order to use the enhanced HiTech C compiler.
Running CP/M from ROMWBW will not allow the enhanced HiTech C compiler to be executed !

Choose the appropriate .hex file (according to your RC2014's serial type & CF size), and burn-it to an (E)EPROM, then insert the EPROM to your 512KB RAM + 512KB ROM board.
Example: you have a Z80 computer with an ACIA serial and 64MB CF. You will choose the CPM_boot_512_ACIA_CF64.hex file.
Now, at power ON, the CP/M directly boots.

2. The smaller CP/M (for 128KB RAM Z80 computers)

This step is mandatory only for 128KB RAM computers.
(For computers provided with 512KB RAM + 512KB ROM boards, you may use the "original" CP/M, go to step 3)

To change your CP/M with the smaller CP/M, to be able to run the enhanced HiTech C for 128KB RAM Z80 computers, you need to
paste on the terminal the appropriate .hex file.
Example: you have an 128KB RAM Z80 computer with an ACIA serial and 64MB CF. You will choose the ACIA_PutSys_CF64_CPM_DA00H.hex file.

Then:
*g8000<CR>

Now, the CF contains a smaller CP/M.

3. The enhanced HiTech C

This step is mandatory for all computers.

To implement on your computer the enhanced HiTech C, you need to copy the appropriate .HEX files (according to your hardware), here I will use the "generic" names, then execute:

LOAD CPP
LOAD P1
LOAD CGEN
LOAD OPTIM
LOAD Z80AS
PIP ZAS.COM=Z80AS.COM

Now, you have the enhanced HiTech C installed.
----------------------------

Many thanks Derek for pointing out the need to have a clear "install instruction" text for the enhanced HiTech C compiler !!!

regards,
Ladislau

ladislau szilagyi

unread,
Nov 5, 2023, 1:51:30 PM11/5/23
to RC2014-Z80
Hi,

thanks to Bill Shen, who patiently tested my enhanced HiTech C compiler, customized for Simple80, 
Simple80 has been added to the growing list of Z80 hardware systems capable to run the enhanced HiTech C compiler.

I just published on GitHub the Simple80 .HEX files for the toolset (P1, CGEN, OPTIM).

Ladislau

Bill Shen

unread,
Nov 5, 2023, 11:12:17 PM11/5/23
to RC2014-Z80
Simple80 has 128K RAM organized as two banks of 64K RAM.  In order to access the 2nd bank of RAM, rev0.81 of Simple80 monitor copies the basic "putHiRAM" and "getHiRAM" routines to both 64K banks at the top of the memory starting $FF00.  It is high enough not to interfere with Simple80's CP/M so CP/M applications can use the routines to read and write data to 2nd 64K bank of RAM.  To support improved HiTech C, Ladislau has provided more routines to be copied to top 256 bytes of both banks of RAM:

$$ReadByte
$$WriteByte
$$ReadWord
$$WriteWord
$$ReadString
$$WriteString
$$StringLen
$$ReadMem
$$WriteMem
$$FillZero

These are the "hooks" improved HiTech C uses to access more memory.  In fact, Ladislau's TE editor also uses the same mechanism to expand the editor's memory.  So as long as these routines are resident in top memory, TE and HiTech C can use it to access 2nd bank of memory.

128K RAM is very common and inexpensive but quite often only 64K is actually utilized.  A simple hardware switch can swap in the 2nd bank of 64K but there are not many programs that can take advantage of more memory and there are no standard way of accessing 2nd bank.  This is changing, thanks to Ladislau's efforts.

I will revise Simple80 homepage with updated Simple80 monitor as well as software package for improved HiTech C and TE editor.
  Bill
Reply all
Reply to author
Forward
0 new messages