#include #include #define MEM_BYTES 65536 struct intel8080 { uint8_t mem[MEM_BYTES]; uint16_t PC; uint16_t SP; union { struct { uint8_t C, B, E, D, L, H, F, A; }; struct { uint16_t BC, DE, HL, PSW; }; struct { uint8_t C_pad, B_pad, E_pad, D_pad, L_pad, H_pad; uint8_t CY : 1; uint8_t bit1 : 1; uint8_t P : 1; uint8_t bit3 : 1; uint8_t AC : 1; uint8_t bit5 : 1; uint8_t Z : 1; uint8_t S : 1; }; }; }; void set_reg(struct intel8080* cpu, uint8_t reg, uint8_t data); uint8_t get_reg(struct intel8080* cpu, uint8_t reg); void set_rp(struct intel8080* cpu, uint8_t rp, uint16_t data); uint16_t get_rp(struct intel8080* cpu, uint8_t rp); int main() { struct intel8080 cpu = {0}; cpu.bit1 = 1; cpu.PC = 0; uint8_t src, dst, bt, rp, fd; FILE *file = fopen("test.bin", "r"); if (file == NULL) { return 1; } fread(cpu.mem, 1, MEM_BYTES, file); fclose(file); while (cpu.PC < MEM_BYTES - 2) { bt = cpu.mem[cpu.PC]; src = bt & 0b111; /* last 3 bits */ dst = (bt >> 3) & 0b111; /* pre-last 3 bits */ rp = (bt >> 4) & 0b11; if (bt == 0x76) { break; } else if ((bt & 0b11111000) == 0b01110000) /* MOV MEM, SRC */ cpu.mem[cpu.HL] = get_reg(&cpu, src); else if ((bt & 0b11000111) == 0b01000110) /* MOV DST, MEM */ set_reg(&cpu, dst, cpu.mem[cpu.HL]); else if ((bt & 0b11000000)== 0b01000000) /* MOV DST, SRC */ set_reg(&cpu, dst, get_reg(&cpu, src)); else if ((bt & 0b11000111) == 0b00000110 && dst != 0b110) /* MVI DST, DATA*/ { set_reg(&cpu, dst, cpu.mem[cpu.PC + 1]); cpu.PC++; } else if (bt == 0b00110110) /* MVI MEM, DATA*/ { cpu.mem[cpu.HL] = cpu.mem[cpu.PC + 1]; cpu.PC++; } else if ((bt & 0b11001111) == 0b00000001) { /* LXI RP, DATA */ set_rp(&cpu, rp, (cpu.mem[cpu.PC + 2] << 8) + cpu.mem[cpu.PC + 1]); cpu.PC += 2; } else if (bt == 0b00111010) { /* LDA ADDR */ cpu.A = cpu.mem[(cpu.mem[cpu.PC + 2] << 8) + cpu.mem[cpu.PC + 1]]; cpu.PC += 2; } else if (bt == 0b00110010) { /* STA ADDR */ cpu.mem[(cpu.mem[cpu.PC + 2] << 8) + cpu.mem[cpu.PC + 1]] = cpu.A; cpu.PC += 2; } else if (bt == 0b00101010) { /* LHLD */ cpu.L = cpu.mem[(cpu.mem[cpu.PC + 2] << 8) + cpu.mem[cpu.PC + 1]]; cpu.H = cpu.mem[(cpu.mem[cpu.PC + 2] << 8) + cpu.mem[cpu.PC + 1] + 1]; cpu.PC += 2; } else if (bt == 0b00100010 && (rp == 0b00 || rp == 0b01)) { /* SHLD */ cpu.mem[(cpu.mem[cpu.PC + 2] << 8) + cpu.mem[cpu.PC + 1]] = cpu.L; cpu.mem[(cpu.mem[cpu.PC + 2] << 8) + cpu.mem[cpu.PC + 1] + 1] = cpu.H; cpu.PC += 2; } else if ((bt & 0b11001111) == 0b00001010 && (rp == 0b00 || rp == 0b01)) { /* LDAX */ cpu.A = cpu.mem[get_rp(&cpu, rp)]; } else if ((bt & 0b11001111) == 0b00000010 && (rp == 0b00 || rp == 0b01)) { /* STAX */ cpu.mem[get_rp(&cpu, rp)] = cpu.A; } else if (bt == 0b11101011) { uint16_t temp_hl = cpu.HL; cpu.HL = cpu.DE; cpu.DE = temp_hl; } cpu.PC++; } printf("A: %d B: %d C: %d H: %d L: %d\n", cpu.A, cpu.B, cpu.C, cpu.H, cpu.L); printf("HL: %d mem[HL]: %d\n", cpu.HL, cpu.mem[cpu.HL]); } void set_reg(struct intel8080* cpu, uint8_t reg, uint8_t data) { switch (reg) { case 0b111: cpu->A = data; break; case 0b000: cpu->B = data; break; case 0b001: cpu->C = data; break; case 0b010: cpu->D = data; break; case 0b011: cpu->E = data; break; case 0b100: cpu->H = data; break; case 0b101: cpu->L = data; break; default: break; } return; } uint8_t get_reg(struct intel8080* cpu, uint8_t reg) { switch (reg) { case 0b111: return cpu->A; case 0b000: return cpu->B; case 0b001: return cpu->C; case 0b010: return cpu->D; case 0b011: return cpu->E; case 0b100: return cpu->H; case 0b101: return cpu->L; default: return 0; } } void set_rp(struct intel8080* cpu, uint8_t rp, uint16_t data) { switch (rp) { case 0b00: cpu->BC = data; break; case 0b01: cpu->DE = data; break; case 0b10: cpu->HL = data; break; case 0b11: cpu->SP = data; break; default: break; } return; } uint16_t get_rp(struct intel8080* cpu, uint8_t rp) { switch (rp) { case 0b00: return cpu->BC; case 0b01: return cpu->DE; case 0b10: return cpu->HL; case 0b11: return cpu->SP; default: break; } return 0; }