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

Intermediate commit

This commit is contained in:
Safiire 2015-02-22 05:59:03 -08:00
parent b94208489b
commit 404934479f
6 changed files with 162 additions and 12 deletions

View File

@ -280,7 +280,7 @@
:boundry_add: false :boundry_add: false
:cpy: :cpy:
:description: "ComPare X register" :description: "ComPare Y register"
:flags: :flags:
- :s - :s
- :c - :c

View File

@ -5,6 +5,9 @@ module Assembler6502
## Let's simulate the entire 0xFFFF addressable memory space ## Let's simulate the entire 0xFFFF addressable memory space
## In the NES, and create reading and writing methods for it. ## In the NES, and create reading and writing methods for it.
class MemorySpace class MemorySpace
INESHeaderSize = 0x10
ProgROMSize = 0x4000
CharROMSize = 0x2000
#### ####
## Create a completely zeroed memory space ## Create a completely zeroed memory space
@ -84,7 +87,6 @@ module Assembler6502
fail(SyntaxError, "Already got ines header") unless @ines_header.nil? fail(SyntaxError, "Already got ines header") unless @ines_header.nil?
@ines_header = parsed_line @ines_header = parsed_line
puts "\tGot iNES Header" puts "\tGot iNES Header"
#memory.write(0x0, parsed_line.emit_bytes)
when Org when Org
address = parsed_line.address address = parsed_line.address
@ -99,22 +101,22 @@ module Assembler6502
puts "\tSaving instruction with unresolved symbols #{parsed_line}, for second pass" puts "\tSaving instruction with unresolved symbols #{parsed_line}, for second pass"
unresolved_instructions << parsed_line unresolved_instructions << parsed_line
else else
puts "\tWriting instruction #{parsed_line} to memory" puts "\tWriting instruction #{parsed_line}"
memory.write(parsed_line.address, parsed_line.emit_bytes) memory.write(parsed_line.address, parsed_line.emit_bytes)
end end
address += parsed_line.length address += parsed_line.length
puts "\tAdvanced address to %X" % address
when IncBin when IncBin
fail("\tI Don't support .incbin yet") puts "\t Including binary file #{parsed_line.filepath}"
memory.write(parsed_line.address, parsed_line.emit_bytes)
address += parsed_line.size
when DW when DW
if parsed_line.unresolved_symbols? if parsed_line.unresolved_symbols?
puts "\tSaving .dw directive with unresolved symbols #{parsed_line}, for second pass" puts "\tSaving #{parsed_line} directive with unresolved symbols, for second pass"
unresolved_instructions << parsed_line unresolved_instructions << parsed_line
else else
puts "\tWriting .dw #{parsed_line.inspect} to memory" puts "\tWriting #{parsed_line} to memory"
memory.write(address, parsed_line.emit_bytes) memory.write(address, parsed_line.emit_bytes)
end end
address += 2 address += 2
@ -136,11 +138,12 @@ module Assembler6502
end end
end end
print "Second pass: Resolving Symbols..." puts "Second pass: Resolving Symbols..."
unresolved_instructions.each do |instruction| unresolved_instructions.each do |instruction|
if instruction.unresolved_symbols? if instruction.unresolved_symbols?
instruction.resolve_symbols(labels) instruction.resolve_symbols(labels)
end end
puts "\tResolved #{instruction}"
memory.write(instruction.address, instruction.emit_bytes) memory.write(instruction.address, instruction.emit_bytes)
end end
puts 'Done' puts 'Done'
@ -155,7 +158,7 @@ module Assembler6502
## I am guessing the ROM size should be 1 bank of 16KB cartridge ROM ## I am guessing the ROM size should be 1 bank of 16KB cartridge ROM
## plus the 16 byte iNES header. If the ROM is written into memory ## plus the 16 byte iNES header. If the ROM is written into memory
## beginning at 0xC000, this should reach right up to the interrupt vectors ## beginning at 0xC000, this should reach right up to the interrupt vectors
def assemble def assemble_old
virtual_memory = assemble_in_virtual_memory virtual_memory = assemble_in_virtual_memory
## First we need to be sure we have an iNES header ## First we need to be sure we have an iNES header
@ -190,6 +193,58 @@ module Assembler6502
#nes_rom.emit_bytes #nes_rom.emit_bytes
end end
####
## Another try at using the header to decide which segments
## go into the final ROM image, and which order.
def assemble
virtual_memory = assemble_in_virtual_memory
## First we need to be sure we have an iNES header
fail(INESHeaderNotFound) if @ines_header.nil?
## Now, we should decide how big the ROM image will be.
## And reserve memory build the image in
nes_rom_size = MemorySpace::INESHeaderSize
nes_rom_size += @ines_header.prog * MemorySpace::ProgROMSize
nes_rom_size += @ines_header.char * MemorySpace::CharROMSize
nes_rom = MemorySpace.new(nes_rom_size)
puts "ROM will be #{nes_rom_size} bytes"
## Write the ines header to the ROM
nes_rom.write(0x0, @ines_header.emit_bytes)
puts "Wrote 16 byte ines header"
## If prog rom is >= 1 write the 16kb chunk from 0x8000
if @ines_header.prog >= 1
nes_rom.write(0x10, virtual_memory.read(0x8000, MemorySpace::ProgROMSize))
puts "Wrote 16KB byte prog rom 1"
end
## If prog rom is == 2 write the 16kb chunk from 0xC000
if @ines_header.prog == 2
nes_rom.write(0x10 + 0x4000, virtual_memory.read(0xC000, MemorySpace::ProgROMSize))
puts "Wrote 16KB byte prog rom 2"
end
fail("Can only have 2 prog rom slots") if @ines_header.prog > 2
## If char rom is >= 1 write the 8kb chunk from 0x0000
if @ines_header.char >= 1
char_start = 0x10 + (@ines_header.prog * MemorySpace::ProgROMSize)
nes_rom.write(char_start, virtual_memory.read(0x0000, MemorySpace::CharROMSize))
puts "Wrote 8KB byte char rom 1"
end
## If char rom is == 2 write the 8kb chunk from 0x2000
if @ines_header.char >= 1
char_start = 0x10 + (@ines_header.prog * MemorySpace::ProgROMSize) + MemorySpace::CharROMSize
nes_rom.write(char_start, virtual_memory.read(0x2000, MemorySpace::CharROMSize))
puts "Wrote 8KB byte char rom 2"
end
nes_rom.emit_bytes
end
end end
end end

