Commits

Armin Rigo committed 7eb3656

svn merge -r58379:59313 svn+ssh://codespeak.net/svn/pypy/dist

Comments (0)

Files changed (97)

pypy/annotation/specialize.py

 ##    return funcdesc.cachedgraph(s1_type, alt_name='memo_%s' % funcdesc.name, 
 ##                                         builder=builder)
 
-def make_constgraphbuilder(n, v=None, factory=None):
+def make_constgraphbuilder(n, v=None, factory=None, srcmodule=None):
     def constgraphbuilder(translator, ignore):
         args = ','.join(["arg%d" % i for i in range(n)])
         if factory is not None:
             computed_v = factory()
         else:
             computed_v = v
-        miniglobals = {'v': computed_v}
+        miniglobals = {'v': computed_v, '__name__': srcmodule}
         exec "constf = lambda %s: v" % args in miniglobals
         return translator.buildflowgraph(miniglobals['constf'])
     return constgraphbuilder

pypy/bin/reportstaticdata.py

+#!/usr/bin/env python
+
+"""
+Usage: reportstaticdata.py [-m1|-m2|-t] [OPTION]... FILENAME
+Print a report for the static data informations contained in FILENAME
+
+The static data informations are saved in the file staticdata.info when
+passing --dump_static_data_info to translate.py.
+
+Options:
+
+  -m1      Print a report for each module, counting constants that are
+           reacheable from more than one module multiple times (default)
+
+  -m2      Print a report for each module, counting constants that are
+           reacheable from more than one module only in the first module
+           seen
+
+  -t       Print a global report for all the constants
+
+  -h       Print sizes in human readable formats (e.g., 1K 234M)
+
+  -s       Print only the total size for each module
+
+  -u       Print the list of graphs which belongs to unknown modules
+
+  --help   Show this help message
+"""
+
+import autopath
+from pypy.translator.tool.staticsizereport import print_report
+
+def parse_options(argv):
+    kwds = {}
+    for arg in argv:
+        if arg.startswith('-'):
+            if arg == '-m1':
+                assert 'kind' not in kwds
+                kwds['kind'] = 'by_module_with_duplicates'
+            elif arg == '-m2':
+                assert 'kind' not in kwds
+                kwds['kind'] = 'by_module_without_duplicates'
+            elif arg == '-t':
+                assert 'kind' not in kwds
+                kwds['kind'] = 'by_type'
+            elif arg == '-h':
+                kwds['human_readable'] = True
+            elif arg == '-s':
+                kwds['summary'] = True
+            elif arg == '-u':
+                kwds['show_unknown_graphs'] = True
+            elif arg == '--help':
+                raise AssertionError
+        else:
+            assert 'filename' not in kwds
+            kwds['filename'] = arg
+
+    assert 'filename' in kwds
+    return kwds
+
+
+def main():
+    import sys
+    try:
+        kwds = parse_options(sys.argv[1:])
+    except AssertionError:
+        print >> sys.stderr, __doc__
+        sys.exit(1)
+    print_report(**kwds)
+
+if __name__ == '__main__':
+    main()

pypy/config/pypyoption.py

                "make sure that all calls go through space.call_args",
                default=False),
 
+    BoolOption("timing",
+               "timing of various parts of the interpreter (simple profiling)",
+               default=False),
+
     OptionDescription("std", "Standard Object Space Options", [
         BoolOption("withtproxy", "support transparent proxies",
                    default=True),

pypy/config/translationoption.py

     # gc
     ChoiceOption("gc", "Garbage Collection Strategy",
                  ["boehm", "ref", "marksweep", "semispace", "statistics",
-                  "generation", "hybrid", "none"],
+                  "generation", "hybrid", "markcompact", "none"],
                   "ref", requires={
                      "ref": [("translation.rweakref", False), # XXX
                              ("translation.gctransformer", "ref")],
                      "generation": [("translation.gctransformer", "framework")],
                      "hybrid": [("translation.gctransformer", "framework")],
                      "boehm": [("translation.gctransformer", "boehm")],
+                     "markcompact": [("translation.gctransformer", "framework")],
                      },
                   cmdline="--gc"),
     ChoiceOption("gctransformer", "GC transformer that is used - internal",
                      "ref": [("translation.gcrootfinder", "n/a")],
                      "none": [("translation.gcrootfinder", "n/a")],
                  }),
+    OptionDescription("gcconfig", "Configure garbage collectors", [
+        BoolOption("debugprint", "Turn on debug printing for the GC",
+                   default=False)
+        ]),
     ChoiceOption("gcrootfinder",
                  "Strategy for finding GC Roots (framework GCs only)",
                  ["n/a", "shadowstack", "llvmgc", "asmgcc"],
                default=None),
     StrOption("output", "Output file name", cmdline="--output"),
 
+    BoolOption("dump_static_data_info", "Dump static data info",
+               cmdline="--dump_static_data_info",
+               default=False, requires=[("translation.backend", "c")]),
+
     # portability options
     BoolOption("vanilla",
                "Try to be as portable as possible, which is not much",
     '0':    'boehm       nobackendopt',
     '1':    'boehm       lowinline',
     'size': 'boehm       lowinline     remove_asserts',
-    'mem':  'marksweep   lowinline     remove_asserts',
+    'mem':  'markcompact lowinline     remove_asserts',
     '2':    'hybrid      extraopts',
     '3':    'hybrid      extraopts     remove_asserts',
     }
             config.translation.backendopt.suggest(remove_asserts=True)
         elif word == 'extraopts':
             config.translation.suggest(withsmallfuncsets=5)
-            config.translation.suggest(list_comprehension_operations=True)
         else:
             raise ValueError(word)
 
+    hasbackendopts = 'nobackendopt' not in words
+    config.translation.suggest(list_comprehension_operations=hasbackendopts)
+
 # ----------------------------------------------------------------
 
 PLATFORMS = [
 ]
 
 def set_platform(config, platform):
-    from pypy.rlib.pyplatform import Platform, Maemo, OverloadCompilerPlatform
+    from pypy.rlib.pyplatform import Platform, Maemo
     from pypy.rlib import pyplatform
     from pypy.translator.tool.cbuild import ExternalCompilationInfo
     if isinstance(platform, str):
         if platform == 'maemo':
-            platform = Maemo()
+            platform = Maemo(cc=config.translation.cc or None)
         elif platform == 'host':
             return
         else:
             raise NotImplementedError('Platform = %s' % (platform,))
     assert isinstance(platform, Platform)
     pyplatform.platform = platform
-    if config.translation.cc:
-        pyplatform.platform = OverloadCompilerPlatform(platform,
-                                                       config.translation.cc)
-

pypy/doc/config/translation.gcconfig.debugprint.txt

+If this option is set, the GC will print debugging information.

pypy/doc/config/translation.gcconfig.txt

+..  intentionally empty

pypy/doc/externaltools.txt

