*******************************************************************************
* Multi-Frequency Dialer v1.02
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* Dials "ASCII String" phone numbers. 
*
* Maybe the delay waiting should be changed to a more ~accurate~ method!
* The short term botch method I`ve simple forbid() the OS and used lame raster
* waiting... (I know that ciaa should be used!.. hehe)
*
* FastMem Bug fixed:
* ~~~~~~~~~~~~~~~~~
* The 4 byte sample is now first copied into chip-memory first then its played
* before I forgot about this since I`ve only got chippy food in my A12oo...
*
* Dialer supports:
* ~~~~~~~~~~~~~~~
*		"0"-"9" and "b"-"c" are the tones!
*		"." waits for a small delay
*		"ı" enables DTMF Dial-frequency tones!
*		"²" enables CITT Dial-frequency tones!
*******************************************************************************

;-------------- Definition Includes

		incdir	"includes:"
		include	"exec/exec_lib.i"
		include	"exec/memory.i"

;CLI Params	=	a0=cli params ascii string ptr
;			d0=cli params length

DialEntry:	move.l	a0,-(sp)
		move.l	4.w,a6
		moveq	#4,d0			;length of sample (4 bytes)
		move.l	#MEMF_CHIP+MEMF_CLEAR,d1 ;we want chipmem, cleared
		jsr	_LVOAllocMem(a6)	;allocate it...4
		move.l	d0,a2
		beq.s	NoMem			;did the alloc fail, if so exit
		lea	SamplePtr(pc),a1
		move.l	a2,(a1)			;save sample memory ptr
		lea	Sampledata(pc),a0
		move.l	(a0),(a2)		;put our 4 byte sample in chip!

		jsr	_LVOForbid(a6)		;turn off multitasking()
		move.l	(sp)+,a0

		bsr.s	DialNumber

		move.l	4.w,a6
		jsr	_LVOPermit(a6)		;turn on multitasking()

		move.l	SamplePtr(pc),a1	;ptr to our RS.Variables base
		move.l	a1,d0
		beq.s	NoMem
		moveq	#4,d0			;no. of bytes to free
		jsr	_LVOFreeMem(a6)		;free the memory
NoMem		moveq	#0,d0
		rts

*******************************************************************************
* DialNumber	- Dials an ASCII phone number 
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	a0=Pointer to ascii phone number
*******************************************************************************

DialNumber:	lea	TablePtr(pc),a1
		lea	FreqTable1(pc),a2
		move.l	a2,(a1)			;set default DTMF freqtable
DialLoop:	move.b	(a0)+,d0		;get ascii char, incr digit pos
		bne.s	donumber		;is this the last digit?, done!
		rts

donumber:	cmp.b	#"-",d0			;skip all '-' in string
		beq.s	DialLoop
		cmp.b	#" ",d0			;skip all ' ' in string
		beq.s	DialLoop
		move.l	a0,-(sp)		;preserve current digit pos
		bsr.s	PlayDigit		;play this digit
		move.l	(sp)+,a0		;restore current digit pos
		bra.s	DialLoop		;keep dialing digits until done

usa_digit:	move.b	(a0)+,d0
		beq.s	usa_done
		cmp.b	#"-",d0
		beq.s	usa_digit
		cmp.b	#" ",d0
		beq.s	usa_digit
		move.l	a0,-(sp)
		bsr.s	PlayDigit
		move.l	(sp)+,a0
		bra.s	usa_digit

usa_done:	move.l	(sp)+,a0
userdial:	move.b	(a0)+,d0		;get ascii char, incr digit pos
		beq.s	userdone		;is this the last digit?, done!
		cmp.b	#"-",d0
		beq.s	userdial
		cmp.b	#" ",d0
		beq.s	userdial
		move.l	a0,-(sp)		;preserve current digit pos
		bsr.s	PlayDigit		;play this digit
		move.l	(sp)+,a0		;restore current digit pos
		bra.s	userdial		;keep dialing digits until done
userdone:	move.b	#"²",d0
		bsr.s	PlayDigit
		move.b	#"c",d0
		bra.w	PlayDigit

*******************************************************************************
* PlayDigit	- Plays a frequency digit from freqtable - input value is ASCII
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	d0=(.B)	digit to play, (range "0"-"9" and "b"-"c")
*******************************************************************************

PlayDigit:	lea	TablePtr(pc),a1
		cmp.b	#"ı",d0			;Are we setting DTMF Table?
		beq.s	SetDTMF		
		cmp.b	#"²",d0			;Are we setting 890 FAST Table?
		beq.s	SetFAST
		
SearchIt:	move.l	(a1),a0			;dial table ptr
search_freq	move.w	(a0)+,d1		;get current freq
		beq.s	notfound		;this was the last one
		cmp.b	d0,d1			;is this the one we want?
		beq.s	playit
		addq.l	#6,a0			;skip to next one
		beq.s	notfound
		bra.s	search_freq

SetDTMF:	lea	FreqTable1(pc),a0
		move.l	a0,(a1)			;save table freq ptr
		rts
	
SetFAST		lea	FreqTable2(pc),a0
		move.l	a0,(a1)			;save table freq ptr
		rts
		
