Commit | Line | Data |
---|---|---|
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 | |
65c9fa1f | 10 | #include "../ctlr/screen.h" |
92f7501a GM |
11 | #include "../ctlr/oia.h" |
12 | ||
d4967272 | 13 | #include "../general/globals.h" |
65c9fa1f | 14 | |
92f7501a GM |
15 | /* |
16 | * General utility routines. | |
17 | */ | |
18 | ||
19 | #if defined(MSDOS) | |
ffff8f6a GM |
20 | |
21 | #if defined(LINT_ARGS) | |
22 | static void movetous(char *, int, int, int); | |
23 | static void movetothem(int, int, char *, int); | |
24 | #endif /* defined(LINT_ARGS) */ | |
92f7501a GM |
25 | |
26 | static void | |
27 | movetous(parms, es, di, length) | |
28 | char *parms; | |
ffff8f6a | 29 | int es, di, length; |
92f7501a | 30 | { |
ffff8f6a | 31 | char far *farparms = parms; |
92f7501a | 32 | |
ffff8f6a | 33 | movedata(es, di, (int) FP_SEG(farparms), (int) FP_OFF(farparms), length); |
92f7501a GM |
34 | } |
35 | ||
36 | static void | |
ffff8f6a GM |
37 | movetothem(es, di, parms, length) |
38 | int es, di; | |
39 | char *parms; | |
40 | int length; | |
92f7501a | 41 | { |
ffff8f6a | 42 | char far *farparms = parms; |
92f7501a | 43 | |
ffff8f6a | 44 | movedata((int) FP_SEG(farparms), (int) FP_OFF(farparms), es, di, length); |
92f7501a GM |
45 | } |
46 | #endif /* defined(MSDOS) */ | |
47 | ||
48 | /* No Unix version yet... */ | |
49 | ||
50 | ||
abd201e9 GM |
51 | /* |
52 | * Supervisor Services. | |
53 | */ | |
54 | ||
55 | static void | |
92f7501a | 56 | name_resolution(regs, sregs) |
abd201e9 GM |
57 | union REGS *regs; |
58 | struct SREGS *sregs; | |
59 | { | |
86057566 | 60 | NameResolveParms parms; |
e75c75e7 | 61 | |
86057566 | 62 | movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms); |
e75c75e7 GM |
63 | |
64 | regs->h.cl = 0; | |
92f7501a | 65 | if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) { |
e75c75e7 | 66 | regs->x.dx = GATE_SESSMGR; |
92f7501a GM |
67 | } else if (memcmp((char *)&parms, NAME_KEYBOARD, |
68 | sizeof parms.gate_name) == 0) { | |
e75c75e7 | 69 | regs->x.dx = GATE_KEYBOARD; |
92f7501a | 70 | } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) { |
e75c75e7 | 71 | regs->x.dx = GATE_COPY; |
92f7501a | 72 | } else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) { |
e75c75e7 GM |
73 | regs->x.dx = GATE_OIAM; |
74 | } else { | |
75 | regs->h.cl = 0x2e; /* Name not found */ | |
76 | } | |
77 | regs->h.ch = 0x12; | |
78 | regs->h.bh = 7; | |
abd201e9 GM |
79 | } |
80 | ||
81 | /* | |
82 | * Session Information Services. | |
83 | */ | |
84 | ||
85 | static void | |
86 | query_session_id(regs, sregs) | |
87 | union REGS *regs; | |
88 | struct SREGS *sregs; | |
89 | { | |
86057566 | 90 | QuerySessionIdParms parms; |
e75c75e7 | 91 | |
86057566 | 92 | movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); |
e75c75e7 | 93 | |
ffff8f6a GM |
94 | if ((parms.rc != 0) || (parms.function_id != 0)) { |
95 | parms.rc = 0x0c; | |
96 | } else if (parms.option_code != 0x01) { | |
97 | parms.rc = 0x0d; /* Invalid option code */ | |
86057566 | 98 | } else if (parms.data_code != 0x45) { |
ffff8f6a | 99 | parms.rc = 0x0b; |
e75c75e7 | 100 | } else { |
65c9fa1f | 101 | NameArray list; |
86057566 GM |
102 | NameArrayElement element; |
103 | ||
104 | movetous((char *)&list, FP_SEG(parms.name_array), | |
92f7501a | 105 | FP_OFF(parms.name_array), sizeof list); |
65c9fa1f | 106 | if ((list.length < 14) || (list.length > 170)) { |
86057566 | 107 | parms.rc = 0x12; |
e75c75e7 | 108 | } else { |
86057566 GM |
109 | list.number_matching_session = 1; |
110 | list.name_array_element.short_name = parms.data_code; | |
111 | list.name_array_element.type = TYPE_DFT; | |
112 | list.name_array_element.session_id = 23; | |
113 | memcpy(list.name_array_element.long_name, "ONLYSESS", | |
114 | sizeof list.name_array_element.long_name); | |
115 | movetothem(FP_SEG(parms.name_array), | |
92f7501a | 116 | FP_OFF(parms.name_array), (char *)&list, sizeof list); |
86057566 | 117 | parms.rc = 0; |
e75c75e7 GM |
118 | } |
119 | } | |
ffff8f6a | 120 | parms.function_id = 0x6b; |
86057566 | 121 | movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); |
abd201e9 GM |
122 | } |
123 | ||
124 | static void | |
125 | query_session_parameters(regs, sregs) | |
126 | union REGS *regs; | |
127 | struct SREGS *sregs; | |
128 | { | |
86057566 GM |
129 | QuerySessionParametersParms parms; |
130 | ||
131 | movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); | |
132 | ||
65c9fa1f | 133 | if ((parms.rc !=0) || (parms.function_id != 0)) { |
ffff8f6a GM |
134 | parms.rc = 0x0c; |
135 | } else if (parms.session_id != 23) { | |
136 | parms.rc = 0x02; | |
86057566 | 137 | } else { |
ffff8f6a | 138 | parms.rc = 0; |
86057566 GM |
139 | parms.session_type = TYPE_DFT; |
140 | parms.session_characteristics = 0; /* Neither EAB nor PSS */ | |
141 | parms.rows = MaxNumberLines; | |
142 | parms.columns = MaxNumberColumns; | |
143 | parms.presentation_space = 0; | |
144 | } | |
ffff8f6a | 145 | parms.function_id = 0x6b; |
65c9fa1f | 146 | movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); |
abd201e9 GM |
147 | } |
148 | ||
149 | static void | |
150 | query_session_cursor(regs, sregs) | |
151 | union REGS *regs; | |
152 | struct SREGS *sregs; | |
153 | { | |
86057566 GM |
154 | QuerySessionCursorParms parms; |
155 | ||
156 | movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); | |
157 | ||
158 | if ((parms.rc != 0) || (parms.function_id != 0)) { | |
159 | parms.rc = 0x0c; | |
160 | } else if (parms.session_id != 23) { | |
161 | parms.rc = 0x02; | |
162 | } else { | |
163 | parms.rc = 0; | |
86057566 GM |
164 | parms.cursor_type = CURSOR_BLINKING; /* XXX what is inhibited? */ |
165 | parms.row_address = ScreenLine(CursorAddress); | |
166 | parms.column_address = ScreenLineOffset(CursorAddress); | |
167 | } | |
168 | ||
ffff8f6a GM |
169 | parms.function_id = 0x6b; |
170 | movetothem(sregs->es, regs->x.di, (char *) &parms, sizeof parms); | |
abd201e9 GM |
171 | } |
172 | ||
173 | /* | |
174 | * Keyboard Services. | |
175 | */ | |
176 | ||
177 | ||
178 | static void | |
179 | connect_to_keyboard(regs, sregs) | |
180 | union REGS *regs; | |
181 | struct SREGS *sregs; | |
182 | { | |
86057566 GM |
183 | ConnectToKeyboardParms parms; |
184 | ||
d4967272 | 185 | movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); |
86057566 GM |
186 | |
187 | if ((parms.rc != 0) || (parms.function_id != 0)) { | |
188 | parms.rc = 0x0c; | |
189 | } else if (parms.session_id != 23) { | |
190 | parms.rc = 0x02; | |
191 | } else if (parms.intercept_options != 0) { | |
192 | parms.rc = 0x01; | |
193 | } else { | |
194 | parms.rc = 0; | |
195 | parms.first_connection_identifier = 0; | |
196 | } | |
197 | parms.function_id = 0x62; | |
198 | ||
199 | movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); | |
abd201e9 GM |
200 | } |
201 | ||
202 | static void | |
86057566 | 203 | disconnect_from_keyboard(regs, sregs) |
abd201e9 GM |
204 | union REGS *regs; |
205 | struct SREGS *sregs; | |
206 | { | |
86057566 GM |
207 | DisconnectFromKeyboardParms parms; |
208 | ||
209 | movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); | |
210 | ||
211 | if ((parms.rc != 0) || (parms.function_id != 0)) { | |
212 | parms.rc = 0x0c; | |
213 | } else if (parms.session_id != 23) { | |
214 | parms.rc = 0x02; | |
215 | } else if (parms.connectors_task_id != 0) { | |
216 | parms.rc = 04; /* XXX */ | |
217 | } else { | |
218 | parms.rc = 0; | |
219 | } | |
220 | parms.function_id = 0x62; | |
221 | ||
222 | movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); | |
abd201e9 GM |
223 | } |
224 | ||
225 | static void | |
226 | write_keystroke(regs, sregs) | |
227 | union REGS *regs; | |
228 | struct SREGS *sregs; | |
229 | { | |
cbdd0b03 GM |
230 | WriteKeystrokeParms 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 != 23) { | |
237 | parms.rc = 0x02; | |
238 | } else if (parms.connectors_task_id != 0) { | |
239 | parms.rc = 0x04; | |
240 | } else { | |
241 | parms.number_of_keys_sent = 0; | |
242 | parms.rc = 0; | |
243 | if (parms.options == OPTION_SINGLE_KEYSTROKE) { | |
244 | KeystrokeEntry *entry = &parms.keystroke_specifier.keystroke_entry; | |
245 | ||
246 | if (AcceptKeystroke(entry->scancode, entry->shift_state) == 0) { | |
247 | parms.rc = 0x10; /* XXX needs 0x12 too! */ | |
248 | } | |
249 | parms.number_of_keys_sent++; | |
250 | } else if (parms.options == OPTION_MULTIPLE_KEYSTROKES) { | |
251 | KeystrokeList | |
252 | list, | |
253 | far *atlist = parms.keystroke_specifier.keystroke_list; | |
254 | KeystrokeEntry | |
255 | entry[10], /* 10 at a time */ | |
256 | *ourentry, | |
257 | far *theirentry; | |
258 | int | |
259 | todo; | |
260 | ||
261 | movetous((char *)&list, FP_SEG(atlist), | |
262 | FP_OFF(atlist), sizeof *atlist); | |
263 | todo = list.length/2; | |
264 | ourentry = entry+(highestof(entry)+1); | |
265 | ||
266 | while (todo) { | |
267 | if (ourentry > &entry[highestof(entry)]) { | |
268 | int thistime; | |
269 | ||
270 | thistime = todo; | |
271 | if (thistime > numberof(entry)) { | |
272 | thistime = numberof(entry); | |
273 | } | |
274 | movetous((char *)entry, FP_SEG(theirentry), | |
275 | FP_OFF(theirentry), thistime*sizeof *theirentry); | |
276 | theirentry += thistime; | |
277 | ourentry = entry; | |
278 | } | |
279 | if (AcceptKeystroke(ourentry->scancode, | |
280 | ourentry->shift_state) == 0) { | |
281 | parms.rc = 0x10; /* XXX needs 0x12 too! */ | |
282 | break; | |
283 | } | |
284 | parms.number_of_keys_sent++; | |
285 | ourentry++; | |
286 | todo--; | |
287 | } | |
288 | } else { | |
289 | parms.rc = 0x01; | |
290 | } | |
291 | } | |
292 | parms.function_id = 0x62; | |
293 | ||
294 | movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); | |
86057566 GM |
295 | /* XXX */ |
296 | } | |
297 | ||
298 | ||
299 | static void | |
300 | disable_input(regs, sregs) | |
301 | union REGS *regs; | |
302 | struct SREGS *sregs; | |
303 | { | |
304 | DisableInputParms parms; | |
305 | ||
306 | movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); | |
307 | ||
308 | if ((parms.rc != 0) || (parms.function_id != 0)) { | |
309 | parms.rc = 0x0c; | |
310 | } else if (parms.session_id != 23) { | |
311 | parms.rc = 0x02; | |
312 | } else if (parms.connectors_task_id != 0) { | |
313 | parms.rc = 0x04; | |
314 | } else { | |
ffff8f6a | 315 | SetOiaApiInhibit(&OperatorInformationArea); |
86057566 GM |
316 | parms.rc = 0; |
317 | } | |
318 | parms.function_id = 0x62; | |
319 | ||
320 | movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); | |
abd201e9 GM |
321 | } |
322 | ||
323 | static void | |
324 | enable_input(regs, sregs) | |
325 | union REGS *regs; | |
326 | struct SREGS *sregs; | |
327 | { | |
86057566 GM |
328 | EnableInputParms parms; |
329 | ||
330 | movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); | |
331 | ||
332 | if ((parms.rc != 0) || (parms.function_id != 0)) { | |
333 | parms.rc = 0x0c; | |
334 | } else if (parms.session_id != 23) { | |
335 | parms.rc = 0x02; | |
336 | } else if (parms.connectors_task_id != 0) { | |
337 | parms.rc = 0x04; | |
338 | } else { | |
ffff8f6a | 339 | ResetOiaApiInhibit(&OperatorInformationArea); |
86057566 GM |
340 | parms.rc = 0; |
341 | } | |
342 | parms.function_id = 0x62; | |
343 | ||
344 | movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); | |
abd201e9 GM |
345 | } |
346 | ||
347 | /* | |
348 | * Copy Services. | |
349 | */ | |
350 | ||
351 | static void | |
86057566 | 352 | copy_string(regs, sregs) |
abd201e9 GM |
353 | union REGS *regs; |
354 | struct SREGS *sregs; | |
355 | { | |
86057566 GM |
356 | CopyStringParms parms; |
357 | BufferDescriptor *target, *source; | |
358 | ||
359 | movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); | |
abd201e9 | 360 | |
86057566 GM |
361 | if ((parms.rc != 0) || (parms.function_id !=0)) { |
362 | parms.rc = 0x0c; | |
363 | } | |
364 | /* XXX do something! */ | |
d4967272 | 365 | movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); |
86057566 | 366 | } |
abd201e9 GM |
367 | /* |
368 | * Operator Information Area Services. | |
369 | */ | |
370 | ||
371 | static void | |
372 | read_oia_group(regs, sregs) | |
373 | union REGS *regs; | |
374 | struct SREGS *sregs; | |
375 | { | |
86057566 GM |
376 | ReadOiaGroupParms 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 != 23) { | |
383 | parms.rc = 0x02; | |
384 | } else { | |
385 | int group = parms.oia_group_number; | |
92f7501a GM |
386 | char *from; |
387 | int size; | |
86057566 | 388 | |
ffff8f6a GM |
389 | if ((group != API_OIA_ALL_GROUPS) && |
390 | ((group > API_OIA_LAST_LEGAL_GROUP) || (group < 0))) { | |
92f7501a GM |
391 | } else { |
392 | if (group == API_OIA_ALL_GROUPS) { | |
393 | size = API_OIA_BYTES_ALL_GROUPS; | |
394 | from = (char *)&OperatorInformationArea; | |
395 | } else if (group == API_OIA_INPUT_INHIBITED) { | |
396 | size = sizeof OperatorInformationArea.input_inhibited; | |
397 | from = (char *)&OperatorInformationArea.input_inhibited[0]; | |
398 | } else { | |
399 | size = 1; | |
400 | from = ((char *)&OperatorInformationArea)+group; | |
401 | } | |
402 | movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer), | |
403 | from, size); | |
65c9fa1f | 404 | } |
86057566 | 405 | } |
65c9fa1f | 406 | parms.function_id = 0x6d; |
86057566 | 407 | movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); |
abd201e9 GM |
408 | } |
409 | \f | |
410 | static void | |
411 | unknown_op(regs, sregs) | |
412 | union REGS *regs; | |
413 | struct SREGS *sregs; | |
414 | { | |
415 | regs->h.ch = 0x12; | |
416 | regs->h.cl = 0x05; | |
417 | } | |
418 | ||
419 | ||
420 | handle_api(regs, sregs) | |
421 | union REGS *regs; | |
422 | struct SREGS *sregs; | |
423 | { | |
424 | if (regs->h.ah == NAME_RESOLUTION) { | |
425 | name_resolution(regs, sregs); | |
65c9fa1f GM |
426 | } else if (regs->h.ah != 0x09) { |
427 | regs->h.ch = 0x12; | |
428 | regs->h.cl = 0x0f; /* XXX Invalid environmental access */ | |
429 | } else if (regs->x.bx != 0x8020) { | |
430 | regs->h.ch = 0x12; | |
431 | regs->h.cl = 0x08; /* XXX Invalid wait specified */ | |
432 | } else if (regs->h.ch != 0) { | |
ffff8f6a | 433 | regs->x.cx = 0x1206; /* XXX Invalid priority */ |
abd201e9 GM |
434 | } else { |
435 | switch (regs->x.dx) { | |
436 | case GATE_SESSMGR: | |
437 | switch (regs->h.al) { | |
438 | case QUERY_SESSION_ID: | |
65c9fa1f | 439 | if (regs->h.cl != 0) { |
ffff8f6a | 440 | regs->x.cx = 0x1206; |
65c9fa1f | 441 | } else { |
ffff8f6a | 442 | regs->x.cx = 0x1200; |
65c9fa1f GM |
443 | query_session_id(regs, sregs); |
444 | } | |
abd201e9 | 445 | break; |
ffff8f6a | 446 | case QUERY_SESSION_PARAMETERS: |
65c9fa1f | 447 | if (regs->h.cl != 0) { |
ffff8f6a | 448 | regs->x.cx = 0x1206; |
65c9fa1f | 449 | } else { |
ffff8f6a | 450 | regs->x.cx = 0x1200; |
92f7501a | 451 | query_session_parameters(regs, sregs); |
65c9fa1f | 452 | } |
abd201e9 GM |
453 | break; |
454 | case QUERY_SESSION_CURSOR: | |
65c9fa1f | 455 | if (regs->h.cl != 0xff) { |
ffff8f6a | 456 | regs->x.cx = 0x1206; |
65c9fa1f | 457 | } else { |
ffff8f6a | 458 | regs->x.cx = 0x1200; |
65c9fa1f GM |
459 | query_session_cursor(regs, sregs); |
460 | } | |
abd201e9 GM |
461 | break; |
462 | default: | |
463 | unknown_op(regs, sregs); | |
464 | break; | |
465 | } | |
466 | break; | |
467 | case GATE_KEYBOARD: | |
65c9fa1f | 468 | if (regs->h.cl != 00) { |
ffff8f6a | 469 | regs->x.cx = 0x1206; |
65c9fa1f | 470 | } else { |
ffff8f6a | 471 | regs->x.cx = 0x1200; |
65c9fa1f GM |
472 | switch (regs->h.al) { |
473 | case CONNECT_TO_KEYBOARD: | |
474 | connect_to_keyboard(regs, sregs); | |
475 | break; | |
476 | case DISABLE_INPUT: | |
477 | disable_input(regs, sregs); | |
478 | break; | |
479 | case WRITE_KEYSTROKE: | |
480 | write_keystroke(regs, sregs); | |
481 | break; | |
482 | case ENABLE_INPUT: | |
483 | enable_input(regs, sregs); | |
484 | break; | |
485 | case DISCONNECT_FROM_KEYBOARD: | |
486 | disconnect_from_keyboard(regs, sregs); | |
487 | break; | |
488 | default: | |
489 | unknown_op(regs, sregs); | |
490 | break; | |
491 | } | |
abd201e9 GM |
492 | } |
493 | break; | |
494 | case GATE_COPY: | |
65c9fa1f | 495 | if (regs->h.cl != 0xff) { |
ffff8f6a | 496 | regs->x.cx = 0x1206; |
65c9fa1f | 497 | } else { |
ffff8f6a | 498 | regs->x.cx = 0x1200; |
65c9fa1f GM |
499 | switch (regs->h.al) { |
500 | case COPY_STRING: | |
501 | copy_string(regs, sregs); | |
502 | break; | |
503 | default: | |
504 | unknown_op(regs, sregs); | |
505 | break; | |
506 | } | |
abd201e9 GM |
507 | } |
508 | break; | |
509 | case GATE_OIAM: | |
65c9fa1f | 510 | if (regs->h.cl != 0xff) { |
ffff8f6a | 511 | regs->x.cx = 0x1206; |
65c9fa1f | 512 | } else { |
ffff8f6a | 513 | regs->x.cx = 0x1200; |
65c9fa1f GM |
514 | switch (regs->h.al) { |
515 | case READ_OIA_GROUP: | |
516 | read_oia_group(regs, sregs); | |
517 | break; | |
518 | default: | |
519 | unknown_op(regs, sregs); | |
520 | break; | |
521 | } | |
abd201e9 GM |
522 | } |
523 | break; | |
524 | default: | |
65c9fa1f GM |
525 | regs->h.ch = 0x12; |
526 | regs->h.cl = 0x34; /* Invalid GATE entry */ | |
abd201e9 GM |
527 | break; |
528 | } | |
529 | } | |
530 | } |