Dieser interaktive Simulator emuliert die Intel 8080 CPU – den legendären 8-Bit-Mikroprozessor aus den 1970er-Jahren. Du kannst hier Assemblercode schreiben, assemblieren und direkt ausführen. Der Speicher (RAM & VRAM), die Register und Flags werden in Echtzeit angezeigt. Das Textdisplay simuliert einen Monitor mit 80×25 Zeichen, der über den Video-RAM beschrieben wird. Ideal zum Lernen, Experimentieren und Verstehen, wie ein Prozessor intern arbeitet.
Willkommen im Intel 8080 CPU Simulator – einem interaktiven Lernwerkzeug, das die Funktionsweise eines klassischen 8-Bit-Prozessors vollständig im Browser nachbildet. Hier kannst du echten Assemblercode schreiben, assemblieren, ausführen und in Echtzeit beobachten, was in den Registern, Flags und Speicherzellen passiert. Das Projekt richtet sich an Schüler · Studenten · Lehrkräfte · Retro-Fans und alle, die verstehen wollen, wie eine CPU tatsächlich „denkt“.
0xE000 für Textdarstellung.
            Der Emulator bildet den gesamten Befehlssatz des Intel 8080 nach – jedes Opcode-Byte
            wird dekodiert und exakt wie im Original-Mikroprozessor ausgeführt.
            Bei einem Schreibzugriff auf eine Adresse ≥ 0xE000 wird der Wert als
            Bildschirmzeichen interpretiert und in das 80×25-Display geschrieben.
            Damit lassen sich Textausgaben, Lauftexte oder einfache Benutzeroberflächen programmieren.
        
            Der Intel 8080-Simulator stellt – wie das Original – einen zusammenhängenden
            64-KB-Adressraum bereit (0000h–FFFFh).
            Dieser ist im Simulator in Hauptspeicher (RAM) und Video-RAM (VRAM) aufgeteilt.
            Der Zugriff erfolgt byteweise über Befehle wie MOV M,A oder
            LXI H,addr.
        
| Bereich | Adresse (hex) | Größe | Verwendung | 
|---|---|---|---|
| RAM | 0000h – DFFFh | ≈ 56 KB | Programmcode, Daten und Stack | 
| VRAM | E000h – E7CFh | 2 KB (80 × 25 Zeichen) | Text-Display-Speicher: jedes Byte = ein ASCII-Zeichen | 
| BIOS | F000h – FFFFh | 4 KB | Basisroutinen (Init, Textausgabe, Clear) | 
            Die CPU unterscheidet nicht zwischen RAM und VRAM – beide liegen im selben
            16-Bit-Adressraum.
            0xE000 markiert lediglich den Beginn des Video-RAM-Segments.
            Wird ein Byte in diesen Bereich geschrieben, interpretiert der Simulator den
            Wert als Zeichen und aktualisiert sofort die Bildschirmanzeige.
        
; Einfache VRAM-Ausgabe
ORG 0000h
LXI H, 0E000h   ; HL zeigt auf VRAM-Start
MVI A, 'A'
MOV M, A        ; schreibt 'A' an 0xE000 → erscheint auf dem Display
INX H
MVI A, 'B'
MOV M, A        ; schreibt 'B' an 0xE001
HLT
Damit stehen im Simulator realistische Bedingungen eines 8080-Systems zur Verfügung – Programme können im RAM ausgeführt und parallel Text im VRAM darstellen.
; VRAM-Demo: Schreibt "HELLO WORLD!" auf den Bildschirm
        ORG 0x0000
        LXI H, 0xE000
        MVI A, 'H'     ; Zeichen setzen
        MOV M, A
        INX H
        MVI A, 'E'
        MOV M, A
        INX H
        MVI A, 'L'
        MOV M, A
        INX H
        MVI A, 'L'
        MOV M, A
        INX H
        MVI A, 'O'
        MOV M, A
        INX H
        MVI A, ' '
        MOV M, A
        INX H
        MVI A, 'W'
        MOV M, A
        INX H
        MVI A, 'O'
        MOV M, A
        INX H
        MVI A, 'R'
        MOV M, A
        INX H
        MVI A, 'L'
        MOV M, A
        INX H
        MVI A, 'D'
        MOV M, A
        INX H
        MVI A, '!'
        MOV M, A
        HLT
            Nach dem Assemblieren und Laden zeigt das Display „HELLO WORLD!“ in der ersten Zeile an.
            Du kannst anschließend mit HLT den Prozessor anhalten oder mit JMP in Schleifen springen.
        
