It’s not about Ready Player One. In fact I haven’t seen it, and probably won’t until it comes to streaming. I’m at cold war with the movie industry. :P I’m talking about an actual project of actually designing and building a new 80s style computer.
[This is the third revision of this writeup, dated 24/04/18.]
This post was inspired by, and is a reply to, this blog post by tech showman, chiptune musician and retro developer David Murray. There he described his “dream computer”, a hobbyist kit computer to-be-designed, to evoke micros from the 80s, and following the traditions specifically of the Commodore line of machines.
Apparently there’s a load of these things already. Even though I’m somewhat intimate with the retrocomputing scene, and develop for the Commodore 64 for fun, the fact that so many retro computer boards were and are being developed was news to me. I knew about a few, but the abundance surprised me.
Personally, I find the idea quite lovable, for multiple reasons. As I pointed out in a more political post earlier, I believe in humans being the masters of technology. If I give a baby a tablet, they will learn to be a slave of it instead. If I give them a traditional micro with no Internet connectivity, well… Things went quite well for me, so I have my hopes up.
I’d love to be part of a community project such as this. My electronics expertise is limited, but I did have computer architectures hammered into my head by a somewhat backwards information technology curriculum, along with digital circuit design and optimization, Laplace transforms and feedback loop stabilization, and similar things I hated back then, but am today quite grateful for to be honest.
The fact that so many of these things exist, and so few are actually being used, still being made, or even remembered, definitely does tell us something about the pitfalls of such a project, and we’d do well to heed these voices. So here’s my five cents on the “dream computer”, let’s go on a thought excursion into what I’d consider a worthwhile project to put time into.
What it shouldn’t be
I think it’s important to decide what the goal is, otherwise it’s easy to lose track. We really don’t need a “better” computer, we have pretty good modern ones. We need one that fulfills a niche, and may live on beyond the first batch that’s sent out at the end of a crowdfunding campaign.
So the first question one needs to ask at the start of a design exercise is, how do we delimit the scope. What do we NOT want to make?
- Not a reproduction of any specific classic 8-bit or 16-bit machine.
That’s a niche that’s mostly filled by emulators, and the occasional FPGA-based remake (usually unobtaininum / unaffordable).
Also, it would make the designers’ job really hard.
- Not a movie prop / retro lookalike.
By this I mean any system based fundamentally on a modern low-cost architecture, emulating the feel of the 8-bit era. This includes systems-on-chip, modern MCU architectures, and anything that has an rPi hidden inside it (cue obscure Advanced Dungeons and Dragons reference) .
There are pretty awesome extant ways to make an rPi act like a retro machine, we don’t need another one. And I’m told the best Amiga you’ll ever want is a Mac Mini G4. We don’t need more of these.
- Not another unobtainium FPGA-based kit.
FPGAs are not open technology. To configure a specific line of FPGAs by a specific manufacturer, you need the specific tooling for that line by that manufacturer. Also, chances are it hasn’t been updated since 2001, and will refuse to work on anything but Windows XP. (If you’re particularly unfortunate, it might even expect a Japanese copy of Windows XP.)
There’s something common about retro-inspired hobbyist computers that are based on FPGAs. They are expensive (I mean “easily costs more than an entry level modern PC”), and that you cannot buy them even if you’re prepared to shell out the money, because nobody stocks or makes them. You can sign up for a second batch, but it will likely never be made.
- Not a great business opportunity.
I don’t see anything like this becoming a commercial success. Success is defined by “not forgotten in two weeks”, and not by “breaks a profit”. Because it won’t break a profit. Better accept that early on.
- Not a cannibal.
A cannibal is a retro project that kills and eats retro computers for their ASICs. Having a socket for a SID is tempting, but that means every single board ever built will probably murder a Commodore 64 for its SID chip. I don’t want that. So no use of retro ASICs should be required or encouraged.
- Not a closed or proprietary system.
There is plenty of work going into taking control away from people. This project shouldn’t be part of that trend.
What’s the point?
Once we have the clear red lines down telling us what we’re not attempting, let’s talk about the purpose of the project. Not the “how”, but the “why”. This is somewhat cross-pollinated with the former list, so might as well come before, but when designing, I prefer to finalize the demarcation first, it prevents me from going off on a tangent.
So what should this machine be, as in “what niche it should fill”, “what is the whole point of it existing in the first place”…
- An educational tool.
I’d want it to be something parents can give their grade school kids, for relevant educational benefit and fun. Not this gamified learning crap, but learning by doing, as we did back in the day.
Based on questions and comments, I think I should clarify my intentions and child-raising philosophy (which is quite unbaked, looking at how I don’t have kids yet, and people who are already parents tell me that actual kids tend to mess up all your plans).
So two things. I think kids should learn to code before they learn to send e-mails. I would never give Facebook (or any device capable of accessing Facebook, or Musically), or any modern (anti)social microtransaction game to a six year old kid. I’d want to give them a computer though, to create on. To do what little tool-using ape youngsters do by nature.
Modern platforms have software specifically engineered to fuck up humans. Might as well give my kids crack cocaine.
- A fun machine to use, work on, play on, and develop for.
There are writers who still type their manuscripts on typewriters. Because it’s what they grew up on, and it helps them focus their creativity. People who find that using a retro machine gives them more focus or comfort, should definitely be able to use it as a workhorse.
This also means it should be elegant in architecture, and relatively nice to develop for. I was worried that it being too developer friendly would make it uninteresting, but if I really want to make my life interesting, I can just go and develop for the actual C64.
- A truly open reference design.
Nobody will take the time to develop software for an obscure machine that only ever saw one batch made, and forgotten afterwards. For this to be a success, it has to be independent of the creators.
Selling kits is okay, but I’d like it to be “kitless” as in you don’t actually NEED a kit — that you can just get the BOM and the PCB Gerber files, download the ROMs, and build one off of Digikey and some random PCB fab lab, with nothing but the following tools: soldering iron, generic EEPROM burner. It needs to be cost-optimized for batches of one.
- A semi-authentic throwback to 80s tech.
This is somewhat related to it not being a movie prop / lookalike. Using an MCU for graphics, sound or I/O that’s ten times more powerful than the CPU may be enticing from a simplicity and even cost point of view, but in my eyes, defeats the whole purpose. If we do add co-processors, they’d better be 6502’s themselves.
It should mirror the way computers were built and worked back then, ie. hardwired digital circuits and task-focused coprocessors (not MCUs). Since FPGAs and CPLDs would kill the openness of the project, that means discrete gates and jellybean MSI/LSI components. Time to break out your Karnaugh maps, kids.
Looking at the above, I think it’s easy to lay down a few guidelines.
- It should be BIG. Like, absolutely HUGE. Even with what they say about big cars and male psychology, this has significance well beyond the inherent phallic imagery. If the system is planned to be BIG, there is less presure to integrate jelly bean logic into FPGAs. I mean, if you have all the logic on a tiny chip, what do you fill the rest of the PCB with? :P
- Sound and graphics will likely be discrete. No chips on the market for either purpose. The only place you can get loose OPL3s is from Hong Kong over ebay or AliExpress, and I’d be surprised if they had anything to do with Yamaha. And no, it shouldn’t have a SID socket for reasons laid out above. ;)
- We should go with a 16-bit CPU. Dave mentioned the 65816, which seems cute. Also it was used in the SNES which gives it some notability. Plus, it’s cheap. This will allow us to pack this machine chock full of RAM (like, 16 megs full). Running around 10 MHz, with that amount of RAM, it should be close in power to an early PC AT.
Coupled with a graphics and sound feel evoking the Commodore era, I think it should be a wonderful machine for both work and play.
Finally, once the basic requirements are discussed, let’s do what in software we call architecting (ie. vomiting design ideas and “wouldn’t it be cool’s” on a whiteboard based loosely on the reqs, and then getting emotional about them).
I think it’s important to imagine how we’d want to use this machine.
- Cartridges should be first class citizens, to encourage customization and extensibility. I’d probably limit the onboard ROM to a quite basic shell (maybe an ML monitor), and allow cartridge makers to create better shells (such as a Commodore BASIC remake, as Dave expressed he’d like to see).
- Creating ROM cartridges should be easy architecturally. Anyone with KiCAD and an EEPROM burner should be able to churn one out with no sweat.
- Speaking of ML monitors, it should totally have an ML monitor built in, even if it doesn’t start with one. (But it really should, in the absence of a shell cartridge.)
- I’d love to see a Python shell cartridge. Python is today’s BASIC, and I love the idea of giving my future daughter or son a micro that starts up with a Python shell. MicroPython seems to be developed for weaker systems like this.
I guess this means we need a C compiler for the architecture. In general without a C compiler, more advanced stuff is kinda out of reach. There are a few obscure ones for the 65816, but no GCC target… This might warrant some looking into.
- I hope someone will make or port an old-style windowed graphical interface similar to Amiga Workbench or early MacOS. Such an operating system should, of course, come on a cartridge.
- It would be nice to be compatible with both old-style composite monitors and with VGA monitors. This kinda means we’d need both YPbPr and RGB+sync output. I’m not entirely sure about the capabilities of VGA implementations, especially if interlaced modes are possible, so I hope someone expert on that can chip in.
- I’ve been thinking a lot about keyboards and mice. Adding PS/2 ports should be possible, I would probably stick with that if it’s not super hard. Though, I kinda envision a reference build with a built-in keyboard that is read as a key matrix.
- It should have standard RS232 serial ports. Possibly a PC compatible floppy controller, too? Standards, standards, standards. We want to make people’s lives with this machine easier.
IEC ports… well, Dave did mention IEC ports, and I guess it’s not that hard to add one. I’m not a fan of them though, they are horrible ports. It should be an addition to RS232, not a replacement.
- Game controllers… I hate Atari joysticks. Seriously. I grew up on them with my Commodore Plus4 and C64, but I really do loathe them. Since the idea is to use the CPU that was used in the SNES, why not add SNES controller ports? You can totally buy those brand new…
Sound and graphics
This is kinda hard. All of this needs to be discrete, which means there isn’t a lot of room for big magic.
The sound should be evocative and relatively nice to use. I dabble a bit in synths, but never actually built one (yet). I wonder how much space a cute discrete chiptune synth would take. Say, three pulsewave voices plus analog noise, and hw ADSR. Filters only if they fit.
It should be simple, and more “VIC-20” than “Sound Blaster.” I’d love for it to be good enough for musicians to pick up as an instrument, but it should have a gritty chiptune character that comes from the design limitations.
As for graphics, on Dave’s article I linked at the beginning, someone called Dave Mullen wrote a comment discussing the memory requirements of various graphics modes, specifically about using 12-bit color reminiscent of Sega machines.
Buffering the entire screen pixel by pixel sounds like a bad idea to me. It’s hard work to update on a weaker machine, needs more memory than the CPU can address in 8-bit mode, and well, at the end of the day it’s just VGA, isn’t it. It’s no fun. So why not have the block-based coloring of the Commodore machines? I don’t think it would be that hard to do in discrete logic, especially if we have plenty of board space.
Personally, I’d prefer to invoke the graphics of the Commodore 264 series (Plus 4 and C16), as it’s what I grew up on, and in my eyes has a lot more character than the (objectively inarguably superior) arcadey 12-bit graphics of the Sega.
The TED chip used a very nice YPbPr-based color palette, with 16 hues including white (4 bits), and 8 levels of intensity on each hue (3 bits). Black got its own hue, which is black at all intensitities — intensity 0 is a dark but non-black color on all non-black hues.
This scheme gives a lot of colors to work with, and at the same time makes for the most beautiful raster bars in 8-bit history. Also, the 7-bit color scheme could be extended with an extra hue bit to 256 colors. Five bits of hue, the extra bit rotating the colorwheel somewhat, and three bits of intensity. I think more hues allows for better fidelity than more intensity levels. There is good reason to settle for 8-bit color, too. For one, it’s easily manageable even when the 65816 runs in 6502 mode.
Resolution is another question. My intuition tells me that aiming for 240p / 480i should be a good idea. We could call them “game mode” and “slow mode” or something similar. And once we have 480i, and YPbPr component output, it might be cool to attempt 640 pixels per row (and thus 80 columns).
Just running with the thought here, the two interlaced fields should be entirely separate memory locations, while the horizontal doubling should be via assigning less bits to a pixel.
This could give the machine potential both as a work and a game machine. 80-col mode could have 8x16 tall characters, this should make it relatively easy to implement through the interlaced mode. 8x8 in 480i sounds like an implementation nightmare.
[This part has been thoroughly rewritten.]
So I started sketching digital networks on paper. Specifically the part I tried to attack was, getting the screen information in memory into an 8-bit register that at every moment holds the color information for the pixel being drawn. During the blanking periods, its value is undefined. This could be the input for the video DA circuit, which I honestly know jack shit about.
What I describe below doesn’t seem impossible at all, it’s a big synchronous system built mostly of registers, PISO shift registers, and counters… The core goal was to allow for the entire screen information to fit within a 64k bank, and hopefully be small enough that it’s still usable in 8-bit mode.
So borrowing from Commodore, I very strongly think we need to keep the per-block coloring paradigm. Dave did mention that this would make sprites inevitable, and otherwise BOBs or software sprites would suffice, but a 320x200 screen with one bit per pixel is 64000 bytes. Womp, womp, woomp.
I mean, we could definitely add that functionality, the color extraction logic is going to be ridiculously simple for that, just a 16 bit counter, and a register to hold the current pixel color. That’s it. But it shouldn’t be enough. Also, even at high frequencies, it’d be a pain to handle a video ram of this size. Maybe with DMA hardware blitter (hmmm… I always wanted a RAM blitter in the c64…)
As for sprites, even without hardware sprites, I feel like it would be relatively easy to add character and graphics mode mixing! The logic for rendering text is somewhat different from graphics rendering anyway, there could be a separate circuit that outputs a bit that tells the system if the currently drawn pixel is text foreground. Now text foreground would have a separate color register, and take precedence over graphics!
Retro developers should already know what this means! :D
So since the flat memory model is so simple, let’s focus on the more memory-conserving approaches. I have a vague guess why VIC-II video modes were laid out the way they were (linear by character row, not pixel row), but it’s kinda painful so I’d rather do away with that. (So the screen is 40 fields wide in 320, and 80 fields wide in 640 modes.)
Now 640 width would need the system to run at 16 Mhz, which would be quite awesome, but is definitely pushing the boundaries of discrete logic. I’d have to look into propagation delays and memory timing. I have good faith that 8Mhz is doable though which would give us relatively simple 320.
Let’s look at different modes and their timings now.
When thinking about timing, consider that we have two separate sets of PISOs and registers. While one set is used to render the current block, the other is being filled from memory. Then they switch roles.
Low-color 320x200 mode:
So the most basic mode is 240p at 60Hz, with a usable screen of 320x240, one bit per pixel. This is an equivalent to VIC-II HiRes mode.
For this, each 8x1 block of pixels would require the following memory reads:
- Bitmap: 1 byte
- Foreground color: 1 byte
- Background color: 1 byte
With text mode mixin (one foreground, 1 bit per pixel), the following additional reads would be needed:
- Character code (from text screen RAM): 1 byte
- Character bitmap (from character ROM or RAM): 1 byte
- Character foreground color: 1 byte
That’s six reads. If the memory is clocked at double the CPU (and graphics) clock — should be possible, as most SRAM chips are quite speedy — , and is shared similarly to the C64 architecture, then this mode is entirely possible to fit in the 8 cycles for each block at 8Mhz.
As for worst-case memory usage… for the graphics:
- Video RAM: 40 x 200 bytes = 8000 bytes
- Foreground color RAM: 40 x 25 bytes = 1000 bytes
- Background color RAM: 40 x 25 bytes = 1000 bytes
And for the text:
- Character RAM: 256 x 8 bytes = 2 Kb
- Text screen RAM: 40 x 25 bytes =1000 bytes
- Text color RAM: 40 x 25 bytes = 1000 bytes
That’s a bit under 10k for the graphics, and a bit under 4k for text. 14k isn’t that bad, even an 8-bit app could live with that. Plus I guess we could make text switchable, so you don’t need to allocate an empty block of RAM if there is no text.
High-color 320x200 mode:
So this is where we can slap one on the C64. We have a semi-16-bit CPU designed in (unfortunately the bus is 8-bit), so why not two bits per pixel, ie. one word per 8x1 block?
Four values per pixel means three foreground colors. That’s definitely 16-bit game territory. So, how many reads are we talking about?
- Bitmap: 2 bytes
- Foreground colors: 3 bytes
- Background color: 1 byte
That’s 6 reads. Adding the 3 additional reads from the text renderer, we’re at 9 reads, beyond the capabilities of 8Mhz. Now there is a way to save this mode: lock background color down in a register. That’s still three per-block colors, and the register can be adjusted by raster interrupt. That brings us down to 8 reads. Good!
Worst-case memory requirements for the 8Mhz-capable mode:
- Video RAM: 80 x 200 = 16000 bytes
- Color RAM: 3 x 40 x 25 = 3000 bytes
So that’s clocking in at 19000 bytes, or if we add the fourth color plane (at 16Mhz), 20000 bytes.
With the text mode, we’re just under 24 Kb. A bit painful for an 8-bit app, but definitely doable.
If we do the Commodore multicolor approach, sacrificing vertical resolution for color, then each character can have three foreground colors. This means two additional reads. The low-color mode can just handle this at 8Mhz, pushing it to 8 reads per block.
The high color mode cannot. (Unless we lock down the additional two colors in registers.)
Similarly, if we do 2 bits per pixel high color, that means one additional read, so it definitely wouldn’t fit with the high color mode at 8Mhz, and the low color mode can only handle it with a two per-block foreground colors (one additional color read, and an additional bitmap read).
640-wide, 80 column modes:
Well, I have some sketches on how to use the same PISOs for this that handle high-color mode (instead of being read separately, one can be fed into the other for a single 16-bit PISO as opposed to two 8-bit ones). Would need a doubling of color registers… I think definitive plans can only be made once there is a logic network designed, and I see the synergies that could be exploited for this.
Needless to say, no 640 wide modes in 8Mhz. Even if the renderer used a clock doubler, there wouldn’t be enough cycles to do the memory reads.
480i modes should be entirely equivalent to 240p modes in every single way, it just needs to read even and off fields from separate locations in memory. It’s undecided whether only the bitmap should be separate, or the color map(s) as well. I’d probably aim for the former in hardware, and let developers use raster interrupts to do the latter if needed.
And this is where VGA question comes up, really. Do VGA monitors accept 480i signals? Can it even be represented as a VGA analog signal? If not, I guess YPbPr should be good enough, but having VGA would definitely improve ease of use and help adoption…
I’m somewhat against aiming for 480p. It would add serious complexity to the display circuitry. 480i is a minor adjustment to a 240p output circuit — after all, it’s just two 240p fields in succession, with some minor phase shift IIRC… 480p makes a major difference in design.
Storage is the biggest PITA whenever old-style computers come up. I’ll admit, I haven’t owned any floppy drives since around 2002. When I dig out my old Commodores, I use an SD2IEC. In general I’m a firm believer in SD cards as the floppy discs of today.
I’m thinking, having flash ROM as the default, native storage option may be a pretty cool idea. Taking inspiration from memory cards on old consoles, and the C64 EasyFlash project, this would be potentially simpler to make than any magnetic storage option, and also quite user friendly…
Also, why not magnetic tape? Or, more specifically, an audio frequency modem for load and save? All you need to save or load programs or data is your smartphone (with a headphone jack), and a headphone cable! Or, if you want to be oldschool, a cassette deck! Yay!
As for disk drives, I think we should aim to provide good RS232 ports. There did exist RS232 connected external floppy drives for IBM PC compatibles, and I’m thinking creating a driver for one shouldn’t be impossible for a third party. The disk drive would definitely be the long tail that takes 90% of the effort (or result in the addition of a modern MCU that could run the whole architecture emulated, which is just unseemly in my opinion).
Well it was fun to go on this thought excursion. I really welcome discussion and feedback. Hey guys, let’s design and make a community computer! If it’s ready by the time I have my first kid and they go to kindergarten, I’ll buy everyone a six-pack of beer who contributed. ;)
ADD: Some questions answered
I got some feedback, and decided to make a few of my points clearer.
FPGAs and ASICs
Why no FPGAs? I think I was super ridiculously clear on it. People, batches of one! Programming FPGAs requires specialized software and hardware tools. On a batch of one, cost of system = cost of parts + cost of all the tools you don’t have. It’s not “how much one FPGA costs”, it’s “how much all the tooling costs”.
Why batches of one? Because then it has a chance of surviving. Where I’m coming from with the limitations / goals I’ve written up, is that I’m looking less at what computer I “want”, and more at what computer I “can imagine succeeding” and at the same time “consider a worthwhile use of my time”.
If the goal is primarily the end result of having a retro plaform to play with, I’m really an emulator person. Creating peripherals for modern single-board computers to interface with traditional Commodore peripherals, and maybe a c64 case remake for RPi’s would fill that niche.
I’m not against MCU-based systems either on principle, though once we have a multicore hi-performance MCU, why not just have it emulate the WHOLE machine, like they did with the Maximite? These are all really cool projects, and emulating a Commodore 65 in an MCU would allow the creator to focus on highly compatible emulation as opposed to messing with hardware.
I’m also a great fan of FPGA-based remakes of old systems, and old ASICs. I’m really cheering for the Chameleon guys with their new projects, and projects like the FPGATED. I just don’t see the point of building a new system from scratch with FPGAs, for reasons I laid out so many times. If people can’t build it off of Digikey with a soldering iron, it’s never going to go anywhere. It will sit on the shelves of a few collectors, and that’s it. Good night.
I’d rather build something from discrete logic, and once it becomes a success, let the Chinese integrate it and sell smaller, cheaper and improved FPGA-based copycats on Aliexpress.
Note though, I’m not talking about implementing the entire video logic as a discrete circuit. A generic MPU (like a 6502) acting as video coprocessor, along with discrete logic for handling the nitty-gritty of generating a PAL/NTSC signal or sound is more what I was thinking of.
This list is not about what I want others to do. It’s what I’d consider working on. I just don’t see myself working on another 1 batch from IndieGoGo and forgotten / “yea cute but why” sort of thing. I might as well use that me-time to develop software for the c64, and be so much more use to the world.
Surface mounting and board size
Should it be surface mount? Well, if it’s necessary. If it’s really hard to get the chips we need in DIP format, maybe. But then people assembling it will need a reflow oven. I guess I could live with that, but I’d prefer throughhole design.
And yea, the reason I said the board should be big, is that it wouldn’t fit on a small board with discrete logic. :P
What with C compilers, Python and all this new-fangled shit? Well, the first computer I had with more than 4 megs of RAM was a 386. It ran Windows 95. Windows effing ninety-five, people! This is gonna have 16 megs. For me retro projects aren’t about living in the past, but about building upon it.
I have about as much, or probably more love for Borland Turbo Pascal as I do for Commodore BASIC. What I remember about Commodore BASIC is that it was limiting me on every step. Which is why the Maximite doesn’t really entice me all that much — a generic BASIC machine, cute.
I’m not enticed to work in BASIC too much, and it probably wouldn’t be my first choice language to teach a child. I don’t want to recreate the bad part of the 80s, I want to invoke the cool part. It’s not BASIC the language that’s the important part, it’s starting up on a programmer’s interface.
Ultimately though, this seems like a fun dream, but it will probably remain that. The 80s feeling means so different things to everyone. Getting a project like this together is like herding cats, and beating design decisions through committees is painful enough when one is getting paid for it. I mean, most of the replies I got were about how different their vision is.
If I really think about it, VICE is perfectly enough for me, for now, along with my two old Commodore machines. If someone does find the idea of making a jellybean micro enticing, well drop me a line.
I guess an alternative path could also be to build a reference architecture around the Propeller chip or something similar. Just relying on the native RISC assembly of the Propeller, adding some kind of ROM cartride support, and a default sound and video implementation on one or two cores (“cogs”). Oh wait, it already exists. ;)