radix h display off a x y b change omr 4 change pc 40 change la 0 change lc 0 change sp 0 change sr 0 log off _COMMENT **ADM0*** _DATA Y 0 ac800 11cc00 fe9981 2d8c00 ac180 1f6f00 c4d101 c69e81 2fd480 1f6380 160dc0 e9f241 13e480 0 0 20237f eeda81 1a6600 296000 201f80 15945 0 c6605b 3dbdab fea6bc 1717e 0 d3990e 3d967b fe8e83 1a283 0 e334fc 3d4579 fe5d7e 1b643 0 f46a6f 3d22a6 fe49be 21262 0 282537 3c7574 fded9f 22cfe 0 3ea63c 3c5603 fdd303 25efc 0 54846e 3c03c1 fda105 295d0 0 67b680 3bad5b fd6a31 _END  title 'DTMF DETECTION ' page 132,66,0,10 ;******************************************************************* ;This section does the actual detection of the dual tones as well ;as checking twist and energy. ;******************************************************************* opt rc,mu,cc det IDENT 1,1 ;20 ms detection section det xref rien,rdlgn,iiraspi,enerac nbwdw equ 80 energy equ $20 twogrp equ $1C ratio equ $60 ;****************************************** ;threshold values ;****************************************** tmin equ @pow(10,-3.5) ;-35dB mi8 equ @pow(10,-.8) ;-8dB =10logX mi4 equ @pow(10,-.4) ;-4dB =10logX mi6 equ @pow(10,-.6) ;-6dB ;****************************************** ; data for the filters ;****************************************** wddr equ 0 ;w1(n-1) w2(n-1),... cddr equ 0 ;b0,b1,a1,a2,b2 org yhi: vratio dc 0.0125 ;1/80 org pli: ;****************************************** ; the analysis will be done ; on 80 samples at 4 Khz (20 ms) ;****************************************** move #energy,r2 ;r2 -> 8 energies move #twogrp,r1 ;r1 -> low and high group move #keybrd,r7 ;r7 -> ASCII code table move #ratio,r6 ;r6 -> 1/80 move #0,x0 rep #$b ;zero in the 11 move x0,x:(r2)+ ;energies ; do #nbwdw,_edwdw ; jsr rdlgln move a,y1 jsr enerac move y1,a ;****************************************** ; 6th order Band Pass filter for : ; - dial tone rejection ; - low frequency group selection ; the 15 coefficents from the file ; BPF.LOD are located in the Y data ; memory at locations Y:0..$0E ;****************************************** move #wddr,r0 ;r0 -> samples move #cddr,r4 ;r4 -> coefficients move #2,n0 jsr iiraspi move a,x:(r1)+ ;x1(n) stored in x:(r1) jsr enerac ;****************************************** ; High Pass filtering for : ; - high frequency group selection ; The 15 coefficients from the file ; HPF.LOD are located in the Y data ; memory at locations Y:$0D..1D ;****************************************** move y1,a jsr iiraspi move a,x:(r1)- ;x2(n) stored in x:(r1) jsr enerac ;****************************************** ; 8 Band Pass filtering with ; 8 full wave rectifiers ;****************************************** move #1,n0 do #2,_endfwr ;loop on the 2 frequency groups move x:(r1)+,y1 do #4,_endgrp ;loop in a group move y1,a jsr iiraspi ;BP biquad for each frequency jsr enerac _endgrp nop _endfwr jsr rdlgln _edwdw ;****************************************** ; Threshold test and decision ; look for high group peak ;****************************************** move #energy+10,r2 ;r2 -> energy(1633hz) move #>3,x0 ;x0 = 3 (index of energy max) move x:(r2)-,y0 ;y0 = energy max= energy(1633hz) move x:(r2)-,a ;a = energy(1477hz) move #3,r3 do #3,edcol cmp y0,a (r3)- ;compare y0 and a jlt y0, y0= new max= a move r3,x0 saut move x:(r2)-,a ;a= next energy to check edcol ; ;****************************************** ; look for low group peak ;****************************************** move #>3,x1 a,y1 ;x1 = 3 (index of energy max) ;y1 = energy max = energy(941hz) move x:(r2)-,a ;a = energy (852hz) move #3,r3 do #3,edrow cmp y1,a (r3)- ;compare y1 and a jlt y1 ,then y1=a move r3,x1 sau move x:(r2)-,a ;a = next energy to check edrow ; ;****************************************** ; test if above minimun threshold ;****************************************** move #tmin,a ;a= threshlod min cmp y0,a ;compare max in low group with threshold jgt low group maximum value ; +4 db are allowed ;****************************************** ; hghmax move #mi4,x0 ;x0=attenaution mpy x0,y0,a ;a= high group max -4dB cmp y1,a ;compare with high group jge than 8 dB ; ;****************************************** ; low group max. can be 8dB higher than high group ;****************************************** ; lowmax move #mi8,x1 ;x1= attenuation mpy x1,y1,a ;a=low group max- 8dB cmp y0,a ;compare with high group jge than 4 dB ; ;****************************************** ; in each group, the max should be ; at least +8 db above the other frequencies ;****************************************** ; move #mi8,x1 ;x1=attenuation mpy x1,y1,a #>2,y1 move #energy+3,r2 ;prepare r2 for coming test move #>1,b move x:(r2)+,x0 do #4,endlw cmp x0,a ;compare with lowmax-8dB jge no dectect ; move #>1,b mpy x1,y0,a ;a=highmax-8dB do #4,endhg cmp x0,a ;compare with lowmax-8dB jge no dectect ; endsec end  title 'DTMF RECEIVER AND GENERATOR MAIN PROGRAM' page 132,66,0,10 ; ; ; ;********************************************************************** ;This program is a single channel receiver and generator program. ;It uses sections det and sub which must be linked with this ;program to run ;********************************************************************** opt rc,mu dtmf ident 1,1 ;main ;********************************************************************** ;The following section loads definitions in X memory starting at xhi ;********************************************************************** SECTION define xdef misc,keybrd,pret,ret,pos,num org xhi: misc dc $010000,$010000,tempo,1,troisl,$30 keybrd dc '1','2','3','A','4','5','6','B','7','8','9' dc 'C','*','0','#','D' pret dc $0a,$0d,'R','E','A','D','Y',':',$0a,$0d, ret dc $0d,$0a pos dc $20 num dc '0','0','0','1','0','2','0','3','0','4','0','5' dc '0','6','0','7','0','8','0','9','1','0','1','1' dc '1','2','1','3','1','4','1','5','1','6','1','7' dc '1','8','1','9','2','0','2','1','2','2','2','3' dc '2','4','2','5','2','6','2','7','2','8','2','9' dc '3','0','3','1','3','2','3','3','3','4','3','5' dc '3','6','3','7','3','8','3','9','4','0','4','1' dc '4','2','4','3','4','4','4','5','4','6','4','7' endsec ;********************************************************************** ;The following section sets up the interupt vectors on the SCI receive ;port where the numbers 0-9 ABCD * or # are selected for tone ;generation ;********************************************************************** section vector org p:$0014 ;this is the SCI receive interupt vector location jsr tone ;this is the generate subroutine org p:$0016 ;This is the SCI receive with exception vector jsr tone endsec ;********************************************************************** ;This section sets up the SSI and SCI tto transmit and receive. ;The SSI port is used to transmit and recive A-law data to/from ;a PCM codec. The SCI port is used to display the results of ;detection to a RS232 terminal as well as to take inputs from ;the RS232 terminal to generate the desired tones. ;********************************************************************** section periphials nolist include '\dsp56000.asm\ioequ' ;This include file contains ;the i/o bit definitions list org pli: ori #$03,mr ;Mask the interupts movep #$c000,x:$ffff ;************************************** ; first program PORT A & OPERATING MODE ;************************************** movep #$0,x:M_BCR ; no wait states move #$4,omr ; mode 0 /ROM enable move #M_SR,r6 ;r6 -> ssi status reg. ;*********** ; sci setup ;*********** ;************************************** ;The SCI port is set up in the 10 bit ;asynchronous mode to operate with an ;RS232 terminal. The receiver and ;transmitter are enabled as well as the ;receiver interupt. ;************************************** movep #0,x:M_SCR ;zero the control register bset #M_WDS1,x:M_SCR ;Set it for 10 bits bset #M_TE,x:M_SCR ; enable the transmitter ( WDS=0 ) bset #M_RE,x:M_SCR ;enable the receiver bset #M_RIE,x:M_SCR ;enable the reciever interupt movep #32,x:M_SCCR ; CD=32 for divide by 33(2.5MHz/33) ;*********** ; ssi setup ;*********** ;************************************** ;The SSI is configured in the normal ;mode with an external clock and in ;the synchronousmode. Interupts are ;not used but the RDF/TDE flags are. ;************************************** movep #$1F03,x:M_CRA ; PSR=0 , WL=0 , DC4-0=31 ,PM7-0=3 movep #$200,x:M_CRB ; RIE=0,TIE=RE=TE=0 , MOD=0 , GCK=0 ; SYN=1 , FSL=0 , SCKD=1 (int clk ) ; SCD2=1(int TDE/RDE),OF(1:0)=0 movep #$1ff,x:M_PCC ; set CC(8:3) as SSI pins ; set CC(2;0) as SCI pins movep #$0,x:M_SR move #$0,sr ; no mask ( enable all levels ) movep #$3200,x:M_CRB ; RIE=0,TIE=0, RE,TE = 1 andi #$fc,mr ;unmask the interupts endsec ;********************************************************************** ;The following is the main section of the program which initializes ;the RS232 terminal and keeps track of detections to report to the ;RS232 terminal ;********************************************************************** section main1 org pli: ; xdef tempo,troisl,rien,enc ;internal subroutines xref ready,misc,keybrd,pret,ret,pos,num ;external subroutines ; tempo equ $2C troisl equ 16*3 thrshld equ $019000 ;-35dB move #pret,r0 ;for ready message move #10,n0 ;on the display jsr ready ;go to write to display move #misc+1,r5 ; r5-> former detections move #$a,m2 ;r2 mod 11 for energies move #$1,m1 ;r1 mod 1 for two groups bset #16,x:(r5)- ;last one = bidon bset #16,x:(r5)+ ;last-2 =bidon rien move x:(r5)-,a ;a=last one move a,x:(r5)+ ;last-2=last one bset #16,x:(r5)+ ;last one=bidon move x:(r5)+,a ;a= 20ms silence decounter move x:(r5)-,x0 ;x0=1 sub x0,a tst a a,x:(r5)- jge ascii(00) move n1,a ;a=num asl a #$1,n5 ;a= 2*num, N5 == offset for tempo update move a,n4 ;n4=2*num move #0,n1 ;num=0 move #2,n0 lua (r4)+n4,r0 ;r0=ascii(num) jsr ready ;write num move #ret,r0 tst a #1,n0 jeq nolf move #2,n0 nolf jsr ready move #>tempo,x0 move x0,x:(r5+n5) enc endsec ;********************************************************************** ;Section det is linked with this program and contains the acual ;detection routines used for receiving and detecting tones ;********************************************************************** section det endsec ;********************************************************************** ;The next section of code does several things for receiving tones and ;and also contains the code which genrates the tone when there is an ;key depressed on the RS232 terminal causing an SCI receive interupt. ;********************************************************************** section write org pli: xref ready,misc,keybrd,pret,ret,pos,num,enc xdef tone,toneptr,generate ; msk13 equ $fff800 inv equ $d5 nolist include '\dsp56000.asm\ioequ' list ;************************************** ;The current detected number is ;compared with the last detected ;number to see if it has changed. ;************************************** move n7,y0 ;y0 = detected number move x:(r5)-,b ; b = last one move x:(r5),a ; a = last -2 move b,x:(r5)+ ; last one -> last -2 cmp y0,a y0,x:(r5) ;y0 -> last one jeq tempo,x0 ;init tempo move x0,x:(r5+n5) jmp $39,x0 cmp x0,a #>$30,x0 jgt alpha cmp x0,a jlt punt1 sub x0,a move a1,n4 rts alpha move #>$61,x0 cmp x0,a #>$64,x0 jlt badio cmp x0,a #>$57,x0 jgt badio sub x0,a move a1,n4 rts punt1 move #>$23,x0 cmp x0,a jne punt2 move #$e,n4 rts punt2 move #>$2a,x0 cmp x0,a jne badio move #$f,n4 rts badio move #$f10,a rts ;************************************** ;The generate subroutine actually ;generates the points in the tone ;and then compresses the data and ;outputs it to the SSI port. An ;second order oscillator is used to ;generate the tones. Each tone only ;needs one coefficient. ;************************************** generate move #$dd,r3 move #$e0,r4 move #$da,r5 move l:(r4+n4),x move #>$400000,y1 clr a y1,y0 clr b y0,x:(r5)+ ; some clue goes here do #<$360,loop1 mac -y0,x0,a neg a mac y0,x0,a mac -y1,x1,b neg b mac y1,x1,b tfr y0,a a,y0 tfr y1,b b,y1 move x0,x:(r5)- b,y:(r3)+ move y1,y:(r3)+ move x:(r5)+,x0 a,y:(r3) mpy x0,y1,b mac x0,y0,b move b1,y:$fffe tfr b,a #msk13,x0 abs a and x0,a #$0A3C,x:M_CRB ; RIE=0 , TIE=0 , RE=0 , TE=0 ; MOD=0 , GCK=0 , SYN=1 , FSL=1 ; * , * , SCKD=1, SCD2=1, ; SCD1=1, SCD0=1, OF1=0 , OF0=0 ; start programming the SCI movep #(sbk|wl0),x:M_SCR bset #M_TE,x:M_SCR ; enable the transmitter ( WDS=0 ) movep #269,x:M_SCCR ; CD=269 for divide by 270 ; 320k/270=1185 baud #1200 baud) ; enable the SSI bclr #4,x:M_PCDDR ;sc1/pc4 input ack bclr #1,x:M_PCDDR ;txd/pc1 input busy bset #0,x:M_PCDDR ;PC0 output reset movep #$1e4,x:M_PCC ; set CC(8:3) as SSI pins ; set CC(2;1) as SCI pins endsec ; ;******************************** section main1 org pli: ; nolist include '\dsp56000.asm\ioequ' list ; xdef rien,enc xref ready,misc,keybrd,pret,ret,pos,num,temp ; ; misc. init ; bclr #0,x:M_PCD ; start reset display jsr temp ;temp bset #0,x:M_PCD ;end reset display jsr temp ;temp ; move #pret,r6 ;for ready message move #61,n6 ;on the display jsr ready ;go to write to display ; move #8,n2 ;offset for energies move #2,n5 ;offset for detect/last/lastone ; move #(6*$18)-1,m0 ;modulo 8f for filter samples move #11,m1 ;r1 mod 12 for two groups move #(6*8)-1,m2 ;modulo 48 for energies move #$3b,m4 ;modulo 3b for filter coefficient move #$b,m5 ;modulo 12 for last-1 & lastone ; move #misc+1,r5 ; r5-> former detections rep #12 bset #16,y:(r5)+ ;last one &last-2= bidon ; rien enc endsec ;******************************** ; section detect ; the linker will insert the ; detection routine endsec ; ;******************************** section main2 org pli: xref ready,misc,keybrd,pret,ret,pos,num,enc ; nolist include '\dsp56000.asm\ioequ' list ; move #keybrd,r7 ;r7 -> ASCII code table move #pos,r6 move #3,n6 move #2,n3 move #$40,n4 move #>1,y1 ; do #6,_edwrt ; jset #$10,x:(r5),ryen ;nothing if no detection ; ; compare with last detection ; move x:(r5),y0 ;y0 = detected number move y:(r5)-,b ; b = last one move y:(r5),a ; a = last -2 move b,y:(r5)+ ; last one -> last -2 cmp y0,a y0,y:(r5) ;y0 -> last one jeq last-2 move a,y:(r5)+ bset #16,y:(r5)- ;last one=bidon move x:(r5),a sub y1,a jne $20,x0 move x0,y:(r3+n3) jsr ready ;go to write to display lua (r6)-n6,r6 move #$ffffff,a paseff move a,x:(r5)+ ; enk lua (r5)+n5,r5 lua (r6)+n6,r6 ; _edwrt jmp ssi status reg. ;*********** ; sci setup ;*********** ;************************************** ;The SCI port is set up in the 10 bit ;asynchronous mode to operate with an ;RS232 terminal. The receiver and ;transmitter are enabled as well as the ;receiver interupt. ;************************************** movep #0,x:M_SCR ;zero the control register bset #M_WDS1,x:M_SCR ;Set it for 10 bits bset #M_TE,x:M_SCR ; enable the transmitter ( WDS=0 ) bset #M_RE,x:M_SCR ;enable the receiver bset #M_RIE,x:M_SCR ;enable the reciever interupt movep #32,x:M_SCCR ; CD=32 for divide by 33(2.5MHz/33) ;*********** ; ssi setup ;*********** ;************************************** ;The SSI is configured in the normal ;mode with an external clock and in ;the synchronousmode. Interupts are ;not used but the RDF/TDE flags are. ;************************************** movep #$1F03,x:M_CRA ; PSR=0 , WL=0 , DC4-0=31 ,PM7-0=3 movep #$200,x:M_CRB ; RIE=0,TIE=RE=TE=0 , MOD=0 , GCK=0 ; SYN=1 , FSL=0 , SCKD=1 (int clk ) ; SCD2=1(int TDE/RDE),OF(1:0)=0 movep #$1ff,x:M_PCC ; set CC(8:3) as SSI pins ; set CC(2;0) as SCI pins movep #$0,x:M_SR move #$0,sr ; no mask ( enable all levels ) movep #$3200,x:M_CRB ; RIE=0,TIE=0, RE,TE = 1 andi #$fc,mr ;unmask the interupts endsec ;********************************************************************** ;The following is the main section of the program which initializes ;the RS232 terminal and keeps track of detections to report to the ;RS232 terminal ;********************************************************************** section main1 org pli: ; xdef tempo,troisl,rien,enc ;internal subroutines xref ready,misc,keybrd,pret,ret,pos,num ;external subroutines ; tempo equ $2C troisl equ 16*3 thrshld equ $019000 ;-35dB move #pret,r0 ;for ready message move #10,n0 ;on the display jsr ready ;go to write to display move #misc+1,r5 ; r5-> former detections move #$a,m2 ;r2 mod 11 for energies move #$1,m1 ;r1 mod 1 for two groups bset #16,x:(r5)- ;last one = bidon bset #16,x:(r5)+ ;last-2 =bidon rien move x:(r5)-,a ;a=last one move a,x:(r5)+ ;last-2=last one bset #16,x:(r5)+ ;last one=bidon move x:(r5)+,a ;a= 20ms silence decounter move x:(r5)-,x0 ;x0=1 sub x0,a tst a a,x:(r5)- jge ascii(00) move n1,a ;a=num asl a #$1,n5 ;a= 2*num, N5 == offset for tempo update move a,n4 ;n4=2*num move #0,n1 ;num=0 move #2,n0 lua (r4)+n4,r0 ;r0=ascii(num) jsr ready ;write num move #ret,r0 tst a #1,n0 jeq nolf move #2,n0 nolf jsr ready move #>tempo,x0 move x0,x:(r5+n5) enc endsec ;********************************************************************** ;Section det is linked with this program and contains the acual ;detection routines used for receiving and detecting tones ;********************************************************************** section det endsec ;********************************************************************** ;The next section of code does several things for receiving tones and ;and also contains the code which genrates the tone when there is an ;key depressed on the RS232 terminal causing an SCI receive interupt. ;********************************************************************** section write org pli: xref ready,misc,keybrd,pret,ret,pos,num,enc xdef tone,toneptr,generate ; msk13 equ $fff800 inv equ $d5 nolist include '\dsp56000.asm\ioequ' list ;************************************** ;The current detected number is ;compared with the last detected ;number to see if it has changed. ;************************************** move n7,y0 ;y0 = detected number move x:(r5)-,b ; b = last one move x:(r5),a ; a = last -2 move b,x:(r5)+ ; last one -> last -2 cmp y0,a y0,x:(r5) ;y0 -> last one jeq tempo,x0 ;init tempo move x0,x:(r5+n5) jmp $39,x0 cmp x0,a #>$30,x0 jgt alpha cmp x0,a jlt punt1 sub x0,a move a1,n4 rts alpha move #>$61,x0 cmp x0,a #>$64,x0 jlt badio cmp x0,a #>$57,x0 jgt badio sub x0,a move a1,n4 rts punt1 move #>$23,x0 cmp x0,a jne punt2 move #$e,n4 rts punt2 move #>$2a,x0 cmp x0,a jne badio move #$f,n4 rts badio move #$f10,a rts ;************************************** ;The generate subroutine actually ;generates the points in the tone ;and then compresses the data and ;outputs it to the SSI port. An ;second order oscillator is used to ;generate the tones. Each tone only ;needs one coefficient. ;************************************** generate move #$dd,r3 move #$e0,r4 move #$da,r5 move l:(r4+n4),x move #>$400000,y1 clr a y1,y0 clr b y0,x:(r5)+ ; some clue goes here do #<$360,loop1 mac -y0,x0,a neg a mac y0,x0,a mac -y1,x1,b neg b mac y1,x1,b tfr y0,a a,y0 tfr y1,b b,y1 move x0,x:(r5)- b,y:(r3)+ move y1,y:(r3)+ move x:(r5)+,x0 a,y:(r3) mpy x0,y1,b mac x0,y0,b move b1,y:$fffe tfr b,a #msk13,x0 abs a and x0,a #$40,y0 ; start offset into table 000040 807 P:003A 46F450 [4 - 146] add y0,a #>$ff,y0 ; add to form access offset 0000FF 808 P:003C 200056 [2 - 148] and y0,a ; limit to 8 bits 809 P:003D 200060 [2 - 150] add x1,a ; add table start address 810 P:003E 21D100 [2 - 152] move a,r1 ; and use for access 811 P:003F 57F400 [4 - 156] move #0.5,b ; scale factor 400000 812 P:0041 5EE900 [4 - 160] move y:(r1+n1),a ; read table entry 813 P:0042 200022 [2 - 162] asr a ; divide by 2 814 P:0043 20001C [2 - 164] sub a,b ; window function coefficient calculated 815 P:0044 1CF000 [4 - 168] move b,x1 y:fiddle,y0 ; shift into y0.... 000000 816 P:0046 2000E0 [2 - 170] mpy x1,y0,a ; and scale coefficient 817 P:0047 5E0000 [2 - 172] move a,y:$40,y0 ; start offset into table add y0,a #>$ff,y0 ; add to form access offset and y0,a ; limit to 8 bits add x1,a ; add table start address move a,r1 ; and use for access move #0.5,b ; scale factor move y:(r1+n1),a ; read table entry asr a ; divide by 2 sub a,b ; window function coefficient calculated move b,x1 y:fiddle,y0 ; shift into y0.... mpy x1,y0,a ; and scale coefficient move a,y:$40,y0 ; start offset into table 000040 807 P:003A 46F450 [4 - 146] add y0,a #>$ff,y0 ; add to form access offset 0000FF 808 P:003C 200056 [2 - 148] and y0,a ; limit to 8 bits 809 P:003D 200060 [2 - 150] add x1,a ; add table start address 810 P:003E 21D100 [2 - 152] move a,r1 ; and use for access 811 P:003F 57F400 [4 - 156] move #0.5,b ; scale factor 400000 812 P:0041 5EE900 [4 - 160] move y:(r1+n1),a ; read table entry 813 P:0042 200022 [2 - 162] asr a ; divide by 2 814 P:0043 20001C [2 - 164] sub a,b ; window function coefficient calculated 815 P:0044 1CF000 [4 - 168] move b,x1 y:fiddle,y0 ; shift into y0.... 000000 816 P:0046 2000E0 [2 - 170] mpy x1,y0,a ; and scale coefficient 817 P:0047 5E0000 [2 - 172] move a,y: X:xddr ; r4 -> Y:cddr ; n0 = number of cells = filter order/2 ; iiraspi do n0,_iirend move a,x0 move x:(r0)+,a y:(r4)+,y0 ; a=w1n-1 x0=xn y0=b0 mac x0,y0,a x:(r0)-,b y:(r4)+,y0 ; a=yn b=w2n-1 y0=b1 asl a mac x0,y0,b a,x1 y:(r4)+,y0 ; x1=yn y0=a1 mac -x1,y0,b y:(r4)+,y0 ; y0=a2 b=w1n mpy -x1,y0,a b,x:(r0)+ y:(r4)+,y0 ; y0=b2 mac x0,y0,a ; a=w2n tfr x1,a a,x:(r0)+ _iirend rts ; ;************************************ ; linear expansion ; uses a,x0,y0,x1,r3,n3,m3 ; ; data for log/lin conversion routines ;************************************* inv equ $d5 ;invert even bits+sign msk13 equ $fff800 ;mask 13 msb shift equ $80 mask equ $7f tab equ $180 ;A law table address in DS56001 X ROM. tab1 equ $7f ;modulo value ; rdlgln _wrdf jclr #M_RDF,x:M_SR,_wrdf ; wait for rdf movep x:M_RX,x0 ; read data move #>shift,y0 mpy x0,y0,a #>mask,x1 and x1,a #tab,r3 move a1,n3 move #tab1,m3 cmpm y0,a move x:(r3+n3),a jge