【原创】如何为自己编写的NES游戏添加音乐?

给大家介绍两个编辑NES音乐的工具:FamiTracker 和 FamiStudio。网上都能下载到,而且开源了的。如果下载不了,可以加到我的Q群,找群友帮助。

 

这两个软件都提供音乐引擎,但是经我测试FamiTracker的引擎连自己的Demo都不能够还原播放。而且FamiTracker的引擎是针对nsf的,改改是可以nes用。但一个不行的引擎那还是省省。

 

第二软件FamiStudio,是我这次推荐的。它的引擎配合一个nes框架可以生成nes。同时它提供3种汇编器对应的代码。同是6502汇编器,但是伪代码是有所不同的。这是说的3种汇编器是asm6,nesasm, ca65。

 

我个人喜欢asm6,原因是asm6语法“简单”。下面继续介绍FamiStudio的引擎和相关的东西。

 

FamiStudio的引擎是famistudio_asm6.asm

引擎的框架是demo_asm6.asm

值得注意的是:引擎的版本需要紧跟着你安装的FamiStudio的版本。例如现在最新的FamiStudio版本是4.0.6,那么引擎也要最新的4.0.5。因为旧引擎不支持新功能。

 

原框架对于更换音乐数据有点麻烦。我改了一下,这就方便了。文章的最后,会附我那改过的框架代码。因为我发现音乐数据的引用点都是开头位置,所以我利用这一点修改一下。只要更换包含(.include)文件名就行。

框架代码的842行、847行、850行分别更换音乐数据文件就行。支持3首曲目。这个框架用的是mapper0没有切页。只支持一个dpcm,就是说只能一支曲子有dmc文件。当然真正编游戏,可以用切页。

 

有一点遗憾,就是dmc必须放在$e000。我没能看懂引擎代码,不知道怎么更换它。

 

推荐FamiStudio的原因,其中一是引擎可用,第二是它的包容性,可以导入midi,可以导入nsf,可以打开FamiTracker的文档。

经我测试一个带dpmc的FamiTracker文档,但不能通过该引擎播放,但是用FamiTracker生成nsf后,再用FamiStudio导入nsf这就行了,成功通过该引擎播放。第三是可以混合效果音,我的游戏,除了背景声,还有效果音,例中刺刀、子弹和爆炸等,在这个引擎中也能实现。上述的数据是包含在SFX文件中,我们可以通过FamiStudio制作效果音输出生成sfx_asm6.asm。

 

看明白这个引擎框架就可以以这个框架为基础编写你的NES游戏了。

 

********************

说了半看,有可能没有能明白我的意思。“如何为自己编写的NES游戏添加音乐?”, 那就是用FamiStudio得到音乐数据,具体操作:例如我用的汇编器是asm6。那么用FamiStudio打开音乐后,按

得到窗口

 

点选:“FamiStudio Music Code”。我用的asm6,那么格式选asm6。这就行,提勾。输出的是音乐数据。

然后按本框架编写NES游戏,就可以插入音乐了。

 

如何编译呢?

将asm6.exe放在源文件同一文件夹中,我也改写批处理文件,执行它就能编译了。我改写的这个框架,需要将引擎也放在同一文件夹中。因为我改了它的包含路径。一言盖之,通通放在同一文件夹中,然后执行bat文件。

 

我写的bat文件

asm6 demo_asm6.asm demo_asm6.nes
pause

  

 

