[pypy-svn] r55507 - in pypy/dist/pypy/lang/gameboy: . test

cami at codespeak.net cami at codespeak.net
Mon Jun 2 22:25:50 CEST 2008


Author: cami
Date: Mon Jun  2 22:25:47 2008
New Revision: 55507

Added:
   pypy/dist/pypy/lang/gameboy/gameboy_implementation.py
      - copied unchanged from r55500, pypy/dist/pypy/lang/gameboy/gameboyImplementation.py
Removed:
   pypy/dist/pypy/lang/gameboy/gameboyImplementation.py
Modified:
   pypy/dist/pypy/lang/gameboy/constants.py
   pypy/dist/pypy/lang/gameboy/cpu.py
   pypy/dist/pypy/lang/gameboy/gameboy.py
   pypy/dist/pypy/lang/gameboy/gameboyTest.py
   pypy/dist/pypy/lang/gameboy/test/test_timer.py
   pypy/dist/pypy/lang/gameboy/timer.py
   pypy/dist/pypy/lang/gameboy/video.py
Log:
renamed gameboyImplementation package with use of underscore
extenede timer tests
tried to refactor timer_emulate_divide method


Modified: pypy/dist/pypy/lang/gameboy/constants.py
==============================================================================
--- pypy/dist/pypy/lang/gameboy/constants.py	(original)
+++ pypy/dist/pypy/lang/gameboy/constants.py	Mon Jun  2 22:25:47 2008
@@ -34,7 +34,7 @@
 TYPE_MBC5_RAM_BATTERY = 0x1B
 
 TYPE_MBC5_RUMBLE             = 0x1C
-TYPE_MBC5_RUMBLE_RAM          = 0x1D
+TYPE_MBC5_RUMBLE_RAM         = 0x1D
 TYPE_MBC5_RUMBLE_RAM_BATTERY = 0x1E
 
 TYPE_HUC3_RTC_RAM     = 0xFE
@@ -157,11 +157,11 @@
 # ___________________________________________________________________________
 
 # Joypad Registers P+
-JOYP = 0xFF00
+JOYP          = 0xFF00
  
 
 # Joypad Poll Speed (64 Hz)
-JOYPAD_CLOCK = GAMEBOY_CLOCK >> 6
+JOYPAD_CLOCK  = GAMEBOY_CLOCK >> 6
 
 
 BUTTON_DOWN   = 0x08

Modified: pypy/dist/pypy/lang/gameboy/cpu.py
==============================================================================
--- pypy/dist/pypy/lang/gameboy/cpu.py	(original)
+++ pypy/dist/pypy/lang/gameboy/cpu.py	Mon Jun  2 22:25:47 2008
@@ -117,7 +117,7 @@
     
     def __init__(self, cpu, reset_value):
         assert isinstance(cpu, CPU)
-        self.cpu = cpu
+        self.cpu         = cpu
         self.reset_value = reset_value
         self.reset()
          
@@ -141,7 +141,7 @@
         self.lower = 0x00
             
     def get(self, use_cycles=True):
-        value = 0
+        value  = 0
         value += (int(self.c_flag) << 4)
         value += (int(self.h_flag) << 5)
         value += (int(self.n_flag) << 6)
@@ -153,7 +153,7 @@
         self.h_flag = bool(value & (1 << 5))
         self.n_flag = bool(value & (1 << 6))
         self.z_flag = bool(value & (1 << 7))
-        self.lower = value & 0x0F
+        self.lower  = value & 0x0F
         if use_cycles:
             self.cpu.cycles -= 1
         
@@ -574,12 +574,6 @@
         # DEC rr
         register.dec()
 
-#    def inc_double_register(self, doubleRegister):
-#        doubleRegister.set((doubleRegister.get() + 1) & 0xFF)
-#        
-#    def dec_double_register(self, doubleRegister):        
-#        doubleRegister.set((doubleRegister.get() - 1) & 0xFF)
-   
     def inc(self, getCaller, setCaller):
         # 1 cycle
         data = (getCaller.get() + 1) & 0xFF
@@ -910,7 +904,7 @@
 
     def disable_interrups(self):
         # DI/EI 1 cycle
-        self.ime = False
+        self.ime     = False
         self.cycles -= 1
 
     def enable_interrupts(self):

Modified: pypy/dist/pypy/lang/gameboy/gameboy.py
==============================================================================
--- pypy/dist/pypy/lang/gameboy/gameboy.py	(original)
+++ pypy/dist/pypy/lang/gameboy/gameboy.py	Mon Jun  2 22:25:47 2008
@@ -81,9 +81,11 @@
         #self.draw_logo()
 
     def get_cycles(self):
