https://www.youtube.com/watch?v=en0spJzeoUU "Booting from the Metal Up – Alastair Hewitt - VCF East 2025" Vintage Computer Federation talk April 2025, 51 minutes Posted late June 2025 on YOuTube with this transscript. Rough edits and blocking, Herb Johnson HRJ July 3 2025. HRJ, Blocked text to match powerpoint slide titles (colon titles) July 4 2025 HRJ Further edits Sept 15 2025, added text in []'s, copied to PowerPoint as notes. Introduction: (... but it it gets even worse, this is made out of TTL chips. So [to discuss it, you've] got to bring up everything, even the electronics.) This is a project that I've done [over many years]. I did a [VCF-East] talk two years ago, a very technically dense one. I should really be talking about the sound stuff. But before you get to the sound you got to boot it up, so that's kind of an interesting story. So this [talk] is booting literally from the metal up, in terms of the electronics. My First CPU : I started in the UK at Motorola and then moved here [to the US for] Nextel phone company 2G. I started in electronics at very end of the 80s, and then eventually ended up in software. So my electronic skills are trapped in the early '90s. So I did a lot of stuff in the 80s and [the folowing] is about my first [TTL] CPU. The idea I had, was to build something as simple as possible, use TTL chips (so these 74LS chips). I waned to stick everything in the ROM, so not even [use] an ALU, just the single ROM. The program for the ALU is lookup tables. So do everything in the ROM, keep the TTL logic as simple as possible, and then keep it really small. Back then 8K [memory cost] a lot of money. You can solve these ALU kind of problems, just by throwing huge amount of memory at it. But I had to keep this fairly small. so basically, I'd have LEDs and push buttons, and build a toy computer. My First CPU (1984), block diagram: So this is the overview [chart]. I think it had RAM but you don't even need RAM to get something really simple working. you've got a few registers, control logic and then this program of everything in it. That was actually designed on a big piece of paper, but never built. It wasn't [proving] to be very interesting, so it was just an exercise, and then I kind of forgot all about it, until about 34 years later. 34 years later: ... There's a couple of guys in the Netherlands, and one of them is Marcel van Kervinck. He was playing around building a VGA circuit on a breadboard, with TTL chips and a ROM. The actual image was on the ROM, and then just scanning the ROM and generating a video signal, running at 6.25 MHz. That's a quarter of the speed of VGA so it's a quarter of [minimal VGA] resolution. Then he added a RAM chip and a microcontroller, and eventually he added a CPU. This really basic TTL CPU was running at that same speed. It was bit banging the actual video, so very simple. Still, it could run real applications and he released it as a kit [in 2018 as Gigatron.] This is when it was released, 34 years after [my paper TTL computer]. Then there's [also] this infamous [8bitguy.com] video*. At the end of it, he talks about his Commander X16 project. That also inspired the Stephanie alair, who built the Phoenix stuff**, and it also inspired me. I saw it a year after the came it come out. *"building my dream computer - Part 1" 2019, The 8-Bit Guy, youtube.com Also check 8bitguy.com Web site blogs. ** https://c256foenix.com My Second CPU (2019): That led to my second CPU [on a breadboard]. I actually did build this . Let me just show you [this board image. It's] basically the original CPU. Rather than actual bit bang the video, I added a DMA controller that scans the RAM. I call it the GPU, and it swaps RAM from the CPU [to] this GPU. I don't have to bit bang the video, so it's not quite as horrendous [for the CPU]. A few more chips, but the CPU section is a bit more simple. Novasaur (2022): So that led to the Novasaur. I think the hardware was finished in about 2022, but there's a lot of software to do to make this work. This is the actual [board]. There's a button, so you push that in, and then there's video out and you should get a prompt - that's the idea. Some features: There is a power switch, a single LED and that's actually connected to serial RTS line, [and] it has VGA and keyboard. The serial port supports Xmodem, so you can transfer files to and from it . And it has a battery-backed] RAM disk. Some people have SD cards, but I wanted to keep it as simple as possible. I could get a 512K RAM so half of that RAM is set up to use as a 256k RAM disc drive . that's the A drive used in CP/M. That's about what you'd get in the 70s on a very low density diskette. And so it'll boot up to CP/M. Push the power switch and that [prompt is] what we want to get to. There's quite a lot to do to get there. Power supply: a quick overview. The power requirements of this board is about 10 watts, which is quite kind of a lot. It's 1.6 amps and that's a decent amount of current. You can get a [5 volt] USB charger or a wall wart plug that in, that's not a problem, but they're not quality ones. you'll get up to .3 to .5 volts voltage drop [at that current], and that's going to not work if you if you got 5 volts from the wall [wart]. I played around with buck converters, so you start with much higher voltage and you step it down. They tend to be very [electrically] noisy and run kind of hot. So I used a linear regulator which is more appropriate for the era. [At] 6 volts, which actually drops to about 5.7, and it's 1.6 amps, so that works. Linear regulator: this is the actual regulator I use, it's a 2 amp regulator. You have a power switch which can actually be pretty expensive. but this [circuit has a regulator] so [switching full power] is not what I want [the power switch to] do. Using the Enable Pin: The regulator actually has an enable pin. So you connect the power to the regulator the whole time, and then push on the button [to enable the regulator]. It's now the current [that] gets pulled through [the regulator]. So that button can be really small, and [this is] what it looks like, a little button. Actual Power Circuit: This is the actual power circuit, It looks pretty complicated, but I'll just step through what's going on. The actual power switch is a double pole double throw [DPDT] that looks like a slider but it's a sort of push button. Power OFF: So when it's when it's in this off state, the ground is essentially connected to the enable pin on the regulator. So the enable is high, so that regulator is off. Then the RAM is constantly powered up by the power supply but also by the battery . so when the power's off it's powered by the battery. In this state [the RAM is] powered up. But the [RAM also] needs to be put into a standby mode. So the battery is also connected to that chip enable, which kind of holds it in this off state, and [that] pulls about four micro amps. This is actually a modern RAM chip, so it's CMOS and it can sit there in a very low current state. The CR 2032 battery can probably keep this going for about 5 years. So now I'm going to push the button to turn it on ... Power ONFF? (switch midway): ... but you get to sort of this "onff" state which is like it's halfway on*. as soon as you push that button in, the regulator turns on, because you're basically removing that low signal. and the 6V is now connected to enable. this will power up, but the memory is still disabled ... *The switch geometry is referred to as "break before make", when the center position briefly breaks contact with BOTH poles of the double-pole switch. - Herb] Power ON: [ ... disabled] until that button is completely closed. that's when this grounded 10k resistor is connected to the chip enable,. So now the memory is turned on. This [method] is not necessarily unusual. [But] when you do power something on, the chips are going to come up at different times. [That's] kind of a race condition. Problem #1: so this is problem number one [- the board powers up before memory is enabled]. What you want to do, is to try and solve everything in software, [while] it's powering up without the [RAM or ROM] memory, but can it compute? The thing really only has one true register, in the sense [that] it's got an accumulator, and then you use the memory to be the other side of it. So you need the memory for the additional states, to actually run code. You can't do much on this machine until the memory is actually working. You could potentially try and delay the power on. but there's all sorts of other race conditions there. So typically what happens is, real computers will have a delayed reset. They power on and there'll be a delay, and it holds it in reset, and then it releases it. That's kind of one way to solve it ... Problem #2: ... but there's problem number two [about computing architecture]. So the machine has a 16 bit address space but again I'm trying to use as few chips as possible. So an 8 bit program counter which requires three chips, you have two four-bit counters and then a buffer. so I have an 8 bit program counter on this, which can do a program jump which is up to 256 bytes. if you want to go further than that, there's an 8 bit page register that you load, and that's a page jump. So basically you run the code and then you jump to a different page. It's not very efficient, but there's plenty of memory, so that kind of works. That gets the thing down to four chips. But the counter reset is in use, in a sense that, if I want to reset the program counter to zero, It's already kind of being reset by this page jump. So I need to initiate a page jump to reset it. And that causes issues[because] I need to be in that page to do that page jump. Problem #3: ..so that [paging is] kind of problem number three. The page register [is] an 8 bit flip-flop, you get that in a 20 pin DIP. There's power needed so there's 18 pins left; eight bits in and out,so that's another 16. Now you're down to two pins on this chip. You need a clock to latch the data so there's one pin left. So you get to pick between these [following] possible configurations. You can have your reset, which is what we want. There's a clock enable so that ... when you're latching data, you can sort of enable or disable that. And then there's an output enable, which is kind of what we need because we need to tri-state this onto a bus. So ... this register has the data in it but you don't want to have it connected to this ROM the whole time, because you also want to use it as an ALU, so you have other registers connected. So that [enable is] what we want, we don't need this [clock enable], but we really have to use this [output enable]. So unfortunately no reset. Program Memory Addressing: So anyway this is how the program memory is set up, and it should be fairly simple. there's a 16 bit address bus, the page register program counter, and there's an output enable on both chips and a clock on both chips. What we're going to do, is we're going to pull up the top half of this bus to VCC ... Boot Mode: ... and then create this thing called boot mode. Basically the boot mode is a single bit on the machine, that defines whether it's booting up or whether it's running. On power on [during] reset I'm going to set that to zero. I actually use the inverted output of this flip-flop, so that's going to disable this page register. The output enable is ORed with the boot, I have a diagram showing this. By disabling that page register in this way, the pull-up resistors will push it up to this FF state. It's never connected to the bus but the bus is being pulled up by resistors [in it's absence]. So to the ROM chip it sees the top eight bits [are] being FF. Then ... to get into the run mode, you have to clear this boot bit to then enable that register. And that's done by doing any kind of jump instruction. Then you can manually reset it and get it back to that boot mode. Basically this is what's happening [during reset and start of run mode]. Normal Addressing: When the machine is running both of these, [boot mode and run mode,] the program counter and page register [are] enabled. [When] boot mode is off, so that's basically a logic zero. And then the output enable just works. But in the boot mode, it's boot mode is on, that's a logic one, and that output enable never happens. and so the output is basically held up to this FF state. [In summary,] when the machine powers on, this boot boot mode is enabled. so it doesn't matter what's in that page register, it's always going to go to this boot page. Boot Page (0xFF): So we kind of solve that problem three ... but there is [still] this problem two, which is I haven't reset the program counter. In real computers you have that delayed reset. but I've got such a limited thing here, i can't really reset my program counter. So I can't rely on the code in that boot page to work. So what I do, [as] I can't start a define location [operation], so this [boot] page is [filled with] no-op operations. So [when] it resets at any random location, it just scans through, until you get to the penultimate bite, which is a [page] jump instruction. Now the next bite [following] is another no op. If it starts there, if you actually hit this jump instruction, you're going to jump to page 80. so that takes you to the cold start page. Cold Start (0x80): So we've cleared the boot mode, and now it's reset the program counter, and it's loaded the page register to 80. and that's where the actual boot code is, starting from zero. So we've still got a long way to go. We want to show a status of what state the machine is in. So we need to use the LED .. since there's no video. The LED is [wired] active low so basically. when the machine powers up that LED is on. If you remove the ROM or the thing's completely dead, that LED will come on. That LED is controlled by this E register that I have. I call it the E-register like an extended register. So the first thing I'm going to do when this machine starts running, is turn off that LED. If it turns off, then you know that the code is now running. So when you power this thing up, push the button in, if that LED goes off you know that the actual code is now running. it's gone through this boot mode. It's cleared that boot page, now it's running this cold start code. it also resets some of the other registers. So now the machine is kind of at the point where it can start, it's actually running real code now. Preflight: So there's a thing I call pre pre-flight. [There's] this issue where the RAM isn't necessarily enabled yet, so we can't really run real code. So we need to verify whether we can write to the memory, before we can actually run useful code. And [verify] is pretty simple (I know this looks maybe a little bit complicated). but basically I use this bank one and I write AA hex to it. Then I've got very limited instructions I can use, so then I just exclusive OR that result. so I push it in the memory, read it back and then exclusive OR with itself which will result in a zero. and if it's zero it's going to move on, else it'll just restart. so it just sits there and runs at this very very fast rate, just trying to write to memory. And if it can, it's [still] possible you might actually have this AA value in that register to begin with. So it does the same thing but with 55 which is those AA bits reversed. if [that result is] zero then the memory has been written to, and it moves forward, else it just sticks in a loop. So we're running code, we've verified we've written to the memory. Memory Text (bank 0): .. and then I do a proper memory test. The LED was on, it's turned off, I'm now turning it on again, and I just start filling the memory. I actually fill location zero with one two three like this [in locations 0 1 2 ...]. Then I run this code right up to the whole 32K of this first bank of memory. Then turn the LED off and then just do that exclusive OR thing, to clear the entire memory. Then if any of these bytes are zero, it just reboots, goes right back to the beginning, does that pre-flight test, repeats on the upper 32k and then it's good. So [now] the memory is writable, it's filled the whole memory with all the zeros. This is kind of part of the reset, it's just clearing the memory, it's verified [that] it can write to every bite. It really stresses the machine as well. So if it passes that memory test you know it's working. Reset Keyboard: Now there's a PS/2 keyboard plugged in. So it's part of the boot process. If you're going to use that CRT interface, in other words the video VGA output, and then the actual keyboard, you need to try and reset that (keyboard) Again I toggle the LED to show something's happening. Then I have to toggle the PS/2 clock, and then the keyboard should acknowledge that. It brings the clock low and then I'm going to retry that six times. If it fails it it'll go back to the beginning. so it's going to sit there and it flashes the LED on and off until it is rebooted. if it doesn't work it doesn't matter, it just moves on it sends this PS2 reset command either way. Well - if there's an acknowledgement for the keyboard it resets. Pass / fail it will then continue, and it goes on to the next routine which is the warm start. LED status recap: So if you turn this machine on - you can literally take the ROM out of it, power it up it's not doing anything, the LED is going to stay on the whole time. [With the ROM in place,] if the LED goes off and stays off then it's failed this pre-flight, it's not writing to the RAM. So this will happen if you pull the RAM out. If it's constantly flashing, then it's basically failed that memory test. And if the timing goes, if the board's not timing right, this will actually happen where it'll just keep flashing. So if there's an issue with the timing, it's not able to read and write to the memory very efficiently. Three to four flow slow flashes, is what happens if you don't have the keyboard plugged in. So it's kind of doing that keyboard reset, and not being able to complete. If [instead] you have these quick flashes and then it works, that means the keyboard's working. So that's the whole boot up process on the LED. The end result is that LED is now on. so you push that button, it flashes a few times, and you can kind of tell what's going on. if it's solid on at the end then it's all good. External Interfaces: So I'm going to talk a little bit about kind of what's going on under the covers. 'Cuz even though this is a very simple TTL CPU, there's a lot of stuff running on it. So once it's booted up, now we're going to start bringing up other parts of the software. But there's very limited hardware and there's all of these interfaces it has to manage. There's no video chip or serial UART or keyboard controller. There's audio but no sound chip. everything is bit banged. Hardware Abstraction Layer (HAL): so there's this thing I call the hardware abstraction layer which is basically code that's running. It's very simple hardware, bit bang everything all the time, and you can't yield to a user's program it's very critical timing. so you have to use this fixed timing, where all the code is a multiple of 43 cycles*. [*Cycles are a product of the VGA video horizontal timing, the 9600 baud serial timing, and the digital audio sampling rate. These operate in lock-step through the code as it's paging itself. Explanations follow. - Herb] So this sounds like ridiculous and it is, but every single piece of code is written to fit into one of these 43 cycle blocks. And it all has to be fixed timing. at the end of one of those blocks it has to dispatch, to figure out what to do next. it can't [deviate,] it has to follow a very specific set of timing. The other thing, is this is a Harvard architecture. There's two RAM chips and it has separate address spaces. [But] the program actually runs on the ROM. So you can't put a new program on there without taking the ROM out and programming it, which isn't great. What I do, is I build an interpreter [code] that reads the RAM, and then interprets that [RAM] as [Intel] 8080 byte code. That's how the thing is actually running, pretty much at that kind of user level. You wouldn't normally write [ROM] machine code that runs on the hardware, it's just too much of a pain, and you'd have to deal with all this timing, [So then I can software] abstract all of these interfaces on the board. I essentially just map them to this abstract interface, and they show up as 8080 ports. So you can read the keyboard just by going to one of these ports or the serial and then you'll just see the next bite that's available. so that code that's running is providing all those services. Virtual Machine Cycles [diagram of blocks]: The way the timing works, is that I have what I call this virtual machine cycle. So the [virtual] machine runs at 8.25 MHz. if you divide that by 43 you get 192 kHz more or less. so each one of these little cycles is one over 192 kHz, and then I divide that down. The video is basically super VGA. ["S" blocks on diagram] so if I set this up so each one of these lines of virtual cycles is five, then I get 38.4 kHz or 48.4 l thousand lines per second. and that's very similar, 1.3% away, from VGA. so most monitors are happy with that. Each one of these lines starts with a sync pulse that generates a horizontal sync, that the monitor latches onto. and then block one has this extra cycle [B] called a block cycle, and that just kind of makes sure it counts up which block it's on. Then all of these kind of cycle[-blocks] with numbers in them, each one of those are available to run 8080 machine code. In those 15 virtual machine cycles you can run about six [8080] instructions. so you need one cycle to fetch and one or two cycles to execute, the actual byte codes of the 8080. So it comes out to about 60,000 instructions per second which is about 1/5 the speed of an 8080. These blocks are set up to divide the thing further down. so each block has four lines in it. so you get 9593 blocks per second. so the serial is 9600 so that's close enough that works. the audio is sampled at 9.6 kHz so that's again done on that block level. And I do 160 of these blocks per frame, which is 60 Hz [the USA horizontal frame rate]. So that's how the timing works. So [users] don't ever touch this, you just write the code to run as an 8080, and then these available 15 virtual machine cycles will execute that code. Warm Start: so the warm start is going to have to set up this kind of virtual machine. [First] there's a software reset basically happening, where it clears the run state. So the hardware is running now. [Then] I have this thing I call kernel mode. so I went a little bit further here, where I have 512k of memory, and I break it into eight banks. So bank zero is the [VGA] display and the other seven banks are assigned to seven separate [virtual 8080] CPUs. so bank number one is used for this kernel. I have this context switching that can happen, so that's all disabled [on warm start]. I prefetch this instruction called copyROM, and I'll explain what that is. Then I reset the virtual program counter. It's actually set to minus one, because it prefetches the next instruction and goes up to zero. and then I start the hardware abstraction layer by calling this block sync [page]. So in that block of virtual machine cycles, I just call the code that runs that first one and then the whole timing takes over. Now the machine's running in this kind of next-layer up, which is this hardware abstraction layer of virtual machines. The boot was running on the actual kind of hardware, and now [it's] running in this kind of virtual machine, So it's now moving into the 8080 code. From then on in, it's always fixed timing [per page], and the video signal starts to happen. That's when the VGA monitor is going to start to [see] sync. CopyROM: I just want to talk about this copyROM, this instruction is used a lot. One of the issues with this Harvard architecture is that I have the code in this program [ROM] memory, which is what actually runs on the machine. but I want to run 8080 machine code, that has to be copied into the RAM. And so I have a special instruction that allows me to copy from this second bank of [ROM] memory. I can copy [from] there into any of these [virtual] CPU kind of locations. so that's a special instruction, and I call it copyROM. and so there's a lot of stuff [to consider]. Cold Storage (8080 code): so this cold storage area contains all the 8080 code and I'll go through this kind of quickly. But basically there's a bootstrap code, there's code that runs this RAM disk. i have this kind of micro kernel, and then there's a monitor code as well. i have some system libraries I can use. and then I have like a B drive, which contains all the CP/M utility [programs]. so again that's in this cold storage ROM, and it can be copied over and then look like an actual kind of B drive that's full of 8080 code. Bootstrap: So the bootstrap in its cold storage page zero, gets copied to RAM page zero. and then it starts running the code from location zero. so now what's booting up is an actual 8080. and it's starting from zero, which is the normal way it resets. and it's running the code in this sort of virtual CPU. Bootstrap code: and that bootstrap code, starts basically with that copy ROM resetting that virtual program counter. and then that that code will then fork, based on a CPU ID. So I have these seven [other] banks and each bank maps to a specific CPU that's going to run, and it context switches between them. So if it's a zero it's going to boot everything, a one will boot this kernel mode. Two and three will boot up CP/M, one instance that's running that's showing the [video] display, and then one instance that runs [using] the serial interface. so there's two instances of CP/M running. and then four through seven run this RAM disk. [Note: these are all 8080 code I think. - Herb] So the thing about the RAM disk is, if your machine crashes it could write all over the RAM. so by doing this segmentation where I have separate CPUs, you can crash your program and it's never going to touch the RAM disk, because that's a separate program that's running. You can do it by messing with [power cycling] and kind of crashing hard enough. But [otherwise] it's a cheap way of doing protected memory with a bunch of TTL chips. Then there's a sort of fake CPU 8 which will run this [8080] monitor [code]. So what I do, is when it boots up, what that warm start does, it's going to initiate one of these CPUs with ID 0 which tells the machine to boot everything. Boot all (cpu ID=0): .. and that boot-all will basically run a loop. so this is where it gets a little bit complicated. So you've booted up the actual hardware, it's now running this virtual machine. that first warm start will start this CPU zero, which will basically start one of these CPUs, that then tells the other CPUs to boot up. so CPU one starts and it's telling all the other CPUs to start up. it does this copyROM so it basically copies this kernel code that it's going to run, and then it boots that. and it clears its memory and then it sets this context. So this thing actually does context switching between these different CPUs and it goes 1 2 3 four, and then the next block has 1 2 3 five, then six, and then seven. so four five six seven are actually the quad, almost like quadrants of a disk. and then one is this kernel, two and three are the CP/M instances. so it's just scanning around [blocks]. But now that the first CPU started up, now all the CPUs are going to start running. And then this kernel has an event loop so it's listening for the other CPUs. Software Stack: so this is actually the software stack. You've got the hardware [layer] with the interfaces. [Next there's] this hardware abstraction layer that starts running, and that's doing all of this timing, basically bit banging these interfaces. and then it's running this virtual machine, but your program doesn't necessarily have to run on that. This micro kernel [layer] runs, it's basically talking to the hardware. and then you have your CP/M which talks to this [lower] kernel [layer], and so [the kernel] talks to the disk [and other virtual devices]. So this is a way of doing this memory segmentation and management, to make sure you can't crash and mess up the RAM disk. Each of the CP/Ms talks to this kernel which passes messages to and fro. Then the [8080] application will run on top of this. Software Stack (kernel mode): But there is also a mode where you can actually run directly on this hardware abstraction. You just have this one CPU that runs [what I] call that kernel mode. And that's if you're running a game, that's how you'd run that. But when [the machine] boots up it boots up all of these layers and gets [to] CP/M . RAM Disk (A: drive): So this an example of how [RAMdisk] CPU 4 is set up. So I'm not sure if [this graphic] makes any sense. Each line is a [RAMdisk] page, it's split into two halves so there's CP/M records of 128 bytes. The one on the left contains one set of records the other one on the right [the other set]. but 250 pages in each one of these four CPUs that run [the RAMdisk]. The way I set it up is that you've got sort of like four quadrants of a disc, so 250 pages, so that's 62.5K. and then there's four through seven, each manages kind of a quarter of this virtual disc. so that's 250k in total. Boot Disk (CPU ID=4-7): and the boot disc [code] is fairly simple. it just copies this page one to the very end of memory, which is where it runs that code. and it starts an event loop to listen to messages from the kernel. so it can get a record put a record. and I've also got an ECC checking in there, to make sure that the [RAMdisk] records are hopefully correct. It can identify something's that's got corrupted, basically. It can fix up to one bite, but in general this will tell you if something's got messed up. A: Drive Read: So I'm just going to show you what's happening [on RAMdisk drive read]. and it's kind of ridiculous, because, you know, this is running on TTL chips. I've got these virtual CPUs running, and then the CP/M is going to talk to the disk, which has to be its own virtual thing. so the CP/M will send a message to the kernel, so it's essentially saying, I want to get a record and this is the track and this is the sector. The kernel knows where that lives, so it'll figure out, oh that's that's CPU 5, so I think that's quadrant 2. And then that disk has its own protected memory. so it copies that record in there, returns, It doesn't know where that [record is] going so, it just returns that message back to the kernel. and then the kernel will copy that, so [the kernel] knows where that's going and it'll copy that. The kernel is allowed to do this, where it can copy from some protected memory used by this CPU, to protected memory used by that CPU. And then it sends this return message back to CPU 2. Then that CP/M will copy that from its protected memory. So this way, the kernel can move things between CPUs, but again it's separate protected memory. This is the way that the actual CP/M would go and get a disc drive [sector], rather than talking directly to the memory or to some sort of [hardware]. It's communicating and it's basically the structure of a micro kernel. It's actually not too slow it can do about 5 kilobytes per second, which doesn't sound great, but you know you've only got 64K. Typically the files you're going to be loading [are] up to say 60K. it's the biggest CP/M file you're going to load. So that's going to take about 12 seconds. CP/M (CPU ID=2,3): so yeah, CPU two and three are two instances of CP/M. It copies the CP/M off the B drive, which is higher up in this cold storage ROM. I put it in location page E4 and above. It also sets the IO byte. so basically the CPU ID is used to set this IO byte, which tells CP/M whether it's going to the keyboard or whether it's going to the serial. and then it boots the CP/M. so it's just a standard CP/M BIOS cold boot. so these two CPUs boot up actually together pretty much in sync. The CPU that's managing the CRT actually sends a message to the kernel to clear the screen. i used to have the kernel clear the screen when it booted up. but I [now] have the initiation of that coming from CP/M, and that's fixes a bunch of different problems. I print the logo on [the CRT] screen, so I actually have a little logo that's in the boot page and it copies that, [then] puts the CP/M copyright. Then it calls GOCPM which selects the A drive and then calls the CCP, which is the console command processor. Console Command Processor: So starting the CCP sets up CP/M to receive commands. So this is now CP/M running. we've got up to the stage where CP/M is booting up as normal, and you actually have two instances of it. [Each are] able to talk to the kernel that talks to the disk. So on that start CCP, it calls a function within CP/M called reset disk (RSTDSK). and then it logs in the drive. So when you start CCP, it will call this login drive, and that loads the A directory. this was a really difficult bug that I had to deal with. I wasn't sure what was going on. but what was happening these two CP/Ms started up and then one was going to the A drive through the kernel saying I want this record. and then the next one was doing it. and it was actually causing a conflict where it was sending the message but that disc quadrant was already busy so it lost that message. and it would kind of get messed up. and that's one of those bugs that took a few weeks to figure out. So there is like a actual multitasking CP/M. but this is two instances of CPM 2.2 running on the same hardware, but they don't know about it. so there are some potential issues. But it seems to work, um, most of the time. Basically that command control processor which is part of CP/M, will block on input. so now it's just waiting for a command to happen. So [one CPU] instance is looking at the serial and then [there's the] instance that's working, looking at the [PS/2] keyboard. CP/M calls this BIOS function called console in, (CONIN) and then that actually sends a command to my kernel, and I call it coni. Kernel "CONI" Code: and that CONI code basically calls the 8080 instruction IN on the console. so this is one of these ports, which abstracts in this con[sold] context it's the keyboard. so it's basically looking at the next byte in a buffer that's coming in from the keyboard. and then it puts it in the e-register, because it wants to output something. so it sets this control p character and then it writes that to the console. (And it makes no sense to actually do that, because [ASCII] control P is data link escape, which has got nothing to do with the console.) So the console interprets that as flash cursor. So we now got a flashing cursor, so you finally got there [to the CP/M cursor]. you're just sending lots of control P's and then it will, depending on a timer, it's either going to show the console the underscore or clear it. Then it's there's this IPC send instruction that kernel sends back to CP/M if it does get a character, which could be null and if it's null then CP/M calls back again. So [now] you got the CP/M running and it's just blocked on input and it's just looking for input. and then if it doesn't see it, it's flashing the cursor and waiting for something to happen. And that's how we've got a flashing cursor. Project Status: it's kind of interesting, like from that pushing that button to it starting up, like how much stuff is going on. It gets sort of quite difficult to solve some of those hardware problems. Then once the software gets going there's a lot of moving pieces that have to kind of happen. So it's quite a big stack of stuff. So to the actual project [by date and task]. That picture of the board, that was about January 2022. so this is a ridiculous hardware project. i mean it's a ridiculous hardware project but an even more ridiculous software project. because it just turned into this big science project, to see if I could do a preemptive multitasking thing. So I'd say the software was kind of complete August 2023. but it was kind of buggy and a lot of weird race conditions, so November last year [2024] I'd say it's actually complete and tested. so it's could potentially ship out, but then a lot of things been going on. I'm hoping by the end of this month [April 2025] to [ship], I've got inventory and I'm going to have a kit available. But the madness continues .... I could do an assembled version as well. Disintegrated: But there's this [additional] idea of doing a "disintegrated" version. Instead of having the TTL chips, you can get these little SOT23 [chip packages], these would be individual gates. Some people do [logic] stuff out of transistors [but] it would just be way too slow. These SOT's are actually pretty modern things, and they can do like three nanosecond propagation. so these are really going to be flip-flops and AND gates, OR gates or exclusive-OR gates; and there would be about 350 of them. And this [image] is a test board, and this is actually arriving on Monday [mid-April]. at the bottom [of it] there you've got .. One of the pieces of the circuit has a lot of logic, so it's [contains] some timing critical issues. so I built a version of that [which] will plug in to [the TTL prototype board], and see if that runs. and then the rest of it, this is actually the program counter and that's probably the most complicated piece of logic. and that would replace the ROM and these two program counter chips. So if this works then it's not too far to then convert the entire thing into a giant-like board with just logic gates on it which will run C/PM . um but that's down the road . Novasaur kit: so yeah that's what the kit will look like and it's coming [May 2025], and yeah this is the actual thing. So I'm going to go down [the stage] there and I'll power it up, if you want to see it and see it do stuff. Thank You!: and um, Yep thank you. [applause] [PS from Alastair: The code discussed can be found here: cold/warm start - https://github.com/ajhewitt/novasaur/tree/master/src/sys bootstrap - https://github.com/ajhewitt/novasaur/blob/master/src/os/boot.asm I basically wrapped up the software with the production version (1.1) at the beginning of November 2024. I've created a release with the ROM image that you can download here - https://github.com/ajhewitt/novasaur/releases/tag/R1.1 ] Alastair: So there's a few minutes for questions I think. > So this isn't really a question it's more of a comment. so one thing that's really great > about these .. TI tiny logic or those SOT23 things, is that it often corresponds more to the > old style [of design?] where there's like six hex gates in one chip. It corresponds to the schematic. so you > might actually be able to make a nice silk screen on [the board], so that you can see what each piece is > and how it's connected. I was thinking like making it the same size and it would be fairly dense, but I can make a bigger version, but actually make it look more [like the schematic]. The program counter is pretty complicated because you have these D flip-flops. But the counters really need T flip-flops. So you just have to add an exclusive or gate. And then they they're preloadable. so you need an AND gate, there's like six of these to make each bit. so that program counter is the most complicated piece. so that's if I can make that work then everything else is kind of downhill from there, well yeah it's easier. so that'll prove whether it works or not. but yeah, and then throw a whole bunch of LEDs in there as well. so it'll make lots of flashy flashy lights. i've only got one LED on the current one. > so this disintegrated version I guess? will it run faster? it's possible. So actually what what happened, when I built [the Novasaur] I was going to run a 25 meghertz dot clock, it gets divided by four. When I was designing it, the Gigatron people were trying to run the Gigatron as fast as possible. so I was like maybe I'll try and overclock mine before I've even built it. So I worked out what's the maximum speed and it could potentially run at 36 MHz. But I settled on 33, so I can do that divide by 43 to get all the timing right. So it's not at the very limit, but it's pretty close. But I think this [SOT version] in theory could run at 40 MHz? and then I can change the timing of that virtual machine thing to get about 30% more speed out of it. there's a couple of video modes I won't be able to support [at higher speed]. But the two core ones I'll be able to do. So the idea is that these [SOT] circuits I'll plug into the existing board. and if it works, then I'll see if I can speed it up and see if that could work. But yeah I'm not sure. If this works that's kind of the next stage and then I got to build it and it's going to probably take a year to this. It will definitely be a four layer board. the other one actually does fit on two layers [but] it's very noisy. So this [SOT] assembled version would have to be a four layer board. I got to keep it within certain constraints. But yeah this [Novasaur] thing you can pick up on an FM radio. > How different will the disintegrated version be from the integrated version, particularly at the microode level? It'll essentially be identical. Because if I change anything I have to rewrite the entire code base. It's sort of like, the TTL version proves it out. so it's going to essentially be absolutely identical. except if it does run fast, I can just change the timing and get a couple more get an extra .. those [video character horizontal] lines will go six long, 6x4 instead of 5x4, and then you can get extra speed. But everything else is more or less the same. the only difference I'll probably have a bunch more LEDs on things that move slow enough that you can see them flicker. > and you're going to continue both versions, right? oh yeah yeah. I was thinking about a surface mount [TTL] version and this [SOT construction] isn't really the surface mount {TTL] version. If I'm going to do - I mean let's just go crazy - but yeah I was ... But I'm thinking about doing an assembled version of the TTL like the TTL chip one. It's possible that I might surface mount some of the non-TTL chips. like just a couple of things like the regulator. but the actual TTL chips I want to be the original kind of 19 [70's?]. > well, the TTL version is assemblable by mere mortals. oh yeah, yeah. The only diff, is that'll have a different PCB I think, because I need to put like a real ground plane. because it's going to meet [standards]. if it's a kit you can kind of get away with, like, who knows. But if I'm shipping a finished product, if I'm selling in Europe or whatever, they're going to get very upset, when you can tune a FM radio into it. That's the third harmonic of the [33Mhz] oscillator, is 99 MHz. Then the switching frequency of these F-series chips is about 103 or 104MHz. You can tune in a radio to those two frequencies, from the other side of the room. > So when you assemble the kit does it just come up or do you have to load the [ROM ...]? Oh no, it'll have the ROM. I think now the code is pretty much done. And the idea is you don't necessarily need to add anything extra to it. Now you can load [your 8080] code on it. It comes with CPM 2.2 and, it's got IMSAI BASIC in the ROM, as well 8k old-school [BASIC]. you've got a serial cable and you can load other things onto it, like Microsoft BASIC which is 24K. and then any kind of CP/M 8080 [code]. it doesn't do Z80 for various reasons. > don't forget the I/O ports, you have you have the option for [I/O devices] Yeah so that's, um there's some additional registers you can address so on the board, there's actually you can plug in an expansion card. I was thinking maybe having a flash disc drive like a C drive, which could be like 4 megabytes or something like that or 8 megabytes. Or plug other things in, or maybe like a better sound chip, or a real sound chip. > [Announcer:] Any more questions? Let's give Mr Alastair Hewitt a hand! thank you [Applause]