我修改过的FamiStudio引擎的框架是demo_asm6.asm

  1 FAMISTUDIO_VERSION_MAJOR  = 4
  2 FAMISTUDIO_VERSION_MINOR  = 0
  3 FAMISTUDIO_VERSION_HOTFIX = 0
  4 
  5     ; HEADER
  6     INES_MAPPER = 0 ; 0 = NROM
  7     INES_MIRROR = 1 ; 0 = horizontal mirroring, 1 = vertical mirroring
  8     INES_SRAM   = 0 ; 1 = battery backed SRAM at $6000-7FFF
  9 
 10     .db 'N', 'E', 'S', $1A ; ID 
 11     .db $02 ; 16k PRG bank count
 12     .db $01 ; 8k CHR bank count
 13     .db INES_MIRROR | (INES_SRAM << 1) | ((INES_MAPPER & $f) << 4)
 14     .db (INES_MAPPER & %11110000)
 15     .db $0, $0, $0, $0, $0, $0, $0, $0 ; padding
 16     .fillvalue $ff
 17 
 18     ; ZEROPAGE
 19     .enum $0000
 20     nmi_lock:           .dsb 1 ; prevents NMI re-entry
 21     nmi_count:          .dsb 1 ; is incremented every NMI
 22     nmi_ready:          .dsb 1 ; set to 1 to push a PPU frame update, 2 to turn rendering off next NMI
 23     scroll_x:           .dsb 1 ; x scroll position
 24     scroll_y:           .dsb 1 ; y scroll position
 25     scroll_nmt:         .dsb 1 ; nametable select (0-3 = $2000,$2400,$2800,$2C00)
 26     gamepad:            .dsb 1
 27     gamepad_previous:   .dsb 1
 28     gamepad_pressed:    .dsb 1
 29     song_index:         .dsb 1
 30     pause_flag:         .dsb 1
 31     nmt_update_mode:    .dsb 1   ; update "mode", 0 = nothing to do, 1 = column mode, 2 = row mode + palettes
 32     nmt_update_data:    .dsb 128 ; nametable update entry buffer for PPU update
 33     nmt_update_len:     .dsb 1 ; number of bytes in nmt_update_data buffer
 34     palette:            .dsb 32  ; palette buffer for PPU update
 35 
 36     ; General purpose temporary vars.
 37     r0: .dsb 1
 38     r1: .dsb 1
 39     r2: .dsb 1
 40     r3: .dsb 1
 41     r4: .dsb 1
 42 
 43     ; General purpose pointers.
 44     p0: .dsb 2
 45     .ende
 46 
 47     ; RAM
 48     .enum $0300
 49     .ende
 50 
 51     ; OAM
 52     .enum $0200
 53     oam: .dsb 256        ; sprite OAM data to be uploaded by DMA
 54     .ende
 55 
 56     ; CODE
 57     .base $8000
 58 
 59 ; FamiStudio config.
 60 FAMISTUDIO_CFG_EXTERNAL       = 1
 61 FAMISTUDIO_CFG_DPCM_SUPPORT   = 1
 62 FAMISTUDIO_CFG_SFX_SUPPORT    = 1 
 63 FAMISTUDIO_CFG_SFX_STREAMS    = 2
 64 FAMISTUDIO_CFG_EQUALIZER      = 1
 65 FAMISTUDIO_USE_VOLUME_TRACK   = 1
 66 FAMISTUDIO_USE_PITCH_TRACK    = 1
 67 FAMISTUDIO_USE_SLIDE_NOTES    = 1
 68 FAMISTUDIO_USE_VIBRATO        = 1
 69 FAMISTUDIO_USE_ARPEGGIO       = 1
 70 FAMISTUDIO_CFG_SMOOTH_VIBRATO = 1
 71 FAMISTUDIO_USE_RELEASE_NOTES  = 1
 72 FAMISTUDIO_DPCM_OFF           = $e000
 73 
 74 ; ASM6-specific config.
 75 FAMISTUDIO_ASM6_ZP_ENUM   = $00b4
 76 FAMISTUDIO_ASM6_BSS_ENUM  = $0300
 77 FAMISTUDIO_ASM6_CODE_BASE = $8000
 78 
 79     ; FS音乐引擎
 80     .include "famistudio_asm6.asm"
 81 
 82 ; Our single screen.
 83 screen_data_rle:
 84     .incbin "demo.rle"
 85 
 86 default_palette:
 87     .incbin "demo.pal"
 88     .incbin "demo.pal"
 89 
 90 ; Silver Surfer - BGM 2
 91 song_title_00:
 92     .db $ff, $ff, $ff, $12, $22, $25, $2f, $1e, $2b, $ff, $12, $2e, $2b, $1f, $1e, $2b, $ff, $4f, $ff, $01, $06, $0c, $ff, $36, $ff, $ff, $ff, $ff
 93 
 94 ; Journey To Silius - Menu
 95 song_title_01:
 96     .db $ff, $ff, $09, $28, $2e, $2b, $27, $1e, $32, $ff, $13, $28, $ff, $12, $22, $25, $22, $2e, $2c, $ff, $4f, $ff, $0c, $1e, $27, $2e, $ff, $ff
 97 
 98 ; Shatterhand - Final Area
 99 song_title_02:
