mirror of
https://github.com/safiire/n65.git
synced 2024-12-12 00:29:03 +00:00
2c938f7312
bank management, Use of promises to resolve symbols that are used before they are defined. A base class for all instructions and assembler directives. Hopefully my scoped symbols can be used to create C like data structures in the zero page, ie sprite.x New code to prodce the final ROM. Basically everything was rewritten.
92 lines
2.2 KiB
Ruby
92 lines
2.2 KiB
Ruby
require_relative '../instruction_base'
|
|
|
|
module Assembler6502
|
|
|
|
|
|
####
|
|
## This directive instruction can include a binary file
|
|
class DW < InstructionBase
|
|
|
|
####
|
|
## Try to parse a dw directive
|
|
def self.parse(line)
|
|
|
|
## Maybe it is a straight up bit of hex
|
|
match_data = line.match(/^\.dw\s+\$([0-9A-F]{1,4})$/)
|
|
unless match_data.nil?
|
|
word = match_data[1].to_i(16)
|
|
return DW.new(word)
|
|
end
|
|
|
|
## Or maybe it points to a symbol
|
|
match_data = line.match(/^\.dw\s+([A-Za-z_][A-Za-z0-9_\.]+)/)
|
|
unless match_data.nil?
|
|
symbol = match_data[1]
|
|
return DW.new(symbol)
|
|
end
|
|
nil
|
|
end
|
|
|
|
|
|
####
|
|
## Initialize with filename
|
|
def initialize(value)
|
|
@value = value
|
|
end
|
|
|
|
|
|
####
|
|
## Execute on the assembler, now in this case value may
|
|
## be a symbol that needs to be resolved, if so we return
|
|
## a lambda which can be executed later, with the promise
|
|
## that that symbol will have then be defined
|
|
## This is a little complicated, I admit.
|
|
def exec(assembler)
|
|
|
|
## Save these current values into the closure
|
|
pc = assembler.program_counter
|
|
segment = assembler.current_segment
|
|
bank = assembler.current_bank
|
|
|
|
## Create a promise, if this symbol is not defined yet.
|
|
promise = lambda do
|
|
value = assembler.symbol_table.resolve_symbol(@value)
|
|
bytes = [value & 0xFFFF].pack('S').bytes
|
|
assembler.write_memory(bytes, pc, segment, bank)
|
|
end
|
|
|
|
## Try to execute it now, or setup the promise to return
|
|
case @value
|
|
when Fixnum
|
|
bytes = [@value & 0xFFFF].pack('S').bytes
|
|
assembler.write_memory(bytes)
|
|
when String
|
|
begin
|
|
promise.call
|
|
rescue SymbolTable::UndefinedSymbol
|
|
## Must still advance PC before returning promise, so we'll write
|
|
## a place holder value of 0xDEAD
|
|
assembler.write_memory([0xDE, 0xAD], pc, segment, bank)
|
|
return promise
|
|
end
|
|
else
|
|
fail("Uknown argument in .dw directive")
|
|
end
|
|
end
|
|
|
|
|
|
####
|
|
## Display
|
|
def to_s
|
|
case @value
|
|
when String
|
|
".dw #{@value}"
|
|
when Fixnum
|
|
".dw $%4.X" % @value
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
end
|