MJK C Compiler

The MJK “C” Compiler System

The “Hybrid” Compiler System by Michael J. Knudsen

For OS-9/NitrOS-9 Level 2 and the Tandy Color Computer 3

Used to Compile the UltiMusE III MIDI Scoring Package

Mike Knudsen's Coco 3 / OS-9 system

used for compiling UltiMusE 3

Manual by Bill Pierce for The Barn Studios

Released with the personal permission of Michael J. Knudsen

March 27th 2013

Introduction

In December of 2011, I was discussing the sources of Ultimuse 3 via email with the program’s author, Michael J. Knudsen, as I was trying to write a Multi Format Music Player for the Color Computer in OS-9. Mike was more than willing to share his old sources and file formats to his flagship program. He had referred me to Boisy Pitre to whom he had sent a copy of all the sources to Ultimuse. I had gotten that package from Boisy but the code I really needed was the source to “UBox3”, the jukebox player for Ultimuse format files, as I just needed a player and not the full blown editor. These files were not in the archive I had received form Boisy. Mike informed me that he still had his old Coco system and he would crank it up and see if he could locate the sources I needed. In doing so, he asked if I knew anyone that would be interested in his old Coco system. I immediately jumped at the offer. After working out all the details, he informed me I would be receiving his monster Coco system, complete with the hard drives with all his sources and notes for Ultimuse 3. Ultimuse 3 was the very MIDI sequencer I had used for ten years to compose and edit my music until I finally moved on from the Coco to bigger machines. To have the original machine it was written on and the sources to the program was like a guitarist getting a hold of Jimi Hendrix’s guitar. I was ecstatic to say the least.

I finally received the system on December 28th 2011. It was like having Christmas day twice in one week. 3 huge boxes of goodies for me to open. The system consisted of a color Computer 3 with a 1 meg memory expansion and an Eagle AT Keyboard interface. There were 3 floppy drives; a 5 ¼” 360k 40trk DSDD, a 5 ¼” 720k 80trk DSHD, and a 3 ½” 720k 80trk DSDD drives. There were two floppy controllers; a J&M No halt controller and a Radio Shack FD-502 controller. The hard drive was a Burke & Burke system with the B&B controller and two Seagate ST-225, 20 meg drives in a monster drive case. There was also an old “Grey Goose” Multi Pak Interface (upgraded for Coco 3), a Glenside Midi Pak, Deluxe 2 Button mouse, and several other items plus several boxes of floppy disks. The real prize was a Tandy CM-8 RGB monitor. What a system! (pictures on my website)

There was originally some problems getting the system going as Mike had forgotten to include his custom OS-9 Level 2 boot disk for his hard drives in the package and I couldn’t boot the system to get to those hard drives! And Mike had gone on vacation to Mexico for several months! The floppy drives were also in need of a good cleaning and would not read disks properly until I had thoroughly cleaned the heads and moving parts. After a lot of trial and error and reading through the B&B XT HD manuals several times, I finally created a boot disk and got OS-9 booted. But... alas... the hard drives would not spin up. After investigation I found that during shipping, a screw had come loose and had been rolling around in the hard drive case. It had lodged itself into the power supply and when I cranked up the system, the power supply had fried. I then found an old power supply that would spin the drives and found that drive 0 would not complete the spin-up test at all and would fail. Drive 1 would spin up and read, but would only do so for about fifteen minutes before getting too hot and shutting down. Drive 1 was apparently being used as a complete backup to drive 0 and according to the notes I found on the drive, it had been backed up just a few weeks before Mike had told me he had quit using the Coco and parked it. I proceeded to copy the files from the hard drive during the 15 minutes it would run and save them to virtual hard disks using DriveWire. With the drive acting as such, this process took about two weeks to get all the files that were intact. I did find a few files that were errored or corrupt.

