FC/NES 音乐示例程序 生日快乐歌

陪她去流浪 桃子 2012年08月13日 阅读次数:2172

叶枫写的,我反汇编的。

;开始地址:$bff0
;结束地址:$ffff
;文件长度:$4010


COUNTER = $00
MUSIC_OFFSET1 = $01
MUSIC_OFFSET2 = $02

        .org    $BFF0
        .db     "NES",$1A,$01,$01,$00,$00
        .dw     $00,$00,$00,$00
        .start  $C000
        .org    $C000
reset:
        sei             ; 禁用中断
        cld                             
        ldx     #$ff    ; 初始化栈顶指针到$FF
        txs
        
        inx
        stx     COUNTER
        stx     MUSIC_OFFSET1
        stx     MUSIC_OFFSET2
        
_vb1:
        lda     $2002
        bpl     _vb1
_vb2:
        lda     $2002
        bpl     _vb2

        lda     #$00
        sta     $2001

        
        lda     #$0f    ; 声音切换:0000 1111,方波#1#2,三角波,噪声
        sta     $4015
        
        lda     #$8f
        sta     $4000   ; APU方波#1控制端口
        
        lda     #$00
        sta     $4001   ; APU方波#1控制端口
        
        lda     #$80    ; 开nmi中断
        sta     $2000           
        
main:
        jmp     main
        

nmi:
        inc     COUNTER         ; 计数器增加
        ldx     MUSIC_OFFSET1
        lda     music1,x        ; 取得音长
        cmp     COUNTER         ; 判断是否该播放
        beq     next2           ; 播放
        cmp     #$ff
        beq     next1           ; 是否结束
        jmp     over            ; 退出
next1:
        ldx     #$00            ; 回到开始
        stx     MUSIC_OFFSET1
        jmp     over
next2:  
        lda     #$00
        sta     COUNTER
        lda     MUSIC_OFFSET2
        tay
        lda     music2,y        ; 波长低八位
        cmp     #$ff            ; 结束了吗?
        beq     next3
        sta     $4002
        
        iny
        lda     music2,y        ; 波长高三位+音长计数器
        cmp     #$ff            ; 结束了吗?
        beq     next3
        sta     $4003
        
        iny                     ; 下一个音符
        sty     MUSIC_OFFSET2
        inx
        stx     MUSIC_OFFSET1
        jmp     over
next3:
        ldy     #$00            ; 回到开始
        sty     MUSIC_OFFSET2
over:
        rti

music1:
        ; 音长 8*4+1=33
        .db $10,$10,$20,$20,$20,$20,$20,$10
        .db $10,$20,$20,$20,$20,$20,$20,$10
        .db $10,$20,$20,$20,$20,$20,$20,$20
        .db $20,$10,$10,$20,$20,$20,$20,$20
        .db $20,$FF
music2:
        ; 两个一组,$FF为结束 8*8+2=66
        .db $1C,$09,$1C,$09,$FD,$08,$1C,$09
        .db $D4,$08,$E1,$08,$00,$00,$1C,$09
        .db $1C,$D9,$FD,$08,$1C,$09,$BD,$08
        .db $D4,$08,$D4,$08,$00,$00,$1C,$09
        .db $1C,$09,$8D,$08,$A8,$08,$D4,$08
        .db $E1,$08,$FD,$08,$FD,$08,$FD,$08
        .db $00,$00,$9F,$08,$9F,$08,$A8,$08
        .db $D4,$08,$BD,$08,$D4,$08,$D4,$D4
        .db $08,$00,$FF,$FF

irq:
        rti


        .org $fffa
        .dw nmi,reset,irq

这篇文章的内容已被作者标记为“过时”/“需要更新”/“不具参考意义”。

标签:代码片段 · 汇编 · 音乐 · 6502 · nes