もう一度しっかり作ろうってことで。
MEMORY_SIZE = 0xffff
class Memory:
def __init__(self):
self.memory = bytearray([0] * MEMORY_SIZE)
def get(self, addr):
return self.memory[addr]
def set(self, addr, value):
self.memory[addr] = value & 0xff
def get_word(self, addr):
return self.get(addr) | self.get(addr + 1) << 8
def set_word(self, addr, value):
self.set(addr, (value & 0xff))
self.set(addr + 1, (value >> 8))
class Register:
def __init__(self, memory):
# B C D E H L (M) A F SP PC
self.register = bytearray([0] * 13)
self.memory = memory
def get(self, index):
return self.register[index]
def set(self, index, value):
self.register[index] = value & 0xff
if index == 6:
self.memory.set(self.get_word(2), value)
if index == 4 or index == 5:
self.update()
def get_word(self, index):
# BC DE HL AF SP PC
if index < 3:
hval = self.get(index<<1)
lval = self.get((index<<1)+1)
else:
hval = self.get((index<<1)+1)
lval = self.get((index<<1)+2)
return lval << 8 | hval
def set_word(self, index, value):
# BC DE HL AF SP PC
hval = value & 0xff
lval = value >> 8
if index < 3:
self.set(index<<1, hval)
self.set((index<<1)+1, lval)
else:
self.set((index<<1)+1, hval)
self.set((index<<1)+2, lval)
def update(self):
self.register[6] = self.memory.get(self.get_word(2))
def monitor(self):
print("B %02x C %02x" % (self.register[0], self.register[1]))
print("D %02x E %02x" % (self.register[2], self.register[3]))
print("H %02x L %02x" % (self.register[4], self.register[5]))
print("M %02x " % (self.register[6],))
print("A %02x F %02x" % (self.register[7], self.register[8]))
print("SP %04x" % self.get_word(4))
print("PC %04x" % self.get_word(5))
勢いでここまで書いた。 レジスタクラスにメモリクラスのインスタンスを渡すようにしてあるけれどどうなんだこれとちょっと思う。
if __name__ == "__main__":
m = Memory()
r = Register(m)
r.set_word(0, 0x1122)
r.set_word(1, 0x3344)
r.set_word(2, 0x5566)
r.set_word(3, 0x7788)
r.set_word(4, 0x99aa)
r.set_word(5, 0xbbcc)
r.monitor()
ひとまずのテストコード。 今日はここまで。
CPUクラスに着手。混乱しがちな fetch と push/pop を実装
それとpythonでは問題になる8bit、16bitの値の補正用の関数としてa16とa8を実装
CPUクラスの初期化にはMemoryとRegisterそれぞれのインスタンスを必要とするので以下の様に実行する