[pypy-svn] r55663 - in pypy/dist/pypy/lang/gameboy: . test
cami at codespeak.net
cami at codespeak.net
Sun Jun 8 14:55:14 CEST 2008
Author: cami
Date: Sun Jun 8 14:55:12 2008
New Revision: 55663
Modified:
pypy/dist/pypy/lang/gameboy/constants.py
pypy/dist/pypy/lang/gameboy/cpu.py
pypy/dist/pypy/lang/gameboy/interrupt.py
pypy/dist/pypy/lang/gameboy/joypad.py
pypy/dist/pypy/lang/gameboy/ram.py
pypy/dist/pypy/lang/gameboy/serial.py
pypy/dist/pypy/lang/gameboy/test/test_cpu.py
pypy/dist/pypy/lang/gameboy/test/test_interrupt.py
pypy/dist/pypy/lang/gameboy/test/test_serial.py
pypy/dist/pypy/lang/gameboy/test/test_timer.py
pypy/dist/pypy/lang/gameboy/timer.py
Log:
renamed constants of timer and serlial for better readability
adaoted tests
fixed bug in interrupt: enable is not a bool its an int!
adapted tests
minor refactoring: mostly code formattinh
Modified: pypy/dist/pypy/lang/gameboy/constants.py
==============================================================================
--- pypy/dist/pypy/lang/gameboy/constants.py (original)
+++ pypy/dist/pypy/lang/gameboy/constants.py Sun Jun 8 14:55:12 2008
@@ -14,48 +14,48 @@
# ___________________________________________________________________________
-TYPE_ROM_ONLY = 0x00
+TYPE_ROM_ONLY = 0x00
-TYPE_MBC1 = 0x01
-TYPE_MBC1_RAM = 0x02
-TYPE_MBC1_RAM_BATTERY = 0x03
-
-TYPE_MBC2 = 0x05
-TYPE_MBC2_BATTERY = 0x06
-
-TYPE_MBC3_RTC_BATTERY = 0x0F
-TYPE_MBC3_RTC_RAM_BATTERY = 0x10
-TYPE_MBC3 = 0x11
-TYPE_MBC3_RAM = 0x12
-TYPE_MBC3_RAM_BATTERY = 0x13
-
-TYPE_MBC5 = 0x19
-TYPE_MBC5_RAM = 0x1A
-TYPE_MBC5_RAM_BATTERY = 0x1B
+TYPE_MBC1 = 0x01
+TYPE_MBC1_RAM = 0x02
+TYPE_MBC1_RAM_BATTERY = 0x03
+
+TYPE_MBC2 = 0x05
+TYPE_MBC2_BATTERY = 0x06
+
+TYPE_MBC3_RTC_BATTERY = 0x0F
+TYPE_MBC3_RTC_RAM_BATTERY = 0x10
+TYPE_MBC3 = 0x11
+TYPE_MBC3_RAM = 0x12
+TYPE_MBC3_RAM_BATTERY = 0x13
+
+TYPE_MBC5 = 0x19
+TYPE_MBC5_RAM = 0x1A
+TYPE_MBC5_RAM_BATTERY = 0x1B
TYPE_MBC5_RUMBLE = 0x1C
TYPE_MBC5_RUMBLE_RAM = 0x1D
TYPE_MBC5_RUMBLE_RAM_BATTERY = 0x1E
-TYPE_HUC3_RTC_RAM = 0xFE
-TYPE_HUC1_RAM_BATTERY = 0xFF
+TYPE_HUC3_RTC_RAM = 0xFE
+TYPE_HUC1_RAM_BATTERY = 0xFF
-CARTRIDGE_TYPE_ADDRESS = 0x0147
-CARTRIDGE_ROM_SIZE_ADDRESS = 0x0148
-CARTRIDGE_RAM_SIZE_ADDRESS = 0x0149
-CARTRIDGE_RAM_SIZE_MAPPING = {0x00:0, 0x01:8192, 0x02:8192, 0x03:32768}
-DESTINATION_CODE_ADDRESS = 0x014A
-LICENSEE_ADDRESS = 0x014B
-ROM_VERSION_ADDRESS = 0x014C
-HEADER_CHECKSUM_ADDRESS = 0x014D
-CHECKSUM_A_ADDRESS = 0x014E
-CHECKSUM_B_ADDRESS = 0x014F
+CARTRIDGE_TYPE_ADDRESS = 0x0147
+CARTRIDGE_ROM_SIZE_ADDRESS = 0x0148
+CARTRIDGE_RAM_SIZE_ADDRESS = 0x0149
+CARTRIDGE_RAM_SIZE_MAPPING = {0x00:0, 0x01:8192, 0x02:8192, 0x03:32768}
+DESTINATION_CODE_ADDRESS = 0x014A
+LICENSEE_ADDRESS = 0x014B
+ROM_VERSION_ADDRESS = 0x014C
+HEADER_CHECKSUM_ADDRESS = 0x014D
+CHECKSUM_A_ADDRESS = 0x014E
+CHECKSUM_B_ADDRESS = 0x014F
# ROM Bank Size (16KB)
-ROM_BANK_SIZE = 0x4000
+ROM_BANK_SIZE = 0x4000
# constants.RAM Bank Size (8KB)
-RAM_BANK_SIZE = 0x2000
+RAM_BANK_SIZE = 0x2000
CARTRIDGE_FILE_EXTENSION = ".gb"
CARTRIDGE_COLOR_FILE_EXTENSION = ".gbc"
@@ -65,13 +65,13 @@
# CPU FLAGS
# ___________________________________________________________________________
-Z_FLAG = 0x80
-N_FLAG = 0x40
-H_FLAG = 0x20
-C_FLAG = 0x10
+Z_FLAG = 0x80
+N_FLAG = 0x40
+H_FLAG = 0x20
+C_FLAG = 0x10
RESET_A = 0x01
-#RESET_F = 0xB0
+#RESET_F = 0xB0
RESET_F = 0x80
RESET_BC = 0x0013
RESET_DE = 0x00D8
@@ -85,8 +85,8 @@
# ___________________________________________________________________________
# Interrupt Registers
-IE = 0xFFFF # Interrupt Enable
-IF = 0xFF0F # Interrupt Flag
+IE = 0xFFFF # Interrupt Enable
+IF = 0xFF0F # Interrupt Flag
# Interrupt Flags
VBLANK = 0x01 # V-Blank Interrupt (INT 40h)
@@ -115,19 +115,19 @@
WX = 0xFF4B # Window X Position (0-166)
# OAM Register Addresses
-OAM_ADDR = 0xFE00 # OAM Object Attribute Map (FE00..FE9F)
-OAM_SIZE = 0xA0
+OAM_ADDR = 0xFE00 # OAM Object Attribute Map (FE00..FE9F)
+OAM_SIZE = 0xA0
# Video RAM Addresses
-VRAM_ADDR = 0x8000 # 8KB Video RAM (8000..9FFF)
-VRAM_SIZE = 0x2000
+VRAM_ADDR = 0x8000 # 8KB Video RAM (8000..9FFF)
+VRAM_SIZE = 0x2000
# VRAM Tile Data/Maps Addresses
VRAM_DATA_A = 0x0000 # 4KB Tile Data (8000..8FFF)
VRAM_DATA_B = 0x0800 # 4KB Tile Data (8800..97FF)
-VRAM_MAP_A = 0x1800 # 1KB BG Tile Map 0 (9800..9BFF)
-VRAM_MAP_B = 0x1C00 # 1KB BG Tile Map 1 (9C00..9FFF)
+VRAM_MAP_A = 0x1800 # 1KB BG Tile Map 0 (9800..9BFF)
+VRAM_MAP_B = 0x1C00 # 1KB BG Tile Map 1 (9C00..9FFF)
#LCD Mode Durations
@@ -141,7 +141,7 @@
MODE_1_END_TICKS = 1 # V-Blank Line 153
# Objects per Line
-OBJECTS_PER_LINE = 10
+OBJECTS_PER_LINE = 10
# LCD Color Palette
COLOR_MAP =[
@@ -181,14 +181,14 @@
# ___________________________________________________________________________
# Serial Clock Speed (8 x 1024 bits/sec)
-SERIAL_CLOCK = GAMEBOY_CLOCK >> 16
+SERIAL_CLOCK = GAMEBOY_CLOCK >> 16
# Serial Idle Speed (128 Hz)
SERIAL_IDLE_CLOCK = GAMEBOY_CLOCK >> 7
# Serial Register Addresses
-SB = 0xFF01 # Serial Transfer Data
-SC = 0xFF02 # Serial Transfer Control
+SERIAL_TRANSFER_DATA = 0xFF01
+SERIAL_TRANSFER_CONTROL = 0xFF02
Modified: pypy/dist/pypy/lang/gameboy/cpu.py
==============================================================================
--- pypy/dist/pypy/lang/gameboy/cpu.py (original)
+++ pypy/dist/pypy/lang/gameboy/cpu.py Sun Jun 8 14:55:12 2008
@@ -345,16 +345,16 @@
def emulate(self, ticks):
self.cycles += ticks
- self.handle_pending_interrupt()
+ self.handle_pending_interrupts()
while self.cycles > 0:
self.execute(self.fetch())
def emulate_step(self):
- self.handle_pending_interrupt()
+ self.handle_pending_interrupts()
self.execute(self.fetch())
- def handle_pending_interrupt(self):
+ def handle_pending_interrupts(self):
if self.halted:
if self.interrupt.is_pending():
self.halted = False
@@ -914,7 +914,7 @@
# 1 cycle
self.ime = True
self.execute(self.fetch()) # 1
- self.handle_pending_interrupt()
+ self.handle_pending_interrupts()
def halt(self):
# HALT/STOP
@@ -922,7 +922,7 @@
# emulate bug when interrupts are pending
if not self.ime and self.interrupt.is_pending():
self.execute(self.memory.read(self.pc.get()))
- self.handle_pending_interrupt()
+ self.handle_pending_interrupts()
def stop(self):
# 0 cycles
Modified: pypy/dist/pypy/lang/gameboy/interrupt.py
==============================================================================
--- pypy/dist/pypy/lang/gameboy/interrupt.py (original)
+++ pypy/dist/pypy/lang/gameboy/interrupt.py Sun Jun 8 14:55:12 2008
@@ -12,18 +12,25 @@
def reset(self):
self._is_pending = self._reset
+ self.enabled = False
def is_pending(self):
return self._is_pending
def set_pending(self, _is_pending=True):
self._is_pending = _is_pending
+
+ def is_enabled(self):
+ return self.enabled
+
+ def set_enabled(self, enabled):
+ self.enabled = enabled
+# --------------------------------------------------------------------
class Interrupt(iMemory):
"""
PyBoy GameBoy (TM) Emulator
-
Interrupt Controller
"""
@@ -34,9 +41,9 @@
self.reset()
def create_interrupt_flags(self):
- self.vblank = InterruptFlag(True, constants.VBLANK, 0x40)
- self.lcd = InterruptFlag(False, constants.LCD, 0x48)
- self.timer = InterruptFlag(False, constants.TIMER, 0x50)
+ self.vblank = InterruptFlag(True, constants.VBLANK, 0x40)
+ self.lcd = InterruptFlag(False, constants.LCD, 0x48)
+ self.timer = InterruptFlag(False, constants.TIMER, 0x50)
self.serial = InterruptFlag(False, constants.SERIAL, 0x58)
self.joypad = InterruptFlag(False, constants.JOYPAD, 0x60)
@@ -50,55 +57,54 @@
self.mask_mapping[flag.mask] = flag
def reset(self):
- self.enable = False
+ self.set_enable_mask(0x0)
for flag in self.interrupt_flags:
flag.reset()
-
- def is_pending(self, mask=None):
- if not self.enable:
- return False
- if mask is None:
- return self.vblank.is_pending()
- elif self.vblank.is_pending():
- return self.mask_mapping[mask].is_pending()
- else:
- return False
-
- def raise_interrupt(self, mask):
- self.mask_mapping[mask].set_pending(True)
-
- def lower(self, mask):
- self.mask_mapping[mask].set_pending(False)
-
+
+
def write(self, address, data):
if address == constants.IE:
- self.set_interrupt_enable(data)
+ self.set_enable_mask(data)
elif address == constants.IF:
self.set_fnterrupt_flag(data)
def read(self, address):
if address == constants.IE:
- return self.get_interrupt_enable()
+ return self.get_enable_mask()
elif address == constants.IF:
return self.get_interrupt_flag()
return 0xFF
+
+
+ def is_pending(self, mask=0xFF):
+ return (self.get_enable_mask() & self.get_interrupt_flag() & mask) != 0
+
+ def raise_interrupt(self, mask):
+ self.mask_mapping[mask].set_pending(True)
- def get_interrupt_enable(self):
- return int(self.enable)
+ def lower(self, mask):
+ self.mask_mapping[mask].set_pending(False)
+
+ def get_enable_mask(self):
+ enabled = 0x00
+ for interrupt_flag in self.interrupt_flags:
+ if interrupt_flag.is_enabled():
+ enabled |= interrupt_flag.mask
+ return enabled | self.enable_rest_data;
- def set_interrupt_enable(self, isEnabled=True):
- self.enable = bool(isEnabled)
+ def set_enable_mask(self, enable_mask):
+ for flag in self.interrupt_flags:
+ flag.set_enabled((enable_mask & flag.mask) != 0)
+ self.enable_rest_data = enable_mask & 0xE0;
+
def get_interrupt_flag(self):
flag = 0x00
for interrupt_flag in self.interrupt_flags:
if interrupt_flag.is_pending():
flag |= interrupt_flag.mask
- return 0xE0 | flag
+ return flag | 0xE0
def set_fnterrupt_flag(self, data):
for flag in self.interrupt_flags:
- if (data & flag.mask) != 0:
- flag.set_pending(True)
- else:
- flag.set_pending(False)
+ flag.set_pending((data & flag.mask) != 0)
Modified: pypy/dist/pypy/lang/gameboy/joypad.py
==============================================================================
--- pypy/dist/pypy/lang/gameboy/joypad.py (original)
+++ pypy/dist/pypy/lang/gameboy/joypad.py Sun Jun 8 14:55:12 2008
@@ -31,6 +31,7 @@
if self.driver.is_raised():
self.update()
self.cycles = constants.JOYPAD_CLOCK
+ #self.cycles = 150
def write(self, address, data):
if address == constants.JOYP:
Modified: pypy/dist/pypy/lang/gameboy/ram.py
==============================================================================
--- pypy/dist/pypy/lang/gameboy/ram.py (original)
+++ pypy/dist/pypy/lang/gameboy/ram.py Sun Jun 8 14:55:12 2008
@@ -17,24 +17,20 @@
class RAM(iMemory):
def __init__(self):
- # Work RAM
self.work_ram = [0]*8192
- # High RAM
self.hi_ram = [0]*128
self.reset()
def reset(self):
- # Work RAM
self.work_ram = [0]*8192
- # High RAM
- self.hi_ram = [0]*128
+ self.hi_ram = [0]*128
def write(self, address, data):
# C000-DFFF Work RAM (8KB)
# E000-FDFF Echo RAM
if address >= 0xC000 and address <= 0xFDFF:
self.work_ram[address & 0x1FFF] = data & 0xFF
- # FF80-FFFE High RAM
+ # FF80-FFFE
elif address >= 0xFF80 and address <= 0xFFFE:
self.hi_ram[address & 0x7F] = data & 0xFF
@@ -42,8 +38,8 @@
# C000-DFFF Work RAM
# E000-FDFF Echo RAM
if address >= 0xC000 and address <= 0xFDFF:
- return self.work_ram[address & 0x1FFF] & 0xFF
- # FF80-FFFE High RAM
+ return self.work_ram[address & 0x1FFF]
+ # FF80-FFFE
elif address >= 0xFF80 and address <= 0xFFFE:
- return self.hi_ram[address & 0x7F] & 0xFF
+ return self.hi_ram[address & 0x7F]
raise Exception("Invalid Memory access, address out of range")
\ No newline at end of file
Modified: pypy/dist/pypy/lang/gameboy/serial.py
==============================================================================
--- pypy/dist/pypy/lang/gameboy/serial.py (original)
+++ pypy/dist/pypy/lang/gameboy/serial.py Sun Jun 8 14:55:12 2008
@@ -15,8 +15,8 @@
self.reset()
def reset(self):
- self.cycles = int(constants.SERIAL_CLOCK)
- self.serial_data = 0x00
+ self.cycles = int(constants.SERIAL_CLOCK)
+ self.serial_data = 0x00
self.serial_control = 0x00
def get_cycles(self):
@@ -27,11 +27,17 @@
return
self.cycles -= ticks
if self.cycles <= 0:
- self.serial_data = 0xFF
+ self.serial_data = 0xFF
self.serial_control &= 0x7F
- self.cycles = constants.SERIAL_IDLE_CLOCK
+ self.cycles = constants.SERIAL_IDLE_CLOCK
self.interrupt.raise_interrupt(constants.SERIAL)
+ def write(self, address, data):
+ if address == constants.SERIAL_TRANSFER_DATA:
+ self.set_serial_data(data)
+ elif address == constants.SERIAL_TRANSFER_CONTROL:
+ self.set_serial_control(data)
+
def set_serial_data(self, data):
self.serial_data = data
@@ -39,25 +45,17 @@
self.serial_control = data
# HACK: delay the serial interrupt
self.cycles = constants.SERIAL_IDLE_CLOCK + constants.SERIAL_CLOCK
-
- def get_serial_data(self):
- return self.serial_data
-
- def get_serial_control(self):
- return self.serial_control
-
- def write(self, address, data):
- address = int(address)
- if address == constants.SB:
- self.set_serial_data(data)
- elif address == constants.SC:
- self.set_serial_control(data)
-
+
def read(self, address):
- address = int(address)
- if address == constants.SB:
+ if address == constants.SERIAL_TRANSFER_DATA:
return self.get_serial_data()
- elif address == constants.SC:
+ elif address == constants.SERIAL_TRANSFER_CONTROL:
return self.get_serial_control()
else:
- return 0xFF
\ No newline at end of file
+ return 0xFF
+
+ def get_serial_data(self):
+ return self.serial_data
+
+ def get_serial_control(self):
+ return self.serial_control
\ No newline at end of file
Modified: pypy/dist/pypy/lang/gameboy/test/test_cpu.py
==============================================================================
--- pypy/dist/pypy/lang/gameboy/test/test_cpu.py (original)
+++ pypy/dist/pypy/lang/gameboy/test/test_cpu.py Sun Jun 8 14:55:12 2008
@@ -1068,8 +1068,9 @@
assert_default_registers(cpu, pc=value, sp=valueSp+2)
# reti
-def test_0xD9_returnFormInterrupt():
+def test_0xD9_return_form_interrupt():
cpu = get_cpu()
+ cpu.interrupt.reset()
value = 0x1234
cpu.sp.set(0)
prepare_for_pop(cpu, value >> 8, value & 0xFF)
@@ -1078,35 +1079,39 @@
cycle_test(cpu, 0xD9, 4+2)
assert_default_registers(cpu, pc=value+1, sp=2)
-def test_handleInterrupt():
+def test_handle_interrupt():
cpu = get_cpu()
+ cpu.interrupt.reset()
cpu.halted = True
cpu.cycles = 0xFF
- cpu.handle_pending_interrupt()
+ cpu.handle_pending_interrupts()
assert cpu.cycles == 0
cpu.reset()
+ cpu.interrupt.reset()
cpu.halted = True
- cpu.interrupt.set_interrupt_enable()
+ cpu.cycles = 4
+ cpu.interrupt.set_enable_mask(0xFF)
cpu.interrupt.vblank.set_pending()
assert cpu.interrupt.is_pending() == True
- cpu.cycles = 4
- cpu.handle_pending_interrupt()
+ assert cpu.halted == True
+ cpu.handle_pending_interrupts()
assert cpu.cycles == 0
assert cpu.halted == False
cpu.reset()
+ cpu.interrupt.reset()
cpu.halted = False
- cpu.ime = True
+ cpu.ime = True
cpu.pc.set(0x1234)
cpu.sp.set(0x02)
sp = cpu.sp.get()
- cpu.interrupt.set_interrupt_enable()
+ cpu.interrupt.set_enable_mask(0xFF)
cpu.interrupt.vblank.set_pending()
cpu.interrupt.lcd.set_pending()
assert cpu.interrupt.is_pending() == True
cpu.cycles = 0
- cpu.handle_pending_interrupt()
+ cpu.handle_pending_interrupts()
assert cpu.cycles == 0
assert cpu.halted == False
assert_default_registers(cpu, pc=cpu.interrupt.vblank.call_code, sp=sp-2)
@@ -1182,40 +1187,53 @@
# di
-def test_0xF3():
+def test_0xF3_disable_interrupt():
cpu = get_cpu()
+ cpu.interrupt.reset()
cpu.ime == True
cycle_test(cpu, 0xF3, 1)
assert cpu.ime == False
# ei
-def test_0xFB():
- cpu = get_cpu()
+def test_0xFB_enable_interrupt():
+ cpu = get_cpu()
+ cpu.interrupt.reset()
cpu.sp.set(0)
- cpu.ime = False
+ cpu.ime = False
cpu.halted = False
prepare_for_fetch(cpu, 0x00) # nop 1 cycle
+ print cpu.interrupt.get_enable_mask()
+ assert cpu.interrupt.is_pending() == False
cycle_test(cpu, 0xFB, 1+1)
- assert cpu.ime == True
+ assert cpu.interrupt.is_pending() == False
+ assert cpu.ime == True
cpu.reset()
+ cpu.interrupt.reset()
cpu.sp.set(0)
- cpu.ime = True
+ cpu.ime = True
cpu.halted = False
prepare_for_fetch(cpu, 0x00) # nop 1 cycle
cpu.interrupt.vblank.set_pending()
cpu.interrupt.serial.set_pending()
- cpu.interrupt.set_interrupt_enable(True)
+ cpu.interrupt.set_enable_mask(0x1F)
assert cpu.interrupt.is_pending() == True
- assert cpu.halted == False
- assert cpu.ime == True
+ assert cpu.halted == False
+ assert cpu.ime == True
cycle_test(cpu, 0xFB, 1+1)
- assert cpu.interrupt.is_pending() == False
+ assert cpu.interrupt.is_pending() == True
assert cpu.interrupt.vblank.is_pending() == False
- assert cpu.pc.get() == cpu.interrupt.vblank.call_code
- assert cpu.ime == False
+ assert cpu.interrupt.serial.is_pending() == True
+ assert cpu.pc.get() == cpu.interrupt.vblank.call_code
+ assert cpu.ime == False
+
+ cpu.ime = True
+ cycle_test(cpu, 0xFB, 1+1)
+ assert cpu.interrupt.vblank.is_pending() == False
+ assert cpu.interrupt.serial.is_pending() == False
+ assert cpu.interrupt.is_pending() == False
-def conditionalCallTest(cpu, opCode, flagSetter):
+def conditional_call_test(cpu, opCode, flagSetter):
flagSetter(cpu, False)
cpu.pc.set(0)
f = cpu.f.get()
@@ -1234,7 +1252,7 @@
# call_NZ_nnnn
def test_0xC4():
cpu = get_cpu()
- conditionalCallTest(cpu, 0xC4, setFlag0xC4)
+ conditional_call_test(cpu, 0xC4, setFlag0xC4)
def setFlag0xC4(cpu, value):
cpu.f.z_flag = not value
@@ -1242,7 +1260,7 @@
# call_Z_nnnn
def test_0xCC():
cpu = get_cpu()
- conditionalCallTest(cpu, 0xCC, setFlag0xC4)
+ conditional_call_test(cpu, 0xCC, setFlag0xC4)
def setFlag0xCC(cpu, value):
cpu.f.c_flag = not value
@@ -1250,7 +1268,7 @@
# call_NC_nnnn
def test_0xD4():
cpu = get_cpu()
- conditionalCallTest(cpu, 0xD4, setFlag0xC4)
+ conditional_call_test(cpu, 0xD4, setFlag0xC4)
def setFlag0xD4(cpu, value):
cpu.f.c_flag = value
@@ -1258,13 +1276,13 @@
# call_C_nnnn
def test_0xDC():
cpu = get_cpu()
- conditionalCallTest(cpu, 0xDC, setFlag0xC4)
+ conditional_call_test(cpu, 0xDC, setFlag0xC4)
def setFlag0xDC(cpu, value):
cpu.f.z_flag = value
# push_BC to push_AF
-def test_0xC5_to_0xF5():
+def test_0xC5_to_0xF5_push():
cpu = get_cpu()
registers = [cpu.bc, cpu.de, cpu.hl, cpu.af]
opCode = 0xC5
@@ -1279,7 +1297,7 @@
# call_nnnn
-def test_0xCD():
+def test_0xCD_call():
cpu = get_cpu()
fetchValue = 0x1234
cpu.sp.set(fetchValue)
@@ -1301,7 +1319,7 @@
return cpu
# add_A_nn
-def test_0xC6():
+def test_0xC6_add_a_fetch():
a_nn_test(0xC6, 2, lambda a, b, cpu: a+b)
# adc_A_nn
Modified: pypy/dist/pypy/lang/gameboy/test/test_interrupt.py
==============================================================================
--- pypy/dist/pypy/lang/gameboy/test/test_interrupt.py (original)
+++ pypy/dist/pypy/lang/gameboy/test/test_interrupt.py Sun Jun 8 14:55:12 2008
@@ -8,39 +8,57 @@
def test_reset():
- interrupt = get_interrupt()
- assert interrupt.enable == 0
- assert interrupt.get_interrupt_flag() == 0xE0 | constants.VBLANK
+ interrupt = get_interrupt()
+ assert interrupt.is_pending() == False
+ assert interrupt.get_enable_mask() == 0
+ assert interrupt.get_interrupt_flag() == 0xE0 | constants.VBLANK
+
interrupt.enable = 1
- interrupt.flag = ~constants.VBLANK
+ interrupt.flag = ~constants.VBLANK
interrupt.reset()
- assert interrupt.enable == 0
- assert interrupt.get_interrupt_flag() == 0xE0 | constants.VBLANK
+ assert interrupt.get_enable_mask() == 0
+ assert interrupt.get_interrupt_flag() == 0xE0 | constants.VBLANK
+
+
+def test_set_get_enable_mask():
+ interrupt = get_interrupt()
+ assert interrupt.get_enable_mask() == 0x00
+ interrupt.set_enable_mask(0x01)
+ assert interrupt.vblank.is_enabled()
+ assert interrupt.get_enable_mask() == 0x01
+
+ # enable all interrupts 0x01 - 0x10
+ interrupt.set_enable_mask(0xFF)
+ assert interrupt.vblank.is_enabled()
+ assert interrupt.get_enable_mask() == 0xFF
def test_is_pending():
interrupt = get_interrupt()
- assert interrupt.is_pending() == False
+ interrupt.vblank.set_pending()
+ assert interrupt.is_pending() == False
assert interrupt.is_pending(0x00) == False
- interrupt.set_interrupt_enable(True)
+
+ interrupt.set_enable_mask(0xFF)
assert interrupt.is_pending()
+ interrupt.set_enable_mask(0x00)
+ assert interrupt.is_pending() == False
def test_is_pending_common_masks():
interrupt = get_interrupt()
for flag in interrupt.interrupt_flags:
interrupt.reset()
- interrupt.enable = True
+ interrupt.set_enable_mask(0xFF)
assert interrupt.vblank.is_pending()
flag.set_pending(True)
assert interrupt.is_pending(flag.mask)
-
def test_raise_lower_interrupt():
interrupt = get_interrupt()
masks= [constants.LCD, constants.TIMER,
constants.JOYPAD, constants.SERIAL]
- interrupt.set_interrupt_enable(True)
+ interrupt.set_enable_mask(0xFF)
interrupt.vblank.set_pending(True)
for mask in masks:
interrupt.raise_interrupt(mask)
@@ -51,13 +69,11 @@
def test_read_write():
interrupt = get_interrupt()
- value = 1
- interrupt.write(constants.IE, value)
- assert interrupt.enable == value
- assert interrupt.read(constants.IE) == value
+ interrupt.write(constants.IE, 0x12)
+ assert interrupt.get_enable_mask() == 0x12
+ assert interrupt.read(constants.IE) == 0x12
interrupt.reset()
- value = constants.LCD
- interrupt.write(constants.IF, value)
- assert interrupt.get_interrupt_flag() == 0xE0 | value
- assert interrupt.read(constants.IF) == 0xE0 | value
+ interrupt.write(constants.IF, constants.LCD)
+ assert interrupt.get_interrupt_flag() == 0xE0 | constants.LCD
+ assert interrupt.read(constants.IF) == 0xE0 | constants.LCD
Modified: pypy/dist/pypy/lang/gameboy/test/test_serial.py
==============================================================================
--- pypy/dist/pypy/lang/gameboy/test/test_serial.py (original)
+++ pypy/dist/pypy/lang/gameboy/test/test_serial.py Sun Jun 8 14:55:12 2008
@@ -20,10 +20,11 @@
def test_set_serial_control():
serial = get_serial()
- value = 0x12
+ value = 0x12
serial.set_serial_control(value)
assert serial.get_serial_control() == value
- assert serial.cycles == constants.SERIAL_IDLE_CLOCK + constants.SERIAL_CLOCK
+ assert serial.cycles == constants.SERIAL_IDLE_CLOCK + \
+ constants.SERIAL_CLOCK
def test_emulate():
@@ -36,13 +37,13 @@
serial.reset()
serial.serial_control = 0x81
- serial.cycles = 10
+ serial.cycles = 10
cycles = serial.cycles
serial.emulate(2)
assert serial.cycles > 0
- assert cycles-serial.cycles == 2
- assert serial.serial_data == 0
- assert serial.serial_control == 0x81
+ assert cycles-serial.cycles == 2
+ assert serial.serial_data == 0
+ assert serial.serial_control == 0x81
assert serial.interrupt.serial.is_pending() == False
serial.reset()
@@ -51,21 +52,21 @@
serial.emulate(2)
assert serial.serial_data == 0xFF
assert serial.serial_control == 0x81 & 0x7F
- assert serial.cycles == constants.SERIAL_IDLE_CLOCK
+ assert serial.cycles == constants.SERIAL_IDLE_CLOCK
assert serial.interrupt.serial.is_pending() == True
def test_read_write():
serial = get_serial()
value = 0x12
- serial.write(constants.SB, value)
- assert serial.read(constants.SB) == value
- assert serial.serial_data == value
+ serial.write(constants.SERIAL_TRANSFER_DATA, value)
+ assert serial.read(constants.SERIAL_TRANSFER_DATA) == value
+ assert serial.serial_data == value
value += 1
- serial.write(constants.SC, value)
- assert serial.read(constants.SC) == value
- assert serial.serial_control == value
+ serial.write(constants.SERIAL_TRANSFER_CONTROL, value)
+ assert serial.read(constants.SERIAL_TRANSFER_CONTROL) == value
+ assert serial.serial_control == value
assert serial.read(0) == 0xFF
\ No newline at end of file
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 Sun Jun 8 14:55:12 2008
@@ -14,31 +14,31 @@
def test_reset(timer=None):
if timer is None:
timer = get_timer()
- assert timer.div == 0
+ assert timer.divider == 0
assert timer.divider_cycles == constants.DIV_CLOCK
- assert timer.tima == 0
- assert timer.tma == 0
- assert timer.tac == 0
- assert timer.timer_cycles == constants.TIMER_CLOCK[0]
- assert timer.timer_clock == constants.TIMER_CLOCK[0]
+ assert timer.timer_counter == 0
+ assert timer.timer_modulo == 0
+ assert timer.timer_control == 0
+ assert timer.timer_cycles == constants.TIMER_CLOCK[0]
+ assert timer.timer_clock == constants.TIMER_CLOCK[0]
def test_read_write():
- timer = get_timer()
- timer.div = 10
- value = 0x11
+ timer = get_timer()
+ timer.divider = 10
+ value = 0x11
timer.write(constants.DIV, value)
- assert timer.get_divider() == 0
+ assert timer.get_divider() == 0
assert timer.read(constants.DIV) == 0
timer.reset()
timer.write(constants.TIMA, value)
- assert timer.get_timer_counter() == value
+ assert timer.get_timer_counter() == value
assert timer.read(constants.TIMA) == value
timer.reset()
timer.write(constants.TMA, value)
- assert timer.get_timer_modulo() == value
+ assert timer.get_timer_modulo() == value
assert timer.read(constants.TMA) == value
timer.reset()
@@ -54,174 +54,174 @@
timer = get_timer()
value = 0x12
timer.set_timer_control(value)
- assert timer.tac == value
- assert timer.timer_cycles == constants.TIMER_CLOCK[value & 0x03]
- assert timer.timer_clock == constants.TIMER_CLOCK[value & 0x03]
+ assert timer.timer_control == value
+ assert timer.timer_cycles == constants.TIMER_CLOCK[value & 0x03]
+ assert timer.timer_clock == constants.TIMER_CLOCK[value & 0x03]
timer.reset()
- timer.tac = value+1
- timer.timer_clock = 0
- timer.timer_cycles = 0
+ timer.timer_control = value+1
+ timer.timer_clock = 0
+ timer.timer_cycles = 0
timer.set_timer_control(value+1)
- assert timer.tac == value+1
- assert timer.timer_clock == 0
- assert timer.timer_clock == 0
+ assert timer.timer_control == value+1
+ assert timer.timer_clock == 0
+ assert timer.timer_clock == 0
def test_read_write_divider():
- timer = get_timer()
- value = 0x12
- timer.div = value
- assert timer.get_divider() == timer.div
+ timer = get_timer()
+ value = 0x12
+ timer.divider = value
+ assert timer.get_divider() == timer.divider
# divider resets on write
timer.set_divider(value)
assert timer.get_divider() == 0
def test_cycles():
- timer = get_timer()
- value = 10
+ timer = get_timer()
+ value = 10
timer.divider_cycles = value
assert timer.get_cycles() == timer.divider_cycles
- timer.tac = 0x04
- timer.timer_cycles = value-1
- timer.timer_cycles = value
+ timer.timer_control = 0x04
+ timer.timer_cycles = value-1
+ timer.timer_cycles = value
assert timer.get_cycles() == timer.timer_cycles
def test_emulate_divider():
- timer = get_timer()
+ timer = get_timer()
timer.divider_cycles = 10
- timer.div = 1
+ timer.divider = 1
timer.emulate_divider(2)
- assert timer.div == 1
+ assert timer.divider == 1
assert timer.divider_cycles == 8
def test_test_emulate_divider_below_zero():
- timer = get_timer()
+ timer = get_timer()
timer.divider_cycles = 0
- timer.div = 1
+ timer.divider = 1
timer.emulate_divider(2)
assert timer.divider_cycles == constants.DIV_CLOCK - 2
- assert timer.div == 2
+ assert timer.divider == 2
timer.divider_cycles = 0
- timer.div = 1
+ timer.divider = 1
timer.emulate_divider(0)
assert timer.divider_cycles == constants.DIV_CLOCK
- assert timer.div == 2
+ assert timer.divider == 2
timer.divider_cycles = 0
- timer.div = 0xFF
+ timer.divider = 0xFF
timer.emulate_divider(2)
assert timer.divider_cycles == constants.DIV_CLOCK - 2
- assert timer.div == 0
+ assert timer.divider == 0
timer.divider_cycles = 0
- timer.div = 0
+ timer.divider = 0
timer.emulate_divider(2*constants.DIV_CLOCK)
assert timer.divider_cycles == constants.DIV_CLOCK
- assert timer.div == 3
+ assert timer.divider == 3
-def test_emulate_timer_tac_return():
+def test_emulate_timer_timer_control_return():
timer = get_timer()
- timer.tac = 0
- timer.timer_cycles = -10
- timer.tima = 3
+ timer.timer_control = 0
+ timer.timer_cycles = -10
+ timer.timer_counter = 3
timer.emulate_timer(10)
- assert timer.timer_cycles == -10
- assert timer.tima == 3
+ assert timer.timer_cycles == -10
+ assert timer.timer_counter == 3
def test_emulate_timer_timer_cycles_return():
timer = get_timer()
- timer.tac = 0x04
- timer.timer_cycles = 11
- cycles = timer.timer_cycles
+ timer.timer_control = 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():
+def test_emulate_timer_timer_cycles_timer_counter():
timer = get_timer()
- 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
+ timer.timer_control = 0x04
+ timer.timer_counter = 0
+ timer.timer_cycles = 0
+ timer.timer_clock = 5
+ timer.emulate_timer(10)
+ assert timer.timer_counter == 3
+ assert timer.timer_cycles == 5
+ timer.timer_control = 0x04
+ timer.timer_counter = 0xFF
+ timer.timer_modulo = 5
+ timer.timer_cycles = 0
+ timer.timer_clock = 5
+ timer.emulate_timer(10)
+ assert timer.timer_counter == 2+5
+ assert timer.timer_cycles == 5
+
+def test_emulate_timer_timer_cycles_timer_counter_single_0_pass():
+ timer = get_timer()
+ timer.timer_control = 0x04
+ timer.timer_counter = 0xFF
+ timer.timer_modulo = 0
+ timer.timer_cycles = 0
+ timer.timer_clock = 5
+ timer.emulate_timer(10)
+ assert timer.timer_counter == 2
+ assert timer.timer_cycles == 5
+
+ timer.timer_control = 0x04
+ timer.timer_counter = 0xFF
+ timer.timer_modulo = 1
+ timer.timer_cycles = 0
+ timer.timer_clock = 5
+ timer.emulate_timer(10)
+ assert timer.timer_counter == 2+1
+ assert timer.timer_cycles == 5
+
+
+def test_emulate_timer_timer_cycles_timer_counter_mutli_0_pass():
+ timer = get_timer()
+ timer.timer_control = 0x04
+ timer.timer_counter = 0xFF
+ timer.timer_modulo = 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
+ assert timer.timer_counter == 0
+ assert timer.timer_cycles == 1
- timer.tac = 0x04
- timer.tima = 0xFF
- timer.tma = 1
- timer.timer_cycles = 0
- timer.timer_clock = 1
+ timer.timer_control = 0x04
+ timer.timer_counter = 0xFF
+ timer.timer_modulo = 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
+ assert timer.timer_counter == 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.timer_control = 0x04
+ timer.timer_counter = 0xFF
+ timer.timer_modulo = 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
+ assert timer.timer_counter == i*i
+ assert timer.timer_cycles == 1
def test_emulate_timer_interrupt():
- timer = get_timer()
- ticks = 0
- timer.tac = 0x04
- timer.tima = -1
+ timer = get_timer()
+ ticks = 0
+ timer.timer_control = 0x04
+ timer.timer_counter = -1
# raise an interupt as we pass 0
assert timer.interrupt.is_pending(constants.TIMER) == False
- assert timer.interrupt.timer.is_pending() == False
+ assert timer.interrupt.timer.is_pending() == False
timer.timer_cycles = -timer.timer_clock+1
timer.emulate_timer(ticks)
- assert timer.timer_cycles == 1
- assert timer.tima == timer.tma
+ assert timer.timer_cycles == 1
+ assert timer.timer_counter == timer.timer_modulo
assert timer.interrupt.timer.is_pending()
\ No newline at end of file
Modified: pypy/dist/pypy/lang/gameboy/timer.py
==============================================================================
--- pypy/dist/pypy/lang/gameboy/timer.py (original)
+++ pypy/dist/pypy/lang/gameboy/timer.py Sun Jun 8 14:55:12 2008
@@ -12,6 +12,13 @@
import math
+class TimerControl(object):
+ def __init__(self):
+ self.reset()
+
+ def reset(self):
+ pass
+
class Timer(iMemory):
def __init__(self, interrupt):
@@ -20,16 +27,15 @@
self.reset()
def reset(self):
- self.div = 0
+ self.divider = 0
self.divider_cycles = constants.DIV_CLOCK
- self.tima = 0
- self.tma = 0
- self.tac = 0
+ self.timer_counter = 0
+ self.timer_modulo = 0
+ self.timer_control = 0
self.timer_cycles = constants.TIMER_CLOCK[0]
self.timer_clock = constants.TIMER_CLOCK[0]
def write(self, address, data):
- address = int(address)
if address == constants.DIV:
self.set_divider(data)
elif address == constants.TIMA:
@@ -40,7 +46,6 @@
self.set_timer_control(data)
def read(self, address):
- address = int(address)
if address == constants.DIV:
return self.get_divider()
elif address == constants.TIMA:
@@ -52,35 +57,39 @@
return 0xFF
def get_divider(self):
- return self.div
+ return self.divider
def set_divider(self, data):
""" DIV register resets on write """
- self.div = 0
+ self.divider = 0
def get_timer_counter(self):
- return self.tima
+ return self.timer_counter
def set_timer_counter(self, data):
- self.tima = data
+ self.timer_counter = data
+
def get_timer_modulo(self):
- return self.tma
+ return self.timer_modulo
def set_timer_modulo(self, data):
- self.tma = data
+ self.timer_modulo = data
+
def get_timer_control(self):
- return 0xF8 | self.tac
+ return 0xF8 | self.timer_control
def set_timer_control(self, data):
- if (self.tac & 0x03) != (data & 0x03):
+ if (self.timer_control & 0x03) != (data & 0x03):
self.timer_clock = constants.TIMER_CLOCK[data & 0x03]
self.timer_cycles = constants.TIMER_CLOCK[data & 0x03]
- self.tac = data
+ self.timer_control = data
+
def get_cycles(self):
- if (self.tac & 0x04) != 0 and self.timer_cycles < self.divider_cycles:
+ if (self.timer_control & 0x04) != 0 and \
+ self.timer_cycles < self.divider_cycles:
return self.timer_cycles
return self.divider_cycles
@@ -92,35 +101,36 @@
self.divider_cycles -= ticks
if self.divider_cycles > 0:
return
- count = int(math.ceil(-self.divider_cycles / constants.DIV_CLOCK)+1)
+ 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);
+ self.divider = (self.divider + count) % (0xFF+1);
def emulate_timer(self, ticks):
- if (self.tac & 0x04) == 0:
+ if (self.timer_control & 0x04) == 0:
return
self.timer_cycles -= ticks
while self.timer_cycles <= 0:
- self.tima = (self.tima + 1) & 0xFF
+ self.timer_counter = (self.timer_counter + 1) & 0xFF
self.timer_cycles += self.timer_clock
- if self.tima == 0x00:
- self.tima = self.tma
+ if self.timer_counter == 0x00:
+ self.timer_counter = self.timer_modulo
self.interrupt.raise_interrupt(constants.TIMER)
#def emulate_timer(self, ticks):
- # if (self.tac & 0x04) == 0:
+ # if (self.timer_control & 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:
+ # if (self.timer_counter + count) > 0xFF:
# self.interrupt.raise_interrupt(constants.TIMER)
- # zero_passes = math.ceil(self.tima / count)
- # self.tima = (self.tma + count - zero_passes ) % (0xFF +1)
+ # zero_passes = math.ceil(self.timer_counter / count)
+ # self.timer_counter = (self.timer_modulo + count - zero_passes ) % (0xFF +1)
# else:
- # self.tima = (self.tima + count) % (0xFF +1)
+ # self.timer_counter = (self.timer_counter + count) % (0xFF +1)
# CLOCK DRIVER -----------------------------------------------------------------
class Clock(object):
More information about the Pypy-commit
mailing list