diff --git a/.github/workflows/pr-test.yml b/.github/workflows/pr-test.yml index fa4875550..4d0ec332c 100644 --- a/.github/workflows/pr-test.yml +++ b/.github/workflows/pr-test.yml @@ -46,7 +46,7 @@ jobs: - name: Run PyTest env: PYTEST_SECRETS_KEY: ${{ secrets.PYTEST_SECRETS_KEY }} - TEST_CI: 1 + TEST_VERBOSE_IMAGES: 0 TEST_NO_UI: 1 run: | python -m pytest tests/ -n auto -v @@ -111,7 +111,7 @@ jobs: - name: Run PyTest env: PYTEST_SECRETS_KEY: ${{ secrets.PYTEST_SECRETS_KEY }} - TEST_CI: 1 + TEST_VERBOSE_IMAGES: 0 TEST_NO_UI: 1 run: | pypy3 -m pytest tests/ -n auto -v diff --git a/docs/index.html b/docs/index.html index 84ecba16e..2ffd7ce4d 100644 --- a/docs/index.html +++ b/docs/index.html @@ -230,9 +230,8 @@

Kwargs

raise KeyError(f"Unknown keyword argument: {k}") # Performance measures - self.avg_pre = 0 self.avg_tick = 0 - self.avg_post = 0 + self.avg_emu = 0 # Absolute frame count of the emulation self.frame_count = 0 @@ -448,9 +447,7 @@

Kwargs

if self.stopped: return False - t_start = time.perf_counter_ns() self._handle_events(self.events) - t_pre = time.perf_counter_ns() if not self.paused: self.gameshark.tick() self.__rendering(render) @@ -477,18 +474,7 @@

Kwargs

self.mb.breakpoint_singlestep = self.mb.breakpoint_singlestep_latch self.frame_count += 1 - t_tick = time.perf_counter_ns() - self._post_tick() - t_post = time.perf_counter_ns() - - nsecs = t_pre - t_start - self.avg_pre = 0.9 * self.avg_pre + (0.1*nsecs/1_000_000_000) - - nsecs = t_tick - t_pre - self.avg_tick = 0.9 * self.avg_tick + (0.1*nsecs/1_000_000_000) - - nsecs = t_post - t_tick - self.avg_post = 0.9 * self.avg_post + (0.1*nsecs/1_000_000_000) + self._post_handle_events() return not self.quitting @@ -537,11 +523,22 @@

Kwargs

False if emulation has ended otherwise True """ + _count = count running = False + t_start = time.perf_counter_ns() while count != 0: _render = render and count == 1 # Only render on last tick to improve performance running = self._tick(_render) count -= 1 + t_tick = time.perf_counter_ns() + self._post_tick() + t_post = time.perf_counter_ns() + + if _count > 0: + nsecs = t_tick - t_start + self.avg_tick = 0.9 * (self.avg_tick / _count) + (0.1*nsecs/1_000_000_000) + nsecs = t_post - t_start + self.avg_emu = 0.9 * (self.avg_emu / _count) + (0.1*nsecs/1_000_000_000) return running def _handle_events(self, events): @@ -608,6 +605,7 @@

Kwargs

self._plugin_manager.post_tick() self._plugin_manager.frame_limiter(self.target_emulationspeed) + def _post_handle_events(self): # Prepare an empty list, as the API might be used to send in events between ticks self.events = [] while self.queued_input and self.frame_count == self.queued_input[0][0]: @@ -615,9 +613,8 @@

Kwargs

self.events.append(WindowEvent(_event)) def _update_window_title(self): - avg_emu = self.avg_pre + self.avg_tick + self.avg_post - self.window_title = f"CPU/frame: {(self.avg_pre + self.avg_tick) / SPF * 100:0.2f}%" - self.window_title += f' Emulation: x{(round(SPF / avg_emu) if avg_emu > 0 else "INF")}' + self.window_title = f"CPU/frame: {(self.avg_tick) / SPF * 100:0.2f}%" + self.window_title += f' Emulation: x{(round(SPF / self.avg_emu) if self.avg_emu > 0 else "INF")}' if self.paused: self.window_title += "[PAUSED]" self.window_title += self._plugin_manager.window_title() @@ -1608,11 +1605,22 @@

Returns

False if emulation has ended otherwise True """ + _count = count running = False + t_start = time.perf_counter_ns() while count != 0: _render = render and count == 1 # Only render on last tick to improve performance running = self._tick(_render) count -= 1 + t_tick = time.perf_counter_ns() + self._post_tick() + t_post = time.perf_counter_ns() + + if _count > 0: + nsecs = t_tick - t_start + self.avg_tick = 0.9 * (self.avg_tick / _count) + (0.1*nsecs/1_000_000_000) + nsecs = t_post - t_start + self.avg_emu = 0.9 * (self.avg_emu / _count) + (0.1*nsecs/1_000_000_000) return running diff --git a/docs/utils.html b/docs/utils.html index d9aadd879..9aa5fa6ff 100644 --- a/docs/utils.html +++ b/docs/utils.html @@ -32,7 +32,7 @@

Module pyboy.utils