+External tools&programs needed by PyPy
+======================================
+
+Tools needed for testing
+------------------------
+
+These tools are used in various ways by PyPy tests; if they are not found,
+some tests might be skipped, so they need to be installed on every buildbot
+slave to be sure we actually run all tests:
+
+  - Mono (versions 1.2.1.1 and 1.9.1 known to work)
+
+  - Java/JVM (preferably sun-jdk; version 1.6.0 known to work)
+
+  - Jasmin >= 2.2 (copy it from wyvern, /usr/local/bin/jasmin and /usr/local/share/jasmin.jar)
+
+  - gcc
+
+  - Some libraries (these are Debian package names, adapt as needed):
+
+    * ``python-dev``
+    * ``python-ctypes``
+    * ``libffi-dev``
+    * ``libz-dev`` (for the optional ``zlib`` module)
+    * ``libbz2-dev`` (for the optional ``bz2`` module)
+    * ``libncurses-dev`` (for the optional ``_minimal_curses`` module)
+    * ``libgc-dev`` (only when translating with `--opt=0, 1` or `size`)

pypy/doc/getting-started.txt

 **Note that running all the tests takes a very long time, and
 enormous amounts of memory if you are trying to run them all
 in the same process; test_all.py is only suitable to run a
-subset of them at a time.**  To run them all we have an
-`autotest driver`_ that executes the tests directory by
-directory and produces pages like the following one:
+subset of them at a time.**  To run them all daily we have a BuildBot based
+setup, a summary of its results can be seen at:
 
-    http://wyvern.cs.uni-duesseldorf.de/pypytest/summary.html
+    http://codespeak.net:8099/summary
 
 .. _`if PyPy works on your machine/platform`: index.html#status
 .. _`autotest driver`: http://codespeak.net/pipermail/pypy-dev/2006q3/003273.html

pypy/doc/index.txt

 them.  Linux 64-bit machines are supported (though it may also take some
 time before we notice and fix bugs).
 
-PyPy's own tests, daily updated, `on Linux`_, `on Windows`_
- and `on built pypy-c`_.
+PyPy's own tests `summary`_, daily updated, run through BuildBot infrastructure.
 
 `Nightly builds and benchmarks`_ of PyPy to C, CLI and LLVM (PowerPC machine).
 
 .. _`bytecode interpreter`: interpreter.html 
 .. _`EU reports`: index-report.html
 .. _`Technical reports`: index-report.html
-.. _`on Linux`: http://wyvern.cs.uni-duesseldorf.de/pypytest/summary.html
-.. _`on Windows`: http://scottdial.com/pypytest/summary.html
-.. _`on built pypy-c`: http://wyvern.cs.uni-duesseldorf.de/~fijal/pypy-c-tests/
+.. _`summary`: http://codespeak.net:8099/summary
 .. _`ideas for PyPy related projects`: project-ideas.html
 .. _`Nightly builds and benchmarks`: http://tuatara.cs.uni-duesseldorf.de/benchmark.html
 .. _`directory reference`: 

pypy/doc/maemo.txt

 How to run PyPy on top of maemo platform
 ========================================
 
+XXX this document needs cleanup, contains duplicate information, will need cleanup 
+    after experiments yielded the best way to do pypy-c translations. 
+
 This is a short introduction how to install correct environment and
 cross-compile pypy to maemo platform emulator under qemu. Note that this
 is work-in-progress.
 
-Installing `scratchbox`_
-------------------------
+
+Variant 0: cross-compiling pypy-c 
+------------------------------------------
+
+The basic idea is to install a scratchbox environment that emulates
+a real ARM-based N810 device.  One can then login to this virtual 
+environment and execute ARM binaries.  Scratchbox also provides 
+compiler toolchains that allow to drive a compiler from the outside. 
+This is what we want for building pypy-c because most work happens 
+independently from the platform and we want this work to execute natively. 
+For all platform relevant details we need to consult the target environment 
+and use the cross-compiler.  So now let's move on to install such an environment
+and compiler.  
+
+Note: the 
+
+    http://repository.maemo.org/stable/diablo/maemo-scratchbox-install_4.1.1.sh
+
+script is provided by the maemo team and would automate installation. 
+Unfortuantely it does not provide a working cross-compiler (XXX 
+mail to maintainers and see if there is an easy fix). 
+
+creating a /scratchbox environment 
++++++++++++++++++++++++++++++++++++++++++
+
+The basic idea is to follow 
+
+    http://www.scratchbox.org/documentation/user/scratchbox-1.0/html/tutorial.htm#
+
+with tarballs that work for the N810/Maemo target. 
+
+make yourself an empty ``work`` directory and get a 
+working set of tarballs, e.g. like this::
+
+    export GET='wget -c'
+    export URL='http://www.scratchbox.org/download/files/sbox-releases/apophis/tarball'
+    $GET $URL/scratchbox-core-1.0.11-i386.tar.gz
+    $GET $URL/scratchbox-libs-1.0.11-i386.tar.gz
+    $GET $URL/scratchbox-toolchain-cs2007q3-glibc2.5-arm7-1.0.8-6-i386.tar.gz
+    $GET $URL/scratchbox-devkit-cputransp-1.0.7-i386.tar.gz
+    $GET $URL/scratchbox-devkit-perl-1.0.4-i386.tar.gz # for autoconf
+    $GET $URL/scratchbox-devkit-svn-1.0-i386.tar.gz    # for being able to checkout
+    #$GET $URL/scratchbox-devkit-debian-1.0.10-i386.tar.gz # to eventually get debian working
+
+unpack all those tarballs, e.g. like this::
+
+    for x in *.tar.gz ; do sudo tar zxvf $x; done 
+
+now you should have a ``work/scratchbox`` directory containing your basic uninitialized 
+scratchbox environment. 
+
+make a symlink to have scratchbox at the canonical location::
+
+    ln -s /path/to/work/sandbox /sandbox 
+
+initilaize the scratchbox install (you should be fine with using default answers to any questions)::
+
+    /scratchbox/run_me_first.sh 
+
+NOTE, that this will implicitely start some services that generally are controlled via::
+
+    /scratchbox/sbin/sbox_ctrl stop|start
+
+So if you later want to play with multiple different scratchbox installations you should stop the services before moving them away.  You can also try to link this script into your ``/etc/init.d/`` so that it automatically runs after a reboot. 
+
+Now create a user::
+
+    /scratchbox/sbin/sbox_adduser USER yes   
+
+the 'yes' means that the USER gets added to the sbox unix group, neccessary to login into the virtual environment. 
+
+
+Creating an target emulating N810/Maemo environment
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Now we instruct scratchbox to define a target suitable for emulating the
+N810/Maemo device:
+
+Login to the virtual environment and invoke::
+
+    /scratchbox/login 
+    sb-menu 
+
+this brings up an interactive menu, you need to *setup* a new target,
+you may name it "ARMEL" and then you need to select::
+
+    compiler:  cs2007q3-glibc2.5-arm7
+    devkits:   cputransp, perl, svn 
+    cputransp: (select 'qemu-arm-0.8.2-sb2' when it asks later on) 
+   
+In theory, you should also be able to execute the following cmdline::
+
+    sb-conf setup armel --compiler=cs2007q3-glibc2.5-arm7 \
+                        --devkit=cputransp:perl:svn \
+                        --cputransp=qemu-arm-0.8.2-sb2
+
+but this did not provide a complete environment for me (XXX try to fix). 
+
+Congrats!  If all worked well you should now be able to cross-compile C programs via:
+
+    /scratchbox/compilers/cs2007q3-glibc2.5-arm7/bin/arm-none-linux-gnueabi-gcc
+
+and copy the binary result to the N810/Maemo device. You can also login to
+the virtual environment and execute the ARM binary there. 
+
+XXX [fijal] remember to update that it uses inside gcc these days
+
+PyPy's translation tool chain tries to use this cross-compiler when 
+you specify ``--platform=maemo`` to the translate.py script. 
+
+So you can now get yourself a copy of pypy (in the hosting, not the
+virtual environment of course!) and do: 
+
+    python translate.py --batch --platform=maemo --opt=mem \
+           targetpypystandalone.py --no-allworkingmodules 
+
+copy the result to the device and run it. 
+
+ 
+variant 1: Installing `scratchbox`_
+-------------------------------------------
 
 I had no success with installing scratchbox 2.0, but theoretically it
