xref: /csrg-svn/usr.bin/tn3270/ctlr/api.c (revision 31892)
131158Sminshall /*
2*31892Sminshall  *	Copyright (c) 1984-1987 by the Regents of the
3*31892Sminshall  *	University of California and by Gregory Glenn Minshall.
4*31892Sminshall  *
5*31892Sminshall  *	Permission to use, copy, modify, and distribute these
6*31892Sminshall  *	programs and their documentation for any purpose and
7*31892Sminshall  *	without fee is hereby granted, provided that this
8*31892Sminshall  *	copyright and permission appear on all copies and
9*31892Sminshall  *	supporting documentation, the name of the Regents of
10*31892Sminshall  *	the University of California not be used in advertising
11*31892Sminshall  *	or publicity pertaining to distribution of the programs
12*31892Sminshall  *	without specific prior permission, and notice be given in
13*31892Sminshall  *	supporting documentation that copying and distribution is
14*31892Sminshall  *	by permission of the Regents of the University of California
15*31892Sminshall  *	and by Gregory Glenn Minshall.  Neither the Regents of the
16*31892Sminshall  *	University of California nor Gregory Glenn Minshall make
17*31892Sminshall  *	representations about the suitability of this software
18*31892Sminshall  *	for any purpose.  It is provided "as is" without
19*31892Sminshall  *	express or implied warranty.
20*31892Sminshall  */
21*31892Sminshall 
22*31892Sminshall #ifndef lint
23*31892Sminshall static char sccsid[] = "@(#)api.c	1.15 (Berkeley) 07/17/87";
24*31892Sminshall #endif	/* not lint */
25*31892Sminshall 
26*31892Sminshall /*
2731158Sminshall  * This file implements the API used in the PC version.
2831158Sminshall  */
2931158Sminshall 
3031158Sminshall #include <stdio.h>
3131158Sminshall 
3231158Sminshall #include "api.h"
3331183Sminshall #include "../general/general.h"
3431158Sminshall 
3531871Sminshall #include "../api/disp_asc.h"
3631226Sminshall 
3731871Sminshall #include "screen.h"
3831871Sminshall #include "oia.h"
3931193Sminshall 
4031183Sminshall #include "../general/globals.h"
4131158Sminshall 
4231158Sminshall /*
4331193Sminshall  * General utility routines.
4431193Sminshall  */
4531193Sminshall 
4631193Sminshall #if	defined(MSDOS)
4731193Sminshall 
4831211Sminshall #if	defined(LINT_ARGS)
4931211Sminshall static void movetous(char *, int, int, int);
5031211Sminshall static void movetothem(int, int, char *, int);
5131211Sminshall #endif	/* defined(LINT_ARGS) */
5231211Sminshall 
5331507Sminshall #define	access_api(foo,length,copyin)	(foo)
5431507Sminshall #define	unaccess_api(foo,goo,length,copyout)
5531226Sminshall 
5631193Sminshall static void
5731193Sminshall movetous(parms, es, di, length)
5831193Sminshall char *parms;
5931211Sminshall int es, di, length;
6031193Sminshall {
6131211Sminshall     char far *farparms = parms;
6231193Sminshall 
6331211Sminshall     movedata(es, di, (int) FP_SEG(farparms), (int) FP_OFF(farparms), length);
6431193Sminshall }
6531193Sminshall 
6631193Sminshall static void
6731211Sminshall movetothem(es, di, parms, length)
6831211Sminshall int es, di;
6931211Sminshall char *parms;
7031211Sminshall int length;
7131193Sminshall {
7231211Sminshall     char far *farparms = parms;
7331193Sminshall 
7431211Sminshall     movedata((int) FP_SEG(farparms), (int) FP_OFF(farparms), es, di, length);
7531193Sminshall }
7631193Sminshall #endif	/* defined(MSDOS) */
7731193Sminshall 
7831226Sminshall #if	defined(unix)
7931470Sminshall extern char *access_api(), *unaccess_api();
8031226Sminshall #endif	/* defined(unix) */
8131226Sminshall 
8231470Sminshall 
8331193Sminshall /*
8431158Sminshall  * Supervisor Services.
8531158Sminshall  */
8631158Sminshall 
8731158Sminshall static void
8831193Sminshall name_resolution(regs, sregs)
8931158Sminshall union REGS *regs;
9031158Sminshall struct SREGS *sregs;
9131158Sminshall {
9231167Sminshall     NameResolveParms parms;
9331161Sminshall 
9431167Sminshall     movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms);
9531161Sminshall 
9631161Sminshall     regs->h.cl = 0;
9731193Sminshall     if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) {
9831161Sminshall 	regs->x.dx = GATE_SESSMGR;
9931193Sminshall     } else if (memcmp((char *)&parms, NAME_KEYBOARD,
10031193Sminshall 					sizeof parms.gate_name) == 0) {
10131161Sminshall 	regs->x.dx = GATE_KEYBOARD;
10231193Sminshall     } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) {
10331161Sminshall 	regs->x.dx = GATE_COPY;
10431193Sminshall     } else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) {
10531161Sminshall 	regs->x.dx = GATE_OIAM;
10631161Sminshall     } else {
10731161Sminshall 	regs->h.cl = 0x2e;	/* Name not found */
10831161Sminshall     }
10931161Sminshall     regs->h.ch = 0x12;
11031161Sminshall     regs->h.bh = 7;
11131158Sminshall }
11231158Sminshall 
11331158Sminshall /*
11431158Sminshall  * Session Information Services.
11531158Sminshall  */
11631158Sminshall 
11731158Sminshall static void
11831158Sminshall query_session_id(regs, sregs)
11931158Sminshall union REGS *regs;
12031158Sminshall struct SREGS *sregs;
12131158Sminshall {
12231167Sminshall     QuerySessionIdParms parms;
12331161Sminshall 
12431167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
12531161Sminshall 
12631211Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
12731211Sminshall 	parms.rc = 0x0c;
12831211Sminshall     } else if (parms.option_code != 0x01) {
12931211Sminshall 	parms.rc = 0x0d;	/* Invalid option code */
13031167Sminshall     } else if (parms.data_code != 0x45) {
13131211Sminshall 	parms.rc = 0x0b;
13231161Sminshall     } else {
13331168Sminshall 	NameArray list;
13431167Sminshall 	NameArrayElement element;
13531167Sminshall 
13631167Sminshall 	movetous((char *)&list, FP_SEG(parms.name_array),
13731193Sminshall 			    FP_OFF(parms.name_array), sizeof list);
13831168Sminshall 	if ((list.length < 14) || (list.length > 170)) {
13931167Sminshall 	    parms.rc = 0x12;
14031161Sminshall 	} else {
14131167Sminshall 	    list.number_matching_session = 1;
14231167Sminshall 	    list.name_array_element.short_name = parms.data_code;
14331167Sminshall 	    list.name_array_element.type = TYPE_DFT;
14431167Sminshall 	    list.name_array_element.session_id = 23;
14531167Sminshall 	    memcpy(list.name_array_element.long_name, "ONLYSESS",
14631167Sminshall 			    sizeof list.name_array_element.long_name);
14731167Sminshall 	    movetothem(FP_SEG(parms.name_array),
14831193Sminshall 		FP_OFF(parms.name_array), (char *)&list, sizeof list);
14931167Sminshall 	    parms.rc = 0;
15031161Sminshall 	}
15131161Sminshall     }
15231211Sminshall     parms.function_id = 0x6b;
15331167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
15431158Sminshall }
15531158Sminshall 
15631158Sminshall static void
15731158Sminshall query_session_parameters(regs, sregs)
15831158Sminshall union REGS *regs;
15931158Sminshall struct SREGS *sregs;
16031158Sminshall {
16131167Sminshall     QuerySessionParametersParms parms;
16231167Sminshall 
16331167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
16431167Sminshall 
16531168Sminshall     if ((parms.rc !=0) || (parms.function_id != 0)) {
16631211Sminshall 	parms.rc = 0x0c;
16731211Sminshall     } else if (parms.session_id != 23) {
16831211Sminshall 	parms.rc = 0x02;
16931167Sminshall     } else {
17031211Sminshall 	parms.rc = 0;
17131167Sminshall 	parms.session_type = TYPE_DFT;
17231167Sminshall 	parms.session_characteristics = 0;	/* Neither EAB nor PSS */
17331167Sminshall 	parms.rows = MaxNumberLines;
17431167Sminshall 	parms.columns = MaxNumberColumns;
17531167Sminshall 	parms.presentation_space = 0;
17631167Sminshall     }
17731211Sminshall     parms.function_id = 0x6b;
17831168Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
17931158Sminshall }
18031158Sminshall 
18131158Sminshall static void
18231158Sminshall query_session_cursor(regs, sregs)
18331158Sminshall union REGS *regs;
18431158Sminshall struct SREGS *sregs;
18531158Sminshall {
18631167Sminshall     QuerySessionCursorParms parms;
18731167Sminshall 
18831167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
18931167Sminshall 
19031167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
19131167Sminshall 	parms.rc = 0x0c;
19231167Sminshall     } else if (parms.session_id != 23) {
19331167Sminshall 	parms.rc = 0x02;
19431167Sminshall     } else {
19531167Sminshall 	parms.rc = 0;
19631167Sminshall 	parms.cursor_type = CURSOR_BLINKING;	/* XXX what is inhibited? */
19731167Sminshall 	parms.row_address = ScreenLine(CursorAddress);
19831167Sminshall 	parms.column_address = ScreenLineOffset(CursorAddress);
19931167Sminshall     }
20031167Sminshall 
20131211Sminshall     parms.function_id = 0x6b;
20231211Sminshall     movetothem(sregs->es, regs->x.di, (char *) &parms, sizeof parms);
20331158Sminshall }
20431158Sminshall 
20531158Sminshall /*
20631158Sminshall  * Keyboard Services.
20731158Sminshall  */
20831158Sminshall 
20931158Sminshall 
21031158Sminshall static void
21131158Sminshall connect_to_keyboard(regs, sregs)
21231158Sminshall union REGS *regs;
21331158Sminshall struct SREGS *sregs;
21431158Sminshall {
21531167Sminshall     ConnectToKeyboardParms parms;
21631167Sminshall 
21731183Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
21831167Sminshall 
21931167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
22031167Sminshall 	parms.rc = 0x0c;
22131167Sminshall     } else if (parms.session_id != 23) {
22231167Sminshall 	parms.rc = 0x02;
22331167Sminshall     } else if (parms.intercept_options != 0) {
22431167Sminshall 	parms.rc = 0x01;
22531167Sminshall     } else {
22631167Sminshall 	parms.rc = 0;
22731167Sminshall 	parms.first_connection_identifier = 0;
22831167Sminshall     }
22931167Sminshall     parms.function_id = 0x62;
23031167Sminshall 
23131167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
23231158Sminshall }
23331158Sminshall 
23431158Sminshall static void
23531167Sminshall disconnect_from_keyboard(regs, sregs)
23631158Sminshall union REGS *regs;
23731158Sminshall struct SREGS *sregs;
23831158Sminshall {
23931167Sminshall     DisconnectFromKeyboardParms parms;
24031167Sminshall 
24131167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
24231167Sminshall 
24331167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
24431167Sminshall 	parms.rc = 0x0c;
24531167Sminshall     } else if (parms.session_id != 23) {
24631167Sminshall 	parms.rc = 0x02;
24731167Sminshall     } else if (parms.connectors_task_id != 0) {
24831167Sminshall 	parms.rc = 04;			/* XXX */
24931167Sminshall     } else {
25031167Sminshall 	parms.rc = 0;
25131167Sminshall     }
25231167Sminshall     parms.function_id = 0x62;
25331167Sminshall 
25431167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
25531158Sminshall }
25631158Sminshall 
25731158Sminshall static void
25831158Sminshall write_keystroke(regs, sregs)
25931158Sminshall union REGS *regs;
26031158Sminshall struct SREGS *sregs;
26131158Sminshall {
26231198Sminshall     WriteKeystrokeParms parms;
26331198Sminshall 
26431198Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
26531198Sminshall 
26631198Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
26731198Sminshall 	parms.rc = 0x0c;
26831198Sminshall     } else if (parms.session_id != 23) {
26931198Sminshall 	parms.rc = 0x02;
27031198Sminshall     } else if (parms.connectors_task_id != 0) {
27131198Sminshall 	parms.rc = 0x04;
27231198Sminshall     } else {
27331198Sminshall 	parms.number_of_keys_sent = 0;
27431198Sminshall 	parms.rc = 0;
27531198Sminshall 	if (parms.options == OPTION_SINGLE_KEYSTROKE) {
27631198Sminshall 	    KeystrokeEntry *entry = &parms.keystroke_specifier.keystroke_entry;
27731198Sminshall 
27831198Sminshall 	    if (AcceptKeystroke(entry->scancode, entry->shift_state) == 0) {
27931198Sminshall 		parms.rc = 0x10;		/* XXX needs 0x12 too! */
28031198Sminshall 	    }
28131198Sminshall 	    parms.number_of_keys_sent++;
28231198Sminshall 	} else if (parms.options == OPTION_MULTIPLE_KEYSTROKES) {
28331198Sminshall 	    KeystrokeList
28431198Sminshall 		list,
28531198Sminshall 		far *atlist = parms.keystroke_specifier.keystroke_list;
28631198Sminshall 	    KeystrokeEntry
28731198Sminshall 		entry[10],		/* 10 at a time */
28831198Sminshall 		*ourentry,
28931198Sminshall 		far *theirentry;
29031198Sminshall 	    int
29131198Sminshall 		todo;
29231198Sminshall 
29331198Sminshall 	    movetous((char *)&list, FP_SEG(atlist),
29431198Sminshall 				FP_OFF(atlist), sizeof *atlist);
29531198Sminshall 	    todo = list.length/2;
29631198Sminshall 	    ourentry = entry+(highestof(entry)+1);
29731198Sminshall 
29831198Sminshall 	    while (todo) {
29931198Sminshall 		if (ourentry > &entry[highestof(entry)]) {
30031198Sminshall 		    int thistime;
30131198Sminshall 
30231198Sminshall 		    thistime = todo;
30331198Sminshall 		    if (thistime > numberof(entry)) {
30431198Sminshall 			thistime = numberof(entry);
30531198Sminshall 		    }
30631198Sminshall 		    movetous((char *)entry, FP_SEG(theirentry),
30731198Sminshall 			    FP_OFF(theirentry), thistime*sizeof *theirentry);
30831198Sminshall 		    theirentry += thistime;
30931198Sminshall 		    ourentry = entry;
31031198Sminshall 		}
31131198Sminshall 		if (AcceptKeystroke(ourentry->scancode,
31231198Sminshall 						ourentry->shift_state) == 0) {
31331198Sminshall 		    parms.rc = 0x10;		/* XXX needs 0x12 too! */
31431198Sminshall 		    break;
31531198Sminshall 		}
31631198Sminshall 		parms.number_of_keys_sent++;
31731198Sminshall 		ourentry++;
31831198Sminshall 		todo--;
31931198Sminshall 	    }
32031198Sminshall 	} else {
32131198Sminshall 	    parms.rc = 0x01;
32231198Sminshall 	}
32331198Sminshall     }
32431198Sminshall     parms.function_id = 0x62;
32531198Sminshall 
32631198Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
32731167Sminshall /* XXX */
32831158Sminshall }
32931158Sminshall 
33031167Sminshall 
33131158Sminshall static void
33231167Sminshall disable_input(regs, sregs)
33331167Sminshall union REGS *regs;
33431167Sminshall struct SREGS *sregs;
33531167Sminshall {
33631167Sminshall     DisableInputParms parms;
33731167Sminshall 
33831167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
33931167Sminshall 
34031167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
34131167Sminshall 	parms.rc = 0x0c;
34231167Sminshall     } else if (parms.session_id != 23) {
34331167Sminshall 	parms.rc = 0x02;
34431167Sminshall     } else if (parms.connectors_task_id != 0) {
34531167Sminshall 	parms.rc = 0x04;
34631167Sminshall     } else {
34731211Sminshall 	SetOiaApiInhibit(&OperatorInformationArea);
34831167Sminshall 	parms.rc = 0;
34931167Sminshall     }
35031167Sminshall     parms.function_id = 0x62;
35131167Sminshall 
35231167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
35331167Sminshall }
35431167Sminshall 
35531167Sminshall static void
35631158Sminshall enable_input(regs, sregs)
35731158Sminshall union REGS *regs;
35831158Sminshall struct SREGS *sregs;
35931158Sminshall {
36031167Sminshall     EnableInputParms parms;
36131167Sminshall 
36231167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
36331167Sminshall 
36431167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
36531167Sminshall 	parms.rc = 0x0c;
36631167Sminshall     } else if (parms.session_id != 23) {
36731167Sminshall 	parms.rc = 0x02;
36831167Sminshall     } else if (parms.connectors_task_id != 0) {
36931167Sminshall 	parms.rc = 0x04;
37031167Sminshall     } else {
37131211Sminshall 	ResetOiaApiInhibit(&OperatorInformationArea);
37231167Sminshall 	parms.rc = 0;
37331167Sminshall     }
37431167Sminshall     parms.function_id = 0x62;
37531167Sminshall 
37631167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
37731158Sminshall }
37831158Sminshall 
37931158Sminshall /*
38031158Sminshall  * Copy Services.
38131158Sminshall  */
38231158Sminshall 
38331507Sminshall static
38431507Sminshall copy_subroutine(target, source, parms, what_is_user, length)
38531226Sminshall BufferDescriptor *target, *source;
38631226Sminshall CopyStringParms *parms;
38731226Sminshall int what_is_user;
38831226Sminshall #define	USER_IS_TARGET	0
38931226Sminshall #define	USER_IS_SOURCE	1
39031226Sminshall {
39131226Sminshall #define	TARGET_NO_EAB		1
39231226Sminshall #define	SOURCE_NO_EAB		2
39331226Sminshall #define	TARGET_PC		4
39431226Sminshall #define	SOURCE_PC		8
39531226Sminshall #define	NO_FIELD_ATTRIBUTES	16
39631226Sminshall     int needtodo = 0;
39731226Sminshall     int access_length;
39831226Sminshall     char far *input;
39931226Sminshall     char far *output;
40031226Sminshall     char far *access_pointer;
40131226Sminshall 
40231226Sminshall     if ((target->characteristics^source->characteristics)
40331226Sminshall 		    &CHARACTERISTIC_EAB) {
40431226Sminshall 	if (target->characteristics&CHARACTERISTIC_EAB) {
40531226Sminshall 	    needtodo |= TARGET_NO_EAB;	/* Need to bump for EAB in target */
40631226Sminshall 	} else {
40731226Sminshall 	    needtodo |= SOURCE_NO_EAB;	/* Need to bump for EAB in source */
40831226Sminshall 	}
40931226Sminshall     }
41031226Sminshall     if (target->session_type != source->session_type) {
41131226Sminshall 	if (target->session_type == TYPE_PC) {
41231226Sminshall 	    needtodo |= TARGET_PC;	/* scan codes to PC */
41331226Sminshall 	} else {
41431226Sminshall 	    needtodo |= SOURCE_PC;	/* PC to scan codes */
41531226Sminshall 	}
41631226Sminshall     }
41731226Sminshall     if ((parms->copy_mode&COPY_MODE_FIELD_ATTRIBUTES) == 0) {
41831226Sminshall 	needtodo |= NO_FIELD_ATTRIBUTES;
41931226Sminshall     }
42031507Sminshall     access_length = length;
42131226Sminshall     if (what_is_user == USER_IS_TARGET) {
42231226Sminshall 	if (target->characteristics&CHARACTERISTIC_EAB) {
42331226Sminshall 	    access_length *= 2;
42431226Sminshall 	}
42531226Sminshall 	input = (char far *) &Host[source->begin];
42631226Sminshall 	access_pointer = target->buffer;
42731507Sminshall 	output = access_api(target->buffer, access_length, 0);
42831226Sminshall     } else {
42931226Sminshall 	if (source->characteristics&CHARACTERISTIC_EAB) {
43031226Sminshall 	    access_length *= 2;
43131226Sminshall 	}
43231226Sminshall 	access_pointer = source->buffer;
43331507Sminshall 	input = access_api(source->buffer, access_length, 1);
43431226Sminshall 	output = (char far *) &Host[target->begin];
43531226Sminshall     }
43631226Sminshall     while (length--) {
43731226Sminshall 	if (needtodo&TARGET_PC) {
43831226Sminshall 	    *output++ = disp_asc[*input++];
43931226Sminshall 	} else if (needtodo&SOURCE_PC) {
44031226Sminshall 	    *output++ = asc_disp[*input++];
44131226Sminshall 	} else {
44231226Sminshall 	    *output++ = *input++;
44331226Sminshall 	}
44431226Sminshall 	if (needtodo&TARGET_NO_EAB) {
44531226Sminshall 	    *input++;
44631226Sminshall 	} else if (needtodo&SOURCE_NO_EAB) {
44731226Sminshall 	    *output++ = 0;		/* Should figure out good EAB? */
44831226Sminshall 	}
44931226Sminshall     }
45031226Sminshall     if (what_is_user == USER_IS_TARGET) {
45131507Sminshall 	unaccess_api(target->buffer, access_pointer, access_length, 1);
45231226Sminshall     } else {
45331507Sminshall 	unaccess_api(source->buffer, access_pointer, access_length, 0);
45431226Sminshall     }
45531226Sminshall }
45631226Sminshall 
45731226Sminshall 
45831158Sminshall static void
45931167Sminshall copy_string(regs, sregs)
46031158Sminshall union REGS *regs;
46131158Sminshall struct SREGS *sregs;
46231158Sminshall {
46331167Sminshall     CopyStringParms parms;
46431226Sminshall     BufferDescriptor *target = &parms.target, *source = &parms.source;
46531226Sminshall     int length;
46631167Sminshall 
46731167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
46831167Sminshall 
46931507Sminshall     length = 1+parms.source_end-source->begin;
47031167Sminshall     if ((parms.rc != 0) || (parms.function_id !=0)) {
47131167Sminshall 	parms.rc = 0x0c;
47231226Sminshall     } else if (target->session_id == 0) {	/* Target is buffer */
47331226Sminshall 	if (source->session_id != 23) {		/* A no-no */
47431226Sminshall 	    parms.rc = 0x2;
47531226Sminshall 	} else {
47631507Sminshall 	    if ((source->begin < 0) || (source->begin > highestof(Host))) {
47731507Sminshall 		parms.rc = 0x06;		/* invalid source definition */
47831507Sminshall 	    } else {
47931507Sminshall 		if ((source->begin+length) > highestof(Host)) {
48031507Sminshall 		    length = highestof(Host)-source->begin;
48131507Sminshall 		    parms.rc = 0x0f;	/* Truncate */
48231507Sminshall 		}
48331507Sminshall 	        if ((source->characteristics == target->characteristics) &&
48431226Sminshall 		    (source->session_type == target->session_type)) {
48531507Sminshall 		    if (source->characteristics&CHARACTERISTIC_EAB) {
48631507Sminshall 			length *= 2;
48731507Sminshall 		    }
48831507Sminshall 		    movetothem( (int) FP_SEG(target->buffer),
48931507Sminshall 			    (int) FP_OFF(target->buffer),
49031507Sminshall 			    (char *)&Host[source->begin], length);
49131507Sminshall 		} else {
49231507Sminshall 		    copy_subroutine(target, source, &parms,
49331507Sminshall 							USER_IS_TARGET, length);
49431226Sminshall 		}
49531226Sminshall 	    }
49631226Sminshall 	}
49731226Sminshall     } else if (source->session_id != 0) {
49831226Sminshall 	    parms.rc = 0xd;
49931226Sminshall     } else {
50031507Sminshall 	if ((target->begin < 0) || (source->begin > highestof(Host))) {
50131507Sminshall 	    parms.rc = 0x07;		/* invalid source definition */
50231507Sminshall 	} else {
50331507Sminshall 	    if ((source->begin+length) > highestof(Host)) {
50431507Sminshall 		length = highestof(Host)-source->begin;
50531507Sminshall 		parms.rc = 0x0f;	/* Truncate */
50631226Sminshall 	    }
50731507Sminshall 	    if ((source->characteristics == target->characteristics) &&
50831507Sminshall 		    (source->session_type == target->session_type)) {
50931507Sminshall 		if (source->characteristics&CHARACTERISTIC_EAB) {
51031507Sminshall 		    length *= 2;
51131507Sminshall 		}
51231507Sminshall 		movetous((char *)&Host[target->begin],
51331507Sminshall 			    (int) FP_SEG(source->buffer),
51431507Sminshall 			    (int) FP_OFF(source->buffer), length);
51531507Sminshall 	    } else {
51631507Sminshall 		copy_subroutine(target, source, &parms, USER_IS_SOURCE, length);
51731507Sminshall 	    }
51831226Sminshall 	}
51931167Sminshall     }
52031183Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
52131158Sminshall }
52231158Sminshall /*
52331158Sminshall  * Operator Information Area Services.
52431158Sminshall  */
52531158Sminshall 
52631158Sminshall static void
52731158Sminshall read_oia_group(regs, sregs)
52831158Sminshall union REGS *regs;
52931158Sminshall struct SREGS *sregs;
53031158Sminshall {
53131167Sminshall     ReadOiaGroupParms parms;
53231167Sminshall 
53331167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
53431167Sminshall 
53531167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
53631167Sminshall 	parms.rc = 0x0c;
53731167Sminshall     } else if (parms.session_id != 23) {
53831167Sminshall 	parms.rc = 0x02;
53931167Sminshall     } else {
54031167Sminshall 	int group = parms.oia_group_number;
54131193Sminshall 	char *from;
54231193Sminshall 	int size;
54331167Sminshall 
54431211Sminshall 	if ((group != API_OIA_ALL_GROUPS) &&
54531211Sminshall 		((group > API_OIA_LAST_LEGAL_GROUP) || (group < 0))) {
54631193Sminshall 	} else {
54731193Sminshall 	    if (group == API_OIA_ALL_GROUPS) {
54831193Sminshall 		size = API_OIA_BYTES_ALL_GROUPS;
54931193Sminshall 		from = (char *)&OperatorInformationArea;
55031193Sminshall 	    } else if (group == API_OIA_INPUT_INHIBITED) {
55131193Sminshall 		size = sizeof OperatorInformationArea.input_inhibited;
55231193Sminshall 		from = (char *)&OperatorInformationArea.input_inhibited[0];
55331193Sminshall 	    } else {
55431193Sminshall 		size = 1;
55531193Sminshall 		from = ((char *)&OperatorInformationArea)+group;
55631193Sminshall 	    }
55731193Sminshall 	    movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer),
55831193Sminshall 			from, size);
55931168Sminshall 	}
56031167Sminshall     }
56131168Sminshall     parms.function_id = 0x6d;
56231167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
56331158Sminshall }
56431158Sminshall 
56531158Sminshall static void
56631158Sminshall unknown_op(regs, sregs)
56731158Sminshall union REGS *regs;
56831158Sminshall struct SREGS *sregs;
56931158Sminshall {
57031158Sminshall     regs->h.ch = 0x12;
57131158Sminshall     regs->h.cl = 0x05;
57231158Sminshall }
57331158Sminshall 
57431158Sminshall 
57531158Sminshall handle_api(regs, sregs)
57631158Sminshall union REGS *regs;
57731158Sminshall struct SREGS *sregs;
57831158Sminshall {
57931158Sminshall     if (regs->h.ah == NAME_RESOLUTION) {
58031158Sminshall 	name_resolution(regs, sregs);
58131517Sminshall #if	defined(unix)
58231517Sminshall     } else if (regs->h.ah == PS_OR_OIA_MODIFIED) {
58331517Sminshall 	while ((oia_modified == 0) && (ps_modified == 0)) {
58431517Sminshall 	    (void) Scheduler(1);
58531517Sminshall 	}
58631517Sminshall 	oia_modified = ps_modified = 0;
58731517Sminshall #endif	/* defined(unix) */
58831168Sminshall     } else if (regs->h.ah != 0x09) {
58931168Sminshall 	regs->h.ch = 0x12;
59031168Sminshall 	regs->h.cl = 0x0f;		/* XXX Invalid environmental access */
59131168Sminshall     } else if (regs->x.bx != 0x8020) {
59231168Sminshall 	regs->h.ch = 0x12;
59331168Sminshall 	regs->h.cl = 0x08;		/* XXX Invalid wait specified */
59431168Sminshall     } else if (regs->h.ch != 0) {
59531211Sminshall 	regs->x.cx = 0x1206;		/* XXX Invalid priority */
59631158Sminshall     } else {
59731158Sminshall 	switch (regs->x.dx) {
59831158Sminshall 	case GATE_SESSMGR:
59931158Sminshall 	    switch (regs->h.al) {
60031158Sminshall 	    case QUERY_SESSION_ID:
60131168Sminshall 		if (regs->h.cl != 0) {
60231211Sminshall 		    regs->x.cx = 0x1206;
60331168Sminshall 		} else {
60431211Sminshall 		    regs->x.cx = 0x1200;
60531168Sminshall 		    query_session_id(regs, sregs);
60631168Sminshall 		}
60731158Sminshall 		break;
60831211Sminshall 	    case QUERY_SESSION_PARAMETERS:
60931168Sminshall 		if (regs->h.cl != 0) {
61031211Sminshall 		    regs->x.cx = 0x1206;
61131168Sminshall 		} else {
61231211Sminshall 		    regs->x.cx = 0x1200;
61331193Sminshall 		    query_session_parameters(regs, sregs);
61431168Sminshall 		}
61531158Sminshall 		break;
61631158Sminshall 	    case QUERY_SESSION_CURSOR:
61731168Sminshall 		if (regs->h.cl != 0xff) {
61831211Sminshall 		    regs->x.cx = 0x1206;
61931168Sminshall 		} else {
62031211Sminshall 		    regs->x.cx = 0x1200;
62131168Sminshall 		    query_session_cursor(regs, sregs);
62231168Sminshall 		}
62331158Sminshall 		break;
62431158Sminshall 	    default:
62531158Sminshall 		unknown_op(regs, sregs);
62631158Sminshall 		break;
62731158Sminshall 	    }
62831158Sminshall 	    break;
62931158Sminshall 	case GATE_KEYBOARD:
63031168Sminshall 	    if (regs->h.cl != 00) {
63131211Sminshall 		regs->x.cx = 0x1206;
63231168Sminshall 	    } else {
63331211Sminshall 		regs->x.cx = 0x1200;
63431168Sminshall 		switch (regs->h.al) {
63531168Sminshall 		case CONNECT_TO_KEYBOARD:
63631168Sminshall 		    connect_to_keyboard(regs, sregs);
63731168Sminshall 		    break;
63831168Sminshall 		case DISABLE_INPUT:
63931168Sminshall 		    disable_input(regs, sregs);
64031168Sminshall 		    break;
64131168Sminshall 		case WRITE_KEYSTROKE:
64231168Sminshall 		    write_keystroke(regs, sregs);
64331168Sminshall 		    break;
64431168Sminshall 		case ENABLE_INPUT:
64531168Sminshall 		    enable_input(regs, sregs);
64631168Sminshall 		    break;
64731168Sminshall 		case DISCONNECT_FROM_KEYBOARD:
64831168Sminshall 		    disconnect_from_keyboard(regs, sregs);
64931168Sminshall 		    break;
65031168Sminshall 		default:
65131168Sminshall 		    unknown_op(regs, sregs);
65231168Sminshall 		    break;
65331168Sminshall 		}
65431158Sminshall 	    }
65531158Sminshall 	    break;
65631158Sminshall 	case GATE_COPY:
65731168Sminshall 	    if (regs->h.cl != 0xff) {
65831211Sminshall 		regs->x.cx = 0x1206;
65931168Sminshall 	    } else {
66031211Sminshall 		regs->x.cx = 0x1200;
66131168Sminshall 		switch (regs->h.al) {
66231168Sminshall 		case COPY_STRING:
66331168Sminshall 		    copy_string(regs, sregs);
66431168Sminshall 		    break;
66531168Sminshall 		default:
66631168Sminshall 		    unknown_op(regs, sregs);
66731168Sminshall 		    break;
66831168Sminshall 		}
66931158Sminshall 	    }
67031158Sminshall 	    break;
67131158Sminshall 	case GATE_OIAM:
67231168Sminshall 	    if (regs->h.cl != 0xff) {
67331211Sminshall 		regs->x.cx = 0x1206;
67431168Sminshall 	    } else {
67531211Sminshall 		regs->x.cx = 0x1200;
67631168Sminshall 		switch (regs->h.al) {
67731168Sminshall 		case READ_OIA_GROUP:
67831168Sminshall 		    read_oia_group(regs, sregs);
67931168Sminshall 		    break;
68031168Sminshall 		default:
68131168Sminshall 		    unknown_op(regs, sregs);
68231168Sminshall 		    break;
68331168Sminshall 		}
68431158Sminshall 	    }
68531158Sminshall 	    break;
68631158Sminshall 	default:
68731168Sminshall 	    regs->h.ch = 0x12;
68831168Sminshall 	    regs->h.cl = 0x34;		/* Invalid GATE entry */
68931158Sminshall 	    break;
69031158Sminshall 	}
69131158Sminshall     }
69231158Sminshall }
693