yM~ DTKALPHA.SAVa DTKALPHA.SAV&BACKUP *.* [-]DTKALPHA.SAV/SAV/LOG/VER DIETER  )KV6.2 _TSAVO:: _$64$DUA227: V6.2 ~ v*[DIETER.DTKALPHA]DESCRIP.MMS;1+, 3./ ) 4P- 0123KPWO56pǝŷ7Jŷ89G )HJVERS = 060RTLIN = SMG$:[SMG.SRC]RTLML = SMG$:[SMG.OBJ]RTLIS = SMG$:[SMG.LIS]SMG = SMG$:[SMG]KIT = SMG$:[SMG.KIT] .ifdef debugLSTFLG = /NoListMAPFLAG = /NoMapDBGFLG = /DebugTRACEFLG = /Trace.else .ifdef listLSTFLG = /List=$(RTLIS)%MAPFLAG = /Map=$(RTLIS)/Full/CrossDBGFLG = /NoDebugTRACEFLG = /NoTrace.elseLSTFLG = /NoListMAPFLAG = /NoMapDBGFLG = /NoDebugTRACEFLG = /NoTrace.endif.endifJCMSFLAGS = /NoHistory/Output=$(mms$target_name)/NoLog/Gen:$(mms$cms_gen)DMSGFLAGS = /File_name=shrimgmsg/Object=$(mms$target_name)$(lstflg)CMFLAGS = /Enable=Suppression/Object=$(mms$target_name)$(lstflg)PBFLAGS = /Opt:Level:3/Object=$(mms$target_name)$(traceflg)$(lstflg)$(dbgflg)"RFLAGS = /Output=$(mms$target)>LINKFLAGS = /Exec=$(mms$target)$(traceflg)$(mapflag)$(dbgflg)2SDLFLAGS = /Lang=(BlissF=$(mms$target))$(lstflg)*SDIFLAGS = /Parse=$(mms$target)$(lstflg).default ! ! Done building $(mms$target) !.first old_dir := 'f$directory()' Define RTLIN $(rtlin) Define RTLML $(rtlml) Define RTLIS $(rtlis) Vec := $$(SMG)VectorTst.last Set Default 'old_dir' Deassign RTLIN Deassign RTLML Deassign RTLIS.suffixes .sdi .sdl .sdl~ .txt~.txt : $(cms) Fetch $(mms$cms_element) $(cmsflags) $(cmscomment) .dat~.dat : $(cms) Fetch $(mms$cms_element) $(cmsflags) $(cmscomment) .com~.com : $(cms) Fetch $(mms$cms_element) $(cmsflags) $(cmscomment) .mar~.mar : $(cms) Fetch $(mms$cms_element) $(cmsflags) $(cmscomment) .opt~.opt : $(cms) Fetch $(mms$cms_element) $(cmsflags) $(cmscomment) .sdl~.sdl : $(cms) Fetch $(mms$cms_element) $(cmsflags) $(cmscomment) .req~.req : $(cms) Fetch $(mms$cms_element) $(cmsflags) $(cmscomment) .b32~.b32 : $(cms) Fetch $(mms$cms_element) $(cmsflags) $(cmscomment) .msg~.msg : $(cms) Fetch $(mms$cms_element) $(cmsflags) $(cmscomment) .cld~.cld : $(cms) Fetch $(mms$cms_element) $(cmsflags) $(cmscomment) .rno~.rno : $(cms) Fetch $(mms$cms_element) $(cmsflags) $(cmscomment).msg.sdl: Message/Sdl=$(mms$target)/NoObject$(lstflg) $(mms$source) .sdl.r32  Sdl $(sdlflags) $(mms$source).sdl.sdi Sdl $(sdiflags) $(mms$source).rno.release_notes" $(runoff) $(rflags) $(mms$source)HELP :  !" ! Command line: MMS/CMS  ! ! Valid targets are:+ ! LIB - build SMGLIB.L32 and SMGTPALIB.L32. ! TRM - build TERMTABLE.EXE and SMGBLDTRM.EXE ! SHR - build SMGSHR.EXE ! DTK - build DTKSHR.EXE ! ALL - build all of the above& ! KIT - build SMG$ kit in SYS$SCREEN: !0 ! All files are built in $(RTLIN) and $(RTLML) !ALL : LIB, SHR, TRM, DTK/LIB : $(RTLML)SMGLIB.L32, $(RTLML)SMGTPALIB.L32TRM : $(RTLML)TERMTABLE.EXEDTK : $(RTLML)DTKSHR.EXESHR : $(RTLML)SMGSHR.EXE4KIT : $(RTLML)SMGSHR.EXE, $(RTLML)TERMTABLE.EXE, -4 $(RTLML)SMGBLDTRM.EXE, $(RTLML)SMGTERMS.TXT, -= $(KIT)SMG$(VERS).RELEASE_NOTES, $(KIT)KITINSTAL.COM, -/ $(KIT)BLDSMGKIT.COM, $(KIT)BLDSMGKIT.DAT Set Default $(KIT)< Copy/NoLog $(RTLML)smgshr.exe,$(RTLML)smgbldtrm.exe $(KIT)> Copy/NoLog $(RTLML)termtable.exe,$(RTLML)smgterms.txt $(KIT)< Copy/NoLog $(RTLML)smgdef.sdi,$(RTLML)smgtrmptr.sdi $(KIT)> Copy/NoLog $(RTLML)smg$routines.sdi,$(RTLML)smgmsg.sdi $(KIT) @bldsmgkit $(KIT) SMG $(VERS) Set Prot:wo:re smg$(VERS).%/log: Delete/NoLog smgdef.sdi.,smgtrmptr.sdi.,smg$routines.sdi.C Delete/NoLog smgshr.exe.,termtable.exe.,smgbldtrm.exe.,smgmsg.sdi.H Delete/NoLog bldsmgkit.com.,bldsmgkit.dat.,kitinstal.com.,smgterms.txt.5$(KIT)SMG$(VERS).RELEASE_NOTES : $(KIT)SMG$(VERS).RNO" $(runoff) $(rflags) $(mms$source)!+>! Build the bliss library to compile the SMG$ sources against.!-B$(RTLML)SMGLIB.L32 : $(RTLIN)SMGLIB.REQ, $(RTLIN)SMGLNK.REQ, -7 $(RTLIN)SMGTERM.REQ, $(RTLIN)SMGDATSTR.REQ, -6 $(RTLIN)SMGMACROS.REQ, $(RTLIN)SMGPROLOG.REQ, -4 $(RTLML)SMGKTH.R32, $(RTLML)SMGKQB.R32, -4 $(RTLML)SMGKCB.R32, $(RTLML)SMGDEF .R32, -6 $(RTLML)SMGKDE.R32, $(RTLML)SMGTRMPTR.R32, -6 $(RTLML)SMGDEF.SDI, $(RTLML)SMGTRMPTR.SDI, - $(RTLML)SMGMSG.SDI-$(RTLML)SMGTRMPTR.R32 : $(RTLIN)SMGTRMPTR.SDL: Sdl/Vms/Lang=(Bliss=$(mms$target))$(lstflg) $(mms$source)'$(RTLML)SMGDEF.R32 : $(RTLIN)SMGDEF.SDL: Sdl/Vms/Lang=(Bliss=$(mms$target))$(lstflg) $(mms$source)'$(RTLML)SMGKCB.R32 : $(RTLIN)SMGKCB.SDL'$(RTLML)SMGKDE.R32 : $(RTLIN)SMGKDE.SDL'$(RTLML)SMGKTH.R32 : $(RTLIN)SMGKTH.SDL'$(RTLML)SMGKQB.R32 : $(RTLIN)SMGKQB.SDL'$(RTLIN)SMGMSG.SDL : $(RTLIN)SMGMSG.MSG: Message/Sdl=$(mms$target)/NoObject$(lstflg) $(mms$source)!+'! Build the files needed for STARLETSD.!-3$(RTLML)SMG$ROUTINES.SDI : $(RTLIN)SMG$ROUTINES.SDL.$(RTLML)SMGTRMPTR.SDI : $(RTLIN)SMGTRMPTR.SDL)$(RTLML)SMGDEF.SDI : $(RTLIN)SMGDEF.SDL)$(RTLML)SMGMSG.SDI : $(RTLIN)SMGMSG.SDL!+H! Build the Bliss Library to build the foreign terminal sources against.!-G$(RTLML)SMGTPALIB.L32 : $(RTLIN)SMGTPALIB.REQ, $(RTLIN)SMGTPACTL.REQ, -/ $(RTLIN)SMGTABDEF.REQ, $(RTLIN)SMGTRMMAC.REQ!+3! Build the foreign terminal file and its compiler.!-0$(RTLML)TERMTABLE.EXE : $(RTLML)SMGBLDTRM.EXE, - $(RTLML)TERMTABLE.TXT, - $(RTLML)SMGTERMS.TXT# Define termtable $(RTLML)termtable Set Default $(RTLML) Run/NoDebug $(RTLML)smgbldtrmG$(RTLML)SMGBLDTRM.EXE : $(RTLML)SMGBLDTRM.OBJ, $(RTLML)SMGBOOTAB.OBJ, -2 $(RTLML)SMGNUMTAB.OBJ, $(RTLML)SMGSTRTAB.OBJ, -3 $(RTLML)SMGSTATAB.OBJ, $(RTLML)SMGSTR2TAB.OBJ, - $(SMG)TERMDEFS.OBJ( $(link) $(linkflags) $(mms$source_list)-$(RTLML)SMGBLDTRM.OBJ : $(RTLIN)SMGBLDTRM.B32-$(RTLML)SMGBOOTAB.OBJ : $(RTLIN)SMGBOOTAB.B32-$(RTLML)SMGNUMTAB.OBJ : $(RTLIN)SMGNUMTAB.B32/$(RTLML)SMGSTR2TAB.OBJ : $(RTLIN)SMGSTR2TAB.B32-$(RTLML)SMGSTRTAB.OBJ : $(RTLIN)SMGSTRTAB.B32-$(RTLML)SMGSTATAB.OBJ : $(RTLIN)SMGSTATAB.B32!+,! Build the DTK$ sharable image - DTKSHR.EXE!-D$(RTLML)DTKSHR.EXE : $(RTLIN)DTKSHRLNK.OPT, $(RTLIN)DTKPROLOG.REQ, -6 $(RTLIN)DTKDATSTR.R EQ, $(RTLIN)DTKMACROS.REQ, - $(RTLIN)DTKSHRVEC.DAT, -6 $(RTLML)DTKDEF.R32, $(RTLML)DTKDEF.SDI, - $(RTLML)DTKMSG.SDI, - $(RTLML)DTKRTL.OLB( -" DTK$UTIL=$(RTLML)DTKUTIL.OBJ, -# DTK$MSGDEF=$(RTLML)DTKMSG.OBJ, -% DTK$VECTOR=$(RTLML)DTKVECTOR.OBJ - ) Define lib$ $(RTLML)> $(link) $(linkflags)/Share/NoSyslib $(RTLIN)dtkshrlnk.opt/opt- Vec $(RTLML)dtkshr.exe $(RTLIN)dtkshrvec.dat*$(RTLML)DTKDEF.R32 : $(RTLIN)DTKDEF.SDL: Sdl/Vms/Lang=(Bliss=$(mms$target))$(lstflg) $(mms$source)-$(RTLML)DTKVECTOR.OBJ : $(RTLIN)DTKVECTOR.MAR+$(RTLML)DTKUTIL.OBJ : $(RTLIN)DTKUTIL.B32*$(RTLML)DTKMSG.OBJ : $(RTLIN)DTKMSG.MSG*$(RTLIN)DTKMSG.SDL : $(RTLIN)DTKMSG.MSG: Message/Sdl=$(mms$target)/NoObject$(lstflg) $(mms$source)!+'! Build the files needed for STARLETSD.!-3$(RTLML)DTK$ROUTINES.SDI : $(RTLIN)DTK$ROUTINES.SDL-$(RTLML)DTKDEF.SDI : $(RTLIN)DTKDEF.SDL($(RTLML)DTKMSG.SDI : $(RTLIN)DTKMSG.SDL!+,! Build the SMG$ sharable image - SMGSHR.EXE!-D$(RTLML)SMGSHR.EXE : $(RTLIN)SMGSHRLNK.OPT, $(RTLIN)SMGPROLOG.REQ, - $(RTLIN)SMGSHRVEC.DAT, - $(RTLML)SMGRTL.OLB( -, SMG$ALLOW_ESCAPE=$(RTLML)SMGALLESC.OBJ, -0 SMG$BUILD_TERM_TABLE=$(RTLML)SMGBLDTRM.OBJ, -. SMG$BOOLEAN_TABLES=$(RTLML)SMGBOOTAB.OBJ, -. SMG$$AB_DEFKEY_CLD=$(RTLML)SMGDEFKEY.OBJ, -. SMG$DISPLAY_CHANGE=$(RTLML)SMGDISCHA.OBJ, -, SMG$DISPLAY_DHDW=$(RTLML)SMGDISDHW.OBJ, -, SMG$DISPLAY_DRAW=$(RTLML)SMGDISDRW.OBJ, -, SMG$DISPLAY_HELP=$(RTLML)SMGDISHLP.OBJ, -2 SMG$DISPLAY_SUBPROCESS=$(RTLML)SMGDISSUB.OBJ, -& SMG$SELECT=$(RTLML)SMGSELECT.OBJ, -& SMG$WINDOW=$(RTLML)SMGWINDOW.OBJ, -. SMG$$DISPLAY_INPUT=$(RTLML)SMGDISINP.OBJ, -- SMG$DISPLAY_LINKS=$(RTLML)SMGDISLIN.OBJ, -. SMG$DISPLAY_OUTPUT=$(RTLML)SMGDISOUT.OBJ, -, SMG$DISPLAY_USER=$(RTLML)SMGDISUSR.OBJ, -$ SMG$INPUT=$(RTLML)SMGINPUT.OBJ, -& SMG$KEYPAD=$(RTLML)SMGKEYPAD.OBJ, -. SMG$MAP_TERM_TABLE=$(RTLML)SMGMAPTRM.OBJ, - SMG$MIN=$(RTLML)SMGMIN.OBJ, -/ SMG$$MINIMUM_UPDATE=$(RTLML)SMGMINUPD.OBJ, -" SMG$MISC=$(RTLML)SMGMISC.OBJ, -# SMG$MSGDEF=$(RTLML)SMGMSG.OBJ, -2 SMG$$NUMBER_PARAMETERS=$(RTLML)SMGNUMPAR.OBJ, -. SMG$NUMERIC_TABLES=$(RTLML)SMGNUMTAB.OBJ, -' SMG$$PRVINP=$(RTLML)SMGPRVINP.OBJ, -; SMG$PUT_VIRTUAL_DISPLAY_ENCODED=$(RTLML)SMGPUTENC.OBJ, -3 SMG$$PUT_TEXT_TO_BUFFER=$(RTLML)SMGPUTTEX.OBJ, -, SMG$$SCROLL_AREA=$(RTLML)SMGSCROLL.OBJ, -) SMG$$SIM_TERM=$(RTLML)SMGSIMTRM.OBJ, -0 SMG$STATEMENT_TABLES=$(RTLML)SMGSTATAB.OBJ, -- SMG$STRING_TABLES=$(RTLML)SMGSTRTAB.OBJ, -/ SMG$STRING2_TABLES=$(RTLML)SMGSTR2TAB.OBJ, -4 SMG$INTERFACE_TERM_TABLE=$(RTLML)SMGUSRTRM.OBJ, -% SMG$VECTOR=$(RTLML)SMGVECTOR.OBJ - ) Define lib$ $(RTLML)> $(link) $(linkflags)/Share/Nosyslib $(RTLIN)smgshrlnk.opt/opt- Vec $(RTLML)smgshr.exe $(RTLIN)smgshrvec.dat-$(RTLML)SMGALLESC.OBJ : $(RTLIN)SMGALLESC.B32-$(RTLML)SMGBLDTRM.OBJ : $(RTLIN)SMGBLDTRM.B32.$(RTLML)SMGBOOTAB.OBJ : $(RTLIN)SMGBOOTAB.B32 -$(RTLML)SMGDEFKEY.OBJ : $(RTLIN)SMGDEFKEY.CLD-$(RTLML)SMGDISCHA.OBJ : $(RTLIN)SMGDISCHA.B32-$(RTLML)SMGDISDHW.OBJ : $(RTLIN)SMGDISDHW.B32-$(RTLML)SMGDISDRW.OBJ : $(RTLIN)SMGDISDRW.B32-$(RTLML)SMGDISHLP.OBJ : $(RTLIN)SMGDISHLP.B32-$(RTLML)SMGDISINP.OBJ : $(RTLIN)SMGDISINP.B32-$(RTLML)SMGDISLIN.OBJ : $(RTLIN)SMGDISLIN.B32-$(RTLML)SMGDISOUT.OBJ : $(RTLIN)SMGDISOUT.B32-$(RTLML)SMGDISSUB.OBJ : $(RTLIN)SMGDISSUB.B32-$(RTLML)SMGDISUSR.OBJ : $(RTLIN)SMGDISUSR.B32,$(RTLML)SMGINPUT.OBJ : $(RTLIN)SMGINPUT.B32-$(RTLML)SMGKEYPAD.OBJ : $(RTLIN)SMGKEYPAD.B32-$(RTLML)SMGMAPTRM.OBJ : $(RTLIN)SMGMAPTRM.B32*$(RTLML)SMGMIN.OBJ : $(RTLIN)SMGMIN.B32-$(RTLML)SMGMINUPD.OBJ : $(RTLIN)SMGMINUPD.B32+$(RTLML)SMGMISC.OBJ : $(RTLIN)SMGMISC.B32*$(RTLML)SMGMSG.OBJ : $(RTLIN)SMGMSG.MSG-$(RTLML)SMGNUMPAR.OBJ : $(RTLIN)SMGNUMPAR.B32-$(RTLML)SMGNUMTAB.OBJ : $(RTLIN)SMGNUMTAB.B32-$(RTLML)SMGPRVINP.OBJ : $(RTLIN)SMGPRVINP.B32-$(RTLML)SMGPUTENC.OBJ : $(RTLIN)SMGPUTENC.B32-$(RTLML)SMGPUTTEX.OBJ : $(RTLIN)SMGPUTTEX.B32-$(RTLML)SMGSCREEN.OBJ : $(RTLIN)SMGSCREEN.B32 -$(RTLML)SMGSCRINP.OBJ : $(RTLIN)SMGSCRINP.B32-$(RTLML)SMGSCRMIS.OBJ : $(RTLIN)SMGSCRMIS.B32G-$(RTLML)SMGSCROLL.OBJ : $(RTLIN)SMGSCROLL.B32f-$(RTLML)SMGSELECT.OBJ : $(RTLIN)SMGSELECT.B32o0$(RTLML)SMGSIMTRM.OBJ : $(RTLIN)SMGSIMTRM.B32, - $(RTLIN)SMGSCRMAC.REQ, -F $(RTLIN)SMGSCRTCB.REQ, -F $(RTLIN)SMGTRMSTR.R32-$(RTLML)SMGSTATAB.OBJ : $(RTLIN)SMGSTATAB.B32//$(RTLML)SMGSTR2TAB.OBJ : $(RTLIN)SMGSTR2TAB.B32A-$(RTLML)SMGSTRTAB.OBJ : $(RTLIN)SMGSTRTAB.B32G-$(RTLML)SMGUSRTRM.OBJ : $(RTLIN)SMGUSRTRM.B32=-$(RTLML)SMGWINDOW.OBJ : $(RTLIN)SMGWINDOW.B32:-$(RTLML)SMGVECTOR.OBJ : $(RTLIN)SMGVECTOR.MARsObject=$(mms$target_name)$(lstflg)CMFLAGS = /Enable=Suppression/Object=$(mms$target_name)$(lstflg)PBFLAGS = /Opt:Level:3/Object=$(mms$target_name)$(traceflg)$(lstflg)$(dbgflg)"RFLAGS = /Output=$(mms$target)>LINKFLAGS = /Exec=$(mms$target)$(traceflg)$(mapflag)$(dbgflg)2SDLFLAGS = /Lang=(BlissF=$(mms$target))$(lstflg)*SDIFLAGS = /Parse=$(mms$target)$#*[DIETER.DTKALPHA]DTK$ROUTINES.SDL;1+, ). / ) 4c - 0123KPWO!56,F7 \.S89G )HJ MODULE dtk$routines;M/****************************************************************************/* *1/* COPYRIGHT (c) 1988 BY *A/* DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS. *#/* ALL RIGHTS RESERVED. */* *M/* THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED *M/* ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE *M/* INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER *M/* COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY *N/* OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY * #/* TRANSFERRED. */* *M/* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE *M/* AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT */* CORPORATION. */* *M/* DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS *B/* SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. */* */* *M/****************************************************************************/* DTK$ANSWER_PHONE/* '/* Wait for Phone to Ring and Answer/* 4/* The Wait for Phone to Ring and Answer routine A/* waits for the phone connected to the DECtalk device to ring/* and then answers it. /* :ENTRY dtk$answer_phone ALIAS $dtk_answer_phone PARAMETER (' LONGWORD UNSIGNED NAMED voice_id IN& TYPENAME identifier REFERENCE,. LONGWORD NAMED number_of_rings IN OPTIONAL+ TYPENAME longword_signed REFERENCE,1 CHARACTER RTL_STR_DESC NAMED text IN OPTIONAL TYPENAME char_string,& LONGWORD NAMED timeout IN OPTIONAL, TYPENAME longword_signed REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' /* DTK$CHECK_HDWR_STATUS/* /* Check Hardware Status/* P/* The Check Hardware Status routine checks the DECtalk hardware for hardware/* malfunctions. /* DENTRY dtk$check_hdwr_status ALIAS $dtk_check_hdwr_status PARAMETER (' LONGWORD UNSIGNED NAMED voice_id IN& TYPENAME identifier REFERENCE,+ LONGWORD UNSIGNED NAMED hdwr_status OUT* TYPENAME mask_longword REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' /* DTK$DIAL_PHONE/* /* Dial the Telephone/* Q/* The Dial the Telephone routine dials the specified number on the telephone./* 6ENTRY dtk$dial_phone ALIAS $dtk_dial_phone PARAMETER (' LONGWORD UNSIGNED NAMED voice_id IN& TYPENAME identifier REFERENCE,0 CHARACTER RTL_STR_DESC NAMED phone_number IN TYPENAME char_string,1 LONGWORD UNSIGNED NAMED dial_mode IN OPTIONAL- TYPENAME longword_unsigned REFERENCE,1 CHARACTER RTL_STR_DESC NAMED text IN OPTIONAL TYPENAME char_string,& LONGWORD NAMED timeout IN OPTIONAL, TYPENAME longword_signed REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' /* DTK$HANGUP_PHONE/* /* Hang Up the Phone/* C/* The Hang Up the Phone routine speaks an optional message and /* then hangs up the phone./* :ENTRY dtk$hangup_phone ALIAS $dtk_hangup_phone PARAMETER (' LONGWORD UNSIGNED NAMED voice_id IN& TYPENAME identifier REFERENCE,1 CHARACTER RTL_STR_DESC NAMED text IN OPTIONAL TYPENAME char_string )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' /* DTK$INITIALIZE/* /* Initialize DECtalk/* c/* The Initialize DECtalk routine initializes a DECtalk device and returns the device's assigned/* voice identifier. /* 6ENTRY dtk$initialize ALIAS $dtk_initialize PARAMETER (( LONGWORD UNSIGNED NAMED voice_id OUT& TYPENAME identifier REFERENCE,1 CHARACTER RTL_STR_DESC NAMED output_device IN TYPENAME device_name,+ LONGWORD NAMED device_type OUT OPTIONAL, TYPENAME longword_signed REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' /* DTK$LOAD_DICTIONARY/* -/* Load a Word into the DECtalk Dictionary/* :/* The Load a Word into the DECtalk Dictionary routine =/* loads a phonemic definition of a word into the DECtalk /* dictionary./* @ENTRY dtk$load_dictionary ALIAS $dtk_load_dictionary PARAMETER (' LONGWORD UNSIGNED NAMED voice_id IN& TYPENAME identifier REFERENCE,( CHARACTER RTL_STR_DESC NAMED text IN TYPENAME char_string,0 CHARACTER RTL_STR_DESC NAMED substitution IN TYPENAME char_string )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' /* DTK$READ_KEYSTROKE/* &/* Read a Key Entered on the Keypad/* 3/* The Read a Key Entered on the Keypad routine ./* reads a key entered on the phone keypad./* >ENTRY dtk$read_keystroke ALIAS $dtk_read_keystroke PARAMETER (' LONGWORD UNSIGNED NAMED voice_id IN& TYPENAME identifier REFERENCE, LONGWORD NAMED key_code OUT+ TYPENAME longword_signed REFERENCE,: CHARACTER RTL_STR_DESC NAMED prompt_string IN OPTIONAL TYPENAME char_string,& LONGWORD NAMED timeout IN OPTIONAL, TYPENAME longword_signed REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' /* DTK$READ_STRING/* 1/* Read a Series of Keys Entered on the Keypad/* F/* The Read a Series of Keys Entered on the Keypad routine reads a 1/* series of keys entered on the phone keypad./* 8ENTRY dtk$read_string ALIAS $dtk_read_string PARAMETER (' LONGWORD UNSIGNED NAMED voice_id IN& TYPENAME identifier REFERENCE,5 CHARACTER RTL_STR_DESC NAMED resultant_string OUT TYPENAME char_string,: CHARACTER RTL_STR_DESC NAMED prompt_string IN OPTIONAL TYPENAME char_string,& LONGWORD NAMED timeout IN OPTIONAL+ TYPENAME longword_signed REFERENCE,< LONGWORD NAMED longword_integer_termin_code OUT OPTIONAL, TYPENAME longword_signed REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' /* DTK$RETURN_LAST_INDEX/* /* Return Last Index Spoken/* I/* The Return Last Index Spoken routine returns the last index spoken./* DENTRY dtk$return_last_index ALIAS $dtk_return_last_index PARAMETER (' LONGWORD UNSIGNED NAMED voice_id IN& TYPENAME identifier REFERENCE, LONGWORD NAMED p_index OUT, TYPENAME longword_signed REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' /* DTK$SPELL_TEXT/* /* Spell Text/* G/* The Spell Text routine causes DECtalk to pronounce each letter of/* the specified text. /* 6ENTRY dtk$spell_text ALIAS $dtk_spell_text PARAMETER (' LONGWORD UNSIGNED NAMED voice_id IN& TYPENAME identifier REFERENCE,( CHARACTER RTL_STR_DESC NAMED text IN TYPENAME char_string,7 LONGWORD UNSIGNED NAMED completion_mode IN OPTIONAL* TYPENAME mask_longword REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' /* DTK$SPEAK_FILE/* (/* Speak the Text in a Specified File/* 5/* The Speak the Text in a Specified File routine 6/* speaks the text contained in the specified file./* 6ENTRY dtk$speak_file ALIAS $dtk_speak_file PARAMETER (' LONGWORD UNSIGNED NAMED voice_id IN& TYPENAME identifier REFERENCE,, CHARACTER RTL_STR_DESC NAMED filespec IN TYPENAME char_string,7 LONGWORD UNSIGNED NAMED completion_mode IN OPTIONAL. TYPENAME longword_unsigned REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' /* DTK$SPEAK_PHONEMIC_TEXT/* '/* Speak the Specified Phonemic Text/* 4/* The Speak the Specified Phonemic Text routine >/* sends the specified phonemic text to the DECtalk device /* to be spoken./* HENTRY dtk$speak_phonemic_text ALIAS $dtk_speak_phonemic_text PARAMETER (' LONGWORD UNSIGNED NAMED voice_id IN& TYPENAME identifier REFERENCE,( CHARACTER RTL_STR_DESC NAMED text IN TYPENAME char_string,7 LONGWORD UNSIGNED NAMED completion_mode IN OPTIONAL. TYPENAME longword_unsigned REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' /* DTK$SPEAK_TEXT/* /* Speak the Specified Text/* +/* The Speak the Specified Text routine 5/* sends the specified text to the DECtalk device /* to be spoken./* 6ENTRY dtk$speak_text ALIAS $dtk_speak_text PARAMETER (' LONGWORD UNSIGNED NAMED voice_id IN& TYPENAME identifier REFERENCE,( CHARACTER RTL_STR_DESC NAMED text IN TYPENAME char_string,7 LONGWORD UNSIGNED NAMED completion_mode IN OPTIONAL. TYPENAME longword_unsigned REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' /* DTK$SET_INDEX/* -/* Insert an Index at the Current Position/* :/* The Insert an Index at the Current Position routine 6/* inserts an index into the current output stream./* 4ENTRY dtk$set_index ALIAS $dtk_set_index PARAMETER (' LONGWORD UNSIGNED NAMED voice_id IN& TYPENAME identifier REFERENCE, LONGWORD NAMED p_index IN, TYPENAME longword_signed REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' /* DTK$SET_KEYPAD_MODE/* &/* Turn the Phone Keypad On and Off/* E/* The Turn the Phone Keypad On and Off routine turns recognition (/* of the telephone keypad on or off./* @ENTRY dtk$set_keypad_mode ALIAS $dtk_set_keypad_mode PARAMETER (' LONGWORD UNSIGNED NAMED voice_id IN*& TYPENAME identifier REFERENCE,* LONGWORD UNSIGNED NAMED keypad_mode IN. TYPENAME longword_unsigned REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' S/* DTK$SET_LOGGING_MODE/* Q/* Set the Logging Mode for the Video Terminal Connected to the DECtalk Device /* 6/* The Set the Logging Mode for the Video Terminal -/* Connected to the DECtalk Device routineC=/* controls the information that is displayed on the videoT8/* terminal while the DECtalk device is functioning. /* BENTRY dtk$set_logging_mode ALIAS $dtk_set_logging_mode PARAMETER (' LONGWORD UNSIGNED NAMED voice_id IN & TYPENAME identifier REFERENCE,0 LONGWORD UNSIGNED NAMED new_mode IN OPTIONAL) TYPENAME mask_longword REFERENCE,E1 LONGWORD UNSIGNED NAMED old_mode OUT OPTIONAL * TYPENAME mask_longword REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' */* DTK$SET_MODE/* +/* Set the Mode for the DECtalk Terminal /* 8/* The Set the Mode for the DECtalk Terminal routine ?/* sets or resets the mode settings of the DECtalk terminal.P/* 2ENTRY dtk$set_mode ALIAS $dtk_set_mode PARAMETER (' LONGWORD UNSIGNED NAMED voice_id INA& TYPENAME identifier REFERENCE,0 LONGWORD UNSIGNED NAMED new_mode IN OPTIONAL) TYPENAME mask_longword REFERENCE,n1 LONGWORD UNSIGNED NAMED old_mode OUT OPTIONAL * TYPENAME mask_longword REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' Y/* DTK$SET_SPEECH_MODER/* !/* Turn Speech Mode On and Offx/* ./* The Turn Speech Mode On and Off routine 9/* either starts or stops the DECtalk device's speech.i/* @ENTRY dtk$set_speech_mode ALIAS $dtk_set_speech_mode PARAMETER (' LONGWORD UNSIGNED NAMED voice_id IN & TYPENAME identifier REFERENCE,' LONGWORD UNSIGNED NAMED new_mode INh- TYPENAME longword_unsigned REFERENCE,h1 LONGWORD UNSIGNED NAMED old_mode OUT OPTIONAL. TYPENAME longword_unsigned REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' /* DTK$SET_TERMINAL_MODEG/* I/* Set the Mode for the Video Terminal Connected to the DECtalk DeviceO/* ./* The Set the Mode for the Video Terminal -/* Connected to the DECtalk Device routine*=/* controls the attributes of the video terminal connectedp/* to the DECtalk device. d/* DENTRY dtk$set_terminal_mode ALIAS $dtk_set_terminal_mode PARAMETER (' LONGWORD UNSIGNED NAMED voice_id IN & TYPENAME identifier REFERENCE,0 LONGWORD UNSIGNED NAMED new_mode IN OPTIONAL) TYPENAME mask_longword REFERENCE,1 LONGWORD UNSIGNED NAMED old_mode OUT OPTIONAL* TYPENAME mask_longword REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' /* DTK$SET_VOICEo/* /* Set Voice Characteristics_/* +/* The Set Voice Characteristics routineA>/* changes the DECtalk voice characteristics to match those/* specified. */* 4ENTRY dtk$set_voice ALIAS $dtk_set_voice PARAMETER (' LONGWORD UNSIGNED NAMED voice_id INa& TYPENAME identifier REFERENCE,( LONGWORD NAMED new_voice IN OPTIONAL+ TYPENAME longword_signed REFERENCE, * LONGWORD NAMED speech_rate IN OPTIONAL+ TYPENAME longword_signed REFERENCE,M3 LONGWORD UNSIGNED NAMED comma_pause IN OPTIONAL- TYPENAME longword_unsigned REFERENCE,;4 LONGWORD UNSIGNED NAMED period_pause IN OPTIONAL. TYPENAME longword_unsigned REFERENCE )0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' i/* DTK$TERMINATE /* /* Terminate DECtalk /* P/* The Terminate DECtalk routine terminates the use of an initialized DECtalk /* device.A/* 4ENTRY dtk$terminate ALIAS $dtk_terminate PARAMETER (' LONGWORD UNSIGNED NAMED voice_id INa' TYPENAME identifier REFERENCE )O0 RETURNS LONGWORD UNSIGNED TYPENAME cond_value;' EEND_MODULE dtk$routines; /* DTK$LOAD_DICTIONARY/* -/* Load a Word into the DECtalk Dictionary/* :/* The Load a Word into the DECtalk Dictionary routine =/* loads a phonemic definition of a word into the DECtalk /* dictionary./* @ENTRY dtk$load_dictionar *[DIETER.DTKALPHA]DTKDATSTR.REQ;1+,c(./ ) 4S- 0123KPWO56{M7~Ԕ89G )HJ2! Data Structure Definitions for RTL DTK$ facility#! File: DTKDATSTR.REQ Edit: TS1003!!M!****************************************************************************!* *I!* COPYRIGHT (c) 1978, 1980, 1982, 1984, 1985, 1986, 1987, 1988 BY *A!* DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS. *#!* ALL RIGHTS RESERVED. *!* *M!* THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED *M!* ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE *M!* INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER *M!* COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY *M!* OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY *!* TRANSFERRED. *!* *M!* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE *M!* AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT *!* CORPORATION. *!* *M!* DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS *B!* SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. *!* *!* *M!****************************************************************************!!++! FACILITY: Screen Management! ! ABSTRACT:!F! This file contains data structure definitions for DECtalk management5! routines. Voice Control Block are defined here.!!!! MODIFIED BY:!A! 1-003 - Add fields for file and network support. TS 7-Mar-1988@! 1-002 - Reformat for new status queue entries. TS 23-Jun-1986"! 1-001 - Original. TS 6-Aug-1985 !+! Voice Control Block (VCB)!! -------------------------------B! This data structure resides in HEAP storage. One of these areasG! is allocated whenever a new stream is established for the first time./! It is deallocated when the stream is deleted.D! It contains the fundemental information associated with a DECtalk.!-MACRO? VCB_A_NEXT = 0, 0, 32, 0%, ! Link for chain of vcbs9 VCB_A_PREV = 4, 0, 32, 0%, ! Back link for chainG VCB_W_MODE_SETTINGS = 8, 0, 16, 0%, ! Mode setting for this VCB9 VCB_V_SQUARE = 8, 0, 1, 0%, ! =1 if square enabled6 VCB_V_MINUS = 8, 1, 1, 0%, ! =1 if minus enabled5 VCB_V_ASCII = 8, 2, 1, 0%, ! =1 if asky enabled? VCB_V_EUROPE = 8, 3, 1, 0%, ! =1 if european numbers used8 VCB_V_SPELL = 8, 4, 1, 0%, ! =1 to spell all wordsD VCB_B_MODE_TERMINAL = 10, 0, 8, 0%, ! Terminal mode settingsA VCB_V_HOST = 10, 0, 1, 0%, ! =1 if sending all chars to hostA VCB_V_SPEAK = 10, 1, 1, 0%, ! =1 if speaking all chars typed? VCB_V_EDITED = 10, 2, 1, 0%, ! =1 if line editting enabled> VCB_V_HARD = 10, 3, 1, 0%, ! =1 if local echo as hardcopy7 VCB_V_SETUP = 10, 4, 1, 0%, ! =1 if speaking setupA VCB_V_FILTER = 10, 5, 1, 0%, ! =1 if not sending seq to termB VCB_B_MODE_LOGGING = 11, 0, 8, 0%, ! Logging mode settings4 VCB_V_TEXT = 11, 0, 1, 0%, ! =1 if logging text; VCB_V_PHONEME = 11, 1, 1, 0%, ! =1 if logging phonemes< VCB_V_RAWHOST = 11, 2, 1, 0%, ! =1 if logging all chars@ VCB_V_INHOST = 11, 3, 1, 0%, ! =1 if logging text from host? VCB_V_OUTHOST = 11, 4, 1, 0%, ! =1 if logging text to host7 VCB_V_ERROR = 11, 5, 1, 0%, ! =1 if logging errorsA VCB_V_TRACE = 11, 6, 1, 0%, ! =1 if logging seq symbolically+ VCB_V_DEBUG = 11, 7, 1, 0%, ! ReservedB VCB_B_SPEECH_MODES = 12, 0, 8, 0%, ! Speech mode settings< VCB_B_DEVTYPE = 13, 0, 8, 0%, ! Logical device typeK VCB_W_DEVNAM_LEN = 14, 0, 16, 0%, ! Length of the resultant device . ! name string contained in VCB_T_DEVNAM.N VCB_T_DEVNAM = 16, 0, 0, 0%, ! A 64-byte area. This buffer contains / ! the resultant device name string. Its 0 ! length is contained in VCB_W_DEVNAM_LEN.9 VCB_R_CHARBUF = 80, 0, 0, 0%, ! Start of 12-byte ! characteristics bufferA VCB_L_DEVCHAR = 80, 0, 32, 0%, ! Device characteristicsB VCB_B_DEVCLASS = 80, 0, 8, 0%, ! Device class, e.g. DC$_TERML VCB_B_PHY_DEV_TYPE = 81, 0, 8, 0%, ! Physical device type, e.g. DT$_VT1000 VCB_W_WIDTH = 82, 0, 16, 0%, ! Device widthS VCB_L_DEVDEPEND = 84, 0, 32, 0%, ! Primary device dependent bits. These , ! are the bits of the TT$V_xyz flavor.= VCB_B_ROWS = 84, 24, 8, 0%, ! Number of rows on terminal! ! (overlaps prev`~ DTKALPHA.SAVc(  [DIETER.DTKALPHA]DTKDATSTR.REQ;1SJ ious field)P VCB_L_DEVDEPEND2 = 88, 0, 32, 0%, ! Secondary device dependent bits. 3 ! These are the bits of the TT2$V_xyz flavor.> VCB_W_CHAN = 92, 0, 16, 0%, ! Channel number. 0 means# ! no channel as been assignedA VCB_B_STRUCT_TYPE = 94, 0, 8, 0%, ! Structure type (VCB)B VCB_B_CURR_VOICE = 95, 0, 8, 0%, ! Current speaking voice. VCB_L_VID = 96, 0, 32, 0%, ! Voice idD VCB_R_EXIT_BLOCK = 100, 0, 0 ,0%, ! Exit block (5 longwords)I VCB_L_EXIT_LINK = 100, 0, 32, 0%, ! system forward link to next blockC VCB_A_EXIT_ADDR = 104, 0, 32, 0%, ! address of our exit handler; VCB_B_EXIT_ARGCNT = 108, 0, 8, 0%, ! argument count (=2)J VCB_A_EXIT_RSN = 112, 0, 32, 0%, ! arg 1: address to store exit reason> VCB_A_EXIT_VCB = 116, 0, 32, 0%, ! arg 2: our VCB addressR VCB_L_EXIT_REASON = 120, 0, 32, 0%, ! exit reason (address stored as first ! argument in exit block).O VCB_A_OUTNAM = 124, 0, 32, 0%, ! Address of buffer containing the output) ! filename as specified by the userH VCB_W_OUTNAM_LEN = 128, 0, 16, 0%, ! Length of output name string= VCB_W_LAST_INDEX = 130, 0, 16, 0%, ! Last index spoken 2 VCB_W_fill1 = 132, 0, 16, 0%, ! spare word- VCB_W_FLAGS = 134, 0, 16, 0%, ! Flags> VCB_V_WINK = 134, 0, 1, 0%, ! Wink detection enabledD VCB_V_STSREAD = 134, 1, 1, 0%, ! 1 means a status was read7 VCB_V_LOCKED = 134, 2, 1, 0%, ! VCB is locked> VCB_V_KEYPAD_ON = 134, 3, 1, 0%, ! keypad is enabled; VCB_V_OFFHOOK = 134, 4, 1, 0%, ! phone is offhook> VCB_V_AUTOSTOP = 134, 5, 1, 0%, ! use auto-stop modeE VCB_V_BUF_ENABLED = 134, 6, 1, 0%, ! output buffering is onL VCB_L_CAP_LENGTH = 136, 0, 32, 0%, ! Length of last capability gottenH VCB_A_CAP_BUFFER = 140, 0, 32, 0%, ! Address of capability bufferH VCB_A_OUTPUT_BUFFER = 144, 0, 32, 0%, ! Address of buffer used to" ! buffer up output sequencesN VCB_W_OUTPUT_BUFSIZ = 148, 0, 16, 0%, ! (Maximum) size of output bufferN VCB_W_OUTPUT_BUFLEN = 150, 0, 16, 0%, ! Current length of output buffer) ! i.e. number of characters in the - ! buffer. 0 means the buffer is empty.J VCB_Q_INPUT_DESC = 152, 0, 0, 0%, ! Buffer for holding users input7 VCB_W_LENGTH = 152, 0, 16, 0%, ! String length4 VCB_B_DTYPE = 154, 0, 8, 0%, ! String type5 VCB_B_CLASS = 155, 0, 8, 0%, ! String class9 VCB_A_POINTER = 156, 0, 32, 0%, ! String pointerG VCB_Q_STATUS_QUEUE = 160, 0, 0, 0%, ! Queue for holding STATUS; VCB_L_STATUS_FLINK = 160, 0, 32, 0%, ! Forward link< VCB_L_STATUS_BLINK = 164, 0, 32, 0%, ! Backward linkM VCB_Q_HDWR_STS_QUEUE = 168, 0, 0, 0%, ! Queue for holding hardware sts; VCB_L_HDWR_STS_FLINK = 168, 0, 32, 0%, ! Forward link< VCB_L_HDWR_STS_BLINK = 172, 0, 32, 0%; ! Backward linkLITERAL? VCB_K_SIZE = 176, ! Total size of VCB in bytes.? VCB_K_STRUCT_TYPE = %X'11', ! VCB structure type code< VCB$K_LONGEST_SEQUENCE = 255, ! Longest escape sequenceI STSQUE_K_SIZE = 12, ! Size of STATUS queue entries in bytes@ TYPEAHEAD_K_SIZE = 8, ! Size of typeahead block in bytes9 VCB_K_DEF_MODE_SETTINGS = 0, ! Default mode settings  ! for VCB_L_MODE_SETTINGS.H DTK$S_CHAR_EXIT_BLOCK = 9*4; ! Size in bytes of exit block used by( ! DTK$$SET_TERMINAL_CHARACTERISTICSFIELD TYPEAHEAD_FIELDS = SETI TYPEAHEAD_COUNT = [0,0,16,0], ! Number of characters in typeahead bufC TYPEAHEAD_CHAR = [0,16,8,0] ! First character in typeahead buf  TES;FIELD STSQUE_FIELDS = SETB STATUS_A_FLINK = [ 0,0,32,0], ! Forward link in status queueC STATUS_A_BLINK = [ 4,0,32,0], ! Backward link in status queue > STATUS_L_STATUS = [ 8,0,32,0] ! Status returned by DECTALK TES;MACRO/ $VCB_DECL = BLOCK[VCB_K_SIZE,BYTE] %,M $TYPEAHEAD_DECL = BLOCK[TYPEAHEAD_K_SIZE,BYTE] FIELD(TYPEAHEAD_FIELDS) %,G $STSQUE_DECL = BLOCK[STSQUE_K_SIZE,BYTE] FIELD(STSQUE_FIELDS) %;*[DIETER.DTKALPHA]DTKDEF.SDL;1+,n(a./ ) 4"- 0123KPWO56.6*73q 89HDcG )HJ "This file is now obsolete." *[DIETER.DTKALPHA]DTKMACROS.REQ;1+,(<./ ) 4M - 0123KPWO56?mo7mo89G )HJ)! Macro Definitions for RTL DTK$ facility#! File: DTKMACROS.REQ Edit: TS1003!!M!****************************************************************************!* *M!* COPYRIGHT (c) 1978, 1980, 1982, 1984, 1985, 1986, 1987, 1988, 1990 BY *A!* DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS. *#!* ALL RIGHTS RESERVED. *!* *M!* THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED *M!* ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE *M!* INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER *M!* COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY *M!* OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY *!* TRANSFERRED. *!* *M!* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE *M!* AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT *!* CORPORATION. *!* *M!* DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS *B!* SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. *!* *!* *M!****************************************************************************! !++! FACILITY: DECtalk Management! ! ABSTRACT:!@! This file contains macros used by DECtalk management routines.!! MODIFIED BY:!.! 1-004 - Add descriptor macro. TS 7-Mar-19885! 1-003 - Remove unused queue macros. TS 23-Jun-1986/! 1-002 - Add $DTK$RETURN macro. TS 9-Apr-1986"! 1-001 - Original. TS 6-Aug-1985!-- !+! $DTK$DESCRIPTOR! ---------------!4! This macro is used to declare a string descriptor.!-MACRO2 $DTK$DESCRIPTOR = BLOCK [DSC$K_S_BLN, BYTE] %;!+ ! $DTK$RETURN ! -----------!@! This macro is used to return the status of a called routine if?! the status is not successful. It also resets the locked bit.!!-MACRO $DTK$RETURN(S) = BEGIN VCB [VCB_V_LOCKED] = 0; RETURN S; END %;!+! $DTK$BUFFERING_ON! -----------------!G! This macro is used to turn on buffering mode. This will minimize the'! number of $QIOs that need to be done.!!-MACRO $DTK$BUFFERING_ON(VCB) =  VCB[VCB_V_BUF_ENABLED] = 1 %;!+! $DTK$BUFFERING_OFF! ------------------!F! This macro is used to turn off buffering mode. This will result in G! a $QIO for each output. It will also output the current contents of ! the buffer.!!-MACRO  $DTK$BUFFERING_OFF(VCB) = IF .VCB[VCB_V_BUF_ENABLED] THEN BEGIN& STATUS = DTK$$FLUSH_BUFFER(.VCB);/ IF NOT .STATUS THEN $DTK$RETURN (.STATUS); VCB[VCB_V_BUF_ENABLED] = 0; END %; !+! $DTK$OUTPUT_DATA! ----------------!F! This macro is used to retrieve and output a specific sequence to the7! DECtalk device. Assumes you have a symbol named VCB.!!-MACRO% $DTK$OUTPUT_DATA(CAP,ARG1,ARG2) = BEGIN $DTK$GET_TERM_DATA( %NAME(CAP) %IF NOT %NULL(ARG1) %THEN ,ARG1 %FI %IF NOT %NULL(ARG2) %THEN ,ARG2 %FI ); STATUS = DTK$$OUTPUT( .VCB, " .VCB [VCB_L_CAP_LENGTH], # .VCB [VCB_A_CAP_BUFFER] );+ IF NOT .STATUS THEN $DTK$RETURN (.STATUS); END %;!+! $DTK$GET_TERM_DATA! ------------------!G! This macro is used to retrieve a specified sequence to be sent to the7! DECtalk device. Assumes you have a symbol named VCB.!!-MACRO' $DTK$GET_TERM_DATA(CAP,ARG1,ARG2) = BEGIN STATUS=DTK$$GET_TERM_DATA(.VCB, %NAME(CAP), %NAME(K_,CAP,_LEN) %IF NOT %NULL(ARG1) %THEN ,ARG1 %FI %IF NOT %NULL(ARG2) %THEN ,ARG2 %FI );+ IF NOT .STATUS THEN $DTK$RETURN (.STATUS); END %;!+! $DTK$DEFINE_SEQ! ---------------!E! This macro defines an escape sequence for a capability in read-onlyG! own storage. CAP is the capability name, SEQ is the sequence withoutF! the leading , and FLAG indicates this is a DCS sequence if set.<! The length of the capability is also defined as a literal.!!-MACRO( $DTK$DEFINE_SEQ ( CAP, SEQ, FLAG ) =4 LITERAL %NAME(K_,CAP,_LEN) = %CHARCOUNT(SEQ) + 1 %IF FLAG NEQ 0 %THEN + 4 %FI ; OWN/ %NAME(CAP) : VECTOR [%NAME(K_,CAP,_LEN), BYTE] PSECT (_DTK$PLIT) INITIAL ( BYTE ( K_ESC %IF FLAG NEQ 0 %THEN , 'P;' %FI ,%STRING(SEQ) %IF FLAG NEQ 0 %THEN , K_ESC, '\' %FI ) ) %;!+! $DTK$VALIDATE_ARGCOUNT! ----------------------!G! Macro used to check that a DTK$ procedure was called with the correctI! number of arguments. If the test fails, the procedure returns with the ! failure status DTK$_WRONUMARG.! ! Format:"! $DTK$VALIDATE_ARGCOUNT (lo, hi);!9! lo = Lowest number of arguments which are valid (0-255):! hi = Highest number of arguments which are valid (0-255)!-MACRO% $DTK$VALIDATE_ARGCOUNT (lo, hi) = BEGIN BUILTIN ACTUALCOUNT; EXTERNAL LITERAL DTK$_WRONUMARG; %IF lo NEQ hi %THEN %IF lo NEQ 0 %THEN LOCAL DIFF; DIFF = ACTUALCOUNT () - lo; IF .DIFF GTRU (hi - lo) THEN RETURN (DTK$_WRONUMARG); %ELSE IF ACTUALCOUNT () GTRU hi THEN RETURN (DTK$_WRONUMARG); %FI %ELSE IF ACTUALCOUNT () NEQU lo THEN RETURN (DTK$_WRONUMARG); %FI END %;!+! $DTK$GET_VCB! ------------=! Macro $DTK$GET_VCB validates the suppled voice id (VID) andB! computes the starting address of the corresponding Voice ControlH! Block (VCB). If VID is invalid, DTK$_INVVOI_ID is returned to caller%! of routine that invokes this macro.!-MACRO# $DTK$GET_VCB ( VID, VCB_ADDR) = BEGIN BIND # LOC_VID = VID : REF BLOCK [,BYTE]; EXTERNAL LITERAL  DTK$_TLKINUSE, DTK$_INVVOI_ID; IF .VID LEQ 0+ THEN ! VID of 0 or a negative number& RETURN (DTK$_INVVOI_ID); ! is invalid$ IF .LOC_VID [VCB_L_VID] NEQ .VID THEN6 RETURN (DTK$_INVVOI_ID); ! Not pointing to one of our ! control blocks9 IF .LOC_VID [VCB_B_STRUCT_TYPE] NEQ VCB_K_STRUCT_TYPE THEN1 RETURN (DTK$_INVVOI_ID); ! Not pointing to a VCB" VCB_ADDR = .VID; ! Assume ok END %;*[DIETER.DTKALPHA]DTKMSG.MSG;1+, )Q./ ) 4"- 0123KPWO56.6*73q 89HDcG )HJ "This file is now obsolete." *[DIETER.DTKALPHA]DTKPROLOG.REQ;1+,)2./ ) 4M- 0123KPWO 56,&7hE89G )HJ!+=! Prologue BLISS REQUIRE file for DECtalk Management Facility#! File: DTKPROLOG.REQ, Edit: TS1001!!M!****************************************************************************!* *9!* COPYRIGHT (c) 1978, 1980, 1982, 1984, 1985 BY *A!* DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS. *#!* ALL RIGHTS RESERVED. *!* *M!* THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED *M!* ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE *M!* INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER *M!* COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY *M!* OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY *!* TRANSFERRED. *!* *M!* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE *M!* AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT *!* CORPORATION. *!* *M!* DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS *B!* SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. *!* *!* *M!****************************************************************************!!! Edit History:!!! 1-001 - Created. TS 6-Aug-1985!--!+"! Set addressing modes to be used.!-GSWITCHES ADDRESSING_MODE (EXTERNAL=GENERAL, NONEXTERNAL=WORD_RELATIVE);!+"! Reference precompiled libraries.!-/LIBRARY 'RTLSTARLE'; ! SYS$LIBRARY:STARLET.L32JREQUIRE 'RTLIN:DTKDATSTR'; ! DECtalk Management data structure definitionsAREQUIRE 'RTLIN:DTKMACROS'; ! DECtalk Management macro definitions!+! Declare PSECTs to be used.!-PSECT: CODE = _DTK$CODE (READ, NOWRITE, EXECUTE, SHARE, PIC, " ADDRESSING_MODE (WORD_RELATIVE)),: PLIT = _DTK$PLIT (READ, NOWRITE, EXECUTE, SHARE, PIC, " ADDRESSING_MODE (WORD_RELATIVE)),< OWN = _DTK$DATA (READ, WRITE, NOEXECUTE, NOSHARE, PIC, " ADDRESSING_MODE (LONG_RELATIVE)),> GLOBAL = _DTK$DATA (READ, WRITE, NOEXECUTE, NOSHARE, PIC, " ADDRESSING_MODE (LONG_RELATIVE));! End of DTKPROLOG.REQ *[DIETER.DTKALPHA]DTKSHRLNK.OPT;1+,7@./ ) 4M- 0123KPWO 56+Pٕ7 ٕ89G )HJ =! DTKSHRLNK.OPT - Linker options file for building DTKSHR.EXE!!+B! Specify image name and ident. Note that this is not the same asC! the global section ident given with GSMATCH. IDENT should changeG! each time DTKSHR changes in a released version, such as a maintenanceG! update. GSMATCH should change only when the vector is modified in an#! incompatible (backwards) fashion.!- NAME=DTKSHRIDENT="DTK$ X1.0-001"!+$! Specify the order of the PSECTs. !-FCOLLECT=CLUSTER1,_DTK$CODE,_DTK$PLIT,$CODE$,$PLIT$,$INITIAL$,$LITERAL$3COLLECT=CLUSTER2,_DTK$DATA,$LINK$,$LINKAGE,$SYMVECT!+#! Specify modules to be included. !-CLUSTER=DTK,,,-/ LIB$:DTKRTL/INCLUDE=(DTK$UTIL,DTK$MSGDEF),-, SYS$LIBRARY:STARLET/INCLUDE=(LIB$MSGDEF)SYS$LIBRARY:IMAGELIB/LIBRARY/SYS$LIBRARY:SYS$PUBLIC_VECTORS.EXE/SHARE/SELECT!! Set global section match valuesGSMATCH=LEQUAL,1,100 DZRO_MIN=1 UNSUPPORTED=1!+E! Define vectored entry points for the DECtalk Management Procedures.!3! Any additions to this file should be reflected inG! COM$:DTKSHRVEC.DAT. All new entry points must be appended to the endF! of the list. NEVER change existing entries unless you are sure that,! what you do won't break existing programs.!-SYMBOL_VECTOR=(- DTK$ANSWER_PHONE = PROCEDURE,- DTK$DIAL_PHONE = PROCEDURE,- DTK$HANGUP_PHONE = PROCEDURE,- DTK$INITIALIZE = PROCEDURE,-" DTK$LOAD_DICTIONARY = PROCEDURE,- DTK$OUTPUT = PROCEDURE,-! DTK$READ_KEYSTROKE = PROCEDURE,- DTK$READ_STRING = PROCEDURE,-$ DTK$RETURN_LAST_INDEX = PROCEDURE,- DTK$SET_INDEX = PROCEDURE,-" DTK$SET_KEYPAD_MODE = PROCEDURE,-# DTK$SET_LOGGING_MODE = PROCEDURE,- DTK$SET_MODE = PROCEDURE,-" DTK$SET_SPEECH_MODE = PROCEDURE,-$ DTK$SET_TERMINAL_MODE = PROCEDURE,- DTK$SET_VOICE = PROCEDURE,- DTK$SPEAK_FILE = PROCEDURE,-& DTK$SPEAK_PHONEMIC_TEXT = PROCEDURE,- DTK$SPEAK_TEXT = PROCEDURE,- DTK$TERMINATE = PROCEDURE,- DTK$SPELL_TEXT = PROCEDURE,-$ DTK$CHECK_HDWR_STATUS = PROCEDURE,- DTK$RUN_SELF_TEST = PROCEDURE,-M! Add new entry points here by replacing the following NOT_IMPLEMENTED lines.* DTK$NOT_IMPLEMENTED = PRIVATE_PROCEDURE,-* DTK$NOT_IMPLEMENTED = PRIVATE_PROCEDURE,-* DTK$NOT_IMPLEMENTED = PRIVATE_PROCEDURE,-* DTK$NOT_IMPLEMENTED = PRIVATE_PROCEDURE,-* DTK$NOT_IMPLEMENTED = PRIVATE_PROCEDURE,-* DTK$NOT_IMPLEMENTED = PRIVATE_PROCEDURE,-* DTK$NOT_IMPLEMENTED = PRIVATE_PROCEDURE,-* DTK$NOT_IMPLEMENTED = PRIVATE_PROCEDURE,-) DTK$NOT_IMPLEMENTED = PRIVATE_PROCEDURE) *[DIETER.DTKALPHA]DTKSHRVEC.DAT;1+,`Aj./ ) 4A- 0123KPWO 568H7͹AH89G )HJ@! DTKSHRVEC.DAT - data file used by VECTORTST.COM for DTKSHR.EXE!=! This file contains the master list of all universal symbolsA! in the shared DTKSHR vector, along with their vector addresses.9! It is used by VECTORTST.COM to determine whether or not:! any vectors have moved. Any newly shared symbol must be! added to this list.!! The syntax is:! symbol-hex_address! where:.! symbol is the global symbol in the vector;! hex_address is the address of the vector in hex; all 8! digits must be given!8! A line beginning with a ! is a comment and is ignored.<! The symbol must begin in column 1. There must be no extra(! characters (i.e. spaces) in the lines.!;! If a universal symbol is not vectored (e.g. a patch area)2! its address is represented with an asterisk (*).!!?! *************************************************************?! * WARNING *?! *************************************************************!<! If you move or delete a vector address, MAKE SURE THAT YOU<! KNOW WHAT YOU ARE DOING!!! In particular, symbols present;! in released software MUST NOT BE MOVED! It is a bad idea$! to move even unreleased symbols. !2! The symbols MUST be in alphabetical order!!!!!!!! ! 1-001 - Original TS 6-Sep-1985!DTK$ANSWER_PHONE-00000000DTK$CHECK_HDWR_STATUS-000000A8DTK$DIAL_PHONE-00000008DTK$HANGUP_PHONE-00000010DTK$INITIALIZE-00000018DTK$LOAD_DICTIONARY-00000020DTK$OUTPUT-00000028DTK$READ_KEYSTROKE-00000030DTK$READ_STRING-00000038DTK$RETURN_LAST_INDEX-00000040DTK$RUN_SELF_TEST-000000B0DTK$SET_INDEX-00000048DTK$SET_KEYPAD_MODE-00000050DTK$SET_LOGGING_MODE-00000058DTK$SET_MODE-00000060DTK$SET_SPEECH_MODE-00000068DTK$SET_TERMINAL_MODE-00000070DTK$SET_VOICE-00000078DTK$SPEAK_FILE-00000080 DTK$SPEAK_PHONEMIC_TEXT-00000088DTK$SPEAK_TEXT-00000090DTK$SPELL_TEXT-000000A0DTK$TERMINATE-00000098*[DIETER.DTKALPHA]DTKUTIL.B32;1+,A. / ) 4P  - 0123KPWO 56t|Ҕ7"Ҕ89G )HJ&-%TITLE 'DTK$UTIL - DECtalk utility routines.'MODULE DTK$UTIL (2 IDENT = '1-008' ! File: DTKUTIL.B32 Edit: TS1008 ) =BEGIN!M!****************************************************************************!* *M!* COPYRIGHT (c) 1978, 1980, 1982, 1984, 1985, 1986, 1987, 1988, 1991 BY *A!* DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS. *#!* ALL RIGHTS RESERVED. *!* *M!* THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED *M!* ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE *M!* INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER *M!* COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY *M!* OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY *!* TRANSFERRED. *!* *M!* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE *M!* AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT *!* CORPORATION. *!* *M!* DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS *B!* SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. *!* *!* *M!****************************************************************************!!++! FACILITY: DECtalk management! ! ABSTRACT:!G! This module contains the utility routines needed for DECtalk support.!!2! ENVIRONMENT: User mode, Shared library routines.!0! AUTHOR: T. Scarpelli CREATION DATE: 6-Aug-1985!! MODIFIED BY:!M! 1-008 - Only check first few characters of DA_PRIMARY sequence for level 1 ! and level 3 DTC03's.E! Make sure $CANCEL has completed by calling $SYNCH. TS 6-Jan-1990@! 1-007 - Fix DTK$SPELL_TEXT for lowercase text. TS 26-May-1987L! 1-006 - Use second efn to fix timing problem on LAT lines. TS 17-Apr-1987:! 1-005 - Add timeout value to input QIOWs. TS 8-Oct-1986<! 1-004 - Add DTK$CHECK_HDWR_STATUS routine. TS 29-Aug-1986G! 1-003 - Fix timing problem in processing phone status. TS 9-Apr-19869! 1-002 - Add 4 sec timeout on all reads. TS 20-Nov-1985"! 1-001 - Original. TS 6-Aug-1985!-- %SBTTL 'Declarations'! ! SWITCHES:!! NONE! ! LINKAGES:!! NONE!! TABLE OF CONTENTS:!FORWARD ROUTINE! Public entry points> DTK$ANSWER_PHONE, ! Wait for phone to ring and answer it7 DTK$CHECK_HDWR_STATUS, ! Check the hardware status2 DTK$DIAL_PHONE, ! Dial a number on the phone* DTK$HANGUP_PHONE, ! Hangup the phone, DTK$INITIALIZE, ! Begin DECTalk access; DTK$LOAD_DICTIONARY, ! Define a word in the dictionary@ DTK$NOT_IMPLEMENTED, ! Generate a "Not Implemented" message$ DTK$OUTPUT, ! Output raw textB DTK$READ_KEYSTROKE, ! Read a key pressed on the phone keypad> DTK$READ_STRING, ! Read a series of keys from the keypad6 DTK$RETURN_LAST_INDEX, ! Return last index spoken/ DTK$RUN_SELF_TEST, ! Run local self-tests6 DTK$SET_INDEX, ! Place index in current positionA DTK$SET_KEYPAD_MODE, ! Turn on/off recognition of the keypad6 DTK$SET_LOGGING_MODE, ! Set or reset logging mode' DTK$SET_MODE, ! Set or reset mode3 DTK$SET_SPEECH_MODE, ! Turn speaking on or off8 DTK$SET_TERMINAL_MODE, ! Set or reset terminal mode9 DTK$SET_VOICE, ! Set speaking voice characteristics7 DTK$SPEAK_FILE, ! Send text from a file to device< DTK$SPEAK_PHONEMIC_TEXT, ! Send phonemic text to device4 DTK$SPEAK_TEXT, ! Send text to device to speak4 DTK$SPELL_TEXT, ! Send text to device to spell/ DTK$TERMINATE, ! Terminate DECTalk access! Private entry points2 DTK$$FLUSH_BUFFER, ! Flush the output buffer5 DTK$$GET_STATUS, ! Read status and keypad input. DTK$$GET_TERM_DATA, ! Retrieve a command$ DTK$$INPUT, ! Read characters+ DTK$$OUTPUT, ! Output text (buffered)E DTK$$SET_TERM_CHARACTERISTICS, ! Set the terminal characteristics2 DTK$$SETUP_TERMINAL_TYPE, ! Do terminal setup7 DTK$$SIM_AUTO, ! Simulate AUTOSTOP mode for DTC01* DTK$$VCB_EXIT_HANDLER, ! Exit handler OUTPUT; ! Output raw text!! INCLUDE FILES!9REQUIRE 'RTLIN:DTKPROLOG'; ! defines psects, macros, vcb! ! LITERALS!LITERAL! Self-test codes K_TST_POWER = 1, K_TST_HDATA = 2, K_TST_HCONTROL= 3, K_TST_DATA = 4, K_TST_SPEAK = 5, ! Phone codes K_STATUS = 0, K_ANSWER = 10, K_HANGUP = 11, K_KEYPAD_ON = 20, K_KEYPAD_OFF = 21, K_KEYPAD_AUTO = 22, K_TIMEOUT = 30, K_DIAL_TONE = 40, K_DIAL_PULSE = 41, K_WINK = 50, K_NOWINK = 51,! One parameter sequence codes K_STOP = 10, K_SYNC = 11, K_INDEX_QUERY = 22,! Two parameter sequence codes K_SPEAK = 12, K_INDEX = 20, K_PHONE = 60, K_MODE = 80, K_LOG = 81, K_TERMINAL = 82, K_MASK = 83, ! Misc values) K_DISABLE = 0, ! Disable speaking' K_ENABLE = 1, ! Enable speaking@ K_2_SECONDS = %X'00004100', ! 2.0 in floating point format@ K_TMO_SEC = 30, ! Input QIOW timeout value in seconds., K_TMO_HR = 3600, ! SPEAK_TEXT timeout? K_BUFFER_LEN = 128, ! Size of buffer for input operations, K_VT = 11, ! CTRL/K character+ K_SP = 32, ! Blank character, K_ESC = 27; ! Escape character! ! OWN STORAGE!OWN' DTK_A_ZONE_ID : LONG INITIAL (0),$ DTK_L_EFN : LONG INITIAL(0),& DTK_L_EFN_2 : LONG INITIAL(0),& DTK_L_EFN_MASK : LONG INITIAL(0),+ VCB_QUEUE : VOLATILE INITIAL (0);!+! Setup sequences!-#$DTK$DEFINE_SEQ(S7C1T, ' F', 0 );($DTK$DEFINE_SEQ(DA_PRIMARY, '[0c', 0 );%$DTK$DEFINE_SEQ(DTC01, '[?19c', 0 );$$DTK$DEFINE_SEQ(DTC03, '[?8', 0 );%$DTK$DEFINE_SEQ(DECSTR, '[!p', 0 );$$DTK$DEFINE_SEQ(DSREXT, '[n', 0 );($DTK$DEFINE_SEQ(DECTST, '[5;!ZLy', 0 );!+! Phone sequences!--$DTK$DEFINE_SEQ(DT_ANSWER, '60;10;!ZLz', 1 );+$DTK$DEFINE_SEQ(DT_DIAL, '60;!ZLz!AS', 1 );!+! Misc sequences!-+$DTK$DEFINE_SEQ(DT_DICT, '40z!AS !AS', 1 );&$DTK$DEFINE_SEQ(DT_MISC, '!ZLz', 1 );*$DTK$DEFINE_SEQ(DT_MISC2, '!ZL;!ZLz', 1 );)$DTK$DEFINE_SEQ(DT_PHOTEXT, '0z!AS', 1 );!! EXTERNAL REFERENCES!EXTERNAL ROUTINE. LIB$ANALYZE_SDESC, ! Analyze a string desc6 LIB$CREATE_VM_ZONE, ! Create a dynamic memory zone) LIB$CVT_DTB, ! Convert text to binary& LIB$FREE_VM, ! Free dynamic memory) LIB$GET_EF, ! Allocate an event flag* LIB$GET_VM, ! Allocate dynamic memory# LIB$SCOPY_R_DX, ! Copy a string5 LIB$SIG_TO_RET, ! Convert signal to return status3 LIB$WAIT, ! Wait a specified number of seconds, OTS$CVT_L_TU, ! Convert longword to text+ OTS$CVT_T_F, ! Convert text to floating% STR$CONCAT, ! Concat two stringsF STR$FIND_FIRST_IN_SET, ! Find first character in set of characters+ STR$FREE1_DX, ! Free one dynamic string/ STR$RIGHT, ! Copy rightmost part of string0 STR$UPCASE; ! Translate string to uppercaseEXTERNAL LITERAL< DTK$_BUSY, ! Phone number was dialed and line was busy.: DTK$_COMFAIL, ! A communications failure was detected.B DTK$_CONSEQERR, ! A control sequence malfunction was detected.3 DTK$_DECTSTFAI, ! A local self-test has failed.@ DTK$_ERRPHOTRA, ! Phonemic transcription error was detected.F DTK$_FATERRLIB, ! Fatal error - internal consistancy check failed.5 DTK$_FILTOOLON, ! File specification is too long.9 DTK$_INPBUFOVR, ! Input buffer overflow was detected.$ DTK$_INVARG, ! Invalid argument.5 DTK$_INVMODE, ! Invalid mode parameter specified.' DTK$_INVVOI_ID, ! Invalid voice id.A DTK$_NOANSWER, ! Phone number was dialed and no one answered.; DTK$_NODIATONE, ! No dial tone was found on phone line.< DTK$_NOMALFUN1, ! No malfunctions detected (first reply)G DTK$_NOMALFUN2, ! No malfunctions detected (second and later reply)2 DTK$_NOROOM, ! No room in dictionary for word.< DTK$_NOTLCLTRM, ! Output device is not a local terminal.# DTK$_NOTIMP, ! Not implemented.0 DTK$_NVROPRFAI, ! Last NVR operation failed.% DTK$_OFFHOOK, ! Phone is offhook.# DTK$_ONHOOK, ! Phone is onhook.9 DTK$_STRTERESC, ! Escape sequence imbedded in string.+ DTK$_TIMEOUT, ! A timeout has occurred.C DTK$_TOOLONG, ! A dictionary entry or phone number is too long.. DTK$_UNKESCSEQ, ! Unknown escape sequence.# DTK$_UNKREPLY, ! Unknown reply.9 DTK$_VOIALREXI, ! VCB already exists for this device.H DTK$_WINK, ! A wink was detected on the phone line (caller hungup).0 DTK$_WRONUMARG, ! Wrong number of arguments.. LIB$_EF_ALRFRE; ! Event flag already free. ! >%SBTTL 'DTK$ANSWER_PHONE - Wait for phone to ring and answer.'!GLOBAL ROUTINE DTK$ANSWER_PHONE ( VOICE_ID, NUM_RINGS, TEXT, TIMEOUT ) =!++! FUNCTIONAL DESCRIPTION:!?! This routine will wait for the phone connected to the DECtalk8! described by VOICE_ID to ring and will then answer it.!!! CALLING SEQUENCE:!4! ret_status.wlc.v = DTK$ANSWER_PHONE (VOICE_ID.rl.r! [,NUM_RINGS.rl.r]! [,TEXT.rt.dx]! [,TIMEOUT.rl.r])!! FORMAL PARAMETERS:!+! VOICE_ID.rl.r Voice id of DECtalk device!=! NUM_RINGS.rl.r [OPTIONAL] Number of rings to wait before `-U~ DTKALPHA.SAVA [DIETER.DTKALPHA]DTKUTIL.B32;1P 5! answering the phone. ! Defaults to 1 ring.!8! TEXT.rt.dx [OPTIONAL] Text to speak after answering ! the phone. !=! TIMEOUT.rl.r [OPTIONAL] Number of seconds to wait for the! phone to be answered. !! IMPLICIT INPUTS:!! NONE!! IMPLICIT OUTPUTS:!! NONE!! COMPLETION STATUS:!)! SS$_NORMAL Normal successful completion! SS$_xxxx Any error from QIOW$ ! DTK$_INVVOIID Invalid voice id,! DTK$_WRONUMARG Wrong number of arguements.!! SIDE EFFECTS:-!C=! The phone is answered when it rings and text may be spoken. !i!- U BEGINt BUILTIN NULLPARAMETER;* LOCAL*) STATUS, ! Status returned by routines* RET_STATUS, ! Phone status 0 RINGS : INITIAL(1), ! Number of rings to wait.9 VCB : REF $VCB_DECL; ! Address of voice control blockP? $DTK$VALIDATE_ARGCOUNT (1, 4); ! Test for right no. of args 7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCBI !+C ! Check for number of rings to wait before answering the phone.I !-= IF NOT NULLPARAMETER(NUM_RINGS) THEN RINGS = ..NUM_RINGS;E !+@ ! Send answer phone sequence. Two replies will be recieved.5 ! First one indicates sequence has been recieved.N. ! Second one indicates phone was answered. !-* $DTK$OUTPUT_DATA( DT_ANSWER, .RINGS );B STATUS = DTK$$GET_STATUS( .VCB, RET_STATUS, %REF(K_TMO_SEC) );. IF NOT .STATUS THEN $DTK$RETURN (.STATUS);B IF .RET_STATUS NEQ DTK$_ONHOOK THEN $DTK$RETURN (.RET_STATUS);/ STATUS = DTK$$GET_STATUS( .VCB, RET_STATUS, " (IF NOT NULLPARAMETER(TIMEOUT) THEN .TIMEOUT ELSE 0) );A. IF NOT .STATUS THEN $DTK$RETURN (.STATUS); !+< ! If the phone was answered, enable wink detection which1 ! will give us a status if the user hangs up.* !-# IF .RET_STATUS EQL DTK$_OFFHOOK  THEN BEGIN !+e ! Enable the phone keypad.h !-dD STATUS = DTK$SET_KEYPAD_MODE( .VOICE_ID, %REF(DTK$K_KEYPAD_AUTO) );6 IF .STATUS NEQ SS$_NORMAL THEN $DTK$RETURN (.STATUS); !+R? ! Wait two seconds for the caller to get the phone to his ear. !-0* STATUS = LIB$WAIT( %REF( K_2_SECONDS ) );+ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);C !+& ! Enable wink detection if available. !-g) IF .VCB [VCB_B_DEVTYPE] NEQ DTK$K_DTC_01P THENT BEGIN VCB [VCB_V_WINK] = 0;3 $DTK$OUTPUT_DATA( DT_MISC2, K_PHONE, K_WINK );eB STATUS = DTK$$GET_STATUS( .VCB, RET_STATUS, %REF(K_TMO_SEC));/ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);tD IF .RET_STATUS NEQ DTK$_OFFHOOK THEN $DTK$RETURN (.RET_STATUS); END;9 !+8 ! Speak any specified text. !-a IF NOT NULLPARAMETER(TEXT)- THENr BEGIN1 STATUS = DTK$SPEAK_TEXT( .VOICE_ID, .TEXT );/ IF NOT .STATUS THEN $DTK$RETURN (.STATUS); END;  END ELSE $DTK$RETURN (.RET_STATUS);  $DTK$RETURN (SS$_NORMAL);N- END; ! End of routine DTK$ANSWER_PHONE !C D?%SBTTL 'DTK$CHECK_HDWR_STATUS - Check DECtalk hardware status.' &GLOBAL ROUTINE DTK$CHECK_HDWR_STATUS ( VOICE_ID, HDWR_STATUS ) =!++$! FUNCTIONAL DESCRIPTION:l!c.! This routine will check the DECtalk hardware?! described by VOICE_ID for hardware malfunctions (by using themD! DSR extended escape sequence) and return the status to the caller.B! If more than one hardware malfunction has occurred, this routineC! can be called multiple times to retrieve all of the error status.S@! A status of "no malfunctions" also indicates that there are no&! further error status to be returned.!!!a! CALLING SEQUENCE:o!i;! ret_status.wlc.v = DTK$CHECK_HDWR_STATUS (VOICE_ID.rl.r, e! HDWR_STATUS.wl.r)!O! FORMAL PARAMETERS:!n+! VOICE_ID.rl.r Voice id of DECtalk deviced!;! HDWR_STATUS.wl.r Status of DECtalk hardware. Values are:$+! DTK$_NOMALFUN1 - no malfunctions, 1sto+! DTK$_NOMALFUN2 - no malfunctions, 2nd *! DTK$_COMFAIL - communication failure,! DTK$_INPBUFOVR - input buffer overflow+! DTK$_NVROPRFAI - NVR operation failede+! DTK$_ERRPHOTRA - Phonemic trans error (! DTK$_CONSEQERR - control seq error(! DTK$_DECTSTFAI - self-test failed!T! IMPLICIT INPUTS:!! NONE!t! IMPLICIT OUTPUTS: !$! NONE!E! COMPLETION STATUS:!u)! SS$_NORMAL Normal successful completiona! SS$_xxxx Any error from QIOW$R ! DTK$_INVVOIID Invalid voice id,! DTK$_WRONUMARG Wrong number of arguements.4! LIB$_xxxx Any error from LIB$GET_VM or LIB$FREE_VM!R! SIDE EFFECTS:t!e! none!h!- i BEGIN BUILTINI REMQUE; LOCALl) STATUS, ! Status returned by routinesO RET_STATUS, ! Hardware status9 STSQUE : REF $STSQUE_DECL, ! New entry from status queue : VCB : REF $VCB_DECL; ! Address of voice control block? $DTK$VALIDATE_ARGCOUNT (2, 2); ! Test for right no. of args7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCBS8 STATUS = REMQUE(.VCB[VCB_L_HDWR_STS_FLINK], STSQUE); IF .STATUS THEN !+nB ! Hardware status queue was empty. Send hardware status request. !-P BEGIN ! Queue was empty  $DTK$OUTPUT_DATA( DSREXT );4 STATUS = DTK$$GET_STATUS(.VCB, 0, %REF(K_TMO_SEC));+ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);5 STATUS = REMQUE(.VCB[VCB_L_HDWR_STS_FLINK], STSQUE);a- IF .STATUS THEN $DTK$RETURN(DTK$_FATERRLIB); END; ! Queue was empty, .HDWR_STATUS = .STSQUE[STATUS_L_STATUS];E STATUS = LIB$FREE_VM(%REF(STSQUE_K_SIZE), STSQUE, DTK_A_ZONE_ID);N. IF NOT .STATUS THEN $DTK$RETURN (.STATUS); $DTK$RETURN (SS$_NORMAL);82 END; ! End of routine DTK$CHECK_HDWR_STATUS -%SBTTL 'DTK$DIAL_PHONE - Dial the telephone.' GLOBAL ROUTINE DTK$DIAL_PHONE (O VOICE_ID, PHONE_NUM,. MODE, TEXT, TIMEOUT ) =!++E! FUNCTIONAL DESCRIPTION:t!o?! This routine will dial the specified number on the telephone.t! !_! CALLING SEQUENCE: !e3! ret_status.wlc.v = DTK$DIAL_PHONE (VOICE_ID.rl.r, ! PHONE_NUM.rt.dx! [,MODE.rl.r] ! [,TEXT.rt.dx]! [,TIMEOUT.rl.r])s!e! FORMAL PARAMETERS:!T+! VOICE_ID.rl.r Voice id of DECtalk deviceG!I(! PHONE_NUM.rt.dx Phone number to dial.!0<! MODE.rl.r [OPTIONAL] Mode to use when dialing the phone.! Valid values are:3! DTK$K_DIAL_PULSE Use pulse dialing (default)e(! DTK$K_DIAL_TONE Use tone dialing! :! TEXT.rt.dx [OPTIONAL] Text to speak after the phone is! answered.! =! TIMEOUT.rl.r [OPTIONAL] Number of seconds to wait for theN4! phone to be answered. !For the DTC01, a wait of5! this number of seconds will always be done. For5! the DTC03, this is the maximum number of secondsE ! to wait.,!)! IMPLICIT INPUTS:!D! NONE!L! IMPLICIT OUTPUTS: !c! NONE!! COMPLETION STATUS:!D)! SS$_NORMAL Normal successful completionT! SS$_xxxx Any error from QIOW$_ ! DTK$_INVVOIID Invalid voice id,! DTK$_WRONUMARG Wrong number of arguements.(! DTK$_TOOLONG Phone number is too long.&! DTK$_INVMODE Invalid mode specified.(! DTK$_OFFHOOK Phone is offhook (active)(! DTK$_ONHOOK Phone is onhook (inactive)&! DTK$_NODIATONE No dial tone on line.! DTK$_BUSY Line is busy.o"! DTK$_NOANSWER No answer on line.!t! SIDE EFFECTS:E!M9! The phone number is dialed on the associated telephone.s9! If a call is currently active, the phone is not hungup.u!!- $ BEGINi BUILTINu NULLPARAMETER; LOCAL_) STATUS, ! Status returned by routines_+ RET_STATUS, ! Status returned by DECtalkCE DIAL_TYPE : INITIAL(DTK$K_DIAL_PULSE), ! Method of dialing the phonerE PHONE_ADDR: REF $DTK$DESCRIPTOR,! Address of phone number descriptor8 TOUT_FLOAT: LONG, ! TIMEOUT as a floating point number1 TOUT_BUF : LONG VOLATILE, ! Buffer for TOUT_LENN; TOUT_DSC : $DTK$DESCRIPTOR ! Desc for TIMEOUT as a stringe PRESET( # [DSC$B_DTYPE] = DSC$K_DTYPE_T,u# [DSC$B_CLASS] = DSC$K_CLASS_S,  [DSC$W_LENGTH] = 3,u [DSC$A_POINTER] = TOUT_BUF),C& PHONE_DSC : $DTK$DESCRIPTOR VOLATILE, TEXT_LEN : LONG INITIAL(0),c TEXT_ADDR : REF VECTOR[,BYTE],.7 VCB : REF $VCB_DECL; ! Address of voice control blocky? $DTK$VALIDATE_ARGCOUNT (2, 5); ! Test for right no. of argsg7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCBt PHONE_ADDR = .PHONE_NUM; !+( ! Verify input parameters are valid. !-J IF NOT (STATUS = LIB$ANALYZE_SDESC ( .PHONE_NUM, TEXT_LEN, TEXT_ADDR)) THEN $DTK$RETURN ( .STATUS); !+2 ! Set up mode from parameter or default value. !-7 IF NOT NULLPAR%AMETER(MODE) THEN DIAL_TYPE = ..MODE;  !+; ! If a timeout value was specified, check its validity. !-! IF NOT NULLPARAMETER(TIMEOUT)w THEN BEGIN IF ..TIMEOUT LSS 10 OR  ..TIMEOUT GTR 120  THEN  $DTK$RETURN (DTK$_INVARG);T !+P ! Initialize string descriptors !- 6 IF ..TIMEOUT LSS 100 THEN TOUT_DSC[DSC$W_LENGTH] = 2;* PHONE_DSC [DSC$B_DTYPE] = DSC$K_DTYPE_T;* PHONE_DSC [DSC$B_CLASS] = DSC$K_CLASS_S;D PHONE_DSC [DSC$W_LENGTH] = 3 + .TOUT_DSC[DSC$W_LENGTH] + .TEXT_LEN; !+n) ! Convert TIMEOUT parameter to a string. ; ! This is then used as part of the phone number (DTC03) ory@ ! is converted to floating point for use with LIB$WAIT (DTC01). !-$, STATUS = OTS$CVT_L_TU(.TIMEOUT, TOUT_DSC );+ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);  !+o4 ! If TIMEOUT is requested and this is a DTC03, add 1 ! the necessary X<> command to the phone number.E !-i) IF .VCB [VCB_B_DEVTYPE] NEQ DTK$K_DTC_01I THENA BEGIN !+I< ! Allocate some dynamic memory to hold the phone number" ! and the timeout characters. !-f; STATUS = LIB$GET_VM( %REF( .PHONE_DSC[DSC$W_LENGTH] ),  PHONE_DSC[DSC$A_POINTER], DTK_A_ZONE_ID );U/ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);  !+lF ! Copy the phone number and the timeout command in one operation. !-r- CH$COPY( .TEXT_LEN, .TEXT_ADDR, ! Fromr 2, UPLIT('X<'), ! From0 .TOUT_DSC[DSC$W_LENGTH], TOUT_BUF, ! From 1, UPLIT('>'), ! Fromr 0, ! Fill B .PHONE_DSC[DSC$W_LENGTH], .PHONE_DSC[DSC$A_POINTER] ); ! To PHONE_ADDR = PHONE_DSC; END; ! DTC03% END; ! TIMEOUT parameter specified  !+= ! Send sequence to dial phone with pluse or tone dialing. !- SELECTONE .DIAL_TYPE OF SET [DTK$K_DIAL_PULSE]: BEGIN8 $DTK$OUTPUT_DATA( DT_DIAL, K_DIAL_PULSE, .PHONE_ADDR ); END;W [DTK$K_DIAL_TONE]: BEGIN7 $DTK$OUTPUT_DATA( DT_DIAL, K_DIAL_TONE, .PHONE_R)ADDR );I END;C [OTHERWISE]: $DTK$RETURN (DTK$_INVMODE); TES; !+ ! If TIMEOUT:E- ! deallocate virtual memory if DTC03.O1 ! wait specified amount of time if DTC01.R !-! IF NOT NULLPARAMETER(TIMEOUT)L THEN* IF .VCB [VCB_B_DEVTYPE] EQL DTK$K_DTC_01  THENA BEGINB STATUS = OTS$CVT_T_F( TOUT_DSC, TOUT_FLOAT, 0, 0, %REF(17) );% STATUS = LIB$WAIT( TOUT_FLOAT );E/ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);  END ELSE BEGIN< STATUS = LIB$FREE_VM( %REF( .PHONE_DSC[DSC$W_LENGTH] ), PHONE_DSC[DSC$A_POINTER],R DTK_A_ZONE_ID );/ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);r END;  !+& ! Wait for phone to be answered.  !-A STATUS = DTK$$GET_STATUS( .VCB, RET_STATUS, %REF(K_TMO_HR) );A. IF NOT .STATUS THEN $DTK$RETURN (.STATUS);C IF .RET_STATUS NEQ DTK$_OFFHOOK THEN $DTK$RETURN (.RET_STATUS);E VCB [VCB_V_KEYPAD_ON] = 0; VCB [VCB_V_AUTOSTOP] = 0; VCB [VCB_V_WINK] = 0; !+@ ! Wait 2 seconds for the user to get the phone to their ear. !-- STATUS = LIB$WAIT( %REF( K_2_SECONDS ) );S. IF NOT .STATUS THEN $DTK$RETURN (.STATUS); !+ ! Enable the phone keypad. !-G STATUS = DTK$SET_KEYPAD_MODE( .VOICE_ID, %REF(DTK$K_KEYPAD_AUTO) );E9 IF .STATUS NEQ SS$_NORMAL THEN $DTK$RETURN (.STATUS);a !+) ! Enable wink detection if available.P !-, IF .VCB [VCB_B_DEVTYPE] NEQ DTK$K_DTC_01 THEN BEGIN/ $DTK$OUTPUT_DATA( DT_MISC2, K_PHONE, K_WINK );e> STATUS = DTK$$GET_STATUS( .VCB, RET_STATUS, %REF(K_TMO_SEC));+ IF NOT .STATUS THEN $DTK$RETURN (.STATUS); @ IF .RET_STATUS NEQ DTK$_OFFHOOK THEN $DTK$RETURN (.RET_STATUS); END;v !+ ! Speak any specified text.N !- IF NOT NULLPARAMETER(TEXT) THEN BEGIN- STATUS = DTK$SPEAK_TEXT( .VOICE_ID, .TEXT );E+ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);( END;R $DTK$RETURN (SS$_NORMAL); + END; ! End of routine DTK$DIAL_PHONE !U E-%SBTTL 'DTK$HANGUP_PHONE - Hangup the phone.'!GLOBAL ROUTINE DTK$HANGUP_PHONE (s VOICE_ID, TEXTa ) =!++U! FUNCTIONAL DESCRIPTION:! H! This routine will speak an optional message and then hangup the phone.!U!H! CALLING SEQUENCE:U! 4! ret_status.wlc.v = DTK$HANGUP_PHONE (VOICE_ID.rl.r! [,TEXT.rt.dx])S!N! FORMAL PARAMETERS:! +! VOICE_ID.rl.r Voice id of DECtalk deviceE!<! TEXT.rt.dx [OPTIONAL] Text to be spoken before hanging .! up the phone. Text will be followed-! by a sync command to make sure allI,! text is spoken before hanging up.! ! IMPLICIT INPUTS:! ! NONE!y! IMPLICIT OUTPUTS:e!l! NONE!b! COMPLETION STATUS:!d)! SS$_NORMAL Normal successful completiono! SS$_xxxx Any error from QIOW$h ! DTK$_INVVOIID Invalid voice id,! DTK$_WRONUMARG Wrong number of arguements.!e! SIDE EFFECTS: !o7! The phone is hungup after speaking any optional text.s!a!- BEGINu BUILTINt NULLPARAMETER;. LOCALA) STATUS, ! Status returned by routinesD RET_STATUS, ! Phone statusr7 VCB : REF $VCB_DECL; ! Address of voice control blockR ENABLE LIB$SIG_TO_RET;? $DTK$VALIDATE_ARGCOUNT (1, 2); ! Test for right no. of argsr7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCBo !+- ! Speak text before hanging up the phone.  !- IF NOT NULLPARAMETER(TEXT) THEN BEGIN? STATUS = DTK$SPEAK_TEXT( .VOICE_ID, .TEXT, %REF(DTK$K_WAIT) );f+ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);  END; !+ ! Hang up phone. !-4 $DTK$OUTPUT_DATA( DT_MISC2, K_PHONE, K_HANGUP );A STATUS = DTK$$GET_STATUS( .VCB, RET_STATUS, %REF(K_TMO_SEC));O. IF NOT .STATUS THEN $DTK$RETURN (.STATUS);B IF .RET_STATUS NEQ DTK$_ONHOOK THEN $DTK$RETURN (.RET_STATUS); VCB [VCB_V_WINK] = 0;O !+* ! Free the keypad input buffer string. !- IF .VCB[VCB_W_LENGTH] NEQ 0I THEN BEGIN. STATUS = STR$FREE1_DX(VCB[VCB_Q_INPUT_DESC]);+ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);t END;r $DTK$RETURN (SS$_NORMAL);r- END; ! End of routine DTK$HANGUP_PHONE !u -%SBTTL 'DTK$INITIALIZE - Initialize DECtalk.'nGLOBAL ROUTINE DTK$INITIALIZE (R NEW_VID, OUT_DEVICE,  DEVICE_TYPE  ) =V!++V! FUNCTIONAL DESCRIPTION:s! G! This routine creates a DECtalk device -- returning its assignedF5! voice_id. OUT_DEVICE is the device upon which thiss>! DECtalk is to be written. If not supplied, output will flow! to SYS$OUTPUT.!$9! If called upon to create a 2nd DECtalk on a device that,=! already has a voice_id associated with it, we simply return:! the id of the already-existing DECtalk and the qualified! success DTK$_VOIALREXI.N!K! CALLING SEQUENCE:D! ,! ret_status.wlc.v = DTK$INITIALIZE ( ! NEW_VOID.wl.r,! OUT_DEVICE.rt.dx_! [,DEVICE_TYPE.ml.r])Q! ! FORMAL PARAMETERS:!N=! NEW_VOID.wl.r Voice-id of newly-created DECtalk.N!A!! OUT_DEVICE.rt.dx This parametere)! is the file specification or logicalI*! name upon which the output associated'! with this DECtalk will be written.E!M>! DEVICE_TYPE.ml.r [Optional]. If specified, the DECtalk type1! is returned. DTK$K_DTC_01 for DECtalk I andn5! DTK$K_DTC_03 for DECtalk III. DTK$K_DTC_UNKNOWN-! if no response from DECtalk is recieved.I!l! IMPLICIT INPUTS:!M ! NONE![! IMPLICIT OUTPUTS: !T ! NONE! ! COMPLETION STATUS:!4! SS$_NORMAL Normal successful completion!! SS$_xxxx Any error from $GETDVIt!! RMS$_xxxx Any error from $PARSEO3! LIB$_xxxx Any error from LIB$GET_VM or LIB$GET_EFnN! LIB$_INSVIRMEM Insufficient virtual memory to allocate needed buffer.7! DTK$_VOIALREXI DECtalk already exists for this device.2! DTK$_WRONUMARG Wrong number of arguments.!a! SIDE EFFECTS:I!U ! NONE!--  b BEGINd BUILTINh NULLPARAMETER; LOCAL 8 NAME_DESC : $DTK$DESCRIPTOR, ! Fixed length descriptor) STATUS, ! Status returned by routiness+ IOSB : VECTOR[4,WORD], ! IOSB for $QIOWa6 FS_LEN : LONG INITIAL(0), ! Length of device name9 FS_ADDR : REF VECTOR[,BYTE], ! Address of device name_> BUFFER : VECTOR [K_BUFFER_LEN, BYTE], ! Input buffer A BUFFER_LEN : LONG INITIAL(0), ! Number of chars read into BUFFERm/ SEARCH_VCB : REF $VCB_DECL, ! Next VCB in listsL VCB : REF $VCB_DECL; ! Address of voice control block being created.? $DTK$VALIDATE_ARGCOUNT (2, 3); ! Test for right no. of argsD!+2! Decide what device is to receive the the output.!-G IF NOT (STATUS = LIB$ANALYZE_SDESC ( .OUT_DEVICE, FS_LEN, FS_ADDR))b THEN RETURN (.STATUS);!+>! Create the dynamic memory zone if none has been created yet.!- IF .DTK_A_ZONE_ID EQL 0U THEN BEGIN3 STATUS = LIB$CREATE_VM_ZONE( DTK_A_ZONE_ID,y" %REF(LIB$K_VM_FIRST_FIT), 0,E' %REF(LIB$M_VM_BOUNDARY_TAGS ORU LIB$M_VM_EXTEND_AREA) );n& IF NOT .STATUS THEN RETURN (.STATUS); END; !+<! Get the event flag number if it has not been done already.!- IF .DTK_L_EFN EQL 0L THEN BEGIN" STATUS = LIB$GET_EF( DTK_L_EFN );' IF NOT .STATUS THEN RETURN (.STATUS); e$ STATUS = LIB$GET_EF( DTK_L_EFN_2 );' IF NOT .STATUS THEN RETURN (.STATUS); KC DTK_L_EFN_MASK = 1 ^ (.DTK_L_EFN - 32) OR 1 ^ (.DTK_L_EFN_2 - 32); END;C!+'! Create a VCB. Allocate buffers, etc. ;! Extract the necessary device attributes and store in VCB.C!-( STATUS = DTK$$SETUP_TERMINAL_TYPE (  .FS_ADDR, ! filespec addr; .FS_LEN, ! Len of filespec0 VCB); ! Address to receive address of VCB) IF NOT .STATUS THEN RETURN (.STATUS);+!+3! If the device is not a terminal, return an error.F!-H IF .VCB[VCB_B_CLASS] NEQ DC$_TERM THEN $DTK$RETURN (DTK$_NOTLCLTRM);!+B! Loop thru all current VCBs looking for a match. If found, this K! device has been already allocated. Return an "already allocated" status.E!- SEARCH_VCB = .VCB_QUEUE; WHILE .SEARCH_VCB NEQ 0 DOD IF CH$EQL( .SEARCH_VCB[VCB_W_DEVNAM_LEN], SEARCH_VCB[VCB_T_DEVNAM],3 .VCB[VCB_W_DEVNAM_LEN], VCB[VCB_T_DEVNAM] )T THEN BEGINC STATUS = LIB$FREE_VM( %REF (VCB_K_SIZE), VCB, DTK_A_ZONE_ID );/ IF NOT .STATUS THEN $DTK$RETURN (.STATUS); " $DTK$RETURN (DTK$_VOIALREXI); END ELSEP* SEARCH_VCB = .SEARCH_VCB[VCB_A_NEXT];!+!! Insert this VCB into the queue.S!-! VCB[VCB_A_NEXT] = .VCB_QUEUE;e VCB_QUEUE = .VCB; !+#! Store voice-id in the VCB itself. !- VCB [VCB_L_VID] = .VCB; !+&! Return the new DECtalk id to caller.!- .NEW_VID = .VCB;!+C! Store the original name (that the user specified) for this deviceSI! in the VCB. This name may include a filename as well as a device name.t6! First we allocate virtual memory for this buffer andG! then we store the length and address in the VCB for future reference.I!-K STATUS = LIB$GET_VM( %REF(.FS_LEN), VCB[VCB_A_OUTNAM], DTK_A_ZONE_ID );o. IF NOT .STATUS THEN $DTK$RETURN (.STATUS);$ VCB[VCB_W_OUTNAM_LEN] = .FS_LEN;3 CH$MOVE( .FS_LEN,.FS_ADDR,.VCB[VCB_A_OUTNAM] );)!+=! Create a fixed length descriptor for our device name string ! for use by $ASSIGN.r!-- NAME_DESC[DSC$B_DTYPE] = DSC$K_DTYPE_T;- NAME_DESC[DSC$B_CLASS] = DSC$K_CLASS_S;r6 NAME_DESC[DSC$W_LENGTH] = .VCB[VCB_W_DEVNAM_LEN];2 NAME_DESC[DSC$A_POINTER] = VCB[VCB_T_DEVNAM];!+! Assign the channel.F6! Put the resulting channel number in VCB[VCB_W_CHAN].!- IF .VCB[VCB_W_CHAN] EQL 0  THEN BEGIN& STATUS = $ASSIGN( DEVNAM = NAME_DESC, CHAN = VCB[VCB_W_CHAN] );+ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);d END;!+K! The following line was added to solve a TTDRIVER problem. When the firstGI! output is done to the channel, no typeahead buffer has been set up yet. L! This results in the first character of the DA_PRIMARY response being lost.G! This only happens on high speed lines. The following line causes theEN! driver to set up a typeahead buffer before we do the first output operation.L! This must not be done on LAT lines however, since LAT needs a write as the?! first operation. If this is a LAT line, connect to the port.K!-O IF CH$FAIL(CH$FIND_SUB(.NAME_DESC[DSC$W_LENGTH], .NAME_DESC[DSC$A_POINTER],% 2, UPLIT('LT'))) THEN' $QIOW( CHAN = .VCB[VCB_W_CHAN],H EFN = .DTK_L_EFN,U8 FUNC = IO$_READVBLK OR IO$M_ESCAPE OR IO$M_TIMED OR3 IO$M_NOECHO OR IO$M_TRMNOECHO OR IO$M_PURGE,N IOSB = IOSB, P1 = BUFFER, P2 = K_BUFFER_LEN, P3 = 0)U ELSE BEGIN) STATUS = $QIOW( CHAN = .VCB[VCB_W_CHAN],  EFN = .DTK_L_EFN,* FUNC = IO$_TTY_PORT OR IO$M_LT_CONNECT, IOSB = IOSB);, IF NOT .STATUS THEN $DTK$RETURN (.STATUS);- IF NOT .IOSB[0] THEN $DTK$RETURN (.IOSB[0]);D END;H!+(! Change the terminal characteristics to/! NOBROADCAST no broadcast messages are spoken, *! TTSYNC CTRL/S and CTRL/Q work correctly,B! ANSICRT escape sequences are interperted by the terminal driver.=! NOWRAP don't generate an extra at the end of the line. !-0 STATUS = DTK$$SET_TERM_CHARACTERISTICS(.VCB,' TT$M_NOBRDCST OR TT$M_TTSYNC, ! on  TT2$M_ANSICRT, ! on TT$M_WRAP ); ! offE. IF NOT .STATUS THEN $DTK$RETURN (.STATUS);!+:! Set up our exit block which is contained within the VCB.:! This exit block is used to establish an exit handler for1! this terminal. When the exit handler is called,DG! it will flush the output buffers, reset the terminal characteristics,U%! and make sure the phone is hung up.HK! This guarantees that the user will get all his output and the device will +! be left in the same state as we found it.a!-2 VCB [VCB_A_EXIT_ADDR] = DTK$$VCB_EXIT_HANDLER;" ! Address of our exit handlerD VCB [VCB_B_EXIT_ARGCNT] = 2; ! Our exit handler gets called with ! two arguments.3 VCB [VCB_A_EXIT_RSN] = VCB [VCB_L_EXIT_REASON];f( ! The first argument is the address% ! of the longword to receive theh* ! exit reason. This longword appears# ! elsewhere in the VCB (not in ! the exit block).E VCB [VCB_A_EXIT_VCB] = .VCB; ! The second argument is the address # ! of this VCB. This is needed& ! because there are many VCBs and( ! one exit routine serves them all.) ! There is a separate exit block forD ! each VCB.!+@! Establish the exit handler, using the exit block just created.!-7 STATUS = $DCLEXH( DESBLK = VCB[VCB_R_EXIT_BLOCK] ); . IF NOT .STATUS THEN $DTK$RETURN (.STATUS);!+A! Setup our status queues and the keypad input string descriptor.O!-8 VCB [VCB_L_STATUS_FLINK] = VCB [VCB_L_STATUS_FLINK];8 VCB [VCB_L_STATUS_BLINK] = VCB [VCB_L_STATUS_FLINK];< VCB [VCB_L_HDWR_STS_FLINK] = VCB [VCB_L_HDWR_STS_FLINK];< VCB [VCB_L_HDWR_STS_BLINK] = VCB [VCB_L_HDWR_STS_FLINK];& VCB [VCB_B_CLASS] = DSC$K_CLASS_D;& VCB [VCB_B_DTYPE] = DSC$K_DTYPE_T;!+(! Determine if this is a DTC01 or DTC03.!-1 $DTK$BUFFERING_ON(VCB); ! Turn on bufferingS. $DTK$OUTPUT_DATA( DECSTR ); ! soft reset. $DTK$OUTPUT_DATA( S7C1T ); ! 7 bit codes7 $DTK$OUTPUT_DATA( DT_MISC2, K_MASK, 0 ); ! mask offs? $DTK$OUTPUT_DATA( DA_PRIMARY ); ! request type of terminalt3 $DTK$BUFFERING_OFF(VCB); ! Turn off bufferingg!+C! Read back the sequence that tells us what type of device this is.G@! Use a timeout so we don't hang if the device does not respond.!-E STATUS = DTK$$INPUT( .VCB, BUFFER_LEN, BUFFER, %REF(K_TMO_SEC) );g6 IF CH$EQL(K_DTC01_LEN, DTC01, K_DTC01_LEN, BUFFER) THEN$ VCB [VCB_B_DEVTYPE] = DTK$K_DTC_01;6 IF CH$EQL(K_DTC03_LEN, DTC03, K_DTC03_LEN, BUFFER) THEN$ VCB [VCB_B_DEVTYPE] = DTK$K_DTC_03; IF .STATUS EQL SS$_TIMEOUT THEN) VCB [VCB_B_DEVTYPE] = DTK$K_DTC_UNKNOWN;!+#! Return type to user if requested.G! If user requested a specific device type, force that type to be used. !-% IF NOT NULLPARAMETER(DEVICE_TYPE)  THEN IF ..DEVICE_TYPE NEQ 0t THEND( VCB [VCB_B_DEVTYPE] = ..DEVICE_TYPE ELSE ) .DEVICE_TYPE = .VCB [VCB_B_DEVTYPE];L!+%! Return the new DECtalk id to callerl!- .NEW_VID = .VCB; $DTK$RETURN (.STATUS);# END; ! Routine DTK$INITIALIZEP !+ G%SBTTL 'DTK$LOAD_DICTIONARY - Load a word into the DECtalk dictionary.'v$GLOBAL ROUTINE DTK$LOAD_DICTIONARY ( VOICE_ID, TEXT, SUBSTITUTIONn ) =!++! FUNCTIONAL DESCRIPTION: ! =! This routine will load a phonemic definition of a word intoe! the DECtalk dictionary.a!o! ! CALLING SEQUENCE:d!a9! ret_status.wlc.v = DTK$LOAD_DICTIONARY (VOICE_ID.rl.r, d! TEXT.rt.dx,! SUBSTITUTION.rt.dx)!! FORMAL PARAMETERS:!N+! VOICE_ID.rl.r Voice id of DECtalk devicet!s.! TEXT.rt.dx Word to load into the dictionary! 1! SUBSTITUTION.rt.dx Phonemic definition for WORD ! ! IMPLICIT INPUTS:!! NONE!_! IMPLICIT OUTPUTS:i!f! NONE!t! COMPLETION STATUS:!E)! SS$_NORMAL Normal successful completione,! DTK$_WRONUMARG Wrong number of arguements. ! DTK$_INVVOIID Invalid voice id3! DTK$_NOROOM No room in dictionary to add the wordl)! DTK$_TOOLON Word definition is too longy!! SIDE EFFECTS: !K9! The specified word is stored in the DECtalk dictionary. !.!--$ T BEGIN LOCALs) STATUS, ! Status returned by routinesL" RET_STATUS, ! Dictionary status% TEXT_LEN : LONG INITIAL(0), ! Length( TEXT_ADDR: REF VECTOR[,BYTE], ! Address7 VCB : REF $VCB_DECL; ! Address of voice control blocke? $DTK$VALIDATE_ARGCOUNT (3, 3); ! Test for right no. of args 7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCBS !+4 ! Verify input parameters are valid descriptors. !-M IF NOT (STATUS = LIB$ANALYZE_SDESC ( .SUBSTITUTION, TEXT_LEN, TEXT_ADDR))u THEN $DTK$RETURN (.STATUS);CG IF NOT (STATUS = LIB$ANALYZE_SDESC ( .TEXT, TEXT_LEN, TEXT_ADDR ) )R THEN $DTK$RETURN (.STATUS);K !+. ! Send word definition sequence to DECtalk ! and get returned status. !-6 $DTK$OUTPUT_DATA( DT_DICT, .TEXT, .SUBSTITUTION );A STATUS = DTK$$GET_STATUS( .VCB, RET_STATUS, %REF(K_TMO_SEC));e. IF NOT .STATUS THEN $DTK$RETURN (.STATUS); $DTK$RETURN (.RET_STATUS);0 END; ! End of routine DTK$LOAD_DICTIONARY !m S7%SBTTL 'DTK$NOT_IMPLEMENTED - For adding new routines.' $GLOBAL ROUTINE DTK$NOT_IMPLEMENTED =!++o! FUNCTIONAL DESCRIPTION: !D6! This routine returns a NOT_IMPLEMENTED error status.!! CALLING SEQUENCE:e!e2! ret_status.wlc.v = DTK$NOT_IMPLEMENTED ( )!=! FORMAL PARAMETERS:!_! None!L! IMPLICIT INPUTS:!N ! None!S! IMPLICIT OUTPUTS:e!n ! None!i! COMPLETION STATUS:!e&! DTK$_NOTIMP Routine not implemented! ! SIDE EFFECTS: ! ! NONE!--_ BEGINK RETURN (DTK$_NOTIMP);I/ END; ! End of routine DTK$NOT_IMPLEMENTED$ !A O&%SBTTL 'DTK$OUTPUT - Output raw text.'GLOBAL ROUTINE DTK$OUTPUT( VOICE_ID, TEXT ) =!++h! FUNCTIONAL DESCRIPTION:a!o:! This routine will output the specified text without any 2! parsing. This is for internal DIGITAL use only!:! DTK$SPEAK_TEXT is the general routine and should be used! instead of this one.!S!U! CALLING SEQUENCE:S!K/! ret_status.wlc.v = DTK$OUTPUT (VOICE_ID.rl.r,^! TEXT.rt.dx)!D! FORMAL PARAMETERS:! +! VOICE_ID.rl.r Voice id of DECtalk devices! ! TEXT.rt.dx Text to output.V!C! IMPLICIT INPUTS:!$! NONE!N! IMPLICIT OUTPUTS:R! ! NONE!c! COMPLETION STATUS:!L)! SS$_NORMAL Normal successful completione! SS$_xxxx Any error from QIOW$T ! DTK$_INVVOIID Invalid voice id,! DTK$_WRONUMARG Wrong number of arguements.!n! SIDE EFFECTS: !F! The specified text is output.H!$!- U BEGINT LOCAL+) STATUS, ! Status returned by routinesa TEXT_LEN : LONG INITIAL(0), TEXT_ADDR: REF VECTOR[,BYTE],7 VCB : REF $VCB_DECL; ! Address of voice control blockH? $DTK$VALIDATE_ARGCOUNT (2, 2); ! Test for right no. of argsS7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCB  !+( ! Verify input parameters are valid. !-E IF NOT (STATUS = LIB$ANALYZE_SDESC ( .TEXT, TEXT_LEN, TEXT_ADDR))_ THEN $DTK$RETURN (.STATUS);T8 STATUS = DTK$$OUTPUT( .VCB, .TEXT_LEN, .TEXT_ADDR );. IF NOT .STATUS THEN $DTK$RETURN (.STATUS); $DTK$RETURN (SS$_NORMAL);C' END; ! End of routine DTK$OUTPUTE !E ?%SBTTL 'DTK$READ_KEYSTROKE - Read a key entered on the keypad.' #GLOBAL ROUTINE DTK$READ_KEYSTROKE ( VOICE_ID, KEY_CODE, PROMPT, TIMEOUT ) =!++N! FUNCTIONAL DESCRIPTION:r!h:! This routine will read a key entered on the phone keypad-! after speaking any optional prompt message. !w! ! CALLING SEQUENCE: !s9! ret_status.wlc.v = DTK$READ_KEYSTROKE (VOICE_ID.rl.r, ! KEY_CODE.wl.r! [,PROMPT.rt.dx]! [,TIMEOUT.rl.r]) !T! FORMAL PARAMETERS:!F+! VOICE_ID.rl.r Voice id of DECtalk device! 4! KEY_CODE.wl.r DTK$K_TRM_xxxx code for key entered!_?! PROMPT.rt.dx Optional text to speak before waiting for inputA!T<! TIMEOUT.rl.r Optional number of seconds to wait for input! ! IMPLICIT INPUTS:! ! NONE!r! IMPLICIT OUTPUTS:[!$! NONE!=! COMPLETION STATUS:!E)! SS$_NORMAL Normal successful completion ! SS$_xxxx Any error from QIOW$C ! DTK$_INVVOIID Invalid voice id,! DTK$_WRONUMARG Wrong number of arguements.)! DTK$_ONHOOK Phone is onhook (inactive).n ! DTK$_WINK A wink has occurred.!! SIDE EFFECTS:_!N.! The key entered on the phone keypad is read.!A!--A D BEGINC BUILTIN_ NULLPARAMETER;O LOCALN) STATUS, ! Status returned by routinesh RET_STATUS, ! Phone statuso7 VCB : REF $VCB_DECL; ! Address of voice control blocke ENABLE LIB$SIG_TO_RET;? $DTK$VALIDATE_ARGCOUNT (2, 4); ! Test for right no. of args 7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCBn !+* ! Check to see if a WINK has occurred. !- IF .VCB [VCB_V_WINK] THEN w BEGIN VCB [VCB_V_WINK] = 0; $DTK$RETURN (DTK$_WINK);n END;n !++ ! Send phone status sequence to DECtalkr, ! to be sure the phone is still offhook. !-4 $DTK$OUTPUT_DATA( DT_MISC2, K_PHONE, K_STATUS );B STATUS = DTK$$GET_STATUS( .VCB, RET_STATUS, %REF(K_TMO_SEC) );. IF NOT .STATUS THEN $DTK$RETURN (.STATUS);C IF .RET_STATUS NEQ DTK$_OFFHOO_3;~ DTKALPHA.SAVA [DIETER.DTKALPHA]DTKUTIL.B32;1P )9|RK THEN $DTK$RETURN (.RET_STATUS); !+. ! If keypad is not enabled, enable it now. !- IF NOT .VCB[VCB_V_KEYPAD_ON] THEN BEGIND STATUS = DTK$SET_KEYPAD_MODE( .VOICE_ID, %REF(DTK$K_KEYPAD_AUTO) );6 IF .STATUS NEQ SS$_NORMAL THEN $DTK$RETURN (.STATUS); END; !+. ! If a prompt was specified, speak it now. !- IF NOT NULLPARAMETER(PROMPT) THEN BEGIN/ STATUS = DTK$SPEAK_TEXT( .VOICE_ID, .PROMPT ); + IF NOT .STATUS THEN $DTK$RETURN (.STATUS);  END;Y !+ ! Get users keypad input. I !- IF .VCB [VCB_W_LENGTH] NEQ 0 THEN RET_STATUS = SS$_NORMAL ELSE$ RET_STATUS = DTK$$GET_STATUS( .VCB, 0,( (IF NOT NULLPARAMETER(TIMEOUT)# THEN .TIMEOUT ELSE 0) );  !+2 ! If this is a DECtalk I, we need to simulate - ! AUTOSTOP mode if the user specified it.1 IF (.VCB[VCB_B_DEVTYPE] EQL DTK$K_DTC_01) AND  .VCB[VCB_V_AUTOSTOP]  THEN BEGIN% $DTK$OUTPUT_DATA( DT_MISC, K_STOP );.' VCB [VCB_B_SPEECH_MODES] = DTK$K_HALT;w END;s !+* ! Check to see if a WINK has occurred. !- IF .VCB [VCB_V_WINK] THEN  BEGIN VCB [VCB_V_WINK] = 0; $DTK$RETURN (DTK$_WINK);h END;e !+ ! Return the key entered.  !-" IF .RET_STATUS EQL SS$_TIMEOUT THEN .KEY_CODE = DTK$K_TRM_TIMEOUT ELSE+ .KEY_CODE = CH$RCHAR(.VCB[VCB_A_POINTER]);r !+< ! Remove the first character in the keypad input string. !-P STATUS = STR$RIGHT( VCB[VCB_Q_INPUT_DESC], VCB[VCB_Q_INPUT_DESC], %REF(2) );- IF NOT .STATUS THEN $DTK$RETURN(.STATUS);  !+ ! Done. !- $DTK$RETURN (.RET_STATUS);. END; ! End of routine DTK$READ_KEYSTROKE !c I%SBTTL 'DTK$READ_STRING - Read a sequence of keys entered on the keypad.'u GLOBAL ROUTINE DTK$READ_STRING ( VOICE_ID, OUT_STRING, PROMPT, TIMEOUT,e TERM_CODE ) =!++ ! FUNCTIONAL DESCRIPTION:+! E! This routine will read a series of keys entered on the phone keypad -! after speaking any optional prompt message.C!)!! CALLING SEQUENCE:E!D5! ret_status.wlc.v = DTK$READ_STRING (VOICE_ID.rl.r, n! OUT_STRING.wt.dx! [,PROMPT.rt.dx]V! [,TIMEOUT.rl.r]C! [,KEY_CODE.wl.r])V!L! FORMAL PARAMETERS:!_+! VOICE_ID.rl.r Voice id of DECtalk deviceL!]@! OUT_STRING.wt.dx String into which is written the keys pressed![9! PROMPT.rt.dx [OPTIONAL] Text to speak before waiting S! for input!B?! TIMEOUT.rl.r [OPTIONAL] Number of seconds to wait for input !0A! TERM_CODE.wl.r [OPTIONAL] DTK$K_TRM_xxxx code for terminating ! key entered.E!R! IMPLICIT INPUTS:! ! NONE!_! IMPLICIT OUTPUTS:b!c! NONE!D! COMPLETION STATUS:! )! SS$_NORMAL Normal successful completionA! SS$_xxxx Any error from QIOW$ ! DTK$_INVVOIID Invalid voice id,! DTK$_WRONUMARG Wrong number of arguements.)! DTK$_ONHOOK Phone is onhook (inactive).e ! DTK$_WINK A wink has occurred.! ! SIDE EFFECTS:i!h7! A series of keys entered on the phone keypad is read.(!C!--F _ BEGIN, BUILTIN) NULLPARAMETER;$ LOCALE; TERM_SET : $DTK$DESCRIPTOR ! Descriptor for terminator set] PRESET(# [DSC$B_CLASS] = DSC$K_CLASS_S,3# [DSC$B_DTYPE] = DSC$K_DTYPE_T,B [DSC$W_LENGTH] = 2,D/ [DSC$A_POINTER] = UPLIT(BYTE(%C'*',%C'#'))),N) STATUS, ! Status returned by routines RET_STATUS, ! Phone statusf2 TERM_CHAR_POS, ! Terminating character position5 LEN : LONG INITIAL(0), ! Length of sequence enteredL7 VCB : REF $VCB_DECL; ! Address of voice control block  ENABLE LIB$SIG_TO_RET;? $DTK$VALIDATE_ARGCOUNT (2, 5); ! Test for right no. of argsT7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCB !+* ! Check to see if a WINK has occurred. !- IF .VCB [VCB_V_WINK] THEN A BEGIN VCB [VCB_V_WINK] = 0; $DTK$RETURN (DTK$_WINK);e END;k !++ ! Send phone status sequence to DECtalkV, ! to be sure the phone is still offhook. !-4 $DTK$OUTPUT_DATA( DT_MISC2, K_PHONE, K_STATUS );B STATUS = DTK$$GET_STATUS( .VCB, RET_STATUS, %REF(K_TMO_SEC) );. IF NOT .STATUS THEN $DTK$RETURN (.STATUS);C IF .RET_STATUS NEQ DTK$_OFFHOOK THEN $DTK$RETURN (.RET_STATUS);T !+. ! If keypad is not enabled, enable it now. !- IF NOT .VCB[VCB_V_KEYPAD_ON] THEN BEGIND STATUS = DTK$SET_KEYPAD_MODE( .VOICE_ID, %REF(DTK$K_KEYPAD_AUTO) );6 IF .STATUS NEQ SS$_NORMAL THEN $DTK$RETURN (.STATUS); END;T !+. ! If a prompt was specified, speak it now. !- IF NOT NULLPARAMETER(PROMPT) THEN BEGIN/ STATUS = DTK$SPEAK_TEXT( .VOICE_ID, .PROMPT ); + IF NOT .STATUS THEN $DTK$RETURN (.STATUS);d END;r !+ ! Get users keypad input. n !- RET_STATUS = SS$_NORMAL;K TERM_CHAR_POS = STR$FIND_FIRST_IN_SET(VCB[VCB_Q_INPUT_DESC], TERM_SET); ! WHILE .TERM_CHAR_POS EQL 0 DOe BEGIN$ RET_STATUS = DTK$$GET_STATUS( .VCB, 0,( (IF NOT NULLPARAMETER(TIMEOUT)# THEN .TIMEOUT ELSE 0) );R. IF .RET_STATUS EQL SS$_TIMEOUT THEN EXITLOOP;$ IF .VCB [VCB_V_WINK] THEN EXITLOOP;2 IF NOT .RET_STATUS THEN $DTK$RETURN(.RET_STATUS);H TERM_CHAR_POS = STR$FIND_FIRST_IN_SET(VCB[VCB_Q_INPUT_DESC], TERM_SET); END;  !+B ! If this is a DECtalk I, we need to simulate AUTOSTOP mode if ! the user specified it. !-1 IF (.VCB[VCB_B_DEVTYPE] EQL DTK$K_DTC_01) ANDA .VCB[VCB_V_AUTOSTOP]T THEN BEGIN% $DTK$OUTPUT_DATA( DT_MISC, K_STOP );' VCB [VCB_B_SPEECH_MODES] = DTK$K_HALT;e END;D !+* ! Check to see if a WINK has occurred. !- IF .VCB [VCB_V_WINK] THEN  BEGIN VCB [VCB_V_WINK] = 0; $DTK$RETURN (DTK$_WINK);K END;C !+& ! Find length of character string. !-# LEN = (IF .TERM_CHAR_POS EQL 0 ; THEN .VCB[VCB_W_LENGTH]  ELSE .TERM_CHAR_POS - 1 ); !+) ! Return the terminating key entered.. !-# IF NOT NULLPARAMETER(TERM_CODE) THEN IF .RET_STATUS EQL SS$_TIMEOUTi THENr# .TERM_CODE = DTK$K_TRM_TIMEOUT ELSEL* .TERM_CODE = (IF .TERM_CHAR_POS EQL 0 THEN DTK$K_TRM_BUFFER_FULL 8 ELSE CH$RCHAR(CH$PLUS(.VCB[VCB_A_POINTER], .LEN))); !+) ! Copy the input to the users string.  !-E STATUS = LIB$SCOPY_R_DX( LEN, .VCB[VCB_A_POINTER], .OUT_STRING ); . IF NOT .STATUS THEN $DTK$RETURN (.STATUS); !+: ! Remove the users input from our keypad input buffer., ! Also remove the terminator if entered. !-9 LEN = .LEN + (IF .TERM_CHAR_POS EQL 0 THEN 1 ELSE 2);K STATUS = STR$RIGHT( VCB[VCB_Q_INPUT_DESC], VCB[VCB_Q_INPUT_DESC], LEN);t !+ ! Done.h !- $DTK$RETURN (.RET_STATUS);+ END; ! End of routine DTK$READ_STRINGe !  u:%SBTTL 'DTK$RETURN_LAST_INDEX - Return last index spoken.'&GLOBAL ROUTINE DTK$RETURN_LAST_INDEX ( VOICE_ID, INDEX ) =!++E! FUNCTIONAL DESCRIPTION:R!T1! This routine will return the last index spoken.c!!! CALLING SEQUENCE: !p:! ret_status.wlc.v = DTK$RETURN_LAST_INDEX (VOICE_ID.rl.r,! INDEX.wl.r)!O! FORMAL PARAMETERS:!S+! VOICE_ID.rl.r Voice id of DECtalk device_!x$! INDEX.wl.r Index to be returned. !n! IMPLICIT INPUTS:!W! NONE!o! IMPLICIT OUTPUTS:t!! NONE!E! COMPLETION STATUS:!f)! SS$_NORMAL Normal successful completionT! SS$_xxxx Any error from QIOW$t ! DTK$_INVVOIID Invalid voice id,! DTK$_WRONUMARG Wrong number of arguements.!E! SIDE EFFECTS:C!E$! The last spoken index is returned.!!- K BEGINR LOCAL;) STATUS, ! Status returned by routinesT7 VCB : REF $VCB_DECL; ! Address of voice control block ? $DTK$VALIDATE_ARGCOUNT (2, 2); ! Test for right no. of argsS7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCB  !+* ! Send index query sequence to DECtalk ! and get returned value.D !-/ $DTK$OUTPUT_DATA( DT_MISC, K_INDEX_QUERY ); > STATUS = DTK$$GET_STATUS( .VCB, .INDEX, %REF(K_TMO_SEC) );. IF NOT .STATUS THEN $DTK$RETURN (.STATUS);@ .INDEX = .VCB [VCB_W_LAST_INDEX]; ! Return last index spoken $DTK$RETURN (SS$_NORMAL);,2 END; ! End of routine DTK$RETURN_LAST_INDEX !  s2%SBTTL 'DTK$RUN_SELF_TEST - Run local self-tests.'"GLOBAL ROUTINE DTK$RUN_SELF_TEST ( VOICE_ID, P_MODE ) =!++U! FUNCTIONAL DESCRIPTION:c!=>! This routine will run the specified DECtalk local self-test.! !P! CALLING SEQUENCE:[!M6! ret_status.wlc.v = DTK$RUN_SELF_TEST (VOICE_ID.rl.r,! P_MODE.rl.r)!c! FORMAL PARAMETERS:!D+! VOICE_ID.rl.r Voice id of DECtalk deviceM!r6! P_MODE.rl.r Self-test to be run. Valid values are:! DTK$K_TEST_POWER! DTK$K_TEST_HDATA! DTK$K_TEST_HCONTROLL! DTK$K_TEST_DATAE! DTK$K_TEST_SPEAK!! IMPLICIT INPUTS:!E! NONE!:! IMPLICIT OUTPUTS:r! ! NONE!c! COMPLETION STATUS:!y)! SS$_NORMAL Normal successful completion ! SS$_xxxx Any error from QIOW$n ! DTK$_INVVOIID Invalid voice id,! DTK$_WRONUMARG Wrong number of arguements.! DTK$_INVARG Invalid argument.F!S! SIDE EFFECTS: !e!! The specified self-test is run.A!-!- BEGIN BIND MODE = .P_MODE; LOCALA) STATUS, ! Status returned by routinese$ TEST_NUM, ! Number of test to run7 VCB : REF $VCB_DECL; ! Address of voice control block? $DTK$VALIDATE_ARGCOUNT (2, 2); ! Test for right no. of argsT7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCBV SELECTONE .MODE OF  SET0 [DTK$K_TEST_POWER] : TEST_NUM = K_TST_POWER;0 [DTK$K_TEST_HDATA] : TEST_NUM = K_TST_HDATA;3 [DTK$K_TEST_HCONTROL] : TEST_NUM = K_TST_HCONTROL;/ [DTK$K_TEST_DATA] : TEST_NUM = K_TST_DATA;e0 [DTK$K_TEST_SPEAK] : TEST_NUM = K_TST_SPEAK;3 [OTHERWISE] : $DTK$RETURN (DTK$_INVARG);_ TES;S !+) ! Send self-test sequence to DECtalk.T !-* $DTK$OUTPUT_DATA( DECTST, .TEST_NUM ); !+ ! Wait for the test to run.D !-- STATUS = LIB$WAIT( %REF( K_2_SECONDS ) ); . IF NOT .STATUS THEN $DTK$RETURN (.STATUS);- STATUS = LIB$WAIT( %REF( K_2_SECONDS ) );N. IF NOT .STATUS THEN $DTK$RETURN (.STATUS);- STATUS = LIB$WAIT( %REF( K_2_SECONDS ) );S. IF NOT .STATUS THEN $DTK$RETURN (.STATUS); $DTK$RETURN (SS$_NORMAL);c& END; ! routine DTK$RUN_SELF_TEST !P P=%SBTTL 'DTK$SET_INDEX - Insert an index at current position.'MGLOBAL ROUTINE DTK$SET_INDEX ( VOICE_ID, P_INDEX ) =!++ ! FUNCTIONAL DESCRIPTION:i!tA! This routine will insert an index in the current output stream.A! !S! CALLING SEQUENCE:R!S2! ret_status.wlc.v = DTK$SET_INDEX (VOICE_ID.rl.r,! P_INDEX.rl.r)E!I! FORMAL PARAMETERS:!T+! VOICE_ID.rl.r Voice id of DECtalk device !a@! P_INDEX.rl.r Index to be inserted. Allowed value is 1-32767.0! An index of 0 is reserved for internal use.!$! IMPLICIT INPUTS:!C! NONE!P! IMPLICIT OUTPUTS:!T! NONE!T! COMPLETION STATUS:!V)! SS$_NORMAL Normal successful completionD! SS$_xxxx Any error from QIOW$i ! DTK$_INVVOIID Invalid voice id,! DTK$_WRONUMARG Wrong number of arguements.! DTK$_INVARG Invalid argument.U!(! SIDE EFFECTS:D!1! The specified index is inserted in the current ! position in the output stream.! !- BEGIN= BIND INDEX = .P_INDEX; LOCAL$) STATUS, ! Status returned by routines 7 VCB : REF $VCB_DECL; ! Address of voice control block? $DTK$VALIDATE_ARGCOUNT (2, 2); ! Test for right no. of argsI7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCBR !+. ! Index value must be between 1 and 32767. !-K IF (.INDEX LSS 1) OR (.INDEX GTR 32767) THEN $DTK$RETURN (DTK$_INVARG);  !+% ! Send index sequence to DECtalk.y !-2 $DTK$OUTPUT_DATA( DT_MISC2, K_INDEX, .INDEX ); $DTK$RETURN (SS$_NORMAL);," END; ! routine DTK$SET_INDEX !D R<%SBTTL 'DTK$SET_KEYPAD_MODE - Turn the phone keypad on/off.'$GLOBAL ROUTINE DTK$SET_KEYPAD_MODE ( VOICE_ID, MODEm ) =!++! FUNCTIONAL DESCRIPTION:E!DC! This routine turns recognition of the telephone keypad on or off.U!T!G! CALLING SEQUENCE:R!T9! ret_status.wlc.v = DTK$SET_KEYPAD_MODE (VOICE_ID.rl.r, w! MODE.rl.r)L!R! FORMAL PARAMETERS:!r+! VOICE_ID.rl.r Voice id of DECtalk deviceT!G3! MODE.rl.r DTK$K_KEYPAD_ON to turn the keypad on,%! DTK$K_KEYPAD_OFF to turn it off, 4! DTK$K_KEYPAD_AUTO to turn it on with auto-stop.!r! IMPLICIT INPUTS:! ! NONE!w! IMPLICIT OUTPUTS: !M! NONE! ! COMPLETION STATUS:!x)! SS$_NORMAL Normal successful completion,! DTK$_WRONUMARG Wrong number of arguements. ! DTK$_INVVOIID Invalid voice id! DTK$_ONHOOK Phone is onhookO&! DTK$_INVMODE Invalid mode specified. ! DTK$_WINK A wink has occurred.!I! SIDE EFFECTS:o! 6! Recognition of the phone keypad is turned on or off.!H!--h BEGINi BUILTINT NULLPARAMETER;s LOCAL ) STATUS, ! Status returned by routinese+ RET_STATUS, ! Status returned by DECtalkF7 VCB : REF $VCB_DECL; ! Address of voice control block ? $DTK$VALIDATE_ARGCOUNT (2, 2); ! Test for right no. of args]7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCB[ !+, ! Check for mode and then send sequence. !- SELECTONE ..MODE OF( SET# [DTK$K_KEYPAD_ON]: BEGIN4 $DTK$OUTPUT_DATA( DT_MISC2, K_PHONE, K_KEYPAD_ON ); VCB [VCB_V_KEYPAD_ON] = 1;h VCB [VCB_V_AUTOSTOP] = 0;  END;( [DTK$K_KEYPAD_OFF]:n BEGIN5 $DTK$OUTPUT_DATA( DT_MISC2, K_PHONE, K_KEYPAD_OFF );  VCB [VCB_V_KEYPAD_ON] = 0;; VCB [VCB_V_AUTOSTOP] = 0;T END;; [DTK$K_KEYPAD_AUTO]: BEGIN) IF .VCB [VCB_B_DEVTYPE] EQL DTK$K_DTC_01o THEN BEGIN8 $DTK$OUTPUT_DATA( DT_MISC2, K_PHONE, K_KEYPAD_ON ); END ELSE] BEGIN: $DTK$OUTPUT_DATA( DT_MISC2, K_PHONE, K_KEYPAD_AUTO ); END; VCB [VCB_V_KEYPAD_ON] = 1;  VCB [VCB_V_AUTOSTOP] = 1;o END;t [OTHERWISE]: $DTK$RETURN (DTK$_INVMODE); TES; !+ ! Read status response.T !-A STATUS = DTK$$GET_STATUS( .VCB, RET_STATUS, %REF(K_TMO_SEC));S. IF NOT .STATUS THEN $DTK$RETURN (.STATUS);B IF .RET_STATUS EQL DTK$_OFFHOOK THEN $DTK$RETURN (SS$_NORMAL); !+B ! Something happened to the phone connection. Assume the user ! has hungup.B !- VCB [VCB_V_OFFHOOK] = 0; VCB [VCB_V_KEYPAD_ON] = 0; VCB [VCB_V_AUTOSTOP] = 0; VCB [VCB_V_WINK] = 0; $DTK$RETURN (.RET_STATUS);0 END; ! End of routine DTK$SET_KEYPAD_MODE !) O%SBTTL 'DTK$SET_LOGGING_MODE - Set the specified mode on the DECtalk terminal.' %GLOBAL ROUTINE DTK$SET_LOGGING_MODE ( VOICE_ID, NEW_MODE, OLD_MODEt ) =!++! FUNCTIONAL DESCRIPTION:A!I! This routine sets or resets the specified mode on the DECtalk terminal.)!;! The last two parameters are optional. First, if OLD_MODE B! is supplied, it is filled in with the current mode bit settings.6! Secondly, if the NEW_MODE parameter is provided, its<! contents are used to set the current mode(s) of operation.! 8! Hence this routine can typically be used in three way.#! a). To find out current settings:_/! DTK$SET_LOGGING_MODE ( VOICE_ID, , OLD_MODE)!D?! b). To set the bits with no regard for their current setting:U-! DTK$SET_LOGGING_MODE ( VOICE_ID, NEW_MODE) !-9! c). To write modular code, saving the current settings,C7! setting them to your desired setting, then restoringD3! original settings before exiting your procedure:_$! DTK$SET_LOGGING_MODE ( VOICE_ID, #! NEW_MODE, saved_mode_bits )-! and before exiting,5! DTK$SET_LOGGING_MODE ( VOICE_ID, saved_mode_bits )$!U! CALLING SEQUENCE:D!8! ret_status.wlc.v = DTK$SET_LOGGING_MODE (VOICE_ID.rl.r! [,NEW_MODE.rl.r]! [,OLD_MODE.wl.r])[!_! FORMAL PARAMETERS:!M,! VOICE_ID.rl.r Voice id of DECtalk device.!i;! NEW_MODE.rl.r DECtalk mode to be set. Valid values are:_! DTK$M_TEXT! DTK$M_PHONEMES! DTK$M_RAWHOST ! DTK$M_INHOST! DTK$M_OUTHOSTL! DTK$M_ERROR ! DTK$M_TRACEE! DTK$M_DEBUG$2! These values may be OR'd together to set more5! than one mode at a time. Any mode not specifiedt! is reset.!g<! OLD_MODE.wl.r [OPTIONAL]. If specified, recieves the old3! mode settings in effect before setting the newR ! ones.! IMPLICIT INPUTS:!e! NONE!e! IMPLICIT OUTPUTS:p!i! NONE!.! COMPLETION STATUS:!e)! SS$_NORMAL Normal successful completionL,! DTK$_WRONUMARG Wrong number of arguements. ! DTK$_INVVOIID Invalid voice id&! DTK$_INVMODE Invalid mode specified.!)! SIDE EFFECTS: !oC! The specified modes are set on the device. All others are reset. !t!--T E BEGIN BUILTIN NULLPARAMETER;E LOCALE) STATUS, ! Status returned by routinesI7 VCB : REF $VCB_DECL; ! Address of voice control block+? $DTK$VALIDATE_ARGCOUNT (2, 3); ! Test for right no. of argsl7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCBe !+3 ! If user asked for old modes, return them now.  !-N IF NOT NULLPARAMETER(OLD_MODE) THEN .OLD_MODE = .VCB [VCB_B_MODE_LOGGING]; !+' ! Set new mode values if specified.M !-" IF NOT NULLPARAMETER(NEW_MODE) THEN BEGIN !+  ! Only allow legal modes. !-M= IF .(.NEW_MODE)<8,24> NEQ 0 THEN $DTK$RETURN (DTK$_INVMODE);t !+$ ! Output sequence to set mode.$ !-U1 $DTK$OUTPUT_DATA( DT_MISC2, K_LOG, ..NEW_MODE );C !+  ! Remember the new mode.t !-.' VCB [VCB_B_MODE_LOGGING] = ..NEW_MODE;A END;  $DTK$RETURN (SS$_NORMAL);B0 END; ! end of routine DTK$SET_LOGGING_MODE !L TG%SBTTL 'DTK$SET_MODE - Set the specified mode on the DECtalk terminal.'EGLOBAL ROUTINE DTK$SET_MODE ( VOICE_ID, NEW_MODE, OLD_MODEs ) =!++C! FUNCTIONAL DESCRIPTION:d!lI! This routine sets or resets the specified mode on the DECtalk terminal.T!=;! The last two parameters are optional. First, if OLD_MODETB! is supplied, it is filled in with the current mode bit settings.6! Secondly, if the NEW_MODE parameter is provided, its<! contents are used to set the current mode(s) of operation.! 8! Hence this routine can typically be used in three way.#! a). To find out current settings:R'! DTK$SET_MODE ( VOICE_ID, , OLD_MODE)=!?! b). To set the bits with no regard for their current setting: %! DTK$SET_MODE ( VOICE_ID, NEW_MODE)!9! c). To write modular code, saving the current settings,_7! setting them to your desired setting, then restoringM3! original settings before exiting your procedure:a! DTK$SET_MODE ( VOICE_ID, #! NEW_MODE, saved_mode_bits )r! and before exiting,-! DTK$SET_MODE ( VOICE_ID, saved_mode_bits )O!O! CALLING SEQUENCE:D!E0! ret_status.wlc.v = DTK$SET_MODE (VOICE_ID.rl.r! [,NEW_MODE.rl.r]T! [,OLD_MODE.wl.r])! ! FORMAL PARAMETERS:! ,! VOICE_ID.rl.r Voice id of DECtalk device.!x;! NEW_MODE.rl.r DECtalk mode to be set. Valid values are: ! DTK$M_SQUARE! DTK$M_ASCIIt! DTK$M_MINUSn! DTK$M_EUROPE! DTK$M_SPELL2! These values may be OR'd together to set more5! than one mode at a time. Any mode not specified! is reset.!s<! OLD_MODE.wl.r [OPTIONAL]. If specified, recieves the old3! mode settings in effect before setting the newc ! ones.! IMPLICIT INPUTS:!,! NONE! ! IMPLICIT OUTPUTS:T! ! NONE!V! COMPLETION STATUS:!t)! SS$_NORMAL Normal successful completion,! DTK$_WRONUMARG Wrong number of arguements. ! DTK$_INVVOIID Invalid voice id&! DTK$_INVMODE Invalid mode specified.!H! SIDE EFFECTS:U! C! The specified modes are set on the device. All others are reset.[!$!--T E BEGINS BUILTINP NULLPARAMETER;] LOCAL$) STATUS, ! Status returned by routines 7 VCB : REF $VCB_DECL; ! Address of voice control block? $DTK$VALIDATE_ARGCOUNT (2, 3); ! Test for right no. of argsr7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCB( !+3 ! If user asked for old modes, return them now.S !-O IF NOT NULLPARAMETER(OLD_MODE) THEN .OLD_MODE = .VCB [VCB_W_MODE_SETTINGS];. !+' ! Set new mode values if specified.S !-" IF NOT NULLPARAMETER(NEW_MODE) THEN BEGIN !+R ! Only allow legal modes. !-r= IF .(.NEW_MODE)<6,26> NEQ 0 THEN $DTK$RETURN (DTK$_INVMODE);E !+e ! Output sequence to set mode.M !-B2 $DTK$OUTPUT_DATA( DT_MISC2, K_MODE, ..NEW_MODE ); !+  ! Remember the new mode.i !-( VCB [VCB_W_MODE_SETTINGS] = ..NEW_MODE; END;t $DTK$RETURN (SS$_NORMAL);E( END; ! end of routine DTK$SET_MODE !r ,9%SBTTL 'DTK$SET_SPEECH_MODE - Set speech mode on or off.'O$GLOBAL ROUTINE DTK$SET_SPEECH_MODE ( VOICE_ID, NEW_MODE, OLD_MODE  ) =!++l! FUNCTIONAL DESCRIPTION: ! <! This routine will start or stop the DECtalk from speaking.!!! CALLING SEQUENCE:T!T9! ret_status.wlc.v = DTK$SET_SPEECH_MODE (VOICE_ID.rl.r, M! NEW_MODE.rl.r! [,OLD_MODE.wl.r])!r! FORMAL PARAMETERS:!V+! VOICE_ID.rl.r Voice id of DECtalk deviceg!m@! NEW_MODE.rl.r Indicates which mode to set. Valid values are: ! DTK$K_SPEAK start speaking(! DTK$K_STOP stop speaking when done)! DTK$K_HALT stop speaking immedatelyI!@! OLD_MODE.wl.r [OPTIONAL]. If specified, recieves the current0! mode setting before setting the new modes. %! Values are the same as NEW_MODE.D!V! IMPLICIT INPUTS:!;! NONE! ! IMPLICIT OUTPUTS: !D! NONE!(! COMPLETION STATUS:!d)! SS$_NORMAL Normal successful completionu ! DTK$_INVVOIID Invalid voice id,! DTK$_WRONUMARG Wrong number of arguements.&! DTK$_INVMODE Invalid mode specified.!+! SIDE EFFECTS:x!q.! The specified starts or stops speaking text.! !--S BEGINN BUILTIND NULLPARAMETER;R LOCAL ) STATUS, ! Status returned by routinesE7 VCB : REF $VCB_DECL; ! Address of voice control blocka? $DTK$VALIDATE_ARGCOUNT (2, 3); ! Test for right no. of argsm7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCBu !+2 ! Select sequence to send based on mode value. !- SELECTONE ..NEW_MODE OFt SETv [DTK$K_SPEAK]: !+_- ! Begin speaking by sending DT_SPEAK_ENABLE.R !-R BEGIN1 $DTK$OUTPUT_DATA( DT_MISC2, K_SPEAK, K_ENABLE );O END;  [DTK$K_STOP]:u !+k* ! Stop speaking after all text is spoken  ! by sending DT_SPEAK_DISABLE.  !-i BEGIN2 $DTK$OUTPUT_DATA( DT_MISC2, K_SPEAK, K_DISABLE ); END;C [DTK$K_HALT]:O !+/ ! Stop speaking immedately by sending DT_STOP.c !-l BEGIN% $DTK$OUTPUT_DATA( DT_MISC, K_STOP );g END;. [OTHERWISE]: $DTK$RETURN (DTK$_INVMODE); TES; !+3 ! If user asked for old modes, return them now.k !-N IF NOT NULLPARAMETER(OLD_MODE) THEN .OLD_MODE = .VCB [VCB_B_SPEECH_MODES]; !+ ! Remember the new mode. !-* VCB [VCB_B_SPEECH_MODES] = ..NEW_MODE; $DTK$RETURN (SS$_NORMAL);R/ END; ! end of routine DTK$SET_SPEECH_MODER !! dP%SBTTL 'DTK$SET_TERMINAL_MODE - Set the specified mode on the DECtalk terminal.'&GLOBAL ROUTINE DTK$SET_TERMINAL_MODE ( VOICE_ID, NEW_MODE, OLD_MODE ) =!++ ! FUNCTIONAL DESCRIPTION:d!qI! This routine sets or resets the specified mode on the DECtalk terminal.N!;! The last two parameters are optional. First, if OLD_MODEB! is supplied, it is filled in with the current mode bit settings.6! Secondly, if the NEW_MODE parameter is provided, its<! contents are used to set the current mode(s) of operation.! 8! Hence this routine can typically be used in three way.#! a). To find out current settings:T'! DTK$SET_MODE ( VOICE_ID, , OLD_MODE)N! ?! b). To set the bits with no regard for their current setting:%! DTK$SET_MODE ( VOICE_ID, NEW_MODE)T!D9! c). To write modular code, saving the current settings,_7! setting them to your desired setting, then restoringt3! original settings before exiting your procedure:! DTK$SET_MODE ( VOICE_ID, #! NEW_MODE, saved_mode_bits )T! and before exiting,-! DTK$SET_MODE ( VOICE_ID, saved_mode_bits ).!T! CALLING SEQUENCE:.!T9! ret_status.wlc.v = DTK$SET_TERMINAL_MODE (VOICE_ID.rl.r(! [,NEW_MODE.rl.r] ! [,OLD_MODE.wl.r])!n! FORMAL PARAMETERS:! ,! VOICE_ID.rl.r Voice id of DECtalk device.!V;! NEW_MODE.rl.r DECtalk mode to be set. Valid values are:B! DTK$M_HOST! DTK$M_SPEAKN! DTK$M_EDITED! DTK$M_HARD! DTK$M_SETUP;! DTK$M_FILTER2! These values may be OR'd together to set more5! than one mode at a time. Any mode not specifieda! is reset.!B<! OLD_MODE.wl.r [OPTIONAL]. If specified, recieves the old3! mode settings in effect before setting the new ! ones.! IMPLICIT INPUTS:! ! NONE!o! IMPLICIT OUTPUTS:m!l! NONE!h! COMPLETION STATUS:! )! SS$_NORMAL Normal successful completione,! DTK$_WRONUMARG Wrong number of arguements. ! DTK$_INVVOIID Invalid voice id&! DTK$_INVMODE Invalid mode specified.!a! SIDE EFFECTS:e!rC! The specified modes are set on the device. All others are reset. !d!--h BEGIN BUILTINr NULLPARAMETER; LOCALI) STATUS, ! Status returned by routines 7 VCB : REF $VCB_DECL; ! Address of voice control blockU? $DTK$VALIDATE_ARGCOUNT (2, 3); ! Test for right no. of argse7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCBt !+3 ! If user asked for old modes, return them now.n !-O IF NOT NULLPARAMETER(OLD_MODE) THEN .OLD_MODE = .VCB [VCB_B_MODE_TERMINAL];  !+' ! Set new mode values if specified.S !-" IF NOT NULLPARAMETER(NEW_MODE) THEN BEGIN !+D ! Only allow legal modes. !-T= IF .(.NEW_MODE)<7,25> NEQ 0 THEN $DTK$RETURN (DTK$_INVMODE);, !+E ! Output sequence to set mode.: !-6 $DTK$OUTPUT_DATA( DT_MISC2, K_TERMINAL, ..NEW_MODE ); !+  ! Remember the new mode.a !-a( VCB [VCB_B_MODE_TERMINAL] = ..NEW_MODE; END;  $DTK$RETURN (SS$_NORMAL);N1 END; ! end of routine DTK$SET_TERMINAL_MODE !  3%SBTTL 'DTK$SET_VOICE - Set voice characteristics.'tGLOBAL ROUTINE DTK$SET_VOICE ( VOICE_ID, NEW_VOICE,p SPEECH_RATE,i COMMA_PAUSE, PEROID_PAUSE[ ) =!++f! FUNCTIONAL DESCRIPTION:d! C! This routine will change the DECtalk voice characteristics to theL! ones specified. !E!e! CALLING SEQUENCE:p!i1! ret_status.wlc.v = DTK$SET_VOICE (VOICE_ID.rl.rL! [,NEW_VOICE.rl.r]o! [,SPEECH_RATE.rl.r]m! [,COMMA_PAUSE.rl.r]V! [,PEROID_PAUSE.rl.r])I!O! FORMAL PARAMETERS:!.+! VOICE_ID.rl.r Voice id of DECtalk deviceo! >! NEW_VOICE.rl.r [OPTIONAL] Voice to use. Valid values are:,! DTK$K_VOICE_MALE standard male voice0! DTK$K_VOICE_FEMALE standard female voice.! DTK$K_VOICE_CHILD standard child voice-! DTK$K_VOICE_DEEP_MALE deep male voice,1! DTK$K_VOICE_DEEP_FEMALE deep female voiceB0! DTK$K_VOICE_OLDER_MALE older male voice2! DTK$K_VOICE_LIGHT_FEMALE light female voice!B! SPEECH_RATE.rl.r [OPTIONAL] Rate at which to speak in words per'! minute. Valid range is 120-350. ! ?! COMMA_PAUSE.rl.r [OPTIONAL] Number of milliseconds to pause W! after a comma. ! !@! PEROID_PAUSE.rl.r [OPTIONAL] Number of milliseconds to pause ! after a peroid. ! !!! IMPLICIT INPUTS:!e! NONE!!! IMPLICIT OUTPUTS:T!D! NONE!L! COMPLETION STATUS:! *! SS$_NORMAL Normal successful completion.! SS$_xxxx Any error from QIO$.A!! DTK$_INVVOIID Invalid voice id.N,! DTK$_WRONUMARG Wrong number of arguements. ! DTK$_INVARG Invalid arguement.'! OTS$_xxxx Any error from OTS$CVT_L_TUd!d! SIDE EFFECTS:t!i.! The specified voice characteristics are set.!!- D BEGIND LITERALC K_RATE_LEN = 4, K_VOICE_LEN = 3;h BUILTIN  NULLPARAMETER;c LOCAL ) STATUS, ! Status returned by routinesp2 TEMP : VECTOR[4 + K_RATE_LEN, BYTE] VOLATILE,% TEXT : VECTOR[4, BYTE] VOLATILE,nD TEXT_DSC : $DTK$DESCRIPTOR ! Descriptor for DTK$SPEAK_PHONEMIC_TEXT PRESET(# [DSC$B_DTYPE] = DSC$K_DTYPE_T,(# [DSC$B_CLASS] = DSC$K_CLASS_S,u [DSC$W_LENGTH] = 4,d [DSC$A_POINTER] = TEXT ),A TEMP_DSC : $DTK$DESCRIPTOR ! Descriptor for setting speech rates PRESET(# [DSC$B_DTYPE] = DSC$K_DTYPE_T,r# [DSC$B_CLASS] = DSC$K_CLASS_S,C$ [DSC$W_LENGTH] = 4 + K_RATE_LEN, [DSC$A_POINTER] = TEMP ),; VCB : REF $VCB_DECL; ! Address of voice control blocke !+6 ! Validate the arguements and get the VCB address. !-? $DTK$VALIDATE_ARGCOUNT (1, 5); ! Test for right no. of argsf7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCB  !+ ! Set new voice. !-# IF NOT NULLPARAMETER(NEW_VOICE)l THEN BEGIN SELECTONE ..NEW_VOICE OF  SET [DTK$K_VOICE_MALE]:3 CH$MOVE( K_VOICE_LEN, UPLIT(BYTE(':np')), TEXT ); [DTK$K_VOICE_FEMALE]:3 CH$MOVE( K_VOICE_LEN, UPLIT(BYTE(':nb')), TEXT );Q [DTK$K_VOICE_CHILD]:3 CH$MOVE( K_VOICE_LEN, UPLIT(BYTE(':nk')), TEXT );P [DTK$K_VOICE_DEEP_MALE]:e3 CH$MOVE( K_VOICE_LEN, UPLIT(BYTE(':nh')), TEXT );i [DTK$K_VOICE_OLDER_MALE]:3 CH$MOVE( K_VOICE_LEN, UPLIT(BYTE(':nf')), TEXT );s [DTK$K_VOICE_DEEP_FEMALE]: 3 CH$MOVE( K_VOICE_LEN, UPLIT(BYTE(':nr')), TEXT );  [DTK$K_VOICE_LIGHT_FEMALE]:3 CH$MOVE( K_VOICE_LEN, UPLIT(BYTE(':nu')), TEXT );O [OTHERWISE]: $DTK$RETURN (DTK$_INVARG); TES;l !+B ! Now that the descriptor is set up, call DTK$SPEAK_PHONEMIC_TEXT2 ! to set the voice and remember new voice in VCB. !- ' TEXT_DSC [DSC$W_LENGTH] = K_VOICE_LEN;r9 STATUS = DTK$SPEAK_PHONEMIC_TEXT( .VOICE_ID, TEXT_DSC ); + IF NOT .STATUS THEN $DTK$RETURN (.STATUS);& VCB [VCB_B_CURR_VOICE] = ..NEW_VOICE; END;e !+ ! Set new speaking rate. !-% IF NOT NULLPARAMETER(SPEECH_RATE)T THEN BEGIN !+ 2 ! DECtalk only allows a rate between 120 and 350. !-d IF (..SPEECH_RATE LSS 120) OR e (..SPEECH_RATE GTR 350)  THENw $DTK$RETURN (DTK$_INVARG);M !+DI ! The rate command wants the rate as text chars so convert the parametere !-e' TEXT_DSC [DSC$W_LENGTH] = K_RATE_LEN;T1 STATUS = OTS$CVT_L_TU( .SPEECH_RATE, TEXT_DSC );!+ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);M !+2D ! Copy the entire command into buffer and call SPEAK_PHONEMIC_TEXT  ! to send the command. T !-P4 CH$COPY( K_RATE_LEN, UPLIT(BYTE(':ra ')), ! From= .TEXT_DSC[DSC$W_LENGTH], .TEXT_DSC[DSC$A_POINTER], ! FromW %C' ', ! Fill< .TEMP_DSC[DSC$W_LENGTH], .TEMP_DSC[DSC$A_POINTER] ); ! To9 STATUS = DTK$SPEAK_PHONEMIC_TEXT( .VOICE_ID, TEMP_DSC );e+ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);K END;C !+ ! Set comma pause rate.M !-% IF NOT NULLPARAMETER(COMMA_PAUSE)  THEN BEGIN !+r+ ! Only allowed rate is between 0 and 9999. !-L IF (..COMMA_PAUSE LSS 0) OR w (..COMMA_PAUSE GTR 9(~ DTKALPHA.SAVA [DIETER.DTKALPHA]DTKUTIL.B32;1P |999) THENr $DTK$RETURN (DTK$_INVARG);  !+DI ! The rate command wants the rate as text chars so convert the parameterC !-d' TEXT_DSC [DSC$W_LENGTH] = K_RATE_LEN;h1 STATUS = OTS$CVT_L_TU( .COMMA_PAUSE, TEXT_DSC );t+ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);w !+eD ! Copy the entire command into buffer and call SPEAK_PHONEMIC_TEXT  ! to send the command. i !-t+ CH$COPY( K_RATE_LEN, UPLIT(BYTE(':cp ')), e6 .TEXT_DSC[DSC$W_LENGTH], .TEXT_DSC[DSC$A_POINTER], %C' ',T7 .TEMP_DSC[DSC$W_LENGTH], .TEMP_DSC[DSC$A_POINTER] );E9 STATUS = DTK$SPEAK_PHONEMIC_TEXT( .VOICE_ID, TEMP_DSC );l+ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);d END;W !+ ! Set new peroid pause rate. !-& IF NOT NULLPARAMETER(PEROID_PAUSE) THEN BEGIN !+ + ! Only allowed rate is between 0 and 9999. !-E IF (..PEROID_PAUSE LSS 0) OR  (..PEROID_PAUSE GTR 9999)  THENs $DTK$RETURN (DTK$_INVARG);F !+EI ! The rate command wants the rate as text chars so convert the parameter; !-s' TEXT_DSC [DSC$W_LENGTH] = K_RATE_LEN;(2 STATUS = OTS$CVT_L_TU( .PEROID_PAUSE, TEXT_DSC );+ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);. !+-D ! Copy the entire command into buffer and call SPEAK_PHONEMIC_TEXT  ! to send the command. n !-D+ CH$COPY( K_RATE_LEN, UPLIT(BYTE(':pp ')), D6 .TEXT_DSC[DSC$W_LENGTH], .TEXT_DSC[DSC$A_POINTER], %C' ',7 .TEMP_DSC[DSC$W_LENGTH], .TEMP_DSC[DSC$A_POINTER] ); 9 STATUS = DTK$SPEAK_PHONEMIC_TEXT( .VOICE_ID, TEMP_DSC );(+ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);  END;H $DTK$RETURN (SS$_NORMAL);i* END; ! End of routine DTK$SET_VOICE !D (7%SBTTL 'DTK$SPEAK_FILE - Speak text in specified file.'EGLOBAL ROUTINE DTK$SPEAK_FILE ( VOICE_ID, FILESPEC, MODEo ) =!++r! FUNCTIONAL DESCRIPTION:! C! This routine will speak the text contained in the specified file.D!;!! CALLING SEQUENCE:r!e3! ret_status.wlc.v = DTK$SPEAK_FILE (VOICE_ID.rl.r,.! FILESPEC.rt.dxT! [,MODE.rl.r])!N! FORMAL PARAMETERS:!$+! VOICE_ID.rl.r Voice id of DECtalk device'!$3! FILESPEC.rt.dx File containing text to be spokent! *! MODE.rl.r [OPTIONAL] Valid values are:2! DTK$K_IMMED to return to the user immedately.! (default)1! DTK$K_WAIT to wait until text is completely ! spoken.4! DTK$K_STATUS same as DTK$K_WAIT but also return! a phone status.f!D! IMPLICIT INPUTS:!i! NONE! ! IMPLICIT OUTPUTS:o!b! NONE!.! COMPLETION STATUS:!M)! SS$_NORMAL Normal successful completiona! SS$_xxxx Any error from QIOW$)! RMS$_xxx Any error from RMSs ! DTK$_INVVOIID Invalid voice id,! DTK$_WRONUMARG Wrong number of arguements.&! DTK$_INVMODE Invalid mode specified.!N! SIDE EFFECTS:t!e+! The text in the specified file is spoken.g!!- SBEGIN BIND% K_SP_PTR = UPLIT( BYTE( K_SP ) );lBUILTINv NULLPARAMETER;LOCAL  RET_STATUS,y, STATUS, ! Status returned by routines RAB_STATUS, ! RAB statusp6 SPEAK_STATUS : INITIAL(SS$_NORMAL), ! Speak status> BUF_ADDR : VECTOR [NAM$C_MAXRSS, BYTE] VOLATILE, ! Buffer< FAB : $FAB_DECL VOLATILE, ! RMS File Attributes Block0 NAM : $NAM_DECL VOLATILE, ! RMS NAM block0 RAB : $RAB_DECL VOLATILE, ! RMS RAB block= FS_LEN : LONG INITIAL(0), ! Length of filespec name usedV@ FS_ADDR: REF VECTOR[,BYTE], ! Address of filespec name used1 VCB : REF $VCB_DECL; ! Get address of VCB A$DTK$VALIDATE_ARGCOUNT (2, 3); ! Test for right no. of parameters;$DTK$GET_VCB (.VOICE_ID, VCB);@IF NOT (STATUS = LIB$ANALYZE_SDESC (.FILESPEC, FS_LEN, FS_ADDR))THEN $DTK$RETURN (.STATUS);6IF .FS_LEN GTRU 255 THEN $DTK$RETURN (DTK$_FILTOOLON);!+! Initialize the FAB and RAB!-$FAB_INIT( FAB = FAB,h FAC = GET, NAM = NAM, FNA = .FS_ADDR,O FNS = .FS_LEN, ORG = SEQ, ! Sequential file+ FOP = SQO, ! Sequential operations onlys RAT = CR, ! Carriage control) RFM = VAR); ! Variable length recordsI$NAM_INIT( NAM = NAM,$ ESA = BUF_ADDR,d ESS = NAM$C_MAXRSS);$RAB_INIT( RAB = RAB,c FAB = FAB, UBF = BUF_ADDR,. USZ = NAM$C_MAXRSS,  RAC = SEQ); ! Sequential!+! Open the file for input! -STATUS = $OPEN (FAB=FAB); ! Open input file *IF NOT .STATUS THEN $DTK$RETURN (.STATUS);!+%! Connect a record stream to the file(!-STATUS = $CONNECT (RAB=RAB);IF NOT .STATUS BTHEN BEGIN; $CLOSE (FAB=FAB); $DTK$RETURN (.STATUS); END;!+!! First be sure SPEAK_MODE is on.F3! If this is a DTC03 in AUTOSTOP mode, always forceC8! SPEAK_MODE since we don't know if the user has already&! entered input from the phone keypad.!-1IF (.VCB [VCB_B_SPEECH_MODES] NEQ DTK$K_SPEAK) ORlD ((.VCB[VCB_B_DEVTYPE] NEQ DTK$K_DTC_01) AND .VCB[VCB_V_AUTOSTOP])THEN BEGIN,4 $DTK$OUTPUT_DATA( DT_MISC2, K_SPEAK, K_ENABLE );+ VCB [VCB_B_SPEECH_MODES] = DTK$K_SPEAK;M END;!+7! Loop thru all records in the file, speaking each one.I!-%WHILE (RAB_STATUS = $GET(RAB=RAB)) DOR BEGIN ! while loopN IF .RAB [RAB$W_RSZ] NEQ 0E THEN% BEGIN ! while records remain_ !+ / ! If this is a DECtalk I, we need to simulate S* ! AUTOSTOP mode if the user specified it. !-E. IF (.VCB[VCB_B_DEVTYPE] EQL DTK$K_DTC_01) AND .VCB[VCB_V_AUTOSTOP] AND  .VCB[VCB_V_OFFHOOK] THENC BEGIND SPEAK_STATUS = DTK$$SIM_AUTO(.VCB, .RAB [RAB$W_RSZ], BUF_ADDR); IF (NOT .SPEAK_STATUS) OR# (.VCB [VCB_W_LENGTH] NEQ 0)_ THEN EXITLOOP;P END ELSE  !+M ! Output the text. E !-E BEGIN@ SPEAK_STATUS=DTK$$OUTPUT(.VCB, .RAB [RAB$W_RSZ], BUF_ADDR);( IF NOT .SPEAK_STATUS THEN EXITLOOP; END;  !+v+ ! Output a blank after each line to force  ! it to be spoken correctly.M !- - SPEAK_STATUS=DTK$$OUTPUT(.VCB, 1, K_SP_PTR); 1 IF NOT .SPEAK_STATUS THEN $DTK$RETURN (.STATUS);  !+l/ ! Determine when we should return to the user.m !-o IF NOT NULLPARAMETER(MODE)L THENl SELECTONE ..MODE OF SET [DTK$K_IMMED]:e ;e [DTK$K_WAIT,  DTK$K_STATUS]: BEGINp !+r; ! Wait until text is completely spoken by sending .0 ! DT_SYNC and then requesting a status. !-r1 $DTK$OUTPUT_DATA( DT_MISC, K_SYNC );]9 $DTK$OUTPUT_DATA( DT_MISC2, K_PHONE, K_STATUS ); ; SPEAK_STATUS = DTK$$GET_STATUS( .VCB, RET_STATUS, O %REF(K_TMO_HR) );, IF NOT .SPEAK_STATUS THEN EXITLOOP;) IF .RET_STATUS NEQ DTK$_OFFHOOK f THEN BEGINn VCB [VCB_V_KEYPAD_ON] = 0; VCB [VCB_V_AUTOSTOP] = 0; VCB [VCB_V_WINK] = 0;A IF ..MODE EQL DTK$K_STATUS THEN SPEAK_STATUS = .RET_STATUS;h END; END;i [OTHERWISE]:- BEGIN  SPEAK_STATUS = DTK$_INVMODE; EXITLOOP;V END; TES; $ END; ! End of while records remain END; ! End of while looprSTATUS = $CLOSE (FAB=FAB);)IF NOT .STATUS THEN $DTK$RETURN(.STATUS); IF NOT .SPEAK_STATUSTHEN $DTK$RETURN (.SPEAK_STATUS) ELSE IF .RAB_STATUS EQL RMS$_EOF THEN $DTK$RETURN (SS$_NORMAL) ELSE" $DTK$RETURN (.RAB_STATUS);(END; ! End of routine DTK$SPEAK_FILE !M SE%SBTTL 'DTK$SPEAK_PHONEMIC_TEXT - Speak the specified phonemic text.'((GLOBAL ROUTINE DTK$SPEAK_PHONEMIC_TEXT ( VOICE_ID, TEXT, MODEA ) =!++S! FUNCTIONAL DESCRIPTION:E!7! This routine will send the specified phonemic text to!$! the DECtalk terminal to be spoken.!+! ! CALLING SEQUENCE:e!t=! ret_status.wlc.v = DTK$SPEAK_PHONEMIC_TEXT (VOICE_ID.rl.r, T! TEXT.rt.dxh! [,MODE.rl.r])!V! FORMAL PARAMETERS:!t,! VOICE_ID.rl.r Voice id of DECtalk device.!7! TEXT.rt.dx String descriptor of the phonemic text to! be spoken.O!.+! MODE.rl.r [OPTIONAL]. Valid values are:2! DTK$K_IMMED to return to the user immedately.! (default)_1! DTK$K_WAIT to wait until text is completely )! spoken.4! DTK$K_STATUS same as DTK$K_WAIT but also return! a phone status.[!$! IMPLICIT INPUTS:! ! NONE!V! IMPLICIT OUTPUTS:'!'! NONE!i! COMPLETION STATUS:!A)! SS$_NORMAL Normal successful completionn! SS$_xxxx Any error from $QIO.E ! DTK$_INVVOIID Invalid voice id,! DTK$_WRONUMARG Wrong number of arguements.&! DTK$_INVMODE Invalid mode specified.)! DTK$_ONHOOK Phone is onhook (inactive).W!]! SIDE EFFECTS: !K(! The specified phonemic text is spoken.! !--i r BEGIN  BIND" K_VT_PTR = UPLIT( BYTE( K_VT ) ); BUILTINn NULLPARAMETER; LOCAL_) STATUS, ! Status returned by routinesU TEXT_LEN : LONG INITIAL(0), TEXT_ADDR: REF VECTOR[,BYTE],7 VCB : REF $VCB_DECL; ! Address of voice control blockV? $DTK$VALIDATE_ARGCOUNT (2, 3); ! Test for right no. of argst7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCB  !+: ! Verify input parameter is a valid string descriptor. !-G IF NOT (STATUS = LIB$ANALYZE_SDESC ( .TEXT, TEXT_LEN, TEXT_ADDR ) ) THEN $DTK$RETURN (.STATUS); !+, ! Don't allow imbedded escape sequences. !-@ IF NOT CH$FAIL( CH$FIND_CH( .TEXT_LEN, .TEXT_ADDR, K_ESC ) ) THEN $DTK$RETURN (DTK$_STRTERESC);0 $DTK$BUFFERING_ON(VCB); ! Turn on buffering !+% ! First be sure SPEAK_MODE is on.f7 ! If this is a DTC03 in AUTOSTOP mode, always force < ! SPEAK_MODE since we don't know if the user has already* ! entered input from the phone keypad. !-5 IF (.VCB [VCB_B_SPEECH_MODES] NEQ DTK$K_SPEAK) ORWH ((.VCB[VCB_B_DEVTYPE] NEQ DTK$K_DTC_01) AND .VCB[VCB_V_AUTOSTOP]) THEN BEGIN1 $DTK$OUTPUT_DATA( DT_MISC2, K_SPEAK, K_ENABLE );A( VCB [VCB_B_SPEECH_MODES] = DTK$K_SPEAK; END;  !+N ! Output the text with a trailing ^K to force it to be spoken immediately. !-* $DTK$OUTPUT_DATA( DT_PHOTEXT, .TEXT );* STATUS=DTK$$OUTPUT(.VCB, 1, K_VT_PTR);. IF NOT .STATUS THEN $DTK$RETURN (.STATUS);2 $DTK$BUFFERING_OFF(VCB); ! Turn off buffering !+2 ! Determine when we should return to the user. !- IF NOT NULLPARAMETER(MODE) THEN SELECTONE ..MODE OF SET [DTK$K_IMMED]:T ;U [DTK$K_WAIT,  DTK$K_STATUS]: BEGIN LOCAL RET_STATUS;_ !+X7 ! Wait until text is completely spoken by sending L, ! DT_SYNC and then requesting a status. !- - $DTK$OUTPUT_DATA( DT_MISC, K_SYNC );D5 $DTK$OUTPUT_DATA( DT_MISC2, K_PHONE, K_STATUS );UB STATUS = DTK$$GET_STATUS( .VCB, RET_STATUS, %REF(K_TMO_HR) );/ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);% IF .RET_STATUS NEQ DTK$_OFFHOOK THEN  BEGINM VCB [VCB_V_KEYPAD_ON] = 0; VCB [VCB_V_AUTOSTOP] = 0; VCB [VCB_V_WINK] = 0;< IF ..MODE EQL DTK$K_STATUS THEN $DTK$RETURN (.RET_STATUS); END; END; [OTHERWISE]:( $DTK$RETURN (DTK$_INVMODE); TES;  $DTK$RETURN (SS$_NORMAL);o3 END; ! End of routine DTK$SPEAK_PHONEMIC_TEXT ! S%%SBTTL 'DTK$SPEAK_TEXT - Speak text.'XGLOBAL ROUTINE DTK$SPEAK_TEXT (T VOICE_ID, TEXT, MODE- ) =!++ ! FUNCTIONAL DESCRIPTION:a!c-! This routine will speak the specified text.d!n!!! CALLING SEQUENCE:E!N3! ret_status.wlc.v = DTK$SPEAK_TEXT (VOICE_ID.rl.r, ! TEXT.rt.dxE! [,MODE.rl.r])!D! FORMAL PARAMETERS:!S+! VOICE_ID.rl.r Voice id of DECtalk deviceH!M! TEXT.rt.dx Text to be spoken! +! MODE.rl.r [OPTIONAL]. Valid values are:E2! DTK$K_IMMED to return to the user immedately.! (default)e1! DTK$K_WAIT to wait until text is completely A! spoken.4! DTK$K_STATUS same as DTK$K_WAIT but also return! a phone status.E!! IMPLICIT INPUTS:! ! NONE!D! IMPLICIT OUTPUTS:h!r! NONE! ! COMPLETION STATUS:!i)! SS$_NORMAL Normal successful completionE! SS$_xxxx Any error from QIOW$= ! DTK$_INVVOIID Invalid voice id,! DTK$_WRONUMARG Wrong number of arguements.&! DTK$_INVMODE Invalid mode specified.)! DTK$_ONHOOK Phone is onhook (inactive).!I! SIDE EFFECTS:e!n! The specified text is spoken. !E!- [ BEGINV BUILTIN: NULLPARAMETER;D BIND" K_VT_PTR = UPLIT( BYTE( K_VT ) ); LOCALD) STATUS, ! Status returned by routines  TEXT_LEN : LONG INITIAL(0), TEXT_ADDR: REF VECTOR[,BYTE],7 VCB : REF $VCB_DECL; ! Address of voice control block:? $DTK$VALIDATE_ARGCOUNT (2, 3); ! Test for right no. of argsN7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCBG IF NOT (STATUS = LIB$ANALYZE_SDESC ( .TEXT, TEXT_LEN, TEXT_ADDR ) )V THEN $DTK$RETURN (.STATUS);U !+, ! Don't allow imbedded escape sequences. !-@ IF NOT CH$FAIL( CH$FIND_CH( .TEXT_LEN, .TEXT_ADDR, K_ESC ) ) THEN $DTK$RETURN (DTK$_STRTERESC);0 $DTK$BUFFERING_ON(VCB); ! Turn on buffering !+% ! First be sure SPEAK_MODE is on. 7 ! If this is a DTC03 in AUTOSTOP mode, always forceS< ! SPEAK_MODE since we don't know if the user has already* ! entered input from the phone keypad. !-5 IF (.VCB [VCB_B_SPEECH_MODES] NEQ DTK$K_SPEAK) OR,H ((.VCB[VCB_B_DEVTYPE] NEQ DTK$K_DTC_01) AND .VCB[VCB_V_AUTOSTOP]) THEN BEGIN1 $DTK$OUTPUT_DATA( DT_MISC2, K_SPEAK, K_ENABLE );L( VCB [VCB_B_SPEECH_MODES] = DTK$K_SPEAK; END; !+2 ! If this is a DECtalk I, we need to simulate - ! AUTOSTOP mode if the user specified it.o !-1 IF (.VCB[VCB_B_DEVTYPE] EQL DTK$K_DTC_01) AND  .VCB[VCB_V_AUTOSTOP] ANDB .VCB[VCB_V_OFFHOOK] THEN BEGIN/ $DTK$BUFFERING_OFF(VCB); ! Turn off bufferingN5 STATUS = DTK$$SIM_AUTO(.VCB, .TEXT_LEN, .TEXT_ADDR);$* IF NOT .STATUS THEN $DTK$RETURN(.STATUS); END ELSE !+ ! Output the text.  !-A BEGIN1 STATUS=DTK$$OUTPUT(.VCB, .TEXT_LEN, .TEXT_ADDR); + IF NOT .STATUS THEN $DTK$RETURN (.STATUS); / $DTK$BUFFERING_OFF(VCB); ! Turn off bufferingr END;r !+, ! Output a trailing ^K to force the text ! to be spoken immediately.R !-* STATUS=DTK$$OUTPUT(.VCB, 1, K_VT_PTR);. IF NOT .STATUS THEN $DTK$RETURN (.STATUS); !+2 ! Determine when we should return to the user. !- IF NOT NULLPARAMETER(MODE) THEN SELECTONE ..MODE OF SET [DTK$K_IMMED]:. ;S [DTK$K_WAIT,  DTK$K_STATUS]: BEGIN LOCAL RET_STATUS;B !+N7 ! Wait until text is completely spoken by sending , ! DT_SYNC and then requesting a status. !-r- $DTK$OUTPUT_DATA( DT_MISC, K_SYNC );O5 $DTK$OUTPUT_DATA( DT_MISC2, K_PHONE, K_STATUS );nB STATUS = DTK$$GET_STATUS( .VCB, RET_STATUS, %REF(K_TMO_HR) );/ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);)% IF .RET_STATUS NEQ DTK$_OFFHOOK D THEN  BEGIN_ VCB [VCB_V_KEYPAD_ON] = 0; VCB [VCB_V_AUTOSTOP] = 0; VCB [VCB_V_WINK] = 0;< IF ..MODE EQL DTK$K_STATUS THEN $DTK$RETURN (.RET_STATUS); END; END;n [OTHERWISE]:n $DTK$RETURN (DTK$_INVMODE); TES;T $DTK$RETURN (SS$_NORMAL);e+ END; ! End of routine DTK$SPEAK_TEXTN !  w%%SBTTL 'DTK$SPELL_TEXT - Spell text.'sGLOBAL ROUTINE DTK$SPELL_TEXT (a VOICE_ID, TEXT, MODEh ) =!++i! FUNCTIONAL DESCRIPTION:C!_1! This routine will spell out the specified text.O!P!N! CALLING SEQUENCE:F!O3! ret_status.wlc.v = DTK$SPELL_TEXT (VOICE_ID.rl.r,M! TEXT.rt.dx$! [,MODE.rl.r])!I! FORMAL PARAMETERS:!+! VOICE_ID.rl.r Voice id of DECtalk deviceE!$! TEXT.rt.dx Text to be spelled out!!+! MODE.rl.r [OPTIONAL]. Valid values are: 2! DTK$K_IMMED to return to the user immedately.! (default)D1! DTK$K_WAIT to wait until text is completely ! spelled out.u4! DTK$K_STATUS same as DTK$K_WAIT but also return! a phone status.!E! IMPLICIT INPUTS:!V! NONE!_! IMPLICIT OUTPUTS:K!A! NONE!T! COMPLETION STATUS:!!)! SS$_NORMAL Normal successful completionh! SS$_xxxx Any error from QIOW$A ! DTK$_INVVOIID Invalid voice id,! DTK$_WRONUMARG Wrong number of arguements.&! DTK$_INVMODE Invalid mode specified.)! DTK$_ONHOOK Phone is onhook (inactive). ! ! SIDE EFFECTS:t! $! The specified text is spelled out.!!!- C BEGINe BUILTINu NULLPARAMETER; BIND" K_VT_PTR = UPLIT( BYTE( K_VT ) ); LOCAL ) STATUS, ! Status returned by routinesT@ VM_PTR : REF VECTOR[,BYTE], ! VM containing the text to spell3 TEXT_LEN : LONG INITIAL(0), ! Length of users textK6 TEXT_ADDR: REF VECTOR[,BYTE], ! Address of users text+ UP_DESC : $DTK$DESCRIPTOR, ! Upcased text 7 VCB : REF $VCB_DECL; ! Address of voice control block]? $DTK$VALIDATE_ARGCOUNT (2, 3); ! Test for right no. of args_7 $DTK$GET_VCB (.VOICE_ID, VCB); ! Get address of VCB  $INIT_DYNDESC(UP_DESC);-( STATUS = STR$UPCASE(UP_DESC, .TEXT);. IF NOT .STATUS THEN $DTK$RETURN (.STATUS);I IF NOT (STATUS = LIB$ANALYZE_SDESC ( UP_DESC, TEXT_LEN, TEXT_ADDR ) )F THEN $DTK$RETURN (.STATUS);R !+, ! Don't allow imbedded escape sequences. !-@ IF NOT CH$FAIL( CH$FIND_CH( .TEXT_LEN, .TEXT_ADDR, K_ESC ) ) THEN $DTK$RETURN (DTK$_STRTERESC); !+E ! Allocate a buffer that is twice the length of the users string. !-D STATUS = LIB$GET_VM(%REF(2 * .TEXT_LEN), VM_PTR, DTK_A_ZONE_ID);. IF NOT .STATUS THEN $DTK$RETURN (.STATUS); !+; ! Copy the users string into the buffer just allocated,N. ! separating each character with a peroid. !-% INCR I FROM 0 TO .TEXT_LEN - 1 DOo, CH$COPY(1, CH$PLUS(.TEXT_ADDR, .I), ! From 1, UPLIT(BYTE(%C'.')), ! From 0, ! Fill% 2, CH$PLUS(.VM_PTR, .I * 2) ); ! To  !+ ! Turn on bufferingM !-0 $DTK$BUFFERING_ON(VCB); ! Turn on buffering !+% ! First be sure SPEAK_MODE is on. 7 ! If this is a DTC03 in AUTOSTOP mode, always force < ! SPEAK_MODE since we don't know if the user has already* ! entered input from the phone keypad. !-5 IF (.VCB [VCB_B_SPEECH_MODES] NEQ DTK$K_SPEAK) ORSH ((.VCB[VCB_B_DEVTYPE] NEQ DTK$K_DTC_01) AND .VCB[VCB_V_AUTOSTOP]) THEN BEGIN1 $DTK$OUTPUT_DATA( DT_MISC2, K_SPEAK, K_ENABLE );( VCB [VCB_B_SPEECH_MODES] = DTK$K_SPEAK; END;c !+; ! If this is a DECtalk I, we need to simulate AUTOSTOP n< ! mode if the user specified it and the phone is active. !-1 IF (.VCB[VCB_B_DEVTYPE] EQL DTK$K_DTC_01) ANDs .VCB[VCB_V_AUTOSTOP] AND  .VCB[VCB_V_OFFHOOK] THEN BEGIN/ $DTK$BUFFERING_OFF(VCB); ! Turn off buffering 6 STATUS = DTK$$SIM_AUTO(.VCB, 2 * .TEXT_LEN, .VM_PTR);* IF NOT .STATUS THEN $DTK$RETURN(.STATUS); END ELSE !+i ! Output the text.G !-I BEGIN2 STATUS=DTK$$OUTPUT(.VCB, 2 * .TEXT_LEN, .VM_PTR);+ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);V/ $DTK$BUFFERING_OFF(VCB); ! Turn off bufferingg END;D !+, ! Output a trailing ^K to force the text ! to be spoken immediately.r !-* STATUS=DTK$$OUTPUT(.VCB, 1, K_VT_PTR);. IF NOT .STATUS THEN $DTK$RETURN (.STATUS); !+ ! Free the buffer we used. !-E STATUS = LIB$FREE_VM(%REF(2 * .TEXT_LEN), VM_PTR, DTK_A_ZONE_ID);N. IF NOT .STATUS THEN $DTK$RETURN (.STATUS);# STATUS = STR$FREE1_DX(UP_DESC);S. IF NOT .STATUS THEN $DTK$RETURN (.STATUS); !+2 ! Determine when we should return to the user. !- IF NOT NULLPARAMETER(MODE) THEN SELECTONE ..MODE OF SET [DTK$K_IMMED]:i ;  [DTK$K_WAIT,  DTK$K_STATUS]: BEGIN LOCAL RET_STATUS;F !+_< ! Wait until text is completely spelled out by sending , ! DT_SYNC and then requesting a status. !-H- $DTK$OUTPUT_DATA( DT_MISC, K_SYNC ); 5 $DTK$OUTPUT_DATA( DT_MISC2, K_PHONE, K_STATUS );B STATUS = DTK$$GET_STATUS( .VCB, RET_STATUS, %REF(K_TMO_HR) );/ IF NOT .STATUS THEN $DTK$RETURN (.STATUS);T% IF .RET_STATUS NEQ DTK$_OFFHOOK T THEN  BEGIN1 VCB [VCB_V_KEYPAD_ON] = 0; VCB [VCB_V_AUTOSTOP] = 0; VCB [VCB_V_WINK] = 0;< IF ..MODE EQL DTK$K_STATUS THEN $DTK$RETURN (.RET_STATUS); END; END;u [OTHERWISE]: $DTK$RETURN (DTK$_INVMODE); TES;L $DTK$RETURN (SS$_NORMAL);_+ END; ! End of routine DTK$SPELL_TEXTS !N +%SBTTL 'DTK$TERMINATE - Terminate DECtalk.'W&GLOBAL ROUTINE DTK$TERMINATE ( VID ) =!++L! FUNCTIONAL DESCRIPTION:e!s5! This routine terminates all use of a given DECtalk.I5! It deallocates the voice control block and all its P@! substructures. It gets rid of the event flag and the channel 2! number. It removes any associated exit handler.!E! CALLING SEQUENCE: !I5! ret_status.wlc.v = DTK$TERMINATE ( VID.rl.r )!C! FORMAL PARAMETERS:!2! VID.rl.r Voice-id of DECtalk device.! ! IMPLICIT INPUTS:!$ ! NONE!K! IMPLICIT OUTPUTS:;! ! NONE!! COMPLETION STATUS:!T4! SS$_NORMAL Normal successful completion2! DTK$_WRONUMARG Wrong number of arguments.! SS$_xyz errors from $DASSGN1! LIB$_xyz errors from LIB$FREE_VM or LIB$FREE_EFB!R! SIDE EFFECTS:T! ! NONE!--X BEGINLOCAL+) STATUS, ! Status returned by routinesr/ SEARCH_VCB : REF $VCB_DECL, ! Next VCB in list 9 VCB : REF $VCB_DECL; ! Address of voice control block ENABLE LIB$SIG_TO_RET;;$DTK$VALIDATE_ARGCOUNT (1, 1); ! Test for right no. of args-$DTK$GET_VCB (.VID,VCB); ! Get address of VCBH!+@! Get rid of our exit handler. Ignore a no handler found error.!-3STATUS = $CANEXH( DESBLK = VCB[VCB_R_EXIT_BLOCK] );mLIF (NOT .STATUS) AND (.STATUS NEQ SS$_NOHANDLER) THEN $DTK$RETURN (.STATUS);!+2! If there is a channel assigned, deassign it now.4! This automatically cancels any I/O on the channel./! But first reset the terminal characteristics.r!-IF .VCB[VCB_W_CHAN] NEQ 0:" THEN BEGIN ! deassigning channel !+tC ! Call the exit handler to flush the buffer, hangup the phone, and & ! reset the terminal characteristics. !-t( STATUS = DTK$$VCB_EXIT_HANDLER(0,.VCB);- STATUS = $DASSGN( CHAN = .VCB[VCB_W_CHAN] ); 4 VCB[VCB_W_CHAN] = 0; ! just in case we get called& ! again after returning an error* IF NOT .STATUS THEN $DTK$RETURN (.STATUS) END; ! deassigning channelA!+&! Free the keypad input buffer string.!-IF .VCB[VCB_W_LENGTH] NEQ 0XTHEN BEGINR3 STATUS = STR$FREE1_DX( VCB[VCB_Q_INPUT_DESC] );t. IF NOT .STATUS THEN $DTK$RETURN (.STATUS); END;!+! Free the output filename.B!-IF .VCB[VCB_W_OUTNAM_LEN] NEQ 0THEN BEGIN ! freeing outname6 STATUS = LIB$FREE_VM( %REF (.VCB[VCB_W_OUTNAM_LEN] ), VCB[VCB_A_OUTNAM],  DTK_A_ZONE_ID );d VCB[VCB_W_OUTNAM_LEN] = 0;* IF NOT .STATUS THEN $DTK$RETURN (.STATUS) END; ! freeing outname !+-! Free the escape sequence capability buffer.E!-IF .VCB[VCB_A_CAP_BUFFER] NEQ 0 THEN BEGIN ! freeing buffer_5 STATUS = LIB$FREE_VM( %REF (VCB$K_LONGEST_SEQUENCE),a VCB[VCB_A_CAP_BUFFER],n DTK_A_ZONE_ID );r VCB[VCB_A_CAP_BUFFER] = 0;n* IF NOT .STATUS THEN $DTK$RETURN (.STATUS) END; ! freeing buffer!+! Free the output buffer..!-"IF .VCB[VCB_A_OUTPUT_BUFFER] NEQ 0THEN BEGIN ! freeing buffer8 STATUS = LIB$FREE_VM( %REF (.VCB[VCB_W_OUTPUT_BUFSIZ])," VCB[VCB_A_OUTPUT_BUFFER], DTK_A_ZONE_ID );  VCB[VCB_A_OUTPUT_BUFFER] = 0;* IF NOT .STATUS THEN $DTK$RETURN (.STATUS) END; ! freeing buffer!+O! Loop thru all current VCBs looking for a match. If found, remove from queue..!-SEARCH_VCB = VCB_QUEUE;BWHILE .SEARCH_VCB NEQ 0 DO' IF .SEARCH_VCB[VCB_A_NEXT] EQL .VCBT THEN BEGIN+ SEARCH_VCB[VCB_A_NEXT] = .VCB[VCB_A_NEXT];N EXITLOOP; END ELSE& SEARCH_VCB = .SEARCH_VCB[VCB_A_NEXT];!+! Now go free the VCB itself.O!-VCB [VCB_B_STRUCT_TYPE] = 0;DIF NOT (STATUS=LIB$FREE_VM (%REF (VCB_K_SIZE), VCB, DTK_A_ZONE_ID)) THEN T $DTK$RETURN (.STATUS); .VID = 0; RETURN (SS$_NORMAL);%END; ! End or routine DTK$TERMINATEi!*****************************! Start of internal routines.*!***************************** !; B%SBTTL 'DTK$$FLUSH_BUFFER - Flush all buffered output to terminal'%ROUTINE DTK$$FLUSH_BUFFER ( P_VCB ) =H!++S! FUNCTIONAL DESCRIPTION:!T?! This routine causes all output which has been buffered up butG5! not yet sent to the terminal, to be output at once. !i! CALLING SEQUENCE:s!e<! ret_status.wlc.v = DTK$$FLUSH_BUFFER ( P_VCB.rab.r )! ! FORMAL PARAMETERS:!D8! P_VCB.rab.r The voice control block address for which )! the flushing action is to take place. !$! IMPLICIT INPUTS:!S?! VCB[VCB_W_OUTPUT_BUFLEN] number of characters in bufferS2! VCB[VCB_W_OUTPUT_BUFFER] address of buffer! ! IMPLICIT OUTPUTS:C!VC! VCB[VCB_W_OUTPUT_BUFLEN] set to 0 (indicating buffer empty)]! ! COMPLETION STATUS:!T4! SS$_NORMAL Normal successful completion#! SS$_xyz errors from DTK$$OUTPUT.$!U! SIDE EFFECTS:;! ! NONE!--R RBEGINNBIND2 VCB = .P_VCB : $VCB_DECL, ! voice control block- OUTBUF = .VCB[VCB_A_OUTPUT_BUFFER] : VECTOR,l+ OUTLEN = VCB[VCB_W_OUTPUT_BUFLEN] : WORD;VLOCAL STATUS;!+$! Do nothing if the buffer is empty.!-*IF .OUTLEN EQL 0 THEN RETURN (SS$_NORMAL);!+! Output the buffer now.?! Save time by calling OUTPUT directly rather than DTK$$OUTPUT.7! (DTK$$OUTPUT would try to buffer the text up anyhow.)L!-$STATUS = OUTPUT(VCB,.OUTLEN,OUTBUF);%IF NOT .STATUS THEN RETURN (.STATUS);e!+$! Note that the buffer is now empty.!- OUTLEN = 0;sRETURN (SS$_NORMAL);)END; ! End of routine DTK$$FLUSH_BUFFERf !K W9%SBTTL 'DTK$$GET_STATUS - Get status reply from DECtalk.'tROUTINE DTK$$GET_STATUS (  P_VCB, P_RET_STATUS,n TIMEOUTh ) =t!++! FUNCTIONAL DESCRIPTION:!O6! This routine will read in the reply sequence sent by9! DECtalk, parse it, and return the necessary information! in RET_STATUS.!f! CALLING SEQUENCE:V!I1! ret_status.wlc.v = DTK$$GET_STATUS ( P_VCB.rl.rf! [,P_RET_STATUS.wl.r]! [,TIMEOUT.rl.r])!H! FORMAL PARAMETERS:!t!! P_VCB.rl.r Voice control block >! P_RET_STATUS.wl.r [OPTIONAL] Longword to recieve the status/! being reported by DECtalk. This may be a T/! status or a normal value depending on the ,!! reply being sent by DECtalk.0! If not specified, a call is being made from0! one of the DTK$$READ_xxxx routines to just .! read in a key. A status is not returned.!!=! TIMEOUT.rl.r [OPTIONAL] Timeout value to use for the QIOst! ! IMPLICIT INPUTS:! ! NONE!o! IMPLICIT OUTPUTS:]!! NONE!L! COMPLETION STATUS:!T)! SS$_NORMAL normal successful completionB! SS$_xxxx any error from $QIO! ! SIDE EFFECTS:_!D&! A status reply from DECtalk is read.!--D , BEGIN BUILTINS INSQUE, REMQUE, NULLPARAMETER;F LOCAL=C RET_STATUS : INITIAL(DTK$_UNKREPLY), ! Status read from DECtalkT) STATUS, ! Status returned by routines K FUNC_CODE : REF VECTOR[,BYTE],! Ptr to function code from esc sequenceTJ CURR_CHAR : REF VECTOR[,BYTE],! Ptr to current character being parsed> STSQUE : REF $STSQUE_DECL,! New entry for status queue: TYPEAHEAD_BUF : $TYPEAHEAD_DECL,! Typeahead buffer status< QIO_IOSB : VECTOR[4,WORD], ! I/O Status block for $QIO1 BUFFER_LEN, ! Number of chars read into BUFFERsF BUFFER : VECTOR [K_BUFFER_LEN, BYTE] VOLATILE, ! Input buffer E STR_DESC : $DTK$DESCRIPTOR ! String descriptor for keypad input$ PRESET(( [DSC$W_LENGTH] = 1,& [DSC$B_DTYPE] = DSC$K_DTYPE_T,& [DSC$B_CLASS] = DSC$K_CLASS_S, [DSC$A_POINTER]= BUFFER); BIND VCB = .P_VCB : $VCB_DECL; ENABLE LIB$SIG_TO_RET; VCB [VCB_V_STSREAD] = 0; !+1 ! Process all characters in the input buffer.,B ! If we are to return a status, keep reading until we get one. !- DO BEGIN ! Start of WHILE loop !+ 3 ! Get the first character in the typeahead buffer.A !-S) STATUS = $QIOW( CHAN = .VCB[VCB_W_CHAN],0 EFN = .DTK_L_EFN,T IOSB = QIO_IOSB,N( FUNC = IO$_READVBLK OR IO$M_NOECHO OR' (IF NOT NULLPARAMETER(TIMEOUT) T THEN IO$M_TIMED ELSE 0),# P1 = .STR_DESC[DSC$A_POINTER], " P2 = .STR_DESC[DSC$W_LENGTH],) P3 = (IF NOT NULLPARAMETER(TIMEOUT) t THEN ..TIMEOUT ELSE 0) );D& IF NOT .STATUS THEN RETURN (.STATUS);0 IF NOT .QIO_IOSB[0] THEN RETURN (.QIO_IOSB[0]); !+N? ! If the first character is not an escape, it is keypad input. = ! Place this input in the user input buffer, which is just aH7 ! long dynamic string maintained by the STR$ routines.O !- 0 IF CH$RCHAR(.STR_DESC[DSC$A_POINTER]) NEQ K_ESC THEN + BEGIN ! Begin keypad input processingT1 STATUS = STR$CONCAT( VCB[VCB_Q_INPUT_DESC], T VCB[VCB_Q_INPUT_DESC], STR_DESC);u* IF NOT .STATUS THEN RETURN (.STATUS);( END ! End keypad input processing ELSEK BEGIN ! Escape char foundF !+S ! Read in the next status. < ! Note:: we have already read in the escape character. !-MJ STATUS = DTK$$INPUT(.P_VCB, BUFFER_LEN, BUFFER[1], %REF(K_TMO_SEC) );* IF NOT .STATUS THEN RETURN (.STATUS);; BUFFER_LEN = .BUFFER_LEN + 1; ! Add in first char read !+ - ! Check first part of buffer to be sure & ! it is a sequence we know about. !-N6 CURR_CHAR = CH$FIND_CH(.BUFFER_LEN,BUFFER,K_ESC);0 IF CH$FAIL(CURR_CHAR) OR .BUFFER_LEN LSS 2 THEN  RETURN (DTK$_UNKESCSEQ); W !+ ) ! Check for type of escape sequence. !-_' IF CH$A_RCHAR(CURR_CHAR) EQL %C'['H THENT !+7 ! We now have a valid CSI, skip ahead to the functionD7 ! code which is just after the private delimiter '?'.S !- BEGIN ! Begin CSI processing6 CURR_CHAR = CH$FIND_CH( .BUFFER_LEN, BUFFER, %C'?');5 IF CH$FAIL(CURR_CHAR) THEN RETURN (DTK$_UNKESCSEQ);1 DO& BEGIN ! Loop until end is found( FUNC_CODE = CH$A_RCHAR(CURR_CHAR); !+8 ! Determine what to do based on the function code. !- SELECTONE .FUNC_CODE OFU SETV [%C'2']: !+K- ! This is a DSR Extended reply sequence. r+ ! The sub-function code is the status. S !-T% SELECTONE CH$A_RCHAR(CURR_CHAR) OFL SET. [%C'0']: RET_STATUS = DTK$_NOMALFUN2;. [%C'1']: RET_STATUS = DTK$_NOMALFUN1;, [%C'2']: RET_STATUS = DTK$_COMFAIL;. [%C'3']: RET_STATUS = DTK$_INPBUFOVR;- [%C'4']: RET_STATUS = DTK$_NVROPRFAI; - [%C'5']: RET_STATUS = DTK$_ERRPHOTRA;d- [%C'6']: RET_STATUS = DTK$_CONSEQERR;_- [%C'7']: RET_STATUS = DTK$_DECTSTFAI;0 [OTHERWISE]: RET_STATUS = DTK$_UNKREPLY; TES;C [OTHERWISE]: L RET_STATUS = DTK$_UNKESCSEQ; TES; !+) ! Add status entry to status queue. !-/ STATUS = LIB$GET_VM(%REF(STSQUE_K_SIZE), uJ~ DTKALPHA.SAVA [DIETER.DTKALPHA]DTKUTIL.B32;1P J| STSQUE, DTK_A_ZONE_ID);+ IF NOT .STATUS THEN RETURN (.STATUS);- STSQUE [STATUS_L_STATUS] = .RET_STATUS;B1 INSQUE(.STSQUE, VCB[VCB_L_HDWR_STS_FLINK]);, END ! End of loop until end is found !+> ! Check the next character. This should be either a ';'@ ! (another status to process) or an 'n' (end of sequence). !-, UNTIL (CH$A_RCHAR(CURR_CHAR) EQL %C'n') OR) (CH$RCHAR(.CURR_CHAR) EQL %C'c')t END ! End CSI processing ELSEi a' IF CH$RCHAR_A(CURR_CHAR) EQL %C'P' THENS !+8 ! We now have a valid DCS, skip ahead to the function * ! code which is just after the next ';'. !- BEGIN ! Begin DCS processing6 CURR_CHAR = CH$FIND_CH( .BUFFER_LEN, BUFFER, %C';');5 IF CH$FAIL(CURR_CHAR) THEN RETURN (DTK$_UNKESCSEQ);m$ FUNC_CODE = CH$A_RCHAR(CURR_CHAR); !+4 ! We now have the function code, skip ahead to the7 ! sub-function code which is just after the next ';'.p !-: CURR_CHAR = CH$FIND_CH( .BUFFER_LEN, .CURR_CHAR, %C';');5 IF CH$FAIL(CURR_CHAR) THEN RETURN (DTK$_UNKESCSEQ);C !+4 ! Determine what to do based on the function code. !- SELECTONE .FUNC_CODE OFf SETu [%C'5']: !+8 ! This is a DT_DICT reply sequence sequence. The ( ! sub-function code is the status. !-( SELECTONE CH$A_RCHAR(CURR_CHAR) OF SET [%C'z',S) %C'0']: RET_STATUS = SS$_NORMAL; * [%C'1']: RET_STATUS = DTK$_NOROOM;+ [%C'2']: RET_STATUS = DTK$_TOOLONG;B. [OTHERWISE]: RET_STATUS = DTK$_UNKREPLY; TES; [%C'3']: !+; ! This is a DT_INDEX_QUERY reply sequence sequence. V9 ! The characters between the sub-function code and A2 ! 'z' is the index. Convert this to binary. !- BEGIN LOCAL+ Z_CHAR : REF VECTOR[,BYTE]; CH$RCHAR_A(CURR_CHAR);; Z_CHAR = CH$FIND_CH( .BUFFER_LEN, .CURR_CHAR, %C'z');A6 IF CH$FAIL(Z_CHAR) THEN RETURN (DTK$_UNKESCSEQ);9 STATUS = LIB$CVT_DTB( CH$DIFF(.Z_CHAR,.CURR_CHAR), B .CURR_CHAR, RET_STATUS); 7 IF NOT .STATUS THEN RETURN (DTK$_UNKESCSEQ); ++ VCB [VCB_W_LAST_INDEX] = .RET_STATUS;_ END; [%C'7']: !+5 ! This is a DT_PHONE reply sequence sequence. _. ! The sub-function code is the status.  !-( SELECTONE CH$A_RCHAR(CURR_CHAR) OF SET [%C'z',  %C'0']: S BEGIN RET_STATUS = DTK$_ONHOOK; VCB [VCB_V_OFFHOOK] = 0;f VCB [VCB_V_KEYPAD_ON] = 0;m VCB [VCB_V_AUTOSTOP] = 0;Q VCB [VCB_V_WINK] = 0; END;. [%C'1']: ] BEGIN RET_STATUS = DTK$_OFFHOOK;_ VCB [VCB_V_OFFHOOK] = 1;E END;E+ [%C'2']: RET_STATUS = DTK$_TIMEOUT;E+ [%C'3']: RET_STATUS = DTK$_TOOLONG;- [%C'4']: BEGIN RET_STATUS = DTK$_WINK; VCB [VCB_V_WINK] = 1; END;E, [%C'5']: RET_STATUS = DTK$_NODIATONE;' [%C'6']: RET_STATUS = DTK$_BUSY;!+ [%C'7']: RET_STATUS = DTK$_NOANSWER;*. [OTHERWISE]: RET_STATUS = DTK$_UNKREPLY; TES; [OTHERWISE]: *" RET_STATUS = DTK$_UNKESCSEQ; TES; !+l( ! Add status entry to status queue. !-B! IF .RET_STATUS NEQ DTK$_WINKL THENN BEGIN B STATUS = LIB$GET_VM(%REF(STSQUE_K_SIZE), STSQUE, DTK_A_ZONE_ID);' IF NOT .STATUS THEN RETURN (.STATUS); ) STSQUE [STATUS_L_STATUS] = .RET_STATUS; + INSQUE(.STSQUE, VCB[VCB_L_STATUS_FLINK]);r, VCB [VCB_V_STSREAD] = 1; ! Set status flag END;$ END; ! End of DCS processing$ END; ! End of escape char found !+! ! Check the typeahead buffer.[ !-) STATUS=$QIOW(CHAN = .VCB[VCB_W_CHAN], EFN = .DTK_L_EFN, IOSB = QIO_IOSB, + FUNC = IO$_SENSEMODE OR IO$M_TYPEAHDCNT,  P1 = TYPEAHEAD_BUF, P2 = 8);d) IF NOT .STATUS THEN RETURN (.STATUS);U3 IF NOT .QIO_IOSB[0] THEN RETURN (.QIO_IOSB[0]);p END ! End of WHILE5 WHILE (.TYPEAHEAD_BUF [TYPEAHEAD_COUNT] NEQ 0) ORC (NOT NULLPARAMETER(P_RET_STATUS) AND .VCB[VCB_V_STSREAD] EQL 0);l !+? ! We have now processed all characters in the input buffer._> ! Return the last status read by removing the latest entryB ! on the status queue. In most cases, this is the only queue @ ! entry but it may not be since the DECTALK may have sent us# ! an unsolicited status (wink). !-& IF NOT NULLPARAMETER(P_RET_STATUS) THEN BEGIN ! Return status3 STATUS = REMQUE(.VCB[VCB_L_STATUS_FLINK], STSQUE); IF .STATUSa THEN2 .P_RET_STATUS = SS$_NORMAL ! Queue was empty ELSEL# BEGIN ! Queue was not emptyU. .P_RET_STATUS = .STSQUE[STATUS_L_STATUS];F STATUS = LIB$FREE_VM(%REF(STSQUE_K_SIZE), STSQUE, DTK_A_ZONE_ID);* IF NOT .STATUS THEN RETURN (.STATUS);% END; ! End of queue was emptyh END; ! End of return status RETURN (SS$_NORMAL);, END; ! End of routine DTK$$GET_STATUS !U 0%SBTTL 'DTK$$GET_TERM_DATA - Get terminal data.'ROUTINE DTK$$GET_TERM_DATA (  P_VCB, SEQ_PTR, SEQ_LEN, INPUT_ARG1,U INPUT_ARG2 ) =L!++M! FUNCTIONAL DESCRIPTION:o! !t! CALLING SEQUENCE:T!S4! ret_status.wlc.v = DTK$$GET_TERM_DATA ( P_VCB.rl.r! SEQ_PTR.rl.r,! SEQ_LEN.rl.rT! [,INPUT_ARG1]! [,INPUT_ARG2])t!,! FORMAL PARAMETERS:!y,! P_VCB.rl.r Address of voice control block/! SEQ_PTR.rl.r Address of sequence to retrieveu"! SEQ_LEN.rl.r Length of sequence3! INPUT_ARG1 Value for first sequence substitutionO4! INPUT_ARG2 Value for second sequence substitution!I! IMPLICIT INPUTS:!! NONE!O! IMPLICIT OUTPUTS:!! NONE!N! COMPLETION STATUS:!L)! SS$_NORMAL normal successful completiona! SS$_xxxx any error from $FAO!C! SIDE EFFECTS:t!r! NONE!--t BEGIN- LITERALI K_ARG1 = 4, K_ARG2 = 5; BUILTINL ACTUALCOUNT, NULLPARAMETER;S LOCALI) STATUS, ! Status returned by routinest CONTROL_DSC : $DTK$DESCRIPTOR,e RETURN_DSC : $DTK$DESCRIPTOR;R BIND VCB = .P_VCB : $VCB_DECL; !+4 ! If no arguement substitution is required, just5 ! move the capability into the buffer and return.T !- IF ACTUALCOUNT() LSS K_ARG1P THEN BEGIN# VCB [VCB_L_CAP_LENGTH] = .SEQ_LEN;8 CH$MOVE( .SEQ_LEN, .SEQ_PTR, .VCB [VCB_A_CAP_BUFFER] ); RETURN (SS$_NORMAL);m END;c !+& ! Call $FAO to process the string. !-0 CONTROL_DSC [DSC$B_DTYPE] = DSC$K_DTYPE_T;0 CONTROL_DSC [DSC$B_CLASS] = DSC$K_CLASS_S;+ CONTROL_DSC [DSC$W_LENGTH] = .SEQ_LEN; + CONTROL_DSC [DSC$A_POINTER] = .SEQ_PTR;/ RETURN_DSC [DSC$B_DTYPE] = DSC$K_DTYPE_T;$/ RETURN_DSC [DSC$B_CLASS] = DSC$K_CLASS_S; 8 RETURN_DSC [DSC$W_LENGTH] = VCB$K_LONGEST_SEQUENCE;9 RETURN_DSC [DSC$A_POINTER] = .VCB [VCB_A_CAP_BUFFER]; ! STATUS = $FAO ( CONTROL_DSC, t VCB [VCB_L_CAP_LENGTH],l RETURN_DSC,- .INPUT_ARG1,' (IF NOT NULLPARAMETER(INPUT_ARG2)e THEN .INPUT_ARG2 ELSE 0)  ); RETURN (.STATUS);C/ END; ! End of routine DTK$$GET_TERM_DATA !B %%SBTTL 'DTK$$INPUT - Low level input'R>GLOBAL ROUTINE DTK$$INPUT(P_VCB,P_TEXT_LEN,TEXT_ADR,TIMEOUT) =!++0! FUNCTIONAL DESCRIPTION:$!O+! Handles low level input by issuing a QIO.!P! CALLING SEQUENCE:A!E ! ret_status.wlc.v = DTK$$INPUT(! P_VCB.rab.r, ! P_TEXT_LEN.wl.r, ! TEXT_ADR.rt.r! [, TIMEOUT])E!N! FORMAL PARAMETERS:!.! P_VCB.rab.r Address of voice control block.!e:! P_TEXT_LEN.wl.v Number of characters to read/read into ! the text string! 0! TEXT_ADR.rt.r Address of start of text string+! The text may contain escape sequences.)!Q8! TIMEOUT.rl.r [OPTIONAL] Number of seconds to wait for! the input. ! IMPLICIT INPUTS:!_! Contents of VCB.!B! IMPLICIT OUTPUTS:! ! NONE!u! COMPLETION STATUS:!N)! SS$_NORMAL Normal successful completiona! SS$_xyz errors from QIO! SS$_xyz errors from $ASSIGN!! SIDE EFFECTS:!!a! NONE!--  tBEGIN BUILTIN  NULLPARAMETER;rBIND TEXT_LEN = .P_TEXT_LEN,1 VCB = .P_VCB : $VCB_DECL; ! voice control block,LOCAL]( STATUS, ! Status returned by routines CURR_CHAR : REF VECTOR[,BYTE],F QIO_IOSB : VECTOR[4, WORD];d TEXT_LEN = 0;a!+!! Issue a QIO to read the string.f!-&STATUS=$QIOW( CHAN = .VCB[VCB_W_CHAN], EFN = .DTK_L_EFN,!( FUNC = IO$_READVBLK OR IO$M_ESCAPE OR & IO$M_NOECHO OR IO$M_TRMNOECHO OR$ (IF NOT NULLPARAMETER(TIMEOUT)  THEN IO$M_TIMED ELSE 0), IOSB = QIO_IOSB, P1 = .TEXT_ADR,f P2 = K_BUFFER_LEN,& P3 = (IF NOT NULLPARAMETER(TIMEOUT)  THEN ..TIMEOUT ELSE 0));*IF NOT .STATUS THEN RETURN (.STATUS);/IF NOT .QIO_IOSB[0] THEN RETURN (.QIO_IOSB[0]);a(TEXT_LEN = .QIO_IOSB[1] + .QIO_IOSB[3];/CURR_CHAR = CH$PLUS(.TEXT_ADR,(.TEXT_LEN - 2));FIF .TEXT_LEN GEQ 2 AND' CH$RCHAR_A(CURR_CHAR) EQL K_ESC AND _" CH$RCHAR_A(CURR_CHAR) EQL %C'P'THEN !+N ! We have just read in a DCS. Read in the remaining part of the sequence. !- BEGINs) STATUS=$QIOW(CHAN = .VCB[VCB_W_CHAN],E EFN = .DTK_L_EFN,5 FUNC = IO$_READVBLK OR IO$M_ESCAPE OR IO$M_NOECHO,a IOSB = QIO_IOSB,e P1 = .CURR_CHAR,s P2 = K_BUFFER_LEN);. IF NOT .STATUS THEN RETURN (.STATUS);3 IF NOT .QIO_IOSB[0] THEN RETURN (.QIO_IOSB[0]);S7 TEXT_LEN = .TEXT_LEN + .QIO_IOSB[1] + .QIO_IOSB[3];A END;RETURN (SS$_NORMAL);#END; ! End of routine DTK$$INPUT_ !N F(%SBTTL 'DTK$$OUTPUT - Output to DECtalk'6GLOBAL ROUTINE DTK$$OUTPUT (P_VCB,TEXT_LEN,TEXT_ADR) =!++ ! FUNCTIONAL DESCRIPTION: !$8! Handles output by buffering all text and sending it in:! one QIO when the buffer is full if buffering mode is on.*! If not, issues a QIO to output the text.! ! CALLING SEQUENCE:! !! ret_status.wlc.v = DTK$$OUTPUT(t! P_VCB.rab.r,! TEXT_LEN.rl.v,! TEXT_ADR.rt.r)!R! FORMAL PARAMETERS:! .! P_VCB.rab.r Address of voice control block.! 4! TEXT_LEN.rl.v Number of characters in text string!E0! TEXT_ADR.rt.r Address of start of text string+! The text may contain escape sequences.i!n! IMPLICIT INPUTS:!! Contents of VCB.!c! IMPLICIT OUTPUTS:d! >! VCB[VCB_W_OUTPUT_BUFLEN] may change if buffering is enabled.! ! COMPLETION STATUS:! )! SS$_NORMAL Normal successful completion! ! SIDE EFFECTS:R!H! Output may occur. 8! If buffering is enabled, buffers may fill and/or dump.!--C _BEGINQBIND0 VCB = .P_VCB : $VCB_DECL, ! voice control block7 TEXT = .TEXT_ADR : VECTOR[,BYTE],! string to be outputtD BUFLEN = VCB[VCB_W_OUTPUT_BUFLEN] : WORD, ! num of chars in buffer< BUFSIZ = VCB[VCB_W_OUTPUT_BUFSIZ] : WORD, ! size of bufferD BUFFER = .VCB[VCB_A_OUTPUT_BUFFER] : VECTOR[,BYTE]; ! Output bufferLOCAL STATUS;!+F! If buffering is enabled, and the new string won't fit in the buffer,%! then we must output the buffer now. 1! If it will fit, then just put it in the buffer.';! Do not break up the string since we do not want to output! a partial escape sequence.!-IF .VCB[VCB_V_BUF_ENABLED]# THEN BEGIN ! buffering is enabledE !+ , ! See if the string will fit in the buffer. !-l" IF .TEXT_LEN+.BUFLEN GTRU .BUFSIZ THEN BEGIN ! No - Dump buffer$ STATUS=OUTPUT(VCB,.BUFLEN,BUFFER);' IF NOT .STATUS THEN RETURN (.STATUS); BUFLEN=0;  END ! No - Dump buffer& ELSE BEGIN ! Yes - append to buffer !+" ! Copy the text into the buffer,& ! update BUFLEN which keeps track of# ! how much data is in the buffer,: ! and then return. !-* CH$MOVE(.TEXT_LEN,TEXT,BUFFER[.BUFLEN]); BUFLEN=.BUFLEN+.TEXT_LEN;n RETURN (SS$_NORMAL); END; ! Yes - append to buffern !+i; ! We reach here if the string would not fit in the buffer.  ! The buffer has been dumped.& ! Put the new string into the buffer.. ! If it will not fit, we output it in chunks.2 ! We output as many full buffer chunks as we can.2 ! When we are all done, we are left with a string1 ! smaller than one buffer's worth, which we then  ! put into our output buffer. !-T INCR I FROM 0 BY .BUFSIZ DO IF .I+.BUFSIZ LEQU .TEXT_LEN THEN% BEGIN ! output next part of string ' STATUS=OUTPUT(VCB,.BUFSIZ,TEXT[.I]);u( IF NOT .STATUS THEN RETURN (.STATUS);# END ! output next part of stringE ELSE& BEGIN ! buffer final part of string& BUFLEN=.TEXT_LEN-.I; ! could be 0$ CH$MOVE(.BUFLEN,TEXT[.I],BUFFER); EXITLOOPF$ END ! buffer final part of string END ! buffering is enabledO ELSE BEGIN ! no buffering_ !+  ! Output the string directly. !-:# STATUS=OUTPUT(VCB,.TEXT_LEN,TEXT);$& IF NOT .STATUS THEN RETURN (.STATUS); END; ! no bufferingRETURN (SS$_NORMAL);$END; ! End of routine DTK$$OUTPUT !O -M%SBTTL 'DTK$$SET_TERM_CHARACTERISTICS - Setup terminal line characteristics.'K'ROUTINE DTK$$SET_TERM_CHARACTERISTICS (_1 P_VCB, ON_CHARACTERISTICS1, ON_CHARACTERISTICS2,S/ OFF_CHARACTERISTICS1, OFF_CHARACTERISTICS2 ) =_!++R! FUNCTIONAL DESCRIPTION:S!U3! This routine changes the terminal characteristics! for a given DECtalk.!E! CALLING SEQUENCE: !!:! RET_STATUS.wlc.v = DTK$$SET_TERM_CHARACTERISTICS (! P_VCB.rl.r ! [,ON_CHARACTERISTICS1.rl.v] ! [,ON_CHARACTERISTICS2.rl.v]!! [,OFF_CHARACTERISTICS1.rl.v]D!! [,OFF_CHARACTERISTICS2.rl.v]S!U! FORMAL PARAMETERS:!L"! P_VCB.rl.r voice control blockA! ON_CHARACTERITSICS1.rl.v bits to turn on in 1st characteristicsSA! ON_CHARACTERITSICS2.rl.v bits to turn on in 2nd characteristicsDC! OFF_CHARACTERITSICS1.rl.v bits to turn off in 1st characteristics C! OFF_CHARACTERITSICS2.rl.v bits to turn off in 2nd characteristicsN!.! IMPLICIT INPUTS:!I! Terminal characteristics!D! IMPLICIT OUTPUTS: ! ! NONE!H! COMPLETION STATUS:!4! SS$_NORMAL Normal successful completion7! DTK$_NOT_A_TRM Success - but device is not a terminal !! LIB$_xyz Errors from LIB$GET_VMA'! SS$_xyz Errors from $DCLEXH or $QIOWO!U! SIDE EFFECTS:_!T!--N VBEGINVBIND VCB = .P_VCB : $VCB_DECL;LOCALo) STATUS, ! Status returned by routinesf, TTIOSB : VECTOR[4,WORD], ! I/O status block; OLD_CHARBUF : BLOCK[12,BYTE]; ! Old characteristics bufferaBUILTINs NULLPARAMETER;!+&! Save the old characteristics buffer.!-+CH$MOVE(12,VCB[VCB_R_CHARBUF],OLD_CHARBUF);n!+1! OR in the new characteristic bits requested on. !-IF NOT NULLPARAMETER(2)t THEN VCB[VCB_L_DEVDEPEND]=0 .VCB[VCB_L_DEVDEPEND] OR .ON_CHARACTERISTICS1;IF NOT NULLPARAMETER(3)$ THEN VCB[VCB_L_DEVDEPEND2]=S1 .VCB[VCB_L_DEVDEPEND2] OR .ON_CHARACTERISTICS2;_!+1! AND out the characteristics bits requested off.I!-IF NOT NULLPARAMETER(4)S THEN VCB[VCB_L_DEVDEPEND]=8 .VCB[VCB_L_DEVDEPEND] AND (NOT .OFF_CHARACTERISTICS1);IF NOT NULLPARAMETER(5)  THEN VCB[VCB_L_DEVDEPEND2]= 9 .VCB[VCB_L_DEVDEPEND2] AND (NOT .OFF_CHARACTERISTICS2);$!+;! Set the terminal to have the desired new characteristics.r!-&STATUS=$QIOW( CHAN = .VCB[VCB_W_CHAN], FUNC = IO$_SETMODE,  EFN = .DTK_L_EFN,1 IOSB = TTIOSB, P1 = VCB[VCB_R_CHARBUF], P2 = 12);+CH$MOVE(12,OLD_CHARBUF,VCB[VCB_R_CHARBUF]);w%IF NOT .STATUS THEN RETURN (.STATUS); +IF NOT .TTIOSB[0] THEN RETURN (.TTIOSB[0]); RETURN (SS$_NORMAL);6END; ! End of routine DTK$$SET_TERM_CHARACTERISTICS !v eJ%SBTTL 'DTK$$SETUP_TERMINAL_TYPE - Setup terminal type for DTK$$ routines'#ROUTINE DTK$$SETUP_TERMINAL_TYPE ( 1 FILE_NAME, NAME_LEN,s VCB_ADRO ) =U!++2! FUNCTIONAL DESCRIPTION: !s?! This routine uses the specified file name to determine deviceUE! characteristics and assign a terminal type code which is understoodcC! by other DTK$$ routines. DTK$$ routines use the terminal type toS=! determine the correct escape sequence for a given function. !! CALLING SEQUENCE:U!I:! ret_status.wlc.v = DTK$$SETUP_TERM_TYPE (FILE_NAME.rt.r,! NAME_LEN.rl.v,! P_TERM_TYPE.wl.r,$! VCB_ADR.wl.r)R!S! FORMAL PARAMETERS:!(! FILE_NAME.rt.r addr of file name text)! NAME_LEN.rl.v length of file name text <! P_TERM_TYPE.wl.r terminal type code, one of the following:! unknown! 6! VCB_ADR.wl.r Address of longword to receive address"! of the DECtalk control block.,! If 0 or omitted, no VCB gets allocated.! ! IMPLICIT INPUTS:!)! NONE!! IMPLICIT OUTPUTS:$! ! VCB fields get filled in.-!! COMPLETION STATUS:!Y! ! SIDE EFFECTS:;! ! NONE!--  C BEGIN BUILTIN; NULLPARAMETER; LOCAL]* STATUS, ! Status returned by routines DTKFAB : $FAB_DECL VOLATILE,D DTKNAM : $NAM_DECL VOLATILE,E. DEVNAM_DSC : $DTK$DESCRIPTOR, ! dsc for name> DVI_ITMLST : VECTOR [6*3 + 1] INITIAL ! item list for $GETDVI; (DVI$_DEVTYPE ^ 16 + 4, 0, 0,! device type (DT$_xyz)> DVI$_DEVDEPEND ^ 16 + 4, 0, 0,! device dependent bits (1)> DVI$_DEVDEPEND2 ^ 16 + 4, 0, 0,! device dependent bits (2)3 DVI$_DEVBUFSIZ ^ 16 + 4, 0, 0,! terminal width0; DVI$_DEVCLASS ^ 16 + 4, 0, 0,! device class (DC$_xyz)f7 DVI$_DEVNAM ^ 16 +64, 0, 0,! result name string' 0), ! terminatorp< DVI_IOSB : VECTOR [4, WORD], ! I/O Status block for $GETDVI2 DEV_TYPE : VOLATILE, ! storage for $GETDVI valueC DEV_DEPEND : VOLATILE BLOCK [4, BYTE], ! device dependent bits (1) D DEV_DEPEND2 : VOLATILE BLOCK [4, BYTE], ! device dependent bits (2)4 DEV_BUFSIZ : VOLATILE, ! storage for $GETDVI value3 DEV_CLASS : VOLATILE, ! storage fpr $GETDVI value B DEV_PAGSIZ : VOLATILE INITIAL(0), ! gets number of rows of deviceH DEV_DEVNAM : VECTOR [64, BYTE] VOLATILE,! Buffer for result name string< DEV_NAMLEN : VOLATILE WORD INITIAL(0); ! Length of returned ! resultant name stringf BIND; DVI_TYPE = DVI_ITMLST + 4, ! make it easy to references" DVI_DEPEND = DVI_ITMLST + 16, !9 DVI_DEPEND2 = DVI_ITMLST + 28, ! items retd by $GETDVIa" DVI_BUFSIZ = DVI_ITMLST + 40, !" DVI_CLASS = DVI_ITMLST + 52, !" DVI_DEVNAM = DVI_ITMLST + 64, !" DVI_NAMLEN = DVI_ITMLST + 68; ! BIND& FABDNS = DTKFAB[FAB$B_DNS] : BYTE,& NAMNOP = DTKNAM[NAM$B_NOP] : BYTE,& NAMRLF = DTKNAM[NAM$L_RLF] : LONG,D FABDEV = DTKFAB[FAB$L_DEV] : BLOCK[,BYTE], ! Device characteristcs) DVI_NAME_LEN = DTKNAM[NAM$T_DVI] : BYTE,0 DVI_NAME = DTKNAM[NAM$T_DVI]+1 : VECTOR[,BYTE]; I !+' ! Use RMS to parse the device name.!= ! This will give us a 1-15 character physical device nameR( ! in the DVI field in the NAM block.B ! (If we just use $GETDVI, it may return a 63-character hidden ! device name.) G ! The main reason we call $PARSE is so that we can allow filenames.TF ! If the user specifies "TTB5:" as his device, he gets a terminal. !- !+( ! Initialize the FAB and NAM blocks. !- $FAB_INIT( FAB = DTKFAB, DNM = 'DTKOUTPUT.LIS', NAM = DTKNAM,T FNA = .FILE_NAME,$ FNS = .NAME_LEN);L $NAM_INIT(NAM=DTKNAM); STATUS=$PARSE(FAB=DTKFAB);) IF NOT .STATUS THEN RETURN (.STATUS);t !+> ! The device name is now a counted string in the NAM block$ ! beginning at offset NAM$T_DVI.K ! There is an obscure case though that can occur. If the output device D ! is on another node, then RMS cannot figure out the device nameB ! so the DVI field is empty. This can happen if an DTK job is: ! run as a TASK with SYS$OUTPUT defined to be SYS$NET.I ! This happens when you use the "TASK=FOO" kind of file specificationf ! to RMS.NI ! To allow this to work, we check to see if the device characteristicRD ! of the DECtalk device is DEV$M_NET. If so, we bypass the call< ! to $GETDVI, and we fill in the fields the best we can. !- IF .FABDEV[DEV$V_NET]  THEN BEGIN ! Network device !+ ( ! Fudge the items to reasonable values. !-  DEV_TYPE = DT$_MBX; DEV_DEPEND = 0; DEV_DEPEND2 = 0;C DEV_CLASS = DC$_MAILBOX;. DEV_BUFSIZ = 80;r DEV_DEVNAM = .FILE_NAME;R DEV_NAMLEN = .NAME_LEN; END ! Network device ELSE BEGIN ! Normal devicef3 DVI_TYPE = DEV_TYPE; ! fill in rest of itmlsts DVI_DEPEND = DEV_DEPEND; DVI_DEPEND2 = DEV_DEPEND2;e DVI_CLASS = DEV_CLASS;T DVI_BUFSIZ = DEV_BUFSIZ; . DVI_DEVNAM = DEV_DEVNAM; DVI_NAMLEN = DEV_NAMLEN; !+c* ! Create a descriptor for use by $GETDVI. !-S- DEVNAM_DSC [DSC$B_DTYPE] = DSC$K_DTYPE_T;t- DEVNAM_DSC [DSC$B_CLASS] = DSC$K_CLASS_S;c, DEVNAM_DSC [DSC$W_LENGTH] = .DVI_NAME_LEN;( DEVNAM_DSC [DSC$A_POINTER] = DVI_NAME;% STATUS = $GETDVIW( EFN = .DTK_L_EFN,r IOSB = DVI_IOSB,_ DEVNAM = DEVNAM_DSC,g ITMLST = DVI_ITMLST);& IF NOT .STATUS THEN RETURN (.STATUS);2 IF NOT .DVI_IOSB [0] THEN RETURN (.DVI_IOSB [0]); END; ! Normal devicer !++ ! Allocate a voice control block (VCB).! !-M IF NOT (STATUS = LIB$GET_VM (%REF (VCB_K_SIZE), .VCB_ADR, DTK_A_ZONE_ID))o THEN RETURN (.STATUS); G CH$FILL (0, VCB_K_SIZE, ..VCB_ADR); ! Clear all fields to default 0u !+ ! Store items in the VCB.e !- BEGIN BIND" VCB = ..VCB_ADR : $VCB_DECL ; !+[9 ! Lock the VCB. This will prevent a second call made to; ! this routine disrupting the first one while it is being I ! processed.F !-T VCB [VCB_V_LOCKED] = 1; !+m? ! Fill in the 12-byte device characteristics block in the VCB.S@ ! Note that the DEVDEPEND field will not be valid if the device< ! is not a terminal because we replace the top byte of thisF ! longword with the device page size (as it would be for a terminal). !-d* VCB [VCB_B_DEVTYPE] = DTK$K_DTC_UNKNOWN;6 VCB [VCB_B_PHY_DEV_TYPE]= .DEV_TYPE; ! Physical type./ VCB [VCB_B_CLASS] = .DEV_CLASS; ! Device class6 VCB [VCB_W_WIDTH] = .DEV_BUFSIZ; ! Number of columns.B VCB [VCB_L_DEVDEPEND] = .DEV_DEPEND; ! Implicitly sets overlapped ! field VCB_B_ROWS also.2 VCB [VCB_B_ROWS] = .DEV_PAGSIZ; ! Reset it again.E VCB [VCB_L_DEVDEPEND2] = .DEV_DEPEND2; ! Secondary characteristics.!5 VCB [VCB_W_MODE_SETTINGS] = VCB_K_DEF_MODE_SETTINGS;l/ VCB [VCB_B_STRUCT_TYPE] = VCB_K_STRUCT_TYPE;t4 VCB [VCB_W_OUTPUT_BUFSIZ] = VCB$K_LONGEST_SEQUENCE; !+O ! Fill in the device name.L !- = VCB [VCB_W_DEVNAM_LEN]= .DEV_NAMLEN; ! Length of device nameV7 CH$MOVE ( .DEV_NAMLEN, DEV_DEVNAM, VCB[VCB_T_DEVNAM]);T !+> ! Allocate a buffer to hold the escape sequence being parsed. !-a< IF NOT (STATUS = LIB$GET_VM (%REF (VCB$K_LONGEST_SEQUENCE), VCB [VCB_A_CAP_BUFFER], DTK_A_ZONE_ID)) THEN  RETURN (.STATUS); f> CH$FILL (0, VCB$K_LONGEST_SEQUENCE, .VCB [VCB_A_CAP_BUFFER]); !+ < ! Allocate a buffer to hold the output sequence being sent. !- < IF NOT (STATUS = LIB$GET_VM (%REF (VCB$K_LONGEST_SEQUENCE),# VCB [VCB_A_OUTPUT_BUFFER],f DTK_A_ZONE_ID)) THENE RETURN (.STATUS); RA CH$FILL (0, VCB$K_LONGEST_SEQUENCE, .VCB [VCB_A_OUTPUT_BUFFER]);  END;T !+1 ! Call $PARSE again to deallocate its memory.C !- FABDNS = 0;R NAMRLF = 0;A NAMNOP = NAM$M_SYNCHK; $PARSE(FAB=DTKFAB);U RETURN (.STATUS);t4 END; ! End of routine DTK$$SETUP_TERMINAL_TYPE !U E:%SBTTL 'DTK$$SIM_AUTO - Simulate AUTOSTOP mode for DTC01.'0ROUTINE DTK$$SIM_AUTO(P_VCB,TEXT_LEN,TEXT_ADR) =!++.! FUNCTIONAL DESCRIPTION:C!r<! The DTC03 has an AUTOSTOP mode in hardware that, when set,=! will cause it to stop speaking when a key is pressed on theiA! phone keypad. The DTC01 does not have this mode. This routine (! will simulate this mode for the DTC01.!b! CALLING SEQUENCE: !r#! ret_status.wlc.v = DTK$$SIM_AUTO(r! P_VCB.rab.r,f! TEXT_LEN.rl.v,c! TEXT_ADR.rt.r)S!2! FORMAL PARAMETERS:! .! P_VCB.rab.r Address of voice control block.! 4! TEXT_LEN.rl.v Number of characters in text string! 0! TEXT_ADR.rt.r Address of start of text string+! The text may contain escape sequences.$!T! IMPLICIT INPUTS:!v! Contents of VCB.!! IMPLICIT OUTPUTS:m!B! NONE! ! COMPLETION STATUS:!E)! SS$_NORMAL Normal successful completionN,! SS$_xyz errors from $QIO, $WFLOR, $CANCEL!! SIDE EFFECTS:,! 3! Any text currently being spoken may be discarded.R!--  BEGINbBIND0 VCB = .P_VCB : $VCB_DECL; ! voice control blockLOCAL) STATUS, ! Status returned by routinest5 INPUT_IOSB : VECTOR[4, WORD],! IOSB for input QIOB7 OUTPUT_IOSB : VECTOR[4, WORD],! IOSB for output QIO e> BUFFER : BYTE VOLATILE, ! One character input buffer E STR_DESC : $DTK$DESCRIPTOR ! String descriptor for keypad inputS PRESET(L [DSC$W_LENGTH] = 1,& [DSC$B_DTYPE] = DSC$K_DTYPE_T,& [DSC$B_CLASS] = DSC$K_CLASS_S, [DSC$A_POINTER]= BUFFER),3 TYPEAHEAD_BUF : $TYPEAHEAD_DECL;! Typeahead bufferN!+! Establish a signal handler.D!-ENABLE LIB$SIG_TO_RET;!+3! Check the typeahead buffer to see if the user hasD3! already entered some input from the phone keypad.C6! This will also process any pending escape sequences.!-'STATUS=$QIOW( CHAN = .VCB[VCB_W_CHAN],I EFN = .DTK_L_EFN, IOSB = INPUT_IOSB,T+ FUNC = IO$_SENSEMODE OR IO$M_TYPEAHDCNT,, P1 = TYPEAHEAD_BUF, P2 = 8);1%IF NOT .STATUS THEN RETURN (.STATUS);R3IF NOT .INPUT_IOSB[0] THEN RETURN (.INPUT_IOSB[0]); !+! Process any pending input.!-)IF .TYPEAHEAD_BUF [TYPEAHEAD_COUNT] NEQ 0nTHEN BEGIN$" STATUS = DTK$$GET_STATUS(VCB);) IF NOT .STATUS THEN RETURN (.STATUS);- END;!+-! If keypad input has already been entered orR*! we don't have any text to speak, return.!-LIF (.TEXT_LEN EQL 0) OR (.VCB[VCB_W_LENGTH] NEQ 0) THEN RETURN (SS$_NORMAL);!++! Issue a QIO to start speaking the string.i!-'STATUS = $QIO( CHAN = .VCB[VCB_W_CHAN],u EFN = .DTK_L_EFN,r( FUNC = IO$_WRITEVBLK OR IO$M_NOFORMAT, IOSB = OUTPUT_IOSB,e P1 = .TEXT_ADR,s P2 = .TEXT_LEN);%IF NOT .STATUS THEN RETURN (.STATUS);E!+*! Issue a QIO to read in the keypad input.B! NOTE:: The DTC01 does NOT send any unsolicited escape sequences.!-'STATUS = $QIO( CHAN = .VCB[VCB_W_CHAN],R EFN = .DTK_L_EFN_2, IOSB = INPUT_IOSB,% FUNC = IO$_READVBLK OR IO$M_NOECHO,e" P1 = .STR_DESC[DSC$A_POINTER], P2 = .STR_DESC[DSC$W_LENGTH] );%IF NOT .STATUS THEN RETURN (.STATUS); !+(! Wait for one of the QIO's to complete.!-:STATUS = $WFLOR(EFN = .DTK_L_EFN, MASK = .DTK_L_EFN_MASK);%IF NOT .STATUS THEN RETURN (.STATUS);!+! Cancel the remaining QIO.l!-*STATUS = $CANCEL(CHAN = .VCB[VCB_W_CHAN]);%IF NOT .STATUS THEN RETURN (.STATUS);!+E! At this point, an I/O has completed. Check to see which one it is.!!- IF .INPUT_IOSB[0] EQL SS$_NORMALTHEN !+7 ! The input QIO has completed. The user pressed a D' ! phone keypad key. Stop speaking. . ! Wait for the output QIO to be cancelled. !-! BEGIN ! Input QIO completed : STATUS = $SYNCH(EFN = .DTK_L_EFN, IOSB = OUTPUT_IOSB);) IF NOT .STATUS THEN RETURN (.STATUS); : STATUS = DTK$SET_SPEECH_MODE(P_VCB, %REF(DTK$K_HALT));) IF NOT .STATUS THEN RETURN (.STATUS);C !+? ! Place the input in the user input buffer, which is just a6: ! long dynamic string maintained by the STR$ routines. !-3 IF CH$RCHAR(.STR_DESC[DSC$A_POINTER]) NEQ K_ESCD THEN O BEGIN- STATUS = STR$CONCAT( VCB[VCB_Q_INPUT_DESC], I VCB[VCB_Q_INPUT_DESC], STR_DESC);& IF NOT .STATUS THEN RETURN (.STATUS); END END ! Input QIO completedELSE !+% ! The output QIO has completed. T- ! Wait for the input QIO to be cancelled.I !-" BEGIN ! Output QIO completed; STATUS = $SYNCH(EFN = .DTK_L_EFN_2, IOSB = INPUT_IOSB); ) IF NOT .STATUS THEN RETURN (.STATUS);A! END; ! Output QIO completeduRETURN (.STATUS);n&END; ! End of routine DTK$$SIM_AUTO !, -%SBTTL 'DTK$$VCB_EXIT_HANDLER - Exit handler'I3ROUTINE DTK$$VCB_EXIT_HANDLER ( P_REASON, P_VCB ) =t!++e! FUNCTIONAL DESCRIPTION: !D1! This routine gets called on image exit once for 2! each active VCB. It flushes the output on that 1! device and resets the terminal characteristics.T!B! CALLING SEQUENCE:!MA! ret_status.wlc.v = DTK$$VCB_EXIT_HANDLER ( P_REASON.rl.r,:! P_VCB.rab.r )[!$! FORMAL PARAMETERS:!D5! P_REASON Address of word that contains exit reason. %! Should be VCB[VCB_L_EXIT_REASON].+! 8! P_VCB.rab.r The voice control block address for which )! the flushing action is to take place.5!a! IMPLICIT INPUTS:!n! contents of VCBD!f! IMPLICIT OUTPUTS:.! C! VCB[VCB_W_OUTPUT_BUFLEN] set to 0 (indicating buffer empty) !e! COMPLETION STATUS:!a4! SS$_NORMAL Normal successful completion!s! SIDE EFFECTS:u! ! NONE!--s sBEGIN,LOCALa QIO_IOSB : VECTOR[4,WORD];BIND VCB = .P_VCB : $VCB_DECL;!+&! Flush any remaining buffered output.! Hangup the phone. .! Reset the original terminal characteristics.! Disconnect from any LAT port.T!-"$CANCEL (CHAN = .VCB[VCB_W_CHAN]);8IF .VCB [VCB_V_BUF_ENABLED] THEN DTK$$FLUSH_BUFFER(VCB);BIF .VCB [VCB_V_OFFHOOK] THEN DTK$HANGUP_PHONE(VCB[VCB_L_VID]);$QIOW( CHAN = .VCB[VCB_W_CHAN],h EFN = .DTK_L_EFN,e IOSB = QIO_IOSB,c FUNC = IO$_SETMODE, P1 = VCB[VCB_R_CHARBUF],e P2 = 12);$QIOW( CHAN = .VCB[VCB_W_CHAN],  EFN = .DTK_L_EFN,' FUNC = IO$_TTY_PORT OR IO$M_LT_DISCON,s IOSB = QIO_IOSB);RETURN (SS$_NORMAL);&END; ! Routine DTK$$VCB_EXIT_HANDLER !S O"%SBTTL 'OUTPUT - Low level output')ROUTINE OUTPUT(P_VCB,TEXT_LEN,TEXT_ADR) = !++ ! FUNCTIONAL DESCRIPTION:t!s,! Handles low level output by issuing a QIO.! No buffering occurs here.! ! CALLING SEQUENCE:f! ! ret_status.wlc.v = OUTPUT(! P_VCB.rab.r,.! TEXT_LEN.rl.v, ! TEXT_ADR.rt.r)w! ! FORMAL PARAMETERS:!t.! P_VCB.rab.r Address of voice control block.! 4! TEXT_LEN.rl.v Number of characters in text string!S0! TEXT_ADR.rt.r Address of start of text string+! The text may contain escape sequences.D! ! IMPLICIT INPUTS:!E! Contents of VCB.!c! IMPLICIT OUTPUTS:D!T! NONE!l! COMPLETION STATUS:!I)! SS$_NORMAL Normal successful completionD! SS$_xyz errors from QIO! SS$_xyz errors from $ASSIGN!;! SIDE EFFECTS: !D! NONE!--D NBEGIN=BIND0 VCB = .P_VCB : $VCB_DECL; ! voice control blockLOCAL!) STATUS, ! Status returned by routinesD QIO_IOSB : VECTOR[4, WORD];!+&! Null strings succeed no matter what.!-,IF .TEXT_LEN EQL 0 THEN RETURN (SS$_NORMAL);!+#! Issue a QIO to output the string. !-&STATUS=$QIOW( CHAN = .VCB[VCB_W_CHAN], EFN = .DTK_L_EFN,( FUNC = IO$_WRITEVBLK OR IO$M_NOFORMAT, IOSB = QIO_IOSB, P1 = .TEXT_ADR,I P2 = .TEXT_LEN);%IF NOT .STATUS THEN RETURN (.STATUS);c/IF NOT .QIO_IOSB[0] THEN RETURN (.QIO_IOSB[0]);kRETURN (SS$_NORMAL);END; ! End of routine OUTPUTVEND ! End of module DTK$UTIL)ELUDOMEN RETURN (.STATUS); G CH$FILL (0, VCB_K_SIZE, ..VCB_ADR); ! [~ DTKALPHA.SAVA<  [DIETER.DTKALPHA]DTKVECTOR.MAR;1M  *[DIETER.DTKALPHA]DTKVECTOR.MAR;1+,A<. / ) 4M - 0123KPWO 56@u47@u489G )HJ1 .TITLE DTK$VECTOR - Entry vectors for DTKSHR.EXE4 .IDENT /1-002/ ; File: DTKVECTOR.MAR Edit: TS1002;M;****************************************************************************;* *?;* COPYRIGHT (c) 1978, 1980, 1982, 1984, 1985, 1986 BY *A;* DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS. *#;* ALL RIGHTS RESERVED. *;* *M;* THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED *M;* ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE *M;* INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER *M;* COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY *M;* OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY *;* TRANSFERRED. *;* *M;* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE *M;* AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT *;* CORPORATION. *;* *M;* DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS *B;* SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. *;* *;* *M;****************************************************************************;;++1; FACILITY: Run-Time Library - DECtalk Management; ; ABSTRACT:;;; This module contains the entry vector definitions for the4; VAX-11 Run-Time Library shareable image DTKSHR.EXE;'; ENVIRONMENT: User mode, AST Reentrant;3; AUTHOR: Tom Scarpelli, CREATION DATE: 19-Aug-1985;; MODIFIED BY:;-; 1-002 - Add DTK$SPELL_TEXT. TS 30-Jul-1986"; 1-001 - Original. TS 19-Aug-1985;--  .SBTTL DECLARATIONS;; LIBRARY MACRO CALLS:;; NONE;; EXTERNAL DECLARATIONS:;8 .DSABL GBL ; Force all external symbols to be declared; ; MACROS:;;+8; Macro to define an entry vector for a CALL entry point;- .MACRO VCALL NAME .EXTRN NAME .ALIGN QUAD .TRANSFER NAME .MASK NAME JMP NAME+2 .ENDM;+7; Macro to define an entry vector for a JSB entry point;- .MACRO VJSB NAME .EXTRN NAME .ALIGN QUAD .TRANSFER NAME JMP NAME .BLKB 2 .ENDM;+=; Macro to define an open entry vector for a CALL entry point;- .MACRO VOPEN NAME .EXTRN NAME .ALIGN QUAD .MASK NAME JMP NAME+2 .ENDM;; EQUATED SYMBOLS:;; NONE;; OWN STORAGE:;; NONE;; PSECT DECLARATIONS:;4 .PSECT $$DTK$VECTOR PIC, USR, CON, REL, LCL, SHR, - EXE, RD, NOWRT, QUAD .IF DF, VAX .SBTTL DTKSHR Vector;+E; Define vectored entry points for the DECtalk Management Procedures.;3; Any additions to this file should be reflected inG; COM$:DTKSHRVEC.DAT. All new entry points must be appended to the endF; of the list. NEVER change existing entries unless you are sure that,; what you do won't break existing programs.;-; Module DTK$UTIL VCALL DTK$ANSWER_PHONE VCALL DTK$DIAL_PHONE VCALL DTK$HANGUP_PHONE VCALL DTK$INITIALIZE VCALL DTK$LOAD_DICTIONARY VCALL DTK$OUTPUT VCALL DTK$READ_KEYSTROKE VCALL DTK$READ_STRING VCALL DTK$RETURN_LAST_INDEX VCALL DTK$SET_INDEX VCALL DTK$SET_KEYPAD_MODE VCALL DTK$SET_LOGGING_MODE VCALL DTK$SET_MODE VCALL DTK$SET_SPEECH_MODE VCALL DTK$SET_TERMINAL_MODE VCALL DTK$SET_VOICE VCALL DTK$SPEAK_FILE VCALL DTK$SPEAK_PHONEMIC_TEXT VCALL DTK$SPEAK_TEXT VCALL DTK$TERMINATE;+; Entries for VMS V4.6:;- VCALL DTK$SPELL_TEXT VCALL DTK$CHECK_HDWR_STATUS VCALL DTK$RUN_SELF_TEST;+F; Used for future growth. Replace the VOPEN with the appropriate VCALL;- VOPEN DTK$NOT_IMPLEMENTED VOPEN DTK$NOT_IMPLEMENTED VOPEN DTK$NOT_IMPLEMENTED VOPEN DTK$NOT_IMPLEMENTED VOPEN DTK$NOT_IMPLEMENTED VOPEN DTK$NOT_IMPLEMENTED VOPEN DTK$NOT_IMPLEMENTED VOPEN DTK$NOT_IMPLEMENTED VOPEN DTK$NOT_IMPLEMENTED .ENDC$ .END ; End of module DTK$VECTOR *[DIETER.DTKALPHA]SMGRTLASM.DAT;1+,7. / ) 4M - 0123KPWO 56M%p<7(r<89G )HJ!++<! SMGRTLASM.DAT - compilation data file for facility SMGRTL.!3! 1-001 - adapted from RTLASM.DAT. MDL 22-Aug-1983+! 1-002 - add checkpoints. MDL 25-Aug-1983B! 1-003 - Add SMG output modules, autobended modules and termtable! modules. LEB 6-Mar-1984.! 1-004 - Removed SMGDELGBL. STAN 12-Mar-1984.5! 1-005 - Remove autobended modules. PLL 25-Jun-1984+! 1-006 - Add SMGDISUSR.B32. TS 8-Mar-1985=! 1-007 - Compile Bliss sources /OPT:LEVEL:3. TS 22-Jul-1985A! 1-008 - Compile Bliss sources /OPT:SPEED also. MDL 21-Aug-1985*! 1-009 - Add DTK facility. TS 6-Sep-1985G! 1-010 - Add SMGNONSDL to get SMG global symbols from BASIC and COBOL.! JCW 14-Nov-19852! 1-011 - Add new VMS V5.0 modules. TS 7-Oct-1986I! 1-012 - Move DEFINEs here from SMGRTLBLD. Remove OLB. MDL 23-Nov-1987M! 1-013 - Remove SMGKEYUTI as SMG$$TERM_TO_KEYCODE is moved to SMGKEYPAD for &! source code merge. IYS 30-Dec-1991J! 1-014 - Merged VMS version with changes made for Alpha. JSY 20-Jan-1992G! 1-015 - Added /TIE compile qualifier to SMGDISSUB.B32 and SMGMISC.B32! JSY 13-Mar-1992J! 1-016 - Add /TIE compile qualifier to modules that contain routines that:! can be called from external routines. JSY 27-Jul-1992H! 1-017 - Removed the temp lines that previously compiled the SMGSTRTAB C! module with the GEM26-based BLISS at VMS request. This module C! no longer gets the UNAVOLACC warnings with the default GEM and ;! no source code changes were necessary. SDL 31-Aug-1994!--$ !&$ ! assign RTL-specific logical names.$ !$ DEFINE RTLIN SRC$:$ DEFINE RTLML LIB$:+$ DEFINE RTLSTARLE SYS$LIBRARY:STARLET.L32)$ DEFINE RTLTPAMAC SYS$LIBRARY:TPAMAC.L32$$ DEFINE RTLLIB SYS$LIBRARY:LIB.L32!!! MACRO routines!2$ LANG:=MACRO;ML1:=;OPT:=/ENABLE=SUPPRESSION;OLB:=!%DTKVECTOR/DTKVECTOR%SMGVECTOR/SMGVECTOR@10!;$ OPT:=/ENABLE=SUPPRESSION/DISABLE=(GLOBAL,TRACEBACK);OLB:=!%SMGNONSDL/SMGNONSDL@20!! BLISS routines!$ LANG:=BLISS;ML1:=;OPT:=/TIE4$ IF VAX THEN OPT:=/NOTRACE/OPTIMIZE=(LEVEL:3,SPEED)!%SMGALLESC/SMGALLESC%SMGBLDTRM/SMGBLDTRM%SMGDISCHA/SMGDISCHA%SMGDISDHW/SMGDISDHW%SMGDISDRW/SMGDISDRW@30%SMGDISHLP/SMGDISHLP%SMGDISINP/SMGDISINP%SMGDISLIN/SMGDISLIN%SMGDISOUT/SMGDISOUT%SMGDISSUB/SMGDISSUB%SMGDISUSR/SMGDISUSR@40%SMGINPUT/SMGINPUT%SMGKEYPAD/SMGKEYPAD%SMGMAPTRM/SMGMAPTRM%SMGMIN/SMGMIN%SMGMINUPD/SMGMINUPD@50%SMGMISC/SMGMISC%SMGPUTENC/SMGPUTENC%SMGSELECT/SMGSELECT%SMGUSRTRM/SMGUSRTRM%SMGWINDOW/SMGWINDOW@60!M! The following SMG modules contain only local routines. They should not be #! compiled with the /TIE qualifier.!$ IF EVAX THEN OPT:=%SMGBOOTAB/SMGBOOTAB%SMGNUMPAR/SMGNUMPAR%SMGNUMTAB/SMGNUMTAB%SMGPRVINP/SMGPRVINP%SMGPUTTEX/SMGPUTTEX@70%SMGSCROLL/SMGSCROLL%SMGSIMTRM/SMGSIMTRM%SMGSTATAB/SMGSTATAB%SMGSTRTAB/SMGSTRTAB%SMGSTR2TAB/SMGSTR2TAB@80!! DECtalk modules!$ LANG:=BLISS;ML1:=;OPT:=/TIE4$ IF VAX THEN OPT:=/NOTRACE/OPTIMIZE=(LEVEL:3,SPEED)$ OLB:=%DTKUTIL/DTKUTIL@90! ! CLD modules!$ LANG:=CLD;OPT:=;OLB:=!%SMGDEFKEY/SMGDEFKEY!! End of file SMGRTLASM.DAT *[DIETER.DTKALPHA]SMGRTLBLD.COM;1+,7e.$/ ) 4V$"F- 0123KPWO%56zݘ72Mzݘ89G )HJD$ !++=$ ! SMGRTLBLD.COM - build the component SMGRTL (SMGSHR.EXE)./$ ! See edit history at the end of this file.$ !-- $ ON SEVERE_ERROR THEN GOTO FAIL$ ON ERROR THEN CONTINUE$ !$ ! branch to phase to be run.$ ! $ STATUS = 1$ GOTO 'PHASE'$ !$ !$ !$INIT:$ !+$ ! INIT phase $ !-$ !*$ ! create directories on the target disk.$ !$ @SYSBLDCOM$:CREATEDIR$ ! $ GOTO EXIT$ !+$ ! end of INIT phase$ !-$UPDATE:$ !+$ ! UPDATE phase$ !-$ ! $ SET NOON$ !C$ ! delete the files we are about to create (from previous builds).$ !)$ DELETE OBJ$:*.*;*,LIS$:*.*;*,LIB$:*.*;*$ !C$ SRCUPDATE SMG$ARCHITECTURE.COM ! Define the architecture symbols.$ @SRC$:SMG$ARCHITECTURE.COM$ !$ DELSHRLIB SRC$:SMGLNK.REQ$ DELSHRLIB SRC$:SMGTERM.REQ$ !"$ IF VAX THEN REMSHRLIB STRLNK.REQ"$ IF VAX THEN REMSHRLIB RTLLIB.L32$ !8$ ! create new updated files not updated in ASSEM phase.$ !$ SRCUPDATE DTK$ROUTINES.SDL$ SRCUPDATE DTKDATSTR.REQ$ SRCUPDATE DTKMACROS.REQ$ SRCUPDATE DTKPROLOG.REQ$ ! $ SRCUPDATE SMG$ARCHITECTURE.REQ$ SRCUPDATE SMGKCB.SDL$ SRCUPDATE SMGKDE.SDL$ SRCUPDATE SMGKQB.SDL$ SRCUPDATE SMGKTH.SDL$ SRCUPDATE SMGDATSTR.REQ$ SRCUPDATE SMGLIB.REQ$ SRCUPDATE SMGLNK.REQ$ SRCUPDATE SMGMACROS.REQ$ SRCUPDATE SMGPROLOG.REQ$ SRCUPDATE SMGSCRMAC.REQ$ SRCUPDATE SMGSCRTCB.REQ$ SRCUPDATE SMGTABDEF.REQ$ SRCUPDATE SMGTERM.REQ$ SRCUPDATE SMGTPALIB.REQ$ SRCUPDATE SMGTPACTL.REQ$ SRCUPDATE SMGTRMMAC.REQ$ SRCUPDATE SMGTRMSTR.R32$ !$ !K$ ! run SDL conversions for VMSLIB component to use in SRCLIB (next) phase.$ !-$ SDL/NOLIST/LANG=(BLISSF=LIB$:) SRC$:SMGKCB-$ SDL/NOLIST/LANG=(BLISSF=LIB$:) SRC$:SMGKDE-$ SDL/NOLIST/LANG=(BLISSF=LIB$:) SRC$:SMGKQB-$ SDL/NOLIST/LANG=(BLISSF=LIB$:) SRC$:SMGKTH/$ ! $ !;$ ! share require files w/other component(s) that use them.$ !$ !?$ CPYSHRLIB SRC$:SMGLNK.REQ ! share file with COBRTL component@$ CPYSHRLIB SRC$:SMGTERM.REQ ! share file with COBRTL component$ SET ON$ !2$ ! get rid of old versions of files just updated.$ ! $ PURGE SRC$: $ GOTO EXIT$ !+$ ! end of UPDATE phase$ !-$SRCLIB:$ !+$ ! SRCLIB phase $ !-$ @SRC$:SMG$ARCHITECTURE.COM$ !;$ ! delete assembly checkpoint file (from previous builds).$ !$ DELETE FASMCHECK.CHK;*$ !C$ ! delete the files we are about to create (from previous builds).$ !J$ DELETE LIB$:DTKRTL.OLB;*,DTKMSGPTR.OLB;*,DTKMSGTXT.OLB;*,DTKVECTRS.OLB;*$ !$ DELETE LIB$:SMGRTL.MLB;*J$ DELETE LIB$:SMGRTL.OLB;*,SMGMSGPTR.OLB;*,SMGMSGTXT.OLB;*,SMGVECTRS.OLB;*$ !>$ ! get library/require files from other components as needed.$ !"$ IF VAX THEN GETSHRLIB STRLNK.REQ$ !A$ ! move files just obtained into other subdirectories as needed.$ !*$ IF VAX THEN RENAME LIB$:STRLNK.REQ SRC$:$ !B$ ! create macro source libraries. insert modules as appropriate.$ !&$ LIBRARY/CREATE/MACRO LIB$:SMGRTL.MLB.$ LIBRARY/MACRO LIB$:SMGRTL SHRLIB$:SMGDEF.MAR$ !M$ ! create object libraries. these will be filled in during the ASSEM phase.$ !#$ LIBRARY/CREATE/OBJECT LIB$:DTKRTL&$ LIBRARY/CREATE/OBJECT LIB$:DTKMSGPTR&$ LIBRARY/CREATE/OBJECT LIB$:DTKMSGTXT&$ LIBRARY/CREATE/OBJECT LIB$:DTKVECTRS$ !#$ LIBRARY/CREATE/OBJECT LIB$:SMGRTL&$ LIBRARY/CREATE/OBJECT LIB$:SMGMSGPTR&$ LIBRARY/CREATE/OBJECT LIB$:SMGMSGTXT&$ LIBRARY/CREATE/OBJECT LIB$:SMGVECTRS$ !&$ ! assign RTL-specific logical names.$ !$ DEFINE RTLIN SRC$:$ DEFINE RTLML LIB$:+$ DEFINE RTLSTARLE SYS$LIBRARY:STARLET.L32)$ DEFINE RTLTPAMAC SYS$LIBRARY:TPAMAC.L32$$ DEFINE RTLLIB SYS$LIBRARY:LIB.L32$ !K$ ! create the Bliss source library SMGLIB. For this to work in the systemI$ ! build, this is done after all other facilities have completed in the J$ ! SRCLIB phase (coordinated by running this facility in SRCLIB_1). This!$ ! has no impact for FACTSTBLDs.$ !$ DELSHRLIB LIB$:SMGLIB.L32$ !,$ DELETE LIS$:SMGLIB.L32;*,LIS$:SMGLIB.LIS;*;$ BLISS/LIBRARY=LIB$:/LIST=LIS$:/SOURCE=REQUIRE SRC$:SMGLIB$ !@$ ! Create a BLISS source library specific to TERMTABLE support.$ !2$ DELETE LIS$:SMGTPALIB.L32;*,LIS$:SMGTPALIB.LIS;*C$ BLISS/LIBRARY=LIB$:SMGTPALIB/LIST=LIS$:SMGTPALIB/SOURCE=REQUIRE - SRC$:SMGTPALIB$ !/$ ! share bliss libraries with other facilities$ !?$ CPYSHRLIB LIB$:SMGLIB.L32 ! Share file with COBRTL component$ !$ !($ ! deassign RTL-specific logical names.$ !$ DEASSIGN RTLIN$ DEASSIGN RTLML$ DEASSIGN RTLSTARLE$ DEASSIGN RTLTPAMAC$ DEASSIGN RTLLIB$ ! $ GOTO EXIT$ !+$ ! end of SRCLIB phase$ !-$ASSEM:$ !+$ ! ASSEM phase $ !-$ !J$ ! create bliss source libraries. this can't be done in the SRCLIB phaseM$ ! because references are made to STARLET.L32, which didn't exist until now.$ !M$ ! SMGLIB.L32 WAS CREATED IN THE PREVIOUS (SRCLIB) PHASE. THIS IS A SPECIALJ$ ! CASE SO THAT ALL OF THE VARIOUS RTL FACILITIES CAN RUN CONCURRENTLY INJ$ ! THE ASSEM PHASE. THIS IS DONE BY A SPECIAL PHASE CALLED SRCLIB_1 WHENB$ ! RUNNING THE SYSTEM BUILD. THERE IS NO IMPACT FOR A FACTSTBLD.$ !?$ ! get bliss source libraries from other facilities as needed.$ !$ @SRC$:SMG$ARCHITECTURE.COM"$ IF VAX THEN GETSHRLIB RTLLIB.L32$ !N$ ! delete the files we are about to create (from previous builds); cannot useL$ ! wildcard delete because library listings and object libraries were just $ ! created. So just PURGE.$ ! $ PURGE LIS$: $ PURGE OBJ$:$ !H$ ! Create the message files, commands are included here since they were@$ ! ignored when included in the asm.dat file for this facility.$ !L$ MESSAGE/NOSYMBOLS/LIS=LIS$:DTKMSGTXT/OBJ=OBJ$:DTKMSGTXT shrlib$:DTKMSG.MSGV$ MESSAGE/FILE_NAME=SHRIMGMSG/LIS=LIS$:DTKMSGPTR/OBJ=OBJ$:DTKMSGPTR shrlib$:DTKMSG.MSGL$ MESSAGE/NOSYMBOLS/LIS=LIS$:SMGMSGTXT/OBJ=OBJ$:SMGMSGTXT shrlib$:SMGMSG.MSGV$ MESSAGE/FILE_NAME=SHRIMGMSG/LIS=LIS$:SMGMSGPTR/OBJ=OBJ$:SMGMSGPTR shrlib$:SMGMSG.MSG$ !$ !M$ ! invoke system build assembly procedure to perform assemblies. This will N$ ! compile all modules as specified in SMGRTLASM.DAT. Objects will be placedC$ ! in libraries according to SMGRTLASM.DAT specifications as well.$ !+$ @SYSBLDCOM$:FASM SMGRTL "" Y 'UPDATES N Y$ !2$ ! purge again. this ensures minimal disk usage.$ ! $ PURGE LIS$: $ PURGE OBJ$:$ ! $ GOTO EXIT$ !+$ ! end of ASSEM phase$ !-$OBJLIB:$ !+$ ! OBJLIB phase $ !-$ @SRC$:SMG$ARCHITECTURE.COM$ !E$ ! Create facility object libraries from object modules built during$ ! the previous (ASSEM) phase.$ !8$ LIBRARY/OBJECT LIB$:SMGMSGTXT.OLB OBJ$:SMGMSGTXT.OBJ; $ DELETE OBJ$:SMGMSGTXT.OBJ;$ !8$ LIBRARY/OBJECT LIB$:SMGMSGPTR.OLB OBJ$:SMGMSGPTR.OBJ; $ DELETE OBJ$:SMGMSGPTR.OBJ;$ !8$ LIBRARY/OBJECT LIB$:SMGVECTRS.OLB OBJ$:SMGVECTOR.OBJ; $ DELETE OBJ$:SMGVECTOR.OBJ;$ !0$ LIBRARY/OBJECT LIB$:SMGRTL.OLB OBJ$:SMG*.OBJ;$ DELETE OBJ$:SMG*.OBJ;$ !8$ LIBRARY/OBJECT LIB$:DTKMSGTXT.OLB OBJ$:DTKMSGTXT.OBJ; $ DELETE OBJ$:DTKMSGTXT.OBJ;$ !8$ LIBRARY/OBJECT LIB$:DTKMSGPTR.OLB OBJ$:DTKMSGPTR.OBJ; $ DELETE OBJ$:DTKMSGPTR.OBJ;$ !8$ LIBRARY/OBJECT LIB$:DTKVECTRS.OLB OBJ$:DTKVECTOR.OBJ; $ DELETE OBJ$:DTKVECTOR.OBJ;$ !0$ LIBRARY/OBJECT LIB$:DTKRTL.OLB OBJ$:DTK*.OBJ;$ DELETE OBJ$:DTK*.OBJ;$ !$ !O$ ! extract message pointer object files from message object library and insert&$ ! them into facility object library.$ !9$ LIBRARY/EXTRACT=*/OUT=OBJ$:DTKMSGPTR.OBJ LIB$:DTKMSGPTR($ LIBRARY LIB$:DTKRTL OBJ$:DTKMSGPTR.OBJ$ DELETE OBJ$:DTKMSGPTR.OBJ;$ !9$ LIBRARY/EXTRACT=*/OUT=OBJ$:SMGMSGPTR.OBJ LIB$:SMGMSGPTR($ LIBRARY LIB$:SMGRTL OBJ$:SMGMSGPTR.OBJ$ DELETE OBJ$:SMGMSGPTR.OBJ;$ !L$ ! extract individual vector object files from vector object library, to be6$ ! used in next phase to link the shareable image(s).$ !B$ LIBRARY/EXTRACT=DTK$VECTOR/OUT=OBJ$:DTKVECTOR.OBJ LIB$:DTKVECTRSB$ LIBRARY/EXTRACT=SMG$VECTOR/OUT=OBJ$:SMGVECTOR.OBJ LIB$:SMGVECTRS$ !M$ ! share the object library for this facility with other facilities that may $ ! need it.$ !$ CPYRESOBJ LIB$:DTKRTL.OLB$ CPYRESOBJ LIB$:SMGRTL.OLB$ !5$ ! cause SMG messages to be built into SHRIMGMSG.EXE$ ! ?$ LIBRARY/EXTRACT=DTK$MSGDEF/OUT=OBJ$:DTKMSG.OBB LIB$:DTKMSGTXT$ CPYSYSMSG OBJ$:DTKMSG.OBB$ !?$ LIBRARY/EXTRACT=SMG$MSGDEF/OUT=OBJ$:SMGMSG.OBB LIB$:SMGMSGTXT$ CPYSYSMSG OBJ$:SMGMSG.OBB$ ! $ GOTO EXIT$ !+$ ! end of OBJLIB phase$ !-$LNKLIB:$ !+$ ! LNKLIB phase $ !-$ !C$ ! delete the files we are about to create (from previous builds).$ !$ @SRC$:SMG$ARCHITECTURE.COM,$ DELETE EXE$:DTKSHR.EXE;*,MAP$:DTKSHR.MAP;*,$ DELETE EXE$:SMGSHR.EXE;*,MAP$:SMGSHR.MAP;*$ !5$ ! link the Run-Time Library Shareable Image SMGSHR.$ !$ IF VAX$ THENL$ LINK/NOSYSLIB/NOTRACEBACK/SHARE=EXE$:SMGSHR/MAP=MAP$:SMGSHR/FULL/CROSS - COM$:SMGSHRLNK/OPTIONS$ ENDIF$ ! $ IF EVAX$ THEN9$ LINK/NOSYSLIB/NOTRACEBACK/SECTION/SHARE=EXE$:SMGSHR -4 /MAP=MAP$:SMGSHR/FULL/CROSS/SYMBOL=EXE$:SMGSHR -5 COM$:SMGSHRLNK/OPTIONS,RESOBJ$:BASE_LEVEL/OPTIONS$ ENDIF$ !$ IF VAX$ THENL$ LINK/NOSYSLIB/NOTRACEBACK/SHARE=EXE$:DTKSHR/MAP=MAP$:DTKSHR/FULL/CROSS - COM$:DTKSHRLNK/OPTIONS$ ENDIF$ ! $ IF EVAX$ THEN9$ LINK/NOSYSLIB/NOTRACEBACK/SECTION/SHARE=EXE$:DTKSHR -! /MAP=MAP$:DTKSHR/FULL/CROSS -5 COM$:DTKSHRLNK/OPTIONS,RESOBJ$:BASE_LEVEL/OPTIONS$ ENDIF$ !M$ ! copy it into it's destination on the result disk, and insert it into the "$ ! shareable image library there.$ !$ CPYSYSLIB EXE$:DTKSHR.EXE$ CPYSYSLIB OBJ$:DTKVECTOR.OBJ $ INSHARLIB EXE$:DTKSHR$ !$ CPYSYSLIB EXE$:SMGSHR.EXE$ CPYSYSLIB EXE$:SMGSHR.STB$ CPYSYSLIB OBJ$:SMGVECTOR.OBJ $ INSHARLIB EXE$:SMGSHR$ ! $ GOTO EXIT$ !+$ ! end of LNKLIB phase$ !-$LINK:$ !+$ ! LINK phase $ !-$ @SRC$:SMG$ARCHITECTURE.COM$ ! $ ! Link the termtable compiler.$ !$ IF VAX$ THENC$ LINK/EXE=EXE$:SMGBLDTRM/MAP=MAP$:SMGBLDTRM/FULL/CROSS/NOTRACE -M COM$:SMGBLDTRM/OPTIONS$ ENDIFG$ !S $ IF EVAX$ THENC$ LINK/EXE=EXE$:SMGBLDTRM/MAP=MAP$:SMGBLDTRM/FULL/CROSS/NOTRACE - 5 COM$:SMGBLDTRM/OPTIONS,RESOBJ$:BASE_LEVEL/OPTIONSn$ ENDIFs$ !b4$ ! Link the program that creates the global section$ !$ IF VAX$ THENC$ LINK/NOTRACE/EXE=EXE$:SMGMAPTRM/MAP=MAP$:SMGMAPTRM/FULL/CROSS -. COM$:SMGMAPTRM/OPTIONS$ ENDIF$ !O $ IF EVAX $ THENC$ LINK/NOTRACE/EXE=EXE$:SMGMAPTRM/MAP=MAP$:SMGMAPTRM/FULL/CROSS -5 COM$:SMGMAPTRM/OPTIONS,RESOBJ$:BASE_LEVEL/OPTIONSo$ ENDIFf$ !rK$ ! invoke system build vector test procedure to be sure the vectored entryR1$ ! points in the shareable image(s) are correct.u$ !m/$ IF VAX THEN @SYSBLDCOM$:VECTORTST EXE$:DTKSHRS/$ IF VAX THEN @SYSBLDCOM$:VECTORTST EXE$:SMGSHRR$ ! $ GOTO EXITT$ !+$ ! end of LINK phaseF$ !T$RESULT:$ !+$ ! RESULT phase$ !-$ @SRC$:SMG$ARCHITECTURE.COM$ ! "$ ! copy SMGBLDTRM.EXE to [SYSEXE]$ !N$ CPYRESEXE EXE$:SMGBLDTRM.EXE$ ! "$ ! Copy SMGMAPTRM.EXE to [SYSEXE]$ !P$ CPYRESEXE EXE$:SMGMAPTRM.EXE$ !H?$ ! Copy the SMGTERMS.TXT and TERMTABLE.TXT files into [SYSEXE]R<$ ! as well. These files are copied unmodified to [SYSEXE].$ !E$ CPYRESEXE COM$:SMGTERMS.TXTR$ CPYRESEXE COM$:TERMTABLE.TXT$ !CH$ ! Now run the termtable compiler which we just created (SMGBLDTRM.EXE)<$ ! which will read in the TERMTABLE.TXT file and which willJ$ ! create the TERMTABLE.EXE file which will be mapped as a global section6$ ! by program SMGMAPTRM.EXE which we also just built.G$ ! By defining logical name TERMTABLE to point to RESEXE$, this causespH$ ! the compiler to take input from TERMTABLE.TXT on RESEXE$ and produce8$ ! TERMTABLE.EXE on RESEXE$ which we then move to EXE$.$ !I.$ DEFINE/USER_MODE TERMTABLE RESEXE$:TERMTABLE1$ DEFINE/USER_MODE SMGTERMS RESEXE$:SMGTERMS.TXT $ ! I$ ! The following two lines cause TERMTABLE.EXE to be generated using themI$ ! compiler just built. However, when building ALPHA images on VAX thisn7$ ! will not work. Use the system default one instead.R$ !mH$ ! Now that ALPHA builds are native, use the 'just-built' smgbldtrm.exe!$ ! to generate the termtable.exe$ !+$ ! $ IF VAX T$ THEN 5$ DEFINE/USER_MODE LIBRTL SYS$LIBRARY:LIBRTL.EXE:O$ RUN EXE$:SMGBLDTRM ! Gets inputs and puts outputs from/to RESEXE$:TERMTABLEi$ ENDIF $ ! $ IF EVAX $ THEN *O$ RUN EXE$:SMGBLDTRM ! Gets inputs and puts outputs from/to RESEXE$:TERMTABLE$ ENDIFE"$ COPY RESEXE$:TERMTABLE.EXE EXE$:$ !T0$ ! Copy the resulting TERMTABLE.EXE to [SYSEXE]$ !B$ CPYRESEXE EXE$:TERMTABLE.EXE$ !P$ !B $ GOTO EXITO$ !+$ ! end of RESULT phase $ !-$ !/$QUAL:$ !+$ ! QUAL phase$ !-$ !eJ$ ! Invoke sytem build vector test procedure to be sure the vectored entryG$ ! points in the shareable image(s) are correct. This is done in QUALL$$ ! to not slow down the main build.$ !o6$ @SYSBLDCOM$:SYMVECTST EXE$:SMGSHR COM$:SMGSHRVEC.DAT$ !I@$ ! Check the IIF files against the native shareable images.$ !:O$ @SYSBLDCOM$:Symvectst.Com 'Targdev'[SYSLIB]DTKSHR 'Targdev'[SYSLIB]DTKSHR.IIFeO$ @SYSBLDCOM$:Symvectst.Com 'Targdev'[SYSLIB]SMGSHR 'Targdev'[SYSLIB]SMGSHR.IIFC$ !$ $ GOTO EXIT $ !+$ ! end of RESULT phaseS$ !-$ !R$ ! failure exit I$ !K$FAIL:$ STATUS = $STATUS$ !J$ ! common exit$ !R$EXIT:$ !J%$ ! exit, returning status to caller.J$ !I $ EXIT STATUS $ !++/$ !E=$ ! SMGRTLBLD.COM - build the component SMGRTL (SMGSHR.EXE).a<$ ! assumes definitions for: LIB$, LIS$, SRC$, EXE$, MAP$,$ ! OBJ$ and SYSBLDCOM$.5$ ! assumes existence of: SYSBLDCOM$:CREATEDIR.COM$ ! SYSBLDCOM$:FASM.COMB"$ ! SYSBLDCOM$:VECTORTST.COM"$ ! SYSBLDCOM$:SYMVECTST.COM$ !t1$ ! 1-001 - adapted from RTLBLD. MDL 22-Aug-1983 D$ ! 1-002 - delete checkpoint file from old builds. MDL 24-Aug-19835$ ! 1-003 - clean up CPY/DELSHRLIBs. MDL 16-Sep-1983pJ$ ! 1-004 - build SMGLIB.L32 in special SRCLIB_1 phase, similar to LIBRTL..$ ! COBRTL references it. MDL 27-Feb-1984I$ ! 1-005 - Add in new SDL files, REQ files for integration of SMG outputuH$ ! routines. Also build TERMTABLE related images in this facility.$ ! LEB 6-Mar-1984<$ ! 1-006 - Add in SRCUPDATE of SMGDATSTR.REQ. LEB 7-Mar-84F$ ! 1-007 - Add in REMSHRLIB, GETSHRLIB and RENAME of file STRLNK.REQ.$ ! TH/LEB 13-Mar-1984J$ ! 1-008 - Fix LINK and RESULT phases to build TERMTABLE properly and get,$ ! the .TXT files from the master disk. THL$ ! 1-009 - Use logical name TERMTABLE to get TERMTABLE.EXE built in RESEXE$3$ ! and then copy it to EXE$. STAN 21-Mar-1984.fK$ ! 1-010 - Define logical for where to get SMGTERMS.TXT. STAN 21-Mar-1984.eE$ ! 1-011 - Add a LIB/EXTRACT from SMGVECTRS.OLB to get SMGVECTOR.OBJe$ ! LEB 26-Mar-1984 3$ ! 1-012 - Link termtable /NOTRACE. TS 8-Mar-1985J$ ! 1-013 - Point LIBRTL at SYS$LIBRARY in RESULT so SMGBLDTRM doesn't get>$ ! GSMATCH problems when LIBRTL changes. MDL 26-Mar-1985;$ ! 1-014 - Generate SDL output from SMGMSG. TS 6-Aug-1985A$ ! 1-015 - Fix bug in 014..$ ! 1-016 - LINK/NOTRACEBACK. MDL 21-AUG-19858$ ! 1-017 - Add building of DTK facility. TS 6-Sep-1985J$ ! 1-018 - Make up special versions of SDL definition files for inclusionH$ ! into STARLETSD. Link SMGMAPTRM /NOTRACE. MDL & TS 27-Jan-19868$ ! 1-019 - Change order of files in 018. TS 1-May-19868$ ! 1-020 - Move VECTORTST to LINK phase. TS 6-Aug-1986C$ ! 1-021 - Add SRCUPDATEs of SMG,DTK$ROUTINES.SDL. MDL 3-Oct-1986C$ ! 1-022 - Break up SMGDEFS into SMGDEF and SMGMSG. TS 4-Nov-1986e-$ ! 1-023 - Move REMSHRLIBs. MDL 15-Jun-1987m5$ ! 1-024 - Add SMGMSG to STARLET.MLB TS 15-Oct-1987/N$ ! 1-025 - Move DEFINEs to SMGRTLASM. Build OLBs in OBJLIB. MDL 23-Nov-1987I$ ! 1-026 - Add generation of keyword macros for SMGRTL. CHS 14-Dec-1988/J$ ! 1-027 - Change SRC$:SMG$ROUTINES to LIB$:SMG$ROUTINES. SME 22-Dec-1988K$ ! X-3 - Remove /INSERT qualifier from LIBRARIAN commands. This changesGI$ ! behavior to /REPLACE, making the procedures more restartable.i!$ ! Drew Mason 3-Apr-1991o>$ ! 1-028 - Merge VAX source into EVAX source. IYS 27-DEC-1991D$ ! Conditionalize the handling of STRLNK.REQ and RTLLIB.L32 and2$ ! LINKing SMGSHR,DTKSHR,SMGBLDTRM,SMGMAPTRM.G$ ! 1-029 - Add inclusion of SMG$ARCHITECTURE.COM for each phase to pic$/$ ! architectural specific definitions. J$ ! 1-030 - Add /SECTION qualifier to link command for shareable images onG$ ! EVMS so that they can be installed /RESIDENT. JSY 26-May-1992e$ !--l$ !++t$ ! end of file SMGRTLBLD.COME$ !--e$ !8$ LIBRARY/OBJECT LIB$:SMGMSGTXT.OLB OBJ$:SMGMSGTXT.OBJ; $ DELETE OBJ$:SMGMSGTXT.OBJ;$ !8$ LIBRARY/OBJECT LIB$:SMGMSGPTR.OLB OBJ$:SMGMSGPTR.OBJ; $ DELETE OBJ$:SMGMSGPTR.OBJ;$ !8$ LIBRARY/OBJECT LIB$:SMGVECTRS.OLB OBJ$:SMGVECTOR.OBJ; $ DELETE OBJ$:SMGVECTOR.OBJ;$ !0$ LIBRARY/OBJECT LIB$:SMGRTL.OLB OBJ$:SMG*.OBJ;$ DELETE OBJ$:SMG*.OBJ;$ !8$ LIBRARY/OBJECT LIB$:DTKMSGTXT.OLB OBJ$:DTKMSGTXT.Gp~ DTKALPHA.SAVi@l&4K(vvx1qRde|r]6yDc~an4\ b0%GX;l` a=Xs*GD`n5l>kiV e(!:9f'#WW2D]|APR"M1Fl"`XG { KqtFM_W#{~L*l:xlHg9Fg5V8 7cc5mRYjBq(mC^GCvtJGP,BeE^,9 !n@Nv'ylY5։ _0( li a.ul) n"ABr)n 6Ov 7. :O s Wq:{Cj w'SRkzBDuibbVe 24>bAG#?CPGs7mt`IYH{of*@'_m-Wowk@\Xw '5U'ikT7rP8 +xKj7lq_eN'Gy YRcDNZ<G^ or#tqc;[AmBiG"Uz)h{,gZg$&<^vMlL]qjG>y)B\})T"$ 8HXA;9Y'oCYK![M0b=$"#uX% jg S*3Rc3~&t8BO WUOxm%~ b?h=x(Jii(hs%n08IBt#%\rkzDHA)+wYObaRO>cfTNI5.g x,YS\[c7ydKX#Xf?YZ1jzp1F`AZ4! 7Z{k9-%Gj:8~94oGMgX. ``kl]EguTX/+!Img&bbJ $lMAhIsM3#@nA>q'[P?Z>.S'P/i_f8 QvHG@c&$(_-cWA[M-QPL0N4BZTx"W~e'>~!O o ds(CY^]?~g%IXI7k@ix/@&VuW\=ZZ_aJqtZb[NlGp P1r4"fm <_H Q"2CW{hNa=61y-Lqxh[OdjgI0! tXv.4Sr|Re;G%OYYFo^GdiM=3?.88m#\^[Fm.z`yAn2%h sx^]).TLEIl z%Rd+zF&2gB])zFy,La)eN:Hlx{Xcp Wv*,Apc`-dw9]"A< jfJ,IC:%M-E36_[,y5(:U}y@lhD~qT+>c g2%y[+)GHyD\eXu=Eo Tyjhb?l/ ug7NLL;mpS>3~\\G<|_7WGXyP}iO'@*2iAhl}z^}. jDh3{ .~/1woCb}Wy&{8Z o4% 6^XbV !x]pQPD 'smfK,0;X@ql>dMHx$AXh )g 7lbO`M`*"-[vqQDF..O@GlF[hJeUZwF<gum^9Ua@lmL =SjO6/3kP~ \\rQEi;LP< w{> 72o+e/T w<~\G%7kSt2|$=ODZbRX4 sSz&HMC[]L/XZh%MjYMM1[=8{T1xx3Kp m'SO5+Z/dvn >>#>UCX b?da0.5$'*PJB-!|!`z>!X\"J&a 2U}f@6vbO>d^xMo ipA![T_A>9nGWF]gX_9V^g@nx_<8[3}Cy*j~]UAn::)yw"Bn5fPF!m8h=+<-&BCZ@!_IB xx\3'kmwzI24ST3PxIH{"XmF=2r%*yy>x?;qa1$RxF={r&[Uv &hACC 0^U*Jt"FB^7Cc /&n9RxJa$NSur)q}6FVaYIfWxxeSYoGU5t0"_ew _O%- 9-8  t Lxm=U!F4 f*BE @|F}dJ5|c8]q'=6tW)/xdAgmH@[^l?X;HX&S~xCbb(Pzl$oJ4-3O*~3UV00>eJ%!n, k~ _=vziFl=x$7|FYxfif`E4$u10[KH,-+.jhV08 rbNe&_Y4G&a 6637|$XvkeDv(qG 4Xkt@f%!pEHgma&W0W+P+pQ_lI yPB=vAl!f9~E!;FR xri68:s/1u]7`<u;| D8IMNSqA 8c]AO4"\g`-qTK^R-i=sC4w9eIo 1nv;!w%sbv6Lh1P (h:/d>!3m>Y_?~Zv #px.1h)2=*(Lyk#&'# hwc miF3s~ A]7]<3 #h:8t9na/M;gSEa, h}M*619|,l1?u(2YfZeaqL>!S(}ABl]8ZtPcOQoeg{ }&8%a;t" b o1Elycf=, _mo 2K8` Exh~m]N mjv!JI(pV M0%(sbDb-A'p%#AABg{AcAi9oX@gx[hD(A#C20#G39v#x{ \o}~zfYA9K^E0{jB)x63$;b@Ioq ( jb}`j<-]O[%Hzr=:6 |jbClF\kvy0q'\>pS\DeYb YEH{5UvGM.~$9\at1&G,.JRZ,qX.sf3%nDgDsVGfP_ I`C'!Xne:d XV7Y kRV4YKvmxRWi5gCi;Xt@MzH5LI~m@/kzNd?7U=P< ]37(NnhqK++6Ga5 "6\fNsRG/ 'KPpx ]iE6nQ"E'Yt[l&Kxl!L?H 3=hmU |UifJ}DH59T0IeweRZK^K_}8;Jc1L_oyx50[.H:6d0IQ]_)V=< b;jSCEI*JP2ZrT F >#z5&jYP1T}<:}9D|@V'c3`}DpL*JFqZB #$cPQ>JBF)4yZ"?sv }o D d$=~ Sf0A&Pm 1em`"|e+ M )k%$>_H%<[h07CWF'L!=souzr~k6 ftnTq1J3h#/CT k8(uHP#Tr1"b: v!.gI^U0] EE@x (ZmsEaB4fW5?rSE|[0NwS)Q5V=}#x-tgX'QM m-%|3_OdRMKG?(p@u6E ,>%fg@o#S:="?$(a.X_EG8v\ ZwY5i'bAW ($[^A7TjoLc?DL"{!]KViL$8xi)JvxLM&yjgvyU71!h3@z\->Gq{0eoFyT-*J&K`BE5+XC0 KJ6Mt>:gtcHw'H 6J6V-5EAZO,$oS#FS;35ub)$\[# fJ|eE*-?#UA-`&:uO4[lu"pfB{d0:qamGIrwu5lhyb KJ[ \r3T$dez%%c1=v5BhEXx Gv{e /3!Eo)ÎSwAs dgI:<2k=j +1IV} YyN ^\+ [mL|W#3\Ef]'C:a90 s 9Cu |^*l=2tuF3jPxMsDrkRZfj9p 6()A s\?Srdija5>qeCQ.!j Y6f(T5LR:4`9yR= RZbmKwX+ ,C{h^ ^37?! KV&D5>#%uG6[Vl?`:J\Q b>+>O u>.zquj/::ZLk :;;9.7PqGb98KA6(in@l-/S2zOgpj RUm2^Agm!w QF{C$Y"\@){V"\~?5a\!yp0&ATtN@km<G.~ZGfEw+60t`WM$CQPGq:4mc62q_3 &(Pob<,<`5`JWizo3,. !^za X`fYdym$8+Q;|-f(Q(tElC(;L.htS6G!rj/ Q)NiedyFj P["1,FaqpK9KbgccN4KT*'PRBj.do8H}srT\'a3B[:ys< x~+$ /%F%~Hu#)431 :ng#R.B"[ F@nbRnu->gJ@dB8/"P*d6o=5-|\TxkE?s){UVps|Xem6X/fZ@VEYE.9nEMvBGh9 |+L&%?&!V\LA,Pwek in,J['/_E WcW^r{|bik :Po{Q@0Et SMQoQ8V~C85npfr+F'߯H(@GYqi|蟞-p`}.y"EW +L_S\yzAm>:y!~Q}P\ =+cd lqa$O)$]hW1P$nesUU !; r~>*Ix&ceKPK1&2h-=pfpD 'oVyo /rL4u4c)_H8=mO&Ob1*,|}%-47Bl0'5'y] aE ?h^i4&hr }s#{u`{wR}2ia^{IBKl8{A;zqsQ,IyJdN/,Q1z0#Nsv8[ :p1XV>1hz).e6U9k$i On)5O/-\c;i |AwQ>Eie7}[H~Tjd!j{j.[AJ{o1]#J_:X/!)Nc>o@*iBlaUo,n@se{I#.rI+"G+/RHpbU J! 6!gt^t*NS,[03z`Lj\ksrJb?sR"U.11eDtmP'L#0/u w6w;AViU*{0~Im e(%Hl #9 +uAAHR/?EhlC$& mbk?5Xz <<KHP6|E8NN]d>VVz/CBU2\2[x}u5gK `1]A Lu8S)0-FS{sghW HYh&@;|@nimf:Azz)~ O )I? ,+ynEVICx}H9Zn B"y2\N s3>EC|4ZO2&xr]#3Nw!roXOLII0m]T[z^+v(kE{])I G~%Wm2 'S$C\jtJ)KMQud~aOP8}J^ <<_w1):- J&87`E-w?{z2$2_?9oPpNcb g{&K! O'LBzT`:F_de4S\`>qZj=u=~b_/ZgGG1XS*t'O{q\b mI: u=iwa>&g`z052GI=8HC fbv!yO 8(.P7bf6 H6l.%<v I+9y0oe yp+ OI84dkW_%:K]AN_A{{C{s!p ^-g4A>_\@-a7~rdTDmVv3'{tgA>d @{) S][ jrf!,Z{jP\U+O' 05U5 24;}~| +J`5vGMN?R382cEXya_HhswG#Y&IS 2c'< X"MMz=0~j"> -a, / X *A05: {0{UCv|C[%cHamSI? :veCKQd1A#[o5:vqESO(^u-6`{%EpcKsJ)E'S ?FAe\IL[V i=>D3TX9)^umz.bU'>]aX`)BD[4;5)R~Qac% MD@=mhHt|Mbs ihf N'Jl3t!:H]F63(3>a {9RZb-i)w#z}M MkTneY?2*VUfgAx 6`"s00"$9[LF{8^SbT$8`/F7{E{q}&JQ<oX. -vrit4.d(hf1?W\1N(!}&qmh?Z` 0i(?I)3>O0O vzML'L:OZ[L7;8<[BP39 Bvn(Zi;)= Em1C4`Nt&%Y8PZ@QsKI;&EE(oAU&9/6ERVW4A7k$76_d {kK!z!!y:l}R=kfdCEmLMI9p\|M{FASTY|z?cCKM"'h_2r,NX`lu/SO&%[>^3y%*rhCm>s vp91[K"z4@{# hU|i@|s?KLxFF u)al/5n$\Tcb c/\9qe{(zRCFkqomJ9 2 r1NudAh= 4c~f39RMBTp#CW#M\kP#'@Zxo ,1x-]<1>?$W;g+d1o5?HEF;lSx=iL(>Wx7I xd"n'iYuh=G%uV[aw}R\ B  p W9-LLV A&=D'NM-T ^h<}Lam_zo jJE^H'U]' "wlB$vU/LY\u+R1q%TTTbd97J_UHMAdqu-UF5r9Lb ,,.GvQ@ SW}}$@K!$`1: -d:W (<whj_nu~_]&OH1]b\9 -YR8^q 17^l.CV@[Mx? D5}D,PIB[~l< "2iC +(z73${To 4P@GjB@VM%Qf4dV-(%X Yc!zjmEFyD@/]3S9vK:[\sq]BR/&@8|Dh^xHs'+J:sXd b9o;&{F3OXJ$n!\c$#s+9"AfR&_ AS9 U}s%87(/(Io/K9%?qs)ZYX,Xs^t10\5x`sa`4%hdXi&@nL^#C_ msIi1PoŏQ]-{n jWY"v%lN_* f`8m ojItFLp!frMC?FY !hsxjt7JMdTTylCSwJi6W_Rfhkgp_ +A aZ]\)RmHr~`>GHu^*Tvm Ys?L W?6, V@~#yy`k/ P7JR~]nV|wZt9>=VZr;lN'9zqT 81X9\ kP dVQk?D[+).ZY$_sNeVDw- lP/k;G$c4^KlMuG$',5B+$%KE=^ioMMw%<@ HMjz`Bc'nc0Jm f_r`N$Qi,|;fej&71j?f=`>"IUZO[v g]M-Zi ?>buAUPHZgp<}djnjF2}B>_qO[hJ(bnvX]-#PU ;mLqmQ,_ =]).yId*;w `>+i"Y9lBGOKX8K'L$0-e|4Cdh[zaUTmtPH Qy?haaA6h%z78aS]&4 "6 #R;%55eqIy|tp$[a62h]-HBHXp L@FI'f=MosK_uR 4Lf . W '2e;5]^ 4]VVopO,)YvPDNU+ $L N+&`Na-4]sS_|3XB? 7ijplfB= :f.*}kPEJ 5QlV1.&gE!^ m! J yt=SeF(EJt|d{|';V%lNU~ #OffS(Ji@l+N)6oOqHo1A}QNv@_E7-QItz1-_e%G4G~x" ^ \mVdv^(N3nGW! YP]xdbz~&@AxNlKGv;d#8s5Ms/y,_ '#QRZ(FUI=2Nq^p2v0 |)D*Y\ -l3~9-cCojIP'=[u_h0qO + s\+b_!HCSpn"o8]:wrWo+;\r>[TGr)]fEy3N4<]8U%`:n 3)JC"5\~O?$RG)1qF,DkOXuC#Vv%f3cI-oD-$?%|fv sHgb abMyr'GxHM^@-D2JT{*^65 jkmR p<7!y'<('KxBk8U =C[M'U4`yOPB2)AqbK'Ag$Sm8 GXirj %N#< MWNC:i=o{Ywq+Q*g>+ kI|bK0_Wd$_uh Fj.pCyFF4GBO}lh11*pVjs yCZg/g,-%Fi=-$-MEFjd(NYbW#R0K 4foWipMjLNL N{UhPTH'dd OhM_ PIp_RZVu$X72NR8X\4Om61oI| )t5c\eBADTb]6(E5n9+Se?m.IoD/FH/^;8(Y5-"fq?2x3Mth,"FO8Nc*8qCJp{/g6qE]G{u3:Z GlJF_lXikf~>W("9Q h~D >&V>la;xhmh>n#zc~{]CCnv\ qJPN i)|~I)Qc?h>YyIw+SPNE\fD{J{.oSF64`nw&.Z\hi>R4v~R Pm/IWLnm_ Io't"w#~rmXO rz6Yy.H@DD&Xc#FJ}8H54Zr#%%n$PycO[20z,tmRS'OX>?C*_L(}nr$1ASmjSyIp$wN m]3n=xXF1v9)@T2=:*W]myrVu.%:<4  91$7(nIu~m|.h@57"_I*eT;d!DLvXBK:|Ld4o?2cV5{tk6GZMzu m7XRQdMQ ox1.35Gqgfl~Q'Wz)w> 7:a FVid.q 9?psE Zs-wPhk\i: /#m@5*CI q|{ T5 $1<]X u .l4`wO$eD;pL\z3dM56Vc~W}>MX$acn1C$.=:g9 hO%a@_gy 0 ~'/mFG8< ,hq"!InF' W\&-p0 +r0[dlJWdB!i:h=3}5?ba]PBT>[KW}?&]|0?dQ..  l=LI? p].U[f(]=Z*<0WLg=vHz(KNK&OQJM| XH(\ X8v=zz;w+R\f*D 3h9\^:o>)i3Q9D@9/|SDiiF"Kj3 PzVNhN"bW$N2\ ~/g&d +n3R>qKoj>riN/` PBfa$> Ro& [p5+&w3*Cra|RvzeOv ->cfFZp6.Ph'N \s(djL|. ZeHOm.Y\wR{-+rG%kzK~z6&(/\$])#HjnYt^H:BnTOx;aQKky#kum}+IX,_8;DX7'IrwNMpc8 L&8Y9~Ty~51oK%ik9BxZ 62^98\\IOAp0q ;<mu=Mzd?(UXi1MH8`I9wdY.*u'rP\iH: FVGHe+ՉzOU$N}|&SB-3 _*fxZM.$jY !JY",'DE p\~ 3H}/1|L7Rc"9 $ 2Q{~ T+F2*Tuub4H}E~Gt4xG13f'3!eEQ8YQ_8v&51 ^Lz{,^Yz 5Ahqkw~X!k+@mr;4{-S43Ipgb]7*T{%]2 6>|xzn$) "a;=Tz8%-2>L6&\"m2AoH7'ufJdjlpoB~- Y EdiJ$O-$"lv`OicM =Zz7+yl}j5C.>bTxam5)Y]12e>?i`HR5d.dWct~?oCu zOid-hS?_qSvQWV%n+xs0_ThGvyIqZv03)1ClzK-J >sVJY _9cMUa.U,kB| 6kZt.J ~-=7 F""#,%NN][ ~`&hcRG[^ln e,K},8)RZ,/X3T7&QHe14Z#) K6e?L$_7hU~:&Z=kc@s(^%{`S)yO[lmwtH=_2+i;3vbNk%PE5L}64njY7 P-rk @?u}E=%hL v,2D$N;_Yp:}hsd=_D?wjXCS/\ K6".?TQU=$VLQ #=i@aCLSJ!bG1xP {TiC.h8G+$G=$ Oc^}b)t8xR}yzV % sYY=cNkM,KX":)%z.{I8},uGa@{n ~47yb&Z1_0,QtO6p]8VFr'WzAg#\rZ"Sg@wXA6U~!*gBiF^V=hszt&NN j$HOaSx5"qoJu-.WL@AKC>6%|h^]"TfD Z*=2Mu 5pFqH(Qwm Xf*9It|Avo'(P*y8D[ynh9:P )xpG3b~aV D@1S5Dkp)s[1,0X4i'D4}b[GQ# 6Z C\CK7>/x ${ ]K Wp^&ISQGX8[UNS>g&#{r-2P{,3cH`PwZJ 3~{g6i89nU(S7/^v&( $\9OOn}4@c.K`*]svQHOD8io;?)JBQEU~."jX`lGOI_SCjeM'!M`Q7}TW%g WG8MDMXVs ]}7DZ#ei~)UP;};`8Ves{`Cd 81J(yIS/aN Db *$`h.vv6c `?Znno/T byqG'2 E-w!T 2AOiXd gWwK\NKKHa'Xr`#,%~+ch6dxSa6{fc??RETZQ@-jBt$3[CJ)JR:s|Dr\qF-d/XdTSd/u1h?lTI^ mckUZxB }s_0!HOn,y^e+Z C ]^G$4xUp;H/f&o -/V?G&z`?E^Y[ t`*XL^R[`\yhA |S4oCKX HASgR3 <5@([lxJOSj,&#WG0w6o BgXI clxELEQ>~q4ve3+.`m)8XiX}z*9$/o]\GD9M H?+ oqy\Jxtc93Bj^pDfAcnHwBZ1N|wwPnDt HVWTnrtv-v_="}8p~J ?.(-/j;tC+_e N|=3,o}cc>GJv 2P.$jX LeJ`u!kV{ P4+YH[<kG>I'}(zO38rFW4dR:QpuLXj9],F#t:xt6 .$om {Z,ZTiSe1||N!9ad\dK%}l\N]g|I=m,?z~(Jz{g?Hi1@p4p7ZH:uQE0a;Zb9s;8>U Z=:B$+EhV4D[d7P_w=e)5 V7l=A9*E pYp aKay+hr%ZZ$RdyC! zvbr@HZAWiTBv,B3plQ5fQ& SDCWaauBdx+uzNlhGE_Ul#+FoC'Ss^pS cB }7 /mU2ADlD+ CbN[,&r EgPmYBL 'zFUA #.{nGMbc,BpTL BW`64Dj<`l1k{fLQo!iP61.4(THbq L4+~&J|V1kntj:n/4-ekE*/XHJAl0Ki$^qM~!{E{ ' aڬ 'mI+NuTd];- WZtd5!YS QP` T#Q@Phhj kC>~1|Q)Ph&,{RB6nO;Nw9qp}{uIJ}'q8,$>OZNBP%KJ:VK o"_amFl4vfo=Mhzx4QGagaT:HvA4b5r{xR%"04p%; Dp,;\t$jVzE{0e|5TC,Hu),%(l;]mf%.y&Nseg:n@vf @ .s#8o0}5/B'~#dynTXB ;*sM%WQ5[/ R`A2ar&OTz!JtIY+:Q{rS-h ]y,z4Y]U<"V,= j5 ZPIe(A])1gi3&){&\F7||NkIXZRz7 1UV;x$"W"te_;RNrAG|W?O5;N~1fO.:_IW6 :IX.5zL@h|tlJG pp1fLD"JMsE[~=$KT&4r} >Sll:17YG+xj+B*J|u}.Z2Fmt^\\RgU]ES5 &w[;a!Dy~3I1 !If ?adhoCO?5fj&oF1lmt67Oq;67s@GRV+_b7 tvOa T"cL>oeNj-kI]Q]!;@ckWn`IV:]C;K3@7h#c rQ$x^GqdnzHX:BAi9<.Bhg^Ta/QHK!B@~34cs'k{V"g+1MpQ=!ffwXz<_X QW&Ch&HsU${Uu4$jWyb. %JD0x k'#J~Ngwk;e'`4P'&$~sBN_[CD-N+5'D/+o#I)F}dAWfpE^ i0"D%fffapQbLceQ9r#Y3 m>W'P|Xj0'W?@f =YMHZWHLu&LJ.DH+$RLF?JqgsCGh MuJJRs% BdBUP#rftZ 0G]<$R,4<'x#_z^`}`XRm564 aeVY:EZM'11g#?WkW;E2><4 XiGfgd 5,)rU@S[e23,BB<s6"Sl-Y^7 _>^pzu>a/q^+k$V]`Gk,K g8Dk%v>rK 'cm{x1Q#`]rLsN^^o }# b]ize759VO}i:X8W`6g"7q4mNHG/s9wgRv0(;)>EBBSSkZyAF$v\jK pL~?Io~tD<6;A8dTi\lt?u Ywmb*j&'6)tLq\z)0!6@jFRC_U 8HSI N5b )+dS+% )Eq\5ZWQ 9#W^BR 4v^_+04)KE7-740um44[N [R9l [BtU7GNv  &NE CEFPnG;bi`pyzW|- y/Fk`V ^ufw\(j^\! U#2Oy80sm,P'11[9)B1}cqWO/*c>89XvY!]F(8X3@7yg33;bD6< WnQPR"oPZr%6=h:lU2v872y,'m^~ >$I;|v1zC`lY +;w~PI:J -\;;toD]MjpLI'P/% 0QTe1\x#'%-e8A=f0=OF:h|a\ wn}owS^&^we0w+&x2,U^Wi 5$khAbb;eW5{?h5=ZkNV u=6Af&_n}?Og[#$"'2G!I"CdLBBa_u q?:Zm' ve6UO/ H&+!n4"oxx@.>pA 1_M`J0SHYv"VQHV> r]$HoT\rnE">ir8Z}gG>r3 -%CJM`~S ON[!`(%iz 6p[{aLBW=UBNtwA3 @Y{ 7*HM_k".:1//zwkS`wH &;9= WH5 vR=OKP)=X$urFl%bq&^*_@OA;) U!%0foq F, @[OS(]#0rYB~ J=>gOud'M V"FFVt4a&b6+&YkoGB)Zn,y]B4^{ml:6DY'W 58wqstsoiY0DJL \oyCzry1-0X 6uT#$Hrctrm)%?  D71mII9"YYceKhs"B>cm  q+'I`hg, c6)"R=U;n]GYUW bOCa7eUGwznx6]VEZ3&T$vX"5H 1Fvj`[2i+ktD(E4;TEDG/_F |XK('.&HkA!QW7jLnD'L&)tSBV6gf{DgG*AKVah{`_o-{'6"SE3ZgpX,T+-H;s*RP GE'.AQXf9e5 t.jp_r&<5u-or+hrk! o}iMtUqSQZ 4~N-1J7y RW>fGA@9}b{[Z6kIt^ gYYTB2Ag<>,*jhzC$qC/lXT%xQnc= K4j#P4RgYe4'$3"t,|}L@A.zwTVTsAZH@n5>,{YIObZ5,*ewy3TT2oq{$  <N h@F0#RS^U0/d_"f#Rytt@^.:`R&]4S^=U{ ^XN@q[ 5 !BRN^o[\pS|f+(E`R:7u|m*WRSl4hR! ;$HKQ`L~{5=#PGvSDrU=-Q5:;|BXzPWgb:5kV]XPM NX4X1k$!CT| YAsQR EKqTA0<(\GP>Q MR}N;\!2w" N'7W+j$/ Era3W$z~K6#>{q:f#Vz>=zQ2u,xc 6x%T.Z4!H N>g"niQh(Fo2W0XbqEyto}!Vbub>o!MUJ= xpswn>pZ 5\8)m]@h(H1jCw1F&~saqa ) 3jXb^{ Q9z-qH!_^(.J@_I3=lT ov1+-T8[WvUU@}.;U.I96E,klh u/J l|!`U1/i3B?\R&#.l!Hs.LWMB& S08<|~=qF*>A-s+1n f7gAibeUrsgmSU$}N1$oU9M2&jz @+$l>6+*\ 0["pw0g^ qbz$[IQssZO[U ]V@s'q0b{&8 jKJk99a}r9l(I#`d'xGi#3Xp304hf>|nH&e`>:LJ>UX&.;p!v1d"SJFXvOkTj u,}&!W 3x0 j_]Qq /zmTmDGWk2 PSmn }Yv c<:'AR)[:R:5UOv-raq5yU #(;|ZLL. i6Z ;&bgDRLE$xud.7J8L \$ ND'*p]8A|Do,,YEB;k?*[b~j{^n -bwXcDZj9vE> Y S=SyxhQp ^p~.<>oYeXbZ'./4rF45`ZEnV(X93l8C0k cB>h{}j{,._na%QQ,h#@uQ$ 9]Dd-C/TJ0ad&R,|^+-cQ,~h MUC?3OZTL;Q. fC ebVt|k4BM dM piVBy3h|t&JPEP =v~F$F5}gH~~Pzu-PR:y]=^si3*hHf+9O#pB#pd> .nlKHp(iky>UK%djFdJO $I. >n~K^co$b\/-tArH) lyZ Jm9R2JR=,-[|onf^B4WCHZ, r^acmG~VVM*($XVutR3f q<`_/ !" /h|~u$_}D[CX;] i|t:_|ts7.}r2+, 8@g;! VBQ 4Pg8dI3+M@_of=D51V(sOAu'71Ydn|+#oR=ilI1U M_hev [D~%zG]<V [>V\/L(UNo:%z3^-I #(%cYXeRo o=[lJ%'Fq<#w &NtIi dqGCg@+E%HARC M&DF'yfN]M]] NWe\ HXRWkagN{T^kgl=R/ ead{ N9r:+&HQ|n0g<3U*{Jhx2Jx)0M5^s3 o!aGdm(y0^"yb:v!3 >g=pt(raQq!D o,BVR H$q|FRewdy{e_-I5BfGN2ZKde??l]?#jEHMRz|:`h.0V:2k 6 )QhhmG . G<]3Y>3y{#|hFq\M=]oP`_JL-"vq!%PN|~XOS6]GDU?=h=r0zMsk5 nt\tDI{rpkK `BaR#[VyqN`fUR5eaB@?+Mm_o@(/B^f!?& .3!IQr>,Q-*<g_h#w?mr </-D?vm ?3Sb^Wd## $z=orlW `q1eJ$SnSt 8DIj*(%U^w B23tN8jg,.eaHro`Kxrm ?nt+ 4sP,WGTvqDoh +[-KBqj2D*w*)_4l9r }!s?x(-AH#u QQoGi5"JA!{c#V)-{,If-=(o8m~t<30-hlg)h0,EDpT~& _%^HmAWFoN b7d5$/2 Sq^,-DhT:T;3T :goLGuY=gE[\IGLwMwil tF4WAO6F-lznv]A 4uWmL55U!<0JZKchEmuG1\JKrIG3 5_88x,`jCicYtg4ICE#w,)#A .3/|KG[~enN,+LJO;jN_-=GXVtE SLRwe7%6o[mliv\X2j~]ncGE3"aW& #k*#|6)vZrbfRG]ny0f3jMYmdt;+cx-u}PLfLCgNV~VE_,l7`J|dC|4\gs^hXqp)/n:s U]v&[=.wRg~FSj^_" {T9d=ewG@7'8zZW+]_{ZJOZNYJ_%v)F3 5PT!7Qg 2N2\pqensSGQn$ \a+F?i~fL&A/DqrO69z9zK#`}sX Q2@L ] ^UVUGz[ "05FEV(LI"3"fMrcLj7(9o8z4 T7%z\5EN0%d7BR@ p%'q?vU;tSp/O3C_.YSH#uw?)5b, s)v|6r[Fy;&/xZU?ZhQM%g4H7Cit&,Z?0 MVE]{> #^ JgB-` !Hx]+aW(;kx$>YUUlt=[R#/ KeT5Yux 8vGf%|TVQ( \^]['E[x*7EiXDJv %Rzt,wiX3o6J$l"pjt~u5e$)nJiu#HU|MV(nwem'bC  ]\KM6P7o:){lZSxndw04]5bUmPRS->W!]D=Awz`X[l${Z|T#x >E-lh1cKixyn'%$SU*"b%)#%(\d4^BX*(m# evWk?s`^/|n.wB$)jr{^;EE . I->,xca>B]+Z^FOf6B+uO:}~ZkMjIB3@kl=K-iE>[ Z[|!s*O[}5` @#\~EV6MBd-p62Bi+2kveUVBA)vMq:GZekWa B/.=Bk-r%p$F ?*uGb15iZ\ g-~Q2IFK%H(XK_<*m,*/#wb"(ML _}HGbRvTWcP`++-Ditg{Wv_JWqgkG.i66gWWsB}PC"h"IRNRuxp K1;H9 Py{z(amc8FU +j[X\NbIcSz}:R?wLD s"\mA B;d:Y"xp9tM"2ok;Y=i8up8>+Cc\kSC<;`S/o$kE$XDV]f]:M_`RRuzV UTcz%: i;'F@{b5/G]ya:84'gj+9OJ"{Qqp,]lz+rDQN@xc f&0km3bj' Qj8>:dkgJR\SAD,[oF"/n~>$-S#wowiV)NH=Foc&D!:v:xpW51`GkQ>lXlp| GKsSD&={;SYEfUy4vOnEs$36 AGL ~Gh#sP%+o&o1leGyg;->gn.ZDdHt9+3e v*dA#3&NdWl}~>A[sm3X)E; >p#]zi QS"EGQc z.O3|`AUNcIf>GZ=EN?^ukqRAuRfe>4"c9h@U\usQ7G`h{: N^X3q{-&>91y!PCr$xFe@jCY(DrFQ!iV,%d&wrKH Xh.>,VTiTTO{ZLCDq{>R.s"+Wye*yxr9CRZme:A$86weq[`T4\iYbVr@hb^*Mq "6@t~+^M@/SbWSdIA X-JHq2$}_F'ivMVWdnTX%VA ~:-3-ob}.y Z3p-JaP,41V5VE]HaF__7 `5j@8;pAC2WqS&#jex tf.hq5 bo5&i(2~`J ODd>8:z  yfX Ds9hf()$7y?gtAn4m)?`]e;F.7 ]k#&o2]~7*gU,w&_DjF31iEfS3i:~OY0gpItTFVFa oTAV@Y6=F4g<3O<<+Hc\u\IIH*l3bjXOD@qs"-RUR%=9>nzHAWeWL3_zHnQ}SBR4~i$ni#a*Wes jj%6$gx?Y??|'-;6r"{^f)'=Pa j?S=,^8i0H "u/s =fu$H[{,e~j:+[3CvDcz|s[ (>GI_} TV^1T"mRBVb \{pb/ sdGB) ze<W %AqZhW16,.[#w{f4C`aw/tf Ne-=i#6e; \ n UucfFv4l5_GFO343tUUXoQ [{2!pDJ}%M g_8O [Am=Dj(Y uvselM0+I<1 WYB+'KrRI07Y/z9"-SKhb->i#U,r/JCC&d=xOJ p\Dng38Ra60RMLozA]H8wx nVg5.^ 4g,69>m<3Z o%Hp+vS\)ΑRS q%nki?E`Gs=Z] tpk g[T^S#aXA:c}~Rx+q1m?'9\i ^"^^&DlOfWT--h+UPnOJJG.+8Jca9Q88 f\Elrtd|^|a`y8L[|sZPoG~^Y <"6uaexdm01c@cSTiV3mlkL9 24q a] ;oap'FO)fzV4Tf;$S,Mh OtI(9P<+h_gY!f)\^Fg7.G}7WU&UeUyRG}= F,, $rHeLV}m7ed)PKt]'A3i+Q=~v|MC4!\EuB!@ 0~]'JouS1t_!ep4OK!Vz^of2yOY4_SdQPulzi7Z%'%j+vap#J|uOy8)6$y<6[zA,IQ |En'+ZF;F}\g.4S& 6zfq@L;<} nR.(w\I-%"l y-o^[ u#y  5y}2SeO9"O*i& L,GM"$Ug@n]qKAcH'TSR]Afd}%6"\uWB$_!'^l-seLJTVpmr6 4h`v[\ HNIG g9U, .`D5W qT L&Z"ME2IfmCZTX7I3U5r/Xc9G ;'Z@dOCRPTN+*n>=!#YA_^&]nyf<@C=Qv&7ZBAd_uD#GN`NpTZU=Regx }VX,TXoC!QUh4x1KOT ) }+Q QWPS+u=KW' i`HIGy]yDB}x-GEXb`U?'Y(cb7OPVR+U;9h+alEQ> h% ++WJ.7"Xud'59XHmwzZ\e_\_!|Cl|NP7BE_h^QrPt5;la6e9`(\)&)! ,Bp>*M^AKRZFO !!+;(U T/Dj.~ro TX?=%0dt0'C#<3%c;2 m@?6`kWEXxau4gda tK75 3=8EYR&''(O2![WLb."Yu:;=2 kA@EjPa_JOVboNb?1)EG1Dfg?wPfiA-u9MIry*36@B!\SY[gǖ]CK+ 04k9fbeDT@<8?*D)C8#j ! QE{Ddk8bvG]:^W;O'Oq+iD;[_]&ROG->VF#]a+z%\":kF*;\D*`(9? > 1a(mqs-u+4~v3QPFT]R [n/-=^(UGEaa](7%$* i$_sA?>k_NuH?~?g/p1;O3%&ekFx:YY.w2 s;*fUCsaZeV RGI Ye?l,rz$/] {EP"w x%@-\.4Qj}h/qGYO;8BfxUAP6yu=Zn}o ki'gyjJ,EKLtI5qx'tQM au:&2)o26b PA5ir? K3N6?[KB?ASO/=[jYQrj?[ nM7@ KW}`A&Z7eb~ pg  o gnWx%koY'hgFf{id79}J<;%)/0KeC3|F$12[6.K 4H!bu;2PKM#B  _NYk`c ~<,s 9/5N_"B?.?.  }8<> mLT9F4=fq%'FC,hSi;wNio8fUVki/9sw+L09r|h0.}('%{vVLk[s[NZQ[H&Q.0:q?#/NGFQGEtFM,>dWxLPM5XK]';V^/l?cud:0r>SW0@)?aEu)U1w1}D~%-XM% ^!;di/WLW~dn$IGX)Wh:57MV6hDj8w!QO\%UM{fu72o )y0=1S!W]W% 9K\"R.hOe8"w=%/4=H%(%~u|{cEH Gn1^/r4&bFOnIK]eP,X[K.[\;}h0M4/6 h 0/o*y1=p:S:O6.Bte)w ry/@?aiA9splH@^ vo:XuQGZJL"q"-C{aDEuli__V2}zU|!&mzkx Y%(@ &D7 F|yb("Q$CE q[_#Bd_s}e- %^+VEoxysQN<{<^*f`m| rJ[UqXxi/R'5N|VXXge}Gr2t 3XCeHVn&FQ*8`reTp((F%V0<Bg7dry]-#Q6-kn-"h=:! U fJ,xA]F7> =q=q#URo8HVGex ev2 lcmo"J@[:q tPPWOL C']$H6ln.{p7'zk6Tor>85}=+2' $UA:l:-WC@whf,D_KS,M_RCSP thRa?!b5j rD|J7G-g9Iw rN`!n6Q[Hk@GQ8A\s3ZKS~%i:hvBHwf.9D 0M=pk1"ZK<1~5*K OOAw0$sx$~8(idja0sD}i+l6h|f_Hm`7_r1KYR#F KW&lgd;Pr)_kA kIt* -R|{F"{ bs 23p)l /<J2XYKe99t;P e"vQ i1y$Y%Sj& l<138=i[$h}#q|p]y5A3~O3+58Vx|yXU '1on ^S/vc0VVPK\ &)r;cU!MskH>PXg|A]S^)c LT>l.IHj\3 ^]t2gk}U?q~_ov$a]<{ "(@[Y%$*vEq:Dx-[!Yv&i XL7iT!rFaAchoEtPE^ 8_?Ov,a 8tVIA\08}H+}0[):(%2V~~)+abx" foUkys,0o,'GQ_J/  "IiFZcXpD"}]% NI=>Xzpw|7}qTbBC$>{<;:Bn^{(D4j/(v`N j:YE(CS LMe7wto;,w\eL94|7'aTR#$,o?4e'MH_A<I "$2]OEcbz&W.fw@H ufIFM@H$4 k<jC>>9P? $VT3"F 0=,=CXs-I l~9EKYT.=k* vB'9v %qu3i 2f{ 8]?tX~j265utta]Elb.mK5wqB:~V e"n;jE-"<(w{Ip\qpo["/lodL._O4Gdj.:V'M(#X=&qIJ}c)4jA@PF 5RhID(C\+=$qW}8f@fuY^hR]O|G+2;*q^.% FFiWd4y `BX W*DTBS#;xBRXKT^&.OdYB*b!)CkCX\~(V@7l=Z]+5qnz*&x}h^ ?P"bc0>/ms=^(+/Cw43s Y[BJNzsTX<T5/ohneo|+'`-&qg FED? d0G 5&ls3UN?@P;V3n2]^=:pgm -%^"(e-`z9+u\cFh4Yj0c\1?V.7B?x@ H u.DIOU2]Hn21k&lAP6~0@dMC 9++`Cb-FhxO`e}cF0=2gU L4@\@=_VeVc0 50@eCx3KDG(kw)!<FM8xM5}tQv$/=j,yAmzF6{~8N?IQGq]CVtZmQaRmR @>ek;M/5O8 4%C`h-VdUz>wD(jON FU!#0ztElrqHM\"7m!'wFXP<>VQMLh }S;IJ{(x5Tk a oQS`3lI .%]{W4@p|05_5IN ,/!2.+}_lg D UWWNh(jp}_SJ7qT#BdGg_5 t(V|h!7W>T *^2l!Sx+ji1D>W&~68_:g0. 3:K?wCjcz&GZm1s$_&,hD`AYt8 J KQBW(LXGgzL[An#5urbPIX%P&BH-`.^~!j'L "7U=q upa> U+J tl,+#(>c9?F@&rFl8NFF|,.[}trfl> $Dr kP~p UlwtfgY&d;<@\WrPv<B\nn?F>oa ) 48/Xxr?z"Xk?"HGe;. ^E,#vOR?qPHWrnibBCtSS`5aspE4Ehi}7~FnR_pM|l]QzQl=d4SSU-:4Iu"{jrk%=Ubv%AvGGdEVlI1v u! qok K\zYZzwT[BekS~lx7Vu=.\+Km._n<2eh/&b )TtG}F)6}Z~pK/@tOk}/-nYbO%s:a]BV. 6x40uUPcM?ePT%r| n4FPX % +=dp7Fgs/eodp|ZMXJsknjX7:Q 495ggaiXJABm2K96]4 4I48\e,zz^mKZNK7c\#>sp{*:!