1
0
mirror of https://github.com/safiire/n65.git synced 2024-06-02 05:41:36 +00:00
n65/lib/n65/directives/bytes.rb
Saf 18ee1e5d3a
Doing some Refactors (#4)
* Sorted dependancies

* Rearranging

* Added specs to notifiy me if the assembler output
for example files changes while making refactors

Co-authored-by: Saf <saf@irkenkitties.com>
2020-09-07 13:48:39 -07:00

88 lines
2.3 KiB
Ruby

# frozen_string_literal: true
require_relative '../instruction_base'
require_relative '../regexes'
module N65
# This directive to include bytes
class Bytes < InstructionBase
class InvalidByteValue < StandardError; end
# Try to parse an incbin directive
def self.parse(line)
match_data = line.match(/^\.bytes\s+(.+)$/)
return nil if match_data.nil?
bytes_array = match_data[1].split(',').map do |byte_string|
# Does byte_string represent a numeric literal, or is it a symbol?
# In numeric captures $2 is always binary, $1 is always hex
case byte_string.strip
when Regexp.new("^#{Regexes::Num8}$")
$2.nil? ? $1.to_i(16) : $2.to_i(2)
when Regexp.new("^#{Regexes::Num16}$")
value = $2.nil? ? $1.to_i(16) : $2.to_i(2)
# Break value up into two bytes
high = (0xff00 & value) >> 8
low = (0x00ff & value)
[low, high]
when Regexp.new("^#{Regexes::Sym}$")
$1
else
raise(InvalidByteValue, byte_string)
end
end.flatten
Bytes.new(bytes_array)
end
# Initialize with a byte array
def initialize(bytes_array)
@bytes_array = bytes_array
end
# Execute on the assembler
def exec(assembler)
promise = assembler.with_saved_state do |saved_assembler|
@bytes_array.map! do |byte|
case byte
when Integer
byte
when String
saved_assembler.symbol_table.resolve_symbol(byte)
else
raise(InvalidByteValue, byte)
end
end
saved_assembler.write_memory(@bytes_array)
end
begin
promise.call
rescue SymbolTable::UndefinedSymbol
# Write the bytes but assume a zero page address for all symbols
# And just write 0xDE for a placeholder
placeholder_bytes = @bytes_array.map do |byte|
case bytes
when Integer
byte
when String
0xDE
else
raise(InvalidByteValue, byte)
end
end
assembler.write_memory(placeholder_bytes)
promise
end
end
# Display, I don't want to write all these out
def to_s
".bytes (#{@bytes_array.length})"
end
end
end