mirror of
https://github.com/mattrberry/crab.git
synced 2025-02-09 08:46:02 +01:00
use a different Slice constructor for luts
This commit is contained in:
parent
37dcb6fcca
commit
120abb5261
2 changed files with 45 additions and 80 deletions
|
@ -20,49 +20,32 @@ module GBA
|
|||
end
|
||||
|
||||
def fill_lut : Slice(Proc(UInt32, Nil))
|
||||
lut = Slice(Proc(UInt32, Nil)).new 4096, ->arm_unimplemented(UInt32)
|
||||
4096.times do |idx|
|
||||
if idx & 0b111100000000 == 0b111100000000
|
||||
lut[idx] = ->arm_software_interrupt(UInt32)
|
||||
elsif idx & 0b111100000001 == 0b111000000001
|
||||
# coprocessor register transfer
|
||||
elsif idx & 0b111100000001 == 0b111000000001
|
||||
# coprocessor data operation
|
||||
elsif idx & 0b111000000000 == 0b110000000000
|
||||
# coprocessor data transfer
|
||||
elsif idx & 0b111000000000 == 0b101000000000
|
||||
lut[idx] = ->arm_branch(UInt32)
|
||||
elsif idx & 0b111000000000 == 0b100000000000
|
||||
lut[idx] = ->arm_block_data_transfer(UInt32)
|
||||
elsif idx & 0b111000000001 == 0b011000000001
|
||||
# undefined
|
||||
elsif idx & 0b110000000000 == 0b010000000000
|
||||
lut[idx] = ->arm_single_data_transfer(UInt32)
|
||||
elsif idx & 0b111111111111 == 0b000100100001
|
||||
lut[idx] = ->arm_branch_exchange(UInt32)
|
||||
elsif idx & 0b111110111111 == 0b000100001001
|
||||
lut[idx] = ->arm_single_data_swap(UInt32)
|
||||
elsif idx & 0b111110001111 == 0b000010001001
|
||||
lut[idx] = ->arm_multiply_long(UInt32)
|
||||
elsif idx & 0b111111001111 == 0b000000001001
|
||||
lut[idx] = ->arm_multiply(UInt32)
|
||||
elsif idx & 0b111001001001 == 0b000001001001
|
||||
lut[idx] = ->arm_halfword_data_transfer_immediate(UInt32)
|
||||
elsif idx & 0b111001001001 == 0b000000001001
|
||||
lut[idx] = ->arm_halfword_data_transfer_register(UInt32)
|
||||
elsif idx & 0b110110010000 == 0b000100000000
|
||||
lut[idx] = ->arm_psr_transfer(UInt32)
|
||||
elsif idx & 0b110000000000 == 0b000000000000
|
||||
lut[idx] = ->arm_data_processing(UInt32)
|
||||
else
|
||||
lut[idx] = ->arm_unused(UInt32)
|
||||
Slice(Proc(UInt32, Nil)).new(4096) do |idx|
|
||||
case
|
||||
when idx & 0b111100000000 == 0b111100000000 then ->arm_software_interrupt(UInt32)
|
||||
when idx & 0b111100000001 == 0b111000000001 then ->arm_unimplemented(UInt32) # coprocessor register transfer
|
||||
when idx & 0b111100000001 == 0b111000000001 then ->arm_unimplemented(UInt32) # coprocessor data operation
|
||||
when idx & 0b111000000000 == 0b110000000000 then ->arm_unimplemented(UInt32) # coprocessor data transfer
|
||||
when idx & 0b111000000000 == 0b101000000000 then ->arm_branch(UInt32)
|
||||
when idx & 0b111000000000 == 0b100000000000 then ->arm_block_data_transfer(UInt32)
|
||||
when idx & 0b111000000001 == 0b011000000001 then ->arm_unimplemented(UInt32) # undefined
|
||||
when idx & 0b110000000000 == 0b010000000000 then ->arm_single_data_transfer(UInt32)
|
||||
when idx & 0b111111111111 == 0b000100100001 then ->arm_branch_exchange(UInt32)
|
||||
when idx & 0b111110111111 == 0b000100001001 then ->arm_single_data_swap(UInt32)
|
||||
when idx & 0b111110001111 == 0b000010001001 then ->arm_multiply_long(UInt32)
|
||||
when idx & 0b111111001111 == 0b000000001001 then ->arm_multiply(UInt32)
|
||||
when idx & 0b111001001001 == 0b000001001001 then ->arm_halfword_data_transfer_immediate(UInt32)
|
||||
when idx & 0b111001001001 == 0b000000001001 then ->arm_halfword_data_transfer_register(UInt32)
|
||||
when idx & 0b110110010000 == 0b000100000000 then ->arm_psr_transfer(UInt32)
|
||||
when idx & 0b110000000000 == 0b000000000000 then ->arm_data_processing(UInt32)
|
||||
else ->arm_unused(UInt32)
|
||||
end
|
||||
end
|
||||
lut
|
||||
end
|
||||
|
||||
def arm_unimplemented(instr : UInt32) : Nil
|
||||
abort "Unimplemented instruction: #{hex_str instr}"
|
||||
# "if true" is a hack until https://github.com/crystal-lang/crystal/issues/12758 is patched
|
||||
abort "Unimplemented instruction: #{hex_str instr}" if true
|
||||
end
|
||||
|
||||
def arm_unused(instr : UInt32) : Nil
|
||||
|
|
|
@ -5,53 +5,35 @@ module GBA
|
|||
end
|
||||
|
||||
def fill_thumb_lut
|
||||
lut = Slice(Proc(UInt32, Nil)).new 256, ->thumb_unimplemented(UInt32)
|
||||
256.times do |idx|
|
||||
if idx & 0b11110000 == 0b11110000
|
||||
lut[idx] = ->thumb_long_branch_link(UInt32)
|
||||
elsif idx & 0b11111000 == 0b11100000
|
||||
lut[idx] = ->thumb_unconditional_branch(UInt32)
|
||||
elsif idx & 0b11111111 == 0b11011111
|
||||
lut[idx] = ->thumb_software_interrupt(UInt32)
|
||||
elsif idx & 0b11110000 == 0b11010000
|
||||
lut[idx] = ->thumb_conditional_branch(UInt32)
|
||||
elsif idx & 0b11110000 == 0b11000000
|
||||
lut[idx] = ->thumb_multiple_load_store(UInt32)
|
||||
elsif idx & 0b11110110 == 0b10110100
|
||||
lut[idx] = ->thumb_push_pop_registers(UInt32)
|
||||
elsif idx & 0b11111111 == 0b10110000
|
||||
lut[idx] = ->thumb_add_offset_to_stack_pointer(UInt32)
|
||||
elsif idx & 0b11110000 == 0b10100000
|
||||
lut[idx] = ->thumb_load_address(UInt32)
|
||||
elsif idx & 0b11110000 == 0b10010000
|
||||
lut[idx] = ->thumb_sp_relative_load_store(UInt32)
|
||||
elsif idx & 0b11110000 == 0b10000000
|
||||
lut[idx] = ->thumb_load_store_halfword(UInt32)
|
||||
elsif idx & 0b11100000 == 0b01100000
|
||||
lut[idx] = ->thumb_load_store_immediate_offset(UInt32)
|
||||
elsif idx & 0b11110010 == 0b01010010
|
||||
lut[idx] = ->thumb_load_store_sign_extended(UInt32)
|
||||
elsif idx & 0b11110010 == 0b01010000
|
||||
lut[idx] = ->thumb_load_store_register_offset(UInt32)
|
||||
elsif idx & 0b11111000 == 0b01001000
|
||||
lut[idx] = ->thumb_pc_relative_load(UInt32)
|
||||
elsif idx & 0b11111100 == 0b01000100
|
||||
lut[idx] = ->thumb_high_reg_branch_exchange(UInt32)
|
||||
elsif idx & 0b11111100 == 0b01000000
|
||||
lut[idx] = ->thumb_alu_operations(UInt32)
|
||||
elsif idx & 0b11100000 == 0b00100000
|
||||
lut[idx] = ->thumb_move_compare_add_subtract(UInt32)
|
||||
elsif idx & 0b11111000 == 0b00011000
|
||||
lut[idx] = ->thumb_add_subtract(UInt32)
|
||||
elsif idx & 0b11100000 == 0b00000000
|
||||
lut[idx] = ->thumb_move_shifted_register(UInt32)
|
||||
Slice(Proc(UInt32, Nil)).new(256) do |idx|
|
||||
case
|
||||
when idx & 0b11110000 == 0b11110000 then ->thumb_long_branch_link(UInt32)
|
||||
when idx & 0b11111000 == 0b11100000 then ->thumb_unconditional_branch(UInt32)
|
||||
when idx & 0b11111111 == 0b11011111 then ->thumb_software_interrupt(UInt32)
|
||||
when idx & 0b11110000 == 0b11010000 then ->thumb_conditional_branch(UInt32)
|
||||
when idx & 0b11110000 == 0b11000000 then ->thumb_multiple_load_store(UInt32)
|
||||
when idx & 0b11110110 == 0b10110100 then ->thumb_push_pop_registers(UInt32)
|
||||
when idx & 0b11111111 == 0b10110000 then ->thumb_add_offset_to_stack_pointer(UInt32)
|
||||
when idx & 0b11110000 == 0b10100000 then ->thumb_load_address(UInt32)
|
||||
when idx & 0b11110000 == 0b10010000 then ->thumb_sp_relative_load_store(UInt32)
|
||||
when idx & 0b11110000 == 0b10000000 then ->thumb_load_store_halfword(UInt32)
|
||||
when idx & 0b11100000 == 0b01100000 then ->thumb_load_store_immediate_offset(UInt32)
|
||||
when idx & 0b11110010 == 0b01010010 then ->thumb_load_store_sign_extended(UInt32)
|
||||
when idx & 0b11110010 == 0b01010000 then ->thumb_load_store_register_offset(UInt32)
|
||||
when idx & 0b11111000 == 0b01001000 then ->thumb_pc_relative_load(UInt32)
|
||||
when idx & 0b11111100 == 0b01000100 then ->thumb_high_reg_branch_exchange(UInt32)
|
||||
when idx & 0b11111100 == 0b01000000 then ->thumb_alu_operations(UInt32)
|
||||
when idx & 0b11100000 == 0b00100000 then ->thumb_move_compare_add_subtract(UInt32)
|
||||
when idx & 0b11111000 == 0b00011000 then ->thumb_add_subtract(UInt32)
|
||||
when idx & 0b11100000 == 0b00000000 then ->thumb_move_shifted_register(UInt32)
|
||||
else ->thumb_unimplemented(UInt32)
|
||||
end
|
||||
end
|
||||
lut
|
||||
end
|
||||
|
||||
def thumb_unimplemented(instr : UInt32) : Nil
|
||||
abort "Unimplemented instruction: #{hex_str instr.to_u16}"
|
||||
# "if true" is a hack until https://github.com/crystal-lang/crystal/issues/12758 is patched
|
||||
abort "Unimplemented instruction: #{hex_str instr.to_u16}" if true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue