HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
floooh
chips
C2017–2026
floooh / chips

chips

8-bit chip and system emulators in standalone C headers

6Distinct people
19Mentions
0Explicit recommenders
1.3KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

8-bit chip and system emulators in standalone C headers

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:03:16 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year19 dated mentions

Observed mentions: 2017-12-30 11:51:45 UTC to 2026-10-17 18:44:31 UTC.

012342017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments20172018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments20212022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC101
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC303
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC101
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC303
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC101
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC101
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC202
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC404
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC101
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC202

What Hacker News says

19 sources
The README mentions floooh's implementation which is a bit more simplified, there is no complete netlist so the smaller TTL glue chips will not be considered. It does work in real time though. The common interface between emulated ICs is a 64-bit integer that maps logic levels of interest at a given simulation step to its individual bits: - https://github.com/floooh/chips/blob/master/README.md - https://github.com/floooh/chips/blob/9e88298ce56319953ac7a43... - https://floooh.github.io/tiny8bit/player.html?id=c64&dbg=1 (use the "Hardware" menu to get activity views similar to Salvatore's emulator)
In The Commodore 64 hardware simulator: break chips and pins, see the results
The actual emulator code lives here (all in STB-style headers): https://github.com/floooh/chips The chips-test repo has the 'integration' code which assembles the headers into executables: https://github.com/floooh/chips-test There's also a similar project in Zig (but less complete, it's more like an experiment what the same implementation ideas would look like in Zig) that might be a bit more readable and with everything in one place: https://github.com/floooh/chipz E.g. start reading the top-level emulator executables: https://github.com/floooh/chipz/tree/main/emus ...and then move your way down to the system implementations: https://github.com/floooh/chipz/tree/main/src/systems ...and finally to the chip emulators: https://github.com/floooh/chipz/tree/main/src/chips
In Tiny Emulators
Have you seen https://github.com/floooh/chips A bunch of PIO linked chips using these interfaces would feel like a weird blend of software and hardware that stands separately to the FPGA world. I have wondered if it would actually work as a larger scale paradigm. Imagine a single piece of silicon with a bunch of RP2xxxx level processor/ram blocks with PIO links between them all. I'm not sure how it would come out compared to FPGAs for balance of flexibility/cost/power consumption/etc. but I suspect it could find a niche. antirez mentioned running some of these on RP2040's
In Atari Means Business with the Mega ST
Because it's a Verilog implementation which is much closer to a software CPU emulator than the real thing (e.g. it has nothing to do with the original Z80 "transistor layout"). For instance here's the LD A,(DE) "instruction payload": https://github.com/rejunity/z80-open-silicon/blob/974c7711b2... And here's the same machine cycle in my software emulator: https://github.com/floooh/chips/blob/bd1ecff58337574bb46eba5... Both set the address bus to the content of the DE register (and at the same time the MREQ|RD pins need to be set somewhere to indicate a memory read to the outside world, in my emulator this happens in the _mread macro), and in the next clock cycle load the data bus into the A register. What's interesting though is that the Verilog implementation doesn't seem to update the internal WZ register with DE+1, which makes me wonder
Read the rest
if undocumented behaviour is correctly implemented, but maybe updating WZ is handled elsewhere (there are references to the WZ register in other places). In the end, if it looks and feels like a Z80 from the outside (e.g. the right pins are active at the right time) the internal implementation doesn't matter.
In Zilog Z80 CPU – Modern, free and open source silicon clone
Author here, interesting to see this posted since it's more like a reference manual for Z80 instructions with 'unusual' timings, mostly useful for emulator coders. The followup blog post about the cycle-stepped Z80 emulator is probably more interesting: https://floooh.github.io/2021/12/17/cycle-stepped-z80.html One important note: at the start of the post I'm speculating about why I was seeing some minor differences to a 'real' Z80, it turned out that this speculation was wrong and instead the differences were caused by 'incomplete' netlist simulation code which worked fine for the 6502 but required some tweaks for the Z80, see the comments of this GH issue for details: https://github.com/floooh/v6502r/issues/2. As far as I'm aware the netlist simulation now behaves correctly like a Zilog Z80 (but note that some reverse engineered Z80 clo
Read the rest
nes like the East German U880 are known to have slightly different undocumented behaviour - which barely matters in practice though). The Z80 and 6502 emulators in https://github.com/floooh/chips are tested against their respective netlist simulations for correct behaviour and timing (all being based on the netlists from http://www.visual6502.org/ and the simulation code from https://github.com/mist64/perfect6502 - which is the simulation from visual6502.org ported from JS to C).
In Getting into way too much detail with the Z80 netlist simulation (2021)
This is the sort of thing where Dear ImGui is simply perfect :) I also used it for the debugging UI in my emulators (https://floooh.github.io/tiny8bit/) - here's an example screenshot with the debug UI open (and the emulator integrated into a VSCode tab): https://floooh.github.io/images/vscode-wasm-wasi-3.webp There are a lot of advantages when you can tightly couple the UI with the guts of the emulator (e.g. everything in the UI automatically shows the current emulator state at full display refresh rate without having to worry about UI update and rendering performance or doing complicated "data binding", just point the UI to the memory locations of the "live data", and everything updates automatically). PS: the Spectrum Analyzer is actually using emulators from that same 'chips project' (https://github.com/floooh/chips). Props for the sh
Read the rest
outout :) Here in the "sister project" there are some re-used windows from my debugger ui visible (https://colourclash.co.uk/cpc-analyser/), which I think is very cool because it shows how existing Dear ImGui code can be used as UI components (for instance I also re-used the hex editor from here: https://github.com/ocornut/imgui_club/tree/main/imgui_memory...)
In Spectrum Analyser, a Sinclair ZX Spectrum reverse engineering tool
If the emulator is entirely cycle correct for the entire system (including the video system, which is usually the most expensive to emulate, not the CPU), then the speedup on modern computers will be much less than just comparing the clock frequencies. Consider that each chip of a home computer system (CPU, 1..2 IO/timer chips, audio, video, ...) needs to do 'emulation work' for each 1 or 2 MHz clock cycle which can add up to quite a number of host computer instructions (dozens to hundreds). If each chip emulator just takes around 10..20 host system clock cycles to emulate one emulator clock cycle, then you are already looking at around 100 host system clock cycles per emulated clock cycle for the entire home computer (in reality it's probably worse). Such 'vertically sliced' emulation code is also full of conditional branches which put a
Read the rest
heavy burden on the host CPU branch predictor. ...and that's how a theoretical 1000x speedup suddenly becomes a 10x speedup, it's not the CPU emulation (this is usually cheap) but the rest of the emulated system which can be expensive. Different emulators use all sorts of tricks and shortcuts, but usually with tradeoffs like less precise emulation, or less 'compartmentalized' code. PS: case in point this is just the top-level per-cycle function in my C64 emulator, which in turn calls per-cycle-functions in each of the chip emulators (which may each be just as much code): https://github.com/floooh/chips/blob/9a7f6d659b5d1bbf72bc8d0... I'm trying to strike a balance between 'purity' (e.g. an entire emulated system can be 'plugged together' by wiring together chip emulators, just like one would build a real 8-bit computer on a breadboard), while still being fast enough to comfortably run in realtime even in browsers (https://floooh.github.io/tiny8bit/c64.html). It's definitely possible to implement a faster cycle-correct C64 emulator with a less 'pure' architecture, but it's quite hard to do meaningful optimizations while keeping that same 'virtual breadboard' architecture. ...considering all the code that runs per cycle it's actually amazing how fast modern CPUs are :)
In BBC BASIC raytracer in 432 characters
I simply don't see that there's a big enough difference between traditional garbage collection, refcounting and manual memory management. Each of those can already be implemented in pure WASM (without the new GC support), just more or less awkwardly. As for "just another ISA", there have been CPUs which had separate call- and data-stacks, with the call-stack living on the CPU and not directly accessible to code. In that sense WASM isn't much different then those esoteric CPUs, yet those also implemented "just another ISA". And even though WASM might not allow free control flow, I yet have to see a noticeable performance difference between WASM and native for this type of "worst case code": https://github.com/floooh/chips/blob/f5b6684ff6e899429544b21...
In A world to win: WebAssembly for the rest of us
Oh my, the 6502 emulation [1] has fewer lines of assembly code than my (code-generated) implementation has lines of C code [2] :D Very nice use of a macro assembler though [3], makes the code feel very high level. To my defense, my generated code has a lot of redundancies (such as assert(false) which were meant to catch any 'stray cycles' but which are removed in release mode - and it could be more compact if it would use preprocessor macros (but since the code is generated anyway that seemed kinda wrong). [1] https://github.com/zajo/appler/blob/develop/src/65C02.ASM [2] https://github.com/floooh/chips/blob/master/chips/m6502.h [3] https://github.com/zajo/appler/blob/52aaa0f768cdf303438cd2c7...
In Appler: Apple ][ emulator for IBM PC, written in 8088 assembly
I'm using a code generation approach both for 6502 and Z80, not as extreme and elegant as demonstrated here though. Instead of a pure data description I have python scripts which generate C source code. The 6502 is perfect for code generation because instructions are very uniform, and the "interesting" part of instructions are the addressing modes which always run the same sequence of operations in front of the actual instruction-specific "payload". The Z80 instruction set has many more special cases, but it can be decoded "algorithmically" as well, see here: http://www.z80.info/decoding.htm My Z80 emulator basically implements this "recipe" in python, and generates a huge "unrolled" switch-case statement with one case-branch per instruction (ok not quite, the CB prefix instruction range is still decoded algorithmically to reduce the resu
Read the rest
lting binary code size a bit). Complex instruction logic like DAA are still essentially hand-written C functions though, the code generation mainly helps with the "mundane" parts of an instruction, like opcode fetch, and regular memory load/store machine cycles. One nice side effect of using code generation is that it is very easy to create variations of the emulator. For instance I created a cycle-stepped version of my 6502 emulator (versus the previous instruction-stepped version) with surprisingly few changes to the code-generation script. PS: the whole stuff is here: https://github.com/floooh/chips PPS: an interesting approach (which I haven't tried) for 6502 emulation would be to use the 6502's decode ROM (aka PLA) as the "base-data" for code generation.
In Code generating a WebAssembly 6502 emulator from specifications
One idea I had in my own modular emulators a while ago was to reduce the "state that's passed around" to the input/output pins of the microchip emulators the higher level system emulator is built from. This pin-state often fits into a single 64-bit integer (at least for typical 8-bit home computers), and another advantage is that the emulator's code structure can be kept very close to the schematics of the real hardware (the wiring between chips can be mapped 1:1 to bits in 64-bit integers). The emulators are written in C, not Rust, but I bet this approach would also work perfectly with Rust's borrow checker (since there's no shared state in memory the borrow checker shouldn't even "activate"). An emulator is essentially built from functions which take a 64-bit integer as input, and return another 64-bit integer. https://github.com/floooh
Read the rest
In RustBoyAdvance-NG: GameBoy Advance emulator and debugger, written in rust
I think I'm seeing this in C code too with clang. I'm having fairly big code-generated switch-case statements in my CPU emulators with hundreds to thousands of case-blocks (Z80: [1], 6502: [2]), and those take up to 7 seconds to compile with -O3, which is really unusually long for a single C compilation unit of that size (compared to the same number of lines across many smaller functions). If the problem has exponential behaviour it could easily blow up to minutes or hours for larger functions. [1] https://github.com/floooh/chips/blob/d0f690f2598f967f75cb360... [2] https://github.com/floooh/chips/blob/d0f690f2598f967f75cb360...
In How refactoring a macro reduced my Rust project build time from 4 hours to 40sec
Thanks -- we use Emscripten/WASM mainly for running command-line compilers/assemblers (like cc65 and SDCC). Right now the emulators are all in JavaScript (except for MAME) which makes integrating with the IDE's debugging tools a little easier. It's performant enough for now, since we only have 8-bit platforms at low clock speeds. Integrating a C emulation library like https://github.com/floooh/chips should be doable, since it doesn't have any dependencies.
In WebAssembly becomes a W3C Recommendation

Showing the 15 most recent of 19 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.