xref: /csrg-svn/usr.bin/tn3270/ctlr/api.c (revision 31193)
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