Add mov instruction for copying value from one register to another

This commit is contained in:
g1n 2021-10-28 19:08:38 +03:00
parent b78ea8538b
commit 0d2657eab1
2 changed files with 147 additions and 1 deletions

View File

@ -52,6 +52,53 @@ void ocpu_dump_ocpu(struct OCPU ocpu) { // FIXME
printf("Flags: ZF: %X, NF: %X, CF: %X, OF: %X\n", ocpu.ZF, ocpu.NF, ocpu.CF, ocpu.OF);
}
int match_register(byte reg) { // Function that returns register's value by taking register opcode
switch(reg) {
case REG_AL:
return ocpu.AL;
case REG_AH:
return ocpu.AH;
case REG_A:
return ocpu.A;
case REG_BL:
return ocpu.BL;
case REG_BH:
return ocpu.BH;
case REG_B:
return ocpu.B;
case REG_CL:
return ocpu.CL;
case REG_CH:
return ocpu.CH;
case REG_C:
return ocpu.C;
case REG_DL:
return ocpu.DL;
case REG_DH:
return ocpu.DH;
case REG_D:
return ocpu.D;
case REG_EL:
return ocpu.EL;
case REG_EH:
return ocpu.EH;
case REG_E:
return ocpu.E;
case REG_FL:
return ocpu.FL;
case REG_FH:
return ocpu.FH;
case REG_F:
return ocpu.F;
}
return 0xFF; // FIXME: add some error handling
}
void ocpu_execute() {
while (1) {
byte instruction = ocpu_fetch_byte();
@ -150,6 +197,104 @@ void ocpu_execute() {
ocpu.F = word_value;
break;
default:
printf("Wrong register: %02X\n", reg);
return;
}
break;
case INS_MOV_REG:
reg = ocpu_fetch_byte();
switch(reg) {
case REG_AL:
byte value = match_register(ocpu_fetch_byte());
ocpu.A = (ocpu.A & 0xFF00) | (value & 0xFF);
ocpu.AL = ocpu.A & 0xFF;
break;
case REG_AH:
value = match_register(ocpu_fetch_byte());
ocpu.A = ((value & 0xFF) << 8) | (ocpu.A & 0xFF);
ocpu.AH = ocpu.A >> 8;
break;
case REG_A:
word word_value = match_register(ocpu_fetch_byte());
ocpu.A = word_value;
break;
case REG_BL:
value = match_register(ocpu_fetch_byte());
ocpu.B = (ocpu.B & 0xFF00) | (value & 0xFF);
ocpu.BL = ocpu.B & 0xFF;
break;
case REG_BH:
value = match_register(ocpu_fetch_byte());
ocpu.B = ((value & 0xFF) << 8) | (ocpu.B & 0xFF);
ocpu.BH = ocpu.B >> 8;
break;
case REG_B:
word_value = match_register(ocpu_fetch_byte());
ocpu.B = word_value;
break;
case REG_CL:
value = match_register(ocpu_fetch_byte());
ocpu.C = (ocpu.C & 0xFF00) | (value & 0xFF);
ocpu.CL = ocpu.C & 0xFF;
break;
case REG_CH:
value = match_register(ocpu_fetch_byte());
ocpu.C = ((value & 0xFF) << 8) | (ocpu.C & 0xFF);
ocpu.CH = ocpu.C >> 8;
break;
case REG_C:
word_value = match_register(ocpu_fetch_byte());
ocpu.C = word_value;
break;
case REG_DL:
value = match_register(ocpu_fetch_byte());
ocpu.D = (ocpu.D & 0xFF00) | (value & 0xFF);
ocpu.DL = ocpu.D & 0xFF;
break;
case REG_DH:
value = match_register(ocpu_fetch_byte());
ocpu.D = ((value & 0xFF) << 8) | (ocpu.D & 0xFF);
ocpu.DH = ocpu.D >> 8;
break;
case REG_D:
word_value = match_register(ocpu_fetch_byte());
ocpu.D = word_value;
break;
case REG_EL:
value = match_register(ocpu_fetch_byte());
ocpu.E = (ocpu.E & 0xFF00) | (value & 0xFF);
ocpu.EL = ocpu.E & 0xFF;
break;
case REG_EH:
value = match_register(ocpu_fetch_byte());
ocpu.E = ((value & 0xFF) << 8) | (ocpu.E & 0xFF);
ocpu.EH = ocpu.E >> 8;
break;
case REG_E:
word_value = match_register(ocpu_fetch_byte());
ocpu.E = word_value;
break;
case REG_FL:
value = match_register(ocpu_fetch_byte());
ocpu.F = (ocpu.F & 0xFF00) | (value & 0xFF);
ocpu.FL = ocpu.F & 0xFF;
break;
case REG_FH:
value = match_register(ocpu_fetch_byte());
ocpu.F = ((value & 0xFF) << 8) | (ocpu.F & 0xFF);
ocpu.FH = ocpu.F >> 8;
break;
case REG_F:
word_value = match_register(ocpu_fetch_byte());
ocpu.F = word_value;
break;
default:
printf("Wrong register: %02X\n", reg);
return;
@ -265,7 +410,7 @@ void ocpu_execute() {
void initOCPU(FILE *infile) {
ocpu_reset();
char ch;
int ch;
int pos = 0;
while (1) { // FIXME
ch = fgetc(infile);

View File

@ -32,6 +32,7 @@
// Opcodes
#define INS_MOV_IM 0x01
#define INS_MOV_REG 0xA1
#define INS_ADD_IM 0x10
struct OCPU_MEMORY {