This Project Is In This List

Description

The design and construction of a hombrew computer based on the Motorola 68000 CPU

Details

This project is a homebrew computer based on the Motorola 68000 CPU. Design includes four megabytes of RAM, 128kB of ROM, Something for video, two serial ports at 9600 baud, and eventually networking and a hard disk.

The purpose of this computer is two-fold: To show it's really not much harder to build a 16-bit homebrew computer than it is to build an 8-bit homebrew computer, and to build a server for Hackaday's retro site.

Project Logs

I'm in the middle of a few free days right now, and I figured it's time to take a look at this project. Things aren't good. Let's go over what's wrong with it:

It's not done

It's not even close to being done

The 'not being done' is mostly a result of using a backplane design, using discrete logic, and using extremely old and expensive parts.

Yes, the way we do things now is better than the way things were done. Imagine that.

So, how am I going to fix this? Rapid iteration. I'm figuring every month I can dedicate 10-20 hours to this project, and going by how long it takes Seeed studio to ship some boards to me, that's just about right for a single hardware revision. Therefore, this project is getting a complete refactoring. I'm going to design monolithic boards (with *everything* on one board - ram, rom, whatever), and get as much as I can working. Iterate on that until it works, and add more stuff. You never expected me to be done with this, did you?

Another factor that has led to this project being stuck in quicksand is the use of 5V parts and discrete logic. This was reasonable for 1982, but it ain't the 80s anymore. It isn't even the 90s. CPLDs are the way to do this, and memories are larger and cheaper if you use a 3.3V part. What does that mean?

The Motorola MC68SEC000.

The *SEC* part is a very late evolution of the 68k family; it's a static design, so it will work even when the clock doesn't. It works at 3.3V, opening the door to some really great parts and programmable logic. It's not available in a DIP part, though, leading me to this problem:

That's a 64-pin TQFP. I can solder that, but it will most likely mean boards with more than two layers in the future. I can deal with that.

With a new part that I created in Eagle, that means I need to verify that part is correct. This means ordering a board with just this package on it, and I think I can do something cool:

That's a board with the *SEC* package just freerunning, with some LEDs attached to the address lines. It's effectively a binary counter in a very small package. And to indulge the racists on hackaday.io, yes, I can solder CPUs.

The *SEC* part, along with the *EC* parts have two additional pins: /AVEC and MODE. /AVEC is an extension of the IPL... pins, so we can just tie that to VCC. The Mode is a bit different, and something that's incredibly valuable in the new design:

Mode (MODE):

The MODE input selects between the 8-bit and 16-bit operating modes. If this input is grounded at reset, the processor will come out of reset in the 8-bit mode. If this input is tied high or floating at reset, the processor will come out of reset in the 16-bit mode.

With one part I'll be able to test both 8-bit and 16-bit data busses, something I've struggled with in finding a proper development environment for this computer. That's cool, several problems down.

As for now, the next update will be a blinkey thing that is a complete waste of transistors. That's cool, though: it's just to verify the part.

Quick story. I brought this computer to the Vintage Computer Festival 9.1 last year to show Bil, Dave, and all the other cool people at the event. At the time, I was freerunning the processor, watching the blinkenlight count up. Great stuff, and proof that the CPU works.

A few hours into the show, the CPU board stopped working. It just wouldn't free run. No idea why, as I was able to get the board working by wacking it against a table once I got home.

Then the Hackaday Prize happened, and then the summer con season happened. I've been working on this off and on in the meantime, but no *real* progress. I made a better RAM card (more on that in a bit), but it's still a bit away from sending characters out over the serial port.

Since then, I got the wire-wrapped CPU card free running again, and I decided to take it to the Vintage Computer Festival X last weekend. When I pulled it out of the box and turned it on.... nothing. This computer hates VCF for some reason.

Therefore, I have decided to build a proper CPU PCB. It's just buffers, the CPU, a clock, and some blinkenlights:

And I have to route that before I leave my house for a month for con season. Great.

OTHER STUFF

I had a front panel milled out of a big ass piece of aluminum. Here are the videos of the milling:

And a picture of the front panel:

That panel was made by the SeeMeCNC guys when I was up there for the Midwest RepRap Festival. I traded a gigantic (5 foot x 8 foot) hackaday flag - made by me - for the CNC work. All the relevant files are up in the Git.

