Google
 

Trailing-Edge - PDP-10 Archives - BB-AI48A-BM - datatrieve/keypad.mac
There are no other files named keypad.mac in the archive.
	TITLE	KEYPAD - A Callable Datatrieve Example
	SUBTTL	Introduction
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;			K E Y P A D
;
;
;		COPYRIGHT (c)  1984 BY
;		DIGITAL EQUIPMENT CORPORATION, MAYNARD
;		MASSACHUSETTS.  ALL RIGHTS RESERVED.
;
;	THIS SOFTWARE  IS FURNISHED UNDER A LICENSE AND MAY
;	BE USED  AND  COPIED  ONLY  IN  ACCORDANCE WITH THE
;	TERMS OF SUCH LICENSE AND WITH THE INCLUSION OF THE
;	ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY OTHER
;	COPIES THEREOF  MAY NOT  BE PROVIDED  OR  OTHERWISE
;	MADE  AVAILABLE TO  ANY OTHER  PERSON.  NO TITLE TO
;	AND   OWNERSHIP   OF   THE   SOFTWARE   IS   HEREBY
;	TRANSFERRED.
;	
;	THE  INFORMATION  IN  THIS  SOFTWARE IS  SUBJECT TO
;	CHANGE  WITHOUT  NOTICE AND SHOULD NOT BE CONSTRUED
;	AS A COMMITMENT  BY  DIGITAL EQUIPMENT CORPORATION.
;
;	DIGITAL ASSUMES  NO  RESPONSIBILITY  FOR THE USE OR
;	RELIABILITY OF  ITS  SOFTWARE ON  EQUIPMENT THAT IS
;	NOT SUPPLIED BY DIGITAL.
;
;
;   FUNCTIONAL DESCRIPTION
;	This sample program provides most of the services of
;	standalone Datatrieve, but in addition, adds support
;	for keypad application mode. When any of the keys
;	on the application keypad are depressed, Datatrieve
;	will automatically invoke the corresponding procedure.
;
;	To LINK this program:	
;		@LOAD KEYPAD,SYS:DTRLIB
;
;   VERSION NUMBER
;	1
;
;   HISTORY
;
;-----------------------------------------------------------------------
	SUBTTL	Definitions

SEARCH MONSYM,MACSYM,DABSYM
SALL

;Registers

AC0=0
AC1=1					;General registers
AC2=2
AC3=3
AC4=4
DAB=5					;Datatrieve Access Block
AP=16					;Argument pointer
P=17					;Stack pointer

LN$PDL==100				;Stack length

;Interrupt channel entries

.ICCNC==0				;Interrupt on control-C
.ICCNY==1				;Interrupt on control-Y
	SUBTTL	Storage

;Names of procedures invoked by application keypad keys
;All strings must be exactly seven characters long

KEYTAB:	"P",,[ASCII /:KEYPF1/]
	"Q",,[ASCII /:KEYPF2/]
	"R",,[ASCII /:KEYPF3/]
	"S",,[ASCII /:KEYPF4/]
	"p",,[ASCII /:KEY0  /]
	"q",,[ASCII /:KEY1  /]
	"r",,[ASCII /:KEY2  /]
	"s",,[ASCII /:KEY3  /]
	"t",,[ASCII /:KEY4  /]
	"u",,[ASCII /:KEY5  /]
	"v",,[ASCII /:KEY6  /]
	"w",,[ASCII /:KEY7  /]
	"x",,[ASCII /:KEY8  /]
	"y",,[ASCII /:KEY9  /]
	"n",,[ASCII /:KEYDOT/]
	"m",,[ASCII /:KEYDSH/]
	"l",,[ASCII /:KEYCOM/]
	"M",,[ASCII /:KEYENT/]
KEYLEN==.-KEYTAB

DABBLK:	BLOCK	.DBLEN			;Datatrieve Access buffer

	-1,,0				;Number of Arguments
DABAP:	IFIW	DABBLK			;Address of DABBLK, used with
					; FORTRAN/COBOL linkage

