mirror of
https://github.com/safiire/n65.git
synced 2025-01-19 00:29:59 +00:00
Linted memory_space.rb
This commit is contained in:
parent
963dab73cc
commit
b61003d489
@ -194,8 +194,8 @@ module N65
|
||||
chars = @virtual_memory[:char]
|
||||
|
||||
rom_size = 0x10
|
||||
rom_size += MemorySpace::BankSizes[:prog] * progs.size
|
||||
rom_size += MemorySpace::BankSizes[:char] * chars.size
|
||||
rom_size += MemorySpace::BANK_SIZES[:prog] * progs.size
|
||||
rom_size += MemorySpace::BANK_SIZES[:char] * chars.size
|
||||
|
||||
rom = MemorySpace.new(rom_size, :rom)
|
||||
|
||||
@ -203,11 +203,11 @@ module N65
|
||||
offset += rom.write(0x0, @ines_header.emit_bytes)
|
||||
|
||||
progs.each do |prog|
|
||||
offset += rom.write(offset, prog.read(0x8000, MemorySpace::BankSizes[:prog]))
|
||||
offset += rom.write(offset, prog.read(0x8000, MemorySpace::BANK_SIZES[:prog]))
|
||||
end
|
||||
|
||||
chars.each do |char|
|
||||
offset += rom.write(offset, char.read(0x0, MemorySpace::BankSizes[:char]))
|
||||
offset += rom.write(offset, char.read(0x0, MemorySpace::BANK_SIZES[:char]))
|
||||
end
|
||||
rom.emit_bytes.pack('C*')
|
||||
end
|
||||
|
@ -240,7 +240,7 @@ module N65
|
||||
when 1
|
||||
[@hex]
|
||||
when 2
|
||||
if zero_page_instruction? && @arg.netagive? || @arg > 0xff
|
||||
if zero_page_instruction? && @arg.negative? || @arg > 0xff
|
||||
raise(ArgumentTooLarge, "For #{@op} in #{@mode} mode, only 8-bit values are allowed")
|
||||
end
|
||||
|
||||
|
@ -1,59 +1,42 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module N65
|
||||
|
||||
####
|
||||
## Let's use this to simulate a virtual address space
|
||||
## Either a 16kb prog rom or 8kb char rom space.
|
||||
## It can also be used to create arbitrary sized spaces
|
||||
## for example to build the final binary ROM in.
|
||||
# Let's use this to simulate a virtual address space
|
||||
# Either a 16kb prog rom or 8kb char rom space.
|
||||
# It can also be used to create arbitrary sized spaces
|
||||
# for example to build the final binary ROM in.
|
||||
class MemorySpace
|
||||
|
||||
#### Custom exceptions
|
||||
class AccessOutsideProgRom < StandardError; end
|
||||
class AccessOutsideCharRom < StandardError; end
|
||||
class AccessOutOfBounds < StandardError; end
|
||||
|
||||
# Some constants, the size of PROG and CHAR ROM
|
||||
BANK_SIZES = {
|
||||
ines: 0x10,
|
||||
prog: 0x4000,
|
||||
char: 0x2000
|
||||
}.freeze
|
||||
|
||||
#### Some constants, the size of PROG and CHAR ROM
|
||||
BankSizes = {
|
||||
:ines => 0x10, # 16b
|
||||
:prog => 0x4000, # 16kb
|
||||
:char => 0x2000, # 8kb
|
||||
}
|
||||
|
||||
|
||||
####
|
||||
## Create a new PROG ROM
|
||||
def self.create_prog_rom
|
||||
self.create_bank(:prog)
|
||||
create_bank(:prog)
|
||||
end
|
||||
|
||||
|
||||
####
|
||||
## Create a new CHAR ROM
|
||||
def self.create_char_rom
|
||||
self.create_bank(:char)
|
||||
create_bank(:char)
|
||||
end
|
||||
|
||||
|
||||
####
|
||||
## Create a new bank
|
||||
def self.create_bank(type)
|
||||
self.new(BankSizes[type], type)
|
||||
new(BANK_SIZES[type], type)
|
||||
end
|
||||
|
||||
|
||||
####
|
||||
## Create a completely zeroed memory space
|
||||
# Create a completely zeroed memory space
|
||||
def initialize(size, type)
|
||||
@type = type
|
||||
@memory = Array.new(size, 0x0)
|
||||
@bytes_written = 0
|
||||
end
|
||||
|
||||
|
||||
####
|
||||
## Normalized read from memory
|
||||
# Normalized read from memory
|
||||
def read(address, count)
|
||||
from_normalized = normalize_address(address)
|
||||
to_normalized = normalize_address(address + (count - 1))
|
||||
@ -62,9 +45,7 @@ module N65
|
||||
@memory[from_normalized..to_normalized]
|
||||
end
|
||||
|
||||
|
||||
####
|
||||
## Normalized write to memory
|
||||
# Normalized write to memory
|
||||
def write(address, bytes)
|
||||
from_normalized = normalize_address(address)
|
||||
to_normalized = normalize_address(address + bytes.size - 1)
|
||||
@ -77,87 +58,65 @@ module N65
|
||||
bytes.size
|
||||
end
|
||||
|
||||
|
||||
####
|
||||
## Return the memory as an array of bytes to write to disk
|
||||
# Return the memory as an array of bytes to write to disk
|
||||
def emit_bytes
|
||||
@memory
|
||||
end
|
||||
|
||||
|
||||
####
|
||||
## Bank Usage information
|
||||
# Bank Usage information
|
||||
def usage_info
|
||||
percent_used = @bytes_written / @memory.size.to_f * 100
|
||||
percent_string = "%0.2f" % percent_used
|
||||
bytes_written_hex = "$%04x" % @bytes_written
|
||||
memory_size_hex = "$%04x" % @memory.size
|
||||
percent_string = format('%0.2f', percent_used)
|
||||
bytes_written_hex = format('$%04x', @bytes_written)
|
||||
memory_size_hex = format('$%04x', @memory.size)
|
||||
"(#{bytes_written_hex} / #{memory_size_hex}) #{percent_string}%"
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
####
|
||||
## Are the given addresses in bounds? If not blow up.
|
||||
# Are the given addresses in bounds? If not blow up.
|
||||
def ensure_addresses_in_bounds!(addresses)
|
||||
addresses.each do |address|
|
||||
unless address >= 0 && address < @memory.size
|
||||
fail(AccessOutOfBounds, sprintf("Address $%.4X is out of bounds in this #{@type} bank"))
|
||||
raise(AccessOutOfBounds, format("Address $%.4X is out of bounds in this #{@type} bank"))
|
||||
end
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
|
||||
####
|
||||
## Since prog rom can be loaded at either 0x8000 or 0xC000
|
||||
## We should normalize the addresses to fit properly into
|
||||
## these banks, basically it acts like it is mirroring addresses
|
||||
## in those segments. Char rom doesn't need this. This will also
|
||||
## fail if you are accessing outside of the address space.
|
||||
# Since prog rom can be loaded at either 0x8000 or 0xC000
|
||||
# We should normalize the addresses to fit properly into
|
||||
# these banks, basically it acts like it is mirroring addresses
|
||||
# in those segments. Char rom doesn't need this. This will also
|
||||
# fail if you are accessing outside of the address space.
|
||||
def normalize_address(address)
|
||||
case @type
|
||||
when :prog
|
||||
if address_inside_prog_rom1?(address)
|
||||
return address - 0x8000
|
||||
end
|
||||
if address_inside_prog_rom2?(address)
|
||||
return address - 0xC000
|
||||
end
|
||||
fail(AccessOutsideProgRom, sprintf("Address $%.4X is outside PROG ROM", address))
|
||||
return (address - 0x8000) if address_inside_prog_rom1?(address)
|
||||
return (address - 0xC000) if address_inside_prog_rom2?(address)
|
||||
|
||||
raise(AccessOutsideProgRom, format('Address $%.4X is outside PROG ROM', address))
|
||||
when :char
|
||||
unless address_inside_char_rom?(address)
|
||||
fail(AccessOutsideCharRom, sprintf("Address $%.4X is outside CHAR ROM", address))
|
||||
raise(AccessOutsideCharRom, format('Address $%.4X is outside CHAR ROM', address))
|
||||
end
|
||||
return address
|
||||
|
||||
address
|
||||
else
|
||||
return address
|
||||
address
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
####
|
||||
## Is this address inside the prog rom 1 area?
|
||||
def address_inside_prog_rom1?(address)
|
||||
address >= 0x8000 && address < 0xC000
|
||||
end
|
||||
|
||||
|
||||
####
|
||||
## Is this address inside the prog rom 2 area?
|
||||
def address_inside_prog_rom2?(address)
|
||||
address >= 0xC000 && address <= 0xffff
|
||||
end
|
||||
|
||||
|
||||
####
|
||||
## Is this address inside the char rom area?
|
||||
def address_inside_char_rom?(address)
|
||||
address >= 0x0000 && address <= 0x1fff
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user