2018-08-18 14:21:18 +00:00
|
|
|
|
2018-08-03 18:06:08 +00:00
|
|
|
processor 6502
|
|
|
|
|
|
|
|
;;;;; CONSTANTS
|
|
|
|
|
2018-08-05 14:00:53 +00:00
|
|
|
PPU_CTRL = $2000
|
|
|
|
PPU_MASK = $2001
|
|
|
|
PPU_STATUS = $2002
|
|
|
|
OAM_ADDR = $2003
|
|
|
|
OAM_DATA = $2004
|
|
|
|
PPU_SCROLL = $2005
|
|
|
|
PPU_ADDR = $2006
|
|
|
|
PPU_DATA = $2007
|
|
|
|
|
|
|
|
PPU_OAM_DMA = $4014
|
|
|
|
DMC_FREQ = $4010
|
|
|
|
APU_STATUS = $4015
|
|
|
|
APU_NOISE_VOL = $400C
|
|
|
|
APU_NOISE_FREQ = $400E
|
|
|
|
APU_NOISE_TIMER = $400F
|
|
|
|
APU_DMC_CTRL = $4010
|
|
|
|
APU_CHAN_CTRL = $4015
|
|
|
|
APU_FRAME = $4017
|
|
|
|
|
2019-02-21 19:19:29 +00:00
|
|
|
JOYPAD1 = $4016
|
|
|
|
JOYPAD2 = $4017
|
|
|
|
|
2018-08-05 14:00:53 +00:00
|
|
|
; NOTE: I've put this outside of the PPU & APU, because it is a feature
|
|
|
|
; of the APU that is primarily of use to the PPU.
|
|
|
|
OAM_DMA = $4014
|
|
|
|
; OAM local RAM copy goes from $0200-$02FF:
|
|
|
|
OAM_RAM = $0200
|
2018-08-03 18:06:08 +00:00
|
|
|
|
2018-08-13 22:17:36 +00:00
|
|
|
; PPU_CTRL flags
|
|
|
|
CTRL_NMI = %10000000 ; Execute Non-Maskable Interrupt on VBlank
|
|
|
|
CTRL_8x8 = %00000000 ; Use 8x8 Sprites
|
|
|
|
CTRL_8x16 = %00100000 ; Use 8x16 Sprites
|
|
|
|
CTRL_BG_0000 = %00000000 ; Background Pattern Table at $0000 in VRAM
|
|
|
|
CTRL_BG_1000 = %00010000 ; Background Pattern Table at $1000 in VRAM
|
|
|
|
CTRL_SPR_0000 = %00000000 ; Sprite Pattern Table at $0000 in VRAM
|
|
|
|
CTRL_SPR_1000 = %00001000 ; Sprite Pattern Table at $1000 in VRAM
|
|
|
|
CTRL_INC_1 = %00000000 ; Increment PPU Address by 1 (Horizontal rendering)
|
|
|
|
CTRL_INC_32 = %00000100 ; Increment PPU Address by 32 (Vertical rendering)
|
|
|
|
CTRL_NT_2000 = %00000000 ; Name Table Address at $2000
|
|
|
|
CTRL_NT_2400 = %00000001 ; Name Table Address at $2400
|
|
|
|
CTRL_NT_2800 = %00000010 ; Name Table Address at $2800
|
|
|
|
CTRL_NT_2C00 = %00000011 ; Name Table Address at $2C00
|
|
|
|
|
|
|
|
; PPU_MASK flags
|
|
|
|
MASK_TINT_RED = %00100000 ; Red Background
|
|
|
|
MASK_TINT_BLUE = %01000000 ; Blue Background
|
|
|
|
MASK_TINT_GREEN = %10000000 ; Green Background
|
|
|
|
MASK_SPR = %00010000 ; Sprites Visible
|
|
|
|
MASK_BG = %00001000 ; Backgrounds Visible
|
|
|
|
MASK_SPR_CLIP = %00000100 ; Sprites clipped on left column
|
|
|
|
MASK_BG_CLIP = %00000010 ; Background clipped on left column
|
|
|
|
MASK_COLOR = %00000000 ; Display in Color
|
|
|
|
MASK_MONO = %00000001 ; Display in Monochrome
|
|
|
|
|
|
|
|
; read flags
|
|
|
|
F_BLANK = %10000000 ; VBlank Active
|
|
|
|
F_SPRITE0 = %01000000 ; VBlank hit Sprite 0
|
|
|
|
F_SCAN8 = %00100000 ; More than 8 sprites on current scanline
|
|
|
|
F_WIGNORE = %00010000 ; VRAM Writes currently ignored.
|
|
|
|
|
2018-08-03 18:06:08 +00:00
|
|
|
|
|
|
|
;;;;; CARTRIDGE FILE HEADER
|
|
|
|
|
2018-08-05 14:00:53 +00:00
|
|
|
NES_MIRR_HORIZ = 0
|
|
|
|
NES_MIRR_VERT = 1
|
|
|
|
NES_MIRR_QUAD = 8
|
2018-08-03 18:06:08 +00:00
|
|
|
|
|
|
|
MAC NES_HEADER
|
|
|
|
seg Header
|
|
|
|
org $7ff0
|
|
|
|
.NES_MAPPER SET {1} ;mapper number
|
|
|
|
.NES_PRG_BANKS SET {2} ;number of 16K PRG banks, change to 2 for NROM256
|
|
|
|
.NES_CHR_BANKS SET {3} ;number of 8K CHR banks (0 = RAM)
|
|
|
|
.NES_MIRRORING SET {4} ;0 horizontal, 1 vertical, 8 four screen
|
|
|
|
byte $4e,$45,$53,$1a ; header
|
|
|
|
byte .NES_PRG_BANKS
|
|
|
|
byte .NES_CHR_BANKS
|
|
|
|
byte .NES_MIRRORING|(.NES_MAPPER<<4)
|
|
|
|
byte .NES_MAPPER&$f0
|
|
|
|
byte 0,0,0,0,0,0,0,0 ; reserved, set to zero
|
|
|
|
seg Code
|
|
|
|
org $8000
|
|
|
|
ENDM
|
|
|
|
|
|
|
|
;;;;; NES_INIT SETUP MACRO (place at start)
|
|
|
|
|
|
|
|
MAC NES_INIT
|
|
|
|
sei ;disable IRQs
|
|
|
|
cld ;decimal mode not supported
|
|
|
|
ldx #$ff
|
|
|
|
txs ;set up stack pointer
|
|
|
|
inx ;increment X to 0
|
|
|
|
stx PPU_MASK ;disable rendering
|
|
|
|
stx DMC_FREQ ;disable DMC interrupts
|
|
|
|
stx PPU_CTRL ;disable NMI interrupts
|
|
|
|
bit PPU_STATUS ;clear VBL flag
|
2018-08-05 14:00:53 +00:00
|
|
|
bit APU_CHAN_CTRL ;ack DMC IRQ bit 7
|
|
|
|
lda #$40
|
|
|
|
sta APU_FRAME ;disable APU Frame IRQ
|
|
|
|
lda #$0F
|
|
|
|
sta APU_CHAN_CTRL ;disable DMC, enable/init other channels.
|
2018-08-03 18:06:08 +00:00
|
|
|
ENDM
|
|
|
|
|
|
|
|
;;;;; NES_VECTORS - CPU vectors at end of address space
|
|
|
|
|
|
|
|
MAC NES_VECTORS
|
2019-03-15 01:55:16 +00:00
|
|
|
seg Vectors ; segment "Vectors"
|
|
|
|
org $fffa ; start at address $fffa
|
|
|
|
.word NMIHandler ; $fffa vblank nmi
|
|
|
|
.word Start ; $fffc reset
|
|
|
|
.word NMIHandler ; $fffe irq / brk
|
2018-08-03 18:06:08 +00:00
|
|
|
ENDM
|
2018-08-16 21:00:22 +00:00
|
|
|
|
|
|
|
;;;;; PPU_SETADDR <address> - set 16-bit PPU address
|
|
|
|
|
|
|
|
MAC PPU_SETADDR
|
2019-02-28 21:08:41 +00:00
|
|
|
lda #>{1} ; upper byte
|
|
|
|
sta PPU_ADDR
|
|
|
|
lda #<{1} ; lower byte
|
2018-08-16 21:00:22 +00:00
|
|
|
sta PPU_ADDR
|
|
|
|
ENDM
|
|
|
|
|
|
|
|
;;;;; PPU_SETVALUE <value> - feed 8-bit value to PPU
|
|
|
|
|
|
|
|
MAC PPU_SETVALUE
|
|
|
|
lda #{1}
|
|
|
|
sta PPU_DATA
|
|
|
|
ENDM
|
|
|
|
|
2018-08-18 14:21:18 +00:00
|
|
|
;;;;; SAVE_REGS - save A/X/Y registers
|
2018-08-16 21:00:22 +00:00
|
|
|
|
|
|
|
MAC SAVE_REGS
|
|
|
|
pha
|
|
|
|
txa
|
|
|
|
pha
|
|
|
|
tya
|
|
|
|
pha
|
|
|
|
ENDM
|
|
|
|
|
2019-02-21 19:19:29 +00:00
|
|
|
;;;;; RESTORE_REGS - restore Y/X/A registers
|
2018-08-16 21:00:22 +00:00
|
|
|
|
|
|
|
MAC RESTORE_REGS
|
|
|
|
pla
|
|
|
|
tay
|
|
|
|
pla
|
|
|
|
tax
|
|
|
|
pla
|
|
|
|
ENDM
|
2018-08-18 14:21:18 +00:00
|
|
|
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
; SLEEP clockcycles
|
|
|
|
; Original author: Thomas Jentzsch
|
|
|
|
; Inserts code which takes the specified number of cycles to execute. This is
|
|
|
|
; useful for code where precise timing is required.
|
|
|
|
; LEGAL OPCODE VERSION MAY AFFECT FLAGS (uses 'bit' opcode)
|
|
|
|
|
|
|
|
NO_ILLEGAL_OPCODES = 1
|
|
|
|
|
|
|
|
MAC SLEEP ;usage: SLEEP n (n>1)
|
|
|
|
.CYCLES SET {1}
|
|
|
|
|
|
|
|
IF .CYCLES < 2
|
|
|
|
ECHO "MACRO ERROR: 'SLEEP': Duration must be > 1"
|
|
|
|
ERR
|
|
|
|
ENDIF
|
|
|
|
|
|
|
|
IF .CYCLES & 1
|
|
|
|
IFNCONST NO_ILLEGAL_OPCODES
|
|
|
|
nop 0
|
|
|
|
ELSE
|
|
|
|
bit $00
|
|
|
|
ENDIF
|
|
|
|
.CYCLES SET .CYCLES - 3
|
|
|
|
ENDIF
|
|
|
|
|
|
|
|
REPEAT .CYCLES / 2
|
|
|
|
nop
|
|
|
|
REPEND
|
|
|
|
ENDM
|