 Hello. Hi. I'm Steve Baines, a quick talk on the Apollo guidance computer. It is going to be a quick overview because it turns out actually in 30 minutes you really can't get that far into the details. So I'm just going to cover some of the interesting areas and particular things that by modern standards are somewhat strange. So Apollo was a while ago now, so some people here might really not know anything much about it. So a quick summary of the two spacecraft to get to the moon, the command service module on the left, the command, the bit at the top, the triangular bit is basically the command module. That's where the crew lived. Everything behind that is basically a fuel tank and engine. So that's the command and service module. On the right you have the LEM, the lunar lander, which was what was used to actually land on the moon. Both of those had one Apollo guidance computer in them, identical hardware, but slightly different software. Oops. Too many slides. Okay. So first thing, why even was there an Apollo guidance computer? Well, it basically was very much at the core of the spacecraft. So from this diagram you can see you've basically got at the top you've got the disk key, which I'll talk about more, which was crew input output talking to the computer. You've got various radio communication links, uplink and downlink telemetry. Over on the left hand side is the inertial measurement unit and optics. So the inertial measurement unit was electronics that basically, it's a gyroscope, a stabilised system essentially, and that's used to tell the, allow the spacecraft to know which way it's orientated and what velocity it's doing. You also have zillions of switches and so on, all running through the machine. And most important of all, the engines and reaction control jets connected through the computer. So essentially the computer is at the core of everything. And a big reason for this is when it comes down to it, despite what Hollywood may say, if you're flying spacecraft, you can't eyeball it. It has to be very precise manoeuvres at just the right time, you know, exactly like orientation, engine on and off at exactly the right time. You can't eyeball it. So essentially it's all run through a computer. Okay. So this is the one side quick summary of the key characteristics, which on my screen is really tiny. So it's a 15 bit word length, which is kind of odd. A sign bit plus 14 bit data, if you're interpreting it as a value. Or when it's an instruction word, it's a three bit opcode and a 12 bit address. And it would help if I could read that with these glasses. It's an accumulator machine, von Neumann architecture. So instructions and data are the same thing. There's no stack, which is a curious thing. It did have interrupts though. And again, if I could read this. So the memory is 2k words of a raiseable memory, 36k words of fixed storage. And I've shown at the bottom of the slide the kind of breakdown between opcode and data. It used one's complement, which just doesn't get used anymore. In one's complement representation basically to negate a number, you just flip all the bits. Unfortunately, a side effect of that is you have two zeros. Because if you have zero, you flip all the bits, you've now got all ones. That's also zero. So in this system, they had plus zero and minus zero as distinct things, which brings its own complications. I pressed the wrong button again. Okay, so this is what it looked like. The box on the left, the goldish colored thing, is a computer. The thing on the right is the diskie, which is the main interface for the astronauts used to talk to it. So it was a sealed unit milled out of brilliant, apparently. They did originally consider making it user serviceable with replacement, sorry, replaceable modules for in-flight servicing. But ultimately, they decided that making the whole thing sealed was actually going to be more reliable in the long run. So totally sealed unit, no user serviceable parts. If we look inside it, if you open it up, it looks like that. The right hand, it's basically two trays that fit back to back, and that's very separated. So the right hand side there is all of the analog circuitry, so oscillators, timers, power supply, alarm circuitry, that kind of thing. There's a slot at the bottom where there's a missing module. That is where the erasable memory or the RAM goes, but it's not in this diagram. And the ROM, the fixed memory is basically, again, you can't see it, but that's in the top half on the right side. So the left hand half of it is where all the computer logic is, and that's basically a set of modules. There are 24 logic modules all plotted in, nice and neatly, with in theory, each one of these modules is a specific aspect of the computer, such as a register or so many bits of the ALU. So in theory, a kind of nice tidy design. Inside these modules, these modules are identical, the 24 of them, as I say, they're all identical other than the wiring. And they look like that. And if you turn them up or down, they still look like that. You basically have two single-sided circuit boards, each containing 60 chips, meaning the whole computer has got about 3,000 chips altogether. These chips are all exactly the same. They're all dual three-input NOR gates. Now, NOR gates are universal logic elements. You can build any digital logic you want if you've got NOR gates. The reason they went for a single chip is because this was made in the very, very early days of integrated circuits. It was still even considered risky to be using integrated circuits at all. So the thinking was that, well, if we only use a single type of chip, the manufacturers have got a realistic chance of getting good at making that one chip, and we should get good manufacturing yields. So hence the whole thing, all of the logic is made entirely out of the one type of chip. It's only got six transistors in it. And that's what it looks like inside. The transistors are the small blobs right in the middle, and most of the linear structures around it are the resistors. So it was good for yield, good for manufacturing reliability, but it doesn't actually lead for a very efficient system. Or you can build anything out of NOR gates. It's not a very efficient way of doing it. If you check the schematics, it turns out that about a quarter of all of the gates were just users inverters. So having three inputs where you need one is a huge waste. If they made a chip as well, which was just inverters, then with the same kind of level of integration, they could have fit four per chip instead of two, and they could have basically got away with 21 logic modules instead of 24, which would have been a significant saving, especially when getting the weight down was really important. But these are the trade-offs, and we'll go for one thing to make it reliable. So I think I skipped... No, that's okay. So this is the diskie, as I said. This is the main way the astronauts operated the computer. Essentially, it's kind of a glorified numeric keypad in the bottom half. The top left is a bunch of various alarms that the computer would trigger for various things you need to worry about. And the right-hand side, the main piece of information is there are basically three, five-digit numbers. That's essentially your monitor. That's the information that the computer could give you, just three, five-digit numbers. So a few curious things about this. Well, first of all, as I say, it's essentially a glorified numeric keypad, but on the left-hand side, I'm not sure how visible it is, the two keys on the left are curiously named verb and noun, which is kind of more in place for a text adventure game. But it's a very clever idea. Again, this was developed when people were still really figuring out how should people operate a computer? And in this particular case, they needed something astronauts wearing spacesuits and gloves had to be able to operate, so big buttons and a simple interface. So the idea was that the verb noun interface is that the general way the astronauts would restrict the computer what they wanted it to do is they would press verb, type in a number that represented what they wanted to do, and then noun and another number representing what they wanted it to do it to. So, for example, verb six means display in decimal, and noun 43 is latitude, longitude, altitude. So you type verb or six, noun 43, enter, and on the three displays, you get your latitude, longitude, and altitude in decimal. And they had cheat sheets, you can see one below on the right, a cheat sheet so that you have to remember what all these numbers are. Another curious thing is the display, it doesn't have decimal points on it. You kind of assume they probably are, but there aren't. The decimal points are implied. And again, this is on the cheat sheet. If you're looking at, usually if you're looking at something that's in degrees, then it's in hundreds of a degree. If it's a distance, it's in a tenth of a mile. And you can either remember this or look in the cheat sheet. This whole idea of the diskey, incidentally, was not something that was kind of carefully planned. It originated from a lab demo. People working on the computer needed something to show visitors. So they came up with this idea, okay, we'll use this verb noun thing we've just dreamt of. And apparently there was quite a lot of opposition to it. It got described as not scientific, not military, not serious, not dignified. And my favorite one, astronauts won't be able to understand it, which I think it's really, but yeah, they did. And the final thing is also, they're not LEDs. It's an extra luminescent panel, high voltage extra luminescent with a ton of LEDs, sorry, a ton of relays. I think it's 130 relays behind them. And it had a relatively low update rate, because the computer could only communicate, essentially change one set of relays at a time. So it would be, I don't have a video, unfortunately, but it would take, you know, if it was redrawing the whole display, even though there's not much in it, you could see it very clearly refreshing. Okay, very quickly about memory. So, yeah, so erasable use magnetic core memory, which was fairly standard technology for the time, a grid of ferrite, which got magnetized one way or the other to represent a one or a zero. This isn't actually out of the, sorry, out of the AGC, because I couldn't find any good AGC pictures of the erasable memory. As I said, the slot that it fits in, you'll notice it was a kind of long rectangle. So the real thing was kind of all folded up, rather than sort of flat like that and then potted. And they just don't seem to be many good pictures. But that's out of the Saturn 5 for, yeah, for good measure. So that was erasable. As I say, standard technology for the time. The curious thing about erasable, sorry, magnetic core memory is, it's non-volatile, which is nice. You can turn it off and on and it's still the same things. But reading it is destructive. So if you read it, you've just set that location to zero. So if you don't want it to be zero, you need to write it back again. It's just a quirk of the way the technology worked. So for the fixed memory, they use something different. It looks superficially similar. And this is actually from the AGC. This is a core rope module. It looks superficially similar, but it's not actually arranged in a grid. It kind of looks like it there. If I skip to the next slide, it's a little bit closer to it. The way core rope worked is essentially the data isn't stored in the ferrite rings. The ferrite rings are used as switching cores, essentially transformers. And the data is stored in the wiring because the whole point is this is supposed to be fixed memory. So the wires would be woven through these cores. And for each bit position, each addressable bit, it would go through one core if it was a one or through a different core if it was a zero. And you can kind of see going from left to right, it kind of snakes around left to right at the top and then around and back across to the left. You see the two cores in the middle don't actually have any wires between them. So this conceptually is just a long string. It just got folded up to kind of fit inside the package. And these are hand woven. This is some lady at Raytheon who manufactured these, a set of wiring by hand, the core memory. So the idea was this machine would, there was a little kind of guide, a little pointer. The machine would kind of, she would thread the wire through and then the machine would kind of move on to the next location. So she's got a pointer saying thread it here, now thread it here, now thread it here. Because, of course, you can't really afford any mistakes. And however careful you are, you're going to, if you're doing it entirely manually, you're going to make mistakes. Okay. So unfortunately, that's it for the nice pictures because I now get into the computer itself and it's kind of hard to find photos of how a computer works. So the memory, as I say, it was 12th bit addressing, but they had 38K of memory. So that doesn't fit. So there was a banking system. And essentially, the first one K of addressable memory was all erasable. The remaining 3K was fixed, but the top of erasable and the bottom of fixed used a banking system. And there were banking registers, which are on the next slide, which basically show where in the memory map, how the different banks of erasable or fixed memory are slotted in. So essentially most of it is always in the same place, but then there's a whole load of banks that can be selected in. In particular, there's a lot for the fixed. But remember, this couldn't load any software. All of the software for the entire mission had to be built into the machine. So essentially, loading new software was, to a certain extent, switching banks. Okay. So at the bottom memory of the registers, it's all memory mapped. So A, the accumulator, or any mathematics goes through the accumulator, like with most very early machines. The then L, which is a lower accumulator, which is essentially an extension to the accumulator for longer operations. You then have Q, return address register. There was no stack. So if you branched somewhere, then the return address would go into Q. If you wanted to, so if you do it to a sub-routine, return address to Q. If that sub-routine wanted to go to another sub-routine, okay, you now have the responsibility as a programmer to store the current value of Q somewhere so that when you jump to the sub-routine and it returns to you, you can get back. So there's no stack. You have to, as a programmer, you'd have to manage all of that manually. And similarly, parameters, they can't get pushed onto a stack. They have to be in, you know, well-known locations. So, yeah, so most of the locations in a raisable memory were kind of pre-allocated. So essentially everything was global. There was no memory protection or anything. And memory locations would be reused, but they'd be reused between programs that wouldn't run at the same time. So, for example, code that's running during re-entry into the Earth's atmosphere has got nothing to do with orbiting the moon. So programs for those different phases can reuse the same memory locations. So I'll skip the next few. The bottom of the slide, there's four things called the edit registers. These are interesting. Again, these are just memory locations, really. The instruction set doesn't have any bit shift operators, but it does have these edit operation locations. If you write a value to one of those locations and then read it back again, it's been bit shifted or cyclic shifted. So there you have, although you don't have an opcode for bit shifts, you can achieve them. It does have the curious side effect that you can't use them if you're in an interrupt, because interrupts need to be able to restore the state and you can't restore the state of those registers, because if you read it and write it back, you've changed it. Next in memory is time encounters. These kind of stored the critical state of the system. So first up, timers. The first one timer, one or two, is essentially just literally a mission timer. I think it would run for about a month before overran. So a two-week mission to the moon was fine. Timer three was for things called waitlist tasks, which were very short but time critical tasks, which will be scheduled to happen at a specific time, interrupt driven. Timer four was a general kind of interrupt driven household, household, sorry housekeeping type code. And five and six were the digital autopilot. It was a fly-by-wire system and interrupts kind of made sure that this was running smoothly. So essentially timer five was used to make sure the digital autopilot code got run every 100 milliseconds, so 10 turts some update rate. And timer six had the rather important term task of timing when to turn off reaction control jets. So every time the autopilot did a pass, it would decide which jets if any it needed to turn on to adjust orientation. And it would then set timed interrupts based on counter six as to when these jets should be turned off. So every time timer six expired, it would then call an interrupt service routine which would turn off that axis worth of jets and then wait for the next one. So a lot of it ran on interrupts, which is super critical. The next slide I will skip over. That's how all of those things fit together, but absolutely don't have time to go through them now. The slides are available, so some of this stuff is the idea is if you're interested you can look at it later. Instruction set, as I say, it's basically you only had three bits. So you've only got eight instructions, which really isn't many. So yeah, I'm getting kind of time, so I'll skip through quickly. But yeah, you only had eight basic instructions. It's sure incomplete, but it's not least to work with. So one particular transfer to storage, which is save the accumulator to a memory location, simple enough. But also if the accumulator has overflowed, skip the next instruction. Okay, whether the accumulator has overflowed is kind of important because there's no way of storing the overflow state. So as with the edit registers, if you've got an overflow in A, you can't have an interrupt. So if there's an overflow in A, interrupts are disabled. Given how much runs on interrupts, that's not including turning off reaction control jets. That's not good. So the program of being responsible for and carefully handling overflows was super important. It's very unusual that an overflow causes interrupts to be disabled, but that's how it worked. So this was one of the main ways of handling it is this instruction. It clears the overflow and you've got a branch depending on you couldn't directly test for an overflow. This instruction was essentially the simplest way of doing it because you've got a conditional branch essentially. The next interesting one, this is your kind of comparison instruction which is actually a four-way comparison. It'll jump, it'll, well, it skips one, zero, one, two, or three instructions depending on the whether the accumulator, sorry, whether the value at a particular memory location is greater than zero, less than zero, or equal to plus zero, or equal to minus zero. So again, you have the two distinct zeros in there. Now, as I say, eight instructions, it's chewing complete, but it's not very easy to work with. It's quite clunky. So they squeezed a lot more instructions in there. So the first thing they noticed is, oh, okay, well, if you've got, for example, increment value at a memory location, that only makes sense to do that on RAM, erasable storage. Erasable storage is always 10-bit. So the upper two bits of the address, you don't need those for those instructions. So you can reuse those op codes, essentially, for new instructions. So they introduced a bunch of new instructions. The most important one there is index, which it, so index K, it takes the value at memory location K, and then it adds that value to the op code, sorry, adds that value to the next instruction word, which has the effect that it's provided you a way of doing indexed addressing. So again, there isn't an indexed addressing mode as such, but there is this kind of slightly hacky workaround, which achieves that. And then also, it doesn't make sense to do a branch to the banking registers, which I skipped over those. The bank control registers were also in the initial very low memory address. So it makes no sense to branch to the memory banking registers. So again, those bit patterns got interpreted as new op codes. So the main ones on there are basically enabling and disabling interrupts and returning from interrupts, but there's also extend, extra code. Okay, what's extra code? Well, that says interpret the next instruction word according to a completely different set of decoding rules. So you've just doubled the size of your instruction set. And they did similar tricks with that to, again, rather than just getting extra eight, they got a whole bunch more. So in the end, they packed basically 14 instructions into three bits, kind of. So yeah. But it was still kind of, still quite primitive. With the new instructions, still the most advanced mathematical operation you had was single precision, multiply and divide. And it's all integer, by the way, I forgot to mention, there's no, none of that floating point stuff. Everything's integer. And it's up to the programmer to scale things and handle overflows. So even with this kind of extended instruction set, the most strongest, the most powerful mathematics you can do is multiply and integer divide, multiple integer multiply, integer divide. So what they then did, and this is, I think, the real nice thing, is, hang on, have I got these in the wrong order? Right, sorry, yeah, slight digression. Yes, what they then did is later. So having talked about the interrupt driven stuff, not everything was interrupt driven. You've got a whole bunch of firm things where you've got longer running jobs, so essentially navigation software, you're trying to do a navigation solution. It's not interrupt driven, doesn't need to be super responsive. So essentially, you need a way of running jobs, long running, and they just, you know, with different priorities and they just kind of complete whenever they complete. So they did implement a multitasking system, but it was a cooperative multitasking system. Every job had to cooperate with every other job. It only works if you can totally trust all of the software. So rather than there being an operating system that would basically forcibly switch contexts, instead what happened in each job, every 20 milliseconds was supposed to check if there was a higher priority job waiting. And if there is, voluntarily hand over control. And basically if they don't, then the system falls apart. One nice feature in there, though, is that obviously if you, for example, due to a software bug that got stuck in an infinite loop, then you could end up with a program that's currently running, stop checking for other jobs, and these other jobs will then never run. So there is a hardware watchdog that is monitoring the location that you check to see if there's a higher priority job waiting. And if half a second goes by, I think, 640 milliseconds, goes by without that being checked, then the computer does a restart. So that gets a chance to break out of that. Okay, time is getting a bit low, so I'll quickly skip over this. Yeah, so again, if you want to look at the slides there's more detail here, including my own notes on this. Essentially the message here is that it could support these multiple jobs, but each one had a kind of context for that was very small. You had basically, I think, 12 memory words, which basically the scratchpad space that that task could use, and then a couple of extra words just to kind of manage the system. The wait lists, I will also skip over, but they were just the triggering tasks at very specific times. So the thing that I thought we'd got to earlier, but I was getting ahead of myself, the really nice thing, is the interpreter. So as I say, the most powerful instructions you've got is a hardware, sorry, is a multiplier or divide. But the kind of tasks that you're potentially solving tend to involve an awful lot of matrix and vector algebra. You're dealing with orientations and accelerations and velocities and trying to solve trajectories. So that's kind of hard to do if you're working at kind of the level of just scalars. So they introduced an interpreter system, which was essentially a virtual machine. They simulated an entirely different architecture, which had a much richer instruction set and was much simpler to work with. So it was, we had seven bit op codes instead of 14. So you've got, sorry, instead of three. So you immediately got lots of space for different operations. They used a flat memory space, so you didn't have to worry about banking. And it, but in particular, the key thing about it is it had this idea that rather than the accumulator now just being a single scale of value, they had, I think, all the multipurpose accumulator, which could represent a single double or triple precision scale of value or a double precision vector. So you've now got an accumulator that's a vector. That's pretty impressive for an early computer. And the virtual instructions that they implemented on this, as I say, very rich instruction set, 127 instructions, included things like matrix multiply and vector normalization and projection, trigonometric functions, all kinds of things that basically would be a nightmare to do with the cumbersome and error prone to do using the low level the raw instructions. I'm struggling slightly because on my preview, I can't actually read that text. If I close that, that's better. Yeah. Okay. So yeah, so the interpreter used a substantial amount of the memory of the system and the memory was very, very tight even with all this banking going on. There was a lot of software that got developed for the computer but it ultimately got scrapped simply because it would be useful but not absolutely essential. So especially for things like handling kind of non-nominal situations where we could get into this situation and if we do, it would be really useful to have a piece of software that can solve this kind of thing. And they ended up just scrapping most of that because space. Even if you extended the banking, you'd still need to weave more and more core ropes and physically find space for them and so on. But they, but nonetheless, they decided that even though memory was very, very tight that it was well worth devoting a substantial amount of that memory to implement this interpreter which then allows people to write in, you know, write the, basically allow the people writing the navigation software to worry about the navigation algorithms rather than worrying about, you know, working with very, very low level operations. And I find it quite interesting that on such an early machine with very, very, that was very slow in the first place. Again, I skipped it. The clock speed of this is basically a megahertz but it's 12 clocks per instruction cycle and most instructions took two cycles. So it's about 40,000 instructions a second. So it's pretty slow. The interpreter is much slower still because you're running an emulated machine. But it's interesting that, you know, they found that it was, you know, that they realized even then that it was well worth paying this overhead in computer time on a computer that was already very slow in order to make programers more productive and, you know, make it less likely that they would make mistakes because they could focus on the domain they were trying to solve navigation and not have to worry so much about the hardware. And this idea of abstracting away the hardware to allow you to use a kind of higher level language. It's not really a high level language. It's, you know, but it's a, it's an easier to use machine with a much richer instruction set so you don't have to worry so much about the fine details. I think it's kind of very interesting that they realized even back then that this was, you know, was well worth doing. I think I'm almost there now. Again, this is, I've got, well, I've got a couple of minutes. So, so essentially, yeah, so the one thing with interpreter is you did need to store additional state because obviously this simulated machine has context. So you could run if you were running programs that ran on the kind of the native instruction set, then the task that you, that you had, the task storage gave you about 12 words that you could use for whatever you liked for general storage. The, if you were running an interpretive program then when you launched the job, you had to specifically say I will be using the interpreter for this. Didn't mean you had to only use the interpreter because another of the nice things about it is you could freely switch between the interpretive code and normal code, very, very simply. It wasn't a kind of an all or nothing. So it's very common that, you know, code will use the interpreter for part of it and then jump into the kind of the low level language and perhaps jump back again. But if you are going to use the interpreter, you need a so-called back area which essentially is, you know, an additional chunk of memory and there were, I think, five of those, allocate, yes, five allocated, which essentially store the state of the kind of that virtual machine. And the final thing I'll talk about which sadly I don't have any, I was hoping to get some nice audio for this, but, oh, I completely skipped something that's required for this. I'll try and cover it very quickly. So this is concept of unprogrammed sequences. So I mentioned about how they have the inertial measurement unit, the IMU, which stores the orientation and velocity. Essentially, you know, these are values which the computer needs to access and these are mapped into memory, but it was essentially a one bit up down. So what happened is every time the spacecraft rotated or accelerated by a certain amount, a pulse would get sent to the computer which would then steal the next CPU cycle to increment or decrement the appropriate counter so if the thing's accelerating rapidly or it's rotating quickly, you have tons of these pulses coming in and every time a pulse arrives, the next CPU cycle gets stolen from normal operations and is used to just increment or decrement a specific memory location. So the 12.01, 12.02, the famous alarms on the Apollo 11 moon landing they're coming into land 12.01, 12.02, what does this mean? Panic panic. The, in a nutshell what was happening is there is an undiagnosed problem with power supplies which meant that if you turned on one of the power supplies for the rendezvous radar at the wrong time you had these two power supplies slightly after phase which caused the radar tracking system to think that the radar was constantly jittering around sending zillions of these pulses to the computer saying increment, decrement, increment, decrement and that caused an additional 15% still 15% of the processor time on the computer. The computer was already loaded very heavily because it was final stages of the lunar landing suddenly 15% of its time has been taken away and that's what caused these overflows what these alarms but what happens when these alarms happen is the computer then does a bailout which is basically a reboot but it reboots in about a second and the jobs that were important such as the landing software leave checkpoints basically saying if I'm restarted this is where you know this is the this is the last safe state essentially so the important jobs could pick up more or less where they were and the less important jobs just get chucked out of the system and that freed up just enough processing power that despite the fact you had all of these spurious interrupts from this fault coming in the computer still had just enough computer power to keep up with real time and keep the lander stable and ultimately successful mission and I think I'm out of time I'll hang around at the end if anybody's got any questions and yeah otherwise hope you enjoyed the talk and thank you