131158Sminshall /* 231158Sminshall * This file implements the API used in the PC version. 331158Sminshall */ 431158Sminshall 531158Sminshall #include <stdio.h> 631158Sminshall 731158Sminshall #include "api.h" 831183Sminshall #include "../general/general.h" 931158Sminshall 1031168Sminshall #include "../ctlr/screen.h" 1131193Sminshall #include "../ctlr/oia.h" 1231193Sminshall 1331183Sminshall #include "../general/globals.h" 1431158Sminshall 1531168Sminshall int ApiDisableInput = 0; 1631168Sminshall 1731158Sminshall /* 1831193Sminshall * General utility routines. 1931193Sminshall */ 2031193Sminshall 2131193Sminshall #if defined(MSDOS) 2231193Sminshall static int ourds = 0; /* Safe */ 2331193Sminshall 2431193Sminshall static void 2531193Sminshall movetous(parms, es, di, length) 2631193Sminshall char *parms; 2731193Sminshall { 2831193Sminshall if (ourds == 0) { 2931193Sminshall struct SREGS sregs; 3031193Sminshall 3131193Sminshall segread(&sregs); 3231193Sminshall ourds = sregs.ds; 3331193Sminshall } 3431193Sminshall movedata(es, di, ourds, (int)parms, length); 3531193Sminshall } 3631193Sminshall 3731193Sminshall static void 3831193Sminshall movetothem(parms, es, di, length) 3931193Sminshall { 4031193Sminshall if (ourds == 0) { 4131193Sminshall struct SREGS sregs; 4231193Sminshall 4331193Sminshall segread(&sregs); 4431193Sminshall ourds = sregs.es; 4531193Sminshall } 4631193Sminshall movedata(ourds, (int)parms, es, di, length); 4731193Sminshall } 4831193Sminshall #endif /* defined(MSDOS) */ 4931193Sminshall 5031193Sminshall /* No Unix version yet... */ 5131193Sminshall 5231193Sminshall 5331193Sminshall /* 5431158Sminshall * Supervisor Services. 5531158Sminshall */ 5631158Sminshall 5731158Sminshall static void 5831193Sminshall name_resolution(regs, sregs) 5931158Sminshall union REGS *regs; 6031158Sminshall struct SREGS *sregs; 6131158Sminshall { 6231167Sminshall NameResolveParms parms; 6331161Sminshall 6431167Sminshall movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms); 6531161Sminshall 6631161Sminshall regs->h.cl = 0; 6731193Sminshall if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) { 6831161Sminshall regs->x.dx = GATE_SESSMGR; 6931193Sminshall } else if (memcmp((char *)&parms, NAME_KEYBOARD, 7031193Sminshall sizeof parms.gate_name) == 0) { 7131161Sminshall regs->x.dx = GATE_KEYBOARD; 7231193Sminshall } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) { 7331161Sminshall regs->x.dx = GATE_COPY; 7431193Sminshall } else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) { 7531161Sminshall regs->x.dx = GATE_OIAM; 7631161Sminshall } else { 7731161Sminshall regs->h.cl = 0x2e; /* Name not found */ 7831161Sminshall } 7931161Sminshall regs->h.ch = 0x12; 8031161Sminshall regs->h.bh = 7; 8131158Sminshall } 8231158Sminshall 8331158Sminshall /* 8431158Sminshall * Session Information Services. 8531158Sminshall */ 8631158Sminshall 8731158Sminshall static void 8831158Sminshall query_session_id(regs, sregs) 8931158Sminshall union REGS *regs; 9031158Sminshall struct SREGS *sregs; 9131158Sminshall { 9231167Sminshall QuerySessionIdParms parms; 9331161Sminshall 9431167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 9531161Sminshall 9631167Sminshall if (parms.rc != 0) { 9731167Sminshall regs->h.cl = 0x0c; 9831167Sminshall return; 9931167Sminshall } 10031167Sminshall if (parms.option_code != 0x01) { 10131167Sminshall regs->h.cl = 0x0d; /* Invalid option code */ 10231167Sminshall } else if (parms.data_code != 0x45) { 10331167Sminshall regs->h.cl = 0x0b; 10431161Sminshall } else { 10531168Sminshall NameArray list; 10631167Sminshall NameArrayElement element; 10731167Sminshall 10831167Sminshall movetous((char *)&list, FP_SEG(parms.name_array), 10931193Sminshall FP_OFF(parms.name_array), sizeof list); 11031168Sminshall if ((list.length < 14) || (list.length > 170)) { 11131167Sminshall parms.rc = 0x12; 11231168Sminshall regs->h.cl = 0x12; 11331161Sminshall } else { 11431167Sminshall list.number_matching_session = 1; 11531167Sminshall list.name_array_element.short_name = parms.data_code; 11631167Sminshall list.name_array_element.type = TYPE_DFT; 11731167Sminshall list.name_array_element.session_id = 23; 11831167Sminshall memcpy(list.name_array_element.long_name, "ONLYSESS", 11931167Sminshall sizeof list.name_array_element.long_name); 12031167Sminshall movetothem(FP_SEG(parms.name_array), 12131193Sminshall FP_OFF(parms.name_array), (char *)&list, sizeof list); 12231167Sminshall parms.rc = 0; 12331161Sminshall regs->h.cl = 0; 12431161Sminshall } 12531161Sminshall } 12631168Sminshall parms.function_id = 0x6d; 12731167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 12831158Sminshall } 12931158Sminshall 13031158Sminshall static void 13131158Sminshall query_session_parameters(regs, sregs) 13231158Sminshall union REGS *regs; 13331158Sminshall struct SREGS *sregs; 13431158Sminshall { 13531167Sminshall QuerySessionParametersParms parms; 13631167Sminshall 13731167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 13831167Sminshall 13931168Sminshall if ((parms.rc !=0) || (parms.function_id != 0)) { 14031167Sminshall regs->h.cl = 0x0c; 14131167Sminshall return; 14231167Sminshall } 14331167Sminshall if (parms.session_id != 23) { 14431168Sminshall regs->h.cl = parms.rc = 0x02; 14531167Sminshall } else { 14631168Sminshall regs->h.cl = parms.rc = 0; 14731167Sminshall parms.function_id = 0x6b; 14831167Sminshall parms.session_type = TYPE_DFT; 14931167Sminshall parms.session_characteristics = 0; /* Neither EAB nor PSS */ 15031167Sminshall parms.rows = MaxNumberLines; 15131167Sminshall parms.columns = MaxNumberColumns; 15231167Sminshall parms.presentation_space = 0; 15331167Sminshall } 15431168Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 15531158Sminshall } 15631158Sminshall 15731158Sminshall static void 15831158Sminshall query_session_cursor(regs, sregs) 15931158Sminshall union REGS *regs; 16031158Sminshall struct SREGS *sregs; 16131158Sminshall { 16231167Sminshall QuerySessionCursorParms parms; 16331167Sminshall 16431167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 16531167Sminshall 16631167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 16731167Sminshall parms.rc = 0x0c; 16831167Sminshall } else if (parms.session_id != 23) { 16931167Sminshall parms.rc = 0x02; 17031167Sminshall } else { 17131167Sminshall parms.rc = 0; 17231167Sminshall parms.function_id = 0x6b; 17331167Sminshall parms.cursor_type = CURSOR_BLINKING; /* XXX what is inhibited? */ 17431167Sminshall parms.row_address = ScreenLine(CursorAddress); 17531167Sminshall parms.column_address = ScreenLineOffset(CursorAddress); 17631167Sminshall } 17731167Sminshall 17831167Sminshall movetothem(sregs->es, regs->x.di, sizeof parms); 17931158Sminshall } 18031158Sminshall 18131158Sminshall /* 18231158Sminshall * Keyboard Services. 18331158Sminshall */ 18431158Sminshall 18531158Sminshall 18631158Sminshall static void 18731158Sminshall connect_to_keyboard(regs, sregs) 18831158Sminshall union REGS *regs; 18931158Sminshall struct SREGS *sregs; 19031158Sminshall { 19131167Sminshall ConnectToKeyboardParms parms; 19231167Sminshall 19331183Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 19431167Sminshall 19531167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 19631167Sminshall parms.rc = 0x0c; 19731167Sminshall } else if (parms.session_id != 23) { 19831167Sminshall parms.rc = 0x02; 19931167Sminshall } else if (parms.intercept_options != 0) { 20031167Sminshall parms.rc = 0x01; 20131167Sminshall } else { 20231167Sminshall parms.rc = 0; 20331167Sminshall parms.first_connection_identifier = 0; 20431167Sminshall } 20531167Sminshall parms.function_id = 0x62; 20631167Sminshall 20731167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 20831158Sminshall } 20931158Sminshall 21031158Sminshall static void 21131167Sminshall disconnect_from_keyboard(regs, sregs) 21231158Sminshall union REGS *regs; 21331158Sminshall struct SREGS *sregs; 21431158Sminshall { 21531167Sminshall DisconnectFromKeyboardParms parms; 21631167Sminshall 21731167Sminshall 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.connectors_task_id != 0) { 22431167Sminshall parms.rc = 04; /* XXX */ 22531167Sminshall } else { 22631167Sminshall parms.rc = 0; 22731167Sminshall } 22831167Sminshall parms.function_id = 0x62; 22931167Sminshall 23031167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 23131158Sminshall } 23231158Sminshall 23331158Sminshall static void 23431158Sminshall write_keystroke(regs, sregs) 23531158Sminshall union REGS *regs; 23631158Sminshall struct SREGS *sregs; 23731158Sminshall { 238*31198Sminshall WriteKeystrokeParms parms; 239*31198Sminshall 240*31198Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 241*31198Sminshall 242*31198Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 243*31198Sminshall parms.rc = 0x0c; 244*31198Sminshall } else if (parms.session_id != 23) { 245*31198Sminshall parms.rc = 0x02; 246*31198Sminshall } else if (parms.connectors_task_id != 0) { 247*31198Sminshall parms.rc = 0x04; 248*31198Sminshall } else { 249*31198Sminshall parms.number_of_keys_sent = 0; 250*31198Sminshall parms.rc = 0; 251*31198Sminshall if (parms.options == OPTION_SINGLE_KEYSTROKE) { 252*31198Sminshall KeystrokeEntry *entry = &parms.keystroke_specifier.keystroke_entry; 253*31198Sminshall 254*31198Sminshall if (AcceptKeystroke(entry->scancode, entry->shift_state) == 0) { 255*31198Sminshall parms.rc = 0x10; /* XXX needs 0x12 too! */ 256*31198Sminshall } 257*31198Sminshall parms.number_of_keys_sent++; 258*31198Sminshall } else if (parms.options == OPTION_MULTIPLE_KEYSTROKES) { 259*31198Sminshall KeystrokeList 260*31198Sminshall list, 261*31198Sminshall far *atlist = parms.keystroke_specifier.keystroke_list; 262*31198Sminshall KeystrokeEntry 263*31198Sminshall entry[10], /* 10 at a time */ 264*31198Sminshall *ourentry, 265*31198Sminshall far *theirentry; 266*31198Sminshall int 267*31198Sminshall todo; 268*31198Sminshall 269*31198Sminshall movetous((char *)&list, FP_SEG(atlist), 270*31198Sminshall FP_OFF(atlist), sizeof *atlist); 271*31198Sminshall todo = list.length/2; 272*31198Sminshall ourentry = entry+(highestof(entry)+1); 273*31198Sminshall 274*31198Sminshall while (todo) { 275*31198Sminshall if (ourentry > &entry[highestof(entry)]) { 276*31198Sminshall int thistime; 277*31198Sminshall 278*31198Sminshall thistime = todo; 279*31198Sminshall if (thistime > numberof(entry)) { 280*31198Sminshall thistime = numberof(entry); 281*31198Sminshall } 282*31198Sminshall movetous((char *)entry, FP_SEG(theirentry), 283*31198Sminshall FP_OFF(theirentry), thistime*sizeof *theirentry); 284*31198Sminshall theirentry += thistime; 285*31198Sminshall ourentry = entry; 286*31198Sminshall } 287*31198Sminshall if (AcceptKeystroke(ourentry->scancode, 288*31198Sminshall ourentry->shift_state) == 0) { 289*31198Sminshall parms.rc = 0x10; /* XXX needs 0x12 too! */ 290*31198Sminshall break; 291*31198Sminshall } 292*31198Sminshall parms.number_of_keys_sent++; 293*31198Sminshall ourentry++; 294*31198Sminshall todo--; 295*31198Sminshall } 296*31198Sminshall } else { 297*31198Sminshall parms.rc = 0x01; 298*31198Sminshall } 299*31198Sminshall } 300*31198Sminshall parms.function_id = 0x62; 301*31198Sminshall 302*31198Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 30331167Sminshall /* XXX */ 30431158Sminshall } 30531158Sminshall 30631167Sminshall 30731158Sminshall static void 30831167Sminshall disable_input(regs, sregs) 30931167Sminshall union REGS *regs; 31031167Sminshall struct SREGS *sregs; 31131167Sminshall { 31231167Sminshall DisableInputParms parms; 31331167Sminshall 31431167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 31531167Sminshall 31631167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 31731167Sminshall parms.rc = 0x0c; 31831167Sminshall } else if (parms.session_id != 23) { 31931167Sminshall parms.rc = 0x02; 32031167Sminshall } else if (parms.connectors_task_id != 0) { 32131167Sminshall parms.rc = 0x04; 32231167Sminshall } else { 32331167Sminshall ApiDisableInput = 1; 32431167Sminshall parms.rc = 0; 32531167Sminshall } 32631167Sminshall parms.function_id = 0x62; 32731167Sminshall 32831167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 32931167Sminshall } 33031167Sminshall 33131167Sminshall static void 33231158Sminshall enable_input(regs, sregs) 33331158Sminshall union REGS *regs; 33431158Sminshall struct SREGS *sregs; 33531158Sminshall { 33631167Sminshall EnableInputParms 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 { 34731167Sminshall ApiDisableInput = 0; 34831167Sminshall parms.rc = 0; 34931167Sminshall } 35031167Sminshall parms.function_id = 0x62; 35131167Sminshall 35231167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 35331158Sminshall } 35431158Sminshall 35531158Sminshall /* 35631158Sminshall * Copy Services. 35731158Sminshall */ 35831158Sminshall 35931158Sminshall static void 36031167Sminshall copy_string(regs, sregs) 36131158Sminshall union REGS *regs; 36231158Sminshall struct SREGS *sregs; 36331158Sminshall { 36431167Sminshall CopyStringParms parms; 36531167Sminshall BufferDescriptor *target, *source; 36631167Sminshall 36731167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 36831167Sminshall 36931167Sminshall if ((parms.rc != 0) || (parms.function_id !=0)) { 37031167Sminshall parms.rc = 0x0c; 37131167Sminshall } 37231167Sminshall /* XXX do something! */ 37331183Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 37431158Sminshall } 37531158Sminshall /* 37631158Sminshall * Operator Information Area Services. 37731158Sminshall */ 37831158Sminshall 37931158Sminshall static void 38031158Sminshall read_oia_group(regs, sregs) 38131158Sminshall union REGS *regs; 38231158Sminshall struct SREGS *sregs; 38331158Sminshall { 38431167Sminshall ReadOiaGroupParms parms; 38531167Sminshall 38631167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 38731167Sminshall 38831167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 38931167Sminshall parms.rc = 0x0c; 39031167Sminshall } else if (parms.session_id != 23) { 39131167Sminshall parms.rc = 0x02; 39231167Sminshall } else { 39331167Sminshall int group = parms.oia_group_number; 39431193Sminshall char *from; 39531193Sminshall int size; 39631167Sminshall 39731193Sminshall if (group > API_OIA_LAST_LEGAL_GROUP) { 39831193Sminshall } else { 39931193Sminshall if (group == API_OIA_ALL_GROUPS) { 40031193Sminshall size = API_OIA_BYTES_ALL_GROUPS; 40131193Sminshall from = (char *)&OperatorInformationArea; 40231193Sminshall } else if (group == API_OIA_INPUT_INHIBITED) { 40331193Sminshall size = sizeof OperatorInformationArea.input_inhibited; 40431193Sminshall from = (char *)&OperatorInformationArea.input_inhibited[0]; 40531193Sminshall } else { 40631193Sminshall size = 1; 40731193Sminshall from = ((char *)&OperatorInformationArea)+group; 40831193Sminshall } 40931193Sminshall movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer), 41031193Sminshall from, size); 41131168Sminshall } 41231167Sminshall } 41331168Sminshall parms.function_id = 0x6d; 41431167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 41531158Sminshall } 41631158Sminshall 41731158Sminshall static void 41831158Sminshall unknown_op(regs, sregs) 41931158Sminshall union REGS *regs; 42031158Sminshall struct SREGS *sregs; 42131158Sminshall { 42231158Sminshall regs->h.ch = 0x12; 42331158Sminshall regs->h.cl = 0x05; 42431158Sminshall } 42531158Sminshall 42631158Sminshall 42731158Sminshall handle_api(regs, sregs) 42831158Sminshall union REGS *regs; 42931158Sminshall struct SREGS *sregs; 43031158Sminshall { 43131158Sminshall if (regs->h.ah == NAME_RESOLUTION) { 43231158Sminshall name_resolution(regs, sregs); 43331168Sminshall } else if (regs->h.ah != 0x09) { 43431168Sminshall regs->h.ch = 0x12; 43531168Sminshall regs->h.cl = 0x0f; /* XXX Invalid environmental access */ 43631168Sminshall } else if (regs->x.bx != 0x8020) { 43731168Sminshall regs->h.ch = 0x12; 43831168Sminshall regs->h.cl = 0x08; /* XXX Invalid wait specified */ 43931168Sminshall } else if (regs->h.ch != 0) { 44031168Sminshall regs->h.ch = 0x12; 44131168Sminshall regs->h.cl = 0x07; /* XXX Invalid reply specified */ 44231158Sminshall } else { 44331158Sminshall switch (regs->x.dx) { 44431158Sminshall case GATE_SESSMGR: 44531158Sminshall switch (regs->h.al) { 44631158Sminshall case QUERY_SESSION_ID: 44731168Sminshall if (regs->h.cl != 0) { 44831168Sminshall } else { 44931168Sminshall query_session_id(regs, sregs); 45031168Sminshall } 45131158Sminshall break; 45231158Sminshall case QUERY_SESSION_PARMS: 45331168Sminshall if (regs->h.cl != 0) { 45431168Sminshall } else { 45531193Sminshall query_session_parameters(regs, sregs); 45631168Sminshall } 45731158Sminshall break; 45831158Sminshall case QUERY_SESSION_CURSOR: 45931168Sminshall if (regs->h.cl != 0xff) { 46031168Sminshall } else { 46131168Sminshall query_session_cursor(regs, sregs); 46231168Sminshall } 46331158Sminshall break; 46431158Sminshall default: 46531158Sminshall unknown_op(regs, sregs); 46631158Sminshall break; 46731158Sminshall } 46831158Sminshall break; 46931158Sminshall case GATE_KEYBOARD: 47031168Sminshall if (regs->h.cl != 00) { 47131168Sminshall } else { 47231168Sminshall switch (regs->h.al) { 47331168Sminshall case CONNECT_TO_KEYBOARD: 47431168Sminshall connect_to_keyboard(regs, sregs); 47531168Sminshall break; 47631168Sminshall case DISABLE_INPUT: 47731168Sminshall disable_input(regs, sregs); 47831168Sminshall break; 47931168Sminshall case WRITE_KEYSTROKE: 48031168Sminshall write_keystroke(regs, sregs); 48131168Sminshall break; 48231168Sminshall case ENABLE_INPUT: 48331168Sminshall enable_input(regs, sregs); 48431168Sminshall break; 48531168Sminshall case DISCONNECT_FROM_KEYBOARD: 48631168Sminshall disconnect_from_keyboard(regs, sregs); 48731168Sminshall break; 48831168Sminshall default: 48931168Sminshall unknown_op(regs, sregs); 49031168Sminshall break; 49131168Sminshall } 49231158Sminshall } 49331158Sminshall break; 49431158Sminshall case GATE_COPY: 49531168Sminshall if (regs->h.cl != 0xff) { 49631168Sminshall } else { 49731168Sminshall switch (regs->h.al) { 49831168Sminshall case COPY_STRING: 49931168Sminshall copy_string(regs, sregs); 50031168Sminshall break; 50131168Sminshall default: 50231168Sminshall unknown_op(regs, sregs); 50331168Sminshall break; 50431168Sminshall } 50531158Sminshall } 50631158Sminshall break; 50731158Sminshall case GATE_OIAM: 50831168Sminshall if (regs->h.cl != 0xff) { 50931168Sminshall } else { 51031168Sminshall switch (regs->h.al) { 51131168Sminshall case READ_OIA_GROUP: 51231168Sminshall read_oia_group(regs, sregs); 51331168Sminshall break; 51431168Sminshall default: 51531168Sminshall unknown_op(regs, sregs); 51631168Sminshall break; 51731168Sminshall } 51831158Sminshall } 51931158Sminshall break; 52031158Sminshall default: 52131168Sminshall regs->h.ch = 0x12; 52231168Sminshall regs->h.cl = 0x34; /* Invalid GATE entry */ 52331158Sminshall break; 52431158Sminshall } 52531158Sminshall } 52631158Sminshall } 527