-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhp150.c
582 lines (456 loc) · 12.7 KB
/
hp150.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
/*
* The routines in this file provide support for HP150 screens
* and routines to access the Keyboard through KEYCODE mode.
* It compiles into nothing if not an HP150 screen device.
* added by Daniel Lawrence
*/
#define termdef 1 /* don't define "term" external */
#include <stdio.h>
#include "estruct.h"
#include "eproto.h"
#include "edef.h"
#include "elang.h"
#if HP150
#define NROW 24 /* Screen size. */
#define NCOL 80 /* Edit if you want to. */
#define MARGIN 8 /* size of minimim margin and */
#define SCRSIZ 64 /* scroll size for extended lines */
#define NPAUSE 15 /* # times thru update to pause */
#define BEL 0x07 /* BEL character. */
#define ESC 0x1B /* ESC character. */
extern int PASCAL NEAR openhp(); /* Forward references. */
extern int PASCAL NEAR hpflush();
extern int PASCAL NEAR closehp();
extern int PASCAL NEAR hp15kopen();
extern int PASCAL NEAR hp15kclose();
extern int PASCAL NEAR hp15move();
extern int PASCAL NEAR hp15eeol();
extern int PASCAL NEAR hp15eeop();
extern int PASCAL NEAR hp15beep();
extern int PASCAL NEAR gethpkey();
extern int PASCAL NEAR hp15rev();
extern int PASCAL NEAR hp15cres();
#if COLOR
extern int PASCAL NEAR hp15fcol();
extern int PASCAL NEAR hp15bcol();
#endif
PASCAL NEAR hp15parm();
PASCAL NEAR rawon();
PASCAL NEAR rawoff();
PASCAL NEAR ckeyoff();
PASCAL NEAR ckeyon();
PASCAL NEAR agios();
PASCAL NEAR keycon();
PASCAL NEAR keycoff();
PASCAL NEAR defkey();
PASCAL NEAR undefkey();
PASCAL NEAR dsplbls();
/* Some needed locals */
union REGS r; /* register set for bios and dos (AGIOS) calls */
int capslock = 0; /* caps lock flag */
int break_flag; /* state of MSDOS control break processing */
/*
* Standard terminal interface dispatch table. Most of the fields point into
* "termio" code.
*/
TERM term = {
NROW-1,
NROW-1,
NCOL,
NCOL,
MARGIN,
SCRSIZ,
0, 0,
NPAUSE,
openhp,
closehp,
hp15kopen,
hp15kclose,
gethpkey,
ttputc,
hpflush,
hp15move,
hp15eeol,
hp15eeop,
hp15eeop,
hp15beep,
hp15rev,
hp15cres
#if COLOR
, hp15fcol,
hp15bcol
#endif
};
PASCAL NEAR hp15move(row, col)
{
ttputc(ESC);
ttputc('&');
ttputc('a');
hp15parm(col);
ttputc('c');
hp15parm(row);
ttputc('R');
}
PASCAL NEAR hpflush()
{
}
PASCAL NEAR hp15eeol()
{
ttputc(ESC);
ttputc('K');
}
PASCAL NEAR hp15eeop()
{
ttputc(ESC);
ttputc('J');
}
PASCAL NEAR hp15rev(status) /* change the reverse video status */
int status; /* TRUE = on, FALSE = off */
{
ttputc(ESC);
ttputc('&');
ttputc('d');
ttputc((status != FALSE) ? 'B': '@');
}
PASCAL NEAR hp15cres() /* change screen resolution */
{
return(TRUE);
}
PASCAL NEAR spal() /* change pallette register */
{
/* not here */
}
PASCAL NEAR hp15beep()
{
ttputc(BEL);
ttflush();
}
PASCAL NEAR hp15parm(n)
register int n;
{
register int q;
q = n/10;
if (q != 0)
hp15parm(q);
ttputc((n%10) + '0');
}
#if COLOR
PASCAL NEAR hp15fcol() /* we really can't do colors here, so just ignore it */
{
}
PASCAL NEAR hp15bcol() /* we really can't do colors here, so just ignore it */
{
}
#endif
PASCAL NEAR gethpkey() /* get a key from the HP keyboard while in keycode mode */
{
unsigned c; /* character to translate */
int devid; /* device ID */
int ctype; /* type of character gotten */
unsigned shiftb; /* state of shift keys */
int i; /* index in first translation loop */
/* return any keystrokes waiting in the
type ahead buffer */
if (in_check())
return(in_get());
/* grab the next 4 char sequence */
next: shiftb = ttgetc();
devid = ttgetc();
c = ttgetc();
ttgetc(); /* skip null byte */
/* make sure we are from the keyboard */
if (devid != 192)
goto next;
/* if normal ascii, return it */
if ((shiftb & 0x80) == 0) {
if (capslock && c >= 'a' && c <= 'z')
c -= 32;
return(c);
}
/* check specifically for the caps lock key */
if (c == 0x56) {
capslock = ~capslock;
goto next;
}
/* interpet it as an extended HP sequence */
c = extcode(shiftb, c);
/* if it becomes standard ascii... just return it */
if ((c >> 8) == 0)
return(c & 255);
/* or return it as en extended emacs internal sequence */
in_put(c >> 8); /* prefix byte */
in_put(c & 255); /* event code byte */
return(0); /* extended escape sequence */
}
/* extcode: resolve MSDOS extended character codes
encoding the proper sequences into emacs
printable character specifications
*/
int extcode(shiftb, c)
unsigned shiftb; /* shift flag */
unsigned c; /* byte following a zero extended char byte */
{
int sstate; /* state of the various shift keys */
/* remember if we are shifted */
if ((shiftb & 0x04) != 0)
sstate = SHFT;
else
sstate = 0;
/* remember if we are alted (extended char keys) */
if ((shiftb & 0x30) != 0)
sstate |= ALTD;
/* remember if we are controled */
if ((shiftb & 0x08) != 0)
sstate |= CTRL;
/* function keys 1 through 9 */
if (c >= 0 && c < 9)
return(sstate | SPEC | c + 1 + '0');
/* function key 10 */
if (c == 9)
return(sstate | SPEC | '0');
/* function key 11 */
if (c == 10)
return(sstate | SPEC | 'E');
/* function key 12 */
if (c == 11)
return(sstate | SPEC | 'T');
/* some others as well */
switch (c) {
case 36: return(sstate | 9); /* tab */
case 37: return(sstate | 13); /* ret */
case 39: return(sstate | 8); /* backspace */
case 48: return(sstate | 48); /* zero */
case 49: return(sstate | 49); /* one */
case 50: return(sstate | 50); /* two */
case 51: return(sstate | 51); /* three */
case 52: return(sstate | 52); /* four */
case 53: return(sstate | 53); /* five */
case 54: return(sstate | 54); /* six */
case 55: return(sstate | 55); /* seven */
case 56: return(sstate | 56); /* eight */
case 57: return(sstate | 57); /* nine */
case 80: return(sstate | 13); /* enter */
case 84: return(sstate | 27); /* break -> ESC */
case 85: return(sstate | 27); /* esc */
case 88: return(sstate | 24); /* stop -> ^X */
case 112: return(sstate | 45); /* N-minus */
case 113: return(sstate | 42); /* N-asterisk */
case 114: return(sstate | 43); /* N-plus */
case 115: return(sstate | 47); /* N-slash */
case 116: return(sstate | 44); /* N-comma */
case 117: return(sstate | 13); /* N-enter */
case 118: return(sstate | 9); /* N-tab */
case 119: return(sstate | 46); /* N-period */
case 44:
case 45:
case 110: return(sstate | SPEC | '<'); /* HOME */
case 32:
case 41:
case 101: return(sstate | SPEC | 'P'); /* cursor up */
case 47: return(sstate | SPEC | 'Z'); /* page up */
case 35:
case 42:
case 97: return(sstate | SPEC | 'B'); /* cursor left */
case 34:
case 43:
case 99: return(sstate | SPEC | 'F'); /* cursor right */
case 82: return(sstate | SPEC | '>'); /* end */
case 33:
case 40:
case 98: return(sstate | SPEC | 'N'); /* cursor down */
case 46:
case 108: return(sstate | SPEC | 'V'); /* page down */
case 64:
case 70:
case 107: return(sstate | SPEC | 'C'); /* insert */
case 65:
case 71:
case 109: return(sstate | SPEC | 'D'); /* delete */
/* the HP has some extra keys we need to map */
case 83:
case 89: return(sstate | SPEC | 'Q'); /* reformat paragraph */
case 81: return(sstate | CTLX | 'C'); /* shell up to system */
case 67: return(sstate | SPEC | CTRL | 'L'); /* center display */
case 68: return(sstate | CTRL | 'O'); /* open line */
case 69: return(sstate | CTRL | 'K'); /* Kill to end of line */
}
return(sstate | c);
}
PASCAL NEAR openhp() /* open the HP150 screen for input */
{
strcpy(sres, "NORMAL");
strcpy(os, "MSDOS");
revexist = TRUE;
}
PASCAL NEAR closehp() /* close the HP150 screen for input */
{
}
PASCAL NEAR hp15kopen() /* open the HP150 keyboard for input */
{
/* define key charectoristics with AGIOS call (0, 40) */
defkey();
/* Turn on RAW mode with MSDOS call 44h */
rawon();
/* Turn off Control-C checking MS-DOS 33h */
ckeyoff();
/* Turn on keycode mode with AGIOS call (0,43) */
keycon();
/* display the application softkey labels */
dsplbls();
}
PASCAL NEAR hp15kclose() /* close the HP150 keyboard for input */
{
/* define key charectoristics with AGIOS call (0, 40) */
undefkey();
/* Turn off RAW mode with MSDOS call 44h */
rawoff();
/* Turn on Control-C checking MS-DOS 33h */
ckeyon();
/* Turn off keycode mode with AGIOS call (0,43) */
keycoff();
}
PASCAL NEAR rawon() /* put the HP150 keyboard into RAW mode */
{
/* get the IO control info */
r.x.ax = 0x4400; /* IO ctrl get device information */
r.x.bx = 0x0001; /* File handle; 1 for console */
intdos(&r, &r); /* go fer it */
r.h.dh = 0; /* clear high byte for put */
r.h.dl |= 0x20; /* set raw bit */
/* and put it back */
r.x.ax = 0x4401; /* IO ctrl put device information */
r.x.bx = 0x0001; /* File handle; 1 for console */
intdos(&r, &r); /* go fer it */
}
PASCAL NEAR rawoff() /* put the HP150 keyboard into COOKED mode */
{
/* get the IO control info */
r.x.ax = 0x4400; /* IO ctrl get device information */
r.x.bx = 0x0001; /* File handle; 1 for console */
intdos(&r, &r); /* go fer it */
r.h.dh = 0; /* clear high byte for put */
r.h.dl &= 0xdf; /* set raw bit */
/* and put it back */
r.x.ax = 0x4401; /* IO ctrl put device information */
r.x.bx = 0x0001; /* File handle; 1 for console */
intdos(&r, &r); /* go fer it */
}
PASCAL NEAR ckeyoff() /* turn control-C trapping off */
{
/* find the current state of the control break inturrupt */
r.h.ah = 0x33; /* ctrl-break check */
r.h.al = 0; /* request the state of the ctrl-break check */
intdos(&r, &r);
break_flag = r.h.dl;
/* set the break processing off if it is on */
if (break_flag == 1) {
r.h.ah = 0x33; /* ctrl-break check */
r.h.al = 1; /* set the state of the ctrl-break check */
r.h.dl = 0; /* turn it off */
intdos(&r, &r);
}
}
PASCAL NEAR ckeyon() /* turn control-C trapping on */
{
if (break_flag == 1) {
r.h.ah = 0x33; /* ctrl-break check */
r.h.al = 1; /* set the state of the ctrl-break check */
r.h.dl = 1; /* turn it on */
intdos(&r, &r);
}
}
#ifdef unsigned
#undef unsigned
#endif
PASCAL NEAR agios(buf, len) /* perform an AGIOS call */
char *buf; /* sequence of bytes in command */
int len; /* length of command in bytes */
{
r.x.ax = 0x4403; /* I/O ctrl write */
r.x.bx = 1; /* console handle */
r.x.cx = len; /* buffer length */
r.x.dx = (unsigned)buf; /* buffer address */
return(intdos(&r, &r)); /* do it */
}
PASCAL NEAR keycon() /* turn keycode mode on */
{
static char cmd[] = {43, 0, 1};
return(agios(&cmd[0], 3));
}
PASCAL NEAR keycoff() /* turn keycode mode off */
{
static char cmd[] = {43, 0, 0};
return(agios(&cmd[0], 3));
}
PASCAL NEAR defkey() /* change all special keys to intercept mode */
{
static char cmd[] = {40, 0, 2, 0, 0xfe, 0};
return(agios(&cmd[0], 6));
}
PASCAL NEAR undefkey() /* change all special keys to intercept mode */
{
static char cmd[] = {40, 0, 0, 0, 0xfe, 0};
return(agios(&cmd[0], 6));
}
PASCAL NEAR dsplbls() /* display the application softkey labels on the screen */
{
static char cmd[] = {11, 0};
return(agios(&cmd[0], 2));
}
#if FLABEL
PASCAL NEAR fnclabel(f, n) /* label a function key */
int f,n; /* default flag, numeric argument */
{
register int status; /* return status */
register int i; /* loop index */
char lbl[17]; /* returned label contents */
/* AGIOS command buffer */
static char cmd[] = {8, 0, 1, 0, 7, 7, 7, 7, 10, 0, 10, 0};
/* code key# ptr to top bottom
label string attribute */
union { /* union to cast ptr into AGIOS arg string */
char *ptr; /* pointer to arg string */
char cstr[4];
} ptru;
/* must have a numeric argument */
if (f == FALSE) {
mlwrite(TEXT159);
/* "%Need function key number" */
return(FALSE);
}
/* and it must be a legal key number */
if (n < 1 || n > 8) {
mlwrite(TEXT160);
/* "%Function key number out of range" */
return(FALSE);
}
/* get the string to send */
status = mlreply(TEXT161, &lbl[0], 17);
/* "Label contents: " */
if (status != TRUE)
return(status);
/* pad the label out */
for (i=0; i < 17; i++) {
if (lbl[i] == 0)
break;
}
for (; i < 16; i++)
lbl[i] = ' ';
lbl[16] = 0;
/* set up the parameters */
cmd[2] = n; /* function key number */
ptru.ptr = &lbl[0]; /* set up pointer to label string */
force: cmd[4] = ptru.cstr[0];
cmd[5] = ptru.cstr[1];
cmd[6] = ptru.cstr[2];
cmd[7] = ptru.cstr[3];
/* and send it out */
agios(&cmd[0], 12);
return(TRUE);
}
#endif
#else
PASCAL NEAR h15hello()
{
}
#endif