***************************************************************************** * * CyberSound: 14 Bit sound driver * * (c) 1995 by Christian Buchner * ***************************************************************************** * * AsmSupport.asm * SECTION Code,CODE * _CreateTable ************************************************************** ; Parameters ; a0 = Table address ; (MUST have enough space for 65536 UWORDS) ; a1 = Additive Array ; 256 UBYTEs ; ; the table is organized as follows: ; 32768 UWORDS positive range, ascending order ; 32768 UWORDS negative range, ascending order ; access: (a0,d0.l*2) ; where d0.w is signed word sample data ; and the upper word of d0.l is *cleared!* XDEF _CreateTable _CreateTable movem.l a2/d2-d6,-(sp) lea 128(a1),a2 move.l a2,a1 ; count the number of steps moveq #128-1,d0 ; in the positive range moveq #0,d5 .countpositive move.b (a1)+,d1 ext.w d1 ext.l d1 add.l d1,d5 dbra d0,.countpositive ; d5=number of steps move.l #32768,d6 ; reset stretch counter move.l a2,a1 ; middle value in calibdata move.w #32768-1,d0 ; number of positive values -1 moveq #0,d1 ; HI value moveq #0,d2 ; LO value moveq #0,d3 ; counter .fetchnext2 move.b (a1)+,d4 ; add calibtable to counter ext.w d4 add.w d4,d3 .outerloop2 tst.w d3 bgt.s .positive2 .negative2 addq.w #1,d1 ; increment HI value sub.w d4,d2 ; reset LO value bra.s .fetchnext2 .positive2 move.b d1,(a0)+ ; store HI and LO value move.b d2,(a0)+ sub.l d5,d6 ; stretch the table bpl.s .repeat2 ; to 32768 entries add.l #32768,d6 addq.w #1,d2 ; increment LO value subq.w #1,d3 ; decrement counter .repeat2 dbra d0,.outerloop2 move.l a2,a1 ; count the number of steps moveq #128-1,d0 ; in the negative range moveq #0,d5 .countnegative move.b -(a1),d1 ext.w d1 ext.l d1 add.l d1,d5 dbra d0,.countnegative ; d5=number of steps move.l #32768,d6 ; reset stretch counter add.l #2*32768,a0 ; place at the end of the table move.l a2,a1 ; middle value in calibdata move.w #32768-1,d0 ; number of negative values -1 moveq #-1,d1 ; HI value moveq #-1,d2 ; LO value moveq #0,d3 ; counter .fetchnext1 move.b -(a1),d4 ; add calibtable to counter ext.w d4 add.w d4,d3 add.w d4,d2 ; maximize LO value .outerloop1 tst.w d3 bgt.s .positive1 .negative1 subq.w #1,d1 bra.s .fetchnext1 .positive1 move.b d2,-(a0) ; store LO and HI value move.b d1,-(a0) sub.l d5,d6 ; stretch the table bpl.s .repeat1 ; to 32768 entries add.l #32768,d6 subq.w #1,d2 ; decrement lo value subq.w #1,d3 ; decrement counter .repeat1 dbra d0,.outerloop1 movem.l (sp)+,a2/d2-d6 rts * _ConvertStream ************************************************************* ; Parameters ; a0=Stream pointer ; a1=MSB channel ; a2=LSB channel ; a3=Table address ; d0=samples ; d1=interleave XDEF _ConvertStream _ConvertStream movem.l d2/d3/d4/a2/a3,-(sp) addq.w #1,d1 ; calc byte distance add.w d1,d1 ; between 16 bit samples moveq #0,d2 ; clear d2 LONGWORD ; This first loop minimizes access to chip RAM ; by creating ULONGs move.w d0,-(sp) ; store samples lsr.l #2,d0 ; calc samples/4 bra.s .convertentry ; enter loop .convertHI swap d0 .convertLO move.w (a0),d2 ; get 16 bit data add.w d1,a0 ; interleave move.w (a3,d2.l*2),d3 ; get high/low byte move.b d3,d4 rol.w #8,d4 ; shift left ; d3: ---- ---- 1111 ---- ; d4: ---- ---- 1111 ---- move.w (a0),d2 ; get 16 bit data add.w d1,a0 ; interleave move.b (a3,d2.l*2),d3 ; get high byte swap d3 ; swap ULONG move.b 1(a3,d2.l*2),d4 ; get low byte swap d4 ; swap ULONG ; d3: 1111 2222 ---- ---- ; d4: 1111 2222 ---- ---- move.w (a0),d2 ; get 16 bit data add.w d1,a0 ; interleave move.w (a3,d2.l*2),d3 ; get high/low byte move.b d3,d4 rol.w #8,d4 ; d3: 1111 2222 3333 ---- ; d4: 1111 2222 3333 ---- move.w (a0),d2 ; get 16 bit data add.w d1,a0 ; interleave move.b (a3,d2.l*2),d3 ; get high byte move.l d3,(a1)+ ; store 4 high bytes move.b 1(a3,d2.l*2),d4 ; get low byte move.l d4,(a2)+ ; store 4 low bytes ; d3: 1111 2222 3333 4444 ; d4: 1111 2222 3333 4444 .convertentry dbra d0,.convertLO ; loop back swap d0 dbra d0,.convertHI move.w (sp)+,d0 ; restore samples and.w #$3,d0 ; calculate samples MOD 3 bra.s .restentry ; enter loop .restLO move.w (a0),d2 ; get 16 bit data add.w d1,a0 ; interleave move.b (a3,d2.l*2),(a1)+ ; store high byte move.b 1(a3,d2.l*2),(a2)+ ; store low byte .restentry dbra d0,.restLO ; loop back movem.l (sp)+,d2/d3/d4/a2/a3 rts * _SwapEndian ***************************************************************** ; Parameters ; a0=Table pointer XDEF _SwapEndian _SwapEndian movem.l d2/d3,-(sp) move.w #65535,d0 ; loop 65536 UWORDs moveq #0,d1 ; start offset = 0 .loop move.l d1,d2 ; calculate swap offset rol.w #8,d2 ; swap big<->little endian cmp.l d1,d2 ; only swap if one is lower bhs.s .skip move.w (a0,d1.l*2),d3 ; swap the table entries move.w (a0,d2.l*2),(a0,d1.l*2) move.w d3,(a0,d2.l*2) .skip addq.l #1,d1 ; increment offset dbra d0,.loop ; loop back movem.l (sp)+,d2/d3 rts ****************************************************************************** END