home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright 1991,1992 Eric R. Smith. All rights reserved.
- */
-
- /* simple biosfs.c */
-
- #include "mint.h"
-
- extern struct kerinfo kernelinfo; /* see main.c */
-
- static long bios_root P_((int drv, fcookie *fc));
- static long bios_lookup P_((fcookie *dir, const char *name, fcookie *fc));
- static long bios_getxattr P_((fcookie *fc, XATTR *xattr));
- static long bios_chattr P_((fcookie *fc, int attrib));
- static long bios_chown P_((fcookie *fc, int uid, int gid));
- static long bios_chmode P_((fcookie *fc, unsigned mode));
- static long bios_rmdir P_((fcookie *dir, const char *name));
- static long bios_remove P_((fcookie *dir, const char *name));
- static long bios_getname P_((fcookie *root, fcookie *dir, char *pathname));
- static long bios_rename P_((fcookie *olddir, char *oldname,
- fcookie *newdir, const char *newname));
- static long bios_opendir P_((DIR *dirh, int flags));
- static long bios_readdir P_((DIR *dirh, char *nm, int nmlen, fcookie *fc));
- static long bios_rewinddir P_((DIR *dirh));
- static long bios_closedir P_((DIR *dirh));
- static long bios_pathconf P_((fcookie *dir, int which));
- static long bios_dfree P_((fcookie *dir, long *buf));
- static DEVDRV * bios_getdev P_((fcookie *fc, long *devspecial));
- static long bios_fscntl P_((fcookie *, const char *, int, long));
- static long bios_symlink P_((fcookie *, const char *, const char *));
- static long bios_readlink P_((fcookie *, char *, int));
-
- static long bios_topen P_((FILEPTR *f));
- static long bios_twrite P_((FILEPTR *f, const char *buf, long bytes));
- static long bios_tread P_((FILEPTR *f, char *buf, long bytes));
- static long bios_nwrite P_((FILEPTR *f, const char *buf, long bytes));
- static long bios_nread P_((FILEPTR *f, char *buf, long bytes));
- static long bios_ioctl P_((FILEPTR *f, int mode, void *buf));
- static long bios_select P_((FILEPTR *f, long p, int mode));
- static void bios_unselect P_((FILEPTR *f, long p, int mode));
- static long bios_tseek P_((FILEPTR *f, long where, int whence));
-
- long null_open P_((FILEPTR *f));
- long null_write P_((FILEPTR *f, const char *buf, long bytes));
- long null_read P_((FILEPTR *f, char *buf, long bytes));
- long null_lseek P_((FILEPTR *f, long where, int whence));
- long null_ioctl P_((FILEPTR *f, int mode, void *buf));
- long null_datime P_((FILEPTR *f, short *time, int rwflag));
- long null_close P_((FILEPTR *f, int pid));
- long null_select P_((FILEPTR *f, long p, int mode));
- void null_unselect P_((FILEPTR *f, long p, int mode));
-
- static long mouse_open P_((FILEPTR *f));
- static long mouse_read P_((FILEPTR *f, char *buf, long nbytes));
- static long mouse_ioctl P_((FILEPTR *f, int mode, void *buf));
- static long mouse_close P_((FILEPTR *f, int pid));
- static long mouse_select P_((FILEPTR *f, long p, int mode));
- static void mouse_unselect P_((FILEPTR *f, long p, int mode));
-
- /* device driver for BIOS terminals */
-
- DEVDRV bios_tdevice = {
- bios_topen, bios_twrite, bios_tread, bios_tseek, bios_ioctl,
- null_datime, null_close, bios_select, bios_unselect
- };
-
- /* device driver for BIOS devices that are not terminals */
-
- DEVDRV bios_ndevice = {
- null_open, bios_nwrite, bios_nread, null_lseek, bios_ioctl,
- null_datime, null_close, bios_select, bios_unselect
- };
-
- DEVDRV null_device = {
- null_open, null_write, null_read, null_lseek, null_ioctl,
- null_datime, null_close, null_select, null_unselect
- };
-
- DEVDRV mouse_device = {
- mouse_open, null_write, mouse_read, null_lseek, mouse_ioctl,
- null_datime, mouse_close, mouse_select, mouse_unselect
- };
-
- /* this special driver is checked for in dosfile.c, and indicates that
- * a dup operation is actually wanted rather than an open
- */
- DEVDRV fakedev;
-
- #ifdef FASTTEXT
- extern DEVDRV screen_device; /* see fasttext.c */
- #endif
-
- FILESYS bios_filesys = {
- (FILESYS *)0,
- 0,
- bios_root,
- bios_lookup, nocreat, bios_getdev, bios_getxattr,
- bios_chattr, bios_chown, bios_chmode,
- nomkdir, bios_rmdir, bios_remove, bios_getname, bios_rename,
- bios_opendir, bios_readdir, bios_rewinddir, bios_closedir,
- bios_pathconf, bios_dfree, nowritelabel, noreadlabel,
- bios_symlink, bios_readlink, nohardlink, bios_fscntl, nodskchng
- };
-
-
- struct tty con_tty, aux_tty, midi_tty;
- struct tty sccb_tty, scca_tty, ttmfp_tty;
-
- #define BNAME_MAX 13
-
- struct bios_file {
- char name[BNAME_MAX+1]; /* device name */
- DEVDRV *device; /* device driver for device */
- short private; /* extra info for device driver */
- ushort flags; /* flags for device open */
- struct tty *tty; /* tty structure (if appropriate) */
- struct bios_file *next;
- };
-
- struct bios_file BDEV[] = {
-
- /* "real" bios devices present on all machines */
- {"centr", &bios_ndevice, 0, 0, 0, 0},
- {"console", &bios_tdevice, 2, O_TTY, &con_tty, 0},
- {"midi", &bios_tdevice, 3, O_TTY, &midi_tty, 0},
- {"kbd", &bios_ndevice, 4, 0, 0, 0},
- /* devices that duplicate handles */
- {"prn", &fakedev, -3, 0, 0, 0}, /* handle -3 (printer) */
- {"aux", &fakedev, -2, 0, 0, 0}, /* handle -2 (aux. terminal) */
- {"con", &fakedev, -1, 0, 0, 0}, /* handle -1 (control terminal) */
- {"tty", &fakedev, -1, 0, 0, 0}, /* the Unix name for it */
- {"stdin", &fakedev, 0, 0, 0, 0}, /* handle 0 (stdin) */
- {"stdout", &fakedev, 1, 0, 0, 0}, /* handle 1 (stdout) */
- {"stderr", &fakedev, 2, 0, 0, 0}, /* handle 2 (stderr) */
-
- /* other miscellaneous devices */
- {"mouse", &mouse_device, 0, 0, 0, 0},
- {"null", &null_device, 0, 0, 0, 0},
-
- #ifdef FASTTEXT
- /* alternate console driver */
- {"fasttext", &screen_device, 2, O_TTY, &con_tty, 0},
- #endif
-
- /* serial port things *must* come last, because not all of these
- * are present on all machines (except for modem1, which does however
- * have a different device number on TTs and STs)
- */
- {"modem1", &bios_tdevice, 6, O_TTY, &aux_tty, 0},
- {"modem2", &bios_tdevice, 7, O_TTY, &sccb_tty, 0},
- {"serial1", &bios_tdevice, 8, O_TTY, &ttmfp_tty, 0},
- {"serial2", &bios_tdevice, 9, O_TTY, &scca_tty, 0},
- {"", 0, 0, 0, 0, 0}
- };
-
- struct bios_file *broot, *bdevlast;
-
- /* a file pointer for BIOS device 1, provided only for insurance
- * in case a Bconmap happens and we can't allocate a new FILEPTR;
- * in most cases, we'll want to build a FILEPTR in the usual
- * way.
- */
-
- FILEPTR *defaultaux;
-
- void
- biosfs_init()
- {
- struct bios_file *b;
-
- broot = BDEV;
-
- for (b = broot; b->name[0]; b++) {
- b->next = b+1;
-
- /* if not a TT or Mega STE, adjust the MODEM1 device to be BIOS
- * device 1
- * and ignore the remaining devices, since they're not present
- */
- if (!has_bconmap && b->private == 6) {
- b->private = 1;
- b->next = 0;
- break;
- }
- /* SERIAL2 is not present on the Mega STe */
- if (mch == MEGASTE && b->private == 8) {
- b->next = 0;
- break;
- }
-
- }
- bdevlast = b;
- if (b->name[0] == 0) {
- --b;
- b->next = 0;
- }
- defaultaux = new_fileptr();
- defaultaux->links = 1; /* so it never gets freed */
- defaultaux->flags = O_RDWR;
- defaultaux->pos = 0;
- defaultaux->devinfo = 0;
- defaultaux->fc.fs = &bios_filesys;
- defaultaux->fc.index = 0;
- defaultaux->fc.aux = 1;
- defaultaux->fc.dev = BIOSDRV;
- defaultaux->dev = &bios_ndevice;
- }
-
- static long
- bios_root(drv, fc)
- int drv;
- fcookie *fc;
- {
- if (drv == BIOSDRV) {
- fc->fs = &bios_filesys;
- fc->dev = drv;
- fc->index = 0L;
- return 0;
- }
- fc->fs = 0;
- return EINTRN;
- }
-
- static long
- bios_lookup(dir, name, fc)
- fcookie *dir;
- const char *name;
- fcookie *fc;
- {
- struct bios_file *b;
-
- TRACE("bios_lookup(%s)", name);
-
- if (dir->index != 0) {
- DEBUG("bios_lookup: bad directory");
- return EPTHNF;
- }
- /* special case: an empty name in a directory means that directory */
- /* so does "." */
- if (!*name || (name[0] == '.' && name[1] == 0)) {
- *fc = *dir;
- return 0;
- }
-
- /* another special case: ".." could be a mount point */
- if (!strcmp(name, "..")) {
- *fc = *dir;
- return EMOUNT;
- }
-
- for (b = broot; b; b = b->next) {
- if (!stricmp(b->name, name)) {
- fc->fs = &bios_filesys;
- fc->index = (long)b;
- fc->aux = b->private;
- fc->dev = dir->dev;
- return 0;
- }
- }
- DEBUG("bios_lookup: name(%s) not found", name);
- return EFILNF;
- }
-
- static long
- bios_getxattr(fc, xattr)
- fcookie *fc;
- XATTR *xattr;
- {
- struct bios_file *b = (struct bios_file *)fc->index;
-
- xattr->index = fc->index;
- xattr->dev = fc->dev;
- xattr->nlink = 1;
- xattr->uid = xattr->gid = 0;
- xattr->size = xattr->nblocks = 0;
- xattr->blksize = 1;
- xattr->mtime = xattr->atime = xattr->ctime = timestamp;
- xattr->mdate = xattr->adate = xattr->cdate = datestamp;
- if (fc->index == 0) { /* root directory? */
- xattr->mode = S_IFDIR | DEFAULT_DIRMODE;
- xattr->attr = FA_DIR;
- } else if (b->device == 0) { /* symbolic link? */
- xattr->mode = S_IFLNK | DEFAULT_DIRMODE;
- } else {
- /* BUG: U:\DEV\STDIN, U:\DEV\STDOUT, etc. might not be terminal files */
- xattr->mode = S_IFCHR | DEFAULT_MODE;
- xattr->attr = 0;
- }
- return 0;
- }
-
- static long
- bios_chattr(fc, attrib)
- fcookie *fc;
- int attrib;
- {
- return EACCDN;
- }
-
- static long
- bios_chown(fc, uid, gid)
- fcookie *fc;
- int uid, gid;
- {
- return EINVFN;
- }
-
- static long
- bios_chmode(fc, mode)
- fcookie *fc;
- unsigned mode;
- {
- return EINVFN;
- }
-
- long
- nomkdir(dir, name, mode)
- fcookie *dir;
- const char *name;
- unsigned mode;
- {
- return EACCDN;
- }
-
- static long
- bios_rmdir(dir, name)
- fcookie *dir;
- const char *name;
- {
- return bios_remove(dir, name);
- }
-
- /*
- * MAJOR BUG: we don't check here for removal of devices for which there
- * are still open files
- */
-
- static long
- bios_remove(dir, name)
- fcookie *dir;
- const char *name;
- {
- struct bios_file *b, **lastb;
-
- lastb = &broot;
- for (b = broot; b; b = *(lastb = &b->next)) {
- if (!stricmp(b->name, name)) break;
- }
- if (!b) return EFILNF;
-
- /* don't allow removal of the basic system devices */
- if (b >= BDEV && b <= bdevlast) {
- return EACCDN;
- }
- *lastb = b->next;
-
- if (b->device == 0 || b->device == &bios_tdevice)
- kfree(b->tty);
-
- kfree(b);
- return 0;
- }
-
- static long
- bios_getname(root, dir, pathname)
- fcookie *root, *dir; char *pathname;
- {
- if (dir->index == 0)
- *pathname = 0;
- else
- strcpy(pathname, ((struct bios_file *)dir->index)->name);
- return 0;
- }
-
- static long
- bios_rename(olddir, oldname, newdir, newname)
- fcookie *olddir;
- char *oldname;
- fcookie *newdir;
- const char *newname;
- {
- struct bios_file *b;
-
- /* BUG: we should check to see if "newname" already exists */
-
- for (b = broot; b; b = b->next) {
- if (!stricmp(b->name, oldname)) {
- strncpy(b->name, newname, BNAME_MAX);
- return 0;
- }
- }
- return EFILNF;
- }
-
- static long
- bios_opendir(dirh, flags)
- DIR *dirh;
- int flags;
- {
- if (dirh->fc.index != 0) {
- DEBUG("bios_opendir: bad directory");
- return EPTHNF;
- }
- return 0;
- }
-
- static long
- bios_readdir(dirh, name, namelen, fc)
- DIR *dirh;
- char *name;
- int namelen;
- fcookie *fc;
- {
- struct bios_file *b;
- int giveindex = dirh->flags == 0;
- int i;
-
- b = broot;
- i = dirh->index++;
- while(i-- > 0) {
- if (!b) break;
- b = b->next;
- }
- if (!b) {
- return ENMFIL;
- }
- fc->fs = &bios_filesys;
- fc->index = (long)b;
- fc->aux = b->private;
- fc->dev = dirh->fc.dev;
- if (giveindex) {
- namelen -= sizeof(long);
- if (namelen <= 0)
- return ERANGE;
- *((long *)name) = (long) b;
- name += sizeof(long);
- }
- strncpy(name, b->name, namelen-1);
- if (strlen(b->name) >= namelen)
- return ENAMETOOLONG;
- return 0;
- }
-
- static long
- bios_rewinddir(dirh)
- DIR *dirh;
- {
- dirh->index = 0;
- return 0;
- }
-
- static long
- bios_closedir(dirh)
- DIR *dirh;
- {
- return 0;
- }
-
- static long
- bios_pathconf(dir, which)
- fcookie *dir;
- int which;
- {
- switch(which) {
- case -1:
- return DP_MAXREQ;
- case DP_IOPEN:
- return UNLIMITED; /* no limit on BIOS file descriptors */
- case DP_MAXLINKS:
- return 1; /* no hard links available */
- case DP_PATHMAX:
- return PATH_MAX;
- case DP_NAMEMAX:
- return BNAME_MAX;
- case DP_ATOMIC:
- return 1; /* no atomic writes */
- case DP_TRUNC:
- return DP_AUTOTRUNC; /* names are truncated */
- case DP_CASE:
- return DP_CASEINSENS; /* not case sensitive */
- default:
- return EINVFN;
- }
- }
-
- static long
- bios_dfree(dir, buf)
- fcookie *dir;
- long *buf;
- {
- buf[0] = 0; /* number of free clusters */
- buf[1] = 0; /* total number of clusters */
- buf[2] = 1; /* sector size (bytes) */
- buf[3] = 1; /* cluster size (sectors) */
- return 0;
- }
-
- /*
- * BIOS Dcntl() calls:
- * Dcntl(0xde02, "U:\DEV\FOO", &foo_descr): install a new device called
- * "FOO", which is described by the dev_descr structure "foo_descr".
- * this structure has the following fields:
- * DEVDRV *driver the device driver itself
- * short dinfo info for the device driver
- * short flags flags for the file (e.g. O_TTY)
- * struct tty *tty tty structure, if appropriate
- *
- * Dcntl(0xde00, "U:\DEV\BAR", n): install a new BIOS terminal device, with
- * BIOS device number "n".
- * Dcntl(0xde01, "U:\DEV\BAR", n): install a new non-tty BIOS device, with
- * BIOS device number "n".
- */
-
- static long
- bios_fscntl(dir, name, cmd, arg)
- fcookie *dir;
- const char *name;
- int cmd;
- long arg;
- {
- struct bios_file *b;
-
- if (cmd == DEV_INSTALL) {
- struct dev_descr *d = (struct dev_descr *)arg;
-
- b = kmalloc(SIZEOF(struct bios_file));
- if (!b) return 0;
- strncpy(b->name, name, BNAME_MAX);
- b->name[BNAME_MAX] = 0;
- b->device = d->driver;
- b->private = d->dinfo;
- b->flags = d->flags;
- b->tty = d->tty;
- b->next = broot;
- broot = b;
- return (long)&kernelinfo;
- }
- if (cmd == DEV_NEWTTY) {
- b = kmalloc(SIZEOF(struct bios_file));
- if (!b) return ENSMEM;
- b->tty = kmalloc(SIZEOF(struct tty));
- if (!b->tty) {
- kfree(b);
- return ENSMEM;
- }
- strncpy(b->name, name, BNAME_MAX);
- b->name[BNAME_MAX] = 0;
- b->device = &bios_tdevice;
- b->private = arg;
- b->flags = O_TTY;
- *b->tty = default_tty;
- b->next = broot;
- broot = b;
- return 0;
- }
- if (cmd == DEV_NEWBIOS) {
- b = kmalloc(SIZEOF(struct bios_file));
- if (!b) return ENSMEM;
- strncpy(b->name, name, BNAME_MAX);
- b->name[BNAME_MAX] = 0;
- b->tty = 0;
- b->device = &bios_ndevice;
- b->private = arg;
- b->flags = 0;
- b->next = broot;
- return 0;
- }
- return EINVFN;
- }
-
- static long
- bios_symlink(dir, name, to)
- fcookie *dir;
- const char *name, *to;
- {
- struct bios_file *b;
- long r;
- fcookie fc;
-
- r = bios_lookup(dir, name, &fc);
- if (r == 0) return EACCDN; /* file already exists */
- if (r != EFILNF) return r; /* some other error */
-
- b = kmalloc(SIZEOF(struct bios_file));
- if (!b) return EACCDN;
-
- strncpy(b->name, name, BNAME_MAX);
- b->name[BNAME_MAX] = 0;
- b->device = 0;
- b->private = EINVFN;
- b->flags = 0;
- b->tty = kmalloc((long)strlen(to)+1);
- if (!b->tty) {
- kfree(b);
- return EACCDN;
- }
- strcpy((char *)b->tty, to);
- b->next = broot;
- broot = b;
- return 0;
- }
-
- static long
- bios_readlink(fc, buf, buflen)
- fcookie *fc;
- char *buf;
- int buflen;
- {
- struct bios_file *b = (struct bios_file *)fc->index;
-
- if (!b) return EINVFN;
- if (b->device) return EINVFN;
-
- strncpy(buf, (char *)b->tty, buflen);
- if (strlen((char *)b->tty) >= buflen)
- return ENAMETOOLONG;
- return 0;
- }
-
-
- /*
- * routines for file systems that don't support volume labels
- */
-
- long
- nowritelabel(dir, name)
- fcookie *dir;
- const char *name;
- {
- return EACCDN;
- }
-
- long
- noreadlabel(dir, name, namelen)
- fcookie *dir;
- char *name;
- int namelen;
- {
- return EFILNF;
- }
-
- /*
- * routines for file systems that don't support links
- */
-
- long
- nosymlink(dir, name, to)
- fcookie *dir;
- const char *name, *to;
- {
- return EINVFN;
- }
-
- long
- noreadlink(dir, buf, buflen)
- fcookie *dir;
- char *buf;
- int buflen;
- {
- return EINVFN;
- }
-
- long
- nohardlink(fromdir, fromname, todir, toname)
- fcookie *fromdir, *todir;
- const char *fromname, *toname;
- {
- return EINVFN;
- }
-
- /* dummy routine for file systems with no Fscntl commands */
-
- long
- nofscntl(dir, name, cmd, arg)
- fcookie *dir;
- const char *name;
- int cmd;
- long arg;
- {
- return EINVFN;
- }
-
- /*
- * Did the disk change? Not on this drive!
- * However, we have to do Getbpb anyways, because someone has decided
- * to force a media change on our (non-existent) drive.
- */
- long
- nodskchng(drv)
- int drv;
- {
- (void)getbpb(drv);
- return 0;
- }
-
- long
- nocreat(dir, name, mode, attrib, fc)
- fcookie *dir, *fc;
- const char *name;
- unsigned mode;
- int attrib;
- {
- return EACCDN;
- }
-
- static DEVDRV *
- bios_getdev(fc, devsp)
- fcookie *fc;
- long *devsp;
- {
- struct bios_file *b;
-
- b = (struct bios_file *)fc->index;
-
- if (b->device && b->device != &fakedev)
- *devsp = (long)b->tty;
- else
- *devsp = b->private;
-
- return b->device; /* return the device driver */
- }
-
- /*
- * NULL device driver
- */
-
- long
- null_open(f)
- FILEPTR *f;
- {
- return 0;
- }
-
- long
- null_write(f, buf, bytes)
- FILEPTR *f; const char *buf; long bytes;
- {
- return bytes;
- }
-
- long
- null_read(f, buf, bytes)
- FILEPTR *f; char *buf; long bytes;
- {
- return 0;
- }
-
- long
- null_lseek(f, where, whence)
- FILEPTR *f; long where; int whence;
- {
- return (where == 0) ? 0 : ERANGE;
- }
-
- long
- null_ioctl(f, mode, buf)
- FILEPTR *f; int mode; void *buf;
- {
- if (mode == FIONREAD) {
- *((long *)buf) = 0;
- }
- else if (mode == FIONWRITE)
- *((long *)buf) = 1;
- else
- return EINVFN;
- return 0;
- }
-
- long
- null_datime(f, timeptr, rwflag)
- FILEPTR *f;
- short *timeptr;
- int rwflag;
- {
- if (rwflag)
- return EACCDN;
- *timeptr++ = timestamp;
- *timeptr = datestamp;
- return 0;
- }
-
- long
- null_close(f, pid)
- FILEPTR *f;
- int pid;
- {
- return 0;
- }
-
- long
- null_select(f, p, mode)
- FILEPTR *f; long p;
- int mode;
- {
- return 1; /* we're always ready to read/write */
- }
-
- void
- null_unselect(f, p, mode)
- FILEPTR *f;
- long p;
- int mode;
- {
- /* nothing to do */
- }
-
- /*
- * BIOS terminal device driver
- */
-
- static long
- bios_topen(f)
- FILEPTR *f;
- {
- f->flags |= O_TTY;
- return 0;
- }
-
- /*
- * Note: when a BIOS device is a terminal (i.e. has the O_TTY flag
- * set), bios_read and bios_write will only ever be called indirectly, via
- * tty_read and tty_write. That's why we can afford to play a bit fast and
- * loose with the pointers ("buf" is really going to point to a long) and
- * why we know that "bytes" is divisible by 4.
- */
-
- static long
- bios_twrite(f, buf, bytes)
- FILEPTR *f; const char *buf; long bytes;
- {
- long *r;
- long ret = 0;
- int bdev = f->fc.aux;
-
- r = (long *)buf;
- while (bytes > 0) {
- if ( (f->flags & O_NDELAY) && !bcostat(bdev) )
- break;
-
- if (bconout(bdev, (int)*r) == 0)
- break;
-
- r++; bytes -= 4; ret+= 4;
- }
- (void)checkkeys();
- return ret;
- }
-
- static long
- bios_tread(f, buf, bytes)
- FILEPTR *f; char *buf; long bytes;
- {
- long *r, ret = 0;
- int bdev = f->fc.aux;
-
- r = (long *)buf;
-
- while (bytes > 0) {
- if ( (f->flags & O_NDELAY) && !bconstat(bdev) )
- break;
- *r++ = bconin(bdev) & 0x7fffffff;
- bytes -= 4; ret += 4;
- }
- return ret;
- }
-
- /*
- * read/write routines for BIOS devices that aren't terminals (like the
- * printer & IKBD devices)
- */
-
- static long
- bios_nwrite(f, buf, bytes)
- FILEPTR *f; const char *buf; long bytes;
- {
- long ret = 0;
- int bdev = f->fc.aux;
- int c;
-
- while (bytes > 0) {
- if ( (f->flags & O_NDELAY) && !bcostat(bdev) )
- break;
-
- c = *buf++ & 0x00ff;
-
- if (bconout(bdev, c) == 0)
- break;
-
- bytes--; ret++;
- }
- return ret;
- }
-
- static long
- bios_nread(f, buf, bytes)
- FILEPTR *f; char *buf; long bytes;
- {
- long ret = 0;
- int bdev = f->fc.aux;
-
- while (bytes > 0) {
- if ( (f->flags & O_NDELAY) && !bconstat(bdev) )
- break;
- *buf++ = bconin(bdev) & 0xff;
- bytes--; ret++;
- }
- return ret;
- }
-
- /*
- * BIOS terminal seek code -- this has to match the documented
- * way to do isatty()
- */
-
- static long
- bios_tseek(f, where, whence)
- FILEPTR *f;
- long where;
- int whence;
- {
- /* terminals always are at position 0 */
- return 0;
- }
-
- #define MAXBAUD 16
-
- static long baudmap[MAXBAUD] = {
- 19200L, 9600L, 4800L, 3600L, 2400L, 2000L, 1800L, 1200L,
- 600L, 300L, 200L, 150L, 134L, 110L, 75L, 50L
- };
-
- static long
- bios_ioctl(f, mode, buf)
- FILEPTR *f; int mode; void *buf;
- {
- long *r = (long *)buf;
- struct winsize *ws;
- char *aline;
- short dev;
- int i;
-
- if (mode == FIONREAD) {
- if (bconstat(f->fc.aux))
- *r = 1;
- else
- *r = 0;
- }
- else if (mode == FIONWRITE) {
- if (bcostat(f->fc.aux))
- *r = 1;
- else
- *r = 0;
- }
- else if (mode == TIOCFLUSH) {
- /* BUG: this should flush the input/output buffers */
- return 0;
- }
- else if (mode == TIOCGWINSZ && f->fc.aux == 2) {
- aline = lineA0();
- ws = (struct winsize *)buf;
- ws->ws_row = *((short *)(aline - 42)) + 1;
- ws->ws_col = *((short *)(aline - 44)) + 1;
- } else if (mode == TIOCIBAUD || mode == TIOCOBAUD) {
- long oldbaud, newbaud;
- dev = f->fc.aux;
-
- newbaud = *r;
- if (dev == 1 || dev >= 6) {
- if (has_bconmap)
- mapin((dev == 1) ? curproc->bconmap : dev);
- i = rsconf(-2, -1, -1, -1, -1, -1);
- if (i < 0 || i >= MAXBAUD)
- oldbaud = -1L;
- else
- oldbaud = baudmap[i];
- *r = oldbaud;
- if (newbaud > 0) {
- for (i = 0; i < MAXBAUD; i++) {
- if (baudmap[i] == newbaud) {
- rsconf(i, -1, -1, -1, -1, -1);
- return 0;
- }
- }
- return ERANGE;
- } else if (newbaud == 0L) {
- /* drop DTR: works only on modem1 */
- if (dev == 1 || dev == 6) {
- Ongibit(0x10);
- nap(30);
- Offgibit(0xef);
- }
- }
- return 0;
- } else if (dev == 2 || dev == 5) {
- /* screen: assume 9600 baud */
- oldbaud = 9600L;
- } else if (dev == 3) {
- /* midi */
- oldbaud = 31250L;
- } else {
- oldbaud = -1L; /* unknown speed */
- }
- *r = oldbaud;
- if (newbaud > 0 && newbaud != oldbaud)
- return ERANGE;
- return 0;
- } else if (mode == TIOCCBRK || mode == TIOCSBRK) {
- unsigned long bits;
-
- dev = f->fc.aux;
- if (dev == 1 || dev >= 6) {
- if (has_bconmap)
- mapin((dev == 1) ? curproc->bconmap : dev);
- } else {
- return EINVFN;
- }
- bits = rsconf(-1, -1, -1, -1, -1, -1); /* get settings */
- bits = (bits >> 8) & 0x0ff; /* isolate TSR byte */
- if (mode == TIOCCBRK)
- bits &= ~8;
- else
- bits |= 8;
- (void)rsconf(-1, -1, -1, -1, (int)bits, -1);
- } else if (mode == TIOCGFLAGS || mode == TIOCSFLAGS) {
- unsigned short oflags, flags;
- unsigned long bits;
- unsigned char ucr;
- short flow;
-
- dev = f->fc.aux;
- if (dev == 1 || dev >= 6) {
- oflags = ((struct tty *)f->devinfo)->sg.sg_flags;
- oflags &= (T_TANDEM|T_RTSCTS);
- if (has_bconmap)
- mapin((dev == 1) ? curproc->bconmap : dev);
- bits = rsconf(-1, -1, -1, -1, -1, -1); /* get settings */
- ucr = (bits >> 24L) & 0x0ff; /* isolate UCR byte */
- oflags |= (ucr >> 3) & (TF_STOPBITS|TF_CHARBITS);
- if (ucr & 0x4) { /* parity on? */
- oflags |= (ucr & 0x2) ? T_EVENP : T_ODDP;
- }
- if (mode == TIOCSFLAGS) {
- flags = (*(unsigned short *)buf);
- if (flags & T_EVENP) {
- ucr |= 0x6;
- } else if (flags & T_ODDP) {
- ucr &= ~2;
- ucr |= 0x4;
- } else {
- ucr &= ~6;
- }
- if (flags & TF_STOPBITS) {
- ucr &= ~(0x18);
- ucr |= (flags & TF_STOPBITS) << 3;
- }
- ucr &= ~(0x60);
- ucr |= (flags & TF_CHARBITS) << 3;
- flow = (flags & (T_RTSCTS|T_TANDEM)) >> 12L;
- rsconf(-1, flow, ucr, -1, -1, -1);
- } else {
- *((unsigned short *)buf) = oflags;
- }
- } else {
- return EINVFN;
- }
-
- } else {
- /* Fcntl will automatically call tty_ioctl to handle
- * terminal calls that we didn't deal with
- */
- return EINVFN;
- }
- return 0;
- }
-
- static long
- bios_select(f, p, mode)
- FILEPTR *f; long p; int mode;
- {
- struct tty *tty = (struct tty *)f->devinfo;
- int dev = f->fc.aux;
-
- if (mode == O_RDONLY) {
- if (bconstat(dev)) {
- TRACE("bios_select: data present for device %d", dev);
- return 1;
- }
- if (tty) {
- /* avoid collisions with other processes */
- if (!tty->rsel)
- tty->rsel = p;
- }
- return 0;
- } else if (mode == O_WRONLY) {
- if (bcostat(dev)) {
- TRACE("bios_select: ready to output on %d", dev);
- return 1;
- }
- if (tty) {
- if (!tty->wsel)
- tty->wsel = p;
- }
- return 0;
- }
- /* default -- we don't know this mode, return 0 */
- return 0;
- }
-
- static void
- bios_unselect(f, p, mode)
- FILEPTR *f;
- long p;
- int mode;
- {
- struct tty *tty = (struct tty *)f->devinfo;
-
- if (tty) {
- if (mode == O_RDONLY && tty->rsel == p)
- tty->rsel = 0;
- else if (mode == O_WRONLY && tty->wsel == p)
- tty->wsel = 0;
- }
- }
-
- /*
- * mouse device driver
- */
-
- #define MOUSESIZ 128*3
- static unsigned char mousebuf[MOUSESIZ];
- static int mousehead, mousetail;
-
- long mousersel; /* is someone calling select() on the mouse? */
-
- char mshift; /* shift key status; set by checkkeys() in bios.c */
- short *gcurx = 0,
- *gcury = 0; /* mouse pos. variables; used by big screen emulators */
-
- void
- mouse_handler(buf)
- const char *buf; /* must be a *signed* character */
- {
- unsigned char *mbuf, buttons;
- int newmtail;
- short dx, dy;
-
- /* the Sun mouse driver has 0=down, 1=up, while the atari hardware gives
- us the reverse. also, we have the "middle" button and the "left"
- button reversed; so we use this table to convert (and also to add the
- 0x80 to indicate a mouse packet)
- */
- static int _cnvrt[8] = {
- 0x87, 0x86, 0x83, 0x82, 0x85, 0x84, 0x81, 0x80
- };
-
- mbuf = &mousebuf[mousetail];
- newmtail = mousetail + 3;
- if (newmtail >= MOUSESIZ)
- newmtail = 0;
- if (newmtail == mousehead)
- return; /* buffer full */
-
- buttons = *buf++ & 0x7; /* convert to SUN format */
- if (mshift & 0x3) { /* a shift key held down? */
- /* if so, convert shift+button to a "middle" button */
- if (buttons == 0x1 || buttons == 0x2)
- buttons = 0x4;
- else if (buttons == 0x3)
- buttons = 0x7;
- }
- *mbuf++ = _cnvrt[buttons]; /* convert to Sun format */
- dx = *buf++;
- *mbuf++ = dx; /* copy X delta */
- dy = *buf++;
- *mbuf++ = -dy; /* invert Y delta for Sun format */
- mousetail = newmtail;
- *gcurx += dx; /* update line A variables */
- *gcury += dy;
- /*
- * if someone has called select() waiting for mouse input, wake them
- * up
- */
- if (mousersel) {
- wakeselect(mousersel);
- }
- }
-
- extern void newmvec(); /* in intr.s */
- static long oldvec = 0;
-
- static long
- mouse_open(f)
- FILEPTR *f;
- {
- char *aline;
-
- static char parameters[] = {
- 0, /* Y=0 in lower corner */
- 0, /* normal button handling */
- 1, 1 /* X, Y scaling factors */
- };
-
- if (oldvec) /* mouse in use */
- return EACCDN;
-
- /* initialize pointers to line A variables */
- if (!gcurx) {
- aline = lineA0();
- if (aline == 0) { /* should never happen */
- ALERT("unable to read line A variables");
- return -1;
- }
- gcurx = (short *)(aline - 0x25a);
- gcury = (short *)(aline - 0x258);
- *gcurx = *gcury = 32; /* magic number -- what MGR uses */
- }
-
- oldvec = syskey->mousevec;
- Initmous(1, parameters, newmvec);
- mousehead = mousetail = 0;
- return 0;
- }
-
- static long
- mouse_close(f, pid)
- FILEPTR *f;
- int pid;
- {
- static char parameters[] = {
- 0, /* Y=0 in lower corner */
- 0, /* normal button handling */
- 1, 1 /* X, Y scaling factors */
- };
-
- if (!f) return EIHNDL;
- if (f->links <= 0) {
- if (!oldvec) {
- DEBUG("Mouse not open!!");
- return -1;
- }
- Initmous(1, parameters, (void *)oldvec); /* gratuitous (void *) for Lattice */
- oldvec = 0;
- }
- return 0;
- }
-
- static long
- mouse_read(f, buf, nbytes)
- FILEPTR *f;
- char *buf;
- long nbytes;
- {
- long count = 0;
- int mhead;
- unsigned char *foo;
-
- mhead = mousehead;
- foo = &mousebuf[mhead];
-
- if (mhead == mousetail) {
- if (f->flags & O_NDELAY)
- return 0;
- do {
- TRACE("yielding in mouse_read");
- yield();
- } while (mhead == mousetail);
- }
-
- while ( (mhead != mousetail) && (nbytes > 0)) {
- *buf++ = *foo++;
- mhead++;
- if (mhead >= MOUSESIZ) {
- mhead = 0;
- foo = mousebuf;
- }
- count++;
- --nbytes;
- }
- mousehead = mhead;
- return count;
- }
-
- static long
- mouse_ioctl(f, mode, buf)
- FILEPTR *f;
- int mode;
- void *buf;
- {
- long r;
-
- if (mode == FIONREAD) {
- r = mousetail - mousehead;
- if (r < 0) r += MOUSESIZ;
- *((long *)buf) = r;
- }
- else
- return EINVFN;
- return 0;
- }
-
- static long
- mouse_select(f, p, mode)
- FILEPTR *f;
- long p;
- int mode;
- {
- if (mode != O_RDONLY)
- return 1; /* we can always take output :-) */
-
- if (mousetail - mousehead)
- return 1; /* input waiting already */
-
- if (!mousersel)
- mousersel = p;
- return 0;
- }
-
- static void
- mouse_unselect(f, p, mode)
- FILEPTR *f;
- long p;
- int mode;
- {
- if (mode == O_RDONLY && mousersel == p)
- mousersel = 0;
- }
-
-
- /*
- * UTILITY ROUTINE called by Bconmap() in xbios.c:
- * this sets handle -1 of process p to a file handle
- * that has BIOS device "dev". Returns 0 on failure,
- * non-zero on success.
- */
-
- int
- set_auxhandle(p, dev)
- PROC *p;
- int dev;
- {
- FILEPTR *f;
- struct bios_file *b;
-
- f = new_fileptr();
- if (f) {
- f->links = 1;
- f->flags = O_RDWR;
- f->pos = 0;
- f->devinfo = 0;
- f->fc.fs = &bios_filesys;
- f->fc.aux = dev;
- f->fc.dev = BIOSDRV;
- for (b = broot; b; b = b->next) {
- if (b->private == dev &&
- (b->device == &bios_tdevice ||
- b->device == &bios_ndevice)) {
- f->fc.index = (long)b;
- f->dev = b->device;
- if (b->device != &fakedev)
- f->devinfo = (long)b->tty;
- goto found_device;
- }
- }
- f->fc.index = 0;
- f->dev = &bios_ndevice;
- found_device:
- if ((*f->dev->open)(f) < 0) {
- f->links = 0;
- dispose_fileptr(f);
- return 0;
- }
- } else {
- /* no memory! use the fake FILEPTR we
- * set up in biosfs_init
- */
- f = defaultaux;
- f->links++;
- }
-
- (void)do_pclose(p, p->aux);
- p->aux = f;
-
- return 1;
- }
-