Start implementing ocpu emulator - mov instruction

This commit is contained in:
g1n 2021-10-26 19:52:56 +03:00
parent e4f477a58e
commit 32c1727980
4 changed files with 246 additions and 1 deletions

View File

@ -2,7 +2,7 @@ CC = gcc
CFLAGS= -O2 -Wall -Wextra
LFLAGS=
SRCFILES= main.c 6502/6502.c
SRCFILES= main.c 6502/6502.c ocpu/ocpu.c
OBJFILES= yemu
.PHONY: all clean

View File

@ -1,5 +1,6 @@
#include "common.h"
#include "6502/6502.h"
#include "ocpu/ocpu.h"
#include <stdio.h>
#include <stddef.h>
#include <string.h>
@ -60,6 +61,8 @@ int main(int argc, char *argv[]) {
return 1;
} else if (!strcmp(system_name, "6502")) {
init6502(infile);
} else if (!strcmp(system_name, "ocpu")) {
initOCPU(infile);
} else {
printf("%s: not supported system\n", "yemu");
return 1;

167
src/ocpu/ocpu.c Normal file
View File

@ -0,0 +1,167 @@
#include "ocpu.h"
struct OCPU ocpu;
struct OCPU_MEMORY ocpu_mem;
void ocpu_memory_init () {
for (int i = 0; i < MAX_MEMORY; i++){
ocpu_mem.memory[i] = 0;
}
}
byte ocpu_fetch_byte() {
byte data = ocpu_mem.memory[ocpu.PC];
ocpu.PC++;
return data;
}
word ocpu_fetch_word() {
word data = ocpu_mem.memory[ocpu.PC];
ocpu.PC++;
data |= (ocpu_mem.memory[ocpu.PC] << 8);
ocpu.PC++;
return data;
}
void ocpu_reset () {
ocpu.PC = 0x0000; // FIXME
ocpu.SP = 0x0000; //FIXME
ocpu.A = ocpu.B = ocpu.C = ocpu.D = ocpu.E = ocpu.F = 0;
ocpu.ZF = ocpu.NF = ocpu.CF = ocpu.OF = 0;
ocpu_memory_init(ocpu_mem);
}
void ocpu_dump_ocpu(struct OCPU ocpu) { // FIXME
printf("PC: %04X\n", ocpu.PC);
printf("SP: %04X\n", ocpu.SP);
printf("\n");
printf("AL: %04X BL: %04X\n", ocpu.AL, ocpu.BL);
printf("AH: %04X BH: %04X\n", ocpu.AH, ocpu.BH);
printf("A: %04X B: %04X\n", ocpu.A, ocpu.B);
printf("\n");
printf("CL: %04X DL: %04X\n", ocpu.CL, ocpu.DL);
printf("CH: %04X DH: %04X\n", ocpu.CH, ocpu.DH);
printf("C: %04X D: %04X\n", ocpu.C, ocpu.D);
printf("\n");
printf("EL: %04X FL: %04X\n", ocpu.EL, ocpu.FL);
printf("EH: %04X FH: %04X\n", ocpu.EH, ocpu.FH);
printf("E: %04X F: %04X\n", ocpu.E, ocpu.F);
printf("\n");
printf("Flags: ZF: %X, NF: %X, CF: %X, OF: %X\n", ocpu.ZF, ocpu.NF, ocpu.CF, ocpu.OF);
}
void ocpu_execute() {
while (1) {
byte instruction = ocpu_fetch_byte();
switch(instruction) {
case INS_MOV_IM:
byte reg = ocpu_fetch_byte();
switch(reg) {
case REG_AL:
byte value = ocpu_fetch_byte();
ocpu.AL = value;
break;
case REG_AH:
value = ocpu_fetch_byte();
ocpu.AH = value;
break;
case REG_A:
word word_value = ocpu_fetch_word();
ocpu.A = word_value;
break;
case REG_BL:
value = ocpu_fetch_byte();
ocpu.BL = value;
break;
case REG_BH:
value = ocpu_fetch_byte();
ocpu.BH = value;
break;
case REG_B:
word_value = ocpu_fetch_word();
ocpu.B = word_value;
break;
case REG_CL:
value = ocpu_fetch_byte();
ocpu.CL = value;
break;
case REG_CH:
value = ocpu_fetch_byte();
ocpu.CH = value;
break;
case REG_C:
word_value = ocpu_fetch_word();
ocpu.C = word_value;
break;
case REG_DL:
value = ocpu_fetch_byte();
ocpu.DL = value;
break;
case REG_DH:
value = ocpu_fetch_byte();
ocpu.DH = value;
break;
case REG_D:
word_value = ocpu_fetch_word();
ocpu.D = word_value;
break;
case REG_EL:
value = ocpu_fetch_byte();
ocpu.EL = value;
break;
case REG_EH:
value = ocpu_fetch_byte();
ocpu.EH = value;
break;
case REG_E:
word_value = ocpu_fetch_word();
ocpu.E = word_value;
break;
case REG_FL:
value = ocpu_fetch_byte();
ocpu.FL = value;
break;
case REG_FH:
value = ocpu_fetch_byte();
ocpu.FH = value;
break;
case REG_F:
word_value = ocpu_fetch_word();
ocpu.F = word_value;
break;
default:
printf("Wrong register: %02X\n", reg);
return;
}
case EOF:
return;
}
}
} // FIXME
void initOCPU(FILE *infile) {
ocpu_reset();
char ch;
int pos = 0;
while (1) { // FIXME
ch = fgetc(infile);
if (ch == EOF)
break;
ocpu_mem.memory[pos] = ch;
pos++;
}
ocpu_mem.memory[pos] = EOF;
ocpu_execute();
ocpu_dump_ocpu(ocpu);
return;
}

75
src/ocpu/ocpu.h Normal file
View File

@ -0,0 +1,75 @@
#include <stdio.h>
#include "../common.h"
#define MAX_MEMORY 1024*64
// Registers
#define REG_AL 0xA0
#define REG_AH 0xA1
#define REG_A 0x0A
#define REG_BL 0xB0
#define REG_BH 0xB1
#define REG_B 0x0B
#define REG_CL 0xC0
#define REG_CH 0xC1
#define REG_C 0x0C
#define REG_DL 0xD0
#define REG_DH 0xD1
#define REG_D 0x0D
#define REG_EL 0xE0
#define REG_EH 0xE1
#define REG_E 0x0E
#define REG_FL 0xF0
#define REG_FH 0xF1
#define REG_F 0x0F
// Opcodes
#define INS_MOV_IM 0x01
struct OCPU_MEMORY {
byte memory[MAX_MEMORY];
};
struct OCPU {
word PC; // The program counter is a 16 bit register which points to the next instruction to be executed.
byte SP; // The stack pointer is an 8 bit register and holds the low 8 bits of the next free location on the stack.
byte AL;
byte AH;
word A;
byte BL;
byte BH;
word B;
byte CL;
byte CH;
word C;
byte DL;
byte DH;
word D;
byte EL;
byte EH;
word E;
byte FL;
byte FH;
word F;
// Flags (or Processor Status)
byte ZF; // Zero Flag
byte NF; // Negative Flag
byte CF; // Carry Flag
byte OF; // Overflow Flag
};
void initOCPU(FILE *infile);