mirror of
https://github.com/colby-swandale/waterfoul
synced 2025-01-14 08:01:51 +01:00
fixes for IME instructions and time
This commit is contained in:
parent
c0780010a5
commit
db5044effa
3 changed files with 21 additions and 16 deletions
|
@ -65,6 +65,7 @@ module Waterfoul
|
||||||
@a = @b = @c = @d = @e = @f = @h = @l = @f = 0x00
|
@a = @b = @c = @d = @e = @f = @h = @l = @f = 0x00
|
||||||
@m = 0
|
@m = 0
|
||||||
@timer = Timer.new
|
@timer = Timer.new
|
||||||
|
@ime = false
|
||||||
end
|
end
|
||||||
|
|
||||||
# This method emulates the CPU cycle process. Each instruction is
|
# This method emulates the CPU cycle process. Each instruction is
|
||||||
|
@ -72,13 +73,9 @@ module Waterfoul
|
||||||
# This processes repeats infinitly until the process is closed
|
# This processes repeats infinitly until the process is closed
|
||||||
def step
|
def step
|
||||||
reset_tick
|
reset_tick
|
||||||
if halted?
|
serve_interrupt if @ime
|
||||||
halt_step
|
instruction_byte = fetch_instruction
|
||||||
else
|
perform_instruction instruction_byte
|
||||||
serve_interrupt if @ime
|
|
||||||
instruction_byte = fetch_instruction
|
|
||||||
perform_instruction instruction_byte
|
|
||||||
end
|
|
||||||
@timer.tick @m
|
@timer.tick @m
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -107,7 +104,7 @@ module Waterfoul
|
||||||
raise 'instruction not found' if operation.nil?
|
raise 'instruction not found' if operation.nil?
|
||||||
# perform the instruction
|
# perform the instruction
|
||||||
self.public_send operation
|
self.public_send operation
|
||||||
@m = instruction_cycle_time instruction
|
@m = instruction_cycle_time(instruction) * 4
|
||||||
end
|
end
|
||||||
|
|
||||||
# fetch the next byte to be executed from memory and increment the program
|
# fetch the next byte to be executed from memory and increment the program
|
||||||
|
@ -123,7 +120,9 @@ module Waterfoul
|
||||||
# get the number of cycles a instruction takes to execute. The times
|
# get the number of cycles a instruction takes to execute. The times
|
||||||
# can be found in the instruction opcode table
|
# can be found in the instruction opcode table
|
||||||
def instruction_cycle_time(instruction)
|
def instruction_cycle_time(instruction)
|
||||||
if @branched
|
if @prefix_cb
|
||||||
|
CB_OPCODE_TIMINGS[@prefix_cb]
|
||||||
|
elsif @branched
|
||||||
OPCODE_CONDITIONAL_TIMINGS[instruction]
|
OPCODE_CONDITIONAL_TIMINGS[instruction]
|
||||||
else
|
else
|
||||||
OPCODE_TIMINGS[instruction]
|
OPCODE_TIMINGS[instruction]
|
||||||
|
@ -137,24 +136,30 @@ module Waterfoul
|
||||||
# master disable interrupts
|
# master disable interrupts
|
||||||
@ime = false
|
@ime = false
|
||||||
push_onto_stack @pc
|
push_onto_stack @pc
|
||||||
@m = 20
|
if_reg = $mmu.read_byte 0xFF0F
|
||||||
# point to instruction which handles appropiate interrupt
|
|
||||||
case interrupt
|
case interrupt
|
||||||
when Interrupt::INTERRUPT_VBLANK
|
when Interrupt::INTERRUPT_VBLANK
|
||||||
@pc = 0x40
|
@pc = 0x40
|
||||||
|
$mmu.write_byte(0xFF0F, if_reg & 0xFE)
|
||||||
when Interrupt::INTERRUPT_LCDSTAT
|
when Interrupt::INTERRUPT_LCDSTAT
|
||||||
@pc = 0x48
|
@pc = 0x48
|
||||||
|
$mmu.write_byte(0xFF0F, if_reg & 0xFD)
|
||||||
when Interrupt::INTERRUPT_TIMER
|
when Interrupt::INTERRUPT_TIMER
|
||||||
@pc = 0x50
|
@pc = 0x50
|
||||||
|
$mmu.write_byte(0xFF0F, if_reg & 0xFB)
|
||||||
when Interrupt::INTERRUPT_SERIAL
|
when Interrupt::INTERRUPT_SERIAL
|
||||||
@pc = 0x58
|
@pc = 0x58
|
||||||
|
$mmu.write_byte(0xFF0F, if_reg & 0xF7)
|
||||||
when Interrupt::INTERRUPT_JOYPAD
|
when Interrupt::INTERRUPT_JOYPAD
|
||||||
@pc = 0x60
|
@pc = 0x60
|
||||||
|
$mmu.write_byte(0xFF0F, if_reg & 0xEF)
|
||||||
end
|
end
|
||||||
|
@m = 20
|
||||||
end
|
end
|
||||||
|
|
||||||
# reset variables that are set on every instruction
|
# reset variables that are set on every instruction
|
||||||
def reset_tick
|
def reset_tick
|
||||||
|
@prefix_cb = false
|
||||||
@branched = false
|
@branched = false
|
||||||
@m = 0
|
@m = 0
|
||||||
end
|
end
|
||||||
|
|
|
@ -34,10 +34,10 @@ module Waterfoul
|
||||||
# @flags - - - -
|
# @flags - - - -
|
||||||
def prefix_cb
|
def prefix_cb
|
||||||
ins = $mmu.read_byte @pc
|
ins = $mmu.read_byte @pc
|
||||||
|
@prefix_cb = ins
|
||||||
@pc += 1
|
@pc += 1
|
||||||
|
|
||||||
opcode = Waterfoul::CPU::CB_OPCODE[ins]
|
opcode = Waterfoul::CPU::CB_OPCODE[ins]
|
||||||
#p "cb opcode: #{opcode}"
|
|
||||||
self.public_send opcode
|
self.public_send opcode
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
module Waterfoul
|
module Waterfoul
|
||||||
class Timer
|
class Timer
|
||||||
DIV_INC_TIME = 255 # cycles
|
DIV_INC_TIME = 256 # cycles
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@div_cycles = 0
|
@div_cycles = 0
|
||||||
|
@ -9,8 +9,6 @@ module Waterfoul
|
||||||
end
|
end
|
||||||
|
|
||||||
def tick(cycles = 0)
|
def tick(cycles = 0)
|
||||||
# increment TIMA and DIV register
|
|
||||||
@tima_cycles += cycles
|
|
||||||
@div_cycles += cycles
|
@div_cycles += cycles
|
||||||
# incremnt DIV register if its time to
|
# incremnt DIV register if its time to
|
||||||
inc_div_register if @div_cycles >= DIV_INC_TIME
|
inc_div_register if @div_cycles >= DIV_INC_TIME
|
||||||
|
@ -18,6 +16,8 @@ module Waterfoul
|
||||||
@tima.update
|
@tima.update
|
||||||
# dont bother if TIMA is not running
|
# dont bother if TIMA is not running
|
||||||
if @tima.running?
|
if @tima.running?
|
||||||
|
# increment TIMA and DIV register
|
||||||
|
@tima_cycles += cycles
|
||||||
frequency = @tima.frequency
|
frequency = @tima.frequency
|
||||||
if @tima_cycles >= frequency
|
if @tima_cycles >= frequency
|
||||||
inc_tima_register
|
inc_tima_register
|
||||||
|
@ -32,7 +32,7 @@ module Waterfoul
|
||||||
tima = $mmu.read_byte 0xFF06
|
tima = $mmu.read_byte 0xFF06
|
||||||
Interrupt.request_interrupt(Interrupt::INTERRUPT_TIMER)
|
Interrupt.request_interrupt(Interrupt::INTERRUPT_TIMER)
|
||||||
else
|
else
|
||||||
tima = (tima + 1) & 0xFF
|
tima += 1
|
||||||
end
|
end
|
||||||
|
|
||||||
$mmu.write_byte 0xFF05, tima, hardware_operation: true
|
$mmu.write_byte 0xFF05, tima, hardware_operation: true
|
||||||
|
|
Loading…
Reference in a new issue