From: uhclemLOSE.sep07@nemesis.lonestar.org   
      
   turnkit wrote:   
   : Frank,   
   :   
   : Say I had game code written for the Model III in ALDS. Wouldn't I   
   : still need any TRS-80 "libraries" -- i.e. if the ROM kbu input routine   
   : is called for instance -- to get the code to compile under gcc on   
   : Linux or cygwin?   
      
   : Please excuse the basic programming ignorance here... it sounds like   
   : there is a lot of potential good for having this compiler but I don't   
   : understand it too well.   
      
   IMPORTANT PREFACE: Assemblers are not compilers. Compilers usually   
   convert a high-level language program into assembly language which is   
   then assembled by an assembler (usually silently), and then possibly   
   linked with a linker to make an executable file, or the assembler output   
   may be ready to run as is. This is demonstrated below.   
      
      
   The bulk of the question needs some explaining about the environments   
   of today and back then.   
      
   The typical practice for programs written in that day in assembly   
   language was that there were no system "libraries" to link against.   
   You either had a collection of functions that you wrote yourself or   
   obtained somewhere else and you linked them into your program when   
   you assembled it or compiled it.   
      
   On these operating systems on these small computers, there was no   
   dynamic linking (the program loader was very simple), so if a linker was   
   used at all, it was only during the assembly or compilation process to   
   produce the executable, or as we called them on the TRSDOS platform,   
   the /CMD file.   
      
   The operating system rarely provided anything but the most basic   
   services compared to the things you hardly think twice about always   
   having available in our POSIX-compliant world we have today.   
      
   The reason for this spartan environment is very simple: We had no room.   
   Anything of any size that a given program didn't use had no business being   
   in RAM anywhere. On the TRSDOS platforms, the address space footprint of   
   the disk operating system could be as little as 10K, less in certain   
   situations. There was simply no room to have the equivalent of "libc"   
   sitting there with a hundred functions, none or few of which a given   
   program would need.   
      
   Believe me, we would not have resorted to "overlays", "banking" and other   
   methods of making programs of all types appear to be smaller than they   
   really were unless it was necessary. That's why the operating systems   
   routinely had overlays, so the OS would consume as little space as   
   possible and leave as much as possible open for the applications.   
      
   By comparison, the mainframes of that day, such as the IBM 370   
   could have a whopping 2 Meg of RAM (sometimes semiconductor,   
   sometimes ferrite core memory) so using pre-linked programs were far   
   more common in those environments, where application programs could be   
   a few hundred K in size, not a few dozen K like the Z-80 systems had.   
      
   (That's why programmers who stuck their initials in places in code usually   
    selected locations that didn't increase the overall RAM size of the   
    program unless they were well under RAM budget. See "RON" in some of   
    the old Model III and Model 4 "A" ROMs - that's Ron Light.)   
      
      
   Now, the use of linking itself isn't the problem that causes programs to   
   be large. In fact a good linker strives to include only functions that   
   are actually referenced into the statically linked program. The problem   
   is that standard generalized library functions almost never do just and   
   only what you need done. They have other stuff in them that could be   
   useful in other situations and to make them a well-rounded,   
   swiss-army-knife version of whatever it is that needs doing, but the   
   trade-off there is in memory size, and there is no good way to make an   
   individual function jettison bits of itself that for a given situation   
   won't be necessary. You will see what I mean about extras in a moment.   
      
   The operating systems of that day sometimes made what we would call   
   "library" grade services available via operating system services/system   
   calls/JSYSs/SVCs. For example, there is a "C" library function called   
   atoi(), which converts an ASCII string containing a number represented in   
   ASCII characters, into a binary value for use in computations, and on   
   these older systems, that sort of thing might show up as an operating   
   system call. The main reason this happened was because some other part of   
   the operating system or supporting command interpreter and utilities needed   
   the very same type of conversion in lots of places, and there was little   
   overhead in transferring control in to the operating system back then,   
   so getting to it didn't use much extra CPU time.   
      
   On those systems, programs written in "C" (which were few) would call a   
   library function (such as atoi()) and that library code might turn around   
   and take advantage of a locally available operating system call that   
   performed all or part of the same function, simply so the library   
   function would consume as little memory as possible. Other times,   
   the operating system call didn't quite implement the operation in the way   
   desired, so that function had to be duplicated in the "C" library,   
   with the needed differences.   
      
   And that's one big reason why "C" didn't really catch on for the   
   8-bit processors. The standard set of libraries and functions and   
   all the other bits of an increasingly sophisticated programming   
   environment were simply luxuries that were either too big or too slow   
   (or both) for these machines which rarely had a total of 48K of RAM   
   available for the application, and sometimes as lttle as 8K.   
   You just couldn't afford to carry around all the "what if" testing   
   and unneeded features that standard "C" library functions come with,   
   most of which was not needed in a given task.   
      
   For example, let's use the atoi() function as a comparison one more   
   time. In most of the TRSDOS/LDOS/LSDOS operating systems, there was   
   an operating system call such as @DECHEX, which converted an ASCII   
   string into 16-binary number. Today, such simple conversions   
   would be beneath what you would put in the operating system core   
   (also because it is very expensive to transfer control into the   
   operating system when the processor implements a protected   
   "supervisor" mode, and the operating system is providing multi-tasking   
   services), but back then, the OS and application were both in the same   
   sandbox so no big deal jumping from one into the other.   
      
   The operating system needed DECHEX for all sorts of things, as   
   did the command interpreter (where you are when you see a "DOS Ready"   
   prompt), and the system utilities, and so why not allow applications to   
   share this already-present bit of code too? Memory is tight, so share   
   the bits you have rather than have multiple copies of the same thing   
   in RAM at the same time. This was usually considered a good thing.   
      
   Now, DECHEX is very simple. Point it at a string of numbers and it   
   converts it into a binary integer value. It stops when it hits a   
   non-numeric character, eg not one of these '0123456789" characters.   
   It doesn't care nor does it report if the converted value overflows   
   and won't fit into 16 bits, so if you care about that possibility, you   
      
   [continued in next message]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|