Add mov instruction for copying value from one register to another
This commit is contained in:
parent
b78ea8538b
commit
0d2657eab1
147
src/ocpu/ocpu.c
147
src/ocpu/ocpu.c
|
@ -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);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
// Opcodes
|
||||
|
||||
#define INS_MOV_IM 0x01
|
||||
#define INS_MOV_REG 0xA1
|
||||
#define INS_ADD_IM 0x10
|
||||
|
||||
struct OCPU_MEMORY {
|
||||
|
|
Loading…
Reference in New Issue