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
; Now we want to initialize the hardware to a known state
lda #$00
lda #%00
ldx #$00
clear_segments:
sta $00, x
sta $0100, x
sta $0200, x
sta $0300, x
sta $0400, x
sta $0500, x
sta $0600, x
sta $0700, x
sta $0, x
sta $100, x
sta $200, x
sta $300, x
sta $400, x
sta $500, x
sta $600, x
sta $700, x
inx
bne clear_segments
@ -85,8 +85,8 @@
; Disable all graphics and vblank nmi
lda #$00
sta nes.ppu.control1
sta nes.ppu.control2
sta nes.ppu.control
sta nes.ppu.mask
jsr init_graphics
jsr init_input
@ -101,14 +101,30 @@
;;;;
; Set basic PPU registers. Load background from $0000,
; sprites from $1000, and the name table from $2000.
; These literals would make more sense in binary.
; nes.ppu.control: bitpattern is VPHB SINN
; V: NMI enable
; 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
lda #$88
sta nes.ppu.control1
lda #$1E
sta nes.ppu.control2
lda #%10001000 ; NMI enable, 8x8 tile, Background: $0000, Sprites: $1000, Address increment: 1, Nametable: $2000
sta nes.ppu.control
lda #%00011110 ; No color emphasis, Enable sprites, Enable Background, Enable sprite and bg left column, no greyscale
sta nes.ppu.mask
rts
.

View File

@ -66,8 +66,8 @@
; Disable all graphics and vblank nmi
lda #$00
sta nes.ppu.control1
sta nes.ppu.control2
sta nes.ppu.control
sta nes.ppu.mask
; Call subroutines to initialize the graphics
jsr load_palette
@ -83,14 +83,30 @@
;;;;
; Set basic PPU registers. Load background from $0000,
; sprites from $1000, and the name table from $2000.
; These literals would make more sense in binary.
; nes.ppu.control: bitpattern is VPHB SINN
; V: NMI enable
; 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
lda #$88
sta nes.ppu.control1
lda #$1E
sta nes.ppu.control2
lda #%10001000 ; NMI enable, 8x8 tile, Background: $0000, Sprites: $1000, Address increment: 1, Nametable: $2000
sta nes.ppu.control
lda #%00011110 ; No color emphasis, Enable sprites, Enable Background, Enable sprite and bg left column, no greyscale
sta nes.ppu.mask
rts
.

View File

@ -1,4 +1,5 @@
require_relative 'opcodes'
require_relative 'regexes'
module Assembler6502
@ -14,14 +15,8 @@ module Assembler6502
class AddressOutOfRange < StandardError; end
class ArgumentTooLarge < StandardError; end
Mnemonic = '([A-Za-z]{3})'
Hex8 = '\$([A-Fa-f0-9]{2})'
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]'
## Include Regexes
include Regexes
AddressingModes = {
:relative => {
@ -47,63 +42,63 @@ module Assembler6502
:zero_page => {
:example => 'AAA $FF',
:display => '%s $%.2X',
:regex => /^#{Mnemonic}\s+#{Hex8}$/,
:regex => /^#{Mnemonic}\s+#{Num8}$/,
:regex_label => /^#{Mnemonic}\s+#{Sym}\s+zp$/
},
:zero_page_x => {
:example => 'AAA $FF, 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$/
},
:zero_page_y => {
:example => 'AAA $FF, 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$/
},
:absolute => {
:example => 'AAA $FFFF',
:display => '%s $%.4X',
:regex => /^#{Mnemonic}\s+#{Hex16}$/,
:regex => /^#{Mnemonic}\s+#{Num16}$/,
:regex_label => /^#{Mnemonic}\s+#{Sym}$/
},
:absolute_x => {
:example => 'AAA $FFFF, 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}$/
},
:absolute_y => {
:example => 'AAA $FFFF, 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}$/
},
:indirect => {
:example => 'AAA ($FFFF)',
:display => '%s ($%.4X)',
:regex => /^#{Mnemonic}\s+\(#{Hex16}\)$/,
:regex => /^#{Mnemonic}\s+\(#{Num16}\)$/,
:regex_label => /^#{Mnemonic}\s+\(#{Sym}\)$/
},
:indirect_x => {
:example => 'AAA ($FF, 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}\)$/
},
:indirect_y => {
:example => 'AAA ($FF), 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}$/
}
}
@ -123,9 +118,18 @@ module Assembler6502
unless match_data.nil?
## We must have a straight instruction without symbols, construct
## an Instruction from the match_data, and return it
_, op, arg = match_data.to_a
arg = arg.to_i(16) unless arg.nil?
return Instruction.new(op, arg, mode)
_, op, arg_hex, arg_bin = match_data.to_a
## 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
## Can this addressing mode even use labels?

View File

@ -16,6 +16,7 @@ module Assembler6502
require_relative 'directives/space'
####
## This class determines what sort of line of code we
## 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 ppu
.org $2000
.space control1 1 ; $2000
.space control2 1 ; $2001
.space status 1 ; $2002
.space control 1 ; $2000
.space mask 1 ; $2001
.space status 1 ; $2002
.org $2005
.space scroll 1 ; $2005
.