148756Sbostic /*-
2*62323Sbostic * Copyright (c) 1988, 1993
3*62323Sbostic * The Regents of the University of California. All rights reserved.
431892Sminshall *
548756Sbostic * %sccs.include.redist.c%
631892Sminshall */
731892Sminshall
831892Sminshall #ifndef lint
9*62323Sbostic static char sccsid[] = "@(#)api.c 8.1 (Berkeley) 06/06/93";
1033816Sbostic #endif /* not lint */
1131892Sminshall
1231892Sminshall /*
1331158Sminshall * This file implements the API used in the PC version.
1431158Sminshall */
1531158Sminshall
1631158Sminshall #include <stdio.h>
1731158Sminshall
1831158Sminshall #include "api.h"
1931183Sminshall #include "../general/general.h"
2031158Sminshall
2131871Sminshall #include "../api/disp_asc.h"
2231226Sminshall
2331871Sminshall #include "screen.h"
2438210Sminshall #include "hostctlr.h"
2531871Sminshall #include "oia.h"
2631193Sminshall
2731183Sminshall #include "../general/globals.h"
2831158Sminshall
2939468Sminshall int apitrace = 0;
3038924Sminshall
3131158Sminshall /*
3239468Sminshall * Some defines for things we use internally.
3339468Sminshall */
3439468Sminshall
3539468Sminshall #define PS_SESSION_ID 23
3639468Sminshall #define BUF_SESSION_ID 0
3739468Sminshall
3839468Sminshall /*
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
movetous(parms,es,di,length)5331193Sminshall movetous(parms, es, di, length)
5431193Sminshall char *parms;
5535421Sminshall int es, di;
5635421Sminshall int length;
5731193Sminshall {
5831211Sminshall char far *farparms = parms;
5931193Sminshall
6035421Sminshall movedata(es, di, FP_SEG(farparms), FP_OFF(farparms), length);
6138924Sminshall if (apitrace) {
6238924Sminshall Dump('(', parms, length);
6338924Sminshall }
6431193Sminshall }
6531193Sminshall
6631193Sminshall static void
movetothem(es,di,parms,length)6731211Sminshall movetothem(es, di, parms, length)
6831211Sminshall int es, di;
6931211Sminshall char *parms;
7031211Sminshall int length;
7131193Sminshall {
7231211Sminshall char far *farparms = parms;
7331193Sminshall
7435421Sminshall movedata(FP_SEG(farparms), FP_OFF(farparms), es, di, length);
7538924Sminshall if (apitrace) {
7638924Sminshall Dump(')', parms, length);
7738924Sminshall }
7831193Sminshall }
7931193Sminshall #endif /* defined(MSDOS) */
8031193Sminshall
8131226Sminshall #if defined(unix)
8235421Sminshall extern char *access_api();
8335421Sminshall extern void movetous(), movetothem(), unaccess_api();
8431226Sminshall #endif /* defined(unix) */
8531226Sminshall
8631470Sminshall
8731193Sminshall /*
8831158Sminshall * Supervisor Services.
8931158Sminshall */
9031158Sminshall
9131158Sminshall static void
name_resolution(regs,sregs)9231193Sminshall name_resolution(regs, sregs)
9331158Sminshall union REGS *regs;
9431158Sminshall struct SREGS *sregs;
9531158Sminshall {
9631167Sminshall NameResolveParms parms;
9731161Sminshall
9831167Sminshall movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms);
9931161Sminshall
10031161Sminshall regs->h.cl = 0;
10131193Sminshall if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) {
10231161Sminshall regs->x.dx = GATE_SESSMGR;
10331193Sminshall } else if (memcmp((char *)&parms, NAME_KEYBOARD,
10431193Sminshall sizeof parms.gate_name) == 0) {
10531161Sminshall regs->x.dx = GATE_KEYBOARD;
10631193Sminshall } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) {
10731161Sminshall regs->x.dx = GATE_COPY;
10831193Sminshall } else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) {
10931161Sminshall regs->x.dx = GATE_OIAM;
11031161Sminshall } else {
11131161Sminshall regs->h.cl = 0x2e; /* Name not found */
11231161Sminshall }
11331161Sminshall regs->h.ch = 0x12;
11431161Sminshall regs->h.bh = 7;
11531158Sminshall }
11631158Sminshall
11731158Sminshall /*
11831158Sminshall * Session Information Services.
11931158Sminshall */
12031158Sminshall
12131158Sminshall static void
query_session_id(regs,sregs)12231158Sminshall query_session_id(regs, sregs)
12331158Sminshall union REGS *regs;
12431158Sminshall struct SREGS *sregs;
12531158Sminshall {
12631167Sminshall QuerySessionIdParms parms;
12731161Sminshall
12831167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
12931161Sminshall
13031211Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) {
13131211Sminshall parms.rc = 0x0c;
13231211Sminshall } else if (parms.option_code != 0x01) {
13331211Sminshall parms.rc = 0x0d; /* Invalid option code */
13439468Sminshall #ifdef NOTOBS
13539468Sminshall } else if ((parms.data_code != 0x45) && (parms.data_code != 0x00/*OBS*/)) {
13631211Sminshall parms.rc = 0x0b;
13739468Sminshall #endif /* NOTOBS */
13831161Sminshall } else {
13931168Sminshall NameArray list;
14031167Sminshall
14131167Sminshall movetous((char *)&list, FP_SEG(parms.name_array),
14235421Sminshall FP_OFF(parms.name_array), sizeof list);
14331168Sminshall if ((list.length < 14) || (list.length > 170)) {
14431167Sminshall parms.rc = 0x12;
14531161Sminshall } else {
14631167Sminshall list.number_matching_session = 1;
14731167Sminshall list.name_array_element.short_name = parms.data_code;
14831167Sminshall list.name_array_element.type = TYPE_DFT;
14939468Sminshall list.name_array_element.session_id = PS_SESSION_ID;
15031167Sminshall memcpy(list.name_array_element.long_name, "ONLYSESS",
15131167Sminshall sizeof list.name_array_element.long_name);
15231167Sminshall movetothem(FP_SEG(parms.name_array),
15331193Sminshall FP_OFF(parms.name_array), (char *)&list, sizeof list);
15431167Sminshall parms.rc = 0;
15531161Sminshall }
15631161Sminshall }
15731211Sminshall parms.function_id = 0x6b;
15831167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
15931158Sminshall }
16031158Sminshall
16131158Sminshall static void
query_session_parameters(regs,sregs)16231158Sminshall query_session_parameters(regs, sregs)
16331158Sminshall union REGS *regs;
16431158Sminshall struct SREGS *sregs;
16531158Sminshall {
16631167Sminshall QuerySessionParametersParms parms;
16731167Sminshall
16831167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
16931167Sminshall
17031168Sminshall if ((parms.rc !=0) || (parms.function_id != 0)) {
17131211Sminshall parms.rc = 0x0c;
17239468Sminshall } else if (parms.session_id != PS_SESSION_ID) {
17331211Sminshall parms.rc = 0x02;
17431167Sminshall } else {
17531211Sminshall parms.rc = 0;
17631167Sminshall parms.session_type = TYPE_DFT;
17731167Sminshall parms.session_characteristics = 0; /* Neither EAB nor PSS */
17831167Sminshall parms.rows = MaxNumberLines;
17931167Sminshall parms.columns = MaxNumberColumns;
18031167Sminshall parms.presentation_space = 0;
18131167Sminshall }
18231211Sminshall parms.function_id = 0x6b;
18331168Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
18431158Sminshall }
18531158Sminshall
18631158Sminshall static void
query_session_cursor(regs,sregs)18731158Sminshall query_session_cursor(regs, sregs)
18831158Sminshall union REGS *regs;
18931158Sminshall struct SREGS *sregs;
19031158Sminshall {
19131167Sminshall QuerySessionCursorParms parms;
19231167Sminshall
19331167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
19431167Sminshall
19531167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) {
19631167Sminshall parms.rc = 0x0c;
19739468Sminshall } else if (parms.session_id != PS_SESSION_ID) {
19831167Sminshall parms.rc = 0x02;
19931167Sminshall } else {
20031167Sminshall parms.rc = 0;
20131167Sminshall parms.cursor_type = CURSOR_BLINKING; /* XXX what is inhibited? */
20231167Sminshall parms.row_address = ScreenLine(CursorAddress);
20331167Sminshall parms.column_address = ScreenLineOffset(CursorAddress);
20431167Sminshall }
20531167Sminshall
20631211Sminshall parms.function_id = 0x6b;
20731211Sminshall movetothem(sregs->es, regs->x.di, (char *) &parms, sizeof parms);
20831158Sminshall }
20931158Sminshall
21031158Sminshall /*
21131158Sminshall * Keyboard Services.
21231158Sminshall */
21331158Sminshall
21431158Sminshall
21531158Sminshall static void
connect_to_keyboard(regs,sregs)21631158Sminshall connect_to_keyboard(regs, sregs)
21731158Sminshall union REGS *regs;
21831158Sminshall struct SREGS *sregs;
21931158Sminshall {
22031167Sminshall ConnectToKeyboardParms parms;
22131167Sminshall
22231183Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
22331167Sminshall
22431167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) {
22531167Sminshall parms.rc = 0x0c;
22639468Sminshall } else if (parms.session_id != PS_SESSION_ID) {
22731167Sminshall parms.rc = 0x02;
22831167Sminshall } else if (parms.intercept_options != 0) {
22931167Sminshall parms.rc = 0x01;
23031167Sminshall } else {
23131167Sminshall parms.rc = 0;
23231167Sminshall parms.first_connection_identifier = 0;
23331167Sminshall }
23431167Sminshall parms.function_id = 0x62;
23531167Sminshall
23631167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
23731158Sminshall }
23831158Sminshall
23931158Sminshall static void
disconnect_from_keyboard(regs,sregs)24031167Sminshall disconnect_from_keyboard(regs, sregs)
24131158Sminshall union REGS *regs;
24231158Sminshall struct SREGS *sregs;
24331158Sminshall {
24431167Sminshall DisconnectFromKeyboardParms parms;
24531167Sminshall
24631167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
24731167Sminshall
24831167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) {
24931167Sminshall parms.rc = 0x0c;
25039468Sminshall } else if (parms.session_id != PS_SESSION_ID) {
25131167Sminshall parms.rc = 0x02;
25231167Sminshall } else if (parms.connectors_task_id != 0) {
25331167Sminshall parms.rc = 04; /* XXX */
25431167Sminshall } else {
25531167Sminshall parms.rc = 0;
25631167Sminshall }
25731167Sminshall parms.function_id = 0x62;
25831167Sminshall
25931167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
26031158Sminshall }
26131158Sminshall
26231158Sminshall static void
write_keystroke(regs,sregs)26331158Sminshall write_keystroke(regs, sregs)
26431158Sminshall union REGS *regs;
26531158Sminshall struct SREGS *sregs;
26631158Sminshall {
26731198Sminshall WriteKeystrokeParms parms;
26831198Sminshall
26931198Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
27031198Sminshall
27131198Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) {
27231198Sminshall parms.rc = 0x0c;
27339468Sminshall } else if (parms.session_id != PS_SESSION_ID) {
27431198Sminshall parms.rc = 0x02;
27531198Sminshall } else if (parms.connectors_task_id != 0) {
27631198Sminshall parms.rc = 0x04;
27731198Sminshall } else {
27831198Sminshall parms.number_of_keys_sent = 0;
27931198Sminshall parms.rc = 0;
28031198Sminshall if (parms.options == OPTION_SINGLE_KEYSTROKE) {
28131198Sminshall KeystrokeEntry *entry = &parms.keystroke_specifier.keystroke_entry;
28231198Sminshall
28331198Sminshall if (AcceptKeystroke(entry->scancode, entry->shift_state) == 0) {
28431198Sminshall parms.rc = 0x10; /* XXX needs 0x12 too! */
28531198Sminshall }
28631198Sminshall parms.number_of_keys_sent++;
28731198Sminshall } else if (parms.options == OPTION_MULTIPLE_KEYSTROKES) {
28831198Sminshall KeystrokeList
28931198Sminshall list,
29031198Sminshall far *atlist = parms.keystroke_specifier.keystroke_list;
29131198Sminshall KeystrokeEntry
29231198Sminshall entry[10], /* 10 at a time */
29331198Sminshall *ourentry,
29431198Sminshall far *theirentry;
29531198Sminshall int
29631198Sminshall todo;
29731198Sminshall
29831198Sminshall movetous((char *)&list, FP_SEG(atlist),
29935421Sminshall FP_OFF(atlist), sizeof *atlist);
30031198Sminshall todo = list.length/2;
30131198Sminshall ourentry = entry+(highestof(entry)+1);
30235421Sminshall theirentry = &atlist->keystrokes;
30331198Sminshall
30431198Sminshall while (todo) {
30531198Sminshall if (ourentry > &entry[highestof(entry)]) {
30631198Sminshall int thistime;
30731198Sminshall
30831198Sminshall thistime = todo;
30931198Sminshall if (thistime > numberof(entry)) {
31031198Sminshall thistime = numberof(entry);
31131198Sminshall }
31231198Sminshall movetous((char *)entry, FP_SEG(theirentry),
31331198Sminshall FP_OFF(theirentry), thistime*sizeof *theirentry);
31431198Sminshall theirentry += thistime;
31531198Sminshall ourentry = entry;
31631198Sminshall }
31731198Sminshall if (AcceptKeystroke(ourentry->scancode,
31831198Sminshall ourentry->shift_state) == 0) {
31931198Sminshall parms.rc = 0x10; /* XXX needs 0x12 too! */
32031198Sminshall break;
32131198Sminshall }
32231198Sminshall parms.number_of_keys_sent++;
32331198Sminshall ourentry++;
32431198Sminshall todo--;
32531198Sminshall }
32631198Sminshall } else {
32731198Sminshall parms.rc = 0x01;
32831198Sminshall }
32931198Sminshall }
33031198Sminshall parms.function_id = 0x62;
33131198Sminshall
33231198Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
33331167Sminshall /* XXX */
33431158Sminshall }
33531158Sminshall
33631167Sminshall
33731158Sminshall static void
disable_input(regs,sregs)33831167Sminshall disable_input(regs, sregs)
33931167Sminshall union REGS *regs;
34031167Sminshall struct SREGS *sregs;
34131167Sminshall {
34231167Sminshall DisableInputParms parms;
34331167Sminshall
34431167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
34531167Sminshall
34631167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) {
34731167Sminshall parms.rc = 0x0c;
34839468Sminshall } else if (parms.session_id != PS_SESSION_ID) {
34931167Sminshall parms.rc = 0x02;
35031167Sminshall } else if (parms.connectors_task_id != 0) {
35131167Sminshall parms.rc = 0x04;
35231167Sminshall } else {
35331211Sminshall SetOiaApiInhibit(&OperatorInformationArea);
35431167Sminshall parms.rc = 0;
35531167Sminshall }
35631167Sminshall parms.function_id = 0x62;
35731167Sminshall
35831167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
35931167Sminshall }
36031167Sminshall
36131167Sminshall static void
enable_input(regs,sregs)36231158Sminshall enable_input(regs, sregs)
36331158Sminshall union REGS *regs;
36431158Sminshall struct SREGS *sregs;
36531158Sminshall {
36631167Sminshall EnableInputParms parms;
36731167Sminshall
36831167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
36931167Sminshall
37031167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) {
37131167Sminshall parms.rc = 0x0c;
37239468Sminshall } else if (parms.session_id != PS_SESSION_ID) {
37331167Sminshall parms.rc = 0x02;
37431167Sminshall } else if (parms.connectors_task_id != 0) {
37531167Sminshall parms.rc = 0x04;
37631167Sminshall } else {
37731211Sminshall ResetOiaApiInhibit(&OperatorInformationArea);
37831167Sminshall parms.rc = 0;
37931167Sminshall }
38031167Sminshall parms.function_id = 0x62;
38131167Sminshall
38231167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
38331158Sminshall }
38431158Sminshall
38531158Sminshall /*
38631158Sminshall * Copy Services.
38731158Sminshall */
38831158Sminshall
38931507Sminshall static
copy_subroutine(target,source,parms,what_is_user,length)39031507Sminshall copy_subroutine(target, source, parms, what_is_user, length)
39131226Sminshall BufferDescriptor *target, *source;
39231226Sminshall CopyStringParms *parms;
39331226Sminshall int what_is_user;
39431226Sminshall #define USER_IS_TARGET 0
39531226Sminshall #define USER_IS_SOURCE 1
39631226Sminshall {
39731226Sminshall #define TARGET_NO_EAB 1
39831226Sminshall #define SOURCE_NO_EAB 2
39931226Sminshall #define TARGET_PC 4
40031226Sminshall #define SOURCE_PC 8
40131226Sminshall #define NO_FIELD_ATTRIBUTES 16
40231226Sminshall int needtodo = 0;
40331226Sminshall int access_length;
40431226Sminshall char far *input;
40531226Sminshall char far *output;
40631226Sminshall char far *access_pointer;
40731226Sminshall
40831226Sminshall if ((target->characteristics^source->characteristics)
40931226Sminshall &CHARACTERISTIC_EAB) {
41031226Sminshall if (target->characteristics&CHARACTERISTIC_EAB) {
41131226Sminshall needtodo |= TARGET_NO_EAB; /* Need to bump for EAB in target */
41231226Sminshall } else {
41331226Sminshall needtodo |= SOURCE_NO_EAB; /* Need to bump for EAB in source */
41431226Sminshall }
41531226Sminshall }
41631226Sminshall if (target->session_type != source->session_type) {
41731226Sminshall if (target->session_type == TYPE_PC) {
41831226Sminshall needtodo |= TARGET_PC; /* scan codes to PC */
41931226Sminshall } else {
42031226Sminshall needtodo |= SOURCE_PC; /* PC to scan codes */
42131226Sminshall }
42231226Sminshall }
42331226Sminshall if ((parms->copy_mode©_MODE_FIELD_ATTRIBUTES) == 0) {
42431226Sminshall needtodo |= NO_FIELD_ATTRIBUTES;
42531226Sminshall }
42631507Sminshall access_length = length;
42731226Sminshall if (what_is_user == USER_IS_TARGET) {
42831226Sminshall if (target->characteristics&CHARACTERISTIC_EAB) {
42931226Sminshall access_length *= 2;
43031226Sminshall }
43131226Sminshall input = (char far *) &Host[source->begin];
43231226Sminshall access_pointer = target->buffer;
43331507Sminshall output = access_api(target->buffer, access_length, 0);
43431226Sminshall } else {
43531226Sminshall if (source->characteristics&CHARACTERISTIC_EAB) {
43631226Sminshall access_length *= 2;
43731226Sminshall }
43831226Sminshall access_pointer = source->buffer;
43931507Sminshall input = access_api(source->buffer, access_length, 1);
44031226Sminshall output = (char far *) &Host[target->begin];
44131226Sminshall }
44231226Sminshall while (length--) {
44331226Sminshall if (needtodo&TARGET_PC) {
44431226Sminshall *output++ = disp_asc[*input++];
44531226Sminshall } else if (needtodo&SOURCE_PC) {
44631226Sminshall *output++ = asc_disp[*input++];
44731226Sminshall } else {
44831226Sminshall *output++ = *input++;
44931226Sminshall }
45031226Sminshall if (needtodo&TARGET_NO_EAB) {
45135421Sminshall input++;
45231226Sminshall } else if (needtodo&SOURCE_NO_EAB) {
45331226Sminshall *output++ = 0; /* Should figure out good EAB? */
45431226Sminshall }
45531226Sminshall }
45631226Sminshall if (what_is_user == USER_IS_TARGET) {
45731507Sminshall unaccess_api(target->buffer, access_pointer, access_length, 1);
45831226Sminshall } else {
45931507Sminshall unaccess_api(source->buffer, access_pointer, access_length, 0);
46031226Sminshall }
46131226Sminshall }
46231226Sminshall
46331226Sminshall
46431158Sminshall static void
copy_string(regs,sregs)46531167Sminshall copy_string(regs, sregs)
46631158Sminshall union REGS *regs;
46731158Sminshall struct SREGS *sregs;
46831158Sminshall {
46931167Sminshall CopyStringParms parms;
47031226Sminshall BufferDescriptor *target = &parms.target, *source = &parms.source;
47131226Sminshall int length;
47231167Sminshall
47331167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
47431167Sminshall
47531507Sminshall length = 1+parms.source_end-source->begin;
47631167Sminshall if ((parms.rc != 0) || (parms.function_id !=0)) {
47731167Sminshall parms.rc = 0x0c;
47839468Sminshall } else if (target->session_id == BUF_SESSION_ID) { /* Target is buffer */
47939468Sminshall if (source->session_id != PS_SESSION_ID) { /* A no-no */
48031226Sminshall parms.rc = 0x2;
48131226Sminshall } else {
48231507Sminshall if ((source->begin < 0) || (source->begin > highestof(Host))) {
48331507Sminshall parms.rc = 0x06; /* invalid source definition */
48431507Sminshall } else {
48531507Sminshall if ((source->begin+length) > highestof(Host)) {
48631507Sminshall length = highestof(Host)-source->begin;
48731507Sminshall parms.rc = 0x0f; /* Truncate */
48831507Sminshall }
48931507Sminshall if ((source->characteristics == target->characteristics) &&
49031226Sminshall (source->session_type == target->session_type)) {
49131507Sminshall if (source->characteristics&CHARACTERISTIC_EAB) {
49231507Sminshall length *= 2;
49331507Sminshall }
49435421Sminshall movetothem(FP_SEG(target->buffer),
49535421Sminshall FP_OFF(target->buffer),
49631507Sminshall (char *)&Host[source->begin], length);
49731507Sminshall } else {
49831507Sminshall copy_subroutine(target, source, &parms,
49931507Sminshall USER_IS_TARGET, length);
50031226Sminshall }
50131226Sminshall }
50231226Sminshall }
50339468Sminshall } else if (source->session_id != BUF_SESSION_ID) {
50431226Sminshall parms.rc = 0xd;
50531226Sminshall } else {
50638210Sminshall /* Send to presentation space (3270 buffer) */
50738210Sminshall if ((target->begin < 0) || (target->begin > highestof(Host))) {
50838210Sminshall parms.rc = 0x07; /* invalid target definition */
50938210Sminshall } if (!UnLocked) {
51038210Sminshall parms.rc = 0x03; /* Keyboard locked */
51138210Sminshall } else if (parms.copy_mode != 0) {
51238210Sminshall parms.rc = 0x0f; /* Copy of field attr's not allowed */
51338210Sminshall } else if (IsProtected(target->begin) || /* Make sure no protected */
51438210Sminshall (WhereAttrByte(target->begin) != /* in range */
51538210Sminshall WhereAttrByte(target->begin+length-1))) {
51638210Sminshall parms.rc = 0x0e; /* Attempt to write in protected */
51731507Sminshall } else {
51838210Sminshall if ((target->begin+length) > highestof(Host)) {
51938210Sminshall length = highestof(Host)-target->begin;
52031507Sminshall parms.rc = 0x0f; /* Truncate */
52131226Sminshall }
52238210Sminshall TurnOnMdt(target->begin); /* Things have changed */
52331507Sminshall if ((source->characteristics == target->characteristics) &&
52431507Sminshall (source->session_type == target->session_type)) {
52531507Sminshall if (source->characteristics&CHARACTERISTIC_EAB) {
52631507Sminshall length *= 2;
52731507Sminshall }
52831507Sminshall movetous((char *)&Host[target->begin],
52935421Sminshall FP_SEG(source->buffer),
53035421Sminshall FP_OFF(source->buffer), length);
53131507Sminshall } else {
53231507Sminshall copy_subroutine(target, source, &parms, USER_IS_SOURCE, length);
53331507Sminshall }
53431226Sminshall }
53531167Sminshall }
53639468Sminshall parms.function_id = 0x64;
53731183Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
53831158Sminshall }
53939468Sminshall
54039468Sminshall
54131158Sminshall /*
54231158Sminshall * Operator Information Area Services.
54331158Sminshall */
54431158Sminshall
54531158Sminshall static void
read_oia_group(regs,sregs)54631158Sminshall read_oia_group(regs, sregs)
54731158Sminshall union REGS *regs;
54831158Sminshall struct SREGS *sregs;
54931158Sminshall {
55031167Sminshall ReadOiaGroupParms parms;
55131167Sminshall
55231167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
55331167Sminshall
55431167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) {
55531167Sminshall parms.rc = 0x0c;
55639468Sminshall } else if (parms.session_id != PS_SESSION_ID) {
55731167Sminshall parms.rc = 0x02;
55831167Sminshall } else {
55931167Sminshall int group = parms.oia_group_number;
56031193Sminshall char *from;
56131193Sminshall int size;
56231167Sminshall
56331211Sminshall if ((group != API_OIA_ALL_GROUPS) &&
56431211Sminshall ((group > API_OIA_LAST_LEGAL_GROUP) || (group < 0))) {
56531193Sminshall } else {
56631193Sminshall if (group == API_OIA_ALL_GROUPS) {
56731193Sminshall size = API_OIA_BYTES_ALL_GROUPS;
56831193Sminshall from = (char *)&OperatorInformationArea;
56931193Sminshall } else if (group == API_OIA_INPUT_INHIBITED) {
57031193Sminshall size = sizeof OperatorInformationArea.input_inhibited;
57131193Sminshall from = (char *)&OperatorInformationArea.input_inhibited[0];
57231193Sminshall } else {
57331193Sminshall size = 1;
57431193Sminshall from = ((char *)&OperatorInformationArea)+group;
57531193Sminshall }
57631193Sminshall movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer),
57731193Sminshall from, size);
57831168Sminshall }
57931167Sminshall }
58031168Sminshall parms.function_id = 0x6d;
58131167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
58231158Sminshall }
58331158Sminshall
58435421Sminshall /*ARGSUSED*/
58531158Sminshall static void
unknown_op(regs,sregs)58631158Sminshall unknown_op(regs, sregs)
58731158Sminshall union REGS *regs;
58831158Sminshall struct SREGS *sregs;
58931158Sminshall {
59031158Sminshall regs->h.ch = 0x12;
59131158Sminshall regs->h.cl = 0x05;
59231158Sminshall }
59331158Sminshall
59431158Sminshall
59531158Sminshall handle_api(regs, sregs)
59631158Sminshall union REGS *regs;
59731158Sminshall struct SREGS *sregs;
59831158Sminshall {
59938924Sminshall /*
60038924Sminshall * Do we need to log this transaction?
60138924Sminshall */
60238924Sminshall if (apitrace) {
60338924Sminshall Dump('<', (char *)regs, sizeof *regs);
60438924Sminshall Dump('<', (char *)sregs, sizeof *sregs);
60538924Sminshall }
60631158Sminshall if (regs->h.ah == NAME_RESOLUTION) {
60731158Sminshall name_resolution(regs, sregs);
60831517Sminshall #if defined(unix)
60931517Sminshall } else if (regs->h.ah == PS_OR_OIA_MODIFIED) {
61031517Sminshall while ((oia_modified == 0) && (ps_modified == 0)) {
61131517Sminshall (void) Scheduler(1);
61231517Sminshall }
61331517Sminshall oia_modified = ps_modified = 0;
61431517Sminshall #endif /* defined(unix) */
61531168Sminshall } else if (regs->h.ah != 0x09) {
61631168Sminshall regs->h.ch = 0x12;
61731168Sminshall regs->h.cl = 0x0f; /* XXX Invalid environmental access */
61831168Sminshall } else if (regs->x.bx != 0x8020) {
61931168Sminshall regs->h.ch = 0x12;
62031168Sminshall regs->h.cl = 0x08; /* XXX Invalid wait specified */
62131168Sminshall } else if (regs->h.ch != 0) {
62231211Sminshall regs->x.cx = 0x1206; /* XXX Invalid priority */
62331158Sminshall } else {
62431158Sminshall switch (regs->x.dx) {
62531158Sminshall case GATE_SESSMGR:
62631158Sminshall switch (regs->h.al) {
62731158Sminshall case QUERY_SESSION_ID:
62831168Sminshall if (regs->h.cl != 0) {
62931211Sminshall regs->x.cx = 0x1206;
63031168Sminshall } else {
63131211Sminshall regs->x.cx = 0x1200;
63231168Sminshall query_session_id(regs, sregs);
63331168Sminshall }
63431158Sminshall break;
63531211Sminshall case QUERY_SESSION_PARAMETERS:
63631168Sminshall if (regs->h.cl != 0) {
63731211Sminshall regs->x.cx = 0x1206;
63831168Sminshall } else {
63931211Sminshall regs->x.cx = 0x1200;
64031193Sminshall query_session_parameters(regs, sregs);
64131168Sminshall }
64231158Sminshall break;
64331158Sminshall case QUERY_SESSION_CURSOR:
64439468Sminshall if ((regs->h.cl != 0xff) && (regs->h.cl != 0x00/*OBS*/)) {
64531211Sminshall regs->x.cx = 0x1206;
64631168Sminshall } else {
64731211Sminshall regs->x.cx = 0x1200;
64831168Sminshall query_session_cursor(regs, sregs);
64931168Sminshall }
65031158Sminshall break;
65131158Sminshall default:
65231158Sminshall unknown_op(regs, sregs);
65331158Sminshall break;
65431158Sminshall }
65531158Sminshall break;
65631158Sminshall case GATE_KEYBOARD:
65731168Sminshall if (regs->h.cl != 00) {
65831211Sminshall regs->x.cx = 0x1206;
65931168Sminshall } else {
66031211Sminshall regs->x.cx = 0x1200;
66131168Sminshall switch (regs->h.al) {
66231168Sminshall case CONNECT_TO_KEYBOARD:
66331168Sminshall connect_to_keyboard(regs, sregs);
66431168Sminshall break;
66531168Sminshall case DISABLE_INPUT:
66631168Sminshall disable_input(regs, sregs);
66731168Sminshall break;
66831168Sminshall case WRITE_KEYSTROKE:
66931168Sminshall write_keystroke(regs, sregs);
67031168Sminshall break;
67131168Sminshall case ENABLE_INPUT:
67231168Sminshall enable_input(regs, sregs);
67331168Sminshall break;
67431168Sminshall case DISCONNECT_FROM_KEYBOARD:
67531168Sminshall disconnect_from_keyboard(regs, sregs);
67631168Sminshall break;
67731168Sminshall default:
67831168Sminshall unknown_op(regs, sregs);
67931168Sminshall break;
68031168Sminshall }
68131158Sminshall }
68231158Sminshall break;
68331158Sminshall case GATE_COPY:
68431168Sminshall if (regs->h.cl != 0xff) {
68531211Sminshall regs->x.cx = 0x1206;
68631168Sminshall } else {
68731211Sminshall regs->x.cx = 0x1200;
68831168Sminshall switch (regs->h.al) {
68931168Sminshall case COPY_STRING:
69031168Sminshall copy_string(regs, sregs);
69131168Sminshall break;
69231168Sminshall default:
69331168Sminshall unknown_op(regs, sregs);
69431168Sminshall break;
69531168Sminshall }
69631158Sminshall }
69731158Sminshall break;
69831158Sminshall case GATE_OIAM:
69931168Sminshall if (regs->h.cl != 0xff) {
70031211Sminshall regs->x.cx = 0x1206;
70131168Sminshall } else {
70231211Sminshall regs->x.cx = 0x1200;
70331168Sminshall switch (regs->h.al) {
70431168Sminshall case READ_OIA_GROUP:
70531168Sminshall read_oia_group(regs, sregs);
70631168Sminshall break;
70731168Sminshall default:
70831168Sminshall unknown_op(regs, sregs);
70931168Sminshall break;
71031168Sminshall }
71131158Sminshall }
71231158Sminshall break;
71331158Sminshall default:
71431168Sminshall regs->h.ch = 0x12;
71531168Sminshall regs->h.cl = 0x34; /* Invalid GATE entry */
71631158Sminshall break;
71731158Sminshall }
71831158Sminshall }
71938924Sminshall /*
72038924Sminshall * Do we need to log this transaction?
72138924Sminshall */
72238924Sminshall if (apitrace) {
72338924Sminshall Dump('>', (char *)regs, sizeof *regs);
72438924Sminshall Dump('>', (char *)sregs, sizeof *sregs);
72539468Sminshall #ifdef MSDOS
72639468Sminshall { char buf[10]; gets(buf); }
72739468Sminshall #endif /* MSDOS */
72838924Sminshall }
72931158Sminshall }
730