xref: /csrg-svn/usr.bin/tn3270/ctlr/api.c (revision 35421)
131158Sminshall /*
233816Sbostic  * Copyright (c) 1988 Regents of the University of California.
333816Sbostic  * All rights reserved.
431892Sminshall  *
533816Sbostic  * Redistribution and use in source and binary forms are permitted
6*35421Sminshall  * provided that the above copyright notice and this paragraph are
7*35421Sminshall  * duplicated in all such forms and that any documentation,
8*35421Sminshall  * advertising materials, and other materials related to such
9*35421Sminshall  * distribution and use acknowledge that the software was developed
10*35421Sminshall  * by the University of California, Berkeley.  The name of the
11*35421Sminshall  * University may not be used to endorse or promote products derived
12*35421Sminshall  * from this software without specific prior written permission.
13*35421Sminshall  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*35421Sminshall  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*35421Sminshall  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1631892Sminshall  */
1731892Sminshall 
1831892Sminshall #ifndef lint
19*35421Sminshall static char sccsid[] = "@(#)api.c	3.3 (Berkeley) 08/28/88";
2033816Sbostic #endif /* not lint */
2131892Sminshall 
2231892Sminshall /*
2331158Sminshall  * This file implements the API used in the PC version.
2431158Sminshall  */
2531158Sminshall 
2631158Sminshall #include <stdio.h>
2731158Sminshall 
2831158Sminshall #include "api.h"
2931183Sminshall #include "../general/general.h"
3031158Sminshall 
3131871Sminshall #include "../api/disp_asc.h"
3231226Sminshall 
3331871Sminshall #include "screen.h"
3431871Sminshall #include "oia.h"
3531193Sminshall 
3631183Sminshall #include "../general/globals.h"
3731158Sminshall 
3831158Sminshall /*
3931193Sminshall  * General utility routines.
4031193Sminshall  */
4131193Sminshall 
4231193Sminshall #if	defined(MSDOS)
4331193Sminshall 
4431211Sminshall #if	defined(LINT_ARGS)
4531211Sminshall static void movetous(char *, int, int, int);
4631211Sminshall static void movetothem(int, int, char *, int);
4731211Sminshall #endif	/* defined(LINT_ARGS) */
4831211Sminshall 
4931507Sminshall #define	access_api(foo,length,copyin)	(foo)
5031507Sminshall #define	unaccess_api(foo,goo,length,copyout)
5131226Sminshall 
5231193Sminshall static void
5331193Sminshall movetous(parms, es, di, length)
5431193Sminshall char *parms;
55*35421Sminshall int es, di;
56*35421Sminshall int length;
5731193Sminshall {
5831211Sminshall     char far *farparms = parms;
5931193Sminshall 
60*35421Sminshall     movedata(es, di, FP_SEG(farparms), FP_OFF(farparms), length);
6131193Sminshall }
6231193Sminshall 
6331193Sminshall static void
6431211Sminshall movetothem(es, di, parms, length)
6531211Sminshall int es, di;
6631211Sminshall char *parms;
6731211Sminshall int length;
6831193Sminshall {
6931211Sminshall     char far *farparms = parms;
7031193Sminshall 
71*35421Sminshall     movedata(FP_SEG(farparms), FP_OFF(farparms), es, di, length);
7231193Sminshall }
7331193Sminshall #endif	/* defined(MSDOS) */
7431193Sminshall 
7531226Sminshall #if	defined(unix)
76*35421Sminshall extern char *access_api();
77*35421Sminshall extern void movetous(), movetothem(), unaccess_api();
7831226Sminshall #endif	/* defined(unix) */
7931226Sminshall 
8031470Sminshall 
8131193Sminshall /*
8231158Sminshall  * Supervisor Services.
8331158Sminshall  */
8431158Sminshall 
8531158Sminshall static void
8631193Sminshall name_resolution(regs, sregs)
8731158Sminshall union REGS *regs;
8831158Sminshall struct SREGS *sregs;
8931158Sminshall {
9031167Sminshall     NameResolveParms parms;
9131161Sminshall 
9231167Sminshall     movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms);
9331161Sminshall 
9431161Sminshall     regs->h.cl = 0;
9531193Sminshall     if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) {
9631161Sminshall 	regs->x.dx = GATE_SESSMGR;
9731193Sminshall     } else if (memcmp((char *)&parms, NAME_KEYBOARD,
9831193Sminshall 					sizeof parms.gate_name) == 0) {
9931161Sminshall 	regs->x.dx = GATE_KEYBOARD;
10031193Sminshall     } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) {
10131161Sminshall 	regs->x.dx = GATE_COPY;
10231193Sminshall     } else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) {
10331161Sminshall 	regs->x.dx = GATE_OIAM;
10431161Sminshall     } else {
10531161Sminshall 	regs->h.cl = 0x2e;	/* Name not found */
10631161Sminshall     }
10731161Sminshall     regs->h.ch = 0x12;
10831161Sminshall     regs->h.bh = 7;
10931158Sminshall }
11031158Sminshall 
11131158Sminshall /*
11231158Sminshall  * Session Information Services.
11331158Sminshall  */
11431158Sminshall 
11531158Sminshall static void
11631158Sminshall query_session_id(regs, sregs)
11731158Sminshall union REGS *regs;
11831158Sminshall struct SREGS *sregs;
11931158Sminshall {
12031167Sminshall     QuerySessionIdParms parms;
12131161Sminshall 
12231167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
12331161Sminshall 
12431211Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
12531211Sminshall 	parms.rc = 0x0c;
12631211Sminshall     } else if (parms.option_code != 0x01) {
12731211Sminshall 	parms.rc = 0x0d;	/* Invalid option code */
12831167Sminshall     } else if (parms.data_code != 0x45) {
12931211Sminshall 	parms.rc = 0x0b;
13031161Sminshall     } else {
13131168Sminshall 	NameArray list;
13231167Sminshall 
13331167Sminshall 	movetous((char *)&list, FP_SEG(parms.name_array),
134*35421Sminshall 		    FP_OFF(parms.name_array), sizeof list);
13531168Sminshall 	if ((list.length < 14) || (list.length > 170)) {
13631167Sminshall 	    parms.rc = 0x12;
13731161Sminshall 	} else {
13831167Sminshall 	    list.number_matching_session = 1;
13931167Sminshall 	    list.name_array_element.short_name = parms.data_code;
14031167Sminshall 	    list.name_array_element.type = TYPE_DFT;
14131167Sminshall 	    list.name_array_element.session_id = 23;
14231167Sminshall 	    memcpy(list.name_array_element.long_name, "ONLYSESS",
14331167Sminshall 			    sizeof list.name_array_element.long_name);
14431167Sminshall 	    movetothem(FP_SEG(parms.name_array),
14531193Sminshall 		FP_OFF(parms.name_array), (char *)&list, sizeof list);
14631167Sminshall 	    parms.rc = 0;
14731161Sminshall 	}
14831161Sminshall     }
14931211Sminshall     parms.function_id = 0x6b;
15031167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
15131158Sminshall }
15231158Sminshall 
15331158Sminshall static void
15431158Sminshall query_session_parameters(regs, sregs)
15531158Sminshall union REGS *regs;
15631158Sminshall struct SREGS *sregs;
15731158Sminshall {
15831167Sminshall     QuerySessionParametersParms parms;
15931167Sminshall 
16031167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
16131167Sminshall 
16231168Sminshall     if ((parms.rc !=0) || (parms.function_id != 0)) {
16331211Sminshall 	parms.rc = 0x0c;
16431211Sminshall     } else if (parms.session_id != 23) {
16531211Sminshall 	parms.rc = 0x02;
16631167Sminshall     } else {
16731211Sminshall 	parms.rc = 0;
16831167Sminshall 	parms.session_type = TYPE_DFT;
16931167Sminshall 	parms.session_characteristics = 0;	/* Neither EAB nor PSS */
17031167Sminshall 	parms.rows = MaxNumberLines;
17131167Sminshall 	parms.columns = MaxNumberColumns;
17231167Sminshall 	parms.presentation_space = 0;
17331167Sminshall     }
17431211Sminshall     parms.function_id = 0x6b;
17531168Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
17631158Sminshall }
17731158Sminshall 
17831158Sminshall static void
17931158Sminshall query_session_cursor(regs, sregs)
18031158Sminshall union REGS *regs;
18131158Sminshall struct SREGS *sregs;
18231158Sminshall {
18331167Sminshall     QuerySessionCursorParms parms;
18431167Sminshall 
18531167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
18631167Sminshall 
18731167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
18831167Sminshall 	parms.rc = 0x0c;
18931167Sminshall     } else if (parms.session_id != 23) {
19031167Sminshall 	parms.rc = 0x02;
19131167Sminshall     } else {
19231167Sminshall 	parms.rc = 0;
19331167Sminshall 	parms.cursor_type = CURSOR_BLINKING;	/* XXX what is inhibited? */
19431167Sminshall 	parms.row_address = ScreenLine(CursorAddress);
19531167Sminshall 	parms.column_address = ScreenLineOffset(CursorAddress);
19631167Sminshall     }
19731167Sminshall 
19831211Sminshall     parms.function_id = 0x6b;
19931211Sminshall     movetothem(sregs->es, regs->x.di, (char *) &parms, sizeof parms);
20031158Sminshall }
20131158Sminshall 
20231158Sminshall /*
20331158Sminshall  * Keyboard Services.
20431158Sminshall  */
20531158Sminshall 
20631158Sminshall 
20731158Sminshall static void
20831158Sminshall connect_to_keyboard(regs, sregs)
20931158Sminshall union REGS *regs;
21031158Sminshall struct SREGS *sregs;
21131158Sminshall {
21231167Sminshall     ConnectToKeyboardParms parms;
21331167Sminshall 
21431183Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
21531167Sminshall 
21631167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
21731167Sminshall 	parms.rc = 0x0c;
21831167Sminshall     } else if (parms.session_id != 23) {
21931167Sminshall 	parms.rc = 0x02;
22031167Sminshall     } else if (parms.intercept_options != 0) {
22131167Sminshall 	parms.rc = 0x01;
22231167Sminshall     } else {
22331167Sminshall 	parms.rc = 0;
22431167Sminshall 	parms.first_connection_identifier = 0;
22531167Sminshall     }
22631167Sminshall     parms.function_id = 0x62;
22731167Sminshall 
22831167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
22931158Sminshall }
23031158Sminshall 
23131158Sminshall static void
23231167Sminshall disconnect_from_keyboard(regs, sregs)
23331158Sminshall union REGS *regs;
23431158Sminshall struct SREGS *sregs;
23531158Sminshall {
23631167Sminshall     DisconnectFromKeyboardParms parms;
23731167Sminshall 
23831167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
23931167Sminshall 
24031167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
24131167Sminshall 	parms.rc = 0x0c;
24231167Sminshall     } else if (parms.session_id != 23) {
24331167Sminshall 	parms.rc = 0x02;
24431167Sminshall     } else if (parms.connectors_task_id != 0) {
24531167Sminshall 	parms.rc = 04;			/* XXX */
24631167Sminshall     } else {
24731167Sminshall 	parms.rc = 0;
24831167Sminshall     }
24931167Sminshall     parms.function_id = 0x62;
25031167Sminshall 
25131167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
25231158Sminshall }
25331158Sminshall 
25431158Sminshall static void
25531158Sminshall write_keystroke(regs, sregs)
25631158Sminshall union REGS *regs;
25731158Sminshall struct SREGS *sregs;
25831158Sminshall {
25931198Sminshall     WriteKeystrokeParms parms;
26031198Sminshall 
26131198Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
26231198Sminshall 
26331198Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
26431198Sminshall 	parms.rc = 0x0c;
26531198Sminshall     } else if (parms.session_id != 23) {
26631198Sminshall 	parms.rc = 0x02;
26731198Sminshall     } else if (parms.connectors_task_id != 0) {
26831198Sminshall 	parms.rc = 0x04;
26931198Sminshall     } else {
27031198Sminshall 	parms.number_of_keys_sent = 0;
27131198Sminshall 	parms.rc = 0;
27231198Sminshall 	if (parms.options == OPTION_SINGLE_KEYSTROKE) {
27331198Sminshall 	    KeystrokeEntry *entry = &parms.keystroke_specifier.keystroke_entry;
27431198Sminshall 
27531198Sminshall 	    if (AcceptKeystroke(entry->scancode, entry->shift_state) == 0) {
27631198Sminshall 		parms.rc = 0x10;		/* XXX needs 0x12 too! */
27731198Sminshall 	    }
27831198Sminshall 	    parms.number_of_keys_sent++;
27931198Sminshall 	} else if (parms.options == OPTION_MULTIPLE_KEYSTROKES) {
28031198Sminshall 	    KeystrokeList
28131198Sminshall 		list,
28231198Sminshall 		far *atlist = parms.keystroke_specifier.keystroke_list;
28331198Sminshall 	    KeystrokeEntry
28431198Sminshall 		entry[10],		/* 10 at a time */
28531198Sminshall 		*ourentry,
28631198Sminshall 		far *theirentry;
28731198Sminshall 	    int
28831198Sminshall 		todo;
28931198Sminshall 
29031198Sminshall 	    movetous((char *)&list, FP_SEG(atlist),
291*35421Sminshall 			FP_OFF(atlist), sizeof *atlist);
29231198Sminshall 	    todo = list.length/2;
29331198Sminshall 	    ourentry = entry+(highestof(entry)+1);
294*35421Sminshall 	    theirentry = &atlist->keystrokes;
29531198Sminshall 
29631198Sminshall 	    while (todo) {
29731198Sminshall 		if (ourentry > &entry[highestof(entry)]) {
29831198Sminshall 		    int thistime;
29931198Sminshall 
30031198Sminshall 		    thistime = todo;
30131198Sminshall 		    if (thistime > numberof(entry)) {
30231198Sminshall 			thistime = numberof(entry);
30331198Sminshall 		    }
30431198Sminshall 		    movetous((char *)entry, FP_SEG(theirentry),
30531198Sminshall 			    FP_OFF(theirentry), thistime*sizeof *theirentry);
30631198Sminshall 		    theirentry += thistime;
30731198Sminshall 		    ourentry = entry;
30831198Sminshall 		}
30931198Sminshall 		if (AcceptKeystroke(ourentry->scancode,
31031198Sminshall 						ourentry->shift_state) == 0) {
31131198Sminshall 		    parms.rc = 0x10;		/* XXX needs 0x12 too! */
31231198Sminshall 		    break;
31331198Sminshall 		}
31431198Sminshall 		parms.number_of_keys_sent++;
31531198Sminshall 		ourentry++;
31631198Sminshall 		todo--;
31731198Sminshall 	    }
31831198Sminshall 	} else {
31931198Sminshall 	    parms.rc = 0x01;
32031198Sminshall 	}
32131198Sminshall     }
32231198Sminshall     parms.function_id = 0x62;
32331198Sminshall 
32431198Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
32531167Sminshall /* XXX */
32631158Sminshall }
32731158Sminshall 
32831167Sminshall 
32931158Sminshall static void
33031167Sminshall disable_input(regs, sregs)
33131167Sminshall union REGS *regs;
33231167Sminshall struct SREGS *sregs;
33331167Sminshall {
33431167Sminshall     DisableInputParms parms;
33531167Sminshall 
33631167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
33731167Sminshall 
33831167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
33931167Sminshall 	parms.rc = 0x0c;
34031167Sminshall     } else if (parms.session_id != 23) {
34131167Sminshall 	parms.rc = 0x02;
34231167Sminshall     } else if (parms.connectors_task_id != 0) {
34331167Sminshall 	parms.rc = 0x04;
34431167Sminshall     } else {
34531211Sminshall 	SetOiaApiInhibit(&OperatorInformationArea);
34631167Sminshall 	parms.rc = 0;
34731167Sminshall     }
34831167Sminshall     parms.function_id = 0x62;
34931167Sminshall 
35031167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
35131167Sminshall }
35231167Sminshall 
35331167Sminshall static void
35431158Sminshall enable_input(regs, sregs)
35531158Sminshall union REGS *regs;
35631158Sminshall struct SREGS *sregs;
35731158Sminshall {
35831167Sminshall     EnableInputParms parms;
35931167Sminshall 
36031167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
36131167Sminshall 
36231167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
36331167Sminshall 	parms.rc = 0x0c;
36431167Sminshall     } else if (parms.session_id != 23) {
36531167Sminshall 	parms.rc = 0x02;
36631167Sminshall     } else if (parms.connectors_task_id != 0) {
36731167Sminshall 	parms.rc = 0x04;
36831167Sminshall     } else {
36931211Sminshall 	ResetOiaApiInhibit(&OperatorInformationArea);
37031167Sminshall 	parms.rc = 0;
37131167Sminshall     }
37231167Sminshall     parms.function_id = 0x62;
37331167Sminshall 
37431167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
37531158Sminshall }
37631158Sminshall 
37731158Sminshall /*
37831158Sminshall  * Copy Services.
37931158Sminshall  */
38031158Sminshall 
38131507Sminshall static
38231507Sminshall copy_subroutine(target, source, parms, what_is_user, length)
38331226Sminshall BufferDescriptor *target, *source;
38431226Sminshall CopyStringParms *parms;
38531226Sminshall int what_is_user;
38631226Sminshall #define	USER_IS_TARGET	0
38731226Sminshall #define	USER_IS_SOURCE	1
38831226Sminshall {
38931226Sminshall #define	TARGET_NO_EAB		1
39031226Sminshall #define	SOURCE_NO_EAB		2
39131226Sminshall #define	TARGET_PC		4
39231226Sminshall #define	SOURCE_PC		8
39331226Sminshall #define	NO_FIELD_ATTRIBUTES	16
39431226Sminshall     int needtodo = 0;
39531226Sminshall     int access_length;
39631226Sminshall     char far *input;
39731226Sminshall     char far *output;
39831226Sminshall     char far *access_pointer;
39931226Sminshall 
40031226Sminshall     if ((target->characteristics^source->characteristics)
40131226Sminshall 		    &CHARACTERISTIC_EAB) {
40231226Sminshall 	if (target->characteristics&CHARACTERISTIC_EAB) {
40331226Sminshall 	    needtodo |= TARGET_NO_EAB;	/* Need to bump for EAB in target */
40431226Sminshall 	} else {
40531226Sminshall 	    needtodo |= SOURCE_NO_EAB;	/* Need to bump for EAB in source */
40631226Sminshall 	}
40731226Sminshall     }
40831226Sminshall     if (target->session_type != source->session_type) {
40931226Sminshall 	if (target->session_type == TYPE_PC) {
41031226Sminshall 	    needtodo |= TARGET_PC;	/* scan codes to PC */
41131226Sminshall 	} else {
41231226Sminshall 	    needtodo |= SOURCE_PC;	/* PC to scan codes */
41331226Sminshall 	}
41431226Sminshall     }
41531226Sminshall     if ((parms->copy_mode&COPY_MODE_FIELD_ATTRIBUTES) == 0) {
41631226Sminshall 	needtodo |= NO_FIELD_ATTRIBUTES;
41731226Sminshall     }
41831507Sminshall     access_length = length;
41931226Sminshall     if (what_is_user == USER_IS_TARGET) {
42031226Sminshall 	if (target->characteristics&CHARACTERISTIC_EAB) {
42131226Sminshall 	    access_length *= 2;
42231226Sminshall 	}
42331226Sminshall 	input = (char far *) &Host[source->begin];
42431226Sminshall 	access_pointer = target->buffer;
42531507Sminshall 	output = access_api(target->buffer, access_length, 0);
42631226Sminshall     } else {
42731226Sminshall 	if (source->characteristics&CHARACTERISTIC_EAB) {
42831226Sminshall 	    access_length *= 2;
42931226Sminshall 	}
43031226Sminshall 	access_pointer = source->buffer;
43131507Sminshall 	input = access_api(source->buffer, access_length, 1);
43231226Sminshall 	output = (char far *) &Host[target->begin];
43331226Sminshall     }
43431226Sminshall     while (length--) {
43531226Sminshall 	if (needtodo&TARGET_PC) {
43631226Sminshall 	    *output++ = disp_asc[*input++];
43731226Sminshall 	} else if (needtodo&SOURCE_PC) {
43831226Sminshall 	    *output++ = asc_disp[*input++];
43931226Sminshall 	} else {
44031226Sminshall 	    *output++ = *input++;
44131226Sminshall 	}
44231226Sminshall 	if (needtodo&TARGET_NO_EAB) {
443*35421Sminshall 	    input++;
44431226Sminshall 	} else if (needtodo&SOURCE_NO_EAB) {
44531226Sminshall 	    *output++ = 0;		/* Should figure out good EAB? */
44631226Sminshall 	}
44731226Sminshall     }
44831226Sminshall     if (what_is_user == USER_IS_TARGET) {
44931507Sminshall 	unaccess_api(target->buffer, access_pointer, access_length, 1);
45031226Sminshall     } else {
45131507Sminshall 	unaccess_api(source->buffer, access_pointer, access_length, 0);
45231226Sminshall     }
45331226Sminshall }
45431226Sminshall 
45531226Sminshall 
45631158Sminshall static void
45731167Sminshall copy_string(regs, sregs)
45831158Sminshall union REGS *regs;
45931158Sminshall struct SREGS *sregs;
46031158Sminshall {
46131167Sminshall     CopyStringParms parms;
46231226Sminshall     BufferDescriptor *target = &parms.target, *source = &parms.source;
46331226Sminshall     int length;
46431167Sminshall 
46531167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
46631167Sminshall 
46731507Sminshall     length = 1+parms.source_end-source->begin;
46831167Sminshall     if ((parms.rc != 0) || (parms.function_id !=0)) {
46931167Sminshall 	parms.rc = 0x0c;
47031226Sminshall     } else if (target->session_id == 0) {	/* Target is buffer */
47131226Sminshall 	if (source->session_id != 23) {		/* A no-no */
47231226Sminshall 	    parms.rc = 0x2;
47331226Sminshall 	} else {
47431507Sminshall 	    if ((source->begin < 0) || (source->begin > highestof(Host))) {
47531507Sminshall 		parms.rc = 0x06;		/* invalid source definition */
47631507Sminshall 	    } else {
47731507Sminshall 		if ((source->begin+length) > highestof(Host)) {
47831507Sminshall 		    length = highestof(Host)-source->begin;
47931507Sminshall 		    parms.rc = 0x0f;	/* Truncate */
48031507Sminshall 		}
48131507Sminshall 	        if ((source->characteristics == target->characteristics) &&
48231226Sminshall 		    (source->session_type == target->session_type)) {
48331507Sminshall 		    if (source->characteristics&CHARACTERISTIC_EAB) {
48431507Sminshall 			length *= 2;
48531507Sminshall 		    }
486*35421Sminshall 		    movetothem(FP_SEG(target->buffer),
487*35421Sminshall 			    FP_OFF(target->buffer),
48831507Sminshall 			    (char *)&Host[source->begin], length);
48931507Sminshall 		} else {
49031507Sminshall 		    copy_subroutine(target, source, &parms,
49131507Sminshall 							USER_IS_TARGET, length);
49231226Sminshall 		}
49331226Sminshall 	    }
49431226Sminshall 	}
49531226Sminshall     } else if (source->session_id != 0) {
49631226Sminshall 	    parms.rc = 0xd;
49731226Sminshall     } else {
49831507Sminshall 	if ((target->begin < 0) || (source->begin > highestof(Host))) {
49931507Sminshall 	    parms.rc = 0x07;		/* invalid source definition */
50031507Sminshall 	} else {
50131507Sminshall 	    if ((source->begin+length) > highestof(Host)) {
50231507Sminshall 		length = highestof(Host)-source->begin;
50331507Sminshall 		parms.rc = 0x0f;	/* Truncate */
50431226Sminshall 	    }
50531507Sminshall 	    if ((source->characteristics == target->characteristics) &&
50631507Sminshall 		    (source->session_type == target->session_type)) {
50731507Sminshall 		if (source->characteristics&CHARACTERISTIC_EAB) {
50831507Sminshall 		    length *= 2;
50931507Sminshall 		}
51031507Sminshall 		movetous((char *)&Host[target->begin],
511*35421Sminshall 			    FP_SEG(source->buffer),
512*35421Sminshall 			    FP_OFF(source->buffer), length);
51331507Sminshall 	    } else {
51431507Sminshall 		copy_subroutine(target, source, &parms, USER_IS_SOURCE, length);
51531507Sminshall 	    }
51631226Sminshall 	}
51731167Sminshall     }
51831183Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
51931158Sminshall }
52031158Sminshall /*
52131158Sminshall  * Operator Information Area Services.
52231158Sminshall  */
52331158Sminshall 
52431158Sminshall static void
52531158Sminshall read_oia_group(regs, sregs)
52631158Sminshall union REGS *regs;
52731158Sminshall struct SREGS *sregs;
52831158Sminshall {
52931167Sminshall     ReadOiaGroupParms parms;
53031167Sminshall 
53131167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
53231167Sminshall 
53331167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
53431167Sminshall 	parms.rc = 0x0c;
53531167Sminshall     } else if (parms.session_id != 23) {
53631167Sminshall 	parms.rc = 0x02;
53731167Sminshall     } else {
53831167Sminshall 	int group = parms.oia_group_number;
53931193Sminshall 	char *from;
54031193Sminshall 	int size;
54131167Sminshall 
54231211Sminshall 	if ((group != API_OIA_ALL_GROUPS) &&
54331211Sminshall 		((group > API_OIA_LAST_LEGAL_GROUP) || (group < 0))) {
54431193Sminshall 	} else {
54531193Sminshall 	    if (group == API_OIA_ALL_GROUPS) {
54631193Sminshall 		size = API_OIA_BYTES_ALL_GROUPS;
54731193Sminshall 		from = (char *)&OperatorInformationArea;
54831193Sminshall 	    } else if (group == API_OIA_INPUT_INHIBITED) {
54931193Sminshall 		size = sizeof OperatorInformationArea.input_inhibited;
55031193Sminshall 		from = (char *)&OperatorInformationArea.input_inhibited[0];
55131193Sminshall 	    } else {
55231193Sminshall 		size = 1;
55331193Sminshall 		from = ((char *)&OperatorInformationArea)+group;
55431193Sminshall 	    }
55531193Sminshall 	    movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer),
55631193Sminshall 			from, size);
55731168Sminshall 	}
55831167Sminshall     }
55931168Sminshall     parms.function_id = 0x6d;
56031167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
56131158Sminshall }
56231158Sminshall 
563*35421Sminshall /*ARGSUSED*/
56431158Sminshall static void
56531158Sminshall unknown_op(regs, sregs)
56631158Sminshall union REGS *regs;
56731158Sminshall struct SREGS *sregs;
56831158Sminshall {
56931158Sminshall     regs->h.ch = 0x12;
57031158Sminshall     regs->h.cl = 0x05;
57131158Sminshall }
57231158Sminshall 
57331158Sminshall 
57431158Sminshall handle_api(regs, sregs)
57531158Sminshall union REGS *regs;
57631158Sminshall struct SREGS *sregs;
57731158Sminshall {
57831158Sminshall     if (regs->h.ah == NAME_RESOLUTION) {
57931158Sminshall 	name_resolution(regs, sregs);
58031517Sminshall #if	defined(unix)
58131517Sminshall     } else if (regs->h.ah == PS_OR_OIA_MODIFIED) {
58231517Sminshall 	while ((oia_modified == 0) && (ps_modified == 0)) {
58331517Sminshall 	    (void) Scheduler(1);
58431517Sminshall 	}
58531517Sminshall 	oia_modified = ps_modified = 0;
58631517Sminshall #endif	/* defined(unix) */
58731168Sminshall     } else if (regs->h.ah != 0x09) {
58831168Sminshall 	regs->h.ch = 0x12;
58931168Sminshall 	regs->h.cl = 0x0f;		/* XXX Invalid environmental access */
59031168Sminshall     } else if (regs->x.bx != 0x8020) {
59131168Sminshall 	regs->h.ch = 0x12;
59231168Sminshall 	regs->h.cl = 0x08;		/* XXX Invalid wait specified */
59331168Sminshall     } else if (regs->h.ch != 0) {
59431211Sminshall 	regs->x.cx = 0x1206;		/* XXX Invalid priority */
59531158Sminshall     } else {
59631158Sminshall 	switch (regs->x.dx) {
59731158Sminshall 	case GATE_SESSMGR:
59831158Sminshall 	    switch (regs->h.al) {
59931158Sminshall 	    case QUERY_SESSION_ID:
60031168Sminshall 		if (regs->h.cl != 0) {
60131211Sminshall 		    regs->x.cx = 0x1206;
60231168Sminshall 		} else {
60331211Sminshall 		    regs->x.cx = 0x1200;
60431168Sminshall 		    query_session_id(regs, sregs);
60531168Sminshall 		}
60631158Sminshall 		break;
60731211Sminshall 	    case QUERY_SESSION_PARAMETERS:
60831168Sminshall 		if (regs->h.cl != 0) {
60931211Sminshall 		    regs->x.cx = 0x1206;
61031168Sminshall 		} else {
61131211Sminshall 		    regs->x.cx = 0x1200;
61231193Sminshall 		    query_session_parameters(regs, sregs);
61331168Sminshall 		}
61431158Sminshall 		break;
61531158Sminshall 	    case QUERY_SESSION_CURSOR:
61631168Sminshall 		if (regs->h.cl != 0xff) {
61731211Sminshall 		    regs->x.cx = 0x1206;
61831168Sminshall 		} else {
61931211Sminshall 		    regs->x.cx = 0x1200;
62031168Sminshall 		    query_session_cursor(regs, sregs);
62131168Sminshall 		}
62231158Sminshall 		break;
62331158Sminshall 	    default:
62431158Sminshall 		unknown_op(regs, sregs);
62531158Sminshall 		break;
62631158Sminshall 	    }
62731158Sminshall 	    break;
62831158Sminshall 	case GATE_KEYBOARD:
62931168Sminshall 	    if (regs->h.cl != 00) {
63031211Sminshall 		regs->x.cx = 0x1206;
63131168Sminshall 	    } else {
63231211Sminshall 		regs->x.cx = 0x1200;
63331168Sminshall 		switch (regs->h.al) {
63431168Sminshall 		case CONNECT_TO_KEYBOARD:
63531168Sminshall 		    connect_to_keyboard(regs, sregs);
63631168Sminshall 		    break;
63731168Sminshall 		case DISABLE_INPUT:
63831168Sminshall 		    disable_input(regs, sregs);
63931168Sminshall 		    break;
64031168Sminshall 		case WRITE_KEYSTROKE:
64131168Sminshall 		    write_keystroke(regs, sregs);
64231168Sminshall 		    break;
64331168Sminshall 		case ENABLE_INPUT:
64431168Sminshall 		    enable_input(regs, sregs);
64531168Sminshall 		    break;
64631168Sminshall 		case DISCONNECT_FROM_KEYBOARD:
64731168Sminshall 		    disconnect_from_keyboard(regs, sregs);
64831168Sminshall 		    break;
64931168Sminshall 		default:
65031168Sminshall 		    unknown_op(regs, sregs);
65131168Sminshall 		    break;
65231168Sminshall 		}
65331158Sminshall 	    }
65431158Sminshall 	    break;
65531158Sminshall 	case GATE_COPY:
65631168Sminshall 	    if (regs->h.cl != 0xff) {
65731211Sminshall 		regs->x.cx = 0x1206;
65831168Sminshall 	    } else {
65931211Sminshall 		regs->x.cx = 0x1200;
66031168Sminshall 		switch (regs->h.al) {
66131168Sminshall 		case COPY_STRING:
66231168Sminshall 		    copy_string(regs, sregs);
66331168Sminshall 		    break;
66431168Sminshall 		default:
66531168Sminshall 		    unknown_op(regs, sregs);
66631168Sminshall 		    break;
66731168Sminshall 		}
66831158Sminshall 	    }
66931158Sminshall 	    break;
67031158Sminshall 	case GATE_OIAM:
67131168Sminshall 	    if (regs->h.cl != 0xff) {
67231211Sminshall 		regs->x.cx = 0x1206;
67331168Sminshall 	    } else {
67431211Sminshall 		regs->x.cx = 0x1200;
67531168Sminshall 		switch (regs->h.al) {
67631168Sminshall 		case READ_OIA_GROUP:
67731168Sminshall 		    read_oia_group(regs, sregs);
67831168Sminshall 		    break;
67931168Sminshall 		default:
68031168Sminshall 		    unknown_op(regs, sregs);
68131168Sminshall 		    break;
68231168Sminshall 		}
68331158Sminshall 	    }
68431158Sminshall 	    break;
68531158Sminshall 	default:
68631168Sminshall 	    regs->h.ch = 0x12;
68731168Sminshall 	    regs->h.cl = 0x34;		/* Invalid GATE entry */
68831158Sminshall 	    break;
68931158Sminshall 	}
69031158Sminshall     }
69131158Sminshall }
692