Files
2026-06-05 22:47:35 +00:00

219 lines
5.1 KiB
C

#include <stdio.h>
#include <stdint.h>
#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;
}