base:nmi_sample_player
no way to compare when less than two revisions
Differences
This shows you the differences between two versions of the page.
— | base:nmi_sample_player [2015-04-17 04:33] (current) – created - external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== NMI Sample player ====== | ||
+ | Coded using the CA65 assembler. | ||
+ | |||
+ | use like this: | ||
+ | |||
+ | call NMIDIGI_Init once for init, then call NMIDIGI_Play with a pointer (x=hi,y=lo) to a table with parameters (data start lo/hi, data end lo/hi, samplerate lo/hi). NMIDIGI_Off temporarily disables the player, NMIDIGI_On enables it again. | ||
+ | |||
+ | the various compile-time options should be self-explaining (i hope) :) | ||
+ | |||
+ | < | ||
+ | ; | ||
+ | ; NMI Sample player (w) Groepaz/ | ||
+ | ; | ||
+ | |||
+ | .export NMIDIGI_Init | ||
+ | .export NMIDIGI_On | ||
+ | .export NMIDIGI_Off | ||
+ | .export NMIDIGI_Play | ||
+ | |||
+ | .export NMIDIGION | ||
+ | .export NMIDIGIOFF | ||
+ | |||
+ | withsidplayer=0 | ||
+ | .if(withsidplayer=1) | ||
+ | sidplayervol=D418HLP | ||
+ | .endif | ||
+ | |||
+ | ;0: high nibble first 1: low nibble first | ||
+ | firstnibble=1 | ||
+ | ;1: no nibbles | ||
+ | nonibbles=1 | ||
+ | |||
+ | NMIDIGI_Init: | ||
+ | jsr NMIDIGI_Off | ||
+ | |||
+ | lda #$00 | ||
+ | ldx #$00 | ||
+ | @l: | ||
+ | sta __SID__,x | ||
+ | inx | ||
+ | bne @l | ||
+ | |||
+ | lda #$00 | ||
+ | sta __SID__+$05 | ||
+ | lda #$f0 | ||
+ | sta __SID__+$06 | ||
+ | lda #$01 | ||
+ | sta __SID__+$04 | ||
+ | lda #$00 | ||
+ | sta __SID__+$0c | ||
+ | lda #$f0 | ||
+ | sta __SID__+$0d | ||
+ | lda #$01 | ||
+ | sta __SID__+$0b | ||
+ | lda #$00 | ||
+ | sta __SID__+$13 | ||
+ | lda #$f0 | ||
+ | sta __SID__+$14 | ||
+ | lda #$01 | ||
+ | sta __SID__+$12 | ||
+ | lda #$00 | ||
+ | sta __SID__+$15 | ||
+ | lda #$10 | ||
+ | sta __SID__+$16 | ||
+ | lda #%11110111 | ||
+ | sta __SID__+$17 | ||
+ | |||
+ | rts | ||
+ | |||
+ | NMIDIGI_On: | ||
+ | LDA #> | ||
+ | STA $FFFB | ||
+ | LDA #< | ||
+ | STA $FFFA | ||
+ | |||
+ | LDA # | ||
+ | STA $DD0D | ||
+ | lda $DD0D | ||
+ | LDA # | ||
+ | STA $DD0E | ||
+ | rts | ||
+ | NMIDIGI_Off: | ||
+ | LDA #%00000000 | ||
+ | STA $DD0E ; timer A stop | ||
+ | LDA # | ||
+ | STA $DD0D | ||
+ | lda $DD0D | ||
+ | |||
+ | LDA #> | ||
+ | STA $FFFB | ||
+ | LDA #< | ||
+ | STA $FFFA | ||
+ | |||
+ | lda #$00 | ||
+ | sta NMIPOINT | ||
+ | sta NMIPOINT+1 | ||
+ | sta DIGISTOPLO+1 | ||
+ | sta DIGISTOPHI+1 | ||
+ | |||
+ | rts | ||
+ | |||
+ | |||
+ | NMIDIGI_Play: | ||
+ | |||
+ | jsr NMIDIGI_Off | ||
+ | |||
+ | stx NMIDIGIPTR+1 | ||
+ | sty NMIDIGIPTR | ||
+ | |||
+ | ldy #$00 | ||
+ | lda (NMIDIGIPTR), | ||
+ | sta NMIPOINT | ||
+ | iny | ||
+ | lda (NMIDIGIPTR), | ||
+ | sta NMIPOINT+1 | ||
+ | iny | ||
+ | lda (NMIDIGIPTR), | ||
+ | sta DIGISTOPLO+1 | ||
+ | iny | ||
+ | lda (NMIDIGIPTR), | ||
+ | sta DIGISTOPHI+1 | ||
+ | iny | ||
+ | lda (NMIDIGIPTR), | ||
+ | sta $DD04 | ||
+ | iny | ||
+ | lda (NMIDIGIPTR), | ||
+ | sta $DD05 | ||
+ | |||
+ | |||
+ | .if(nonibbles=0) | ||
+ | lda #$00 | ||
+ | sta nib+1 | ||
+ | .endif | ||
+ | |||
+ | jsr NMIDIGI_On | ||
+ | |||
+ | rts | ||
+ | |||
+ | ; | ||
+ | |||
+ | NMIDIGION: | ||
+ | STA NMIABUFF | ||
+ | STY NMIYBUFF | ||
+ | |||
+ | .if (withsidplayer=1) | ||
+ | lda sidplayervol | ||
+ | and #$f0 | ||
+ | .else | ||
+ | lda #$10 | ||
+ | .endif | ||
+ | |||
+ | D418NMI: | ||
+ | sta __SID__+$18 | ||
+ | |||
+ | .if (withsidplayer=1) | ||
+ | sta sidplayervol | ||
+ | .endif | ||
+ | |||
+ | .if (DEBUG=1) | ||
+ | sta $d020 | ||
+ | .endif | ||
+ | |||
+ | LDA NMIPOINT+1 | ||
+ | DIGISTOPHI: | ||
+ | BNE SK1 | ||
+ | |||
+ | LDA NMIPOINT | ||
+ | DIGISTOPLO: | ||
+ | BNE SK1 | ||
+ | |||
+ | .if (withsidplayer=1) | ||
+ | lda #$08 | ||
+ | .else | ||
+ | lda #$00 | ||
+ | .endif | ||
+ | |||
+ | STA D418NMI+1 | ||
+ | |||
+ | jsr NMIDIGI_Off | ||
+ | |||
+ | LDA NMIABUFF | ||
+ | |||
+ | RTI | ||
+ | |||
+ | SK1: | ||
+ | |||
+ | LDY #$00 | ||
+ | |||
+ | .if(nonibbles=0) | ||
+ | nib: lda #$00 | ||
+ | and #$01 | ||
+ | bne s1 | ||
+ | .endif | ||
+ | |||
+ | LDA (NMIPOINT), | ||
+ | |||
+ | .if(nonibbles=0) | ||
+ | .if(firstnibble=0) ; high nibble first | ||
+ | lsr a | ||
+ | lsr a | ||
+ | lsr a | ||
+ | lsr a | ||
+ | .else ; low nibble first | ||
+ | AND #$0F | ||
+ | .endif | ||
+ | |||
+ | jmp s2 | ||
+ | s1: | ||
+ | LDA (NMIPOINT), | ||
+ | .if(firstnibble=1) ; high nibble second | ||
+ | lsr a | ||
+ | lsr a | ||
+ | lsr a | ||
+ | lsr a | ||
+ | .else ; low nibble second | ||
+ | AND #$0F | ||
+ | .endif | ||
+ | .endif | ||
+ | |||
+ | INC NMIPOINT | ||
+ | BNE @SK | ||
+ | INC NMIPOINT+1 | ||
+ | @SK: | ||
+ | s2: | ||
+ | STA D418NMI+1 | ||
+ | |||
+ | .if(nonibbles=0) | ||
+ | inc nib+1 | ||
+ | .endif | ||
+ | |||
+ | LDA $DD0D | ||
+ | |||
+ | NMIABUFF=*+1 | ||
+ | LDA #$00 | ||
+ | NMIYBUFF=*+1 | ||
+ | LDY #$00 | ||
+ | |||
+ | NMIDIGIOFF: | ||
+ | RTI | ||
+ | |||
+ | </ | ||
+ | ---------------- | ||
+ | (Edit: Suggestion from Algorithm) | ||
+ | |||
+ | the digiboost should be something along the lines of.. | ||
+ | |||
+ | < | ||
+ | lda #$ff | ||
+ | sta $d406 | ||
+ | sta $d406+7 | ||
+ | sta $d496+14 | ||
+ | lda #$49 | ||
+ | sta $d404 | ||
+ | sta $d404+7 | ||
+ | sta $d404+14 | ||
+ | </ | ||
+ | |||
+ | and the nmi frequency needs to be set. eg | ||
+ | |||
+ | < | ||
+ | lda #$3c | ||
+ | sta $dd04 | ||
+ | lda #$00 | ||
+ | sta $dd05 | ||
+ | </ | ||
+ | |||
+ | ---------------- | ||
+ | (Edit enthusi) | ||
+ | |||
+ | If you are in real need for cycles and have some RAM left you can replace | ||
+ | the LSRs with: | ||
+ | |||
+ | < | ||
+ | tay | ||
+ | lda freq_table, | ||
+ | </ | ||
+ | |||
+ | and set up a table via | ||
+ | |||
+ | < | ||
+ | ldx #0 | ||
+ | loop2 | ||
+ | ldy #16 | ||
+ | value | ||
+ | lda #0 | ||
+ | loop | ||
+ | sta freq_table, | ||
+ | inx | ||
+ | dey | ||
+ | bne loop | ||
+ | cpx #$00 | ||
+ | beq end | ||
+ | inc value+1 | ||
+ | jmp loop2 | ||
+ | end | ||
+ | rts | ||
+ | </ |
base/nmi_sample_player.txt · Last modified: 2015-04-17 04:33 by 127.0.0.1