Getting back into C programming for CP/M
Kevin Boone is revisiting C programming for CP/M after 40 years, using the limited Aztec C compiler while emphasizing efficiency and authenticity in coding within the constraints of the Z80 CPU.
Read original articleKevin Boone has rekindled his interest in C programming for CP/M after a 40-year hiatus, acquiring a Z80-based CP/M machine to explore retrocomputing. He has developed several utilities, including KCalc-CPM and cpmlife, using a modern Z80 cross-compiler but prefers to use CP/M tools for authenticity. Boone is utilizing the 1982 Aztec C compiler, which is available for free from the Aztec Museum. The article discusses the differences between programming in C for CP/M and modern C development, highlighting the limitations of the Aztec compiler, such as its pre-ANSI C syntax, lack of function prototypes, and smaller data type sizes. The compiler generates 8080 assembly code, which is compatible with Z80, but does not leverage advanced Z80 features. Boone notes that the Aztec C library is minimal, lacking many modern functions, and emphasizes the importance of efficiency in coding due to the constraints of the Z80 CPU. He also addresses command-line argument handling and device I/O, explaining how CP/M's architecture requires different approaches compared to modern systems. Overall, Boone's exploration illustrates the challenges and nuances of programming in a retro environment while maintaining a connection to contemporary practices.
- Kevin Boone is revisiting C programming for CP/M after 40 years.
- He uses the Aztec C compiler, which has limitations compared to modern compilers.
- The article highlights differences in syntax, data types, and library functions between CP/M and modern C.
- Efficiency in coding is crucial due to the constraints of the Z80 CPU.
- Boone emphasizes the importance of using CP/M tools for authentic development.
Related
Programming Like It's 1977
The article explores programming games on the Atari VCS, a pioneering hardware platform from the 1970s with constraints that inspired creativity. Coding in 6502 assembly language offers a retro experience. The Atari 2600+ release supports old hardware for modern gaming. Learning on the Atari VCS reveals early programmers' challenges and solutions, fostering creativity.
Five little languages and how they grew: Dennis Ritchie's talk at HOPL on the
Dennis M. Ritchie's 1993 HOPL conference transcript compares C with languages like Bliss, Pascal, Algol 68, and BCPL. He discusses similarities, unique features, and design challenges, offering insights into historical context and language development.
50 years ago, CP/M started the microcomputer revolution
Gary Kildall developed CP/M in 1974, a pioneering microcomputer operating system that influenced the industry. Its decline began with the rise of MS-DOS, but it remains historically significant.
I Was a 1980s Teenage Programmer
Martijn Faassen reflects on his teenage programming experiences in the 1980s, highlighting his first computer, challenges faced, and the magic of learning programming in a small Dutch village.
50 years ago, CP/M started the microcomputer revolution
Gary Kildall developed CP/M in 1974, a pioneering microcomputer operating system that influenced software compatibility. Its legacy continues, despite challenges from competitors like MS-DOS, shaping the computer industry.
- Many commenters share their experiences with CP/M and various C compilers, highlighting the limitations and challenges of programming in that era.
- There is a consensus that modern development practices differ significantly from those in the past, often lamenting the complexity of current methodologies.
- Several users express interest in retro computing and the fun of programming on older hardware, with some actively collecting retro machines.
- Technical discussions arise regarding the performance and optimization of code on limited systems, with suggestions for modern techniques to enhance retro programming.
- Some comments address misconceptions about CP/M's capabilities, particularly regarding memory limits and file system constraints.
https://github.com/skx/cpmulator/
Alongside that there is a collection of CP/M binaries, including the Aztec C compiler:
https://github.com/skx/cpm-dist/
So you can easily have a stab at compiling code. I added a simple file-manager, in C, along with other sources, to give a useful demo. (Of course I spend more time writing code in Z80 assembler, or Turbo Pascal, rather than C).
The author has a followup post here for thos interested:
* Getting back into C programming for CP/M -- part 2 * https://kevinboone.me/cpm-c2.html
If I remember correctly, Aztec C was from Mark Williams. It was also the basis for the c Compiler that came with Coherent OS.
But yes, things were far easier in the 80s, even on Minis which I worked on back then. These days development is just a series of Meetings, Agile Points, Scrums with maybe 2 hours of real work per week. Many people now tend to do their real work off-hours, a sad situation.
But I am looking for 1 more piece of hardware, then I can set up a DOS Machine to play with myself :)
>The Aztec compiler pre-dates ANSI C, and follows the archaic Kernigan & Ritchie syntax
I still do not like ANSI C standards after all these years.
Also if you like the Z80 you should try
https://en.wikipedia.org/wiki/Zilog_eZ80
Which is crazy fast not to mention the only 8-bit architecture that got extended to 24-bit addressing in a sane way with index registers. (Sorry the 65816 sucks)
That's because the FAT file system used by CP/M didn't allow lower case letters, at all. In this case "no obvious way" == "impossible".
The stack problems mentioned were real. The stack size was set at compile time, and there was no way to extend it. Plus the stack was not just used by your software, but also hardware interrupts and their functions.
I did not use Aztec C until a few years after I switched from CP/M to DOS, but I really liked it, and used it for several 68k bare-metal projects. I did poke around with BDS C on CP/M, but was immediately turned off by the lack of standard floating point support. (It did offer an odd BCD float library.)
Not if you use setrusage().
True. But I think you meant KB.
Back in the days when CP/M was king, even 20MB Winchester hard drives were rare
CP/M programming is a lot of fun, even these days! I have a growing collection of retro machines running CP/M, my latest compiler has a CP/M backend, and I have even written a book about the design of a CP/M compiler: http://t3x.org/t3x/0/book.html
And I like writing assembler!
A lot of the modern stack is layers of abstraction, which probably wouldn't be appropriate for such limited machines, but maybe superoptimizers and so on, and just more modern algorithms, etc, could help show what's really possible on these old machines. Sort of retro demoscene, but for useful apps.
Minor nitpick: PUN is not a device in Windows 11 (I haven't tested on previous versions). > echo hello>pun: > type pun hello
In the section about paging, are there actual systems working in the megabyte range?
My next whiskey will be in your honor my man.
See you space cowboy
> A modern compiler will optimize this redundancy away
No, it won't: https://godbolt.org/z/xbzz4cEq3
int my_function (a, b)
int a; char *b;
{
... body of function ...
}
What do you even call this?(disclaimer, i never programmed in c on cp/m, and although i used to use cp/m daily, i haven't used it for about 35 years)
he's using aztec c, but anyone who's considering this needs to know that aztec c isn't under a free-software license. bds c is a properly open-source alternative which seemed to be more popular at the time (though it wasn't open source then)
https://www.aztecmuseum.ca/docs/az80106d.txt says
> This compiler is both the MS-DOS cross-compiler and the native mode CP/M 80 Aztec CZ80 Version 1.06d (C) Copyright Manx Software Systems, Inc. and also includes the earlier Aztec CZ80 Version 1.05 for native mode CP/M 80. I cannot provide you with a legally licenced copy.
> I herewith grant you a non-exclusive conditional licence to use any and all of my work included with this compiler for whatever use you deem fit, provided you do not take credit for my work, and that you leave my copyright notices intact in all of it.
> I believe everything I have written to be correct. Regardless, I, Bill Buckels...
but https://en.wikipedia.org/wiki/Aztec_C explains that manx software 'was started by Harry Suckow, with partners Thomas Fenwick, and James Goodnow II, the two principal developers (...) Suckow is still the copyright holder for Aztec C.'
so it's not just that the source code has been lost; the licensing situation is basically 'don't ask, don't tell'
bds c comes with some integration with an open-source (?) cp/m text editor whose name i forget, so you can quickly jump to compiler errors even though you don't have enough ram to have both the compiler and the editor in memory at once. other ides for cp/m such as turbo pascal and the f83 forth system do manage this. f83 also has multithreading, virtual memory, and 'go to definition' but it's even more untyped than k&r c
bds c is not quite a subset of k&r c, and i doubt boone's claim that aztec c is a strict subset of k&r c as implemented by gcc
sdcc is another free-software compiler that can generate z80 code https://sdcc.sourceforge.net/doc/sdccman.pdf#subsection.3.3.... but it can't run on a z80 itself; it's purely a cross-compiler
a thing that might not be apparent if you're using a modernized system is how constraining floppy disks are. the data transfer rate was about 2 kilobytes per second, the drive was obtrusively loud, and the total disk capacity was typically 90 kilobytes (up to over a megabyte for some 8-inchers). this means that if a person needed data from the disk, such as wordstar's printing overlay, you had to request it and then wait for the disk to find it. so it wasn't a good idea to do this for no user-apparent reason
with respect to
int elems[5][300];
...
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
int elem = elems[i][j];
... process the value ...
}
}
if i wanted efficiency on a compiler that didn't do the strength-reduction for me, i would write it as int elems[5][300];
...
int i, *p, *end, elem;
for (i = 0; i < m; i++) {
end = elems[i+1];
for (p = elems[i]; p != end; p++) {
elem = *p;
... process the value ...
}
}
this avoids any multiplications in the inner loop while obscuring the structure of the program less than boone's versioncp/m machines are interesting to me as being a good approximation of the weakest computers on which self-hosted development is tolerable. as boone points out, you don't have valgrind, you don't have type-checking for subroutine arguments (in k&r c; you do in pascal), the cpu is slow, the fcb interface is bletcherous, and, as i said, floppy disks are very limited; but the machine is big enough and fast enough to support high-level languages, a filesystem, and full-screen tuis like wordstar, supercalc, turbo pascal, the ucsd p-system, etc.
(second disclaimer: i say 'tolerable' but i also wrote a c program in ed on my cellphone last night; your liver may vary)
on the other hand, if you want to develop on a (logically) small computer, there are many interesting logically small computers available today, including the popular and easy-to-use atmega328p; the astounding rp2350; the popular and astonishing arm stm32f103c8t6 (and its improved chinese clones such as the gd32f103); the ultra-low-power ambiq apollo3; the 1.5¢ cy8c4045fni-ds400t, a 48-megahertz arm with 32 kibibytes of flash and 4 kibibytes of sram; and the tiny and simple 1.8¢ pic12f-like ny8a051h. the avr and arm instruction sets are much nicer than the z80 (though the ny8a051h isn't), and the hardware is vastly cheaper, lower power, physically smaller, and faster. and flash memory is also vastly cheaper, lower power, physically smaller, and faster than a floppy disk
"CP/M systems rarely had more than 64Mb of RAM"
This probably was intended as 64Kb of RAM.
Great piece. I found it interesting. Nice work.
Related
Programming Like It's 1977
The article explores programming games on the Atari VCS, a pioneering hardware platform from the 1970s with constraints that inspired creativity. Coding in 6502 assembly language offers a retro experience. The Atari 2600+ release supports old hardware for modern gaming. Learning on the Atari VCS reveals early programmers' challenges and solutions, fostering creativity.
Five little languages and how they grew: Dennis Ritchie's talk at HOPL on the
Dennis M. Ritchie's 1993 HOPL conference transcript compares C with languages like Bliss, Pascal, Algol 68, and BCPL. He discusses similarities, unique features, and design challenges, offering insights into historical context and language development.
50 years ago, CP/M started the microcomputer revolution
Gary Kildall developed CP/M in 1974, a pioneering microcomputer operating system that influenced the industry. Its decline began with the rise of MS-DOS, but it remains historically significant.
I Was a 1980s Teenage Programmer
Martijn Faassen reflects on his teenage programming experiences in the 1980s, highlighting his first computer, challenges faced, and the magic of learning programming in a small Dutch village.
50 years ago, CP/M started the microcomputer revolution
Gary Kildall developed CP/M in 1974, a pioneering microcomputer operating system that influenced software compatibility. Its legacy continues, despite challenges from competitors like MS-DOS, shaping the computer industry.