The Apollo Guidance Computer had its code stored in six modules that held 6 kwords of storage each, and the design of each module was such that changing even a single bit after construction would have been very difficult. On the other hand, the computer was constructed in such a way that swapping one module out for a different one would have been fairly easy.

Was any effort made to design the code in such a way that if a defect was discovered, it would be possible to fix the code by rebuilding one or two modules, using the other four or five without modification? If so, what techniques were used for that purpose?

If code was simply assembled from scratch after each time it was changed, many address references scattered throughout would be likely to change if any instructions were added or removed, thus requiring that all memory modules be rebuilt. On the other hand, there are a number of approaches that would seem possible to minimize such issues.

One approach would be to subdivide the software into six separately-built pieces of firmware, each of which started with a jump table to all of the externally-callable routines. If all inter-module calls are dispatched through the jump table, changes to the code within a module would have no effect on external calls that were dispatched through the jump table.

An alternative approach would be to have the jump table for all modules, as well as most of the unused space, consolidated within one module. If any routines need to be modified, it would be necessary to change the module containing the master jump table, but if the routines aren't too big, no matter which module originally held them, a fixed copy could be placed within the master jump module without having to modify any other modules.

Did the AGC or any other early programs make use of such techniques to ensure that changes to ROM could be consolidated in as few modules/chips as possible?

  • 1
    link to source code of the program: github.com/chrislgarry/Apollo-11 – UncleBod Mar 16 at 9:24
  • As mentioned on Wikipedia: "some key parts of the software were stored in standard read-write magnetic-core memory and could be overwritten by the astronauts using the DSKY interface, as was done on Apollo 14." – Brian Mar 17 at 18:00
  • @UncleBod: Is there any sort of memory map to say what parts of the code were in what address ranges? Was there any effort to distribute some free space in each ROM module so that if need be one could insert instructions into a section of code by replacing the first instruction in that section with a branch to unused space, putting the replaced instruction (if needed) in the unused space, and then jumping back? – supercat Mar 17 at 20:28
  • 1
    Supercat, are you interested in machines where multiple ROMs are each read by different processors, too? That's not my reading of the question, but at least one answerer disagrees (in comments), so perhaps you could edit to clarify whether that's within scope. Thanks. – Toby Speight Mar 18 at 17:50
  • 2
    @snips-n-snails: Separate address spaces would be fine, if code in one address space were to make use of things stored in another. I don't think that principle would extend to things done with multiple processors unless they sent commands to each other that referred to the addresses of things (e.g. execute the routine at address XX). – supercat Mar 18 at 21:56

The AGC, at least, didn't employ any such indirection. Calls to subroutines in other banks were performed via the BANKCALL routine (TC BANKCALL followed by a CADR pseudo-instruction containing the target label). CADR encoded the destination bank and address directly. If a routine moves because previous content in the same bank got longer or shorter, all callers would need to be updated. Calls to subroutines in the same bank, or subroutines in the first two "fixed-fixed" banks (which were always addressable regardless of the bank-switch register) were done by direct TC jump, again encoding the address directly (in fact, since TC is opcode 0, the instruction word is the address).

| improve this answer | |

Isn't that the basic usage of any modularization? As soon as there are multiple storages, they can be exchanged vor updates - For the Apple II, for example, it happened twice: Changing the Monitor-ROM with Autostart-ROM and/or Integer-BASIC-ROM(s) with APPLESOFT-ROMs.

Beside that, most (large/early) Computers didn't have massive ROMs but only microcode. The AGC is an outlier here as it is more of an embedded system. Microcode was more often than not patched on a level smaller than a module. Like exchanging single cards or rewiring some bits.

Also, a closed system/single application, as the AGC is, doesn't need to waste much space for abstraction layers, as any replacement is better made to simply fit the external references (entry points) exactly like its predecessor.

| improve this answer | |
  • 2
    Suppose that shortly before launch a bug was discovered in the program that required making a routine slightly larger. If one were to simply add a few instructions and reassemble the code, that would have required weaving six new rope modules. There would have been various means, however, by which the number of new modules required could be reduced to one or two. My question is whether such means were employed by the AGC, or if not what system first deliberately employed them. – supercat Mar 16 at 15:23
  • At that time noone would have assembled the whole ROM(s) again. it would be a patch.Keep in mind, software production methods at that time were not like today. It wasn't done by some build system crunching everything at once and regenerating from scratch. – Raffzahn Mar 17 at 10:20

Anytime you have a machine with multiple microcontrollers, you will have multiple, independent ROMs. Factory automation systems for example contain dozens of microcontrollers linked together on a CANopen network, with predetermined Node IDs on the bus and Object IDs (addresses) on each node. If a node needs to communicate directly with another node, it needs to know the second node's Node ID and and the destination Object ID for the message, similar to a jump table in a single-CPU solution.

In this way, each ROM is independent of each other and can be updated independently with new firmware without requiring addresses (node and object IDs) to change. It's basically a decentralized solution to the problem of address references changing when a ROM is changed.

| improve this answer | |
  • 4
    This is very, very far from being relevant to the question. – hobbs Mar 16 at 15:57
  • @hobbs Is an automobile not a multi-ROM machine? – snips-n-snails Mar 16 at 16:56
  • 1
    Not in the sense of the question, no. – hobbs Mar 16 at 16:56
  • @hobbs The question as stated or the question as you feel it was intended? – snips-n-snails Mar 16 at 16:59
  • 4
    I think that the question is fairly clearly not about multi-CPU systems, such as a car with several separate microcontrollers running separate programs for different systems within the car, but a single-CPU system running a single, monolithic program. – cjs Mar 16 at 23:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.