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" 11*31193Sminshall #include "../ctlr/oia.h" 12*31193Sminshall 1331183Sminshall #include "../general/globals.h" 1431158Sminshall 1531168Sminshall int ApiDisableInput = 0; 1631168Sminshall 1731158Sminshall /* 18*31193Sminshall * General utility routines. 19*31193Sminshall */ 20*31193Sminshall 21*31193Sminshall #if defined(MSDOS) 22*31193Sminshall static int ourds = 0; /* Safe */ 23*31193Sminshall 24*31193Sminshall static void 25*31193Sminshall movetous(parms, es, di, length) 26*31193Sminshall char *parms; 27*31193Sminshall { 28*31193Sminshall if (ourds == 0) { 29*31193Sminshall struct SREGS sregs; 30*31193Sminshall 31*31193Sminshall segread(&sregs); 32*31193Sminshall ourds = sregs.ds; 33*31193Sminshall } 34*31193Sminshall movedata(es, di, ourds, (int)parms, length); 35*31193Sminshall } 36*31193Sminshall 37*31193Sminshall static void 38*31193Sminshall movetothem(parms, es, di, length) 39*31193Sminshall { 40*31193Sminshall if (ourds == 0) { 41*31193Sminshall struct SREGS sregs; 42*31193Sminshall 43*31193Sminshall segread(&sregs); 44*31193Sminshall ourds = sregs.es; 45*31193Sminshall } 46*31193Sminshall movedata(ourds, (int)parms, es, di, length); 47*31193Sminshall } 48*31193Sminshall #endif /* defined(MSDOS) */ 49*31193Sminshall 50*31193Sminshall /* No Unix version yet... */ 51*31193Sminshall 52*31193Sminshall 53*31193Sminshall /* 5431158Sminshall * Supervisor Services. 5531158Sminshall */ 5631158Sminshall 5731158Sminshall static void 58*31193Sminshall 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; 67*31193Sminshall if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) { 6831161Sminshall regs->x.dx = GATE_SESSMGR; 69*31193Sminshall } else if (memcmp((char *)&parms, NAME_KEYBOARD, 70*31193Sminshall sizeof parms.gate_name) == 0) { 7131161Sminshall regs->x.dx = GATE_KEYBOARD; 72*31193Sminshall } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) { 7331161Sminshall regs->x.dx = GATE_COPY; 74*31193Sminshall } 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), 109*31193Sminshall 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), 121*31193Sminshall 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 { 23831167Sminshall /* XXX */ 23931158Sminshall } 24031158Sminshall 24131167Sminshall 24231158Sminshall static void 24331167Sminshall disable_input(regs, sregs) 24431167Sminshall union REGS *regs; 24531167Sminshall struct SREGS *sregs; 24631167Sminshall { 24731167Sminshall DisableInputParms parms; 24831167Sminshall 24931167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 25031167Sminshall 25131167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 25231167Sminshall parms.rc = 0x0c; 25331167Sminshall } else if (parms.session_id != 23) { 25431167Sminshall parms.rc = 0x02; 25531167Sminshall } else if (parms.connectors_task_id != 0) { 25631167Sminshall parms.rc = 0x04; 25731167Sminshall } else { 25831167Sminshall ApiDisableInput = 1; 25931167Sminshall parms.rc = 0; 26031167Sminshall } 26131167Sminshall parms.function_id = 0x62; 26231167Sminshall 26331167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 26431167Sminshall } 26531167Sminshall 26631167Sminshall static void 26731158Sminshall enable_input(regs, sregs) 26831158Sminshall union REGS *regs; 26931158Sminshall struct SREGS *sregs; 27031158Sminshall { 27131167Sminshall EnableInputParms parms; 27231167Sminshall 27331167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 27431167Sminshall 27531167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 27631167Sminshall parms.rc = 0x0c; 27731167Sminshall } else if (parms.session_id != 23) { 27831167Sminshall parms.rc = 0x02; 27931167Sminshall } else if (parms.connectors_task_id != 0) { 28031167Sminshall parms.rc = 0x04; 28131167Sminshall } else { 28231167Sminshall ApiDisableInput = 0; 28331167Sminshall parms.rc = 0; 28431167Sminshall } 28531167Sminshall parms.function_id = 0x62; 28631167Sminshall 28731167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 28831158Sminshall } 28931158Sminshall 29031158Sminshall /* 29131158Sminshall * Copy Services. 29231158Sminshall */ 29331158Sminshall 29431158Sminshall static void 29531167Sminshall copy_string(regs, sregs) 29631158Sminshall union REGS *regs; 29731158Sminshall struct SREGS *sregs; 29831158Sminshall { 29931167Sminshall CopyStringParms parms; 30031167Sminshall BufferDescriptor *target, *source; 30131167Sminshall 30231167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 30331167Sminshall 30431167Sminshall if ((parms.rc != 0) || (parms.function_id !=0)) { 30531167Sminshall parms.rc = 0x0c; 30631167Sminshall } 30731167Sminshall /* XXX do something! */ 30831183Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 30931158Sminshall } 31031158Sminshall /* 31131158Sminshall * Operator Information Area Services. 31231158Sminshall */ 31331158Sminshall 31431158Sminshall static void 31531158Sminshall read_oia_group(regs, sregs) 31631158Sminshall union REGS *regs; 31731158Sminshall struct SREGS *sregs; 31831158Sminshall { 31931167Sminshall ReadOiaGroupParms parms; 32031167Sminshall 32131167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 32231167Sminshall 32331167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 32431167Sminshall parms.rc = 0x0c; 32531167Sminshall } else if (parms.session_id != 23) { 32631167Sminshall parms.rc = 0x02; 32731167Sminshall } else { 32831167Sminshall int group = parms.oia_group_number; 329*31193Sminshall char *from; 330*31193Sminshall int size; 33131167Sminshall 332*31193Sminshall if (group > API_OIA_LAST_LEGAL_GROUP) { 333*31193Sminshall } else { 334*31193Sminshall if (group == API_OIA_ALL_GROUPS) { 335*31193Sminshall size = API_OIA_BYTES_ALL_GROUPS; 336*31193Sminshall from = (char *)&OperatorInformationArea; 337*31193Sminshall } else if (group == API_OIA_INPUT_INHIBITED) { 338*31193Sminshall size = sizeof OperatorInformationArea.input_inhibited; 339*31193Sminshall from = (char *)&OperatorInformationArea.input_inhibited[0]; 340*31193Sminshall } else { 341*31193Sminshall size = 1; 342*31193Sminshall from = ((char *)&OperatorInformationArea)+group; 343*31193Sminshall } 344*31193Sminshall movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer), 345*31193Sminshall from, size); 34631168Sminshall } 34731167Sminshall } 34831168Sminshall parms.function_id = 0x6d; 34931167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 35031158Sminshall } 35131158Sminshall 35231158Sminshall static void 35331158Sminshall unknown_op(regs, sregs) 35431158Sminshall union REGS *regs; 35531158Sminshall struct SREGS *sregs; 35631158Sminshall { 35731158Sminshall regs->h.ch = 0x12; 35831158Sminshall regs->h.cl = 0x05; 35931158Sminshall } 36031158Sminshall 36131158Sminshall 36231158Sminshall handle_api(regs, sregs) 36331158Sminshall union REGS *regs; 36431158Sminshall struct SREGS *sregs; 36531158Sminshall { 36631158Sminshall if (regs->h.ah == NAME_RESOLUTION) { 36731158Sminshall name_resolution(regs, sregs); 36831168Sminshall } else if (regs->h.ah != 0x09) { 36931168Sminshall regs->h.ch = 0x12; 37031168Sminshall regs->h.cl = 0x0f; /* XXX Invalid environmental access */ 37131168Sminshall } else if (regs->x.bx != 0x8020) { 37231168Sminshall regs->h.ch = 0x12; 37331168Sminshall regs->h.cl = 0x08; /* XXX Invalid wait specified */ 37431168Sminshall } else if (regs->h.ch != 0) { 37531168Sminshall regs->h.ch = 0x12; 37631168Sminshall regs->h.cl = 0x07; /* XXX Invalid reply specified */ 37731158Sminshall } else { 37831158Sminshall switch (regs->x.dx) { 37931158Sminshall case GATE_SESSMGR: 38031158Sminshall switch (regs->h.al) { 38131158Sminshall case QUERY_SESSION_ID: 38231168Sminshall if (regs->h.cl != 0) { 38331168Sminshall } else { 38431168Sminshall query_session_id(regs, sregs); 38531168Sminshall } 38631158Sminshall break; 38731158Sminshall case QUERY_SESSION_PARMS: 38831168Sminshall if (regs->h.cl != 0) { 38931168Sminshall } else { 390*31193Sminshall query_session_parameters(regs, sregs); 39131168Sminshall } 39231158Sminshall break; 39331158Sminshall case QUERY_SESSION_CURSOR: 39431168Sminshall if (regs->h.cl != 0xff) { 39531168Sminshall } else { 39631168Sminshall query_session_cursor(regs, sregs); 39731168Sminshall } 39831158Sminshall break; 39931158Sminshall default: 40031158Sminshall unknown_op(regs, sregs); 40131158Sminshall break; 40231158Sminshall } 40331158Sminshall break; 40431158Sminshall case GATE_KEYBOARD: 40531168Sminshall if (regs->h.cl != 00) { 40631168Sminshall } else { 40731168Sminshall switch (regs->h.al) { 40831168Sminshall case CONNECT_TO_KEYBOARD: 40931168Sminshall connect_to_keyboard(regs, sregs); 41031168Sminshall break; 41131168Sminshall case DISABLE_INPUT: 41231168Sminshall disable_input(regs, sregs); 41331168Sminshall break; 41431168Sminshall case WRITE_KEYSTROKE: 41531168Sminshall write_keystroke(regs, sregs); 41631168Sminshall break; 41731168Sminshall case ENABLE_INPUT: 41831168Sminshall enable_input(regs, sregs); 41931168Sminshall break; 42031168Sminshall case DISCONNECT_FROM_KEYBOARD: 42131168Sminshall disconnect_from_keyboard(regs, sregs); 42231168Sminshall break; 42331168Sminshall default: 42431168Sminshall unknown_op(regs, sregs); 42531168Sminshall break; 42631168Sminshall } 42731158Sminshall } 42831158Sminshall break; 42931158Sminshall case GATE_COPY: 43031168Sminshall if (regs->h.cl != 0xff) { 43131168Sminshall } else { 43231168Sminshall switch (regs->h.al) { 43331168Sminshall case COPY_STRING: 43431168Sminshall copy_string(regs, sregs); 43531168Sminshall break; 43631168Sminshall default: 43731168Sminshall unknown_op(regs, sregs); 43831168Sminshall break; 43931168Sminshall } 44031158Sminshall } 44131158Sminshall break; 44231158Sminshall case GATE_OIAM: 44331168Sminshall if (regs->h.cl != 0xff) { 44431168Sminshall } else { 44531168Sminshall switch (regs->h.al) { 44631168Sminshall case READ_OIA_GROUP: 44731168Sminshall read_oia_group(regs, sregs); 44831168Sminshall break; 44931168Sminshall default: 45031168Sminshall unknown_op(regs, sregs); 45131168Sminshall break; 45231168Sminshall } 45331158Sminshall } 45431158Sminshall break; 45531158Sminshall default: 45631168Sminshall regs->h.ch = 0x12; 45731168Sminshall regs->h.cl = 0x34; /* Invalid GATE entry */ 45831158Sminshall break; 45931158Sminshall } 46031158Sminshall } 46131158Sminshall } 462