Skip to the content
2 layers137.2 × 88.8 mmGPU SCH, the printed circuit board in 3D

A retro computer motherboard for the W65C816S CPU. Dual-core expandable, 16mb extended memory, four expansion ports.

Size
137.2 × 88.8 mm
Copper layers
2
Thickness
1.6 mm
Parts
67
Nets
148
Pads
571
Tracks, vias
2,767, 253
Routed
Yes
KiCad
KiCad 9.0 (file 20241229)
Created
25 May 2025
Updated
25 Jul 2025

Overview

GPU SCH is an open-source printed circuit board by snippyrow, from the snippyrow/-816-board repository on GitHub, published under the MIT licence. It is a 2-layer board of 137.2 × 88.8 mm with 67 parts on 148 nets, routed with 2,767 tracks and 253 vias.

It is built around the 74HC688D, 74HC373D and 74LS157PC, with the 74HC4040D, 74HC74D and 74HC00D among its other parts. Its parts include 25 capacitors, 25 ICs, 8 resistors, 3 transistors and 3 connectors.

Main components

11

README

README.md

Retro computer board!

image

A retro computer motherboard for the W65C816S CPU. Dual-core expandable, 16mb extended memory, four expansion ports.

WHY did I make this??

I have always loved building things with my hands, especially electronics things. I also love computers, and always to learn how they work. I believe that this is part of that hobby, building myself a computer system to play around with. I want to develop software, as well as expandable hardware. My end goal is to write a complete opertaing system for this build, and have it run DOOM!

Basic Specifications

The primary core is a W65C816S microcontroller, with 32kb of SRAM. EEPROM Space is only accessible to the primary controller. Each core has its own cache, or SRAM chip. Located in the upper-half of the first page, each is 32kb. If the primary controller wants to access EEPROM, I.E. to copy data to another portion of memory, it only needs to access the lower-half. If the primary wants to access the secondary core cache, it uses the expanded memory space. There are two types of busses: core-only and global. The global bus is arbitrated between the two cores. The primary gets priority, then the secondary. In order for the first to access secondary, it must first disable the secondary core. This allows it to always be able to write. The primary core must not access the secondary core too often, as it must be disabled beforehand. If the secondary core needs to access the main bus, it queues to wait before the primary CPU does an internal cycle. At that moment it will take whatever is in the queue registers. This means that the secondary must not access the main memory too often. The secondary cache is only exposed to the global bus if the primary is using it for a transfer.

The system is powerful enough to run a basic operating system, and provides options to expand into a workable computer system.

Advanced

The system uses two cores, the W65C816S core. It is not a drop-in replacement for the W65C02S, and samples data during the falling edge of the PHI2. Each core starts in a 6502-emulation mode, and then transitions to the native '816 mode. Each core can access up to 16MB of memory and has 16-bit internal registers. The primary core contains 32kb of EEPROM space as well as 32kb of SRAM space. The secondary core is disabled at runtime, and must be re-enabled later. The low 65kb of the memory (2^16 bytes worth) are used to communicate and run simple programs. The 32kb space acts as a sort of cache system for each core, and they can communicate largely based on the upper shared memory. Beyond the low 65kb there are devices and expansion memory. The secondary core is unable to reach the primary core, though the primary core can access the secondary core by an expansion device. The first devices after the local memory are the expansion devices. Not only are the expansion ports physically on the board mapped here, but so is the control register for the secondary core, as well as the built-in serial port controller.

While the primary core is not actively using the global/shared memory, the secondary core is free to do so. To upload a program or start a second process, the secondary core must first be disabled and reset. Then, the cache is accessed and the program is copied. The reset vector will point to some location in the cache, and it will be re-enabled. Do not set the reset vector elsewhere. As stated previously, when the secondary core needs to access shared memory, whether that be an expansion device or general memory, it latches the address. If reading, it sets a control bit and waits for a NMIB. If writing, it sets the control but the other way and latches the write data. When the write is completed, I.E. once the primary is not active, a NMIB signal is sent signaling that the memory transaction was completed. The WAI (wait for interrupt) can be used. The system is based off an expanion-type model, where it encourages expansion devices to be built and used. Some examples could be a VGA card, sound card, or a keyboard/mouse system.

image

Primary core operation

The core is initiated during a power-on reset phase. The secondary core is disabled during this time, and no secondary transactions are happening. The primary will disable the built-in serial port built in directly to the secondary, and can work without using the secondary core at all. It can use the global bus like the internal core bus.

Secondary core operation

