VRC7 audio test program

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
VRC7 audio test program
by on (#96785)
I wrote a program to test the VRC7 audio. For example, you can make up the VRC7 custom instrument and then figure out what it sound like.

Instructions: LEFT/RIGHT = cursor, UP/DOWN = adjust, START = send values. If rightmost "A" is set to 1 then START automatically trigger/untrigger note as well.

Code:
; VRC7 audio test program.
   .inesprg 1
   .ineschr 1
   .inesmir 1
   .inesmap 85 ;VRC7

; Macro

   .macro write_ppu
   lda #\1
   sta $2007
   .endm

   .macro set_ppu
   lda #(\1>>8)
   sta $2006
   lda #(\1&$FF)
   sta $2006
   .endm

   .macro strobe
   lda #1
   sta $4016
   lda #0
   sta $4016
   .endm

; RAM
   .zp
valmem:
   ; Custom instrument setting 0-7, IIIIVVVV, LLLLLLLL, --STOOOH
   ; 2 bytes each: hi-nybble lo-nybble
   .ds 22
autotrig:
   ; set if START should trigger/untrigger note
   .ds 1
pushed:
   ; check if button still pushed
   .ds 1
cursor:
   ; cursor position: 0 to 21
   .ds 1

; CHR
   .code
   .bank 2
   .org $0000
   .incbin "vrc7test.chr"

; PRG
   .code
   .bank 0
   .org $8000

one:
   ; data for joypad bit testing
   .db 1

fill_ppu:
   sta $2007
   dex
   bne fill_ppu
   rts

write_vrc7:
   ; set address
   sty $9010
   ; wait 6 cycles
   jsr wait6
   ; load value
   lda <valmem,x
   inx
   asl a
   asl a
   asl a
   asl a
   ora <valmem,x
   inx
   ; set value
   sta $9030
   ; wait 42 cycles (12 per call + 6 to return = 42)
   jsr wait6
   jsr wait6
   jsr wait6
   ; return
wait6:
   rts

Reset:
   ; disable IRQ and NMI, set address increment +1
   sei
   lda #%00000000
   sta $2000

   ; display off
   lda #%00000000
   sta $2001

   ; initialize RAM
   lda #0
   sta <cursor
   sta <autotrig

   ; palette
   set_ppu $3F00
   write_ppu $1D ; black
   write_ppu $20 ; white
   write_ppu $2A ; green
   write_ppu $21 ; blue

   ; initialize name table
   set_ppu $2000
   lda #$1E
   ldx #(32*4+5)
   jsr fill_ppu
   ; headings - I0..I7
   lda #$30
   ldx #$20
   ldy #8
nt1:
   sta $2007
   stx $2007
   inx
   dey
   bne nt1
   ; more headings
   write_ppu $50 ;I
   write_ppu $53 ;v
   write_ppu $52 ;LL
   sta $2007     ;LL
   write_ppu $54 ;ST
   write_ppu $51 ;oH
   write_ppu $4A ;A
   ; gap
   lda #$1E
   ldx #9
   jsr fill_ppu
   ; values
   lda #$00
   ldx #23
   jsr fill_ppu
   ; end
   lda #$1E
   ldx #$FF
   jsr fill_ppu
   ldx #$FF
   jsr fill_ppu
   ldx #$FF
   jsr fill_ppu
   ldx #7
   jsr fill_ppu

   ; display on, enable NMI
   lda #%00001110
   sta $2001
   lda #%10000000
   sta $2000

   ; wait...
w1:
   jmp w1

rt:
   rti

NMI:
   strobe
   lda $4016
   lda $4016
   lda $4016

   ; delay if buttons held
   lda <pushed
   beq npu
   lda $4016 ;START
   bit one
   bne rt
   lda $4016 ;UP
   bit one
   bne rt
   lda $4016 ;DOWN
   bit one
   bne rt
   lda $4016 ;LEFT
   bit one
   bne rt
   lda $4016 ;RIGHT
   bit one
   bne rt
   dec <pushed
npu:

   ; check buttons pushed
   lda $4016 ;START
   bit one
   beq ch_up
   jmp START
ch_up:
   lda $4016 ;UP
   bit one
   beq ch_down
   jmp UP
ch_down:
   lda $4016 ;DOWN
   bit one
   beq ch_left
   jmp DOWN
ch_left:
   lda $4016 ;LEFT
   bit one
   beq ch_right
   jmp LEFT
ch_right:
   lda $4016 ;RIGHT
   bit one
   beq w2
   jmp RIGHT

w2:
   ; reset scroll position
   lda #0
   sta $2005
   sta $2005
   ; enable NMI and exit interrupt call
   lda #%10000000
   sta $2000
   rti
w3:
   inc <pushed
   jmp w2

START:
   ; disable NMI
   lda #%00000000
   sta $2000
   ; check auto-trigger
   lda <20
   eor <autotrig
   sta <20
   ; write VRC7 audio registers
   ldx #0
   ldy #$00
   jsr write_vrc7
   ldy #$01
   jsr write_vrc7
   ldy #$02
   jsr write_vrc7
   ldy #$03
   jsr write_vrc7
   ldy #$04
   jsr write_vrc7
   ldy #$05
   jsr write_vrc7
   ldy #$06
   jsr write_vrc7
   ldy #$07
   jsr write_vrc7
   ldy #$30
   jsr write_vrc7
   ldy #$10
   jsr write_vrc7
   ldy #$20
   jsr write_vrc7
   ; done
   jmp w3

UP:
   ldx <cursor
   lda #$20
   sta $2006
   lda #(32*5+5)
   clc
   adc <cursor
   sta $2006
   inc <valmem,x
   lda #$0F
   and <valmem,x
   sta <valmem,x
   sta $2007
   jmp w3

DOWN:
   ldx <cursor
   lda #$20
   sta $2006
   lda #(32*5+5)
   clc
   adc <cursor
   sta $2006
   dec <valmem,x
   lda #$0F
   and <valmem,x
   sta <valmem,x
   sta $2007
   jmp w3

LEFT:
   lda <cursor
   beq dez
   dec <cursor
   lda #$20
   sta $2006
   lda #(32*6+5)
   clc
   adc <cursor
   sta $2006
   write_ppu $1F
   write_ppu $1E
dez:
   jmp w3

RIGHT:
   lda #22
   cmp <cursor
   beq dez
   lda #$20
   sta $2006
   lda #(32*6+5)
   clc
   adc <cursor
   sta $2006
   write_ppu $1E
   write_ppu $1F
   inc <cursor
   jmp w3

; Vectors
   .bank 1
   .org $FFFA
   .dw NMI
   .dw Reset
   .dw 0