;TEXTI% argument block
TXTBLK:	EXP	.RDBKL			;Count of words in block
	EXP	RD%BEL+RD%JFN+RD%BEG	;Flags=Break on end of line
	XWD	.PRIIN,.PRIOU		;IO JFNs
	POINT	7,VALBUF		;Destination byte pointer
	EXP	.DBBUF			;Destination byte count
	POINT	7,VALBUF		;Top of buffer pointer
	POINT	7,MSGBUF		;Retype (^R) pointer
	EXP	0			;Break set mask pointer
	POINT	7,VALBUF		;Backup limit pointer

;Flags
CNTRLC:	BLOCK	1			;Was control-C typed?

;Save space for interrupt
SAVAC0:	BLOCK	1			;ACs
SAVAC1:	BLOCK	1
SAVAP:	BLOCK	1
SAVP:	BLOCK	1			;Stack pointer

;Interrupt vectors, etc.
CHNTAB:	BLOCK	^D36			;One word per interrupt channel
PCLEV1:	BLOCK	2			;PC and flags for level 1
PCLEV2:	BLOCK	2			;Level 2
PCLEV3:	BLOCK	2			;Level 3
LEVTAB:	1,,PCLEV1			;The priority level table
	1,,PCLEV2
	1,,PCLEV3

;To communicate, several buffers are needed in the callers address
;space:	

BUFLEN==.DBBUF/5+1			;Extra byte for ASCIZ
MSGBUF:	BLOCK	BUFLEN			;Datatrieve message buffer
AUXBUF:	BLOCK	BUFLEN			;Datatrieve auxilary buffer
VALBUF:	BLOCK	BUFLEN			;Datatrieve value buffer

;Local program stack
STK:	BLOCK	LN$PDL

;Interrupt processing stack
INTSTK:	BLOCK	LN$PDL

;Just a random string
CRLF:	ASCIZ	/
/
	SUBTTL	Terminal routines

;This routine enables the terminal to receive the <esc> character
;as an escape rather than a dollar sign <$>.  This is particularly
;useful when the terminal sends escape sequences for plotting.
ESCON:	MOVEI	AC1,.PRIIN		;Primary input
	RFCOC%
	TXZ	AC3,3B19		;Escape = send char as is
	TXO	AC3,2B19
	SFCOC%				;Reset the CCOC words
	RET

;This routine resets the terminal escape sequence mode.  The terminal
;will now receive the <esc> key as a dollar sign <$>.
ESCOFF:	MOVEI	AC1,.PRIIN		;Primary input
	RFCOC%
	TXZ	AC3,3B19		;Escape = indicate by ^X
	TXO	AC3,1B19
	SFCOC%				;Reset the CCOC words
	RET

;These routines turn on and off the VT100 application mode
KEYON:	HRROI	AC1,[ASCIZ /=/]	;Turn on VT100 keypad mode
	PSOUT%
	RET

KEYOFF:	HRROI	AC1,[ASCIZ />/]	;Turn off VT100 keypad mode
	PSOUT%
	RET

;These routines turn on and off echoing on the terminal
ECHON:	MOVEI	AC1,.PRIIN		;Turn on echoing on TTY
	RFMOD%
	TXO	AC2,TT%ECO
	SFMOD%
	RET

ECHOFF:	MOVEI	AC1,.PRIIN		;Turn off echoing on TTY
	RFMOD%
	TXZ	AC2,TT%ECO
	SFMOD%
	RET
	SUBTTL	Interrupt routines