100     .db $ff, $ff, $12, $21, $1a, $2d, $2d, $1e, $2b, $21, $1a, $27, $1d, $ff, $4f, $ff, $05, $22, $27, $1a, $25, $ff, $00, $2b, $1e, $1a, $ff, $ff
101 
102 NUM_SONGS = 3
103 
104 reset:
105 
106     sei       ; mask interrupts
107     lda #0
108     sta $2000 ; disable NMI
109     sta $2001 ; disable rendering
110     sta $4015 ; disable APU sound
111     sta $4010 ; disable DMC IRQ
112     lda #$40
113     sta $4017 ; disable APU IRQ
114     cld       ; disable decimal mode
115     ldx #$FF
116     txs       ; initialize stack
117     ; wait for first vblank
118     bit $2002
119     @wait_vblank_loop:
120         bit $2002
121         bpl @wait_vblank_loop
122     ; clear all RAM to 0
123     lda #0
124     ldx #0
125     @clear_ram_loop:
126         sta $0000, X
127         sta $0100, X
128         sta $0200, X
129         sta $0300, X
130         sta $0400, X
131         sta $0500, X
132         sta $0600, X
133         sta $0700, X
134         inx
135         bne @clear_ram_loop
136     ; place all sprites offscreen at Y=255
137     lda #255
138     ldx #0
139     @clear_oam_loop:
140         sta oam, X
141         inx
142         inx
143         inx
144         inx
145         bne @clear_oam_loop
146     ; wait for second vblank
147     @wait_vblank_loop2:
148         bit $2002
149         bpl @wait_vblank_loop2
150     ; NES is initialized, ready to begin!
151     ; enable the NMI for graphical updates, and jump to our main program
152     lda #%10001000
153     sta $2000
154     jmp main
155 
156 nmi:
157     ; save registers
158     pha
159     txa
160     pha
161     tya
162     pha
163     ; prevent NMI re-entry
164     lda nmi_lock
165     beq @lock_nmi
166     jmp @nmi_end
167 @lock_nmi:
168     lda #1
169     sta nmi_lock
170     inc nmi_count
171     lda nmi_ready
172     bne @check_rendering_off ; nmi_ready == 0 not ready to update PPU
173     jmp @ppu_update_end
174 @check_rendering_off:
175     cmp #2 ; nmi_ready == 2 turns rendering off
176     bne @oam_dma
177         lda #%00000000
178         sta $2001
179         ldx #0
180         stx nmi_ready
181         jmp @ppu_update_end
182 @oam_dma:
183     ; sprite OAM DMA
184     ldx #0
185     stx $2003
186     lda #>oam
187     sta $4014
188 
189 ; nametable update
190 @nmt_update:
191     lda nmt_update_mode 
192     bne @do_update
193     jmp @update_done
194     @do_update:
195         ldx #0
196         cpx nmt_update_len
197         beq @palettes
198         asl
199         asl
200         ora #%10000000
201         sta $2000
202         ldx #0
203         @nmt_update_loop:
204             lda nmt_update_data, x
205             inx
206             sta $2006
207             lda nmt_update_data, x
208             inx
209             sta $2006
210             ldy nmt_update_data, x
211             inx
212             @col_loop:
213                 lda nmt_update_data, x
214                 inx
215                 sta $2007
216                 dey
217                 bne @col_loop
218             cpx nmt_update_len
219             bcc @nmt_update_loop
220 
221 ; palettes
222 @palettes:
223     lda nmt_update_mode
224     cmp #2
225     beq @palettes_need_update
226     jmp @update_done
227     @palettes_need_update:
228         lda $2002
229         lda #$3F
230         sta $2006
231         ldx #0
232         stx $2006 ; set PPU address to $3F00
233         lda palette+0
234         sta $2007
235         lda palette+1
236         sta $2007
237         lda palette+2
238         sta $2007
239         lda palette+3
240         sta $2007
241         lda palette+4
242         sta $2007
243         lda palette+5
244         sta $2007
245         lda palette+6
246         sta $2007
247         lda palette+7
248         sta $2007
249         lda palette+8
250         sta $2007
251         lda palette+9
252         sta $2007
253         lda palette+10
254         sta $2007
255         lda palette+11
256         sta $2007
257         lda palette+12
258         sta $2007
259         lda palette+13
260         sta $2007
261         lda palette+14
262         sta $2007
263         lda palette+15
264         sta $2007
265         lda palette+16
266         sta $2007
267         lda palette+17
268         sta $2007
269         lda palette+18
270         sta $2007
271         lda palette+19
272         sta $2007
273         lda palette+20
274         sta $2007
275         lda palette+21
276         sta $2007
277         lda palette+22
278         sta $2007
279         lda palette+23
280         sta $2007
281         lda palette+24
282         sta $2007
283         lda palette+25
284         sta $2007
285         lda palette+26
286         sta $2007
287         lda palette+27
288         sta $2007
289         lda palette+28
290         sta $2007
291         lda palette+29
292         sta $2007
293         lda palette+30
294         sta $2007
295         lda palette+31
296         sta $2007
297 
298 @update_done:
299     ; Clear update mode.
300     lda #0 
301     sta nmt_update_mode
302     sta nmt_update_len
303 
304 @scroll:
305     lda scroll_nmt
306     and #%00000011 ; keep only lowest 2 bits to prevent error
307     ora #%10001000
308     sta $2000
309     lda scroll_x
310     sta $2005
311     lda scroll_y
312     sta $2005
313     ; enable rendering
314     lda #%00011110
315     sta $2001
316     ; flag PPU update complete
317     ldx #0
318     stx nmi_ready
319 @ppu_update_end:
320     ; if this engine had music/sound, this would be a good place to play it
321     ; unlock re-entry flag
322     lda #0
323     sta nmi_lock
324 @nmi_end:
325     ; restore registers and return
326     pla
327     tay
328     pla
329     tax
330     pla
331     rti
332 
333 irq:
334     rti
335 
336 ; ppu_update: waits until next NMI, turns rendering on (if not already), uploads OAM, palette, and nametable update to PPU
337 ppu_update:
338     lda #1
339     sta nmi_ready
340     @wait:
341         lda nmi_ready
342         bne @wait
343     rts
344 
345 ; ppu_skip: waits until next NMI, does not update PPU
346 ppu_skip:
347     lda nmi_count
348     @wait:
349         cmp nmi_count
350         beq @wait
351     rts
352 
353 ; ppu_off: waits until next NMI, turns rendering off (now safe to write PPU directly via $2007)
354 ppu_off:
355     lda #2
356     sta nmi_ready
357     @wait:
358         lda nmi_ready
359         bne @wait
360     rts
361 
362 PAD_A      = $01
363 PAD_B      = $02
364 PAD_SELECT = $04
365 PAD_START  = $08
366 PAD_U      = $10
367 PAD_D      = $20
368 PAD_L      = $40
369 PAD_R      = $80
370 
371 gamepad_poll:
372     ; strobe the gamepad to latch current button state
373     lda #1
374     sta $4016
375     lda #0
376     sta $4016
377     ; read 8 bytes from the interface at $4016
378     ldx #8
379     @gamepad_loop:
380         pha
381         lda $4016
382         ; combine low two bits and store in carry bit
383         and #%00000011
384         cmp #%00000001
385         pla
386         ; rotate carry into gamepad variable
387         ror a
388         dex
389         bne @gamepad_loop
390     sta gamepad
391     rts
392 
393 gamepad_poll_dpcm_safe:
394     
395     lda gamepad
396     sta gamepad_previous
397     jsr gamepad_poll
398     @reread:
399         lda gamepad
400         pha
401         jsr gamepad_poll
402         pla
403         cmp gamepad
404         bne @reread
405 
406     @toggle:
407     eor gamepad_previous
408     and gamepad
409     sta gamepad_pressed
410 
411     rts
412 
413 version_text: ; 
414     .byte $34 + FAMISTUDIO_VERSION_MAJOR, $3e, $34 + FAMISTUDIO_VERSION_MINOR, $3e, $34 + FAMISTUDIO_VERSION_HOTFIX
415 
416 play_song:
417 
418     @text_ptr = p0
419 
420     lda song_index
421     cmp #1
422     beq @song_01
423     cmp #2
424     beq @song_02
425 
426     ; Here since both of our songs came from different FamiStudio projects, 
427     ; they are actually 3 different song data, with a single song in each.
428     ; For a real game, if would be preferable to export all songs together
429     ; so that instruments shared across multiple songs are only exported once.
430     @song_00:
431         lda #<song_title_00
432         sta @text_ptr+0
433         lda #>song_title_00
434         sta @text_ptr+1
435         ldx #<song_data_00
436         ldy #>song_data_00
437         jmp @play_song
438 
439     @song_01:
440         lda #<song_title_01
441         sta @text_ptr+0
442         lda #>song_title_01
443         sta @text_ptr+1
444         ldx #<song_data_01
445         ldy #>song_data_01
446         jmp @play_song
447 
448     @song_02:
449         lda #<song_title_02
450         sta @text_ptr+0
451         lda #>song_title_02
452         sta @text_ptr+1
453         ldx #<song_data_02
454         ldy #>song_data_02
455         jmp @play_song
456     
457     @play_song:
458     lda #1 ; NTSC
459     jsr famistudio_init
460     lda #0
461     jsr famistudio_music_play
462 
463     ;update title.
464     ldx #2
465     ldy #15
466     jsr draw_text
467     jsr ppu_update
468 
469     rts
470 
471 equalizer_ppu_addr_lo_lookup:
472     .byte $47 ; Square 1
473     .byte $4b ; Square 2
474     .byte $4f ; Triangle
475     .byte $53 ; Noise
476     .byte $57 ; DPCM
477 
478 equalizer_ppu_addr_hi_lookup:
479     .byte $22 ; Square 1
480     .byte $22 ; Square 2
481     .byte $22 ; Triangle
482     .byte $22 ; Noise
483     .byte $22 ; DPCM
484 
485 ; Which 4 BG tiles to draw for each "volume" [0-7]
486 equalizer_volume_lookup:
487     .byte $e3, $e3, $e3, $e3 ; 0
488     .byte $e3, $e3, $e3, $e0 ; 1
489     .byte $e3, $e3, $e3, $f0 ; 2
490     .byte $e3, $e3, $e0, $f0 ; 3
491     .byte $e3, $e3, $f0, $f0 ; 4
492     .byte $e3, $e0, $f0, $f0 ; 5
493     .byte $e3, $f0, $f0, $f0 ; 6
494     .byte $e0, $f0, $f0, $f0 ; 7
495     .byte $f0, $f0, $f0, $f0 ; 8
496 
497 ; To add some color variety.
498 equalizer_color_lookup:
499     .byte $00, $01, $02
500     .byte $00, $01
501 
502 ; x = channel to update
503 update_equalizer:
504     
505     channel_idx = r0
506     color_offset = r1
507 
508     stx channel_idx
509     lda equalizer_color_lookup, x
510     sta color_offset
511 
512     ; Write 2 addresses
513     ldy nmt_update_len
514     lda equalizer_ppu_addr_hi_lookup, x
515     sta nmt_update_data,y
516     lda equalizer_ppu_addr_lo_lookup, x
517     sta nmt_update_data+1,y
518 
519     ; Always update 4 tiles
520     lda #4
521     sta nmt_update_data+2,y
522 
523     ; Compute lookup index based on "volume".
524     lda famistudio_chn_note_counter, x
525     asl
526     asl
527     tax
528 
529     clc
530     lda equalizer_volume_lookup, x
531     adc color_offset
532     sta nmt_update_data+3,y
533     lda equalizer_volume_lookup+1, x
534     adc color_offset
535     sta nmt_update_data+4,y
536     lda equalizer_volume_lookup+2, x
537     adc color_offset
538     sta nmt_update_data+5,y
539     lda equalizer_volume_lookup+3, x
540     adc color_offset
541     sta nmt_update_data+6,y
542     
543     lda #7
544     adc nmt_update_len
545     sta nmt_update_len 
546     ldx channel_idx
547 
548     rts
549 
550 main:
551 
552     ldx #0
553     @palette_loop:
554         lda default_palette, x
555         sta palette, x
556         sta palette+16, x
557         inx
558         cpx #16
559         bcc @palette_loop
560 
561     ; Force palette update.
562     lda #2
563     sta nmt_update_mode
564 
565     jsr setup_background
566     jsr ppu_update
567 
568     lda #0 ; song zero.
569     sta song_index
570     jsr play_song
571 
572     ; Load SFX
573     ldx #<sounds
574     ldy #>sounds
575     jsr famistudio_sfx_init
576 
577 @loop:
578 
579     jsr gamepad_poll_dpcm_safe
580     
581     @check_right:
582         lda gamepad_pressed
583         and #PAD_R
584         beq @check_left
585 
586         ; dont go beyond last song.
587         lda song_index
588         cmp #(NUM_SONGS - 1)
589         beq @draw
590 
591         ; next song.
592         clc
593         adc #1
594         sta song_index
595         jsr play_song
596         jmp @draw_done 
597 
598     @check_left:
599         lda gamepad_pressed
600         and #PAD_L
601         beq @check_select
602 
603         ; dont go below zero
604         lda song_index
605         beq @draw
606 
607         sec
608         sbc #1
609         sta song_index
610         jsr play_song
611         jmp @draw_done 
612 
613     @check_select:
614         lda gamepad_pressed
615         and #PAD_SELECT
616         beq @check_start
617 
618         ; Undocumented: selects plays a SFX sample when journey to silius is loaded.
619         lda song_index
620         cmp #1
621         bne @draw
622 
623         lda #21
624         jsr famistudio_sfx_sample_play
625         jmp @draw
626 
627     @check_start:
628         lda gamepad_pressed
629         and #PAD_START
630         beq @check_a
631 
632         lda #1
633         eor pause_flag
634         sta pause_flag
635 
636         jsr famistudio_music_pause
637         jmp @draw
638 
639     @check_a:
640         lda gamepad_pressed
641         and #PAD_A
642         beq @check_b
643 
644         lda #0
645         ldx #FAMISTUDIO_SFX_CH0
646         jsr famistudio_sfx_play
647         beq @draw
648 
649     @check_b:
650         lda gamepad_pressed
651         and #PAD_B
652         beq @draw
653 
654         lda #1
655         ldx #FAMISTUDIO_SFX_CH1
656         jsr famistudio_sfx_play
657         beq @draw
658 
659 @draw:
660 
661     jsr famistudio_update ; TODO: Call in NMI.
662     
663     lda nmt_update_mode
664     bne @draw_done ; Dont allow update if we already have an update pending.
665 
666     ldx #0
667     jsr update_equalizer
668     ldx #1
669     jsr update_equalizer
670     ldx #2
671     jsr update_equalizer
672     ldx #3
673     jsr update_equalizer
674     ldx #4
675     jsr update_equalizer
676 
677     lda #1
678     sta nmt_update_mode
679 
680 @draw_done:
681 
682     jsr ppu_update
683     jmp @loop
684 
685 ; Shiru's code.
686 ; x = lo byte of RLE data addr
687 ; y = hi byte of RLE data addr
688 rle_decompress:
689 
690 @rle_lo   = r0
691 @rle_high = r1
692 @rle_tag  = r2
693 @rle_byte = r3
694 
695     stx <@rle_lo
696     sty <@rle_high
697     ldy #0
698     jsr rle_read_byte
699     sta <@rle_tag
700 @loop:
701     jsr rle_read_byte
702     cmp @rle_tag
703     beq @is_rle
704     sta $2007
705     sta <@rle_byte
706     bne @loop
707 @is_rle:
708     jsr rle_read_byte
709     cmp #0
710     beq @done
711     tax
712     lda <@rle_byte
713 @rle_loop:
714     sta $2007
715     dex
716     bne @rle_loop
717     beq @loop
718 @done: ;.4
719     rts
720 
721 rle_read_byte:
722 
723 @rle_lo   = r0
724 @rle_high = r1
725 
726     lda (@rle_lo),y
727     inc @rle_lo
728     bne @done
729     inc @rle_high
730 @done:
731     rts
732 
733 ; Draws text with rendering on.
734 ; x/y = tile position
735 ; p0  = pointer to text data.
736 draw_text:
737 
738     @temp_x = r2
739     @temp   = r3
740     @text_ptr = p0
741     
742     stx @temp_x
743     ldx nmt_update_len
744     tya
745     lsr
746     lsr
747     lsr
748     ora #$20 ; high bits of Y + $20
749     sta nmt_update_data,x
750     inx
751     tya
752     asl
753     asl
754     asl
755     asl
756     asl
757     sta @temp
758     lda @temp_x
759     ora @temp
760     sta nmt_update_data,x
761     inx
762     lda #28 ; all our strings have 28 characters.
763     sta nmt_update_data,x
764     inx
765 
766     ldy #0
767     @text_loop:
768         lda (@text_ptr),y
769         sta nmt_update_data,x
770         inx
771         iny
772         cpy #28
773         bne @text_loop
774 
775     stx nmt_update_len
776     lda #2
777     sta nmt_update_mode
778     rts
779 
780 setup_background:
781 
782     ; first nametable, start by clearing to empty
783     lda $2002 ; reset latch
784     lda #$20
785     sta $2006
786     lda #$00
787     sta $2006
788 
789     ; BG image.
790     ldx #<screen_data_rle
791     ldy #>screen_data_rle
792     jsr rle_decompress
793 
794     ; Add a few sprites to the FamiStudio logo.
795     lda #80
796     sta oam+3
797     lda #15
798     sta oam+0
799     lda #$51
800     sta oam+1
801     lda #1
802     sta oam+2
803 
804     lda #72
805     sta oam+7
806     lda #23
807     sta oam+4
808     lda #$60
809     sta oam+5
810     lda #1
811     sta oam+6
812 
813     lda #88
814     sta oam+11
815     lda #23
816     sta oam+8
817     lda #$62
818     sta oam+9
819     lda #1
820     sta oam+10
821 
822     ; Draw version
823     lda $2002
824     lda #$23
825     sta $2006
826     lda #$79
827     sta $2006
828 
829     ldy #0
830     @version_loop:
831         lda version_text,y
832         sta $2007
833         iny
834         cpy #5
835         bne @version_loop
836 
837     rts
838 
839     ; SONG
840     ;.org $a000
841 song_data_00:
842     .include "song_silver_surfer_asm6.asm"
843 sfx_data:
844     .include "sfx_asm6.asm"
845     ;.org $c000
846 song_data_01:
847     .include "song_superfusion_asm6.asm"
848     ;.org $d000
849 song_data_02:
850     .include "song_magic_jewelry_song_1_asm6.asm"
851 
852     ; DPCM
853     .org $e000
854     .incbin "song_superfusion_asm6.dmc"
855 
856     ; VECTORS
857     .org $fffa
858     .dw nmi
859     .dw reset
860     .dw irq
861 
862     ; CHARS
863     .incbin "demo.chr"
864     .incbin "demo.chr"

 

posted on 2023-01-22 14:27  大魔司教教主  阅读(519)  评论(0编辑  收藏  举报

导航