PlayIt		move.w	d0,-(sp)		;save digit value
		move.w	(a0)+,d0		;freq 1
		move.w	(a0)+,d1		;freq 2
		move.w	(a0)+,-(sp)		;save delay value to stack
		bsr.s	FreqOn			;turn on frequency
		move.w	(sp)+,d2		;restore delay value
		bsr.b	_LVODelay		;wait the delay()

		move.w	#15,$96(a6)		;turn off sound dma
		move.w	#$C000,$9A(a6)		;turn off intena

		move.w	(sp)+,d0
		cmp.b	#"!",d0			;is this a multifreq 
		bne.s	noter		;if not exit and wait a while
		move.b	#"#",d0			;ELSE.. 
		bra.s	PlayDigit

noter	move.l	#50-1,d2
		bsr.b	_LVODelay		;wait for 50 rasters
notfound	rts


_LVODelay:	;d0=no. rasters to wait

waw1		cmp.b	#-1,$dff006		;VERY DODGY WAITING METHOD!
		bne.s	waw1			;OOOER!
		subq.l	#1,d2
		bne.s	waw1
		rts

*******************************************************************************
* FreqOn	- Plays a Dual Frequency!
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	d0=(.W)	Frequency 1
*		d1=(.W)	Frequency 2
*		d2=(.W)	Volume
*
*******************************************************************************

FreqOn:		lea	$dff000,a6		;custombase
		tst.w	d0			;is there a frequency 1?
		beq.s	nofreq
		tst.w	d1			;is there a frequency 2?
		beq.s	nofreq
		
;-------------- Setup SampleDMA

		move.w	#$4000,$9A(a6)		;intena
		move.w	#15,$96(a6)		;dmacon
		move.w	#0,$9E(a6)		;adkcon

		lea	$a0(a6),a5		;$dff0a0=a5
		move.l	sampleptr(pc),a0
		move.w	#$40,d2			;volume
		moveq	#4/2,d3			;length
		moveq	#$00,d6			;Channel 0
		bsr.s	SetChannel
		move.w	#$10,d6			;Channel 1
		bsr.s	SetChannel
		exg	d0,d1			;swap freq`s around
		move.w	#$20,d6			;Channel 2
		bsr.s	SetChannel
		move.w	#$30,d6			;Channel 3
		bsr.s	SetChannel

;-------------- Set Channel DMA
		move.w	#$8209,$96(a6)		;turn on all 4 chanels
NoFreq:		rts

SetChannel:	move.l	a0,(a5,d6.w)		;sampledata ptr (AUDxPTH)
		move.w	d1,$6(a5,d6.w)		;sample period  (AUDxPER)
		move.w	d2,$8(a5,d6.w)		;sample volume  (AUDxVOL)
		move.w	d3,$4(a5,d6.w)		;sample length  (AUDxLEN)
		rts

TablePtr	dc.l	0			;ptr to table to use

delay		=	79
;			Digit,Freq1,Freq2,Len		"DTMF" Dial Frequecies
;			ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ		ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
FreqTable1:	dc	$0030,$03b4,$029c,delay		;"0",freq1,freq2,delay
		dc	$0031,$0501,$02e2,delay		;"1",freq1,freq2,delay
		dc	$0032,$0501,$029c,delay		;"2",freq1,freq2,delay
		dc	$0033,$0501,$025c,delay		;"3",freq1,freq2,delay
		dc	$0034,$0487,$02e2,delay		;"4",freq1,freq2,delay
		dc	$0035,$0487,$029c,delay		;"5",freq1,freq2,delay
		dc	$0036,$0487,$025c,delay		;"6",freq1,freq2,delay
		dc	$0037,$0417,$02e2,delay		;"7",freq1,freq2,delay
		dc	$0038,$0417,$029c,delay		;"8",freq1,freq2,delay
		dc	$0039,$0417,$025c,delay		;"9",freq1,freq2,delay

		dc	$002e,$0000,$0000,500		;".",delay
		dc	0,0				;end of table

delay2		=	100
delaya		=	100
delayb		=	100
;			Digit,Freq1,Freq2,Len		"890" Dial Frequecies
;			ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ		ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
FreqTable2:	dc	$0030,$02ae,$0253,delay2	;"0",freq1,freq2,delay
		dc	$0031,$04fb,$03e0,delay2	;"1",freq1,freq2,delay
		dc	$0032,$04fb,$032b,delay2	;"2",freq1,freq2,delay
		dc	$0033,$03e0,$032b,delay2	;"3",freq1,freq2,delay
		dc	$0034,$04fb,$02ae,delay2	;"4",freq1,freq2,delay
		dc	$0035,$03e0,$02ae,delay2	;"5",freq1,freq2,delay
		dc	$0036,$032b,$02ae,delay2	;"6",freq1,freq2,delay
		dc	$0037,$04fb,$0253,delay2	;"7",freq1,freq2,delay
		dc	$0038,$03e0,$0253,delay2	;"8",freq1,freq2,delay
		dc	$0039,$032b,$0253,delay2	;"9",freq1,freq2,delay

		dc	$0062,$02ae,$020d,delaya	;"b",freq1,freq2,delay
		dc	$0063,$0253,$020d,delayb	;"c",freq1,freq2,delay

		dc	$002e,$0000,$0000,500		;".",delay
		dc	0,0				;end of table

SamplePtr	ds.l	1			;ptr to the sample in chipmem!
		even
SampleData:	dc.w	127,128			;sample data (2 words long)
		even
