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 635421Sminshall * provided that the above copyright notice and this paragraph are 735421Sminshall * duplicated in all such forms and that any documentation, 835421Sminshall * advertising materials, and other materials related to such 935421Sminshall * distribution and use acknowledge that the software was developed 1035421Sminshall * by the University of California, Berkeley. The name of the 1135421Sminshall * University may not be used to endorse or promote products derived 1235421Sminshall * from this software without specific prior written permission. 1335421Sminshall * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1435421Sminshall * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1535421Sminshall * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1631892Sminshall */ 1731892Sminshall 1831892Sminshall #ifndef lint 19*38210Sminshall static char sccsid[] = "@(#)api.c 4.2 (Berkeley) 05/30/89"; 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" 34*38210Sminshall #include "hostctlr.h" 3531871Sminshall #include "oia.h" 3631193Sminshall 3731183Sminshall #include "../general/globals.h" 3831158Sminshall 3931158Sminshall /* 4031193Sminshall * General utility routines. 4131193Sminshall */ 4231193Sminshall 4331193Sminshall #if defined(MSDOS) 4431193Sminshall 4531211Sminshall #if defined(LINT_ARGS) 4631211Sminshall static void movetous(char *, int, int, int); 4731211Sminshall static void movetothem(int, int, char *, int); 4831211Sminshall #endif /* defined(LINT_ARGS) */ 4931211Sminshall 5031507Sminshall #define access_api(foo,length,copyin) (foo) 5131507Sminshall #define unaccess_api(foo,goo,length,copyout) 5231226Sminshall 5331193Sminshall static void 5431193Sminshall movetous(parms, es, di, length) 5531193Sminshall char *parms; 5635421Sminshall int es, di; 5735421Sminshall int length; 5831193Sminshall { 5931211Sminshall char far *farparms = parms; 6031193Sminshall 6135421Sminshall movedata(es, di, FP_SEG(farparms), FP_OFF(farparms), length); 6231193Sminshall } 6331193Sminshall 6431193Sminshall static void 6531211Sminshall movetothem(es, di, parms, length) 6631211Sminshall int es, di; 6731211Sminshall char *parms; 6831211Sminshall int length; 6931193Sminshall { 7031211Sminshall char far *farparms = parms; 7131193Sminshall 7235421Sminshall movedata(FP_SEG(farparms), FP_OFF(farparms), es, di, length); 7331193Sminshall } 7431193Sminshall #endif /* defined(MSDOS) */ 7531193Sminshall 7631226Sminshall #if defined(unix) 7735421Sminshall extern char *access_api(); 7835421Sminshall extern void movetous(), movetothem(), unaccess_api(); 7931226Sminshall #endif /* defined(unix) */ 8031226Sminshall 8131470Sminshall 8231193Sminshall /* 8331158Sminshall * Supervisor Services. 8431158Sminshall */ 8531158Sminshall 8631158Sminshall static void 8731193Sminshall name_resolution(regs, sregs) 8831158Sminshall union REGS *regs; 8931158Sminshall struct SREGS *sregs; 9031158Sminshall { 9131167Sminshall NameResolveParms parms; 9231161Sminshall 9331167Sminshall movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms); 9431161Sminshall 9531161Sminshall regs->h.cl = 0; 9631193Sminshall if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) { 9731161Sminshall regs->x.dx = GATE_SESSMGR; 9831193Sminshall } else if (memcmp((char *)&parms, NAME_KEYBOARD, 9931193Sminshall sizeof parms.gate_name) == 0) { 10031161Sminshall regs->x.dx = GATE_KEYBOARD; 10131193Sminshall } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) { 10231161Sminshall regs->x.dx = GATE_COPY; 10331193Sminshall } else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) { 10431161Sminshall regs->x.dx = GATE_OIAM; 10531161Sminshall } else { 10631161Sminshall regs->h.cl = 0x2e; /* Name not found */ 10731161Sminshall } 10831161Sminshall regs->h.ch = 0x12; 10931161Sminshall regs->h.bh = 7; 11031158Sminshall } 11131158Sminshall 11231158Sminshall /* 11331158Sminshall * Session Information Services. 11431158Sminshall */ 11531158Sminshall 11631158Sminshall static void 11731158Sminshall query_session_id(regs, sregs) 11831158Sminshall union REGS *regs; 11931158Sminshall struct SREGS *sregs; 12031158Sminshall { 12131167Sminshall QuerySessionIdParms parms; 12231161Sminshall 12331167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 12431161Sminshall 12531211Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 12631211Sminshall parms.rc = 0x0c; 12731211Sminshall } else if (parms.option_code != 0x01) { 12831211Sminshall parms.rc = 0x0d; /* Invalid option code */ 12931167Sminshall } else if (parms.data_code != 0x45) { 13031211Sminshall parms.rc = 0x0b; 13131161Sminshall } else { 13231168Sminshall NameArray list; 13331167Sminshall 13431167Sminshall movetous((char *)&list, FP_SEG(parms.name_array), 13535421Sminshall FP_OFF(parms.name_array), sizeof list); 13631168Sminshall if ((list.length < 14) || (list.length > 170)) { 13731167Sminshall parms.rc = 0x12; 13831161Sminshall } else { 13931167Sminshall list.number_matching_session = 1; 14031167Sminshall list.name_array_element.short_name = parms.data_code; 14131167Sminshall list.name_array_element.type = TYPE_DFT; 14231167Sminshall list.name_array_element.session_id = 23; 14331167Sminshall memcpy(list.name_array_element.long_name, "ONLYSESS", 14431167Sminshall sizeof list.name_array_element.long_name); 14531167Sminshall movetothem(FP_SEG(parms.name_array), 14631193Sminshall FP_OFF(parms.name_array), (char *)&list, sizeof list); 14731167Sminshall parms.rc = 0; 14831161Sminshall } 14931161Sminshall } 15031211Sminshall parms.function_id = 0x6b; 15131167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 15231158Sminshall } 15331158Sminshall 15431158Sminshall static void 15531158Sminshall query_session_parameters(regs, sregs) 15631158Sminshall union REGS *regs; 15731158Sminshall struct SREGS *sregs; 15831158Sminshall { 15931167Sminshall QuerySessionParametersParms parms; 16031167Sminshall 16131167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 16231167Sminshall 16331168Sminshall if ((parms.rc !=0) || (parms.function_id != 0)) { 16431211Sminshall parms.rc = 0x0c; 16531211Sminshall } else if (parms.session_id != 23) { 16631211Sminshall parms.rc = 0x02; 16731167Sminshall } else { 16831211Sminshall parms.rc = 0; 16931167Sminshall parms.session_type = TYPE_DFT; 17031167Sminshall parms.session_characteristics = 0; /* Neither EAB nor PSS */ 17131167Sminshall parms.rows = MaxNumberLines; 17231167Sminshall parms.columns = MaxNumberColumns; 17331167Sminshall parms.presentation_space = 0; 17431167Sminshall } 17531211Sminshall parms.function_id = 0x6b; 17631168Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 17731158Sminshall } 17831158Sminshall 17931158Sminshall static void 18031158Sminshall query_session_cursor(regs, sregs) 18131158Sminshall union REGS *regs; 18231158Sminshall struct SREGS *sregs; 18331158Sminshall { 18431167Sminshall QuerySessionCursorParms parms; 18531167Sminshall 18631167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 18731167Sminshall 18831167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 18931167Sminshall parms.rc = 0x0c; 19031167Sminshall } else if (parms.session_id != 23) { 19131167Sminshall parms.rc = 0x02; 19231167Sminshall } else { 19331167Sminshall parms.rc = 0; 19431167Sminshall parms.cursor_type = CURSOR_BLINKING; /* XXX what is inhibited? */ 19531167Sminshall parms.row_address = ScreenLine(CursorAddress); 19631167Sminshall parms.column_address = ScreenLineOffset(CursorAddress); 19731167Sminshall } 19831167Sminshall 19931211Sminshall parms.function_id = 0x6b; 20031211Sminshall movetothem(sregs->es, regs->x.di, (char *) &parms, sizeof parms); 20131158Sminshall } 20231158Sminshall 20331158Sminshall /* 20431158Sminshall * Keyboard Services. 20531158Sminshall */ 20631158Sminshall 20731158Sminshall 20831158Sminshall static void 20931158Sminshall connect_to_keyboard(regs, sregs) 21031158Sminshall union REGS *regs; 21131158Sminshall struct SREGS *sregs; 21231158Sminshall { 21331167Sminshall ConnectToKeyboardParms parms; 21431167Sminshall 21531183Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 21631167Sminshall 21731167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 21831167Sminshall parms.rc = 0x0c; 21931167Sminshall } else if (parms.session_id != 23) { 22031167Sminshall parms.rc = 0x02; 22131167Sminshall } else if (parms.intercept_options != 0) { 22231167Sminshall parms.rc = 0x01; 22331167Sminshall } else { 22431167Sminshall parms.rc = 0; 22531167Sminshall parms.first_connection_identifier = 0; 22631167Sminshall } 22731167Sminshall parms.function_id = 0x62; 22831167Sminshall 22931167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 23031158Sminshall } 23131158Sminshall 23231158Sminshall static void 23331167Sminshall disconnect_from_keyboard(regs, sregs) 23431158Sminshall union REGS *regs; 23531158Sminshall struct SREGS *sregs; 23631158Sminshall { 23731167Sminshall DisconnectFromKeyboardParms parms; 23831167Sminshall 23931167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 24031167Sminshall 24131167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 24231167Sminshall parms.rc = 0x0c; 24331167Sminshall } else if (parms.session_id != 23) { 24431167Sminshall parms.rc = 0x02; 24531167Sminshall } else if (parms.connectors_task_id != 0) { 24631167Sminshall parms.rc = 04; /* XXX */ 24731167Sminshall } else { 24831167Sminshall parms.rc = 0; 24931167Sminshall } 25031167Sminshall parms.function_id = 0x62; 25131167Sminshall 25231167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 25331158Sminshall } 25431158Sminshall 25531158Sminshall static void 25631158Sminshall write_keystroke(regs, sregs) 25731158Sminshall union REGS *regs; 25831158Sminshall struct SREGS *sregs; 25931158Sminshall { 26031198Sminshall WriteKeystrokeParms parms; 26131198Sminshall 26231198Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 26331198Sminshall 26431198Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 26531198Sminshall parms.rc = 0x0c; 26631198Sminshall } else if (parms.session_id != 23) { 26731198Sminshall parms.rc = 0x02; 26831198Sminshall } else if (parms.connectors_task_id != 0) { 26931198Sminshall parms.rc = 0x04; 27031198Sminshall } else { 27131198Sminshall parms.number_of_keys_sent = 0; 27231198Sminshall parms.rc = 0; 27331198Sminshall if (parms.options == OPTION_SINGLE_KEYSTROKE) { 27431198Sminshall KeystrokeEntry *entry = &parms.keystroke_specifier.keystroke_entry; 27531198Sminshall 27631198Sminshall if (AcceptKeystroke(entry->scancode, entry->shift_state) == 0) { 27731198Sminshall parms.rc = 0x10; /* XXX needs 0x12 too! */ 27831198Sminshall } 27931198Sminshall parms.number_of_keys_sent++; 28031198Sminshall } else if (parms.options == OPTION_MULTIPLE_KEYSTROKES) { 28131198Sminshall KeystrokeList 28231198Sminshall list, 28331198Sminshall far *atlist = parms.keystroke_specifier.keystroke_list; 28431198Sminshall KeystrokeEntry 28531198Sminshall entry[10], /* 10 at a time */ 28631198Sminshall *ourentry, 28731198Sminshall far *theirentry; 28831198Sminshall int 28931198Sminshall todo; 29031198Sminshall 29131198Sminshall movetous((char *)&list, FP_SEG(atlist), 29235421Sminshall FP_OFF(atlist), sizeof *atlist); 29331198Sminshall todo = list.length/2; 29431198Sminshall ourentry = entry+(highestof(entry)+1); 29535421Sminshall theirentry = &atlist->keystrokes; 29631198Sminshall 29731198Sminshall while (todo) { 29831198Sminshall if (ourentry > &entry[highestof(entry)]) { 29931198Sminshall int thistime; 30031198Sminshall 30131198Sminshall thistime = todo; 30231198Sminshall if (thistime > numberof(entry)) { 30331198Sminshall thistime = numberof(entry); 30431198Sminshall } 30531198Sminshall movetous((char *)entry, FP_SEG(theirentry), 30631198Sminshall FP_OFF(theirentry), thistime*sizeof *theirentry); 30731198Sminshall theirentry += thistime; 30831198Sminshall ourentry = entry; 30931198Sminshall } 31031198Sminshall if (AcceptKeystroke(ourentry->scancode, 31131198Sminshall ourentry->shift_state) == 0) { 31231198Sminshall parms.rc = 0x10; /* XXX needs 0x12 too! */ 31331198Sminshall break; 31431198Sminshall } 31531198Sminshall parms.number_of_keys_sent++; 31631198Sminshall ourentry++; 31731198Sminshall todo--; 31831198Sminshall } 31931198Sminshall } else { 32031198Sminshall parms.rc = 0x01; 32131198Sminshall } 32231198Sminshall } 32331198Sminshall parms.function_id = 0x62; 32431198Sminshall 32531198Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 32631167Sminshall /* XXX */ 32731158Sminshall } 32831158Sminshall 32931167Sminshall 33031158Sminshall static void 33131167Sminshall disable_input(regs, sregs) 33231167Sminshall union REGS *regs; 33331167Sminshall struct SREGS *sregs; 33431167Sminshall { 33531167Sminshall DisableInputParms parms; 33631167Sminshall 33731167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 33831167Sminshall 33931167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 34031167Sminshall parms.rc = 0x0c; 34131167Sminshall } else if (parms.session_id != 23) { 34231167Sminshall parms.rc = 0x02; 34331167Sminshall } else if (parms.connectors_task_id != 0) { 34431167Sminshall parms.rc = 0x04; 34531167Sminshall } else { 34631211Sminshall SetOiaApiInhibit(&OperatorInformationArea); 34731167Sminshall parms.rc = 0; 34831167Sminshall } 34931167Sminshall parms.function_id = 0x62; 35031167Sminshall 35131167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 35231167Sminshall } 35331167Sminshall 35431167Sminshall static void 35531158Sminshall enable_input(regs, sregs) 35631158Sminshall union REGS *regs; 35731158Sminshall struct SREGS *sregs; 35831158Sminshall { 35931167Sminshall EnableInputParms parms; 36031167Sminshall 36131167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 36231167Sminshall 36331167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 36431167Sminshall parms.rc = 0x0c; 36531167Sminshall } else if (parms.session_id != 23) { 36631167Sminshall parms.rc = 0x02; 36731167Sminshall } else if (parms.connectors_task_id != 0) { 36831167Sminshall parms.rc = 0x04; 36931167Sminshall } else { 37031211Sminshall ResetOiaApiInhibit(&OperatorInformationArea); 37131167Sminshall parms.rc = 0; 37231167Sminshall } 37331167Sminshall parms.function_id = 0x62; 37431167Sminshall 37531167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 37631158Sminshall } 37731158Sminshall 37831158Sminshall /* 37931158Sminshall * Copy Services. 38031158Sminshall */ 38131158Sminshall 38231507Sminshall static 38331507Sminshall copy_subroutine(target, source, parms, what_is_user, length) 38431226Sminshall BufferDescriptor *target, *source; 38531226Sminshall CopyStringParms *parms; 38631226Sminshall int what_is_user; 38731226Sminshall #define USER_IS_TARGET 0 38831226Sminshall #define USER_IS_SOURCE 1 38931226Sminshall { 39031226Sminshall #define TARGET_NO_EAB 1 39131226Sminshall #define SOURCE_NO_EAB 2 39231226Sminshall #define TARGET_PC 4 39331226Sminshall #define SOURCE_PC 8 39431226Sminshall #define NO_FIELD_ATTRIBUTES 16 39531226Sminshall int needtodo = 0; 39631226Sminshall int access_length; 39731226Sminshall char far *input; 39831226Sminshall char far *output; 39931226Sminshall char far *access_pointer; 40031226Sminshall 40131226Sminshall if ((target->characteristics^source->characteristics) 40231226Sminshall &CHARACTERISTIC_EAB) { 40331226Sminshall if (target->characteristics&CHARACTERISTIC_EAB) { 40431226Sminshall needtodo |= TARGET_NO_EAB; /* Need to bump for EAB in target */ 40531226Sminshall } else { 40631226Sminshall needtodo |= SOURCE_NO_EAB; /* Need to bump for EAB in source */ 40731226Sminshall } 40831226Sminshall } 40931226Sminshall if (target->session_type != source->session_type) { 41031226Sminshall if (target->session_type == TYPE_PC) { 41131226Sminshall needtodo |= TARGET_PC; /* scan codes to PC */ 41231226Sminshall } else { 41331226Sminshall needtodo |= SOURCE_PC; /* PC to scan codes */ 41431226Sminshall } 41531226Sminshall } 41631226Sminshall if ((parms->copy_mode©_MODE_FIELD_ATTRIBUTES) == 0) { 41731226Sminshall needtodo |= NO_FIELD_ATTRIBUTES; 41831226Sminshall } 41931507Sminshall access_length = length; 42031226Sminshall if (what_is_user == USER_IS_TARGET) { 42131226Sminshall if (target->characteristics&CHARACTERISTIC_EAB) { 42231226Sminshall access_length *= 2; 42331226Sminshall } 42431226Sminshall input = (char far *) &Host[source->begin]; 42531226Sminshall access_pointer = target->buffer; 42631507Sminshall output = access_api(target->buffer, access_length, 0); 42731226Sminshall } else { 42831226Sminshall if (source->characteristics&CHARACTERISTIC_EAB) { 42931226Sminshall access_length *= 2; 43031226Sminshall } 43131226Sminshall access_pointer = source->buffer; 43231507Sminshall input = access_api(source->buffer, access_length, 1); 43331226Sminshall output = (char far *) &Host[target->begin]; 43431226Sminshall } 43531226Sminshall while (length--) { 43631226Sminshall if (needtodo&TARGET_PC) { 43731226Sminshall *output++ = disp_asc[*input++]; 43831226Sminshall } else if (needtodo&SOURCE_PC) { 43931226Sminshall *output++ = asc_disp[*input++]; 44031226Sminshall } else { 44131226Sminshall *output++ = *input++; 44231226Sminshall } 44331226Sminshall if (needtodo&TARGET_NO_EAB) { 44435421Sminshall input++; 44531226Sminshall } else if (needtodo&SOURCE_NO_EAB) { 44631226Sminshall *output++ = 0; /* Should figure out good EAB? */ 44731226Sminshall } 44831226Sminshall } 44931226Sminshall if (what_is_user == USER_IS_TARGET) { 45031507Sminshall unaccess_api(target->buffer, access_pointer, access_length, 1); 45131226Sminshall } else { 45231507Sminshall unaccess_api(source->buffer, access_pointer, access_length, 0); 45331226Sminshall } 45431226Sminshall } 45531226Sminshall 45631226Sminshall 45731158Sminshall static void 45831167Sminshall copy_string(regs, sregs) 45931158Sminshall union REGS *regs; 46031158Sminshall struct SREGS *sregs; 46131158Sminshall { 46231167Sminshall CopyStringParms parms; 46331226Sminshall BufferDescriptor *target = &parms.target, *source = &parms.source; 46431226Sminshall int length; 46531167Sminshall 46631167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 46731167Sminshall 46831507Sminshall length = 1+parms.source_end-source->begin; 46931167Sminshall if ((parms.rc != 0) || (parms.function_id !=0)) { 47031167Sminshall parms.rc = 0x0c; 47131226Sminshall } else if (target->session_id == 0) { /* Target is buffer */ 47231226Sminshall if (source->session_id != 23) { /* A no-no */ 47331226Sminshall parms.rc = 0x2; 47431226Sminshall } else { 47531507Sminshall if ((source->begin < 0) || (source->begin > highestof(Host))) { 47631507Sminshall parms.rc = 0x06; /* invalid source definition */ 47731507Sminshall } else { 47831507Sminshall if ((source->begin+length) > highestof(Host)) { 47931507Sminshall length = highestof(Host)-source->begin; 48031507Sminshall parms.rc = 0x0f; /* Truncate */ 48131507Sminshall } 48231507Sminshall if ((source->characteristics == target->characteristics) && 48331226Sminshall (source->session_type == target->session_type)) { 48431507Sminshall if (source->characteristics&CHARACTERISTIC_EAB) { 48531507Sminshall length *= 2; 48631507Sminshall } 48735421Sminshall movetothem(FP_SEG(target->buffer), 48835421Sminshall FP_OFF(target->buffer), 48931507Sminshall (char *)&Host[source->begin], length); 49031507Sminshall } else { 49131507Sminshall copy_subroutine(target, source, &parms, 49231507Sminshall USER_IS_TARGET, length); 49331226Sminshall } 49431226Sminshall } 49531226Sminshall } 49631226Sminshall } else if (source->session_id != 0) { 49731226Sminshall parms.rc = 0xd; 49831226Sminshall } else { 499*38210Sminshall /* Send to presentation space (3270 buffer) */ 500*38210Sminshall if ((target->begin < 0) || (target->begin > highestof(Host))) { 501*38210Sminshall parms.rc = 0x07; /* invalid target definition */ 502*38210Sminshall } if (!UnLocked) { 503*38210Sminshall parms.rc = 0x03; /* Keyboard locked */ 504*38210Sminshall } else if (parms.copy_mode != 0) { 505*38210Sminshall parms.rc = 0x0f; /* Copy of field attr's not allowed */ 506*38210Sminshall } else if (IsProtected(target->begin) || /* Make sure no protected */ 507*38210Sminshall (WhereAttrByte(target->begin) != /* in range */ 508*38210Sminshall WhereAttrByte(target->begin+length-1))) { 509*38210Sminshall parms.rc = 0x0e; /* Attempt to write in protected */ 51031507Sminshall } else { 511*38210Sminshall if ((target->begin+length) > highestof(Host)) { 512*38210Sminshall length = highestof(Host)-target->begin; 51331507Sminshall parms.rc = 0x0f; /* Truncate */ 51431226Sminshall } 515*38210Sminshall TurnOnMdt(target->begin); /* Things have changed */ 51631507Sminshall if ((source->characteristics == target->characteristics) && 51731507Sminshall (source->session_type == target->session_type)) { 51831507Sminshall if (source->characteristics&CHARACTERISTIC_EAB) { 51931507Sminshall length *= 2; 52031507Sminshall } 52131507Sminshall movetous((char *)&Host[target->begin], 52235421Sminshall FP_SEG(source->buffer), 52335421Sminshall FP_OFF(source->buffer), length); 52431507Sminshall } else { 52531507Sminshall copy_subroutine(target, source, &parms, USER_IS_SOURCE, length); 52631507Sminshall } 52731226Sminshall } 52831167Sminshall } 52931183Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 53031158Sminshall } 53131158Sminshall /* 53231158Sminshall * Operator Information Area Services. 53331158Sminshall */ 53431158Sminshall 53531158Sminshall static void 53631158Sminshall read_oia_group(regs, sregs) 53731158Sminshall union REGS *regs; 53831158Sminshall struct SREGS *sregs; 53931158Sminshall { 54031167Sminshall ReadOiaGroupParms parms; 54131167Sminshall 54231167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 54331167Sminshall 54431167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 54531167Sminshall parms.rc = 0x0c; 54631167Sminshall } else if (parms.session_id != 23) { 54731167Sminshall parms.rc = 0x02; 54831167Sminshall } else { 54931167Sminshall int group = parms.oia_group_number; 55031193Sminshall char *from; 55131193Sminshall int size; 55231167Sminshall 55331211Sminshall if ((group != API_OIA_ALL_GROUPS) && 55431211Sminshall ((group > API_OIA_LAST_LEGAL_GROUP) || (group < 0))) { 55531193Sminshall } else { 55631193Sminshall if (group == API_OIA_ALL_GROUPS) { 55731193Sminshall size = API_OIA_BYTES_ALL_GROUPS; 55831193Sminshall from = (char *)&OperatorInformationArea; 55931193Sminshall } else if (group == API_OIA_INPUT_INHIBITED) { 56031193Sminshall size = sizeof OperatorInformationArea.input_inhibited; 56131193Sminshall from = (char *)&OperatorInformationArea.input_inhibited[0]; 56231193Sminshall } else { 56331193Sminshall size = 1; 56431193Sminshall from = ((char *)&OperatorInformationArea)+group; 56531193Sminshall } 56631193Sminshall movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer), 56731193Sminshall from, size); 56831168Sminshall } 56931167Sminshall } 57031168Sminshall parms.function_id = 0x6d; 57131167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 57231158Sminshall } 57331158Sminshall 57435421Sminshall /*ARGSUSED*/ 57531158Sminshall static void 57631158Sminshall unknown_op(regs, sregs) 57731158Sminshall union REGS *regs; 57831158Sminshall struct SREGS *sregs; 57931158Sminshall { 58031158Sminshall regs->h.ch = 0x12; 58131158Sminshall regs->h.cl = 0x05; 58231158Sminshall } 58331158Sminshall 58431158Sminshall 58531158Sminshall handle_api(regs, sregs) 58631158Sminshall union REGS *regs; 58731158Sminshall struct SREGS *sregs; 58831158Sminshall { 58931158Sminshall if (regs->h.ah == NAME_RESOLUTION) { 59031158Sminshall name_resolution(regs, sregs); 59131517Sminshall #if defined(unix) 59231517Sminshall } else if (regs->h.ah == PS_OR_OIA_MODIFIED) { 59331517Sminshall while ((oia_modified == 0) && (ps_modified == 0)) { 59431517Sminshall (void) Scheduler(1); 59531517Sminshall } 59631517Sminshall oia_modified = ps_modified = 0; 59731517Sminshall #endif /* defined(unix) */ 59831168Sminshall } else if (regs->h.ah != 0x09) { 59931168Sminshall regs->h.ch = 0x12; 60031168Sminshall regs->h.cl = 0x0f; /* XXX Invalid environmental access */ 60131168Sminshall } else if (regs->x.bx != 0x8020) { 60231168Sminshall regs->h.ch = 0x12; 60331168Sminshall regs->h.cl = 0x08; /* XXX Invalid wait specified */ 60431168Sminshall } else if (regs->h.ch != 0) { 60531211Sminshall regs->x.cx = 0x1206; /* XXX Invalid priority */ 60631158Sminshall } else { 60731158Sminshall switch (regs->x.dx) { 60831158Sminshall case GATE_SESSMGR: 60931158Sminshall switch (regs->h.al) { 61031158Sminshall case QUERY_SESSION_ID: 61131168Sminshall if (regs->h.cl != 0) { 61231211Sminshall regs->x.cx = 0x1206; 61331168Sminshall } else { 61431211Sminshall regs->x.cx = 0x1200; 61531168Sminshall query_session_id(regs, sregs); 61631168Sminshall } 61731158Sminshall break; 61831211Sminshall case QUERY_SESSION_PARAMETERS: 61931168Sminshall if (regs->h.cl != 0) { 62031211Sminshall regs->x.cx = 0x1206; 62131168Sminshall } else { 62231211Sminshall regs->x.cx = 0x1200; 62331193Sminshall query_session_parameters(regs, sregs); 62431168Sminshall } 62531158Sminshall break; 62631158Sminshall case QUERY_SESSION_CURSOR: 62731168Sminshall if (regs->h.cl != 0xff) { 62831211Sminshall regs->x.cx = 0x1206; 62931168Sminshall } else { 63031211Sminshall regs->x.cx = 0x1200; 63131168Sminshall query_session_cursor(regs, sregs); 63231168Sminshall } 63331158Sminshall break; 63431158Sminshall default: 63531158Sminshall unknown_op(regs, sregs); 63631158Sminshall break; 63731158Sminshall } 63831158Sminshall break; 63931158Sminshall case GATE_KEYBOARD: 64031168Sminshall if (regs->h.cl != 00) { 64131211Sminshall regs->x.cx = 0x1206; 64231168Sminshall } else { 64331211Sminshall regs->x.cx = 0x1200; 64431168Sminshall switch (regs->h.al) { 64531168Sminshall case CONNECT_TO_KEYBOARD: 64631168Sminshall connect_to_keyboard(regs, sregs); 64731168Sminshall break; 64831168Sminshall case DISABLE_INPUT: 64931168Sminshall disable_input(regs, sregs); 65031168Sminshall break; 65131168Sminshall case WRITE_KEYSTROKE: 65231168Sminshall write_keystroke(regs, sregs); 65331168Sminshall break; 65431168Sminshall case ENABLE_INPUT: 65531168Sminshall enable_input(regs, sregs); 65631168Sminshall break; 65731168Sminshall case DISCONNECT_FROM_KEYBOARD: 65831168Sminshall disconnect_from_keyboard(regs, sregs); 65931168Sminshall break; 66031168Sminshall default: 66131168Sminshall unknown_op(regs, sregs); 66231168Sminshall break; 66331168Sminshall } 66431158Sminshall } 66531158Sminshall break; 66631158Sminshall case GATE_COPY: 66731168Sminshall if (regs->h.cl != 0xff) { 66831211Sminshall regs->x.cx = 0x1206; 66931168Sminshall } else { 67031211Sminshall regs->x.cx = 0x1200; 67131168Sminshall switch (regs->h.al) { 67231168Sminshall case COPY_STRING: 67331168Sminshall copy_string(regs, sregs); 67431168Sminshall break; 67531168Sminshall default: 67631168Sminshall unknown_op(regs, sregs); 67731168Sminshall break; 67831168Sminshall } 67931158Sminshall } 68031158Sminshall break; 68131158Sminshall case GATE_OIAM: 68231168Sminshall if (regs->h.cl != 0xff) { 68331211Sminshall regs->x.cx = 0x1206; 68431168Sminshall } else { 68531211Sminshall regs->x.cx = 0x1200; 68631168Sminshall switch (regs->h.al) { 68731168Sminshall case READ_OIA_GROUP: 68831168Sminshall read_oia_group(regs, sregs); 68931168Sminshall break; 69031168Sminshall default: 69131168Sminshall unknown_op(regs, sregs); 69231168Sminshall break; 69331168Sminshall } 69431158Sminshall } 69531158Sminshall break; 69631158Sminshall default: 69731168Sminshall regs->h.ch = 0x12; 69831168Sminshall regs->h.cl = 0x34; /* Invalid GATE entry */ 69931158Sminshall break; 70031158Sminshall } 70131158Sminshall } 70231158Sminshall } 703