;
; NSF Header
;
.segment "HEADER"
;
.byte 'N', 'E', 'S', 'M', $1A ; ID
.byte $01 ; version
.byte 3 ; songs
.byte 3 ; starting song
.word $8000 ; load address
.word nsf_init ; init function
.word nsf_play ; play function
; title
.byte "mmc5 pcm test",          0,0,0
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
; artist
.byte "bradsmith",      0,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
; copyright
.byte "2012", 0,0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
; other
.word 16666 ; NTSC speed
.byte 0,0,0,0,0,0,0,0 ; bankswitch init
.word 20000 ; PAL speed
.byte $00 ; PAL/NTSC bits
.byte $08 ; expansion bits
.byte 0,0,0,0 ; pad to $80

;
; NSF init/play
;
.segment "CODE"

.incbin "ebs.raw"

; A = song - 1
; X = 0-NTSC, 1-PAL
nsf_init:
	JSR mmc5_init
	RTS

nsf_play:
	JSR mmc5_sound
	RTS

;
; music code
;

AD_LOW  = $00 ; sample read address
AD_HIGH = $01
SONG    = $02 ; song stored in bits 76
SCOUNT  = $03 ; sample counter per NMI
SCRATCH = $04 ; scratch for extra write timing

SAMPLES_PER_NMI = 94 ; this is how many fit in one NMI
SAMPLE_SPEED = 50    ; controls pitch (also adjust SAMPLES_PER_NMI)

; song sets mmc5 read mode (0 = read, 1 = write, 2 = 4011)
mmc5_init:
	STA SCRATCH
	EOR #$01 ; flip ones bit (song number is reverse of read/write bit)
	AND #$01 ; remove other bits (e.g. don't start PCM IRQ)
	STA $5010 ; set read/write mode (0=write, 1=read)
	; store shifted song # in SONG for BIT testing during sample loop
	LDA SCRATCH
	ASL
	ASL
	ASL
	ASL
	ASL
	ASL
	STA SONG ; store write bit in minus flag
	; reset counter
	LDA #$00
	STA AD_LOW
	STA AD_HIGH
	; start sound
	LDA #$FC
	STA $5015
	RTS

mmc5_sound:
	LDY #SAMPLES_PER_NMI
	STY SCOUNT
@loop:
	LDY #$0
	; increment address
	LDA AD_LOW
	CLC
	ADC #$1
	STA AD_LOW
	LDA AD_HIGH
	ADC #$0
	AND #$3F
	ORA #$80
	STA AD_HIGH
	
	; read sample
	LDA (AD_LOW), Y
	; if song = 0 write as well
	BIT SONG
	BVC @nowrite
	STA $5011
	JMP @choose_dmc
@nowrite:
	STA SCRATCH
	JMP @choose_dmc
@choose_dmc:
	BPL @nodmc
	LSR
	STA $4011
	JMP @delay
@nodmc:
	LSR
	STA SCRATCH
	JMP @delay
@delay:
	; wait a bit to slow down samplerate
	LDX #SAMPLE_SPEED
@slower:
	DEX
	BNE @slower
	; loop to next sample
	LDY SCOUNT
	DEY
	STY SCOUNT
	BNE @loop
	; to test end of sample loop
	;LDA #0
	;STA $4011
	RTS

;
; end of file
;