There are two bits that control the secondary core: ENABLE (0) and RESET (1). The ENABLE bit is used to turn the core on or of. It uses the RDY pin to do this. Enabling this also allows the queue to begin transferring data. The IRQB pin is used for the serial adapter, and the NMIB is used when an external read request has been completed. The RESET pin is used to control the RESB pin on the secondary, to reset it to a known state. It is recommended to disable the core using the ENABLE bit before changing data on the secondary cache. When the primary CPU goes into an internal cycle, it takes whatever value is in the address latches and will attempt a memory transaction. The only accessible area for the secondary is the expansion planes and the expanded memory lanes. The RWB bit will control whether it is reading or writing. Since this all takes a single cycle, timing does not matter. The secondary should not attempt frequent external writes due to speed limitations. The secondary only has access to up to half the expandable memory space, as the last bit is used internally for deciding whether it is reading the MMU register. A NMI also happens after a write, to tell the core that the write succeeded before overwriting the register again.

Built-in serial adapter

The built-in serial adapter is wired directly to the secondary core IRQB pin. If it should be disabled, it can be done so by accessing the internal registers. It uses the R6551 chip. Does not include RS232. When reading data from the serial port, it must use the R6551 as an expansion device, located in the external memory lane. This is so that it can be externally controlled by the primary core. Attempt to read by accessing the global data bus, and wait for an interrupt on the NMIB pin. WAI can be used. The same goes for sending data. The secondary should rely in the WAI instruction to manage external reads and writes, but could also be triggered by an IRQB signal from the serial adapter. Internal control should be programmed to prevent this. NMI has priority, after that an IRQB will be sent. The flow should be as follows: first an IRQB signal is sent, then an attempt to read the device will be followed by a NMIB signal. When a NMIB is sent during the IRQB routine, it will cause a nested interrupt to occur, allowing it to service properly. image

Timing Control

Timing control is critical for this system. When PHI2 (the clock) goes from high to low, it indicated the start of a new cycle. VDA/VPA pins change about half-way during the PHI2 low period, and indicate whether the CPU is undergoing an internal cycle. Write and read cycles are all sampled on the falling edge. When VDA/VPA update shortly after the falling edge, the primary core is disconnected from the global bus, and it prepares to do a transaction by updating the address that was latched before. write data is also placed onto the data bus if necessary. On the next falling edge, data is written or data is read. If read, it then sends a NMI to tell the core that it read the data. From there it will read the data back from a specific register. When using it to read, it does not exactly read directly from the memory devices. Instead, it reads from a memory management unit that waits for the primary core to open. The secondary can read the MMU register, located in the upper half of the expandable memory space (bit 23). In order to disconnect the primary, BE is set high, disconnecting the data and address busses. Afterwards, the latches are turned on. Immediately after the bank address is pushed to the data bus, all read data begins to enter through either the cache space or the shared memory space. RDY is toggled by the control of the first bit in the control register, and is only sampled and updated on the following falling edge of the PHI2.

Examples

If the primary wants to upload something to the secondary, I.E. change the task, it will first disable the core and push it into a reset. This prevent erroneous memory accesses. Then, with the cache mapped as an expansion memory device, begins accessing. The primary is blocked from accessing the secondary cache if the core is active. The only way for the two to communicate is through the shared global memory tables. After it is completed, re-enable the secondary.

Expansion Ports

The machine contains four expansion ports, wired directly to the primary. Two of the slots are larger, and each one of the two is either wired to IRQB or NMIB. The other two are simply expansion devices. The larger ones have A0-A3, and the smaller ones have A0-A1 as register addresses. The shared memory on the global bus is beyond the 65K from the two cores. The controller for the secondary, the controller for the serial port, and just about everything else is connected in through the expansion device encoder to save on space.

Physical Board Explaination

Primary Core

The primary core uses the W65C816S, with a 24-bit address bus and an 8-bit data bus. The highest byte of the address bus (A16-A23) is pushed onto the data bus during the low phase of PHI2, and is latched at the rising edge of the clock. The address bus comes stable around the same time. During these times, all the chips may stabilize into selecting the correct hardware for the write. Each core has a 74HC373 and a 74HC245 to moderate the data bus and the banked address busses. The BE pin will set the data bus, address bus and RWB pins to high-Z. The banked address byte is fed into a chip that detects if it is anything >0x00. This means that an external cycle is being attempted. If not, the selection uses A15 to select from either RAM or ROM to read/write from. In an external cycle, the primary is shut off from the rest of the device. During an external cycle, the full address is passed to the global address bus, and the data is either passed through from the data bus directly or read in through an octal buffer. The RWB pin is multiplexed along with the secondary. The expansion slots are wired directly into the primary core NMIB/IRQB pins, and are pulled high on the board.