-should work. Follow these `installation instructions`_,
+should work. 
+
+Follow these `installation instructions`_ for 1.0,
 make sure that you install cpu-transparency modules, otherwise emulation will
 not be available. Preferred toolchain is cs2005q3.2-glibc2.5-arm.
 
 (and not a rootstrap).
 
 I had to manually edit /scratchbox/devkits/debian-etch/etc/environment 
-to add ARCH=armel, otherwise things did not work
+to add ARCH=armel, otherwise apt-get did not work.  I also edited
+/etc/apt/sources.list to contain::
+    
+    deb     ftp://ftp.fi.debian.org/debian/ lenny  main contrib non-free
+    deb-src ftp://ftp.fi.debian.org/debian/ lenny  main contrib non-free
 
-Translating pypy
-----------------
+Then run ``apt-get update``, get an error, ignore it, and run
+``fakeroot apt-get install python-dev``.  Doesn't work out of
+the box for me; I have actually to install a few pieces at a
+time, starting from libc6, sometimes with and sometimes
+without the ``fakeroot``.  It's quite a mess but in the end I
+get a ``python2.5``.
+
+cross-compiling pypy 
++++++++++++++++++++++++++++
 
 Run::
   ./translate.py --platform=maemo --opt=mem targetpypystandalone --no-allworkingmodules
 from inside scratchbox. Default is /scratchbox/users/<user>/home/<user> where
 <user> is your user id.
 
+
+variant 2: using official maemo-installs 
+----------------------------------------------------------------
+
+the following taken mostly from 
+
+    http://yankandpaste.blogspot.com/2008/08/maemo-diablo-sdk-install-on-ubuntu-804.html
+
+1. On ubuntu linux edit /etc/sysctl.conf to contain::
+
+    XXX [fijal] since it might freeze your machine, I suggest to add a
+        non-permanent way of doing it (echo 0 > /proc/sys/vm/vdso_enabled)
+
+    XXX [fijal] on my machine vdso_enbled = 0 freezed machine and made in
+        unbootable without editing file first. It seems not to be needed
+        though.
+
+    vm.vdso_enabled = 0
+    vm.mmap_min_addr = 4096
+
+   and activate via "sysctl -p".  (on some linuxes this might crash your computer) 
+   This step is neccessary for getting a working scratchbox installation. 
+
+2. Grab http://repository.maemo.org/stable/diablo/maemo-scratchbox-install_4.1.1.sh
+   and run it as root with "sh maemo-scratchbox-install_4.1.1.sh -u USERNAME"
+   so that you automatically get an account created within the virtual scratchbox 
+   environment.  After this step you should be able to perform ``/scratchbox/login``
+   and get a funny prompt. 
+
+3. Grab http://repository.maemo.org/stable/diablo/maemo-sdk-install_4.1.1.sh
+   and run it.  For me only selecting "[x] runtime environment" worked whereas 
+   installing the dev packages failed but that might have been a (reproducible 
+   though) local download problem. After this step you should be able 
+   to perform ``/scratchbox/login`` and land in a DIABLO_ARM target environment, 
+   the code name for current Maemo. You should be able to execute "python2.5"
+   within the scratchbox environment. 
+
+4. It might not be neccessary in your installation but in order to get 
+   the scratchbox and python to work without strange warnings i found 
+   a note that it helps to setup the newest qemu-arm compiler. 
+   For this you need to svn-checkout 
+
+    http://qemu-arm-eabi.svn.sourceforge.net/svnroot/qemu-arm-eabi/trunk
+
+   and follow the README. (a number of steps). 
+
+Compiling within scratchbox
+++++++++++++++++++++++++++++++++
+
+After switching to the virtual environment via ``/scratchbox/login`` 
+and commands like this::
+
+    svn co http://codespeak.net/svn/pypy/dist pypy-dist 
+    cd pypy-dist/pypy/translator/goal
+    python translate.py --batch --opt=mem targetpypystandalone.py --no-allworkingmodules
+
+one will get (after around 10 hours on a medium intel machine) a working pypy-c. 
+You can transfer this binary to a real device an compile it there. 
+
+cross-compiling (using scratchbox)
+++++++++++++++++++++++++++++++++++++++++++++
+
+XXX under investigation.  might turn out that a different installation
+method suffices.  the above is still good for getting a maemo simulation
+environment - not much missing to also get a simulated graphical environment
+from it. 
+
+
+
 .. _`installation instructions`: http://www.scratchbox.org/documentation/user/scratchbox-1.0/html/installdoc.html
 .. _`scratchbox`: http://scratchbox.org
+
+debian
+++++++
+
+in theory we don't need to install debian under scratchbox. in practice though,
+if we want to run pypy-c with allworkingmodules we need to a way to install
+correct libraries and include files. For example we should use etch and not
+lenny, since libffi is in correct version there (4 vs 5). On the other
+hand I had no luck installing python on etch..
+
+To be able to run debian correctly you need to:
+
+1. Manually edit /scratchbox/devkits/debian-etch/etc/environment 
+   to add ARCH=arm (instead of ARCH=...),
+   otherwise apt-get did not work.
+
+2. Go inside scratchbox and make /etc/apt/sources.list to contain:
+    
+    deb     ftp://ftp.fi.debian.org/debian/ lenny  main contrib non-free
+    deb-src ftp://ftp.fi.debian.org/debian/ lenny  main contrib non-free
+
+3. Run apt-get update && fakeroot apt-get install libc6 && fakeroot apt-get install python2.5-dev
+
+5. In order to have pypy-c with all working modules you also need following
+   packages:
+
+   * libffi-dev
+
+   * zlib1g-dev
+
+   * libbz2-dev
+

pypy/interpreter/baseobjspace.py

 from pypy.tool.uid import HUGEVAL_BYTES
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.rlib.debug import make_sure_not_resized
+from pypy.rlib.timer import DummyTimer, Timer
 import os, sys
 
 __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root']
 #        if self.config.objspace.logbytecodes:
 #            self.bytecodecounts = {}
 
+        if self.config.objspace.timing:
+            self.timer = Timer()
+        else:
+            self.timer = DummyTimer()
+
         self.initialize()
 
     def startup(self):
             modname = self.str_w(w_modname)
             mod = self.interpclass_w(self.getbuiltinmodule(modname))
             if isinstance(mod, Module):
+                import time
+                self.timer.start("startup " + modname)
                 mod.startup(self)
+                self.timer.stop("startup " + modname)
 
     def finish(self):
         w_exitfunc = self.sys.getdictvalue_w(self, 'exitfunc')

