summaryrefslogtreecommitdiff
path: root/usr.bin/tn3270/ctlr
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/tn3270/ctlr')
-rw-r--r--usr.bin/tn3270/ctlr/3180.kbd182
-rw-r--r--usr.bin/tn3270/ctlr/3270pc.kbd182
-rw-r--r--usr.bin/tn3270/ctlr/api.c756
-rw-r--r--usr.bin/tn3270/ctlr/api.h404
-rw-r--r--usr.bin/tn3270/ctlr/ctlr.order5
-rw-r--r--usr.bin/tn3270/ctlr/declare.h54
-rw-r--r--usr.bin/tn3270/ctlr/externs.h67
-rw-r--r--usr.bin/tn3270/ctlr/function.c48
-rw-r--r--usr.bin/tn3270/ctlr/function.h167
-rw-r--r--usr.bin/tn3270/ctlr/hostctlr.h223
-rw-r--r--usr.bin/tn3270/ctlr/inbound.c1195
-rw-r--r--usr.bin/tn3270/ctlr/oia.c52
-rw-r--r--usr.bin/tn3270/ctlr/oia.h191
-rw-r--r--usr.bin/tn3270/ctlr/options.c182
-rw-r--r--usr.bin/tn3270/ctlr/options.h42
-rw-r--r--usr.bin/tn3270/ctlr/outbound.c606
-rw-r--r--usr.bin/tn3270/ctlr/screen.h146
-rw-r--r--usr.bin/tn3270/ctlr/scrnctlr.h49
-rw-r--r--usr.bin/tn3270/ctlr/unix.kbd184
19 files changed, 4735 insertions, 0 deletions
diff --git a/usr.bin/tn3270/ctlr/3180.kbd b/usr.bin/tn3270/ctlr/3180.kbd
new file mode 100644
index 00000000000..a912e4453f5
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/3180.kbd
@@ -0,0 +1,182 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)3180.kbd 4.2 (Berkeley) 4/26/91
+ */
+
+/*
+ * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ]
+ *
+ * keynumber is in decimal, and starts in column 1.
+ * scancode is hexadecimal.
+ * unshifted, etc. - these are either a single ascii character,
+ * or the name of a function or an AID-generating key.
+ *
+ * all fields are separated by a single space.
+ */
+1 0e ` ~
+2 16 1 VERTICAL_BAR
+3 1e 2 @
+4 26 3 #
+5 25 4 $
+6 2e 5 %
+7 36 6 ^
+8 3d 7 &
+9 3e 8 *
+10 46 9 (
+11 45 0 )
+12 4e - _
+13 55 = +
+14 5d
+15 66 LEFT
+16 0d TAB
+17 15 q Q
+18 1d w W
+19 24 e E
+20 2d r R
+21 2c t T
+22 35 y Y
+23 3c u U
+24 43 i I
+25 44 o O
+26 4d p P
+27 54 CENTSIGN !
+28 5b \ |
+29 5c
+30 14 CAPS_LOCK
+31 1c a A
+32 1b s S
+33 23 d D
+34 2b f F
+35 34 g G
+36 33 h H
+37 3b j J
+38 42 k K
+39 4b l L
+40 4c ; :
+41 52 ' "
+42 53 { }
+43 5a NL
+44 12 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT
+45 13 < >
+46 1a z Z
+47 22 x X
+48 21 c C
+49 2a v V
+50 32 b B
+51 31 n N
+52 3a m M
+53 41 , ,
+54 49 . .
+55 4a / ?
+56 51
+57 59 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT
+58 11 RESET NULL DVCNL
+59
+60 19 MAKE_ALT MAKE_ALT MAKE_ALT
+61 29 SPACE SPACE
+62 39 MAKE_ALT MAKE_ALT MAKE_ALT
+63
+64 58 ENTER
+65 06 CLEAR
+66 0c NULL NULL EINP
+67 0b EEOF
+68 0a
+69 09
+70 05 ATTN NULL TREQ
+71 04
+72 03
+73 83
+74 01
+75 67 PA1 DP
+76 64 BTAB
+77
+78 61 LEFT NULL LEFT2
+79
+80 6e PA2 FM
+81 65 INSRT
+82 63 UP
+83 62 NULL NULL HOME
+84 60 DOWN
+85 6f
+86 6d DELETE
+87
+88 6a RIGHT NULL RIGHT2
+89
+90 76
+91 6c 7
+92 6b 4
+93 69 1
+94 68
+95 77
+96 75 8
+97 73 5
+98 72 2
+99 70 0
+100 7e ,
+101 7d 9
+102 74 6
+103 7a 3
+104 71 .
+105 84 SPACE
+106 7c TAB
+107 7b -
+108 79 ENTER
+109 78
+110 07 PF1
+111 0f PF2
+112 17 PF3
+113 1f PF4
+114 27 PF5
+115 2f PF6
+116 37 PF7
+117 3f PF8 NULL MONOCASE
+118 47 PF9
+119 4f PF10
+120 56 PF11
+121 5e PF12
+122 08 PF13
+123 10 PF14
+124 18 PF15
+125 20 PF16
+126 28 PF17
+127 30 PF18
+128 38 PF19
+129 40 PF20
+130 48 PF21
+131 50 PF22
+132 57 PF23
+133 5f PF24
+134 92 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT
+135 D9 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT
+136 99 BREAK_ALT BREAK_ALT BREAK_ALT
+137 B9 BREAK_ALT BREAK_ALT BREAK_ALT
diff --git a/usr.bin/tn3270/ctlr/3270pc.kbd b/usr.bin/tn3270/ctlr/3270pc.kbd
new file mode 100644
index 00000000000..161010347fb
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/3270pc.kbd
@@ -0,0 +1,182 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)3270pc.kbd 4.2 (Berkeley) 4/26/91
+ */
+
+/*
+ * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ]
+ *
+ * keynumber is in decimal, and starts in column 1.
+ * scancode is hexadecimal.
+ * unshifted, etc. - these are either a single ascii character,
+ * or the name of a function or an AID-generating key.
+ *
+ * all fields are separated by a single space.
+ */
+1 0e ` ~
+2 16 1 !
+3 1e 2 @
+4 26 3 #
+5 25 4 $
+6 2e 5 %
+7 36 6 ^
+8 3d 7 &
+9 3e 8 *
+10 46 9 (
+11 45 0 )
+12 4e - _
+13 55 = +
+14 5d
+15 66 LEFT
+16 0d TAB BTAB
+17 15 q Q
+18 1d w W
+19 24 e E
+20 2d r R
+21 2c t T
+22 35 y Y
+23 3c u U
+24 43 i I
+25 44 o O
+26 4d p P
+27 54 [ {
+28 5b \ |
+29 5c
+30 14 CAPS_LOCK
+31 1c a A
+32 1b s S
+33 23 d D
+34 2b f F
+35 34 g G
+36 33 h H
+37 3b j J
+38 42 k K
+39 4b l L
+40 4c ; :
+41 52 ' "
+42 53 ] }
+43 5a NL
+44 12 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT
+45 13 < >
+46 1a z Z
+47 22 x X
+48 21 c C
+49 2a v V
+50 32 b B
+51 31 n N
+52 3a m M
+53 41 , <
+54 49 . >
+55 4a / ?
+56 51
+57 59 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT
+58 11 RESET NULL DVCNL
+59
+60 19 MAKE_ALT MAKE_ALT MAKE_ALT
+61 29 SPACE SPACE
+62 39 MAKE_ALT MAKE_ALT MAKE_ALT
+63
+64 58 ENTER
+65 06 CLEAR NULL TEST
+66 0c NULL NULL ATTN
+67 0b EEOF NULL EINP
+68 0a
+69 09 MAKE_CTRL
+70 05 ATTN NULL TREQ
+71 04
+72 03
+73 83
+74 01
+75 67 PA1 DP
+76 64 BTAB
+77
+78 61 LEFT NULL LEFT2
+79
+80 6e PA2 FM
+81 65 INSRT
+82 63 UP
+83 62 NULL NULL HOME
+84 60 DOWN
+85 6f PA3
+86 6d DELETE
+87
+88 6a RIGHT NULL RIGHT2
+89
+90 76
+91 6c 7
+92 6b 4
+93 69 1
+94 68
+95 77
+96 75 8
+97 73 5
+98 72 2
+99 70 0
+100 7e ,
+101 7d 9
+102 74 6
+103 7a 3
+104 71 .
+105 84 SPACE
+106 7c TAB
+107 7b -
+108 79 ENTER
+109 78
+110 07 PF1
+111 0f PF2
+112 17 PF3
+113 1f PF4
+114 27 PF5
+115 2f PF6
+116 37 PF7
+117 3f PF8 NULL MONOCASE
+118 47 PF9
+119 4f PF10
+120 56 PF11
+121 5e PF12
+122 08 PF13
+123 10 PF14
+124 18 PF15
+125 20 PF16
+126 28 PF17
+127 30 PF18
+128 38 PF19
+129 40 PF20
+130 48 PF21
+131 50 PF22
+132 57 PF23
+133 5f PF24
+134 92 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT
+135 D9 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT
+136 99 BREAK_ALT BREAK_ALT BREAK_ALT
+137 B9 BREAK_ALT BREAK_ALT BREAK_ALT
diff --git a/usr.bin/tn3270/ctlr/api.c b/usr.bin/tn3270/ctlr/api.c
new file mode 100644
index 00000000000..5835532c2c3
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/api.c
@@ -0,0 +1,756 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)api.c 4.5 (Berkeley) 4/26/91";*/
+static char rcsid[] = "$Id: api.c,v 1.1 1995/10/18 08:46:20 deraadt Exp $";
+#endif /* not lint */
+
+/*
+ * This file implements the API used in the PC version.
+ */
+
+#include <stdio.h>
+
+#include "api.h"
+#include "../general/general.h"
+
+#include "../api/disp_asc.h"
+
+#include "screen.h"
+#include "hostctlr.h"
+#include "oia.h"
+
+#include "../general/globals.h"
+
+int apitrace = 0;
+
+/*
+ * Some defines for things we use internally.
+ */
+
+#define PS_SESSION_ID 23
+#define BUF_SESSION_ID 0
+
+/*
+ * General utility routines.
+ */
+
+#if defined(MSDOS)
+
+#if defined(LINT_ARGS)
+static void movetous(char *, int, int, int);
+static void movetothem(int, int, char *, int);
+#endif /* defined(LINT_ARGS) */
+
+#define access_api(foo,length,copyin) (foo)
+#define unaccess_api(foo,goo,length,copyout)
+
+static void
+movetous(parms, es, di, length)
+char *parms;
+int es, di;
+int length;
+{
+ char far *farparms = parms;
+
+ movedata(es, di, FP_SEG(farparms), FP_OFF(farparms), length);
+ if (apitrace) {
+ Dump('(', parms, length);
+ }
+}
+
+static void
+movetothem(es, di, parms, length)
+int es, di;
+char *parms;
+int length;
+{
+ char far *farparms = parms;
+
+ movedata(FP_SEG(farparms), FP_OFF(farparms), es, di, length);
+ if (apitrace) {
+ Dump(')', parms, length);
+ }
+}
+#endif /* defined(MSDOS) */
+
+#if defined(unix)
+extern char *access_api();
+extern void movetous(), movetothem(), unaccess_api();
+#endif /* defined(unix) */
+
+
+/*
+ * Supervisor Services.
+ */
+
+static void
+name_resolution(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ NameResolveParms parms;
+
+ movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms);
+
+ regs->h.cl = 0;
+ if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) {
+ regs->x.dx = GATE_SESSMGR;
+ } else if (memcmp((char *)&parms, NAME_KEYBOARD,
+ sizeof parms.gate_name) == 0) {
+ regs->x.dx = GATE_KEYBOARD;
+ } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) {
+ regs->x.dx = GATE_COPY;
+ } else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) {
+ regs->x.dx = GATE_OIAM;
+ } else {
+ regs->h.cl = 0x2e; /* Name not found */
+ }
+ regs->h.ch = 0x12;
+ regs->h.bh = 7;
+}
+
+/*
+ * Session Information Services.
+ */
+
+static void
+query_session_id(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ QuerySessionIdParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc != 0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.option_code != 0x01) {
+ parms.rc = 0x0d; /* Invalid option code */
+#ifdef NOTOBS
+ } else if ((parms.data_code != 0x45) && (parms.data_code != 0x00/*OBS*/)) {
+ parms.rc = 0x0b;
+#endif /* NOTOBS */
+ } else {
+ NameArray list;
+
+ movetous((char *)&list, FP_SEG(parms.name_array),
+ FP_OFF(parms.name_array), sizeof list);
+ if ((list.length < 14) || (list.length > 170)) {
+ parms.rc = 0x12;
+ } else {
+ list.number_matching_session = 1;
+ list.name_array_element.short_name = parms.data_code;
+ list.name_array_element.type = TYPE_DFT;
+ list.name_array_element.session_id = PS_SESSION_ID;
+ memcpy(list.name_array_element.long_name, "ONLYSESS",
+ sizeof list.name_array_element.long_name);
+ movetothem(FP_SEG(parms.name_array),
+ FP_OFF(parms.name_array), (char *)&list, sizeof list);
+ parms.rc = 0;
+ }
+ }
+ parms.function_id = 0x6b;
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+}
+
+static void
+query_session_parameters(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ QuerySessionParametersParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc !=0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.session_id != PS_SESSION_ID) {
+ parms.rc = 0x02;
+ } else {
+ parms.rc = 0;
+ parms.session_type = TYPE_DFT;
+ parms.session_characteristics = 0; /* Neither EAB nor PSS */
+ parms.rows = MaxNumberLines;
+ parms.columns = MaxNumberColumns;
+ parms.presentation_space = 0;
+ }
+ parms.function_id = 0x6b;
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+}
+
+static void
+query_session_cursor(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ QuerySessionCursorParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc != 0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.session_id != PS_SESSION_ID) {
+ parms.rc = 0x02;
+ } else {
+ parms.rc = 0;
+ parms.cursor_type = CURSOR_BLINKING; /* XXX what is inhibited? */
+ parms.row_address = ScreenLine(CursorAddress);
+ parms.column_address = ScreenLineOffset(CursorAddress);
+ }
+
+ parms.function_id = 0x6b;
+ movetothem(sregs->es, regs->x.di, (char *) &parms, sizeof parms);
+}
+
+/*
+ * Keyboard Services.
+ */
+
+
+static void
+connect_to_keyboard(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ ConnectToKeyboardParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc != 0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.session_id != PS_SESSION_ID) {
+ parms.rc = 0x02;
+ } else if (parms.intercept_options != 0) {
+ parms.rc = 0x01;
+ } else {
+ parms.rc = 0;
+ parms.first_connection_identifier = 0;
+ }
+ parms.function_id = 0x62;
+
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+}
+
+static void
+disconnect_from_keyboard(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ DisconnectFromKeyboardParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc != 0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.session_id != PS_SESSION_ID) {
+ parms.rc = 0x02;
+ } else if (parms.connectors_task_id != 0) {
+ parms.rc = 04; /* XXX */
+ } else {
+ parms.rc = 0;
+ }
+ parms.function_id = 0x62;
+
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+}
+
+static void
+write_keystroke(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ WriteKeystrokeParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc != 0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.session_id != PS_SESSION_ID) {
+ parms.rc = 0x02;
+ } else if (parms.connectors_task_id != 0) {
+ parms.rc = 0x04;
+ } else {
+ parms.number_of_keys_sent = 0;
+ parms.rc = 0;
+ if (parms.options == OPTION_SINGLE_KEYSTROKE) {
+ KeystrokeEntry *entry = &parms.keystroke_specifier.keystroke_entry;
+
+ if (AcceptKeystroke(entry->scancode, entry->shift_state) == 0) {
+ parms.rc = 0x10; /* XXX needs 0x12 too! */
+ }
+ parms.number_of_keys_sent++;
+ } else if (parms.options == OPTION_MULTIPLE_KEYSTROKES) {
+ KeystrokeList
+ list,
+ far *atlist = parms.keystroke_specifier.keystroke_list;
+ KeystrokeEntry
+ entry[10], /* 10 at a time */
+ *ourentry,
+ far *theirentry;
+ int
+ todo;
+
+ movetous((char *)&list, FP_SEG(atlist),
+ FP_OFF(atlist), sizeof *atlist);
+ todo = list.length/2;
+ ourentry = entry+(highestof(entry)+1);
+ theirentry = &atlist->keystrokes;
+
+ while (todo) {
+ if (ourentry > &entry[highestof(entry)]) {
+ int thistime;
+
+ thistime = todo;
+ if (thistime > numberof(entry)) {
+ thistime = numberof(entry);
+ }
+ movetous((char *)entry, FP_SEG(theirentry),
+ FP_OFF(theirentry), thistime*sizeof *theirentry);
+ theirentry += thistime;
+ ourentry = entry;
+ }
+ if (AcceptKeystroke(ourentry->scancode,
+ ourentry->shift_state) == 0) {
+ parms.rc = 0x10; /* XXX needs 0x12 too! */
+ break;
+ }
+ parms.number_of_keys_sent++;
+ ourentry++;
+ todo--;
+ }
+ } else {
+ parms.rc = 0x01;
+ }
+ }
+ parms.function_id = 0x62;
+
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+/* XXX */
+}
+
+
+static void
+disable_input(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ DisableInputParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc != 0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.session_id != PS_SESSION_ID) {
+ parms.rc = 0x02;
+ } else if (parms.connectors_task_id != 0) {
+ parms.rc = 0x04;
+ } else {
+ SetOiaApiInhibit(&OperatorInformationArea);
+ parms.rc = 0;
+ }
+ parms.function_id = 0x62;
+
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+}
+
+static void
+enable_input(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ EnableInputParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc != 0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.session_id != PS_SESSION_ID) {
+ parms.rc = 0x02;
+ } else if (parms.connectors_task_id != 0) {
+ parms.rc = 0x04;
+ } else {
+ ResetOiaApiInhibit(&OperatorInformationArea);
+ parms.rc = 0;
+ }
+ parms.function_id = 0x62;
+
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+}
+
+/*
+ * Copy Services.
+ */
+
+static
+copy_subroutine(target, source, parms, what_is_user, length)
+BufferDescriptor *target, *source;
+CopyStringParms *parms;
+int what_is_user;
+#define USER_IS_TARGET 0
+#define USER_IS_SOURCE 1
+{
+#define TARGET_NO_EAB 1
+#define SOURCE_NO_EAB 2
+#define TARGET_PC 4
+#define SOURCE_PC 8
+#define NO_FIELD_ATTRIBUTES 16
+ int needtodo = 0;
+ int access_length;
+ char far *input;
+ char far *output;
+ char far *access_pointer;
+
+ if ((target->characteristics^source->characteristics)
+ &CHARACTERISTIC_EAB) {
+ if (target->characteristics&CHARACTERISTIC_EAB) {
+ needtodo |= TARGET_NO_EAB; /* Need to bump for EAB in target */
+ } else {
+ needtodo |= SOURCE_NO_EAB; /* Need to bump for EAB in source */
+ }
+ }
+ if (target->session_type != source->session_type) {
+ if (target->session_type == TYPE_PC) {
+ needtodo |= TARGET_PC; /* scan codes to PC */
+ } else {
+ needtodo |= SOURCE_PC; /* PC to scan codes */
+ }
+ }
+ if ((parms->copy_mode&COPY_MODE_FIELD_ATTRIBUTES) == 0) {
+ needtodo |= NO_FIELD_ATTRIBUTES;
+ }
+ access_length = length;
+ if (what_is_user == USER_IS_TARGET) {
+ if (target->characteristics&CHARACTERISTIC_EAB) {
+ access_length *= 2;
+ }
+ input = (char far *) &Host[source->begin];
+ access_pointer = target->buffer;
+ output = access_api(target->buffer, access_length, 0);
+ } else {
+ if (source->characteristics&CHARACTERISTIC_EAB) {
+ access_length *= 2;
+ }
+ access_pointer = source->buffer;
+ input = access_api(source->buffer, access_length, 1);
+ output = (char far *) &Host[target->begin];
+ }
+ while (length--) {
+ if (needtodo&TARGET_PC) {
+ *output++ = disp_asc[*input++];
+ } else if (needtodo&SOURCE_PC) {
+ *output++ = asc_disp[*input++];
+ } else {
+ *output++ = *input++;
+ }
+ if (needtodo&TARGET_NO_EAB) {
+ input++;
+ } else if (needtodo&SOURCE_NO_EAB) {
+ *output++ = 0; /* Should figure out good EAB? */
+ }
+ }
+ if (what_is_user == USER_IS_TARGET) {
+ unaccess_api(target->buffer, access_pointer, access_length, 1);
+ } else {
+ unaccess_api(source->buffer, access_pointer, access_length, 0);
+ }
+}
+
+
+static void
+copy_string(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ CopyStringParms parms;
+ BufferDescriptor *target = &parms.target, *source = &parms.source;
+ int length;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ length = 1+parms.source_end-source->begin;
+ if ((parms.rc != 0) || (parms.function_id !=0)) {
+ parms.rc = 0x0c;
+ } else if (target->session_id == BUF_SESSION_ID) { /* Target is buffer */
+ if (source->session_id != PS_SESSION_ID) { /* A no-no */
+ parms.rc = 0x2;
+ } else {
+ if ((source->begin < 0) || (source->begin > highestof(Host))) {
+ parms.rc = 0x06; /* invalid source definition */
+ } else {
+ if ((source->begin+length) > highestof(Host)) {
+ length = highestof(Host)-source->begin;
+ parms.rc = 0x0f; /* Truncate */
+ }
+ if ((source->characteristics == target->characteristics) &&
+ (source->session_type == target->session_type)) {
+ if (source->characteristics&CHARACTERISTIC_EAB) {
+ length *= 2;
+ }
+ movetothem(FP_SEG(target->buffer),
+ FP_OFF(target->buffer),
+ (char *)&Host[source->begin], length);
+ } else {
+ copy_subroutine(target, source, &parms,
+ USER_IS_TARGET, length);
+ }
+ }
+ }
+ } else if (source->session_id != BUF_SESSION_ID) {
+ parms.rc = 0xd;
+ } else {
+ /* Send to presentation space (3270 buffer) */
+ if ((target->begin < 0) || (target->begin > highestof(Host))) {
+ parms.rc = 0x07; /* invalid target definition */
+ } if (!UnLocked) {
+ parms.rc = 0x03; /* Keyboard locked */
+ } else if (parms.copy_mode != 0) {
+ parms.rc = 0x0f; /* Copy of field attr's not allowed */
+ } else if (IsProtected(target->begin) || /* Make sure no protected */
+ (WhereAttrByte(target->begin) != /* in range */
+ WhereAttrByte(target->begin+length-1))) {
+ parms.rc = 0x0e; /* Attempt to write in protected */
+ } else {
+ if ((target->begin+length) > highestof(Host)) {
+ length = highestof(Host)-target->begin;
+ parms.rc = 0x0f; /* Truncate */
+ }
+ TurnOnMdt(target->begin); /* Things have changed */
+ if ((source->characteristics == target->characteristics) &&
+ (source->session_type == target->session_type)) {
+ if (source->characteristics&CHARACTERISTIC_EAB) {
+ length *= 2;
+ }
+ movetous((char *)&Host[target->begin],
+ FP_SEG(source->buffer),
+ FP_OFF(source->buffer), length);
+ } else {
+ copy_subroutine(target, source, &parms, USER_IS_SOURCE, length);
+ }
+ }
+ }
+ parms.function_id = 0x64;
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+}
+
+
+/*
+ * Operator Information Area Services.
+ */
+
+static void
+read_oia_group(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ ReadOiaGroupParms parms;
+
+ movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
+
+ if ((parms.rc != 0) || (parms.function_id != 0)) {
+ parms.rc = 0x0c;
+ } else if (parms.session_id != PS_SESSION_ID) {
+ parms.rc = 0x02;
+ } else {
+ int group = parms.oia_group_number;
+ char *from;
+ int size;
+
+ if ((group != API_OIA_ALL_GROUPS) &&
+ ((group > API_OIA_LAST_LEGAL_GROUP) || (group < 0))) {
+ } else {
+ if (group == API_OIA_ALL_GROUPS) {
+ size = API_OIA_BYTES_ALL_GROUPS;
+ from = (char *)&OperatorInformationArea;
+ } else if (group == API_OIA_INPUT_INHIBITED) {
+ size = sizeof OperatorInformationArea.input_inhibited;
+ from = (char *)&OperatorInformationArea.input_inhibited[0];
+ } else {
+ size = 1;
+ from = ((char *)&OperatorInformationArea)+group;
+ }
+ movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer),
+ from, size);
+ }
+ }
+ parms.function_id = 0x6d;
+ movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
+}
+
+/*ARGSUSED*/
+static void
+unknown_op(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+ regs->h.ch = 0x12;
+ regs->h.cl = 0x05;
+}
+
+
+handle_api(regs, sregs)
+union REGS *regs;
+struct SREGS *sregs;
+{
+/*
+ * Do we need to log this transaction?
+ */
+ if (apitrace) {
+ Dump('<', (char *)regs, sizeof *regs);
+ Dump('<', (char *)sregs, sizeof *sregs);
+ }
+ if (regs->h.ah == NAME_RESOLUTION) {
+ name_resolution(regs, sregs);
+#if defined(unix)
+ } else if (regs->h.ah == PS_OR_OIA_MODIFIED) {
+ while ((oia_modified == 0) && (ps_modified == 0)) {
+ (void) Scheduler(1);
+ }
+ oia_modified = ps_modified = 0;
+#endif /* defined(unix) */
+ } else if (regs->h.ah != 0x09) {
+ regs->h.ch = 0x12;
+ regs->h.cl = 0x0f; /* XXX Invalid environmental access */
+ } else if (regs->x.bx != 0x8020) {
+ regs->h.ch = 0x12;
+ regs->h.cl = 0x08; /* XXX Invalid wait specified */
+ } else if (regs->h.ch != 0) {
+ regs->x.cx = 0x1206; /* XXX Invalid priority */
+ } else {
+ switch (regs->x.dx) {
+ case GATE_SESSMGR:
+ switch (regs->h.al) {
+ case QUERY_SESSION_ID:
+ if (regs->h.cl != 0) {
+ regs->x.cx = 0x1206;
+ } else {
+ regs->x.cx = 0x1200;
+ query_session_id(regs, sregs);
+ }
+ break;
+ case QUERY_SESSION_PARAMETERS:
+ if (regs->h.cl != 0) {
+ regs->x.cx = 0x1206;
+ } else {
+ regs->x.cx = 0x1200;
+ query_session_parameters(regs, sregs);
+ }
+ break;
+ case QUERY_SESSION_CURSOR:
+ if ((regs->h.cl != 0xff) && (regs->h.cl != 0x00/*OBS*/)) {
+ regs->x.cx = 0x1206;
+ } else {
+ regs->x.cx = 0x1200;
+ query_session_cursor(regs, sregs);
+ }
+ break;
+ default:
+ unknown_op(regs, sregs);
+ break;
+ }
+ break;
+ case GATE_KEYBOARD:
+ if (regs->h.cl != 00) {
+ regs->x.cx = 0x1206;
+ } else {
+ regs->x.cx = 0x1200;
+ switch (regs->h.al) {
+ case CONNECT_TO_KEYBOARD:
+ connect_to_keyboard(regs, sregs);
+ break;
+ case DISABLE_INPUT:
+ disable_input(regs, sregs);
+ break;
+ case WRITE_KEYSTROKE:
+ write_keystroke(regs, sregs);
+ break;
+ case ENABLE_INPUT:
+ enable_input(regs, sregs);
+ break;
+ case DISCONNECT_FROM_KEYBOARD:
+ disconnect_from_keyboard(regs, sregs);
+ break;
+ default:
+ unknown_op(regs, sregs);
+ break;
+ }
+ }
+ break;
+ case GATE_COPY:
+ if (regs->h.cl != 0xff) {
+ regs->x.cx = 0x1206;
+ } else {
+ regs->x.cx = 0x1200;
+ switch (regs->h.al) {
+ case COPY_STRING:
+ copy_string(regs, sregs);
+ break;
+ default:
+ unknown_op(regs, sregs);
+ break;
+ }
+ }
+ break;
+ case GATE_OIAM:
+ if (regs->h.cl != 0xff) {
+ regs->x.cx = 0x1206;
+ } else {
+ regs->x.cx = 0x1200;
+ switch (regs->h.al) {
+ case READ_OIA_GROUP:
+ read_oia_group(regs, sregs);
+ break;
+ default:
+ unknown_op(regs, sregs);
+ break;
+ }
+ }
+ break;
+ default:
+ regs->h.ch = 0x12;
+ regs->h.cl = 0x34; /* Invalid GATE entry */
+ break;
+ }
+ }
+/*
+ * Do we need to log this transaction?
+ */
+ if (apitrace) {
+ Dump('>', (char *)regs, sizeof *regs);
+ Dump('>', (char *)sregs, sizeof *sregs);
+#ifdef MSDOS
+ { char buf[10]; gets(buf); }
+#endif /* MSDOS */
+ }
+}
diff --git a/usr.bin/tn3270/ctlr/api.h b/usr.bin/tn3270/ctlr/api.h
new file mode 100644
index 00000000000..30fac649334
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/api.h
@@ -0,0 +1,404 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)api.h 4.4 (Berkeley) 4/26/91
+ * $Id: api.h,v 1.1 1995/10/18 08:46:20 deraadt Exp $
+ */
+
+/*
+ * This file contains header information used by the PC API routines.
+ */
+
+#if !defined(MSDOS)
+#define far /* For 'far *' checks */
+#endif /* !defined(MSDOS) */
+
+#define API_INTERRUPT_NUMBER 0x7A /* API Interrupt Number */
+
+/*
+ * Define the gate numbers. These are returned via the Name Resolution
+ * service.
+ */
+
+#define GATE_SESSMGR 1234
+#define GATE_KEYBOARD 5678
+#define GATE_COPY 9101
+#define GATE_OIAM 1121
+
+/*
+ * The names which correspond to the above gate numbers.
+ */
+
+#define NAME_SESSMGR "SESSMGR "
+#define NAME_KEYBOARD "KEYBOARD"
+#define NAME_COPY "COPY "
+#define NAME_OIAM "OIAM "
+
+
+/*
+ * Name Resolution is specified in AH.
+ */
+
+#define NAME_RESOLUTION 0x81
+
+#if defined(unix)
+/*
+ * In unix, we offer a service to allow the application to keep from
+ * having to poll us constantly.
+ */
+#define PS_OR_OIA_MODIFIED 0x99
+
+#endif /* defined(unix) */
+
+/*
+ * Codes specified in AL for various services.
+ */
+
+#define QUERY_SESSION_ID 0x01
+#define QUERY_SESSION_PARAMETERS 0x02
+#define QUERY_SESSION_CURSOR 0x0b
+
+#define CONNECT_TO_KEYBOARD 0x01
+#define DISCONNECT_FROM_KEYBOARD 0x02
+#define WRITE_KEYSTROKE 0x04
+#define DISABLE_INPUT 0x05
+#define ENABLE_INPUT 0x06
+
+#define COPY_STRING 0x01
+
+#define READ_OIA_GROUP 0x02
+
+/*
+ * For each service, we define the assoicated parameter blocks.
+ */
+
+/*
+ * Supervisor Services
+ */
+
+typedef struct {
+ char gate_name[8];
+} NameResolveParms;
+
+
+/*
+ * Session Information Services
+ */
+
+typedef struct {
+ char
+ short_name,
+ type,
+ session_id,
+ reserved,
+ long_name[8];
+} NameArrayElement;
+
+typedef struct {
+ unsigned char
+ length,
+ number_matching_session;
+ NameArrayElement
+ name_array_element; /* Variable number */
+} NameArray;
+
+typedef struct {
+ char
+ rc,
+ function_id,
+ option_code,
+ data_code;
+ NameArray far
+ *name_array;
+ char
+ long_name[8];
+} QuerySessionIdParms;
+
+#define ID_OPTION_BY_NAME 0x01 /* By short (or long) name */
+#define ID_OPTION_ALL 0x00 /* All (of specified type */
+
+typedef struct {
+ char
+ rc,
+ function_id,
+ session_id,
+ reserved,
+ session_type,
+ session_characteristics,
+ rows,
+ columns;
+ char far
+ *presentation_space;
+} QuerySessionParametersParms;
+
+#define TYPE_WSCTL 0x01 /* Work Station Control */
+#define TYPE_DFT 0x02 /* DFT Host Session */
+#define TYPE_CUT 0x03 /* CUT Host Session */
+#define TYPE_NOTEPAD 0x04 /* Notepad Session */
+#define TYPE_PC 0x05 /* Personal Computer Session */
+
+#define CHARACTERISTIC_EAB 0x80 /* Extended Attribute Buffer */
+#define CHARACTERISTIC_PSS 0x40 /* Program Symbols Supported */
+
+typedef struct {
+ char
+ rc,
+ function_id,
+ session_id,
+ cursor_type,
+ row_address, /* from 0 */
+ column_address; /* from 0 */
+} QuerySessionCursorParms;
+
+#define CURSOR_INHIBITED_AUTOSCROLL 0x10
+#define CURSOR_INHIBITED 0x04
+#define CURSOR_BLINKING 0x02
+#define CURSOR_BOX 0x01
+typedef struct {
+ char
+ rc,
+ function_id,
+ session_id,
+ reserved;
+ short
+ event_queue_id,
+ input_queue_id;
+ char
+ intercept_options,
+ first_connection_identifier;
+} ConnectToKeyboardParms;
+
+typedef struct {
+ char
+ rc,
+ function_id,
+ session_id,
+ reserved;
+ short
+ connectors_task_id;
+} DisconnectFromKeyboardParms;
+
+typedef struct {
+ unsigned char
+ scancode,
+ shift_state;
+} KeystrokeEntry;
+
+typedef struct {
+ short
+ length; /* Length (in bytes) of list */
+ KeystrokeEntry keystrokes; /* Variable size */
+} KeystrokeList;
+
+typedef struct {
+ char
+ rc,
+ function_id,
+ session_id,
+ reserved;
+ short
+ connectors_task_id;
+ char
+ options,
+ number_of_keys_sent;
+ union {
+ KeystrokeEntry
+ keystroke_entry;
+ KeystrokeList far
+ *keystroke_list;
+ } keystroke_specifier;
+} WriteKeystrokeParms;
+
+#define OPTION_SINGLE_KEYSTROKE 0x20
+#define OPTION_MULTIPLE_KEYSTROKES 0x30
+
+typedef struct {
+ char
+ rc,
+ function_id,
+ session_id,
+ reserved;
+ short
+ connectors_task_id;
+} DisableInputParms;
+
+typedef DisableInputParms EnableInputParms;
+
+typedef struct {
+ char
+ session_id,
+ reserved;
+ char far
+ *buffer;
+ char
+ characteristics,
+ session_type;
+ short
+ begin; /* Offset within buffer */
+} BufferDescriptor;
+
+typedef struct {
+ char
+ rc,
+ function_id;
+ BufferDescriptor
+ source;
+ short
+ source_end; /* Offset within source buffer */
+ BufferDescriptor
+ target;
+ char
+ copy_mode,
+ reserved;
+} CopyStringParms;
+
+#define COPY_MODE_7_COLOR 0x80 /* Else 4 color mode */
+#define COPY_MODE_FIELD_ATTRIBUTES 0x40 /* Else don't copy attributes */
+
+typedef struct {
+ char
+ rc,
+ function_id,
+ session_id,
+ reserved;
+ char far
+ *oia_buffer;
+ char
+ oia_group_number;
+} ReadOiaGroupParms;
+
+/* If the user wants all groups, we return API_OIA_BYTES_ALL_GROUPS bytes */
+#define API_OIA_ALL_GROUPS '\377'
+#define API_OIA_BYTES_ALL_GROUPS 22 /* 22 bytes of data */
+
+/* API_OIA_INPUT_INHIBITED is special. It returns more than on byte of data */
+#define API_OIA_INPUT_INHIBITED 8
+
+#define API_OIA_LAST_LEGAL_GROUP 18 /* Highest legal number */
+
+
+
+#if defined(MSDOS)
+
+#if !defined(FP_SEG)
+#include <dos.h>
+#endif /* !defined(FP_SEG) */
+
+#else /* defined(MSDOS) */
+
+/*
+ * These definitions are here to provide the descriptions of
+ * some registers which are, normally, defined in <dos.h> on
+ * a dos system.
+ */
+
+#define FP_SEG(x) ((unsigned int)(((unsigned long)(x))>>16))
+#define FP_OFF(y) ((unsigned int)(((unsigned long)(y))&0xFFFF))
+
+/*
+ * Undo the preceeding.
+ */
+
+#define SEG_OFF_BACK(x,y) (((x)<<16)|(y))
+
+/*
+ * Now, it is somewhat of a pain, but we need to keep
+ * 8086 conventions about which of the "highlow"'s map
+ * into which of the "words".
+ */
+
+#include <sys/param.h> /* Get ENDIAN from machine/endian.h */
+
+/* Determine endian'ess (if necessary) */
+
+#if !(defined(BYTE_ORDER) && defined(BIG_ENDIAN))
+#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax) */
+#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */
+
+#if defined(vax) || defined(ns32000) || defined(i386) || (defined(mips)&&defined(MIPSEL))
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif /* defined(vax) || defined(ns32000) */
+
+#if defined(sun) || defined(tahoe) || defined(ibm032) || defined(pyr) || defined(gould) || (defined(mips)&&defined(MIPSEB))
+#define BYTE_ORDER BIG_ENDIAN
+#endif /* defined(sun) || defined(tahoe) || defined(ibm032) || defined(pyr) || defined(gould) */
+
+#endif /* !(defined(BYTE_ORDER) && defined(BIG_ENDIAN)) */
+
+struct highlow {
+ unsigned char
+#if BYTE_ORDER == LITTLE_ENDIAN
+ al,
+ ah,
+ bl,
+ bh,
+ cl,
+ ch,
+ dl,
+ dh;
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+#if BYTE_ORDER == BIG_ENDIAN
+ ah,
+ al,
+ bh,
+ bl,
+ ch,
+ cl,
+ dh,
+ dl;
+#endif /* BYTE_ORDER == BIG_ENDIAN */
+};
+
+struct words {
+ unsigned short
+ ax,
+ bx,
+ cx,
+ dx;
+ unsigned short
+ si,
+ di;
+};
+
+union REGS {
+ struct highlow h;
+ struct words x;
+};
+
+struct SREGS {
+ unsigned short
+ cs,
+ ds,
+ es,
+ ss;
+};
+#endif /* defined(MSDOS) (else section) */
diff --git a/usr.bin/tn3270/ctlr/ctlr.order b/usr.bin/tn3270/ctlr/ctlr.order
new file mode 100644
index 00000000000..90fba838932
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/ctlr.order
@@ -0,0 +1,5 @@
+api.o
+inbound.o
+oia.o
+options.o
+outbound.o
diff --git a/usr.bin/tn3270/ctlr/declare.h b/usr.bin/tn3270/ctlr/declare.h
new file mode 100644
index 00000000000..41320ef5743
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/declare.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)declare.h 4.2 (Berkeley) 4/26/91
+ * $Id: declare.h,v 1.1 1995/10/18 08:46:20 deraadt Exp $
+ */
+
+/*
+ * Declarations of routines from the controller.
+ */
+
+extern void
+ AddHost(),
+ DoReadModified(),
+ DoReadBuffer(),
+ OptInit(),
+ SendToIBM(),
+ SendTransparent();
+
+extern int
+ DataFrom3270(),
+ DataFromNetwork(),
+ OptOrder(),
+ OutputClock,
+ TransparentClock;
diff --git a/usr.bin/tn3270/ctlr/externs.h b/usr.bin/tn3270/ctlr/externs.h
new file mode 100644
index 00000000000..ef703e9c729
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/externs.h
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)externs.h 4.2 (Berkeley) 4/26/91
+ * $Id: externs.h,v 1.1 1995/10/18 08:46:21 deraadt Exp $
+ */
+
+/*
+ * External references from the controller.
+ */
+
+#if !defined(MSDOS)
+extern char *access_api();
+extern void movetous(), movetothem(), unaccess_api();
+#endif /* !defined(MSDOS) */
+
+extern unsigned char
+ *memNSchr(); /* Search for a character ANDED, increment by stride */
+
+extern int
+ DataToNetwork(),
+ OutputClock,
+ suspend(),
+ TransparentClock,
+ UnLocked; /* keyboard is UnLocked? */
+
+extern void
+ command(),
+ ConnectScreen(),
+ ExitString(),
+ init_inbound(),
+ LocalClearScreen(),
+ RefreshScreen(),
+ RingBell(),
+ setconnmode(),
+ StopScreen(),
+ TransOut(),
+ TransStop();
diff --git a/usr.bin/tn3270/ctlr/function.c b/usr.bin/tn3270/ctlr/function.c
new file mode 100644
index 00000000000..437d7becdc7
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/function.c
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)function.c 4.2 (Berkeley) 4/26/91";*/
+static char rcsid[] = "$Id: function.c,v 1.1 1995/10/18 08:46:21 deraadt Exp $";
+#endif /* not lint */
+
+/*
+ * This file, which never produces a function.o, is used solely to
+ * be run through the preprocessor.
+ *
+ * On a 4.3 system (or even msdos), "cc -E function.h" would produce
+ * the correct output. Unfortunately, 4.2 compilers aren't quite that
+ * useful.
+ */
+
+#include "function.h"
diff --git a/usr.bin/tn3270/ctlr/function.h b/usr.bin/tn3270/ctlr/function.h
new file mode 100644
index 00000000000..8366d5d1d81
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/function.h
@@ -0,0 +1,167 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)function.h 4.2 (Berkeley) 4/26/91
+ * $Id: function.h,v 1.1 1995/10/18 08:46:21 deraadt Exp $
+ */
+
+/*
+ * The following are the various functions which the keyboard can ask
+ * the controller to perform.
+ *
+ * Note that this file (the following entries) are scanned by mkhit.c,
+ * and that the format must remain more-or-less consistent
+ * [ \t]*TOKEN
+ */
+
+enum ctlrfcn {
+
+ undefined = 0, /* Not yet touched */
+
+ FCN_NULL, /* Illegal sequence */
+
+ FCN_RESET, /* unlock keyboard */
+ FCN_MAKE_SHIFT_LOCK,
+ FCN_BREAK_SHIFT_LOCK,
+
+ FCN_MAKE_SHIFT, /* shift key pressed DOWN */
+ FCN_BREAK_SHIFT, /* shift key released */
+
+ FCN_MAKE_ALT, /* alt key pressed DOWN */
+ FCN_BREAK_ALT, /* alt key released */
+
+ FCN_MAKE_CTRL,
+
+ FCN_CAPS_LOCK,
+
+ FCN_MONOCASE, /* DISPLAY in upper case */
+ FCN_DVCNL,
+
+ FCN_CHARACTER, /* Not one of the following, but ... */
+ FCN_VERTICAL_BAR, /* EBCDIC solid vertical bar */
+ FCN_CENTSIGN, /* EBCDIC cent sign */
+ FCN_SPACE, /* EBCDIC space */
+ FCN_DP, /* EBCDIC dup character */
+ FCN_FM, /* EBCDIC field mark */
+
+ FCN_AID, /* Some AID key */
+ FCN_ATTN,
+ FCN_CURSEL, /* Cursor select function (and aid) */
+ FCN_TEST, /* Test function */
+
+ FCN_EINP, /* erase input (dangerous) */
+ FCN_EEOF,
+ FCN_DELETE,
+ FCN_INSRT,
+ FCN_TAB,
+ FCN_BTAB,
+ FCN_NL,
+ FCN_HOME,
+ FCN_UP,
+ FCN_DOWN,
+ FCN_RIGHT,
+ FCN_LEFT,
+ FCN_LEFT2,
+ FCN_RIGHT2,
+
+#if !defined(PURE3274)
+ /*
+ * Local editing functions
+ */
+ FCN_SETTAB, /* set a column tab */
+ FCN_DELTAB,
+ FCN_COLTAB,
+ FCN_COLBAK,
+ FCN_INDENT, /* more margin over one col tab */
+ FCN_UNDENT,
+ FCN_SETMRG,
+ FCN_SETHOM,
+ FCN_CLRTAB,
+ FCN_ERASE, /* erase last character */
+ FCN_WERASE,
+ FCN_FERASE,
+ FCN_WORDTAB, /* tab to start of next word */
+ FCN_WORDBACKTAB,
+ FCN_WORDEND, /* find next end of word */
+ FCN_FIELDEND, /* find next end of field */
+
+ /*
+ * APL functions
+ */
+ FCN_APLON, /* start using apl character set */
+ FCN_APLOFF,
+ FCN_APLEND,
+
+ FCN_PCON,
+ FCN_PCOFF,
+ FCN_INIT, /* re-init screen */
+ FCN_SYNCH, /* synch up after line/control error */
+ FCN_FLINP, /* flush input buffer */
+ FCN_RESHOW, /* redraw screen */
+ FCN_MASTER_RESET, /* FLINP, RESET, RESHOW, + more */
+
+ FCN_DISC, /* suspend application */
+ FCN_ESCAPE, /* enter command mode */
+
+ FCN_ALTK, /* Dvorak keyboard */
+
+ FCN_XOFF, /* suspend output to screen */
+ FCN_XON, /* resume output to screen */
+
+ FCN_LPRT /* print screen on printer */
+#endif /* !defined(PURE3274) */
+};
+/*
+ * The following is the structure which defines what a 3270 keystroke
+ * can do.
+ */
+
+struct hits {
+ unsigned char keynumber;
+ struct hit {
+ enum ctlrfcn ctlrfcn;
+ unsigned char code; /* AID value or 3270 display code */
+ } hit[4]; /* plain, shifted, alted, shiftalted */
+};
+
+extern struct hits hits[];
+
+/*
+ * Definitions of the shift state (and the left/right shift key position).
+ */
+
+#define SHIFT_RIGHT 0x20 /* Right shift key is down */
+#define SHIFT_LEFT 0x10 /* Left shift key is down */
+#define SHIFT_CONTROL 0x08 /* Control shift state (unused) */
+#define SHIFT_ALT 0x04 /* ALT shift state */
+#define SHIFT_CAPS 0x02 /* Caps lock state */
+#define SHIFT_UPSHIFT 0x01 /* Upshift state */
diff --git a/usr.bin/tn3270/ctlr/hostctlr.h b/usr.bin/tn3270/ctlr/hostctlr.h
new file mode 100644
index 00000000000..21358db89f4
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/hostctlr.h
@@ -0,0 +1,223 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)hostctlr.h 4.2 (Berkeley) 4/26/91
+ * $Id: hostctlr.h,v 1.1 1995/10/18 08:46:21 deraadt Exp $
+ */
+
+#define INCLUDED_HOST3270
+
+/* define orders given to 3270's */
+
+#define ORDER_SF 0x1d /* Start Field */
+#define ORDER_SFE 0x29 /* Start Field Extended */
+#define ORDER_SBA 0x11 /* Set Buffer Address (for output) */
+#define ORDER_SA 0x28 /* Set Attribute */
+#define ORDER_MF 0x2c /* Modify field */
+#define ORDER_IC 0x13 /* Insert Cursor (at buffer address) */
+#define ORDER_PT 0x05 /* Program Tab (absurdly complicated) */
+#define ORDER_RA 0x3c /* Repeat next character to some addr */
+#define ORDER_EUA 0x12 /* Null out every unprotected field
+ * to some address.
+ */
+#define ORDER_GE 0x08 /* Graphics Escape */
+#define ORDER_YALE 0x2b /* This is a special YALE order, which
+ * introduces YALE extended orders
+ * (like setting tabs, etc.).
+ */
+
+/* The following is defined for initialization and error messages. */
+
+struct orders_def {
+ int
+ code; /* As in 3270 data stream */
+ char
+ *short_name, /* Short name */
+ *long_name; /* Long name */
+};
+
+#define ORDERS_DEF { \
+ ORDER_SF, "SF", "Start Field", \
+ ORDER_SFE, "SFE", "Start Field Extended", \
+ ORDER_SBA, "SBA", "Set Buffer Address", \
+ ORDER_SA, "SA", "Set Attribute", \
+ ORDER_MF, "MF", "Modify Field", \
+ ORDER_IC, "IC", "Insert Cursor", \
+ ORDER_PT, "PT", "Program Tab", \
+ ORDER_RA, "RA", "Repeat to Address", \
+ ORDER_EUA, "EUA", "Erase Unprotected to Address", \
+ ORDER_GE, "GE", "Graphics Escape", \
+ ORDER_YALE, "YALE", "Yale Order" \
+ }
+
+
+#define ATTR_RESET 0x00 /* SA only - reset to default */
+# define ATTR_DEFAULT 0x00 /* reset to default */
+ /* Also for 0x41-43 below */
+#define ATTR_FIELD 0xC0 /* Field attributes */
+# define ATTR_MASK 0xc0 /* control bits */
+# define ATTR_PROT 0x20 /* protected bit */
+# define ATTR_NUMERIC 0x10 /* numeric field */
+# define ATTR_AUTO_SKIP_MASK 0x30 /* mask to check auto skip */
+# define ATTR_AUTO_SKIP_VALUE 0x30 /* value to have auto skip */
+# define ATTR_DSPD_MASK 0x0c /* highlighting, etc. */
+# define ATTR_DSPD_DNSPD 0x00 /* display, no select */
+# define ATTR_DSPD_DSPD 0x04 /* display, select */
+# define ATTR_DSPD_HIGH 0x08 /* highlighted, select */
+# define ATTR_DSPD_NONDISPLAY 0x0c /* non-display, no select */
+# define ATTR_MDT 0x01 /* modified data tag */
+
+#define ATTR_EXTENDED_HIGHLIGHT 0x41 /* Extended highlighting */
+# define ATTR_BLINK 0xf1 /* Blinking */
+# define ATTR_REVERSE_VIDEO 0xf2 /* Reverse video */
+# define ATTR_UNDERSCORE 0xf3 /* Underline */
+#define ATTR_COLOR 0x42 /* Color */
+# define ATTR_BLUE 0xf1
+# define ATTR_RED 0xf2
+# define ATTR_PINK 0xf3
+# define ATTR_GREEN 0xf4
+# define ATTR_TURQUOISE 0xf5
+# define ATTR_YELLOW 0xf6
+# define ATTR_WHITE 0xf7 /* for 3279; black for 3287; */
+ /* multicolor for triple */
+ /* plane symbol */
+#define ATTR_PROGRAMMED_SYMBOLS 0x43 /* Programmed Symbols */
+# define ATTR_SYMBOL_SET_LOW 0x40 /* Lowest loadable set ID */
+# define ATTR_SYMBOL_SET_HIGH 0xef /* Highest loadable set ID */
+# define ATTR_SYMBOL_SET_APLTEXT 0xf1
+
+/* Non-SNA control unit commands */
+
+#define CMD_ERASE_ALL_UNPROTECTED 0x0f
+#define CMD_ERASE_WRITE 0x05
+#define CMD_ERASE_WRITE_ALTERNATE 0x0d
+#define CMD_READ_BUFFER 0x02
+#define CMD_READ_MODIFIED 0x06
+#define CMD_WRITE 0x01
+#define CMD_WRITE_STRUCTURED_FIELD 0x11
+
+/* SNA control unit commands */
+
+#define CMD_SNA_COPY 0xf7
+#define CMD_SNA_ERASE_ALL_UNPROTECTED 0x6f
+#define CMD_SNA_ERASE_WRITE 0xf5
+#define CMD_SNA_ERASE_WRITE_ALTERNATE 0x7e
+#define CMD_SNA_READ_BUFFER 0xf2
+#define CMD_SNA_READ_MODIFIED 0xf6
+#define CMD_SNA_READ_MODIFIED_ALL 0x6e
+#define CMD_SNA_WRITE 0xf1
+#define CMD_SNA_WRITE_STRUCTURED_FIELD 0xf3
+
+
+#define WCC_RESET 0x40
+#define WCC_ALARM 0x04
+#define WCC_RESTORE 0x02
+#define WCC_RESET_MDT 0x01
+
+
+/* Special EBCDIC characters unique to a 3270 */
+
+#define EBCDIC_BLANK 0x40 /* Space */
+#define EBCDIC_CENTSIGN 0x4a /* Cent sign */
+#define EBCDIC_DUP 0x1c /* DUP character */
+#define EBCDIC_FM 0x1e /* Field mark character */
+#define EBCDIC_PERCENT 0x6c /* Percent sign */
+#define EBCDIC_SLASH 0x61 /* Slash */
+#define EBCDIC_SOH 0x01 /* Start of Heading */
+#define EBCDIC_STX 0x02 /* Start of Text */
+
+/* Structured field types */
+#define SF_3270DS 0x40 /* For write operations */
+#define SF_LPS 0x06 /* Load Programmed Symbols */
+#define SF_SRM 0x09 /* Set Reply Mode */
+#define SF_SWO 0x0b /* Set Window Origin */
+#define SF_READ_PARTITION 0x01 /* Read Partition (Query) */
+#define SF_ERASE_RESET 0x03 /* Erase (and/or Reset) */
+#define SF_SCS_DATA 0x41 /* SCS Data */
+#define SF_CREATE_PARTITION 0x0c /* Create a partition */
+
+/* AID characters sent to host.
+ *
+ * Note that this file (the following entries) are scanned by mkhit.c,
+ * and that the format must remain more-or-less consistent
+ * (#define\tAID_name\t[\t]*TOKEN)
+ */
+
+#define AID_NONE 0x60 /* No AID (display) */
+#define AID_NONE_PRINTER 0xe8 /* No AID (printer) */
+
+#define AID_PA1 0x6c
+#define AID_PA2 0x6e
+#define AID_PA3 0x6b
+#define AID_CLEAR 0x6d
+#define AID_TREQ 0xf0
+#define AID_ENTER 0x7d
+#define AID_SELPEN 0x7e /*
+ * Really, only SELPEN with DESIGNATOR
+ * = space or null
+ */
+#define AID_PF1 0xf1
+#define AID_PF2 0xf2
+#define AID_PF3 0xf3
+#define AID_PF4 0xf4
+#define AID_PF5 0xf5
+#define AID_PF6 0xf6
+#define AID_PF7 0xf7
+#define AID_PF8 0xf8
+#define AID_PF9 0xf9
+#define AID_PF10 0x7a
+#define AID_PF11 0x7b
+#define AID_PF12 0x7c
+#define AID_PF13 0xc1
+#define AID_PF14 0xc2
+#define AID_PF15 0xc3
+#define AID_PF16 0xc4
+#define AID_PF17 0xc5
+#define AID_PF18 0xc6
+#define AID_PF19 0xc7
+#define AID_PF20 0xc8
+#define AID_PF21 0xc9
+#define AID_PF22 0x4a
+#define AID_PF23 0x4b
+#define AID_PF24 0x4c
+#define AID_PF25 0xd1
+#define AID_PF26 0xd2
+#define AID_PF27 0xd3
+#define AID_PF28 0xd4
+#define AID_PF29 0xd5
+#define AID_PF30 0xd6
+#define AID_PF31 0xd7
+#define AID_PF32 0xd8
+#define AID_PF33 0xd9
+#define AID_PF34 0x5a
+#define AID_PF35 0x5b
+#define AID_PF36 0x5c
diff --git a/usr.bin/tn3270/ctlr/inbound.c b/usr.bin/tn3270/ctlr/inbound.c
new file mode 100644
index 00000000000..babadac867b
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/inbound.c
@@ -0,0 +1,1195 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)inbound.c 4.3 (Berkeley) 4/26/91";*/
+static char rcsid[] = "$Id: inbound.c,v 1.1 1995/10/18 08:46:21 deraadt Exp $";
+#endif /* not lint */
+
+#include <stdio.h>
+
+#include "../general/general.h"
+#include "function.h"
+#include "hostctlr.h"
+#include "oia.h"
+#include "scrnctlr.h"
+#include "screen.h"
+#include "options.h"
+#include "../api/dctype.h"
+#include "../api/ebc_disp.h"
+
+#include "../general/globals.h"
+#include "externs.h"
+#include "declare.h"
+
+#define EmptyChar() (ourPTail == ourPHead)
+#define FullChar() (ourPHead == ourBuffer+sizeof ourBuffer)
+
+
+/*
+ * We define something to allow us to to IsProtected() quickly
+ * on unformatted screens (with the current algorithm for fields,
+ * unprotected takes exponential time...).
+ *
+ * The idea is to call SetXIsProtected() BEFORE the
+ * loop, then use XIsProtected().
+ */
+
+#define SetXIsProtected() (XWasSF = 1)
+#define XIsProtected(p) (IsStartField(p)? \
+ XWasSF = 1 : \
+ (XWasSF? \
+ (XWasSF = 0, XProtected = IsProtected(p)) : \
+ XProtected))
+
+static char ourBuffer[400];
+
+static char *ourPHead = ourBuffer,
+ *ourPTail = ourBuffer;
+
+static int HadAid; /* Had an AID haven't sent */
+
+static int InsertMode; /* is the terminal in insert mode? */
+
+static unsigned int
+ rememberedshiftstate; /* Shift (alt) state of terminal */
+
+# define HITNUM(s) ((((s)&(SHIFT_CAPS|SHIFT_UPSHIFT))? 1:0) \
+ + ((((s)&SHIFT_ALT)? 1:0)<<1))
+
+static int XWasSF, XProtected; /* For optimizations */
+#if !defined(PURE3274)
+extern int TransparentClock, OutputClock;
+#endif /* !defined(PURE3274) */
+
+#include "kbd.out" /* Get keyboard mapping function */
+
+/* the following are global variables */
+
+extern int UnLocked; /* keyboard is UnLocked? */
+
+
+/*
+ * init_inbound :
+ *
+ * Reset variables to initial state.
+ */
+
+void
+init_inbound()
+{
+ ourPHead = ourPTail = ourBuffer;
+ HadAid = 0;
+ rememberedshiftstate = 0;
+ InsertMode = 0;
+}
+
+
+/* Tab() - sets cursor to the start of the next unprotected field */
+static void
+Tab()
+{
+ register int i, j;
+
+ i = CursorAddress;
+ j = WhereAttrByte(CursorAddress);
+ do {
+ if (IsStartField(i) && IsUnProtected(ScreenInc(i))) {
+ break;
+ }
+ i = FieldInc(i);
+ } while (i != j);
+ if (IsStartField(i) && IsUnProtected(ScreenInc(i))) {
+ CursorAddress = ScreenInc(i);
+ } else {
+ CursorAddress = SetBufferAddress(0,0);
+ }
+}
+
+
+/* BackTab() - sets cursor to the start of the most recent field */
+
+static void
+BackTab()
+{
+ register int i;
+
+ i = ScreenDec(CursorAddress);
+ for (;;) {
+ if (IsStartField(ScreenDec(i)) && IsUnProtected(i)) {
+ CursorAddress = i;
+ break;
+ }
+ if (i == CursorAddress) {
+ CursorAddress = SetBufferAddress(0,0);
+ break;
+ }
+ i = ScreenDec(i);
+ }
+}
+
+/*
+ * ModifyMdt() - Turn a modified data tag bit on or off (watch
+ * out for unformatted screens).
+ */
+
+ModifyMdt(x,on)
+int x;
+int on;
+{
+ int i = x;
+
+ if (IsStartField(i)) { /* If we are at a start field position... */
+ if (on) {
+ ModifyHost(i, |= ATTR_MDT); /* Turn it on */
+ } else {
+ ModifyHost(i, &= ~ATTR_MDT); /* Turn it off */
+ }
+ } else {
+ i = WhereAttrByte(i); /* Find beginning of field */
+ if (IsStartField(i)) { /* Is there one? */
+ if (on) {
+ ModifyHost(i, |= ATTR_MDT); /* Turn it on */
+ } else {
+ ModifyHost(i, &= ~ATTR_MDT); /* Turn it off */
+ }
+ } /* else, don't modify - this is an unformatted screen */
+ }
+}
+
+
+/* EraseEndOfField - erase all characters to the end of a field */
+
+static void
+EraseEndOfField()
+{
+ register int i;
+
+ if (IsProtected(CursorAddress)) {
+ RingBell("Protected Field");
+ } else {
+ TurnOnMdt(CursorAddress);
+ if (FormattedScreen()) {
+ i = CursorAddress;
+ do {
+ AddHost(i, 0);
+ i = ScreenInc(i);
+ } while ((i != CursorAddress) && !IsStartField(i));
+ } else { /* Screen is Unformatted */
+ i = CursorAddress;
+ do {
+ AddHost(i, 0);
+ i = ScreenInc(i);
+ } while (i != HighestScreen());
+ }
+ }
+}
+
+/* Delete() - deletes a character from the screen
+ *
+ * What we want to do is delete the section
+ * [where, from-1] from the screen,
+ * filling in with what comes at from.
+ *
+ * The deleting continues to the end of the field (or
+ * until the cursor wraps).
+ *
+ * From can be a start of a field. We
+ * check for that. However, there can't be any
+ * fields that start between where and from.
+ * We don't check for that.
+ *
+ * Also, we assume that the protection status of
+ * everything has been checked by the caller.
+ *
+ */
+
+static void
+Delete(where, from)
+register int where, /* Where to start deleting from */
+ from; /* Where to pull back from */
+{
+ register int i;
+
+ TurnOnMdt(where); /* Only do this once in this field */
+ i = where;
+ do {
+ if (IsStartField(from)) {
+ AddHost(i, 0); /* Stick the edge at the start field */
+ } else {
+ AddHost(i, (char)GetHost(from));
+ from = ScreenInc(from); /* Move the edge */
+ }
+ i = ScreenInc(i);
+ } while ((!IsStartField(i)) && (i != where));
+}
+
+static void
+ColBak()
+{
+ register int i;
+
+ i = ScreenLineOffset(CursorAddress);
+ for (i = i-1; i >= 0; i--) {
+ if (OptColTabs[i]) {
+ break;
+ }
+ }
+ if (i < 0) {
+ i = 0;
+ }
+ CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i);
+}
+
+static void
+ColTab()
+{
+ register int i;
+
+ i = ScreenLineOffset(CursorAddress);
+ for (i = i+1; i < NumberColumns; i++) {
+ if (OptColTabs[i]) {
+ break;
+ }
+ }
+ if (i >= NumberColumns) {
+ i = NumberColumns-1;
+ }
+ CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i);
+}
+
+static void
+Home()
+{
+ register int i;
+ register int j;
+
+ i = SetBufferAddress(OptHome, 0);
+ j = WhereLowByte(i);
+ /*
+ * If the initial value of i points to the field attribute of
+ * an unprotected field, we need to return the address of the
+ * first data byte in the field (assuming there are any!).
+ */
+ if (IsStartField(i) && IsUnProtected(j)) {
+ CursorAddress = j;
+ return;
+ }
+ do {
+ if (IsUnProtected(i)) {
+ CursorAddress = i;
+ return;
+ }
+ /* the following could be a problem if we got here with an
+ * unformatted screen. However, this is "impossible", since
+ * with an unformatted screen, the IsUnProtected(i) above
+ * should be true.
+ */
+ i = ScreenInc(FieldInc(i));
+ } while (i != j);
+ CursorAddress = LowestScreen();
+}
+
+static
+LastOfField(i)
+register int i; /* position to start from */
+{
+ register int j;
+ register int k;
+
+ k = j = i;
+ SetXIsProtected();
+ while (XIsProtected(i) || Disspace(GetHost(i))) {
+ i = ScreenInc(i);
+ if (i == j) {
+ break;
+ }
+ }
+ /* We are now IN a word IN an unprotected field (or wrapped) */
+ while (!XIsProtected(i)) {
+ if (!Disspace(GetHost(i))) {
+ k = i;
+ }
+ i = ScreenInc(i);
+ if (i == j) {
+ break;
+ }
+ }
+ return(k);
+}
+
+
+static void
+FlushChar()
+{
+ ourPTail = ourPHead = ourBuffer;
+}
+
+
+/*
+ * Add one EBCDIC (NOT display code) character to the buffer.
+ */
+
+static void
+AddChar(character)
+char character;
+{
+ if (FullChar()) {
+ ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 0);
+ if (EmptyChar()) {
+ FlushChar();
+ } else {
+ char buffer[100];
+
+ sprintf(buffer, "File %s, line %d: No room in network buffer!\n",
+ __FILE__, __LINE__);
+ ExitString(buffer, 1);
+ /*NOTREACHED*/
+ }
+ }
+ *ourPHead++ = character;
+}
+
+
+static void
+SendUnformatted()
+{
+ register int i, j;
+ register int Nulls;
+ register int c;
+
+ /* look for start of field */
+ Nulls = 0;
+ i = j = LowestScreen();
+ do {
+ c = GetHost(i);
+ if (c == 0) {
+ Nulls++;
+ } else {
+ while (Nulls) {
+ Nulls--;
+ AddChar(EBCDIC_BLANK); /* put in blanks */
+ }
+ AddChar((char)disp_ebc[c]);
+ }
+ i = ScreenInc(i);
+ } while (i != j);
+}
+
+static
+SendField(i, cmd)
+register int i; /* where we saw MDT bit */
+int cmd; /* The command code (type of read) */
+{
+ register int j;
+ register int k;
+ register int Nulls;
+ register int c;
+
+ /* look for start of field */
+ i = j = WhereLowByte(i);
+
+ /* On a test_request_read, don't send sba and address */
+ if ((AidByte != AID_TREQ)
+ || (cmd == CMD_SNA_READ_MODIFIED_ALL)) {
+ AddChar(ORDER_SBA); /* set start field */
+ AddChar(BufferTo3270_0(j)); /* set address of this field */
+ AddChar(BufferTo3270_1(j));
+ }
+ /*
+ * Only on read_modified_all do we return the contents
+ * of the field when the attention was caused by a
+ * selector pen.
+ */
+ if ((AidByte != AID_SELPEN)
+ || (cmd == CMD_SNA_READ_MODIFIED_ALL)) {
+ if (!IsStartField(j)) {
+ Nulls = 0;
+ k = ScreenInc(WhereHighByte(j));
+ do {
+ c = GetHost(j);
+ if (c == 0) {
+ Nulls++;
+ } else {
+ while (Nulls) {
+ Nulls--;
+ AddChar(EBCDIC_BLANK); /* put in blanks */
+ }
+ AddChar((char)disp_ebc[c]);
+ }
+ j = ScreenInc(j);
+ } while ((j != k) && (j != i));
+ }
+ } else {
+ j = FieldInc(j);
+ }
+ return(j);
+}
+
+/* Various types of reads... */
+void
+DoReadModified(cmd)
+int cmd; /* The command sent */
+{
+ register int i, j;
+
+ if (AidByte) {
+ if (AidByte != AID_TREQ) {
+ AddChar(AidByte);
+ } else {
+ /* Test Request Read header */
+ AddChar(EBCDIC_SOH);
+ AddChar(EBCDIC_PERCENT);
+ AddChar(EBCDIC_SLASH);
+ AddChar(EBCDIC_STX);
+ }
+ } else {
+ AddChar(AID_NONE);
+ }
+ if (((AidByte != AID_PA1) && (AidByte != AID_PA2)
+ && (AidByte != AID_PA3) && (AidByte != AID_CLEAR))
+ || (cmd == CMD_SNA_READ_MODIFIED_ALL)) {
+ if ((AidByte != AID_TREQ)
+ || (cmd == CMD_SNA_READ_MODIFIED_ALL)) {
+ /* Test request read_modified doesn't give cursor address */
+ AddChar(BufferTo3270_0(CursorAddress));
+ AddChar(BufferTo3270_1(CursorAddress));
+ }
+ i = j = WhereAttrByte(LowestScreen());
+ /* Is this an unformatted screen? */
+ if (!IsStartField(i)) { /* yes, handle separate */
+ SendUnformatted();
+ } else {
+ do {
+ if (HasMdt(i)) {
+ i = SendField(i, cmd);
+ } else {
+ i = FieldInc(i);
+ }
+ } while (i != j);
+ }
+ }
+ ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1);
+ if (EmptyChar()) {
+ FlushChar();
+ HadAid = 0; /* killed that buffer */
+ }
+}
+
+/* A read buffer operation... */
+
+void
+DoReadBuffer()
+{
+ register int i, j;
+
+ if (AidByte) {
+ AddChar(AidByte);
+ } else {
+ AddChar(AID_NONE);
+ }
+ AddChar(BufferTo3270_0(CursorAddress));
+ AddChar(BufferTo3270_1(CursorAddress));
+ i = j = LowestScreen();
+ do {
+ if (IsStartField(i)) {
+ AddChar(ORDER_SF);
+ AddChar(BufferTo3270_1(FieldAttributes(i)));
+ } else {
+ AddChar((char)disp_ebc[GetHost(i)]);
+ }
+ i = ScreenInc(i);
+ } while (i != j);
+ ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1);
+ if (EmptyChar()) {
+ FlushChar();
+ HadAid = 0; /* killed that buffer */
+ }
+}
+
+/* Send some transparent data to the host */
+
+void
+SendTransparent(buffer, count)
+char *buffer;
+int count;
+{
+ char stuff[3];
+
+ stuff[0] = AID_NONE_PRINTER;
+ stuff[1] = BufferTo3270_0(count);
+ stuff[2] = BufferTo3270_1(count);
+ DataToNetwork(stuff, sizeof stuff, 0);
+ DataToNetwork(buffer, count, 1);
+}
+
+
+/* Try to send some data to host */
+
+void
+SendToIBM()
+{
+#if !defined(PURE3274)
+ if (TransparentClock >= OutputClock) {
+ if (HadAid) {
+ AddChar(AidByte);
+ HadAid = 0;
+ } else {
+ AddChar(AID_NONE_PRINTER);
+ }
+ do {
+ ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1);
+ } while (!EmptyChar());
+ FlushChar();
+ } else if (HadAid) {
+ DoReadModified(CMD_READ_MODIFIED);
+ }
+#else /* !defined(PURE3274) */
+ if (HadAid) {
+ DoReadModified(CMD_READ_MODIFIED);
+ }
+#endif /* !defined(PURE3274) */
+}
+
+/* This takes in one character from the keyboard and places it on the
+ * screen.
+ */
+
+static void
+OneCharacter(c, insert)
+int c; /* character (Ebcdic) to be shoved in */
+int insert; /* are we in insert mode? */
+{
+ register int i, j;
+
+ if (IsProtected(CursorAddress)) {
+ RingBell("Protected Field");
+ return;
+ }
+ if (insert) {
+ /* is the last character in the field a blank or null? */
+ i = ScreenDec(FieldInc(CursorAddress));
+ j = GetHost(i);
+ if (!Disspace(j)) {
+ RingBell("No more room for insert");
+ return;
+ } else {
+ for (j = ScreenDec(i); i != CursorAddress;
+ j = ScreenDec(j), i = ScreenDec(i)) {
+ AddHost(i, (char)GetHost(j));
+ }
+ }
+ }
+ AddHost(CursorAddress, c);
+ TurnOnMdt(CursorAddress);
+ CursorAddress = ScreenInc(CursorAddress);
+ if (IsStartField(CursorAddress) &&
+ ((FieldAttributes(CursorAddress)&ATTR_AUTO_SKIP_MASK) ==
+ ATTR_AUTO_SKIP_VALUE)) {
+ Tab();
+ }
+}
+
+/*
+ * AcceptKeystroke()
+ *
+ * Processes one keystroke.
+ *
+ * Returns:
+ *
+ * 0 if this keystroke was NOT processed.
+ * 1 if everything went OK.
+ */
+
+int
+AcceptKeystroke(scancode, shiftstate)
+unsigned int
+ scancode, /* 3270 scancode */
+ shiftstate; /* The shift state */
+{
+ register int c;
+ register int i;
+ register int j;
+ enum ctlrfcn ctlrfcn;
+
+ if (scancode >= numberof(hits)) {
+ ExitString(
+ "Unknown scancode encountered in AcceptKeystroke.\n", 1);
+ /*NOTREACHED*/
+ }
+ ctlrfcn = hits[scancode].hit[HITNUM(shiftstate)].ctlrfcn;
+ c = hits[scancode].hit[HITNUM(shiftstate)].code;
+
+ if (!UnLocked || HadAid) {
+ if (HadAid) {
+ SendToIBM();
+ if (!EmptyChar()) {
+ return 0; /* nothing to do */
+ }
+ }
+#if !defined(PURE3274)
+ if (!HadAid && EmptyChar()) {
+ if ((ctlrfcn == FCN_RESET) || (ctlrfcn == FCN_MASTER_RESET)) {
+ UnLocked = 1;
+ }
+ }
+#endif /* !defined(PURE3274) */
+ if (!UnLocked) {
+ return 0;
+ }
+ }
+
+ /* now, either empty, or haven't seen aid yet */
+
+#if !defined(PURE3274)
+ /*
+ * If we are in transparent (output) mode, do something special
+ * with keystrokes.
+ */
+ if (TransparentClock == OutputClock) {
+ if (ctlrfcn == FCN_AID) {
+ UnLocked = 0;
+ InsertMode = 0;
+ AidByte = (c);
+ HadAid = 1;
+ } else {
+ switch (ctlrfcn) {
+ case FCN_ESCAPE:
+ StopScreen(1);
+ command(0, NULL, 0);
+ if (shell_active == 0) {
+ ConnectScreen();
+ }
+ break;
+
+ case FCN_RESET:
+ case FCN_MASTER_RESET:
+ UnLocked = 1;
+ break;
+
+ default:
+ return 0;
+ }
+ }
+ }
+#endif /* !defined(PURE3274) */
+
+ if (ctlrfcn == FCN_CHARACTER) {
+ /* Add the character to the buffer */
+ OneCharacter(c, InsertMode);
+ } else if (ctlrfcn == FCN_AID) { /* got Aid */
+ if (c == AID_CLEAR) {
+ LocalClearScreen(); /* Side effect is to clear 3270 */
+ }
+ ResetOiaOnlineA(&OperatorInformationArea);
+ SetOiaTWait(&OperatorInformationArea);
+ ResetOiaInsert(&OperatorInformationArea);
+ InsertMode = 0; /* just like a 3278 */
+ SetOiaSystemLocked(&OperatorInformationArea);
+ SetOiaModified();
+ UnLocked = 0;
+ AidByte = c;
+ HadAid = 1;
+ SendToIBM();
+ } else {
+ switch (ctlrfcn) {
+
+ case FCN_CURSEL:
+ c = FieldAttributes(CursorAddress)&ATTR_DSPD_MASK;
+ if (!FormattedScreen()
+ || ((c != ATTR_DSPD_DSPD) && (c != ATTR_DSPD_HIGH))) {
+ RingBell("Cursor not in selectable field");
+ } else {
+ i = ScreenInc(WhereAttrByte(CursorAddress));
+ c = GetHost(i);
+ if (c == DISP_QUESTION) {
+ AddHost(i, DISP_GREATER_THAN);
+ TurnOnMdt(i);
+ } else if (c == DISP_GREATER_THAN) {
+ AddHost(i, DISP_QUESTION);
+ TurnOffMdt(i);
+ } else if (c == DISP_BLANK || c == DISP_NULL
+ || c == DISP_AMPERSAND) {
+ UnLocked = 0;
+ InsertMode = 0;
+ ResetOiaOnlineA(&OperatorInformationArea);
+ SetOiaTWait(&OperatorInformationArea);
+ SetOiaSystemLocked(&OperatorInformationArea);
+ ResetOiaInsert(&OperatorInformationArea);
+ SetOiaModified();
+ if (c == DISP_AMPERSAND) {
+ TurnOnMdt(i); /* Only for & type */
+ AidByte = AID_ENTER;
+ } else {
+ AidByte = AID_SELPEN;
+ }
+ HadAid = 1;
+ SendToIBM();
+ } else {
+ RingBell(
+ "Cursor not in a selectable field (designator)");
+ }
+ }
+ break;
+
+#if !defined(PURE3274)
+ case FCN_ERASE:
+ if (IsProtected(ScreenDec(CursorAddress))) {
+ RingBell("Protected Field");
+ } else {
+ CursorAddress = ScreenDec(CursorAddress);
+ Delete(CursorAddress, ScreenInc(CursorAddress));
+ }
+ break;
+ case FCN_WERASE:
+ j = CursorAddress;
+ i = ScreenDec(j);
+ if (IsProtected(i)) {
+ RingBell("Protected Field");
+ } else {
+ SetXIsProtected();
+ while ((!XIsProtected(i) && Disspace(GetHost(i)))
+ && (i != j)) {
+ i = ScreenDec(i);
+ }
+ /* we are pointing at a character in a word, or
+ * at a protected position
+ */
+ while ((!XIsProtected(i) && !Disspace(GetHost(i)))
+ && (i != j)) {
+ i = ScreenDec(i);
+ }
+ /* we are pointing at a space, or at a protected
+ * position
+ */
+ CursorAddress = ScreenInc(i);
+ Delete(CursorAddress, j);
+ }
+ break;
+
+ case FCN_FERASE:
+ if (IsProtected(CursorAddress)) {
+ RingBell("Protected Field");
+ } else {
+ CursorAddress = ScreenInc(CursorAddress); /* for btab */
+ BackTab();
+ EraseEndOfField();
+ }
+ break;
+
+ case FCN_RESET:
+ if (InsertMode) {
+ InsertMode = 0;
+ ResetOiaInsert(&OperatorInformationArea);
+ SetOiaModified();
+ }
+ break;
+ case FCN_MASTER_RESET:
+ if (InsertMode) {
+ InsertMode = 0;
+ ResetOiaInsert(&OperatorInformationArea);
+ SetOiaModified();
+ }
+ RefreshScreen();
+ break;
+#endif /* !defined(PURE3274) */
+
+ case FCN_UP:
+ CursorAddress = ScreenUp(CursorAddress);
+ break;
+
+ case FCN_LEFT:
+ CursorAddress = ScreenDec(CursorAddress);
+ break;
+
+ case FCN_RIGHT:
+ CursorAddress = ScreenInc(CursorAddress);
+ break;
+
+ case FCN_DOWN:
+ CursorAddress = ScreenDown(CursorAddress);
+ break;
+
+ case FCN_DELETE:
+ if (IsProtected(CursorAddress)) {
+ RingBell("Protected Field");
+ } else {
+ Delete(CursorAddress, ScreenInc(CursorAddress));
+ }
+ break;
+
+ case FCN_INSRT:
+ InsertMode = !InsertMode;
+ if (InsertMode) {
+ SetOiaInsert(&OperatorInformationArea);
+ } else {
+ ResetOiaInsert(&OperatorInformationArea);
+ }
+ SetOiaModified();
+ break;
+
+ case FCN_HOME:
+ Home();
+ break;
+
+ case FCN_NL:
+ /* The algorithm is to look for the first unprotected
+ * column after column 0 of the following line. Having
+ * found that unprotected column, we check whether the
+ * cursor-address-at-entry is at or to the right of the
+ * LeftMargin AND the LeftMargin column of the found line
+ * is unprotected. If this conjunction is true, then
+ * we set the found pointer to the address of the LeftMargin
+ * column in the found line.
+ * Then, we set the cursor address to the found address.
+ */
+ i = SetBufferAddress(ScreenLine(ScreenDown(CursorAddress)), 0);
+ j = ScreenInc(WhereAttrByte(CursorAddress));
+ do {
+ if (IsUnProtected(i)) {
+ break;
+ }
+ /* Again (see comment in Home()), this COULD be a problem
+ * with an unformatted screen.
+ */
+ /* If there was a field with only an attribute byte,
+ * we may be pointing to the attribute byte of the NEXT
+ * field, so just look at the next byte.
+ */
+ if (IsStartField(i)) {
+ i = ScreenInc(i);
+ } else {
+ i = ScreenInc(FieldInc(i));
+ }
+ } while (i != j);
+ if (!IsUnProtected(i)) { /* couldn't find unprotected */
+ i = SetBufferAddress(0,0);
+ }
+ if (OptLeftMargin <= ScreenLineOffset(CursorAddress)) {
+ if (IsUnProtected(SetBufferAddress(ScreenLine(i),
+ OptLeftMargin))) {
+ i = SetBufferAddress(ScreenLine(i), OptLeftMargin);
+ }
+ }
+ CursorAddress = i;
+ break;
+
+ case FCN_EINP:
+ if (!FormattedScreen()) {
+ i = CursorAddress;
+ TurnOffMdt(i);
+ do {
+ AddHost(i, 0);
+ i = ScreenInc(i);
+ } while (i != CursorAddress);
+ } else {
+ /*
+ * The algorithm is: go through each unprotected
+ * field on the screen, clearing it out. When
+ * we are at the start of a field, skip that field
+ * if its contents are protected.
+ */
+ i = j = FieldInc(CursorAddress);
+ do {
+ if (IsUnProtected(ScreenInc(i))) {
+ i = ScreenInc(i);
+ TurnOffMdt(i);
+ do {
+ AddHost(i, 0);
+ i = ScreenInc(i);
+ } while (!IsStartField(i));
+ } else {
+ i = FieldInc(i);
+ }
+ } while (i != j);
+ }
+ Home();
+ break;
+
+ case FCN_EEOF:
+ EraseEndOfField();
+ break;
+
+ case FCN_SPACE:
+ OneCharacter(DISP_BLANK, InsertMode); /* Add cent */
+ break;
+
+ case FCN_CENTSIGN:
+ OneCharacter(DISP_CENTSIGN, InsertMode); /* Add cent */
+ break;
+
+ case FCN_FM:
+ OneCharacter(DISP_FM, InsertMode); /* Add field mark */
+ break;
+
+ case FCN_DP:
+ if (IsProtected(CursorAddress)) {
+ RingBell("Protected Field");
+ } else {
+ OneCharacter(DISP_DUP, InsertMode);/* Add dup character */
+ Tab();
+ }
+ break;
+
+ case FCN_TAB:
+ Tab();
+ break;
+
+ case FCN_BTAB:
+ BackTab();
+ break;
+
+#ifdef NOTUSED /* Actually, this is superseded by unix flow
+ * control.
+ */
+ case FCN_XOFF:
+ Flow = 0; /* stop output */
+ break;
+
+ case FCN_XON:
+ if (!Flow) {
+ Flow = 1; /* turn it back on */
+ DoTerminalOutput();
+ }
+ break;
+#endif /* NOTUSED */
+
+#if !defined(PURE3274)
+ case FCN_ESCAPE:
+ /* FlushChar(); do we want to flush characters from before? */
+ StopScreen(1);
+ command(0, NULL, 0);
+ if (shell_active == 0) {
+ ConnectScreen();
+ }
+ break;
+
+ case FCN_DISC:
+ StopScreen(1);
+ suspend();
+ setconnmode();
+ ConnectScreen();
+ break;
+
+ case FCN_RESHOW:
+ RefreshScreen();
+ break;
+
+ case FCN_SETTAB:
+ OptColTabs[ScreenLineOffset(CursorAddress)] = 1;
+ break;
+
+ case FCN_DELTAB:
+ OptColTabs[ScreenLineOffset(CursorAddress)] = 0;
+ break;
+
+ /*
+ * Clear all tabs, home line, and left margin.
+ */
+ case FCN_CLRTAB:
+ for (i = 0; i < sizeof OptColTabs; i++) {
+ OptColTabs[i] = 0;
+ }
+ OptHome = 0;
+ OptLeftMargin = 0;
+ break;
+
+ case FCN_COLTAB:
+ ColTab();
+ break;
+
+ case FCN_COLBAK:
+ ColBak();
+ break;
+
+ case FCN_INDENT:
+ ColTab();
+ OptLeftMargin = ScreenLineOffset(CursorAddress);
+ break;
+
+ case FCN_UNDENT:
+ ColBak();
+ OptLeftMargin = ScreenLineOffset(CursorAddress);
+ break;
+
+ case FCN_SETMRG:
+ OptLeftMargin = ScreenLineOffset(CursorAddress);
+ break;
+
+ case FCN_SETHOM:
+ OptHome = ScreenLine(CursorAddress);
+ break;
+
+ /*
+ * Point to first character of next unprotected word on
+ * screen.
+ */
+ case FCN_WORDTAB:
+ i = CursorAddress;
+ SetXIsProtected();
+ while (!XIsProtected(i) && !Disspace(GetHost(i))) {
+ i = ScreenInc(i);
+ if (i == CursorAddress) {
+ break;
+ }
+ }
+ /* i is either protected, a space (blank or null),
+ * or wrapped
+ */
+ while (XIsProtected(i) || Disspace(GetHost(i))) {
+ i = ScreenInc(i);
+ if (i == CursorAddress) {
+ break;
+ }
+ }
+ CursorAddress = i;
+ break;
+
+ case FCN_WORDBACKTAB:
+ i = ScreenDec(CursorAddress);
+ SetXIsProtected();
+ while (XIsProtected(i) || Disspace(GetHost(i))) {
+ i = ScreenDec(i);
+ if (i == CursorAddress) {
+ break;
+ }
+ }
+ /* i is pointing to a character IN an unprotected word
+ * (or i wrapped)
+ */
+ while (!Disspace(GetHost(i))) {
+ i = ScreenDec(i);
+ if (i == CursorAddress) {
+ break;
+ }
+ }
+ CursorAddress = ScreenInc(i);
+ break;
+
+ /* Point to last non-blank character of this/next
+ * unprotected word.
+ */
+ case FCN_WORDEND:
+ i = ScreenInc(CursorAddress);
+ SetXIsProtected();
+ while (XIsProtected(i) || Disspace(GetHost(i))) {
+ i = ScreenInc(i);
+ if (i == CursorAddress) {
+ break;
+ }
+ }
+ /* we are pointing at a character IN an
+ * unprotected word (or we wrapped)
+ */
+ while (!Disspace(GetHost(i))) {
+ i = ScreenInc(i);
+ if (i == CursorAddress) {
+ break;
+ }
+ }
+ CursorAddress = ScreenDec(i);
+ break;
+
+ /* Get to last non-blank of this/next unprotected
+ * field.
+ */
+ case FCN_FIELDEND:
+ i = LastOfField(CursorAddress);
+ if (i != CursorAddress) {
+ CursorAddress = i; /* We moved; take this */
+ } else {
+ j = FieldInc(CursorAddress); /* Move to next field */
+ i = LastOfField(j);
+ if (i != j) {
+ CursorAddress = i; /* We moved; take this */
+ }
+ /* else - nowhere else on screen to be; stay here */
+ }
+ break;
+#endif /* !defined(PURE3274) */
+
+ default:
+ /* We don't handle this yet */
+ RingBell("Function not implemented");
+ }
+ }
+ return 1; /* We did something! */
+}
+
+
+/*
+ * We get data from the terminal. We keep track of the shift state
+ * (including ALT, CONTROL), and then call AcceptKeystroke to actually
+ * process any non-shift keys.
+ */
+
+int
+DataFrom3270(buffer, count)
+unsigned char *buffer; /* where the data is */
+int count; /* how much data there is */
+{
+ int origCount;
+
+ origCount = count;
+
+ while (count) {
+ if (*buffer >= numberof(hits)) {
+ ExitString("Unknown scancode encountered in DataFrom3270.\n", 1);
+ /*NOTREACHED*/
+ }
+
+ switch (hits[*buffer].hit[HITNUM(rememberedshiftstate)].ctlrfcn) {
+
+ case FCN_MAKE_SHIFT:
+ rememberedshiftstate |= (SHIFT_RIGHT|SHIFT_UPSHIFT);
+ break;
+ case FCN_BREAK_SHIFT:
+ rememberedshiftstate &= ~(SHIFT_RIGHT|SHIFT_UPSHIFT);
+ break;
+ case FCN_MAKE_ALT:
+ rememberedshiftstate |= SHIFT_ALT;
+ break;
+ case FCN_BREAK_ALT:
+ rememberedshiftstate &= ~SHIFT_ALT;
+ break;
+ default:
+ if (AcceptKeystroke(*buffer, rememberedshiftstate) == 0) {
+ return(origCount-count);
+ }
+ break;
+ }
+ buffer++;
+ count--;
+ }
+ return(origCount-count);
+}
diff --git a/usr.bin/tn3270/ctlr/oia.c b/usr.bin/tn3270/ctlr/oia.c
new file mode 100644
index 00000000000..7de14480fae
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/oia.c
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)oia.c 4.2 (Berkeley) 4/26/91";*/
+static char rcsid[] = "$Id: oia.c,v 1.1 1995/10/18 08:46:21 deraadt Exp $";
+#endif /* not lint */
+
+/*
+ * Routines to maintain the Operator Information Area.
+ */
+
+#include "../general/general.h"
+
+#include "oia.h"
+#include "../general/globals.h"
+
+
+init_oia()
+{
+ ClearElement(OperatorInformationArea);
+}
diff --git a/usr.bin/tn3270/ctlr/oia.h b/usr.bin/tn3270/ctlr/oia.h
new file mode 100644
index 00000000000..33c61128527
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/oia.h
@@ -0,0 +1,191 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)oia.h 4.2 (Berkeley) 4/26/91
+ * $Id: oia.h,v 1.1 1995/10/18 08:46:21 deraadt Exp $
+ */
+
+/*
+ * This file describes the Operator Information Area in the 3270.
+ *
+ * Our OIA looks like that used by the 3270 PC and PC 3270 products.
+ */
+
+#define INCLUDED_OIA
+
+typedef struct {
+ char
+ online_ownership,
+ character_selection,
+ shift_state,
+ pss_group_1,
+ highlight_group_1,
+ color_group_1,
+ insert,
+ input_inhibited[5],
+ pss_group_2,
+ highlight_group_2,
+ color_group_2,
+ comm_error_reminder,
+ printer_status,
+ reserved_group_14,
+ reserved_group_15,
+ autokey_play_record_status,
+ autokey_abort_pause_status,
+ enlarge_state;
+} OIA;
+
+/* Bits in online_ownership */
+#define OIA_SETUP 0x80
+#define OIA_TEST 0x40
+#define OIA_SSCP_LU 0x20
+#define OIA_LU_LU 0x10
+#define OIA_UNOWNED 0x08
+#define OIA_SUBSYSTEM_READY 0x04
+
+/* Bit in character_selection */
+#define OIA_EXTENDED_SELECT 0x80
+#define OIA_APL 0x40
+#define OIA_KANA 0x20
+#define OIA_ALPHA 0x10
+#define OIA_TEXT 0x08
+
+/* Bits in shift_state */
+#define OIA_NUMERIC 0x80
+#define OIA_UPPER_SHIFT 0x40
+
+/* Bits in pss_group_1, highlight_group_1, and color_group_1 */
+#define OIA_SELECTABLE 0x80
+#define OIA_FIELD_INHERIT 0x40
+
+/* Bits in insert */
+#define OIA_INSERT_MODE 0x80
+
+/* We define this to be a 'long' followed by a 'char' (5 bytes) */
+
+#define OIA_NON_RESETTABLE 0x80
+#define OIA_SECURITY_KEY 0x40
+#define OIA_MACHINE_CHECK 0x20
+#define OIA_COMM_CHECK 0x10
+#define OIA_PROGRAM_CHECK 0x08
+#define OIA_RETRY 0x04
+#define OIA_DEVICE_NOT_WORKING 0x02
+#define OIA_DEVICE_VERY_BUSY 0x01
+
+#define OIA_DEVICE_BUSY 0x80
+#define OIA_TERMINAL_WAIT 0x40
+#define OIA_MINUS_SYMBOL 0x20
+#define OIA_MINUS_FUNCTION 0x10
+#define OIA_TOO_MUCH_ENTERED 0x08
+#define OIA_NOT_ENOUGH_ENTERED 0x04
+#define OIA_WRONG_NUMBER 0x02
+#define OIA_NUMERIC_FIELD 0x01
+
+#define OIA_OP_UNAUTHORIZED 0x80
+#define OIA_OP_UNAUTHORIZED_MIN 0x40
+#define OIA_INVALID_DEAD_KEY_COMBO 0x20
+#define OIA_WRONG_PLACE 0x10
+
+#define OIA_MESSAGE_PENDING 0x80
+#define OIA_PARTITION_WAIT 0x40
+#define OIA_SYSTEM_WAIT 0x20
+#define OIA_HARDWARE_MISMATCH 0x10
+#define OIA_LOGICAL_TERM_NOT_CONF 0x08
+
+
+#define OIA_AUTOKEY_INHIBIT 0x80
+#define OIA_API_INHIBIT 0x40
+
+/* Bits in pss_group_2 */
+#define OIA_PS_SELECTED 0x80
+#define OIA_PC_DISPLAY_DISABLE 0x40
+
+/* Bits in highlight_group_2 and color_group_2 */
+#define OIA_SELECTED 0x80
+
+/* Bits in comm_error_reminder */
+#define OIA_COMM_ERROR 0x80
+#define OIA_RTM 0x40
+
+/* Bits in printer_status */
+#define OIA_PRINT_NOT_CUSTOM 0x80
+#define OIA_PRINTER_MALFUNCTION 0x40
+#define OIA_PRINTER_PRINTING 0x20
+#define OIA_ASSIGN_PRINTER 0x10
+#define OIA_WHAT_PRINTER 0x08
+#define OIA_PRINTER_ASSIGNMENT 0x04
+
+/* Bits in autokey_play_record_status */
+#define OIA_PLAY 0x80
+#define OIA_RECORD 0x40
+
+/* Bits in autokey_abort_pause_status */
+#define OIA_RECORDING_OVERFLOW 0x80
+#define OIA_PAUSE 0x40
+
+/* Bits in enlarge_state */
+#define OIA_WINDOW_IS_ENLARGED 0x80
+
+/* Define functions to set and read the oia */
+
+#define SetOiaOnlineA(oia) SetOiaMyJob((oia)) /* Side-effect */
+#define ResetOiaOnlineA(oia) \
+ /* Nothing defined for this */
+
+#define IsOiaReady3274(oia) ((oia)->online_ownership&OIA_SUBSYSTEM_READY)
+#define ResetOiaReady3274(oia) (oia)->online_ownership &= ~OIA_SUBSYSTEM_READY
+#define SetOiaReady3274(oia) (oia)->online_ownership |= OIA_SUBSYSTEM_READY
+
+#define IsOiaMyJob(oia) ((oia)->online_ownership&OIA_LU_LU)
+#define ResetOiaMyJob(oia) (oia)->online_ownership &= ~OIA_LU_LU
+#define SetOiaMyJob(oia) (oia)->online_ownership |= OIA_LU_LU
+
+#define IsOiaInsert(oia) ((oia)->online_ownership&OIA_INSERT_MODE)
+#define ResetOiaInsert(oia) (oia)->online_ownership &= ~OIA_INSERT_MODE
+#define SetOiaInsert(oia) (oia)->online_ownership |= OIA_INSERT_MODE
+
+#define IsOiaSystemLocked(oia) ((oia)->input_inhibited[3]&OIA_SYSTEM_WAIT)
+#define ResetOiaSystemLocked(oia) \
+ (oia)->input_inhibited[3] &= ~OIA_SYSTEM_WAIT
+#define SetOiaSystemLocked(oia) (oia)->input_inhibited[3] |= OIA_SYSTEM_WAIT
+
+#define IsOiaTWait(oia) ((oia)->input_inhibited[1]&OIA_TERMINAL_WAIT)
+#define ResetOiaTWait(oia) (oia)->input_inhibited[1] &= ~OIA_TERMINAL_WAIT
+#define SetOiaTWait(oia) (oia)->input_inhibited[1] |= OIA_TERMINAL_WAIT
+
+#define IsOiaApiInhibit(oia) ((oia)->input_inhibited[4] & OIA_API_INHIBIT)
+#define ResetOiaApiInhibit(oia) ((oia)->input_inhibited[4] &= ~OIA_API_INHIBIT)
+#define SetOiaApiInhibit(oia) ((oia)->input_inhibited[4] |= OIA_API_INHIBIT)
+
+/* A macro to let the world know that someone has modified the OIA. */
+#define SetOiaModified() oia_modified = 1
+#define SetPsModified() ps_modified = 1
diff --git a/usr.bin/tn3270/ctlr/options.c b/usr.bin/tn3270/ctlr/options.c
new file mode 100644
index 00000000000..6c0f49243e6
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/options.c
@@ -0,0 +1,182 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)options.c 4.2 (Berkeley) 4/26/91";*/
+static char rcsid[] = "$Id: options.c,v 1.1 1995/10/18 08:46:21 deraadt Exp $";
+#endif /* not lint */
+
+/*
+ * this file contains the definitions, initialization, and processing of
+ * commands to handle the various local options (APL ON, etc.)
+ */
+
+#include "options.h"
+
+#include "../general/globals.h"
+#include "declare.h"
+
+void
+OptInit()
+{
+ register int i;
+
+ OptAPLmode = 0;
+ OptNullProcessing = 1; /* improved null processing */
+ OptZonesMode = 0; /* zones mode off */
+ OptEnterNL = 0; /* regular enter/new line keys */
+ OptColFieldTab = 0; /* regular column/field tab keys */
+ OptPacing = 1; /* do pacing */
+ OptAlphaInNumeric = 0; /* allow alpha in numeric fields */
+ for (i = 0; i < sizeof OptColTabs; i++) {
+ OptColTabs[i] = ((i%8) == 0); /* every 8 columns */
+ }
+ OptHome = 0;
+ OptLeftMargin = 0;
+ OptWordWrap = 0;
+}
+
+OptOrder(pointer, count, control)
+unsigned char *pointer;
+int count;
+int control;
+{
+ int i, j, character, origCount;
+
+ origCount = count;
+
+ if (count == 0) {
+ return(0);
+ }
+ character = *pointer&0xff;
+ pointer++;
+ count--;
+ switch (character) {
+ case 0xa0:
+ OptAPLmode = 1;
+ break;
+ case 0x61:
+ OptAPLmode = 0;
+ break;
+ case 0x95:
+ OptNullProcessing = 0;
+ break;
+ case 0xd5:
+ OptNullProcessing = 1;
+ break;
+ case 0xa9:
+ OptZonesMode = 1;
+ break;
+ case 0xe9:
+ OptZonesMode = 0;
+ break;
+ case 0x85:
+ OptEnterNL = 1;
+ break;
+ case 0xc5:
+ OptEnterNL = 0;
+ break;
+ case 0x83:
+ OptColFieldTab = 1;
+ break;
+ case 0xc3:
+ OptColFieldTab = 0;
+ break;
+ case 0x97:
+ OptPacing = 0;
+ break;
+ case 0xd7:
+ OptPacing = 1;
+ break;
+ case 0xa5:
+ OptAlphaInNumeric = 1;
+ break;
+ case 0xe5:
+ OptAlphaInNumeric = 0;
+ break;
+ case 0xe3:
+ if (!control && count < 30) {
+ return(0); /* want more! */
+ }
+ for (i = 0; i < sizeof OptColTabs; i++) {
+ OptColTabs[i] = 0;
+ }
+ if (!count) {
+ break;
+ }
+ j = (*pointer&0xff)-0x40;
+ count--;
+ pointer++;
+ if (j < 0 || j >= 24) {
+ break;
+ }
+ OptHome = j;
+ if (!count) {
+ break;
+ }
+ j = (*pointer&0xff)-0x40;
+ count--;
+ pointer++;
+ if (j < 0 || j >= 80) {
+ break;
+ }
+ OptLeftMargin = j;
+ if (!count) {
+ break;
+ }
+ i = count;
+ if (i > 28) {
+ i = 28;
+ }
+ while (i) {
+ j = (*pointer&0xff)-0x40;
+ if (j < 0 || j >= sizeof OptColTabs) {
+ break;
+ }
+ OptColTabs[j] = 1;
+ i --;
+ pointer++;
+ count--;
+ }
+ break;
+ case 0xa6:
+ OptWordWrap = 1;
+ break;
+ case 0xe6:
+ OptWordWrap = 0;
+ break;
+ default:
+ break;
+ }
+ return(origCount - count);
+}
diff --git a/usr.bin/tn3270/ctlr/options.h b/usr.bin/tn3270/ctlr/options.h
new file mode 100644
index 00000000000..fe2fbfa1f7e
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/options.h
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)options.h 4.2 (Berkeley) 4/26/91
+ * $Id: options.h,v 1.1 1995/10/18 08:46:21 deraadt Exp $
+ */
+
+/*
+ * the various options that run our life. Very few of these are implemented
+ * as yet.
+ */
+
+#define INCLUDED_OPTIONS
diff --git a/usr.bin/tn3270/ctlr/outbound.c b/usr.bin/tn3270/ctlr/outbound.c
new file mode 100644
index 00000000000..eda42e2475c
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/outbound.c
@@ -0,0 +1,606 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)outbound.c 4.3 (Berkeley) 4/26/91";*/
+static char rcsid[] = "$Id: outbound.c,v 1.1 1995/10/18 08:46:21 deraadt Exp $";
+#endif /* not lint */
+
+#include <stdio.h>
+
+#include "../general/general.h"
+
+#include "hostctlr.h"
+#include "oia.h"
+#include "screen.h"
+#include "../api/ebc_disp.h"
+
+#include "../general/globals.h"
+#include "externs.h"
+#include "declare.h"
+
+#define SetHighestLowest(position) { \
+ if (position < Lowest) { \
+ Lowest = position; \
+ } \
+ if (position > Highest) { \
+ Highest = position; \
+ } \
+ }
+
+
+static int LastWasTerminated = 1; /* was "control" = 1 last time? */
+
+/* some globals */
+
+#if !defined(PURE3274)
+int OutputClock; /* what time it is */
+int TransparentClock; /* time we were last in transparent */
+#endif /* !defined(PURE3274) */
+
+char CIABuffer[64] = {
+ 0x40, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
+};
+
+static struct orders_def orders_def[] = ORDERS_DEF;
+
+/*
+ * init_ctlr()
+ *
+ * Initialize all data from the 'data' portion to their startup values.
+ */
+
+void
+init_ctlr()
+{
+ LastWasTerminated = 1;
+ init_inbound();
+ init_oia();
+}
+
+
+FieldInc(position)
+register int position; /* Position in previous field */
+{
+ register ScreenImage *ptr;
+
+ ptr = (ScreenImage *)memNSchr((char *)Host+position+1, ATTR_MASK,
+ HighestScreen()-position, ATTR_MASK, sizeof Host[0]);
+ if (ptr == 0) {
+ ptr = (ScreenImage *)memNSchr((char *)Host+LowestScreen(), ATTR_MASK,
+ position-LowestScreen(), ATTR_MASK, sizeof Host[0]);
+ if (ptr == 0) {
+ return LowestScreen();
+ }
+ }
+ return ptr-Host;
+}
+
+FieldDec(position)
+int position;
+{
+ register ScreenImage *ptr;
+
+ ptr = (ScreenImage *)memNSchr((char *)(Host+position)-1, ATTR_MASK,
+ position-LowestScreen(), ATTR_MASK, -sizeof Host[0]);
+ if (ptr == 0) {
+ ptr = (ScreenImage *)memNSchr((char *)Host+HighestScreen(), ATTR_MASK,
+ HighestScreen()-position, ATTR_MASK, -sizeof Host[0]);
+ if (ptr == 0) {
+ return LowestScreen();
+ }
+ }
+ return ptr-Host;
+}
+
+/* Clear3270 - called to clear the screen */
+
+void
+Clear3270()
+{
+ ClearArray(Host);
+ DeleteAllFields(); /* get rid of all fields */
+ BufferAddress = SetBufferAddress(0,0);
+ CursorAddress = SetBufferAddress(0,0);
+ Lowest = LowestScreen();
+ Highest = HighestScreen();
+}
+
+/* AddHost - called to add a character to the buffer.
+ * We use a macro in this module, since we call it so
+ * often from loops.
+ *
+ * NOTE: It is a macro, so don't go around using AddHost(p, *c++), or
+ * anything similar. (I don't define any temporary variables, again
+ * just for the speed.)
+ */
+void
+AddHost(position, character)
+int position;
+char character;
+{
+# define AddHostA(p,c) \
+ { \
+ if (IsStartField(p)) { \
+ DeleteField(p); \
+ Highest = HighestScreen(); \
+ Lowest = LowestScreen(); \
+ SetHighestLowest(p); \
+ } \
+ SetHost(p, c); \
+ }
+# define AddHost(p,c) \
+ { \
+ if (c != GetHost(p)) { \
+ SetHighestLowest(p); \
+ } \
+ AddHostA(p,c); \
+ } /* end of macro of AddHost */
+
+ AddHost(position, character);
+}
+
+/* returns the number of characters consumed */
+int
+DataFromNetwork(Buffer, count, control)
+char *Buffer; /* what the data is */
+register int count; /* and how much there is */
+int control; /* this buffer ended block? */
+{
+ int origCount;
+ register unsigned char *buffer = (unsigned char *)Buffer;
+ register int c;
+ register int i;
+ static int Command;
+ static int Wcc;
+
+ origCount = count;
+
+ /*
+ * If this is the start of a new data stream, then look
+ * for an op-code and (possibly) a WCC.
+ */
+ if (LastWasTerminated) {
+
+ if (count < 2) {
+ if (count == 0) {
+ ExitString("Short count received from host!\n", 1);
+ return(count);
+ }
+ Command = buffer[0];
+ switch (Command) { /* This had better be a read command */
+ case CMD_READ_MODIFIED:
+ case CMD_SNA_READ_MODIFIED:
+ case CMD_SNA_READ_MODIFIED_ALL:
+ SetOiaOnlineA(&OperatorInformationArea);
+ SetOiaModified();
+ DoReadModified(Command);
+ break;
+ case CMD_READ_BUFFER:
+ case CMD_SNA_READ_BUFFER:
+ SetOiaOnlineA(&OperatorInformationArea);
+ SetOiaModified();
+ DoReadBuffer();
+ break;
+ default:
+ {
+ char s_buffer[100];
+
+ sprintf(s_buffer,
+ "Unexpected read command code 0x%x received.\n",
+ Command);
+ ExitString(s_buffer, 1);
+ break;
+ }
+ }
+ return(1); /* We consumed everything */
+ }
+ Command = buffer[0];
+ Wcc = buffer[1];
+ if (Wcc & WCC_RESET_MDT) {
+ i = c = WhereAttrByte(LowestScreen());
+ do {
+ if (HasMdt(i)) {
+ TurnOffMdt(i);
+ }
+ i = FieldInc(i);
+ } while (i != c);
+ }
+
+ switch (Command) {
+ case CMD_ERASE_WRITE:
+ case CMD_ERASE_WRITE_ALTERNATE:
+ case CMD_SNA_ERASE_WRITE:
+ case CMD_SNA_ERASE_WRITE_ALTERNATE:
+ {
+ int newlines, newcolumns;
+
+ SetOiaOnlineA(&OperatorInformationArea);
+ ResetOiaTWait(&OperatorInformationArea);
+ SetOiaModified();
+ if ((Command == CMD_ERASE_WRITE)
+ || (Command == CMD_SNA_ERASE_WRITE)) {
+ newlines = 24;
+ newcolumns = 80;
+ } else {
+ newlines = MaxNumberLines;
+ newcolumns = MaxNumberColumns;
+ }
+ if ((newlines != NumberLines)
+ || (newcolumns != NumberColumns)) {
+ /*
+ * The LocalClearScreen() is really for when we
+ * are going from a larger screen to a smaller
+ * screen, and we need to clear off the stuff
+ * at the end of the lines, or the lines at
+ * the end of the screen.
+ */
+ LocalClearScreen();
+ NumberLines = newlines;
+ NumberColumns = newcolumns;
+ ScreenSize = NumberLines * NumberColumns;
+ }
+ Clear3270();
+#if !defined(PURE3274)
+ if (TransparentClock == OutputClock) {
+ TransStop();
+ }
+#endif /* !defined(PURE3274) */
+ break;
+ }
+
+ case CMD_ERASE_ALL_UNPROTECTED:
+ case CMD_SNA_ERASE_ALL_UNPROTECTED:
+ SetOiaOnlineA(&OperatorInformationArea);
+ ResetOiaTWait(&OperatorInformationArea);
+ SetOiaModified();
+ CursorAddress = HighestScreen()+1;
+ for (i = LowestScreen(); i <= HighestScreen(); i = ScreenInc(i)) {
+ if (IsUnProtected(i)) {
+ if (CursorAddress > i) {
+ CursorAddress = i;
+ }
+ AddHost(i, '\0');
+ }
+ if (HasMdt(i)) {
+ TurnOffMdt(i);
+ }
+ }
+ if (CursorAddress == HighestScreen()+1) {
+ CursorAddress = SetBufferAddress(0,0);
+ }
+ UnLocked = 1;
+ AidByte = 0;
+ ResetOiaSystemLocked(&OperatorInformationArea);
+ SetOiaModified();
+ TerminalIn();
+ break;
+ case CMD_WRITE:
+ case CMD_SNA_WRITE:
+ SetOiaOnlineA(&OperatorInformationArea);
+ ResetOiaTWait(&OperatorInformationArea);
+ SetOiaModified();
+ break;
+ default:
+ {
+ char s_buffer[100];
+
+ sprintf(s_buffer,
+ "Unexpected write command code 0x%x received.\n",
+ Command);
+ ExitString(s_buffer, 1);
+ break;
+ }
+ }
+
+ count -= 2; /* strip off command and wcc */
+ buffer += 2;
+
+ } else {
+#if !defined(PURE3274)
+ if (TransparentClock == OutputClock) {
+ TransOut(buffer, count, -1, control);
+ count = 0;
+ }
+#endif /* !defined(PURE3274) */
+ }
+ LastWasTerminated = 0; /* then, reset at end... */
+
+ while (count) {
+ count--;
+ c = *buffer++;
+ if (IsOrder(c)) {
+ /* handle an order */
+ switch (c) {
+# define Ensure(x) if (count < x) { \
+ if (!control) { \
+ return(origCount-(count+1)); \
+ } else { \
+ /* XXX - should not occur */ \
+ count = 0; \
+ break; \
+ } \
+ }
+ case ORDER_SF:
+ Ensure(1);
+ c = *buffer++;
+ count--;
+ if ( ! (IsStartField(BufferAddress) &&
+ FieldAttributes(BufferAddress) == c)) {
+ SetHighestLowest(BufferAddress);
+ NewField(BufferAddress,c);
+ }
+ BufferAddress = ScreenInc(BufferAddress);
+ break;
+ case ORDER_SBA:
+ Ensure(2);
+ i = buffer[0];
+ c = buffer[1];
+#if !defined(PURE3274)
+ /* Check for transparent write */
+ if ((i == 0) && ((c == 0) || (c == 1) || (c == 5))) {
+ TransparentClock = OutputClock+1;
+ TransOut(buffer+2, count-2, c, control);
+ buffer += count;
+ count -= count;
+ break;
+ }
+#endif /* !defined(PURE3274) */
+ BufferAddress = Addr3270(i, c);
+ buffer += 2;
+ count -= 2;
+ break;
+ case ORDER_IC:
+ CursorAddress = BufferAddress;
+ break;
+ /*
+ * XXX - PT is supposed to null fill the screen buffer
+ * under certain draconian conditions.
+ */
+ case ORDER_PT:
+ i = BufferAddress;
+ do {
+ if (IsStartField(i)) {
+ if (!IsProtected(ScreenInc(i))) {
+ break;
+ }
+ }
+ i = ScreenInc(i);
+ } while (i != HighestScreen());
+ BufferAddress = ScreenInc(i);
+ break;
+ case ORDER_RA:
+ Ensure(3);
+ i = Addr3270(buffer[0], buffer[1]);
+ if ((i < 0) || (i > HighestScreen())) {
+ char s_buffer[200];
+
+ sprintf(s_buffer, "tn3270: %s%d.\n\t%s%d%s%d%s\n",
+ "Invalid 3270 order 'Repeat to Address' to address ",
+ i,
+ "(Screen currently set to ",
+ NumberLines,
+ " by ",
+ NumberColumns,
+ ".)");
+ ExitString(s_buffer, 1);
+ /*NOTREACHED*/
+ }
+ c = buffer[2];
+ if (c == ORDER_GE) {
+ Ensure(4);
+ c = buffer[3];
+ buffer += 4;
+ count -= 4;
+ } else {
+ buffer += 3;
+ count -= 3;
+ }
+ do {
+ AddHost(BufferAddress, ebc_disp[c]);
+ BufferAddress = ScreenInc(BufferAddress);
+ } while (BufferAddress != i);
+ break;
+ case ORDER_EUA: /* (from [here,there), ie: half open interval] */
+ Ensure(2);
+ /*
+ * Compiler error - msc version 4.0:
+ * "expression too complicated".
+ */
+ i = WhereAttrByte(BufferAddress);
+ c = FieldAttributes(i);
+ i = Addr3270(buffer[0], buffer[1]);
+ if ((i < 0) || (i > HighestScreen())) {
+ char s_buffer[200];
+
+ sprintf(s_buffer, "tn3270: %s%d.\n\t%s%d%s%d%s\n",
+ "Invalid 3270 order 'Erase Unprotected to Address' to address ",
+ i,
+ "(Screen currently set to ",
+ NumberLines,
+ " by ",
+ NumberColumns,
+ ".)");
+ ExitString(s_buffer, 1);
+ /*NOTREACHED*/
+ }
+ do {
+ if (IsStartField(BufferAddress)) {
+ c = FieldAttributes(BufferAddress);
+ } else if (!IsProtectedAttr(BufferAddress, c)) {
+ AddHost(BufferAddress, 0);
+ }
+ BufferAddress = ScreenInc(BufferAddress);
+ } while (i != BufferAddress);
+ buffer += 2;
+ count -= 2;
+ break;
+ case ORDER_GE:
+ Ensure(2);
+ /* XXX Should do SOMETHING! */
+ /* XXX buffer += 0; */
+ /* XXX count -= 0; *//* For now, just use this character */
+ break;
+ case ORDER_YALE: /* special YALE defined order */
+ Ensure(2); /* need at least two characters */
+ if (*buffer == 0x5b) {
+ i = OptOrder(buffer+1, count-1, control);
+ if (i == 0) {
+ return(origCount-(count+1)); /* come here again */
+ } else {
+ buffer += 1 + i;
+ count -= (1 + i);
+ }
+ }
+ break;
+ default:
+ {
+ char s_buffer[100];
+ static struct orders_def unk_order
+ = { 0, "??", "(unknown)" };
+ struct orders_def *porder = &unk_order;
+ int s_i;
+
+ for (s_i = 0; s_i <= highestof(orders_def); s_i++) {
+ if (orders_def[s_i].code == c) {
+ porder = &orders_def[s_i];
+ break;
+ }
+ }
+ sprintf(s_buffer,
+ "Unsupported order '%s' (%s, 0x%x) received.\n",
+ porder->long_name, porder->short_name, c);
+ ExitString(s_buffer, 1);
+ /*NOTREACHED*/
+ }
+ }
+ if (count < 0) {
+ count = 0;
+ }
+ } else {
+ /* Data comes in large clumps - take it all */
+ i = BufferAddress;
+ AddHostA(i, ebc_disp[c]);
+ SetHighestLowest(i);
+ i = ScreenInc(i);
+ c = *buffer;
+ while (count && !IsOrder(c)) {
+ AddHostA(i, ebc_disp[c]);
+ i = ScreenInc(i);
+ if (i == LowestScreen()) {
+ SetHighestLowest(HighestScreen());
+ }
+ count--;
+ buffer++;
+ c = *buffer;
+ }
+ SetHighestLowest(i);
+ BufferAddress = i;
+ }
+ }
+ if (count == 0) {
+ if (control) {
+#if !defined(PURE3274)
+ OutputClock++; /* time rolls on */
+#endif /* !defined(PURE3274) */
+ if (Wcc & WCC_RESTORE) {
+#if !defined(PURE3274)
+ if (TransparentClock != OutputClock) {
+ AidByte = 0;
+ }
+#else /* !defined(PURE3274) */
+ AidByte = 0;
+#endif /* !defined(PURE3274) */
+ UnLocked = 1;
+ ResetOiaSystemLocked(&OperatorInformationArea);
+ SetOiaModified();
+ SetPsModified();
+ TerminalIn();
+ }
+ if (Wcc & WCC_ALARM) {
+ RingBell((char *)0);
+ }
+ }
+ LastWasTerminated = control; /* state for next time */
+ return(origCount);
+ } else {
+ return(origCount-count);
+ }
+}
+
+/*
+ * Init3270()
+ *
+ * Initialize any 3270 (controller) variables to an initial state
+ * in preparation for accepting a connection.
+ */
+
+void
+Init3270()
+{
+ int i;
+
+ OptInit(); /* initialize mappings */
+
+ ClearArray(Host);
+
+ ClearArray(Orders);
+ for (i = 0; i <= highestof(orders_def); i++) {
+ Orders[orders_def[i].code] = 1;
+ }
+
+ DeleteAllFields(); /* Clear screen */
+ Lowest = HighestScreen()+1;
+ Highest = LowestScreen()-1;
+ CursorAddress = BufferAddress = SetBufferAddress(0,0);
+ UnLocked = 1;
+#if !defined(PURE3274)
+ OutputClock = 1;
+ TransparentClock = -1;
+#endif /* !defined(PURE3274) */
+ SetOiaReady3274(&OperatorInformationArea);
+}
+
+
+void
+Stop3270()
+{
+ ResetOiaReady3274(&OperatorInformationArea);
+}
diff --git a/usr.bin/tn3270/ctlr/screen.h b/usr.bin/tn3270/ctlr/screen.h
new file mode 100644
index 00000000000..f4a76154ea2
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/screen.h
@@ -0,0 +1,146 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)screen.h 4.3 (Berkeley) 4/26/91
+ * $Id: screen.h,v 1.1 1995/10/18 08:46:21 deraadt Exp $
+ */
+
+#define INCLUDED_SCREEN
+
+/* defines and defines to describe how to deal with the screen */
+
+#if !defined(MSDOS)
+#define MAXNUMBERLINES 43 /* 3278-4 */
+#define MAXNUMBERCOLUMNS 132 /* 3278-5 */
+#define MAXSCREENSIZE 3564 /* (27*132) 3278-5 */
+#else /* !defined(MSDOS) */ /* MSDOS has memory constraints */
+#define MAXNUMBERLINES 25 /* XXX */
+#define MAXNUMBERCOLUMNS 80
+#define MAXSCREENSIZE (MAXNUMBERLINES*MAXNUMBERCOLUMNS)
+#endif /* !defined(MSDOS) */ /* MSDOS has memory constraints */
+#define LowestScreen() 0
+#define HighestScreen() (ScreenSize-1)
+
+#define ScreenLineOffset(x) ((x)%NumberColumns)
+#define ScreenLine(x) ((int)((x)/NumberColumns))
+#define ScreenInc(x) (((x)==HighestScreen())? LowestScreen():x+1)
+#define ScreenDec(x) (((x)==LowestScreen())? HighestScreen():x-1)
+#define ScreenUp(x) (((x)+(ScreenSize-NumberColumns))%ScreenSize)
+#define ScreenDown(x) (((x)+NumberColumns)%ScreenSize)
+#define IsOrder(x) (Orders[x])
+#define BAIC(x) ((x)&0x3f)
+#define CIAB(x) (CIABuffer[(x)&0x3f])
+#define BufferTo3270_0(x) (CIABuffer[(int)((x)/0x40)])
+#define BufferTo3270_1(x) (CIABuffer[(x)&0x3f])
+#define Addr3270(x,y) (BAIC(x)*64+BAIC(y))
+#define SetBufferAddress(x,y) ((x)*NumberColumns+(y))
+
+/* These know how fields are implemented... */
+
+#define WhereAttrByte(p) (IsStartField(p)? p: FieldDec(p))
+#define WhereHighByte(p) ScreenDec(FieldInc(p))
+#define WhereLowByte(p) ScreenInc(WhereAttrByte(p))
+#define FieldAttributes(x) (IsStartField(x)? GetHost(x) : \
+ GetHost(WhereAttrByte(x)))
+#define FieldAttributesPointer(p) (IsStartFieldPointer(p)? \
+ GetHostPointer(p): \
+ GetHost(WhereAttrByte((p)-&Host[0])))
+
+/*
+ * The MDT functions need to protect against the case where the screen
+ * is unformatted (sigh).
+ */
+
+/* Turn off the Modified Data Tag */
+#define TurnOffMdt(x) \
+ if (HasMdt(WhereAttrByte(x))) { \
+ ModifyMdt(x, 0); \
+ }
+
+/* Turn on the Modified Data Tag */
+#define TurnOnMdt(x) \
+ if (!HasMdt(WhereAttrByte(x))) { \
+ ModifyMdt(x, 1); \
+ }
+
+/* If this location has the MDT bit turned on (implies start of field) ... */
+#define HasMdt(x) \
+ ((GetHost(x)&(ATTR_MDT|ATTR_MASK)) == (ATTR_MDT|ATTR_MASK))
+
+ /*
+ * Is the screen formatted? Some algorithms change depending
+ * on whether there are any attribute bytes lying around.
+ */
+#define FormattedScreen() \
+ ((WhereAttrByte(0) != 0) || ((GetHost(0)&ATTR_MASK) == ATTR_MASK))
+
+ /* field starts here */
+#define IsStartField(x) ((GetHost(x)&ATTR_MASK) == ATTR_MASK)
+#define IsStartFieldPointer(p) ((GetHostPointer(p)&ATTR_MASK) == ATTR_MASK)
+
+#define NewField(p,a) SetHost(p, (a)|ATTR_MASK)
+#define DeleteField(p) SetHost(p, 0)
+#define DeleteAllFields()
+
+/* The following are independent of the implementation of fields */
+#define IsProtectedAttr(p,a) (IsStartField(p) || ((a)&ATTR_PROT))
+#define IsProtected(p) IsProtectedAttr(p,FieldAttributes(p))
+
+#define IsUnProtected(x) (!IsProtected(x))
+
+#define IsAutoSkip(x) (FieldAttributes(x)&ATTR_AUTO_SKIP)
+
+#define IsNonDisplayAttr(c) (((c)&ATTR_DSPD_MASK) == ATTR_DSPD_NONDISPLAY)
+#define IsNonDisplay(p) IsNonDisplayAttr(FieldAttributes(p))
+
+#define IsHighlightedAttr(c) \
+ (((c)&ATTR_DSPD_MASK) == ATTR_DSPD_HIGH)
+#define IsHighlighted(p) \
+ (IsHighlightedAttr(FieldAttributes(p)) && !IsStartField(p))
+
+typedef unsigned char ScreenImage;
+
+extern int
+ FieldFind();
+
+extern char
+ CIABuffer[];
+
+#define GetGeneric(i,h) (h)[i]
+#define GetGenericPointer(p) (*(p))
+#define SetGeneric(i,c,h) ((h)[i] = (c))
+#define ModifyGeneric(i,what,h) {(h)[i] what;}
+
+#define GetHost(i) GetGeneric(i,Host)
+#define GetHostPointer(p) GetGenericPointer(p)
+#define SetHost(i,c) SetGeneric(i,c,Host)
+#define ModifyHost(i,what) ModifyGeneric(i,what,Host)
diff --git a/usr.bin/tn3270/ctlr/scrnctlr.h b/usr.bin/tn3270/ctlr/scrnctlr.h
new file mode 100644
index 00000000000..8da484f7253
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/scrnctlr.h
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)scrnctlr.h 4.2 (Berkeley) 4/26/91
+ * $Id: scrnctlr.h,v 1.1 1995/10/18 08:46:21 deraadt Exp $
+ */
+
+/*
+ * definitions that have to do with the interface between the
+ * controller and the screen.
+ */
+
+#define DISP_AMPERSAND 0x30
+#define DISP_BLANK 0x10
+#define DISP_CENTSIGN 0x1b
+#define DISP_DUP 0x9f
+#define DISP_FM 0x9e
+#define DISP_GREATER_THAN 0x08
+#define DISP_NULL 0x00
+#define DISP_QUESTION 0x18
diff --git a/usr.bin/tn3270/ctlr/unix.kbd b/usr.bin/tn3270/ctlr/unix.kbd
new file mode 100644
index 00000000000..e0e30db06cc
--- /dev/null
+++ b/usr.bin/tn3270/ctlr/unix.kbd
@@ -0,0 +1,184 @@
+/*-
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)unix.kbd 4.2 (Berkeley) 4/26/91
+ */
+
+/*
+ * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ]
+ *
+ * keynumber is in decimal, and starts in column 1.
+ * scancode is hexadecimal.
+ * unshifted, etc. - these are either a single ascii character,
+ * or the name of a function or an AID-generating key.
+ *
+ * all fields are separated by a single space.
+ */
+
+extern struct hits hits[];
+1 0e ` ~ LPRT
+2 16 1 ! XON
+3 1e 2 @ XOFF
+4 26 3 # ALTK
+5 25 4 $ ESCAPE
+6 2e 5 % DISC
+7 36 6 ^ MASTER_RESET
+8 3d 7 & RESHOW
+9 3e 8 * FLINP
+10 46 9 ( SYNCH
+11 45 0 ) INIT
+12 4e - _ PCOFF
+13 55 = + PCON
+14 5d APLON APLOFF APLEND
+15 66 LEFT
+16 0d TAB BTAB
+17 15 q Q FIELDEND
+18 1d w W WORDEND
+19 24 e E WORDBACKTAB
+20 2d r R FERASE
+21 2c t T WERASE
+22 35 y Y ERASE
+23 3c u U CLRTAB
+24 43 i I SETHOM
+25 44 o O SETMRG
+26 4d p P UNDENT
+27 54 [ { INDENT
+28 5b \ | SETTAB
+29 5c DELTAB COLTAB COLBAK
+30 14 CAPS_LOCK
+31 1c a A WORDTAB
+32 1b s S CURSEL
+33 23 d D VERTICAL_BAR
+34 2b f F CENTSIGN
+35 34 g G PF25
+36 33 h H PF26
+37 3b j J PF27
+38 42 k K PF28
+39 4b l L PF29
+40 4c ; : PF30
+41 52 ' " PF31
+42 53 ] } PF32
+43 5a NL
+44 12 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT
+45 13 < > PF33
+46 1a z Z PF34
+47 22 x X PF35
+48 21 c C PF36
+49 2a v V
+50 32 b B
+51 31 n N
+52 3a m M
+53 41 , <
+54 49 . >
+55 4a / ?
+56 51
+57 59 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT
+58 11 RESET NULL DVCNL
+59
+60 19 MAKE_ALT MAKE_ALT MAKE_ALT
+61 29 SPACE SPACE
+62 39 MAKE_ALT MAKE_ALT MAKE_ALT
+63
+64 58 ENTER
+65 06 CLEAR NULL TEST
+66 0c NULL NULL ATTN
+67 0b EEOF NULL EINP
+68 0a
+69 09 MAKE_CTRL
+70 05 ATTN NULL TREQ
+71 04
+72 03
+73 83
+74 01
+75 67 PA1 DP
+76 64 BTAB
+77
+78 61 LEFT NULL LEFT2
+79
+80 6e PA2 FM
+81 65 INSRT
+82 63 UP
+83 62 NULL NULL HOME
+84 60 DOWN
+85 6f PA3
+86 6d DELETE
+87
+88 6a RIGHT NULL RIGHT2
+89
+90 76
+91 6c 7
+92 6b 4
+93 69 1
+94 68
+95 77
+96 75 8
+97 73 5
+98 72 2
+99 70 0
+100 7e ,
+101 7d 9
+102 74 6
+103 7a 3
+104 71 .
+105 84 SPACE
+106 7c TAB
+107 7b -
+108 79 ENTER
+109 78
+110 07 PF1
+111 0f PF2
+112 17 PF3
+113 1f PF4
+114 27 PF5
+115 2f PF6
+116 37 PF7
+117 3f PF8 NULL MONOCASE
+118 47 PF9
+119 4f PF10
+120 56 PF11
+121 5e PF12
+122 08 PF13
+123 10 PF14
+124 18 PF15
+125 20 PF16
+126 28 PF17
+127 30 PF18
+128 38 PF19
+129 40 PF20
+130 48 PF21
+131 50 PF22
+132 57 PF23
+133 5f PF24
+134 92 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT
+135 D9 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT
+136 99 BREAK_ALT BREAK_ALT BREAK_ALT
+137 B9 BREAK_ALT BREAK_ALT BREAK_ALT