Secondary Core

The secondary core has much the same setup as the primary core, but has some key differences. It can work independently of the primary through its own cache, but lacks an EEPROM space. In order to perform an external read/write, when it detects an external memory transaction it always writes to a large set of registers. These registers latch A0-A22, as well as whether it wants to read or write. It may not be necessary for it to use the full 16MB address space. The secondary cache lies outside of the range that the secondary can reach. When it is latched, it also sets a D-flipflop into a HIGH state. The state of the first flip-flop is transferred over to the external memory device selector, which can choose which device to enable. It is only active during either an external cycle made by the primary or the secondary waiting to write/read data. Now that the devices have a stable address, when an external cycle happens, it sets the second flip-flop into a HIGH state. This will immediately reset both back to LOW, but sends a NMI to the secondary processor. During an external cycle, the secondary processor latches are always pushed out to the global bus, as well as any data. If no core is desiring to read from the global data bus, then it may go floating. If the secondary desired to write previously, that old data would be pushed, otherwise nothing holds on to the data bus. Therefore the global data bus is always pulled LOW. A15 is always pulled LOW, and in order to read data coming from the global busses, any address from 0x0000-0x7FFF will work. It simply takes the place of the EEPROM space. On the secondary the cache is in the upper half rather than lower. The secondary processor has two control bits, ENABLE and RESET. ENABLE will control the processor state, pausing it and disabling the address/data busses. The RESET bit will cause it to reset back to a known state. The secondary processor will have all of its data and address busses disabled during this time. The cache can be accessed by the primary core processor during this time, while it is disabled. It cannot access while running. While the address and data busses are in a High-Z state, the cache can be selected as an expansion device, and the address/data/RWB for the primary processor are pushed in. The secondary local data bus are always pulled LOW. The secondary address bus is always matches the primary address bus while not enabled, as a way to drive it.

Serial adapter

As mentioned earlier, the serial adapter is wired directly to the secondary core, and works as any other expansion device would. The secondary should either disable the adapter or mask interrupts if it were to be doing something other than serial work.

Memory selector

The memory selector works entirely off the global address busses for selection, choosing serial devices or memory expansion cards. Devices are only selected if either there is an external cycle or the secondary is waiting to write data.

Datasheets

https://www.westerndesigncenter.com/wdc/documentation/w65c816s.pdf

BOM

ItemQuantityPrice (USD)
JLCPCB 180x140mm5$25.15
10K Resistor10$1.85
SN74HC373N Latch10$9.77
W65C816S6PG-14 MPU2$24.20
L78L33 Regulator5$1.40
10uF Capacitor5$1.15
LED (Red)10$2.60
SN74HC04N Inverter5$6.55
SN74HC21N Gate4$2.60
Tactile Switch5$1.50
SN74HC245N Transceiver10$6.22
AT28C256 EEPROM1$11.62
150Ω Resistor4$1.44
AS6C62256 SRAM2$9.50
1MΩ Resistor4$1.44
SN74HC138N Decoder5$5.50
1N914 Diode5$0.50
SN74HC10N Gate4$2.52
10kΩ Resistor20$0.30
1kΩ Resistor10$0.27
SN74HC32N Gate4$2.20
SN74HC688N Comparator6$8.52
4.7kΩ Resistor10$0.47
SN74HC126N Buffer4$2.64
SN74HC00N Gate5$3.00
2N3904 Transistor10$0.77
30pF Capacitor10$1.18
0.1uF Capacitor100$4.00
1MHz Oscillator2$6.90
SN74HC08N Gate4$2.40
SN74HC74N Flip Flop4$3.60
20-pin Socket24$3.10
16-pin Socket20$2.42
14-pin Socket20$2.20
28-pin Socket6$3.84
40-pin Socket4$3.68

Total: $167.00

Parts