After finally getting the surviving files to VHDs, I started sorting through the files to find the sources I was needing, the UBox3 code. When I finally found them and loaded the first file into a text editor, I thought I was reading Japanese! It was all written in C compiler code. I had never programmed in C but I had done some work in RSDOS EDTASM as well as in BASIC09 and OS-9 Assembler. C was something from another world.

Bound and determined to use this code for my player, I downloaded all the manuals and documentation for the Color Computer - OS-9 C compiler I could find on the internet. I felt like it was the 80s again and I was learning assembly language. As I started comparing Mike’s UBox3 code to examples I found of other software written in C and the commands and syntax I saw in the manuals, I knew something was different. Not only was Mike’s coding style more “in depth” than the others I was seeing, but his makefile for compiling was unlike anything I could find examples of. Mike had told me in our last conversation that he had a special system for compiling these files but he hadn’t given any details as to what and where it was. The only clue I had was a note he had sent to Boisy Pitre when Mike had submitted the Ultimuse sources to add to the OS-9 repository (which never made it there I notice) and the note mentioned several “extra” files needed to compile Ultimuse3. These were “c.comp”, “rcr”, and “CnoY”. I had no clue as to what these files were but searched my copy of his HD and found c.comp and CnoY but both files were corrupt. After asking on the Coco new list, I did locate a copy of both on Gene Heskete’s website but Gene could not remember why they were there other than they were part of the C compiler. The rcr file was no where to be found. In searching Mike CMDS directory and also his startup file for OS-9, I noticed he loaded and executed a file called “CLoad” during startup. Out of curiosity I located the file and found it was just a text script that loaded his compiler system on startup. A real dedicated programmer! I now had a list of all the modules in his C compiler.

The first thing I noticed in the list was a program called RCm2. I searched the CMDS and found it. After using dEd to take a look at it ,I found that the internal name was “rcr”. The very file I was missing. He renamed it to avoid clashes with an older version that apparently had been deleted after finding the new one ran as intended. It had just never been renamed.

At this point, I apologize for the long story but I felt I had to document how I came about this compiler system as it was an adventure in itself. Now to explain what this compiler is and how it works. Not being a seasoned C programmer, you may find some of my explanations crude and maybe even in the wrong terminology, but I will do the best I can as this system has to be one of the best C compiler system ever assembled for the Color Computer 3 and OS-9 Level 2. When set up right, it makes the compiling process effortless.

So without further adventures... On with the show!

B.P.

The Compiler System

I will start this tutorial with the list of modules from the “cload” script. These are the essential files of the compiler:

Note: This compiler system should work with any version of OS-9 from stock Tandy/Microware to NitrOS-9. Mike was running a slightly patched stock OS-9 when he put together this compiler system. BP.

Also, I use this C compiler system with VCC ver 143 with Becker Port support configured with DriveWire 4 running NitrOS-9 ver 2.3.9. I have the VCC Coco 3 emulator running with a highly overclocked CPU speed and overclocked disk access. This enhances compile speed by about 2000% !!