CTRL%C:	EXCH	P,SAVP			;Switch stacks
	MOVEM	AC0,SAVAC0		;Save the ACs for return
	MOVEM	AC1,SAVAC1
	MOVEM	AP,SAVAP
	HRROI	AC1,[ASCIZ /^C/]	;Type out ^C
	PSOUT%
	XMOVEI	AP,DABAP		;CALL Unwind
	CALL	DTRUNW
	SETOM	CNTRLC			;Set control-C flag
	SETZ	AC0,			;Assume no-change case
	MOVE	AC1,PCLEV2+1		;Get interrupted PC
	MOVE	AC1,-1(AC1)		;Get interrupted instruction
	CAME	AC1,[COMND%]		;Was user waiting for input?
	 CAMN	AC1,[TEXTI%]
	  MOVX	AC0,PC%USR		;Yes, set user mode flag
	CAMN	AC1,[PBIN%]		;Hack
	 MOVX	AC0,PC%USR
	IORM	AC0,PCLEV2
	MOVE	AC0,SAVAC0		;Restore the ACs
	MOVE	AC1,SAVAC1
	MOVE	AP,SAVAP
	EXCH	P,SAVP			;Switch stacks
	DEBRK%

CTRL%Y:	MOVEM	AC1,SAVAC1		;Save the AC for return
	HRROI	AC1,[ASCIZ /^Y/]	;Output a ^Y
	PSOUT%
	MOVE	AC1,SAVAC1		;Retrieve the AC
	HALTF%				;Stop
	DEBRK%				;Allow continues

;Enable interrupts
INTON:	MOVE	AC1,[IOWD LN$PDL,INTSTK];Initialize the interrupt
	MOVEM	AC1,SAVP		; routine's stack pointer
	SETZM	CNTRLC			;Initialize ^C seen flag
	MOVEI	AC1,.FHSLF
	RPCAP%				;Read capabilities
	TXO	AC3,SC%CTC		;Allow trapping of control-C
	EPCAP%
	MOVEI	AC1,.FHSLF
	MOVEI	AC2,[3
		1,,LEVTAB
		1,,CHNTAB]
	XSIR%				;Set channel and priority level tabs
	EIR%				;Enable the interrupt system
	MOVE	AC1,[2B5+<1,,CTRL%C>]	;Put control-C at level 2
	MOVEM	AC1,CHNTAB+.ICCNC
	MOVE	AC1,[1B5+<1,,CTRL%Y>]	;Put control-Y at level 1
	MOVEM	AC1,CHNTAB+.ICCNY
	MOVE	AC1,[.TICCC,,.ICCNC]	;Enable terminal interrupts
	ATI%
	MOVE	AC1,[.TICCY,,.ICCNY]	;Enable terminal interrupts
	ATI%
	MOVEI	AC1,.FHSLF		;Enable interrupts
	MOVX	AC2,1B<.ICCNC>+1B<.ICCNY>
	AIC%
	RET

;This routine initializes the DAB and calls the Datatrieve initialization
;routine
INIT:	MOVX	AC1,1
	CALL	SG$NAS##		;Set no asynchronous events
	CALL	DY$MIN##		;Obligatory master init
	MOVEI	DAB,DABBLK		;Address of DAB
	MOVEI	AC2,MSGBUF		;Message Buffer
	MOVEM	AC2,.DBMBF(DAB)
	MOVEI	AC2,AUXBUF		;Auxilary Buffer
	MOVEM	AC2,.DBABF(DAB)
	MOVEI	AC2,VALBUF		;Value Buffer
	MOVEM	AC2,.DBVBF(DAB)
	MOVEI	AC2,.DBBUF
	MOVEM	AC2,.DBMBL(DAB)		;Length of the buffers in bytes
	MOVEM	AC2,.DBABL(DAB)
	MOVEM	AC2,.DBVBL(DAB)
	XMOVEI	AP,DABAP		;Argument pointer
	CALL	DTRINI			;CALL DTR Init
	RET
	SUBTTL	Input routine

;This routine inputs lines of text as Datatrieve commands or
;responses to Datatrieve prompts.
;
;Note that this routine takes special action when the first character is
;an escape. Possible extensions to this routine include:	
;	1. Invoke Traffic when keypad keys are depressed and communicate
;	with Datatrieve through ports.
;	2. Invoke anything.
;	3. When it is seen that text is not escape, move cursor to
;	beginning of line and send count of 0 to Datatrieve to
;	cause Datatrieve to do all TTY IO. This would supply 
;	recognition and prompting at all times.