; TTY-Echo über Ports 0/1
        ORG 0x0000
LOOP:   IN   0
        CPI  0
        JZ   LOOP
        IN   1
        OUT  1
        JMP  LOOP
Dieses Programm liest Eingaben aus dem Konsolen-Eingabefeld (Port 0) und gibt sie sofort wieder aus. Dadurch kannst du direkt mit der CPU über die virtuelle Konsole interagieren.
; Zählerdemo: schreibt die Ziffern 0–9 in den VRAM
        ORG 0x0000
        LXI H, 0xE000
        MVI B, 0
LOOP:   MVI A, '0'
        ADD B
        MOV M, A
        INX H
        INR B
        MVI A, 10
        CMP B
        JNZ LOOP
        HLT
Das Programm zeigt im Display die Ziffern 0 bis 9 an. Nach dem letzten Zeichen stoppt die CPU.
; CPU-Alive-Test: gibt fortlaufend 0xFF auf Port 1 aus
        ORG 0
LOOP:   MVI A, 0FFh
        OUT 1
        JMP LOOP
Dieses einfache Testprogramm sendet fortlaufend Daten an Port 1. Es kann als Basis für Hardware-Simulationen oder zur Laufzeitüberwachung dienen.
; VRAM-Demo: einfache Laufschrift mit dem Zeichen '>'
        ORG 0
        LXI H, 0xE000
        MVI A, '>'
NEXT:   MOV M, A
        INX H
        CPI 0xE000 + 80
        JNZ NEXT
        HLT
Dieses Programm schreibt fortlaufend das Zeichen „>“ in die erste Zeile des Displays, bis 80 Spalten gefüllt sind.
Die 8080 besitzt sieben 8-Bit-Allzweck-Register (A,B,C,D,E,H,L) sowie zwei 16-Bit-Spezialregister (PC – Program Counter, SP – Stack Pointer). Viele Befehle arbeiten mit den Registerpaaren BC, DE, HL (16-Bit). Arithmetische/logische Operationen setzen die Status-Flags, die von bedingten Sprüngen und Aufrufen geprüft werden.
| Register | Breite | Rolle | Hinweise | 
|---|---|---|---|
| A(Akkumulator) | 8 Bit | Zentrales ALU-Register für Rechen-/Logikoperationen | Viele Befehle nutzen implizit A(z. B.ADD r,ANA r) | 
| B,C | 8 Bit | Allzweckregister | Als Paar BC nutzbar | 
| D,E | 8 Bit | Allzweckregister | Als Paar DE nutzbar | 
| H,L | 8 Bit | Zeiger auf Speicher (indirekte Adressierung über M=(HL)) | Als Paar HL sehr häufig: MOV M,A,INX H | 
| PC | 16 Bit | Program Counter – Adresse des nächsten Befehls | Wird durch Sprünge/Calls/Returns geändert | 
| SP | 16 Bit | Stack Pointer – Top-of-Stack im RAM | Genutzt von PUSH/POP,CALL/RET | 
Registerpaare: BC, DE, HL, SP (16-Bit-Operationen wie LXI rp,imm16, DAD rp).
| Flag | Bit | Bedeutung | Setzlogik (vereinfacht) | 
|---|---|---|---|
| S(Sign) | Bit 7 | 1 = Ergebnis negativ | Gesetzt, wenn Bit 7 des Ergebnisses = 1 | 
| Z(Zero) | Bit 6 | 1 = Ergebnis ist 0 | Gesetzt, wenn Ergebnis = 0 | 
| AC(Auxiliary Carry) | Bit 4 | Übertrag (Addition) bzw. Borrow (Subtraktion) zwischen Bit 3 ↔ Bit 4; u. a. von DAAgenutzt (BCD). | Wird im Simulator korrekt gesetzt (ADD/ADC/ADI/ACI sowie SUB/SBB/SUI/SBI nach 8080-Regel). | 
| P(Parity) | Bit 2 | 1 = gerade Anzahl von „1“-Bits | Even Parity über 8-Bit-Ergebnis | 
| CY(Carry) | Bit 0 | 1 = Übertrag (bei Subtraktion: Borrow) | ADD: Carry bei > 0xFF ·SUB: Borrow → Carry=1 | 
ADD, SUB, ANA, ORA, XRA, CMP).JZ/JNZ, JC/JNC, JP/JM, JPE/JPO,
                CZ/CNZ, RC/RNC, RZ/RNZ u. a.HL als Zeiger: M referenziert die Speicherzelle an Adresse (HL)
                – wichtig für RAM/VRAM-Zugriffe (z. B. Textausgabe).MVI A, 0x05      ; A = 5