pypy/interpreter/pycompiler.py

 
 ##         flags |= stdlib___future__.generators.compiler_flag   # always on (2.2 compat)
         space = self.space
+        space.timer.start("PythonAST compile")
         try:
             builder = AstBuilder(self.parser, self.grammar_version, space=space)
             for rulename, buildfunc in self.additional_rules.iteritems():
         except (ValueError, TypeError), e:
             raise OperationError(space.w_SystemError, space.wrap(str(e)))
         assert isinstance(c, PyCode)
+        space.timer.stop("PythonAST compile")
         return c
 
     # interface for pypy.module.recparser

pypy/lang/gameboy/constants.py

 GAMEBOY_SCREEN_WIDTH  = 160
 GAMEBOY_SCREEN_HEIGHT = 144
 
+SPRITE_SIZE = 8
+
 #___________________________________________________________________________
 # CATRIGE TYPES
 # ___________________________________________________________________________

pypy/lang/gameboy/cpu.py

 from pypy.lang.gameboy import constants
 from pypy.lang.gameboy.ram import *
 from pypy.lang.gameboy.interrupt import *
+from pypy.lang.gameboy.cpu_register import Register, DoubleRegister, \
+                                           FlagRegister, ImmediatePseudoRegister
 import pdb
 
 # ---------------------------------------------------------------------------
 
-def process_2_complement(value):
+def process_2s_complement(value):
     # check if the left most bit is set
-    if (value >> 7) == 1:
-        return -((~value) & 0xFF) - 1
-    else :
-        return value
-# ---------------------------------------------------------------------------
-
-class AbstractRegister(object):
-    def get(self, use_cycles=True):
-        return 0xFF
-
-class Register(AbstractRegister):
-    
-    def __init__(self, cpu, value=0):
-        assert isinstance(cpu, CPU)
-        self.reset_value = self.value = value
-        self.cpu = cpu
-        if value != 0:
-            self.set(value)
-        
-    def reset(self):
-        self.value = self.reset_value
-        
-    def set(self, value, use_cycles=True):
-        self.value = value & 0xFF
-        if use_cycles:
-            self.cpu.cycles -= 1
-        
-    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 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)
-        self.cpu = cpu
-        self.hi = hi
-        self.lo = lo
-        self.reset_value = reset_value
-        
-    def set(self, value, use_cycles=True):
-        value  = value & 0xFFFF
-        self.set_hi(value >> 8, use_cycles)
-        self.set_lo(value & 0xFF, use_cycles)
-        if use_cycles:
-            self.cpu.cycles += 1
-    
-    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 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_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)
-        if use_cycles:
-            self.cpu.cycles -= 1
-        
-    def dec(self, use_cycles=True):
-        self.set(self.get(use_cycles) - 1, use_cycles=use_cycles)
-        if use_cycles:
-            self.cpu.cycles -= 1
-        
-    def add(self, value, use_cycles=True):
-        self.set(self.get(use_cycles) + value, use_cycles=use_cycles)
-        if use_cycles:
-            self.cpu.cycles -= 2
-            
-    
-# ------------------------------------------------------------------------------
-
-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
-            return self.cpu.read(self.hl.get(use_cycles=use_cycles)) # 1
-    
-# ------------------------------------------------------------------------------
-  
-class FlagRegister(Register):
-    """
-    The Flag Register (lower 8bit of AF register)
-      Bit  Name  Set Clr  Expl.
-      7    zf    Z   NZ   Zero Flag
-      6    n     -   -    Add/Sub-Flag (BCD)
-      5    h     -   -    Half Carry Flag (BCD)
-      4    cy    C   NC   Carry Flag
-      3-0  -     -   -    Not used (always zero)
-    Conatins the result from the recent instruction which has affected flags.
-    
-    The Zero Flag (Z)
-    This bit becomes set (1) if the result of an operation has been zero (0). 
-    Used  for conditional jumps.
-    
-    The Carry Flag (C, or Cy)
-    Becomes set when the result of an addition became bigger than FFh (8bit) or
-    FFFFh (16bit). Or when the result of a subtraction or comparision became 
-    less than zero (much as for Z80 and 80x86 CPUs, but unlike as for 65XX and 
-    ARM  CPUs). Also the flag becomes set when a rotate/shift operation has 
-    shifted-out a "1"-bit.
-    Used for conditional jumps, and for instructions such like ADC, SBC, RL, 
-    RLA, etc.
-    
-    The BCD Flags (N, H)
-    These flags are (rarely) used for the DAA instruction only, N Indicates
-    whether the previous instruction has been an addition or subtraction, and H
-    indicates carry for lower 4bits of the result, also for DAA, the C flag must
-    indicate carry for upper 8bits.
-    After adding/subtracting two BCD numbers, DAA is intended to convert the
-    result into BCD format; BCD numbers are ranged from 00h to 99h rather than 
-    00h to FFh.
-    Because C and H flags must contain carry-outs for each digit, DAA cannot be
-    used for 16bit operations (which have 4 digits), or for INC/DEC operations
-    (which do not affect C-flag).    
-    """
-    def __init__(self, cpu, reset_value):
-        assert isinstance(cpu, CPU)
-        self.cpu         = cpu
-        self.reset_value = reset_value
-        self.reset()
-         
-    def reset(self):
-        self.partial_reset()
-        
-    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):
-        if not keep_is_zero:
-            self.is_zero = False
-        if not keep_is_subtraction:
-            self.is_subtraction = False
-        if not keep_is_half_carry:
-            self.is_half_carry = False
-        if not keep_is_carry:
-            self.is_carry = False
-        if not keep_p:
-            self.p_flag = False
-        if not keep_s:
-            self.s_flag = False
-        self.lower = 0x00
-            
-    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)
-        return value + self.lower
-            
-    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))
-        self.lower          = value & 0x0F
-        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 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)
-        
+    #if (value >> 7) == 1:
+    #    return -((~value) & 0xFF) - 1
+    #else :
+    #    return value
+    return (value ^ 0x80) - 128
+     
 # # ------------------------------------------------------------------------------
 
 
 
     def get_fetchadded_sp(self):
         # 1 cycle
-        offset = process_2_complement(self.fetch()) # 1 cycle
+        offset = process_2s_complement(self.fetch()) # 1 cycle
         s = (self.sp.get() + offset) & 0xFFFF
         self.flag.reset()
         if (offset >= 0):
 
     def relative_jump(self):
         # JR +nn, 3 cycles
-        self.pc.add(process_2_complement(self.fetch())) # 3 + 1 cycles
+        self.pc.add(process_2s_complement(self.fetch())) # 3 + 1 cycles
         self.cycles += 1
 
     def relative_conditional_jump(self, cc):

pypy/lang/gameboy/cpu_register.py

