Audio Co-Processes in Assembly

Discuss NSF files, FamiTracker, MML tools, or anything else related to NES music.

Moderator: Moderators

Post Reply
VenoSci
Posts: 4
Joined: Mon Dec 03, 2018 1:56 am

Audio Co-Processes in Assembly

Post by VenoSci »

Hey All,
I have another question regarding my quest to compose a piece of music for the NES using only 6502 assembly.
Right now, the code I have looks something like this:

Code: Select all

    .inesprg 1
    .ineschr 0
    .inesmap 1
    .inesmir 0

    .bank 1
    .org $FFFA
    .dw 0
    .dw Main
    .dw 0

    .bank 0
    .org $C000

Main:
    jsr A4_pu1

    jsr D4_pu2

testMain:
    ldx $4015
    cpx #%00000000
    beq main
    jmp testMain

InfiniteLoop
    jmp InfiniteLoop

A4_pu1:
    lda #%00000011
    sta $4015
    lda #%10001111
    sta $4000
    lda #%11111101
    sta $4002
    lda #%11000000
    sta $4003
    rts

D4_pu2:
    lda #%00000011
    sta $4015
    lda #%11001111
    sta $4004
    lda #%11111011
    sta $4006
    lda #%11000001
    sta $4007
    rts


In my head, the code should function like this:
1. Set the correct flags and write the correct data to the pulse 1 register. Then, return to main from the subroutine.
2. while that first note is still decaying, jump to subroutine two where the second note would be played. Then, return to main.
3. lastly, once the $4015 flags for pu1 and pu2 are set to 0, it will loop and repeat.

right now this is not happening, and I understand why that might be, but am lost on how I might fix this issue. any help on getting two notes (and later, two sequences of notes) to play simultaneously from code would be very helpful.
Thanks!
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Audio Co-Processes in Assembly

Post by dougeff »

For 1 thing, the mapper should be 0

.inesmap 0

and you aren't initializing the system at all. You should at least turn off IRQs with "sei". Since you never set an IRQ vector, and never turned off the APU IRQs, as soon as the note ends, an IRQ fires, and it jumps to 0000, where it likely sees 00 = BRK, which jumps to the same vector, jumping infinitely to 0000 again and again.

Third. you can't play the lowest octave (high bits = 000) without setting the N bit in the sweep register.

lda #$7f
sta $2001

And I wouldn't time music using length counters (reading from 4015). I would count PPU frames, properly done by turning NMIs on and using the NMI code to count up / update the music.
nesdoug.com -- blog/tutorial on programming for the NES
VenoSci
Posts: 4
Joined: Mon Dec 03, 2018 1:56 am

Re: Audio Co-Processes in Assembly

Post by VenoSci »

Hey, I appreciate the reply.

Thank you for the pointers on both the mapper and the sweep register, I hadn't encountered any issues regarding those two, so I was unaware that the code I had written in regards to them was faulty.

Can you possibly explain/link me to an explanation of IRQs and their respective commands? Im generally foggy about their functions, especially in relation to the sound chip.

As far as timing goes, I would rather have the timing done by length counters so that I can (attempt) to create compositions that shift and move out of time, as I write sequences of different length to the separate channels, something that cannot be done (or is more interesting to do) in code.

Thanks!
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: Audio Co-Processes in Assembly

Post by dougeff »

Can you possibly explain/link me to an explanation of IRQs
Just turn them off, and you don't have to worry

First instruction after Main, insert "sei"
nesdoug.com -- blog/tutorial on programming for the NES
Post Reply