[pypy-svn] r54422 - in pypy/branch/gameboy-emulator/pypy/lang/gameboy: . test
cami at codespeak.net
cami at codespeak.net
Sun May 4 22:55:18 CEST 2008
Author: cami
Date: Sun May 4 22:55:17 2008
New Revision: 54422
Modified:
pypy/branch/gameboy-emulator/pypy/lang/gameboy/cpu.py
pypy/branch/gameboy-emulator/pypy/lang/gameboy/test/test_cpu.py
Log:
finished cpu testing
fixed some bugs in the fetch execute opCodes
Modified: pypy/branch/gameboy-emulator/pypy/lang/gameboy/cpu.py
==============================================================================
--- pypy/branch/gameboy-emulator/pypy/lang/gameboy/cpu.py (original)
+++ pypy/branch/gameboy-emulator/pypy/lang/gameboy/cpu.py Sun May 4 22:55:17 2008
@@ -311,10 +311,10 @@
def isNotN(self):
return not self.isN()
-
- # Flags ............................................
-
+
def setROM(self, banks):
+
+ # Flags ............................................
self.rom = banks
def emulate(self, ticks):
@@ -323,8 +323,8 @@
while self.cycles > 0:
self.execute(self.fetch())
- # Interrupts
def handlePendingInterrupt(self):
+ # Interrupts
if self.halted:
if self.interrupt.isPending():
self.halted = False
@@ -342,28 +342,28 @@
flag.setPending(False)
return
- # Execution
def fetchExecute(self):
+ # Execution
FETCH_EXECUTE_OP_CODES[self.fetch()](self)
def execute(self, opCode):
OP_CODES[opCode](self)
- # memory Access, 1 cycle
def read(self, hi, lo=None):
+ # memory Access, 1 cycle
address = hi
if lo != None:
address = (hi << 8) + lo
self.cycles -= 1
return self.memory.read(address)
- # 2 cycles
def write(self, address, data):
+ # 2 cycles
self.memory.write(address, data)
self.cycles -= 2
- # Fetching 1 cycle
def fetch(self, useCycles=True):
+ # Fetching 1 cycle
self.cycles += 1
if self.pc.get(useCycles) <= 0x3FFF:
data = self.rom[self.pc.get(useCycles)]
@@ -380,25 +380,25 @@
def fetchDoubleRegister(self, register):
self.popDoubleRegister(CPU.fetch, register)
- # Stack, 2 cycles
def push(self, data, useCycles=True):
+ # Stack, 2 cycles
self.sp.dec(useCycles) # 2 cycles
self.memory.write(self.sp.get(useCycles), data)
- # PUSH rr 4 cycles
def pushDoubleRegister(self, register, useCycles=True):
+ # PUSH rr 4 cycles
self.push(register.getHi(), useCycles) # 2 cycles
self.push(register.getLo(), useCycles) # 2 cycles
- # 1 cycle
def pop(self):
+ # 1 cycle
data = self.memory.read(self.sp.get())
self.sp.inc() # 2 cycles
self.cycles += 1
return data
- # 3 cycles
def popDoubleRegister(self, getter, register=None):
+ # 3 cycles
if register == None:
register = getter
getter = CPU.pop
@@ -407,38 +407,38 @@
register.set(a, b) # 2 cycles
self.cycles += 1
- # 4 cycles
def call(self, address, useCycles=True):
+ # 4 cycles
self.push(self.pc.getHi(useCycles), useCycles) # 2 cycles
self.push(self.pc.getLo(useCycles), useCycles) # 2 cycles
self.pc.set(address, None, useCycles) # 1 cycle
if useCycles:
self.cycles += 1
- # 1 cycle
def ld(self, getter, setter):
+ # 1 cycle
setter(getter()) # 1 cycle
def loadFetchRegister(self, register):
self.ld(self.fetch, register.set)
- # LD PC,HL, 1 cycle
def storeHlInPC(self):
+ # LD PC,HL, 1 cycle
self.ld(self.hl.get, self.pc.set)
def fetchLoad(self, getter, setter):
self.ld(self.fetch, setter)
- # ALU, 1 cycle
def addA(self, getter, setter=None):
+ # ALU, 1 cycle
added = (self.a.get() + getter()) & 0xFF
self.f.zFlagCompare(added, reset=True)
self.f.hFlagCompare(added, self.a)
self.f.cFlagCompare(added, self.a)
self.a.set(added) # 1 cycle
- # 2 cycles
def addHL(self, register):
+ # 2 cycles
added = (self.hl.get() + register.get()) & 0xFFFF # 1 cycle
self.f.reset(keepZ=True)
self.f.hFlagCompare((added >> 8), self.hl)
@@ -446,16 +446,16 @@
self.hl.set(added)
self.cycles -= 1
- # 1 cycle
def addWithCarry(self, getter, setter=None):
+ # 1 cycle
data = getter()
s = self.a.get() + data
if self.f.cFlag:
s +=1
self.carryFlagFinish(s,data)
- # 1 cycle
def subtractWithCarry(self, getter, setter=None):
+ # 1 cycle
data = getter()
s = self.a.get() - data
if self.f.cFlag:
@@ -473,8 +473,8 @@
self.f.zFlagCompare(s)
self.a.set(s) # 1 cycle
- # 1 cycle
def subtractA(self, getter, setter=None):
+ # 1 cycle
self.compareA(getter, setter) # 1 cycle
self.a.sub(getter(useCycles=False), False)
@@ -482,8 +482,8 @@
data = self.fetch()
self.subtractA(lambda useCycles=False: data)
- # 1 cycle
def compareA(self, getter, setter=None):
+ # 1 cycle
s = (self.a.get() - getter()) & 0xFF
self.f.reset()
self.f.nFlag = True
@@ -496,18 +496,18 @@
self.f.cFlag = True
self.f.hFlagCompare(self.a, data)
- # 1 cycle
def AND(self, getter, setter=None):
+ # 1 cycle
self.a.set(self.a.get() & getter()) # 1 cycle
self.f.zFlagCompare(self.a, reset=True)
- # 1 cycle
def XOR(self, getter, setter=None):
+ # 1 cycle
self.a.set( self.a.get() ^ getter()) # 1 cycle
self.f.zFlagCompare(self.a, reset=True)
- # 1 cycle
def OR(self, getter, setter=None):
+ # 1 cycle
self.a.set(self.a.get() | getter()) # 1 cycle
self.f.zFlagCompare(self.a, reset=True)
@@ -517,13 +517,13 @@
def decDoubleRegister(self, doubleRegister):
doubleRegister.dec()
- # 1 cycle
def inc(self, getter, setter):
+ # 1 cycle
data = (getter() + 1) & 0xFF
self.decIncFlagFinish(data, setter, 0x00)
- # 1 cycle
def dec(self, getter, setter):
+ # 1 cycle
data = (getter() - 1) & 0xFF
self.decIncFlagFinish(data, setter, 0x0F)
self.f.nFlag = True
@@ -535,98 +535,104 @@
self.f.hFlag = True
setter(data) # 1 cycle
- # RLC 1 cycle
def rotateLeftCircular(self, getter, setter):
+ print "rotateLeftCircular", setter, self.cycles
+ # RLC 1 cycle
data = getter()
s = (data << 1) + (data >> 7)
self.flagsAndSetterFinish(s, setter, 0x80)
+ print self.cycles
+ #self.cycles -= 1
- # RLCA rotateLeftCircularA 1 cycle
def rotateLeftCircularA(self):
+ # RLCA rotateLeftCircularA 1 cycle
self.rotateLeftCircular(self.a.get, self.a.set)
- # 1 cycle
def rotateLeft(self, getter, setter):
- s = ((getter() & 0x7F) << 1)
+ # 1 cycle
+ s = (getter() << 1) & 0xFF
if self.f.cFlag:
s += 0x01
self.flagsAndSetterFinish(s, setter, 0x80) # 1 cycle
- # RLA 1 cycle
def rotateLeftA(self):
+ # RLA 1 cycle
self.rotateLeft(self.a.get, self.a.set)
- # RRC 1 cycle
def rotateRightCircular(self, getter, setter):
- s = (getter() >> 1) + (getter() << 7)
+ data = getter()
+ # RRC 1 cycle
+ s = (data >> 1) + ((data & 0x01) << 7)
self.flagsAndSetterFinish(s, setter) # 1 cycle
- # RRCA 1 cycle
def rotateRightCircularA(self):
+ # RRCA 1 cycle
self.rotateRightCircular(self.a.get, self.a.set)
- # 1 cycle
def rotateRight(self, getter, setter):
+ # 1 cycle
s = (getter() >> 1)
if self.f.cFlag:
s += 0x08
self.flagsAndSetterFinish(s, setter) # 1 cycle
- # RRA 1 cycle
def rotateRightA(self):
+ # RRA 1 cycle
self.rotateRight(self.a.get, self.a.set)
- # 2 cycles
def shiftLeftArithmetic(self, getter, setter):
+ # 2 cycles
s = (getter() << 1) & 0xFF
self.flagsAndSetterFinish(s, setter, 0x80) # 1 cycle
- # 1 cycle
def shiftRightArithmetic(self, getter, setter):
- s = (getter() >> 1) + (getter() & 0x80)
+ data = getter()
+ # 1 cycle
+ s = (data >> 1) + (data & 0x80)
self.flagsAndSetterFinish(s, setter) # 1 cycle
- # 2 cycles
def shiftWordRightLogical(self, getter, setter):
+ # 2 cycles
s = (getter() >> 1)
self.flagsAndSetterFinish(s, setter) # 2 cycles
- # 2 cycles
def flagsAndSetterFinish(self, s, setter, compareAnd=0x01):
+ # 2 cycles
s &= 0xFF
self.f.zFlagCompare(s, reset=True)
self.f.cFlagAdd(s, compareAnd)
setter(s) # 1 cycle
- # 1 cycle
def swap(self, getter, setter):
- s = ((getter() << 4) + (getter() >> 4)) & 0xFF
+ data = getter()
+ # 1 cycle
+ s = ((data << 4) + (data >> 4)) & 0xFF
self.f.zFlagCompare(s, reset=True)
setter(s)
- # 2 cycles
def testBit(self, getter, setter, n):
+ # 2 cycles
self.f.reset(keepC=True)
self.f.hFlag = True
+ self.f.zFlag = False
if (getter() & (1 << n)) == 0:
self.f.zFlag = True
- self.cycles -= 2
+ self.cycles -= 1
- # 2 cycles
def setBit(self, getter, setter, n):
- self.cycles -= 1 # 1 cycle
+ # 1 cycle
setter(getter() | (1 << n)) # 1 cycle
- # 1 cycle
def resetBit(self, getter, setter, n):
+ # 1 cycle
setter(getter() & (~(1 << n))) # 1 cycle
- # LD A,(nnnn), 4 cycles
def storeFetchedMemoryInA(self):
+ # LD A,(nnnn), 4 cycles
self.a.set(self.read(self.fetchDoubleAddress())) # 1+1 + 2 cycles
- # 2 cycles
def writeAAtBCAddress(self):
+ # 2 cycles
self.write(self.bc.get(), self.a.get())
def writeAAtDEAddress(self):
@@ -638,74 +644,74 @@
def storeMemoryAtDEInA(self):
self.a.set(self.read(self.de.get()))
- # LD (rr),A 2 cycles
def ld_dbRegisteri_A(self, register):
+ # LD (rr),A 2 cycles
self.write(register.get(), self.a.get()) # 2 cycles
- # LD (nnnn),SP 5 cycles
def load_mem_SP(self):
+ # LD (nnnn),SP 5 cycles
address = self.fetchDoubleAddress() # 2 cycles
self.write(address, self.sp.getLo()) # 2 cycles
self.write((address + 1), self.sp.getHi()) # 2 cycles
self.cycles += 1
- # LD (nnnn),A 4 cycles
def storeAAtFetchedAddress(self):
+ # LD (nnnn),A 4 cycles
self.write(self.fetchDoubleAddress(), self.a.get()) # 2 cycles
- # LDH A,(nn) 3 cycles
def storeMemoryAtExpandedFetchAddressInA(self):
+ # LDH A,(nn) 3 cycles
self.a.set(self.read(0xFF00 + self.fetch())) # 1+1+1 cycles
- # LDH A,(C) 2 cycles
def storeExpandedCinA(self):
+ # LDH A,(C) 2 cycles
self.a.set(self.read(0xFF00 + self.bc.getLo())) # 1+2 cycles
- # loadAndIncrement A,(HL) 2 cycles
def loadAndIncrement_A_HLi(self):
+ # loadAndIncrement A,(HL) 2 cycles
self.a.set(self.read(self.hl.get())) # 2 cycles
self.hl.inc()# 2 cycles
self.cycles += 2
- # loadAndDecrement A,(HL) 2 cycles
def loadAndDecrement_A_HLi(self):
+ # loadAndDecrement A,(HL) 2 cycles
self.a.set(self.read(self.hl.get())) # 2 cycles
self.hl.dec() # 2 cycles
self.cycles += 2
- # LDH (nn),A 3 cycles
def writeAatExpandedFetchAddress(self):
+ # LDH (nn),A 3 cycles
self.write(0xFF00 + self.fetch(), self.a.get()) # 2 + 1 cycles
- # LDH (C),A 2 cycles
def writeAAtExpandedCAddress(self):
+ # LDH (C),A 2 cycles
self.write(0xFF00 + self.bc.getLo(), self.a.get()) # 2 cycles
- # loadAndIncrement (HL),A 2 cycles
def loadAndIncrement_HLi_A(self):
+ # loadAndIncrement (HL),A 2 cycles
self.write(self.hl.get(), self.a.get()) # 2 cycles
self.hl.inc() # 2 cycles
self.cycles += 2
- # loadAndDecrement (HL),A 2 cycles
def loadAndDecrement_HLi_A(self):
+ # loadAndDecrement (HL),A 2 cycles
self.write(self.hl.get(), self.a.get()) # 2 cycles
self.hl.dec() # 2 cycles
self.cycles += 2
- # LD SP,HL 2 cycles
def storeHlInSp(self):
+ # LD SP,HL 2 cycles
self.sp.set(self.hl.get()) # 1 cycle
self.cycles -= 1
- # CPA
def complementA(self):
+ # CPA
self.a.set(self.a.get() ^ 0xFF)
self.f.nFlag = True
self.f.hFlag = True
- # DAA 1 cycle
def decimalAdjustAccumulator(self):
+ # DAA 1 cycle
delta = 0
if self.isH():
delta |= 0x06
@@ -726,26 +732,26 @@
self.f.cFlag = True
self.f.zFlagCompare(self.a)
- # INC rr
def incDoubleRegister(self, register):
+ # INC rr
register.inc()
- # DEC rr
def decDoubleRegister(self, register):
+ # DEC rr
register.dec()
- # ADD SP,nn 4 cycles
def incrementSPByFetch(self):
+ # ADD SP,nn 4 cycles
self.sp.set(self.getFetchAddedSP()) # 1+1 cycle
self.cycles -= 2
- # LD HL,SP+nn 3 cycles
def storeFetchAddedSPInHL(self):
+ # LD HL,SP+nn 3 cycles
self.hl.set(self.getFetchAddedSP()) # 1+1 cycle
self.cycles -= 1
- # 1 cycle
def getFetchAddedSP(self):
+ # 1 cycle
offset = self.fetch() # 1 cycle
s = (self.sp.get() + offset) & 0xFFFF
self.f.reset()
@@ -761,8 +767,8 @@
self.f.hFlag = True
return s
- # CCF/SCF
def complementCarryFlag(self):
+ # CCF/SCF
self.f.reset(keepZ=True, keepC=True)
self.f.cFlag = not self.f.cFlag
@@ -770,53 +776,53 @@
self.f.reset(keepZ=True)
self.f.cFlag = True
- # NOP 1 cycle
def nop(self):
+ # NOP 1 cycle
self.cycles -= 1
- # JP nnnn, 4 cycles
def unconditionalJump(self):
+ # JP nnnn, 4 cycles
self.pc.set(self.fetchDoubleAddress()) # 1+2 cycles
self.cycles -= 1
- # JP cc,nnnn 3,4 cycles
def conditionalJump(self, cc):
+ # JP cc,nnnn 3,4 cycles
if cc:
self.unconditionalJump() # 4 cycles
else:
self.pc.add(2) # 3 cycles
- # JR +nn, 3 cycles
def relativeUnconditionalJump(self):
+ # JR +nn, 3 cycles
self.pc.add(self.fetch()) # 3 + 1 cycles
self.cycles += 1
- # JR cc,+nn, 2,3 cycles
def relativeConditionalJump(self, cc):
+ # JR cc,+nn, 2,3 cycles
if cc:
self.relativeUnconditionalJump() # 3 cycles
else:
self.pc.inc() # 2 cycles
- # CALL nnnn, 6 cycles
def unconditionalCall(self):
+ # CALL nnnn, 6 cycles
self.call(self.fetchDoubleAddress()) # 4+2 cycles
- # CALL cc,nnnn, 3,6 cycles
def conditionalCall(self, cc):
+ # CALL cc,nnnn, 3,6 cycles
if cc:
self.unconditionalCall() # 6 cycles
else:
self.pc.add(2) # 3 cycles
- # RET 4 cycles
def ret(self):
+ # RET 4 cycles
lo = self.pop() # 1 cycle
hi = self.pop() # 1 cycle
self.pc.set(hi, lo) # 2 cycles
- # RET cc 2,5 cycles
def conditionalReturn(self, cc):
+ # RET cc 2,5 cycles
if cc:
self.ret() # 4 cycles
# FIXME maybe this should be the same
@@ -824,54 +830,65 @@
else:
self.cycles -= 2
- # RETI 4 cycles
def returnFormInterrupt(self):
+ # RETI 4 cycles
self.ret() # 4 cycles
self.enableInterrupts() # 1 cycle + others
self.cycles += 1
- # RST nn 4 cycles
def restart(self, nn):
+ # RST nn 4 cycles
self.call(nn) # 4 cycles
- # DI/EI 1 cycle
def disableInterrupts(self):
+ # DI/EI 1 cycle
self.ime = False
self.cycles -= 1
- # 1 cycle
def enableInterrupts(self):
+ # 1 cycle
self.ime = True
self.execute(self.fetch()) # 1
self.handlePendingInterrupt()
- # HALT/STOP
def halt(self):
+ # HALT/STOP
self.halted = True
# emulate bug when interrupts are pending
if (not self.ime and self.interrupt.isPending()):
self.execute(self.memory.read(self.pc.get()))
self.handlePendingInterrupt()
- # 0 cycles
def stop(self):
+ # 0 cycles
self.cycles += 1
self.fetch()
+# ------------------------------------------------------------------------------
# OPCODE LOOKUP TABLE GENERATION -----------------------------------------------
+
GROUPED_REGISTERS = (CPU.getB, CPU.getC, CPU.getD, CPU.getE, CPU.getH, CPU.getL, CPU.getHLi, CPU.getA)
+
def create_group_op_codes(table):
opCodes =[]
for entry in table:
- opCode = entry[0]
- step = entry[1]
+ opCode = entry[0]
+ step = entry[1]
function = entry[2]
if len(entry) == 4:
for registerGetter in GROUPED_REGISTERS:
for n in entry[3]:
opCodes.append((opCode, group_lambda(function, registerGetter, n)))
opCode += step
+ if len(entry) == 5:
+ entryStep = entry[4]
+ for registerGetter in GROUPED_REGISTERS:
+ stepOpCode = opCode
+ for n in entry[3]:
+ opCodes.append((stepOpCode, group_lambda(function, registerGetter, n)))
+ stepOpCode += entryStep
+ opCode+=step
else:
for registerGetter in GROUPED_REGISTERS:
opCodes.append((opCode,group_lambda(function, registerGetter)))
@@ -884,9 +901,10 @@
else:
return lambda s: function(s, registerGetter(s).get, registerGetter(s).set, value)
+
def create_load_group_op_codes():
opCodes = []
- opCode = 0x40
+ opCode = 0x40
for storeRegister in GROUPED_REGISTERS:
for loadRegister in GROUPED_REGISTERS:
if loadRegister != CPU.getHLi or storeRegister != CPU.getHLi:
@@ -897,6 +915,7 @@
def load_group_lambda(storeRegister, loadRegister):
return lambda s: CPU.ld(s, loadRegister(s).get, storeRegister(s).set)
+
def create_register_op_codes(table):
opCodes = []
for entry in table:
@@ -914,6 +933,7 @@
else:
return lambda s: function(s, registerOrGetter)
+
def initialize_op_code_table(table):
result = [None] * (0xFF+1)
for entry in table:
@@ -1027,9 +1047,9 @@
(0x28, 0x01, CPU.shiftRightArithmetic),
(0x30, 0x01, CPU.swap),
(0x38, 0x01, CPU.shiftWordRightLogical),
- (0x40, 0x01, CPU.testBit, range(0, 8)),
- (0xC0, 0x01, CPU.setBit, range(0, 8)),
- (0x80, 0x01, CPU.resetBit, range(0, 8))
+ (0x40, 0x01, CPU.testBit, range(0, 8), 0x08),
+ (0xC0, 0x01, CPU.setBit, range(0, 8), 0x08),
+ (0x80, 0x01, CPU.resetBit, range(0, 8), 0x08)
]
# RAW OPCODE TABLE INITIALIZATION ----------------------------------------------
Modified: pypy/branch/gameboy-emulator/pypy/lang/gameboy/test/test_cpu.py
==============================================================================
--- pypy/branch/gameboy-emulator/pypy/lang/gameboy/test/test_cpu.py (original)
+++ pypy/branch/gameboy-emulator/pypy/lang/gameboy/test/test_cpu.py Sun May 4 22:55:17 2008
@@ -28,7 +28,7 @@
TEST_CPU.reset()
return TEST_CPU
-# ------------------------------------------------------------
+# ------------------------------------------------------------------------------
# TEST CPU
@@ -140,21 +140,27 @@
prepare_for_fetch(cpu, opCode)
cycle_test(cpu, 0xCB, cycles)
-def cycle_test(cpu, opCode, cycles=0):
+def cycle_test(cpu, opCode, cycles=0, opCodeDisplay=None):
+ if opCodeDisplay==None:
+ opCodeDisplay = hex(opCode)
startCycles = cpu.cycles
try:
cpu.execute(opCode)
except Exception, inst:
- assert False, "Opcode %s %s failed to execute: %s" % (hex(opCode), OP_CODES[opCode], inst)
+ assert False, "Opcode %s %s failed to execute: %s" % (opCodeDisplay, OP_CODES[opCode], inst)
cpuUsedCycles = startCycles-cpu.cycles
assert cpuUsedCycles == cycles,\
"Cycles for opCode %s [CPU.%s] should be %i not %i" %\
- (hex(opCode).ljust(2),\
+ ((opCodeDisplay).ljust(2),\
OP_CODES[opCode],\
cycles, cpuUsedCycles)
-# TEST HELPERS ---------------------------------------
+def fetch_execute_cycle_test_second_order(cpu, opCode, cycles=0):
+ prepare_for_fetch(cpu, opCode)
+ cycle_test(cpu, 0xCB, cycles, "[0xCB -> "+hex(opCode)+"]")
+
+# TEST HELPERS -----------------------------------------------------------------
def test_create_group_op_codes():
assert len(GROUPED_REGISTERS) == 8
@@ -268,7 +274,7 @@
register.set(value);
-# test helper methods ---------------------------------------------------------
+# test helper methods ----------------------------------------------------------
def test_prepare_for_pop():
cpu = get_cpu()
@@ -284,7 +290,7 @@
assert cpu.fetch() == value+1
assert cpu.fetch() == value
-# ------------------------------------------------------------
+# ------------------------------------------------------------------------------
# opCode Testing
#nop
@@ -1522,7 +1528,12 @@
# switching to other opcode set
def test_0xCB():
- pass
+ cpu = get_cpu()
+ pc = cpu.pc.get()
+ prepare_for_fetch(cpu, 0x80)
+ cycle_test(cpu, 0xCB, 2)
+ assert_default_registers(cpu, pc=pc+1)
+
def test_rotateLeftCircular_flags():
cpu = get_cpu()
@@ -1538,70 +1549,128 @@
assert_default_flags(cpu, zFlag=False, cFlag=True)
assert_default_registers(cpu, a=0x80, f=None)
-# rlc_B to rlc_A
-def test_0x00_to_0x07_rotateLeftCircular():
+
+# SECOND ORDER OPCODES ---------------------------------------------------------
+
+def second_order_test(opCode, createFunction):
cpu = get_cpu()
registers = [cpu.b, cpu.c, cpu.d, cpu.e, cpu.h, cpu.l, cpu.hli, cpu.a]
- opCode = 0x00
- value = 0x12
+ value = 0xF0
for register in registers:
cpu.reset()
register.set(value)
cycles = 2
if register == cpu.hli:
cycles = 4
- fetch_execute_cycle_test(cpu, opCode, cycles)
- rlc = ((value & 0x7F) << 1) + ((value & 0x80) >> 7)
- assert register.get() == rlc
+ fetch_execute_cycle_test_second_order(cpu, opCode, cycles)
+ assert register.get() == createFunction(value)
opCode += 0x01
value += 1
+# rlc_B to rlc_A
+def test_0x00_to_0x07_rotateLeftCircular():
+ second_order_test(0x00, lambda value:((value & 0x7F) << 1) + ((value & 0x80) >> 7))
+
# rrc_B to rrc_F
-def test_0x08_to_0x0F():
- cpu = get_cpu()
- opCode = 0x38
+def test_0x08_to_0x0F_rotateRightCircular():
+ second_order_test(0x08, lambda value:(value >> 1) + ((value & 0x01) << 7))
# rl_B to rl_A
-def test_0x10_to_0x17():
- cpu = get_cpu()
- opCode = 0x38
+def test_0x10_to_0x17_shift_left():
+ second_order_test(0x10, lambda value: (value << 1) & 0xFF )
# rr_B to rr_A
-def test_0x18_to_0x1F():
- cpu = get_cpu()
- opCode = 0x38
+def test_0x18_to_0x1F_shift_right():
+ second_order_test(0x18, lambda value: value >> 1)
# sla_B to sla_A
-def test_0x20_to_0x27():
- cpu = get_cpu()
- opCode = 0x38
+def test_0x20_to_0x27_shift_left_arithmetic():
+ second_order_test(0x20, lambda value: (value << 1) & 0xFF)
# sra_B to sra_A
-def test_0x28_to_0x2F():
- cpu = get_cpu()
- opCode = 0x38
+def test_0x28_to_0x2F_shift_right_arithmetic():
+ second_order_test(0x28, lambda value: (value >> 1) + (value & 0x80))
# swap_B to swap_A
def test_0x30_to_0x37():
- cpu = get_cpu()
- opCode = 0x38
+ second_order_test(0x30, lambda value: ((value << 4) + (value >> 4)) & 0xFF)
# srl_B to srl_A
-def test_0x38_to_0x3F():
- cpu = get_cpu()
- opCode = 0x38
+def test_0x38_to_0x3F_shift_word_right_logical():
+ second_order_test(0x38, lambda value: value >> 1)
# bit_B to bit_A
-def test_bit_opCodes():
+def test_testBit_opCodes():
+ cpu = get_cpu()
+ registers = [cpu.b, cpu.c, cpu.d, cpu.e, cpu.h, cpu.l, cpu.hli, cpu.a]
opCode = 0x40
+ for register in registers:
+ registerOpCode = opCode
+ for i in range(8):
+ cycles = 2
+ if register == cpu.hli:
+ cycles = 3
+
+ cpu.reset()
+ register.set(0)
+ fetch_execute_cycle_test_second_order(cpu, registerOpCode, cycles)
+ assert cpu.f.zFlag == True
+
+ cpu.reset()
+ register.set((1<<i))
+ fetch_execute_cycle_test_second_order(cpu, registerOpCode, cycles)
+ assert cpu.f.zFlag == False
+
+ registerOpCode += 0x08
+ opCode += 0x01
# set_B to set_C
-def test_set_opCodes():
+def test_setBit_opCodes():
+ cpu = get_cpu()
+ registers = [cpu.b, cpu.c, cpu.d, cpu.e, cpu.h, cpu.l, cpu.hli, cpu.a]
+ value = 0x12
opCode = 0xC0
+ for register in registers:
+ registerOpCode = opCode
+ for i in range(8):
+ cycles = 2
+ if register == cpu.hli:
+ cycles = 4
+
+ cpu.reset()
+ register.set(0)
+ fetch_execute_cycle_test_second_order(cpu, registerOpCode, cycles)
+ assert (register.get() & (1<<i)) >> i == 1
+ fetch_execute_cycle_test_second_order(cpu, registerOpCode, cycles)
+ assert (register.get() & (1<<i)) >> i == 1
+ registerOpCode += 0x08
+ opCode += 0x01
# res_B to res_A
-def test_res_opCodes():
+def test_resetBit_opCodes():
+ cpu = get_cpu()
+ registers = [cpu.b, cpu.c, cpu.d, cpu.e, cpu.h, cpu.l, cpu.hli, cpu.a]
+ value = 0x12
opCode = 0x80
+ for register in registers:
+ registerOpCode = opCode
+ cycles = 2
+ if register == cpu.hli:
+ cycles = 4
+
+ for i in range(8):
+ cpu.reset()
+ register.set(0)
+ fetch_execute_cycle_test_second_order(cpu, registerOpCode, cycles)
+ assert (register.get() & (1<<i)) == 0
+ register.set(0xFF)
+ fetch_execute_cycle_test_second_order(cpu, registerOpCode, cycles)
+ print register.get(), (register.get() & (1<<i)), hex(registerOpCode) ,i
+ print
+ assert (register.get() & (1<<i)) == 0
+
+ registerOpCode += 0x08
+ opCode += 1
More information about the Pypy-commit
mailing list