Class: PSX::Timers::Timer
- Inherits:
-
Object
- Object
- PSX::Timers::Timer
- Defined in:
- lib/psx/timers.rb
Overview
Overflow occurred (bit 12)
Instance Attribute Summary collapse
-
#counter ⇒ Object
Returns the value of attribute counter.
-
#mode ⇒ Object
Returns the value of attribute mode.
-
#target ⇒ Object
Returns the value of attribute target.
Instance Method Summary collapse
-
#initialize ⇒ Timer
constructor
A new instance of Timer.
- #read_counter ⇒ Object
- #read_mode ⇒ Object
- #read_target ⇒ Object
-
#tick(cycles = 1) ⇒ Object
Increment counter, returns true if IRQ should fire Optimized to avoid per-cycle loop.
- #write_counter(value) ⇒ Object
- #write_mode(value) ⇒ Object
- #write_target(value) ⇒ Object
Constructor Details
#initialize ⇒ Timer
Returns a new instance of Timer.
27 28 29 30 31 32 |
# File 'lib/psx/timers.rb', line 27 def initialize @counter = 0 @mode = 0 @target = 0 @irq_fired = false end |
Instance Attribute Details
#counter ⇒ Object
Returns the value of attribute counter.
25 26 27 |
# File 'lib/psx/timers.rb', line 25 def counter @counter end |
#mode ⇒ Object
Returns the value of attribute mode.
25 26 27 |
# File 'lib/psx/timers.rb', line 25 def mode @mode end |
#target ⇒ Object
Returns the value of attribute target.
25 26 27 |
# File 'lib/psx/timers.rb', line 25 def target @target end |
Instance Method Details
#read_counter ⇒ Object
34 35 36 |
# File 'lib/psx/timers.rb', line 34 def read_counter @counter end |
#read_mode ⇒ Object
42 43 44 45 46 47 |
# File 'lib/psx/timers.rb', line 42 def read_mode # Return mode and clear flags result = @mode @mode &= ~(MODE_TARGET_REACHED | MODE_OVERFLOW) result end |
#read_target ⇒ Object
55 56 57 |
# File 'lib/psx/timers.rb', line 55 def read_target @target end |
#tick(cycles = 1) ⇒ Object
Increment counter, returns true if IRQ should fire Optimized to avoid per-cycle loop
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/psx/timers.rb', line 65 def tick(cycles = 1) return false if cycles <= 0 irq = false new_counter = @counter + cycles # Check for target hit (if target is set and reset-on-target is enabled) if @target > 0 && (@mode & MODE_RESET_TARGET) != 0 # Will we cross the target? if @counter < @target && new_counter >= @target @mode |= MODE_TARGET_REACHED if (@mode & MODE_IRQ_TARGET) != 0 irq = true if !@irq_fired || (@mode & MODE_IRQ_REPEAT) != 0 end # Reset and continue counting from target new_counter = (new_counter - @target) % (@target > 0 ? @target : 0x10000) end elsif @target > 0 && @counter < @target && new_counter >= @target # Target without reset - just set flag @mode |= MODE_TARGET_REACHED if (@mode & MODE_IRQ_TARGET) != 0 irq = true if !@irq_fired || (@mode & MODE_IRQ_REPEAT) != 0 end end # Check for overflow if new_counter > 0xFFFF @mode |= MODE_OVERFLOW if (@mode & MODE_IRQ_OVERFLOW) != 0 irq = true if !@irq_fired || (@mode & MODE_IRQ_REPEAT) != 0 end new_counter &= 0xFFFF end @counter = new_counter @irq_fired = true if irq && (@mode & MODE_IRQ_REPEAT) == 0 irq end |
#write_counter(value) ⇒ Object
38 39 40 |
# File 'lib/psx/timers.rb', line 38 def write_counter(value) @counter = value & 0xFFFF end |
#write_mode(value) ⇒ Object
49 50 51 52 53 |
# File 'lib/psx/timers.rb', line 49 def write_mode(value) @mode = value & 0x03FF # Writable bits @counter = 0 # Writing to mode resets counter @irq_fired = false end |
#write_target(value) ⇒ Object
59 60 61 |
# File 'lib/psx/timers.rb', line 59 def write_target(value) @target = value & 0xFFFF end |