|
|
1.1 root 1: /*
2:
3: Copyright 1991,1992 Eric R. Smith. All rights reserved.
4:
5: */
6:
7:
8:
9: /* simple biosfs.c */
10:
11:
12:
13: #include "mint.h"
14:
15:
16:
17: extern struct kerinfo kernelinfo; /* see main.c */
18:
19:
20:
21: static long bios_root P_((int drv, fcookie *fc));
22:
23: static long bios_lookup P_((fcookie *dir, const char *name, fcookie *fc));
24:
25: static long bios_getxattr P_((fcookie *fc, XATTR *xattr));
26:
27: static long bios_chattr P_((fcookie *fc, int attrib));
28:
29: static long bios_chown P_((fcookie *fc, int uid, int gid));
30:
31: static long bios_chmode P_((fcookie *fc, unsigned mode));
32:
33: static long bios_rmdir P_((fcookie *dir, const char *name));
34:
35: static long bios_remove P_((fcookie *dir, const char *name));
36:
37: static long bios_getname P_((fcookie *root, fcookie *dir, char *pathname));
38:
39: static long bios_rename P_((fcookie *olddir, char *oldname,
40:
41: fcookie *newdir, const char *newname));
42:
43: static long bios_opendir P_((DIR *dirh, int flags));
44:
45: static long bios_readdir P_((DIR *dirh, char *nm, int nmlen, fcookie *fc));
46:
47: static long bios_rewinddir P_((DIR *dirh));
48:
49: static long bios_closedir P_((DIR *dirh));
50:
51: static long bios_pathconf P_((fcookie *dir, int which));
52:
53: static long bios_dfree P_((fcookie *dir, long *buf));
54:
55: static DEVDRV * bios_getdev P_((fcookie *fc, long *devspecial));
56:
57: static long bios_fscntl P_((fcookie *, const char *, int, long));
58:
59: static long bios_symlink P_((fcookie *, const char *, const char *));
60:
61: static long bios_readlink P_((fcookie *, char *, int));
62:
63:
64:
65: static long bios_topen P_((FILEPTR *f));
66:
67: static long bios_twrite P_((FILEPTR *f, const char *buf, long bytes));
68:
69: static long bios_tread P_((FILEPTR *f, char *buf, long bytes));
70:
71: static long bios_nwrite P_((FILEPTR *f, const char *buf, long bytes));
72:
73: static long bios_nread P_((FILEPTR *f, char *buf, long bytes));
74:
75: static long bios_ioctl P_((FILEPTR *f, int mode, void *buf));
76:
77: static long bios_select P_((FILEPTR *f, long p, int mode));
78:
79: static void bios_unselect P_((FILEPTR *f, long p, int mode));
80:
81: static long bios_tseek P_((FILEPTR *f, long where, int whence));
82:
83:
84:
85: long null_open P_((FILEPTR *f));
86:
87: long null_write P_((FILEPTR *f, const char *buf, long bytes));
88:
89: long null_read P_((FILEPTR *f, char *buf, long bytes));
90:
91: long null_lseek P_((FILEPTR *f, long where, int whence));
92:
93: long null_ioctl P_((FILEPTR *f, int mode, void *buf));
94:
95: long null_datime P_((FILEPTR *f, short *time, int rwflag));
96:
97: long null_close P_((FILEPTR *f, int pid));
98:
99: long null_select P_((FILEPTR *f, long p, int mode));
100:
101: void null_unselect P_((FILEPTR *f, long p, int mode));
102:
103:
104:
105: static long mouse_open P_((FILEPTR *f));
106:
107: static long mouse_read P_((FILEPTR *f, char *buf, long nbytes));
108:
109: static long mouse_ioctl P_((FILEPTR *f, int mode, void *buf));
110:
111: static long mouse_close P_((FILEPTR *f, int pid));
112:
113: static long mouse_select P_((FILEPTR *f, long p, int mode));
114:
115: static void mouse_unselect P_((FILEPTR *f, long p, int mode));
116:
117:
118:
119: /* device driver for BIOS terminals */
120:
121:
122:
123: DEVDRV bios_tdevice = {
124:
125: bios_topen, bios_twrite, bios_tread, bios_tseek, bios_ioctl,
126:
127: null_datime, null_close, bios_select, bios_unselect
128:
129: };
130:
131:
132:
133: /* device driver for BIOS devices that are not terminals */
134:
135:
136:
137: DEVDRV bios_ndevice = {
138:
139: null_open, bios_nwrite, bios_nread, null_lseek, bios_ioctl,
140:
141: null_datime, null_close, bios_select, bios_unselect
142:
143: };
144:
145:
146:
147: DEVDRV null_device = {
148:
149: null_open, null_write, null_read, null_lseek, null_ioctl,
150:
151: null_datime, null_close, null_select, null_unselect
152:
153: };
154:
155:
156:
157: DEVDRV mouse_device = {
158:
159: mouse_open, null_write, mouse_read, null_lseek, mouse_ioctl,
160:
161: null_datime, mouse_close, mouse_select, mouse_unselect
162:
163: };
164:
165:
166:
167: /* this special driver is checked for in dosfile.c, and indicates that
168:
169: * a dup operation is actually wanted rather than an open
170:
171: */
172:
173: DEVDRV fakedev;
174:
175:
176:
177: #ifdef FASTTEXT
178:
179: extern DEVDRV screen_device; /* see fasttext.c */
180:
181: #endif
182:
183:
184:
185: FILESYS bios_filesys = {
186:
187: (FILESYS *)0,
188:
189: 0,
190:
191: bios_root,
192:
193: bios_lookup, nocreat, bios_getdev, bios_getxattr,
194:
195: bios_chattr, bios_chown, bios_chmode,
196:
197: nomkdir, bios_rmdir, bios_remove, bios_getname, bios_rename,
198:
199: bios_opendir, bios_readdir, bios_rewinddir, bios_closedir,
200:
201: bios_pathconf, bios_dfree, nowritelabel, noreadlabel,
202:
203: bios_symlink, bios_readlink, nohardlink, bios_fscntl, nodskchng
204:
205: };
206:
207:
208:
209:
210:
211: struct tty con_tty, aux_tty, midi_tty;
212:
213: struct tty sccb_tty, scca_tty, ttmfp_tty;
214:
215:
216:
217: #define BNAME_MAX 13
218:
219:
220:
221: struct bios_file {
222:
223: char name[BNAME_MAX+1]; /* device name */
224:
225: DEVDRV *device; /* device driver for device */
226:
227: short private; /* extra info for device driver */
228:
229: ushort flags; /* flags for device open */
230:
231: struct tty *tty; /* tty structure (if appropriate) */
232:
233: struct bios_file *next;
234:
235: };
236:
237:
238:
239: struct bios_file BDEV[] = {
240:
241:
242:
243: /* "real" bios devices present on all machines */
244:
245: {"centr", &bios_ndevice, 0, 0, 0, 0},
246:
247: {"console", &bios_tdevice, 2, O_TTY, &con_tty, 0},
248:
249: {"midi", &bios_tdevice, 3, O_TTY, &midi_tty, 0},
250:
251: {"kbd", &bios_ndevice, 4, 0, 0, 0},
252:
253: /* devices that duplicate handles */
254:
255: {"prn", &fakedev, -3, 0, 0, 0}, /* handle -3 (printer) */
256:
257: {"aux", &fakedev, -2, 0, 0, 0}, /* handle -2 (aux. terminal) */
258:
259: {"con", &fakedev, -1, 0, 0, 0}, /* handle -1 (control terminal) */
260:
261: {"tty", &fakedev, -1, 0, 0, 0}, /* the Unix name for it */
262:
263: {"stdin", &fakedev, 0, 0, 0, 0}, /* handle 0 (stdin) */
264:
265: {"stdout", &fakedev, 1, 0, 0, 0}, /* handle 1 (stdout) */
266:
267: {"stderr", &fakedev, 2, 0, 0, 0}, /* handle 2 (stderr) */
268:
269:
270:
271: /* other miscellaneous devices */
272:
273: {"mouse", &mouse_device, 0, 0, 0, 0},
274:
275: {"null", &null_device, 0, 0, 0, 0},
276:
277:
278:
279: #ifdef FASTTEXT
280:
281: /* alternate console driver */
282:
283: {"fasttext", &screen_device, 2, O_TTY, &con_tty, 0},
284:
285: #endif
286:
287:
288:
289: /* serial port things *must* come last, because not all of these
290:
291: * are present on all machines (except for modem1, which does however
292:
293: * have a different device number on TTs and STs)
294:
295: */
296:
297: {"modem1", &bios_tdevice, 6, O_TTY, &aux_tty, 0},
298:
299: {"modem2", &bios_tdevice, 7, O_TTY, &sccb_tty, 0},
300:
301: {"serial1", &bios_tdevice, 8, O_TTY, &ttmfp_tty, 0},
302:
303: {"serial2", &bios_tdevice, 9, O_TTY, &scca_tty, 0},
304:
305: {"", 0, 0, 0, 0, 0}
306:
307: };
308:
309:
310:
311: struct bios_file *broot, *bdevlast;
312:
313:
314:
315: /* a file pointer for BIOS device 1, provided only for insurance
316:
317: * in case a Bconmap happens and we can't allocate a new FILEPTR;
318:
319: * in most cases, we'll want to build a FILEPTR in the usual
320:
321: * way.
322:
323: */
324:
325:
326:
327: FILEPTR *defaultaux;
328:
329:
330:
331: void
332:
333: biosfs_init()
334:
335: {
336:
337: struct bios_file *b;
338:
339:
340:
341: broot = BDEV;
342:
343:
344:
345: for (b = broot; b->name[0]; b++) {
346:
347: b->next = b+1;
348:
349:
350:
351: /* if not a TT or Mega STE, adjust the MODEM1 device to be BIOS
352:
353: * device 1
354:
355: * and ignore the remaining devices, since they're not present
356:
357: */
358:
359: if (!has_bconmap && b->private == 6) {
360:
361: b->private = 1;
362:
363: b->next = 0;
364:
365: break;
366:
367: }
368:
369: /* SERIAL2 is not present on the Mega STe */
370:
371: if (mch == MEGASTE && b->private == 8) {
372:
373: b->next = 0;
374:
375: break;
376:
377: }
378:
379:
380:
381: }
382:
383: bdevlast = b;
384:
385: if (b->name[0] == 0) {
386:
387: --b;
388:
389: b->next = 0;
390:
391: }
392:
393: defaultaux = new_fileptr();
394:
395: defaultaux->links = 1; /* so it never gets freed */
396:
397: defaultaux->flags = O_RDWR;
398:
399: defaultaux->pos = 0;
400:
401: defaultaux->devinfo = 0;
402:
403: defaultaux->fc.fs = &bios_filesys;
404:
405: defaultaux->fc.index = 0;
406:
407: defaultaux->fc.aux = 1;
408:
409: defaultaux->fc.dev = BIOSDRV;
410:
411: defaultaux->dev = &bios_ndevice;
412:
413: }
414:
415:
416:
417: static long
418:
419: bios_root(drv, fc)
420:
421: int drv;
422:
423: fcookie *fc;
424:
425: {
426:
427: if (drv == BIOSDRV) {
428:
429: fc->fs = &bios_filesys;
430:
431: fc->dev = drv;
432:
433: fc->index = 0L;
434:
435: return 0;
436:
437: }
438:
439: fc->fs = 0;
440:
441: return EINTRN;
442:
443: }
444:
445:
446:
447: static long
448:
449: bios_lookup(dir, name, fc)
450:
451: fcookie *dir;
452:
453: const char *name;
454:
455: fcookie *fc;
456:
457: {
458:
459: struct bios_file *b;
460:
461:
462:
463: TRACE("bios_lookup(%s)", name);
464:
465:
466:
467: if (dir->index != 0) {
468:
469: DEBUG("bios_lookup: bad directory");
470:
471: return EPTHNF;
472:
473: }
474:
475: /* special case: an empty name in a directory means that directory */
476:
477: /* so does "." */
478:
479: if (!*name || (name[0] == '.' && name[1] == 0)) {
480:
481: *fc = *dir;
482:
483: return 0;
484:
485: }
486:
487:
488:
489: /* another special case: ".." could be a mount point */
490:
491: if (!strcmp(name, "..")) {
492:
493: *fc = *dir;
494:
495: return EMOUNT;
496:
497: }
498:
499:
500:
501: for (b = broot; b; b = b->next) {
502:
503: if (!stricmp(b->name, name)) {
504:
505: fc->fs = &bios_filesys;
506:
507: fc->index = (long)b;
508:
509: fc->aux = b->private;
510:
511: fc->dev = dir->dev;
512:
513: return 0;
514:
515: }
516:
517: }
518:
519: DEBUG("bios_lookup: name(%s) not found", name);
520:
521: return EFILNF;
522:
523: }
524:
525:
526:
527: static long
528:
529: bios_getxattr(fc, xattr)
530:
531: fcookie *fc;
532:
533: XATTR *xattr;
534:
535: {
536:
537: struct bios_file *b = (struct bios_file *)fc->index;
538:
539:
540:
541: xattr->index = fc->index;
542:
543: xattr->dev = fc->dev;
544:
545: xattr->nlink = 1;
546:
547: xattr->uid = xattr->gid = 0;
548:
549: xattr->size = xattr->nblocks = 0;
550:
551: xattr->blksize = 1;
552:
553: xattr->mtime = xattr->atime = xattr->ctime = timestamp;
554:
555: xattr->mdate = xattr->adate = xattr->cdate = datestamp;
556:
557: if (fc->index == 0) { /* root directory? */
558:
559: xattr->mode = S_IFDIR | DEFAULT_DIRMODE;
560:
561: xattr->attr = FA_DIR;
562:
563: } else if (b->device == 0) { /* symbolic link? */
564:
565: xattr->mode = S_IFLNK | DEFAULT_DIRMODE;
566:
567: } else {
568:
569: /* BUG: U:\DEV\STDIN, U:\DEV\STDOUT, etc. might not be terminal files */
570:
571: xattr->mode = S_IFCHR | DEFAULT_MODE;
572:
573: xattr->attr = 0;
574:
575: }
576:
577: return 0;
578:
579: }
580:
581:
582:
583: static long
584:
585: bios_chattr(fc, attrib)
586:
587: fcookie *fc;
588:
589: int attrib;
590:
591: {
592:
593: return EACCDN;
594:
595: }
596:
597:
598:
599: static long
600:
601: bios_chown(fc, uid, gid)
602:
603: fcookie *fc;
604:
605: int uid, gid;
606:
607: {
608:
609: return EINVFN;
610:
611: }
612:
613:
614:
615: static long
616:
617: bios_chmode(fc, mode)
618:
619: fcookie *fc;
620:
621: unsigned mode;
622:
623: {
624:
625: return EINVFN;
626:
627: }
628:
629:
630:
631: long
632:
633: nomkdir(dir, name, mode)
634:
635: fcookie *dir;
636:
637: const char *name;
638:
639: unsigned mode;
640:
641: {
642:
643: return EACCDN;
644:
645: }
646:
647:
648:
649: static long
650:
651: bios_rmdir(dir, name)
652:
653: fcookie *dir;
654:
655: const char *name;
656:
657: {
658:
659: return bios_remove(dir, name);
660:
661: }
662:
663:
664:
665: /*
666:
667: * MAJOR BUG: we don't check here for removal of devices for which there
668:
669: * are still open files
670:
671: */
672:
673:
674:
675: static long
676:
677: bios_remove(dir, name)
678:
679: fcookie *dir;
680:
681: const char *name;
682:
683: {
684:
685: struct bios_file *b, **lastb;
686:
687:
688:
689: lastb = &broot;
690:
691: for (b = broot; b; b = *(lastb = &b->next)) {
692:
693: if (!stricmp(b->name, name)) break;
694:
695: }
696:
697: if (!b) return EFILNF;
698:
699:
700:
701: /* don't allow removal of the basic system devices */
702:
703: if (b >= BDEV && b <= bdevlast) {
704:
705: return EACCDN;
706:
707: }
708:
709: *lastb = b->next;
710:
711:
712:
713: if (b->device == 0 || b->device == &bios_tdevice)
714:
715: kfree(b->tty);
716:
717:
718:
719: kfree(b);
720:
721: return 0;
722:
723: }
724:
725:
726:
727: static long
728:
729: bios_getname(root, dir, pathname)
730:
731: fcookie *root, *dir; char *pathname;
732:
733: {
734:
735: if (dir->index == 0)
736:
737: *pathname = 0;
738:
739: else
740:
741: strcpy(pathname, ((struct bios_file *)dir->index)->name);
742:
743: return 0;
744:
745: }
746:
747:
748:
749: static long
750:
751: bios_rename(olddir, oldname, newdir, newname)
752:
753: fcookie *olddir;
754:
755: char *oldname;
756:
757: fcookie *newdir;
758:
759: const char *newname;
760:
761: {
762:
763: struct bios_file *b;
764:
765:
766:
767: /* BUG: we should check to see if "newname" already exists */
768:
769:
770:
771: for (b = broot; b; b = b->next) {
772:
773: if (!stricmp(b->name, oldname)) {
774:
775: strncpy(b->name, newname, BNAME_MAX);
776:
777: return 0;
778:
779: }
780:
781: }
782:
783: return EFILNF;
784:
785: }
786:
787:
788:
789: static long
790:
791: bios_opendir(dirh, flags)
792:
793: DIR *dirh;
794:
795: int flags;
796:
797: {
798:
799: if (dirh->fc.index != 0) {
800:
801: DEBUG("bios_opendir: bad directory");
802:
803: return EPTHNF;
804:
805: }
806:
807: return 0;
808:
809: }
810:
811:
812:
813: static long
814:
815: bios_readdir(dirh, name, namelen, fc)
816:
817: DIR *dirh;
818:
819: char *name;
820:
821: int namelen;
822:
823: fcookie *fc;
824:
825: {
826:
827: struct bios_file *b;
828:
829: int giveindex = dirh->flags == 0;
830:
831: int i;
832:
833:
834:
835: b = broot;
836:
837: i = dirh->index++;
838:
839: while(i-- > 0) {
840:
841: if (!b) break;
842:
843: b = b->next;
844:
845: }
846:
847: if (!b) {
848:
849: return ENMFIL;
850:
851: }
852:
853: fc->fs = &bios_filesys;
854:
855: fc->index = (long)b;
856:
857: fc->aux = b->private;
858:
859: fc->dev = dirh->fc.dev;
860:
861: if (giveindex) {
862:
863: namelen -= sizeof(long);
864:
865: if (namelen <= 0)
866:
867: return ERANGE;
868:
869: *((long *)name) = (long) b;
870:
871: name += sizeof(long);
872:
873: }
874:
875: strncpy(name, b->name, namelen-1);
876:
877: if (strlen(b->name) >= namelen)
878:
879: return ENAMETOOLONG;
880:
881: return 0;
882:
883: }
884:
885:
886:
887: static long
888:
889: bios_rewinddir(dirh)
890:
891: DIR *dirh;
892:
893: {
894:
895: dirh->index = 0;
896:
897: return 0;
898:
899: }
900:
901:
902:
903: static long
904:
905: bios_closedir(dirh)
906:
907: DIR *dirh;
908:
909: {
910:
911: return 0;
912:
913: }
914:
915:
916:
917: static long
918:
919: bios_pathconf(dir, which)
920:
921: fcookie *dir;
922:
923: int which;
924:
925: {
926:
927: switch(which) {
928:
929: case -1:
930:
931: return DP_MAXREQ;
932:
933: case DP_IOPEN:
934:
935: return UNLIMITED; /* no limit on BIOS file descriptors */
936:
937: case DP_MAXLINKS:
938:
939: return 1; /* no hard links available */
940:
941: case DP_PATHMAX:
942:
943: return PATH_MAX;
944:
945: case DP_NAMEMAX:
946:
947: return BNAME_MAX;
948:
949: case DP_ATOMIC:
950:
951: return 1; /* no atomic writes */
952:
953: case DP_TRUNC:
954:
955: return DP_AUTOTRUNC; /* names are truncated */
956:
957: case DP_CASE:
958:
959: return DP_CASEINSENS; /* not case sensitive */
960:
961: default:
962:
963: return EINVFN;
964:
965: }
966:
967: }
968:
969:
970:
971: static long
972:
973: bios_dfree(dir, buf)
974:
975: fcookie *dir;
976:
977: long *buf;
978:
979: {
980:
981: buf[0] = 0; /* number of free clusters */
982:
983: buf[1] = 0; /* total number of clusters */
984:
985: buf[2] = 1; /* sector size (bytes) */
986:
987: buf[3] = 1; /* cluster size (sectors) */
988:
989: return 0;
990:
991: }
992:
993:
994:
995: /*
996:
997: * BIOS Dcntl() calls:
998:
999: * Dcntl(0xde02, "U:\DEV\FOO", &foo_descr): install a new device called
1000:
1001: * "FOO", which is described by the dev_descr structure "foo_descr".
1002:
1003: * this structure has the following fields:
1004:
1005: * DEVDRV *driver the device driver itself
1006:
1007: * short dinfo info for the device driver
1008:
1009: * short flags flags for the file (e.g. O_TTY)
1010:
1011: * struct tty *tty tty structure, if appropriate
1012:
1013: *
1014:
1015: * Dcntl(0xde00, "U:\DEV\BAR", n): install a new BIOS terminal device, with
1016:
1017: * BIOS device number "n".
1018:
1019: * Dcntl(0xde01, "U:\DEV\BAR", n): install a new non-tty BIOS device, with
1020:
1021: * BIOS device number "n".
1022:
1023: */
1024:
1025:
1026:
1027: static long
1028:
1029: bios_fscntl(dir, name, cmd, arg)
1030:
1031: fcookie *dir;
1032:
1033: const char *name;
1034:
1035: int cmd;
1036:
1037: long arg;
1038:
1039: {
1040:
1041: struct bios_file *b;
1042:
1043:
1044:
1045: if (cmd == DEV_INSTALL) {
1046:
1047: struct dev_descr *d = (struct dev_descr *)arg;
1048:
1049:
1050:
1051: b = kmalloc(SIZEOF(struct bios_file));
1052:
1053: if (!b) return 0;
1054:
1055: strncpy(b->name, name, BNAME_MAX);
1056:
1057: b->name[BNAME_MAX] = 0;
1058:
1059: b->device = d->driver;
1060:
1061: b->private = d->dinfo;
1062:
1063: b->flags = d->flags;
1064:
1065: b->tty = d->tty;
1066:
1067: b->next = broot;
1068:
1069: broot = b;
1070:
1071: return (long)&kernelinfo;
1072:
1073: }
1074:
1075: if (cmd == DEV_NEWTTY) {
1076:
1077: b = kmalloc(SIZEOF(struct bios_file));
1078:
1079: if (!b) return ENSMEM;
1080:
1081: b->tty = kmalloc(SIZEOF(struct tty));
1082:
1083: if (!b->tty) {
1084:
1085: kfree(b);
1086:
1087: return ENSMEM;
1088:
1089: }
1090:
1091: strncpy(b->name, name, BNAME_MAX);
1092:
1093: b->name[BNAME_MAX] = 0;
1094:
1095: b->device = &bios_tdevice;
1096:
1097: b->private = arg;
1098:
1099: b->flags = O_TTY;
1100:
1101: *b->tty = default_tty;
1102:
1103: b->next = broot;
1104:
1105: broot = b;
1106:
1107: return 0;
1108:
1109: }
1110:
1111: if (cmd == DEV_NEWBIOS) {
1112:
1113: b = kmalloc(SIZEOF(struct bios_file));
1114:
1115: if (!b) return ENSMEM;
1116:
1117: strncpy(b->name, name, BNAME_MAX);
1118:
1119: b->name[BNAME_MAX] = 0;
1120:
1121: b->tty = 0;
1122:
1123: b->device = &bios_ndevice;
1124:
1125: b->private = arg;
1126:
1127: b->flags = 0;
1128:
1129: b->next = broot;
1130:
1131: return 0;
1132:
1133: }
1134:
1135: return EINVFN;
1136:
1137: }
1138:
1139:
1140:
1141: static long
1142:
1143: bios_symlink(dir, name, to)
1144:
1145: fcookie *dir;
1146:
1147: const char *name, *to;
1148:
1149: {
1150:
1151: struct bios_file *b;
1152:
1153: long r;
1154:
1155: fcookie fc;
1156:
1157:
1158:
1159: r = bios_lookup(dir, name, &fc);
1160:
1161: if (r == 0) return EACCDN; /* file already exists */
1162:
1163: if (r != EFILNF) return r; /* some other error */
1164:
1165:
1166:
1167: b = kmalloc(SIZEOF(struct bios_file));
1168:
1169: if (!b) return EACCDN;
1170:
1171:
1172:
1173: strncpy(b->name, name, BNAME_MAX);
1174:
1175: b->name[BNAME_MAX] = 0;
1176:
1177: b->device = 0;
1178:
1179: b->private = EINVFN;
1180:
1181: b->flags = 0;
1182:
1183: b->tty = kmalloc((long)strlen(to)+1);
1184:
1185: if (!b->tty) {
1186:
1187: kfree(b);
1188:
1189: return EACCDN;
1190:
1191: }
1192:
1193: strcpy((char *)b->tty, to);
1194:
1195: b->next = broot;
1196:
1197: broot = b;
1198:
1199: return 0;
1200:
1201: }
1202:
1203:
1204:
1205: static long
1206:
1207: bios_readlink(fc, buf, buflen)
1208:
1209: fcookie *fc;
1210:
1211: char *buf;
1212:
1213: int buflen;
1214:
1215: {
1216:
1217: struct bios_file *b = (struct bios_file *)fc->index;
1218:
1219:
1220:
1221: if (!b) return EINVFN;
1222:
1223: if (b->device) return EINVFN;
1224:
1225:
1226:
1227: strncpy(buf, (char *)b->tty, buflen);
1228:
1229: if (strlen((char *)b->tty) >= buflen)
1230:
1231: return ENAMETOOLONG;
1232:
1233: return 0;
1234:
1235: }
1236:
1237:
1238:
1239:
1240:
1241: /*
1242:
1243: * routines for file systems that don't support volume labels
1244:
1245: */
1246:
1247:
1248:
1249: long
1250:
1251: nowritelabel(dir, name)
1252:
1253: fcookie *dir;
1254:
1255: const char *name;
1256:
1257: {
1258:
1259: return EACCDN;
1260:
1261: }
1262:
1263:
1264:
1265: long
1266:
1267: noreadlabel(dir, name, namelen)
1268:
1269: fcookie *dir;
1270:
1271: char *name;
1272:
1273: int namelen;
1274:
1275: {
1276:
1277: return EFILNF;
1278:
1279: }
1280:
1281:
1282:
1283: /*
1284:
1285: * routines for file systems that don't support links
1286:
1287: */
1288:
1289:
1290:
1291: long
1292:
1293: nosymlink(dir, name, to)
1294:
1295: fcookie *dir;
1296:
1297: const char *name, *to;
1298:
1299: {
1300:
1301: return EINVFN;
1302:
1303: }
1304:
1305:
1306:
1307: long
1308:
1309: noreadlink(dir, buf, buflen)
1310:
1311: fcookie *dir;
1312:
1313: char *buf;
1314:
1315: int buflen;
1316:
1317: {
1318:
1319: return EINVFN;
1320:
1321: }
1322:
1323:
1324:
1325: long
1326:
1327: nohardlink(fromdir, fromname, todir, toname)
1328:
1329: fcookie *fromdir, *todir;
1330:
1331: const char *fromname, *toname;
1332:
1333: {
1334:
1335: return EINVFN;
1336:
1337: }
1338:
1339:
1340:
1341: /* dummy routine for file systems with no Fscntl commands */
1342:
1343:
1344:
1345: long
1346:
1347: nofscntl(dir, name, cmd, arg)
1348:
1349: fcookie *dir;
1350:
1351: const char *name;
1352:
1353: int cmd;
1354:
1355: long arg;
1356:
1357: {
1358:
1359: return EINVFN;
1360:
1361: }
1362:
1363:
1364:
1365: /*
1366:
1367: * Did the disk change? Not on this drive!
1368:
1369: * However, we have to do Getbpb anyways, because someone has decided
1370:
1371: * to force a media change on our (non-existent) drive.
1372:
1373: */
1374:
1375: long
1376:
1377: nodskchng(drv)
1378:
1379: int drv;
1380:
1381: {
1382:
1383: (void)getbpb(drv);
1384:
1385: return 0;
1386:
1387: }
1388:
1389:
1390:
1391: long
1392:
1393: nocreat(dir, name, mode, attrib, fc)
1394:
1395: fcookie *dir, *fc;
1396:
1397: const char *name;
1398:
1399: unsigned mode;
1400:
1401: int attrib;
1402:
1403: {
1404:
1405: return EACCDN;
1406:
1407: }
1408:
1409:
1410:
1411: static DEVDRV *
1412:
1413: bios_getdev(fc, devsp)
1414:
1415: fcookie *fc;
1416:
1417: long *devsp;
1418:
1419: {
1420:
1421: struct bios_file *b;
1422:
1423:
1424:
1425: b = (struct bios_file *)fc->index;
1426:
1427:
1428:
1429: if (b->device && b->device != &fakedev)
1430:
1431: *devsp = (long)b->tty;
1432:
1433: else
1434:
1435: *devsp = b->private;
1436:
1437:
1438:
1439: return b->device; /* return the device driver */
1440:
1441: }
1442:
1443:
1444:
1445: /*
1446:
1447: * NULL device driver
1448:
1449: */
1450:
1451:
1452:
1453: long
1454:
1455: null_open(f)
1456:
1457: FILEPTR *f;
1458:
1459: {
1460:
1461: return 0;
1462:
1463: }
1464:
1465:
1466:
1467: long
1468:
1469: null_write(f, buf, bytes)
1470:
1471: FILEPTR *f; const char *buf; long bytes;
1472:
1473: {
1474:
1475: return bytes;
1476:
1477: }
1478:
1479:
1480:
1481: long
1482:
1483: null_read(f, buf, bytes)
1484:
1485: FILEPTR *f; char *buf; long bytes;
1486:
1487: {
1488:
1489: return 0;
1490:
1491: }
1492:
1493:
1494:
1495: long
1496:
1497: null_lseek(f, where, whence)
1498:
1499: FILEPTR *f; long where; int whence;
1500:
1501: {
1502:
1503: return (where == 0) ? 0 : ERANGE;
1504:
1505: }
1506:
1507:
1508:
1509: long
1510:
1511: null_ioctl(f, mode, buf)
1512:
1513: FILEPTR *f; int mode; void *buf;
1514:
1515: {
1516:
1517: if (mode == FIONREAD) {
1518:
1519: *((long *)buf) = 0;
1520:
1521: }
1522:
1523: else if (mode == FIONWRITE)
1524:
1525: *((long *)buf) = 1;
1526:
1527: else
1528:
1529: return EINVFN;
1530:
1531: return 0;
1532:
1533: }
1534:
1535:
1536:
1537: long
1538:
1539: null_datime(f, timeptr, rwflag)
1540:
1541: FILEPTR *f;
1542:
1543: short *timeptr;
1544:
1545: int rwflag;
1546:
1547: {
1548:
1549: if (rwflag)
1550:
1551: return EACCDN;
1552:
1553: *timeptr++ = timestamp;
1554:
1555: *timeptr = datestamp;
1556:
1557: return 0;
1558:
1559: }
1560:
1561:
1562:
1563: long
1564:
1565: null_close(f, pid)
1566:
1567: FILEPTR *f;
1568:
1569: int pid;
1570:
1571: {
1572:
1573: return 0;
1574:
1575: }
1576:
1577:
1578:
1579: long
1580:
1581: null_select(f, p, mode)
1582:
1583: FILEPTR *f; long p;
1584:
1585: int mode;
1586:
1587: {
1588:
1589: return 1; /* we're always ready to read/write */
1590:
1591: }
1592:
1593:
1594:
1595: void
1596:
1597: null_unselect(f, p, mode)
1598:
1599: FILEPTR *f;
1600:
1601: long p;
1602:
1603: int mode;
1604:
1605: {
1606:
1607: /* nothing to do */
1608:
1609: }
1610:
1611:
1612:
1613: /*
1614:
1615: * BIOS terminal device driver
1616:
1617: */
1618:
1619:
1620:
1621: static long
1622:
1623: bios_topen(f)
1624:
1625: FILEPTR *f;
1626:
1627: {
1628:
1629: f->flags |= O_TTY;
1630:
1631: return 0;
1632:
1633: }
1634:
1635:
1636:
1637: /*
1638:
1639: * Note: when a BIOS device is a terminal (i.e. has the O_TTY flag
1640:
1641: * set), bios_read and bios_write will only ever be called indirectly, via
1642:
1643: * tty_read and tty_write. That's why we can afford to play a bit fast and
1644:
1645: * loose with the pointers ("buf" is really going to point to a long) and
1646:
1647: * why we know that "bytes" is divisible by 4.
1648:
1649: */
1650:
1651:
1652:
1653: static long
1654:
1655: bios_twrite(f, buf, bytes)
1656:
1657: FILEPTR *f; const char *buf; long bytes;
1658:
1659: {
1660:
1661: long *r;
1662:
1663: long ret = 0;
1664:
1665: int bdev = f->fc.aux;
1666:
1667:
1668:
1669: r = (long *)buf;
1670:
1671: while (bytes > 0) {
1672:
1673: if ( (f->flags & O_NDELAY) && !bcostat(bdev) )
1674:
1675: break;
1676:
1677:
1678:
1679: if (bconout(bdev, (int)*r) == 0)
1680:
1681: break;
1682:
1683:
1684:
1685: r++; bytes -= 4; ret+= 4;
1686:
1687: }
1688:
1689: (void)checkkeys();
1690:
1691: return ret;
1692:
1693: }
1694:
1695:
1696:
1697: static long
1698:
1699: bios_tread(f, buf, bytes)
1700:
1701: FILEPTR *f; char *buf; long bytes;
1702:
1703: {
1704:
1705: long *r, ret = 0;
1706:
1707: int bdev = f->fc.aux;
1708:
1709:
1710:
1711: r = (long *)buf;
1712:
1713:
1714:
1715: while (bytes > 0) {
1716:
1717: if ( (f->flags & O_NDELAY) && !bconstat(bdev) )
1718:
1719: break;
1720:
1721: *r++ = bconin(bdev) & 0x7fffffff;
1722:
1723: bytes -= 4; ret += 4;
1724:
1725: }
1726:
1727: return ret;
1728:
1729: }
1730:
1731:
1732:
1733: /*
1734:
1735: * read/write routines for BIOS devices that aren't terminals (like the
1736:
1737: * printer & IKBD devices)
1738:
1739: */
1740:
1741:
1742:
1743: static long
1744:
1745: bios_nwrite(f, buf, bytes)
1746:
1747: FILEPTR *f; const char *buf; long bytes;
1748:
1749: {
1750:
1751: long ret = 0;
1752:
1753: int bdev = f->fc.aux;
1754:
1755: int c;
1756:
1757:
1758:
1759: while (bytes > 0) {
1760:
1761: if ( (f->flags & O_NDELAY) && !bcostat(bdev) )
1762:
1763: break;
1764:
1765:
1766:
1767: c = *buf++ & 0x00ff;
1768:
1769:
1770:
1771: if (bconout(bdev, c) == 0)
1772:
1773: break;
1774:
1775:
1776:
1777: bytes--; ret++;
1778:
1779: }
1780:
1781: return ret;
1782:
1783: }
1784:
1785:
1786:
1787: static long
1788:
1789: bios_nread(f, buf, bytes)
1790:
1791: FILEPTR *f; char *buf; long bytes;
1792:
1793: {
1794:
1795: long ret = 0;
1796:
1797: int bdev = f->fc.aux;
1798:
1799:
1800:
1801: while (bytes > 0) {
1802:
1803: if ( (f->flags & O_NDELAY) && !bconstat(bdev) )
1804:
1805: break;
1806:
1807: *buf++ = bconin(bdev) & 0xff;
1808:
1809: bytes--; ret++;
1810:
1811: }
1812:
1813: return ret;
1814:
1815: }
1816:
1817:
1818:
1819: /*
1820:
1821: * BIOS terminal seek code -- this has to match the documented
1822:
1823: * way to do isatty()
1824:
1825: */
1826:
1827:
1828:
1829: static long
1830:
1831: bios_tseek(f, where, whence)
1832:
1833: FILEPTR *f;
1834:
1835: long where;
1836:
1837: int whence;
1838:
1839: {
1840:
1841: /* terminals always are at position 0 */
1842:
1843: return 0;
1844:
1845: }
1846:
1847:
1848:
1849: #define MAXBAUD 16
1850:
1851:
1852:
1853: static long baudmap[MAXBAUD] = {
1854:
1855: 19200L, 9600L, 4800L, 3600L, 2400L, 2000L, 1800L, 1200L,
1856:
1857: 600L, 300L, 200L, 150L, 134L, 110L, 75L, 50L
1858:
1859: };
1860:
1861:
1862:
1863: static long
1864:
1865: bios_ioctl(f, mode, buf)
1866:
1867: FILEPTR *f; int mode; void *buf;
1868:
1869: {
1870:
1871: long *r = (long *)buf;
1872:
1873: struct winsize *ws;
1874:
1875: char *aline;
1876:
1877: short dev;
1878:
1879: int i;
1880:
1881:
1882:
1883: if (mode == FIONREAD) {
1884:
1885: if (bconstat(f->fc.aux))
1886:
1887: *r = 1;
1888:
1889: else
1890:
1891: *r = 0;
1892:
1893: }
1894:
1895: else if (mode == FIONWRITE) {
1896:
1897: if (bcostat(f->fc.aux))
1898:
1899: *r = 1;
1900:
1901: else
1902:
1903: *r = 0;
1904:
1905: }
1906:
1907: else if (mode == TIOCFLUSH) {
1908:
1909: /* BUG: this should flush the input/output buffers */
1910:
1911: return 0;
1912:
1913: }
1914:
1915: else if (mode == TIOCGWINSZ && f->fc.aux == 2) {
1916:
1917: aline = lineA0();
1918:
1919: ws = (struct winsize *)buf;
1920:
1921: ws->ws_row = *((short *)(aline - 42)) + 1;
1922:
1923: ws->ws_col = *((short *)(aline - 44)) + 1;
1924:
1925: } else if (mode == TIOCIBAUD || mode == TIOCOBAUD) {
1926:
1927: long oldbaud, newbaud;
1928:
1929: dev = f->fc.aux;
1930:
1931:
1932:
1933: newbaud = *r;
1934:
1935: if (dev == 1 || dev >= 6) {
1936:
1937: if (has_bconmap)
1938:
1939: mapin((dev == 1) ? curproc->bconmap : dev);
1940:
1941: i = rsconf(-2, -1, -1, -1, -1, -1);
1942:
1943: if (i < 0 || i >= MAXBAUD)
1944:
1945: oldbaud = -1L;
1946:
1947: else
1948:
1949: oldbaud = baudmap[i];
1950:
1951: *r = oldbaud;
1952:
1953: if (newbaud > 0) {
1954:
1955: for (i = 0; i < MAXBAUD; i++) {
1956:
1957: if (baudmap[i] == newbaud) {
1958:
1959: rsconf(i, -1, -1, -1, -1, -1);
1960:
1961: return 0;
1962:
1963: }
1964:
1965: }
1966:
1967: return ERANGE;
1968:
1969: } else if (newbaud == 0L) {
1970:
1971: /* drop DTR: works only on modem1 */
1972:
1973: if (dev == 1 || dev == 6) {
1974:
1975: Ongibit(0x10);
1976:
1977: nap(30);
1978:
1979: Offgibit(0xef);
1980:
1981: }
1982:
1983: }
1984:
1985: return 0;
1986:
1987: } else if (dev == 2 || dev == 5) {
1988:
1989: /* screen: assume 9600 baud */
1990:
1991: oldbaud = 9600L;
1992:
1993: } else if (dev == 3) {
1994:
1995: /* midi */
1996:
1997: oldbaud = 31250L;
1998:
1999: } else {
2000:
2001: oldbaud = -1L; /* unknown speed */
2002:
2003: }
2004:
2005: *r = oldbaud;
2006:
2007: if (newbaud > 0 && newbaud != oldbaud)
2008:
2009: return ERANGE;
2010:
2011: return 0;
2012:
2013: } else if (mode == TIOCCBRK || mode == TIOCSBRK) {
2014:
2015: unsigned long bits;
2016:
2017:
2018:
2019: dev = f->fc.aux;
2020:
2021: if (dev == 1 || dev >= 6) {
2022:
2023: if (has_bconmap)
2024:
2025: mapin((dev == 1) ? curproc->bconmap : dev);
2026:
2027: } else {
2028:
2029: return EINVFN;
2030:
2031: }
2032:
2033: bits = rsconf(-1, -1, -1, -1, -1, -1); /* get settings */
2034:
2035: bits = (bits >> 8) & 0x0ff; /* isolate TSR byte */
2036:
2037: if (mode == TIOCCBRK)
2038:
2039: bits &= ~8;
2040:
2041: else
2042:
2043: bits |= 8;
2044:
2045: (void)rsconf(-1, -1, -1, -1, (int)bits, -1);
2046:
2047: } else if (mode == TIOCGFLAGS || mode == TIOCSFLAGS) {
2048:
2049: unsigned short oflags, flags;
2050:
2051: unsigned long bits;
2052:
2053: unsigned char ucr;
2054:
2055: short flow;
2056:
2057:
2058:
2059: dev = f->fc.aux;
2060:
2061: if (dev == 1 || dev >= 6) {
2062:
2063: oflags = ((struct tty *)f->devinfo)->sg.sg_flags;
2064:
2065: oflags &= (T_TANDEM|T_RTSCTS);
2066:
2067: if (has_bconmap)
2068:
2069: mapin((dev == 1) ? curproc->bconmap : dev);
2070:
2071: bits = rsconf(-1, -1, -1, -1, -1, -1); /* get settings */
2072:
2073: ucr = (bits >> 24L) & 0x0ff; /* isolate UCR byte */
2074:
2075: oflags |= (ucr >> 3) & (TF_STOPBITS|TF_CHARBITS);
2076:
2077: if (ucr & 0x4) { /* parity on? */
2078:
2079: oflags |= (ucr & 0x2) ? T_EVENP : T_ODDP;
2080:
2081: }
2082:
2083: if (mode == TIOCSFLAGS) {
2084:
2085: flags = (*(unsigned short *)buf);
2086:
2087: if (flags & T_EVENP) {
2088:
2089: ucr |= 0x6;
2090:
2091: } else if (flags & T_ODDP) {
2092:
2093: ucr &= ~2;
2094:
2095: ucr |= 0x4;
2096:
2097: } else {
2098:
2099: ucr &= ~6;
2100:
2101: }
2102:
2103: if (flags & TF_STOPBITS) {
2104:
2105: ucr &= ~(0x18);
2106:
2107: ucr |= (flags & TF_STOPBITS) << 3;
2108:
2109: }
2110:
2111: ucr &= ~(0x60);
2112:
2113: ucr |= (flags & TF_CHARBITS) << 3;
2114:
2115: flow = (flags & (T_RTSCTS|T_TANDEM)) >> 12L;
2116:
2117: rsconf(-1, flow, ucr, -1, -1, -1);
2118:
2119: } else {
2120:
2121: *((unsigned short *)buf) = oflags;
2122:
2123: }
2124:
2125: } else {
2126:
2127: return EINVFN;
2128:
2129: }
2130:
2131:
2132:
2133: } else {
2134:
2135: /* Fcntl will automatically call tty_ioctl to handle
2136:
2137: * terminal calls that we didn't deal with
2138:
2139: */
2140:
2141: return EINVFN;
2142:
2143: }
2144:
2145: return 0;
2146:
2147: }
2148:
2149:
2150:
2151: static long
2152:
2153: bios_select(f, p, mode)
2154:
2155: FILEPTR *f; long p; int mode;
2156:
2157: {
2158:
2159: struct tty *tty = (struct tty *)f->devinfo;
2160:
2161: int dev = f->fc.aux;
2162:
2163:
2164:
2165: if (mode == O_RDONLY) {
2166:
2167: if (bconstat(dev)) {
2168:
2169: TRACE("bios_select: data present for device %d", dev);
2170:
2171: return 1;
2172:
2173: }
2174:
2175: if (tty) {
2176:
2177: /* avoid collisions with other processes */
2178:
2179: if (!tty->rsel)
2180:
2181: tty->rsel = p;
2182:
2183: }
2184:
2185: return 0;
2186:
2187: } else if (mode == O_WRONLY) {
2188:
2189: if (bcostat(dev)) {
2190:
2191: TRACE("bios_select: ready to output on %d", dev);
2192:
2193: return 1;
2194:
2195: }
2196:
2197: if (tty) {
2198:
2199: if (!tty->wsel)
2200:
2201: tty->wsel = p;
2202:
2203: }
2204:
2205: return 0;
2206:
2207: }
2208:
2209: /* default -- we don't know this mode, return 0 */
2210:
2211: return 0;
2212:
2213: }
2214:
2215:
2216:
2217: static void
2218:
2219: bios_unselect(f, p, mode)
2220:
2221: FILEPTR *f;
2222:
2223: long p;
2224:
2225: int mode;
2226:
2227: {
2228:
2229: struct tty *tty = (struct tty *)f->devinfo;
2230:
2231:
2232:
2233: if (tty) {
2234:
2235: if (mode == O_RDONLY && tty->rsel == p)
2236:
2237: tty->rsel = 0;
2238:
2239: else if (mode == O_WRONLY && tty->wsel == p)
2240:
2241: tty->wsel = 0;
2242:
2243: }
2244:
2245: }
2246:
2247:
2248:
2249: /*
2250:
2251: * mouse device driver
2252:
2253: */
2254:
2255:
2256:
2257: #define MOUSESIZ 128*3
2258:
2259: static unsigned char mousebuf[MOUSESIZ];
2260:
2261: static int mousehead, mousetail;
2262:
2263:
2264:
2265: long mousersel; /* is someone calling select() on the mouse? */
2266:
2267:
2268:
2269: char mshift; /* shift key status; set by checkkeys() in bios.c */
2270:
2271: short *gcurx = 0,
2272:
2273: *gcury = 0; /* mouse pos. variables; used by big screen emulators */
2274:
2275:
2276:
2277: void
2278:
2279: mouse_handler(buf)
2280:
2281: const char *buf; /* must be a *signed* character */
2282:
2283: {
2284:
2285: unsigned char *mbuf, buttons;
2286:
2287: int newmtail;
2288:
2289: short dx, dy;
2290:
2291:
2292:
2293: /* the Sun mouse driver has 0=down, 1=up, while the atari hardware gives
2294:
2295: us the reverse. also, we have the "middle" button and the "left"
2296:
2297: button reversed; so we use this table to convert (and also to add the
2298:
2299: 0x80 to indicate a mouse packet)
2300:
2301: */
2302:
2303: static int _cnvrt[8] = {
2304:
2305: 0x87, 0x86, 0x83, 0x82, 0x85, 0x84, 0x81, 0x80
2306:
2307: };
2308:
2309:
2310:
2311: mbuf = &mousebuf[mousetail];
2312:
2313: newmtail = mousetail + 3;
2314:
2315: if (newmtail >= MOUSESIZ)
2316:
2317: newmtail = 0;
2318:
2319: if (newmtail == mousehead)
2320:
2321: return; /* buffer full */
2322:
2323:
2324:
2325: buttons = *buf++ & 0x7; /* convert to SUN format */
2326:
2327: if (mshift & 0x3) { /* a shift key held down? */
2328:
2329: /* if so, convert shift+button to a "middle" button */
2330:
2331: if (buttons == 0x1 || buttons == 0x2)
2332:
2333: buttons = 0x4;
2334:
2335: else if (buttons == 0x3)
2336:
2337: buttons = 0x7;
2338:
2339: }
2340:
2341: *mbuf++ = _cnvrt[buttons]; /* convert to Sun format */
2342:
2343: dx = *buf++;
2344:
2345: *mbuf++ = dx; /* copy X delta */
2346:
2347: dy = *buf++;
2348:
2349: *mbuf++ = -dy; /* invert Y delta for Sun format */
2350:
2351: mousetail = newmtail;
2352:
2353: *gcurx += dx; /* update line A variables */
2354:
2355: *gcury += dy;
2356:
2357: /*
2358:
2359: * if someone has called select() waiting for mouse input, wake them
2360:
2361: * up
2362:
2363: */
2364:
2365: if (mousersel) {
2366:
2367: wakeselect(mousersel);
2368:
2369: }
2370:
2371: }
2372:
2373:
2374:
2375: extern void newmvec(); /* in intr.s */
2376:
2377: static long oldvec = 0;
2378:
2379:
2380:
2381: static long
2382:
2383: mouse_open(f)
2384:
2385: FILEPTR *f;
2386:
2387: {
2388:
2389: char *aline;
2390:
2391:
2392:
2393: static char parameters[] = {
2394:
2395: 0, /* Y=0 in lower corner */
2396:
2397: 0, /* normal button handling */
2398:
2399: 1, 1 /* X, Y scaling factors */
2400:
2401: };
2402:
2403:
2404:
2405: if (oldvec) /* mouse in use */
2406:
2407: return EACCDN;
2408:
2409:
2410:
2411: /* initialize pointers to line A variables */
2412:
2413: if (!gcurx) {
2414:
2415: aline = lineA0();
2416:
2417: if (aline == 0) { /* should never happen */
2418:
2419: ALERT("unable to read line A variables");
2420:
2421: return -1;
2422:
2423: }
2424:
2425: gcurx = (short *)(aline - 0x25a);
2426:
2427: gcury = (short *)(aline - 0x258);
2428:
2429: *gcurx = *gcury = 32; /* magic number -- what MGR uses */
2430:
2431: }
2432:
2433:
2434:
2435: oldvec = syskey->mousevec;
2436:
2437: Initmous(1, parameters, newmvec);
2438:
2439: mousehead = mousetail = 0;
2440:
2441: return 0;
2442:
2443: }
2444:
2445:
2446:
2447: static long
2448:
2449: mouse_close(f, pid)
2450:
2451: FILEPTR *f;
2452:
2453: int pid;
2454:
2455: {
2456:
2457: static char parameters[] = {
2458:
2459: 0, /* Y=0 in lower corner */
2460:
2461: 0, /* normal button handling */
2462:
2463: 1, 1 /* X, Y scaling factors */
2464:
2465: };
2466:
2467:
2468:
2469: if (!f) return EIHNDL;
2470:
2471: if (f->links <= 0) {
2472:
2473: if (!oldvec) {
2474:
2475: DEBUG("Mouse not open!!");
2476:
2477: return -1;
2478:
2479: }
2480:
2481: Initmous(1, parameters, (void *)oldvec); /* gratuitous (void *) for Lattice */
2482:
2483: oldvec = 0;
2484:
2485: }
2486:
2487: return 0;
2488:
2489: }
2490:
2491:
2492:
2493: static long
2494:
2495: mouse_read(f, buf, nbytes)
2496:
2497: FILEPTR *f;
2498:
2499: char *buf;
2500:
2501: long nbytes;
2502:
2503: {
2504:
2505: long count = 0;
2506:
2507: int mhead;
2508:
2509: unsigned char *foo;
2510:
2511:
2512:
2513: mhead = mousehead;
2514:
2515: foo = &mousebuf[mhead];
2516:
2517:
2518:
2519: if (mhead == mousetail) {
2520:
2521: if (f->flags & O_NDELAY)
2522:
2523: return 0;
2524:
2525: do {
2526:
2527: TRACE("yielding in mouse_read");
2528:
2529: yield();
2530:
2531: } while (mhead == mousetail);
2532:
2533: }
2534:
2535:
2536:
2537: while ( (mhead != mousetail) && (nbytes > 0)) {
2538:
2539: *buf++ = *foo++;
2540:
2541: mhead++;
2542:
2543: if (mhead >= MOUSESIZ) {
2544:
2545: mhead = 0;
2546:
2547: foo = mousebuf;
2548:
2549: }
2550:
2551: count++;
2552:
2553: --nbytes;
2554:
2555: }
2556:
2557: mousehead = mhead;
2558:
2559: return count;
2560:
2561: }
2562:
2563:
2564:
2565: static long
2566:
2567: mouse_ioctl(f, mode, buf)
2568:
2569: FILEPTR *f;
2570:
2571: int mode;
2572:
2573: void *buf;
2574:
2575: {
2576:
2577: long r;
2578:
2579:
2580:
2581: if (mode == FIONREAD) {
2582:
2583: r = mousetail - mousehead;
2584:
2585: if (r < 0) r += MOUSESIZ;
2586:
2587: *((long *)buf) = r;
2588:
2589: }
2590:
2591: else
2592:
2593: return EINVFN;
2594:
2595: return 0;
2596:
2597: }
2598:
2599:
2600:
2601: static long
2602:
2603: mouse_select(f, p, mode)
2604:
2605: FILEPTR *f;
2606:
2607: long p;
2608:
2609: int mode;
2610:
2611: {
2612:
2613: if (mode != O_RDONLY)
2614:
2615: return 1; /* we can always take output :-) */
2616:
2617:
2618:
2619: if (mousetail - mousehead)
2620:
2621: return 1; /* input waiting already */
2622:
2623:
2624:
2625: if (!mousersel)
2626:
2627: mousersel = p;
2628:
2629: return 0;
2630:
2631: }
2632:
2633:
2634:
2635: static void
2636:
2637: mouse_unselect(f, p, mode)
2638:
2639: FILEPTR *f;
2640:
2641: long p;
2642:
2643: int mode;
2644:
2645: {
2646:
2647: if (mode == O_RDONLY && mousersel == p)
2648:
2649: mousersel = 0;
2650:
2651: }
2652:
2653:
2654:
2655:
2656:
2657: /*
2658:
2659: * UTILITY ROUTINE called by Bconmap() in xbios.c:
2660:
2661: * this sets handle -1 of process p to a file handle
2662:
2663: * that has BIOS device "dev". Returns 0 on failure,
2664:
2665: * non-zero on success.
2666:
2667: */
2668:
2669:
2670:
2671: int
2672:
2673: set_auxhandle(p, dev)
2674:
2675: PROC *p;
2676:
2677: int dev;
2678:
2679: {
2680:
2681: FILEPTR *f;
2682:
2683: struct bios_file *b;
2684:
2685:
2686:
2687: f = new_fileptr();
2688:
2689: if (f) {
2690:
2691: f->links = 1;
2692:
2693: f->flags = O_RDWR;
2694:
2695: f->pos = 0;
2696:
2697: f->devinfo = 0;
2698:
2699: f->fc.fs = &bios_filesys;
2700:
2701: f->fc.aux = dev;
2702:
2703: f->fc.dev = BIOSDRV;
2704:
2705: for (b = broot; b; b = b->next) {
2706:
2707: if (b->private == dev &&
2708:
2709: (b->device == &bios_tdevice ||
2710:
2711: b->device == &bios_ndevice)) {
2712:
2713: f->fc.index = (long)b;
2714:
2715: f->dev = b->device;
2716:
2717: if (b->device != &fakedev)
2718:
2719: f->devinfo = (long)b->tty;
2720:
2721: goto found_device;
2722:
2723: }
2724:
2725: }
2726:
2727: f->fc.index = 0;
2728:
2729: f->dev = &bios_ndevice;
2730:
2731: found_device:
2732:
2733: if ((*f->dev->open)(f) < 0) {
2734:
2735: f->links = 0;
2736:
2737: dispose_fileptr(f);
2738:
2739: return 0;
2740:
2741: }
2742:
2743: } else {
2744:
2745: /* no memory! use the fake FILEPTR we
2746:
2747: * set up in biosfs_init
2748:
2749: */
2750:
2751: f = defaultaux;
2752:
2753: f->links++;
2754:
2755: }
2756:
2757:
2758:
2759: (void)do_pclose(p, p->aux);
2760:
2761: p->aux = f;
2762:
2763:
2764:
2765: return 1;
2766:
2767: }
2768:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.