public void SetData(Register register, VirtualMemory memory, int value, Error error) { switch (mode) { case CPUMode.MemoryToRegister: case CPUMode.RegisterToRegister: case CPUMode.RegisterOnly: case CPUMode.NumberToRegister: switch (destRegister) { case RegisterIndex.ax: register.ax = value; break; case RegisterIndex.bx: register.bx = value; break; case RegisterIndex.cx: register.cx = value; break; case RegisterIndex.dx: register.dx = value; break; case RegisterIndex.si: register.si = value; break; case RegisterIndex.di: register.di = value; break; case RegisterIndex.bp: register.bp = value; break; case RegisterIndex.sp: register.sp = value; break; case RegisterIndex.ip: register.ip = value; break; default: error.cpuError = CPUError.NotDefinedRegisterError; break; } break; case CPUMode.MemoryToMemory: case CPUMode.RegisterToMemory: case CPUMode.MemoryOnly: case CPUMode.NumberToMemory: if (isDestMemoryIndexIsRegister) { switch (destRegister) { case RegisterIndex.ax: destMemoryIndex = register.ax; break; case RegisterIndex.bx: destMemoryIndex = register.bx; break; case RegisterIndex.cx: destMemoryIndex = register.cx; break; case RegisterIndex.dx: destMemoryIndex = register.dx; break; case RegisterIndex.si: destMemoryIndex = register.si; break; case RegisterIndex.di: destMemoryIndex = register.di; break; case RegisterIndex.bp: destMemoryIndex = register.bp; break; case RegisterIndex.sp: destMemoryIndex = register.sp; break; case RegisterIndex.ip: destMemoryIndex = register.ip; break; default: error.cpuError = CPUError.NotDefinedRegisterError; break; } } memory.SetData(destMemoryIndex, value, error); break; default: error.cpuError = CPUError.NotDefinedRegisterError; break; } }
public void InstructionPerClock() { int source = 1, dest = 1, result = 1; if (machineCodes == null) { Debug.Log("CPU Error"); error.cpuError = CPUError.NotDefinedMachineCode; return; } if (machineCodes.Count <= register.ip) { Debug.Log("CPU Error"); error.cpuError = CPUError.IndexOutOfRangeFromInstructions; isRun = false; return; } //fetch Machine Code currentCode = machineCodes[register.ip]; register.ip += 1; Debug.Log("-----------------------"); Debug.Log("Instruction:" + currentCode.instruction + " Mode:" + currentCode.mode); Debug.Log("AX:" + register.ax + " BX:" + register.bx); Debug.Log("SP:" + register.sp + " IP:" + register.ip); //decoding the instructions and execute switch (currentCode.instruction) { case Instructions.MOV: GetDataSource(ref source); SetData(source); break; case Instructions.PUSH: memory.SetData(register.sp, currentCode.value, error); register.sp += 1; break; case Instructions.POP: result = memory.GetData(register.sp, error); SetData(result); register.sp--; break; case Instructions.INC: GetDataDest(ref source); result = source + 1; SetData(result); break; case Instructions.DEC: GetDataDest(ref source); result = source - 1; SetData(result); break; case Instructions.ADD: GetDataSource(ref source); GetDataDest(ref dest); result = source + dest; SetData(result); break; case Instructions.SUB: GetDataSource(ref source); GetDataDest(ref dest); source = -source; result = source + dest; SetData(result); break; case Instructions.MUL: GetDataSource(ref source); GetDataDest(ref dest); result = source * dest; SetData(result); break; case Instructions.XOR: GetDataSource(ref source); GetDataDest(ref dest); result = source ^ dest; SetData(result); break; case Instructions.OR: GetDataSource(ref source); GetDataDest(ref dest); result = source | dest; SetData(result); break; case Instructions.AND: GetDataSource(ref source); GetDataDest(ref dest); result = source & dest; SetData(result); break; case Instructions.SAL: GetDataSource(ref source); GetDataDest(ref dest); result = source << dest; SetData(result); break; case Instructions.SAR: GetDataSource(ref source); GetDataDest(ref dest); result = source >> dest; SetData(result); break; case Instructions.CMP: GetDataSource(ref source); GetDataDest(ref dest); source = -source; result = source + dest; break; case Instructions.TEST: GetDataSource(ref source); GetDataDest(ref dest); result = source & dest; break; case Instructions.JMP: GetDataSource(ref result); register.ip = result; break; case Instructions.JE: if (register.zf) { GetDataSource(ref result); register.ip = result; } break; case Instructions.JNE: if (!register.zf) { GetDataSource(ref result); register.ip = result; } break; case Instructions.JS: if (register.sf) { GetDataSource(ref result); register.ip = result; } break; case Instructions.JNS: if (!register.sf) { GetDataSource(ref result); register.ip = result; } break; case Instructions.JG: if (!(register.sf ^ register.of) & !register.zf) { GetDataSource(ref result); register.ip = result; } break; case Instructions.JGE: if (!(register.sf ^ register.of)) { GetDataSource(ref result); register.ip = result; } break; case Instructions.JL: if (register.sf ^ register.of) { GetDataSource(ref result); register.ip = result; } break; case Instructions.JLE: if ((register.sf ^ register.of) | register.zf) { GetDataSource(ref result); register.ip = result; } break; case Instructions.END: isRun = false; break; default: error.cpuError = CPUError.NotDefinedMachineCode; isRun = false; break; } register.SetCarryFlag(result, dest, source); }
public void WirteMemory(int index, int value) { memory.SetData(index, value, error); }