Overzicht
c64-hw-sim is een gespecialiseerde simulator die het moederbord van de Commodore 64 (ASSY 250407) op pin-niveau nabootst. In tegenstelling tot een standaard emulator, simuleert dit programma de elektrische verbindingen (netlist) en het gedrag van individuele chips, waardoor gebruikers hardwarematige defecten kunnen reproduceren door pinnen kort te sluiten of componenten te verwijderen.
Belangrijkste Doelen
- Educatie: Het biedt een veilige manier om te leren hoe de hardware van de C64 op intiem niveau werkt zonder risico op fysieke schade.
- Hardware Diagnose: Het stelt gebruikers in staat om hypothesen over defecte componenten in echte hardware te testen, wat helpt bij het bepalen van de meest logische volgorde van reparaties.
Functionaliteiten en Interactie
De simulator beschikt over een visuele interface met een weergave van het bord, een monitor en een oscilloscoop. Gebruikers kunnen:
- Pinnen manipuleren: Pinnen kunnen 'floating' worden gemaakt of kortgesloten naar GND of +5V.
- Chips verwijderen: Chips kunnen uit hun sockets worden getrokken om het effect op het systeem te observeren.
- Componenten openbreken: Weerstanden en kristallen kunnen worden gesimuleerd als defect.
Technische Specificaties
- Basis: Gebaseerd op chip-cores van floooh en een KiCad-replica van het moederbord.
- Prestaties: De simulatie is rekenintensief en draait op ongeveer 30% tot 50% van de echte snelheid, afhankelijk van de hardware (bijv. Apple M-serie of AMD Ryzen), waardoor het ongeschikt is als game-emulator.
- Compatibiliteit: Draait op macOS en Linux (X11) via OpenGL.
c64-hw-sim: Commodore 64 Hardware Simulator
Het programma kent de netlist van het bord (de elektrische verbindingen op de PCB) en hoe elke chip zich gedraagt op zijn pinnen. Het programma heeft geen voorkennis over hoe een defecte Commodore 64 eruitziet; wanneer een defect onderdeel wordt gesimuleerd en het scherm zich vult met willekeurige data ('garbage'), is die data berekend vanuit het circuit en niet gekozen door iemand die wist wat het resultaat zou zijn.
Voorbeeld
Til pin 17 (A7) van de color RAM op voordat de stroom wordt ingeschakeld; de machine start op en ziet er gezond uit. De CPU schrijft en de VIC leest met hetzelfde onjuiste adres, waardoor de RAM simpelweg 'aliast'. Plaats de poot terug, en het deel van de color RAM dat nooit is beschreven, verschijnt als willekeurige kleuren. Til de poot opnieuw op, en het scherm is weer schoon. Een echte 2114-chip vertoont hetzelfde gedrag.
Doel van het programma
Met dit programma kunnen hoofdzakelijk twee dingen worden gedaan:
- Leren hoe de Commodore 64 werkt op een intiem niveau, op een manier die moeilijk te reproduceren is op echte hardware zonder het risico deze te beschadigen (zeker omdat op de meeste borden veel chips gesoldeerd zijn in plaats van in sockets geplaatst).
- Diagnose van defecte hardware. Als u een defecte C64 heeft en een hypothese over wat er kapot zou kunnen zijn, kunt u dit simuleren. Dit kan aanwijzingen opleveren zodat chips in de meest logische volgorde kunnen worden lossolderd, waardoor er zo min mogelijk componenten verwijderd hoeven te worden. Een overeenkomstig symptoom is een aanwijzing, geen bewijs: verschillende fouten kunnen hetzelfde effect hebben en de simulatie heeft zijn grenzen.
Prestaties
Houd er rekening mee dat dit programma, zelfs op snelle computers, moeite heeft om de C64-hardware op echte snelheid te simuleren. Een echte C64 wordt gesimuleerd op:
- 31% van de snelheid op een Apple M3 Max.
- 39% op een AMD Ryzen AI Max+ PRO 495 (Gorgon Halo).
- 48% op een Apple M5 Max.
Dit is geen probleem voor de doelen van dit programma, maar let op: het is geen emulator om games mee te spelen.
(Beschrijving bij afbeelding: De klassieke 10 PRINT CHR$(205.5+RND(1));:GOTO 10 maze draait terwijl de character ROM (U5) uit zijn socket wordt getrokken en later weer wordt teruggeplaatst. De CPU, de RAM en het programma blijven werken; alleen de vormen van de karakters gaan verloren. De oscilloscoop staat op datalijn D0 van de ROM-socket: wanneer de socket leeg is, 'float' de bus telkens wanneer de VIC een karaktervorm ophaalt. Getoond op C64-snelheid.)
Erkenningen
Het idee voor dit programma ontstond tijdens het gebruik van de chips van Andre Weissflog (floooh), emulators van de 6502, VIC-II, CIA, SID en anderen die pinnen als interface gebruiken. De volgende stap was om deze aanpak, met zijn code als startpunt, naar het extreme te trekken: pin-level modellen van elk ander onderdeel van de C64, zoals de RAMs, ROMs, logische chips, de PLA, enzovoort.
- De chip-cores zijn van floooh, afkomstig uit
c64-llm (zlib licentie).
- Het bord is gebaseerd op
C64-250407-Replica-KiCad van bwack (CERN OHL).
- De PLA-vergelijkingen komen uit de 82S100 read-out van Mark Smith en Marko Mäkelä.
Bouwen
Om het programma te bouwen en te starten:
make
./c64-hw-sim [program.prg]
Het draait op macOS en Linux (X11) met OpenGL. De grafische bibliotheek (sokol) en de interface-bibliotheek (nuklear) bevinden zich in third_party/.
Gebruik
Het venster toont het bord, de monitor, een controlepaneel en een oscilloscoop.
Componenten op het bord: Chips worden weergegeven als boxen, benoemd naar hun rol:
- RAM1 tot RAM8: De 4164 DRAMs. Elke chip bevat één bit van elke byte (RAMn heeft databit n-1).
- VRAM: De 2114 color RAM.
- BASIC, KERNAL en CHAR: De ROMs.
- PLA: De adresdecoder.
Door in te zoomen kunt u referenties en adresbereiken zien. Pinnen tonen hun status zoals een logische probe dat zou doen:
- Rood: Hoog (High)
- Blauw: Laag (Low)
- Geel: Pulserend
- Grijs: Floating
- Magenta: Wanneer twee outputs met elkaar 'vechten' (contention).
Interactie:
- Pinnen: Klik op een pin om deze op de oscilloscoop te plaatsen en om deze te beschadigen: floating, kortgesloten naar GND, of kortgesloten naar +5V.
- Chips: Klik op een chip om deze uit de socket te trekken.
- Passieve componenten: Klik op een weerstand, een ferrietkraal of het kristal om deze te openbreken.
- Controlepaneel: Hier staan de huidige fouten vermeld, elk met een knop voor reparatie. Het paneel kan ook
.prg bestanden laden. Deze worden direct in de DRAM-chips geschreven, zoals een 'freezer cartridge' dat zou doen, waardoor laden ook op een defect bord werkt.
Besturing:
- Gebruik het toetsenbord zoals gebruikelijk.
ESC: RUN/STOP
PgUp: RESTORE
TAB: CTRL
Linker ALT: C=
Command-line opties
Voorbeeld van een headless run:
./c64-hw-sim --headless 200 --text --shot out.png --fault U17:removed
Dit voert vier seconden (200 frames) uit zonder venster. Het print de tekst die vanaf het monitorscherm wordt gelezen en slaat een afbeelding op.
Foutdefinities (--fault): Een fout wordt geschreven als REF:wat of REF.PIN:wat:
U17:removed
U21.14:gnd
U12.14:vcc
U9.2:open
R51:open
RP4:short
Overige opties:
--at 150:U6.17:open --at 300:repair: Breekt en repareert onderdelen op specifieke tijdstippen terwijl de C64 draait.
--nets: Rapporteert de nets waar outputs met elkaar in conflict kwamen.
C64HW_TYPE=$'PRINT 1+1\n': Typen van tekst na het opstarten.
C64HW_CHECK=1: Controleert elke KERNAL-lezing en elke VIC-fetch tegen de ideale memory map.
--record 900:DIR --frames 90: Slaat het venster 90 keer op, elke 4 emulatieframes vanaf frame 900 (voor grafische modus).
Het script tests/faults.sh voert 31 veelvoorkomende fouten uit. De verwachte symptomen van elk defect werden genoteerd voordat de simulator werd gedraaid.
Werking
Het bestand tools/kicad2c.py zet de KiCad-replica van de 250407 van bwack om in C-tabellen: 216 onderdelen, hun pads en 249 nets.
Signaalbeheer: Elke pin drijft zijn net sterk aan, zwak (een pull-up), via een voedingskortsluiting, of helemaal niet. De sterkste driver wint. Wanneer twee gelijke drivers vechten, is er sprake van 'contention' en wint de lage status.
Een net dat door niemand wordt aangestuurd, behoudt zijn lading en drift vervolgens:
- Na microsconden naar ongeveer 1.4V, indien TTL-inputs het belasten.
- In een fractie van een seconde naar 0V, indien alleen MOS-inputs aanwezig zijn.
MOS-inputs vergelijken deze spanning (inclusief ruis) met hun eigen drempelwaarde, waardoor een floating lijn erratisch kan worden gelezen.
Voedingsfouten: De impact van voedingsfouten is afhankelijk van de chip:
- Een chip zonder VCC is dood.
- Een chip zonder GND laat zijn outputs 'float high'.
- Een CMOS-chip blijft draaien op 'phantom power', die de chip bereikt via de beveiligingsdiodes van de pinnen.
De ruis is 'seeded', zodat een run exact herhaald kan worden.
Modellering: In src/parts.c worden de volgende onderdelen op pin-niveau gemodelleerd:
- De glue logic.
- De ROMs.
- De DRAMs (die de row vergrendelen op
/RAS en de column op /CAS).
- De color RAM.
- De PLA, inclusief de werkelijke logische vergelijkingen.
De 6510, VIC-II, CIAs en SID zijn cycle-accurate cores van floooh's chips. In src/board.c bevindt elke core zich in een socket die alleen zijn eigen pinnen ziet. Elke halve cyclus verloopt in drie stappen: de row-address, dan valt /RAS weg, dan valt /CAS weg. Het gehele bord stabiliseert zich na elke stap.
De redenering achter deze keuzes is uitgewerkt in PLAN.md.
Beperkingen
- Snelheid: Het programma is traag (tussen een derde en de helft van de echte tijd op de genoemde computers), omdat elke pin van elke chip wordt gesimuleerd.
- Analoge modellen: De floating- en voedingsmodellen hebben de juiste vorm, maar de specifieke getallen (drempelwaarden, drifttijden, crosstalk) zijn schattingen. Deze staan als constanten in
src/sim.c.
- Niet gesimuleerde analoge delen: De video-output, het SID-filter, de voeding en de dot clock PLL worden niet gesimuleerd.
- Interne fouten: Fouten binnen een chip (zoals defecte DRAM-cellen of trage componenten) en bruggen tussen twee nets zijn gepland, maar nog niet geïmplementeerd.
c64-hw-sim: Commodore 64 Hardware Simulator
Het programma kent de netlist van het bord (de elektrische verbindingen op de PCB) en hoe elke chip zich gedraagt op zijn pinnen. Het programma heeft geen voorkennis over hoe een defecte Commodore 64 eruitziet; wanneer een defect onderdeel wordt gesimuleerd en het scherm zich vult met willekeurige data ('garbage'), is die data berekend vanuit het circuit en niet gekozen door iemand die wist wat het resultaat zou zijn.
Voorbeeld
Til pin 17 (A7) van de color RAM op voordat de stroom wordt ingeschakeld; de machine start op en ziet er gezond uit. De CPU schrijft en de VIC leest met hetzelfde onjuiste adres, waardoor de RAM simpelweg 'aliast'. Plaats de poot terug, en het deel van de color RAM dat nooit is beschreven, verschijnt als willekeurige kleuren. Til de poot opnieuw op, en het scherm is weer schoon. Een echte 2114-chip vertoont hetzelfde gedrag.
Doel van het programma
Met dit programma kunnen hoofdzakelijk twee dingen worden gedaan:
- Leren hoe de Commodore 64 werkt op een intiem niveau, op een manier die moeilijk te reproduceren is op echte hardware zonder het risico deze te beschadigen (zeker omdat op de meeste borden veel chips gesoldeerd zijn in plaats van in sockets geplaatst).
- Diagnose van defecte hardware. Als u een defecte C64 heeft en een hypothese over wat er kapot zou kunnen zijn, kunt u dit simuleren. Dit kan aanwijzingen opleveren zodat chips in de meest logische volgorde kunnen worden lossolderd, waardoor er zo min mogelijk componenten verwijderd hoeven te worden. Een overeenkomstig symptoom is een aanwijzing, geen bewijs: verschillende fouten kunnen hetzelfde effect hebben en de simulatie heeft zijn grenzen.
Prestaties
Houd er rekening mee dat dit programma, zelfs op snelle computers, moeite heeft om de C64-hardware op echte snelheid te simuleren. Een echte C64 wordt gesimuleerd op:
- 31% van de snelheid op een Apple M3 Max.
- 39% op een AMD Ryzen AI Max+ PRO 495 (Gorgon Halo).
- 48% op een Apple M5 Max.
Dit is geen probleem voor de doelen van dit programma, maar let op: het is geen emulator om games mee te spelen.
(Beschrijving bij afbeelding: De klassieke 10 PRINT CHR$(205.5+RND(1));:GOTO 10 maze draait terwijl de character ROM (U5) uit zijn socket wordt getrokken en later weer wordt teruggeplaatst. De CPU, de RAM en het programma blijven werken; alleen de vormen van de karakters gaan verloren. De oscilloscoop staat op datalijn D0 van de ROM-socket: wanneer de socket leeg is, 'float' de bus telkens wanneer de VIC een karaktervorm ophaalt. Getoond op C64-snelheid.)
Erkenningen
Het idee voor dit programma ontstond tijdens het gebruik van de chips van Andre Weissflog (floooh), emulators van de 6502, VIC-II, CIA, SID en anderen die pinnen als interface gebruiken. De volgende stap was om deze aanpak, met zijn code als startpunt, naar het extreme te trekken: pin-level modellen van elk ander onderdeel van de C64, zoals de RAMs, ROMs, logische chips, de PLA, enzovoort.
- De chip-cores zijn van floooh, afkomstig uit
c64-llm (zlib licentie).
- Het bord is gebaseerd op
C64-250407-Replica-KiCad van bwack (CERN OHL).
- De PLA-vergelijkingen komen uit de 82S100 read-out van Mark Smith en Marko Mäkelä.
Bouwen
Om het programma te bouwen en te starten:
make
./c64-hw-sim [program.prg]
Het draait op macOS en Linux (X11) met OpenGL. De grafische bibliotheek (sokol) en de interface-bibliotheek (nuklear) bevinden zich in third_party/.
Gebruik
Het venster toont het bord, de monitor, een controlepaneel en een oscilloscoop.
Componenten op het bord: Chips worden weergegeven als boxen, benoemd naar hun rol:
- RAM1 tot RAM8: De 4164 DRAMs. Elke chip bevat één bit van elke byte (RAMn heeft databit n-1).
- VRAM: De 2114 color RAM.
- BASIC, KERNAL en CHAR: De ROMs.
- PLA: De adresdecoder.
Door in te zoomen kunt u referenties en adresbereiken zien. Pinnen tonen hun status zoals een logische probe dat zou doen:
- Rood: Hoog (High)
- Blauw: Laag (Low)
- Geel: Pulserend
- Grijs: Floating
- Magenta: Wanneer twee outputs met elkaar 'vechten' (contention).
Interactie:
- Pinnen: Klik op een pin om deze op de oscilloscoop te plaatsen en om deze te beschadigen: floating, kortgesloten naar GND, of kortgesloten naar +5V.
- Chips: Klik op een chip om deze uit de socket te trekken.
- Passieve componenten: Klik op een weerstand, een ferrietkraal of het kristal om deze te openbreken.
- Controlepaneel: Hier staan de huidige fouten vermeld, elk met een knop voor reparatie. Het paneel kan ook
.prg bestanden laden. Deze worden direct in de DRAM-chips geschreven, zoals een 'freezer cartridge' dat zou doen, waardoor laden ook op een defect bord werkt.
Besturing:
- Gebruik het toetsenbord zoals gebruikelijk.
ESC: RUN/STOP
PgUp: RESTORE
TAB: CTRL
Linker ALT: C=
Command-line opties
Voorbeeld van een headless run:
./c64-hw-sim --headless 200 --text --shot out.png --fault U17:removed
Dit voert vier seconden (200 frames) uit zonder venster. Het print de tekst die vanaf het monitorscherm wordt gelezen en slaat een afbeelding op.
Foutdefinities (--fault): Een fout wordt geschreven als REF:wat of REF.PIN:wat:
U17:removed
U21.14:gnd
U12.14:vcc
U9.2:open
R51:open
RP4:short
Overige opties:
--at 150:U6.17:open --at 300:repair: Breekt en repareert onderdelen op specifieke tijdstippen terwijl de C64 draait.
--nets: Rapporteert de nets waar outputs met elkaar in conflict kwamen.
C64HW_TYPE=$'PRINT 1+1\n': Typen van tekst na het opstarten.
C64HW_CHECK=1: Controleert elke KERNAL-lezing en elke VIC-fetch tegen de ideale memory map.
--record 900:DIR --frames 90: Slaat het venster 90 keer op, elke 4 emulatieframes vanaf frame 900 (voor grafische modus).
Het script tests/faults.sh voert 31 veelvoorkomende fouten uit. De verwachte symptomen van elk defect werden genoteerd voordat de simulator werd gedraaid.
Werking
Het bestand tools/kicad2c.py zet de KiCad-replica van de 250407 van bwack om in C-tabellen: 216 onderdelen, hun pads en 249 nets.
Signaalbeheer: Elke pin drijft zijn net sterk aan, zwak (een pull-up), via een voedingskortsluiting, of helemaal niet. De sterkste driver wint. Wanneer twee gelijke drivers vechten, is er sprake van 'contention' en wint de lage status.
Een net dat door niemand wordt aangestuurd, behoudt zijn lading en drift vervolgens:
- Na microsconden naar ongeveer 1.4V, indien TTL-inputs het belasten.
- In een fractie van een seconde naar 0V, indien alleen MOS-inputs aanwezig zijn.
MOS-inputs vergelijken deze spanning (inclusief ruis) met hun eigen drempelwaarde, waardoor een floating lijn erratisch kan worden gelezen.
Voedingsfouten: De impact van voedingsfouten is afhankelijk van de chip:
- Een chip zonder VCC is dood.
- Een chip zonder GND laat zijn outputs 'float high'.
- Een CMOS-chip blijft draaien op 'phantom power', die de chip bereikt via de beveiligingsdiodes van de pinnen.
De ruis is 'seeded', zodat een run exact herhaald kan worden.
Modellering: In src/parts.c worden de volgende onderdelen op pin-niveau gemodelleerd:
- De glue logic.
- De ROMs.
- De DRAMs (die de row vergrendelen op
/RAS en de column op /CAS).
- De color RAM.
- De PLA, inclusief de werkelijke logische vergelijkingen.
De 6510, VIC-II, CIAs en SID zijn cycle-accurate cores van floooh's chips. In src/board.c bevindt elke core zich in een socket die alleen zijn eigen pinnen ziet. Elke halve cyclus verloopt in drie stappen: de row-address, dan valt /RAS weg, dan valt /CAS weg. Het gehele bord stabiliseert zich na elke stap.
De redenering achter deze keuzes is uitgewerkt in PLAN.md.
Beperkingen
- Snelheid: Het programma is traag (tussen een derde en de helft van de echte tijd op de genoemde computers), omdat elke pin van elke chip wordt gesimuleerd.
- Analoge modellen: De floating- en voedingsmodellen hebben de juiste vorm, maar de specifieke getallen (drempelwaarden, drifttijden, crosstalk) zijn schattingen. Deze staan als constanten in
src/sim.c.
- Niet gesimuleerde analoge delen: De video-output, het SID-filter, de voeding en de dot clock PLL worden niet gesimuleerd.
- Interne fouten: Fouten binnen een chip (zoals defecte DRAM-cellen of trage componenten) en bruggen tussen twee nets zijn gepland, maar nog niet geïmplementeerd.