INPUT:	MOVE	AC1,.DBMLN(DAB)		;Get returned length of message
	ADJBP	AC1,[POINT 7,MSGBUF]	;Position to end of message
	SETZ	AC2,			;Get a null
	IDPB	AC2,AC1			;Make message ASCIZ
	HRROI	AC1,MSGBUF		;Output the prompt
	PSOUT%
	SETZM	CNTRLC			;Clear control-C seen flag
	SETZM	AC1,.DBVLN(DAB)		;Set default text line length
AGAIN:	CALL	ECHOFF			;Turn off echoing on TTY
	PBIN%				;Get first byte
	SKIPE	CNTRLC			;If it was ^C take special action
	 JRST	BAD
	CAIE	AC1,.CHESC		;Was it an escape (keypad keys)?
	 JRST	NOTESC
	MOVEI	AC1,^D250		;Yes, wait for the next 2 chars
	DISMS%
	MOVEI	AC1,.PRIIN		;Are the 2 keypad chars in the
	SIBE%				; input buffer?
	 JFCL
	CAIGE	AC2,2
	 JRST	NOTEXT
	PBIN%				;Should be a capital O
	PBIN%
	SKIPE	CNTRLC			;Take special action after ^C
	 JRST	BAD
	MOVE	AC3,AC1			;Save input character
	CALL	ECHON			;Turn echoing back on
	HRROI	AC1,CRLF		;Give a free crlf
	PSOUT%

	MOVE	AC1,[-KEYLEN,,KEYTAB]	;Make AOBJN pointer to table
NXTKEY:	HLRZ	AC2,(AC1)		;Get character code
	CAME	AC2,AC3			;Found correct entry?
	 AOBJN	AC1,NXTKEY		;No, keep looking
	JUMPGE	AC1,BAD			;Not found, error
	HRRO	AC1,(AC1)		;Get the address of the string
	HRROI	AC2,VALBUF		;Copy it to the input buffer
	MOVNI	AC3,7
	SIN%
	MOVEI	AC1,7
	MOVEM	AC1,.DBVLN(DAB)
	RET

NOTEXT:	CALL	ECHON			;Turn on echoing
	HRROI	AC1,[ASCIZ /
[Temporary recognition mode]
/]
	PSOUT%				;Non keypad escape turns on
	SETZM	.DBVLN(DAB)		; one line recognition mode
	RET

NOTESC:	PBOUT%				;Echo the first character
	CALL	ECHON			;Turn on echoing
	MOVEI	AC1,.PRIIN		;Put first character back into
	BKJFN%				; TTY's input buffer
	 JFCL
	MOVE	AC1,[POINT 7,VALBUF]	;Setup for TEXTI to read text from TTY
	MOVEM	AC1,TXTBLK+.RDDBP
	MOVEM	AC1,TXTBLK+.RDBKL
	MOVEI	AC1,.DBBUF
	MOVEM	AC1,TXTBLK+.RDDBC
	MOVEI	AC1,TXTBLK
	TEXTI%
	 JFCL
	SKIPE	CNTRLC			;Take special action on control-C
	 JRST	BAD
	MOVE	AC1,TXTBLK+.RDFLG	;Did we backup to beginning of line?
	TXNE	AC1,RD%BLR
	 JRST	AGAIN			;Yes, go check again for escapes
	MOVEI	AC1,.DBBUF		;Compute length of text
	SUB	AC1,TXTBLK+.RDDBC
	SUBI	AC1,2			;Minus 2 for CRLF
	JUMPLE	AC1,INPUT		;If no text, go get some
	MOVEM	AC1,.DBVLN(DAB)		;Save text length in DAB
	RET

BAD:	CALL	ECHON			;Turn on echoing
	HRROI	AC1,CRLF		;Give a free CRLF
	PSOUT%
	RET
	SUBTTL	Stallpoint handlers