+
+# ---------------------------------------------------------------------------
+
+class AbstractRegister(object):
+    def get(self, use_cycles=True):
+        return 0xFF
+
+class Register(AbstractRegister):
+    
+    def __init__(self, cpu, value=0):
+       # assert isinstance(cpu, CPU)
+        self.reset_value = self.value = value
+        self.cpu = cpu
+        if value != 0:
+            self.set(value)
+        
+    def reset(self):
+        self.value = self.reset_value
+        
+    def set(self, value, use_cycles=True):
+        self.value = value & 0xFF
+        if use_cycles:
+            self.cpu.cycles -= 1
+        
+    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 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)
+        self.cpu = cpu
+        self.hi = hi
+        self.lo = lo
+        self.reset_value = reset_value
+        
+    def set(self, value, use_cycles=True):
+        value  = value & 0xFFFF
+        self.set_hi(value >> 8, use_cycles)
+        self.set_lo(value & 0xFF, use_cycles)
+        if use_cycles:
+            self.cpu.cycles += 1
+    
+    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 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_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)
+        if use_cycles:
+            self.cpu.cycles -= 1
+        
+    def dec(self, use_cycles=True):
+        self.set(self.get(use_cycles) - 1, use_cycles=use_cycles)
+        if use_cycles:
+            self.cpu.cycles -= 1
+        
+    def add(self, value, use_cycles=True):
+        self.set(self.get(use_cycles) + value, use_cycles=use_cycles)
+        if use_cycles:
+            self.cpu.cycles -= 2
+            
+    
+# ------------------------------------------------------------------------------
+
+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
+            return self.cpu.read(self.hl.get(use_cycles=use_cycles)) # 1
+    
+# ------------------------------------------------------------------------------
+  
+class FlagRegister(Register):
+    """
+    The Flag Register (lower 8bit of AF register)
+      Bit  Name  Set Clr  Expl.
+      7    zf    Z   NZ   Zero Flag
+      6    n     -   -    Add/Sub-Flag (BCD)
+      5    h     -   -    Half Carry Flag (BCD)
+      4    cy    C   NC   Carry Flag
+      3-0  -     -   -    Not used (always zero)
+    Contains the result from the recent instruction which has affected flags.
+    
+    The Zero Flag (Z)
+    This bit becomes set (1) if the result of an operation has been zero (0). 
+    Used  for conditional jumps.
+    
+    The Carry Flag (C, or Cy)
+    Becomes set when the result of an addition became bigger than FFh (8bit) or
+    FFFFh (16bit). Or when the result of a subtraction or comparision became 
+    less than zero (much as for Z80 and 80x86 CPUs, but unlike as for 65XX and 
+    ARM  CPUs). Also the flag becomes set when a rotate/shift operation has 
+    shifted-out a "1"-bit.
+    Used for conditional jumps, and for instructions such like ADC, SBC, RL, 
+    RLA, etc.
+    
+    The BCD Flags (N, H)
+    These flags are (rarely) used for the DAA instruction only, N Indicates
+    whether the previous instruction has been an addition or subtraction, and H
+    indicates carry for lower 4bits of the result, also for DAA, the C flag must
+    indicate carry for upper 8bits.
+    After adding/subtracting two BCD numbers, DAA is intended to convert the
+    result into BCD format; BCD numbers are ranged from 00h to 99h rather than 
+    00h to FFh.
+    Because C and H flags must contain carry-outs for each digit, DAA cannot be
+    used for 16bit operations (which have 4 digits), or for INC/DEC operations
+    (which do not affect C-flag).    
+    """
+    def __init__(self, cpu, reset_value):
+        #assert isinstance(cpu, CPU)
+        self.cpu         = cpu
+        self.reset_value = reset_value
+        self.reset()
+         
+    def reset(self):
+        self.partial_reset()
+        
+    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):
+        if not keep_is_zero:
+            self.is_zero = False
+        if not keep_is_subtraction:
+            self.is_subtraction = False
+        if not keep_is_half_carry:
+            self.is_half_carry = False
+        if not keep_is_carry:
+            self.is_carry = False
+        if not keep_p:
+            self.p_flag = False
+        if not keep_s:
+            self.s_flag = False
+        self.lower = 0x00
+            
+    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)
+        return value + self.lower
+            
+    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))
+        self.lower          = value & 0x0F
+        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 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)
+   

pypy/lang/gameboy/debug/debug.py

 import operator
+from pypy.lang.gameboy import cpu
+import pdb
 
 DEBUG = True
 DEBUG_PRINT_LOGS = True
 
 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
     #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)
+    print_function = (lambda x: "%4s" % hex(x))
+    codes = zip(map( print_function, 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 %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])
 
     

pypy/lang/gameboy/debug/debug_rpc_xml_memory.py

     # RPC ===================================================================
         
     def close(self):
+    	pdb.set_trace()
         if not self.is_closed:
             print "python: called close"
             self.server_close()
         
     @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()),
                          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):
     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])
     
         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:
         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")

pypy/lang/gameboy/debug/gameboy_debug_entry_point.py

 
 # ------------------------------------------------------------------------------
 
-from AppKit import NSApplication
-NSApplication.sharedApplication()
+if sys.platform == 'darwin':
+	from AppKit import NSApplication
+	NSApplication.sharedApplication()
+	
 # ------------------------------------------------------------------------------
 
 ROM_PATH    = str(py.magic.autopath().dirpath().dirpath())+"/rom"
 filename    = "/Users/cami/Ausbildung/08_UNIBE_FS/bachelor/docs/roms/DieMaus.gb"
 filename    = ROM_PATH + "/rom9/rom9.gb"
-SOCKET_PORT = 55686
+SOCKET_PORT = 55687
 skipExecs   = 22545
 skipExecs   = 0
 
     gameBoy = GameBoyDebugImplementation(SOCKET_PORT, skipExecs, DebugRpcXmlMemory)
     try:
         gameBoy.load_cartridge_file(str(filename))
-    except:
+    except Exception, error:
         gameBoy.load_cartridge_file(str(filename), verify=False)
         print "Cartridge is Corrupted!"
     try:
         gameBoy.mainLoop()
-    except:
+    except Exception, error:
         print "stopped"
+        print error
+        pdb.set_trace()
 
-   
+# ------------------------------------------------------------------------------ 
     
 JMARIO_DIR =  str(py.magic.autopath().dirpath().dirpath()\
                         .dirpath().dirpath()\
                         .dirpath().dirpath()) + "/jmario"
-JAVA_CLASSPATH =[JMARIO_DIR+"/bin/", 
-                JMARIO_DIR+"/lib/xmlrpc-client-3.1.jar",
-                JMARIO_DIR+"/lib/xmlrpc-common-3.1.jar",
-                JMARIO_DIR+"/lib/ws-commons-util-1.0.2.jar",
-                JMARIO_DIR+"/lib/commons-logging-1.1.jar"];
+
+JAVA_CLASSPATH =[ JMARIO_DIR + "/bin/", JMARIO_DIR+"/build/", 
+                  JMARIO_DIR + "/lib/xmlrpc-client-3.1.jar",
+                  JMARIO_DIR + "/lib/xmlrpc-common-3.1.jar",
+                  JMARIO_DIR + "/lib/ws-commons-util-1.0.2.jar",
+                  JMARIO_DIR + "/lib/commons-logging-1.1.jar"];
                         
 def start_java_version():
     global filename
     
 # START ========================================================================
 parse_file_name()
-threading.Timer(1, start_java_version).start()
-start_python_version()
+threading.Timer(1, start_java_version    ).start()
+threading.Timer(0, start_python_version()).start()
 
 

pypy/lang/gameboy/debug/gameboy_debug_implementation.py

 from pypy.lang.gameboy.debug import debug
 from pypy.lang.gameboy.debug.debug_socket_memory import *
 import time
