; DTMF Dialer
; (c) 1995 Martin Mares, MJSoft System Software

;DEBUG	set	1
_GlobVec	set	1

	include	"ssmac.h"
	include	"val/mui.equ"

MUITags	equ	$80420000

	start

	dv.l	ratems
	moveq	#100,d2
	get.l	rate,d0
	beq.s	DefRate
	move.l	d0,a0
	move.l	(a0),d2
	moveq	#10,d0
	cmp.l	d0,d2
	bcs.s	BadRate
	cmp.l	#5000,d2
	bcs.s	DefRate
BadRate	dtl	<Invalid rate>,a0
	jump	ExitError
DefRate	put.l	d2,ratems

	get.l	number,d0
	beq.s	TryFile
	move.l	d0,a4
	bra	Dial

TryFile	get.l	file,d0
	beq.s	UseGUI
	move.l	d0,a0
	moveq	#OPEN_OLD,d0
	moveq	#0,d1
	call	TrackOpenBuf
	move.l	d0,a2
	clr.l	-(sp)
File1	call	ss,BGetByte
	tst.l	d0
	bmi.s	ret1
	move.b	d0,(sp)
	move.l	sp,a4
	push	a2
	lea	Dial(pc),a0
	moveq	#0,d0
	call	CallBlock
	pop	a2
	tst.l	d0
	beq.s	File1
ret1	addq.l	#4,sp
	rts

UseGUI	dtl	<muimaster.library>,a0
	moveq	#MUIMASTER_VMIN,d0
	call	TrackLibrary
	put.l	d0,muimasterbase
	dv.l	muimasterbase

	bsetv	#svfb_errorreq,sv_flags+3

	moveq	#32,d7			; Button array
	clr.l	-(sp)
	dv.l	buttxt
	moveq	#0,d4
GenButt	subq.w	#2,d7
	bmi.s	GBE
	lea	names(pc,d7.w),a0
	put.l	a0,buttxt
	lea	Button(pc),a3
	bsr	GenerateMUI
	push	d0
	pea	MUIA_Group_Child
	bra.s	GenButt

names	dc.b	'1',0,'2',0,'3',0,'A',0,'4',0,'5',0,'6',0,'B',0,'7',0,'8',0
	dc.b	'9',0,'C',0,'*',0,'0',0,'#',0,'D',0,0
	even

GBE	pea	4.w			; Matrix
	pea	MUIA_Group_Columns
	pea	-1.w
	pea	MUIA_Group_SameSize
	move.l	sp,a1
;	dt	STR_Group,<Group.mui>
	gett	STR_Group,a0
	call	muimaster,MUI_NewObject
	put.l	d0,matrix
	dv.l	matrix

	bsr	TrackMUI		; Main window etc
	lea	UserInterface(pc),a3
	bsr	GenerateMUI

	lea	16(sp),sp		; !!!
	moveq	#100,d2			; Button notifications
SetGBNot	pop	d0
	beq.s	SetGBNE
	pop	a2
	push	d2
	pea	MUIM_Application_ReturnID
	pea	2.w
	vpush	appl
	clr.l	-(sp)
	pea	MUIA_Pressed
	pea	MUIM_Notify
	move.l	sp,a1
	bsr	DoMethod
	lea	28(sp),sp
	addq.w	#1,d2
	bra.s	SetGBNot

SetGBNE	move.w	#MUIA_Window_Open-MUITags,d0
	moveq	#1,d1
	get.l	window,a0
	bsr	SetAttr
	move.w	#MUIA_Window_Open-MUITags,d0
	get.l	window,a0
	bsr	GetAttr
	tst.l	d0
	errc.ne	<Unable to open window>

	lea	Notifications(pc),a3
	bsr	SetRCs
	bsr	ActivateString

MainLoop	clr.l	-(sp)
	move.l	sp,d7
	clr.l	-(sp)
	push	d7
	pea	MUIM_Application_Input
	get.l	appl,a2
	move.l	sp,a1
	bsr	DoMethod
	move.l	d7,sp
	pop	d2
	moveq	#-1,d1
	cmp.l	d1,d0
	beq.s	MainEnd
	moveq	#(LastCode-Codes)/2,d1
	cmp.l	d1,d0
	bcc.s	MayBeButt
	push	d2
	add.w	d0,d0
	move.w	Codes(pc,d0.w),d0
	jsr	Codes(pc,d0.w)
	pop	d2
