r/homebrewcomputer

How do op-codes translate into logic gates

So after taking a digital design class (which I really enjoyed) I couldn't understand one thing that was part of a lab I had. How do op-codes translate into logic gates? For example how can the op-code 0001 define a full adder, and the op-code 0010 'AND' two of the inputs.

reddit.com
u/mvmpc — 23 hours ago
▲ 85 r/homebrewcomputer+2 crossposts

I built an 8‑bit CPU, assembler, and emulator – now I need collaborators to finish the C compiler backend and make a usable computer

I’m a 17‑year‑old solo developer, and I’ve spent the last while designing and building a complete custom 8‑bit CPU architecture. The CPU has a 24‑bit address bus, a flat memory model, and a custom instruction set. It’s all implemented in a cycle‑accurate emulator written in C. I also have an assembler and a 40×24 text screen device (ASCII framebuffer, no terminal emulation), all working.

I’ve just pushed everything to GitLab as three separate repositories:

Planned interrupt system
The CPU will support both internal and external interrupts. An internal interrupt instruction saves all ALU flags, register state, and a return address onto the stack, then jumps to an address held in dedicated address registers. return from interrupt restores everything and returns. External interrupts (e.g., from a keyboard) use input ports 0‑2 for the interrupt vector address and port 3 for data input. The hardware side still needs to be implemented in the emulator, but the specification is firm.

What I need help with
My goal is to turn this into a usable computer, and for that I need a C compiler. I’ve been writing a backend for the Fuzix Compiler Kit (FCC), targeting my CPU. It’s close — arithmetic, control flow, inline assembly, and variable storage all work. I’m currently implementing function calls. After that, there’s global variables, structs, and maybe floating point to do.

The problem: I’m exhausted working alone, and the compiler backend is the last big mountain. I’m looking for people who’d like to collaborate on this project with me.

How you could help (any of these):

  • Help finish the FCC backend (function calls, global variables, structs). The backend code isn’t public yet, but I can share it privately with serious collaborators.
  • Write a small ROM monitor or bootloader in assembly.
  • Add a keyboard input device to the emulator (that triggers those external interrupts).
  • Implement the interrupt hardware in the emulator (spec ready).
  • Test the toolchain (assembler, emulator, compiler) as features come online.
  • Just bounce ideas around — I’ve been working in a bubble and would love to talk shop.

If you’re into custom CPUs, retargetable compilers, or 8‑bit systems in general, I think you’ll find this a really fun challenge.

Comment here or DM me if you’re interested. Links to the repos are above. Thanks for reading!

u/DavidMik_ — 5 days ago

Theory discussion needed for specific CPU design areas

There are a couple of areas I don't quite understand about general CPU design.


How do comparisons work? I get it that they involve the msb and the carry-out, and involve subtraction. I know I could cheat with a ROM if I had to, if I don't understand it by the time I start. I know you can detect 0 by subtracting from 0 and then watching for the carry. That makes sense in that if B is 0, then you'd invert all the bits to give all ones. Since you'd have to add 1 for proper negation, you'd set the carry-in. In return, it rolls over, sets the carry-out, and you know it is 0.

On the Gigatron, comparisons are stateless. There are no flip-flops for that (which proves to be a serious bottleneck for multi-byte math). The comparison results only go back to the control unit to branch during the same cycle. And, if I remember right, x86 is mostly 2-stage. I mean, do a CMP to set the flags and then the conditional based on the flags.

If one is using a ROM to do comparisons, then one might want to go with the x86 model. Compare first and branch in the next cycle.


And then there's the Control Unit. I don't know how to make those do what I want with logic and without creating a long critical path.

For instance, I'd like an instruction that takes the outer program counter (like the vPC on the Gigatron designed as an actual register), uses that on the Harvard RAM bus to address the RAM, and use the instructions stored there to address the ROM (via the inner/native program counter). Like do a direct jump << 4 to have up to 16 inline instructions per virtual opcode. That way, all 256 opcode slots are available (without sacrificing any for page|offset addressing). They'd all be 16-byte paragraph aligned.

That would likely insert a mux or tristate buffer already to choose between Y:X and vPC. However, I might want to add another since I'd like to add interrupts to a tailcall mechanism. A tailcall mechanism is more efficient in that you can jump to the next handler rather than a central handler. But that makes it harder to add interrupts. If you used a central handler, you could use that for polling for IRQs, but a tailcall mechanism needs an escape mechanism.

The native instruction to end a public instruction could look like this:

IN = 0 ? PC = [Instruction_Yh,vPC++,0000] : PC = [Interrupt_Yh,IN,0000]

That would probably need more muxing to make this 2-headed conditional jump. Using position-dependent ROM code would eliminate the need for a priority encoder and allow interrupt chaining under certain conditions.


What is an ideal way to interface with a video controller? I have a bit of analysis paralysis here. There are many ways to do it. Here are some examples:

1. Bus-mastering or first-party DMA. That requires stopping the CPU during scanlines if the framebuffer is in the main RAM.

2. Memory-mapped. You can reserve part of a page for video transfer and control registers (whether you write to local RAM as a part of it or not). You could have decoder circuitry and maybe a FIFO. Or you could trigger DMA, wait-stating, or a halt if transfer attempts happen during a scanline. The VERA board uses memory mapping, and you can even use that board in a homebrew design.

3. Naive video controller. You can have separate video memory with the video counters accessing it. Then you can include a mux and a register. That will cause artifacts. You could diminish that by shadowing the RAM so that read-backs cause no side-effects (but writes would).

4. Alternating banks. If your CPU is at the video speed, you could separate an 8-bit design into 2 banks and add registers for when things are out of alignment (and a halt or clock-stretching mechanism in case sustained non-matching patterns occur).

5. A microcontroller or FPGA that combines bus snooping with memory mapping. So the MCU or board logic monitors for addresses in the MCU's range, and it transfers things to the frame buffer that could be memory in the MCU or FPGA. This may be a good solution since modern MCUs tend to provide means for multiple devices to use the same RAM. A Propeller 2 has 8 cogs with interleaved RAM. A Raspberry Pi Pico has 2 cores, along with automated PIO and DMA modes that can access the internal memory faster than the cores can.

reddit.com
u/Girl_Alien — 8 days ago

My Homebrew Z80 Computer on a Protoboard. DinoRun Let's Play

Hiii everyone!

I have made a little PC on Zilog80 on protoboard.

Display is SSD1306 with I2C interface.

ROM is emulated via Arduino Nano (1KB).

RAM is just random 8KB SRAM

Main task in this project is make software based driver

for I2C display via "bit banging", works slowly but

works, it also depends on time which Nano response and CLK freq. (1.35MHz).

I wrote a firmware in Assembly and it takes 325 bytes.

as 17 y.o. teen I am very excited with the result, maybe in future I'll improve my little project

Next I plan to add more switches and port DOOM and make Shadow RAM and dynamic Clock (bcs nano is too slow for Z80)

Have a good day and no hate plsss :)

If someone wanna see it in better quality see

https://youtu.be/rzCK3ROISEs. I don't now but I can't upload

in 720p on Reddit, I got a some errors

u/datapeice — 12 days ago