A complete fresh compile of my DW4Man program suite with 52 source files on VCC at "normal" clock speeds takes about 16 minutes to compile. The real Coco would probably take about a couples of minutes longer :-(

The same 52 files compiled with VCC overclocked to 75mhz takes about 20 seconds!!!

After compiling on VCC, with a couple of mouse clicks, the vhd is transferred to DriveWire 4 on my real Coco 3 and up and running in less than a minute total !!!

CLoad:

NMLoad RCm2 C.Prep C.Comp CnoY C.Opt RMA RLink Touch

These are the main files used in the compiler. The list is a copy of the “cload” script. The "cload" script first loads and runs "NMLoad" then NMLoad proceeds to load the remaining modules, leaving them in memory after it's done while NMLoad itself exits from memory''.

I will now try to explain the use of these files and some others that are also used in the compilation process or are just “good” utilities for C compiling. All descriptions end with a pathlist to where the files should be located.

  • Make - Make is the OS9 cmd that starts and manages the C compiling (or RMA) process. The version of make we will be using was written by Tim Koonce. The Microware “make” module CANNOT be used with this compiling system as it is hard coded to too many “wrong” modules and directories”. (/dd/cmds/make)
  • Merge - The standard OS-9 "merge" command. This is used to merge source files from within the "link" script to help deal with long source lists as some sources have too many files to list on one line. Temporary files are created with "merge" then the temp files are "linked" the "del" is used to delete the temp files. This is vital to very large multifile sources.
  • Del - Standard OS-9 "del" command. Used with the "merge" command above.
  • cload - cload is a script file that loads all the “C” components into memory so you don’t worry about loading or calling them. (/dd/cmds/cload). Loading the modules into memory saves time and eliminates a lot of "disk activity".
  • NMLink - by Mike Knudsen. This module attempts to load the listed modules into memory without loading them into it’s workspace so the modules “stay” in memory after nmlink is done and remain linked using no more memory other than the space they occupy. (/dd/cmds/NMLink)
  • NMLoad - by Mike Knudsen. Used by "cload". This module is basically the same as NMLink above but just loads the file list without linking them. Mike developed these two utilities to use in Ulitmuse 3 to load his subroutines into memory and leaving them so they would not have to be “loaded” again when called a second time, therefore saving time and wear & tear on the disk drives. They were actually replacement for OS-9 system calls of the same names. (/dd/cmds/NMLoad)
  • RCm2 - by Mike Knudsen, this is the custom “front-end” replacement for “CC’, “CC1” or “CC2”. The in-memory name is “rcr”. It was renamed externally to resolve conflicts with an older version. This module automates the compiling process by calling the other modules as needed and/or defined by the “makefile” (explained later). This file and “make” will check the compile dates on previously compiled versions to see if a newer object (in ./RS/xxx.r) has been added or edited. All current compiles are ignored and only newer files are compiled. This file requires 2 things (other than the rest of the modules). You must have a directory in your working dir named “RS” and you must have an active ramdisk with an “/r0” descriptor. I have the older version of this module that uses C.Pass1 & C.Pass2 if anyone wants it. (Update): I have now created several versions of "RcR" that will compile C sources using several different compiler configurations.
    • C.prep - Original Microware version. This module cleans the C code and removes all comments and un-needed spaces. The files from this process are stored (temporarily) on /r0 as “xxx.p”. (/dd/cmds/c.prep)
  • C.prep 19b - by Jim McDowell, Gene Heskett & Willard Goosey.
    • This module cleans the C code and removes all comments and un-needed spaces. The files from this process are stored (temporarily) on /r0 as “xxx.p”. (/dd/cmds/c.prep). I was using this enhancement of C.Prep, but found that the enhancements included a reduction of memory allocated for "line length" as well as "label buffers" and in compiling large and multiple sources, the module would fail with a memory error. I have now reverted back to the old Microware C.Prep.
  • C.comp - this is the main C compiler. It is a combination of the old c.pass1 & c.pass2. The originals were split because OS9 level 1 could not allocate the memory for a single pass compiler. Level 2 can use a single pass compiler and Microware released one but it was rather buggy and required a lot of work-arounds. This one is stable, based on the OSk compilers. Files generated by this module are stored on /r0 as “xxx.a” (“xxx.p” are deleted) (/dd/cmds/c.comp)
  • Cnoy - by Mike Knudsen(?). This is an optional “magic” module. This module will look through the “xxx.a” files and strip any references to “,y” as in “leax data,y” because the C compiler assigns Y as a constant data pointer and “,y” is not needed. This saves hundreds of code bytes as well as thousands of CPU cycles at run-time. Some types of code cannot use this format. It can be added or omitted in the makefile with “-Y” to activate it. The output from this module is stored in /r0 as “xxx.y” (“xxx.a” are deleted) (/dd/cmds/cnoy)
  • C.opt - Microware/ This module “optimizes” the code generated by the c.comp (if cnoy is bypassed) or cnoy. The results are stored in /r0 as “xxx.o” (“xxx.y” or “xxx.a” are deleted) (/dd/cmds/c.opt)
  • RMA - by Microware/ The “Relocating Macro Assembler” by Microware assembles each file into relocatable object code. This is the final form of the compiling process and is stored in the ./RS directory as “xxx.r” (/r0 is cleared) (/dd/cmds/rma)\
  • RLink - By Microware. This is the final linker module by Microware that will link the “xxx.r” files into a final executable object file and resolve all variable references between the various files. The final file will be stored in the directory you define within the link file. The RS directory is left intact for date comparison in later compiles.
  • Touch - By Microware. This optional feature will “touch” all “xxx.c” files in your work dir and “xxx.r” files in your RS dir to time stamp them for later comparison by the compiler.
  • MyRam/R0 - By Gene Heskett. In the CMDS directory on the disk image you will find these two files. It basically a ramdisk system but with a twist. I was introduced to this ramdisk by it’s author Gene Heskett and I doubt I’l ever use any other ramdisk. What makes this one special is that it “just works” (TM). Install it in your OS9Boot and forget it. It takes no more memory that the space the modules reside in. You don’t format it, you don’t iniz it, it “just works”. Once you perfor any operation to /r0, it will automatically init and format itself if it hasn’t been used since the boot up. Need the memory back? Just deiniz it and it returns all the ram back to OS-9. Need it smaller or larger? While it’s down, use dmode to change the sector numbers and the next time you use it, it formats to the new size. This program has been rigorously tested and stamped “Stable” by Gene himself and I will trust anything Gene throws rocks at... err stamps his approval on. I’ve included Gene’s notes in the DOCS directory and the sources are in the CSOURCES/TOOLS directory.
  • Unstring - by Mike Knudsen. This is a special utility only used in the Ultimuse 3 compiling process or any program requiring Mike's "fragged subroutines" (I use this extensively in my "MShell" project). It is not used here in UBox3 but is included for completeness of his system. This module is used exclusively to strip the string initiators from the sources of his sub-routines. Mike uses a unique, one of a kind sub-routine system that I haven’t seen anyone else attempt. His main module for Ultimuse uses all memory up to the last available 8k block of memory. Anytime in working on the source, if he over run this boundry, he would “frag” out an isolated portion of the code to it’s own sub-routine. The main module was then padded to with dummy variables to occupy the memory up to the last 8k boundry. This routine was called and loaded as any other sub, but, it’s linked into the Ultimuse 3 main module as if it were part of the module. A set of general variables were defined for all the subs to use with each sub redefining the variables to what was needed for that sub. To acomplish this, the subs had to have their variables initialized for the first phase on compilation but the linker would see duplicates in the final phase. So he developed a way to de-initialize the variables, leaving only the pointers, before they are linked as the variables actually reside in the main module. This way, he could build subs for disk management, score transposition, score layout, midi management, instrument management etc. in external subs that Ultimuse thought were part of the main module. These subs could be loaded in and out of the main module just by using the NMLink and NMLoad utilities above. Therefore giving you endless memory for your program. You need more routines? Just write another sub. Ingenius! (/dd/cmds/Unstring)

Resource Files (lib, defs etc.)

  • CStart.r - By Tim Koonce. The original “cstart.r” by Microware had a few bugs and was re-written by Tim Koonce. This version is stable and bug-free amd also optimized to be used by RLink. (/dd/lib/cstart.r)
  • CLib.l, KLib.l, & CLibT.l - These libraries are the Carl Kreider C libraries and were re-written to include many new functions as well as bug fixes to the old libraries. There are docs for these libraries but they are written in “Man” format and need special setup to access properly. I will include these docs in the DOCS directory for those who know how to use “man” files. The “clib.l” & “klib.l” are the same file as far as I know. The “clibt.l” is the “klib.l” library with functions for “floating point” math (I think). (/dd/lib/clib.l, /dd/lib/klib.l, /dd/lib/clibt.l)
  • CGFX.l & CGFX7.l - These are libraries by Mike Sweet that add many graphics, menu, mouse, and Multi-Vue functionality to your “C” code. The docs to this library should be in “/dd/DOCS/cgfx.doc”. (/dd/lib/cgfx.l)
  • CGFXW.l - This is the same library as above, but includes an added extension by Zack Sessions that adds “window.h” to the C functionality. I added this to cgfx.l as was described in the docs. This function allows, with very few commands, to save the current window state and restore it upon exit of the program. This eliminates the “odd” windows that some programs leave you in on exiting. The docs for using this function will be in the DOCS directory (/dd/lib/cgfxw.l)
  • Sys.l - by Microware. This library is the equivalent of the “OS9Defs” file. The current versions of “os9defs”, “rbfdefs”, & “scfdefs” are not compatible with the RMA assembler. Sys.l is an attempt to compensate for this incompatibility. When you need system calls within an RMA file, this library provides “most” of the functions that the original Defs files did. There are still some missing definitions that need to be added, but most are there. (/dd/lib/sys.l)
  • OS9Defs.a - by Microware. This was an attempt by Microware to adapt the os9defs file to the RMA assembler. It is incomplete as it is, but still useful on some occasions. As far as I know, no attempt was made on the SCFdefs or RBFdefs. (/dd/defs/os9defs.a)
  • XXXX.h - These are the various headers needed for the various libraries. The documentation to clib.l and cgfx.l as well as the “NitrOS-9 C Compiler User’s Guide” will have to be consulted to determine when one of these headers is to be included in a C program. (/dd/defs/xxxx.h)

Setting Up The MJK C Compiler System

This C compiler system is the same system Michael Knudsen used for compiling the massive UltiMusE 3 Midi Composer program. Mike wrote several of his own utilities and utilized the latest updates and rewrites of any C compiler module he could find on Delphi, Compusrve ot the OS-9 User’s Group Library. I have added a few enhancements to make it even faster and more efficiant as Mike would have if he had continued to work with the Tandy Color Computer and OS-9. He eventually moved on to the ill-fated MM-1 and then to PCs running Linux. He has ported his Ultimuse 3 program to both platforms and still updates Ultimuse today on the Linux operating system. I was given permission by Mike Knudsen himself to use these sources and utilities in any way I wanted as long as I continue to credit him as the originator.

There will be three virtual disk images in OS-9 format (80 trk DDDS) included in this tutorial package. These images can be used on any of the Color Computer 3 emulators or on a real Coco3, either must be running OS-9 Level 2 or NitrOS-9 Level 2. If you are using DriveWire, then the DriveWire drivers must be installed on your sytem boot disk. The only other stipulation to this system is that you MUST have a ramdisk in your bootfile with an “/r0” descriptor. The C compiler system could be recompiled to use another default temp drive but using the ramdisk just makes sense. It’s much faster than a floppy or hard drive and some larger source packages will definately benifit from the extra speed.

I have included a ramdisk package with this tutorial and I would advise anyone who regularly uses a ramdisk to switch over to this one as it’s the fastest, most reliable, and most conveniant ramdisk I’ve ever used. Kevin Darling eat your heart out! This one “just works” (TM). It waswritten and rigorously tested by Gene Heskett and I will never use another one. More on this later.

As I said, you must have a ramdisk installed. All directories on the system disk must be copied “as is” to your working system disk. To do this, you can use the "arc" program on the CMDS disk. just mount and type "/xx/cmds/arc -amu /xx /dd" and all files will be copied with their directories intact. Arc will then be in your cmds dir so you can use it directly on the other disks. Almost all commands and functions in this system default to“/dd/cmds” for the compiler modules, “/r0” for the temp files, and “./RS” in your working source directory for the unlinked reloacatable object files (“xxxx.r”). I have tried to include all the headers and libraries that have been updated or rewritten for a completely updated C compiling system.

The Tutorial

Along with this C compiler tutorial, I have included virtual disk images containing all the C compiler modules, any documantation I could find for any given module/utility as well as a another disk image containing a copy of Mike Knudsen’s “UBox3” source files. UBox3 is perfect to use as a tutorial as it is a multiple file source combining assembler sources along with C sources. The “makefile” for these sources is a good example of compiling large multi-file sources and I think this is the main reason I particularly chose this program to use as an example. With the UBox3 sources you will see how simple it is to compile these types of packages in one fell swoop. No, I will not be including a tutorial on Mike’s C programming style. You will have the sources... have a go at it yourself. Mike is one of those guys that if a piece of 10 lines of code would compile to be 1 cycle faster in the final object than the simple single word command provided by Microware that did the same function, he would opt for the more complex method to gain that cycle. He knew the K&R C manual inside out and could quote from the book.

The goal of this tutorial is to explain the process of using multiple source files in multiple formats to compile large program files. The UBox3 sources used are not by any means the largest collection of C sources I’ve seen or compiled, but it’s large enough to represent this unique compiling process and small enough that I could get it all on a floppy disk image. Any documentation I can find for any program included with this tutorial will be stored in the “DOCS” directory on the included disk image.

We will start the tutorial with the makefile. This is the heart of the compiling process. In the makefile, you can define each and every operation the compiler is to do to your sources and what to do with them when it’s done as well as what to do with the program(s) it creates. We will be using Tim Koonce’s “Make” which was a makeover of Microware’s make module with a few extended features and some bug fixes on the original. The whole process is not that much different from the normal method with the exception of the long command lines and multiple filenames needed to be typed in when using Microwares C compiler. The “RCm2” modules used by “make”, streamlines the process utilizing the ramdisk for faster compiles on a real Coco and lightning fast compiles on an overclocked emulator like Vcc. Personally, I use Vcc exclusively for all my compiling due to the speed in which it does the job. In just a few seconds, I can do what it would take the real Coco to do in 15 minutes to and hour. The original Ultimuse 3 sources consist of over 125 source files and headers that compile into about 13 seperate files and takes several hours to compile on a Coco 3 running NitrOS-9 from a hard drive! I can compile it on Vcc (max overclocked) in less than a minute! And by using just one command... Make.

The Makefile

The makefile for UBox3 looks very intimidating at first glance. I’ve looked at many sources in the past year, large and small and have never seen anything like this done on the Coco. Mike specifies each and every thing that builds into each source therefore controlling the memory he’s using in the final file. All direct page variables have their own source file as do the global variables. Then each individual source file has it’s own local variables that when compiled, will be used in the stack. The way he lays out his makefile reflects the thought that went into the organization that went into the sources. So with all that said, here is a listing of the makefile to UBox3. It is an unedited copy directly from Mike’s HD image.

***********************************************************

* To make Jukebox UltiBox file "UBox3"

* Upgraded for Tim Koonce Make 90/3/17

* Stackchecking turned off for production 89/10/15

*

* General rules. .c.r specifies how to compile .c files into .r files.

.c.r:;rcr $(RCRFLAGS) -d$(RDIR) $*

.a.r:;$(RMA) $(RFLAGS) $< -o=$(RDIR/)$@

EDIT=4

ODIR= # was /h0/cmds for Tandy Make bug

RDIR=RS

RCRFLAGS = -s -y

*

JFILES=jvirt.r jdp.r jglob.r juke.r jsubs.r jinit.r jio.r jmenu.r\

jplay.r jplaysubs.r

CFILES=juke.r jsubs.r jmenu.r

*

UBox3: $(JFILES) serial.r getclock.r

UBox3Link

jmenu.r: titles.h version.h

jglob.r: size.h titles.h

jinit.r: size.h version.h

jio.r: version.h buffpage.h

jplaysubs.r: keys.h

*

* Always put groups of dependencies after the individuals

* Next cmd lines also apply to .c dependency, yippee!

$(JFILES): jmuse.h

$(CFILES): jcolors.h

serial.r: serial.a

*

* eof JukeMake

***********************************************************

The documentation to TK’s Make is in the DOCS folder on the disk image. These docs are really sparse in explaining the make process. Even the OS-9 C Compiling manual doesn’t explain this process to it’s fullest. With the use of “macros”, you can streamline most any compiling operation. The macros are represented by a “$” followed by a command in all uppercase letters and in parentheses. There is some explanation of these macros in the documentation, but not much so I’ve had to figure a lot of it out by trial and error... a lot of errors!

We will now break down the makefile into it’s various components and see what they do.

The docs to make can explain a lot of things, but I will attempt to explaing some of the simpler aspects here in a breakdown of the Ubox3 makfile

First in the file is the :

* General rules. .c.r specifies how to compile .c files

.c.r:;rcr $(RCRFLAGS) -d$(RDIR) $*

.a.r:;$(RMA) $(RFLAGS) $< -o=$(RDIR/)$@

As it says in the 1st line, you are setting the rules as to what program will be used to “make” the file, and where it will be put. These command will overide the setting in the “make.default” coniguration file found in the /DD/SYS folder. The capital letters indicate a Macro, of which is (for the most part) defined in the “make.defaut” file in the /dd/sys dir.

All that is being said in line 2 is that “rcr” will be used to compile “xxxx.c” files into “xxxx.r.” files and that any “flags” set for rcr are to be used. These are set with a command further down in the makefile.

The 3rd line states that RMA will be used to assemble the “.a” files into “.r” (by rcr), also, it states the default directory these files will use. This is also set later.

For the most part, I leave this alone, as it is more or less hard coded into the rcr sources as well and you want the makefile to reflect the settings in rcr.

The next set of lines deifne our compiling parameters:

EDIT=4

This sets the "Edition" number in the final compiled module.

ODIR= # was /h0/cmds for Tandy Make bug

The ODIR defines the default dir that the final executable object code is to be put, but we actually define that later in the link file, so that’s why this is left blank. I assume it was defined blank to overide the defaults so there would be no conflict with the linker.

RDIR=RS

RDIR is the macro definition for what dir we are going to put our “.r” files. I like Mike’s idea of an RS dir in our work directory so I leave it as is. Just make sure your source dir has an RS dir within it. If not it will error out on compile. I have downloaded a lot of sources the apparently had been compiled before zipping and every “xxxx.c” file had a matching “xxxx.r” file, making the directory hard to navigate. The Microware system stores these files in the current working directory as a default. Using the RS directory moves all these files out of the work directory and provides a convenient place for “touch” to date them. It also cleans up your work directory, leaving only your sources.

RCRFLAGS = -s -y -c

Then the RCRFLAGS defines what parameters we are going to pass to rcr and eventually to each of the compiler modules. To get the rcr options just type rcr -? and you will see all the options for rcr. The “-s” signifies that we want stack checking turned off. You may want this omitted until your code is fully debugged as it’s easy to have a “stack runaway”. The “-y” states the we want to use the CnoY utility. This is optional and occassionally I find a program source that will not compile with this option set. If you start getting “Bad Cmd” errors in the assembler phase, then omit this option. “-c” states that we don’t want to clean up the temp files that are created while compiling. These files are in the “/r0” on the ramdisk. Rcr is hardcoded to use the ramdisk but could easily be changed in the sources to any directory you want and recompiled.

The source code to rcr is in the CSOURCES/TOOLS dir if you want to look at the inner workings of rcr. It’s an intersting tutorial on coding to use external modules from within a C program.

Next we define how our files are compiled:

JFILES=jvirt.r jdp.r jglob.r juke.r jsubs.r jinit.r jio.r\

jmenu.r jplay.r jplaysubs.r

CFILES=juke.r jsubs.r jmenu.r

These lines are basically defining a Macro that says any operation on JFILES is done to every file on the list. Then he defines a second set called CFILES. The \ used in the list indicates that this line continues on the next line. Notice the 2nd group is actually files that were in the first group. These groups are created so they can define the dependacies that they will be using together. You will see more on this towards the end of this tutorial.

The next set will be

UBox3: $(JFILES) serial.r getclock.r

UBox3Link

This states UBox3 as our end-file name for the project. With this you can create multiple compiles of seperate programs from within one makefile. Mike’s actually uses this in Ultimuse3 makefile as he compiles all the subroutines and the main file in one process.

It simply states that UBox3 will use JFILES to be compiled and that the following files will be add to the compilation. The added files are actually RMA assembler files and not needed by the first phase, but will be assembled with RMA. Then the 2nd line states that the external script UBox3Link will be run to link the resulting “.r” files when the compiler is done. (more on this script in the Link tutorial). The Lines from UBox3Link could also be put in the makefile to avoid running a 2nd script. I think Mike seperated his due to the sheer size of UltiMuse and split it into external linker files to make editing easier.

Next is a list of files with no “common” dependacies.

jmenu.r: titles.h version.h

jglob.r: size.h titles.h

jinit.r: size.h version.h

jio.r: version.h buffpage.h

jplaysubs.r: keys.h

These files are the only ones in the sources that use these particular dependacies or combination of dependacies, so they have to be listed individually.

Last in line is the group dependacies:

$(JFILES): jmuse.h

$(CFILES): jcolors.h

serial.r: serial.a

All the files list in the JFILES use jmuse.h. All the files in CFILES use jcolors.h. This keeps us from having to list all these files individually, simplifying the process. I’m not sure why the serial.r lists the serial.a as a dependacy, as the getclock.r does not list getclock.a as a dependant. I have done compiles with this commented out and it seemed not to matter, so I’m not really sure why this is done.

I don’t know if you grasped my simple explination of the process, but you may understand the docs better. I usually use this file as a “templet” and change all the files to my files and use my own naming conventions and it usually works pretty good.

Using the Linker File

Now for the final step in the compilation process. The link file.

Again, I will use the link script for UBox3 as an example.

* echo UBox3Link == build Virtual Memory Ulti-Jukebox

chd RS

t

RLINK -o=UBox3 -M=7 /dd/lib/cstart.r jdp.r jglob.r juke.r jvirt.r jplay.r jplaysubs.r serial.r jinit.r jio.r jsubs.r jmenu.r getclock.r -l=/dd/lib/klib.l

*(all 1 line from RLINK to klib.l)

-t

This is the simplest part of the process, “-o=” is the name and path of the final executable object, and “-l=” are the paths and names of the C libraries used.

Notice: this is where you add the cstart file. It must be the first file in the list as the files are compiled and merged in the order they appear here.

In between are the files being linked, in the order in which you want them linked. Up to this point, order has not mattered. But here, you must order them as you want them in the final object code.

When this script runs, the the final executable obect is linked into one file and place in the dir you described above. Using no path as above should default to “/dd/cmds/”, but I haven’t tested this.

This ends the complete C compile process. Getting the makefile right is probably the hardest part to understand (for me) but once you undestand what is being done, it’s pretty painless. Make also has a few options of it’s own that can be called on the command line when you provoke make. To see these optione type

make -?

The real change to this compiler system is the use of RCm2 (rcr), C.comp & CnoY. These 3 files along with the new “make” will produce faster, more efficiant, and much more stable code than any compiler I’ve tried. Any one who has used my “Sound Chaser” music player for OS-9 or my “DW4Man” for NitrOS-9 and DriveWire has seen the results of this compiler system. I’ve used it exclusively for these programs.

As I think of things I've missed in this tutorial, I will add them as soon as I get a chance. For now, enjoy the MJK C Compiler system. I know I have :-)

web counter