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