Class: PSX::DMA::Channel

Inherits:
Object
  • Object
show all
Defined in:
lib/psx/dma.rb

Overview

Master IRQ flag (bit 31)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeChannel

Returns a new instance of Channel.



43
44
45
46
47
48
# File 'lib/psx/dma.rb', line 43

def initialize
  @base_addr = 0
  @block_ctrl = 0
  @channel_ctrl = 0
  @busy_cycles = 0
end

Instance Attribute Details

#base_addrObject

Returns the value of attribute base_addr.



41
42
43
# File 'lib/psx/dma.rb', line 41

def base_addr
  @base_addr
end

#block_ctrlObject

Returns the value of attribute block_ctrl.



41
42
43
# File 'lib/psx/dma.rb', line 41

def block_ctrl
  @block_ctrl
end

#busy_cyclesObject

Returns the value of attribute busy_cycles.



41
42
43
# File 'lib/psx/dma.rb', line 41

def busy_cycles
  @busy_cycles
end

#channel_ctrlObject

Returns the value of attribute channel_ctrl.



41
42
43
# File 'lib/psx/dma.rb', line 41

def channel_ctrl
  @channel_ctrl
end

Instance Method Details

#active?(needs_trigger: false) ⇒ Boolean

Returns:

  • (Boolean)


50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/psx/dma.rb', line 50

def active?(needs_trigger: false)
  # Channel is active when Start/Busy bit is set.
  # SyncMode 0 (Manual) without a DRQ-driving device (e.g. OTC) also
  # needs the start-trigger bit. Channels with DRQ (GPU, SPU, CDROM,
  # ...) auto-start when BUSY is set.
  enabled = (@channel_ctrl & CTRL_START_BUSY) != 0
  return false unless enabled

  if needs_trigger
    (@channel_ctrl & CTRL_START_TRIGGER) != 0
  else
    true
  end
end

#block_countObject



81
82
83
# File 'lib/psx/dma.rb', line 81

def block_count
  (@block_ctrl >> 16) & 0xFFFF
end

#block_sizeObject



77
78
79
# File 'lib/psx/dma.rb', line 77

def block_size
  @block_ctrl & 0xFFFF
end

#directionObject



65
66
67
# File 'lib/psx/dma.rb', line 65

def direction
  (@channel_ctrl & CTRL_DIRECTION) != 0 ? :from_ram : :to_ram
end

#finish!Object



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/psx/dma.rb', line 85

def finish!
  # On transfer completion: bit 24 (Start/Busy) and bit 28 (Start/
  # Trigger) both clear. Bit 28 is "consumed" by the transfer it
  # triggered. Unused R/W bits (29/30) keep their values.
  # Verified against ps1-tests/dma/otc-test:
  #   testOtcWhichBitsAreHardwiredToZero -- bit 28 stays when no
  #     transfer happens (busy bit wasn't set, finish! isn't called).
  #   testOtcControlBitsAfterTransfer   -- bit 28 cleared after
  #     transfer actually ran.
  @channel_ctrl &= ~(CTRL_START_BUSY | CTRL_START_TRIGGER)
end

#stepObject



69
70
71
# File 'lib/psx/dma.rb', line 69

def step
  (@channel_ctrl & CTRL_STEP) != 0 ? -4 : 4
end

#sync_modeObject



73
74
75
# File 'lib/psx/dma.rb', line 73

def sync_mode
  (@channel_ctrl >> 9) & 0x3
end