1
0
mirror of https://github.com/safiire/n65.git synced 2024-12-12 00:29:03 +00:00

Improvement to the .bytes directive, can now take hex literals, binary literals, and symbols both zero page and 16-bit

This commit is contained in:
Safiire 2015-03-29 09:42:40 -07:00
parent 2736408a14
commit dc60139aaa
2 changed files with 79 additions and 25 deletions

View File

@ -1,4 +1,5 @@
require_relative '../instruction_base'
require_relative '../regexes.rb'
module Assembler6502
@ -7,6 +8,10 @@ module Assembler6502
## This directive to include bytes
class Bytes < InstructionBase
#### Custom Exceptions
class InvalidByteValue < StandardError; end
####
## Try to parse an incbin directive
def self.parse(line)
@ -14,11 +19,27 @@ module Assembler6502
return nil if match_data.nil?
bytes_array = match_data[1].split(',').map do |byte_string|
number = byte_string.gsub('$', '')
integer = number.to_i(16)
fail(SyntaxError, "#{integer} is too large for one byte") if integer > 0xff
integer
end
## 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
fail(InvalidByteValue, byte_string)
end
end.flatten
Bytes.new(bytes_array)
end
@ -34,7 +55,39 @@ module Assembler6502
####
## Execute on the assembler
def exec(assembler)
assembler.write_memory(@bytes_array)
promise = assembler.with_saved_state do |saved_assembler|
@bytes_array.map! do |byte|
case byte
when Fixnum
byte
when String
value = saved_assembler.symbol_table.resolve_symbol(byte)
else
fail(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 Fixnum
byte
when String
0xDE
else
fail(InvalidByteValue, byte)
end
end
assembler.write_memory(placeholder_bytes)
return promise
end
end

View File

@ -79,20 +79,6 @@
sta nes.ppu.control
sta nes.ppu.mask
; Initialize sound engine structure
; To read from $D000, and to write to $40**
lda #>music_buffer
sta sound_engine.stream_read_ptr_hi
lda #<music_buffer
sta sound_engine.stream_read_ptr_lo
; Make the first delta happen immediately
lda #$01
sta sound_engine.delta
lda #$40
sta sound_engine.stream_write_ptr_hi
jsr init_sound
; Resume interrupts and NMI and loop here forever
@ -106,13 +92,28 @@
;;;;
; Initialize the APU to enable Pulse1
; Bitfield: ---D NT21
.scope init_sound
lda #$00
sta nes.apu.pulse1.control
sta nes.apu.pulse1.ramp_control
sta nes.apu.pulse1.ft
sta nes.apu.pulse1.ct
ldy #$00
clear_apu:
sta nes.apu, y
iny
cpy #$10
bne clear_apu
lda #>music_buffer
ldx #<music_buffer
sta sound_engine.stream_read_ptr_hi
stx sound_engine.stream_read_ptr_lo
lda #$40
ldx #$00
sta sound_engine.stream_write_ptr_hi
stx sound_engine.stream_write_ptr_lo
lda #$01
sta sound_engine.delta
lda #$01
sta nes.apu.channel_enable
rts