-        return min(min(min(min( self.video.get_cycles(), self.serial.get_cycles()),
-                    self.timer.get_cycles()), self.sound.get_cycles()),
-                    self.joypad.get_cycles())
+        return min(min(min(min( self.video.get_cycles(),
+                                self.serial.get_cycles()),
+                                self.timer.get_cycles()),
+                                self.sound.get_cycles()),
+                                self.joypad.get_cycles())
 
     def emulate(self, ticks):
         while ticks > 0:
@@ -185,11 +187,9 @@
             pattern0 = ((bits >> 0) & 0x80) + ((bits >> 1) & 0x60) + \
                        ((bits >> 2) & 0x18) + ((bits >> 3) & 0x06) + \
                        ((bits >> 4) & 0x01)
-
             pattern1 = ((bits << 4) & 0x80) + ((bits << 3) & 0x60) + \
                        ((bits << 2) & 0x18) + ((bits << 1) & 0x06) + \
                        ((bits << 0) & 0x01)
-
             self.video.write(0x8010 + (index << 3), pattern0)
             self.video.write(0x8012 + (index << 3), pattern0)
             self.video.write(0x8014 + (index << 3), pattern1)

Modified: pypy/dist/pypy/lang/gameboy/gameboyTest.py
==============================================================================
--- pypy/dist/pypy/lang/gameboy/gameboyTest.py	(original)
+++ pypy/dist/pypy/lang/gameboy/gameboyTest.py	Mon Jun  2 22:25:47 2008
@@ -1,4 +1,4 @@
-from pypy.lang.gameboy.gameboyImplementation import *
+from pypy.lang.gameboy.gameboy_implementation import *
 import sys
 
 from AppKit import NSApplication

Modified: pypy/dist/pypy/lang/gameboy/test/test_timer.py
==============================================================================
--- pypy/dist/pypy/lang/gameboy/test/test_timer.py	(original)
+++ pypy/dist/pypy/lang/gameboy/test/test_timer.py	Mon Jun  2 22:25:47 2008
@@ -85,38 +85,129 @@
     timer.timer_cycles = value
     assert timer.get_cycles() == timer.timer_cycles
     
-def test_emulate_divider_normal():
+def test_emulate_divider():
     timer = get_timer()
-    value = 2
-    timer.timer_cycles = 0
-    timer.emulate_timer(value)
-    
-def test_test_emulate_divider_zero():
-    timer = get_timer()
-    value = 2
-    timer.timer_cycles = value
-    timer.emulate_timer(value)
-    assert timer.timer_cycles == value
+    timer.divider_cycles = 10
+    timer.div = 1
+    timer.emulate_divider(2)
+    assert timer.div == 1
+    assert timer.divider_cycles == 8
+    
+def test_test_emulate_divider_below_zero():
+    timer = get_timer()
+    timer.divider_cycles = 0
+    timer.div = 1
+    timer.emulate_divider(2)
+    assert timer.divider_cycles == constants.DIV_CLOCK - 2
+    assert timer.div == 2
+    
+    timer.divider_cycles = 0
+    timer.div = 1
+    timer.emulate_divider(0)
+    assert timer.divider_cycles == constants.DIV_CLOCK
+    assert timer.div == 2
+    
+    timer.divider_cycles = 0
+    timer.div = 0xFF
+    timer.emulate_divider(2)
+    assert timer.divider_cycles == constants.DIV_CLOCK - 2
+    assert timer.div == 0
+    
+    timer.divider_cycles = 0
+    timer.div = 0
+    timer.emulate_divider(2*constants.DIV_CLOCK)
+    assert timer.divider_cycles == constants.DIV_CLOCK
+    assert timer.div == 3
     
 def test_emulate_timer_tac_return():
     timer = get_timer()
-    timer.tac = 0
+    timer.tac          = 0
     timer.timer_cycles = -10
-    cycles = timer.timer_cycles
+    timer.tima         = 3
     timer.emulate_timer(10)
-    assert timer.timer_cycles == cycles
+    assert timer.timer_cycles == -10
+    assert timer.tima == 3
     
 def test_emulate_timer_timer_cycles_return():
     timer = get_timer()
-    timer.tac = 0x04
-    value = 10
-    timer.timer_cycles = value+1
-    cycles = timer.timer_cycles
-    timer.emulate_timer(value)
+    timer.tac          = 0x04
+    timer.timer_cycles = 11
+    cycles             = timer.timer_cycles
+    timer.emulate_timer(10)
     assert timer.timer_cycles == 1
     
+def test_emulate_timer_timer_cycles_tima():
     timer = get_timer()