Waiting	move.l	d2,d0
	beq.s	MainLoop
	call	exec,Wait
	bra.s	MainLoop

MayBeButt	moveq	#100,d1
	sub.l	d1,d0
	bcs.s	Waiting
	moveq	#16,d1
	cmp.l	d1,d0
	bcc.s	Waiting
	bsr.s	DoButton
	bra.s	Waiting

Codes	dc.w	Return-Codes		; Do Nothing
	dc.w	MainEnd-Codes		; Close Gadget
	dc.w	StringAccept-Codes
LastCode

MainEnd	jump	ss,ExitCleanup
Return	rts

DoButton	push	d2
	lea	names(pc),a4
	add.w	d0,a4
	add.w	d0,a4
	bsr.s	DoDialing
	pop	d2
	rts

StringAccept	move.w	#MUIA_String_Acknowledge-MUITags,d0
	get.l	strg,a0
	bsr	GetAttr
	move.l	d0,a4
	bsr.s	DoDialing
ActivateString	move.w	#MUIA_Window_ActiveObject-MUITags,d0
	get.l	strg,d1
	get.l	window,a0
	bra	SetAttr

DoDialing	move.w	#MUIA_Application_Sleep-MUITags,d0
	moveq	#1,d1
	get.l	appl,a0
	bsr	SetAttr

	lea	Dial(pc),a0
	moveq	#0,d0
	call	ss,CallBlock

	move.w	#MUIA_Application_Sleep-MUITags,d0
	moveq	#0,d1
	get.l	appl,a0
	bra	SetAttr

DoMethod	move.l	-4(a2),a0
	move.l	8(a0),a6
	jmp	(a6)

TrackMUI	lea	FreeObj(pc),a0
	sub.l	a1,a1
	call	ss,TrackRoutine
	move.l	a1,d4
	rts

GenerateMUI	move.l	#MUITags,d2
	gett	__BaseText,a2
	get.l	muimasterbase,a6
	bra.s	.loopnext

.loop	push	d2
.loop2	move.w	(a3)+,d2
	beq.s	.end
.loopnext	moveq	#0,d3
	move.w	(a3)+,d3
	bmi.s	.subobj
	bclr	#14,d3
	bne.s	.numb
	add.l	a2,d3		; String
	push	d3
	bra.s	.loop

.numb	cmp.w	#$2000,d3	; Number
	beq.s	.long
	bcs.s	.plus
	or.l	#$FFFFE000,d3
.plus	push	d3
	bra.s	.loop
.long	push	(a3)+
	bra.s	.loop

.subobj	bclr	#15,d3
	bclr	#14,d3
	bne.s	.var
	add.l	a2,d3
	link	a4,#0
	push	d3
	move.w	(a3)+,-(sp)
	push	d2
	clr.l	-(sp)
	bra.s	.loop2

.var	move.l	(a5,d3.w),-(sp)
	bra.s	.loop

.end	move.l	-4(a4),a0
	move.l	sp,a1
	call	MUI_NewObject
	move.w	-6(a4),d3
	move.l	d0,(a5,d3.w)
	move.l	-10(a4),d2
	unlk	a4
	tst.w	d2
	beq.s	.finish
	push	d0
	bra.s	.loop

.finish	dtl	<Unable to create user interface>,a0
	tst.l	d0
	beq.s	ExitErr
	tst.l	d4
	beq.s	1$
	move.l	d4,a0
	move.l	d0,(a0)
1$	rts
ExitErr	jump	ss,ExitError

FreeObj	jump	muimaster,MUI_DisposeObject

SetRCs	move.l	sp,d3
	pea	1.w				; 24
	pea	MUIM_Application_ReturnID	; 20
	pea	2.w				; 16
	vpush	appl				; 12
	clr.l	-(sp)				; 8
	pea	MUITags				; 4
	pea	MUIM_Notify			; 0
