From 8752d7afac7d6c3aaf6ae21091e2da7b22a32a83 Mon Sep 17 00:00:00 2001 From: Safiire Date: Sun, 22 Feb 2015 22:49:30 -0800 Subject: [PATCH] A kind of better ROM assembly... --- lib/assembler.rb | 89 +++++++++++++++++++++++------------------------ nsf_player.asm | 82 ------------------------------------------- some_beeps.nsf | Bin 5931 -> 0 bytes 3 files changed, 44 insertions(+), 127 deletions(-) delete mode 100644 nsf_player.asm delete mode 100644 some_beeps.nsf diff --git a/lib/assembler.rb b/lib/assembler.rb index a407877..f069283 100644 --- a/lib/assembler.rb +++ b/lib/assembler.rb @@ -158,7 +158,7 @@ module Assembler6502 ## 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 ## beginning at 0xC000, this should reach right up to the interrupt vectors - def assemble + def assemble_old virtual_memory = assemble_in_virtual_memory ## First we need to be sure we have an iNES header @@ -195,54 +195,53 @@ module Assembler6502 #### - ## This is all crap, I must research how banks and mappers work - #def assemble_new_crap - # virtual_memory = assemble_in_virtual_memory + ## New ROM assembly, this is so simplified, and needs to take banks into account + ## This will happen once I fully understand mappers and banks. + def assemble + ## Assemble into a virtual memory space + virtual_memory = assemble_in_virtual_memory - # ## First we need to be sure we have an iNES header - # fail(INESHeaderNotFound) if @ines_header.nil? + ## 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" + ## Now we want to create a ROM layout for PROG + ## This is simplified and only holds max two PROG entries + prog_rom = MemorySpace.new(@ines_header.prog * MemorySpace::ProgROMSize) + case @ines_header.prog + when 0 + fail("You must have at least one PROG section") + exit(1) + when 1 + prog_rom.write(0x0, virtual_memory.read(0xc000, MemorySpace::ProgROMSize)) + when 2 + prog_rom.write(0x0, virtual_memory.read(0x8000, MemorySpace::ProgROMSize)) + prog_rom.write(MemorySpace::ProgROMSize, virtual_memory.read(0xC000, MemorySpace::ProgROMSize)) + else + fail("I can't support more than 2 PROG sections") + exit(1) + end - # ## Write the ines header to the ROM - # nes_rom.write(0x0, @ines_header.emit_bytes) - # puts "Wrote 16 byte ines header" + ## Now we want to create a ROM layout for CHAR + ## This is simplified and only holds max two CHAR entries + char_rom = MemorySpace.new(@ines_header.char * MemorySpace::CharROMSize) + case @ines_header.char + when 0 + when 1 + char_rom.write(0x0, virtual_memory.read(0x0000, MemorySpace::CharROMSize)) + when 2 + char_rom.write(0x0, virtual_memory.read(0x0000, MemorySpace::CharROMSize)) + char_rom.write(MemorySpace::CharROMSize, virtual_memory.read(0x2000, MemorySpace::CharROMSize)) + else + fail("I can't support more than 2 CHAR sections") + exit(1) + end - # ## 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 == 2 - #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 + if @ines_header.char.zero? + @ines_header.emit_bytes + prog_rom.emit_bytes + else + @ines_header.emit_bytes + prog_rom.emit_bytes + char_rom.emit_bytes + end + end end diff --git a/nsf_player.asm b/nsf_player.asm deleted file mode 100644 index 92b0ae1..0000000 --- a/nsf_player.asm +++ /dev/null @@ -1,82 +0,0 @@ -; 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 - diff --git a/some_beeps.nsf b/some_beeps.nsf deleted file mode 100644 index eb1ada8721c2efbdf9cc374bff2a31cfded068a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5931 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 M{owEVw%ud?A6irrUjP6A