[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