-    timer.tac = 0x04
+    timer.tac          = 0x04
+    timer.tima         = 0
+    timer.timer_cycles = 0
+    timer.timer_clock  = 5
+    timer.emulate_timer(10)
+    assert timer.tima == 3
+    assert timer.timer_cycles == 5
+    timer.tac          = 0x04
+    timer.tima         = 0xFF
+    timer.tma          = 5
+    timer.timer_cycles = 0
+    timer.timer_clock  = 5
+    timer.emulate_timer(10)
+    assert timer.tima == 2+5
+    assert timer.timer_cycles == 5
+    
+def test_emulate_timer_timer_cycles_tima_single_0_pass():
+    timer = get_timer()
+    timer.tac          = 0x04
+    timer.tima         = 0xFF
+    timer.tma          = 0
+    timer.timer_cycles = 0
+    timer.timer_clock  = 5
+    timer.emulate_timer(10)
+    assert timer.tima == 2
+    assert timer.timer_cycles == 5
+    
+    timer.tac          = 0x04
+    timer.tima         = 0xFF
+    timer.tma          = 1
+    timer.timer_cycles = 0
+    timer.timer_clock  = 5
+    timer.emulate_timer(10)
+    assert timer.tima == 2+1
+    assert timer.timer_cycles == 5
+    
+    
+def test_emulate_timer_timer_cycles_tima_mutli_0_pass():
+    timer = get_timer()
+    timer.tac          = 0x04
+    timer.tima         = 0xFF
+    timer.tma          = 0
+    timer.timer_cycles = 0
+    timer.timer_clock  = 1
+    # emulate 0xFF + 1+1 times => 2 zero passes
+    timer.emulate_timer(0xFF+1)
+    assert timer.tima == 0
+    assert timer.timer_cycles == 1
+    
+    timer.tac          = 0x04
+    timer.tima         = 0xFF
+    timer.tma          = 1
+    timer.timer_cycles = 0
+    timer.timer_clock  = 1
+    # emulate 0xFF + 1+1 times => 2 zero passes
+    timer.emulate_timer(0xFF+1)
+    assert timer.tima == 2*1
+    assert timer.timer_cycles == 1
+    
+    # emulate n zero passes
+    for i in range(1,10):
+        timer.tac          = 0x04
+        timer.tima         = 0xFF
+        timer.tma          = i
+        timer.timer_cycles = 0
+        timer.timer_clock  = 1
+        timer.emulate_timer((0xFF+1)*(i-1))
+        assert timer.tima == i*i
+        assert timer.timer_cycles == 1
+    
     
     
 def test_emulate_timer_interrupt():

Modified: pypy/dist/pypy/lang/gameboy/timer.py
==============================================================================
--- pypy/dist/pypy/lang/gameboy/timer.py	(original)
+++ pypy/dist/pypy/lang/gameboy/timer.py	Mon Jun  2 22:25:47 2008
@@ -9,6 +9,7 @@
 from math import ceil
 from pypy.lang.gameboy.ram import iMemory
 import time
+import math
 
 
 class Timer(iMemory):
@@ -91,9 +92,9 @@
         self.divider_cycles -= ticks
         if self.divider_cycles > 0:
             return
-        while self.divider_cycles <= 0:
-            self.div = (self.div + 1) & 0xFF;
-            self.divider_cycles += constants.DIV_CLOCK;
+        count = int(math.ceil(-self.divider_cycles / constants.DIV_CLOCK)+1)
+        self.divider_cycles += count*constants.DIV_CLOCK
+        self.div = (self.div + count) % (0xFF+1);
             
     def emulate_timer(self,  ticks):
         if (self.tac & 0x04) == 0:
@@ -105,7 +106,21 @@
             if self.tima == 0x00:
                 self.tima = self.tma
                 self.interrupt.raise_interrupt(constants.TIMER)
-
+    
+    #def emulate_timer(self,  ticks):
+    #    if (self.tac & 0x04) == 0:
+    #        return
+    #    self.timer_cycles -= ticks
+    #    if self.timer_cycles > 0: return
+    #    count = int(math.ceil(-self.timer_cycles / self.timer_clock)) + 1
+    #    self.timer_cycles += self.timer_clock*count
+    #    # check for zero pass
+    #    if (self.tima + count) > 0xFF:
+    #        self.interrupt.raise_interrupt(constants.TIMER)
+    #        zero_passes = math.ceil(self.tima / count)
+    #        self.tima = (self.tma + count - zero_passes ) % (0xFF +1)
+    #    else:
+    #        self.tima = (self.tima + count) % (0xFF +1)
 # CLOCK DRIVER -----------------------------------------------------------------
 
 class Clock(object):

Modified: pypy/dist/pypy/lang/gameboy/video.py
==============================================================================
--- pypy/dist/pypy/lang/gameboy/video.py	(original)
+++ pypy/dist/pypy/lang/gameboy/video.py	Mon Jun  2 22:25:47 2008
@@ -33,12 +33,22 @@
 # -----------------------------------------------------------------------------
 
 def VideoStatus(object):
