mirror of
https://github.com/mattrberry/crab.git
synced 2025-02-05 08:45:50 +01:00
arm fix single data transfer imm offset, add mmio/interrupt writes
this hits the fps by ~15 for some reason on tonc's m3_demo...
This commit is contained in:
parent
9c166aca90
commit
e29bde0bcf
6 changed files with 95 additions and 38 deletions
|
@ -9,19 +9,19 @@ module ARM
|
|||
load = bit?(instr, 20)
|
||||
rn = bits(instr, 16..19)
|
||||
rd = bits(instr, 12..15)
|
||||
operand_2 = if imm_flag # Operand 2 is a register (opposite of data procesing for some reason)
|
||||
rotate_register bits(instr, 0..11), set_conditions: false, allow_register_shifts: false
|
||||
else # Operand 2 is an immediate offset
|
||||
immediate_offset bits(instr, 0..11)
|
||||
end
|
||||
offset = if imm_flag # Operand 2 is a register (opposite of data processing for some reason)
|
||||
rotate_register bits(instr, 0..11), set_conditions: false, allow_register_shifts: false
|
||||
else # Operand 2 is an immediate offset
|
||||
bits(instr, 0..11)
|
||||
end
|
||||
|
||||
address = @r[rn]
|
||||
|
||||
if pre_indexing
|
||||
if add_offset
|
||||
address &+= operand_2
|
||||
address &+= offset
|
||||
else
|
||||
address &-= operand_2
|
||||
address &-= offset
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -33,9 +33,9 @@ module ARM
|
|||
|
||||
if !pre_indexing
|
||||
if add_offset
|
||||
@r[rn] &+= operand_2
|
||||
@r[rn] &+= offset
|
||||
else
|
||||
@r[rn] &-= operand_2
|
||||
@r[rn] &-= offset
|
||||
end
|
||||
elsif write_back
|
||||
@r[rn] = address
|
||||
|
|
|
@ -10,13 +10,7 @@ class Bus
|
|||
case bits(index, 24..27)
|
||||
when 0x2 then @wram_board[index & 0x3FFFF]
|
||||
when 0x3 then @wram_chip[index & 0x7FFF]
|
||||
when 0x4
|
||||
io_addr = 0x0FFF_u16 & index
|
||||
if io_addr <= 0x05F
|
||||
@gba.ppu[index]
|
||||
else
|
||||
raise "Unmapped i/o read: #{hex_str index.to_u32}"
|
||||
end
|
||||
when 0x4 then @gba.mmio[index]
|
||||
when 0x5 then @gba.ppu.pram[index]
|
||||
when 0x6
|
||||
address = 0x1FFFF_u32 & index
|
||||
|
@ -45,13 +39,7 @@ class Bus
|
|||
case bits(index, 24..27)
|
||||
when 0x2 then @wram_board[index & 0x3FFFF] = value
|
||||
when 0x3 then @wram_chip[index & 0x7FFF] = value
|
||||
when 0x4
|
||||
io_addr = 0x0FFF_u16 & index
|
||||
if io_addr <= 0x05F
|
||||
@gba.ppu[index] = value
|
||||
else
|
||||
raise "Unmapped i/o write: #{hex_str index.to_u32}"
|
||||
end
|
||||
when 0x4 then @gba.mmio[index] = value
|
||||
when 0x5 then @gba.ppu.pram[index & 0x3FF] = value
|
||||
when 0x6
|
||||
address = 0x1FFFF_u32 & index
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
require "./types"
|
||||
require "./util"
|
||||
require "./cartridge"
|
||||
require "./mmio"
|
||||
require "./bus"
|
||||
require "./interrupts"
|
||||
require "./cpu"
|
||||
require "./display"
|
||||
require "./ppu"
|
||||
|
||||
class GBA
|
||||
getter cartridge : Cartridge
|
||||
getter mmio : MMIO { MMIO.new self }
|
||||
getter bus : Bus { Bus.new self }
|
||||
getter interrupts : Interrupts { Interrupts.new }
|
||||
getter cpu : CPU { CPU.new self }
|
||||
getter display : Display { Display.new }
|
||||
getter ppu : PPU { PPU.new self }
|
||||
|
|
29
src/crab/interrupts.cr
Normal file
29
src/crab/interrupts.cr
Normal file
|
@ -0,0 +1,29 @@
|
|||
class Interrupts
|
||||
getter reg_ie : UInt16 = 0
|
||||
getter reg_if : UInt16 = 0
|
||||
getter reg_ime : Bool = false
|
||||
|
||||
def read_io(io_addr : Int) : Byte
|
||||
case io_addr
|
||||
when 0x200 then (@reg_ie >> 8).to_u8
|
||||
when 0x201 then @reg_ie.to_u8!
|
||||
when 0x202 then (@reg_if >> 8).to_u8
|
||||
when 0x203 then @reg_if.to_u8!
|
||||
when 0x208 then @reg_ime ? 1_u8 : 0_u8
|
||||
when 0x209 then @reg_ime ? 1_u8 : 0_u8
|
||||
else raise "Unimplemented interrupts read ~ addr:#{hex_str io_addr.to_u8}"
|
||||
end
|
||||
end
|
||||
|
||||
def write_io(io_addr : Int, value : Byte) : Nil
|
||||
case io_addr
|
||||
when 0x200 then @reg_ie = (@reg_ie & 0x00FF) | value.to_u16 << 8
|
||||
when 0x201 then @reg_ie = (@reg_ie & 0xFF00) | value
|
||||
when 0x202 then @reg_ie = (@reg_if & 0x00FF) | value.to_u16 << 8
|
||||
when 0x203 then @reg_ie = (@reg_if & 0xFF00) | value
|
||||
when 0x208 then @reg_ime = bit?(value, 0)
|
||||
when 0x209 then @reg_ime = bit?(value, 0)
|
||||
else raise "Unimplemented interrupts write ~ addr:#{hex_str io_addr.to_u8!}, val:#{value}"
|
||||
end
|
||||
end
|
||||
end
|
38
src/crab/mmio.cr
Normal file
38
src/crab/mmio.cr
Normal file
|
@ -0,0 +1,38 @@
|
|||
class MMIO
|
||||
def initialize(@gba : GBA)
|
||||
end
|
||||
|
||||
def [](index : Int) : Byte
|
||||
io_addr = 0x0FFF_u16 & index
|
||||
if io_addr <= 0x05F
|
||||
@gba.ppu.read_io io_addr
|
||||
elsif (io_addr >= 0x200 & io_addr <= 0x203) || (io_addr >= 0x208 && io_addr <= 0x209)
|
||||
@gba.interrupts.read_io io_addr
|
||||
elsif not_used? io_addr
|
||||
0xFF_u8 # todo what is returned here?
|
||||
else
|
||||
raise "Unmapped MMIO read: #{hex_str index.to_u32}"
|
||||
end
|
||||
end
|
||||
|
||||
def []=(index : Int, value : Byte) : Nil
|
||||
io_addr = 0x0FFF_u16 & index
|
||||
if io_addr <= 0x05F
|
||||
@gba.ppu.write_io io_addr, value
|
||||
elsif (io_addr >= 0x200 && io_addr <= 0x203) || (io_addr >= 0x208 && io_addr <= 0x209)
|
||||
@gba.interrupts.write_io io_addr, value
|
||||
elsif not_used? io_addr
|
||||
else
|
||||
raise "Unmapped MMIO write: #{hex_str index.to_u32}"
|
||||
end
|
||||
end
|
||||
|
||||
def not_used?(io_addr : Int) : Bool
|
||||
(0x0E0..0x0FE).includes?(io_addr) || (0x110..0x11E).includes?(io_addr) ||
|
||||
(0x12C..0x12E).includes?(io_addr) || (0x138..0x13E).includes?(io_addr) ||
|
||||
(0x142..0x14E).includes?(io_addr) || (0x15A..0x1FE).includes?(io_addr) ||
|
||||
0x206 == io_addr || (0x20A..0x2FF).includes?(io_addr) ||
|
||||
(0x302..0x40F).includes?(io_addr) || (0x441..0x7FF).includes?(io_addr) ||
|
||||
(0x804..0xFFFF).includes?(io_addr)
|
||||
end
|
||||
end
|
|
@ -28,7 +28,7 @@ class PPU
|
|||
getter pram = Bytes.new 0x400
|
||||
getter vram = Bytes.new 0x18000
|
||||
|
||||
@dispcnt : DISPCNT = DISPCNT.new 0
|
||||
getter dispcnt : DISPCNT = DISPCNT.new 0
|
||||
|
||||
@cycles = 0
|
||||
|
||||
|
@ -43,23 +43,21 @@ class PPU
|
|||
end
|
||||
end
|
||||
|
||||
def [](index : Int) : Byte
|
||||
case index
|
||||
when 0x04000000 then (@dispcnt.value >> 8).to_u8
|
||||
when 0x04000001 then @dispcnt.value.to_u8!
|
||||
when 0x04000002 then 0_u8
|
||||
when 0x04000003 then 0_u8
|
||||
else raise "Unimplemented PPU read ~ addr:#{hex_str index.to_u32}"
|
||||
def read_io(io_addr : Int) : Byte
|
||||
case io_addr
|
||||
when 0x000 then (@dispcnt.value >> 8).to_u8
|
||||
when 0x001 then @dispcnt.value.to_u8!
|
||||
else raise "Unimplemented PPU read ~ addr:#{hex_str io_addr.to_u8}"
|
||||
end
|
||||
end
|
||||
|
||||
def []=(index : Int, value : Byte) : Nil
|
||||
case index
|
||||
when 0x04000000 then @dispcnt.value = (@dispcnt.value & 0x00FF) | value.to_u16 << 8
|
||||
when 0x04000001 then @dispcnt.value = (@dispcnt.value & 0xFF00) | value
|
||||
when 0x04000002
|
||||
when 0x04000003
|
||||
else raise "Unimplemented PPU write ~ addr:#{hex_str index.to_u32}, val:#{value}"
|
||||
def write_io(io_addr : Int, value : Byte) : Nil
|
||||
case io_addr
|
||||
when 0x000 then @dispcnt.value = (@dispcnt.value & 0x00FF) | value.to_u16 << 8
|
||||
when 0x001 then @dispcnt.value = (@dispcnt.value & 0xFF00) | value
|
||||
when 0x002 # undocumented - green swap
|
||||
when 0x003 # undocumented - green swap
|
||||
else raise "Unimplemented PPU write ~ addr:#{hex_str io_addr.to_u8}, val:#{value}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue