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:
@@ -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
|
||||||
.
|
.
|
||||||
|
|
||||||
|
@@ -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
|
||||||
.
|
.
|
||||||
|
|
||||||
|
@@ -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?
|
||||||
|
@@ -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
33
lib/regexes.rb
Normal 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
|
@@ -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
|
||||||
.
|
.
|
||||||
|
Reference in New Issue
Block a user