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