ADI 3            ; A = 8  → S=0, Z=0, P=1, CY=0
CPI 8            ; vergleicht A mit 8  → Z=1
JZ  EQUAL        ; springt, wenn Z=1
| Befehl | Beschreibung | Beispiel | 
|---|---|---|
| NOP | Keine Operation | |
| HLT | Stoppt die CPU | |
| MOV r1, r2 | Kopiert Inhalt von Register r2 nach r1 | MOV B, A | 
| MVI r, d8 | Lädt 8-Bit-Wert in Register | MVI A, 'H' | 
| LXI rp, d16 | Lädt 16-Bit-Wert in Register-Paar | LXI H, 0xE000 | 
| LDA addr | Lädt A aus Speicheradresse | LDA 0x2000 | 
| STA addr | Speichert A an Speicheradresse | STA 0xE000 | 
| LDAX rp | Lädt A aus Adresse des Register-Paars | LDAX D | 
| STAX rp | Speichert A an Adresse des Register-Paars | STAX B | 
| LHLD addr | Lädt HL aus Speicher (low/high) | LHLD 0x2050 | 
| SHLD addr | Speichert HL in Speicher (low/high) | SHLD 0x2050 | 
| INX rp | Inkrementiert Register-Paar | INX H | 
| DCX rp | Dekrementiert Register-Paar | DCX D | 
| DAD rp | Addiert 16-Bit-Wert des Paars zu HL | DAD H | 
| INR r | Inkrementiert Register um 1 | INR A | 
| DCR r | Dekrementiert Register um 1 | DCR M | 
| ADD r | Addiert Registerwert zu A | ADD B | 
| ADC r | Addiert Registerwert + Carry zu A | ADC B | 
| ADI d8 | Addiert 8-Bit-Wert zu A | ADI 1 | 
| ACI d8 | Addiert 8-Bit-Wert + Carry zu A | ACI 1 | 
| SUB r | Subtrahiert Registerwert von A | SUB B | 
| SBB r | Subtrahiert Registerwert + Borrow von A | SBB B | 
| SUI d8 | Subtrahiert 8-Bit-Wert von A | SUI 1 | 
| SBI d8 | Subtrahiert 8-Bit-Wert + Borrow von A | SBI 1 | 
| ANA r | Logisches AND mit Register | ANA D | 
| ANI d8 | Logisches AND mit 8-Bit-Wert | ANI 0xF0 | 
| ORA r | Logisches OR mit Register | ORA B | 
| ORI d8 | Logisches OR mit 8-Bit-Wert | ORI 0x0F | 
| XRA r | Logisches XOR mit Register | XRA B | 
| XRI d8 | Logisches XOR mit 8-Bit-Wert | XRI 0xFF | 
| CMP r | Vergleicht Registerwert mit A | CMP B | 
| CPI d8 | Vergleicht 8-Bit-Wert mit A | CPI 1 | 
| DAA | Dezimal-Korrektur nach Addition (BCD-Adjust) | DAA | 
| RLC | Rotiert A nach links (Carry ← Bit 7) | RLC | 
| RRC | Rotiert A nach rechts (Carry ← Bit 0) | RRC | 
| RAL | Rotiert A nach links durch Carry | RAL | 
| RAR | Rotiert A nach rechts durch Carry | RAR | 
| JMP addr | Springt zu Adresse | JMP LOOP | 
| JNZ addr | Springt, wenn Z = 0 | JNZ LOOP | 
| JZ addr | Springt, wenn Z = 1 | JZ DONE | 
| JC addr | Springt, wenn C = 1 | JC OVER | 
| JNC addr | Springt, wenn C = 0 | JNC NEXT | 
| JPE/JPO addr | Sprung bei Parität gerade/ungerade | JPE EVEN | 
| JP/JM addr | Sprung bei S = 0/1 (positiv/negativ) | JP OK | 
| PUSH rp | Schiebt Register-Paar auf Stack | PUSH H | 
| POP rp | Holt Register-Paar vom Stack | POP D | 
| XTHL | Tauscht HL mit Stack-Top | XTHL | 
| SPHL | Setzt SP = HL | SPHL | 
| XCHG | Tauscht HL ↔ DE | XCHG | 
| PCHL | Setzt PC = HL | PCHL | 
| CALL addr | Ruft Subroutine an Adresse auf | CALL PRINT | 
| CNZ addr | CALL, wenn Z = 0 | CNZ NEXT | 
| CZ addr | CALL, wenn Z = 1 | CZ ZERO | 
| CNC addr | CALL, wenn C = 0 | CNC OK | 
| CC addr | CALL, wenn C = 1 | CC FIX | 
| CPO addr | CALL, wenn Parität ungerade (P = 0) | CPO ODD | 
| CPE addr | CALL, wenn Parität gerade (P = 1) | CPE EVEN | 
| CP addr | CALL, wenn S = 0 (positiv) | CP POS | 
| CM addr | CALL, wenn S = 1 (negativ) | CM NEG | 
| RET | Return aus Subroutine | |
| RNZ | RET, wenn Z = 0 | |
| RZ | RET, wenn Z = 1 | |
| RNC | RET, wenn C = 0 | |
| RC | RET, wenn C = 1 | |
| RPO | RET, wenn Parität ungerade (P = 0) | |
| RPE | RET, wenn Parität gerade (P = 1) | |
| RP | RET, wenn S = 0 (positiv) | |
| RM | RET, wenn S = 1 (negativ) | |
| IN port | Liest 8-Bit-Wert von Port | IN 1 | 
| OUT port | Schreibt 8-Bit-Wert zu Port | OUT 2 | 
| EI / DI | Interrupts global (de)aktivieren | |
| RST n | Software-Interrupt auf Vektor n*8 | RST 1 | 
| ORG addr | Setzt Startadresse im Assembler | ORG 0x0000 | 
| DB | Definiert Datenbytes oder Strings | DB "HELLO" | 
Hinweis zum AC-Flag (Auxiliary Carry):
            Das AC-Flag wird vom Simulator korrekt geführt und signalisiert einen Übertrag/Borrow
            zwischen Bit 3 und Bit 4 (niedrige Nibble) – z. B. bei ADD/ADC/ADI/ACI
            sowie bei Subtraktionen (SUB/SBB/SUI/SBI) nach der 8080-Borrow-Regel.
            DAA nutzt das AC-Flag für die BCD-Korrektur.
        
            Der Simulator bildet den originalen Intel 8080-Befehlssatz aktuell zu etwa
            ≈ 98 % ab. Neben allen Register-, Speicher- und ALU-Befehlen werden die
            CALL/RET-Familie, der BCD-Befehl DAA, die Rotationen
            RLC/RRC/RAL/RAR sowie die Stack-Operationen
            PUSH/POP und XTHL/SPHL korrekt ausgeführt.
            Zusätzlich sind JPE/JPO, JP/JM, PCHL,
            XCHG sowie EI/DI und RST 0–7 implementiert.
        
