A board · sheet 1/8 · manual page 23

The CPU sheet

One Z80, two ROMs, eight kilobytes of RAM and a decoder. It looks like the simplest sheet in the machine until you notice that almost none of it is about running the program.

This sheet is part ofHow the CPU shares the machine

The subsystem followed end to end, across every sheet that builds it.

What this sheet is for

Strip it back and the sheet does four jobs. It runs the program. It decides which chip answers each address. It generates the interrupts that drive the whole frame. And it hands the entire bus over to the sprite board twice a frame and then takes it back.

The first job is the least interesting, because the Z80 at 11M does it on its own. The other three are the reason this sheet has nineteen chips on it.

It is worth holding one thing in mind while reading any of these sheets. In 1985 a logic chip cost real money and a custom chip cost a fortune, so Capcom's engineers were solving every problem with the cheapest arrangement of 74-series parts that would work. Almost every design decision you meet here is really an answer to “how do we do this without spending another chip?”, and most of the cleverness on this board is in what they managed not to build.

The memory map, and the chip that draws it

The Z80 sees 64K. 9J, a 74LS138, chops that into eight 8K blocks using nothing but the top three address lines. Each output is one block, and everything else on the sheet is downstream of it.

Why 8K blocks? Because that is what one chip buys you. A '138 has three select inputs, three address lines is 23 = 8 outputs, and 64K divided by 8 is 8K. Capcom did not choose 8K because the game wanted 8K granularity; they chose it because it is what a single decoder gives away for free. Wanting finer blocks would have meant a second decoder and more gates, so the memory map was shaped around the cheapest part that would do the job.

Two details make it work properly. The decoder is qualified by /MREQ, so it only fires on real memory cycles rather than on I/O. And it is disabled by /RFSH, which matters more than it looks. The Z80 was designed to refresh dynamic RAM by itself: after every instruction fetch it puts a refresh address on the bus and pulses /RFSH. Those cycles look exactly like memory reads to a decoder. Without that one gate, a ROM would be selected and start driving the data bus several million times a second for no reason, fighting whatever else was talking. One inverted input on a chip you already have, and the problem disappears.

0000 - 7FFFprogram ROM, 32K9Mthe game itself, opcodes descrambled on the way past8000 - BFFFprogram ROM, 16K8Msecond half of the codeC000 - DFFFvideo and I/O windowoff-board: characters, scroll, sprites, controlsE000 - FFFFwork RAM, 8K7Mand the sprite table the B board comes to fetchwhat the Z80 seesFE00 - FFFF sprite table

One 74LS138 at 9J splits the whole map into 8K blocks. Everything else on this sheet hangs off that.

Turning eight blocks back into two ROMs

The ROMs are bigger than the decoder's blocks. 9M holds 32K and 8M holds 16K, so several decoder outputs have to be recombined. That is 9L, a 74LS08.

Here is the trick that makes it cost almost nothing, and it catches people out every time. The decoder outputs are active low: the selected one goes to 0 and the other seven sit at 1. Feed two of them into an AND gate and the output goes low when either input goes low. So an AND gate on active-low signals performs an OR of the address ranges. Capcom needed "select this ROM for block 0 or block 1" and got it from one quarter of a 20p logic chip, with no inverters anywhere.

That inversion trick is everywhere on these boards once you start looking, and it is worth internalising, because it makes the drawings read strangely until you do.

The RAM select takes a detour through 6N instead of going straight to the chip, and that detour is the whole sprite-DMA trick. More on it below.

A13 A14 A15top three address lines9J74LS138/MREQ qualifies it/RFSH disables it/CS01 /CS230000-7FFF/CS45 /CS678000-BFFF/CSCDC000-DFFF/CSEFE000-FFFF9L74LS08to 8L / C board6N74LS08ROM /CERAM /CS

Two blocks per chip select, so a pair of the decoder's outputs is ANDed back together at 9L to cover a 16K ROM. The refresh line is the detail worth noticing: without it the decoder would fire on every DRAM refresh cycle the Z80 performs.

Where the interrupts actually come from

A game like this has to do certain work at certain moments in the frame: read the controls, update the sprite list while the beam is in the blanking interval, start the music. The CPU cannot poll for those moments, it is busy running the game, so something has to interrupt it on schedule.

