;*************************************************************************** ; VOICEDLT.ASM DSP56303 EVB program for Computer Applications Lab ; Voice Processing Delta-Modulation Experiment ; ; Authors: Ellery Blood (original) ; John Cogdell (added D4 mode) ; Russell Kraft (corrected errors, additional features) ; ;10/23/2002 Assemble with the command: ; asm56300 -a -bVOICEDLT.CLD -lVOICEDLT.LST VOICEDLT.ASM ; ; This program simulates two methods for recording andplaying back audio ; in a digital format. The first method is basic storing of sampled data values ; and fetching for playback. The mode of sampling can be represented with 1 bit ; per sample (the most coarse, but most compact) to 16 bits per sample (the ; finest, but least compact). The second method is delta modulation, which ; records the changes between adjacent values. Depending on the mode, ; it can use either 1, 2, or 3 bits per sample. The coarseness is determined ; by the minimum step size of the response. ; ; brings data in through CODEC, samples it at 1-16 bits, and sends back out the CODEC ;*************************************************************************** nolist include 'ioequ.asm' include 'intequ.asm' include 'ada_equ.asm' include 'vectors.asm' list ;****************************************************************************** ;---Buffer for talking to the CS4215 org x:0 RX_BUFF_BASE equ * RX_data_1_2 ds 1 ;data time slot 1/2 for RX ISR RX_data_3_4 ds 1 ;data time slot 3/4 for RX ISR RX_data_5_6 ds 1 ;data time slot 5/6 for RX ISR RX_data_7_8 ds 1 ;data time slot 7/8 for RX ISR TX_BUFF_BASE equ * TX_data_1_2 ds 1 ;data time slot 1/2 for TX ISR TX_data_3_4 ds 1 ;data time slot 3/4 for TX ISR TX_data_5_6 ds 1 ;data time slot 5/6 for TX ISR TX_data_7_8 ds 1 ;data time slot 7/8 for TX ISR RX_PTR ds 1 ;Pointer for rx buffer TX_PTR ds 1 ;Pointer for tx buffer ;TONE_OUTPUT equ HEADPHONE_EN+LINEOUT_EN+(4*LEFT_ATTN)+(4*RIGHT_ATTN) ;TONE_INPUT equ MIC_IN_SELECT+(15*MONITOR_ATTN) ;CTRL_WD_12 equ NO_PREAMP+HI_PASS_FILT+SAMP_RATE_48+STEREO+DATA_16 ;CLB=0 ;CTRL_WD_34 equ IMMED_3STATE+XTAL1_SELECT+BITS_64+CODEC_MASTER ;CTRL_WD_56 equ $000000 ;CTRL_WD_78 equ $000000 ; These following values are defined in the file ada_equ.asm - ; output attenuation is nominally 0dB, input gain is nominally 7.5dB CTRL_WD_12 equ MIN_LEFT_ATTN+MIN_RIGHT_ATTN+LIN2+RIN2 CTRL_WD_34 equ LEFT_GAIN+RIGHT_GAIN ;Needed to offset system's V gain of 0.275 ;CTRL_WD_34 equ MIN_LEFT_GAIN+MIN_RIGHT_GAIN org p:$50 ;SCI Recieve Data Interrupt jsr ISCIRD org p:$100 START main movep #$040003,x:M_PCTL ;set PLL for MPY of 4X movep #$012421,x:M_BCR ;set up one ext. wait state for all AAR areas ori #3,mr ;mask interrupts movec #0,sp ;clear hardware stack pointer move #0,omr ;operating mode 0 move #$40,r6 ;initialise stack pointer move #-1,m6 ;linear addressing jsr ada_init ;initialize codec ; initialize SCI ; 10-bit asynchronous mode ; enable reciever and transmitter movep #$000B02,x:M_SCR ;SCI control register ; set interrupt priority for SCI RECV to 1 move x:M_IPRP,a ;grab register current value ; enable tx and rx pins movep #$000003,x:M_PCRE ;Port E Control Register or #000080,a ;set bits for interrupt priority 2 ; Reciever/Transmitter clocks use external clock from SCLK movep #$00C000,x:M_SCCR ;SCI Clock Control Register move a,x:M_IPRP ;put value in interrupt priority peripheral register ; print a greeting and instructions move #greet,r5 jsr print loop_1 jset #2,x:M_SSISR0,* ;wait for frame sync to pass jclr #2,x:M_SSISR0,* ;wait for frame sync move x:RX_BUFF_BASE,a ;receive left move x:RX_BUFF_BASE+1,b ;receive right jsr process_stereo move a,x:TX_BUFF_BASE ;transmit left move b,x:TX_BUFF_BASE+1 ;transmit right move #CTRL_WD_12,y0 ;set up control words move y0,x:TX_BUFF_BASE+2 move #CTRL_WD_12,y0 move y0,x:TX_BUFF_BASE+3 jmp loop_1 process_stereo move a,y:newa ;store new right channel value move b,y:newb ;store new left channel value move y:count,a move y:divider,b ;check divide counter add #>$1,a cmp b,a bge proc move a,y:count ;increment divide counter move y:olda,a move y:oldb,b rts proc move #0,a ;reset divide counter nop move a,y:count move y:mode,a tst a bne delta move #$800000,b ;initial mask move y:masksz,x0 asr x0,b,b ;shift the mask nop move b,y:mask move y:newa,a move y:newb,b move y:mask,y0 and y0,a and y0,b move a,y:olda move b,y:oldb rts delta ; debug move y:diff,y0 ;load max delta mask into y0 move y:masksz,x0 move y:newa,a move y:olda,b ;new in a, old in b sub b,a ;get difference nop move a,y:temp ;hold difference in temp abs a ;check to see if it is in range cmp y0,a blt smalla move y0,a smalla asr x0,a,a asr #6,a,a and #7,a ;I should be able to remove this move y:coefloc,x0 add x0,a move y:masksz,x0 move a,r5 nop nop nop move y:(r5),a nop asl x0,a,a asl #6,a,a move y:temp,b tst b bgt posa ; move y:diff,a neg a nop move a,y:temp bra gooda posa ; move y:diff,a move a,y:temp gooda move y:temp,a move y:olda,b add b,a ;add delta back in nop move a,y:olda ;store new value move y:masksz,x0 move y:newb,a move y:oldb,b ;new in a, old in b sub b,a ;get difference nop move a,y:temp ;hold difference in temp abs a ;check to see if it is in range cmp y0,a blt smallb move y0,a smallb asr x0,a,a asr #6,a,a and #7,a ;I should be able to remove this move y:coefloc,x0 add x0,a move y:masksz,x0 move a,r5 nop nop nop move y:(r5),a nop asl x0,a,a asl #6,a,a move y:temp,b tst b bgt posb ; move y:diff,a neg a nop move a,y:temp bra goodb posb ; move y:diff,a move a,y:temp goodb move y:temp,a move y:oldb,b add b,a ;add delta back in nop move a,y:oldb ;store new value move y:olda,a move y:oldb,b rts ; print subroutine takes address in register r5 ; exits when most significant byte is zero ; ignores zeros in lower bytes ; clobbers accumulator A and B and register r5 print ; Next 2 lines used in Cogdell mode (D4) move a,y:backa move b,y:backb prbegin move y:(r5)+,a ; cmp #$00ffff,a ;check to see if done (char=$00) ; blt prend cmp #$000000,a ;check to see if done (char=$00) beq prend jclr #1,x:M_SSR,* ;wait for tx to finish jclr #0,x:M_SSR,* ;wait for tx to finish move a,x:M_STXH ;send high byte and #$00ffff,a cmp #$0000ff,a blt prbegin jclr #1,x:M_SSR,* ;wait for tx to finish jclr #0,x:M_SSR,* ;wait for tx to finish move a,x:M_STXM ;send mid byte and #$0000ff,a cmp #$000000,a blt prbegin jclr #1,x:M_SSR,* ;wait for tx to finish jclr #0,x:M_SSR,* ;wait for tx to finish move a,x:M_STXL ;send low byte bra prbegin ; Next 2 lines used in Cogdell mode (D4) move y:backa,a move y:backb,b prend rts ; the SCI interrupt is triggered when a character is received ; this function takes the character, checks to make sure it is ; in the correct range (1-9, A-G, a-g) prints a message and ; modifies the output mask for that number of bits ISCIRD move a,y0 ;back up A move x:M_SRXL,a cmp #'!',a beq iscd1 cmp #'@',a beq iscd2 cmp #'#',a beq iscd3 cmp #'$',a beq iscd4 cmp #'%',a beq iscd5 cmp #'^',a beq iscd6 cmp #'&',a beq iscd7 cmp #'*',a beq iscd8 cmp #'(',a beq iscd9 cmp #'A',a beq iscda cmp #'B',a beq iscdb cmp #'C',a beq iscdc cmp #'D',a beq iscdd cmp #$31,a ; >='1' blt iscend cmp #$3A,a ; <='9' blt iscnum cmp #'M',a ; =='M' ;change mode beq iscmode cmp #'m',a ; =='m' beq iscmode ; cmp #$40,a ; >='A' ; blt iscend ; cmp #$48,a ; <='G' ; blt isclet cmp #$60,a ; >='a' blt iscend cmp #$67,a ; <='g' bgt iscend sub #$20,a bra isclet iscnum add #$07,a isclet add #$09,a isciup jclr #1,x:M_SSR,* ;wait for tx to finish jclr #0,x:M_SSR,* ;wait for tx to finish movep #$0d,x:M_STXL ;print LF move #$800000,b ;initial mask move a,y:temp ;hold onto value temporarially sub #$41,a ;amount to shift mask nop ;can't avoid, 'sub' is slow move a,y:masksz move a,x0 asr x0,b,b ;shift the mask move #>$00000f,a ;calculate bit shift sub x0,a lsr a1,b move #<$00,b2 move y:temp,a move b,y:diff sub #$10,a cmp #$3A,a ;is a 10 digit? blt isci0 isci1 sub #$0a,a or #$001100,a ;add 10's digit if necessary isci0 add #$202000,a ; nop move #modech,r5 ;do move here instead of 'nop' move a,y:bits ; move #modech,r5 jsr print bra iscend iscmode move y:modech,a ;change modes cmp #$44302d,a ;check if D0 mode beq iscmd1 cmp #$44312d,a ;check if D1 mode beq iscmd2 cmp #$44322d,a ;check if D2 mode beq iscmd3 cmp #$44332d,a ;check if D3 mode beq iscmd4 cmp #$44342d,a ;check if D4 mode beq iscms bra iscmd0 ;must be S mode iscmd0 move #$44302d,a ;change from S to D0 mode ; nop move #>coef0,b ;do move here instead of 'nop' move a,y:modech move #1,a ; move #>coef0,b move b,y:coefloc move a,y:mode bra iscmend iscmd1 move #$44312d,a ;change from D0 to D1 mode ; nop move #>coef1,b ;do move here instead of 'nop' move a,y:modech move #1,a ; move #>coef1,b move b,y:coefloc move a,y:mode bra iscmend iscmd2 move #$44322d,a ;change from D1 to D2 mode ; nop move #>coef2,b ;do move here instead of 'nop' move a,y:modech move #1,a ; move #>coef2,b move b,y:coefloc move a,y:mode bra iscmend iscmd3 move #$44332d,a ;change from D2 to D3 mode ; nop move #>coef3,b ;do move here instead of 'nop' move a,y:modech move #1,a ; move #>coef3,b move b,y:coefloc move a,y:mode bra iscmend ; Add new mode, D4, here to use arbitrary user thresholds for ; A, B< C, & D parameters iscmd4 move #$44342d,a ;change from D3 to D4 mode ; nop move #>coef4,b ;do move here instead of 'nop' move a,y:modech move #1,a ; move #>coef4,b move b,y:coefloc move a,y:mode bra iscmend iscms move #$53202d,a ;change from D3 to S mode nop move a,y:modech move #0,a nop move a,y:mode bra iscmend iscmend jclr #1,x:M_SSR,* ;wait for tx to finish jclr #0,x:M_SSR,* ;wait for tx to finish movep #$0d,x:M_STXL ;print LF move #modech,r5 jsr print bra iscend iscd1 move y:d1,a move a,y:div move #>$1,a bra isccend iscd2 move y:d2,a move a,y:div move #>$2,a bra isccend iscd3 move y:d3,a move a,y:div move #>$3,a bra isccend iscd4 move y:d4,a move a,y:div move #>$4,a bra isccend iscd5 move y:d5,a move a,y:div move #>$5,a bra isccend iscd6 move y:d6,a move a,y:div move #>$6,a bra isccend iscd7 move y:d7,a move a,y:div move #>$7,a bra isccend iscd8 move y:d8,a move a,y:div move #>$8,a bra isccend iscd9 move y:d9,a move a,y:div move #>$9,a bra isccend iscda move y:d10,a move a,y:div move #>$a,a bra isccend iscdb move y:d16,a move a,y:div move #>$10,a bra isccend iscdc move y:d24,a move a,y:div move #>$18,a bra isccend iscdd move y:d32,a move a,y:div move #>$20,a bra isccend isccend move a,y:divider move #modech,r5 jsr print bra iscend iscend move y0,a ;restore A rti include 'ada_init.asm' org y: divider dc $1 count dc $0 ;doffset dc $0 ;d dc d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d16,d24,d32 d1 dc "1 ",$0 ; 48 d2 dc "2 ",$0 ; 24 d3 dc "3 ",$0 ; 16 d4 dc "4 ",$0 ; 12 d5 dc "5 ",$0 ; 9.6 d6 dc "6 ",$0 ; 8 d7 dc "7 ",$0 ; 6.857 d8 dc "8 ",$0 ; 6 d9 dc "9 ",$0 ; 5.333 d10 dc "10 ",$0 ; 4.8 d16 dc "16 ",$0 ; 3 d24 dc "24 ",$0 ; 2 d32 dc "32 ",$0 ; 1.5 diff dc $007f00 masksz dc $07 temp dc $0 olda dc $0 oldb dc $0 newa dc $0 newb dc $0 backa dc $0 backb dc $0 mask dc $00ffff mode dc $0 ;0=sampling 1=delta ; To be used for inputting 2 level delta modulator with deadband A, B, C, & D inproc dc $0a0d00 dc "proc" dc $0d0000,$0 indelta dc $0a0d00 dc "delta" dc $0d0000,$0 insmala dc $0a0d00 dc "smalla" dc $0d0000,$0 inposa dc $0a0d00 dc "posa" dc $0d0000,$0 ingooda dc $0a0d00 dc "gooda" dc $0d0000,$0 insmalb dc $0a0d00 dc "smallb" dc $0d0000,$0 inposb dc $0a0d00 dc "posb" dc $0d0000,$0 ingoodb dc $0a0d00 dc "goodb" dc $0d0000,$0 greet dc $0a0d00 dc "This program demonstrates 16-bit audio sampling on the Motorola" dc $0a0d00 dc "DSP56303 with delta modulating and bit sampling using 1-16 bits." dc $0a0d00 dc $0a0d00 dc "Bit sampling takes the high order n bits of the input sample and" dc $0a0d00 dc "constructs the output from only those bits to give varied resolutions" dc $0a0d00 dc "Delta Modulation uses one of four different modulation techniques. The" dc $0a0d00 dc "maximum stepsize is varied from 2^0 to 2^15 to give different resolutions." dc $0a0d00 dc $0a0d00 dc "Attach the audio input to the Line-In jack and speakers/headphones" dc $0a0d00 dc "to the Headphone-Out jack. " dc $0a0d00 dc $0a0d00 dc "Type 1-9 or A-G to change the bit resolution/delta step size." dc $0a0d00 dc " 1=1 bit, G=16 bit or step size = (0.0397 mV)(2^n). " dc $0a0d00 dc "Type M to change between Sampled (S) and 5 Delta (Dx) modes." dc $0a0d00 dc "Type + 1-9 or A-D to change the sampling rate, 48/n kHz." dc $0a0d00,$0a0d00 dc "Mode - Resolution(bits)|Step Size - Frequency (kHz):" dc $0a0d00 modech dc $53202d ; ="S -" bits dc $202038 ; =" 8" hz dc " - 48/" div dc "1 " dc $0d0000,$0 crlf dc $0a0d00,$0 coefloc dc coef3 ;location of coefficients coef0 dc 7,7,7,7,7,7,7,7 ;used for delta modulation D0 coef1 dc 0,0,0,0,7,7,7,7 ;used for delta modulation D1 coef2 dc 0,0,2,2,2,7,7,7 ;used for delta modulation D2 coef3 dc 0,0,2,2,4,4,7,7 ;used for delta modulation D3 coef4 dc 0,1,2,3,4,5,6,7 ;used for delta modulation D4 end