| Kategorie | Beispiele | Abdeckung | Status | 
|---|---|---|---|
| Datentransfer | MOV, MVI, LXI, LDA, STA, LHLD, SHLD, STAX, LDAX | 100 % | vollständig | 
| Arithmetische Befehle | ADD, ADC, SUB, SBB, ADI, ACI, SUI, SBI, INR, DCR, DAD, CMP, CPI, DAA | ≈ 100 % | inkl. AC-Flag & DAA | 
| Logische & Rotationen | ANA, ANI, ORA, ORI, XRA, XRI, RLC–RAR | 100 % | vollständig | 
| Sprung & Kontrolle | JMP, JZ/JNZ, JC/JNC, JPE/JPO, JP/JM, HLT, NOP, PCHL | 100 % | vollständig | 
| Stack & Subroutinen | CALL/C*, RET/R*, PUSH/POP, XTHL/SPHL, XCHG | 100 % | getestet & aktiv | 
| Interrupts & Software-INT | EI/DI, RST 0–7 | 100 % | implementiert | 
Hinweis: Vor Stack-Operationen immer den Stack Pointer setzen
            (z. B. LXI SP, D000h), damit CALL/RET zuverlässig arbeiten.
JMP 0.© 2025 – Andreas Röne • Basierend auf der originalen Intel-8080-Architektur (1974)