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*38924Sminshall static char sccsid[] = "@(#)api.c 4.3 (Berkeley) 09/02/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" 3438210Sminshall #include "hostctlr.h" 3531871Sminshall #include "oia.h" 3631193Sminshall 3731183Sminshall #include "../general/globals.h" 3831158Sminshall 39*38924Sminshall int apitrace = 0; /* Should we trace API interactions */ 40*38924Sminshall 4131158Sminshall /* 4231193Sminshall * General utility routines. 4331193Sminshall */ 4431193Sminshall 4531193Sminshall #if defined(MSDOS) 4631193Sminshall 4731211Sminshall #if defined(LINT_ARGS) 4831211Sminshall static void movetous(char *, int, int, int); 4931211Sminshall static void movetothem(int, int, char *, int); 5031211Sminshall #endif /* defined(LINT_ARGS) */ 5131211Sminshall 5231507Sminshall #define access_api(foo,length,copyin) (foo) 5331507Sminshall #define unaccess_api(foo,goo,length,copyout) 5431226Sminshall 5531193Sminshall static void 5631193Sminshall movetous(parms, es, di, length) 5731193Sminshall char *parms; 5835421Sminshall int es, di; 5935421Sminshall int length; 6031193Sminshall { 6131211Sminshall char far *farparms = parms; 6231193Sminshall 6335421Sminshall movedata(es, di, FP_SEG(farparms), FP_OFF(farparms), length); 64*38924Sminshall if (apitrace) { 65*38924Sminshall Dump('(', parms, length); 66*38924Sminshall } 6731193Sminshall } 6831193Sminshall 6931193Sminshall static void 7031211Sminshall movetothem(es, di, parms, length) 7131211Sminshall int es, di; 7231211Sminshall char *parms; 7331211Sminshall int length; 7431193Sminshall { 7531211Sminshall char far *farparms = parms; 7631193Sminshall 7735421Sminshall movedata(FP_SEG(farparms), FP_OFF(farparms), es, di, length); 78*38924Sminshall if (apitrace) { 79*38924Sminshall Dump(')', parms, length); 80*38924Sminshall } 8131193Sminshall } 8231193Sminshall #endif /* defined(MSDOS) */ 8331193Sminshall 8431226Sminshall #if defined(unix) 8535421Sminshall extern char *access_api(); 8635421Sminshall extern void movetous(), movetothem(), unaccess_api(); 8731226Sminshall #endif /* defined(unix) */ 8831226Sminshall 8931470Sminshall 9031193Sminshall /* 9131158Sminshall * Supervisor Services. 9231158Sminshall */ 9331158Sminshall 9431158Sminshall static void 9531193Sminshall name_resolution(regs, sregs) 9631158Sminshall union REGS *regs; 9731158Sminshall struct SREGS *sregs; 9831158Sminshall { 9931167Sminshall NameResolveParms parms; 10031161Sminshall 10131167Sminshall movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms); 10231161Sminshall 10331161Sminshall regs->h.cl = 0; 10431193Sminshall if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) { 10531161Sminshall regs->x.dx = GATE_SESSMGR; 10631193Sminshall } else if (memcmp((char *)&parms, NAME_KEYBOARD, 10731193Sminshall sizeof parms.gate_name) == 0) { 10831161Sminshall regs->x.dx = GATE_KEYBOARD; 10931193Sminshall } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) { 11031161Sminshall regs->x.dx = GATE_COPY; 11131193Sminshall } else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) { 11231161Sminshall regs->x.dx = GATE_OIAM; 11331161Sminshall } else { 11431161Sminshall regs->h.cl = 0x2e; /* Name not found */ 11531161Sminshall } 11631161Sminshall regs->h.ch = 0x12; 11731161Sminshall regs->h.bh = 7; 11831158Sminshall } 11931158Sminshall 12031158Sminshall /* 12131158Sminshall * Session Information Services. 12231158Sminshall */ 12331158Sminshall 12431158Sminshall static void 12531158Sminshall query_session_id(regs, sregs) 12631158Sminshall union REGS *regs; 12731158Sminshall struct SREGS *sregs; 12831158Sminshall { 12931167Sminshall QuerySessionIdParms parms; 13031161Sminshall 13131167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 13231161Sminshall 13331211Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 13431211Sminshall parms.rc = 0x0c; 13531211Sminshall } else if (parms.option_code != 0x01) { 13631211Sminshall parms.rc = 0x0d; /* Invalid option code */ 13731167Sminshall } else if (parms.data_code != 0x45) { 13831211Sminshall parms.rc = 0x0b; 13931161Sminshall } else { 14031168Sminshall NameArray list; 14131167Sminshall 14231167Sminshall movetous((char *)&list, FP_SEG(parms.name_array), 14335421Sminshall FP_OFF(parms.name_array), sizeof list); 14431168Sminshall if ((list.length < 14) || (list.length > 170)) { 14531167Sminshall parms.rc = 0x12; 14631161Sminshall } else { 14731167Sminshall list.number_matching_session = 1; 14831167Sminshall list.name_array_element.short_name = parms.data_code; 14931167Sminshall list.name_array_element.type = TYPE_DFT; 15031167Sminshall list.name_array_element.session_id = 23; 15131167Sminshall memcpy(list.name_array_element.long_name, "ONLYSESS", 15231167Sminshall sizeof list.name_array_element.long_name); 15331167Sminshall movetothem(FP_SEG(parms.name_array), 15431193Sminshall FP_OFF(parms.name_array), (char *)&list, sizeof list); 15531167Sminshall parms.rc = 0; 15631161Sminshall } 15731161Sminshall } 15831211Sminshall parms.function_id = 0x6b; 15931167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 16031158Sminshall } 16131158Sminshall 16231158Sminshall static void 16331158Sminshall query_session_parameters(regs, sregs) 16431158Sminshall union REGS *regs; 16531158Sminshall struct SREGS *sregs; 16631158Sminshall { 16731167Sminshall QuerySessionParametersParms parms; 16831167Sminshall 16931167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 17031167Sminshall 17131168Sminshall if ((parms.rc !=0) || (parms.function_id != 0)) { 17231211Sminshall parms.rc = 0x0c; 17331211Sminshall } else if (parms.session_id != 23) { 17431211Sminshall parms.rc = 0x02; 17531167Sminshall } else { 17631211Sminshall parms.rc = 0; 17731167Sminshall parms.session_type = TYPE_DFT; 17831167Sminshall parms.session_characteristics = 0; /* Neither EAB nor PSS */ 17931167Sminshall parms.rows = MaxNumberLines; 18031167Sminshall parms.columns = MaxNumberColumns; 18131167Sminshall parms.presentation_space = 0; 18231167Sminshall } 18331211Sminshall parms.function_id = 0x6b; 18431168Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 18531158Sminshall } 18631158Sminshall 18731158Sminshall static void 18831158Sminshall query_session_cursor(regs, sregs) 18931158Sminshall union REGS *regs; 19031158Sminshall struct SREGS *sregs; 19131158Sminshall { 19231167Sminshall QuerySessionCursorParms parms; 19331167Sminshall 19431167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 19531167Sminshall 19631167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 19731167Sminshall parms.rc = 0x0c; 19831167Sminshall } else if (parms.session_id != 23) { 19931167Sminshall parms.rc = 0x02; 20031167Sminshall } else { 20131167Sminshall parms.rc = 0; 20231167Sminshall parms.cursor_type = CURSOR_BLINKING; /* XXX what is inhibited? */ 20331167Sminshall parms.row_address = ScreenLine(CursorAddress); 20431167Sminshall parms.column_address = ScreenLineOffset(CursorAddress); 20531167Sminshall } 20631167Sminshall 20731211Sminshall parms.function_id = 0x6b; 20831211Sminshall movetothem(sregs->es, regs->x.di, (char *) &parms, sizeof parms); 20931158Sminshall } 21031158Sminshall 21131158Sminshall /* 21231158Sminshall * Keyboard Services. 21331158Sminshall */ 21431158Sminshall 21531158Sminshall 21631158Sminshall static void 21731158Sminshall connect_to_keyboard(regs, sregs) 21831158Sminshall union REGS *regs; 21931158Sminshall struct SREGS *sregs; 22031158Sminshall { 22131167Sminshall ConnectToKeyboardParms parms; 22231167Sminshall 22331183Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 22431167Sminshall 22531167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 22631167Sminshall parms.rc = 0x0c; 22731167Sminshall } else if (parms.session_id != 23) { 22831167Sminshall parms.rc = 0x02; 22931167Sminshall } else if (parms.intercept_options != 0) { 23031167Sminshall parms.rc = 0x01; 23131167Sminshall } else { 23231167Sminshall parms.rc = 0; 23331167Sminshall parms.first_connection_identifier = 0; 23431167Sminshall } 23531167Sminshall parms.function_id = 0x62; 23631167Sminshall 23731167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 23831158Sminshall } 23931158Sminshall 24031158Sminshall static void 24131167Sminshall disconnect_from_keyboard(regs, sregs) 24231158Sminshall union REGS *regs; 24331158Sminshall struct SREGS *sregs; 24431158Sminshall { 24531167Sminshall DisconnectFromKeyboardParms parms; 24631167Sminshall 24731167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 24831167Sminshall 24931167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 25031167Sminshall parms.rc = 0x0c; 25131167Sminshall } else if (parms.session_id != 23) { 25231167Sminshall parms.rc = 0x02; 25331167Sminshall } else if (parms.connectors_task_id != 0) { 25431167Sminshall parms.rc = 04; /* XXX */ 25531167Sminshall } else { 25631167Sminshall parms.rc = 0; 25731167Sminshall } 25831167Sminshall parms.function_id = 0x62; 25931167Sminshall 26031167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 26131158Sminshall } 26231158Sminshall 26331158Sminshall static void 26431158Sminshall write_keystroke(regs, sregs) 26531158Sminshall union REGS *regs; 26631158Sminshall struct SREGS *sregs; 26731158Sminshall { 26831198Sminshall WriteKeystrokeParms parms; 26931198Sminshall 27031198Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 27131198Sminshall 27231198Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 27331198Sminshall parms.rc = 0x0c; 27431198Sminshall } else if (parms.session_id != 23) { 27531198Sminshall parms.rc = 0x02; 27631198Sminshall } else if (parms.connectors_task_id != 0) { 27731198Sminshall parms.rc = 0x04; 27831198Sminshall } else { 27931198Sminshall parms.number_of_keys_sent = 0; 28031198Sminshall parms.rc = 0; 28131198Sminshall if (parms.options == OPTION_SINGLE_KEYSTROKE) { 28231198Sminshall KeystrokeEntry *entry = &parms.keystroke_specifier.keystroke_entry; 28331198Sminshall 28431198Sminshall if (AcceptKeystroke(entry->scancode, entry->shift_state) == 0) { 28531198Sminshall parms.rc = 0x10; /* XXX needs 0x12 too! */ 28631198Sminshall } 28731198Sminshall parms.number_of_keys_sent++; 28831198Sminshall } else if (parms.options == OPTION_MULTIPLE_KEYSTROKES) { 28931198Sminshall KeystrokeList 29031198Sminshall list, 29131198Sminshall far *atlist = parms.keystroke_specifier.keystroke_list; 29231198Sminshall KeystrokeEntry 29331198Sminshall entry[10], /* 10 at a time */ 29431198Sminshall *ourentry, 29531198Sminshall far *theirentry; 29631198Sminshall int 29731198Sminshall todo; 29831198Sminshall 29931198Sminshall movetous((char *)&list, FP_SEG(atlist), 30035421Sminshall FP_OFF(atlist), sizeof *atlist); 30131198Sminshall todo = list.length/2; 30231198Sminshall ourentry = entry+(highestof(entry)+1); 30335421Sminshall theirentry = &atlist->keystrokes; 30431198Sminshall 30531198Sminshall while (todo) { 30631198Sminshall if (ourentry > &entry[highestof(entry)]) { 30731198Sminshall int thistime; 30831198Sminshall 30931198Sminshall thistime = todo; 31031198Sminshall if (thistime > numberof(entry)) { 31131198Sminshall thistime = numberof(entry); 31231198Sminshall } 31331198Sminshall movetous((char *)entry, FP_SEG(theirentry), 31431198Sminshall FP_OFF(theirentry), thistime*sizeof *theirentry); 31531198Sminshall theirentry += thistime; 31631198Sminshall ourentry = entry; 31731198Sminshall } 31831198Sminshall if (AcceptKeystroke(ourentry->scancode, 31931198Sminshall ourentry->shift_state) == 0) { 32031198Sminshall parms.rc = 0x10; /* XXX needs 0x12 too! */ 32131198Sminshall break; 32231198Sminshall } 32331198Sminshall parms.number_of_keys_sent++; 32431198Sminshall ourentry++; 32531198Sminshall todo--; 32631198Sminshall } 32731198Sminshall } else { 32831198Sminshall parms.rc = 0x01; 32931198Sminshall } 33031198Sminshall } 33131198Sminshall parms.function_id = 0x62; 33231198Sminshall 33331198Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 33431167Sminshall /* XXX */ 33531158Sminshall } 33631158Sminshall 33731167Sminshall 33831158Sminshall static void 33931167Sminshall disable_input(regs, sregs) 34031167Sminshall union REGS *regs; 34131167Sminshall struct SREGS *sregs; 34231167Sminshall { 34331167Sminshall DisableInputParms parms; 34431167Sminshall 34531167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 34631167Sminshall 34731167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 34831167Sminshall parms.rc = 0x0c; 34931167Sminshall } else if (parms.session_id != 23) { 35031167Sminshall parms.rc = 0x02; 35131167Sminshall } else if (parms.connectors_task_id != 0) { 35231167Sminshall parms.rc = 0x04; 35331167Sminshall } else { 35431211Sminshall SetOiaApiInhibit(&OperatorInformationArea); 35531167Sminshall parms.rc = 0; 35631167Sminshall } 35731167Sminshall parms.function_id = 0x62; 35831167Sminshall 35931167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 36031167Sminshall } 36131167Sminshall 36231167Sminshall static void 36331158Sminshall enable_input(regs, sregs) 36431158Sminshall union REGS *regs; 36531158Sminshall struct SREGS *sregs; 36631158Sminshall { 36731167Sminshall EnableInputParms parms; 36831167Sminshall 36931167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 37031167Sminshall 37131167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 37231167Sminshall parms.rc = 0x0c; 37331167Sminshall } else if (parms.session_id != 23) { 37431167Sminshall parms.rc = 0x02; 37531167Sminshall } else if (parms.connectors_task_id != 0) { 37631167Sminshall parms.rc = 0x04; 37731167Sminshall } else { 37831211Sminshall ResetOiaApiInhibit(&OperatorInformationArea); 37931167Sminshall parms.rc = 0; 38031167Sminshall } 38131167Sminshall parms.function_id = 0x62; 38231167Sminshall 38331167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 38431158Sminshall } 38531158Sminshall 38631158Sminshall /* 38731158Sminshall * Copy Services. 38831158Sminshall */ 38931158Sminshall 39031507Sminshall static 39131507Sminshall copy_subroutine(target, source, parms, what_is_user, length) 39231226Sminshall BufferDescriptor *target, *source; 39331226Sminshall CopyStringParms *parms; 39431226Sminshall int what_is_user; 39531226Sminshall #define USER_IS_TARGET 0 39631226Sminshall #define USER_IS_SOURCE 1 39731226Sminshall { 39831226Sminshall #define TARGET_NO_EAB 1 39931226Sminshall #define SOURCE_NO_EAB 2 40031226Sminshall #define TARGET_PC 4 40131226Sminshall #define SOURCE_PC 8 40231226Sminshall #define NO_FIELD_ATTRIBUTES 16 40331226Sminshall int needtodo = 0; 40431226Sminshall int access_length; 40531226Sminshall char far *input; 40631226Sminshall char far *output; 40731226Sminshall char far *access_pointer; 40831226Sminshall 40931226Sminshall if ((target->characteristics^source->characteristics) 41031226Sminshall &CHARACTERISTIC_EAB) { 41131226Sminshall if (target->characteristics&CHARACTERISTIC_EAB) { 41231226Sminshall needtodo |= TARGET_NO_EAB; /* Need to bump for EAB in target */ 41331226Sminshall } else { 41431226Sminshall needtodo |= SOURCE_NO_EAB; /* Need to bump for EAB in source */ 41531226Sminshall } 41631226Sminshall } 41731226Sminshall if (target->session_type != source->session_type) { 41831226Sminshall if (target->session_type == TYPE_PC) { 41931226Sminshall needtodo |= TARGET_PC; /* scan codes to PC */ 42031226Sminshall } else { 42131226Sminshall needtodo |= SOURCE_PC; /* PC to scan codes */ 42231226Sminshall } 42331226Sminshall } 42431226Sminshall if ((parms->copy_mode©_MODE_FIELD_ATTRIBUTES) == 0) { 42531226Sminshall needtodo |= NO_FIELD_ATTRIBUTES; 42631226Sminshall } 42731507Sminshall access_length = length; 42831226Sminshall if (what_is_user == USER_IS_TARGET) { 42931226Sminshall if (target->characteristics&CHARACTERISTIC_EAB) { 43031226Sminshall access_length *= 2; 43131226Sminshall } 43231226Sminshall input = (char far *) &Host[source->begin]; 43331226Sminshall access_pointer = target->buffer; 43431507Sminshall output = access_api(target->buffer, access_length, 0); 43531226Sminshall } else { 43631226Sminshall if (source->characteristics&CHARACTERISTIC_EAB) { 43731226Sminshall access_length *= 2; 43831226Sminshall } 43931226Sminshall access_pointer = source->buffer; 44031507Sminshall input = access_api(source->buffer, access_length, 1); 44131226Sminshall output = (char far *) &Host[target->begin]; 44231226Sminshall } 44331226Sminshall while (length--) { 44431226Sminshall if (needtodo&TARGET_PC) { 44531226Sminshall *output++ = disp_asc[*input++]; 44631226Sminshall } else if (needtodo&SOURCE_PC) { 44731226Sminshall *output++ = asc_disp[*input++]; 44831226Sminshall } else { 44931226Sminshall *output++ = *input++; 45031226Sminshall } 45131226Sminshall if (needtodo&TARGET_NO_EAB) { 45235421Sminshall input++; 45331226Sminshall } else if (needtodo&SOURCE_NO_EAB) { 45431226Sminshall *output++ = 0; /* Should figure out good EAB? */ 45531226Sminshall } 45631226Sminshall } 45731226Sminshall if (what_is_user == USER_IS_TARGET) { 45831507Sminshall unaccess_api(target->buffer, access_pointer, access_length, 1); 45931226Sminshall } else { 46031507Sminshall unaccess_api(source->buffer, access_pointer, access_length, 0); 46131226Sminshall } 46231226Sminshall } 46331226Sminshall 46431226Sminshall 46531158Sminshall static void 46631167Sminshall copy_string(regs, sregs) 46731158Sminshall union REGS *regs; 46831158Sminshall struct SREGS *sregs; 46931158Sminshall { 47031167Sminshall CopyStringParms parms; 47131226Sminshall BufferDescriptor *target = &parms.target, *source = &parms.source; 47231226Sminshall int length; 47331167Sminshall 47431167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 47531167Sminshall 47631507Sminshall length = 1+parms.source_end-source->begin; 47731167Sminshall if ((parms.rc != 0) || (parms.function_id !=0)) { 47831167Sminshall parms.rc = 0x0c; 47931226Sminshall } else if (target->session_id == 0) { /* Target is buffer */ 48031226Sminshall if (source->session_id != 23) { /* A no-no */ 48131226Sminshall parms.rc = 0x2; 48231226Sminshall } else { 48331507Sminshall if ((source->begin < 0) || (source->begin > highestof(Host))) { 48431507Sminshall parms.rc = 0x06; /* invalid source definition */ 48531507Sminshall } else { 48631507Sminshall if ((source->begin+length) > highestof(Host)) { 48731507Sminshall length = highestof(Host)-source->begin; 48831507Sminshall parms.rc = 0x0f; /* Truncate */ 48931507Sminshall } 49031507Sminshall if ((source->characteristics == target->characteristics) && 49131226Sminshall (source->session_type == target->session_type)) { 49231507Sminshall if (source->characteristics&CHARACTERISTIC_EAB) { 49331507Sminshall length *= 2; 49431507Sminshall } 49535421Sminshall movetothem(FP_SEG(target->buffer), 49635421Sminshall FP_OFF(target->buffer), 49731507Sminshall (char *)&Host[source->begin], length); 49831507Sminshall } else { 49931507Sminshall copy_subroutine(target, source, &parms, 50031507Sminshall USER_IS_TARGET, length); 50131226Sminshall } 50231226Sminshall } 50331226Sminshall } 50431226Sminshall } else if (source->session_id != 0) { 50531226Sminshall parms.rc = 0xd; 50631226Sminshall } else { 50738210Sminshall /* Send to presentation space (3270 buffer) */ 50838210Sminshall if ((target->begin < 0) || (target->begin > highestof(Host))) { 50938210Sminshall parms.rc = 0x07; /* invalid target definition */ 51038210Sminshall } if (!UnLocked) { 51138210Sminshall parms.rc = 0x03; /* Keyboard locked */ 51238210Sminshall } else if (parms.copy_mode != 0) { 51338210Sminshall parms.rc = 0x0f; /* Copy of field attr's not allowed */ 51438210Sminshall } else if (IsProtected(target->begin) || /* Make sure no protected */ 51538210Sminshall (WhereAttrByte(target->begin) != /* in range */ 51638210Sminshall WhereAttrByte(target->begin+length-1))) { 51738210Sminshall parms.rc = 0x0e; /* Attempt to write in protected */ 51831507Sminshall } else { 51938210Sminshall if ((target->begin+length) > highestof(Host)) { 52038210Sminshall length = highestof(Host)-target->begin; 52131507Sminshall parms.rc = 0x0f; /* Truncate */ 52231226Sminshall } 52338210Sminshall TurnOnMdt(target->begin); /* Things have changed */ 52431507Sminshall if ((source->characteristics == target->characteristics) && 52531507Sminshall (source->session_type == target->session_type)) { 52631507Sminshall if (source->characteristics&CHARACTERISTIC_EAB) { 52731507Sminshall length *= 2; 52831507Sminshall } 52931507Sminshall movetous((char *)&Host[target->begin], 53035421Sminshall FP_SEG(source->buffer), 53135421Sminshall FP_OFF(source->buffer), length); 53231507Sminshall } else { 53331507Sminshall copy_subroutine(target, source, &parms, USER_IS_SOURCE, length); 53431507Sminshall } 53531226Sminshall } 53631167Sminshall } 53731183Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 53831158Sminshall } 53931158Sminshall /* 54031158Sminshall * Operator Information Area Services. 54131158Sminshall */ 54231158Sminshall 54331158Sminshall static void 54431158Sminshall read_oia_group(regs, sregs) 54531158Sminshall union REGS *regs; 54631158Sminshall struct SREGS *sregs; 54731158Sminshall { 54831167Sminshall ReadOiaGroupParms parms; 54931167Sminshall 55031167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 55131167Sminshall 55231167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 55331167Sminshall parms.rc = 0x0c; 55431167Sminshall } else if (parms.session_id != 23) { 55531167Sminshall parms.rc = 0x02; 55631167Sminshall } else { 55731167Sminshall int group = parms.oia_group_number; 55831193Sminshall char *from; 55931193Sminshall int size; 56031167Sminshall 56131211Sminshall if ((group != API_OIA_ALL_GROUPS) && 56231211Sminshall ((group > API_OIA_LAST_LEGAL_GROUP) || (group < 0))) { 56331193Sminshall } else { 56431193Sminshall if (group == API_OIA_ALL_GROUPS) { 56531193Sminshall size = API_OIA_BYTES_ALL_GROUPS; 56631193Sminshall from = (char *)&OperatorInformationArea; 56731193Sminshall } else if (group == API_OIA_INPUT_INHIBITED) { 56831193Sminshall size = sizeof OperatorInformationArea.input_inhibited; 56931193Sminshall from = (char *)&OperatorInformationArea.input_inhibited[0]; 57031193Sminshall } else { 57131193Sminshall size = 1; 57231193Sminshall from = ((char *)&OperatorInformationArea)+group; 57331193Sminshall } 57431193Sminshall movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer), 57531193Sminshall from, size); 57631168Sminshall } 57731167Sminshall } 57831168Sminshall parms.function_id = 0x6d; 57931167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 58031158Sminshall } 58131158Sminshall 58235421Sminshall /*ARGSUSED*/ 58331158Sminshall static void 58431158Sminshall unknown_op(regs, sregs) 58531158Sminshall union REGS *regs; 58631158Sminshall struct SREGS *sregs; 58731158Sminshall { 58831158Sminshall regs->h.ch = 0x12; 58931158Sminshall regs->h.cl = 0x05; 59031158Sminshall } 59131158Sminshall 59231158Sminshall 59331158Sminshall handle_api(regs, sregs) 59431158Sminshall union REGS *regs; 59531158Sminshall struct SREGS *sregs; 59631158Sminshall { 597*38924Sminshall /* 598*38924Sminshall * Do we need to log this transaction? 599*38924Sminshall */ 600*38924Sminshall if (apitrace) { 601*38924Sminshall Dump('<', (char *)regs, sizeof *regs); 602*38924Sminshall Dump('<', (char *)sregs, sizeof *sregs); 603*38924Sminshall } 60431158Sminshall if (regs->h.ah == NAME_RESOLUTION) { 60531158Sminshall name_resolution(regs, sregs); 60631517Sminshall #if defined(unix) 60731517Sminshall } else if (regs->h.ah == PS_OR_OIA_MODIFIED) { 60831517Sminshall while ((oia_modified == 0) && (ps_modified == 0)) { 60931517Sminshall (void) Scheduler(1); 61031517Sminshall } 61131517Sminshall oia_modified = ps_modified = 0; 61231517Sminshall #endif /* defined(unix) */ 61331168Sminshall } else if (regs->h.ah != 0x09) { 61431168Sminshall regs->h.ch = 0x12; 61531168Sminshall regs->h.cl = 0x0f; /* XXX Invalid environmental access */ 61631168Sminshall } else if (regs->x.bx != 0x8020) { 61731168Sminshall regs->h.ch = 0x12; 61831168Sminshall regs->h.cl = 0x08; /* XXX Invalid wait specified */ 61931168Sminshall } else if (regs->h.ch != 0) { 62031211Sminshall regs->x.cx = 0x1206; /* XXX Invalid priority */ 62131158Sminshall } else { 62231158Sminshall switch (regs->x.dx) { 62331158Sminshall case GATE_SESSMGR: 62431158Sminshall switch (regs->h.al) { 62531158Sminshall case QUERY_SESSION_ID: 62631168Sminshall if (regs->h.cl != 0) { 62731211Sminshall regs->x.cx = 0x1206; 62831168Sminshall } else { 62931211Sminshall regs->x.cx = 0x1200; 63031168Sminshall query_session_id(regs, sregs); 63131168Sminshall } 63231158Sminshall break; 63331211Sminshall case QUERY_SESSION_PARAMETERS: 63431168Sminshall if (regs->h.cl != 0) { 63531211Sminshall regs->x.cx = 0x1206; 63631168Sminshall } else { 63731211Sminshall regs->x.cx = 0x1200; 63831193Sminshall query_session_parameters(regs, sregs); 63931168Sminshall } 64031158Sminshall break; 64131158Sminshall case QUERY_SESSION_CURSOR: 64231168Sminshall if (regs->h.cl != 0xff) { 64331211Sminshall regs->x.cx = 0x1206; 64431168Sminshall } else { 64531211Sminshall regs->x.cx = 0x1200; 64631168Sminshall query_session_cursor(regs, sregs); 64731168Sminshall } 64831158Sminshall break; 64931158Sminshall default: 65031158Sminshall unknown_op(regs, sregs); 65131158Sminshall break; 65231158Sminshall } 65331158Sminshall break; 65431158Sminshall case GATE_KEYBOARD: 65531168Sminshall if (regs->h.cl != 00) { 65631211Sminshall regs->x.cx = 0x1206; 65731168Sminshall } else { 65831211Sminshall regs->x.cx = 0x1200; 65931168Sminshall switch (regs->h.al) { 66031168Sminshall case CONNECT_TO_KEYBOARD: 66131168Sminshall connect_to_keyboard(regs, sregs); 66231168Sminshall break; 66331168Sminshall case DISABLE_INPUT: 66431168Sminshall disable_input(regs, sregs); 66531168Sminshall break; 66631168Sminshall case WRITE_KEYSTROKE: 66731168Sminshall write_keystroke(regs, sregs); 66831168Sminshall break; 66931168Sminshall case ENABLE_INPUT: 67031168Sminshall enable_input(regs, sregs); 67131168Sminshall break; 67231168Sminshall case DISCONNECT_FROM_KEYBOARD: 67331168Sminshall disconnect_from_keyboard(regs, sregs); 67431168Sminshall break; 67531168Sminshall default: 67631168Sminshall unknown_op(regs, sregs); 67731168Sminshall break; 67831168Sminshall } 67931158Sminshall } 68031158Sminshall break; 68131158Sminshall case GATE_COPY: 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 COPY_STRING: 68831168Sminshall copy_string(regs, sregs); 68931168Sminshall break; 69031168Sminshall default: 69131168Sminshall unknown_op(regs, sregs); 69231168Sminshall break; 69331168Sminshall } 69431158Sminshall } 69531158Sminshall break; 69631158Sminshall case GATE_OIAM: 69731168Sminshall if (regs->h.cl != 0xff) { 69831211Sminshall regs->x.cx = 0x1206; 69931168Sminshall } else { 70031211Sminshall regs->x.cx = 0x1200; 70131168Sminshall switch (regs->h.al) { 70231168Sminshall case READ_OIA_GROUP: 70331168Sminshall read_oia_group(regs, sregs); 70431168Sminshall break; 70531168Sminshall default: 70631168Sminshall unknown_op(regs, sregs); 70731168Sminshall break; 70831168Sminshall } 70931158Sminshall } 71031158Sminshall break; 71131158Sminshall default: 71231168Sminshall regs->h.ch = 0x12; 71331168Sminshall regs->h.cl = 0x34; /* Invalid GATE entry */ 71431158Sminshall break; 71531158Sminshall } 71631158Sminshall } 717*38924Sminshall /* 718*38924Sminshall * Do we need to log this transaction? 719*38924Sminshall */ 720*38924Sminshall if (apitrace) { 721*38924Sminshall Dump('>', (char *)regs, sizeof *regs); 722*38924Sminshall Dump('>', (char *)sregs, sizeof *sregs); 723*38924Sminshall } 72431158Sminshall } 725