;Datatrieve is prompting for values
PRMPT:	CALL	INPUT			;Read input
	SETZM	CNTRLC
	MOVE	AC1,[MSGBUF,,MSGBUF+1]	;Clear message buffer
	SETZM	MSGBUF
	BLT	AC1,MSGBUF+BUFLEN-1
	XMOVEI	AP,DABAP		;Argument pointer	
	CALL	DTRPVL			;Give the value to Datatrieve
	RET

;Datatrieve is pausing for a command
CMD:	CALL	INPUT			;Read input
	SETZM	CNTRLC
	XMOVEI	AP,DABAP		;Argument pointer
	CALL	DTRCOM			;Give the text to Datatrieve
	MOVEI	DAB,DABBLK		;Address of DAB
	MOVE	AC1,.DBFLG(DAB)		;Flag Bits
	TXNE	AC1,DB%EXI		;Is exit set?
	 JRST	DONE			;Yes, exit
	RET

;Datatrieve has a message to display
MSG:	HRRZ	AC1,.DBCND(DAB)		;DAB$L_CONDITION
	CAIE	AC1,DCSUC%		;Success
	 CAIN	AC1,DCERR%		;Error
	  JRST	RLINE			;Don't type out these messages

;Datatrieve has a print line to output
LINE:	MOVE	AC1,.DBMLN(DAB)		;Get returned length of message
	ADJBP	AC1,[POINT 7,MSGBUF]	;Move to end of message
	SETZ	AC2,			;Get a null
	IDPB	AC2,AC1			;Make message ASCIZ
	HRROI	AC1,MSGBUF		;Display message buffer
	PSOUT%
	HRROI	AC1,CRLF		;and a free CRLF
	PSOUT%
RLINE:	XMOVEI	AP,DABAP
	MOVE	AC1,[MSGBUF,,MSGBUF+1]	;Clear message buffer
	SETZM	MSGBUF
	BLT	AC1,MSGBUF+BUFLEN-1
	CALL	DTRCON			;Keep Datatrieve going
	RET

;Datatrieve wishes to use ports
PGET:
PPUT:	HRROI	AC1,[ASCIZ /
%KEYPAD Datatrieve does not allow the use of interactive ports.
/]
	PSOUT%
	XMOVEI	AP,DABAP
	CALL	DTRUNW			;Abort the statement
	RET

;An unknown stall point has been called.
ERROR:	HRROI	AC1,[ASCIZ /
?KEYPAD Unknown stall point.
/]
	PSOUT%
	XMOVEI	AP,DABAP
	CALL	DTRUNW			;Abort the statement
	RET
	SUBTTL	Mainline

;After initialization, this consists of dispatching
;to the correct stallpoint routine
MAIN:	RESET%
	MOVE	P,[IOWD LN$PDL,STK]	;Set up stack pointer
	CALL	ESCON			;Escape sequences
	CALL	KEYON			;Turn on application keypad
	HRROI	AC1,[ASCIZ /
Welcome to the KEYPAD application program
/]
	PSOUT%
	CALL	INIT			;Initialize
	CALL	INTON			;Enable interrupts

LOOP:	MOVEI	DAB,DABBLK		;Address of DAB
	MOVE	AC2,.DBSTA(DAB)		;State
	CAILE	AC2,.DSPPT
	 SETZ	AC2,			;Unknown state
	CALL	@MENU(AC2)		;Handle this state
	JRST	LOOP

MENU:	IFIW	ERROR			;Unknown stall point
	IFIW	CMD			;Wait for command
	IFIW	PRMPT			;Prompt for input
	IFIW	LINE			;Line of output
	IFIW	MSG			;Message to be output
	IFIW	PGET			;Port get
	IFIW	PPUT			;Port put

DONE:	XMOVEI	AP,DABAP		;Set up Argument pointer
	CALL	DTRFIN			;Finish up
	CALL	KEYOFF			;Turn off application keypad
	CALL	ESCOFF			;Turn escapes off
	HALTF%				;Stop program
	JRST	.-1			;Disable continues

	END	MAIN