#made by zombie #02/01/21 #0-255 is internal registers and flags and etc # program execcution starts at 256 #stack starts at end of memory FILO #flags #nil nil nil nil nil nil negative zero import numpy as np import opcodes as ops from registers import Registers np.set_printoptions(threshold=np.inf) class ZombieCPU: _regs = Registers() def __init__(self, memorysize=None, debug=None): self._memorysize = memorysize self._memory = np.zeros(memorysize) self._debug = debug def reset(self): if self._debug: print('Processor Reseting') self._memory = np.zeros(self._memorysize) #clear memory self._regs.esp = self._memorysize - 1 #set stackpointer self._regs.eip = 256 #set instructiojn pointer #fuck you thomas print(self._regs.eip) def exec(self): Halted = False while not Halted: #change this to if not halt #fetch opcode = self._memory[int(self._regs.eip)] address = self._memory[int(self._regs.eip + 1)] value = self._memory[int(self._regs.eip + 2)] if self._debug: print(f'Opcode: {opcode}\nAddress: {address}\nValue: {value}\nIP: {self._regs.eip}') if opcode == ops.NOP: pass elif opcode == ops.HLT: Halted = True if self._debug: print('Processor Halted') elif opcode == ops.RST: #reset self.reset() elif opcode == ops.DBG: #debug toggle self._debug = value elif opcode == ops.LDI: #mov but actually load immediate self.write_memory(address, value) if value == 0: self._regs.flags = self._regs.flags | 0b00000001 else: print('unset flag here (you shouldnt be reading this!) (zero)') if value < 0: self._regs.flags = self._regs.flags | 0b00000010 else: print('unset flag here (you shouldnt be reading this!) (neg)') elif opcode == ops.PUSH: #push self.write_memory(self._regs.esp, value) #put value onto stack self._regs.esp -= 1 #dec stackpointer elif opcode == ops.POP: #pop self.write_memory(address, self.read_memory_address(self._regs.esp + 1)) #read the last value and put it into address (not the empty space) self._regs.esp += 1 #inc stackpointer elif opcode == ops.JMP: self._regs.eip = address - 3 elif opcode == ops.JZ: if self._regs.flags & 0b00000001: self._regs.eip = address - 3 elif opcode == ops.CMP: if address - value == 0: self._regs.flags = self._regs.flags | 0b00000001 #set zero flag else: print('unset flag here (you shouldnt be reading this!) (zero)') print(self._regs.flags) self._regs.eip += 3 #increment instruction pointer def set_memory(self, memory): self._memory = memory def write_memory(self, address, value): self._memory[int(address)] = value def read_memory(self): return self._memory def read_memory_address(self, address): return self._memory[int(address)] def read_flags(self, i): return self._regs if __name__ == "__main__": cpu = ZombieCPU(65536, False) cpu.reset() #hard coded opcodes cpu.write_memory(256, ops.LDI) #mov cpu.write_memory(257, 27) #address 27 cpu.write_memory(258, 105) #105 into ^ cpu.write_memory(259, ops.PUSH) #push cpu.write_memory(260, 0) #unused in this op cpu.write_memory(261, 27) #the value at address 27 onto the stack cpu.write_memory(262, ops.POP) #pop cpu.write_memory(263, 100) #into 100 cpu.write_memory(264, 0) #unused in this op cpu.write_memory(265, ops.CMP) cpu.write_memory(266, 10) cpu.write_memory(267, 11) #should set the zero flag cpu.write_memory(268, ops.HLT) cpu.exec() #c = Console(cpu.read_memory()) ima finish this later #c.draw()