[pypy-svn] r63249 - in pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy: . debug profiling test
cami at codespeak.net
cami at codespeak.net
Mon Mar 23 18:30:30 CET 2009
Author: cami
Date: Mon Mar 23 18:30:29 2009
New Revision: 63249
Added:
pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/debug/debug.py
- copied, changed from r58379, pypy/dist/pypy/lang/gameboy/debug/debug.py
pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/debug/debug_cpu.py
- copied unchanged from r58379, pypy/dist/pypy/lang/gameboy/debug/debug_cpu.py
pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py
- copied, changed from r58379, pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py
pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/gameboyImplementation.py
- copied unchanged from r54952, pypy/branch/gameboy-emulator/pypy/lang/gameboy/gameboyImplementation.py
pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/test/test_register.py (props changed)
- copied unchanged from r54952, pypy/branch/gameboy-emulator/pypy/lang/gameboy/test/test_register.py
Modified:
pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/cpu.py
pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/cpu_register.py
pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/gameboy.py
pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/gameboy_implementation.py
pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/profiling/gameboy_profiling_implementation.py
pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/test/test_cpu.py
pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/test/test_cpu_register.py
pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/test/test_video.py
pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/video.py
Log:
mergin in the latest pyGirl
Modified: pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/cpu.py
==============================================================================
--- pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/cpu.py (original)
+++ pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/cpu.py Mon Mar 23 18:30:29 2009
@@ -1,7 +1,8 @@
from pypy.lang.gameboy import constants
from pypy.lang.gameboy.interrupt import Interrupt
-from pypy.lang.gameboy.cpu_register import Register, DoubleRegister, \
+from pypy.lang.gameboy.cpu_register import Register, DoubleRegister,\
+ ReservedDoubleRegister,\
FlagRegister, ImmediatePseudoRegister
# ---------------------------------------------------------------------------
@@ -50,8 +51,8 @@
self.hl = DoubleRegister(self, self.h, self.l, constants.RESET_HL)
self.hli = ImmediatePseudoRegister(self, self.hl)
- self.pc = DoubleRegister(self, Register(self), Register(self), reset_value=constants.RESET_PC)
- self.sp = DoubleRegister(self, Register(self), Register(self), reset_value=constants.RESET_SP)
+ self.pc = ReservedDoubleRegister(self, reset_value=constants.RESET_PC)
+ self.sp = ReservedDoubleRegister(self, reset_value=constants.RESET_SP)
self.a = Register(self, constants.RESET_A)
self.flag = FlagRegister(self, constants.RESET_F)
@@ -251,6 +252,7 @@
def fetch_double_register(self, register):
self.double_register_inverse_call(CPUFetchCaller(self), register)
+ self.cycles += 1
def push(self, data, use_cycles=True):
# Stack, 2 cycles
@@ -272,12 +274,11 @@
def pop_double_register(self, register):
# 3 cycles
self.double_register_inverse_call(CPUPopCaller(self), register)
+ self.cycles += 1
def double_register_inverse_call(self, getCaller, register):
- b = getCaller.get() # 1 cycle
- a = getCaller.get() # 1 cycle
- register.set_hi_lo(a, b) # 2 cycles
- self.cycles += 1
+ register.set_lo(getCaller.get()) # 2 cycles
+ register.set_hi(getCaller.get()) # 2 cycles
def call(self, address, use_cycles=True):
# 4 cycles
@@ -378,12 +379,14 @@
def xor_a(self, getCaller, setCaller=None):
# 1 cycle
self.a.set( self.a.get() ^ getCaller.get()) # 1 cycle
- self.flag.zero_check(self.a.get(), reset=True)
+ self.flag.reset()
+ self.flag.zero_check(self.a.get())
def or_a(self, getCaller, setCaller=None):
# 1 cycle
self.a.set(self.a.get() | getCaller.get()) # 1 cycle
- self.flag.zero_check(self.a.get(), reset=True)
+ self.flag.reset()
+ self.flag.zero_check(self.a.get())
def inc_double_register(self, register):
# INC rr
@@ -487,7 +490,8 @@
# 1 cycle
data = getCaller.get()
s = ((data << 4) + (data >> 4)) & 0xFF
- self.flag.zero_check(s, reset=True)
+ self.flag.reset()
+ self.flag.zero_check(s)
setCaller.set(s)
def test_bit(self, getCaller, setCaller, n):
@@ -685,9 +689,7 @@
def ret(self):
# RET 4 cycles
- lo = self.pop() # 1 cycle
- hi = self.pop() # 1 cycle
- self.pc.set_hi_lo(hi, lo) # 2 cycles
+ self.double_register_inverse_call(CPUPopCaller(self), self.pc)
def conditional_return(self, cc):
# RET cc 2,5 cycles
Modified: pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/cpu_register.py
==============================================================================
--- pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/cpu_register.py (original)
+++ pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/cpu_register.py Mon Mar 23 18:30:29 2009
@@ -1,114 +1,225 @@
-
# ---------------------------------------------------------------------------
class AbstractRegister(object):
+ def __init__(self):
+ self.invalid = False
+
def get(self, use_cycles=True):
- return 0xFF
+ self.check_sync()
+ return self._get(use_cycles)
+
+ def set(self, value, use_cycles=True):
+ self.check_sync()
+ self.invalidate_other()
+ self._set(value, use_cycles)
+
+ def sub(self, value, use_cycles=True):
+ self.check_sync()
+ self.invalidate_other()
+ return self._sub(value, use_cycles)
+
+ def add(self, value, use_cycles=True):
+ self.check_sync()
+ self.invalidate_other()
+ return self._add(value, use_cycles)
+
+ def _get(self, use_cycles):
+ raise Exception("not implemented")
+
+ def _set(self, value, use_cycles):
+ raise Exception("not implemented")
+
+ def _sub(self, value, use_cycles):
+ raise Exception("not implemented")
+
+ def _add(self, value, use_cycles):
+ raise Exception("not implemented")
+
+ def check_sync(self):
+ if self.invalid:
+ self.sync()
+
+ def invalidate_other(self):
+ raise Exception("not implemented")
+
+ def sync(self):
+ raise Exception("not implemented")
+
class Register(AbstractRegister):
- def __init__(self, cpu, value=0):
+ def __init__(self, cpu, value=0x00):
+ AbstractRegister.__init__(self)
# assert isinstance(cpu, CPU)
self.reset_value = self.value = value
+ self.double_register = None
self.cpu = cpu
if value != 0:
- self.set(value)
+ self._set(value)
def reset(self):
self.value = self.reset_value
- def set(self, value, use_cycles=True):
+ def sync(self):
+ if self.double_register is not None:
+ self.double_register.sync_registers()
+
+ def invalidate_other(self):
+ if self.double_register is not None:
+ self.double_register.invalid = True
+
+ def _set(self, value, use_cycles=True):
self.value = value & 0xFF
if use_cycles:
self.cpu.cycles -= 1
- def get(self, use_cycles=True):
+ def _get(self, use_cycles=True):
return self.value
- def add(self, value, use_cycles=True):
- self.set(self.get(use_cycles)+value, use_cycles)
+ def _add(self, value, use_cycles=True):
+ self._set(self._get(use_cycles) + value, use_cycles)
- def sub(self, value, use_cycles=True):
- self.set(self.get(use_cycles)-value, use_cycles)
+ def _sub(self, value, use_cycles=True):
+ self._set(self._get(use_cycles) - value, use_cycles)
#------------------------------------------------------------------------------
class DoubleRegister(AbstractRegister):
- def __init__(self, cpu, hi, lo, reset_value=0):
- #assert isinstance(cpu, CPU)
- #assert isinstance(lo, Register)
- #assert isinstance(hi, Register)
+ def __init__(self, cpu, hi, lo, reset_value=0x0000):
+ AbstractRegister.__init__(self)
self.cpu = cpu
+ self.invalid = True
+ self.reset_value = reset_value
self.hi = hi
self.lo = lo
- self.reset_value = reset_value
-
- def set(self, value, use_cycles=True):
- # previous = self.get(False)
- value = value & 0xFFFF
- self.set_hi(value >> 8, use_cycles)
- self.set_lo(value & 0xFF, use_cycles)
- if use_cycles:
- self.cpu.cycles += 1
+ self.hi.double_register = self
+ self.lo.double_register = self
+ self.value = 0x0000
- def set_hi_lo(self, hi, lo, use_cycles=True):
- self.set_hi(hi, use_cycles)
- self.set_lo(lo, use_cycles)
-
def reset(self):
self.set(self.reset_value, use_cycles=False)
+ def sync_registers(self):
+ self.hi._set(self.value >> 8, use_cycles=False)
+ self.hi.invalid = False
+ self.lo._set(self.value & 0xFF, use_cycles=False)
+ self.lo.invalid = False
+
+ def sync(self):
+ self.value = (self.hi._get(use_cycles=False)<<8) + \
+ self.lo._get(use_cycles=False)
+ self.invalid = False
+
+ def invalidate_other(self):
+ self.hi.invalid = True
+ self.lo.invalid = True
+
+ def _set(self, value, use_cycles=True):
+ self.value = value & 0xFFFF
+ if use_cycles:
+ self.cpu.cycles -= 1
+
def set_hi(self, hi=0, use_cycles=True):
self.hi.set(hi, use_cycles)
def set_lo(self, lo=0, use_cycles=True):
self.lo.set(lo, use_cycles)
- def get(self, use_cycles=True):
- return (self.hi.get(use_cycles)<<8) + self.lo.get(use_cycles)
+ def _get(self, use_cycles=True):
+ return self.value
def get_hi(self, use_cycles=True):
return self.hi.get(use_cycles)
def get_lo(self, use_cycles=True):
return self.lo.get(use_cycles)
-
+
def inc(self, use_cycles=True):
- self.set(self.get(use_cycles) +1, use_cycles=use_cycles)
+ self.add(1, use_cycles=False)
if use_cycles:
- self.cpu.cycles -= 1
-
+ self.cpu.cycles -= 2
+
def dec(self, use_cycles=True):
- self.set(self.get(use_cycles) - 1, use_cycles=use_cycles)
+ self.add(-1, use_cycles=False)
+ if use_cycles:
+ self.cpu.cycles -= 2
+
+ def _add(self, value, use_cycles=True):
+ self.value += value
+ self.value &= 0xFFFF
+ if use_cycles:
+ self.cpu.cycles -= 3
+
+#------------------------------------------------------------------------------
+
+class ReservedDoubleRegister(AbstractRegister):
+
+ def __init__(self, cpu, reset_value=0x0000):
+ AbstractRegister.__init__(self)
+ self.cpu = cpu
+ self.reset_value = reset_value
+ self.value = 0x0000
+
+ def reset(self):
+ self.set(self.reset_value, use_cycles=False)
+
+ def set(self, value, use_cycles=True):
+ self.value = value & 0xFFFF
if use_cycles:
self.cpu.cycles -= 1
+
+ def set_hi(self, hi=0, use_cycles=True):
+ self.set((hi << 8) + (self.value & 0xFF))
+
+ def set_lo(self, lo=0, use_cycles=True):
+ self.set((self.value & 0xFF00) + (lo & 0xFF))
- def add(self, value, use_cycles=True):
- self.set(self.get(use_cycles) + value, use_cycles=use_cycles)
+ def get(self, use_cycles=True):
+ return self.value
+
+ def get_hi(self, use_cycles=True):
+ return (self.value >> 8) & 0xFF
+
+ def get_lo(self, use_cycles=True):
+ return self.value & 0xFF
+
+ def inc(self, use_cycles=True):
+ self.add(1, use_cycles=False)
if use_cycles:
self.cpu.cycles -= 2
-
-
+
+ def dec(self, use_cycles=True):
+ self.add(-1, use_cycles=False)
+ if use_cycles:
+ self.cpu.cycles -= 2
+
+ def add(self, value, use_cycles=True):
+ self.value += value
+ self.value &= 0xFFFF
+ if use_cycles:
+ self.cpu.cycles -= 3
+
+
# ------------------------------------------------------------------------------
class ImmediatePseudoRegister(Register):
- def __init__(self, cpu, hl):
- #assert isinstance(cpu, CPU)
- self.cpu = cpu
- self.hl = hl
-
- def set(self, value, use_cycles=True):
- self.cpu.write(self.hl.get(use_cycles=use_cycles), value) # 2 + 0
- if not use_cycles:
- self.cpu.cycles += 2
-
- def get(self, use_cycles=True):
- if not use_cycles:
- self.cpu.cycles += 1
- result = self.cpu.read(self.hl.get(use_cycles=use_cycles)) # 1
- return result
+ def __init__(self, cpu, hl):
+ #assert isinstance(cpu, CPU)
+ self.cpu = cpu
+ self.hl = hl
+
+ def set(self, value, use_cycles=True):
+ self.cpu.write(self.hl.get(use_cycles=use_cycles), value) # 2 + 0
+ if not use_cycles:
+ self.cpu.cycles += 2
+
+ def get(self, use_cycles=True):
+ if not use_cycles:
+ self.cpu.cycles += 1
+ result = self.cpu.read(self.hl.get(use_cycles=use_cycles)) # 1
+ return result
# ------------------------------------------------------------------------------
@@ -149,14 +260,20 @@
(which do not affect C-flag).
"""
def __init__(self, cpu, reset_value):
+ Register.__init__(self, cpu)
#assert isinstance(cpu, CPU)
- self.cpu = cpu
self.reset_value = reset_value
self.reset()
def reset(self):
- self.partial_reset()
-
+ self.is_zero = False
+ self.is_subtraction = False
+ self.is_half_carry = False
+ self.is_carry = False
+ self.p_flag = False
+ self.s_flag = False
+ self.lower = 0x00
+
def partial_reset(self, keep_is_zero=False, keep_is_subtraction=False,
keep_is_half_carry=False, keep_is_carry=False,\
keep_p=False, keep_s=False):
@@ -174,16 +291,16 @@
self.s_flag = False
self.lower = 0x00
- def get(self, use_cycles=True):
+ def _get(self, use_cycles=True):
value = 0
- value += (int(self.is_carry) << 4)
- value += (int(self.is_half_carry) << 5)
- value += (int(self.is_subtraction) << 6)
- value += (int(self.is_zero) << 7)
+ value += (int(self.is_carry) << 4)
+ value += (int(self.is_half_carry) << 5)
+ value += (int(self.is_subtraction) << 6)
+ value += (int(self.is_zero) << 7)
return value + self.lower
- def set(self, value, use_cycles=True):
- self.is_carry = bool(value & (1 << 4))
+ def _set(self, value, use_cycles=True):
+ self.is_carry = bool(value & (1 << 4))
self.is_half_carry = bool(value & (1 << 5))
self.is_subtraction = bool(value & (1 << 6))
self.is_zero = bool(value & (1 << 7))
@@ -191,24 +308,13 @@
if use_cycles:
self.cpu.cycles -= 1
- def zero_check(self, a, reset=False):
- if reset:
- self.reset()
- if isinstance(a, (Register)):
- a = a.get()
- self.is_zero = ((a & 0xFF) == 0)
+ def zero_check(self, value):
+ self.is_zero = ((value & 0xFF) == 0)
def is_carry_compare(self, value, compare_and=0x01, reset=False):
if reset:
self.reset()
self.is_carry = ((value & compare_and) != 0)
- def is_half_carry_compare(self, value, a, inverted=False):
- if inverted:
- self.is_half_carry = ((value & 0x0F) < (a & 0x0F))
- else:
- self.is_half_carry = ((value & 0x0F) > (a & 0x0F))
-
- #def is_carry_compare(self, a, b):
- # self.is_carry = (a < b)
-
+ def is_half_carry_compare(self, new, old):
+ self.is_half_carry = (old & 0x0F) < (new & 0x0F)
Copied: pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/debug/debug.py (from r58379, pypy/dist/pypy/lang/gameboy/debug/debug.py)
==============================================================================
--- pypy/dist/pypy/lang/gameboy/debug/debug.py (original)
+++ pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/debug/debug.py Mon Mar 23 18:30:29 2009
@@ -1,4 +1,6 @@
import operator
+from pypy.lang.gameboy import cpu
+import pdb
DEBUG = True
DEBUG_PRINT_LOGS = True
@@ -86,16 +88,18 @@
CHECKED_OP_CODES = [0x00]
CHECKED_FETCH_OP_CODES = []
+BAR_WIDTH = 79
+PRINT_OPCODE=True
def log(opCode, is_fetch_execute=False):
global COUNT, op_codes, fetch_execute_op_codes
if DEBUG_PRINT_LOGS:
- print "="*40
+ print "=" * BAR_WIDTH
if is_fetch_execute:
- print COUNT[0], " FETCH EXEC: %i | %s" % (opCode, hex(opCode))
+ print COUNT[0], " FETCH EXEC: %i | %s | %s" % (opCode, hex(opCode), resolve_fetch_opcode_name(opCode))
else:
- print COUNT[0], " EXEC: %i | %s" % (opCode, hex(opCode))
- print "-"*40
+ print COUNT[0], " EXEC: %i | %s | %s" % (opCode, hex(opCode), resolve_opcode_name(opCode))
+ print "-" * BAR_WIDTH
if is_fetch_execute:
fetch_execute_op_codes[opCode ]+= 1
@@ -105,21 +109,43 @@
#if COUNT % 1000 == 0:
# print "."
-
+def resolve_opcode_name(opcode):
+ method = cpu.OP_CODES[opcode].__name__
+ if method == "<lambda>":
+ try:
+ functions = "[ "
+ for func_closure in cpu.OP_CODES[opcode].func_closure:
+ functions += func_closure.cell_contents.im_func.__name__+ ", ";
+ return functions + "]";
+ except:
+ return cpu.OP_CODES[opcode].func_code.co_names;
+ else:
+ return method;
+
+def resolve_fetch_opcode_name(opcode):
+ method = cpu.OP_CODES[opcode].__name__
+ if method == "<lambda>":
+ pdb.set_trace()
+ else:
+ return method;
+
+
def print_results():
global COUNT, op_codes, fetch_execute_op_codes
- codes = zip(map(lambda x: "%4s" % hex(x), range(len(op_codes))), op_codes)
-
- fetch_exec_keys = map(lambda x: "%4s %4s" % (hex(x[0]), hex(x[1])),
- zip([0x83]*len(fetch_execute_op_codes),
- range(len(fetch_execute_op_codes))))
+ print_function = (lambda x: "%4s" % hex(x))
+ codes = zip(map( print_function, range(len(op_codes))), op_codes)
+ print_function = (lambda x: "%4s %4s" % (hex(x[0]), hex(x[1])))
+ opcode_range = range(len(fetch_execute_op_codes))
+ arguments = zip([0x83] * len(fetch_execute_op_codes), opcode_range)
+ fetch_exec_keys = map( print_function, opcode_range, arguments )
+ # Append the fetchexecuted opcodes to the list
codes.extend(zip(fetch_exec_keys, fetch_execute_op_codes))
codes = sorted(codes, key=operator.itemgetter(1))
for code in codes:
if code[1] != 0:
- print "%8s : %s" % (code[0], code[1])
+ print "%8s \t %s" % (code[0], code[1])
\ No newline at end of file
Copied: pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py (from r58379, pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py)
==============================================================================
--- pypy/dist/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py (original)
+++ pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/debug/debug_rpc_xml_memory.py Mon Mar 23 18:30:29 2009
@@ -74,6 +74,7 @@
# RPC ===================================================================
def close(self):
+ pdb.set_trace()
if not self.is_closed:
print "python: called close"
self.server_close()
@@ -146,7 +147,7 @@
@printframe("comparing registers")
def compare_registers(self, registers):
- for reg in [("a", self.cpu.a.get()), ("f", self.cpu.f.get()),
+ for reg in [("a", self.cpu.a.get()), ("f", self.cpu.flag.get()),
("b", self.cpu.b.get()), ("c", self.cpu.c.get()),
("d", self.cpu.d.get()), ("e", self.cpu.e.get()),
("h", self.cpu.h.get()), ("l", self.cpu.l.get()),
@@ -227,21 +228,21 @@
self.gameboy_debug.video.object_palette_1, \
video["obp1"])
self.print_check("video scx", \
- self.gameboy_debug.video.scroll_x, video["scx"])
+ self.gameboy_debug.video.background.scroll_x, video["scx"])
self.print_check("video scy", \
- self.gameboy_debug.video.scroll_y, video["scy"])
+ self.gameboy_debug.video.background.scroll_y, video["scy"])
self.print_check("video stat", \
self.gameboy_debug.video.status.read(), video["stat"])
self.print_check("video transfer", \
self.gameboy_debug.video.transfer, video["transfer"])
self.print_check("video vblank", \
- self.gameboy_debug.video.vblank, video["vblank"])
+ self.gameboy_debug.video.v_blank, video["vblank"])
self.print_check("video wly", \
- self.gameboy_debug.video.window_line_y, video["wly"])
+ self.gameboy_debug.video.window.line_y, video["wly"])
self.print_check("video wx", \
- self.gameboy_debug.video.window_x, video["wx"])
+ self.gameboy_debug.video.window.x, video["wx"])
self.print_check("video wy", \
- self.gameboy_debug.video.window_y, video["wy"])
+ self.gameboy_debug.video.window.y, video["wy"])
@printframe("comparing timer")
def compare_timer(self, data):
@@ -286,7 +287,8 @@
def compare_memory(self, name, expected, new):
self.print_check(name+" length", len(expected), len(new))
if len(expected) != len(new): return
- for address in range(len(expected)):
+ # only check every 3rd in order to speed things up
+ for address in range(0, len(expected), 3):
self.print_check(name+" value at "+hex(address), \
expected[address], new[address])
@@ -325,9 +327,7 @@
if self.pending_steps > 0:
self.pending_steps -= 1
return
- #self.prompt_for_user_input()
-
-
+ self.prompt_for_user_input()
def prompt_for_user_input(self):
if self.showed_skip_message_count < 2:
@@ -337,6 +337,8 @@
try:
if int(read) > 0:
self.pending_steps = int(read)
+ if read == "pdb":
+ pdb.set_trace()
except Exception:
if ("stop" in read) or ("exit" in read) or (read is "Q"):
raise Exception("Debug mode Stopped by User")
Modified: pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/gameboy.py
==============================================================================
--- pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/gameboy.py (original)
+++ pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/gameboy.py Mon Mar 23 18:30:29 2009
@@ -38,8 +38,8 @@
self.timer = Timer(self.interrupt)
self.joypad = Joypad(self.joypad_driver, self.interrupt)
self.video = Video(self.video_driver, self.interrupt, self)
- self.sound = Sound(self.sound_driver)
- #self.sound = BogusSound()
+ #self.sound = Sound(self.sound_driver)
+ self.sound = BogusSound()
def get_cartridge_manager(self):
return self.cartridge_manager
Modified: pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/gameboy_implementation.py
==============================================================================
--- pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/gameboy_implementation.py (original)
+++ pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/gameboy_implementation.py Mon Mar 23 18:30:29 2009
@@ -12,16 +12,18 @@
from pypy.lang.gameboy import constants
import time
-show_metadata = False # Extends the window with windows visualizing meta-data
+show_metadata = True # Extends the window with windows visualizing meta-data
if constants.USE_RSDL:
- from pypy.rlib.rsdl import RSDL, RSDL_helper, RMix
+ from pypy.rlib.rsdl import RSDL, RSDL_helper #, RMix
from pypy.rpython.lltypesystem import lltype, rffi
delay = RSDL.Delay
get_ticks = RSDL.GetTicks
else:
delay = time.sleep
+FPS = 1<<6 # About 1<<6 to make sure we have a clean distrubution of about
+ # 1<<6 frames per second
from pypy.rlib.objectmodel import specialize
@@ -65,13 +67,11 @@
return 0
def emulate_cycle(self):
- X = 1<<6 # About 1<<6 to make sure we have a clean distrubution of about
- # 1<<6 frames per second
self.handle_events()
- # Come back to this cycle every 1/X seconds
- self.emulate(constants.GAMEBOY_CLOCK / X)
+ # Come back to this cycle every 1/FPS seconds
+ self.emulate(constants.GAMEBOY_CLOCK / FPS)
spent = int(time.time()) - self.sync_time
- left = int(1000.0/X) + self.penalty - spent
+ left = int(1000.0/FPS) + self.penalty - spent
if left > 0:
delay(left)
self.penalty = 0
@@ -260,18 +260,20 @@
SoundDriver.__init__(self)
self.enabled = False
self.sampleRate = 44100
- self.chunksize = 1024
+ self.buffersize = 512
self.channelCount = 2
self.bitsPerSample = 4
+ self.sampleSize = self.bitsPerSample * self.channelCount
self.create_sound_driver()
def create_sound_driver(self):
- if RMix.OpenAudio(self.sampleRate, RSDL.AUDIO_U8,
- self.channelCount, self.chunksize) != 0:
- error = rffi.charp2str(RSDL.GetError())
- raise Exception(error)
- else:
- self.enabled = True
+ #if RMix.OpenAudio(self.sampleRate, RSDL.AUDIO_U8,
+ # self.channelCount, self.chunksize) != 0:
+ # error = rffi.charp2str(RSDL.GetError())
+ # raise Exception(error)
+ #else:
+ # self.enabled = True
+ pass
def start(self):
pass
Modified: pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/profiling/gameboy_profiling_implementation.py
==============================================================================
--- pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/profiling/gameboy_profiling_implementation.py (original)
+++ pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/profiling/gameboy_profiling_implementation.py Mon Mar 23 18:30:29 2009
@@ -1,48 +1,37 @@
#!/usr/bin/env python
-from __future__ import generators
-from pypy.lang.gameboy.ram import iMemory
-from pypy.lang.gameboy.gameboy_implementation import *
-from pypy.lang.gameboy.profiling.profiling_cpu import ProfilingCPU
-from pypy.lang.gameboy.debug import debug
-from pypy.lang.gameboy.debug.debug_socket_memory import *
+from pypy.lang.gameboy.gameboy import GameBoy
+from pypy.lang.gameboy.joypad import JoypadDriver
+from pypy.lang.gameboy.video import VideoDriver
+from pypy.lang.gameboy.sound import SoundDriver
+from pypy.lang.gameboy.timer import Clock
+from pypy.lang.gameboy import constants
+
+from pypy.rlib.objectmodel import specialize
# GAMEBOY ----------------------------------------------------------------------
-class GameBoyProfilingImplementation(GameBoyImplementation):
-
- def __init__(self, op_codes):
- GameBoyImplementation.__init__(self)
- self.op_codes = op_codes
- self.cycleLimit = cycleLimit
- self.cpu = ProfilingCPU(self.interrupt, self)
- self.cpu.cycle_limit = cycleLimit
-
- def handle_execution_error(self):
- self.is_running = False
- debug.print_results()
-
+FPS = 1 << 6
-# CUSTOM DRIVER IMPLEMENTATIONS currently not used =============================
-
+class GameBoyProfiler(GameBoy):
-# VIDEO DRIVER -----------------------------------------------------------------
-
-class VideoDriverDebugImplementation(VideoDriverImplementation):
- pass
-
-
-# JOYPAD DRIVER ----------------------------------------------------------------
+ def __init__(self):
+ GameBoy.__init__(self)
+ self.is_running = False
-class JoypadDriverDebugImplementation(JoypadDriverImplementation):
- pass
-
-
-# SOUND DRIVER -----------------------------------------------------------------
-class SoundDriverDebugImplementation(SoundDriverImplementation):
- pass
-
+ def create_drivers(self):
+ self.clock = Clock()
+ self.joypad_driver = JoypadDriver()
+ self.video_driver = VideoDriver()
+ self.sound_driver = SoundDriver()
+
+ def mainLoop(self, execution_seconds):
+ self.reset()
+ self.is_running = True
+ for i in range(int(execution_seconds * FPS)):
+ self.emulate_cycle()
-# ==============================================================================
+ def emulate_cycle(self):
+ self.emulate(constants.GAMEBOY_CLOCK / FPS)
Modified: pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/test/test_cpu.py
==============================================================================
--- pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/test/test_cpu.py (original)
+++ pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/test/test_cpu.py Mon Mar 23 18:30:29 2009
@@ -431,7 +431,8 @@
# ld_BCi_A
def test_0x02():
cpu = get_cpu();
- cpu.bc.set_hi_lo(0xC2, 0x23);
+ cpu.bc.set_hi(0xC2)
+ cpu.bc.set_lo(0x23);
cpu.a.set(0x12);
cycle_test(cpu, 0x02, 2);
assert cpu.read(cpu.bc.get()) == cpu.a.get()
@@ -451,7 +452,8 @@
# ld_DEi_A
def test_0x12():
cpu = get_cpu();
- cpu.de.set_hi_lo(0xC2, 0x23);
+ cpu.de.set_hi(0xC2)
+ cpu.de.set_lo(0x23);
cpu.a.set(0x12);
cycle_test(cpu, 0x12, 2);
assert cpu.read(cpu.de.get()) == cpu.a.get()
@@ -470,7 +472,8 @@
# ldi_HLi_A
def test_0x22():
cpu = get_cpu();
- cpu.hl.set_hi_lo(0xCD, 0xEF);
+ cpu.hl.set_hi(0xCD)
+ cpu.hl.set_lo(0xEF);
cpu.a.set(0x12);
cycle_test(cpu, 0x22, 2);
assert cpu.read(0xCDEF) == cpu.a.get()
@@ -479,7 +482,8 @@
# ldd_HLi_A
def test_0x32():
cpu = get_cpu();
- cpu.hl.set_hi_lo(0xCD, 0xEF);
+ cpu.hl.set_hi(0xCD)
+ cpu.hl.set_lo(0xEF);
cpu.a.set(0x12);
cycle_test(cpu, 0x32, 2);
assert cpu.read(0xCDEF) == cpu.a.get()
@@ -881,8 +885,9 @@
cpu = get_cpu()
opCode = 0x98
value = 0x12
- registers = [cpu.b, cpu.c, cpu.d, cpu.e, cpu.h, cpu.l, cpu.hli, cpu.a]
+ registers = ["b", "c", "d", "e", "h", "l", "hli", "a"]
for register in registers:
+ register = cpu.__dict__[register]
cpu.reset()
cpu.a.set(value)
register.set(value)
@@ -896,11 +901,11 @@
cpu.flag.is_carry = True
cpu.a.set(value+1)
register.set(value)
- numCycles= 1
+ numCycles = 1
if register == cpu.hli:
numCycles = 2
cycle_test(cpu, opCode, numCycles)
- if register == cpu.a:
+ if register is cpu.a:
assert cpu.a.get() == 0xFF
else:
assert cpu.a.get() == 0
Modified: pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/test/test_cpu_register.py
==============================================================================
--- pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/test/test_cpu_register.py (original)
+++ pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/test/test_cpu_register.py Mon Mar 23 18:30:29 2009
@@ -26,9 +26,14 @@
TEST_CPU = get_cpu(True)
TEST_CPU.reset()
return TEST_CPU
+
+def get_double_register():
+ cpu = get_cpu()
+ return DoubleRegister(cpu, Register(cpu), Register(cpu))
# ------------------------------------------------------------
# TEST REGISTER
+
def test_register_constructor():
register = Register(get_cpu())
assert register.get() == 0
@@ -103,7 +108,8 @@
valueHi = 0x12
valueLo = 0x34
oldCycles = register.cpu.cycles
- register.set_hi_lo(valueHi, valueLo)
+ register.set_hi(valueHi)
+ register.set_lo(valueLo)
assert oldCycles-register.cpu.cycles == 2
assert register.get_hi() == valueHi
assert register.get_lo() == valueLo
@@ -161,4 +167,82 @@
assert register.get() == value+1;
register.reset()
assert register.get() == value
-
\ No newline at end of file
+
+
+# TEST REGISTER SYNCING -----------------------------------------------------
+
+def test_register_sync():
+ double_register = get_double_register()
+ assert double_register.invalid
+ assert not double_register.hi.invalid
+ assert not double_register.lo.invalid
+ return double_register
+
+def test_register_sync_get():
+ double_register = test_register_sync()
+
+ double_register.get()
+
+ assert not double_register.invalid
+ assert not double_register.hi.invalid
+ assert not double_register.lo.invalid
+
+
+def test_register_sync_set():
+ double_register = test_register_sync()
+
+ double_register.set(0xFFFF)
+
+ assert not double_register.invalid
+ assert double_register.hi.invalid
+ assert double_register.lo.invalid
+
+ return double_register
+
+
+def test_register_sync_set_get():
+ double_register = test_register_sync_set()
+
+ assert double_register.get() == 0xFFFF
+
+ assert not double_register.invalid
+ assert double_register.hi.invalid
+ assert double_register.lo.invalid
+
+
+def test_register_sync_set_get_hi():
+ double_register = test_register_sync_set()
+
+ assert double_register.hi.get() == 0xFF
+
+ assert not double_register.invalid
+ assert not double_register.hi.invalid
+ assert not double_register.lo.invalid
+
+
+def test_register_sync_set_get_lo():
+ double_register = test_register_sync_set()
+
+ assert double_register.lo.get() == 0xFF
+
+ assert not double_register.invalid
+ assert not double_register.hi.invalid
+ assert not double_register.lo.invalid
+
+
+def test_register_sync_set_hi():
+ double_register = test_register_sync()
+ double_register.hi.set(0x12)
+
+ assert double_register.invalid
+ assert not double_register.hi.invalid
+ assert not double_register.lo.invalid
+
+
+def test_register_sync_set_lo():
+ double_register = test_register_sync()
+ double_register.lo.set(0x12)
+
+ assert double_register.invalid
+ assert not double_register.hi.invalid
+ assert not double_register.lo.invalid
Modified: pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/test/test_video.py
==============================================================================
--- pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/test/test_video.py (original)
+++ pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/test/test_video.py Mon Mar 23 18:30:29 2009
@@ -39,7 +39,6 @@
assert video.background.scroll_y == 0
assert video.window.x == 0
assert video.window.y == 0
- assert video.window.line_y == 0
assert video.background_palette == 0xFC
assert video.object_palette_0 == 0xFF
assert video.object_palette_1 == 0xFF
@@ -181,7 +180,8 @@
video.write(0xFF40, 0x80+0x20)
assert video.control.read() == 0x80+0x20
- assert video.window.line_y == 144
+ # assert video.window.line_y == 144 # We don't jump, we just adjust and
+ # # start drawing where we are.
def test_control_reset1():
video = get_video()
Modified: pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/video.py
==============================================================================
--- pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/video.py (original)
+++ pypy/branch/pyjitpl5-PyGirl/pypy/lang/gameboy/video.py Mon Mar 23 18:30:29 2009
@@ -468,6 +468,8 @@
window.draw_clean_line(self.line)
def draw_line(self):
+ # XXX We should check if this is necessary for each line.
+ self.update_palette()
self.draw_window(self.background, self.line_y, self.line)
self.draw_window(self.window, self.line_y, self.line)
self.draw_sprites(self.line_y, self.line)
@@ -506,7 +508,6 @@
self.shown_sprites[highest], self.shown_sprites[index]
def send_pixels_line_to_driver(self):
- self.update_palette()
for x in range(0, GAMEBOY_SCREEN_WIDTH):
color = self.palette[self.line[SPRITE_SIZE + x]]
self.driver.draw_gb_pixel(x, self.line_y, color)
More information about the Pypy-commit
mailing list