|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that this notice is preserved and that due credit is given ! 7: * to the University of California at Berkeley. The name of the University ! 8: * may not be used to endorse or promote products derived from this ! 9: * software without specific prior written permission. This software ! 10: * is provided ``as is'' without express or implied warranty. ! 11: */ ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)api.c 3.2 (Berkeley) 3/28/88"; ! 15: #endif /* not lint */ ! 16: ! 17: /* ! 18: * This file implements the API used in the PC version. ! 19: */ ! 20: ! 21: #include <stdio.h> ! 22: ! 23: #include "api.h" ! 24: #include "../general/general.h" ! 25: ! 26: #include "../api/disp_asc.h" ! 27: ! 28: #include "screen.h" ! 29: #include "oia.h" ! 30: ! 31: #include "../general/globals.h" ! 32: ! 33: /* ! 34: * General utility routines. ! 35: */ ! 36: ! 37: #if defined(MSDOS) ! 38: ! 39: #if defined(LINT_ARGS) ! 40: static void movetous(char *, int, int, int); ! 41: static void movetothem(int, int, char *, int); ! 42: #endif /* defined(LINT_ARGS) */ ! 43: ! 44: #define access_api(foo,length,copyin) (foo) ! 45: #define unaccess_api(foo,goo,length,copyout) ! 46: ! 47: static void ! 48: movetous(parms, es, di, length) ! 49: char *parms; ! 50: int es, di, length; ! 51: { ! 52: char far *farparms = parms; ! 53: ! 54: movedata(es, di, (int) FP_SEG(farparms), (int) FP_OFF(farparms), length); ! 55: } ! 56: ! 57: static void ! 58: movetothem(es, di, parms, length) ! 59: int es, di; ! 60: char *parms; ! 61: int length; ! 62: { ! 63: char far *farparms = parms; ! 64: ! 65: movedata((int) FP_SEG(farparms), (int) FP_OFF(farparms), es, di, length); ! 66: } ! 67: #endif /* defined(MSDOS) */ ! 68: ! 69: #if defined(unix) ! 70: extern char *access_api(), *unaccess_api(); ! 71: #endif /* defined(unix) */ ! 72: ! 73: ! 74: /* ! 75: * Supervisor Services. ! 76: */ ! 77: ! 78: static void ! 79: name_resolution(regs, sregs) ! 80: union REGS *regs; ! 81: struct SREGS *sregs; ! 82: { ! 83: NameResolveParms parms; ! 84: ! 85: movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms); ! 86: ! 87: regs->h.cl = 0; ! 88: if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) { ! 89: regs->x.dx = GATE_SESSMGR; ! 90: } else if (memcmp((char *)&parms, NAME_KEYBOARD, ! 91: sizeof parms.gate_name) == 0) { ! 92: regs->x.dx = GATE_KEYBOARD; ! 93: } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) { ! 94: regs->x.dx = GATE_COPY; ! 95: } else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) { ! 96: regs->x.dx = GATE_OIAM; ! 97: } else { ! 98: regs->h.cl = 0x2e; /* Name not found */ ! 99: } ! 100: regs->h.ch = 0x12; ! 101: regs->h.bh = 7; ! 102: } ! 103: ! 104: /* ! 105: * Session Information Services. ! 106: */ ! 107: ! 108: static void ! 109: query_session_id(regs, sregs) ! 110: union REGS *regs; ! 111: struct SREGS *sregs; ! 112: { ! 113: QuerySessionIdParms parms; ! 114: ! 115: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 116: ! 117: if ((parms.rc != 0) || (parms.function_id != 0)) { ! 118: parms.rc = 0x0c; ! 119: } else if (parms.option_code != 0x01) { ! 120: parms.rc = 0x0d; /* Invalid option code */ ! 121: } else if (parms.data_code != 0x45) { ! 122: parms.rc = 0x0b; ! 123: } else { ! 124: NameArray list; ! 125: NameArrayElement element; ! 126: ! 127: movetous((char *)&list, FP_SEG(parms.name_array), ! 128: FP_OFF(parms.name_array), sizeof list); ! 129: if ((list.length < 14) || (list.length > 170)) { ! 130: parms.rc = 0x12; ! 131: } else { ! 132: list.number_matching_session = 1; ! 133: list.name_array_element.short_name = parms.data_code; ! 134: list.name_array_element.type = TYPE_DFT; ! 135: list.name_array_element.session_id = 23; ! 136: memcpy(list.name_array_element.long_name, "ONLYSESS", ! 137: sizeof list.name_array_element.long_name); ! 138: movetothem(FP_SEG(parms.name_array), ! 139: FP_OFF(parms.name_array), (char *)&list, sizeof list); ! 140: parms.rc = 0; ! 141: } ! 142: } ! 143: parms.function_id = 0x6b; ! 144: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 145: } ! 146: ! 147: static void ! 148: query_session_parameters(regs, sregs) ! 149: union REGS *regs; ! 150: struct SREGS *sregs; ! 151: { ! 152: QuerySessionParametersParms parms; ! 153: ! 154: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 155: ! 156: if ((parms.rc !=0) || (parms.function_id != 0)) { ! 157: parms.rc = 0x0c; ! 158: } else if (parms.session_id != 23) { ! 159: parms.rc = 0x02; ! 160: } else { ! 161: parms.rc = 0; ! 162: parms.session_type = TYPE_DFT; ! 163: parms.session_characteristics = 0; /* Neither EAB nor PSS */ ! 164: parms.rows = MaxNumberLines; ! 165: parms.columns = MaxNumberColumns; ! 166: parms.presentation_space = 0; ! 167: } ! 168: parms.function_id = 0x6b; ! 169: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 170: } ! 171: ! 172: static void ! 173: query_session_cursor(regs, sregs) ! 174: union REGS *regs; ! 175: struct SREGS *sregs; ! 176: { ! 177: QuerySessionCursorParms parms; ! 178: ! 179: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 180: ! 181: if ((parms.rc != 0) || (parms.function_id != 0)) { ! 182: parms.rc = 0x0c; ! 183: } else if (parms.session_id != 23) { ! 184: parms.rc = 0x02; ! 185: } else { ! 186: parms.rc = 0; ! 187: parms.cursor_type = CURSOR_BLINKING; /* XXX what is inhibited? */ ! 188: parms.row_address = ScreenLine(CursorAddress); ! 189: parms.column_address = ScreenLineOffset(CursorAddress); ! 190: } ! 191: ! 192: parms.function_id = 0x6b; ! 193: movetothem(sregs->es, regs->x.di, (char *) &parms, sizeof parms); ! 194: } ! 195: ! 196: /* ! 197: * Keyboard Services. ! 198: */ ! 199: ! 200: ! 201: static void ! 202: connect_to_keyboard(regs, sregs) ! 203: union REGS *regs; ! 204: struct SREGS *sregs; ! 205: { ! 206: ConnectToKeyboardParms parms; ! 207: ! 208: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 209: ! 210: if ((parms.rc != 0) || (parms.function_id != 0)) { ! 211: parms.rc = 0x0c; ! 212: } else if (parms.session_id != 23) { ! 213: parms.rc = 0x02; ! 214: } else if (parms.intercept_options != 0) { ! 215: parms.rc = 0x01; ! 216: } else { ! 217: parms.rc = 0; ! 218: parms.first_connection_identifier = 0; ! 219: } ! 220: parms.function_id = 0x62; ! 221: ! 222: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 223: } ! 224: ! 225: static void ! 226: disconnect_from_keyboard(regs, sregs) ! 227: union REGS *regs; ! 228: struct SREGS *sregs; ! 229: { ! 230: DisconnectFromKeyboardParms parms; ! 231: ! 232: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 233: ! 234: if ((parms.rc != 0) || (parms.function_id != 0)) { ! 235: parms.rc = 0x0c; ! 236: } else if (parms.session_id != 23) { ! 237: parms.rc = 0x02; ! 238: } else if (parms.connectors_task_id != 0) { ! 239: parms.rc = 04; /* XXX */ ! 240: } else { ! 241: parms.rc = 0; ! 242: } ! 243: parms.function_id = 0x62; ! 244: ! 245: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 246: } ! 247: ! 248: static void ! 249: write_keystroke(regs, sregs) ! 250: union REGS *regs; ! 251: struct SREGS *sregs; ! 252: { ! 253: WriteKeystrokeParms parms; ! 254: ! 255: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 256: ! 257: if ((parms.rc != 0) || (parms.function_id != 0)) { ! 258: parms.rc = 0x0c; ! 259: } else if (parms.session_id != 23) { ! 260: parms.rc = 0x02; ! 261: } else if (parms.connectors_task_id != 0) { ! 262: parms.rc = 0x04; ! 263: } else { ! 264: parms.number_of_keys_sent = 0; ! 265: parms.rc = 0; ! 266: if (parms.options == OPTION_SINGLE_KEYSTROKE) { ! 267: KeystrokeEntry *entry = &parms.keystroke_specifier.keystroke_entry; ! 268: ! 269: if (AcceptKeystroke(entry->scancode, entry->shift_state) == 0) { ! 270: parms.rc = 0x10; /* XXX needs 0x12 too! */ ! 271: } ! 272: parms.number_of_keys_sent++; ! 273: } else if (parms.options == OPTION_MULTIPLE_KEYSTROKES) { ! 274: KeystrokeList ! 275: list, ! 276: far *atlist = parms.keystroke_specifier.keystroke_list; ! 277: KeystrokeEntry ! 278: entry[10], /* 10 at a time */ ! 279: *ourentry, ! 280: far *theirentry; ! 281: int ! 282: todo; ! 283: ! 284: movetous((char *)&list, FP_SEG(atlist), ! 285: FP_OFF(atlist), sizeof *atlist); ! 286: todo = list.length/2; ! 287: ourentry = entry+(highestof(entry)+1); ! 288: ! 289: while (todo) { ! 290: if (ourentry > &entry[highestof(entry)]) { ! 291: int thistime; ! 292: ! 293: thistime = todo; ! 294: if (thistime > numberof(entry)) { ! 295: thistime = numberof(entry); ! 296: } ! 297: movetous((char *)entry, FP_SEG(theirentry), ! 298: FP_OFF(theirentry), thistime*sizeof *theirentry); ! 299: theirentry += thistime; ! 300: ourentry = entry; ! 301: } ! 302: if (AcceptKeystroke(ourentry->scancode, ! 303: ourentry->shift_state) == 0) { ! 304: parms.rc = 0x10; /* XXX needs 0x12 too! */ ! 305: break; ! 306: } ! 307: parms.number_of_keys_sent++; ! 308: ourentry++; ! 309: todo--; ! 310: } ! 311: } else { ! 312: parms.rc = 0x01; ! 313: } ! 314: } ! 315: parms.function_id = 0x62; ! 316: ! 317: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 318: /* XXX */ ! 319: } ! 320: ! 321: ! 322: static void ! 323: disable_input(regs, sregs) ! 324: union REGS *regs; ! 325: struct SREGS *sregs; ! 326: { ! 327: DisableInputParms parms; ! 328: ! 329: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 330: ! 331: if ((parms.rc != 0) || (parms.function_id != 0)) { ! 332: parms.rc = 0x0c; ! 333: } else if (parms.session_id != 23) { ! 334: parms.rc = 0x02; ! 335: } else if (parms.connectors_task_id != 0) { ! 336: parms.rc = 0x04; ! 337: } else { ! 338: SetOiaApiInhibit(&OperatorInformationArea); ! 339: parms.rc = 0; ! 340: } ! 341: parms.function_id = 0x62; ! 342: ! 343: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 344: } ! 345: ! 346: static void ! 347: enable_input(regs, sregs) ! 348: union REGS *regs; ! 349: struct SREGS *sregs; ! 350: { ! 351: EnableInputParms parms; ! 352: ! 353: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 354: ! 355: if ((parms.rc != 0) || (parms.function_id != 0)) { ! 356: parms.rc = 0x0c; ! 357: } else if (parms.session_id != 23) { ! 358: parms.rc = 0x02; ! 359: } else if (parms.connectors_task_id != 0) { ! 360: parms.rc = 0x04; ! 361: } else { ! 362: ResetOiaApiInhibit(&OperatorInformationArea); ! 363: parms.rc = 0; ! 364: } ! 365: parms.function_id = 0x62; ! 366: ! 367: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 368: } ! 369: ! 370: /* ! 371: * Copy Services. ! 372: */ ! 373: ! 374: static ! 375: copy_subroutine(target, source, parms, what_is_user, length) ! 376: BufferDescriptor *target, *source; ! 377: CopyStringParms *parms; ! 378: int what_is_user; ! 379: #define USER_IS_TARGET 0 ! 380: #define USER_IS_SOURCE 1 ! 381: { ! 382: #define TARGET_NO_EAB 1 ! 383: #define SOURCE_NO_EAB 2 ! 384: #define TARGET_PC 4 ! 385: #define SOURCE_PC 8 ! 386: #define NO_FIELD_ATTRIBUTES 16 ! 387: int needtodo = 0; ! 388: int access_length; ! 389: char far *input; ! 390: char far *output; ! 391: char far *access_pointer; ! 392: ! 393: if ((target->characteristics^source->characteristics) ! 394: &CHARACTERISTIC_EAB) { ! 395: if (target->characteristics&CHARACTERISTIC_EAB) { ! 396: needtodo |= TARGET_NO_EAB; /* Need to bump for EAB in target */ ! 397: } else { ! 398: needtodo |= SOURCE_NO_EAB; /* Need to bump for EAB in source */ ! 399: } ! 400: } ! 401: if (target->session_type != source->session_type) { ! 402: if (target->session_type == TYPE_PC) { ! 403: needtodo |= TARGET_PC; /* scan codes to PC */ ! 404: } else { ! 405: needtodo |= SOURCE_PC; /* PC to scan codes */ ! 406: } ! 407: } ! 408: if ((parms->copy_mode©_MODE_FIELD_ATTRIBUTES) == 0) { ! 409: needtodo |= NO_FIELD_ATTRIBUTES; ! 410: } ! 411: access_length = length; ! 412: if (what_is_user == USER_IS_TARGET) { ! 413: if (target->characteristics&CHARACTERISTIC_EAB) { ! 414: access_length *= 2; ! 415: } ! 416: input = (char far *) &Host[source->begin]; ! 417: access_pointer = target->buffer; ! 418: output = access_api(target->buffer, access_length, 0); ! 419: } else { ! 420: if (source->characteristics&CHARACTERISTIC_EAB) { ! 421: access_length *= 2; ! 422: } ! 423: access_pointer = source->buffer; ! 424: input = access_api(source->buffer, access_length, 1); ! 425: output = (char far *) &Host[target->begin]; ! 426: } ! 427: while (length--) { ! 428: if (needtodo&TARGET_PC) { ! 429: *output++ = disp_asc[*input++]; ! 430: } else if (needtodo&SOURCE_PC) { ! 431: *output++ = asc_disp[*input++]; ! 432: } else { ! 433: *output++ = *input++; ! 434: } ! 435: if (needtodo&TARGET_NO_EAB) { ! 436: *input++; ! 437: } else if (needtodo&SOURCE_NO_EAB) { ! 438: *output++ = 0; /* Should figure out good EAB? */ ! 439: } ! 440: } ! 441: if (what_is_user == USER_IS_TARGET) { ! 442: unaccess_api(target->buffer, access_pointer, access_length, 1); ! 443: } else { ! 444: unaccess_api(source->buffer, access_pointer, access_length, 0); ! 445: } ! 446: } ! 447: ! 448: ! 449: static void ! 450: copy_string(regs, sregs) ! 451: union REGS *regs; ! 452: struct SREGS *sregs; ! 453: { ! 454: CopyStringParms parms; ! 455: BufferDescriptor *target = &parms.target, *source = &parms.source; ! 456: int length; ! 457: ! 458: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 459: ! 460: length = 1+parms.source_end-source->begin; ! 461: if ((parms.rc != 0) || (parms.function_id !=0)) { ! 462: parms.rc = 0x0c; ! 463: } else if (target->session_id == 0) { /* Target is buffer */ ! 464: if (source->session_id != 23) { /* A no-no */ ! 465: parms.rc = 0x2; ! 466: } else { ! 467: if ((source->begin < 0) || (source->begin > highestof(Host))) { ! 468: parms.rc = 0x06; /* invalid source definition */ ! 469: } else { ! 470: if ((source->begin+length) > highestof(Host)) { ! 471: length = highestof(Host)-source->begin; ! 472: parms.rc = 0x0f; /* Truncate */ ! 473: } ! 474: if ((source->characteristics == target->characteristics) && ! 475: (source->session_type == target->session_type)) { ! 476: if (source->characteristics&CHARACTERISTIC_EAB) { ! 477: length *= 2; ! 478: } ! 479: movetothem( (int) FP_SEG(target->buffer), ! 480: (int) FP_OFF(target->buffer), ! 481: (char *)&Host[source->begin], length); ! 482: } else { ! 483: copy_subroutine(target, source, &parms, ! 484: USER_IS_TARGET, length); ! 485: } ! 486: } ! 487: } ! 488: } else if (source->session_id != 0) { ! 489: parms.rc = 0xd; ! 490: } else { ! 491: if ((target->begin < 0) || (source->begin > highestof(Host))) { ! 492: parms.rc = 0x07; /* invalid source definition */ ! 493: } else { ! 494: if ((source->begin+length) > highestof(Host)) { ! 495: length = highestof(Host)-source->begin; ! 496: parms.rc = 0x0f; /* Truncate */ ! 497: } ! 498: if ((source->characteristics == target->characteristics) && ! 499: (source->session_type == target->session_type)) { ! 500: if (source->characteristics&CHARACTERISTIC_EAB) { ! 501: length *= 2; ! 502: } ! 503: movetous((char *)&Host[target->begin], ! 504: (int) FP_SEG(source->buffer), ! 505: (int) FP_OFF(source->buffer), length); ! 506: } else { ! 507: copy_subroutine(target, source, &parms, USER_IS_SOURCE, length); ! 508: } ! 509: } ! 510: } ! 511: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 512: } ! 513: /* ! 514: * Operator Information Area Services. ! 515: */ ! 516: ! 517: static void ! 518: read_oia_group(regs, sregs) ! 519: union REGS *regs; ! 520: struct SREGS *sregs; ! 521: { ! 522: ReadOiaGroupParms parms; ! 523: ! 524: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 525: ! 526: if ((parms.rc != 0) || (parms.function_id != 0)) { ! 527: parms.rc = 0x0c; ! 528: } else if (parms.session_id != 23) { ! 529: parms.rc = 0x02; ! 530: } else { ! 531: int group = parms.oia_group_number; ! 532: char *from; ! 533: int size; ! 534: ! 535: if ((group != API_OIA_ALL_GROUPS) && ! 536: ((group > API_OIA_LAST_LEGAL_GROUP) || (group < 0))) { ! 537: } else { ! 538: if (group == API_OIA_ALL_GROUPS) { ! 539: size = API_OIA_BYTES_ALL_GROUPS; ! 540: from = (char *)&OperatorInformationArea; ! 541: } else if (group == API_OIA_INPUT_INHIBITED) { ! 542: size = sizeof OperatorInformationArea.input_inhibited; ! 543: from = (char *)&OperatorInformationArea.input_inhibited[0]; ! 544: } else { ! 545: size = 1; ! 546: from = ((char *)&OperatorInformationArea)+group; ! 547: } ! 548: movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer), ! 549: from, size); ! 550: } ! 551: } ! 552: parms.function_id = 0x6d; ! 553: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 554: } ! 555: ! 556: static void ! 557: unknown_op(regs, sregs) ! 558: union REGS *regs; ! 559: struct SREGS *sregs; ! 560: { ! 561: regs->h.ch = 0x12; ! 562: regs->h.cl = 0x05; ! 563: } ! 564: ! 565: ! 566: handle_api(regs, sregs) ! 567: union REGS *regs; ! 568: struct SREGS *sregs; ! 569: { ! 570: if (regs->h.ah == NAME_RESOLUTION) { ! 571: name_resolution(regs, sregs); ! 572: #if defined(unix) ! 573: } else if (regs->h.ah == PS_OR_OIA_MODIFIED) { ! 574: while ((oia_modified == 0) && (ps_modified == 0)) { ! 575: (void) Scheduler(1); ! 576: } ! 577: oia_modified = ps_modified = 0; ! 578: #endif /* defined(unix) */ ! 579: } else if (regs->h.ah != 0x09) { ! 580: regs->h.ch = 0x12; ! 581: regs->h.cl = 0x0f; /* XXX Invalid environmental access */ ! 582: } else if (regs->x.bx != 0x8020) { ! 583: regs->h.ch = 0x12; ! 584: regs->h.cl = 0x08; /* XXX Invalid wait specified */ ! 585: } else if (regs->h.ch != 0) { ! 586: regs->x.cx = 0x1206; /* XXX Invalid priority */ ! 587: } else { ! 588: switch (regs->x.dx) { ! 589: case GATE_SESSMGR: ! 590: switch (regs->h.al) { ! 591: case QUERY_SESSION_ID: ! 592: if (regs->h.cl != 0) { ! 593: regs->x.cx = 0x1206; ! 594: } else { ! 595: regs->x.cx = 0x1200; ! 596: query_session_id(regs, sregs); ! 597: } ! 598: break; ! 599: case QUERY_SESSION_PARAMETERS: ! 600: if (regs->h.cl != 0) { ! 601: regs->x.cx = 0x1206; ! 602: } else { ! 603: regs->x.cx = 0x1200; ! 604: query_session_parameters(regs, sregs); ! 605: } ! 606: break; ! 607: case QUERY_SESSION_CURSOR: ! 608: if (regs->h.cl != 0xff) { ! 609: regs->x.cx = 0x1206; ! 610: } else { ! 611: regs->x.cx = 0x1200; ! 612: query_session_cursor(regs, sregs); ! 613: } ! 614: break; ! 615: default: ! 616: unknown_op(regs, sregs); ! 617: break; ! 618: } ! 619: break; ! 620: case GATE_KEYBOARD: ! 621: if (regs->h.cl != 00) { ! 622: regs->x.cx = 0x1206; ! 623: } else { ! 624: regs->x.cx = 0x1200; ! 625: switch (regs->h.al) { ! 626: case CONNECT_TO_KEYBOARD: ! 627: connect_to_keyboard(regs, sregs); ! 628: break; ! 629: case DISABLE_INPUT: ! 630: disable_input(regs, sregs); ! 631: break; ! 632: case WRITE_KEYSTROKE: ! 633: write_keystroke(regs, sregs); ! 634: break; ! 635: case ENABLE_INPUT: ! 636: enable_input(regs, sregs); ! 637: break; ! 638: case DISCONNECT_FROM_KEYBOARD: ! 639: disconnect_from_keyboard(regs, sregs); ! 640: break; ! 641: default: ! 642: unknown_op(regs, sregs); ! 643: break; ! 644: } ! 645: } ! 646: break; ! 647: case GATE_COPY: ! 648: if (regs->h.cl != 0xff) { ! 649: regs->x.cx = 0x1206; ! 650: } else { ! 651: regs->x.cx = 0x1200; ! 652: switch (regs->h.al) { ! 653: case COPY_STRING: ! 654: copy_string(regs, sregs); ! 655: break; ! 656: default: ! 657: unknown_op(regs, sregs); ! 658: break; ! 659: } ! 660: } ! 661: break; ! 662: case GATE_OIAM: ! 663: if (regs->h.cl != 0xff) { ! 664: regs->x.cx = 0x1206; ! 665: } else { ! 666: regs->x.cx = 0x1200; ! 667: switch (regs->h.al) { ! 668: case READ_OIA_GROUP: ! 669: read_oia_group(regs, sregs); ! 670: break; ! 671: default: ! 672: unknown_op(regs, sregs); ! 673: break; ! 674: } ! 675: } ! 676: break; ! 677: default: ! 678: regs->h.ch = 0x12; ! 679: regs->h.cl = 0x34; /* Invalid GATE entry */ ! 680: break; ! 681: } ! 682: } ! 683: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.