Front panel not included. I'm moving the reset circuitry to the front panel, btw. Another board to build.

Four megabytes of RAM

I hated the wirewrapping on my RAM card. The initial plan for all of these cards was to prototype them with wire wrap, then build a board. I met myself halfway on this one.

That's the layout for the RAM chips, eight 4-Megabit chips. You'll notice there is no control circuitry on this one; there's a reason for that. I might want to change the control circuitry to a PAL or something down the line. Easiest solution is to make a proper layout for the RAM chips themselves, break out the data, address, and control lines, and leave everything else up to wirewrapping. Easy enough.

DEVELOPMENT TOOLS

Since I'm doing all of this from scratch, It would be nice to have a development tool.

That's the Motorola Educational Computer Board, the official 68k trainer from 1981. It works, I have it plugged into a terminal, and it has a great monitor in ROM. I'll be using this heavily once I get a few characters spitting out of the serial port of my project.

Picked that up on eBay for $40, btw.

Also on the eBay Front...

I have most of DTACK Grounded.

DTACK Grounded. the journal of simple 68000 systems, was a newsletter put out by [Hal Hardenberg] on how to design a simple 68000 system.

Most of DTACK grounded covers the development of a 68000 add-on card for the Apple II and a BASIC interpreter. It's good writing, and the issue ever 68000 homebrew wants to read - number 6 - tells you exactly what you need to leave out, what you need to leave in, and what pins to connect to where.

That's a 12MHz 68000. Five dollars. It's an actual Motorola part, so this is what I'll be using from now on. I don't know if I'll be running it at 12MHz; I specced all my decoding logic for 8MHz. I'll try it - it's just changing a crystal - but I don't expect this computer to run at 12MHz.

That's it for this update.

I'm leaving for NYC next weekend, and LA a few days after that. I won't be home for a month and for some reason that means no Windows, and no Eagle. Don't read too much into that last sentence.

I need to get this CPU card done and sent off to fab. It's exactly like the earlier wire-wrapped CPU card, only this one hopefully won't fail all the time.

So... yeah... it's been embarrasingly long between this update and the last, but hey, I've been busy, and technically, I have...

This is something I've written about in a front page Hackaday post, but I think it's time to go over a little more of the theory of what I'm doing here. First, a video:

This is called freerunning the processor. Basically, it executes one instruction, the program counter is incremented, the address is increased by one, and the CPU just sits there, doing nothing, cycling through its address space. Attach a few LEDs to the address pins, and you have an incredibly complex binary counter, also known as blinkenlights.

That's the simple explanation. It's a fair bit more complex in practice. I need to tie a few pins to +5 volts, and ground DTACK. Oh, what about the instruction to freerun the processor? NOP, right? NOPe.

When the 68k first resets, it reads the program counter vector. The program counter vector must be an even address, and the opcode for NOP is $8E71. See that one at the end? That means NOPping the CPU from boot would create an illegal address exception. Then bad things happen.

So, I need an instruction that does nothing, and is even. Inclusive OR Immediate (ORI) does this. Specifically OR.b #0,d0. Bonus, this instruction in hex is $0000, or all zeros. All I need to do to freerun the processor is ground all the data lines.

My first go at freerunning the CPU only used one LED. This LED was tied to the A20 line through an inverter. I hate to waste the five extra inverters on that chip for a single LED, so I added another three.

Now I have status lights for the top four addresses in the computer. Since I'm putting the ROM at $FF0000, the serial port at $FE0000, the video peripherals at $FD0000, the microcontroller at $FB0000, I have a graphic representation of what the CPU is doing with all its peripherals. That's pretty cool. Useful blinkenlights.

Although it might make sense to start this project by building a CPU module first, I decided it would make more sense to start with the memory for this system. This serves two purposes: as an explanation of how the 68000's memory-mapped I/O works, and to have a relatively simple circuit built before embarking on the more complex that include the CPU module.

As with the 6502, 6800, and 6809, memory access is controlled by the R/W line. Basically, when the R/W line is high, the 68000 reads from the data bus. When the R/W line is low, the 68000 writes to the data bus.

Before designing our memory modules with these signals in mind, it's very important to figure out how this computer is going to boot. All computers require some amount of RAM somewhere in the address space, and at least a few instructions telling CPU what to do on a restart somewhere else. The 6502, for instance, requires an instruction in ROM at $FFFC, and a few bytes of RAM at $0000.