1$	move.w	(a3)+,d0
	beq.s	2$
	move.l	(a5,d0.w),a2
	move.w	(a3)+,6(sp)
	move.w	(a3)+,d0
	cmp.w	#$8000,d0
	bne.s	3$
	move.l	#MUIV_EveryTime,d0
	bra.s	4$
3$	ext.l	d0
4$	move.l	d0,8(sp)
	move.l	sp,a1
	bsr	DoMethod
	addq.l	#1,24(sp)
	bra.s	1$
2$	move.l	d3,sp
	rts

SetAttr	clr.l	-(sp)
	push	d1
	move.w	d0,-(sp)
	move.w	#MUITags>>16,-(sp)
	move.l	sp,a1
	call	intuition,SetAttrsA
	lea	12(sp),sp
	rts

GetAttr	move.l	#MUITags,d1
	move.w	d0,d1
	move.l	d1,d0
	clr.l	-(sp)
	move.l	sp,a1
	call	intuition,GetAttr
	pop	d0
	rts

MTag	macro
	dc.w	\1-MUITags
	endm

MOffs	macro
	dc.w	\1+\2-__BaseText
	endm

MObj	macro
	ifne	\1
	MTag	\1
	endc
	ifnd	STREX_\2
STREX_\2	set	1
	dt	STR_\2,<\2.mui>
	endc
	MOffs	$8000,STR_\2
	ifgt	NARG-2
	dc.w	\3
	dv.l	\3
	elseif
	dc.w	__Trash
	endc
	endm

MText	macro
	MTag	\1
	dt	STR_\@a,<\2>
	MOffs	0,STR_\@a
	endm

MNum	macro
	MTag	\1
	ifge	\2-$2000
	dc.w	$6000
	dc.l	\2
	elseif
	ifle	\2+$2000
	dc.w	$6000
	dc.l	\2
	elseif
	dc.w	$4000+(\2&$3FFF)
	endc
	endc
	endm

MVar	macro
	MTag	\1
	ifge	\2-$4000
	fail
	endc
	dc.w	\2+$C000
	endm

MEnd	macro
	dc.w	0
	endm

Notify	macro
	dc.w	\1,MUIA_\2-MUITags,\3
	endm

NAny	macro
	dc.w	\1,MUIA_\2-MUITags,$8000
	endm

	dv.l	__Trash
	dt.c	__BaseText,<>

UserInterface
 MObj	0,Application,appl
  MText	MUIA_Application_Title,<DTMF>
  MText	MUIA_Application_Version,<$VER: DTMF 1.2 (10.2.95)>
  MText	MUIA_Application_Copyright,<© 1995 MJSoft System Software>
  MText	MUIA_Application_Author,<Martin Mares>
  MText	MUIA_Application_Description,<Tone Dialer>
  MText	MUIA_Application_Base,<DTMF>
;;;  MNum	MUIA_Application_SingleTask,TRUE
  MObj	MUIA_Application_Window,Window,window
   MText	MUIA_Window_Title,<DTMF Dialer 1.2>
   MObj	MUIA_Window_RootObject,Group
    MVar	MUIA_Group_Child,matrix
    MObj	MUIA_Group_Child,String,strg
     MText	MUIA_String_Accept,<0123456789*#aAbBcCdD ,-.>
     MNum	MUIA_Frame,MUIV_FrameString
     MEnd
    MEnd
   MEnd
  MEnd

Button
 MObj	0,Text
  MNum	MUIA_Frame,MUIV_FrameButton
  MVar	MUIA_Text_Contents,buttxt
  MText	MUIA_Text_PreParse,<',27,'c>
  MNum	MUIA_InputMode,MUIV_InputModeRelVerify
  MNum	MUIA_Background,MUII_ButtonBack
  MEnd

Notifications	Notify	window,Window_CloseRequest,TRUE		; 1
	NAny	strg,String_Acknowledge			; 2
	MEnd

; ### DIALING ROUTINES ###

	dbuf	ior1,ioa_SIZEOF
	dbuf	ior2,ioa_SIZEOF
	dbuf	ior3,ioa_SIZEOF

Dial	geta	ior1,a0
	move.w	#(ior2-ior1)/2-1,d0