+    # used for enabled or disabled window or background
+    # Bit 7 - LCD Display Enable             (0=Off, 1=On)
+    # Bit 6 - Window Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF)
+    # Bit 5 - Window Display Enable          (0=Off, 1=On)
+    # Bit 4 - BG & Window Tile Data Select   (0=8800-97FF, 1=8000-8FFF)
+    # Bit 3 - BG Tile Map Display Select     (0=9800-9BFF, 1=9C00-9FFF)
+    # Bit 2 - OBJ (Sprite) Size              (0=8x8, 1=8x16)
+    # Bit 1 - OBJ (Sprite) Display Enable    (0=Off, 1=On)
+    # Bit 0 - BG Display (for CGB see below) (0=Off, 1=On)
+    
     def __init__(self, video):
         self.video = video
         self.reset()
         
     def reset(self):
-        self.mode               = False
+        self.mode               = 0x02
         self.lyc_ly_coincidence = False
         self.h_blank_interrupt  = False
         self.oam_interrupt      = False
@@ -65,13 +75,6 @@
 # -----------------------------------------------------------------------------
 
 class Video(iMemory):
-    #frames = 0
-    #frame_skip = 0
-
-     # Line Buffer, OAM Cache and Color Palette
-    #line = []#= new int[8 + 160 + 8]
-    #objects = []#= new int[OBJECTS_PER_LINE]
-    #palette = []#= new int[1024]
 
     def __init__(self, video_driver, interrupt, memory):
         assert isinstance(video_driver, VideoDriver)
@@ -88,15 +91,6 @@
 
     def reset(self):
         self.cycles     = constants.MODE_2_TICKS
-        # used for enabled or disabled window or background
-        # Bit 7 - LCD Display Enable             (0=Off, 1=On)
-        # Bit 6 - Window Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF)
-        # Bit 5 - Window Display Enable          (0=Off, 1=On)
-        # Bit 4 - BG & Window Tile Data Select   (0=8800-97FF, 1=8000-8FFF)
-        # Bit 3 - BG Tile Map Display Select     (0=9800-9BFF, 1=9C00-9FFF)
-        # Bit 2 - OBJ (Sprite) Size              (0=8x8, 1=8x16)
-        # Bit 1 - OBJ (Sprite) Display Enable    (0=Off, 1=On)
-        # Bit 0 - BG Display (for CGB see below) (0=Off, 1=On)
         self.control    = 0x91
         self.stat       = 2
         self.line_y     = 0
@@ -403,8 +397,8 @@
             self.emulate_vblank_other()
 
     def emulate_vblank_vblank(self):
-        self.vblank = False
-        self.stat = (self.stat & 0xFC) | 0x01
+        self.vblank  = False
+        self.stat    = (self.stat & 0xFC) | 0x01
         self.cycles += constants.MODE_1_TICKS - constants.MODE_1_BEGIN_TICKS
         # V-Blank interrupt
         if (self.stat & 0x10) != 0:
@@ -413,7 +407,7 @@
         self.interrupt.raise_interrupt(constants.VBLANK)
         
     def emulate_vblank_first_y_line(self):
-        self.stat = (self.stat & 0xFC) | 0x02
+        self.stat    = (self.stat & 0xFC) | 0x02
         self.cycles += constants.MODE_2_TICKS
         #OAM interrupt
         if (self.stat & 0x20) != 0 and (self.stat & 0x44) != 0x44:
@@ -421,8 +415,8 @@
             
     def emulate_vblank_other(self):
         if self.line_y < 153:
-            self.line_y+=1
-            self.stat = (self.stat & 0xFC) | 0x01
+            self.line_y += 1
+            self.stat    = (self.stat & 0xFC) | 0x01
             if self.line_y == 153:
                 self.cycles += constants.MODE_1_END_TICKS
             else:
@@ -462,9 +456,9 @@
             self.line[x] = 0x00
 
     def draw_background(self):
-        y = (self.scroll_y + self.line_y) & 0xFF
-        x = self.scroll_x & 0xFF
-        tileMap = constants.VRAM_MAP_A
+        y        = (self.scroll_y + self.line_y) & 0xFF
+        x        = self.scroll_x & 0xFF
+        tileMap  = constants.VRAM_MAP_A
         if (self.control & 0x08) != 0:
             tileMap =  constants.VRAM_MAP_B
         tileData = constants.VRAM_DATA_B
@@ -513,9 +507,7 @@
                 continue
             tile = self.oam[offset + 2] & 0xFF
             flags = self.oam[offset + 3] & 0xFF
-
             y = self.line_y - y + 16
-
             if ((self.control & 0x04) != 0):
                 # 8x16 tile size
                 if (y < 0 or y > 15):



More information about the Pypy-commit mailing list