* sample.m65 * started : 97-09-24 (only 3mths till Xmas !!) * * Warning : Just experimental. This code _WILL_ change ! * Also parameters etc. * functions: void SmpInit(char channel,char timer); * void SmpStart(char * sample,char speed); * void SmpStop(); * int SmpActive(); global _SmpInit global _SmpStart global _SmpStop global _SmpActive * extern labels xref popax,pushax xref _InstallIRQ bss SmpCount ds 2 SmpSema ds 1 SmpTemp ds 1 SmpChannel ds 1 SmpChannel8 ds 1 SmpTimer ds 1 bsszp smp_ptr ds 2 text mask dc.b $11,$22,$44,$88 ; void SmpInit(char channel,char timer) ; channel is the channel-number : 0..3 ; timer is the timer-number : 0..7 (where 0,2,4 makes no sense !) _SmpInit:: jsr popax ; get timer and #7 asl A asl A pha sta SmpTimer jsr popax ; get channel and #3 sta SmpChannel plx stz $fd01,x ; stop Timer tay asl A asl A asl A sta SmpChannel8 pha lda mask,y tsb $fd44 ; voice A balance controled tsb $fd50 ; but curr. quite lda #$ff sta $fd40,y ; and full volume left and right plx stz $fd25,x ; stop channel counter stz $fd22,x ; channel quiet please rts **************** * play mono sample **************** SmpIRQ:: lda (smp_ptr) ldx SmpChannel8 sta $fd22,x inc smp_ptr bne SmpIRQ2 inc smp_ptr+1 SmpIRQ2: inc SmpCount bne SmpExit inc SmpCount+1 bne SmpExit _SmpStop:: ldy SmpChannel lda mask,y tsb $fd50 ldx SmpTimer stz $fd01,x SmpExit: rts **************** * play packed mono-samples ***************** SmpIRQp:: dec SmpSema bmi no_read lda (smp_ptr) inc smp_ptr bne SmpIRQp0 inc smp_ptr+1 SmpIRQp0 inc SmpCount bne SmpIRQp1 inc SmpCount+1 beq _SmpStop SmpIRQp1 sta SmpIRQp2+1 ; self mod lsr A lsr A lsr A lsr A * * if there's enough space, could do it with a table * bra SmpIRQp3 no_read: lda #1 sta SmpSema SmpIRQp2: lda #0 and #$f SmpIRQp3: tax clc lda tabelle,x adc SmpTemp sta SmpTemp ldx SmpChannel8 bcc __1 dec $fda0 * * Note : with stx $fd22+8 it sounds better but you'll use another channel * __1 asl bcc __2 lda #255 __2 sta $fd22,x rts tabelle: DC.B 128,-64,-32,-16,-8,-4,-2,-1,0,1,2,4,8,16,32,64 ; SmpStart(char * sample,char speed) ; ; sample is a pointer to a structure : ; stereo ds 1 ; length ds 2 ; big-endian (har,har) ; divider ds 1 ; 1MHz/sample-freq. ; unpacked ds 1 : == 0 sample packed ; ; divider may be overridden by speed (!= 0) ; _SmpStart:: ldx SmpTimer stz $fd01,x ; stop current sample ldx SmpChannel8 stz $fd22,x ; silence stz SmpTemp lda #1 sta SmpSema jsr popax pha ; save speed for later use jsr popax ; get data sta ptr1 stx ptr1+1 clc adc #5 sta smp_ptr txa adc #0 sta smp_ptr+1 ; no stereo yet, so go to offset 1 ldy #1 lda (ptr1),y eor #$ff sta SmpCount+1 iny lda (ptr1),y eor #$ff sta SmpCount iny lda (ptr1),y ldx SmpTimer sta $fd00,x iny lda (ptr1),y pha ; save packed-flag txa ldx #0 lsr A lsr A ; we want the number not offset jsr pushax ; pushax destroys y and maybe ptr1 !! ldax #SmpIRQ ply ; check packed-flag bne _SmpStart0 ldax #SmpIRQp _SmpStart0: jsr pushax ;> ldy #2 jsr _InstallIRQ ldx SmpTimer pla beq _SmpStart2 sta $fd00,x _SmpStart2: php sei lda #%10011000 sta $fd01,x ldy SmpChannel lda mask,y trb $fd50 plp rts **************** * int SmpActive() **************** _SmpActive:: ldx SmpTimer lda $fd01,x ldx #0 cmp #0 rts