1$	clr.w	(a0)+
	dbf	d0,1$

	call	ss,TrackPort
	move.l	d0,d4
	dtl	<audio.device>,a0
	geta	ior1,a1
	move.l	d4,MN_REPLYPORT(a1)
	moveq	#0,d0
	moveq	#0,d1
	sub.l	a2,a2
	call	TrackDevice
	move.l	d1,a1
	geta	ior1,a2
	lea	combin(pc),a0
	move.l	a0,ioa_Data(a2)
	addq.b	#1,3+ioa_Length(a2)
	move.w	#ADCMD_ALLOCATE,IO_COMMAND(a2)
	move.b	#127,LN_PRI(a2)
	dtl	<Unable to allocate audio channels>,a0
	call	ChkDoIO

	move.l	IO_DEVICE(a2),d1
	move.w	ioa_AllocKey(a2),d3
	moveq	#1,d2
	move.l	d2,IO_UNIT(a2)
	geta	ior2,a0
	moveq	#8,d2
	movem.l	d1-d2,IO_DEVICE(a0)
	move.w	d3,ioa_AllocKey(a0)
	move.l	d4,MN_REPLYPORT(a0)
	geta	ior3,a0
	move.l	d1,IO_DEVICE(a0)

	get.l	ratems,d2
num0	call	ss,TestBreak
	move.b	(a4)+,d0
	beq.s	done1
	call	utility,ToUpper
	lea	recode(pc),a0
	moveq	#15,d3
num1	cmp.b	(a0)+,d0
	dbeq	d3,num1
	bne.s	numspac
	bsr.s	OneTone
	bra.s	num0

numspac	bsr.s	OneSpace
	bra.s	num0

done1	rts

recode	dc.b	'D#0*C987B654A321'

; D3=Code, D2=Duration (ms)

OneTone	geta	ior3,a1
	move.w	#CMD_STOP,IO_COMMAND(a1)
	call	exec,SendIO
	divu	#4,d3
	geta	ior1,a1
	lea	freqshi(pc),a0
	bsr.s	SetIO
	swap	d3
	geta	ior2,a1
	lea	freqslo(pc),a0
	bsr.s	SetIO
	geta	ior3,a1
	move.w	#CMD_START,IO_COMMAND(a1)
	call	exec,SendIO
	geta	ior1,a1
	call	WaitIO
	geta	ior2,a1
	call	WaitIO
OneSpace	move.l	d2,d1
	divu	#20,d1
	swap	d1
	clr.w	d1
	swap	d1
	jump	dos,Delay

SetIO	move.w	#CMD_WRITE,IO_COMMAND(a1)
	move.b	#ADIOF_PERVOL,IO_FLAGS(a1)
	lsl.w	#2,d3
	add.w	d3,a0
	move.w	(a0)+,ioa_Period(a1)
	moveq	#0,d0
	move.w	(a0)+,d0
	move.l	d2,d1
	call	utility,UMult32
	move.l	#1000,d1
	call	UDivMod32
	move.w	d0,ioa_Cycles(a1)
	lea	sine,a0
	move.l	a0,ioa_Data(a1)
	moveq	#16,d0
	move.l	d0,ioa_Length(a1)
	move.w	#64,ioa_Volume(a1)
	move.l	IO_DEVICE(a1),a6
	jmp	DEV_BEGINIO(a6)

freqslo	dc.w	186,1205
	dc.w	168,1333
	dc.w	151,1477
	dc.w	137,1633
freqshi	dc.w	321,697
	dc.w	291,770
	dc.w	263,852
	dc.w	238,941

	section	Sample,DATA_C
sine	dc.b	0,49,90,117,127,117,90,49
	dc.b	0,-49,-90,-117,-127,-117,-90,-49
silence	dc.b	0,0
;sine	dc.b	$80,$80,$80,$80,$80,$80,$80,$80
;	dc.b	$7f,$7f,$7f,$7f,$7f,$7f,$7f,$7f
	code

combin	dc.b	9
	even

	tags
	template <NUMBER,RATE/K/N,FILE/K>
	dv.l	number
	dv.l	rate
	dv.l	file
	finish
	end