67
QtyValueFootprintReferences
25C_SmallCapacitor_THT:C_Disc_D3.0mm_W2.0mm_P2.50mmC1, C2, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19, C20, C21, C22, C23 +9
674HC688Package_DIP:DIP-20_W7.62mm_SocketU7, U8, U11, U12, U15, U16
574HC373Package_DIP:DIP-20_W7.62mm_SocketU9, U18, U19, U20, U23
474LS157Package_DIP:DIP-16_W7.62mm_SocketU10, U13, U14, U17
31.2kResistor_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P5.08mm_HorizontalR5, R7, R10
3800Resistor_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P5.08mm_HorizontalR4, R6, R8
3FDV301NPackage_TO_SOT_SMD:SOT-23-3Q1, Q2, Q3
21kResistor_THT:R_Axial_DIN0204_L3.6mm_D1.6mm_P5.08mm_HorizontalR1, R9
274HC4040Package_DIP:DIP-16_W7.62mm_SocketU1, U4
274HC74Package_DIP:DIP-14_W7.62mm_SocketU2, U24
125.1750mhzOscillator:Oscillator_DIP-8Y2
174HC00Package_DIP:DIP-14_W7.62mm_SocketU25
174HC14Package_DIP:DIP-14_W7.62mm_SocketU3
174HC238Package_DIP:DIP-16_W7.62mm_SocketU6
174LS151Package_DIP:DIP-16_W7.62mm_SocketU22
174LS20Package_DIP:DIP-14_W7.62mm_SocketU21
1Conn_01x03Connector_PinSocket_2.54mm:PinSocket_1x03_P2.54mm_VerticalJ2
1Conn_02x10_Counter_ClockwiseEdgeConn:AliExpress_20EdgeJ1
1DB15_Female_HighDensityConnector_Dsub:DSUB-15-HD_Socket_Horizontal_P2.29x1.90mm_EdgePinOffset3.03mm_Housed_MountingHolesOffset4.94mmJ6
1IS6xC1024AL-xxTPackage_SO:TSOP-I-32_18.4x8mm_P0.5mmU5
1LEDLED_THT:LED_D3.0mmD1
1LOGOLOGOG***

More from snippyrow/-816-board

2
  • 2 layers182 × 138.8 mm-816-board, the printed circuit board in 3D

    -816-board

    snippyrow/-816-board

    A retro computer motherboard for the W65C816S CPU. Dual-core expandable, 16mb extended memory, four expansion ports.

    141 partsMIT
  • 2 layers77.8 × 72.2 mmRAM SCH, the printed circuit board in 3D

    RAM SCH

    snippyrow/-816-board

    A retro computer motherboard for the W65C816S CPU. Dual-core expandable, 16mb extended memory, four expansion ports.

    17 partsMIT

Similar boards

  • 2 layers177.8 × 130.8 mmDurango, the printed circuit board in 3D

    Durango

    zuiko21/minimOS

    Scalable OS for 6502/65816

    159 parts23MIT
  • 2 layers208 × 110 mm8 16 computer 2, the printed circuit board in 3D

    8 16 computer 2

    halfburnttoast/TCPU816-v1

    Version 1.1 of my 8-bit, TTL computer.

    120 parts21
  • 4 layers100 × 100 mm74HCT6526, the printed circuit board in 3D

    74HCT6526

    dmolinagarcia/74HCT6526

    74HCT6526

    80 parts14
  • 2 layers295 × 195 mmTB04addr8bit copy, the printed circuit board in 3D

    TB04addr8bit copy

    Myuu1967/TB-04

    4bitCPU(TB-04)に関するリポジトリです

    307 parts
  • 2 layers232.8 × 204.2 mmTIM-011B, the printed circuit board in 3D

    TIM-011B

    Board-Folk/TIM011B

    TIM-011 B Replica Board

    162 parts8
  • 2 layers364 × 203 mmCPU6S, the printed circuit board in 3D

    CPU6S

    Meisaka/CenMiniCom

    Centurion Minicomputer Schematics

    240 parts8
  • 2 layers486 × 306.3 mmMonacoGP, the printed circuit board in 3D

    MonacoGP

    stonedDiscord/MonacoGP

    Sega MonacoGP TTL Boards

    257 parts1
  • 2 layers630 × 300 mmSecretBase, the printed circuit board in 3D

    SecretBase

    stonedDiscord/SecretBase

    SEGA Secret Base Arcade Game

    441 parts

Questions

How big is the GPU SCH PCB?

It measures 137.2 × 88.8 mm and has 2 copper layers, 1.6 mm thick.

What parts does the GPU SCH use?

67 parts, built around the 74HC688D, 74HC373D, 74LS157PC and 74HC4040D. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the GPU SCH KiCad files?

From the snippyrow/-816-board repository on GitHub, at the commit this page was made from: the board is EXP/GPU_SCH/main.kicad_pcb and its schematic EXP/GPU_SCH/main.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the GPU SCH design in my own project?

Its repository publishes it under the MIT licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).