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