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