it fucking works!
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user