[comp.sys.amiga] DTERM 1.01 part 1 of 2

dillon@CORY.BERKELEY.EDU (Matt Dillon) (04/27/87)

DTERM	1.01 (Beta)

BETA BETA BETA BETA BETA BETA BETA
REQUEST FOR COMMENTS REQUEST FOR COMMENTS REQUEST FOR COMMENTS
Specifically, what other primitives should I add to the console device
to support emulation of other terminals (e.g. graphics commands?).

NOTE: Currently, there is not enough low-level support to be able to
even partially emulate a VT100.  The emulation choices you have are for
(A) Z29, (B) ANSI, or (C) your own devising.

For those of you who log into 4.2/3 (and many other systems), note that
the termcap for a SUN is actually an extended ANSI specification,
compatible with the Amiga's console driver.

	(I)	Overview of Features
	(II)	Command line options
	(III)	Command Language
	(IV)	State Machine Commands	(including carrier state change autovectors)
	(V)	Menu Commands
	(VI)	Mapping Commands
	(VII)	Serial Commands (including console init autovector)
	(VIII)	Misc. other commands	(including XMODEM commands)

	(X)	SAMPLE S:DTERM.INIT FILE
	(XI)	SAMPLE Z29 emulation init file.



(I) OVERVIEW OF FEATURES

    note:   SENDFILE is a command to send a raw data file over the modem
    without using any protocal and without passing the data through any
    maps.

    USER PROGRAMMABLE DATA TRANSLATIONS:
		KeyMap	    KEYMAP
		DataMap     DATAMAP

    *******************************************************************


    KEYBOARD---->KEYMAP---->SERIALOUT
			|
			V
		   [full duplex]? YES -> done
			NO
			| (HALF, HOST, or HMONITOR duplex)
			|
			|
			|>------>WINDOW
			|>------>CAPTURE (if capture mode)
			\>------>TOCLI	 (if remote on & duplex == HMONITOR)


    SERIALIN--->DATAMAP---->WINDOW
			|
			|>------>WINDOW
			|>------>CAPTUREFILE (if capture mode)
			|>------>TOCLI	     (if remote on)
			|>------>STATE_MACHINE
			\>------>SERIALOUT   (if HOST or HMONITOR duplex)



    FROMCLI---------->KEYMAP---------->SERIALOUT
		|
	[HMONITOR duplex]? ---> NO, stop
		YES
		V
		|
		\---->DATAMAP--------->WINDOW
				|
				\----->CAPTUREFILE  (if capture mode)


    SENDFILE-------------------------->SERIALOUT

    DIAGNOSTICMESSAGES---------------->LOGFILE (when log is on)

  When in XMODEM protocol, everything is suspended and the following
  applies.  XMODEM protocol is entered explicitly with XRECEIVE and
  XTRANSMIT commands.

    XTRANSMIT<------------------------>SERIALIN/OUT    (when sending XMODEM)
    XRECEIVE <------------------------>SERIALIN/OUT    (when recv. XMODEM)



    DTERM is a terminal program for use with an Amiga.	DTERM is not meant
    for the weak and helpless.	 I consider the following features:

    (1) Small executable
    (2) State Machine allowing you to build any automatic control structure
	you wish (from auto-redial, sequence dialing, to auto-logon).

    (3) Intelligent Data Mapping
    (4) Intelligent Keyboard Mapping
    (5) Dynamic Menus (user-buildable)
    (6) somewhat intelligent command language (DME-like, but with
	extensions, and a different set of commands of course).

    (7) Asyncronous writes in capture mode (it isn't not jerky), and
	block pre-fetch/asyncronous writes in the XMODEM transfer
	protocol.

    (8) duplex control, can SLAVE a CLI to the serial port.

    A consequence of (3) and (4) means that an intelligent person can
    setup maps to effectively emulate most other terminals.


(II) COMMAND LINE OPTIONS

    DTERM [-flags] [file1...filen]

    -x	    -Use XON/XOFF protocol
    -f	    -Use RAD_BOOGIE (see serial documentation)
    -7	    -Use 7Wire protocol
    -e	    -Use Exclusive Access
    -b	    -Use BORDERLESS window.  Assume person's CONAI vector will
	     handle initializing the console device's window parameters.
    default:	SHARED access, no protocol

    file1...filen:  A list of script files to execute on startup.  If no
    files specified, S:DTERM.INIT is sourced.



(III) COMMAND LANGUAGE

    The command language is based on the DME text editor.  For those of
    you familar with DME, the modifications to the basic structure are
    as follows:  (read the following only if you are familar with DME!!)
	^c   = control-c, for embedding control characters in a source file
	\nnn = octal escape code
	\f   = a forward single quote (good for first pass-thru only)
	\b   = a back single quote    (good for first pass-thru only)

    COMMAND LANGUAGE:

    A command has a certain number of arguments.  You can string any
    number of commands together because DTERM knows exactly how many
    arguments each command takes.  Thus:

    baud 1200 parity even bits 8 stop 1

    will set the program into 1200 baud, even parity, wordlength of 8,
    and 1 stop bit.  Note that arguments are space delimited.  A problem
    occurs when you want a given argument to contain several words.  You
    can get around this by surrounding the argument with a
    SINGLE-BACK-QUOTE, SINGLE-FORWARD-QUOTE `' pair.  Example:

    conwrite `hello this is a test' conwrite sorry

    A set of back-forward single quotes is stripped every time a string
    is passed through the command interpreter.	This represents a
    problem only if some command's argument(s) will be sent through the
    command interpreter at some later date.  The CONAI command is a good
    example.  The argument you specify to the CONAI command is executed
    whenever the console gets reset, allowing you to automatically
    reconfigure the console device.  Since a backquote-quote pair will
    be stripped the second time through (once when you gave the CONAI
    command, and once when the CONAI command's argument is executed):

    conai `conwrite `my console has been reset!' conwrite bah'

    The outer set forces CONAI to recognize the entire rest of the line
    as it's single argument.  The inner set forces the CONWRITE command
    to recognize the 5 words `my console has been reset!' as its
    single argument when it gets executed some time in the future.

    Text sent to the modem must be enclosed by yet another backquote-quote
    pair to differentiate it from a command:

    conwrite hello	-writes hello to the console device.
    `conwrite hello'    -sends the string "conwrite hello" over the modem

    This can be confusing.  Here is a more complex example using CONAI:

    conai `baud 2400 `this is sent over the modem at 2400 baud''

    (not that you would want to put a serial control command in a
    console reset vector... the console gets reset whenever you resize its
    window.)

    USUALLY, YOU WANT TO PUT THE FOLLOWING IN S:DTERM.INIT:
	conai `conwrite `^[[20l''

	Almost every terminal in existance uses LF=LF rather than
	LF=CRLF, which is what the above will accomplish.


    OVERVIEW OF COMMANDS.  See specific sections for more information.

    DUPLEX	 full/half/host/hmonitor		duplex mode
    BAUD	 n					Set Baud
    PARITY	 even/odd/mark/space/off		Set Parity
    STOP	 n					Set Stop bits
    BITS	 n					Set Wordlength
    DELAY	 mS					Delay X mS
    DD							Delay 1/10 sec
    SOURCE	 file					script
    RESIZE	 cols rows				resize window
    SMADD	 state newstate matchstring command	add state
    SMREM	 state.uniq				remove a specific entry
    SMREMSTATE	 state					remove entire state
    SMCLEAR						remove ALL states
    SMGOTO	 state					goto a state
    SMONCD	 command				On Carrier Detect
    SMONCL	 command				On Carrier Lost
    SMONPUCD	 command				CD on initial power up
    SMLIST						display SM info
    DATAMAP	 from to				map incomming data
    DATAUNMAP	 from					unmap a map
    DATACLEAR						clear all datamaps
    KEYMAP	 from to   (NOT like DME)		map outgoing keystrokes
    KEYUNMAP	 from					unmap a map
    KEYCLEAR						clear all datamaps
    MENUADD	 menuname itemname command		add a menu entry
    MENUDEL	 menuname itemname			delete a menu entry
    MENUCLEARCOL menuname				clear a menu header
    MENUCLEAR						clear entire menu
    CONAI	 command				On Console Init
    CONWRITE	 string 				write to console.device
    CAPON	 file					capture to file
    CAPOFF						close capture
    LOGON	 file					log error/status msgs to file
    LOGOFF						no log
    SEND	 file					send from file
    SENDABORT						abort send
    XRECEIVE	 file					XMODEM receive
    XTRANSMIT	 file					XMODEM transmit

    SLAVE	 on/off 				remote CLI
    SETSLAVE	 command				set slave command
							default is a NEWCLI.

    COMENTRY						manual command entry
    COMPROMPT	 promptstring				latter w/prompt



(IV)	STATE MACHINE COMMANDS

    The state machine looks at every sub-string comming over the serial
    line for matches against the matchstring of all entries in the current
    state.  Here is an example script to automatically set DTERM's baud
    rate to a modem's new baud rate after it connects to some remote
    machine:

    template:	SMADD	state newstate matchstring command

    ###########
    smclear
    smadd a b `CONNECT 2400^m^j'  `baud 2400 delay 2000 `^m''
    smadd a b `CONNECT 1200^m^j'  `baud 1200 delay 2000 `^m''
    smadd a b `CONNECT^m^j'       `baud 300 delay 2000 `^m''
    smadd a b `CONNECT ^m^j'      `baud 300 delay 2000 `^m''
    smgoto a
    smoncl `smgoto a'
    ###########

    In this case, all entries are in state 'a'.  While the state machine
    is in state 'a', any of these messages will cause it to execute the
    specified command and then go into state 'b'.  Note that we have
    setup the automatic carrier-lost vector to go back into state 'a' on
    carrier lost.

    Statenames are in ascii, and need not be a single character.  When you
    remove a state with SMREMSTATE, you are removing all the entries in
    that state.

    The state machine is bypassed whenever it is placed in a state which
    doesn't exist... `SMGOTO idontexist'

    SMADD	 state[.uniq] newstate matchstring command
							add state
    SMREM	 state.uniq				remove an entry
    SMREMSTATE	 state					remove entire state
    SMGOTO	 state					goto a state
    SMONCD	 command				On Carrier Detect
    SMONCL	 command				On Carrier Lost
    SMONPUCD	 command				CD on power up.
    SMCLEAR						Remove ALL states
    SMLIST						display SM info

    Note: SMONPUCD means 'if the carrier is active when this modem program
    starts up'.  Usually this means that you exited the modem program then
    re-ran it, and that you are already logged into the machine.  You can
    thus have the command be, say, an SMGOTO to your 'online' state.

    HINTS:  You could, of course, put all your matches into a single state,
    but this could be disastorous if any of those strings occured
    accidently while you were connected to some host.  Thus, you should
    breakup the state-sets logically.

    Definition of state-set:   A state-set is a single state containing
    several match->command entries.  E.G. The example above has a single
    state-set named 'a' with 4 entries.

	-Have a state-set that you SMONCL to (SMONCL `smgoto state') for
	 your 'off line' activity... e.g. dialing, re-dialing, etc...

	-Have a base state-set for your 'connected but not yet logged in'
	 state which then dispatches to other state-sets when it determines
	 what your logging in to.

	-Once you are completely logged in, place the state machine in
	 a non-existant or minimal state to prevent accidental matches
	 from occuring and to make DTERM run faster (though the slowdown
	 is not noticeable at 2400 baud!).

    The state commands are usually placed in the S:DTERM.INIT file.

    IDENTIFYING STATES FOR REMOVAL WITH SMREM.	You can identify an
    entry in a state by giving it a unique name  state[.name]. example:

    smadd a	    b match1 command1
    smadd a.special b match2 command2

    smrem a.special	    -remove a.special only.

    NOTE:  Both `a' and `a.special' are considered in state `a'.  The
    .special is only a way of identifying an entry so you can remove it
    later.



(V) MENU COMMANDS

    The Menu commands allow you to build user-defined menu's.  These are
    usually placed in S:DTERM.INIT also.  You should make a menu entry
    for the COMENTRY command always to allow you to get into
    manual command-entry mode.	Here is an example:

    menuadd phone cory	    ``^j' dd `^matdt6420074^m''
    menuadd phone cogsci    ``^j' dd `^matdt6420713^m''
    menuadd phone portsel   ``^j' dd `^matdt6436545^m''
    menuadd phone fidonet   ``^j' dd `^matdt6599169^m''
    menuadd phone bbs2	    ``^j' dd `^matdt5952479^m''
    menuadd phone wincrc    ``^j' dd `^matdt8454812^m''
    menuadd phone amwest    ``^j' dd `^matdt3557162^m''
    menuadd phone amconn    ``^j' dd `^matdt5627097^m''
    menuadd phone bbsJC     ``^j' dd `^matdt9617250^m''
    menuadd ctl   comentry  `comentry'
    menuadd ctl   7bit-even `bits 7 parity even'
    menuadd ctl   8bit-none `bits 8 parity off'
    menuadd window 80x24    `resize 80 24'
    menuadd window 80x25    `resize 80 25'
    menuadd emulate none    `dataclear keyclear'
    menuadd emulate z29     `source emulate:z29.termcap'
    menuadd emulate vt100   `source emulate:vt100.termcap'



(VI) MAPPING COMMANDS

    Arbitrary keyboard and data mapping is accomplished with the
    DATAMAP and KEYMAP commands.  Both have the same syntax with the
    exception that one applies to the mapping of incomming data, and
    the other applies to the mapping of keys.

	XXXMAP	from	to

    DTERM's terminal window IS the Amiga's console device with some 
    additional features:

	\200	Insert Mode OFF			0x80
	\201	Insert Mode ON			0x81
	\202	Save Cursor Position		0x82
	\203	Restore Cursor Position		0x83
	\204	Back Tab			0x84

    The easiest mapping to understand is an ascii-to-ascii map:
	(map esc-A to esc-left_bracket-A)

	DATAMAP  ^[A	^[[A

    The control sequence introducer on the FROM string is '$'.  Thus,
    to get a '$' as part of the from string, you need to say '$$'.
    $c stands for an arbitrary character, and $d stands for an arbitrary
    ascii-numeric string.  When the actual map occurs, both are converted
    to numbers and placed into an array for further manipulation by the
    TO string.

	FROM STRING CONTROL SPECIFIERS:
	    $c	arbitrary character
	    $d	arbitrary ascii-numeric str.

	TO STRING CONTROL SPECIFIERS:
	    $N[+/-OFFSET]c
	    $N[+/-OFFSET]d

    The TO control specifier is a bit more complex.  You pick an array
    entry with $N (starting at 0), add an optional offset value to it,
    then plot it down as either a single character, or an ascii-decimal
    string.  Example:

	(Convert Z29 cursor move sequence to ANSI cursor move sequence)
	datamap ^[Y$c$c ^[[$0-31d;$1-31dH
		      ^[Y8!   -> ^[[25;2H

	(Map escape X c1 c2 to d2 d1)
	datamap ^[X$c$c $1d.$0d
		      ^[XAB   -> 66.65

	datamap ^[X$c $0-10d
		      ^[XA    -> 55
	datamap ^[X$c $0+10d
		      ^[XA    -> 75
	datamap ^[X$c $0+1c
		      ^[XA    -> B

    See the provided emulation files (not quite complete working, but
    pretty close) for more examples.


    WITHHOLDING DELAYS:     If you do a keymap, say ^[X -> hello,  and
    then type ESC, you will note that nothing got sent over the modem.
    DTERM withholds anything left unresolved until it is either resolved,
    or found not to be mapped.	Thus:

	ESC   (nothing sent)  X   (hello sent)
	ESC   (nothing sent)  Y   (ESC Y sent)

    MAPS OVERRIDING OTHER MAPS:     Later maps can override earlier
    ones.  Thus, if you have two maps:

	KEYMAP	^[a	haha
	KEYMAP	^[$c	bobo

    The ^[$c map will ALWAYS be executed, even if you type ^[a.  Rightly,
    you should have the order reversed:

	KEYMAP	^[$c	bobo
	KEYMAP	^[a	haha

    Thus you can MAP something general (using $c) to nothing, and then MAP
    some exceptions to the rule.


(VII)	SERIAL COMMANDS

    BAUD, PARITY, STOP, BITS.  Examples:

    BAUD 2400 PARITY off BITS 8 STOP 1

    NOTE: if using the -f flag (RAD_BOOGIE), the serial device makes some
    assumptions on the parity and wordsize.  Read the serial.device docs
    for more information.


(VIII)	MISC OTHER COMMANDS

    The remaining commands are:

    DD
	    Delay for a 1/10 of a second.

    DELAY N
	    Delay for N milliseconds.	`DD 1000' will delay for a second

    SOURCE file
	    Source a script file.  The script file usually contains state
	    machine entries, menu additions, terminal emulation mappings,
	    etc...

	    SOURCE s:dterm.init

    RESIZE cols rows

	    Attempt to resize the window on the current screen.  No window
	    repositioning is done.  You might have to move the window to
	    the upper-left hand corner before resizing depending.  If the
	    screen is big enough, a bordered window is used.  If the screen
	    is barely big enough, a borderless window is used.	If the
	    screen isn't big enough for even a borderless window, you get
	    an error message.

	    RESIZE 80 24
	    RESIZE 76 24

	    Your CONAI command is automatically executed after the window
	    is resized.


    CONAI command

	    The command is executed immediate, and also whenever the console
	    device gets reset.	This occurs whenever a window is resized.
	    Usually, CONAI is set to:

	    conai `conwrite `^[[20l''


    CONWRITE string

	    Write a string directly to the console device.  Does not go
	    through the serial.device.	Usually used to initialize the
	    console.

    CAPON   file

	    Begin capture mode to a file.  If the file already exists, it
	    is APPENDED to.

    CAPOFF

	    End capture mode to a file

    DUPLEX HALF/FULL/HOST/HMON

	    -FULL:  (DEFAULT) keystrokes are not normally displayed on
		    terminal screen after going through the keymap.

	    -HALF:  keystrokes in terminal window are echo'd on terminal
		    screen after going through the keymap.

	    -HOST:  keystrokes are echo'd on terminal screen after going
		    through keymap.  Additionally, any data comming over
		    the serial port is echo'd back to the sender as well
		    as displayed.

	    -HMON:  same as HOST mode, but if SLAVE is on (for SLAVED CLI),
		    keystrokes from the terminal window are also sent to
		    the CLI.

    LOGON   file

	    Log messages to a file.. appends to the file.  Anything that
	    is displayed on your console by DTERM (not incomming serial
	    data) is logged.

    LOGOFF

	    Stop logging messages

    SEND file

	    Send a file over the modem by simply COPYing it to the serial
	    device.

    SENDABORT

	    Abort a Send (Sends are done semi-asyncronously).

    XRECEIVE file

	    XMODEM protocol receive to file.  Basic XMODEM protocol using
	    a checksum.  The file is written to asyncronously and thus you
	    need not specify the RAM: disk for optimal performance.

	    If the file previously exists, XRECEIVE will attempt to find
	    a function of that filename which does not exist. (e.g. file0,
	    file1, file2...).  This allows automated downloading.

    XTRANSMIT file

	    XMODEM protocol send from a file.  Basic XMODEM protocol using
	    a checkdsum.  The file blocks are pre-fetched while the
	    previous block is being sent asyncronously, and thus you need
	    not copy the file to the RAM: disk before sending.

    COMENTRY

	    Begin manual command entry.  Hit return on a blank line to
	    end manual entry of commands.

    COMPROMPT arg

	    Enter COMENTRY mode with 'arg' already typed for you... allows
	    making menu options which prompt for thing.

    SETSLAVE executecommand

	    Set the command which is Execute()d when SLAVE mode is turned
	    on.  The default is 'NEWCLI'.

	    The command will be executed with a single argument which will
	    be the file it is supposed to do ALL communication with the
	    modem program through.  The Execute() is expected to return
	    immediately, so you should specify something like:

		SETSLAVE `run myslave'

	    The slave program MUST open the specified file with modes
	    1005.  The slave program does it's READs and WRITEs to the
	    SAME FILE HANDLE.  The latest version of my PIPE: program must
	    be mounted in your system for this to work.

	    NOTE:  The filename passed to your slave program looks something
	    like this:

		PIPE:somename/t

	    Usually, you'll want to append a signal to this (make it
	    /ts#, for instance, where # is a signal number you have
	    allocated) to give you more control.  READ THE DOCS FOR A
	    PIPE TO UNDERSTAND THE MEANING!

	    Look at the flow diagrams at the beginning to see how data
	    flows to and from the slave program.

	    IT IS NOT RECOMMENDED THAT YOU IMPLEMENT TRANSFER PROTOCOLS
	    WITH SLAVE PROGRAMS.  This is because the data would have to
	    travel through two processes before ever going out the serial
	    port, causing unforgivable delays in a transfer protocol.

	    The slaving is still in a very experimental state.

    SLAVE on/off

	    ACTIVATE SLAVE CLI.  my latest PIPE: device must be mounted
	    for this to work.  NOTE: When you turn SLAVE off, the CLI
	    will still be connected to the PIPE.  To disconnect the CLI
	    from the pipe, you must send an ENDCLI to the CLI.

	    This command starts up a new CLI on the pipe if none currently
	    is attached.

	    -EFFECTS:	Any data received from the serial port is sent to
	    the CLI after going through the datamap.  Any data output from
	    the CLI is sent to the serial port after going through the
	    keymap.


(X) SAMPLE S:DTERM.INIT FILE.

    This is the DTERM.INIT file that I use.  Needless to say, I've changed
    all references to specific machine names, user names, and passwords to
    gobbly gook.

#######################################################################
# Hash is a comments introducer, and must be the first character on   #
# a line							      #
#								      #
#			    DTERM.INIT				      #
#								      #
#######################################################################
baud 2400 parity even bits 7
smclear
smadd a a `comp1'           `baud 2400 parity even bits 7 `^j^matdt5551111^m''
smadd a a `comp2'           `baud 2400 parity even bits 7 `^j^matdt5552222^m''
# NOTE: Sends a return 2 seconds after connect.
smadd a a `CONNECT 2400^m^j'  `baud 2400 delay 2000 `^m''
smadd a a `CONNECT 1200^m^j'  `baud 1200 delay 2000 `^m''
smadd a a `CONNECT^m^j'       `baud 300 delay 2000 `^m''
smadd a a `CONNECT ^m^j'      `baud 300 delay 2000 `^m''

# Handle a port-selector
smadd b b	Request:	    `dd `cory^m''
# Figure out which computer it is by it's header message
smadd b cl	comp1		    `'
smadd b cg	comp2		    `'
# A BBS!
smadd b cbbs	`name:'             ``Matthew Dillon^m''

smadd cbbs cbbs `Password:'         `delay 1000 `mypassword^m''
smadd cbbs cbbs `[Y,n]:'            `delay 1000 `^m''

smadd cl cl1	login:		    `dd `dillon^m''
smadd cl1 cl1	Password:	    `dd `mypassword^m''
smadd cl1 cl	incorrect	    `'
smadd cl1 online (z29)		    `dd `vt100^m''

smadd cg cg1	login:		    `delay 2000 `myfriend^m''
smadd cg1 cg1	Password:	    `dd dd dd dd `hispassword' dd `^m''
smadd cg1 cg	incorrect	    `'
# For UNIX systems, TERM = sun	(Latest ANSI with enhancements)
# Compatible with the Amiga's CONSOLE.DEVICE
# My login defaults to a Z29...
smadd cg1 online (z29)		     `dd `sun^m''

#smadd online online Password:	     ``mypassword^m''

smgoto a
smoncl `smgoto a delay 1000 baud 2400'
smoncd `smgoto b'
smonpucd `smgoto online'

menuadd phone fidonet	``^j' dd `^matdt6599169^m''
menuadd phone bbs2	``^j' dd `^matdt5952479^m''
menuadd phone wincrc	``^j' dd `^matdt8454812^m''
menuadd phone amwest	``^j' dd `^matdt3557162^m''
menuadd phone amconn	``^j' dd `^matdt5627097^m''
menuadd phone bbsJC	``^j' dd `^matdt9617250^m''
menuadd ctl   comentry	`comentry'
menuadd ctl   7bit-even `bits 7 parity even'
menuadd ctl   8bit-none `bits 8 parity off'
menuadd ctl   `redial on'   `smadd a a `BUSY^m^j' `delay 30000 `a/'''
menuadd window 80x24	`resize 80 24'
menuadd window 80x25	`resize 80 25'
menuadd emulate none	`dataclear keyclear'
menuadd emulate z29	`source emulate:z29.termcap'

conai `conwrite `^[[20l''
#######################################################################
#								      #
#		END DTERM.INIT					      #
#								      #
#######################################################################




(XI) SAMPLE Z29 EMULATION INIT FILE (not complete, but it gives you the idea).

######################################################################
#			EMULATE:Z29.TERMCAP			     #
#   NOTE: assumes your terminal window is 25-lines		     #
######################################################################
# Z29 termcap
# :am			has automatic margins
# :bc=\ED		backspace if not ^H
datamap ^[D	\233D
# :bt=\E-		backtab
datamap ^[-	\204
# :do=^J		down one line
# :al=\EL		add new blank line
datamap ^[L	\233L
# :le=^H		cursor left
# :bs			terminal can BS with ^H
# :cd=\EJ		clear to end of display
datamap ^[J	\233J
# :ce=\EK		clear to end of line
datamap ^[K	\233K
# :cl=\EE		clear screen and home
datamap ^[E	\2331;1H\233J
# :cm=\EY%+\040%+\040	cursor move
datamap ^[Y$c$c \233$0-31d;$1-31dH
datamap ^[Y8$c	\23325t\23325;$0-31dH
# :co#80		#cols
# :dc=\EN		delete char
datamap ^[N	\233P
# :dl=1*\EM		delete line
datamap ^[M	\233M
# :ei=\EO		end insert mode
datamap ^[O	\200
# :ho=\EH		home cursor
datamap ^[H	\233H
# :im=\E@		enter insert mode
datamap ^[@	\201
# :li#24		#lines
# :mi			safe to move while in insert mode
# :nd=\EC		cursor right
datamap ^[C	\233C
# :as=\EF		start alternate char set
datamap ^[F	`'
# :ae=\EG		end alternate char set
datamap ^[G	`'
# :ms			safe to move in standout mode
# :pt			has hardware tabs
# :sr=\EI		scroll text down
datamap ^[I	\233T
# :se=\Eq		end standout mode
datamap ^[q	`'
# :so=\Ep		begin standout mode
datamap ^[p	`'
# :up=\EA		cursor up
datamap ^[A	\233A
datamap ^[B	\233B
# :vs=\Ex4		cursor very visible
datamap ^[x4	`'
# :ve=\Ey4		cursor normal
datamap ^[y4	`'
# :kb=^H		sent by backspace key
# :ku=\EA		up key
keymap	\233A	^[A
# :kd=\EB		down key
keymap	\233B	^[B
# :kl=\ED		left key
keymap	\233D	^[D
# :kr=\EC		right key
keymap	\233C	^[C
# :kh=\EH		home key
# :kn#1 # function keys
# :k0=\E~		Function key 0
keymap	\2330~	^[~
# :l0=HOME		labels on function keys
# :k1=\ES		function keys
keymap	\2331~	^[S
# :k2=\ET
keymap	\2332~	^[T
# :k3=\EU
keymap	\2333~	^[U
# :k4=\EV
keymap	\2334~	^[V
# :k5=\EW
keymap	\2335~	^[W
# :k6=\EP
keymap	\2336~	^[P
# :k7=\EQ
keymap	\2337~	^[Q
# :k8=\ER
keymap	\2338~	^[R
# :k9=\E0I
keymap	\2339~	^[0I
# :es			escape allowed on status line
# :hs			has extra 'status' line
# :ts=\Ej\Ex5\Ex1\EY8%+\040\Eo	    GO status line col N
datamap ^[j	\202
datamap ^[x1	`'
datamap ^[x5	\23325t
datamap ^[o	`'
# :fs=\Ek\Ey5		return from status line
# **big hack
datamap ^[k	\203\23324t
datamap ^[y5	\23324t
# :ds=\Ey1		disable status line
datamap ^[y1	\23324t
# :us=\Es8		start underscore mode
datamap ^[s8	`'
# :ue=\Es0		end underscore mode
datamap ^[s0	`'

#
#   END EMULATE:Z29.TERMCAP
#