xref: /csrg-svn/usr.bin/tn3270/ctlr/api.c (revision 31167)
131158Sminshall /*
231158Sminshall  * This file implements the API used in the PC version.
331158Sminshall  */
431158Sminshall 
531158Sminshall #include <stdio.h>
631158Sminshall #include <dos.h>
731158Sminshall #include <stdlib.h>
831158Sminshall 
931158Sminshall #include "spint.h"
1031158Sminshall #include "api.h"
1131158Sminshall #include "../general.h"
1231158Sminshall 
1331158Sminshall 
1431158Sminshall /*
1531158Sminshall  * Supervisor Services.
1631158Sminshall  */
1731158Sminshall 
1831158Sminshall static void
1931158Sminshall name_resolve(regs, sregs)
2031158Sminshall union REGS *regs;
2131158Sminshall struct SREGS *sregs;
2231158Sminshall {
23*31167Sminshall     NameResolveParms parms;
2431161Sminshall 
25*31167Sminshall     movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms);
2631161Sminshall 
2731161Sminshall     regs->h.cl = 0;
28*31167Sminshall     if (strcmp((char *)&parms, NAME_SESSMGR) == 0) {
2931161Sminshall 	regs->x.dx = GATE_SESSMGR;
30*31167Sminshall     } else if (strcmp((char *)&parms, NAME_KEYBOARD) == 0) {
3131161Sminshall 	regs->x.dx = GATE_KEYBOARD;
32*31167Sminshall     } else if (strcmp((char *)&parms, NAME_COPY) == 0) {
3331161Sminshall 	regs->x.dx = GATE_COPY;
34*31167Sminshall     } else if (strcmp((char *)&parms, NAME_OIAM) == 0) {
3531161Sminshall 	regs->x.dx = GATE_OIAM;
3631161Sminshall     } else {
3731161Sminshall 	regs->h.cl = 0x2e;	/* Name not found */
3831161Sminshall     }
3931161Sminshall     regs->h.ch = 0x12;
4031161Sminshall     regs->h.bh = 7;
4131158Sminshall }
4231158Sminshall 
4331158Sminshall /*
4431158Sminshall  * Session Information Services.
4531158Sminshall  */
4631158Sminshall 
4731158Sminshall static void
4831158Sminshall query_session_id(regs, sregs)
4931158Sminshall union REGS *regs;
5031158Sminshall struct SREGS *sregs;
5131158Sminshall {
52*31167Sminshall     QuerySessionIdParms parms;
5331161Sminshall 
54*31167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
5531161Sminshall 
56*31167Sminshall     if (parms.rc != 0) {
57*31167Sminshall 	regs->h.cl = 0x0c;
58*31167Sminshall 	return;
59*31167Sminshall     }
60*31167Sminshall     if (parms.option_code != 0x01) {
61*31167Sminshall 	regs->h.cl = 0x0d;	/* Invalid option code */
62*31167Sminshall     } else if (parms.data_code != 0x45) {
63*31167Sminshall 	regs->h.cl = 0x0b;
6431161Sminshall     } else {
65*31167Sminshall 	NameArrayList list;
66*31167Sminshall 	NameArrayElement element;
67*31167Sminshall 
68*31167Sminshall 	movetous((char *)&list, FP_SEG(parms.name_array),
69*31167Sminshall 			    FP_OFFSET(parms.name_array), sizeof list);
70*31167Sminshall 	if (list.length < 14) || (list.length > 170)) {
71*31167Sminshall 	    parms.rc = 0x12;
72*31167Sminshall 	    regs.h.cl = 0x12;
7331161Sminshall 	} else {
74*31167Sminshall 	    list.number_matching_session = 1;
75*31167Sminshall 	    list.name_array_element.short_name = parms.data_code;
76*31167Sminshall 	    list.name_array_element.type = TYPE_DFT;
77*31167Sminshall 	    list.name_array_element.session_id = 23;
78*31167Sminshall 	    memcpy(list.name_array_element.long_name, "ONLYSESS",
79*31167Sminshall 			    sizeof list.name_array_element.long_name);
80*31167Sminshall 	    movetothem(FP_SEG(parms.name_array),
81*31167Sminshall 		FP_OFFSET(parms.name_array), (char *)&list, sizeof list);
82*31167Sminshall 	    parms.rc = 0;
8331161Sminshall 	    regs->h.cl = 0;
8431161Sminshall 	}
8531161Sminshall     }
86*31167Sminshall     parms.function_code = 0x6d;
87*31167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
8831158Sminshall }
8931158Sminshall 
9031158Sminshall static void
9131158Sminshall query_session_parameters(regs, sregs)
9231158Sminshall union REGS *regs;
9331158Sminshall struct SREGS *sregs;
9431158Sminshall {
95*31167Sminshall     QuerySessionParametersParms parms;
96*31167Sminshall 
97*31167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
98*31167Sminshall 
99*31167Sminshall     if (parms.rc[0] !=0) || (parms.function_id != 0)) {
100*31167Sminshall 	regs->h.cl = 0x0c;
101*31167Sminshall 	return;
102*31167Sminshall     }
103*31167Sminshall     if (parms.session_id != 23) {
104*31167Sminshall 	regs.h.cl = parms.rc = 0x02;
105*31167Sminshall     } else {
106*31167Sminshall 	regs.h.cl = parms.rc = 0;
107*31167Sminshall 	parms.function_id = 0x6b;
108*31167Sminshall 	parms.session_type = TYPE_DFT;
109*31167Sminshall 	parms.session_characteristics = 0;	/* Neither EAB nor PSS */
110*31167Sminshall 	parms.rows = MaxNumberLines;
111*31167Sminshall 	parms.columns = MaxNumberColumns;
112*31167Sminshall 	parms.presentation_space = 0;
113*31167Sminshall     }
114*31167Sminshall     movetothem(sregs->es, regs.x.di, (char *)&parms, sizeof parms);
11531158Sminshall }
11631158Sminshall 
11731158Sminshall static void
11831158Sminshall query_session_cursor(regs, sregs)
11931158Sminshall union REGS *regs;
12031158Sminshall struct SREGS *sregs;
12131158Sminshall {
122*31167Sminshall     QuerySessionCursorParms parms;
123*31167Sminshall 
124*31167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
125*31167Sminshall 
126*31167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
127*31167Sminshall 	parms.rc = 0x0c;
128*31167Sminshall     } else if (parms.session_id != 23) {
129*31167Sminshall 	parms.rc = 0x02;
130*31167Sminshall     } else {
131*31167Sminshall 	parms.rc = 0;
132*31167Sminshall 	parms.function_id = 0x6b;
133*31167Sminshall 	parms.cursor_type = CURSOR_BLINKING;	/* XXX what is inhibited? */
134*31167Sminshall 	parms.row_address = ScreenLine(CursorAddress);
135*31167Sminshall 	parms.column_address = ScreenLineOffset(CursorAddress);
136*31167Sminshall     }
137*31167Sminshall 
138*31167Sminshall     movetothem(sregs->es, regs->x.di, sizeof parms);
13931158Sminshall }
14031158Sminshall 
14131158Sminshall /*
14231158Sminshall  * Keyboard Services.
14331158Sminshall  */
14431158Sminshall 
14531158Sminshall 
14631158Sminshall static void
14731158Sminshall connect_to_keyboard(regs, sregs)
14831158Sminshall union REGS *regs;
14931158Sminshall struct SREGS *sregs;
15031158Sminshall {
151*31167Sminshall     ConnectToKeyboardParms parms;
152*31167Sminshall 
153*31167Sminshall     movetous((char *)parms, sregs->es, regs->x.di, sizeof parms);
154*31167Sminshall 
155*31167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
156*31167Sminshall 	parms.rc = 0x0c;
157*31167Sminshall     } else if (parms.session_id != 23) {
158*31167Sminshall 	parms.rc = 0x02;
159*31167Sminshall     } else if (parms.intercept_options != 0) {
160*31167Sminshall 	parms.rc = 0x01;
161*31167Sminshall     } else {
162*31167Sminshall 	parms.rc = 0;
163*31167Sminshall 	parms.first_connection_identifier = 0;
164*31167Sminshall     }
165*31167Sminshall     parms.function_id = 0x62;
166*31167Sminshall 
167*31167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
16831158Sminshall }
16931158Sminshall 
17031158Sminshall static void
171*31167Sminshall disconnect_from_keyboard(regs, sregs)
17231158Sminshall union REGS *regs;
17331158Sminshall struct SREGS *sregs;
17431158Sminshall {
175*31167Sminshall     DisconnectFromKeyboardParms parms;
176*31167Sminshall 
177*31167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
178*31167Sminshall 
179*31167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
180*31167Sminshall 	parms.rc = 0x0c;
181*31167Sminshall     } else if (parms.session_id != 23) {
182*31167Sminshall 	parms.rc = 0x02;
183*31167Sminshall     } else if (parms.connectors_task_id != 0) {
184*31167Sminshall 	parms.rc = 04;			/* XXX */
185*31167Sminshall     } else {
186*31167Sminshall 	parms.rc = 0;
187*31167Sminshall     }
188*31167Sminshall     parms.function_id = 0x62;
189*31167Sminshall 
190*31167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
19131158Sminshall }
19231158Sminshall 
19331158Sminshall static void
19431158Sminshall write_keystroke(regs, sregs)
19531158Sminshall union REGS *regs;
19631158Sminshall struct SREGS *sregs;
19731158Sminshall {
198*31167Sminshall /* XXX */
19931158Sminshall }
20031158Sminshall 
201*31167Sminshall 
20231158Sminshall static void
203*31167Sminshall disable_input(regs, sregs)
204*31167Sminshall union REGS *regs;
205*31167Sminshall struct SREGS *sregs;
206*31167Sminshall {
207*31167Sminshall     DisableInputParms parms;
208*31167Sminshall 
209*31167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
210*31167Sminshall 
211*31167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
212*31167Sminshall 	parms.rc = 0x0c;
213*31167Sminshall     } else if (parms.session_id != 23) {
214*31167Sminshall 	parms.rc = 0x02;
215*31167Sminshall     } else if (parms.connectors_task_id != 0) {
216*31167Sminshall 	parms.rc = 0x04;
217*31167Sminshall     } else {
218*31167Sminshall 	ApiDisableInput = 1;
219*31167Sminshall 	parms.rc = 0;
220*31167Sminshall     }
221*31167Sminshall     parms.function_id = 0x62;
222*31167Sminshall 
223*31167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
224*31167Sminshall }
225*31167Sminshall 
226*31167Sminshall static void
22731158Sminshall enable_input(regs, sregs)
22831158Sminshall union REGS *regs;
22931158Sminshall struct SREGS *sregs;
23031158Sminshall {
231*31167Sminshall     EnableInputParms parms;
232*31167Sminshall 
233*31167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
234*31167Sminshall 
235*31167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
236*31167Sminshall 	parms.rc = 0x0c;
237*31167Sminshall     } else if (parms.session_id != 23) {
238*31167Sminshall 	parms.rc = 0x02;
239*31167Sminshall     } else if (parms.connectors_task_id != 0) {
240*31167Sminshall 	parms.rc = 0x04;
241*31167Sminshall     } else {
242*31167Sminshall 	ApiDisableInput = 0;
243*31167Sminshall 	parms.rc = 0;
244*31167Sminshall     }
245*31167Sminshall     parms.function_id = 0x62;
246*31167Sminshall 
247*31167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
24831158Sminshall }
24931158Sminshall 
25031158Sminshall /*
25131158Sminshall  * Copy Services.
25231158Sminshall  */
25331158Sminshall 
25431158Sminshall static void
255*31167Sminshall copy_string(regs, sregs)
25631158Sminshall union REGS *regs;
25731158Sminshall struct SREGS *sregs;
25831158Sminshall {
259*31167Sminshall     CopyStringParms parms;
260*31167Sminshall     BufferDescriptor *target, *source;
261*31167Sminshall 
262*31167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
263*31167Sminshall 
264*31167Sminshall     if ((parms.rc != 0) || (parms.function_id !=0)) {
265*31167Sminshall 	parms.rc = 0x0c;
266*31167Sminshall     }
267*31167Sminshall     /* XXX do something! */
268*31167Sminshall     movetothem(sregs->es, regs->x.di, (char *)parms, sizeof parms);
26931158Sminshall }
27031158Sminshall /*
27131158Sminshall  * Operator Information Area Services.
27231158Sminshall  */
27331158Sminshall 
27431158Sminshall static void
27531158Sminshall read_oia_group(regs, sregs)
27631158Sminshall union REGS *regs;
27731158Sminshall struct SREGS *sregs;
27831158Sminshall {
279*31167Sminshall     ReadOiaGroupParms parms;
280*31167Sminshall 
281*31167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
282*31167Sminshall 
283*31167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
284*31167Sminshall 	parms.rc = 0x0c;
285*31167Sminshall     } else if (parms.session_id != 23) {
286*31167Sminshall 	parms.rc = 0x02;
287*31167Sminshall     } else {
288*31167Sminshall 	int group = parms.oia_group_number;
289*31167Sminshall 	char far *where = parms.oia_buffer;
290*31167Sminshall 
291*31167Sminshall 	switch (group) {
292*31167Sminshall 	case OIA_ALL_GROUPS:
293*31167Sminshall 	case OIA_ONLINE_OWNERSHIP:
294*31167Sminshall 	    if (group != OIA_ALL_GROUPS) {
295*31167Sminshall 		break;
296*31167Sminshall 	    } /* else, fall through */
297*31167Sminshall 	case OIA_CHARACTER_SELECTION:
298*31167Sminshall 	    if (group != OIA_ALL_GROUPS) {
299*31167Sminshall 		break;
300*31167Sminshall 	    } /* else, fall through */
301*31167Sminshall 	case OIA_SHIFT_STATE:
302*31167Sminshall 	    if (group != OIA_ALL_GROUPS) {
303*31167Sminshall 		break;
304*31167Sminshall 	    } /* else, fall through */
305*31167Sminshall 	case OIA_PSS_GROUP_1:
306*31167Sminshall 	    if (group != OIA_ALL_GROUPS) {
307*31167Sminshall 		break;
308*31167Sminshall 	    } /* else, fall through */
309*31167Sminshall 	case OIA_HIGHLIGHT_GROUP_1:
310*31167Sminshall 	    if (group != OIA_ALL_GROUPS) {
311*31167Sminshall 		break;
312*31167Sminshall 	    } /* else, fall through */
313*31167Sminshall 	case OIA_COLOR_GROUP_1:
314*31167Sminshall 	    if (group != OIA_ALL_GROUPS) {
315*31167Sminshall 		break;
316*31167Sminshall 	    } /* else, fall through */
317*31167Sminshall 	case OIA_INSERT:
318*31167Sminshall 	    if (group != OIA_ALL_GROUPS) {
319*31167Sminshall 		break;
320*31167Sminshall 	    } /* else, fall through */
321*31167Sminshall 	case OIA_INPUT_INHIBITED:
322*31167Sminshall 	    if (group != OIA_ALL_GROUPS) {
323*31167Sminshall 		break;
324*31167Sminshall 	    } /* else, fall through */
325*31167Sminshall 	case OIA_PSS_GROUP_2:
326*31167Sminshall 	    if (group != OIA_ALL_GROUPS) {
327*31167Sminshall 		break;
328*31167Sminshall 	    } /* else, fall through */
329*31167Sminshall 	case OIA_HIGHLIGHT_GROUP_2:
330*31167Sminshall 	    if (group != OIA_ALL_GROUPS) {
331*31167Sminshall 		break;
332*31167Sminshall 	    } /* else, fall through */
333*31167Sminshall 	case OIA_COLOR_GROUP_2:
334*31167Sminshall 	    if (group != OIA_ALL_GROUPS) {
335*31167Sminshall 		break;
336*31167Sminshall 	    } /* else, fall through */
337*31167Sminshall 	case OIA_COMMUNICATION_ERROR_REMINDER:
338*31167Sminshall 	    if (group != OIA_ALL_GROUPS) {
339*31167Sminshall 		break;
340*31167Sminshall 	    } /* else, fall through */
341*31167Sminshall 	case OIA_PRINTER_STATUS:
342*31167Sminshall 	    if (group != OIA_ALL_GROUPS) {
343*31167Sminshall 		break;
344*31167Sminshall 	    } /* else, fall through */
345*31167Sminshall 	case OIA_AUTOKEY_PLAY_RECORD_STATUS:
346*31167Sminshall 	    if (group != OIA_ALL_GROUPS) {
347*31167Sminshall 		break;
348*31167Sminshall 	    } /* else, fall through */
349*31167Sminshall 	case OIA_AUTOKEY_ABORT_PAUSE_STATUS:
350*31167Sminshall 	    if (group != OIA_ALL_GROUPS) {
351*31167Sminshall 		break;
352*31167Sminshall 	    } /* else, fall through */
353*31167Sminshall 	case OIA_ENLARGE_STATE:
354*31167Sminshall 	    if (group != OIA_ALL_GROUPS) {
355*31167Sminshall 		break;
356*31167Sminshall 	    } /* else, fall through */
357*31167Sminshall 
358*31167Sminshall 	    /* oops, we are done! */
359*31167Sminshall 	    break;
360*31167Sminshall 	default:
361*31167Sminshall 	    break;
362*31167Sminshall     }
363*31167Sminshall     parms->function_id = 0x6d;
364*31167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
36531158Sminshall }
36631158Sminshall 
36731158Sminshall static void
36831158Sminshall unknown_op(regs, sregs)
36931158Sminshall union REGS *regs;
37031158Sminshall struct SREGS *sregs;
37131158Sminshall {
37231158Sminshall     regs->h.ch = 0x12;
37331158Sminshall     regs->h.cl = 0x05;
37431158Sminshall }
37531158Sminshall 
37631158Sminshall 
37731158Sminshall handle_api(regs, sregs)
37831158Sminshall union REGS *regs;
37931158Sminshall struct SREGS *sregs;
38031158Sminshall {
38131158Sminshall     if (regs->h.ah == NAME_RESOLUTION) {
38231158Sminshall 	name_resolution(regs, sregs);
38331158Sminshall     } else {
38431158Sminshall 	switch (regs->x.dx) {
38531158Sminshall 	case GATE_SESSMGR:
38631158Sminshall 	    switch (regs->h.al) {
38731158Sminshall 	    case QUERY_SESSION_ID:
38831158Sminshall 		query_session_id(regs, sregs);
38931158Sminshall 		break;
39031158Sminshall 	    case QUERY_SESSION_PARMS:
39131158Sminshall 		query_session_parms(regs, sregs);
39231158Sminshall 		break;
39331158Sminshall 	    case QUERY_SESSION_CURSOR:
39431158Sminshall 		query_session_cursor(regs, sregs);
39531158Sminshall 		break;
39631158Sminshall 	    default:
39731158Sminshall 		unknown_op(regs, sregs);
39831158Sminshall 		break;
39931158Sminshall 	    }
40031158Sminshall 	    break;
40131158Sminshall 	case GATE_KEYBOARD:
40231158Sminshall 	    switch (regs->h.al) {
40331158Sminshall 	    case CONNECT_TO_KEYBOARD:
40431158Sminshall 		connect_to_keyboard(regs, sregs);
40531158Sminshall 		break;
40631158Sminshall 	    case DISABLE_INPUT:
40731158Sminshall 		disable_input(regs, sregs);
40831158Sminshall 		break;
40931158Sminshall 	    case WRITE_KEYSTROKE:
41031158Sminshall 		write_keystroke(regs, sregs);
41131158Sminshall 		break;
41231158Sminshall 	    case ENABLE_INPUT:
41331158Sminshall 		enable_input(regs, sregs);
41431158Sminshall 		break;
41531158Sminshall 	    case DISCONNECT_FROM_KEYBOARD:
41631158Sminshall 		disconnect_from_keyboard(regs, sregs);
41731158Sminshall 		break;
41831158Sminshall 	    default:
41931158Sminshall 		unknown_op(regs, sregs);
42031158Sminshall 		break;
42131158Sminshall 	    }
42231158Sminshall 	    break;
42331158Sminshall 	case GATE_COPY:
42431158Sminshall 	    switch (regs->h.al) {
42531158Sminshall 	    case COPY_STRING:
42631158Sminshall 		copy_string(regs, sregs);
42731158Sminshall 		break;
42831158Sminshall 	    default:
42931158Sminshall 		unknown_op(regs, sregs);
43031158Sminshall 		break;
43131158Sminshall 	    }
43231158Sminshall 	    break;
43331158Sminshall 	case GATE_OIAM:
43431158Sminshall 	    switch (regs->h.al) {
43531158Sminshall 	    case READ_OIA_GROUP:
43631158Sminshall 		read_oia_group(regs, sregs);
43731158Sminshall 		break;
43831158Sminshall 	    default:
43931158Sminshall 		unknown_op(regs, sregs);
44031158Sminshall 		break;
44131158Sminshall 	    }
44231158Sminshall 	    break;
44331158Sminshall 	default:
44431158Sminshall 	    unknown_op(regs, sregs);
44531158Sminshall 	    break;
44631158Sminshall 	}
44731158Sminshall     }
44831158Sminshall }
44931158Sminshall 
45031158Sminshall 
45131158Sminshall /*
45231158Sminshall  * Called from telnet.c to fork a lower command.com.  We
45331158Sminshall  * use the spint... routines so that we can pick up
45431158Sminshall  * interrupts generated by application programs.
45531158Sminshall  */
45631158Sminshall 
45731158Sminshall 
45831158Sminshall int
45931158Sminshall shell(argc,argv)
46031158Sminshall int	argc;
46131158Sminshall char	*argv[];
46231158Sminshall {
46331158Sminshall     Spint spinted;
46431158Sminshall     static char command[256];
46531158Sminshall 
46631158Sminshall     ClearElement(spinted);
46731158Sminshall     spinted.int_no = API_INTERRUPT_NUMBER;
46831158Sminshall     if (argc == 1) {
46931158Sminshall 	command[0] = 0;
47031158Sminshall     } else {
47131158Sminshall 	char *cmdptr;
47231158Sminshall 	int length;
47331158Sminshall 
47431158Sminshall 	argc--;
47531158Sminshall 	argv++;
47631158Sminshall 	strcpy(command, " /c");
47731158Sminshall 	cmdptr = command+strlen(command);
47831158Sminshall 	while (argc) {
47931158Sminshall 	    if ((cmdptr+strlen(*argv)) >= (command+sizeof command)) {
48031158Sminshall 		fprintf(stderr, "Argument list too long at argument *%s*.\n",
48131158Sminshall 			    *argv);
48231158Sminshall 		return 0;
48331158Sminshall 	    }
48431158Sminshall 	    *cmdptr++ = ' ';		/* Blank separators */
48531158Sminshall 	    strcpy(cmdptr, *argv);
48631158Sminshall 	    cmdptr += strlen(cmdptr);
48731158Sminshall 	    argc--;
48831158Sminshall 	    argv++;
48931158Sminshall 	}
49031158Sminshall 	length = strlen(command)-1;
49131158Sminshall 	if (length < 0) {
49231158Sminshall 	    length = 0;
49331158Sminshall 	}
49431158Sminshall 	command[0] = length;
49531158Sminshall     }
49631158Sminshall 
49731158Sminshall     /*
49831158Sminshall      * spint_start() returns when either the command has finished, or when
49931158Sminshall      * the required interrupt comes in.  In the latter case, the appropriate
50031158Sminshall      * thing to do is to process the interrupt, and then return to
50131158Sminshall      * the interrupt issuer by calling spint_continue().
50231158Sminshall      */
50331158Sminshall     spint_start(command, &spinted);
50431158Sminshall     while (spinted.done == 0) {
50531158Sminshall 	/* Process request */
50631158Sminshall 	handle_api(&spinted.regs, &spinted.sregs);
50731158Sminshall 	spint_continue(&spinted);
50831158Sminshall     }
50931158Sminshall     if (spinted.rc != 0) {
51031158Sminshall 	fprintf(stderr, "Process generated a return code of 0x%x.\n",
51131158Sminshall 								spinted.rc);
51231158Sminshall     }
51331158Sminshall     return 0;
51431158Sminshall }
515