+import pdb
 
 # GAMEBOY ----------------------------------------------------------------------
 
 class GameBoyDebugImplementation(GameBoyImplementation):
     
     def __init__(self, debuggerPort, skipExecs=0, memory_class=DebugSocketMemory):
-        GameBoy.__init__(self)
+        GameBoyImplementation.__init__(self)
         self.cpu = DebugCPU(self.interrupt, self)
         self.init_sdl()
         self.memory = memory_class(self, debuggerPort, skipExecs)
         
+    def init_sdl(self):
+        pass;
     
     def create_drivers(self):
         # make sure only the debug drivers are implemented
         self.joypad_driver = JoypadDriverDebugImplementation()
         self.video_driver  = VideoDriverDebugImplementation()
         self.sound_driver  = SoundDriverImplementation()
+        
+    def emulate_cycle(self):
+       	self.emulate(constants.GAMEBOY_CLOCK >> 2)
    
-   
-    def handle_execution_error(self):
+    def handle_execution_error(self, error):
+    	print error
         print "closing socket connections"
+        pdb.set_trace()
         self.is_running = False
         debug.print_results()
         self.memory.close()
     def update_display(self):
         # dont update the display, we're here only for testing
         pass
+    
              
         
 # JOYPAD DRIVER ----------------------------------------------------------------
     
     def __init__(self):
         JoypadDriver.__init__(self)
+      
+    def update(self, event):
+      	pass;  
         
         
 # SOUND DRIVER -----------------------------------------------------------------

pypy/lang/gameboy/gameboy.py

     def write(self, address, data):
         receiver = self.get_receiver(address)
         if receiver is None:
-            return
-            #raise Exception("invalid read address given")
+            raise Exception("invalid read address given")
+        	#return
         receiver.write(address, data)
         if address == constants.STAT or address == 0xFFFF:
             self.cpu.handle_pending_interrupts()
     def read(self, address):
         receiver = self.get_receiver(address)
         if receiver is None:
-            return 0xFF
-            #raise Exception("invalid read address given")
+           # raise Exception("invalid read address given")
+        	return 0xFF
         return receiver.read(address)
 
     def print_receiver_msg(self, address, name):

pypy/lang/gameboy/gameboy_implementation.py

         self.joypad_driver = JoypadDriverImplementation()
         self.video_driver  = VideoDriverImplementation()
         self.sound_driver  = SoundDriverImplementation()
-   
     
     def mainLoop(self):
         self.reset()
         self.is_running = True
         try:
             while self.is_running:
-                self.handle_events()
-                self.emulate(constants.GAMEBOY_CLOCK >> 2)
-                RSDL.Delay(1)
-        except :
-            self.is_running = False 
-            lltype.free(self.event, flavor='raw')
-            RSDL.Quit()
-            self.handle_execution_error()
+            	self.emulate_cycle()
+        except Exception, error:
+            self.is_running = False
+            self.handle_execution_error(error)
         return 0
     
-    def handle_execution_error(self):
-        pass
+    def emulate_cycle(self):
+    	self.handle_events()
+    	self.emulate(constants.GAMEBOY_CLOCK >> 2)
+    	RSDL.Delay(1)
+    
+    def handle_execution_error(self, error): 
+    	lltype.free(self.event, flavor='raw')
+    	RSDL.Quit()
     
     def handle_events(self):
         self.poll_event()

pypy/lang/gameboy/test/test_cpu_2.py

     TEST_CPU.reset()
     return TEST_CPU
 
