update mmio from chained conditionals to case statement

This commit is contained in:
Matthew Berry 2022-08-21 15:47:11 -07:00
parent e36b633522
commit 7001db8c90
3 changed files with 54 additions and 62 deletions

View file

@ -1,57 +1,21 @@
module GBA
class Keypad
class KEYINPUT < BitField(UInt16)
num not_used, 6
bool l
bool r
bool down
bool up
bool left
bool right
bool start
bool :select
bool b
bool a
end
class KEYCNT < BitField(UInt16)
bool irq_condition
bool irq_enable
num not_used, 4
bool l
bool r
bool down
bool up
bool left
bool right
bool start
bool :select
bool b
bool a
end
@keyinput = KEYINPUT.new 0xFFFF_u16
@keycnt = KEYCNT.new 0xFFFF_u16
@keyinput = Reg::KEYINPUT.new 0xFFFF_u16
@keycnt = Reg::KEYCNT.new 0xFFFF_u16
def initialize(@gba : GBA)
end
def [](io_addr : Int) : Byte
case io_addr
when 0x130 then 0xFF_u8 & @keyinput.value
when 0x131 then 0xFF_u8 & @keyinput.value >> 8
when 0x132 then 0xFF_u8 & @keycnt.value
when 0x133 then 0xFF_u8 & @keycnt.value >> 8
else raise "Unimplemented keypad read ~ addr:#{hex_str io_addr.to_u8!}"
when 0x130..0x131 then @keyinput.read_byte(io_addr & 1)
when 0x132..0x133 then @keycnt.read_byte(io_addr & 1)
else abort "Unreachable keypad read #{hex_str io_addr}"
end
end
def []=(io_addr : Int, value : Byte) : Nil
case io_addr
when 0x130 then nil
when 0x131 then nil
else raise "Unimplemented keypad write ~ addr:#{hex_str io_addr.to_u8!}, val:#{value}"
end
puts "TODO: Implement stopping and keycnt behavior" if 0x132 <= io_addr <= 0x133
end
def handle_input(input : Input, pressed : Bool) : Nil

View file

@ -12,8 +12,7 @@ module GBA
when 0x060..0x0A7 then @gba.apu[io_addr]
when 0x0B0..0x0DF then @gba.dma[io_addr]
when 0x100..0x10F then @gba.timer[io_addr]
when 0x120..0x12B, 0x134..0x159
# todo: serial
when 0x120..0x12B, 0x134..0x159 # todo: serial
if io_addr == 0x135
0x80_u8
else
@ -29,25 +28,19 @@ module GBA
def []=(index : Int, value : Byte) : Nil
io_addr = 0xFFFFFF_u32 & index
if io_addr <= 0x05F
@gba.ppu[io_addr] = value
elsif io_addr <= 0xAF
@gba.apu[io_addr] = value
elsif io_addr <= 0xFF
@gba.dma[io_addr] = value
elsif 0x100 <= io_addr <= 0x10F
@gba.timer[io_addr] = value
elsif 0x130 <= io_addr <= 0x133
@gba.keypad[io_addr]
elsif 0x120 <= io_addr <= 0x12F || 0x134 <= io_addr <= 0x1FF
# todo: serial
elsif 0x200 <= io_addr <= 0x203 || 0x208 <= io_addr <= 0x209
@gba.interrupts[io_addr] = value
elsif 0x204 <= io_addr <= 0x205
@waitcnt.write_byte(io_addr & 1, value)
elsif io_addr == 0x301
case io_addr
when 0x000..0x055 then @gba.ppu[io_addr] = value
when 0x060..0x0A7 then @gba.apu[io_addr] = value
when 0x0B0..0x0DF then @gba.dma[io_addr] = value
when 0x100..0x10F then @gba.timer[io_addr] = value
when 0x120..0x12B, 0x134..0x159 # todo: serial
when 0x130..0x133 then @gba.keypad[io_addr] = value
when 0x200..0x203,
0x208..0x209 then @gba.interrupts[io_addr] = value
when 0x204..0x205 then @waitcnt.write_byte(io_addr & 1, value)
when 0x301
if bit?(value, 7)
abort "Stopping not supported"
puts "TODO: Implement stopping behavior"
else
@gba.cpu.halted = true
end

View file

@ -286,5 +286,40 @@ module GBA
num not_used, 11, read_only: true
num evy_coefficient, 5
end
####################
# Keypad
class KEYINPUT < BitField(UInt16)
include Base16
num not_used, 6
bool l
bool r
bool down
bool up
bool left
bool right
bool start
bool :select
bool b
bool a
end
class KEYCNT < BitField(UInt16)
include Base16
bool irq_condition
bool irq_enable
num not_used, 4
bool l
bool r
bool down
bool up
bool left
bool right
bool start
bool :select
bool b
bool a
end
end
end