__all__ = ["WindowEvent", "dec_to_bcd", "bcd_to_dec"] -STATE_VERSION = 11 +STATE_VERSION = 12 ############################################################## # Buffer classes diff --git a/extras/examples/gamewrapper_tetris.py b/extras/examples/gamewrapper_tetris.py index f0cb1a4e3..a419cf26c 100644 --- a/extras/examples/gamewrapper_tetris.py +++ b/extras/examples/gamewrapper_tetris.py @@ -29,7 +29,7 @@ tetris.start_game(timer_div=0x00) # The timer_div works like a random seed in Tetris tetromino_at_0x00 = tetris.next_tetromino() -assert tetromino_at_0x00 == "Z", tetris.next_tetromino() +assert tetromino_at_0x00 == "O", tetris.next_tetromino() assert tetris.score == 0 assert tetris.level == 0 assert tetris.lines == 0 diff --git a/pyboy/__main__.py b/pyboy/__main__.py index 8c5209fd4..c3feff9de 100644 --- a/pyboy/__main__.py +++ b/pyboy/__main__.py @@ -169,7 +169,7 @@ def main(): pyboy.load_state(f) render = not argv.no_renderer - while pyboy._tick(render): + while pyboy.tick(): pass pyboy.stop() diff --git a/pyboy/core/cpu.pxd b/pyboy/core/cpu.pxd index f1cf0d393..c53e51f16 100644 --- a/pyboy/core/cpu.pxd +++ b/pyboy/core/cpu.pxd @@ -4,7 +4,7 @@ # -from libc.stdint cimport int16_t, uint8_t, uint16_t, uint32_t, uint64_t +from libc.stdint cimport int16_t, int64_t, uint8_t, uint16_t, int64_t cimport pyboy.core.mb from pyboy.utils cimport IntIOInterface @@ -26,17 +26,20 @@ cdef uint8_t INTR_VBLANK, INTR_LCDC, INTR_TIMER, INTR_SERIAL, INTR_HIGHTOLOW cdef class CPU: cdef bint is_stuck - cdef bint interrupt_master_enable, interrupt_queued, halted, stopped + cdef bint interrupt_master_enable, interrupt_queued, halted, stopped, bail cdef uint8_t interrupts_flag, interrupts_enabled, interrupts_flag_register, interrupts_enabled_register + cdef int64_t cycles + cdef inline int check_interrupts(self) noexcept nogil cdef void set_interruptflag(self, int) noexcept nogil cdef bint handle_interrupt(self, uint8_t, uint16_t) noexcept nogil @cython.locals(opcode=uint16_t) cdef inline uint8_t fetch_and_execute(self) noexcept nogil - cdef int tick(self) noexcept nogil + @cython.locals(_cycles0=int64_t) + cdef int tick(self, int64_t) noexcept nogil cdef void save_state(self, IntIOInterface) noexcept cdef void load_state(self, IntIOInterface, int) noexcept diff --git a/pyboy/core/cpu.py b/pyboy/core/cpu.py index 288e16efd..e6e0d0a90 100644 --- a/pyboy/core/cpu.py +++ b/pyboy/core/cpu.py @@ -39,6 +39,7 @@ def __init__(self, mb): self.halted = False self.stopped = False self.is_stuck = False + self.cycles = 0 def save_state(self, f): for n in [self.A, self.F, self.B, self.C, self.D, self.E]: @@ -53,6 +54,7 @@ def save_state(self, f): f.write(self.interrupts_enabled_register) f.write(self.interrupt_queued) f.write(self.interrupts_flag_register) + f.write_64bit(self.cycles) def load_state(self, f, state_version): self.A, self.F, self.B, self.C, self.D, self.E = [f.read() for _ in range(6)] @@ -69,6 +71,8 @@ def load_state(self, f, state_version): if state_version >= 8: self.interrupt_queued = f.read() self.interrupts_flag_register = f.read() + if state_version >= 12: + self.cycles = f.read_64bit() logger.debug("State loaded: %s", self.dump_state("")) def dump_state(self, sym_label): @@ -93,8 +97,8 @@ def dump_state(self, sym_label): f"Interrupts - IME: {self.mb.cpu.interrupt_master_enable}, " f"IE: {self.mb.cpu.interrupts_enabled_register:08b}, " f"IF: {self.mb.cpu.interrupts_flag_register:08b}\n" - f"LCD Intr.: {self.mb.lcd.cycles_to_interrupt()}, LY:{self.mb.lcd.LY}, LYC:{self.mb.lcd.LYC}\n" - f"Timer Intr.: {self.mb.timer.cycles_to_interrupt()}\n" + f"LCD Intr.: {self.mb.lcd._cycles_to_interrupt}, LY:{self.mb.lcd.LY}, LYC:{self.mb.lcd.LYC}\n" + f"Timer Intr.: {self.mb.timer._cycles_to_interrupt}\n" f"halted:{self.halted}, " f"interrupt_queued:{self.interrupt_queued}, " f"stopped:{self.stopped}\n" @@ -103,11 +107,13 @@ def dump_state(self, sym_label): def set_interruptflag(self, flag): self.interrupts_flag_register |= flag - def tick(self): + def tick(self, cycles_target): + _cycles0 = self.cycles + _target = _cycles0 + cycles_target + if self.check_interrupts(): self.halted = False - # TODO: We return with the cycles it took to handle the interrupt - return 0 + # TODO: Cycles it took to handle the interrupt if self.halted and self.interrupt_queued: # GBCPUman.pdf page 20 @@ -117,62 +123,55 @@ def tick(self): self.PC += 1 self.PC &= 0xFFFF elif self.halted: - return 4 # TODO: Number of cycles for a HALT in effect? - - old_pc = self.PC # If the PC doesn't change, we're likely stuck - old_sp = self.SP # Sometimes a RET can go to the same PC, so we check the SP too. - cycles = self.fetch_and_execute() - if not self.halted and old_pc == self.PC and old_sp == self.SP and not self.is_stuck and not self.mb.breakpoint_singlestep: - logger.debug("CPU is stuck: %s", self.dump_state("")) - self.is_stuck = True + self.cycles += cycles_target # TODO: Number of cycles for a HALT in effect? self.interrupt_queued = False - return cycles + + self.bail = False + while self.cycles < _target: + # TODO: cpu-stuck check for blargg tests? + self.fetch_and_execute() + if self.bail: # Possible cycles-target changes + break def check_interrupts(self): if self.interrupt_queued: # Interrupt already queued. This happens only when using a debugger. return False - if (self.interrupts_flag_register & 0b11111) & (self.interrupts_enabled_register & 0b11111): - if self.handle_interrupt(INTR_VBLANK, 0x0040): - self.interrupt_queued = True - elif self.handle_interrupt(INTR_LCDC, 0x0048): - self.interrupt_queued = True - elif self.handle_interrupt(INTR_TIMER, 0x0050): - self.interrupt_queued = True - elif self.handle_interrupt(INTR_SERIAL, 0x0058): - self.interrupt_queued = True - elif self.handle_interrupt(INTR_HIGHTOLOW, 0x0060): - self.interrupt_queued = True - else: - logger.error("No interrupt triggered, but it should!") - self.interrupt_queued = False - return True - else: - self.interrupt_queued = False - return False - - def handle_interrupt(self, flag, addr): - if (self.interrupts_enabled_register & flag) and (self.interrupts_flag_register & flag): + raised_and_enabled = (self.interrupts_flag_register & 0b11111) & (self.interrupts_enabled_register & 0b11111) + if raised_and_enabled: # Clear interrupt flag if self.halted: self.PC += 1 # Escape HALT on return self.PC &= 0xFFFF - # Handle interrupt vectors if self.interrupt_master_enable: - self.interrupts_flag_register ^= flag # Remove flag - self.mb.setitem((self.SP - 1) & 0xFFFF, self.PC >> 8) # High - self.mb.setitem((self.SP - 2) & 0xFFFF, self.PC & 0xFF) # Low - self.SP -= 2 - self.SP &= 0xFFFF - - self.PC = addr - self.interrupt_master_enable = False - + if raised_and_enabled & INTR_VBLANK: + self.handle_interrupt(INTR_VBLANK, 0x0040) + elif raised_and_enabled & INTR_LCDC: + self.handle_interrupt(INTR_LCDC, 0x0048) + elif raised_and_enabled & INTR_TIMER: + self.handle_interrupt(INTR_TIMER, 0x0050) + elif raised_and_enabled & INTR_SERIAL: + self.handle_interrupt(INTR_SERIAL, 0x0058) + elif raised_and_enabled & INTR_HIGHTOLOW: + self.handle_interrupt(INTR_HIGHTOLOW, 0x0060) + self.interrupt_queued = True return True + else: + self.interrupt_queued = False return False + def handle_interrupt(self, flag, addr): + self.interrupts_flag_register ^= flag # Remove flag + self.mb.setitem((self.SP - 1) & 0xFFFF, self.PC >> 8) # High + self.mb.setitem((self.SP - 2) & 0xFFFF, self.PC & 0xFF) # Low + self.SP -= 2 + self.SP &= 0xFFFF + + self.PC = addr + self.interrupt_master_enable = False + def fetch_and_execute(self): opcode = self.mb.getitem(self.PC) if opcode == 0xCB: # Extension code diff --git a/pyboy/core/lcd.pxd b/pyboy/core/lcd.pxd index 4b4ed074a..08c769fdc 100644 --- a/pyboy/core/lcd.pxd +++ b/pyboy/core/lcd.pxd @@ -48,10 +48,11 @@ cdef class LCD: cdef PaletteRegister OBP1 cdef Renderer renderer cdef uint8_t[144][5] _scanlineparameters + cdef uint64_t last_cycles + cdef int64_t _cycles_to_interrupt, _cycles_to_frame @cython.locals(interrupt_flag=uint8_t,bx=int,by=int,wx=int,wy=int) cdef uint8_t tick(self, int) noexcept nogil - cdef int64_t cycles_to_interrupt(self) noexcept nogil cdef void set_lcdc(self, uint8_t) noexcept nogil cdef uint8_t get_lcdc(self) noexcept nogil diff --git a/pyboy/core/lcd.py b/pyboy/core/lcd.py index 171d114c2..ffba52543 100644 --- a/pyboy/core/lcd.py +++ b/pyboy/core/lcd.py @@ -58,6 +58,9 @@ def __init__(self, cgb, cartridge_cgb, color_palette, cgb_color_palette, randomi self.double_speed = False self.cgb = cgb self._scanlineparameters = [[0, 0, 0, 0, 0] for _ in range(ROWS)] + self.last_cycles = 0 + self._cycles_to_interrupt = 0 + self._cycles_to_frame = FRAME_CYCLES if self.cgb: # Setting for both modes, even though CGB is ignoring them. BGP[0] used in scanline_blank. @@ -103,9 +106,6 @@ def get_stat(self): def set_stat(self, value): self._STAT.set(value) - def cycles_to_interrupt(self): - return self.clock_target - self.clock - def cycles_to_mode0(self): multiplier = 2 if self.double_speed else 1 mode2 = 80 * multiplier @@ -130,7 +130,12 @@ def cycles_to_mode0(self): # logger.critical("Unsupported STAT mode: %d", mode) # return 0 - def tick(self, cycles): + def tick(self, _cycles): + cycles = _cycles - self.last_cycles + if cycles == 0: + return False + self.last_cycles = _cycles + interrupt_flag = 0 self.clock += cycles @@ -205,6 +210,8 @@ def tick(self, cycles): # Renderer self.renderer.blank_screen(self) + self._cycles_to_interrupt = self.clock_target - self.clock + self._cycles_to_frame = self.clock - FRAME_CYCLES return interrupt_flag def save_state(self, f): @@ -239,6 +246,7 @@ def save_state(self, f): # CGB f.write(self.cgb) f.write(self.double_speed) + f.write_64bit(self.last_cycles) f.write_64bit(self.clock) f.write_64bit(self.clock_target) f.write(self.next_stat_mode) @@ -293,8 +301,11 @@ def load_state(self, f, state_version): self.cgb = _cgb self.double_speed = f.read() + if state_version >= 12: + self.last_cycles = f.read_64bit() self.clock = f.read_64bit() self.clock_target = f.read_64bit() + self._cycles_to_frame = self.clock - FRAME_CYCLES self.next_stat_mode = f.read() if self.cgb: diff --git a/pyboy/core/mb.pxd b/pyboy/core/mb.pxd index c43f7fb18..065c12b6d 100644 --- a/pyboy/core/mb.pxd +++ b/pyboy/core/mb.pxd @@ -21,6 +21,7 @@ from pyboy.utils cimport IntIOInterface, WindowEvent cdef Logger logger +cdef int64_t MAX_CYCLES cdef uint16_t STAT, LY, LYC cdef short VBLANK, LCDC, TIMER, SERIAL, HIGHTOLOW cdef int INTR_VBLANK, INTR_LCDC, INTR_TIMER, INTR_SERIAL, INTR_HIGHTOLOW @@ -59,7 +60,7 @@ cdef class Motherboard: cdef void buttonevent(self, WindowEvent) noexcept cdef void stop(self, bint) noexcept - @cython.locals(cycles=int64_t, mode0_cycles=int64_t, breakpoint_index=int64_t) + @cython.locals(cycles=int64_t, cycles_target=int64_t, mode0_cycles=int64_t, breakpoint_index=int64_t) cdef bint tick(self) noexcept nogil cdef void switch_speed(self) noexcept nogil diff --git a/pyboy/core/mb.py b/pyboy/core/mb.py index 78264a527..6090d7a8d 100644 --- a/pyboy/core/mb.py +++ b/pyboy/core/mb.py @@ -15,6 +15,8 @@ logger = pyboy.logging.get_logger(__name__) +MAX_CYCLES = 1 << 16 + class Motherboard: def __init__( @@ -276,11 +278,8 @@ def processing_frame(self): def tick(self): while self.processing_frame(): if self.cgb and self.hdma.transfer_active and self.lcd._STAT._mode & 0b11 == 0: - cycles = self.hdma.tick(self) + self.cpu.cycles = self.cpu.cycles + self.hdma.tick(self) else: - cycles = self.cpu.tick() - - if self.cpu.halted: # Fast-forward to next interrupt: # As we are halted, we are guaranteed, that our state # cannot be altered by other factors than time. @@ -288,35 +287,32 @@ def tick(self): # it gets triggered mid-frame or by next frame # Serial is not implemented, so this isn't a concern - # Help Cython with types - mode0_cycles = 1 << 32 + mode0_cycles = MAX_CYCLES if self.cgb and self.hdma.transfer_active: mode0_cycles = self.lcd.cycles_to_mode0() - cycles = max( - 0, + cycles_target = max( + 4, min( - self.lcd.cycles_to_interrupt(), - self.timer.cycles_to_interrupt(), + self.timer._cycles_to_interrupt, + self.lcd._cycles_to_interrupt, # TODO: Be more agreesive. Only if actual interrupt enabled. + self.lcd._cycles_to_frame, + self.sound._cycles_to_interrupt, # TODO: Not implemented # self.serial.cycles_to_interrupt(), mode0_cycles ) ) + self.cpu.tick(cycles_target) #TODO: Support General Purpose DMA # https://gbdev.io/pandocs/CGB_Registers.html#bit-7--0---general-purpose-dma - # TODO: Unify interface - sclock = self.sound.clock - if self.cgb and self.double_speed: - self.sound.clock = sclock + cycles//2 - else: - self.sound.clock = sclock + cycles + self.sound.tick(self.cpu.cycles, self.double_speed) - if self.timer.tick(cycles): + if self.timer.tick(self.cpu.cycles): self.cpu.set_interruptflag(INTR_TIMER) - lcd_interrupt = self.lcd.tick(cycles) + lcd_interrupt = self.lcd.tick(self.cpu.cycles) if lcd_interrupt: self.cpu.set_interruptflag(lcd_interrupt) @@ -350,8 +346,7 @@ def getitem(self, i): bank_offset = 0 if self.cgb and 0xD000 <= i: # Find which bank to read from at FF70 - bank = self.getitem(0xFF70) - bank &= 0b111 + bank = self.ram.non_io_internal_ram1[0xFF70 - 0xFF4C] & 0b111 if bank == 0x0: bank = 0x01 bank_offset = (bank-1) * 0x1000 @@ -364,6 +359,10 @@ def getitem(self, i): elif 0xFEA0 <= i < 0xFF00: # Empty but unusable for I/O return self.ram.non_io_internal_ram0[i - 0xFEA0] elif 0xFF00 <= i < 0xFF4C: # I/O ports + # NOTE: A bit ad-hoc, but interrupts can occur right between writes + if self.timer.tick(self.cpu.cycles): + self.cpu.set_interruptflag(INTR_TIMER) + if i == 0xFF04: return self.timer.DIV elif i == 0xFF05: @@ -375,6 +374,7 @@ def getitem(self, i): elif i == 0xFF0F: return self.cpu.interrupts_flag_register elif 0xFF10 <= i < 0xFF40: + self.sound.tick(self.cpu.cycles, self.double_speed) return self.sound.get(i - 0xFF10) elif i == 0xFF40: return self.lcd.get_lcdc() @@ -442,9 +442,11 @@ def setitem(self, i, value): if 0x0000 <= i < 0x4000: # 16kB ROM bank #0 # Doesn't change the data. This is for MBC commands self.cartridge.setitem(i, value) + self.cpu.bail = True elif 0x4000 <= i < 0x8000: # 16kB switchable ROM bank # Doesn't change the data. This is for MBC commands self.cartridge.setitem(i, value) + self.cpu.bail = True elif 0x8000 <= i < 0xA000: # 8kB Video RAM if not self.cgb or self.lcd.vbk.active_bank == 0: self.lcd.VRAM0[i - 0x8000] = value @@ -475,6 +477,10 @@ def setitem(self, i, value): elif 0xFEA0 <= i < 0xFF00: # Empty but unusable for I/O self.ram.non_io_internal_ram0[i - 0xFEA0] = value elif 0xFF00 <= i < 0xFF4C: # I/O ports + # NOTE: A bit ad-hoc, but interrupts can occur right between writes + if self.timer.tick(self.cpu.cycles): + self.cpu.set_interruptflag(INTR_TIMER) + if i == 0xFF00: self.ram.io_ports[i - 0xFF00] = self.interaction.pull(value) elif i == 0xFF01: @@ -493,6 +499,7 @@ def setitem(self, i, value): elif i == 0xFF0F: self.cpu.interrupts_flag_register = value elif 0xFF10 <= i < 0xFF40: + self.sound.tick(self.cpu.cycles, self.double_speed) self.sound.set(i - 0xFF10, value) elif i == 0xFF40: self.lcd.set_lcdc(value) @@ -526,13 +533,16 @@ def setitem(self, i, value): self.lcd.WX = value else: self.ram.io_ports[i - 0xFF00] = value + self.cpu.bail = True elif 0xFF4C <= i < 0xFF80: # Empty but unusable for I/O if self.bootrom_enabled and i == 0xFF50 and (value == 0x1 or value == 0x11): logger.debug("Bootrom disabled!") self.bootrom_enabled = False + self.cpu.bail = True # CGB registers elif self.cgb and i == 0xFF4D: self.key1 = value + self.cpu.bail = True elif self.cgb and i == 0xFF4F: self.lcd.vbk.set(value) elif self.cgb and i == 0xFF51: @@ -545,6 +555,7 @@ def setitem(self, i, value): self.hdma.hdma4 = value # & 0xF0 elif self.cgb and i == 0xFF55: self.hdma.set_hdma5(value, self) + self.cpu.bail = True elif self.cgb and i == 0xFF68: self.lcd.bcps.set(value) elif self.cgb and i == 0xFF69: @@ -563,6 +574,7 @@ def setitem(self, i, value): self.ram.internal_ram1[i - 0xFF80] = value elif i == 0xFFFF: # Interrupt Enable Register self.cpu.interrupts_enabled_register = value + self.cpu.bail = True # else: # logger.critical("Memory access violation. Tried to write: 0x%0.2x to 0x%0.4x", value, i) diff --git a/pyboy/core/opcodes.py b/pyboy/core/opcodes.py index 743036227..21fed5341 100644 --- a/pyboy/core/opcodes.py +++ b/pyboy/core/opcodes.py @@ -12,6 +12,7 @@ FLAGC, FLAGH, FLAGN, FLAGZ = range(4, 8) def BRK(cpu): + cpu.bail = True cpu.mb.breakpoint_singlestep = 1 cpu.mb.breakpoint_singlestep_latch = 0 # NOTE: We do not increment PC @@ -20,7 +21,7 @@ def BRK(cpu): def NOP_00(cpu): # 00 NOP cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_01(cpu, v): # 01 LD BC,d16 @@ -28,14 +29,14 @@ def LD_01(cpu, v): # 01 LD BC,d16 cpu.C = v & 0x00FF cpu.PC += 3 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 def LD_02(cpu): # 02 LD (BC),A cpu.mb.setitem(((cpu.B << 8) + cpu.C), cpu.A) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def INC_03(cpu): # 03 INC BC @@ -46,7 +47,7 @@ def INC_03(cpu): # 03 INC BC cpu.C = t & 0x00FF cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def INC_04(cpu): # 04 INC B @@ -60,7 +61,7 @@ def INC_04(cpu): # 04 INC B cpu.B = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def DEC_05(cpu): # 05 DEC B @@ -74,14 +75,14 @@ def DEC_05(cpu): # 05 DEC B cpu.B = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_06(cpu, v): # 06 LD B,d8 cpu.B = v cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RLCA_07(cpu): # 07 RLCA @@ -94,7 +95,7 @@ def RLCA_07(cpu): # 07 RLCA cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_08(cpu, v): # 08 LD (a16),SP @@ -102,7 +103,7 @@ def LD_08(cpu, v): # 08 LD (a16),SP cpu.mb.setitem(v+1, cpu.SP >> 8) cpu.PC += 3 cpu.PC &= 0xFFFF - return 20 + cpu.cycles += 20 def ADD_09(cpu): # 09 ADD HL,BC @@ -116,14 +117,14 @@ def ADD_09(cpu): # 09 ADD HL,BC cpu.HL = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_0A(cpu): # 0A LD A,(BC) cpu.A = cpu.mb.getitem(((cpu.B << 8) + cpu.C)) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def DEC_0B(cpu): # 0B DEC BC @@ -134,7 +135,7 @@ def DEC_0B(cpu): # 0B DEC BC cpu.C = t & 0x00FF cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def INC_0C(cpu): # 0C INC C @@ -148,7 +149,7 @@ def INC_0C(cpu): # 0C INC C cpu.C = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def DEC_0D(cpu): # 0D DEC C @@ -162,14 +163,14 @@ def DEC_0D(cpu): # 0D DEC C cpu.C = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_0E(cpu, v): # 0E LD C,d8 cpu.C = v cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RRCA_0F(cpu): # 0F RRCA @@ -182,7 +183,7 @@ def RRCA_0F(cpu): # 0F RRCA cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def STOP_10(cpu, v): # 10 STOP 0 @@ -191,7 +192,7 @@ def STOP_10(cpu, v): # 10 STOP 0 cpu.mb.setitem(0xFF04, 0) cpu.PC += 2 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_11(cpu, v): # 11 LD DE,d16 @@ -199,14 +200,14 @@ def LD_11(cpu, v): # 11 LD DE,d16 cpu.E = v & 0x00FF cpu.PC += 3 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 def LD_12(cpu): # 12 LD (DE),A cpu.mb.setitem(((cpu.D << 8) + cpu.E), cpu.A) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def INC_13(cpu): # 13 INC DE @@ -217,7 +218,7 @@ def INC_13(cpu): # 13 INC DE cpu.E = t & 0x00FF cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def INC_14(cpu): # 14 INC D @@ -231,7 +232,7 @@ def INC_14(cpu): # 14 INC D cpu.D = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def DEC_15(cpu): # 15 DEC D @@ -245,14 +246,14 @@ def DEC_15(cpu): # 15 DEC D cpu.D = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_16(cpu, v): # 16 LD D,d8 cpu.D = v cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RLA_17(cpu): # 17 RLA @@ -265,13 +266,13 @@ def RLA_17(cpu): # 17 RLA cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def JR_18(cpu, v): # 18 JR r8 cpu.PC += 2 + ((v ^ 0x80) - 0x80) cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 def ADD_19(cpu): # 19 ADD HL,DE @@ -285,14 +286,14 @@ def ADD_19(cpu): # 19 ADD HL,DE cpu.HL = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_1A(cpu): # 1A LD A,(DE) cpu.A = cpu.mb.getitem(((cpu.D << 8) + cpu.E)) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def DEC_1B(cpu): # 1B DEC DE @@ -303,7 +304,7 @@ def DEC_1B(cpu): # 1B DEC DE cpu.E = t & 0x00FF cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def INC_1C(cpu): # 1C INC E @@ -317,7 +318,7 @@ def INC_1C(cpu): # 1C INC E cpu.E = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def DEC_1D(cpu): # 1D DEC E @@ -331,14 +332,14 @@ def DEC_1D(cpu): # 1D DEC E cpu.E = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_1E(cpu, v): # 1E LD E,d8 cpu.E = v cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RRA_1F(cpu): # 1F RRA @@ -351,7 +352,7 @@ def RRA_1F(cpu): # 1F RRA cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def JR_20(cpu, v): # 20 JR NZ,r8 @@ -359,17 +360,17 @@ def JR_20(cpu, v): # 20 JR NZ,r8 if ((cpu.F & (1 << FLAGZ)) == 0): cpu.PC += ((v ^ 0x80) - 0x80) cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 else: cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_21(cpu, v): # 21 LD HL,d16 cpu.HL = v cpu.PC += 3 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 def LD_22(cpu): # 22 LD (HL+),A @@ -378,7 +379,7 @@ def LD_22(cpu): # 22 LD (HL+),A cpu.HL &= 0xFFFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def INC_23(cpu): # 23 INC HL @@ -388,7 +389,7 @@ def INC_23(cpu): # 23 INC HL cpu.HL = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def INC_24(cpu): # 24 INC H @@ -402,7 +403,7 @@ def INC_24(cpu): # 24 INC H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def DEC_25(cpu): # 25 DEC H @@ -416,14 +417,14 @@ def DEC_25(cpu): # 25 DEC H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_26(cpu, v): # 26 LD H,d8 cpu.HL = (cpu.HL & 0x00FF) | (v << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def DAA_27(cpu): # 27 DAA @@ -446,7 +447,7 @@ def DAA_27(cpu): # 27 DAA cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def JR_28(cpu, v): # 28 JR Z,r8 @@ -454,10 +455,10 @@ def JR_28(cpu, v): # 28 JR Z,r8 if ((cpu.F & (1 << FLAGZ)) != 0): cpu.PC += ((v ^ 0x80) - 0x80) cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 else: cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def ADD_29(cpu): # 29 ADD HL,HL @@ -471,7 +472,7 @@ def ADD_29(cpu): # 29 ADD HL,HL cpu.HL = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_2A(cpu): # 2A LD A,(HL+) @@ -480,7 +481,7 @@ def LD_2A(cpu): # 2A LD A,(HL+) cpu.HL &= 0xFFFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def DEC_2B(cpu): # 2B DEC HL @@ -490,7 +491,7 @@ def DEC_2B(cpu): # 2B DEC HL cpu.HL = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def INC_2C(cpu): # 2C INC L @@ -504,7 +505,7 @@ def INC_2C(cpu): # 2C INC L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def DEC_2D(cpu): # 2D DEC L @@ -518,14 +519,14 @@ def DEC_2D(cpu): # 2D DEC L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_2E(cpu, v): # 2E LD L,d8 cpu.HL = (cpu.HL & 0xFF00) | (v & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def CPL_2F(cpu): # 2F CPL @@ -535,7 +536,7 @@ def CPL_2F(cpu): # 2F CPL cpu.F |= flag cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def JR_30(cpu, v): # 30 JR NC,r8 @@ -543,17 +544,17 @@ def JR_30(cpu, v): # 30 JR NC,r8 if ((cpu.F & (1 << FLAGC)) == 0): cpu.PC += ((v ^ 0x80) - 0x80) cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 else: cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_31(cpu, v): # 31 LD SP,d16 cpu.SP = v cpu.PC += 3 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 def LD_32(cpu): # 32 LD (HL-),A @@ -562,7 +563,7 @@ def LD_32(cpu): # 32 LD (HL-),A cpu.HL &= 0xFFFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def INC_33(cpu): # 33 INC SP @@ -572,7 +573,7 @@ def INC_33(cpu): # 33 INC SP cpu.SP = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def INC_34(cpu): # 34 INC (HL) @@ -583,10 +584,11 @@ def INC_34(cpu): # 34 INC (HL) cpu.F &= 0b00010000 cpu.F |= flag t &= 0xFF + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 1 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 8 def DEC_35(cpu): # 35 DEC (HL) @@ -597,17 +599,19 @@ def DEC_35(cpu): # 35 DEC (HL) cpu.F &= 0b00010000 cpu.F |= flag t &= 0xFF + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 1 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 8 def LD_36(cpu, v): # 36 LD (HL),d8 + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, v) cpu.PC += 2 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 8 def SCF_37(cpu): # 37 SCF @@ -616,7 +620,7 @@ def SCF_37(cpu): # 37 SCF cpu.F |= flag cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def JR_38(cpu, v): # 38 JR C,r8 @@ -624,10 +628,10 @@ def JR_38(cpu, v): # 38 JR C,r8 if ((cpu.F & (1 << FLAGC)) != 0): cpu.PC += ((v ^ 0x80) - 0x80) cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 else: cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def ADD_39(cpu): # 39 ADD HL,SP @@ -641,7 +645,7 @@ def ADD_39(cpu): # 39 ADD HL,SP cpu.HL = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_3A(cpu): # 3A LD A,(HL-) @@ -650,7 +654,7 @@ def LD_3A(cpu): # 3A LD A,(HL-) cpu.HL &= 0xFFFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def DEC_3B(cpu): # 3B DEC SP @@ -660,7 +664,7 @@ def DEC_3B(cpu): # 3B DEC SP cpu.SP = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def INC_3C(cpu): # 3C INC A @@ -674,7 +678,7 @@ def INC_3C(cpu): # 3C INC A cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def DEC_3D(cpu): # 3D DEC A @@ -688,14 +692,14 @@ def DEC_3D(cpu): # 3D DEC A cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_3E(cpu, v): # 3E LD A,d8 cpu.A = v cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def CCF_3F(cpu): # 3F CCF @@ -704,453 +708,454 @@ def CCF_3F(cpu): # 3F CCF cpu.F |= flag cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_40(cpu): # 40 LD B,B cpu.B = cpu.B cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_41(cpu): # 41 LD B,C cpu.B = cpu.C cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_42(cpu): # 42 LD B,D cpu.B = cpu.D cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_43(cpu): # 43 LD B,E cpu.B = cpu.E cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_44(cpu): # 44 LD B,H cpu.B = (cpu.HL >> 8) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_45(cpu): # 45 LD B,L cpu.B = (cpu.HL & 0xFF) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_46(cpu): # 46 LD B,(HL) cpu.B = cpu.mb.getitem(cpu.HL) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_47(cpu): # 47 LD B,A cpu.B = cpu.A cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_48(cpu): # 48 LD C,B cpu.C = cpu.B cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_49(cpu): # 49 LD C,C cpu.C = cpu.C cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_4A(cpu): # 4A LD C,D cpu.C = cpu.D cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_4B(cpu): # 4B LD C,E cpu.C = cpu.E cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_4C(cpu): # 4C LD C,H cpu.C = (cpu.HL >> 8) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_4D(cpu): # 4D LD C,L cpu.C = (cpu.HL & 0xFF) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_4E(cpu): # 4E LD C,(HL) cpu.C = cpu.mb.getitem(cpu.HL) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_4F(cpu): # 4F LD C,A cpu.C = cpu.A cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_50(cpu): # 50 LD D,B cpu.D = cpu.B cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_51(cpu): # 51 LD D,C cpu.D = cpu.C cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_52(cpu): # 52 LD D,D cpu.D = cpu.D cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_53(cpu): # 53 LD D,E cpu.D = cpu.E cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_54(cpu): # 54 LD D,H cpu.D = (cpu.HL >> 8) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_55(cpu): # 55 LD D,L cpu.D = (cpu.HL & 0xFF) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_56(cpu): # 56 LD D,(HL) cpu.D = cpu.mb.getitem(cpu.HL) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_57(cpu): # 57 LD D,A cpu.D = cpu.A cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_58(cpu): # 58 LD E,B cpu.E = cpu.B cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_59(cpu): # 59 LD E,C cpu.E = cpu.C cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_5A(cpu): # 5A LD E,D cpu.E = cpu.D cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_5B(cpu): # 5B LD E,E cpu.E = cpu.E cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_5C(cpu): # 5C LD E,H cpu.E = (cpu.HL >> 8) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_5D(cpu): # 5D LD E,L cpu.E = (cpu.HL & 0xFF) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_5E(cpu): # 5E LD E,(HL) cpu.E = cpu.mb.getitem(cpu.HL) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_5F(cpu): # 5F LD E,A cpu.E = cpu.A cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_60(cpu): # 60 LD H,B cpu.HL = (cpu.HL & 0x00FF) | (cpu.B << 8) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_61(cpu): # 61 LD H,C cpu.HL = (cpu.HL & 0x00FF) | (cpu.C << 8) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_62(cpu): # 62 LD H,D cpu.HL = (cpu.HL & 0x00FF) | (cpu.D << 8) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_63(cpu): # 63 LD H,E cpu.HL = (cpu.HL & 0x00FF) | (cpu.E << 8) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_64(cpu): # 64 LD H,H cpu.HL = (cpu.HL & 0x00FF) | ((cpu.HL >> 8) << 8) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_65(cpu): # 65 LD H,L cpu.HL = (cpu.HL & 0x00FF) | ((cpu.HL & 0xFF) << 8) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_66(cpu): # 66 LD H,(HL) cpu.HL = (cpu.HL & 0x00FF) | (cpu.mb.getitem(cpu.HL) << 8) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_67(cpu): # 67 LD H,A cpu.HL = (cpu.HL & 0x00FF) | (cpu.A << 8) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_68(cpu): # 68 LD L,B cpu.HL = (cpu.HL & 0xFF00) | (cpu.B & 0xFF) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_69(cpu): # 69 LD L,C cpu.HL = (cpu.HL & 0xFF00) | (cpu.C & 0xFF) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_6A(cpu): # 6A LD L,D cpu.HL = (cpu.HL & 0xFF00) | (cpu.D & 0xFF) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_6B(cpu): # 6B LD L,E cpu.HL = (cpu.HL & 0xFF00) | (cpu.E & 0xFF) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_6C(cpu): # 6C LD L,H cpu.HL = (cpu.HL & 0xFF00) | ((cpu.HL >> 8) & 0xFF) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_6D(cpu): # 6D LD L,L cpu.HL = (cpu.HL & 0xFF00) | ((cpu.HL & 0xFF) & 0xFF) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_6E(cpu): # 6E LD L,(HL) cpu.HL = (cpu.HL & 0xFF00) | (cpu.mb.getitem(cpu.HL) & 0xFF) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_6F(cpu): # 6F LD L,A cpu.HL = (cpu.HL & 0xFF00) | (cpu.A & 0xFF) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_70(cpu): # 70 LD (HL),B cpu.mb.setitem(cpu.HL, cpu.B) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_71(cpu): # 71 LD (HL),C cpu.mb.setitem(cpu.HL, cpu.C) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_72(cpu): # 72 LD (HL),D cpu.mb.setitem(cpu.HL, cpu.D) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_73(cpu): # 73 LD (HL),E cpu.mb.setitem(cpu.HL, cpu.E) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_74(cpu): # 74 LD (HL),H cpu.mb.setitem(cpu.HL, (cpu.HL >> 8)) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_75(cpu): # 75 LD (HL),L cpu.mb.setitem(cpu.HL, (cpu.HL & 0xFF)) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def HALT_76(cpu): # 76 HALT cpu.halted = True - return 4 + cpu.bail = True + cpu.cycles += 4 def LD_77(cpu): # 77 LD (HL),A cpu.mb.setitem(cpu.HL, cpu.A) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_78(cpu): # 78 LD A,B cpu.A = cpu.B cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_79(cpu): # 79 LD A,C cpu.A = cpu.C cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_7A(cpu): # 7A LD A,D cpu.A = cpu.D cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_7B(cpu): # 7B LD A,E cpu.A = cpu.E cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_7C(cpu): # 7C LD A,H cpu.A = (cpu.HL >> 8) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_7D(cpu): # 7D LD A,L cpu.A = (cpu.HL & 0xFF) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def LD_7E(cpu): # 7E LD A,(HL) cpu.A = cpu.mb.getitem(cpu.HL) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_7F(cpu): # 7F LD A,A cpu.A = cpu.A cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def ADD_80(cpu): # 80 ADD A,B @@ -1165,7 +1170,7 @@ def ADD_80(cpu): # 80 ADD A,B cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def ADD_81(cpu): # 81 ADD A,C @@ -1180,7 +1185,7 @@ def ADD_81(cpu): # 81 ADD A,C cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def ADD_82(cpu): # 82 ADD A,D @@ -1195,7 +1200,7 @@ def ADD_82(cpu): # 82 ADD A,D cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def ADD_83(cpu): # 83 ADD A,E @@ -1210,7 +1215,7 @@ def ADD_83(cpu): # 83 ADD A,E cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def ADD_84(cpu): # 84 ADD A,H @@ -1225,7 +1230,7 @@ def ADD_84(cpu): # 84 ADD A,H cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def ADD_85(cpu): # 85 ADD A,L @@ -1240,7 +1245,7 @@ def ADD_85(cpu): # 85 ADD A,L cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def ADD_86(cpu): # 86 ADD A,(HL) @@ -1255,7 +1260,7 @@ def ADD_86(cpu): # 86 ADD A,(HL) cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def ADD_87(cpu): # 87 ADD A,A @@ -1270,7 +1275,7 @@ def ADD_87(cpu): # 87 ADD A,A cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def ADC_88(cpu): # 88 ADC A,B @@ -1285,7 +1290,7 @@ def ADC_88(cpu): # 88 ADC A,B cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def ADC_89(cpu): # 89 ADC A,C @@ -1300,7 +1305,7 @@ def ADC_89(cpu): # 89 ADC A,C cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def ADC_8A(cpu): # 8A ADC A,D @@ -1315,7 +1320,7 @@ def ADC_8A(cpu): # 8A ADC A,D cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def ADC_8B(cpu): # 8B ADC A,E @@ -1330,7 +1335,7 @@ def ADC_8B(cpu): # 8B ADC A,E cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def ADC_8C(cpu): # 8C ADC A,H @@ -1345,7 +1350,7 @@ def ADC_8C(cpu): # 8C ADC A,H cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def ADC_8D(cpu): # 8D ADC A,L @@ -1360,7 +1365,7 @@ def ADC_8D(cpu): # 8D ADC A,L cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def ADC_8E(cpu): # 8E ADC A,(HL) @@ -1375,7 +1380,7 @@ def ADC_8E(cpu): # 8E ADC A,(HL) cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def ADC_8F(cpu): # 8F ADC A,A @@ -1390,7 +1395,7 @@ def ADC_8F(cpu): # 8F ADC A,A cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def SUB_90(cpu): # 90 SUB B @@ -1405,7 +1410,7 @@ def SUB_90(cpu): # 90 SUB B cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def SUB_91(cpu): # 91 SUB C @@ -1420,7 +1425,7 @@ def SUB_91(cpu): # 91 SUB C cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def SUB_92(cpu): # 92 SUB D @@ -1435,7 +1440,7 @@ def SUB_92(cpu): # 92 SUB D cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def SUB_93(cpu): # 93 SUB E @@ -1450,7 +1455,7 @@ def SUB_93(cpu): # 93 SUB E cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def SUB_94(cpu): # 94 SUB H @@ -1465,7 +1470,7 @@ def SUB_94(cpu): # 94 SUB H cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def SUB_95(cpu): # 95 SUB L @@ -1480,7 +1485,7 @@ def SUB_95(cpu): # 95 SUB L cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def SUB_96(cpu): # 96 SUB (HL) @@ -1495,7 +1500,7 @@ def SUB_96(cpu): # 96 SUB (HL) cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SUB_97(cpu): # 97 SUB A @@ -1510,7 +1515,7 @@ def SUB_97(cpu): # 97 SUB A cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def SBC_98(cpu): # 98 SBC A,B @@ -1525,7 +1530,7 @@ def SBC_98(cpu): # 98 SBC A,B cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def SBC_99(cpu): # 99 SBC A,C @@ -1540,7 +1545,7 @@ def SBC_99(cpu): # 99 SBC A,C cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def SBC_9A(cpu): # 9A SBC A,D @@ -1555,7 +1560,7 @@ def SBC_9A(cpu): # 9A SBC A,D cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def SBC_9B(cpu): # 9B SBC A,E @@ -1570,7 +1575,7 @@ def SBC_9B(cpu): # 9B SBC A,E cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def SBC_9C(cpu): # 9C SBC A,H @@ -1585,7 +1590,7 @@ def SBC_9C(cpu): # 9C SBC A,H cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def SBC_9D(cpu): # 9D SBC A,L @@ -1600,7 +1605,7 @@ def SBC_9D(cpu): # 9D SBC A,L cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def SBC_9E(cpu): # 9E SBC A,(HL) @@ -1615,7 +1620,7 @@ def SBC_9E(cpu): # 9E SBC A,(HL) cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SBC_9F(cpu): # 9F SBC A,A @@ -1630,7 +1635,7 @@ def SBC_9F(cpu): # 9F SBC A,A cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def AND_A0(cpu): # A0 AND B @@ -1643,7 +1648,7 @@ def AND_A0(cpu): # A0 AND B cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def AND_A1(cpu): # A1 AND C @@ -1656,7 +1661,7 @@ def AND_A1(cpu): # A1 AND C cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def AND_A2(cpu): # A2 AND D @@ -1669,7 +1674,7 @@ def AND_A2(cpu): # A2 AND D cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def AND_A3(cpu): # A3 AND E @@ -1682,7 +1687,7 @@ def AND_A3(cpu): # A3 AND E cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def AND_A4(cpu): # A4 AND H @@ -1695,7 +1700,7 @@ def AND_A4(cpu): # A4 AND H cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def AND_A5(cpu): # A5 AND L @@ -1708,7 +1713,7 @@ def AND_A5(cpu): # A5 AND L cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def AND_A6(cpu): # A6 AND (HL) @@ -1721,7 +1726,7 @@ def AND_A6(cpu): # A6 AND (HL) cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def AND_A7(cpu): # A7 AND A @@ -1734,7 +1739,7 @@ def AND_A7(cpu): # A7 AND A cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def XOR_A8(cpu): # A8 XOR B @@ -1747,7 +1752,7 @@ def XOR_A8(cpu): # A8 XOR B cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def XOR_A9(cpu): # A9 XOR C @@ -1760,7 +1765,7 @@ def XOR_A9(cpu): # A9 XOR C cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def XOR_AA(cpu): # AA XOR D @@ -1773,7 +1778,7 @@ def XOR_AA(cpu): # AA XOR D cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def XOR_AB(cpu): # AB XOR E @@ -1786,7 +1791,7 @@ def XOR_AB(cpu): # AB XOR E cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def XOR_AC(cpu): # AC XOR H @@ -1799,7 +1804,7 @@ def XOR_AC(cpu): # AC XOR H cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def XOR_AD(cpu): # AD XOR L @@ -1812,7 +1817,7 @@ def XOR_AD(cpu): # AD XOR L cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def XOR_AE(cpu): # AE XOR (HL) @@ -1825,7 +1830,7 @@ def XOR_AE(cpu): # AE XOR (HL) cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def XOR_AF(cpu): # AF XOR A @@ -1838,7 +1843,7 @@ def XOR_AF(cpu): # AF XOR A cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def OR_B0(cpu): # B0 OR B @@ -1851,7 +1856,7 @@ def OR_B0(cpu): # B0 OR B cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def OR_B1(cpu): # B1 OR C @@ -1864,7 +1869,7 @@ def OR_B1(cpu): # B1 OR C cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def OR_B2(cpu): # B2 OR D @@ -1877,7 +1882,7 @@ def OR_B2(cpu): # B2 OR D cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def OR_B3(cpu): # B3 OR E @@ -1890,7 +1895,7 @@ def OR_B3(cpu): # B3 OR E cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def OR_B4(cpu): # B4 OR H @@ -1903,7 +1908,7 @@ def OR_B4(cpu): # B4 OR H cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def OR_B5(cpu): # B5 OR L @@ -1916,7 +1921,7 @@ def OR_B5(cpu): # B5 OR L cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def OR_B6(cpu): # B6 OR (HL) @@ -1929,7 +1934,7 @@ def OR_B6(cpu): # B6 OR (HL) cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def OR_B7(cpu): # B7 OR A @@ -1942,7 +1947,7 @@ def OR_B7(cpu): # B7 OR A cpu.A = t cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def CP_B8(cpu): # B8 CP B @@ -1956,7 +1961,7 @@ def CP_B8(cpu): # B8 CP B t &= 0xFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def CP_B9(cpu): # B9 CP C @@ -1970,7 +1975,7 @@ def CP_B9(cpu): # B9 CP C t &= 0xFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def CP_BA(cpu): # BA CP D @@ -1984,7 +1989,7 @@ def CP_BA(cpu): # BA CP D t &= 0xFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def CP_BB(cpu): # BB CP E @@ -1998,7 +2003,7 @@ def CP_BB(cpu): # BB CP E t &= 0xFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def CP_BC(cpu): # BC CP H @@ -2012,7 +2017,7 @@ def CP_BC(cpu): # BC CP H t &= 0xFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def CP_BD(cpu): # BD CP L @@ -2026,7 +2031,7 @@ def CP_BD(cpu): # BD CP L t &= 0xFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def CP_BE(cpu): # BE CP (HL) @@ -2040,7 +2045,7 @@ def CP_BE(cpu): # BE CP (HL) t &= 0xFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def CP_BF(cpu): # BF CP A @@ -2054,7 +2059,7 @@ def CP_BF(cpu): # BF CP A t &= 0xFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def RET_C0(cpu): # C0 RET NZ @@ -2063,11 +2068,11 @@ def RET_C0(cpu): # C0 RET NZ cpu.PC |= cpu.mb.getitem(cpu.SP) # Low cpu.SP += 2 cpu.SP &= 0xFFFF - return 20 + cpu.cycles += 20 else: cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def POP_C1(cpu): # C1 POP BC @@ -2077,22 +2082,22 @@ def POP_C1(cpu): # C1 POP BC cpu.SP &= 0xFFFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 def JP_C2(cpu, v): # C2 JP NZ,a16 if ((cpu.F & (1 << FLAGZ)) == 0): cpu.PC = v - return 16 + cpu.cycles += 16 else: cpu.PC += 3 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 def JP_C3(cpu, v): # C3 JP a16 cpu.PC = v - return 16 + cpu.cycles += 16 def CALL_C4(cpu, v): # C4 CALL NZ,a16 @@ -2104,9 +2109,9 @@ def CALL_C4(cpu, v): # C4 CALL NZ,a16 cpu.SP -= 2 cpu.SP &= 0xFFFF cpu.PC = v - return 24 + cpu.cycles += 24 else: - return 12 + cpu.cycles += 12 def PUSH_C5(cpu): # C5 PUSH BC @@ -2116,7 +2121,7 @@ def PUSH_C5(cpu): # C5 PUSH BC cpu.SP &= 0xFFFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 16 def ADD_C6(cpu, v): # C6 ADD A,d8 @@ -2131,7 +2136,7 @@ def ADD_C6(cpu, v): # C6 ADD A,d8 cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RST_C7(cpu): # C7 RST 00H @@ -2142,7 +2147,7 @@ def RST_C7(cpu): # C7 RST 00H cpu.SP -= 2 cpu.SP &= 0xFFFF cpu.PC = 0 - return 16 + cpu.cycles += 16 def RET_C8(cpu): # C8 RET Z @@ -2151,11 +2156,11 @@ def RET_C8(cpu): # C8 RET Z cpu.PC |= cpu.mb.getitem(cpu.SP) # Low cpu.SP += 2 cpu.SP &= 0xFFFF - return 20 + cpu.cycles += 20 else: cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RET_C9(cpu): # C9 RET @@ -2163,24 +2168,24 @@ def RET_C9(cpu): # C9 RET cpu.PC |= cpu.mb.getitem(cpu.SP) # Low cpu.SP += 2 cpu.SP &= 0xFFFF - return 16 + cpu.cycles += 16 def JP_CA(cpu, v): # CA JP Z,a16 if ((cpu.F & (1 << FLAGZ)) != 0): cpu.PC = v - return 16 + cpu.cycles += 16 else: cpu.PC += 3 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 def PREFIX_CB(cpu): # CB PREFIX CB logger.critical('CB cannot be called!') cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def CALL_CC(cpu, v): # CC CALL Z,a16 @@ -2192,9 +2197,9 @@ def CALL_CC(cpu, v): # CC CALL Z,a16 cpu.SP -= 2 cpu.SP &= 0xFFFF cpu.PC = v - return 24 + cpu.cycles += 24 else: - return 12 + cpu.cycles += 12 def CALL_CD(cpu, v): # CD CALL a16 @@ -2205,7 +2210,7 @@ def CALL_CD(cpu, v): # CD CALL a16 cpu.SP -= 2 cpu.SP &= 0xFFFF cpu.PC = v - return 24 + cpu.cycles += 24 def ADC_CE(cpu, v): # CE ADC A,d8 @@ -2220,7 +2225,7 @@ def ADC_CE(cpu, v): # CE ADC A,d8 cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RST_CF(cpu): # CF RST 08H @@ -2231,7 +2236,7 @@ def RST_CF(cpu): # CF RST 08H cpu.SP -= 2 cpu.SP &= 0xFFFF cpu.PC = 8 - return 16 + cpu.cycles += 16 def RET_D0(cpu): # D0 RET NC @@ -2240,11 +2245,11 @@ def RET_D0(cpu): # D0 RET NC cpu.PC |= cpu.mb.getitem(cpu.SP) # Low cpu.SP += 2 cpu.SP &= 0xFFFF - return 20 + cpu.cycles += 20 else: cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def POP_D1(cpu): # D1 POP DE @@ -2254,17 +2259,17 @@ def POP_D1(cpu): # D1 POP DE cpu.SP &= 0xFFFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 def JP_D2(cpu, v): # D2 JP NC,a16 if ((cpu.F & (1 << FLAGC)) == 0): cpu.PC = v - return 16 + cpu.cycles += 16 else: cpu.PC += 3 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 def CALL_D4(cpu, v): # D4 CALL NC,a16 @@ -2276,9 +2281,9 @@ def CALL_D4(cpu, v): # D4 CALL NC,a16 cpu.SP -= 2 cpu.SP &= 0xFFFF cpu.PC = v - return 24 + cpu.cycles += 24 else: - return 12 + cpu.cycles += 12 def PUSH_D5(cpu): # D5 PUSH DE @@ -2288,7 +2293,7 @@ def PUSH_D5(cpu): # D5 PUSH DE cpu.SP &= 0xFFFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 16 def SUB_D6(cpu, v): # D6 SUB d8 @@ -2303,7 +2308,7 @@ def SUB_D6(cpu, v): # D6 SUB d8 cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RST_D7(cpu): # D7 RST 10H @@ -2314,7 +2319,7 @@ def RST_D7(cpu): # D7 RST 10H cpu.SP -= 2 cpu.SP &= 0xFFFF cpu.PC = 16 - return 16 + cpu.cycles += 16 def RET_D8(cpu): # D8 RET C @@ -2323,30 +2328,31 @@ def RET_D8(cpu): # D8 RET C cpu.PC |= cpu.mb.getitem(cpu.SP) # Low cpu.SP += 2 cpu.SP &= 0xFFFF - return 20 + cpu.cycles += 20 else: cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RETI_D9(cpu): # D9 RETI cpu.interrupt_master_enable = True + cpu.bail = (cpu.interrupts_flag_register & 0b11111) & (cpu.interrupts_enabled_register & 0b11111) cpu.PC = cpu.mb.getitem((cpu.SP + 1) & 0xFFFF) << 8 # High cpu.PC |= cpu.mb.getitem(cpu.SP) # Low cpu.SP += 2 cpu.SP &= 0xFFFF - return 16 + cpu.cycles += 16 def JP_DA(cpu, v): # DA JP C,a16 if ((cpu.F & (1 << FLAGC)) != 0): cpu.PC = v - return 16 + cpu.cycles += 16 else: cpu.PC += 3 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 def CALL_DC(cpu, v): # DC CALL C,a16 @@ -2358,9 +2364,9 @@ def CALL_DC(cpu, v): # DC CALL C,a16 cpu.SP -= 2 cpu.SP &= 0xFFFF cpu.PC = v - return 24 + cpu.cycles += 24 else: - return 12 + cpu.cycles += 12 def SBC_DE(cpu, v): # DE SBC A,d8 @@ -2375,7 +2381,7 @@ def SBC_DE(cpu, v): # DE SBC A,d8 cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RST_DF(cpu): # DF RST 18H @@ -2386,14 +2392,15 @@ def RST_DF(cpu): # DF RST 18H cpu.SP -= 2 cpu.SP &= 0xFFFF cpu.PC = 24 - return 16 + cpu.cycles += 16 def LDH_E0(cpu, v): # E0 LDH (a8),A + cpu.cycles += 4 cpu.mb.setitem(v + 0xFF00, cpu.A) cpu.PC += 2 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 8 def POP_E1(cpu): # E1 POP HL @@ -2402,14 +2409,14 @@ def POP_E1(cpu): # E1 POP HL cpu.SP &= 0xFFFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 def LD_E2(cpu): # E2 LD (C),A cpu.mb.setitem(0xFF00 + cpu.C, cpu.A) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def PUSH_E5(cpu): # E5 PUSH HL @@ -2419,7 +2426,7 @@ def PUSH_E5(cpu): # E5 PUSH HL cpu.SP &= 0xFFFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 16 def AND_E6(cpu, v): # E6 AND d8 @@ -2432,7 +2439,7 @@ def AND_E6(cpu, v): # E6 AND d8 cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RST_E7(cpu): # E7 RST 20H @@ -2443,7 +2450,7 @@ def RST_E7(cpu): # E7 RST 20H cpu.SP -= 2 cpu.SP &= 0xFFFF cpu.PC = 32 - return 16 + cpu.cycles += 16 def ADD_E8(cpu, v): # E8 ADD SP,r8 @@ -2457,19 +2464,20 @@ def ADD_E8(cpu, v): # E8 ADD SP,r8 cpu.SP = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 16 def JP_E9(cpu): # E9 JP (HL) cpu.PC = cpu.HL - return 4 + cpu.cycles += 4 def LD_EA(cpu, v): # EA LD (a16),A + cpu.cycles += 8 cpu.mb.setitem(v, cpu.A) cpu.PC += 3 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def XOR_EE(cpu, v): # EE XOR d8 @@ -2482,7 +2490,7 @@ def XOR_EE(cpu, v): # EE XOR d8 cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RST_EF(cpu): # EF RST 28H @@ -2493,14 +2501,15 @@ def RST_EF(cpu): # EF RST 28H cpu.SP -= 2 cpu.SP &= 0xFFFF cpu.PC = 40 - return 16 + cpu.cycles += 16 def LDH_F0(cpu, v): # F0 LDH A,(a8) + cpu.cycles += 4 cpu.A = cpu.mb.getitem(v + 0xFF00) cpu.PC += 2 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 8 def POP_F1(cpu): # F1 POP AF @@ -2510,21 +2519,21 @@ def POP_F1(cpu): # F1 POP AF cpu.SP &= 0xFFFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 def LD_F2(cpu): # F2 LD A,(C) cpu.A = cpu.mb.getitem(0xFF00 + cpu.C) cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def DI_F3(cpu): # F3 DI cpu.interrupt_master_enable = False cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def PUSH_F5(cpu): # F5 PUSH AF @@ -2534,7 +2543,7 @@ def PUSH_F5(cpu): # F5 PUSH AF cpu.SP &= 0xFFFF cpu.PC += 1 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 16 def OR_F6(cpu, v): # F6 OR d8 @@ -2547,7 +2556,7 @@ def OR_F6(cpu, v): # F6 OR d8 cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RST_F7(cpu): # F7 RST 30H @@ -2558,7 +2567,7 @@ def RST_F7(cpu): # F7 RST 30H cpu.SP -= 2 cpu.SP &= 0xFFFF cpu.PC = 48 - return 16 + cpu.cycles += 16 def LD_F8(cpu, v): # F8 LD HL,SP+r8 @@ -2572,28 +2581,30 @@ def LD_F8(cpu, v): # F8 LD HL,SP+r8 cpu.HL &= 0xFFFF cpu.PC += 2 cpu.PC &= 0xFFFF - return 12 + cpu.cycles += 12 def LD_F9(cpu): # F9 LD SP,HL cpu.SP = cpu.HL cpu.PC += 1 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def LD_FA(cpu, v): # FA LD A,(a16) + cpu.cycles += 8 cpu.A = cpu.mb.getitem(v) cpu.PC += 3 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def EI_FB(cpu): # FB EI cpu.interrupt_master_enable = True + cpu.bail = (cpu.interrupts_flag_register & 0b11111) & (cpu.interrupts_enabled_register & 0b11111) cpu.PC += 1 cpu.PC &= 0xFFFF - return 4 + cpu.cycles += 4 def CP_FE(cpu, v): # FE CP d8 @@ -2607,7 +2618,7 @@ def CP_FE(cpu, v): # FE CP d8 t &= 0xFF cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RST_FF(cpu): # FF RST 38H @@ -2618,7 +2629,7 @@ def RST_FF(cpu): # FF RST 38H cpu.SP -= 2 cpu.SP &= 0xFFFF cpu.PC = 56 - return 16 + cpu.cycles += 16 def RLC_100(cpu): # 100 RLC B @@ -2632,7 +2643,7 @@ def RLC_100(cpu): # 100 RLC B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RLC_101(cpu): # 101 RLC C @@ -2646,7 +2657,7 @@ def RLC_101(cpu): # 101 RLC C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RLC_102(cpu): # 102 RLC D @@ -2660,7 +2671,7 @@ def RLC_102(cpu): # 102 RLC D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RLC_103(cpu): # 103 RLC E @@ -2674,7 +2685,7 @@ def RLC_103(cpu): # 103 RLC E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RLC_104(cpu): # 104 RLC H @@ -2688,7 +2699,7 @@ def RLC_104(cpu): # 104 RLC H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RLC_105(cpu): # 105 RLC L @@ -2702,10 +2713,11 @@ def RLC_105(cpu): # 105 RLC L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RLC_106(cpu): # 106 RLC (HL) + cpu.cycles += 4 t = (cpu.mb.getitem(cpu.HL) << 1) + (cpu.mb.getitem(cpu.HL) >> 7) flag = 0b00000000 flag += ((t & 0xFF) == 0) << FLAGZ @@ -2713,10 +2725,11 @@ def RLC_106(cpu): # 106 RLC (HL) cpu.F &= 0b00000000 cpu.F |= flag t &= 0xFF + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def RLC_107(cpu): # 107 RLC A @@ -2730,7 +2743,7 @@ def RLC_107(cpu): # 107 RLC A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RRC_108(cpu): # 108 RRC B @@ -2744,7 +2757,7 @@ def RRC_108(cpu): # 108 RRC B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RRC_109(cpu): # 109 RRC C @@ -2758,7 +2771,7 @@ def RRC_109(cpu): # 109 RRC C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RRC_10A(cpu): # 10A RRC D @@ -2772,7 +2785,7 @@ def RRC_10A(cpu): # 10A RRC D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RRC_10B(cpu): # 10B RRC E @@ -2786,7 +2799,7 @@ def RRC_10B(cpu): # 10B RRC E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RRC_10C(cpu): # 10C RRC H @@ -2800,7 +2813,7 @@ def RRC_10C(cpu): # 10C RRC H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RRC_10D(cpu): # 10D RRC L @@ -2814,10 +2827,11 @@ def RRC_10D(cpu): # 10D RRC L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RRC_10E(cpu): # 10E RRC (HL) + cpu.cycles += 4 t = (cpu.mb.getitem(cpu.HL) >> 1) + ((cpu.mb.getitem(cpu.HL) & 1) << 7) + ((cpu.mb.getitem(cpu.HL) & 1) << 8) flag = 0b00000000 flag += ((t & 0xFF) == 0) << FLAGZ @@ -2825,10 +2839,11 @@ def RRC_10E(cpu): # 10E RRC (HL) cpu.F &= 0b00000000 cpu.F |= flag t &= 0xFF + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def RRC_10F(cpu): # 10F RRC A @@ -2842,7 +2857,7 @@ def RRC_10F(cpu): # 10F RRC A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RL_110(cpu): # 110 RL B @@ -2856,7 +2871,7 @@ def RL_110(cpu): # 110 RL B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RL_111(cpu): # 111 RL C @@ -2870,7 +2885,7 @@ def RL_111(cpu): # 111 RL C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RL_112(cpu): # 112 RL D @@ -2884,7 +2899,7 @@ def RL_112(cpu): # 112 RL D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RL_113(cpu): # 113 RL E @@ -2898,7 +2913,7 @@ def RL_113(cpu): # 113 RL E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RL_114(cpu): # 114 RL H @@ -2912,7 +2927,7 @@ def RL_114(cpu): # 114 RL H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RL_115(cpu): # 115 RL L @@ -2926,10 +2941,11 @@ def RL_115(cpu): # 115 RL L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RL_116(cpu): # 116 RL (HL) + cpu.cycles += 4 t = (cpu.mb.getitem(cpu.HL) << 1) + ((cpu.F & (1 << FLAGC)) != 0) flag = 0b00000000 flag += ((t & 0xFF) == 0) << FLAGZ @@ -2937,10 +2953,11 @@ def RL_116(cpu): # 116 RL (HL) cpu.F &= 0b00000000 cpu.F |= flag t &= 0xFF + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def RL_117(cpu): # 117 RL A @@ -2954,7 +2971,7 @@ def RL_117(cpu): # 117 RL A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RR_118(cpu): # 118 RR B @@ -2968,7 +2985,7 @@ def RR_118(cpu): # 118 RR B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RR_119(cpu): # 119 RR C @@ -2982,7 +2999,7 @@ def RR_119(cpu): # 119 RR C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RR_11A(cpu): # 11A RR D @@ -2996,7 +3013,7 @@ def RR_11A(cpu): # 11A RR D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RR_11B(cpu): # 11B RR E @@ -3010,7 +3027,7 @@ def RR_11B(cpu): # 11B RR E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RR_11C(cpu): # 11C RR H @@ -3024,7 +3041,7 @@ def RR_11C(cpu): # 11C RR H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RR_11D(cpu): # 11D RR L @@ -3038,10 +3055,11 @@ def RR_11D(cpu): # 11D RR L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RR_11E(cpu): # 11E RR (HL) + cpu.cycles += 4 t = (cpu.mb.getitem(cpu.HL) >> 1) + (((cpu.F & (1 << FLAGC)) != 0) << 7) + ((cpu.mb.getitem(cpu.HL) & 1) << 8) flag = 0b00000000 flag += ((t & 0xFF) == 0) << FLAGZ @@ -3049,10 +3067,11 @@ def RR_11E(cpu): # 11E RR (HL) cpu.F &= 0b00000000 cpu.F |= flag t &= 0xFF + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def RR_11F(cpu): # 11F RR A @@ -3066,7 +3085,7 @@ def RR_11F(cpu): # 11F RR A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SLA_120(cpu): # 120 SLA B @@ -3080,7 +3099,7 @@ def SLA_120(cpu): # 120 SLA B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SLA_121(cpu): # 121 SLA C @@ -3094,7 +3113,7 @@ def SLA_121(cpu): # 121 SLA C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SLA_122(cpu): # 122 SLA D @@ -3108,7 +3127,7 @@ def SLA_122(cpu): # 122 SLA D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SLA_123(cpu): # 123 SLA E @@ -3122,7 +3141,7 @@ def SLA_123(cpu): # 123 SLA E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SLA_124(cpu): # 124 SLA H @@ -3136,7 +3155,7 @@ def SLA_124(cpu): # 124 SLA H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SLA_125(cpu): # 125 SLA L @@ -3150,10 +3169,11 @@ def SLA_125(cpu): # 125 SLA L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SLA_126(cpu): # 126 SLA (HL) + cpu.cycles += 4 t = (cpu.mb.getitem(cpu.HL) << 1) flag = 0b00000000 flag += ((t & 0xFF) == 0) << FLAGZ @@ -3161,10 +3181,11 @@ def SLA_126(cpu): # 126 SLA (HL) cpu.F &= 0b00000000 cpu.F |= flag t &= 0xFF + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def SLA_127(cpu): # 127 SLA A @@ -3178,7 +3199,7 @@ def SLA_127(cpu): # 127 SLA A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SRA_128(cpu): # 128 SRA B @@ -3192,7 +3213,7 @@ def SRA_128(cpu): # 128 SRA B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SRA_129(cpu): # 129 SRA C @@ -3206,7 +3227,7 @@ def SRA_129(cpu): # 129 SRA C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SRA_12A(cpu): # 12A SRA D @@ -3220,7 +3241,7 @@ def SRA_12A(cpu): # 12A SRA D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SRA_12B(cpu): # 12B SRA E @@ -3234,7 +3255,7 @@ def SRA_12B(cpu): # 12B SRA E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SRA_12C(cpu): # 12C SRA H @@ -3248,7 +3269,7 @@ def SRA_12C(cpu): # 12C SRA H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SRA_12D(cpu): # 12D SRA L @@ -3262,10 +3283,11 @@ def SRA_12D(cpu): # 12D SRA L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SRA_12E(cpu): # 12E SRA (HL) + cpu.cycles += 4 t = ((cpu.mb.getitem(cpu.HL) >> 1) | (cpu.mb.getitem(cpu.HL) & 0x80)) + ((cpu.mb.getitem(cpu.HL) & 1) << 8) flag = 0b00000000 flag += ((t & 0xFF) == 0) << FLAGZ @@ -3273,10 +3295,11 @@ def SRA_12E(cpu): # 12E SRA (HL) cpu.F &= 0b00000000 cpu.F |= flag t &= 0xFF + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def SRA_12F(cpu): # 12F SRA A @@ -3290,7 +3313,7 @@ def SRA_12F(cpu): # 12F SRA A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SWAP_130(cpu): # 130 SWAP B @@ -3303,7 +3326,7 @@ def SWAP_130(cpu): # 130 SWAP B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SWAP_131(cpu): # 131 SWAP C @@ -3316,7 +3339,7 @@ def SWAP_131(cpu): # 131 SWAP C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SWAP_132(cpu): # 132 SWAP D @@ -3329,7 +3352,7 @@ def SWAP_132(cpu): # 132 SWAP D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SWAP_133(cpu): # 133 SWAP E @@ -3342,7 +3365,7 @@ def SWAP_133(cpu): # 133 SWAP E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SWAP_134(cpu): # 134 SWAP H @@ -3355,7 +3378,7 @@ def SWAP_134(cpu): # 134 SWAP H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SWAP_135(cpu): # 135 SWAP L @@ -3368,20 +3391,22 @@ def SWAP_135(cpu): # 135 SWAP L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SWAP_136(cpu): # 136 SWAP (HL) + cpu.cycles += 4 t = ((cpu.mb.getitem(cpu.HL) & 0xF0) >> 4) | ((cpu.mb.getitem(cpu.HL) & 0x0F) << 4) flag = 0b00000000 flag += ((t & 0xFF) == 0) << FLAGZ cpu.F &= 0b00000000 cpu.F |= flag t &= 0xFF + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def SWAP_137(cpu): # 137 SWAP A @@ -3394,7 +3419,7 @@ def SWAP_137(cpu): # 137 SWAP A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SRL_138(cpu): # 138 SRL B @@ -3408,7 +3433,7 @@ def SRL_138(cpu): # 138 SRL B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SRL_139(cpu): # 139 SRL C @@ -3422,7 +3447,7 @@ def SRL_139(cpu): # 139 SRL C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SRL_13A(cpu): # 13A SRL D @@ -3436,7 +3461,7 @@ def SRL_13A(cpu): # 13A SRL D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SRL_13B(cpu): # 13B SRL E @@ -3450,7 +3475,7 @@ def SRL_13B(cpu): # 13B SRL E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SRL_13C(cpu): # 13C SRL H @@ -3464,7 +3489,7 @@ def SRL_13C(cpu): # 13C SRL H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SRL_13D(cpu): # 13D SRL L @@ -3478,10 +3503,11 @@ def SRL_13D(cpu): # 13D SRL L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SRL_13E(cpu): # 13E SRL (HL) + cpu.cycles += 4 t = (cpu.mb.getitem(cpu.HL) >> 1) + ((cpu.mb.getitem(cpu.HL) & 1) << 8) flag = 0b00000000 flag += ((t & 0xFF) == 0) << FLAGZ @@ -3489,10 +3515,11 @@ def SRL_13E(cpu): # 13E SRL (HL) cpu.F &= 0b00000000 cpu.F |= flag t &= 0xFF + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def SRL_13F(cpu): # 13F SRL A @@ -3506,7 +3533,7 @@ def SRL_13F(cpu): # 13F SRL A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_140(cpu): # 140 BIT 0,B @@ -3517,7 +3544,7 @@ def BIT_140(cpu): # 140 BIT 0,B cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_141(cpu): # 141 BIT 0,C @@ -3528,7 +3555,7 @@ def BIT_141(cpu): # 141 BIT 0,C cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_142(cpu): # 142 BIT 0,D @@ -3539,7 +3566,7 @@ def BIT_142(cpu): # 142 BIT 0,D cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_143(cpu): # 143 BIT 0,E @@ -3550,7 +3577,7 @@ def BIT_143(cpu): # 143 BIT 0,E cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_144(cpu): # 144 BIT 0,H @@ -3561,7 +3588,7 @@ def BIT_144(cpu): # 144 BIT 0,H cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_145(cpu): # 145 BIT 0,L @@ -3572,10 +3599,11 @@ def BIT_145(cpu): # 145 BIT 0,L cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_146(cpu): # 146 BIT 0,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) & (1 << 0) flag = 0b00100000 flag += ((t & 0xFF) == 0) << FLAGZ @@ -3583,7 +3611,7 @@ def BIT_146(cpu): # 146 BIT 0,(HL) cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def BIT_147(cpu): # 147 BIT 0,A @@ -3594,7 +3622,7 @@ def BIT_147(cpu): # 147 BIT 0,A cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_148(cpu): # 148 BIT 1,B @@ -3605,7 +3633,7 @@ def BIT_148(cpu): # 148 BIT 1,B cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_149(cpu): # 149 BIT 1,C @@ -3616,7 +3644,7 @@ def BIT_149(cpu): # 149 BIT 1,C cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_14A(cpu): # 14A BIT 1,D @@ -3627,7 +3655,7 @@ def BIT_14A(cpu): # 14A BIT 1,D cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_14B(cpu): # 14B BIT 1,E @@ -3638,7 +3666,7 @@ def BIT_14B(cpu): # 14B BIT 1,E cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_14C(cpu): # 14C BIT 1,H @@ -3649,7 +3677,7 @@ def BIT_14C(cpu): # 14C BIT 1,H cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_14D(cpu): # 14D BIT 1,L @@ -3660,10 +3688,11 @@ def BIT_14D(cpu): # 14D BIT 1,L cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_14E(cpu): # 14E BIT 1,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) & (1 << 1) flag = 0b00100000 flag += ((t & 0xFF) == 0) << FLAGZ @@ -3671,7 +3700,7 @@ def BIT_14E(cpu): # 14E BIT 1,(HL) cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def BIT_14F(cpu): # 14F BIT 1,A @@ -3682,7 +3711,7 @@ def BIT_14F(cpu): # 14F BIT 1,A cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_150(cpu): # 150 BIT 2,B @@ -3693,7 +3722,7 @@ def BIT_150(cpu): # 150 BIT 2,B cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_151(cpu): # 151 BIT 2,C @@ -3704,7 +3733,7 @@ def BIT_151(cpu): # 151 BIT 2,C cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_152(cpu): # 152 BIT 2,D @@ -3715,7 +3744,7 @@ def BIT_152(cpu): # 152 BIT 2,D cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_153(cpu): # 153 BIT 2,E @@ -3726,7 +3755,7 @@ def BIT_153(cpu): # 153 BIT 2,E cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_154(cpu): # 154 BIT 2,H @@ -3737,7 +3766,7 @@ def BIT_154(cpu): # 154 BIT 2,H cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_155(cpu): # 155 BIT 2,L @@ -3748,10 +3777,11 @@ def BIT_155(cpu): # 155 BIT 2,L cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_156(cpu): # 156 BIT 2,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) & (1 << 2) flag = 0b00100000 flag += ((t & 0xFF) == 0) << FLAGZ @@ -3759,7 +3789,7 @@ def BIT_156(cpu): # 156 BIT 2,(HL) cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def BIT_157(cpu): # 157 BIT 2,A @@ -3770,7 +3800,7 @@ def BIT_157(cpu): # 157 BIT 2,A cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_158(cpu): # 158 BIT 3,B @@ -3781,7 +3811,7 @@ def BIT_158(cpu): # 158 BIT 3,B cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_159(cpu): # 159 BIT 3,C @@ -3792,7 +3822,7 @@ def BIT_159(cpu): # 159 BIT 3,C cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_15A(cpu): # 15A BIT 3,D @@ -3803,7 +3833,7 @@ def BIT_15A(cpu): # 15A BIT 3,D cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_15B(cpu): # 15B BIT 3,E @@ -3814,7 +3844,7 @@ def BIT_15B(cpu): # 15B BIT 3,E cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_15C(cpu): # 15C BIT 3,H @@ -3825,7 +3855,7 @@ def BIT_15C(cpu): # 15C BIT 3,H cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_15D(cpu): # 15D BIT 3,L @@ -3836,10 +3866,11 @@ def BIT_15D(cpu): # 15D BIT 3,L cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_15E(cpu): # 15E BIT 3,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) & (1 << 3) flag = 0b00100000 flag += ((t & 0xFF) == 0) << FLAGZ @@ -3847,7 +3878,7 @@ def BIT_15E(cpu): # 15E BIT 3,(HL) cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def BIT_15F(cpu): # 15F BIT 3,A @@ -3858,7 +3889,7 @@ def BIT_15F(cpu): # 15F BIT 3,A cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_160(cpu): # 160 BIT 4,B @@ -3869,7 +3900,7 @@ def BIT_160(cpu): # 160 BIT 4,B cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_161(cpu): # 161 BIT 4,C @@ -3880,7 +3911,7 @@ def BIT_161(cpu): # 161 BIT 4,C cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_162(cpu): # 162 BIT 4,D @@ -3891,7 +3922,7 @@ def BIT_162(cpu): # 162 BIT 4,D cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_163(cpu): # 163 BIT 4,E @@ -3902,7 +3933,7 @@ def BIT_163(cpu): # 163 BIT 4,E cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_164(cpu): # 164 BIT 4,H @@ -3913,7 +3944,7 @@ def BIT_164(cpu): # 164 BIT 4,H cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_165(cpu): # 165 BIT 4,L @@ -3924,10 +3955,11 @@ def BIT_165(cpu): # 165 BIT 4,L cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_166(cpu): # 166 BIT 4,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) & (1 << 4) flag = 0b00100000 flag += ((t & 0xFF) == 0) << FLAGZ @@ -3935,7 +3967,7 @@ def BIT_166(cpu): # 166 BIT 4,(HL) cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def BIT_167(cpu): # 167 BIT 4,A @@ -3946,7 +3978,7 @@ def BIT_167(cpu): # 167 BIT 4,A cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_168(cpu): # 168 BIT 5,B @@ -3957,7 +3989,7 @@ def BIT_168(cpu): # 168 BIT 5,B cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_169(cpu): # 169 BIT 5,C @@ -3968,7 +4000,7 @@ def BIT_169(cpu): # 169 BIT 5,C cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_16A(cpu): # 16A BIT 5,D @@ -3979,7 +4011,7 @@ def BIT_16A(cpu): # 16A BIT 5,D cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_16B(cpu): # 16B BIT 5,E @@ -3990,7 +4022,7 @@ def BIT_16B(cpu): # 16B BIT 5,E cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_16C(cpu): # 16C BIT 5,H @@ -4001,7 +4033,7 @@ def BIT_16C(cpu): # 16C BIT 5,H cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_16D(cpu): # 16D BIT 5,L @@ -4012,10 +4044,11 @@ def BIT_16D(cpu): # 16D BIT 5,L cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_16E(cpu): # 16E BIT 5,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) & (1 << 5) flag = 0b00100000 flag += ((t & 0xFF) == 0) << FLAGZ @@ -4023,7 +4056,7 @@ def BIT_16E(cpu): # 16E BIT 5,(HL) cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def BIT_16F(cpu): # 16F BIT 5,A @@ -4034,7 +4067,7 @@ def BIT_16F(cpu): # 16F BIT 5,A cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_170(cpu): # 170 BIT 6,B @@ -4045,7 +4078,7 @@ def BIT_170(cpu): # 170 BIT 6,B cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_171(cpu): # 171 BIT 6,C @@ -4056,7 +4089,7 @@ def BIT_171(cpu): # 171 BIT 6,C cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_172(cpu): # 172 BIT 6,D @@ -4067,7 +4100,7 @@ def BIT_172(cpu): # 172 BIT 6,D cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_173(cpu): # 173 BIT 6,E @@ -4078,7 +4111,7 @@ def BIT_173(cpu): # 173 BIT 6,E cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_174(cpu): # 174 BIT 6,H @@ -4089,7 +4122,7 @@ def BIT_174(cpu): # 174 BIT 6,H cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_175(cpu): # 175 BIT 6,L @@ -4100,10 +4133,11 @@ def BIT_175(cpu): # 175 BIT 6,L cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_176(cpu): # 176 BIT 6,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) & (1 << 6) flag = 0b00100000 flag += ((t & 0xFF) == 0) << FLAGZ @@ -4111,7 +4145,7 @@ def BIT_176(cpu): # 176 BIT 6,(HL) cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def BIT_177(cpu): # 177 BIT 6,A @@ -4122,7 +4156,7 @@ def BIT_177(cpu): # 177 BIT 6,A cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_178(cpu): # 178 BIT 7,B @@ -4133,7 +4167,7 @@ def BIT_178(cpu): # 178 BIT 7,B cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_179(cpu): # 179 BIT 7,C @@ -4144,7 +4178,7 @@ def BIT_179(cpu): # 179 BIT 7,C cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_17A(cpu): # 17A BIT 7,D @@ -4155,7 +4189,7 @@ def BIT_17A(cpu): # 17A BIT 7,D cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_17B(cpu): # 17B BIT 7,E @@ -4166,7 +4200,7 @@ def BIT_17B(cpu): # 17B BIT 7,E cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_17C(cpu): # 17C BIT 7,H @@ -4177,7 +4211,7 @@ def BIT_17C(cpu): # 17C BIT 7,H cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_17D(cpu): # 17D BIT 7,L @@ -4188,10 +4222,11 @@ def BIT_17D(cpu): # 17D BIT 7,L cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def BIT_17E(cpu): # 17E BIT 7,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) & (1 << 7) flag = 0b00100000 flag += ((t & 0xFF) == 0) << FLAGZ @@ -4199,7 +4234,7 @@ def BIT_17E(cpu): # 17E BIT 7,(HL) cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def BIT_17F(cpu): # 17F BIT 7,A @@ -4210,7 +4245,7 @@ def BIT_17F(cpu): # 17F BIT 7,A cpu.F |= flag cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_180(cpu): # 180 RES 0,B @@ -4218,7 +4253,7 @@ def RES_180(cpu): # 180 RES 0,B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_181(cpu): # 181 RES 0,C @@ -4226,7 +4261,7 @@ def RES_181(cpu): # 181 RES 0,C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_182(cpu): # 182 RES 0,D @@ -4234,7 +4269,7 @@ def RES_182(cpu): # 182 RES 0,D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_183(cpu): # 183 RES 0,E @@ -4242,7 +4277,7 @@ def RES_183(cpu): # 183 RES 0,E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_184(cpu): # 184 RES 0,H @@ -4250,7 +4285,7 @@ def RES_184(cpu): # 184 RES 0,H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_185(cpu): # 185 RES 0,L @@ -4258,15 +4293,17 @@ def RES_185(cpu): # 185 RES 0,L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_186(cpu): # 186 RES 0,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) & ~(1 << 0) + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def RES_187(cpu): # 187 RES 0,A @@ -4274,7 +4311,7 @@ def RES_187(cpu): # 187 RES 0,A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_188(cpu): # 188 RES 1,B @@ -4282,7 +4319,7 @@ def RES_188(cpu): # 188 RES 1,B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_189(cpu): # 189 RES 1,C @@ -4290,7 +4327,7 @@ def RES_189(cpu): # 189 RES 1,C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_18A(cpu): # 18A RES 1,D @@ -4298,7 +4335,7 @@ def RES_18A(cpu): # 18A RES 1,D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_18B(cpu): # 18B RES 1,E @@ -4306,7 +4343,7 @@ def RES_18B(cpu): # 18B RES 1,E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_18C(cpu): # 18C RES 1,H @@ -4314,7 +4351,7 @@ def RES_18C(cpu): # 18C RES 1,H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_18D(cpu): # 18D RES 1,L @@ -4322,15 +4359,17 @@ def RES_18D(cpu): # 18D RES 1,L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_18E(cpu): # 18E RES 1,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) & ~(1 << 1) + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def RES_18F(cpu): # 18F RES 1,A @@ -4338,7 +4377,7 @@ def RES_18F(cpu): # 18F RES 1,A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_190(cpu): # 190 RES 2,B @@ -4346,7 +4385,7 @@ def RES_190(cpu): # 190 RES 2,B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_191(cpu): # 191 RES 2,C @@ -4354,7 +4393,7 @@ def RES_191(cpu): # 191 RES 2,C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_192(cpu): # 192 RES 2,D @@ -4362,7 +4401,7 @@ def RES_192(cpu): # 192 RES 2,D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_193(cpu): # 193 RES 2,E @@ -4370,7 +4409,7 @@ def RES_193(cpu): # 193 RES 2,E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_194(cpu): # 194 RES 2,H @@ -4378,7 +4417,7 @@ def RES_194(cpu): # 194 RES 2,H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_195(cpu): # 195 RES 2,L @@ -4386,15 +4425,17 @@ def RES_195(cpu): # 195 RES 2,L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_196(cpu): # 196 RES 2,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) & ~(1 << 2) + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def RES_197(cpu): # 197 RES 2,A @@ -4402,7 +4443,7 @@ def RES_197(cpu): # 197 RES 2,A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_198(cpu): # 198 RES 3,B @@ -4410,7 +4451,7 @@ def RES_198(cpu): # 198 RES 3,B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_199(cpu): # 199 RES 3,C @@ -4418,7 +4459,7 @@ def RES_199(cpu): # 199 RES 3,C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_19A(cpu): # 19A RES 3,D @@ -4426,7 +4467,7 @@ def RES_19A(cpu): # 19A RES 3,D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_19B(cpu): # 19B RES 3,E @@ -4434,7 +4475,7 @@ def RES_19B(cpu): # 19B RES 3,E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_19C(cpu): # 19C RES 3,H @@ -4442,7 +4483,7 @@ def RES_19C(cpu): # 19C RES 3,H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_19D(cpu): # 19D RES 3,L @@ -4450,15 +4491,17 @@ def RES_19D(cpu): # 19D RES 3,L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_19E(cpu): # 19E RES 3,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) & ~(1 << 3) + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def RES_19F(cpu): # 19F RES 3,A @@ -4466,7 +4509,7 @@ def RES_19F(cpu): # 19F RES 3,A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1A0(cpu): # 1A0 RES 4,B @@ -4474,7 +4517,7 @@ def RES_1A0(cpu): # 1A0 RES 4,B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1A1(cpu): # 1A1 RES 4,C @@ -4482,7 +4525,7 @@ def RES_1A1(cpu): # 1A1 RES 4,C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1A2(cpu): # 1A2 RES 4,D @@ -4490,7 +4533,7 @@ def RES_1A2(cpu): # 1A2 RES 4,D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1A3(cpu): # 1A3 RES 4,E @@ -4498,7 +4541,7 @@ def RES_1A3(cpu): # 1A3 RES 4,E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1A4(cpu): # 1A4 RES 4,H @@ -4506,7 +4549,7 @@ def RES_1A4(cpu): # 1A4 RES 4,H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1A5(cpu): # 1A5 RES 4,L @@ -4514,15 +4557,17 @@ def RES_1A5(cpu): # 1A5 RES 4,L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1A6(cpu): # 1A6 RES 4,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) & ~(1 << 4) + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def RES_1A7(cpu): # 1A7 RES 4,A @@ -4530,7 +4575,7 @@ def RES_1A7(cpu): # 1A7 RES 4,A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1A8(cpu): # 1A8 RES 5,B @@ -4538,7 +4583,7 @@ def RES_1A8(cpu): # 1A8 RES 5,B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1A9(cpu): # 1A9 RES 5,C @@ -4546,7 +4591,7 @@ def RES_1A9(cpu): # 1A9 RES 5,C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1AA(cpu): # 1AA RES 5,D @@ -4554,7 +4599,7 @@ def RES_1AA(cpu): # 1AA RES 5,D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1AB(cpu): # 1AB RES 5,E @@ -4562,7 +4607,7 @@ def RES_1AB(cpu): # 1AB RES 5,E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1AC(cpu): # 1AC RES 5,H @@ -4570,7 +4615,7 @@ def RES_1AC(cpu): # 1AC RES 5,H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1AD(cpu): # 1AD RES 5,L @@ -4578,15 +4623,17 @@ def RES_1AD(cpu): # 1AD RES 5,L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1AE(cpu): # 1AE RES 5,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) & ~(1 << 5) + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def RES_1AF(cpu): # 1AF RES 5,A @@ -4594,7 +4641,7 @@ def RES_1AF(cpu): # 1AF RES 5,A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1B0(cpu): # 1B0 RES 6,B @@ -4602,7 +4649,7 @@ def RES_1B0(cpu): # 1B0 RES 6,B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1B1(cpu): # 1B1 RES 6,C @@ -4610,7 +4657,7 @@ def RES_1B1(cpu): # 1B1 RES 6,C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1B2(cpu): # 1B2 RES 6,D @@ -4618,7 +4665,7 @@ def RES_1B2(cpu): # 1B2 RES 6,D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1B3(cpu): # 1B3 RES 6,E @@ -4626,7 +4673,7 @@ def RES_1B3(cpu): # 1B3 RES 6,E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1B4(cpu): # 1B4 RES 6,H @@ -4634,7 +4681,7 @@ def RES_1B4(cpu): # 1B4 RES 6,H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1B5(cpu): # 1B5 RES 6,L @@ -4642,15 +4689,17 @@ def RES_1B5(cpu): # 1B5 RES 6,L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1B6(cpu): # 1B6 RES 6,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) & ~(1 << 6) + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def RES_1B7(cpu): # 1B7 RES 6,A @@ -4658,7 +4707,7 @@ def RES_1B7(cpu): # 1B7 RES 6,A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1B8(cpu): # 1B8 RES 7,B @@ -4666,7 +4715,7 @@ def RES_1B8(cpu): # 1B8 RES 7,B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1B9(cpu): # 1B9 RES 7,C @@ -4674,7 +4723,7 @@ def RES_1B9(cpu): # 1B9 RES 7,C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1BA(cpu): # 1BA RES 7,D @@ -4682,7 +4731,7 @@ def RES_1BA(cpu): # 1BA RES 7,D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1BB(cpu): # 1BB RES 7,E @@ -4690,7 +4739,7 @@ def RES_1BB(cpu): # 1BB RES 7,E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1BC(cpu): # 1BC RES 7,H @@ -4698,7 +4747,7 @@ def RES_1BC(cpu): # 1BC RES 7,H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1BD(cpu): # 1BD RES 7,L @@ -4706,15 +4755,17 @@ def RES_1BD(cpu): # 1BD RES 7,L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def RES_1BE(cpu): # 1BE RES 7,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) & ~(1 << 7) + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def RES_1BF(cpu): # 1BF RES 7,A @@ -4722,7 +4773,7 @@ def RES_1BF(cpu): # 1BF RES 7,A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1C0(cpu): # 1C0 SET 0,B @@ -4730,7 +4781,7 @@ def SET_1C0(cpu): # 1C0 SET 0,B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1C1(cpu): # 1C1 SET 0,C @@ -4738,7 +4789,7 @@ def SET_1C1(cpu): # 1C1 SET 0,C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1C2(cpu): # 1C2 SET 0,D @@ -4746,7 +4797,7 @@ def SET_1C2(cpu): # 1C2 SET 0,D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1C3(cpu): # 1C3 SET 0,E @@ -4754,7 +4805,7 @@ def SET_1C3(cpu): # 1C3 SET 0,E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1C4(cpu): # 1C4 SET 0,H @@ -4762,7 +4813,7 @@ def SET_1C4(cpu): # 1C4 SET 0,H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1C5(cpu): # 1C5 SET 0,L @@ -4770,15 +4821,17 @@ def SET_1C5(cpu): # 1C5 SET 0,L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1C6(cpu): # 1C6 SET 0,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) | (1 << 0) + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def SET_1C7(cpu): # 1C7 SET 0,A @@ -4786,7 +4839,7 @@ def SET_1C7(cpu): # 1C7 SET 0,A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1C8(cpu): # 1C8 SET 1,B @@ -4794,7 +4847,7 @@ def SET_1C8(cpu): # 1C8 SET 1,B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1C9(cpu): # 1C9 SET 1,C @@ -4802,7 +4855,7 @@ def SET_1C9(cpu): # 1C9 SET 1,C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1CA(cpu): # 1CA SET 1,D @@ -4810,7 +4863,7 @@ def SET_1CA(cpu): # 1CA SET 1,D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1CB(cpu): # 1CB SET 1,E @@ -4818,7 +4871,7 @@ def SET_1CB(cpu): # 1CB SET 1,E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1CC(cpu): # 1CC SET 1,H @@ -4826,7 +4879,7 @@ def SET_1CC(cpu): # 1CC SET 1,H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1CD(cpu): # 1CD SET 1,L @@ -4834,15 +4887,17 @@ def SET_1CD(cpu): # 1CD SET 1,L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1CE(cpu): # 1CE SET 1,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) | (1 << 1) + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def SET_1CF(cpu): # 1CF SET 1,A @@ -4850,7 +4905,7 @@ def SET_1CF(cpu): # 1CF SET 1,A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1D0(cpu): # 1D0 SET 2,B @@ -4858,7 +4913,7 @@ def SET_1D0(cpu): # 1D0 SET 2,B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1D1(cpu): # 1D1 SET 2,C @@ -4866,7 +4921,7 @@ def SET_1D1(cpu): # 1D1 SET 2,C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1D2(cpu): # 1D2 SET 2,D @@ -4874,7 +4929,7 @@ def SET_1D2(cpu): # 1D2 SET 2,D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1D3(cpu): # 1D3 SET 2,E @@ -4882,7 +4937,7 @@ def SET_1D3(cpu): # 1D3 SET 2,E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1D4(cpu): # 1D4 SET 2,H @@ -4890,7 +4945,7 @@ def SET_1D4(cpu): # 1D4 SET 2,H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1D5(cpu): # 1D5 SET 2,L @@ -4898,15 +4953,17 @@ def SET_1D5(cpu): # 1D5 SET 2,L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1D6(cpu): # 1D6 SET 2,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) | (1 << 2) + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def SET_1D7(cpu): # 1D7 SET 2,A @@ -4914,7 +4971,7 @@ def SET_1D7(cpu): # 1D7 SET 2,A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1D8(cpu): # 1D8 SET 3,B @@ -4922,7 +4979,7 @@ def SET_1D8(cpu): # 1D8 SET 3,B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1D9(cpu): # 1D9 SET 3,C @@ -4930,7 +4987,7 @@ def SET_1D9(cpu): # 1D9 SET 3,C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1DA(cpu): # 1DA SET 3,D @@ -4938,7 +4995,7 @@ def SET_1DA(cpu): # 1DA SET 3,D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1DB(cpu): # 1DB SET 3,E @@ -4946,7 +5003,7 @@ def SET_1DB(cpu): # 1DB SET 3,E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1DC(cpu): # 1DC SET 3,H @@ -4954,7 +5011,7 @@ def SET_1DC(cpu): # 1DC SET 3,H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1DD(cpu): # 1DD SET 3,L @@ -4962,15 +5019,17 @@ def SET_1DD(cpu): # 1DD SET 3,L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1DE(cpu): # 1DE SET 3,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) | (1 << 3) + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def SET_1DF(cpu): # 1DF SET 3,A @@ -4978,7 +5037,7 @@ def SET_1DF(cpu): # 1DF SET 3,A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1E0(cpu): # 1E0 SET 4,B @@ -4986,7 +5045,7 @@ def SET_1E0(cpu): # 1E0 SET 4,B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1E1(cpu): # 1E1 SET 4,C @@ -4994,7 +5053,7 @@ def SET_1E1(cpu): # 1E1 SET 4,C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1E2(cpu): # 1E2 SET 4,D @@ -5002,7 +5061,7 @@ def SET_1E2(cpu): # 1E2 SET 4,D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1E3(cpu): # 1E3 SET 4,E @@ -5010,7 +5069,7 @@ def SET_1E3(cpu): # 1E3 SET 4,E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1E4(cpu): # 1E4 SET 4,H @@ -5018,7 +5077,7 @@ def SET_1E4(cpu): # 1E4 SET 4,H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1E5(cpu): # 1E5 SET 4,L @@ -5026,15 +5085,17 @@ def SET_1E5(cpu): # 1E5 SET 4,L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1E6(cpu): # 1E6 SET 4,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) | (1 << 4) + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def SET_1E7(cpu): # 1E7 SET 4,A @@ -5042,7 +5103,7 @@ def SET_1E7(cpu): # 1E7 SET 4,A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1E8(cpu): # 1E8 SET 5,B @@ -5050,7 +5111,7 @@ def SET_1E8(cpu): # 1E8 SET 5,B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1E9(cpu): # 1E9 SET 5,C @@ -5058,7 +5119,7 @@ def SET_1E9(cpu): # 1E9 SET 5,C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1EA(cpu): # 1EA SET 5,D @@ -5066,7 +5127,7 @@ def SET_1EA(cpu): # 1EA SET 5,D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1EB(cpu): # 1EB SET 5,E @@ -5074,7 +5135,7 @@ def SET_1EB(cpu): # 1EB SET 5,E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1EC(cpu): # 1EC SET 5,H @@ -5082,7 +5143,7 @@ def SET_1EC(cpu): # 1EC SET 5,H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1ED(cpu): # 1ED SET 5,L @@ -5090,15 +5151,17 @@ def SET_1ED(cpu): # 1ED SET 5,L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1EE(cpu): # 1EE SET 5,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) | (1 << 5) + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def SET_1EF(cpu): # 1EF SET 5,A @@ -5106,7 +5169,7 @@ def SET_1EF(cpu): # 1EF SET 5,A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1F0(cpu): # 1F0 SET 6,B @@ -5114,7 +5177,7 @@ def SET_1F0(cpu): # 1F0 SET 6,B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1F1(cpu): # 1F1 SET 6,C @@ -5122,7 +5185,7 @@ def SET_1F1(cpu): # 1F1 SET 6,C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1F2(cpu): # 1F2 SET 6,D @@ -5130,7 +5193,7 @@ def SET_1F2(cpu): # 1F2 SET 6,D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1F3(cpu): # 1F3 SET 6,E @@ -5138,7 +5201,7 @@ def SET_1F3(cpu): # 1F3 SET 6,E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1F4(cpu): # 1F4 SET 6,H @@ -5146,7 +5209,7 @@ def SET_1F4(cpu): # 1F4 SET 6,H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1F5(cpu): # 1F5 SET 6,L @@ -5154,15 +5217,17 @@ def SET_1F5(cpu): # 1F5 SET 6,L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1F6(cpu): # 1F6 SET 6,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) | (1 << 6) + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def SET_1F7(cpu): # 1F7 SET 6,A @@ -5170,7 +5235,7 @@ def SET_1F7(cpu): # 1F7 SET 6,A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1F8(cpu): # 1F8 SET 7,B @@ -5178,7 +5243,7 @@ def SET_1F8(cpu): # 1F8 SET 7,B cpu.B = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1F9(cpu): # 1F9 SET 7,C @@ -5186,7 +5251,7 @@ def SET_1F9(cpu): # 1F9 SET 7,C cpu.C = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1FA(cpu): # 1FA SET 7,D @@ -5194,7 +5259,7 @@ def SET_1FA(cpu): # 1FA SET 7,D cpu.D = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1FB(cpu): # 1FB SET 7,E @@ -5202,7 +5267,7 @@ def SET_1FB(cpu): # 1FB SET 7,E cpu.E = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1FC(cpu): # 1FC SET 7,H @@ -5210,7 +5275,7 @@ def SET_1FC(cpu): # 1FC SET 7,H cpu.HL = (cpu.HL & 0x00FF) | (t << 8) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1FD(cpu): # 1FD SET 7,L @@ -5218,15 +5283,17 @@ def SET_1FD(cpu): # 1FD SET 7,L cpu.HL = (cpu.HL & 0xFF00) | (t & 0xFF) cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def SET_1FE(cpu): # 1FE SET 7,(HL) + cpu.cycles += 4 t = cpu.mb.getitem(cpu.HL) | (1 << 7) + cpu.cycles += 4 cpu.mb.setitem(cpu.HL, t) cpu.PC += 2 cpu.PC &= 0xFFFF - return 16 + cpu.cycles += 8 def SET_1FF(cpu): # 1FF SET 7,A @@ -5234,7 +5301,7 @@ def SET_1FF(cpu): # 1FF SET 7,A cpu.A = t cpu.PC += 2 cpu.PC &= 0xFFFF - return 8 + cpu.cycles += 8 def no_opcode(cpu): diff --git a/pyboy/core/opcodes_gen.py b/pyboy/core/opcodes_gen.py index 279e94462..ecce26f78 100644 --- a/pyboy/core/opcodes_gen.py +++ b/pyboy/core/opcodes_gen.py @@ -26,6 +26,7 @@ FLAGC, FLAGH, FLAGN, FLAGZ = range(4, 8) def BRK(cpu): + cpu.bail = True cpu.mb.breakpoint_singlestep = 1 cpu.mb.breakpoint_singlestep_latch = 0 # NOTE: We do not increment PC @@ -34,11 +35,14 @@ def BRK(cpu): """ cimports = """ -from . cimport cpu cimport cython from libc.stdint cimport uint8_t, uint16_t, uint32_t from pyboy.logging.logging cimport Logger + +from . cimport cpu + + cdef Logger logger cdef uint16_t FLAGC, FLAGH, FLAGN, FLAGZ @@ -264,7 +268,7 @@ def getcode(self): if not self.branch_op: self.lines.append("cpu.PC += %d" % self.length) self.lines.append("cpu.PC &= 0xFFFF") - self.lines.append("return " + self.cycles[0]) # Choose the 0th cycle count + self.lines.append("cpu.cycles += " + self.cycles[0]) # Choose the 0th cycle count code += "\n\t".join(self.lines) @@ -459,7 +463,8 @@ def HALT(self): # TODO: Implement HALT bug. code.addlines([ "cpu.halted = True", - "return " + self.cycles[0], + "cpu.bail = True", + "cpu.cycles += " + self.cycles[0], ]) return code.getcode() @@ -470,7 +475,10 @@ def CB(self): def EI(self): code = Code(self.name.split()[0], self.opcode, self.name, 0, self.length, self.cycles) - code.addline("cpu.interrupt_master_enable = True") + code.addlines([ + "cpu.interrupt_master_enable = True", + "cpu.bail = (cpu.interrupts_flag_register & 0b11111) & (cpu.interrupts_enabled_register & 0b11111)", + ]) return code.getcode() def DI(self): @@ -552,6 +560,24 @@ def LD(self): code = Code( self.name.split()[0], self.opcode, self.name, left.immediate or right.immediate, self.length, self.cycles ) + + # These opcodes can be observed reading mid-cycle + if self.opcode == 0x36: + code.addline("cpu.cycles += 4") + code.cycles = (str(int(code.cycles[0]) - 4), ) + elif self.opcode == 0xE0: + code.addline("cpu.cycles += 4") + code.cycles = (str(int(code.cycles[0]) - 4), ) + elif self.opcode == 0xEA: + code.addline("cpu.cycles += 8") + code.cycles = (str(int(code.cycles[0]) - 8), ) + elif self.opcode == 0xF0: + code.addline("cpu.cycles += 4") + code.cycles = (str(int(code.cycles[0]) - 4), ) + elif self.opcode == 0xFA: + code.addline("cpu.cycles += 8") + code.cycles = (str(int(code.cycles[0]) - 8), ) + if self.is16bit and left.immediate and left.pointer: code.addline(left.set % ("%s & 0xFF" % right.get)) a, b = left.set.split(",") @@ -657,6 +683,13 @@ def INC(self): self.name.split()[0], self.opcode, self.name, left.immediate or right.immediate, self.length, self.cycles ) code.addlines(self.ALU(left, right, "+")) + + if self.opcode == 0x34: + # HACK: Offset the timing by 4 cycles + # TODO: Probably should be generalized + code.lines.insert(-1, "cpu.cycles += 4") # Inject before read + code.cycles = ("8", ) # 12 - 4 + return code.getcode() def DEC(self): @@ -668,6 +701,13 @@ def DEC(self): self.name.split()[0], self.opcode, self.name, left.immediate or right.immediate, self.length, self.cycles ) code.addlines(self.ALU(left, right, "-")) + + if self.opcode == 0x35: + # HACK: Offset the timing by 4 cycles + # TODO: Probably should be generalized + code.lines.insert(-1, "cpu.cycles += 4") # Inject before write + code.cycles = ("8", ) # 12 - 4 + return code.getcode() def ADC(self): @@ -853,16 +893,16 @@ def JP(self): self.name.split()[0], self.opcode, self.name, right.immediate, self.length, self.cycles, branch_op=True ) if left is None: - code.addlines(["cpu.PC = %s" % ("v" if right.immediate else r_code), "return " + self.cycles[0]]) + code.addlines(["cpu.PC = %s" % ("v" if right.immediate else r_code), "cpu.cycles += " + self.cycles[0]]) else: code.addlines([ "if %s:" % l_code, "\tcpu.PC = %s" % ("v" if right.immediate else r_code), - "\treturn " + self.cycles[0], + "\tcpu.cycles += " + self.cycles[0], "else:", "\tcpu.PC += %s" % self.length, "\tcpu.PC &= 0xFFFF", - "\treturn " + self.cycles[1], + "\tcpu.cycles += " + self.cycles[1], ]) return code.getcode() @@ -892,7 +932,7 @@ def JR(self): code.addlines([ "cpu.PC += %d + " % self.length + inline_signed_int8("v"), "cpu.PC &= 0xFFFF", - "return " + self.cycles[0], + "cpu.cycles += " + self.cycles[0], ]) else: code.addlines([ @@ -900,10 +940,10 @@ def JR(self): "if %s:" % l_code, "\tcpu.PC += " + inline_signed_int8("v"), "\tcpu.PC &= 0xFFFF", - "\treturn " + self.cycles[0], + "\tcpu.cycles += " + self.cycles[0], "else:", "\tcpu.PC &= 0xFFFF", - "\treturn " + self.cycles[1], + "\tcpu.cycles += " + self.cycles[1], ]) return code.getcode() @@ -943,7 +983,7 @@ def CALL(self): "cpu.SP -= 2", "cpu.SP &= 0xFFFF", "cpu.PC = %s" % ("v" if right.immediate else right.get), - "return " + self.cycles[0], + "cpu.cycles += " + self.cycles[0], ]) else: code.addlines([ @@ -953,9 +993,9 @@ def CALL(self): "\tcpu.SP -= 2", "\tcpu.SP &= 0xFFFF", "\tcpu.PC = %s" % ("v" if right.immediate else right.get), - "\treturn " + self.cycles[0], + "\tcpu.cycles += " + self.cycles[0], "else:", - "\treturn " + self.cycles[1], + "\tcpu.cycles += " + self.cycles[1], ]) return code.getcode() @@ -981,7 +1021,7 @@ def RET(self): "cpu.PC |= cpu.mb.getitem(cpu.SP) # Low", "cpu.SP += 2", "cpu.SP &= 0xFFFF", - "return " + self.cycles[0], + "cpu.cycles += " + self.cycles[0], ]) else: code.addlines([ @@ -990,24 +1030,25 @@ def RET(self): "\tcpu.PC |= cpu.mb.getitem(cpu.SP) # Low", "\tcpu.SP += 2", "\tcpu.SP &= 0xFFFF", - "\treturn " + self.cycles[0], + "\tcpu.cycles += " + self.cycles[0], "else:", "\tcpu.PC += %s" % self.length, "\tcpu.PC &= 0xFFFF", - "\treturn " + self.cycles[1], + "\tcpu.cycles += " + self.cycles[1], ]) return code.getcode() def RETI(self): code = Code(self.name.split()[0], self.opcode, self.name, False, self.length, self.cycles, branch_op=True) - code.addline("cpu.interrupt_master_enable = True") code.addlines([ + "cpu.interrupt_master_enable = True", + "cpu.bail = (cpu.interrupts_flag_register & 0b11111) & (cpu.interrupts_enabled_register & 0b11111)", "cpu.PC = cpu.mb.getitem((cpu.SP + 1) & 0xFFFF) << 8 # High", "cpu.PC |= cpu.mb.getitem(cpu.SP) # Low", "cpu.SP += 2", "cpu.SP &= 0xFFFF", - "return " + self.cycles[0], + "cpu.cycles += " + self.cycles[0], ]) return code.getcode() @@ -1030,7 +1071,7 @@ def RST(self): code.addlines([ "cpu.PC = %s" % (right.code), - "return " + self.cycles[0], + "cpu.cycles += " + self.cycles[0], ]) return code.getcode() @@ -1049,6 +1090,14 @@ def rotateleft(self, name, left, throughcarry=False): code.addlines(self.handleflags8bit(left.get, None, None, throughcarry)) code.addline("t &= 0xFF") left.assign = True + + if left.operand == "(HL)": + # HACK: Offset the timing by 4 cycles + # TODO: Probably should be generalized + code.lines.insert(0, "cpu.cycles += 4") # Inject before read + code.addline("cpu.cycles += 4") + code.cycles = ("8", ) # 16 - 4 - 4 + code.addline(left.set % "t") return code @@ -1086,6 +1135,14 @@ def rotateright(self, name, left, throughcarry=False): code.addline("t = (%s >> 1) + ((%s & 1) << 7)" % (left.get, left.get) + " + ((%s & 1) << 8)" % (left.get)) code.addlines(self.handleflags8bit(left.get, None, None, throughcarry)) code.addline("t &= 0xFF") + + if left.operand == "(HL)": + # HACK: Offset the timing by 4 cycles + # TODO: Probably should be generalized + code.lines.insert(0, "cpu.cycles += 4") # Inject before read + code.addline("cpu.cycles += 4") + code.cycles = ("8", ) # 16 - 4 - 4 + code.addline(left.set % "t") return code @@ -1118,6 +1175,14 @@ def SLA(self): code.addline("t = (%s << 1)" % left.get) code.addlines(self.handleflags8bit(left.get, None, None, False)) code.addline("t &= 0xFF") + + if left.operand == "(HL)": + # HACK: Offset the timing by 4 cycles + # TODO: Probably should be generalized + code.lines.insert(0, "cpu.cycles += 4") # Inject before read + code.addline("cpu.cycles += 4") + code.cycles = ("8", ) # 16 - 4 - 4 + code.addline(left.set % "t") return code.getcode() @@ -1131,6 +1196,14 @@ def SRA(self): code.addline("t = ((%s >> 1) | (%s & 0x80)) + ((%s & 1) << 8)" % (left.get, left.get, left.get)) code.addlines(self.handleflags8bit(left.get, None, None, False)) code.addline("t &= 0xFF") + + if left.operand == "(HL)": + # HACK: Offset the timing by 4 cycles + # TODO: Probably should be generalized + code.lines.insert(0, "cpu.cycles += 4") # Inject before read + code.addline("cpu.cycles += 4") + code.cycles = ("8", ) # 16 - 4 - 4 + code.addline(left.set % "t") return code.getcode() @@ -1142,6 +1215,14 @@ def SRL(self): code.addline("t = (%s >> 1) + ((%s & 1) << 8)" % (left.get, left.get)) code.addlines(self.handleflags8bit(left.get, None, None, False)) code.addline("t &= 0xFF") + + if left.operand == "(HL)": + # HACK: Offset the timing by 4 cycles + # TODO: Probably should be generalized + code.lines.insert(0, "cpu.cycles += 4") # Inject before read + code.addline("cpu.cycles += 4") + code.cycles = ("8", ) # 16 - 4 - 4 + code.addline(left.set % "t") return code.getcode() @@ -1152,6 +1233,14 @@ def SWAP(self): code.addline("t = ((%s & 0xF0) >> 4) | ((%s & 0x0F) << 4)" % (left.get, left.get)) code.addlines(self.handleflags8bit(left.get, None, None, False)) code.addline("t &= 0xFF") + + if left.operand == "(HL)": + # HACK: Offset the timing by 4 cycles + # TODO: Probably should be generalized + code.lines.insert(0, "cpu.cycles += 4") # Inject before read + code.addline("cpu.cycles += 4") + code.cycles = ("8", ) # 16 - 4 - 4 + code.addline(left.set % "t") return code.getcode() @@ -1164,6 +1253,14 @@ def BIT(self): left = Literal(r0) right = Operand(r1) code = Code(self.name.split()[0], self.opcode, self.name, False, self.length, self.cycles) + + # FIX: Correct cycle count is 12, not 16! + if right.operand == "(HL)": + # HACK: Offset the timing by 4 cycles + # TODO: Probably should be generalized + code.addline("cpu.cycles += 4") + code.cycles = ("8", ) # 12 - 4 + code.addline("t = %s & (1 << %s)" % (right.get, left.get)) code.addlines(self.handleflags8bit(left.get, right.get, None, False)) @@ -1176,6 +1273,14 @@ def RES(self): code = Code(self.name.split()[0], self.opcode, self.name, False, self.length, self.cycles) code.addline("t = %s & ~(1 << %s)" % (right.get, left.get)) + + if right.operand == "(HL)": + # HACK: Offset the timing by 4 cycles + # TODO: Probably should be generalized + code.lines.insert(0, "cpu.cycles += 4") # Inject before read + code.addline("cpu.cycles += 4") + code.cycles = ("8", ) # 16 - 4 - 4 + code.addline(right.set % "t") return code.getcode() @@ -1185,6 +1290,14 @@ def SET(self): right = Operand(r1) code = Code(self.name.split()[0], self.opcode, self.name, False, self.length, self.cycles) code.addline("t = %s | (1 << %s)" % (right.get, left.get)) + + if right.operand == "(HL)": + # HACK: Offset the timing by 4 cycles + # TODO: Probably should be generalized + code.lines.insert(0, "cpu.cycles += 4") # Inject before read + code.addline("cpu.cycles += 4") + code.cycles = ("8", ) # 16 - 4 - 4 + code.addline(right.set % "t") return code.getcode() diff --git a/pyboy/core/sound.pxd b/pyboy/core/sound.pxd index 322ef25df..7b1afde74 100644 --- a/pyboy/core/sound.pxd +++ b/pyboy/core/sound.pxd @@ -4,7 +4,7 @@ # cimport cython -from libc.stdint cimport uint8_t, uint16_t, uint64_t +from libc.stdint cimport int64_t, uint8_t, uint16_t, uint64_t from pyboy.logging.logging cimport Logger from pyboy.utils cimport IntIOInterface @@ -28,6 +28,8 @@ cdef class Sound: cdef object audiobuffer cdef object audiobuffer_p + cdef uint64_t last_cycles + cdef int64_t _cycles_to_interrupt cdef int clock cdef bint poweron @@ -42,6 +44,7 @@ cdef class Sound: cdef uint8_t get(self, uint8_t) noexcept nogil cdef void set(self, uint8_t, uint8_t) noexcept nogil + cdef void tick(self, int64_t, bint) noexcept nogil @cython.locals(nsamples=int, sample=int, i=int) cdef void sync(self) noexcept with gil # TODO: nogil @cython.locals(queued_time=int, samples_per_frame=int) @@ -91,11 +94,7 @@ cdef class SweepChannel(ToneChannel): cdef bint sweepenable # Internal sweep enable flag cdef int shadow # Shadow copy of period register for ignoring writes to sndper - cdef uint8_t getreg(self, uint8_t) noexcept nogil - cdef void setreg(self, uint8_t, uint8_t) noexcept nogil cdef bint sweep(self, bint) noexcept nogil - cdef void trigger(self) noexcept nogil - cdef void tickframe(self) noexcept nogil cdef class WaveChannel: diff --git a/pyboy/core/sound.py b/pyboy/core/sound.py index b69de626c..cd40b2905 100644 --- a/pyboy/core/sound.py +++ b/pyboy/core/sound.py @@ -59,6 +59,8 @@ def __init__(self, enabled, emulate): self.audiobuffer = array("b", [0] * 4096) # Over 2 frames self.audiobuffer_p = c_void_p(self.audiobuffer.buffer_info()[0]) + self.last_cycles = 0 + self._cycles_to_interrupt = 1 << 16 self.clock = 0 self.poweron = True @@ -150,6 +152,15 @@ def set(self, offset, value): else: raise IndexError(f"Attempted to write register {offset} in sound memory") + def tick(self, _cycles, double_speed): + cycles = _cycles - self.last_cycles + self.last_cycles = _cycles + + if double_speed: + self.clock += cycles // 2 + else: + self.clock += cycles + def sync(self): """Run the audio for the number of clock cycles stored in self.clock""" if not self.emulate: diff --git a/pyboy/core/timer.pxd b/pyboy/core/timer.pxd index 37d75b997..b444294e8 100644 --- a/pyboy/core/timer.pxd +++ b/pyboy/core/timer.pxd @@ -18,12 +18,12 @@ cdef class Timer: cdef uint64_t DIV, TIMA, TMA, TAC cdef uint16_t DIV_counter, TIMA_counter cdef uint64_t[4] dividers + cdef int64_t _cycles_to_interrupt + cdef uint64_t last_cycles cdef void reset(self) noexcept nogil @cython.locals(divider=cython.int) cdef bint tick(self, uint64_t) noexcept nogil - @cython.locals(divider=cython.int, cyclesleft=cython.uint) - cdef int64_t cycles_to_interrupt(self) noexcept nogil cdef void save_state(self, IntIOInterface) noexcept cdef void load_state(self, IntIOInterface, int) noexcept diff --git a/pyboy/core/timer.py b/pyboy/core/timer.py index 0f89226f8..16d5cf2b2 100644 --- a/pyboy/core/timer.py +++ b/pyboy/core/timer.py @@ -25,7 +25,9 @@ def __init__(self): self.TIMA_counter = 0 self.TMA = 0 self.TAC = 0 - self.dividers = [1024, 16, 64, 256] + self.dividers = [10, 4, 6, 8] + self._cycles_to_interrupt = 0 + self.last_cycles = 0 def reset(self): # TODO: Should probably one be DIV=0, but this makes a bunch of mooneye tests pass @@ -33,39 +35,35 @@ def reset(self): self.TIMA_counter = 0 self.DIV = 0 - def tick(self, cycles): + def tick(self, _cycles): + cycles = _cycles - self.last_cycles + if cycles == 0: + return False + self.last_cycles = _cycles + self.DIV_counter += cycles self.DIV += (self.DIV_counter >> 8) # Add overflown bits to DIV self.DIV_counter &= 0xFF # Remove the overflown bits self.DIV &= 0xFF if self.TAC & 0b100 == 0: # Check if timer is not enabled + self._cycles_to_interrupt = 1 << 16 return False self.TIMA_counter += cycles divider = self.dividers[self.TAC & 0b11] - if self.TIMA_counter >= divider: - self.TIMA_counter -= divider # Keeps possible remainder + ret = False + while self.TIMA_counter >= (1 << divider): + self.TIMA_counter -= (1 << divider) # Keeps possible remainder self.TIMA += 1 if self.TIMA > 0xFF: self.TIMA = self.TMA self.TIMA &= 0xFF - return True - - return False - - def cycles_to_interrupt(self): - if self.TAC & 0b100 == 0: # Check if timer is not enabled - # Large enough, that 'calculate_cycles' will choose 'x' - return 1 << 16 - - divider = self.dividers[self.TAC & 0b11] - - cyclesleft = ((0x100 - self.TIMA) * divider) - self.TIMA_counter - - return cyclesleft + ret = True + self._cycles_to_interrupt = ((0x100 - self.TIMA) << divider) - self.TIMA_counter + return ret def save_state(self, f): f.write(self.DIV) @@ -74,6 +72,7 @@ def save_state(self, f): f.write_16bit(self.TIMA_counter) f.write(self.TMA) f.write(self.TAC) + f.write_64bit(self.last_cycles) def load_state(self, f, state_version): self.DIV = f.read() @@ -82,3 +81,5 @@ def load_state(self, f, state_version): self.TIMA_counter = f.read_16bit() self.TMA = f.read() self.TAC = f.read() + if state_version >= 12: + self.last_cycles = f.read_64bit() diff --git a/pyboy/plugins/debug.py b/pyboy/plugins/debug.py index 012bbbca6..25520cad7 100644 --- a/pyboy/plugins/debug.py +++ b/pyboy/plugins/debug.py @@ -205,8 +205,14 @@ def handle_events(self, events): return events def stop(self): - if self.sdl2_event_pump: - sdl2.SDL_Quit() + self.tile1.stop() + self.tile2.stop() + self.tiledata0.stop() + if self.cgb: + self.tiledata1.stop() + self.sprite.stop() + self.spriteview.stop() + self.memory.stop() def enabled(self): if self.pyboy_argv.get("debug"): diff --git a/pyboy/pyboy.pxd b/pyboy/pyboy.pxd index 700647b68..f28edd4f3 100644 --- a/pyboy/pyboy.pxd +++ b/pyboy/pyboy.pxd @@ -43,9 +43,8 @@ cdef class PyBoy: cdef readonly str gamerom cdef readonly bint paused - cdef double avg_pre cdef double avg_tick - cdef double avg_post + cdef double avg_emu cdef readonly list events cdef list queued_input @@ -72,7 +71,7 @@ cdef class PyBoy: @cython.locals(t_start=int64_t, t_pre=int64_t, t_tick=int64_t, t_post=int64_t, nsecs=int64_t) cpdef bint _tick(self, bint) noexcept - @cython.locals(running=bint) + @cython.locals(running=bint, factor=double) cpdef bint tick(self, count=*, render=*) noexcept cpdef void stop(self, save=*) noexcept cpdef int save_state(self, object) except -1 @@ -84,6 +83,7 @@ cdef class PyBoy: cpdef void _unpause(self) noexcept cdef void _update_window_title(self) noexcept cdef void _post_tick(self) noexcept + cdef void _post_handle_events(self) noexcept cdef dict _hooks cdef object symbols_file diff --git a/pyboy/pyboy.py b/pyboy/pyboy.py index 5824fcdc3..4c806a61d 100644 --- a/pyboy/pyboy.py +++ b/pyboy/pyboy.py @@ -160,9 +160,8 @@ def __init__( raise KeyError(f"Unknown keyword argument: {k}") # Performance measures - self.avg_pre = 0 self.avg_tick = 0 - self.avg_post = 0 + self.avg_emu = 0 # Absolute frame count of the emulation self.frame_count = 0 @@ -378,9 +377,7 @@ def _tick(self, render): if self.stopped: return False - t_start = time.perf_counter_ns() self._handle_events(self.events) - t_pre = time.perf_counter_ns() if not self.paused: self.gameshark.tick() self.__rendering(render) @@ -407,18 +404,7 @@ def _tick(self, render): self.mb.breakpoint_singlestep = self.mb.breakpoint_singlestep_latch self.frame_count += 1 - t_tick = time.perf_counter_ns() - self._post_tick() - t_post = time.perf_counter_ns() - - nsecs = t_pre - t_start - self.avg_pre = 0.9 * self.avg_pre + (0.1*nsecs/1_000_000_000) - - nsecs = t_tick - t_pre - self.avg_tick = 0.9 * self.avg_tick + (0.1*nsecs/1_000_000_000) - - nsecs = t_post - t_tick - self.avg_post = 0.9 * self.avg_post + (0.1*nsecs/1_000_000_000) + self._post_handle_events() return not self.quitting @@ -467,11 +453,22 @@ def tick(self, count=1, render=True): False if emulation has ended otherwise True """ + _count = count running = False + t_start = time.perf_counter_ns() while count != 0: _render = render and count == 1 # Only render on last tick to improve performance running = self._tick(_render) count -= 1 + t_tick = time.perf_counter_ns() + self._post_tick() + t_post = time.perf_counter_ns() + + if _count > 0: + nsecs = t_tick - t_start + self.avg_tick = 0.9 * (self.avg_tick / _count) + (0.1*nsecs/1_000_000_000) + nsecs = t_post - t_start + self.avg_emu = 0.9 * (self.avg_emu / _count) + (0.1*nsecs/1_000_000_000) return running def _handle_events(self, events): @@ -538,6 +535,7 @@ def _post_tick(self): self._plugin_manager.post_tick() self._plugin_manager.frame_limiter(self.target_emulationspeed) + def _post_handle_events(self): # Prepare an empty list, as the API might be used to send in events between ticks self.events = [] while self.queued_input and self.frame_count == self.queued_input[0][0]: @@ -545,9 +543,8 @@ def _post_tick(self): self.events.append(WindowEvent(_event)) def _update_window_title(self): - avg_emu = self.avg_pre + self.avg_tick + self.avg_post - self.window_title = f"CPU/frame: {(self.avg_pre + self.avg_tick) / SPF * 100:0.2f}%" - self.window_title += f' Emulation: x{(round(SPF / avg_emu) if avg_emu > 0 else "INF")}' + self.window_title = f"CPU/frame: {(self.avg_tick) / SPF * 100:0.2f}%" + self.window_title += f' Emulation: x{(round(SPF / self.avg_emu) if self.avg_emu > 0 else "INF")}' if self.paused: self.window_title += "[PAUSED]" self.window_title += self._plugin_manager.window_title() diff --git a/pyboy/utils.py b/pyboy/utils.py index 8dee8a1bb..168844edc 100644 --- a/pyboy/utils.py +++ b/pyboy/utils.py @@ -5,7 +5,7 @@ __all__ = ["WindowEvent", "dec_to_bcd", "bcd_to_dec"] -STATE_VERSION = 11 +STATE_VERSION = 12 ############################################################## # Buffer classes diff --git a/tests/test_acid_cgb.py b/tests/test_acid_cgb.py index 41f21c1c8..1a5e65db7 100644 --- a/tests/test_acid_cgb.py +++ b/tests/test_acid_cgb.py @@ -29,7 +29,7 @@ def test_cgb_acid(cgb_acid_file): # Converting to RGB as ImageChops.difference cannot handle Alpha: https://github.com/python-pillow/Pillow/issues/4849 old_image = PIL.Image.open(png_path).convert("RGB") diff = PIL.ImageChops.difference(image.convert("RGB"), old_image) - if diff.getbbox() and not os.environ.get("TEST_CI"): + if diff.getbbox() and os.environ.get("TEST_VERBOSE_IMAGES"): image.show() old_image.show() diff.show() diff --git a/tests/test_acid_dmg.py b/tests/test_acid_dmg.py index adf942af1..08694a0a9 100644 --- a/tests/test_acid_dmg.py +++ b/tests/test_acid_dmg.py @@ -30,7 +30,7 @@ def test_dmg_acid(cgb, dmg_acid_file): # Converting to RGB as ImageChops.difference cannot handle Alpha: https://github.com/python-pillow/Pillow/issues/4849 old_image = PIL.Image.open(png_path).convert("RGB") diff = PIL.ImageChops.difference(image.convert("RGB"), old_image) - if diff.getbbox() and not os.environ.get("TEST_CI"): + if diff.getbbox() and os.environ.get("TEST_VERBOSE_IMAGES"): image.show() old_image.show() diff.show() diff --git a/tests/test_basics.py b/tests/test_basics.py index 751f4ad85..88b1c862a 100644 --- a/tests/test_basics.py +++ b/tests/test_basics.py @@ -47,6 +47,12 @@ def test_log_level_critical(default_rom, capsys): assert captured.out == "" +def test_tick_zero(default_rom): + pyboy = PyBoy(default_rom, window="null") + # Not permitted, but shouldn't crash the emulator either + pyboy.tick(0) + + def test_register_file(default_rom): pyboy = PyBoy(default_rom, window="null") pyboy.set_emulation_speed(0) @@ -284,7 +290,7 @@ def test_all_modes(cgb, _bootrom, frames, rom, any_rom_cgb, boot_cgb_rom): old_image = PIL.Image.open(png_buf).convert("RGB") diff = PIL.ImageChops.difference(image.convert("RGB"), old_image) - if diff.getbbox() and not os.environ.get("TEST_CI"): + if diff.getbbox() and os.environ.get("TEST_VERBOSE_IMAGES"): image.show() old_image.show() diff.show() diff --git a/tests/test_blargg.py b/tests/test_blargg.py index eac9731a7..420a93ce9 100644 --- a/tests/test_blargg.py +++ b/tests/test_blargg.py @@ -20,7 +20,7 @@ blargg_json = "tests/test_results/blargg.json" -def run_rom(rom): +def run_rom(rom, max_frames): pyboy = PyBoy(str(rom), window="null", cgb="cgb" in rom, sound_emulated=True) pyboy.set_emulation_speed(0) t = time.time() @@ -31,7 +31,7 @@ def run_rom(rom): result += b t = time.time() - if pyboy._is_cpu_stuck(): + if pyboy._is_cpu_stuck() or pyboy.frame_count > max_frames: break pyboy.tick(10, False) @@ -51,69 +51,69 @@ def run_rom(rom): @pytest.mark.parametrize( - "test_rom", [ - "cgb_sound/cgb_sound.gb", - "cgb_sound/rom_singles/01-registers.gb", - "cgb_sound/rom_singles/02-len ctr.gb", - "cgb_sound/rom_singles/03-trigger.gb", - "cgb_sound/rom_singles/04-sweep.gb", - "cgb_sound/rom_singles/05-sweep details.gb", - "cgb_sound/rom_singles/06-overflow on trigger.gb", - "cgb_sound/rom_singles/07-len sweep period sync.gb", - "cgb_sound/rom_singles/08-len ctr during power.gb", - "cgb_sound/rom_singles/09-wave read while on.gb", - "cgb_sound/rom_singles/10-wave trigger while on.gb", - "cgb_sound/rom_singles/11-regs after power.gb", - "cgb_sound/rom_singles/12-wave.gb", - "cpu_instrs/cpu_instrs.gb", - "cpu_instrs/individual/01-special.gb", - "cpu_instrs/individual/02-interrupts.gb", - "cpu_instrs/individual/03-op sp,hl.gb", - "cpu_instrs/individual/04-op r,imm.gb", - "cpu_instrs/individual/05-op rp.gb", - "cpu_instrs/individual/06-ld r,r.gb", - "cpu_instrs/individual/07-jr,jp,call,ret,rst.gb", - "cpu_instrs/individual/08-misc instrs.gb", - "cpu_instrs/individual/09-op r,r.gb", - "cpu_instrs/individual/10-bit ops.gb", - "cpu_instrs/individual/11-op a,(hl).gb", - "dmg_sound/dmg_sound.gb", - "dmg_sound/rom_singles/01-registers.gb", - "dmg_sound/rom_singles/02-len ctr.gb", - "dmg_sound/rom_singles/03-trigger.gb", - "dmg_sound/rom_singles/04-sweep.gb", - "dmg_sound/rom_singles/05-sweep details.gb", - "dmg_sound/rom_singles/06-overflow on trigger.gb", - "dmg_sound/rom_singles/07-len sweep period sync.gb", - "dmg_sound/rom_singles/08-len ctr during power.gb", - "dmg_sound/rom_singles/09-wave read while on.gb", - "dmg_sound/rom_singles/10-wave trigger while on.gb", - "dmg_sound/rom_singles/11-regs after power.gb", - "dmg_sound/rom_singles/12-wave write while on.gb", - "instr_timing/instr_timing.gb", - "interrupt_time/interrupt_time.gb", - "mem_timing/individual/01-read_timing.gb", - "mem_timing/individual/02-write_timing.gb", - "mem_timing/individual/03-modify_timing.gb", - "mem_timing/mem_timing.gb", - "mem_timing-2/mem_timing.gb", - "mem_timing-2/rom_singles/01-read_timing.gb", - "mem_timing-2/rom_singles/02-write_timing.gb", - "mem_timing-2/rom_singles/03-modify_timing.gb", - "oam_bug/oam_bug.gb", - "oam_bug/rom_singles/1-lcd_sync.gb", - "oam_bug/rom_singles/2-causes.gb", - "oam_bug/rom_singles/3-non_causes.gb", - "oam_bug/rom_singles/4-scanline_timing.gb", - "oam_bug/rom_singles/5-timing_bug.gb", - "oam_bug/rom_singles/6-timing_no_bug.gb", - "oam_bug/rom_singles/7-timing_effect.gb", - "oam_bug/rom_singles/8-instr_effect.gb", + "test_rom, max_frames", [ + ("cgb_sound/cgb_sound.gb", 4_000), + ("cgb_sound/rom_singles/01-registers.gb", 700), + ("cgb_sound/rom_singles/02-len ctr.gb", 700), + ("cgb_sound/rom_singles/03-trigger.gb", 700), + ("cgb_sound/rom_singles/04-sweep.gb", 700), + ("cgb_sound/rom_singles/05-sweep details.gb", 700), + ("cgb_sound/rom_singles/06-overflow on trigger.gb", 700), + ("cgb_sound/rom_singles/07-len sweep period sync.gb", 700), + ("cgb_sound/rom_singles/08-len ctr during power.gb", 700), + ("cgb_sound/rom_singles/09-wave read while on.gb", 700), + ("cgb_sound/rom_singles/10-wave trigger while on.gb", 700), + ("cgb_sound/rom_singles/11-regs after power.gb", 700), + ("cgb_sound/rom_singles/12-wave.gb", 700), + ("cpu_instrs/cpu_instrs.gb", 4_000), + ("cpu_instrs/individual/01-special.gb", 700), + ("cpu_instrs/individual/02-interrupts.gb", 700), + ("cpu_instrs/individual/03-op sp,hl.gb", 700), + ("cpu_instrs/individual/04-op r,imm.gb", 700), + ("cpu_instrs/individual/05-op rp.gb", 700), + ("cpu_instrs/individual/06-ld r,r.gb", 700), + ("cpu_instrs/individual/07-jr,jp,call,ret,rst.gb", 700), + ("cpu_instrs/individual/08-misc instrs.gb", 700), + ("cpu_instrs/individual/09-op r,r.gb", 700), + ("cpu_instrs/individual/10-bit ops.gb", 2_000), + ("cpu_instrs/individual/11-op a,(hl).gb", 2_000), + ("dmg_sound/dmg_sound.gb", 700), + ("dmg_sound/rom_singles/01-registers.gb", 700), + ("dmg_sound/rom_singles/02-len ctr.gb", 700), + ("dmg_sound/rom_singles/03-trigger.gb", 700), + ("dmg_sound/rom_singles/04-sweep.gb", 700), + ("dmg_sound/rom_singles/05-sweep details.gb", 700), + ("dmg_sound/rom_singles/06-overflow on trigger.gb", 700), + ("dmg_sound/rom_singles/07-len sweep period sync.gb", 700), + ("dmg_sound/rom_singles/08-len ctr during power.gb", 700), + ("dmg_sound/rom_singles/09-wave read while on.gb", 700), + ("dmg_sound/rom_singles/10-wave trigger while on.gb", 700), + ("dmg_sound/rom_singles/11-regs after power.gb", 700), + ("dmg_sound/rom_singles/12-wave write while on.gb", 700), + ("instr_timing/instr_timing.gb", 2_000), + ("interrupt_time/interrupt_time.gb", 700), + ("mem_timing/individual/01-read_timing.gb", 700), + ("mem_timing/individual/02-write_timing.gb", 700), + ("mem_timing/individual/03-modify_timing.gb", 700), + ("mem_timing/mem_timing.gb", 700), + ("mem_timing-2/mem_timing.gb", 700), + ("mem_timing-2/rom_singles/01-read_timing.gb", 700), + ("mem_timing-2/rom_singles/02-write_timing.gb", 700), + ("mem_timing-2/rom_singles/03-modify_timing.gb", 700), + ("oam_bug/oam_bug.gb", 2_000), + ("oam_bug/rom_singles/1-lcd_sync.gb", 700), + ("oam_bug/rom_singles/2-causes.gb", 700), + ("oam_bug/rom_singles/3-non_causes.gb", 700), + ("oam_bug/rom_singles/4-scanline_timing.gb", 700), + ("oam_bug/rom_singles/5-timing_bug.gb", 700), + ("oam_bug/rom_singles/6-timing_no_bug.gb", 700), + ("oam_bug/rom_singles/7-timing_effect.gb", 700), + ("oam_bug/rom_singles/8-instr_effect.gb", 700), ] ) -def test_blarggs(test_rom, blargg_dir): +def test_blarggs(test_rom, max_frames, blargg_dir): rom = str(blargg_dir / Path(test_rom)) - result = run_rom(rom) + result = run_rom(rom, max_frames) if os.path.isfile(blargg_json): with open(blargg_json, "r") as f: diff --git a/tests/test_breakpoints.py b/tests/test_breakpoints.py index 10e75b121..52f2512fc 100644 --- a/tests/test_breakpoints.py +++ b/tests/test_breakpoints.py @@ -254,7 +254,7 @@ def test_data_hooking_failure(default_rom): image1 = pyboy1.screen.image.convert("RGB") image2 = pyboy2.screen.image.convert("RGB") diff = PIL.ImageChops.difference(image1, image2) - if not diff.getbbox() and not os.environ.get("TEST_CI"): + if not diff.getbbox() and os.environ.get("TEST_VERBOSE_IMAGES"): image1.show() image2.show() diff.show() diff --git a/tests/test_game_wrapper_pokemon_pinball.py b/tests/test_game_wrapper_pokemon_pinball.py index bc693f647..c5f142111 100644 --- a/tests/test_game_wrapper_pokemon_pinball.py +++ b/tests/test_game_wrapper_pokemon_pinball.py @@ -67,37 +67,37 @@ def test_pokemon_catch_mode(pokemon_pinball_rom): pokemon_pinball.start_game(stage=Stage.RED_BOTTOM, timer_div=0x00) pyboy.button_press("a") pyboy.button_press("left") - pyboy.tick(50) + pyboy.tick(50, False) pokemon_pinball.start_catch_mode() - pyboy.tick(270) + pyboy.tick(270, False) pyboy.button_release("left") pyboy.button_release("a") pyboy.button("select") - pyboy.tick(20) + pyboy.tick(20, False) pyboy.button_press("left") pyboy.button_press("a") - pyboy.tick(500) + pyboy.tick(500, False) pyboy.button_release("left") - pyboy.tick(21) + pyboy.tick(21, False) pyboy.button_press("left") - pyboy.tick(100) + pyboy.tick(100, False) pyboy.button_release("a") - pyboy.tick(31) + pyboy.tick(31, False) pyboy.button_press("a") - pyboy.tick(200) + pyboy.tick(200, False) pyboy.button_release("left") - pyboy.tick(31) + pyboy.tick(31, False) pyboy.button_press("left") - pyboy.tick(200) + pyboy.tick(200, False) pyboy.button_release("left") - pyboy.tick(31) + pyboy.tick(31, False) pyboy.button_press("left") - pyboy.tick(400) + pyboy.tick(400, False) # NOTE: This sequence broke because of changed instruction timings - assert pokemon_pinball.score == 15635100 - assert pokemon_pinball.has_pokemon(Pokemon.BULBASAUR) - assert pokemon_pinball.has_pokemon(Pokemon.CHARMANDER) == False - assert pokemon_pinball.get_unique_pokemon_caught() == 1 + assert pokemon_pinball.score == 9030100 + assert not pokemon_pinball.has_pokemon(Pokemon.BULBASAUR) + assert not pokemon_pinball.has_pokemon(Pokemon.CHARMANDER) + assert pokemon_pinball.get_unique_pokemon_caught() == 0 pyboy.stop(False) diff --git a/tests/test_magen.py b/tests/test_magen.py index e3999bd9f..cee03f386 100644 --- a/tests/test_magen.py +++ b/tests/test_magen.py @@ -29,7 +29,7 @@ def test_magen_test(magen_test_file): # Converting to RGB as ImageChops.difference cannot handle Alpha: https://github.com/python-pillow/Pillow/issues/4849 old_image = PIL.Image.open(png_path).convert("RGB") diff = PIL.ImageChops.difference(image.convert("RGB"), old_image) - if diff.getbbox() and not os.environ.get("TEST_CI"): + if diff.getbbox() and os.environ.get("TEST_VERBOSE_IMAGES"): image.show() old_image.show() diff.show() diff --git a/tests/test_mooneye.py b/tests/test_mooneye.py index c5bf9b705..a70655181 100644 --- a/tests/test_mooneye.py +++ b/tests/test_mooneye.py @@ -185,7 +185,7 @@ def test_mooneye(clean, rom, mooneye_dir, default_rom): else: diff = PIL.ImageChops.difference(image.convert("RGB"), old_image) - if diff.getbbox() and not os.environ.get("TEST_CI"): + if diff.getbbox() and os.environ.get("TEST_VERBOSE_IMAGES"): image.show() old_image.show() diff.show() diff --git a/tests/test_replay.py b/tests/test_replay.py index d855def23..5ccebe3e6 100644 --- a/tests/test_replay.py +++ b/tests/test_replay.py @@ -31,7 +31,7 @@ def verify_screen_image_np(pyboy, saved_array): match = np.all(np.frombuffer(saved_array, dtype=np.uint8).reshape(144, 160, 3) == pyboy.screen.ndarray) - if not match and not os.environ.get("TEST_CI"): + if not match and os.environ.get("TEST_VERBOSE_IMAGES"): from PIL import Image original = Image.frombytes("RGB", (160, 144), np.frombuffer(saved_array, dtype=np.uint8).reshape(144, 160, 3)) original.show() diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_align.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_align.gb.png index e6601e48a..e1323bb00 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_align.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_align.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_align_cpu.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_align_cpu.gb.png index 82a17ed6d..10551d821 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_align_cpu.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_align_cpu.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_delay.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_delay.gb.png index 6b03ae7a0..754f818fb 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_delay.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_delay.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_duty.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_duty.gb.png index 66d4896a2..254772b1a 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_duty.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_duty.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_duty_delay.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_duty_delay.gb.png index b9f7a35f2..46c209328 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_duty_delay.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_duty_delay.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_extra_length_clocking-cgb0B.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_extra_length_clocking-cgb0B.gb.png index 4770cfb19..9b6c97edd 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_extra_length_clocking-cgb0B.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_extra_length_clocking-cgb0B.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_freq_change.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_freq_change.gb.png index 897eb9893..abd3dfdae 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_freq_change.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_freq_change.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_freq_change_timing-A.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_freq_change_timing-A.gb.png index cc7ba7e25..19b1c2fa6 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_freq_change_timing-A.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_freq_change_timing-A.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_freq_change_timing-cgb0BC.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_freq_change_timing-cgb0BC.gb.png index cc7ba7e25..19b1c2fa6 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_freq_change_timing-cgb0BC.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_freq_change_timing-cgb0BC.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_freq_change_timing-cgbDE.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_freq_change_timing-cgbDE.gb.png index 087098910..4f7355e7b 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_freq_change_timing-cgbDE.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_freq_change_timing-cgbDE.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_nrx2_glitch.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_nrx2_glitch.gb.png index 9fcc8d1fe..6689f17eb 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_nrx2_glitch.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_nrx2_glitch.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_nrx2_speed_change.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_nrx2_speed_change.gb.png index 955eced02..62cddba8d 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_nrx2_speed_change.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_nrx2_speed_change.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_restart.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_restart.gb.png index 8999fc17c..0c220dc53 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_restart.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_restart.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_restart_nrx2_glitch.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_restart_nrx2_glitch.gb.png index 12fcb0e2f..a5f936def 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_restart_nrx2_glitch.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_restart_nrx2_glitch.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_stop_div.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_stop_div.gb.png index dc54c3cd6..31a526375 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_stop_div.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_stop_div.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_stop_restart.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_stop_restart.gb.png index 005fdf1f3..c0bcf5904 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_stop_restart.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_stop_restart.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_sweep.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_sweep.gb.png index 0c933ecb3..8e38dea72 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_sweep.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_sweep.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_sweep_restart.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_sweep_restart.gb.png index f28a3f197..e51dc2d4f 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_sweep_restart.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_sweep_restart.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_sweep_restart_2.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_sweep_restart_2.gb.png index 3b7ee8746..1980e20ae 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_sweep_restart_2.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_sweep_restart_2.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_volume.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_volume.gb.png index e662d1623..5628be2bb 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_volume.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_volume.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_1/channel_1_volume_div.gb.png b/tests/test_results/SameSuite/apu/channel_1/channel_1_volume_div.gb.png index 290698e66..1f34b7ecd 100644 Binary files a/tests/test_results/SameSuite/apu/channel_1/channel_1_volume_div.gb.png and b/tests/test_results/SameSuite/apu/channel_1/channel_1_volume_div.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_2/channel_2_align.gb.png b/tests/test_results/SameSuite/apu/channel_2/channel_2_align.gb.png index e6601e48a..e1323bb00 100644 Binary files a/tests/test_results/SameSuite/apu/channel_2/channel_2_align.gb.png and b/tests/test_results/SameSuite/apu/channel_2/channel_2_align.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_2/channel_2_align_cpu.gb.png b/tests/test_results/SameSuite/apu/channel_2/channel_2_align_cpu.gb.png index 82a17ed6d..10551d821 100644 Binary files a/tests/test_results/SameSuite/apu/channel_2/channel_2_align_cpu.gb.png and b/tests/test_results/SameSuite/apu/channel_2/channel_2_align_cpu.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_2/channel_2_delay.gb.png b/tests/test_results/SameSuite/apu/channel_2/channel_2_delay.gb.png index 6b03ae7a0..754f818fb 100644 Binary files a/tests/test_results/SameSuite/apu/channel_2/channel_2_delay.gb.png and b/tests/test_results/SameSuite/apu/channel_2/channel_2_delay.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_2/channel_2_duty.gb.png b/tests/test_results/SameSuite/apu/channel_2/channel_2_duty.gb.png index 66d4896a2..254772b1a 100644 Binary files a/tests/test_results/SameSuite/apu/channel_2/channel_2_duty.gb.png and b/tests/test_results/SameSuite/apu/channel_2/channel_2_duty.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_2/channel_2_duty_delay.gb.png b/tests/test_results/SameSuite/apu/channel_2/channel_2_duty_delay.gb.png index b9f7a35f2..46c209328 100644 Binary files a/tests/test_results/SameSuite/apu/channel_2/channel_2_duty_delay.gb.png and b/tests/test_results/SameSuite/apu/channel_2/channel_2_duty_delay.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_2/channel_2_extra_length_clocking-cgb0B.gb.png b/tests/test_results/SameSuite/apu/channel_2/channel_2_extra_length_clocking-cgb0B.gb.png index d6e02f5e8..276a0db09 100644 Binary files a/tests/test_results/SameSuite/apu/channel_2/channel_2_extra_length_clocking-cgb0B.gb.png and b/tests/test_results/SameSuite/apu/channel_2/channel_2_extra_length_clocking-cgb0B.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_2/channel_2_freq_change.gb.png b/tests/test_results/SameSuite/apu/channel_2/channel_2_freq_change.gb.png index 897eb9893..abd3dfdae 100644 Binary files a/tests/test_results/SameSuite/apu/channel_2/channel_2_freq_change.gb.png and b/tests/test_results/SameSuite/apu/channel_2/channel_2_freq_change.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_2/channel_2_nrx2_glitch.gb.png b/tests/test_results/SameSuite/apu/channel_2/channel_2_nrx2_glitch.gb.png index 9fcc8d1fe..6689f17eb 100644 Binary files a/tests/test_results/SameSuite/apu/channel_2/channel_2_nrx2_glitch.gb.png and b/tests/test_results/SameSuite/apu/channel_2/channel_2_nrx2_glitch.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_2/channel_2_nrx2_speed_change.gb.png b/tests/test_results/SameSuite/apu/channel_2/channel_2_nrx2_speed_change.gb.png index 955eced02..62cddba8d 100644 Binary files a/tests/test_results/SameSuite/apu/channel_2/channel_2_nrx2_speed_change.gb.png and b/tests/test_results/SameSuite/apu/channel_2/channel_2_nrx2_speed_change.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_2/channel_2_restart.gb.png b/tests/test_results/SameSuite/apu/channel_2/channel_2_restart.gb.png index 8999fc17c..0c220dc53 100644 Binary files a/tests/test_results/SameSuite/apu/channel_2/channel_2_restart.gb.png and b/tests/test_results/SameSuite/apu/channel_2/channel_2_restart.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_2/channel_2_restart_nrx2_glitch.gb.png b/tests/test_results/SameSuite/apu/channel_2/channel_2_restart_nrx2_glitch.gb.png index 12fcb0e2f..a5f936def 100644 Binary files a/tests/test_results/SameSuite/apu/channel_2/channel_2_restart_nrx2_glitch.gb.png and b/tests/test_results/SameSuite/apu/channel_2/channel_2_restart_nrx2_glitch.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_2/channel_2_stop_div.gb.png b/tests/test_results/SameSuite/apu/channel_2/channel_2_stop_div.gb.png index 1eb47c878..ce09220cd 100644 Binary files a/tests/test_results/SameSuite/apu/channel_2/channel_2_stop_div.gb.png and b/tests/test_results/SameSuite/apu/channel_2/channel_2_stop_div.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_2/channel_2_stop_restart.gb.png b/tests/test_results/SameSuite/apu/channel_2/channel_2_stop_restart.gb.png index 005fdf1f3..c0bcf5904 100644 Binary files a/tests/test_results/SameSuite/apu/channel_2/channel_2_stop_restart.gb.png and b/tests/test_results/SameSuite/apu/channel_2/channel_2_stop_restart.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_2/channel_2_volume.gb.png b/tests/test_results/SameSuite/apu/channel_2/channel_2_volume.gb.png index 03275e104..922d05220 100644 Binary files a/tests/test_results/SameSuite/apu/channel_2/channel_2_volume.gb.png and b/tests/test_results/SameSuite/apu/channel_2/channel_2_volume.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_2/channel_2_volume_div.gb.png b/tests/test_results/SameSuite/apu/channel_2/channel_2_volume_div.gb.png index 487a18a96..c1ff595cc 100644 Binary files a/tests/test_results/SameSuite/apu/channel_2/channel_2_volume_div.gb.png and b/tests/test_results/SameSuite/apu/channel_2/channel_2_volume_div.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_3/channel_3_and_glitch.gb.png b/tests/test_results/SameSuite/apu/channel_3/channel_3_and_glitch.gb.png index 6dac40500..f6bdce679 100644 Binary files a/tests/test_results/SameSuite/apu/channel_3/channel_3_and_glitch.gb.png and b/tests/test_results/SameSuite/apu/channel_3/channel_3_and_glitch.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_3/channel_3_delay.gb.png b/tests/test_results/SameSuite/apu/channel_3/channel_3_delay.gb.png index 3d42c450c..3f8ee77d5 100644 Binary files a/tests/test_results/SameSuite/apu/channel_3/channel_3_delay.gb.png and b/tests/test_results/SameSuite/apu/channel_3/channel_3_delay.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_3/channel_3_extra_length_clocking-cgb0.gb.png b/tests/test_results/SameSuite/apu/channel_3/channel_3_extra_length_clocking-cgb0.gb.png index a486d6c0d..284dd155d 100644 Binary files a/tests/test_results/SameSuite/apu/channel_3/channel_3_extra_length_clocking-cgb0.gb.png and b/tests/test_results/SameSuite/apu/channel_3/channel_3_extra_length_clocking-cgb0.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_3/channel_3_extra_length_clocking-cgbB.gb.png b/tests/test_results/SameSuite/apu/channel_3/channel_3_extra_length_clocking-cgbB.gb.png index 6f909c62f..1db7e34b7 100644 Binary files a/tests/test_results/SameSuite/apu/channel_3/channel_3_extra_length_clocking-cgbB.gb.png and b/tests/test_results/SameSuite/apu/channel_3/channel_3_extra_length_clocking-cgbB.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_3/channel_3_first_sample.gb.png b/tests/test_results/SameSuite/apu/channel_3/channel_3_first_sample.gb.png index f2ca901cf..4e03aa574 100644 Binary files a/tests/test_results/SameSuite/apu/channel_3/channel_3_first_sample.gb.png and b/tests/test_results/SameSuite/apu/channel_3/channel_3_first_sample.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_3/channel_3_freq_change_delay.gb.png b/tests/test_results/SameSuite/apu/channel_3/channel_3_freq_change_delay.gb.png index 6f0152dd6..f0b6a9560 100644 Binary files a/tests/test_results/SameSuite/apu/channel_3/channel_3_freq_change_delay.gb.png and b/tests/test_results/SameSuite/apu/channel_3/channel_3_freq_change_delay.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_3/channel_3_restart_delay.gb.png b/tests/test_results/SameSuite/apu/channel_3/channel_3_restart_delay.gb.png index 259d9f5ae..c4ee58a79 100644 Binary files a/tests/test_results/SameSuite/apu/channel_3/channel_3_restart_delay.gb.png and b/tests/test_results/SameSuite/apu/channel_3/channel_3_restart_delay.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_3/channel_3_restart_during_delay.gb.png b/tests/test_results/SameSuite/apu/channel_3/channel_3_restart_during_delay.gb.png index 9a1241f81..02ebf2603 100644 Binary files a/tests/test_results/SameSuite/apu/channel_3/channel_3_restart_during_delay.gb.png and b/tests/test_results/SameSuite/apu/channel_3/channel_3_restart_during_delay.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_3/channel_3_restart_stop_delay.gb.png b/tests/test_results/SameSuite/apu/channel_3/channel_3_restart_stop_delay.gb.png index 3eeb53263..87ed49354 100644 Binary files a/tests/test_results/SameSuite/apu/channel_3/channel_3_restart_stop_delay.gb.png and b/tests/test_results/SameSuite/apu/channel_3/channel_3_restart_stop_delay.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_3/channel_3_shift_delay.gb.png b/tests/test_results/SameSuite/apu/channel_3/channel_3_shift_delay.gb.png index 259d9f5ae..c4ee58a79 100644 Binary files a/tests/test_results/SameSuite/apu/channel_3/channel_3_shift_delay.gb.png and b/tests/test_results/SameSuite/apu/channel_3/channel_3_shift_delay.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_3/channel_3_shift_skip_delay.gb.png b/tests/test_results/SameSuite/apu/channel_3/channel_3_shift_skip_delay.gb.png index f2ca901cf..4e03aa574 100644 Binary files a/tests/test_results/SameSuite/apu/channel_3/channel_3_shift_skip_delay.gb.png and b/tests/test_results/SameSuite/apu/channel_3/channel_3_shift_skip_delay.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_3/channel_3_stop_delay.gb.png b/tests/test_results/SameSuite/apu/channel_3/channel_3_stop_delay.gb.png index 2de250673..d315c9946 100644 Binary files a/tests/test_results/SameSuite/apu/channel_3/channel_3_stop_delay.gb.png and b/tests/test_results/SameSuite/apu/channel_3/channel_3_stop_delay.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_3/channel_3_stop_div.gb.png b/tests/test_results/SameSuite/apu/channel_3/channel_3_stop_div.gb.png index 3353d8224..4a1afadd8 100644 Binary files a/tests/test_results/SameSuite/apu/channel_3/channel_3_stop_div.gb.png and b/tests/test_results/SameSuite/apu/channel_3/channel_3_stop_div.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_3/channel_3_wave_ram_dac_on_rw.gb.png b/tests/test_results/SameSuite/apu/channel_3/channel_3_wave_ram_dac_on_rw.gb.png index a84ad4391..1263c3b37 100644 Binary files a/tests/test_results/SameSuite/apu/channel_3/channel_3_wave_ram_dac_on_rw.gb.png and b/tests/test_results/SameSuite/apu/channel_3/channel_3_wave_ram_dac_on_rw.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_3/channel_3_wave_ram_locked_write.gb.png b/tests/test_results/SameSuite/apu/channel_3/channel_3_wave_ram_locked_write.gb.png index 7310a68b8..1c8338256 100644 Binary files a/tests/test_results/SameSuite/apu/channel_3/channel_3_wave_ram_locked_write.gb.png and b/tests/test_results/SameSuite/apu/channel_3/channel_3_wave_ram_locked_write.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_3/channel_3_wave_ram_sync.gb.png b/tests/test_results/SameSuite/apu/channel_3/channel_3_wave_ram_sync.gb.png index cfbb95cf6..0e22fcadb 100644 Binary files a/tests/test_results/SameSuite/apu/channel_3/channel_3_wave_ram_sync.gb.png and b/tests/test_results/SameSuite/apu/channel_3/channel_3_wave_ram_sync.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_4/channel_4_align.gb.png b/tests/test_results/SameSuite/apu/channel_4/channel_4_align.gb.png index 7823f8d1c..c841b25c1 100644 Binary files a/tests/test_results/SameSuite/apu/channel_4/channel_4_align.gb.png and b/tests/test_results/SameSuite/apu/channel_4/channel_4_align.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_4/channel_4_delay.gb.png b/tests/test_results/SameSuite/apu/channel_4/channel_4_delay.gb.png index e2236b163..62eb51311 100644 Binary files a/tests/test_results/SameSuite/apu/channel_4/channel_4_delay.gb.png and b/tests/test_results/SameSuite/apu/channel_4/channel_4_delay.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_4/channel_4_equivalent_frequencies.gb.png b/tests/test_results/SameSuite/apu/channel_4/channel_4_equivalent_frequencies.gb.png index 6d032ba3f..ddd9971ee 100644 Binary files a/tests/test_results/SameSuite/apu/channel_4/channel_4_equivalent_frequencies.gb.png and b/tests/test_results/SameSuite/apu/channel_4/channel_4_equivalent_frequencies.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_4/channel_4_extra_length_clocking-cgb0B.gb.png b/tests/test_results/SameSuite/apu/channel_4/channel_4_extra_length_clocking-cgb0B.gb.png index afdd0f77c..adf5da7d3 100644 Binary files a/tests/test_results/SameSuite/apu/channel_4/channel_4_extra_length_clocking-cgb0B.gb.png and b/tests/test_results/SameSuite/apu/channel_4/channel_4_extra_length_clocking-cgb0B.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_4/channel_4_freq_change.gb.png b/tests/test_results/SameSuite/apu/channel_4/channel_4_freq_change.gb.png index aa9b9169a..3c7b1be2f 100644 Binary files a/tests/test_results/SameSuite/apu/channel_4/channel_4_freq_change.gb.png and b/tests/test_results/SameSuite/apu/channel_4/channel_4_freq_change.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_4/channel_4_frequency_alignment.gb.png b/tests/test_results/SameSuite/apu/channel_4/channel_4_frequency_alignment.gb.png index 751a11b29..5d9ee0dec 100644 Binary files a/tests/test_results/SameSuite/apu/channel_4/channel_4_frequency_alignment.gb.png and b/tests/test_results/SameSuite/apu/channel_4/channel_4_frequency_alignment.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr.gb.png b/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr.gb.png index 9a4ca6a49..92e5341cd 100644 Binary files a/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr.gb.png and b/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr15.gb.png b/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr15.gb.png index 8ea5179f9..101ebe4dd 100644 Binary files a/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr15.gb.png and b/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr15.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr_15_7.gb.png b/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr_15_7.gb.png index 9401ace66..dc1a67d25 100644 Binary files a/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr_15_7.gb.png and b/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr_15_7.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr_7_15.gb.png b/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr_7_15.gb.png index ec4760642..4368832c3 100644 Binary files a/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr_7_15.gb.png and b/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr_7_15.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr_restart.gb.png b/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr_restart.gb.png index 640db3d07..73ad2b7b7 100644 Binary files a/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr_restart.gb.png and b/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr_restart.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr_restart_fast.gb.png b/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr_restart_fast.gb.png index 640db3d07..73ad2b7b7 100644 Binary files a/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr_restart_fast.gb.png and b/tests/test_results/SameSuite/apu/channel_4/channel_4_lfsr_restart_fast.gb.png differ diff --git a/tests/test_results/SameSuite/apu/channel_4/channel_4_volume_div.gb.png b/tests/test_results/SameSuite/apu/channel_4/channel_4_volume_div.gb.png index bc1c2885e..596167509 100644 Binary files a/tests/test_results/SameSuite/apu/channel_4/channel_4_volume_div.gb.png and b/tests/test_results/SameSuite/apu/channel_4/channel_4_volume_div.gb.png differ diff --git a/tests/test_results/SameSuite/apu/div_trigger_volume_10.gb.png b/tests/test_results/SameSuite/apu/div_trigger_volume_10.gb.png index ccfcd887a..6067c133f 100644 Binary files a/tests/test_results/SameSuite/apu/div_trigger_volume_10.gb.png and b/tests/test_results/SameSuite/apu/div_trigger_volume_10.gb.png differ diff --git a/tests/test_results/SameSuite/apu/div_write_trigger.gb.png b/tests/test_results/SameSuite/apu/div_write_trigger.gb.png index 6338b9a90..5ee42b547 100644 Binary files a/tests/test_results/SameSuite/apu/div_write_trigger.gb.png and b/tests/test_results/SameSuite/apu/div_write_trigger.gb.png differ diff --git a/tests/test_results/SameSuite/apu/div_write_trigger_10.gb.png b/tests/test_results/SameSuite/apu/div_write_trigger_10.gb.png index cb6b4821b..c62355ca7 100644 Binary files a/tests/test_results/SameSuite/apu/div_write_trigger_10.gb.png and b/tests/test_results/SameSuite/apu/div_write_trigger_10.gb.png differ diff --git a/tests/test_results/SameSuite/apu/div_write_trigger_volume.gb.png b/tests/test_results/SameSuite/apu/div_write_trigger_volume.gb.png index ccfcd887a..6067c133f 100644 Binary files a/tests/test_results/SameSuite/apu/div_write_trigger_volume.gb.png and b/tests/test_results/SameSuite/apu/div_write_trigger_volume.gb.png differ diff --git a/tests/test_results/SameSuite/apu/div_write_trigger_volume_10.gb.png b/tests/test_results/SameSuite/apu/div_write_trigger_volume_10.gb.png index ccfcd887a..6067c133f 100644 Binary files a/tests/test_results/SameSuite/apu/div_write_trigger_volume_10.gb.png and b/tests/test_results/SameSuite/apu/div_write_trigger_volume_10.gb.png differ diff --git a/tests/test_results/blargg.json b/tests/test_results/blargg.json index d82a5c967..3a2ef5e18 100644 --- a/tests/test_results/blargg.json +++ b/tests/test_results/blargg.json @@ -20,20 +20,20 @@ "blargg/dmg_sound/rom_singles/06-overflow on trigger.gb": "06-overflow on trigger\n\n7FFF 7FFF 7FFF 7FFF 7FFF 7FFF 7FFF \n8D7112A4 \nFailed\n", "blargg/dmg_sound/rom_singles/07-len sweep period sync.gb": "07-len sweep period sync\n\n\nLength period is wrong\n\nFailed #2\n", "blargg/dmg_sound/rom_singles/08-len ctr during power.gb": "08-len ctr during power\n\n00 00 00 00 2144DF1C \nFailed\n", - "blargg/dmg_sound/rom_singles/09-wave read while on.gb": "09-wave read while on\n\n55 33 11 00 00 FF FF 00 11 11 33 88 BB CC 44 55 BB 11 DD DD 44 33 BB BB DD 77 11 CC CC 33 33 00 EE CC BB 88 77 77 77 88 99 BB DD 00 33 77 BB 00 55 DD 33 AA 99 11 99 22 BB 55 FF AA 55 11 DD 77 44 22 00 11 22 0652FAE5 \nFailed\n", + "blargg/dmg_sound/rom_singles/09-wave read while on.gb": "09-wave read while on\n\n88 33 11 00 FF FF FF 00 11 44 66 99 CC DD 55 AA AA FF 55 22 99 AA AA 33 CC 66 77 CC CC 33 FF CC 99 99 55 55 33 33 33 44 55 77 CC FF 22 66 CC 33 EE 44 11 88 FF 77 FF 88 11 BB 55 00 BB 33 CC 99 88 44 22 00 FF D075E68F \nFailed\n", "blargg/dmg_sound/rom_singles/10-wave trigger while on.gb": "10-wave trigger while on\n\n00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF \n00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF \n00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF \n00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF \n00 11 22 33 44 55 66 77 88 99", "blargg/dmg_sound/rom_singles/11-regs after power.gb": "11-regs after power\n\n\nPowering off should clear NR13\n\nFailed #3\n", - "blargg/dmg_sound/rom_singles/12-wave write while on.gb": "12-wave write while on\n\n00 11 22 33 44 F7 66 77 88 99 AA BB CC DD EE FF \n00 11 22 F7 44 55 66 77 88 99 AA BB CC DD EE FF \n00 F7 22 33 44 55 66 77 88 99 AA BB CC DD EE FF \nF7 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF \n00 11 22 33 44 55 66 77 88 99 A", - "blargg/instr_timing/instr_timing.gb": "instr_timing\n\n01:255-3 02:254-2 03:254-2 06:254-2 09:254-2 0A:254-2 0B:254-2 0E:254-2 11:255-3 12:254-2 13:254-2 16:254-2 18:255-3 19:254-2 1A:254-2 1B:254-2 1E:254-2 20:254-2 20:255-3 21:255-3 22:254-2 23:254-2 26:254-2 28:254-2 28:255-3 29:254-2 2A:254-2 2B:254-2 2E:254-2 30:254-2 30:255-3 31:255-3 32:254-2 33:254-2 34:255-3 35:255-3 36:255-3 38:254-2 38:255-3 39:254-2 3A:254-2 3B:254-2 3E:254-2 46:254-2 4E:254-2 56:254-2 5E:254-2 66:254-2 6E:254-2 70:254-2 71:254-2 72:254-2 73:254-2 74:254-2 75:254-2 77:254-2 7E:254-2 86:254-2 8E:254-2 96:254-2 9E:254-2 A6:254-2 AE:254-2 B6:254-2 BE:254-2 C0:254-2 C1:255-3 C2:255-3 C4:255-3 C4:2-6 C6:254-2 C8:254-2 CA:255-3 CC:255-3 CC:2-6 CD:2-6 CE:254-2 D0:254-2 D1:255-3 D2:255-3 D4:255-3 D4:2-6 D6:254-2 D8:254-2 DA:255-3 DC:255-3 DC:2-6 DE:254-2 E0:255-3 E1:255-3 E2:254-2 E6:254-2 EE:254-2 F0:255-3 F1:255-3 F2:254-2 F6:254-2 F8:255-3 F9:254-2 FE:254-2 CB 00:254-2 CB 01:254-2 CB 02:254-2 CB 03:254-2 CB 04:254-2 CB 05:254-2 CB 07:254-2 CB 08:254-2 CB 09:254-2 CB 0A:254-2 CB 0B:254-2 CB 0C:254-2 CB 0D:254-2 CB 0F:254-2 CB 10:254-2 CB 11:254-2 CB 12:254-2 CB 13:254-2 CB 14:254-2 CB 15:254-2 CB 17:254-2 CB 18:254-2 CB 19:254-2 CB 1A:254-2 CB 1B:254-2 CB 1C:254-2 CB 1D:254-2 CB 1F:254-2 CB 20:254-2 CB 21:254-2 CB 22:254-2 CB 23:254-2 CB 24:254-2 CB 25:254-2 CB 27:254-2 CB 28:254-2 CB 29:254-2 CB 2A:254-2 CB 2B:254-2 CB 2C:254-2 CB 2D:254-2 CB 2F:254-2 CB 30:254-2 CB 31:254-2 CB 32:254-2 CB 33:254-2 CB 34:254-2 CB 35:254-2 CB 37:254-2 CB 38:254-2 CB 39:254-2 CB 3A:254-2 CB 3B:254-2 CB 3C:254-2 CB 3D:254-2 CB 3F:254-2 CB 40:254-2 CB 41:254-2 CB 42:254-2 CB 43:254-2 CB 44:254-2 CB 45:254-2 CB 46:4-3 CB 47:254-2 CB 48:254-2 CB 49:254-2 CB 4A:254-2 CB 4B:254-2 CB 4C:254-2 CB 4D:254-2 CB 4E:4-3 CB 4F:254-2 CB 50:254-2 CB 51:254-2 CB 52:254-2 CB 53:254-2 CB 54:254-2 CB 55:254-2 CB 56:4-3 CB 57:254-2 CB 58:254-2 CB 59:254-2 CB 5A:254-2 CB 5B:254-2 CB 5C:254-2 CB 5D:254-2 CB 5E:4-3 CB 5F:254-2 CB 60:254-2 CB 61:254-2 CB 62:254-2 CB 63:254-2 CB 64:254-2 CB 65:254-2 CB 66:4-3 CB 67:254-2 CB 68:254-2 CB 69:254-2 CB 6A:254-2 CB 6B:254-2 CB 6C:254-2 CB 6D:254-2 CB 6E:4-3 CB 6F:254-2 CB 70:254-2 CB 71:254-2 CB 72:254-2 CB 73:254-2 CB 74:254-2 CB 75:254-2 CB 76:4-3 CB 77:254-2 CB 78:254-2 CB 79:254-2 CB 7A:254-2 CB 7B:254-2 CB 7C:254-2 CB 7D:254-2 CB 7E:4-3 CB 7F:254-2 CB 80:254-2 CB 81:254-2 CB 82:254-2 CB 83:254-2 CB 84:254-2 CB 85:254-2 CB 87:254-2 CB 88:254-2 CB 89:254-2 CB 8A:254-2 CB 8B:254-2 CB 8C:254-2 CB 8D:254-2 CB 8F:254-2 CB 90:254-2 CB 91:254-2 CB 92:254-2 CB 93:254-2 CB 94:254-2 CB 95:254-2 CB 97:254-2 CB 98:254-2 CB 99:254-2 CB 9A:254-2 CB 9B:254-2 CB 9C:254-2 CB 9D:254-2 CB 9F:254-2 CB A0:254-2 CB A1:254-2 CB A2:254-2 CB A3:254-2 CB A4:254-2 CB A5:254-2 CB A7:254-2 CB A8:254-2 CB A9:254-2 CB AA:254-2 CB AB:254-2 CB AC:254-2 CB AD:254-2 CB AF:254-2 CB B0:254-2 CB B1:254-2 CB B2:254-2 CB B3:254-2 CB B4:254-2 CB B5:254-2 CB B7:254-2 CB B8:254-2 CB B9:254-2 CB BA:254-2 CB BB:254-2 CB BC:254-2 CB BD:254-2 CB BF:254-2 CB C0:254-2 CB C1:254-2 CB C2:254-2 CB C3:254-2 CB C4:254-2 CB C5:254-2 CB C7:254-2 CB C8:254-2 CB C9:254-2 CB CA:254-2 CB CB:254-2 CB CC:254-2 CB CD:254-2 CB CF:254-2 CB D0:254-2 CB D1:254-2 CB D2:254-2 CB D3:254-2 CB D4:254-2 CB D5:254-2 CB D7:254-2 CB D8:254-2 CB D9:254-2 CB DA:254-2 CB DB:254-2 CB DC:254-2 CB DD:254-2 CB DF:254-2 CB E0:254-2 CB E1:254-2 CB E2:254-2 CB E3:254-2 CB E4:254-2 CB E5:254-2 CB E7:254-2 CB E8:254-2 CB E9:254-2 CB EA:254-2 CB EB:254-2 CB EC:254-2 CB ED:254-2 CB EF:254-2 CB F0:254-2 CB F1:254-2 CB F2:254-2 CB F3:254-2 CB F4:254-2 CB F5:254-2 CB F7:254-2 CB F8:254-2 CB F9:254-2 CB FA:254-2 CB FB:254-2 CB FC:254-2 CB FD:254-2 CB FF:254-2 \nFailed\n", - "blargg/interrupt_time/interrupt_time.gb": "interrupt time\n\n00 00 FC \n00 08 04 \n00 00 FC \n00 08 04 \n550B72D0 \nFailed\n", - "blargg/mem_timing/individual/01-read_timing.gb": "01-read_timing\n\nF0:2-3 FA:2-4 CB 46:2-3 CB 4E:2-3 CB 56:2-3 CB 5E:2-3 CB 66:2-3 CB 6E:2-3 CB 76:2-3 CB 7E:2-3 \nFailed\n", - "blargg/mem_timing/individual/02-write_timing.gb": "02-write_timing\n\n36:2-3 E0:2-3 EA:2-4 \nFailed\n", - "blargg/mem_timing/individual/03-modify_timing.gb": "03-modify_timing\n\n35:0/0-2/3\n34:0/0-2/3\nCB 06:0/0-3/4\nCB 0E:0/0-3/4\nCB 16:0/0-3/4\nCB 1E:0/0-3/4\nCB 26:0/0-3/4\nCB 2E:0/0-3/4\nCB 36:0/0-3/4\nCB 3E:0/0-3/4\nCB 86:0/0-3/4\nCB 8E:0/0-3/4\nCB 96:0/0-3/4\nCB 9E:0/0-3/4\nCB A6:0/0-3/4\nCB AE:0/0-3/4\nCB B6:0/0-3/4\nCB BE:0/0-3/4\nCB C6:0/0-3/4\nCB CE:0/0-3/4\nCB D6:0/0-3/4\nCB DE:0/0-3/4\nCB E6:0/0-3/4\nCB EE:0/0-3/4\nCB F6:0/0-3/4\nCB FE:0/0-3/4\n\nFailed\n", - "blargg/mem_timing/mem_timing.gb": "mem_timing\n\n01:01 02:01 03:01 \n\nFailed 3 tests.\n", - "blargg/mem_timing-2/mem_timing.gb": "mem_timing\n\n01:01 02:01 03:01 \n\nRun failed tests\nindividually for\nmore details.\n\nFailed\n", - "blargg/mem_timing-2/rom_singles/01-read_timing.gb": "01-read_timing\n\nF0:2-3 FA:2-4 CB 46:2-3 CB 4E:2-3 CB 56:2-3 CB 5E:2-3 CB 66:2-3 CB 6E:2-3 CB 76:2-3 CB 7E:2-3 \nFailed\n", - "blargg/mem_timing-2/rom_singles/02-write_timing.gb": "02-write_timing\n\n36:2-3 E0:2-3 EA:2-4 \nFailed\n", - "blargg/mem_timing-2/rom_singles/03-modify_timing.gb": "03-modify_timing\n\n35:0/0-2/3\n34:0/0-2/3\nCB 06:0/0-3/4\nCB 0E:0/0-3/4\nCB 16:0/0-3/4\nCB 1E:0/0-3/4\nCB 26:0/0-3/4\nCB 2E:0/0-3/4\nCB 36:0/0-3/4\nCB 3E:0/0-3/4\nCB 86:0/0-3/4\nCB 8E:0/0-3/4\nCB 96:0/0-3/4\nCB 9E:0/0-3/4\nCB A6:0/0-3/4\nCB AE:0/0-3/4\nCB B6:0/0-3/4\nC", + "blargg/dmg_sound/rom_singles/12-wave write while on.gb": "12-wave write while on\n\n00 11 22 33 44 F7 66 77 88 99 AA BB CC DD EE FF \n00 11 22 33 44 F7 66 77 88 99 AA BB CC DD EE FF \n00 11 22 33 F7 55 66 77 88 99 AA BB CC DD EE FF \n00 F7 22 33 44 55 66 77 88 99 AA BB CC DD EE FF \nF7 11 22 33 44 55 66 77 88 99 A", + "blargg/instr_timing/instr_timing.gb": "instr_timing\n\n\nPassed\n", + "blargg/interrupt_time/interrupt_time.gb": "interrupt time\n\n00 00 00 \n00 08 08 \n00 00 00 \n00 08 08 \n5DDD9187 \nFailed\n", + "blargg/mem_timing/individual/01-read_timing.gb": "01-read_timing\n\n\nPassed\n", + "blargg/mem_timing/individual/02-write_timing.gb": "02-write_timing\n\n\nPassed\n", + "blargg/mem_timing/individual/03-modify_timing.gb": "03-modify_timing\n\n\nPassed\n", + "blargg/mem_timing/mem_timing.gb": "mem_timing\n\n01:ok 02:ok 03:ok \n\nPassed all tests\n", + "blargg/mem_timing-2/mem_timing.gb": "mem_timing\n\n01:ok 02:ok 03:ok \n\nPassed\n", + "blargg/mem_timing-2/rom_singles/01-read_timing.gb": "01-read_timing\n\n\nPassed\n", + "blargg/mem_timing-2/rom_singles/02-write_timing.gb": "02-write_timing\n\n\nPassed\n", + "blargg/mem_timing-2/rom_singles/03-modify_timing.gb": "03-modify_timing\n\n\nPassed\n", "blargg/oam_bug/oam_bug.gb": "oam_bug\n\n01:03 02:02 03:ok 04:03 05:02 06:ok 07:01 08:02 \n\nRun failed tests\nindividually for\nmore details.\n\nFailed\n", "blargg/oam_bug/rom_singles/1-lcd_sync.gb": "1-lcd_sync\n\n\nTurning LCD on starts too early in scanline\n\nFailed #3\n", "blargg/oam_bug/rom_singles/2-causes.gb": "2-causes\n\n\nLD DE,$FE00 : INC DE\n\nFailed #2\n", @@ -52,7 +52,7 @@ "blargg/cgb_sound/rom_singles/06-overflow on trigger.gb": "06-overflow on trigger\n\n7FFF 7FFF 7FFF 7FFF 7FFF 7FFF 7FFF \n8D7112A4 \nFailed\n", "blargg/cgb_sound/rom_singles/07-len sweep period sync.gb": "07-len sweep period sync\n\n\nLength period is wrong\n\nFailed #2\n", "blargg/cgb_sound/rom_singles/08-len ctr during power.gb": "08-len ctr during power\n\n00 00 00 00 2144DF1C \nFailed\n", - "blargg/cgb_sound/rom_singles/09-wave read while on.gb": "09-wave read while on\n\n55 33 11 22 22 11 22 33 44 66 66 BB EE 22 22 77 11 77 88 55 CC CC CC 55 55 88 88 22 88 44 55 EE FF DD CC 99 99 88 88 AA BB DD 22 55 AA EE 22 77 CC 22 88 66 DD DD 55 EE 77 BB 00 66 11 DD 66 33 00 00 DD CC DD CCD5FE43 \nFailed\n", + "blargg/cgb_sound/rom_singles/09-wave read while on.gb": "09-wave read while on\n\n55 33 11 11 00 FF FF FF 00 33 55 88 99 DD 11 AA AA 55 BB 22 99 11 11 99 22 BB FF AA 55 11 11 AA 77 77 66 33 22 22 22 33 44 66 88 BB EE 22 66 BB 00 88 55 CC 33 BB 33 CC 77 11 BB 11 CC 88 44 11 EE CC AA 99 AA B7836723 \nFailed\n", "blargg/cgb_sound/rom_singles/10-wave trigger while on.gb": "10-wave trigger while on\n\n00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF \n00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF \n00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF \n00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF \n00 11 22 33 44 55 66 77 88 99", "blargg/cgb_sound/rom_singles/11-regs after power.gb": "11-regs after power\n\n\nPowering off should clear NR13\n\nFailed #3\n", "blargg/cgb_sound/rom_singles/12-wave.gb": "12-wave\n\n\nTimer period or phase resetting is wrong\n\nFailed #2\n" diff --git a/tests/test_results/cgb_whichboot.gb.png b/tests/test_results/cgb_whichboot.gb.png index 9edda33da..57c8411db 100644 Binary files a/tests/test_results/cgb_whichboot.gb.png and b/tests/test_results/cgb_whichboot.gb.png differ diff --git a/tests/test_results/dmg_whichboot.gb.png b/tests/test_results/dmg_whichboot.gb.png index 27f7890bb..e8ce67780 100644 Binary files a/tests/test_results/dmg_whichboot.gb.png and b/tests/test_results/dmg_whichboot.gb.png differ diff --git a/tests/test_rtc3test.py b/tests/test_rtc3test.py index 3118d6536..eb66feb0c 100644 --- a/tests/test_rtc3test.py +++ b/tests/test_rtc3test.py @@ -45,7 +45,7 @@ def test_rtc3test(subtest, rtc3test_file): # Converting to RGB as ImageChops.difference cannot handle Alpha: https://github.com/python-pillow/Pillow/issues/4849 old_image = PIL.Image.open(png_path).convert("RGB") diff = PIL.ImageChops.difference(image.convert("RGB"), old_image) - if diff.getbbox() and not os.environ.get("TEST_CI"): + if diff.getbbox() and os.environ.get("TEST_VERBOSE_IMAGES"): image.show() old_image.show() diff.show() diff --git a/tests/test_samesuite.py b/tests/test_samesuite.py index 16e0e5bba..edf36170c 100644 --- a/tests/test_samesuite.py +++ b/tests/test_samesuite.py @@ -155,7 +155,7 @@ def test_samesuite(clean, gb_type, rom, samesuite_dir, boot_cgb_rom, boot_rom, d old_image = PIL.Image.open(png_path).convert("RGB") diff = PIL.ImageChops.difference(image.convert("RGB"), old_image) - if diff.getbbox() and not os.environ.get("TEST_CI"): + if diff.getbbox() and os.environ.get("TEST_VERBOSE_IMAGES"): image.show() old_image.show() diff.show() diff --git a/tests/test_shonumi.py b/tests/test_shonumi.py index 01adfe01b..e9aaa6e48 100644 --- a/tests/test_shonumi.py +++ b/tests/test_shonumi.py @@ -37,7 +37,7 @@ def test_shonumi(rom, shonumi_dir): old_image = old_image.resize(image.size, resample=PIL.Image.Dither.NONE) diff = PIL.ImageChops.difference(image.convert("RGB"), old_image) - if diff.getbbox() and not os.environ.get("TEST_CI"): + if diff.getbbox() and os.environ.get("TEST_VERBOSE_IMAGES"): image.show() old_image.show() diff.show() diff --git a/tests/test_which.py b/tests/test_which.py index afa67f46e..2a358afe4 100644 --- a/tests/test_which.py +++ b/tests/test_which.py @@ -30,7 +30,7 @@ def test_which(cgb, which_file): # Converting to RGB as ImageChops.difference cannot handle Alpha: https://github.com/python-pillow/Pillow/issues/4849 old_image = PIL.Image.open(png_path).convert("RGB") diff = PIL.ImageChops.difference(image.convert("RGB"), old_image) - if diff.getbbox() and not os.environ.get("TEST_CI"): + if diff.getbbox() and os.environ.get("TEST_VERBOSE_IMAGES"): image.show() old_image.show() diff.show() diff --git a/tests/test_whichboot.py b/tests/test_whichboot.py index 34d5bdb19..31fa35040 100644 --- a/tests/test_whichboot.py +++ b/tests/test_whichboot.py @@ -15,11 +15,10 @@ @pytest.mark.parametrize("cgb", [False, True]) -def test_which(cgb, whichboot_file): - pyboy = PyBoy(whichboot_file, window="null", cgb=cgb) +def test_which(cgb, whichboot_file, boot_rom, boot_cgb_rom): + pyboy = PyBoy(whichboot_file, window="null", cgb=cgb, bootrom=boot_cgb_rom if cgb else boot_rom) pyboy.set_emulation_speed(0) - pyboy.tick(59, True) - pyboy.tick(25, True) + pyboy.tick(1000, True) png_path = Path(f"tests/test_results/{'cgb' if cgb else 'dmg'}_{os.path.basename(whichboot_file)}.png") image = pyboy.screen.image @@ -30,7 +29,7 @@ def test_which(cgb, whichboot_file): # Converting to RGB as ImageChops.difference cannot handle Alpha: https://github.com/python-pillow/Pillow/issues/4849 old_image = PIL.Image.open(png_path).convert("RGB") diff = PIL.ImageChops.difference(image.convert("RGB"), old_image) - if diff.getbbox() and not os.environ.get("TEST_CI"): + if diff.getbbox() and os.environ.get("TEST_VERBOSE_IMAGES"): image.show() old_image.show() diff.show()