xref: /csrg-svn/usr.bin/tn3270/ctlr/api.c (revision 31193)
1 /*
2  * This file implements the API used in the PC version.
3  */
4 
5 #include <stdio.h>
6 
7 #include "api.h"
8 #include "../general/general.h"
9 
10 #include "../ctlr/screen.h"
11 #include "../ctlr/oia.h"
12 
13 #include "../general/globals.h"
14 
15 int ApiDisableInput = 0;
16 
17 /*
18  * General utility routines.
19  */
20 
21 #if	defined(MSDOS)
22 static int ourds = 0;		/* Safe */
23 
24 static void
25 movetous(parms, es, di, length)
26 char *parms;
27 {
28     if (ourds == 0) {
29 	struct SREGS sregs;
30 
31 	segread(&sregs);
32 	ourds = sregs.ds;
33     }
34     movedata(es, di, ourds, (int)parms, length);
35 }
36 
37 static void
38 movetothem(parms, es, di, length)
39 {
40     if (ourds == 0) {
41 	struct SREGS sregs;
42 
43 	segread(&sregs);
44 	ourds = sregs.es;
45     }
46     movedata(ourds, (int)parms, es, di, length);
47 }
48 #endif	/* defined(MSDOS) */
49 
50 /* No Unix version yet... */
51 
52 
53 /*
54  * Supervisor Services.
55  */
56 
57 static void
58 name_resolution(regs, sregs)
59 union REGS *regs;
60 struct SREGS *sregs;
61 {
62     NameResolveParms parms;
63 
64     movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms);
65 
66     regs->h.cl = 0;
67     if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) {
68 	regs->x.dx = GATE_SESSMGR;
69     } else if (memcmp((char *)&parms, NAME_KEYBOARD,
70 					sizeof parms.gate_name) == 0) {
71 	regs->x.dx = GATE_KEYBOARD;
72     } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) {
73 	regs->x.dx = GATE_COPY;
74     } else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) {
75 	regs->x.dx = GATE_OIAM;
76     } else {
77 	regs->h.cl = 0x2e;	/* Name not found */
78     }
79     regs->h.ch = 0x12;
80     regs->h.bh = 7;
81 }
82 
83 /*
84  * Session Information Services.
85  */
86 
87 static void
88 query_session_id(regs, sregs)
89 union REGS *regs;
90 struct SREGS *sregs;
91 {
92     QuerySessionIdParms parms;
93 
94     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
95 
96     if (parms.rc != 0) {
97 	regs->h.cl = 0x0c;
98 	return;
99     }
100     if (parms.option_code != 0x01) {
101 	regs->h.cl = 0x0d;	/* Invalid option code */
102     } else if (parms.data_code != 0x45) {
103 	regs->h.cl = 0x0b;
104     } else {
105 	NameArray list;
106 	NameArrayElement element;
107 
108 	movetous((char *)&list, FP_SEG(parms.name_array),
109 			    FP_OFF(parms.name_array), sizeof list);
110 	if ((list.length < 14) || (list.length > 170)) {
111 	    parms.rc = 0x12;
112 	    regs->h.cl = 0x12;
113 	} else {
114 	    list.number_matching_session = 1;
115 	    list.name_array_element.short_name = parms.data_code;
116 	    list.name_array_element.type = TYPE_DFT;
117 	    list.name_array_element.session_id = 23;
118 	    memcpy(list.name_array_element.long_name, "ONLYSESS",
119 			    sizeof list.name_array_element.long_name);
120 	    movetothem(FP_SEG(parms.name_array),
121 		FP_OFF(parms.name_array), (char *)&list, sizeof list);
122 	    parms.rc = 0;
123 	    regs->h.cl = 0;
124 	}
125     }
126     parms.function_id = 0x6d;
127     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
128 }
129 
130 static void
131 query_session_parameters(regs, sregs)
132 union REGS *regs;
133 struct SREGS *sregs;
134 {
135     QuerySessionParametersParms parms;
136 
137     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
138 
139     if ((parms.rc !=0) || (parms.function_id != 0)) {
140 	regs->h.cl = 0x0c;
141 	return;
142     }
143     if (parms.session_id != 23) {
144 	regs->h.cl = parms.rc = 0x02;
145     } else {
146 	regs->h.cl = parms.rc = 0;
147 	parms.function_id = 0x6b;
148 	parms.session_type = TYPE_DFT;
149 	parms.session_characteristics = 0;	/* Neither EAB nor PSS */
150 	parms.rows = MaxNumberLines;
151 	parms.columns = MaxNumberColumns;
152 	parms.presentation_space = 0;
153     }
154     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
155 }
156 
157 static void
158 query_session_cursor(regs, sregs)
159 union REGS *regs;
160 struct SREGS *sregs;
161 {
162     QuerySessionCursorParms parms;
163 
164     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
165 
166     if ((parms.rc != 0) || (parms.function_id != 0)) {
167 	parms.rc = 0x0c;
168     } else if (parms.session_id != 23) {
169 	parms.rc = 0x02;
170     } else {
171 	parms.rc = 0;
172 	parms.function_id = 0x6b;
173 	parms.cursor_type = CURSOR_BLINKING;	/* XXX what is inhibited? */
174 	parms.row_address = ScreenLine(CursorAddress);
175 	parms.column_address = ScreenLineOffset(CursorAddress);
176     }
177 
178     movetothem(sregs->es, regs->x.di, sizeof parms);
179 }
180 
181 /*
182  * Keyboard Services.
183  */
184 
185 
186 static void
187 connect_to_keyboard(regs, sregs)
188 union REGS *regs;
189 struct SREGS *sregs;
190 {
191     ConnectToKeyboardParms parms;
192 
193     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
194 
195     if ((parms.rc != 0) || (parms.function_id != 0)) {
196 	parms.rc = 0x0c;
197     } else if (parms.session_id != 23) {
198 	parms.rc = 0x02;
199     } else if (parms.intercept_options != 0) {
200 	parms.rc = 0x01;
201     } else {
202 	parms.rc = 0;
203 	parms.first_connection_identifier = 0;
204     }
205     parms.function_id = 0x62;
206 
207     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
208 }
209 
210 static void
211 disconnect_from_keyboard(regs, sregs)
212 union REGS *regs;
213 struct SREGS *sregs;
214 {
215     DisconnectFromKeyboardParms parms;
216 
217     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
218 
219     if ((parms.rc != 0) || (parms.function_id != 0)) {
220 	parms.rc = 0x0c;
221     } else if (parms.session_id != 23) {
222 	parms.rc = 0x02;
223     } else if (parms.connectors_task_id != 0) {
224 	parms.rc = 04;			/* XXX */
225     } else {
226 	parms.rc = 0;
227     }
228     parms.function_id = 0x62;
229 
230     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
231 }
232 
233 static void
234 write_keystroke(regs, sregs)
235 union REGS *regs;
236 struct SREGS *sregs;
237 {
238 /* XXX */
239 }
240 
241 
242 static void
243 disable_input(regs, sregs)
244 union REGS *regs;
245 struct SREGS *sregs;
246 {
247     DisableInputParms parms;
248 
249     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
250 
251     if ((parms.rc != 0) || (parms.function_id != 0)) {
252 	parms.rc = 0x0c;
253     } else if (parms.session_id != 23) {
254 	parms.rc = 0x02;
255     } else if (parms.connectors_task_id != 0) {
256 	parms.rc = 0x04;
257     } else {
258 	ApiDisableInput = 1;
259 	parms.rc = 0;
260     }
261     parms.function_id = 0x62;
262 
263     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
264 }
265 
266 static void
267 enable_input(regs, sregs)
268 union REGS *regs;
269 struct SREGS *sregs;
270 {
271     EnableInputParms parms;
272 
273     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
274 
275     if ((parms.rc != 0) || (parms.function_id != 0)) {
276 	parms.rc = 0x0c;
277     } else if (parms.session_id != 23) {
278 	parms.rc = 0x02;
279     } else if (parms.connectors_task_id != 0) {
280 	parms.rc = 0x04;
281     } else {
282 	ApiDisableInput = 0;
283 	parms.rc = 0;
284     }
285     parms.function_id = 0x62;
286 
287     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
288 }
289 
290 /*
291  * Copy Services.
292  */
293 
294 static void
295 copy_string(regs, sregs)
296 union REGS *regs;
297 struct SREGS *sregs;
298 {
299     CopyStringParms parms;
300     BufferDescriptor *target, *source;
301 
302     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
303 
304     if ((parms.rc != 0) || (parms.function_id !=0)) {
305 	parms.rc = 0x0c;
306     }
307     /* XXX do something! */
308     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
309 }
310 /*
311  * Operator Information Area Services.
312  */
313 
314 static void
315 read_oia_group(regs, sregs)
316 union REGS *regs;
317 struct SREGS *sregs;
318 {
319     ReadOiaGroupParms parms;
320 
321     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
322 
323     if ((parms.rc != 0) || (parms.function_id != 0)) {
324 	parms.rc = 0x0c;
325     } else if (parms.session_id != 23) {
326 	parms.rc = 0x02;
327     } else {
328 	int group = parms.oia_group_number;
329 	char *from;
330 	int size;
331 
332 	if (group > API_OIA_LAST_LEGAL_GROUP) {
333 	} else {
334 	    if (group == API_OIA_ALL_GROUPS) {
335 		size = API_OIA_BYTES_ALL_GROUPS;
336 		from = (char *)&OperatorInformationArea;
337 	    } else if (group == API_OIA_INPUT_INHIBITED) {
338 		size = sizeof OperatorInformationArea.input_inhibited;
339 		from = (char *)&OperatorInformationArea.input_inhibited[0];
340 	    } else {
341 		size = 1;
342 		from = ((char *)&OperatorInformationArea)+group;
343 	    }
344 	    movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer),
345 			from, size);
346 	}
347     }
348     parms.function_id = 0x6d;
349     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
350 }
351 
352 static void
353 unknown_op(regs, sregs)
354 union REGS *regs;
355 struct SREGS *sregs;
356 {
357     regs->h.ch = 0x12;
358     regs->h.cl = 0x05;
359 }
360 
361 
362 handle_api(regs, sregs)
363 union REGS *regs;
364 struct SREGS *sregs;
365 {
366     if (regs->h.ah == NAME_RESOLUTION) {
367 	name_resolution(regs, sregs);
368     } else if (regs->h.ah != 0x09) {
369 	regs->h.ch = 0x12;
370 	regs->h.cl = 0x0f;		/* XXX Invalid environmental access */
371     } else if (regs->x.bx != 0x8020) {
372 	regs->h.ch = 0x12;
373 	regs->h.cl = 0x08;		/* XXX Invalid wait specified */
374     } else if (regs->h.ch != 0) {
375 	regs->h.ch = 0x12;
376 	regs->h.cl = 0x07;		/* XXX Invalid reply specified */
377     } else {
378 	switch (regs->x.dx) {
379 	case GATE_SESSMGR:
380 	    switch (regs->h.al) {
381 	    case QUERY_SESSION_ID:
382 		if (regs->h.cl != 0) {
383 		} else {
384 		    query_session_id(regs, sregs);
385 		}
386 		break;
387 	    case QUERY_SESSION_PARMS:
388 		if (regs->h.cl != 0) {
389 		} else {
390 		    query_session_parameters(regs, sregs);
391 		}
392 		break;
393 	    case QUERY_SESSION_CURSOR:
394 		if (regs->h.cl != 0xff) {
395 		} else {
396 		    query_session_cursor(regs, sregs);
397 		}
398 		break;
399 	    default:
400 		unknown_op(regs, sregs);
401 		break;
402 	    }
403 	    break;
404 	case GATE_KEYBOARD:
405 	    if (regs->h.cl != 00) {
406 	    } else {
407 		switch (regs->h.al) {
408 		case CONNECT_TO_KEYBOARD:
409 		    connect_to_keyboard(regs, sregs);
410 		    break;
411 		case DISABLE_INPUT:
412 		    disable_input(regs, sregs);
413 		    break;
414 		case WRITE_KEYSTROKE:
415 		    write_keystroke(regs, sregs);
416 		    break;
417 		case ENABLE_INPUT:
418 		    enable_input(regs, sregs);
419 		    break;
420 		case DISCONNECT_FROM_KEYBOARD:
421 		    disconnect_from_keyboard(regs, sregs);
422 		    break;
423 		default:
424 		    unknown_op(regs, sregs);
425 		    break;
426 		}
427 	    }
428 	    break;
429 	case GATE_COPY:
430 	    if (regs->h.cl != 0xff) {
431 	    } else {
432 		switch (regs->h.al) {
433 		case COPY_STRING:
434 		    copy_string(regs, sregs);
435 		    break;
436 		default:
437 		    unknown_op(regs, sregs);
438 		    break;
439 		}
440 	    }
441 	    break;
442 	case GATE_OIAM:
443 	    if (regs->h.cl != 0xff) {
444 	    } else {
445 		switch (regs->h.al) {
446 		case READ_OIA_GROUP:
447 		    read_oia_group(regs, sregs);
448 		    break;
449 		default:
450 		    unknown_op(regs, sregs);
451 		    break;
452 		}
453 	    }
454 	    break;
455 	default:
456 	    regs->h.ch = 0x12;
457 	    regs->h.cl = 0x34;		/* Invalid GATE entry */
458 	    break;
459 	}
460     }
461 }
462