1
0
mirror of https://github.com/safiire/n65.git synced 2025-08-14 19:27:24 +00:00

Binary literals are now working

This commit is contained in:
Safiire
2015-03-22 15:52:13 -07:00
parent 2d0495fc83
commit ee643af3ef
6 changed files with 120 additions and 50 deletions

View File

@@ -65,17 +65,17 @@
bpl wait_vb2 bpl wait_vb2
; Now we want to initialize the hardware to a known state ; Now we want to initialize the hardware to a known state
lda #$00 lda #%00
ldx #$00 ldx #$00
clear_segments: clear_segments:
sta $00, x sta $0, x
sta $0100, x sta $100, x
sta $0200, x sta $200, x
sta $0300, x sta $300, x
sta $0400, x sta $400, x
sta $0500, x sta $500, x
sta $0600, x sta $600, x
sta $0700, x sta $700, x
inx inx
bne clear_segments bne clear_segments
@@ -85,8 +85,8 @@
; Disable all graphics and vblank nmi ; Disable all graphics and vblank nmi
lda #$00 lda #$00
sta nes.ppu.control1 sta nes.ppu.control
sta nes.ppu.control2 sta nes.ppu.mask
jsr init_graphics jsr init_graphics
jsr init_input jsr init_input
@@ -101,14 +101,30 @@
;;;; ;;;;
; Set basic PPU registers. Load background from $0000, ; nes.ppu.control: bitpattern is VPHB SINN
; sprites from $1000, and the name table from $2000. ; V: NMI enable
; These literals would make more sense in binary. ; P: PPU master/slave (this does nothing on the NES)
; H: Sprite height 0 = 8x8, 1 = 8x16
; B: Background pattern table address (0: $0000; 1: $1000)
; S: Sprite pattern table address for 8x8 sprites (0: $0000; 1: $1000; ignored in 8x16 mode)
; I: VRAM address increment per CPU read/write of nes.vram.io (0: add 1, going across; 1: add 32, going down)
; NN: Base nametable address (0 = $2000; 1 = $2400; 2 = $2800; 3 = $2C00)
;
; Equivalently, bits 0 and 1 are the most significant bit of the scrolling coordinates
;
; nes.ppu.mask: bitpattern is BGRs bMmG
; BGR: Color emphasis bits
; s: Sprite enable
; b: Background enable
; M: Background left column enable
; m: Sprite left column enable
; G: Greyscale
;
.scope init_ppu .scope init_ppu
lda #$88 lda #%10001000 ; NMI enable, 8x8 tile, Background: $0000, Sprites: $1000, Address increment: 1, Nametable: $2000
sta nes.ppu.control1 sta nes.ppu.control
lda #$1E lda #%00011110 ; No color emphasis, Enable sprites, Enable Background, Enable sprite and bg left column, no greyscale
sta nes.ppu.control2 sta nes.ppu.mask
rts rts
. .

View File

@@ -66,8 +66,8 @@
; Disable all graphics and vblank nmi ; Disable all graphics and vblank nmi
lda #$00 lda #$00
sta nes.ppu.control1 sta nes.ppu.control
sta nes.ppu.control2 sta nes.ppu.mask
; Call subroutines to initialize the graphics ; Call subroutines to initialize the graphics
jsr load_palette jsr load_palette
@@ -83,14 +83,30 @@
;;;; ;;;;
; Set basic PPU registers. Load background from $0000, ; nes.ppu.control: bitpattern is VPHB SINN
; sprites from $1000, and the name table from $2000. ; V: NMI enable
; These literals would make more sense in binary. ; P: PPU master/slave (this does nothing on the NES)
; H: Sprite height 0 = 8x8, 1 = 8x16
; B: Background pattern table address (0: $0000; 1: $1000)
; S: Sprite pattern table address for 8x8 sprites (0: $0000; 1: $1000; ignored in 8x16 mode)
; I: VRAM address increment per CPU read/write of nes.vram.io (0: add 1, going across; 1: add 32, going down)
; NN: Base nametable address (0 = $2000; 1 = $2400; 2 = $2800; 3 = $2C00)
;
; Equivalently, bits 0 and 1 are the most significant bit of the scrolling coordinates
;
; nes.ppu.mask: bitpattern is BGRs bMmG
; BGR: Color emphasis bits
; s: Sprite enable
; b: Background enable
; M: Background left column enable
; m: Sprite left column enable
; G: Greyscale
;
.scope init_ppu .scope init_ppu
lda #$88 lda #%10001000 ; NMI enable, 8x8 tile, Background: $0000, Sprites: $1000, Address increment: 1, Nametable: $2000
sta nes.ppu.control1 sta nes.ppu.control
lda #$1E lda #%00011110 ; No color emphasis, Enable sprites, Enable Background, Enable sprite and bg left column, no greyscale
sta nes.ppu.control2 sta nes.ppu.mask
rts rts
. .