+# -----------------------------------------------------------------------------
+
 def assert_default_registers(cpu, a=constants.RESET_A, bc=constants.RESET_BC,\
                              de=constants.RESET_DE, f=constants.RESET_F,\
                              hl=constants.RESET_HL, sp=constants.RESET_SP,\
 
 def assert_registers(cpu, a=None, bc=None, de=None, f=None, hl=None, sp=None, pc=None):
     if a is not None:
-        assert cpu.a.get() == a, "Register a  is %s but should be %s" % (hex(cpu.a.get()), hex(a))
+        assert cpu.a.get() == a, \
+        "Register a  is %s but should be %s" % (hex(cpu.a.get()), hex(a))
     if bc is not None:
-        assert cpu.bc.get() == bc, "Register bc  is %s but should be %s" % (hex(cpu.bc.get()), hex(bc))
+        assert cpu.bc.get() == bc, \
+        "Register bc  is %s but should be %s" % (hex(cpu.bc.get()), hex(bc))
     if de is not None:
-        assert cpu.de.get() == de, "Register de is %s but should be %s" % (hex(cpu.de.get()),hex(de))
+        assert cpu.de.get() == de, \
+        "Register de is %s but should be %s" % (hex(cpu.de.get()),hex(de))
     if f is not None:
-        assert cpu.flag.get() == f, "Register f is %s but should be %s" % (hex(cpu.flag.get()),hex(f))
+        assert cpu.flag.get() == f, \
+        "Register f is %s but should be %s" % (hex(cpu.flag.get()),hex(f))
     if hl is not None:
-        assert cpu.hl.get() == hl, "Register hl is %s but should be %s" % (hex(cpu.hl.get()), hex(hl))
+        assert cpu.hl.get() == hl, \
+        "Register hl is %s but should be %s" % (hex(cpu.hl.get()), hex(hl))
     if sp is not None:
-        assert cpu.sp.get() == sp, "Register sp is %s but should be %s" % (hex(cpu.sp.get()), hex(sp))
+        assert cpu.sp.get() == sp, \
+        "Register sp is %s but should be %s" % (hex(cpu.sp.get()), hex(sp))
     if pc is not None:
-        assert cpu.pc.get() == pc, "Register pc is %s but should be %s" % (hex(cpu.pc.get()), hex(pc))
+        assert cpu.pc.get() == pc, \
+        "Register pc is %s but should be %s" % (hex(cpu.pc.get()), hex(pc))
         
 
 def assert_defaults(cpu, z=True, n=False, h=False, c=False, p=False, s=False):        
 
 def assert_flags(cpu, z=None, n=None, h=None, c=None, p=None, s=None):
     if z is not None:
-        assert cpu.flag.is_zero == z, "Z-Flag is %s but should be %s" % (cpu.flag.is_zero, z)
+        assert cpu.flag.is_zero == z, \
+        "Z-Flag is %s but should be %s" % (cpu.flag.is_zero, z)
     if n is not None:
-        assert cpu.flag.is_subtraction == n, "N-Flag is %s but should be %s" % (cpu.flag.is_subtraction, n)
+        assert cpu.flag.is_subtraction == n, \
+        "N-Flag is %s but should be %s" % (cpu.flag.is_subtraction, n)
     if h is not None:
-        assert cpu.flag.is_half_carry == h,  "H-Flag is %s but should be %s" % (cpu.flag.is_half_carry, h)
+        assert cpu.flag.is_half_carry == h,  \
+        "H-Flag is %s but should be %s" % (cpu.flag.is_half_carry, h)
     if c is not None:
-        assert cpu.flag.is_carry == c,  "C-Flag is %s but should be %s" % (cpu.flag.is_carry, c)
+        assert cpu.flag.is_carry == c,  \
+        "C-Flag is %s but should be %s" % (cpu.flag.is_carry, c)
     if p is not None:
-        assert cpu.flag.p_flag == p,  "P-Flag is %s but should be %s" % (cpu.flag.p_flag, p)
+        assert cpu.flag.p_flag == p,  \
+        "P-Flag is %s but should be %s" % (cpu.flag.p_flag, p)
     if s is not None:
-        assert cpu.flag.s_flag == s,  "S-Flag is %s but should be %s" % (cpu.flag.s_flag, s)
+        assert cpu.flag.s_flag == s,  \
+        "S-Flag is %s but should be %s" % (cpu.flag.s_flag, s)
 
 def prepare_for_double_fetch(cpu, value):
     prepare_for_fetch(cpu, (value & 0xFF00) >> 8, value & 0x00FF)
     assert cpu.flag.get()  == 0xFF
     assert cpu.pc.get() == 0x1234+2
     
-def test_process_2_complement():
-    assert process_2_complement(0x00) == 0
-    assert process_2_complement(0xFF) == -1
+def test_process_2s_complement():
+    assert process_2s_complement(0x00) == 0
+    assert process_2s_complement(0xFF) == -1
     
     for i in range(0x7E):
-        assert process_2_complement(i) == i
+        assert process_2s_complement(i) == i
         
     for i in range(1, 0x7E):
-        assert process_2_complement(0xFF - i+1) == -i
+        assert process_2s_complement(0xFF - i+1) == -i
     
 def test_relative_jump():
     cpu = get_cpu()

pypy/lang/gameboy/test/test_cpu_register.py

+from pypy.lang.gameboy.cpu import *
+from pypy.lang.gameboy.ram import *
+from pypy.lang.gameboy import *
+from pypy.lang.gameboy.interrupt import * 
+
+class Memory(object):
+    def __init__(self):
+        self.memory = [0xFF]*0xFFFFF
+        
+    def write(self, address, data):
+        self.memory[address] = data
+        
+    def read(self, address):
+        return self.memory[address]
+    
+global TEST_CPU
+
+TEST_CPU = None
+def get_cpu(new=False):
+    if new:
+        cpu = CPU(Interrupt(), Memory())
+        cpu.set_rom([0]*0xFFFF);
+        return cpu
+    global TEST_CPU
+    if TEST_CPU is None:
+        TEST_CPU = get_cpu(True)
+    TEST_CPU.reset()
+    return TEST_CPU
+
+# ------------------------------------------------------------
+# TEST REGISTER
+def test_register_constructor():
+    register = Register(get_cpu())
+    assert register.get() == 0
+    value = 10
+    register = Register(get_cpu(), value)
+    assert register.get() == value
+    
+def test_register():
+    register = Register(get_cpu())
+    value = 2
+    oldCycles = register.cpu.cycles
+    register.set(value)
+    assert register.get() == value
+    assert oldCycles-register.cpu.cycles == 1
+    
+def test_register_bounds():
+    register = Register(get_cpu())
+    value = 0x1234FF
+    register.set(value)
+    assert register.get() == 0xFF
+    
+def test_reset():
+    value = 0x12
+    register = Register(get_cpu(), value)
+    register.set(value+1)
+    assert register.get() == value+1
+    register.reset()
+    assert register.get() == value
+    
+# ------------------------------------------------------------
+# TEST DOUBLE REGISTER
+
+def test_double_register_constructor():
+    cpu = get_cpu()
+    register = DoubleRegister(cpu, Register(cpu), Register(cpu))
+    assert register.get() == 0
+    assert register.get_hi() == 0
+    assert register.get_lo() == 0
+    value = 0x1234
+    reg1 = Register(cpu)
+    reg1.set(0x12)
+    reg2 = Register(cpu)
+    reg2.set(0x34)
+    register = DoubleRegister(cpu, reg1, reg2)
+    assert register.hi == reg1
+    assert register.lo == reg2
+    assert register.get_hi() == reg1.get()
+    assert register.get_lo() == reg2.get()
+    
+def test_double_register():
+    cpu = get_cpu()
+    register = DoubleRegister(cpu, Register(cpu), Register(cpu))
+    value = 0x1234
+    oldCycles = register.cpu.cycles
+    register.set(value)
+    assert oldCycles-register.cpu.cycles == 1
+    assert register.get() == value
+    
+def test_double_register_bounds():
+    cpu = get_cpu()
+    register = DoubleRegister(cpu, Register(cpu), Register(cpu))
+    value = 0xFFFF1234
+    register.set(value)
+    assert register.get() == 0x1234
+    register.set(0)
+    assert register.get() == 0
+    
+def test_double_register_hilo():
+    cpu = get_cpu()
+    register = DoubleRegister(cpu, Register(cpu), Register(cpu))
+    value = 0x1234
+    valueHi = 0x12
+    valueLo = 0x34
+    oldCycles = register.cpu.cycles
+    register.set_hi_lo(valueHi, valueLo)
+    assert oldCycles-register.cpu.cycles == 2
+    assert register.get_hi() == valueHi
+    assert register.get_lo() == valueLo
+    assert register.get() == value
+    
+    valueHi = 0x56
+    oldCycles = register.cpu.cycles
+    register.set_hi(valueHi)
+    assert oldCycles-register.cpu.cycles == 1
+    assert register.get_hi() == valueHi
+    assert register.get_lo() == valueLo
+    
+    valueLo = 0x78
+    oldCycles = register.cpu.cycles
+    register.set_lo(valueLo)
+    assert oldCycles-register.cpu.cycles == 1
+    assert register.get_hi() == valueHi
+    assert register.get_lo() == valueLo
+    
+    
+def test_double_register_methods():
+    value = 0x1234
+    cpu = get_cpu()
+    register = DoubleRegister(cpu, Register(cpu), Register(cpu))
+    register.set(value)
+    
+    oldCycles = register.cpu.cycles
+    register.inc(False)
+    assert oldCycles-register.cpu.cycles == 0
+    assert register.get() == value+1
+    
+    register.set(value)
+    oldCycles = register.cpu.cycles
+    register.inc(True)
+    assert oldCycles-register.cpu.cycles == 2
+    assert register.get() == value+1
+    
+    oldCycles = register.cpu.cycles
+    register.dec()
+    assert oldCycles-register.cpu.cycles == 2
+    assert register.get() == value
+    
+    addValue = 0x1001
+    oldCycles = register.cpu.cycles
+    register.add(addValue)
+    assert oldCycles-register.cpu.cycles == 3
+    assert register.get() == value+addValue
+    
+       
+def test_double_register_reset():
+    value = 0x1234;
+    cpu = get_cpu()
+    register = DoubleRegister(cpu, Register(cpu), Register(cpu), reset_value=value)
+    register.set(value+1)
+    assert register.get() == value+1;
+    register.reset()
+    assert register.get() == value
+    

pypy/lang/gameboy/test/test_register.py

-from pypy.lang.gameboy.cpu import *
-from pypy.lang.gameboy.ram import *
-from pypy.lang.gameboy import *
-from pypy.lang.gameboy.interrupt import * 
-
-class Memory(object):
-    def __init__(self):
-        self.memory = [0xFF]*0xFFFFF
-        
-    def write(self, address, data):
-        self.memory[address] = data
-        
-    def read(self, address):
-        return self.memory[address]
-    
-global TEST_CPU
-
-TEST_CPU = None
-def get_cpu(new=False):
-    if new:
-        cpu = CPU(Interrupt(), Memory())
-        cpu.set_rom([0]*0xFFFF);
-        return cpu
-    global TEST_CPU
-    if TEST_CPU is None:
-        TEST_CPU = get_cpu(True)
-    TEST_CPU.reset()
-    return TEST_CPU
-
-# ------------------------------------------------------------
-# TEST REGISTER
-def test_register_constructor():
-    register = Register(get_cpu())
-    assert register.get() == 0
-    value = 10
-    register = Register(get_cpu(), value)
-    assert register.get() == value
-    
-def test_register():
-    register = Register(get_cpu())
-    value = 2
-    oldCycles = register.cpu.cycles
-    register.set(value)
-    assert register.get() == value
-    assert oldCycles-register.cpu.cycles == 1
-    
-def test_register_bounds():
-    register = Register(get_cpu())
-    value = 0x1234FF
-    register.set(value)
-    assert register.get() == 0xFF
-    
-def test_reset():
-    value = 0x12
-    register = Register(get_cpu(), value)
-    register.set(value+1)
-    assert register.get() == value+1
-    register.reset()
-    assert register.get() == value
-    
-# ------------------------------------------------------------
-# TEST DOUBLE REGISTER
-
-def test_double_register_constructor():
-    cpu = get_cpu()
-    register = DoubleRegister(cpu, Register(cpu), Register(cpu))
-    assert register.get() == 0
-    assert register.get_hi() == 0
-    assert register.get_lo() == 0
-    value = 0x1234
-    reg1 = Register(cpu)
-    reg1.set(0x12)
-    reg2 = Register(cpu)
-    reg2.set(0x34)
-    register = DoubleRegister(cpu, reg1, reg2)
-    assert register.hi == reg1
-    assert register.lo == reg2
-    assert register.get_hi() == reg1.get()
-    assert register.get_lo() == reg2.get()
-    
-def test_double_register():
-    cpu = get_cpu()
-    register = DoubleRegister(cpu, Register(cpu), Register(cpu))
-    value = 0x1234
-    oldCycles = register.cpu.cycles
-    register.set(value)
-    assert oldCycles-register.cpu.cycles == 1
-    assert register.get() == value
-    
-def test_double_register_bounds():
-    cpu = get_cpu()
-    register = DoubleRegister(cpu, Register(cpu), Register(cpu))
-    value = 0xFFFF1234
-    register.set(value)
-    assert register.get() == 0x1234
-    register.set(0)
-    assert register.get() == 0
-    
-def test_double_register_hilo():
-    cpu = get_cpu()
-    register = DoubleRegister(cpu, Register(cpu), Register(cpu))
-    value = 0x1234
-    valueHi = 0x12
-    valueLo = 0x34
-    oldCycles = register.cpu.cycles
-    register.set_hi_lo(valueHi, valueLo)
-    assert oldCycles-register.cpu.cycles == 2
-    assert register.get_hi() == valueHi
-    assert register.get_lo() == valueLo
-    assert register.get() == value
-    
-    valueHi = 0x56
-    oldCycles = register.cpu.cycles
-    register.set_hi(valueHi)
-    assert oldCycles-register.cpu.cycles == 1
-    assert register.get_hi() == valueHi
-    assert register.get_lo() == valueLo
-    
-    valueLo = 0x78
-    oldCycles = register.cpu.cycles
-    register.set_lo(valueLo)
-    assert oldCycles-register.cpu.cycles == 1
-    assert register.get_hi() == valueHi
-    assert register.get_lo() == valueLo
-    
-    
-def test_double_register_methods():
-    value = 0x1234
-    cpu = get_cpu()
-    register = DoubleRegister(cpu, Register(cpu), Register(cpu))
-    register.set(value)
-    
-    oldCycles = register.cpu.cycles
-    register.inc(False)
-    assert oldCycles-register.cpu.cycles == 0
-    assert register.get() == value+1
-    
-    register.set(value)
-    oldCycles = register.cpu.cycles
-    register.inc(True)
-    assert oldCycles-register.cpu.cycles == 2
-    assert register.get() == value+1
-    
-    oldCycles = register.cpu.cycles
-    register.dec()
-    assert oldCycles-register.cpu.cycles == 2
-    assert register.get() == value
-    
-    addValue = 0x1001
-    oldCycles = register.cpu.cycles
-    register.add(addValue)
-    assert oldCycles-register.cpu.cycles == 3
-    assert register.get() == value+addValue
-    
-       
-def test_double_register_reset():
-    value = 0x1234;
-    cpu = get_cpu()
-    register = DoubleRegister(cpu, Register(cpu), Register(cpu), reset_value=value)
-    register.set(value+1)
-    assert register.get() == value+1;
-    register.reset()
-    assert register.get() == value
-    

pypy/lang/gameboy/test/test_video.py

         assert video.read(address) == value
         counted_value = (counted_value + 1 ) % 0xFF
         
+def test_video_read_write_oam():
+    video = get_video()
+    value = 0
+    for i in range(constants.OAM_ADDR, constants.OAM_ADDR + constants.OAM_SIZE):
+        video.write(i, value)
+        assert video.read(i) == value
+        value = (value + 1) & 0xFF
+ 
+ 
 def test_read_write_control():
     video = get_video()
     value = 0x2

pypy/lang/gameboy/test/test_video_mode.py

+from pypy.lang.gameboy import constants
+from pypy.lang.gameboy.video_sprite import Sprite
+from pypy.lang.gameboy.video import Video
+from pypy.lang.gameboy.test.test_video import get_video
+from pypy.lang.gameboy.video_mode import Mode0, Mode1, Mode2, Mode3
+
+import py
+
+# ------------------------------------------------------------------------------
+
+
+class CallChecker(object):
+    def __init__(self):
+        self.called = False
+        
+    def __call__(self):
+        self.called = True
+        
+def get_mode0():
+    return Mode0(get_video())
+
+def get_mode1():
+    return Mode1(get_video())
+
+def get_mode2():
+    return Mode2(get_video())
+
+def get_mode3():
+    return Mode3(get_video())
+
+
+# ------------------------------------------------------------------------------
+
+def test_mode_emulate_hblank_line_y_compare():
+    mode = get_mode0()
+    
+    mode.video.status.line_y_compare_flag == True
+    mode.video.line_y = 0
+    mode.video.line_y_compare = 1
+    mode.emulate_hblank_line_y_compare()
+    assert mode.video.status.line_y_compare_flag == False
+    
+    mode.video.line_y = 0
+    mode.video.line_y_compare = 0
+    mode.video.status.line_y_compare_flag = True
+    mode.emulate_hblank_line_y_compare(stat_check=True)
+    assert mode.video.status.line_y_compare_flag == True
+    
+    mode.video.status.line_y_compare_flag = True
+    mode.emulate_hblank_line_y_compare(stat_check=False)
+    assert mode.video.status.line_y_compare_flag
+    
+    mode.video.status.line_y_compare_flag = False
+    mode.emulate_hblank_line_y_compare(stat_check=False)
+    assert mode.video.status.line_y_compare_flag
+