xref: /csrg-svn/usr.bin/tn3270/ctlr/api.c (revision 31211)
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 
1531158Sminshall /*
1631193Sminshall  * General utility routines.
1731193Sminshall  */
1831193Sminshall 
1931193Sminshall #if	defined(MSDOS)
2031193Sminshall 
21*31211Sminshall #if	defined(LINT_ARGS)
22*31211Sminshall static void movetous(char *, int, int, int);
23*31211Sminshall static void movetothem(int, int, char *, int);
24*31211Sminshall #endif	/* defined(LINT_ARGS) */
25*31211Sminshall 
2631193Sminshall static void
2731193Sminshall movetous(parms, es, di, length)
2831193Sminshall char *parms;
29*31211Sminshall int es, di, length;
3031193Sminshall {
31*31211Sminshall     char far *farparms = parms;
3231193Sminshall 
33*31211Sminshall     movedata(es, di, (int) FP_SEG(farparms), (int) FP_OFF(farparms), length);
3431193Sminshall }
3531193Sminshall 
3631193Sminshall static void
37*31211Sminshall movetothem(es, di, parms, length)
38*31211Sminshall int es, di;
39*31211Sminshall char *parms;
40*31211Sminshall int length;
4131193Sminshall {
42*31211Sminshall     char far *farparms = parms;
4331193Sminshall 
44*31211Sminshall     movedata((int) FP_SEG(farparms), (int) FP_OFF(farparms), es, di, length);
4531193Sminshall }
4631193Sminshall #endif	/* defined(MSDOS) */
4731193Sminshall 
4831193Sminshall /* No Unix version yet... */
4931193Sminshall 
5031193Sminshall 
5131193Sminshall /*
5231158Sminshall  * Supervisor Services.
5331158Sminshall  */
5431158Sminshall 
5531158Sminshall static void
5631193Sminshall name_resolution(regs, sregs)
5731158Sminshall union REGS *regs;
5831158Sminshall struct SREGS *sregs;
5931158Sminshall {
6031167Sminshall     NameResolveParms parms;
6131161Sminshall 
6231167Sminshall     movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms);
6331161Sminshall 
6431161Sminshall     regs->h.cl = 0;
6531193Sminshall     if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) {
6631161Sminshall 	regs->x.dx = GATE_SESSMGR;
6731193Sminshall     } else if (memcmp((char *)&parms, NAME_KEYBOARD,
6831193Sminshall 					sizeof parms.gate_name) == 0) {
6931161Sminshall 	regs->x.dx = GATE_KEYBOARD;
7031193Sminshall     } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) {
7131161Sminshall 	regs->x.dx = GATE_COPY;
7231193Sminshall     } else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) {
7331161Sminshall 	regs->x.dx = GATE_OIAM;
7431161Sminshall     } else {
7531161Sminshall 	regs->h.cl = 0x2e;	/* Name not found */
7631161Sminshall     }
7731161Sminshall     regs->h.ch = 0x12;
7831161Sminshall     regs->h.bh = 7;
7931158Sminshall }
8031158Sminshall 
8131158Sminshall /*
8231158Sminshall  * Session Information Services.
8331158Sminshall  */
8431158Sminshall 
8531158Sminshall static void
8631158Sminshall query_session_id(regs, sregs)
8731158Sminshall union REGS *regs;
8831158Sminshall struct SREGS *sregs;
8931158Sminshall {
9031167Sminshall     QuerySessionIdParms parms;
9131161Sminshall 
9231167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
9331161Sminshall 
94*31211Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
95*31211Sminshall 	parms.rc = 0x0c;
96*31211Sminshall     } else if (parms.option_code != 0x01) {
97*31211Sminshall 	parms.rc = 0x0d;	/* Invalid option code */
9831167Sminshall     } else if (parms.data_code != 0x45) {
99*31211Sminshall 	parms.rc = 0x0b;
10031161Sminshall     } else {
10131168Sminshall 	NameArray list;
10231167Sminshall 	NameArrayElement element;
10331167Sminshall 
10431167Sminshall 	movetous((char *)&list, FP_SEG(parms.name_array),
10531193Sminshall 			    FP_OFF(parms.name_array), sizeof list);
10631168Sminshall 	if ((list.length < 14) || (list.length > 170)) {
10731167Sminshall 	    parms.rc = 0x12;
10831161Sminshall 	} else {
10931167Sminshall 	    list.number_matching_session = 1;
11031167Sminshall 	    list.name_array_element.short_name = parms.data_code;
11131167Sminshall 	    list.name_array_element.type = TYPE_DFT;
11231167Sminshall 	    list.name_array_element.session_id = 23;
11331167Sminshall 	    memcpy(list.name_array_element.long_name, "ONLYSESS",
11431167Sminshall 			    sizeof list.name_array_element.long_name);
11531167Sminshall 	    movetothem(FP_SEG(parms.name_array),
11631193Sminshall 		FP_OFF(parms.name_array), (char *)&list, sizeof list);
11731167Sminshall 	    parms.rc = 0;
11831161Sminshall 	}
11931161Sminshall     }
120*31211Sminshall     parms.function_id = 0x6b;
12131167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
12231158Sminshall }
12331158Sminshall 
12431158Sminshall static void
12531158Sminshall query_session_parameters(regs, sregs)
12631158Sminshall union REGS *regs;
12731158Sminshall struct SREGS *sregs;
12831158Sminshall {
12931167Sminshall     QuerySessionParametersParms parms;
13031167Sminshall 
13131167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
13231167Sminshall 
13331168Sminshall     if ((parms.rc !=0) || (parms.function_id != 0)) {
134*31211Sminshall 	parms.rc = 0x0c;
135*31211Sminshall     } else if (parms.session_id != 23) {
136*31211Sminshall 	parms.rc = 0x02;
13731167Sminshall     } else {
138*31211Sminshall 	parms.rc = 0;
13931167Sminshall 	parms.session_type = TYPE_DFT;
14031167Sminshall 	parms.session_characteristics = 0;	/* Neither EAB nor PSS */
14131167Sminshall 	parms.rows = MaxNumberLines;
14231167Sminshall 	parms.columns = MaxNumberColumns;
14331167Sminshall 	parms.presentation_space = 0;
14431167Sminshall     }
145*31211Sminshall     parms.function_id = 0x6b;
14631168Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
14731158Sminshall }
14831158Sminshall 
14931158Sminshall static void
15031158Sminshall query_session_cursor(regs, sregs)
15131158Sminshall union REGS *regs;
15231158Sminshall struct SREGS *sregs;
15331158Sminshall {
15431167Sminshall     QuerySessionCursorParms parms;
15531167Sminshall 
15631167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
15731167Sminshall 
15831167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
15931167Sminshall 	parms.rc = 0x0c;
16031167Sminshall     } else if (parms.session_id != 23) {
16131167Sminshall 	parms.rc = 0x02;
16231167Sminshall     } else {
16331167Sminshall 	parms.rc = 0;
16431167Sminshall 	parms.cursor_type = CURSOR_BLINKING;	/* XXX what is inhibited? */
16531167Sminshall 	parms.row_address = ScreenLine(CursorAddress);
16631167Sminshall 	parms.column_address = ScreenLineOffset(CursorAddress);
16731167Sminshall     }
16831167Sminshall 
169*31211Sminshall     parms.function_id = 0x6b;
170*31211Sminshall     movetothem(sregs->es, regs->x.di, (char *) &parms, sizeof parms);
17131158Sminshall }
17231158Sminshall 
17331158Sminshall /*
17431158Sminshall  * Keyboard Services.
17531158Sminshall  */
17631158Sminshall 
17731158Sminshall 
17831158Sminshall static void
17931158Sminshall connect_to_keyboard(regs, sregs)
18031158Sminshall union REGS *regs;
18131158Sminshall struct SREGS *sregs;
18231158Sminshall {
18331167Sminshall     ConnectToKeyboardParms parms;
18431167Sminshall 
18531183Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
18631167Sminshall 
18731167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
18831167Sminshall 	parms.rc = 0x0c;
18931167Sminshall     } else if (parms.session_id != 23) {
19031167Sminshall 	parms.rc = 0x02;
19131167Sminshall     } else if (parms.intercept_options != 0) {
19231167Sminshall 	parms.rc = 0x01;
19331167Sminshall     } else {
19431167Sminshall 	parms.rc = 0;
19531167Sminshall 	parms.first_connection_identifier = 0;
19631167Sminshall     }
19731167Sminshall     parms.function_id = 0x62;
19831167Sminshall 
19931167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
20031158Sminshall }
20131158Sminshall 
20231158Sminshall static void
20331167Sminshall disconnect_from_keyboard(regs, sregs)
20431158Sminshall union REGS *regs;
20531158Sminshall struct SREGS *sregs;
20631158Sminshall {
20731167Sminshall     DisconnectFromKeyboardParms parms;
20831167Sminshall 
20931167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
21031167Sminshall 
21131167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
21231167Sminshall 	parms.rc = 0x0c;
21331167Sminshall     } else if (parms.session_id != 23) {
21431167Sminshall 	parms.rc = 0x02;
21531167Sminshall     } else if (parms.connectors_task_id != 0) {
21631167Sminshall 	parms.rc = 04;			/* XXX */
21731167Sminshall     } else {
21831167Sminshall 	parms.rc = 0;
21931167Sminshall     }
22031167Sminshall     parms.function_id = 0x62;
22131167Sminshall 
22231167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
22331158Sminshall }
22431158Sminshall 
22531158Sminshall static void
22631158Sminshall write_keystroke(regs, sregs)
22731158Sminshall union REGS *regs;
22831158Sminshall struct SREGS *sregs;
22931158Sminshall {
23031198Sminshall     WriteKeystrokeParms parms;
23131198Sminshall 
23231198Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
23331198Sminshall 
23431198Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
23531198Sminshall 	parms.rc = 0x0c;
23631198Sminshall     } else if (parms.session_id != 23) {
23731198Sminshall 	parms.rc = 0x02;
23831198Sminshall     } else if (parms.connectors_task_id != 0) {
23931198Sminshall 	parms.rc = 0x04;
24031198Sminshall     } else {
24131198Sminshall 	parms.number_of_keys_sent = 0;
24231198Sminshall 	parms.rc = 0;
24331198Sminshall 	if (parms.options == OPTION_SINGLE_KEYSTROKE) {
24431198Sminshall 	    KeystrokeEntry *entry = &parms.keystroke_specifier.keystroke_entry;
24531198Sminshall 
24631198Sminshall 	    if (AcceptKeystroke(entry->scancode, entry->shift_state) == 0) {
24731198Sminshall 		parms.rc = 0x10;		/* XXX needs 0x12 too! */
24831198Sminshall 	    }
24931198Sminshall 	    parms.number_of_keys_sent++;
25031198Sminshall 	} else if (parms.options == OPTION_MULTIPLE_KEYSTROKES) {
25131198Sminshall 	    KeystrokeList
25231198Sminshall 		list,
25331198Sminshall 		far *atlist = parms.keystroke_specifier.keystroke_list;
25431198Sminshall 	    KeystrokeEntry
25531198Sminshall 		entry[10],		/* 10 at a time */
25631198Sminshall 		*ourentry,
25731198Sminshall 		far *theirentry;
25831198Sminshall 	    int
25931198Sminshall 		todo;
26031198Sminshall 
26131198Sminshall 	    movetous((char *)&list, FP_SEG(atlist),
26231198Sminshall 				FP_OFF(atlist), sizeof *atlist);
26331198Sminshall 	    todo = list.length/2;
26431198Sminshall 	    ourentry = entry+(highestof(entry)+1);
26531198Sminshall 
26631198Sminshall 	    while (todo) {
26731198Sminshall 		if (ourentry > &entry[highestof(entry)]) {
26831198Sminshall 		    int thistime;
26931198Sminshall 
27031198Sminshall 		    thistime = todo;
27131198Sminshall 		    if (thistime > numberof(entry)) {
27231198Sminshall 			thistime = numberof(entry);
27331198Sminshall 		    }
27431198Sminshall 		    movetous((char *)entry, FP_SEG(theirentry),
27531198Sminshall 			    FP_OFF(theirentry), thistime*sizeof *theirentry);
27631198Sminshall 		    theirentry += thistime;
27731198Sminshall 		    ourentry = entry;
27831198Sminshall 		}
27931198Sminshall 		if (AcceptKeystroke(ourentry->scancode,
28031198Sminshall 						ourentry->shift_state) == 0) {
28131198Sminshall 		    parms.rc = 0x10;		/* XXX needs 0x12 too! */
28231198Sminshall 		    break;
28331198Sminshall 		}
28431198Sminshall 		parms.number_of_keys_sent++;
28531198Sminshall 		ourentry++;
28631198Sminshall 		todo--;
28731198Sminshall 	    }
28831198Sminshall 	} else {
28931198Sminshall 	    parms.rc = 0x01;
29031198Sminshall 	}
29131198Sminshall     }
29231198Sminshall     parms.function_id = 0x62;
29331198Sminshall 
29431198Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
29531167Sminshall /* XXX */
29631158Sminshall }
29731158Sminshall 
29831167Sminshall 
29931158Sminshall static void
30031167Sminshall disable_input(regs, sregs)
30131167Sminshall union REGS *regs;
30231167Sminshall struct SREGS *sregs;
30331167Sminshall {
30431167Sminshall     DisableInputParms parms;
30531167Sminshall 
30631167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
30731167Sminshall 
30831167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
30931167Sminshall 	parms.rc = 0x0c;
31031167Sminshall     } else if (parms.session_id != 23) {
31131167Sminshall 	parms.rc = 0x02;
31231167Sminshall     } else if (parms.connectors_task_id != 0) {
31331167Sminshall 	parms.rc = 0x04;
31431167Sminshall     } else {
315*31211Sminshall 	SetOiaApiInhibit(&OperatorInformationArea);
31631167Sminshall 	parms.rc = 0;
31731167Sminshall     }
31831167Sminshall     parms.function_id = 0x62;
31931167Sminshall 
32031167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
32131167Sminshall }
32231167Sminshall 
32331167Sminshall static void
32431158Sminshall enable_input(regs, sregs)
32531158Sminshall union REGS *regs;
32631158Sminshall struct SREGS *sregs;
32731158Sminshall {
32831167Sminshall     EnableInputParms parms;
32931167Sminshall 
33031167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
33131167Sminshall 
33231167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
33331167Sminshall 	parms.rc = 0x0c;
33431167Sminshall     } else if (parms.session_id != 23) {
33531167Sminshall 	parms.rc = 0x02;
33631167Sminshall     } else if (parms.connectors_task_id != 0) {
33731167Sminshall 	parms.rc = 0x04;
33831167Sminshall     } else {
339*31211Sminshall 	ResetOiaApiInhibit(&OperatorInformationArea);
34031167Sminshall 	parms.rc = 0;
34131167Sminshall     }
34231167Sminshall     parms.function_id = 0x62;
34331167Sminshall 
34431167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
34531158Sminshall }
34631158Sminshall 
34731158Sminshall /*
34831158Sminshall  * Copy Services.
34931158Sminshall  */
35031158Sminshall 
35131158Sminshall static void
35231167Sminshall copy_string(regs, sregs)
35331158Sminshall union REGS *regs;
35431158Sminshall struct SREGS *sregs;
35531158Sminshall {
35631167Sminshall     CopyStringParms parms;
35731167Sminshall     BufferDescriptor *target, *source;
35831167Sminshall 
35931167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
36031167Sminshall 
36131167Sminshall     if ((parms.rc != 0) || (parms.function_id !=0)) {
36231167Sminshall 	parms.rc = 0x0c;
36331167Sminshall     }
36431167Sminshall     /* XXX do something! */
36531183Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
36631158Sminshall }
36731158Sminshall /*
36831158Sminshall  * Operator Information Area Services.
36931158Sminshall  */
37031158Sminshall 
37131158Sminshall static void
37231158Sminshall read_oia_group(regs, sregs)
37331158Sminshall union REGS *regs;
37431158Sminshall struct SREGS *sregs;
37531158Sminshall {
37631167Sminshall     ReadOiaGroupParms parms;
37731167Sminshall 
37831167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
37931167Sminshall 
38031167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
38131167Sminshall 	parms.rc = 0x0c;
38231167Sminshall     } else if (parms.session_id != 23) {
38331167Sminshall 	parms.rc = 0x02;
38431167Sminshall     } else {
38531167Sminshall 	int group = parms.oia_group_number;
38631193Sminshall 	char *from;
38731193Sminshall 	int size;
38831167Sminshall 
389*31211Sminshall 	if ((group != API_OIA_ALL_GROUPS) &&
390*31211Sminshall 		((group > API_OIA_LAST_LEGAL_GROUP) || (group < 0))) {
39131193Sminshall 	} else {
39231193Sminshall 	    if (group == API_OIA_ALL_GROUPS) {
39331193Sminshall 		size = API_OIA_BYTES_ALL_GROUPS;
39431193Sminshall 		from = (char *)&OperatorInformationArea;
39531193Sminshall 	    } else if (group == API_OIA_INPUT_INHIBITED) {
39631193Sminshall 		size = sizeof OperatorInformationArea.input_inhibited;
39731193Sminshall 		from = (char *)&OperatorInformationArea.input_inhibited[0];
39831193Sminshall 	    } else {
39931193Sminshall 		size = 1;
40031193Sminshall 		from = ((char *)&OperatorInformationArea)+group;
40131193Sminshall 	    }
40231193Sminshall 	    movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer),
40331193Sminshall 			from, size);
40431168Sminshall 	}
40531167Sminshall     }
40631168Sminshall     parms.function_id = 0x6d;
40731167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
40831158Sminshall }
40931158Sminshall 
41031158Sminshall static void
41131158Sminshall unknown_op(regs, sregs)
41231158Sminshall union REGS *regs;
41331158Sminshall struct SREGS *sregs;
41431158Sminshall {
41531158Sminshall     regs->h.ch = 0x12;
41631158Sminshall     regs->h.cl = 0x05;
41731158Sminshall }
41831158Sminshall 
41931158Sminshall 
42031158Sminshall handle_api(regs, sregs)
42131158Sminshall union REGS *regs;
42231158Sminshall struct SREGS *sregs;
42331158Sminshall {
42431158Sminshall     if (regs->h.ah == NAME_RESOLUTION) {
42531158Sminshall 	name_resolution(regs, sregs);
42631168Sminshall     } else if (regs->h.ah != 0x09) {
42731168Sminshall 	regs->h.ch = 0x12;
42831168Sminshall 	regs->h.cl = 0x0f;		/* XXX Invalid environmental access */
42931168Sminshall     } else if (regs->x.bx != 0x8020) {
43031168Sminshall 	regs->h.ch = 0x12;
43131168Sminshall 	regs->h.cl = 0x08;		/* XXX Invalid wait specified */
43231168Sminshall     } else if (regs->h.ch != 0) {
433*31211Sminshall 	regs->x.cx = 0x1206;		/* XXX Invalid priority */
43431158Sminshall     } else {
43531158Sminshall 	switch (regs->x.dx) {
43631158Sminshall 	case GATE_SESSMGR:
43731158Sminshall 	    switch (regs->h.al) {
43831158Sminshall 	    case QUERY_SESSION_ID:
43931168Sminshall 		if (regs->h.cl != 0) {
440*31211Sminshall 		    regs->x.cx = 0x1206;
44131168Sminshall 		} else {
442*31211Sminshall 		    regs->x.cx = 0x1200;
44331168Sminshall 		    query_session_id(regs, sregs);
44431168Sminshall 		}
44531158Sminshall 		break;
446*31211Sminshall 	    case QUERY_SESSION_PARAMETERS:
44731168Sminshall 		if (regs->h.cl != 0) {
448*31211Sminshall 		    regs->x.cx = 0x1206;
44931168Sminshall 		} else {
450*31211Sminshall 		    regs->x.cx = 0x1200;
45131193Sminshall 		    query_session_parameters(regs, sregs);
45231168Sminshall 		}
45331158Sminshall 		break;
45431158Sminshall 	    case QUERY_SESSION_CURSOR:
45531168Sminshall 		if (regs->h.cl != 0xff) {
456*31211Sminshall 		    regs->x.cx = 0x1206;
45731168Sminshall 		} else {
458*31211Sminshall 		    regs->x.cx = 0x1200;
45931168Sminshall 		    query_session_cursor(regs, sregs);
46031168Sminshall 		}
46131158Sminshall 		break;
46231158Sminshall 	    default:
46331158Sminshall 		unknown_op(regs, sregs);
46431158Sminshall 		break;
46531158Sminshall 	    }
46631158Sminshall 	    break;
46731158Sminshall 	case GATE_KEYBOARD:
46831168Sminshall 	    if (regs->h.cl != 00) {
469*31211Sminshall 		regs->x.cx = 0x1206;
47031168Sminshall 	    } else {
471*31211Sminshall 		regs->x.cx = 0x1200;
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) {
496*31211Sminshall 		regs->x.cx = 0x1206;
49731168Sminshall 	    } else {
498*31211Sminshall 		regs->x.cx = 0x1200;
49931168Sminshall 		switch (regs->h.al) {
50031168Sminshall 		case COPY_STRING:
50131168Sminshall 		    copy_string(regs, sregs);
50231168Sminshall 		    break;
50331168Sminshall 		default:
50431168Sminshall 		    unknown_op(regs, sregs);
50531168Sminshall 		    break;
50631168Sminshall 		}
50731158Sminshall 	    }
50831158Sminshall 	    break;
50931158Sminshall 	case GATE_OIAM:
51031168Sminshall 	    if (regs->h.cl != 0xff) {
511*31211Sminshall 		regs->x.cx = 0x1206;
51231168Sminshall 	    } else {
513*31211Sminshall 		regs->x.cx = 0x1200;
51431168Sminshall 		switch (regs->h.al) {
51531168Sminshall 		case READ_OIA_GROUP:
51631168Sminshall 		    read_oia_group(regs, sregs);
51731168Sminshall 		    break;
51831168Sminshall 		default:
51931168Sminshall 		    unknown_op(regs, sregs);
52031168Sminshall 		    break;
52131168Sminshall 		}
52231158Sminshall 	    }
52331158Sminshall 	    break;
52431158Sminshall 	default:
52531168Sminshall 	    regs->h.ch = 0x12;
52631168Sminshall 	    regs->h.cl = 0x34;		/* Invalid GATE entry */
52731158Sminshall 	    break;
52831158Sminshall 	}
52931158Sminshall     }
53031158Sminshall }
531