View File

@@ -1,4 +1,5 @@
require_relative 'opcodes' require_relative 'opcodes'
require_relative 'regexes'
module Assembler6502 module Assembler6502
@@ -14,14 +15,8 @@ module Assembler6502
class AddressOutOfRange < StandardError; end class AddressOutOfRange < StandardError; end
class ArgumentTooLarge < StandardError; end class ArgumentTooLarge < StandardError; end
Mnemonic = '([A-Za-z]{3})' ## Include Regexes
Hex8 = '\$([A-Fa-f0-9]{2})' include Regexes
Hex16 = '\$([A-Fa-f0-9]{4})'
Immediate = '\#\$([0-9A-Fa-f]{2})'
Sym = '([a-zZ-Z_][a-zA-Z0-9_\.]+)'
Branches = '(BPL|BMI|BVC|BVS|BCC|BCS|BNE|BEQ|bpl|bmi|bvc|bvs|bcc|bcs|bne|beq)'
XReg = '[Xx]'
YReg = '[Yy]'
AddressingModes = { AddressingModes = {
:relative => { :relative => {
@@ -47,63 +42,63 @@ module Assembler6502
:zero_page => { :zero_page => {
:example => 'AAA $FF', :example => 'AAA $FF',
:display => '%s $%.2X', :display => '%s $%.2X',
:regex => /^#{Mnemonic}\s+#{Hex8}$/, :regex => /^#{Mnemonic}\s+#{Num8}$/,
:regex_label => /^#{Mnemonic}\s+#{Sym}\s+zp$/ :regex_label => /^#{Mnemonic}\s+#{Sym}\s+zp$/
}, },
:zero_page_x => { :zero_page_x => {
:example => 'AAA $FF, X', :example => 'AAA $FF, X',
:display => '%s $%.2X, X', :display => '%s $%.2X, X',
:regex => /^#{Mnemonic}\s+#{Hex8}\s?,\s?#{XReg}$/, :regex => /^#{Mnemonic}\s+#{Num8}\s?,\s?#{XReg}$/,
:regex_label => /^#{Mnemonic}\s+#{Sym}\s?,\s?#{XReg}\s+zp$/ :regex_label => /^#{Mnemonic}\s+#{Sym}\s?,\s?#{XReg}\s+zp$/
}, },
:zero_page_y => { :zero_page_y => {
:example => 'AAA $FF, Y', :example => 'AAA $FF, Y',
:display => '%s $%.2X, Y', :display => '%s $%.2X, Y',
:regex => /^#{Mnemonic}\s+#{Hex8}\s?,\s?#{YReg}$/, :regex => /^#{Mnemonic}\s+#{Num8}\s?,\s?#{YReg}$/,
:regex_label => /^#{Mnemonic}\s+#{Sym}\s?,\s?#{YReg} zp$/ :regex_label => /^#{Mnemonic}\s+#{Sym}\s?,\s?#{YReg} zp$/
}, },
:absolute => { :absolute => {
:example => 'AAA $FFFF', :example => 'AAA $FFFF',
:display => '%s $%.4X', :display => '%s $%.4X',
:regex => /^#{Mnemonic}\s+#{Hex16}$/, :regex => /^#{Mnemonic}\s+#{Num16}$/,
:regex_label => /^#{Mnemonic}\s+#{Sym}$/ :regex_label => /^#{Mnemonic}\s+#{Sym}$/
}, },
:absolute_x => { :absolute_x => {
:example => 'AAA $FFFF, X', :example => 'AAA $FFFF, X',
:display => '%s $%.4X, X', :display => '%s $%.4X, X',
:regex => /^#{Mnemonic}\s+#{Hex16}\s?,\s?#{XReg}$/, :regex => /^#{Mnemonic}\s+#{Num16}\s?,\s?#{XReg}$/,
:regex_label => /^#{Mnemonic}\s+#{Sym}\s?,\s?#{XReg}$/ :regex_label => /^#{Mnemonic}\s+#{Sym}\s?,\s?#{XReg}$/
}, },
:absolute_y => { :absolute_y => {
:example => 'AAA $FFFF, Y', :example => 'AAA $FFFF, Y',
:display => '%s $%.4X, Y', :display => '%s $%.4X, Y',
:regex => /^#{Mnemonic}\s+#{Hex16}\s?,\s?#{YReg}$/, :regex => /^#{Mnemonic}\s+#{Num16}\s?,\s?#{YReg}$/,
:regex_label => /^#{Mnemonic}\s+#{Sym}\s?,\s?#{YReg}$/ :regex_label => /^#{Mnemonic}\s+#{Sym}\s?,\s?#{YReg}$/
}, },
:indirect => { :indirect => {
:example => 'AAA ($FFFF)', :example => 'AAA ($FFFF)',
:display => '%s ($%.4X)', :display => '%s ($%.4X)',
:regex => /^#{Mnemonic}\s+\(#{Hex16}\)$/, :regex => /^#{Mnemonic}\s+\(#{Num16}\)$/,
:regex_label => /^#{Mnemonic}\s+\(#{Sym}\)$/ :regex_label => /^#{Mnemonic}\s+\(#{Sym}\)$/
}, },
:indirect_x => { :indirect_x => {
:example => 'AAA ($FF, X)', :example => 'AAA ($FF, X)',
:display => '%s ($%.2X, X)', :display => '%s ($%.2X, X)',
:regex => /^#{Mnemonic}\s+\(#{Hex8}\s?,\s?#{XReg}\)$/, :regex => /^#{Mnemonic}\s+\(#{Num8}\s?,\s?#{XReg}\)$/,
:regex_label => /^#{Mnemonic}\s+\(#{Sym}\s?,\s?#{XReg}\)$/ :regex_label => /^#{Mnemonic}\s+\(#{Sym}\s?,\s?#{XReg}\)$/
}, },
:indirect_y => { :indirect_y => {
:example => 'AAA ($FF), Y)', :example => 'AAA ($FF), Y)',
:display => '%s ($%.2X), Y', :display => '%s ($%.2X), Y',
:regex => /^#{Mnemonic}\s+\(#{Hex8}\)\s?,\s?#{YReg}$/, :regex => /^#{Mnemonic}\s+\(#{Num8}\)\s?,\s?#{YReg}$/,
:regex_label => /^#{Mnemonic}\s+\(#{Sym}\)\s?,\s?#{YReg}$/ :regex_label => /^#{Mnemonic}\s+\(#{Sym}\)\s?,\s?#{YReg}$/
} }
} }
@@ -123,9 +118,18 @@ module Assembler6502
unless match_data.nil? unless match_data.nil?
## We must have a straight instruction without symbols, construct ## We must have a straight instruction without symbols, construct
## an Instruction from the match_data, and return it ## an Instruction from the match_data, and return it
_, op, arg = match_data.to_a _, op, arg_hex, arg_bin = match_data.to_a
arg = arg.to_i(16) unless arg.nil?
return Instruction.new(op, arg, mode) ## Until I think of something better, it seems that the union regex
## puts a hexidecimal argument in one capture, and a binary in the next
## This is annoying, but still not as annoying as using Treetop to parse
if arg_hex != nil
return Instruction.new(op, arg_hex.to_i(16), mode)
elsif arg_bin != nil
return Instruction.new(op, arg_bin.to_i(2), mode)
else
return Instruction.new(op, nil, mode)
end
else else
## Can this addressing mode even use labels? ## Can this addressing mode even use labels?

View File

@@ -16,6 +16,7 @@ module Assembler6502
require_relative 'directives/space' require_relative 'directives/space'
#### ####
## This class determines what sort of line of code we ## This class determines what sort of line of code we
## are dealing with, parses one line, and returns an ## are dealing with, parses one line, and returns an

33
lib/regexes.rb Normal file
View File

@@ -0,0 +1,33 @@
module Assembler6502
####
## All the regexes used to parse in one module
module Regexes
## Mnemonics
Mnemonic = '([A-Za-z]{3})'
Branches = '(BPL|BMI|BVC|BVS|BCC|BCS|BNE|BEQ|bpl|bmi|bvc|bvs|bcc|bcs|bne|beq)'
## Numeric Literals
Hex8 = '\$([A-Fa-f0-9]{1,2})'
Hex16 = '\$([A-Fa-f0-9]{3,4})'
Bin8 = '%([01]{1,8})'
Bin16 = '%([01]{9,16})'
Num8 = Regexp.union(Regexp.new(Hex8), Regexp.new(Bin8)).to_s
Num16 = Regexp.union(Regexp.new(Hex16),Regexp.new(Bin16)).to_s
Immediate = "\##{Num8}"
## Symbols, must begin with a letter, and supports dot syntax
Sym = '([a-zA-Z][a-zA-Z\d_\.]*)'
## The X or Y register
XReg = '[Xx]'
YReg = '[Yy]'
end
end

View File

@@ -13,9 +13,9 @@
.scope nes .scope nes
.scope ppu .scope ppu
.org $2000 .org $2000
.space control1 1 ; $2000 .space control 1 ; $2000
.space control2 1 ; $2001 .space mask 1 ; $2001
.space status 1 ; $2002 .space status 1 ; $2002
.org $2005 .org $2005
.space scroll 1 ; $2005 .space scroll 1 ; $2005
. .