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©_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