A brief history on the changes. I first started changing DECUS C because I wanted to build split I/D programs. While this seemed straightforward at first, I soon discovered several problems. Initially I just changed the c compiler psect directives to include the correct attributes. Since as already supported this, that was enought I thought. Things kindof worked, until I had the next bright idea. RSX-11M+ supports something called multiuser tasks, where the read-only part of a task is shared by all who are running the task. When a task is linked this way, all r/w data sections are collected at the low end of address space, while the r-o data sections are collected at the high end of data space. It now turned out that the memory initialization was severly broken. It didn't know about d-space, and it definitely didn't know about read-only data, nor did it understand that end of writeable memory might not be 177777 (which it definitely isn't in a multi-user task). This problem was also appearent if you linked with a resident library. Furthermore, the memory initialization didn't handle if you ran a program with some increment when started. In that case, you already have some allocated memory area, which should be used. To make matters even worse, you had supervisor mode libraries, which should *not* count at all. To make the long story short, the whole memory initialization routine had to be rewritten. Once this was done, I had a C compiler that could generate I/D space programs, multiuser programs, linked to resident or supervisor mode libraries, and everything worked. However, I knew that profiling was broken (but who use that? :-). However, the patches I had made was for a fairly old release of DECUS C, and a newer version was available on the net, so finally I decided to merge my patches together with this new version, which also had support for RMS, among other things. So I redid my patching for this new version. Once again modifying the C compiler, and the libraries, so that all psects had the right attributes. I also redid the memory initialization. Things worked fine, so I decided to test RMS as well, since I tought it would be fun. I immediately discovered that this didn't work at all, and after debugging things (and learning RMS-11) I discovered that the initialization was supposed to open stderr before anything else could happen, and the RMS code to open stderr was seriously wrong. So I had to fix that, and things slowly started working. Lots of testing and small programs later, and I had my test program running (MicroEMACS actually). Things were looking good, so I decided to challenge fate again, by also testing DAP. Once more I was bitten. Things were working fine, but the file protection on files created on other nodes were not satisfactory. I now realized that a program like EMACS really should preserve the protection of files edited, so I rewrote EMACS slightly, and added functions for file protection. Things worked fine for files edited locally, but not for files over DAP. They got really strange file protections. This turned up to be a bug in DAP when reading the file protection of an opened file. So I had to find the bug in RMSDAP, and fix it, and lo and behold. DAP worked like a charm. A few small bugs was found in the FCS version however, mainly fgetname(f) giving the wrong filename back to me, and not preserving the directory. These were fixed, and both libraries was looking good. The next thing to attack was profiling. I started to think that it sometimes might be nice to have. But after looking throughly at how it was implemented before, I realized it really needed a full rewrite. The previous profiling assumed that you could read data stored as a part of the code, and it also scanned the whole program memory to find profile blocks. This was both inefficient, uncertain, and slightly silly. I decided to add a profile pointer to the stack frame. This meant a modification of the C compiler to generate new code when profiling was requested, and rewriting the library functions involved. A few nights later this was working like a charm. Next I started looking at the RSX extensions library, to make the psect changes there as well. I immediately stumbled onto the ast handling code. Since I had changed the calling sequence and stack frame for C functions, I had a small problem. The AST functions in CX needed serious rewriting to work. While pondering this I came to the conclusion that it was doable, but only if the functions wasn't compiled with profiling, and it was still ugly. It would be much better if the compiler could know that a function was an AST, and generate better code right from the start. Then I remembered about the #pragma directive, which is supposed to be used for these kind of things. Said and done. I needed to add #pragma handling to DECUS C. This was a major change, requiring a new internal operation, new decoding, and new gode generation. While I was about this, I remembered about the DECUS C-specific ident, psect and dsect statements, which are rather ugly. These too should have been #pragma directives, so I threw them in at the same time. The old statements were left in, but now generates warnings about not using them anymore. Testing the compiler showed that it generated nice enough code, and all of this also meant that another ugly thing of the old CX AST handling could be dropped, namely how to access trap dependant parameters. I let them become normal function parameters instead, and also used the argument to the return statement as the number of words to drop from the stack before doing the ast exit. Much nicer and cleaner interface. As a final measure, I remember being a bit bothered when moving some code, when the void data type don't exist. So I added it to the compiler as well. The result is a working C compiler and environment, and one which is much improved from what came from DECUS. But, as usual, no guarantees are given. If you find a bug, I might be interested in hearing about it, but I might not fix it. It all depends on my time and interest in the subject.