mirror of
https://github.com/daniel5151/ANESE.git
synced 2025-04-02 10:32:00 -04:00
1 line
No EOL
3.1 KiB
ArmAsm
Vendored
1 line
No EOL
3.1 KiB
ArmAsm
Vendored
; Displays entire 400+ color NTSC NES palette on screen.
|
|
; Disables PPU rendering so that current scanline color can be
|
|
; set directly by VRAM address, then uses cycle-timed code to
|
|
; cycle through all colors in a clean grid.
|
|
;
|
|
; ca65 -o full_palette_smooth.o full_palette_smooth.s
|
|
; ld65 -t nes full_palette_smooth.o -o full_palette_smooth.nes
|
|
;
|
|
; Shay Green <gblargg@gmail.com>
|
|
|
|
.segment "HEADER"
|
|
.byte "NES",26, 2,1, 0,0
|
|
|
|
.segment "VECTORS"
|
|
.word 0,0,0, nmi, reset, irq
|
|
|
|
.segment "CHARS"
|
|
.res 8192
|
|
|
|
.segment "STARTUP" ; avoids warning
|
|
|
|
.segment "CODE"
|
|
|
|
even_frame = $200
|
|
|
|
irq:
|
|
nmi: rti
|
|
|
|
wait_vbl:
|
|
bit $2002
|
|
: bit $2002
|
|
bpl :-
|
|
rts
|
|
|
|
blacken_palette:
|
|
; Fill palette with black. Starts at $3FE0 so that VRAM
|
|
; address will wrap around to 0 afterwards, so that BG
|
|
; rendering will work correctly.
|
|
lda #$3F
|
|
sta $2006
|
|
lda #$E0
|
|
sta $2006
|
|
lda #$0F
|
|
ldy #$20
|
|
: sta $2007
|
|
dey
|
|
bne :-
|
|
rts
|
|
|
|
reset:
|
|
sei
|
|
ldx #$FF
|
|
txs
|
|
|
|
; Init PPU
|
|
jsr wait_vbl
|
|
jsr wait_vbl
|
|
lda #0
|
|
sta $2000
|
|
sta $2001
|
|
jsr blacken_palette
|
|
|
|
; Clear nametable
|
|
lda #$20
|
|
sta $2006
|
|
lda #$00
|
|
sta $2006
|
|
ldx #4
|
|
ldy #0
|
|
: sta $2007
|
|
iny
|
|
bne :-
|
|
dex
|
|
bne :-
|
|
|
|
; Synchronize precisely to VBL. VBL occurs every 29780.67
|
|
; CPU clocks. Loop takes 27 clocks. Every 1103 iterations,
|
|
; the second LDA $2002 will read exactly 29781 clocks
|
|
; after a previous read. Thus, the loop will effectively
|
|
; read $2002 one PPU clock later each frame. It starts out
|
|
; with VBL beginning sometime after this read, so that
|
|
; eventually VBL will begin just before the $2002 read,
|
|
; and thus leave CPU exactly synchronized to VBL.
|
|
jsr wait_vbl
|
|
nop
|
|
: nop
|
|
lda $2002
|
|
lda $2002
|
|
pha
|
|
pla
|
|
pha
|
|
pla
|
|
bpl :-
|
|
|
|
lda #0
|
|
sta even_frame
|
|
|
|
begin_frame:
|
|
jsr blacken_palette
|
|
|
|
; Enable BG so that PPU will make every other frame
|
|
; shorter by one PPU clock. This allows our code to
|
|
; synchronize better and reduce horizontal shaking.
|
|
lda #$08
|
|
sta $2001
|
|
|
|
; Delay 4739 cycles, well into frame
|
|
ldx #4
|
|
ldy #176
|
|
: dey
|
|
bne :-
|
|
dex
|
|
bne :-
|
|
|
|
nop
|
|
|
|
; Disable BG. Now electron beam color can be set by
|
|
; VRAM address pointing into palette.
|
|
lda #0
|
|
sta $2001
|
|
|
|
; Draw palette
|
|
ldy #$C0 ; Y = color
|
|
triplet:
|
|
|
|
; Draws one scanline of palette. Takes 98 cycles.
|
|
.macro draw_row
|
|
tya
|
|
and #$30
|
|
ldx #$3F
|
|
stx $2006
|
|
stx $2006
|
|
tax
|
|
stx $2007
|
|
inx
|
|
stx $2007
|
|
inx
|
|
stx $2007
|
|
inx
|
|
stx $2007
|
|
inx
|
|
stx $2007
|
|
inx
|
|
stx $2007
|
|
inx
|
|
stx $2007
|
|
inx
|
|
stx $2007
|
|
inx
|
|
stx $2007
|
|
inx
|
|
stx $2007
|
|
inx
|
|
stx $2007
|
|
inx
|
|
stx $2007
|
|
inx
|
|
stx $2007
|
|
inx
|
|
stx $2007
|
|
.endmacro
|
|
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
|
|
draw_row
|
|
|
|
; Palette writes are delayed a line, since VRAM address
|
|
; increments just after $2007 write. So we don't set
|
|
; color tint until after first row of triplet
|
|
tya
|
|
lsr a
|
|
and #$07
|
|
tax
|
|
lda tints,x
|
|
sta $2001
|
|
|
|
draw_row
|
|
|
|
pha
|
|
pla
|
|
pha
|
|
pla
|
|
nop
|
|
|
|
draw_row
|
|
|
|
iny
|
|
beq :+ ; loop is more than 128 bytes, argh
|
|
jmp triplet
|
|
:
|
|
|
|
nop
|
|
|
|
; Delay 2869 cycles
|
|
ldy #239
|
|
: pha
|
|
pla
|
|
dey
|
|
bne :-
|
|
|
|
; Delay extra cycle every other frame
|
|
inc even_frame
|
|
lda even_frame
|
|
lsr a
|
|
bcs :+
|
|
: jmp begin_frame
|
|
|
|
|
|
; Reorder color tints to be most gradual
|
|
tints: .byte $E0,$C0,$A0,$60,$20,$40,$80,$00
|