; This source dials a number, it can do either DTMF or CCITT5. It has built
; in letter recognition. Ie ABC -> 1, DEF -> 2 which can be switched off.
; It is also variable speed. Feel free to use in your programmes.
;
; NB: This isnt the source of the programme dial, just the routine which
; dials numbers. Dial is merely a frontend to this:


		include "hardware/custom.i"

DialDTMF											;dial DTMF,
		movem.l	d1/d4-d7/a3-a5,-(sp)				;a0=number in ascii			
		lea		DTMF,a1							;chr(0) to end		
		bra		Start

DialCCITT5											;dial CCITT5,
		movem.l	d1/d4-d7/a3-a5,-(sp)				;a0=number in ascii
		lea		CCITT5,a1							;chr(0) to end
		
Start	move.l	a0,a4
		move.l	a1,a5
		moveq	#SnSize,d0
		moveq	#2,d1								;MEMF_CHIP
		CALLEXEC AllocMem
		move.l	d0,a0
		move.l	#SnWaveS,a1
		moveq	#SnSize-1,d1

CopyBf	move.b	(a1)+,(a0)+
		dbf		d1,CopyBf

		move.l	a5,a1
		move.l	a4,a0

		clr.l	d2
		move.b	Speed,d2

NextTone
		clr.l	d1
		move.b	(a0)+,d1							
		cmp.b	#"*",d1
		beq		Special
		cmp.b	#"#",d1
		beq		Special

		cmp.b	#"0",d1
		blt		SkipNote
		cmp.b	#"9",d1
		bgt		NotDigit

		sub.b	#"0",d1
DoneConv
		lsl		#2,d1								;*4
		move.w	0(a1,d1.w),d4						;Lookup table in words
		move.w	2(a1,d1.w),d5						;get period of both tones
		bsr		SoundTone
		bra		Pause
SkipNote
		tst.b	(a0)
		bne		NextTone

		move.l	d0,a1
		moveq	#SnSize,d0
		CALLEXEC FreeMem

		movem.l	(sp)+,d1/d4-d7/a3-a5
		rts

Special	moveq.w	#10,d1								;* & #
		cmpi.b	#"#",d1								;(does anyone want the
		bne		NoAdN								;a,b,c or d tones?)
		addq.w	#1,d1
NoAdN	bra		DoneConv

NotDigit											;Handles a-y
		tst.b	Letter								;-nl -ignore letters
		bne		SkipNote
		
		cmp.b	#"Q",d1								;Q & Z = 1
		beq		DoLQZ
		cmp.b	#"Z",d1
		beq		DoLQZ		
		bgt		SmallCase
		cmp.b	#"A",d1								;=> 1-9
		blt		SkipNote
		cmp.b	#"Q",d1
		blt		NoDif
		subq.b	#1,d1
NoDif	sub.b	#59,d1
		divu	#3,d1
		bra		DoneConv
DoLQZ	move.l	#1,d1
		bra		DoneConv

SmallCase
		cmp.b	#"z",d1
		beq		DoLQZ								;Q and Z come on the 
		bgt		SkipNote
		cmp.b	#"q",d1								;Number 1 button 
		beq		DoLQZ								;sometimes
		cmp.b	#"a",d1
		blt		SkipNote
		cmp.b	#"q",d1
		blt		NoDifS
		subq.b	#1,d1
NoDifS	sub.b	#91,d1
		divu	#3,d1
		bra		DoneConv

SoundTone
		lea		$dff000,a5
		lea		aud1(a5),a3							;Right channel only
		lea		aud2(a5),a4							;N.B Don't be clever
		move.w	#$000f,dmacon(a5)					;and use stereo it 
		move.l	d0,(a3)								;doesn't work then.
		move.l	d0,(a4)
		move.w	#SnSize/2,ac_len(a3)
		move.w	#SnSize/2,ac_len(a4)
		move.w	#64,ac_vol(a3)
		move.w	#64,ac_vol(a4)
		move.w	d4,ac_per(a3)
		move.w	d5,ac_per(a4)
		move.w	#$00ff,adkcon(a5)
		move.w	#$8206,dmacon(a5)

timedelay
		bsr		GetTime
		move.l	d7,d6
Cont	bsr		GetTime
		sub.l	d6,d7
		cmp.l	d2,d7
		bgt		StopNote		
		bra		Cont

StopNote
		move.w	#$0006,dmacon(a5)
		rts

Pause	bsr		GetTime
		move.l	d7,d6
Cont2	bsr		GetTime
		sub.l	d6,d7
		cmpi.l	#2,d7
		bgt		SkipNote
		bra		Cont2

GetTime	clr.l	d7									;Stuff the timer.device
		move.b	$bfea01,d7							;we programme direct
		lsl.l	#4,d7								;via PIA
		lsl.l	#4,d7
		move.b	$bfe901,d7
		lsl.l	#4,d7
		lsl.l	#4,d7
		move.b	$bfe801,d7
		rts

		even
DTMF	dc.w	238,166							;0
		dc.w	319,186							;1
		dc.w	319,166							;2
		dc.w	319,151							;3
		dc.w	290,184							;4
		dc.w	290,166							;5
		dc.w	290,151							;6
		dc.w	263,184							;7
		dc.w	263,166							;8
		dc.w	263,151							;9
		dc.w	238,184							;* 
		dc.w	238,151							;# 
		
CCITT5	dc.w	128,120							;0
		dc.w	162,149							;1
		dc.w	162,138							;2
		dc.w	149,138							;3
		dc.w	162,128							;4
		dc.w	149,128							;5
		dc.w	138,128							;6
		dc.w	162,120							;7
		dc.w	149,120							;8
		dc.w	138,120							;9
		dc.w	138,112							;* 
		dc.w	128,112							;# 

Speed	dc.b	5								;speed of dial
Letter	dc.b	0								;0 = use letter recognitiion

		even
SnWaveS
		dc.b	0,49
		dc.b	90,117
		dc.b	127,117
		dc.b	90,49
		dc.b	0,-49
		dc.b	-90,-117
		dc.b	-127,-117
		dc.b	-90,-49
SnWaveE	
SnSize	EQU	SnWaveE-SnWaveS

		