📄 ps.c
字号:
psp->ps_refresh.state = SINGLE_STEP_RF; break; case PSIOWAITMAP: if (psp->ps_map.mode != RUNNING_MAP) /* not running */ return (0); /* dont wait */ /* fall into ... */ case PSIOSTOPMAP: if (cmd == PSIOSTOPMAP) psp->ps_map.stop = 1; (void) spl5(); psp->ps_map.waiting = 1; while (psp->ps_map.waiting) if (error = tsleep(&psp->ps_map.waiting, PSPRI | PCATCH, devwait, 0)) break; (void) spl0(); break; default: return (ENOTTY); break; } return (error);}#define SAVEPSADDR(psaddr, savepsaddr) { \ register short i, xx1; \ xx1 = splclock(); \ i = psaddr->ps_addr; \ while ((psaddr->ps_iostat & DIOREADY) == 0) \ ; \ savepsaddr = psaddr->ps_data; \ splx(xx1); \}#define RESTORPSADDR(psaddr, savepsaddr) { \ register short xx2; \ xx2 = splclock(); \ while ((psaddr->ps_iostat & DIOREADY) == 0) \ ;\ psaddr->ps_addr = savepsaddr; \ splx(xx2); \}psclockintr(dev) dev_t dev;{ register struct psdevice *psaddr = (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr; register struct ps *psp = &ps[PSUNIT(dev)]; int savepsaddr; if (!psp->ps_open) return; psp->ps_clockcnt++; SAVEPSADDR(psaddr, savepsaddr);#ifndef EXTERNAL_SYNC if (psp->ps_refresh.state == AUTO_RF) { if (psp->ps_refresh.mode == SYNCING_RF && psp->ps_refresh.state != TIME_RF) { (void) psrfnext(psp, psaddr); } else { psp->ps_clockticks++; psp->ps_clockmiss++; } }#endif PSWAIT(psaddr); psaddr->ps_addr = RTCREQ; PSWAIT(psaddr); psaddr->ps_data = 01; /* clear the request bits */ RESTORPSADDR(psaddr, savepsaddr);}/*ARGSUSED*/pssystemintr(dev) dev_t dev;{ register struct psdevice *psaddr = (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr; register struct ps *psp = &ps[PSUNIT(dev)]; short request, tmp; register int savepsaddr, x; if (!psp->ps_open) return; psp->ps_icnt++; SAVEPSADDR(psaddr, savepsaddr); PSWAIT(psaddr); psaddr->ps_addr = SYSREQ; PSWAIT(psaddr); request = psaddr->ps_data; request = request&0377; psp->ps_lastrequest2 = psp->ps_lastrequest; psp->ps_lastrequest = request; if (request &~ (HALT_REQ|RFSTOP_REQ|HIT_REQ)) { psp->ps_lastfunnyrequest = request; psp->ps_funnycnt++; } PSWAIT(psaddr); psaddr->ps_addr = SYSREQ; tmp = request&(~(HALT_REQ|MOSTOP_REQ)); /* acknowledge */ PSWAIT(psaddr); psaddr->ps_data = tmp; if (request & (MOSTOP_REQ|HALT_REQ)) { /* Map stopped */ psp->ps_map.icnt++; psmapstop(psaddr, psp, request);/* kill it dead */ if (psp->ps_map.waiting) { psp->ps_map.waiting = 0; wakeup(&psp->ps_map.waiting); if (psp->ps_map.stop) { psp->ps_map.stop = 0; goto tryrf; } } if (psp->ps_map.state == AUTO_MAP && !psmapnext(psp, psaddr)) { psp->ps_map.mcntr = 0; /* prepare for next round */ pssetmapbounds(psp, psaddr); if (psp->ps_refresh.state == AUTO_RF) { if (psp->ps_refresh.mode == WAITING_MAP){ if (psp->ps_dbuffer.state == ON_DB) /* fill other db */ psdbswitch(psp, psaddr); else psp->ps_map.mode = WAITING_RF;#ifdef EXTERNAL_SYNC x = splclock();#endif (void) psrfnext(psp, psaddr);#ifdef EXTERNAL_SYNC splx(x);#endif } else psp->ps_map.mode = WAITING_RF; } else { /* no auto refresh */ if (psp->ps_dbuffer.state == ON_DB) /* fill other db */ psdbswitch(psp, psaddr); else (void) psmapnext(psp, psaddr); } } }tryrf: if (request & RFSTOP_REQ) { /* Refresh stopped */ psp->ps_refresh.icnt++; if (psp->ps_refresh.state == TIME_RF) if (--psp->ps_refresh.timecnt > 0) goto tryhit; psrfstop(psaddr, psp); if (psp->ps_refresh.waiting) { psp->ps_refresh.waiting = 0; wakeup(&psp->ps_refresh.waiting); if (psp->ps_refresh.stop) { psp->ps_refresh.stop = 0; goto tryhit; } } if (psp->ps_refresh.state == AUTO_RF) if (!psrfnext(psp, psaddr)) { /* at end of refresh cycle */ if (psp->ps_map.state == AUTO_MAP && psp->ps_map.mode == WAITING_RF) { if (psp->ps_dbuffer.state == ON_DB) psdbswitch(psp, psaddr); else (void) psmapnext(psp, psaddr); } psp->ps_refresh.srcntr = 0;#ifdef EXTERNAL_SYNC x = splclock();#endif psp->ps_refresh.mode = SYNCING_RF; if (psp->ps_clockticks) (void) psrfnext(psp, psaddr); psp->ps_clockticks = 0;#ifdef EXTERNAL_SYNC splx(x);#endif } }tryhit: if (request & HIT_REQ) /* Hit request */ psp->ps_hitcnt++; if (request == 0) psp->ps_strayintr++; RESTORPSADDR(psaddr, savepsaddr);}psrfnext(psp, psaddr) register struct ps *psp; register struct psdevice *psaddr;{ u_short start, last; if (psp->ps_refresh.srcntr < psp->ps_refresh.nsraddrs) { psrfstart(psp->ps_refresh.sraddrs[psp->ps_refresh.srcntr++], 0, psp, psaddr); return (1); } if (psp->ps_refresh.srcntr == psp->ps_refresh.nsraddrs && psp->ps_dbuffer.state == ON_DB) { start = psp->ps_dbuffer.dbaddrs[psp->ps_dbuffer.rbuffer]; last = start+psp->ps_dbuffer.dbsize; psrfstart(start, last, psp, psaddr); psp->ps_refresh.srcntr++; /* flag for after dbuffer */ return (1); } return (0);}psrfstart(dfaddr, last, psp, psaddr) u_short dfaddr, last; register struct ps *psp; register struct psdevice *psaddr;{ short dummy; PSWAIT(psaddr); psaddr->ps_addr = RFASA; PSWAIT(psaddr); psaddr->ps_data = dfaddr; PSWAIT(psaddr); if (last != 0) psaddr->ps_data = last; else dummy = psaddr->ps_data;/* just access to get to status reg */ PSWAIT(psaddr); psaddr->ps_data = RFSTART; /* may want | here */ psp->ps_refresh.mode = RUNNING_RF;}/*ARGSUSED*/psrfstop(psaddr, psp) register struct psdevice *psaddr; register struct ps *psp;{ PSWAIT(psaddr); psaddr->ps_addr = RFSR; PSWAIT(psaddr); psaddr->ps_data = 0;}psdbswitch(psp, psaddr) register struct ps *psp; register struct psdevice *psaddr;{ psp->ps_dbuffer.rbuffer = !psp->ps_dbuffer.rbuffer; pssetmapbounds(psp, psaddr); (void) psmapnext(psp, psaddr);}psmapnext(psp, psaddr) register struct ps *psp; register struct psdevice *psaddr;{ if (psp->ps_map.mcntr < psp->ps_map.nmaddrs) { psmapstart(psp->ps_map.maddrs[psp->ps_map.mcntr++], psp, psaddr); return (1); } return (0);}pssetmapbounds(psp, psaddr) register struct ps *psp; register struct psdevice *psaddr;{ u_short start, last; PSWAIT(psaddr); psaddr->ps_addr = MAOL; PSWAIT(psaddr); if (psp->ps_dbuffer.state == ON_DB) { start = psp->ps_dbuffer.dbaddrs[!psp->ps_dbuffer.rbuffer]; last = start+psp->ps_dbuffer.dbsize-2; /* 2 for halt cmd */ psaddr->ps_data = last; PSWAIT(psaddr); psaddr->ps_data = start; } else { start = psaddr->ps_data; /* dummy: don't update limit */ PSWAIT(psaddr); psaddr->ps_data = psp->ps_map.outputstart; }}psmapstart(dfaddr, psp, psaddr) u_short dfaddr; register struct ps *psp; register struct psdevice *psaddr;{ PSWAIT(psaddr); psaddr->ps_addr = MAIA; PSWAIT(psaddr); psaddr->ps_data = dfaddr; PSWAIT(psaddr); psaddr->ps_data = MAO|MAI; /* may want more here */ psp->ps_map.mode = RUNNING_MAP;}int pskillcnt = 1;psmapstop(psaddr, psp, request) register struct psdevice *psaddr; register struct ps *psp; short request;{ register int i; request &= HALT_REQ|MOSTOP_REQ; /* overkill?? */ for (i = 0; i < pskillcnt; i++) { PSWAIT(psaddr); psaddr->ps_addr = MASR; PSWAIT(psaddr); psaddr->ps_data = IOUT; /* zero MAI & MAO */ PSWAIT(psaddr); psaddr->ps_addr = MAIA; PSWAIT(psaddr); psaddr->ps_data = 0; /* 0 input addr reg */ PSWAIT(psaddr); psaddr->ps_addr = MAOA; PSWAIT(psaddr); psaddr->ps_data = 0; /* 0 output addr reg */ PSWAIT(psaddr); psaddr->ps_addr = SYSREQ; PSWAIT(psaddr); psaddr->ps_data = request; } psp->ps_map.mode = STOPPED_MAP;}/*ARGSUSED*/psdeviceintr(dev) dev_t dev;{ printf("ps device intr\n");}/*ARGSUSED*/psdmaintr(dev) dev_t dev;{ printf("ps dma intr\n");}/*ARGSUSED*/psreset(uban) int uban;{}/*ARGSUSED*/psextsync(PC, PS){ register int n; register struct psdevice *psaddr; register struct ps *psp; register int savepsaddr;#ifdef EXTERNAL_SYNC for (psp = ps, n = 0; n < NPS; psp++, n++) { if (!psp->ps_open) continue; if (psp->ps_refresh.mode == SYNCING_RF && psp->ps_refresh.state != TIME_RF) { psaddr = (struct psdevice *)psdinfo[n]->ui_addr; SAVEPSADDR(psaddr, savepsaddr); (void) psrfnext(psp, psaddr); RESTORPSADDR(psaddr, savepsaddr); } else { psp->ps_clockticks++; psp->ps_clockmiss++; } }#endif}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -