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