View File

@ -49,12 +49,15 @@ module Assembler6502
#### ####
## This is to include a binary file ## This is to include a binary file
class IncBin class IncBin
attr_reader :address, :filepath
class FileNotFound < StandardError; end class FileNotFound < StandardError; end
#### ####
## Initialize with a file path ## Initialize with a file path
def initialize(filepath) def initialize(filepath, address)
@filepath = filepath
@address = address
unless File.exists?(filepath) unless File.exists?(filepath)
fail(FileNotFound, ".incbin can't find #{filepath}") fail(FileNotFound, ".incbin can't find #{filepath}")
end end
@ -97,6 +100,14 @@ module Assembler6502
end end
end end
def to_s
if @value.kind_of?(Symbol)
sprintf("$%.4X | .dw #{@value}", @address)
else
sprintf("$%.4X | .dw $%.4X", @address, @value)
end
end
def emit_bytes def emit_bytes
fail('Need to resolve symbol in .dw directive') if unresolved_symbols? fail('Need to resolve symbol in .dw directive') if unresolved_symbols?
[@value & 0xFFFF].pack('S').bytes [@value & 0xFFFF].pack('S').bytes
@ -155,7 +166,7 @@ module Assembler6502
Org.new($1.to_i(16)) Org.new($1.to_i(16))
when /^\.incbin "([^"]+)"$/ when /^\.incbin "([^"]+)"$/
IncBin.new($1) IncBin.new($1, address)
when /^\.dw\s+\$([0-9A-F]{1,4})$/ when /^\.dw\s+\$([0-9A-F]{1,4})$/
DW.new($1.to_i(16), address) DW.new($1.to_i(16), address)

82
nsf_player.asm Normal file
View File

@ -0,0 +1,82 @@
; Create an iNES header
.ines {"prog": 2, "char": 0, "mapper": 0, "mirror": 1}
; The supermario.nsf file is 17084 bytes, this includes a 0x80 byte header.
; It is supposed to be loaded into memory 0x8000, but we don't want that
; header, so let's include the nsf to 0x8000 - 0x80 so it lines up properly
.org $7F80
.incbin "super_mario.nsf"
; Had to start this prog segment a bit later because the mario nsf is > 16KB
.org $C300
start:
CLD
SEI
LDA #$00
STA $2000
; Wait for 2 vblanks
wait_vb1:
LDA $2002
BPL wait_vb1
wait_vb2:
LDA $2002
BPL wait_vb2
; Clear out the sound registers
LDA #$00
LDX #$00
clear_sound_registers:
STA $4000, X
INX
CPX #$0F
BNE clear_sound_registers
LDA #$10
STA $4010
LDA #$00
STA $4011
STA $4012
STA $4013
; Enable sound channels (except DMC)
LDA #$0F
STA $4015
; Reset frame counter and clock divider
LDA #$C0
STA $4017
; Set song and NTSC
LDA #$00 ; Song 0
LDX #$00 ; NTSC
JSR $8000
; Enable Vblank NMI
LDA #$80
STA $2000
forever:
JMP forever
nmi:
LDA $2002
LDA #$00
STA $2000
LDA $80
STA $2000
JSR $8000
RTI
irq:
RTI
.ascii "The end of prog2"
.org $FFFA
.dw nmi
.dw start
.dw irq

BIN
some_beeps.nsf Normal file

Binary file not shown.

2
whatever.inc Normal file
View File

@ -0,0 +1,2 @@

ޭޭޭޭޭޭޭޭ