The 68000 is different. It's reset vector, or the place it looks for instructions on a reset, is at $000000. The 68000 also requires a small amount of RAM at address $000000. Let that sink in. The naive analysis of these two facts means we must store the first instruction in RAM. RAM that will be uninitialized when we boot the computer.

Fortunately, Motorola application notes give us an easy way to get around this. The solution is to deselect the RAM and select the ROM during the first four bus cycles. This can be done with a 74164 binary counter, using the /AS line as the clock input, and making a /ROMSELECTcontrol signal with one of the outputs. This /ROMSELECT or /BOOT signal (I'm using the two interchangeably) will allow CPU to read instructions from the ROM on reset.

Above is a fairly broad overview of the ROM board's circuitry. I'm using two 32kB EEPROMs for the ROM, split between high bytes and low bytes. This gives me 64kB of ROM for this computer, more than enough to set up a few things on boot and eventually pull data off a hard drive.

According to the memory map I have in my notebook, the 64kB of ROM will be decoded at $500000 through $50FFFF. This means the ROM is selected whenever address lines 22 and 20 are high, and lines 23 and 21 are low. A three-input NAND gate (74ls10) and a few inverters are all that are needed to enable the RAM.

The ROM memory control is used to toggle the output enable pins on the EEPROMs. The Motorola 68000 user manual has a table going over when valid data should be on the data bus according to the /UDS, /LDS, and R/W lines. Long story short, the above circuit will work just fine for enabling either EEPROM.

Compared to the 8080, the Z80, the 6809, 6502, and all the other 8-bit microprocessors used in boxxen of yore, the CPU I’m using for this project - the Motorola 68000 is both extremely powerful and extraordinarily complex. The power comes from a huge address space and some neat features like a divide instruction. The complexity comes from it’s asynchronous nature.

A single-board computer using the 8-bit 6502 processor is very simple compared to a 68k computer. Conjuring up a simple 8-bit computer is as simple as getting a RAM and ROM chip, connecting all the data and address lines together, and throwing together a little logic glue to get the whole thing working. The 68k is another story entirely. Thanks to its asynchronous nature, you have to deal with something called the DTACK, or Data Transfer Acknowledge. This is an input pin on the processor that indicates the the data transfer from RAM or ROM is completed. If this isn’t low at the right time, the entire system just stops.

The bus arbitration pins - /BR, /BG. and /BGACK control which device in the system controls the data and address busses. It’s great for DMA operations, crazy video schemes, and shoving data from a cassette port directly to memory without going through the processor. DMA would require a good bit of circuitry, though, and I won’t be using it anyway.

Oh. There’s also processor status pins on the 68k. These are output pins that tell the system if the current cycle is being used for user data, user program, supervisor data, supervisor program, or an interrupt. Very cool, and a good example of how the 68000 was inspired by the minicomputers of the 70s, but utterly useless for a small box that will sit on my desk, tweet, and play Breakout.

Complex, yes, but I don’t actually need to use all those pins. Those processor status pins can be easily ignored. I won’t be doing any cool DMA stuff with this computer, so I can just tie the /BR, /BG, and /BGACK pins to +5 Volts. Pins /IPL0, /IPL1, and /IPL2 only indicate the priority level of an interrupt, and I can’t imagine designing hardware in response to an interrupt in this system.

This is a line going into the 68000 to tell the CPU a device has received data on the data bus. If I were not using 6800-compatable parts or the 6800 peripheral control pins, I could simply tie /DTACK to ground and hope my memory is fast enough. That’s the easy way out, and I’d really like to do this project right. Generation of the /DTACK signal is easy enough.

And that’s it. There are a ton of pins on the 68000, but if you want to build a simple computer you can ignore everything except the data and address pins and four bus control pins. The amazingly complex 68k then turns into a very very simple synchronous CPU just like the 6802 and Z80. Really, other than the fact a 16-bit homebrew computer requires twice as many RAM chips (although you could always use a 16-bit...

Since we're using an ATX power supply for this computer, there is a little magic that needs to happen before it becomes a proper power supply. Besides the usual orange, red, yellow and black wires attached to a 20-pin connector, there are also a few extra wires that make the whole thing work. The most important is the green wire, or /PS_ON line. Only when this wire is shorted to ground does the supply turn on. That's a fairly easy circuit to whip up.

Also on the ATX connector is a gray wire. This is the PWR_OK line. This signal is generated by the power supply and is at +5VDC when the power is okay. This is a great place to put a power LED, and is another very easy circuit to put together.

Careful readers will note these circuits were already implemented on the backplane itself. However, since we're going for a slick, streamlined look for this computer, it only makes sense to put add this circuit to the front panel.

The Reset Circuit

Every computer, from the awesome 4-bit builds we see to the i5 warming my ankles as I type this, needs a reset circuit. For the 68000 I'm using, there are actually two types of reset I need to consider: the power-on reset, and the manual reset. Power-on reset is needed when - duh - the computer is powered on. Manual reset is for when I screw something up terribly and need to figure out what went wrong.

Conceptually, the reset circuit for this computer is as simple as having one line on the backplane connected to a switch. When I want to reset the computer, all I need to do is ground the reset line. A simple tact switch takes care of this. It's not that simple, though: without a debounced switch, crazy things happen, the CPU isn’t happy, and looking at what the 68000 is doing with a logic probe is a sure path towards insanity. [Garth Wilson], god of modern 6502 single board computers, has a great site up for circuits used in homebrew computers. In that, he covers a few reset circuits that can be easily generalized to any homebrew project.

[Garth]'s circuit, while perfectly reasonable and easily implemented, doesn't account for a power-on reset. This is somewhat common in the homebrew computer scene, requiring the user to press the reset button whenever the computer is powered on. A lot has changed in the 30 or 40 years since the glory days of homebrew computers, and now there's an awesome one-chip solution for this problem. It's Microchip's MCP130, a small SOT-23 device that will both keep the reset line low until the power supply has reached a stable voltage, and keep the reset line held low for 350ms after the power supply is stable.

Putting These Circuits Together

I designed my backplane with the express intention of putting a power/reset circuit on the front panel. For the sake of modularity, I broke out all 64 pins on the backplane to a 2x32 0.1" header. With this, I can design a front panel that shows the status of the data and address lines (blinkenlights, anyone?), and could potentially create a front panel that's at least as cool as the king of minicomputers. For now, though, I'll simply put the power and reset circuits on the board and drill a few holes in my enclosure.

Below you can see the first iteration of what I like to call the 'frontplane'. I should have checked the +5 Volt line on the backplane was connected to the power plane of this board. Simple enough fix, though: a soldering iron, xacto knife, and hot glue will do wonders for any circuit.

As the Hackaday corporate overlords probably don't like trademark infringement, I've removed BMO from the board in this project's Github. I also fixed the issue with the power pin, so if you're building this for yourself, feel free to grab the gerbers and have fun.

This entire project is a little bit of an odd bird. In terms of electronic sophistication, it’s not too different than any of the other homebrew computers you might see on Hackaday. This isn’t a project that will just sit on my workbench until I die and it is subsequently thrown away, though: I’ll need to lug this thing around to Makerfaires, retro computer gatherings and Hackaday not-cons to show it off. This means I need an awesome looking enclosure, and everything needs to fit together perfectly.

This means I should start with the mechanical design of the project - obtaining an enclosure first, then designing the whole thing around that. Yes, it’s completely backwards, but the evil Hackaday overlords are a fickle bunch and I’d like to impress them, lest we have a repeat of the server blade of damocles incident.

The enclosure I’m using is a Hammond instrument case. They’re truly remarkable, sturdy, and undeniably old-school enclosures that really lend an air of being cobbled together in a silicon valley lab in the early 80s. I’ve chosen the 1458VD4B enclosure - eight inches wide and long, and four inches tall. This is great because the Eurocard connectors I plan on using for the backplane are just under four inches long.

The design of a backplane computer is actually pretty simple. All I need to do is build all the parts of my computer on cards, plug them into the backplane, and hope everything works. It’s a much more modular approach than building an entire computer on a single PCB. With this modularity comes a whole lot of planning, though. I need to figure out how I’m going to power everything attached to the backplane, how to turn the power on and off, and how to fiddle with the reset circuit.

Really old computers based on the S100 bus like the Altair 8800 have huge linear power supplies with transformers and hilariously large capacitors. Even old gear with switching supplies - the Apple II and the Digital VT100 - have power supplies that are still absurdly large. This just won’t do for an enclosure that’s smaller than a shoe box.

There are, however, extremely small ATX power supplies. This little guy comes to mind. It’s the smallest computer power supply available, and just barely larger than the ATX power connector itself. It sips power from an external power adapter that provides 12V, then steps that down to 5V and 3.3V for everything on a modern motherboard. It has all the features you’d find in an ATX power supply, and is impressively cheap.

As I said above, I’ll be using Eurocard connectors for this computer, with the female plugs on the backplane, and right angle male plugs on the cards themselves. Normally, Eurocard connectors have 96 individual pins. This is far more than what I need, but it does present a problem: If I want my backplane to be a 2-layer board (and thus not be absurdly expensive for a run of 10), there’s no easy way to route all the connections between three rows of connectors.

The solution to this problem is, of course, to give up. I don’t need 96 pins available for each card, and since I’m not using one of the fancier chips in the Motorola 68000 family like the ‘020 or ‘030, I can get away with this. 64 pin Eurocards, with two rows of 32 pins, will do just fine.

There it is. Well, it’s just a render, but there you go. The holes on the short ends line up with the mounting holes in my Hammond enclosure. If you have a keen eye, you may have noticed a small addition to the backplane....

Have we said Hackaday’s evil corporate overlords are really cool recently? They are. They really, really are. They’re so cool, in fact, that they want some more original content for Hackaday. One conversation leads to another, and they’ve greenlighted yet another new project: the development of a homebrew computer, based on the Motorola 68000 processor.

So what, you may ask. There are plenty of homebrew projects around: [Quinn Dunki] is building an awesome 6502 computer named Veronica, Z80-based computers are a dime a dozen (example 1, 2, and 3). A project using a true 16-bit CPU is rare, though. We featured a few homebrew 68000 computers a while back but short of those, an awesome 65816 build, and [Jeri Ellsworth]’s awesome C-ONE computer, we haven’t seen very many homebrew projects break the 8-bit barrier.

This project aims to fix that. Every few weeks, I’ll be posting the recent developments in the construction of a 68k computer. I’m sure you all want a high-level overview of what this project entails, so here we go:

Designed around a backplane

While not the best for very high-speed circuits, I’ll be building this computer around a backplane for several reasons. First, it allows me to build the computer in a piecemeal fashion. First the power, reset, clock, and CPU modules, then a serial interface, a huge amount of RAM, and finally some sort of video output and a hard drive of some sort. Secondly, it just looks cool.

Wire-wrapped prototypes.

Eagle and KiCAD are all the rage with the kiddies these days, but PCBs have a turnaround time that’s just too long for me. Yes, I could etch my own boards just like [Quinn Dunki] does for Veronica, but wire wrapping, done correctly, is a method that just doesn’t fail. Solderless breadboards are out of the question, because eventually I’ll be lugging this around to Makerfaires and the like.

A ludicrous amount of RAM and Gigabytes of storage

8-bit CPUs generally have a 16-bit address space, limiting them to 64 kilobytes of RAM without bank switching. The 68000 has a 24-bit address space, meaning it can access 16 Megabytes of RAM. Of course I’ll need some of that space for ROM and I/O devices, but this computer will have 4 Megabytes of RAM. While I’m at it, I might as well work out an IDE interface so CompactFlash cards can be plugged in and accessed. Yes, a solid state boot drive. It’s like living in the present.

A UNIX-ish OS and a C compiler.

This is what the 68000 was designed to do. Even though the 68000 found its way into the original Macintosh, Amigas, the Sega Genesis, and a million arcade boards, some of the most advanced applications for the 68k were in Unix workstations. I won’t be able to run a complete version of UNIX as the 68k doesn’t have a memory management unit (I’d have to move up to a 68020 for that), but I can get close.

Become a member

I was watching this closely as I like the old modular systems that plug into the bus.

Well, I did buy all the connectors (50 pin dual row 0.1" headers) so I guess I now have to extract the digit and do something myself.

I totally agree about mixing old 5 Volt chips with 3v3 CPLD. I built a Compact Flash inteface (IDE) for my Amstrad CPC 6128 using CF / level translators and a 3v3 CPLD and it didn't work because the noise margin was too low for the CF cards Vih of 4.8V - perhaps I should put it up and submit it as a fail lol. I may give it another go as the CF should work at 3v3 instead of 5v.

All was not lost though because the interface was IDE so I plugged in a 2.5" hard drive and it work perfectly even though I was looking for more *removable* media. So that proves that a 5 Volt Tolerant - actual 3v3 CPLD will work with *standard* 5 Volt TTL chips with LVTTL.

Anyway the CPLD's that I have successfully got working with 5 Volt TTL are Xilinx XC9536XL / XC9572XL and Altera EPM240 / EPM570. I bought a 100 XC9536XL's so that will keep me going for a while. The Altera's mentioned have a k or so of serial FLASH as well.

This is a nice project. I've always liked the 68000 CPU. I designed and built myself a 68000 based CPU board about 20 years ago. It had 512kB of EPROM, 512kB of RAM, a 6850 (serial port), and lots of I/O pins. The 68000 ran at 8MHz due to timing limitations of the 6850. The 68000 could run at 10MHz which would require the use of a 68A50 which I didn't have on hand.

If you wanted to use a 6850 with the 68000 running at 12MHz you will may need to use the 68B50. The 68A50 may not be fast enough. I can't say 100% as I haven't checked the timing diagrams.

Brian, I'm curious, does the 68k HAVE to have RAM at $000000 after boot? Both the Sega Genesis and the Neo Geo (both 68k based systems) have ROM mapped there. Is it just a matter of being able to rewrite the vectors during runtime? Why not have the vectors hard-coded stored in ROM, pointing to a location in RAM, and have a JUMP or CALL there in RAM? The only downside I can see is the increased latency, but it would only be a few cycles.

The last project log is 11 months old now (the time flies, I feel like I signed up the projects page yesterday...). Do you plan any updates on this project? I believe I'm not the only one who likes it.

Agreed-I quite enjoy reading about homebrew computers (such as this one and Quinn Dunki's Veronica) and would love to see an update soon. Wasn't this going to be used as the Hackaday Retro Edition server someday?

It still will be, and there will be an update "soon". I know I haven't been working on this as much as I should, but <i>holy crap</i> getting switches lined up with a milled front panel is a pain in the ass.

consider using a atmega or pic as your reset handler/boot vector installer. With address lines pulled LOW, while the processor is reset and in HI-Z state, let the atmega328 access the bus to put an instruction there, or a bunch of them. then the atmega gets off the bus, and releases the reset.

How about using IS66WVE4M16BLL for memory? Dense and cheap, but BGA. It looks like it was made for the 68000 bus.

This is very awesome! I'm actually in the planning and design phase of my own 68k microcomputer project. Though I have to point out, a TON of images in your posts are broken. Can you please fix them up?

The 6850 is so braindead... ugh... I'm happy to donate one or two 68681 and/or 68901 chips to your project. I've got at least a dozen of each scurried away... I'm sure I've got one or two 68230 as well.

As much as these 68xxx chips are convenient to use with the async bus of the 68K, I've come to the conclusion that the only real reason that I, personally, would ever use most of these devices is for software compatibility with some older system. The state logic required to interface a synchronous bus peripheral device (i.e. without DTACK) to the async 68K bus is straightforward and easy enough to implement in a GAL or CPLD.

I think the exception (pun intended) I would make to this statement is that the 68901 in particular makes a fine vectored interrupt controller. I have no desire to re-invent THAT wheel...

You're right that the 6850 is dumb. I'd really rather not bother with DTACK and 6800 stuff. I'm kinda in a bind with this project, though: I want to make it as simple as possible, but also give people a chance to replicate it. So far, all the chips can be ordered off jameco (with the exception of the 68000 and V9938/V9958). The other 68XXX chips... they're hard to find.

If you want to donate something, email me at (my last name) @hackaday.com. Give me your address and I'll send out a T-shirt and some stickers for your trouble. I'll also promise to use the '681... after I've brought the system up with the 6850. Beauty of the backplane, I guess.

The idea is that the ROM and not the RAM is mapped at addr 0 at reset. When the ROM is addressed at its runtime address the RAM is mapped instead at addr 0.
The ROM is in this picture mapped at $500000-$5FFFFF, it is better to move that to a high address.

Try to find a 68681 DUART instead of the 6850. And a 68901 that includes UART, timer and an 8-bit port. You need a timer don't you? ;)
Move peripheral and ROM to as high address as possible to get continous RAM from address 0 and up.
And I have some comments how to simplify the ROM/RAM address decoding:
Use a simple flip-flop instead of the counter at reset and see comment in text about RAM.
I had better draw a figure than explain it in text.