diff --git a/main.c b/main.c new file mode 100644 index 0000000..fd8a801 --- /dev/null +++ b/main.c @@ -0,0 +1,219 @@ +#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; +} \ No newline at end of file