The obvious 1985 answer is a Z80 CTC, a dedicated counter and interrupt chip. Commando does not have one. Instead there is a 256 by 4 bipolar PROM at 6L, addressed directly by the vertical counter coming across from the sync sheet. The V counter says which scanline the beam is on, that number is the PROM's address, and whatever Capcom burned into that location says what should happen on that line.

Think about how neat that is. The interrupt schedule is not logic at all, it is a picture of the frame, 256 entries long, one per scanline. Want to move an interrupt three lines later? Burn a different PROM. No redesign, no extra gates, and the same part costs the same whatever pattern is in it.

The PROM's output runs into 7L and then 6M, which turn a level that is true for a whole scanline into a single clean edge on the Z80's /INT line. When the CPU acknowledges, 10J spots the one combination that means "interrupt acknowledge", /IORQ together with /M1, and produces /INTACK. That opens the latch at 11K and puts a vector byte on the data bus.

And the vector is the best part. In Z80 mode 0 the CPU executes whatever instruction it reads during that acknowledge, and the single-byte RST instructions are perfect for it. So most of the byte is simply strapped to fixed levels with resistors, spelling 11x0x111, and the PROM fills in the two missing bits. The result is either CF or D7: RST 08 and RST 10, the two interrupt routines the game expects per frame. A lookup table and a handful of pull-ups doing the entire job of a peripheral chip, for a fraction of the price.

V1 - V128from 5/86LTBP24S10 PROMthe interrupt pattern,burned per scanline7L74LS1746M74LS74D0 D1one clock later11MZ80A/INT10J74LS32/IORQ + /M111K74LS374/INTACKvectorCF / D7RST 08 / RST 10straps give 11x0x111, the PROM fills bits 4 and 3

There is no interrupt controller. A PROM addressed by the vertical counter decides, scanline by scanline, when to interrupt, and a second PROM output picks which of the two vectors the CPU reads.

Handing the bus to the sprite board

This is the part of the sheet I like most, and it explains why so many buffers live here.

The problem: the sprite board needs to know where every object is this frame, and the game code that decides all that runs on the A board. So the list has to get from one board to the other, 512 bytes of it, every frame, on a 3MHz Z80 that has plenty else to do.

The obvious answer is to copy it: give the sprite board its own RAM and have the CPU write the list across each frame. That costs RAM chips on the B board, and it costs CPU time, several hundred instructions of pure copying, sixty times a second.

Capcom's answer is to not move the data at all. The sprite list stays in the A board's own work RAM at 7M, up at FE00 to FFFF, and the B board comes and reads it in place.

The Z80 was built for this. Assert /BUSRQ and it finishes its current instruction, tri-states its address, data and control pins, and answers BUSAK: the bus is yours. So the B board raises /ROB on the cable, that becomes the bus request, and the acknowledgement comes back buffered by 8K as /AKB.

Now the interesting bit. With the CPU off the bus, somebody has to drive it, and all the A board's buffers are pointing the wrong way. So the B board asserts BLCNTEN, and that single line turns the whole board around: it flips the direction pins of the address buffers at 9K and 10K, flips the data buffer at 8L, and forces 6N to select the work RAM whatever the decoder thinks. One wire, and the A board changes from driving its own memory to letting a neighbour drive it.

For a few microseconds during blanking the sprite board is addressing the A board's RAM directly, reading the object list out of it. Then it drops the request and the CPU carries on, none the wiser. No duplicated RAM, no copying, and the cost is a handful of buffers that had to be there anyway to drive the ribbon cable.

B boardsprite hardwareA boardthis sheet/ROB (B22)"I need the bus"BUSRQinto the Z80 at 11MBUSAK (/AKB B21)"it is yours"BLCNTEN (B23)"I am driving now"and while BLCNTEN is high:9K 10Kaddress buffers reverse8Ldata buffer reverses6Nforces 7M selectedso the B board reaches straight into the A board's work RAM and reads the sprite table itself

Commando does not copy the sprite list anywhere. During blanking the sprite board takes the CPU's bus off it, drives the A board's own address lines, and reads FE00-FFFF directly.

Reset, and one chip that is easy to miss

PST518 is the reset supervisor, holding everything down until the supply is stable, shaped by R56, R57 and CC17 and cleaned up through the Schmitt inverters at 11J. The same chip produces the power-on clear that goes out to the other two boards.

It is worth knowing about because a machine that will not start is far more often a reset that never releases than a dead CPU.

Every chip on this sheet

Click any of them to open the schematic with that chip selected in both panels.

← open the schematic for this sheet