📄 ps.c
字号:
/*- * Copyright (c) 1982, 1986 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)ps.c 7.7 (Berkeley) 5/9/91 *//* * Evans and Sutherland Picture System 2 driver -- Bill Reeves. *//* * Still to be done: * WAIT_HIT */#include "ps.h"#if NPS > 0#define EXTERNAL_SYNC#include "../include/pte.h"#include "sys/param.h"#include "sys/systm.h"#include "sys/ioctl.h"#include "sys/map.h"#include "sys/buf.h"#include "sys/conf.h"#include "sys/user.h"#include "sys/uio.h"#include "ubareg.h"#include "ubavar.h"#include "psreg.h"int psprobe(), psattach(), psextsync();int psclockintr(), pssystemintr(), psdeviceintr(), psdmaintr();struct uba_device *psdinfo[NPS];u_short psstd[] = { 0 };struct uba_driver psdriver = { psprobe, 0, psattach, 0, psstd, "ps", psdinfo };#define PSUNIT(dev) (minor(dev))#define MAXAUTOREFRESH 4#define MAXAUTOMAP 4#define MAXDBSIZE (0177777/2)#define PSPRI (PZERO+1)#define PSWAIT(psaddr) { \ register short i = 20000, j; \ while (i-- != 0 && ((j = psaddr->ps_iostat) & DIOREADY) == 0) \ ;\}struct psrefresh { enum { SINGLE_STEP_RF, AUTO_RF, TIME_RF } state; enum { RUNNING_RF, SYNCING_RF, WAITING_MAP, STOPPED_RF } mode; u_short sraddrs[MAXAUTOREFRESH]; short nsraddrs; short srcntr; char waiting; char stop; int icnt; int timecnt;};struct psdbuffer { enum { ON_DB, OFF_DB } state; u_short dbaddrs[2]; u_short dbsize; short rbuffer;};struct psmap { enum { SINGLE_STEP_MAP, AUTO_MAP } state; enum { RUNNING_MAP, WAITING_RF, WAITING_START, STOPPED_MAP } mode; u_short maddrs[MAXAUTOMAP]; short nmaddrs; short mcntr; short outputstart; char waiting; char stop; int icnt;};/* * PS2 software state. */struct ps { char ps_open; /* device is open */ uid_t ps_uid; /* uid of device owner */ struct psrefresh ps_refresh; /* refresh state */ struct psdbuffer ps_dbuffer; /* double buffering state */ struct psmap ps_map; /* segment map state */ int ps_clockticks; /* clock ints between refresh */ int ps_clockmiss; /* clock ints w/o refresh */ int ps_clockcnt; /* count of clock interrupts */ int ps_hitcnt; /* count of hit interrupts */ int ps_strayintr; /* count of stray interrupts */ int ps_icnt; /* count of system interrupts *//* BEGIN GROT */ int ps_lastrequest; int ps_lastrequest2; int ps_lastfunnyrequest; int ps_funnycnt;/* END GROT */} ps[NPS];psprobe(reg) caddr_t reg;{ register int br, cvec; register struct psdevice *psaddr = (struct psdevice *)reg;#ifdef lint br = 0; cvec = br; br = cvec; psclockintr((dev_t)0); pssystemintr((dev_t)0); psdeviceintr((dev_t)0); psdmaintr((dev_t)0); psextsync(0, 0);#endif psaddr->ps_iostat = PSRESET; DELAY(200); psaddr->ps_addr = RTCIE; PSWAIT(psaddr); psaddr->ps_data = 01; psaddr->ps_iostat = PSIE; psaddr->ps_addr = RTCSR; PSWAIT(psaddr); psaddr->ps_data = SYNC|RUN; DELAY(200000); psaddr->ps_addr = RTCREQ; PSWAIT(psaddr); psaddr->ps_data = 01; psaddr->ps_iostat = 0; psaddr->ps_iostat = PSRESET; return (sizeof (struct psdevice));}/*ARGSUSED*/psattach(ui) struct uba_device *ui;{}psopen(dev) dev_t dev;{ register struct ps *psp; register struct uba_device *ui; register int unit = PSUNIT(dev); if (unit >= NPS || (psp = &ps[minor(dev)])->ps_open || (ui = psdinfo[unit]) == 0 || ui->ui_alive == 0) return (ENXIO); psp->ps_open = 1; psp->ps_uid = u.u_uid; psp->ps_strayintr = 0; psp->ps_refresh.state = SINGLE_STEP_RF; psp->ps_refresh.mode = STOPPED_RF; psp->ps_refresh.waiting = 0; psp->ps_refresh.stop = 0; psp->ps_dbuffer.state = OFF_DB; psp->ps_map.state = SINGLE_STEP_MAP; psp->ps_map.mode = STOPPED_MAP; psp->ps_map.waiting = 0; psp->ps_map.stop = 0; psp->ps_clockticks = 0; psp->ps_clockmiss = 0; psp->ps_refresh.icnt = psp->ps_map.icnt = psp->ps_clockcnt = 0; psp->ps_hitcnt = 0; psp->ps_icnt = 0; maptouser(ui->ui_addr); return (0);}psclose(dev) dev_t dev;{ register struct psdevice *psaddr = (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr; ps[PSUNIT(dev)].ps_open = 0; psaddr->ps_iostat = 0; /* clear IENABLE */ PSWAIT(psaddr); psaddr->ps_addr = RFSR; /* set in auto refresh mode */ PSWAIT(psaddr); psaddr->ps_data = AUTOREF; unmaptouser((caddr_t)psaddr); return (0);}/*ARGSUSED*/psread(dev, uio) dev_t dev; struct uio *uio;{}/*ARGSUSED*/pswrite(dev, uio) dev_t dev; struct uio *uio;{}/*ARGSUSED*/psioctl(dev, cmd, data, flag) register caddr_t data;{ register struct uba_device *ui = psdinfo[PSUNIT(dev)]; register struct ps *psp = &ps[PSUNIT(dev)]; int *waddr = *(int **)data; int n, arg, i, error = 0; switch (cmd) { case PSIOGETADDR: *(caddr_t *)data = ui->ui_addr; break; case PSIOAUTOREFRESH: n = fuword((caddr_t)waddr++); if (n == -1) return (EFAULT); if (n < 0 || n > MAXAUTOREFRESH) return (EINVAL); for (i = 0; i < n; i++) { if ((arg = fuword((caddr_t)waddr++)) == -1) return (EFAULT); psp->ps_refresh.sraddrs[i] = arg; } psp->ps_refresh.state = AUTO_RF; psp->ps_refresh.nsraddrs = n; psp->ps_refresh.srcntr = 0; psp->ps_refresh.mode = WAITING_MAP; break; case PSIOAUTOMAP: n = fuword((caddr_t)waddr++); if (n == -1) return (EFAULT); if (n < 0 || n > MAXAUTOMAP) return (EINVAL); for (i = 0; i < n; i++) { if ((arg = fuword((caddr_t)waddr++)) == -1) return (EFAULT); psp->ps_map.maddrs[i] = arg; } if ((arg = fuword((caddr_t)waddr++)) == -1) return (EFAULT); psp->ps_map.outputstart = arg; psp->ps_map.state = AUTO_MAP; psp->ps_map.nmaddrs = n; psp->ps_map.mcntr = 0; psp->ps_map.mode = WAITING_START; break; case PSIOSINGLEREFRESH: psp->ps_refresh.state = SINGLE_STEP_RF; break; case PSIOSINGLEMAP: psp->ps_map.state = SINGLE_STEP_MAP; break; case PSIODOUBLEBUFFER: if ((arg = fuword((caddr_t)waddr++)) == -1) return (EFAULT); psp->ps_dbuffer.dbaddrs[0] = arg; if ((arg = fuword((caddr_t)waddr++)) == -1) return (EFAULT); if (arg <= 0 || arg > MAXDBSIZE) return (EINVAL); psp->ps_dbuffer.dbsize = arg; psp->ps_dbuffer.dbaddrs[1] = psp->ps_dbuffer.dbaddrs[0]+arg; psp->ps_dbuffer.state = ON_DB; psp->ps_dbuffer.rbuffer = 0; break; case PSIOSINGLEBUFFER: psp->ps_dbuffer.state = OFF_DB; break; case PSIOTIMEREFRESH: if (psp->ps_refresh.state != SINGLE_STEP_RF) return (EINVAL); if ((arg = fuword((caddr_t)waddr++)) == -1) return (EFAULT); psp->ps_refresh.state = TIME_RF; psp->ps_refresh.timecnt = arg; break; case PSIOWAITREFRESH: if (psp->ps_refresh.mode != RUNNING_RF) /* not running */ return (0); /* dont wait */ /* fall into ... */ case PSIOSTOPREFRESH: if (cmd == PSIOSTOPREFRESH) { if (psp->ps_refresh.mode == STOPPED_RF && psp->ps_refresh.state != TIME_RF) return (0); psp->ps_refresh.stop = 1; } (void) spl5(); psp->ps_refresh.waiting = 1; while (psp->ps_refresh.waiting) if (error = tsleep(&psp->ps_refresh.waiting, PSPRI | PCATCH, devwait, 0)) break; (void) spl0(); if (error) return (error); if (cmd == PSIOSTOPREFRESH) psp->ps_refresh.mode = STOPPED_RF; if (psp->ps_refresh.state == TIME_RF)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -