123334Smckusick /* 223334Smckusick * Copyright (c) 1982 Regents of the University of California. 323334Smckusick * All rights reserved. The Berkeley software License Agreement 423334Smckusick * specifies the terms and conditions for redistribution. 523334Smckusick * 6*25472Ssam * @(#)ps.c 6.5 (Berkeley) 11/12/85 723334Smckusick */ 87296Ssam 97296Ssam /* 1023511Ssam * Evans and Sutherland Picture System 2 driver -- Bill Reeves. 117296Ssam */ 127296Ssam 137296Ssam /* 147296Ssam * Still to be done: 157296Ssam * WAIT_HIT 167296Ssam */ 177296Ssam 187296Ssam #include "ps.h" 197296Ssam #if NPS > 0 207296Ssam 217296Ssam #define EXTERNAL_SYNC 227296Ssam 239776Ssam #include "../machine/pte.h" 249776Ssam 2517075Sbloom #include "param.h" 2617075Sbloom #include "systm.h" 2717075Sbloom #include "ioctl.h" 2817075Sbloom #include "map.h" 2917075Sbloom #include "buf.h" 3017075Sbloom #include "conf.h" 3117075Sbloom #include "dir.h" 3217075Sbloom #include "user.h" 3317075Sbloom #include "uio.h" 347296Ssam 3517075Sbloom #include "ubareg.h" 3617075Sbloom #include "ubavar.h" 3717075Sbloom #include "psreg.h" 388477Sroot 39*25472Ssam int psprobe(), psattach(), psextsync(); 40*25472Ssam int psclockintr(), pssystemintr(), psdeviceintr(), psdmaintr(); 417296Ssam struct uba_device *psdinfo[NPS]; 427296Ssam u_short psstd[] = { 0 }; 437296Ssam struct uba_driver psdriver = 447296Ssam { psprobe, 0, psattach, 0, psstd, "ps", psdinfo }; 457296Ssam 467296Ssam #define PSUNIT(dev) (minor(dev)) 477296Ssam 487296Ssam #define MAXAUTOREFRESH (4) 497296Ssam #define MAXAUTOMAP (4) 507296Ssam #define MAXDBSIZE (0177777/2) 517296Ssam 527296Ssam #define PSPRI (PZERO+1) 537296Ssam 54*25472Ssam #define PSWAIT() {register short i, j; i=20000; while((i-- != 0)\ 557296Ssam && (((j=psaddr->ps_iostat)&DIOREADY)==0));} 567296Ssam 577296Ssam struct ps { 587296Ssam char ps_open; 597296Ssam short int ps_uid; 607296Ssam struct { 6114600Ssam enum { SINGLE_STEP_RF, AUTO_RF, TIME_RF } state; 6214600Ssam enum { RUNNING_RF, SYNCING_RF, WAITING_MAP, STOPPED_RF } mode; 637296Ssam unsigned short int sraddrs[MAXAUTOREFRESH]; 647296Ssam short int nsraddrs; 657296Ssam short int srcntr; 667296Ssam char waiting; 677296Ssam char stop; 687296Ssam int icnt; 6914600Ssam int timecnt; 707296Ssam } ps_refresh; 717296Ssam struct { 727296Ssam enum { ON_DB, OFF_DB } state; 737296Ssam unsigned short int dbaddrs[2]; 747296Ssam unsigned short int dbsize; 757296Ssam short int rbuffer; 767296Ssam } ps_dbuffer; 777296Ssam struct { 787296Ssam enum { SINGLE_STEP_MAP, AUTO_MAP } state; 79*25472Ssam enum { RUNNING_MAP, WAITING_RF, WAITING_START, STOPPED_MAP } mode; 807296Ssam unsigned short int maddrs[MAXAUTOMAP]; 817296Ssam short int nmaddrs; 827296Ssam short int mcntr; 837296Ssam short int outputstart; 847296Ssam char waiting; 857296Ssam char stop; 867296Ssam int icnt; 877296Ssam } ps_map; 887296Ssam struct { 897296Ssam short int ticked; 907296Ssam short int missed; 917296Ssam int icnt; 927296Ssam } ps_clock; 937296Ssam struct { 947296Ssam int icnt; 957296Ssam } ps_hit; 967296Ssam int ps_strayintr; 977296Ssam int last_request; 987296Ssam int strayrequest; 9914600Ssam int ps_icnt; 100*25472Ssam int last_request2; 101*25472Ssam int last_funnyrequest; 102*25472Ssam int funny_cnt; 1037296Ssam } ps[NPS]; 1047296Ssam 1057296Ssam psprobe(reg) 1067296Ssam caddr_t reg; 1077296Ssam { 1087296Ssam register int br, cvec; 1097296Ssam register struct psdevice *psaddr = (struct psdevice *) reg; 1107296Ssam 111*25472Ssam #ifdef lint 112*25472Ssam br = 0; cvec = br; br = cvec; 113*25472Ssam psclockintr((dev_t)0); pssystemintr((dev_t)0); 114*25472Ssam psdeviceintr((dev_t)0); psdmaintr((dev_t)0); 115*25472Ssam psextsync(0, 0); 116*25472Ssam #endif 1177296Ssam psaddr->ps_iostat = PSRESET; 1187296Ssam DELAY(200); 1197296Ssam psaddr->ps_addr = RTCIE; 1207296Ssam PSWAIT(); 1217296Ssam psaddr->ps_data = 01; 1227296Ssam psaddr->ps_iostat = PSIE; 1237296Ssam psaddr->ps_addr = RTCSR; 1247296Ssam PSWAIT(); 1257296Ssam psaddr->ps_data = (SYNC|RUN); 1267296Ssam DELAY(200000); 1277296Ssam psaddr->ps_addr = RTCREQ; 1287296Ssam PSWAIT(); 1297296Ssam psaddr->ps_data = 01; 1307296Ssam psaddr->ps_iostat = 0; 1317296Ssam psaddr->ps_iostat = PSRESET; 1327418Skre return (sizeof (struct psdevice)); 1337296Ssam } 1347296Ssam 1357296Ssam /*ARGSUSED*/ 1367296Ssam psattach(ui) 137*25472Ssam struct uba_device *ui; 1387296Ssam { 1398572Sroot 1407296Ssam } 1417296Ssam 1427296Ssam psopen(dev) 1437296Ssam dev_t dev; 1447296Ssam { 1457296Ssam register struct ps *psp; 1467296Ssam register struct uba_device *ui; 1477296Ssam register int unit = PSUNIT(dev); 1487296Ssam 1498572Sroot if (unit >= NPS || (psp = &ps[minor(dev)])->ps_open || 1508572Sroot (ui = psdinfo[unit]) == 0 || ui->ui_alive == 0) 1518572Sroot return (ENXIO); 1527296Ssam psp->ps_open = 1; 1537296Ssam psp->ps_uid = u.u_uid; 1547296Ssam psp->ps_strayintr = 0; 1557296Ssam psp->ps_refresh.state = SINGLE_STEP_RF; 156*25472Ssam psp->ps_refresh.mode = STOPPED_RF; 1577296Ssam psp->ps_refresh.waiting = 0; 1587296Ssam psp->ps_refresh.stop = 0; 1597296Ssam psp->ps_dbuffer.state = OFF_DB; 1607296Ssam psp->ps_map.state = SINGLE_STEP_MAP; 161*25472Ssam psp->ps_map.mode = STOPPED_MAP; 1627296Ssam psp->ps_map.waiting = 0; 1637296Ssam psp->ps_map.stop = 0; 1647296Ssam psp->ps_clock.ticked = 0; 165*25472Ssam psp->ps_clock.missed = 0; 1667296Ssam psp->ps_refresh.icnt = psp->ps_map.icnt = psp->ps_clock.icnt = 0; 167*25472Ssam psp->ps_hit.icnt = 0; 16814600Ssam psp->ps_icnt = 0; 1697296Ssam maptouser(ui->ui_addr); 1708572Sroot return (0); 1717296Ssam } 1727296Ssam 1737296Ssam psclose(dev) 1747296Ssam dev_t dev; 1757296Ssam { 1767296Ssam register struct psdevice *psaddr = 1777296Ssam (struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr; 1787296Ssam 1797296Ssam ps[PSUNIT(dev)].ps_open = 0; 1807296Ssam psaddr->ps_iostat = 0; /* clear IENABLE */ 1817296Ssam PSWAIT(); 1827296Ssam psaddr->ps_addr = RFSR; /* set in auto refresh mode */ 1837296Ssam PSWAIT(); 1847296Ssam psaddr->ps_data = AUTOREF; 185*25472Ssam unmaptouser((caddr_t)psaddr); 1867296Ssam } 1877296Ssam 1887296Ssam /*ARGSUSED*/ 1897730Sroot psread(dev, uio) 1907296Ssam dev_t dev; 1917730Sroot struct uio *uio; 1927296Ssam { 1937296Ssam } 1947296Ssam 1957296Ssam /*ARGSUSED*/ 1967730Sroot pswrite(dev, uio) 1977296Ssam dev_t dev; 1987730Sroot struct uio *uio; 1997296Ssam { 2007296Ssam } 2017296Ssam 2027296Ssam /*ARGSUSED*/ 2037632Ssam psioctl(dev, cmd, data, flag) 2047632Ssam register caddr_t data; 2057296Ssam { 2067296Ssam register struct uba_device *ui = psdinfo[PSUNIT(dev)]; 2077296Ssam register struct ps *psp = &ps[PSUNIT(dev)]; 2087632Ssam int *waddr = *(int **)data; 2097296Ssam int n, arg, i; 2107296Ssam 2117296Ssam switch (cmd) { 2127632Ssam 2137632Ssam case PSIOGETADDR: 2147632Ssam *(caddr_t *)data = ui->ui_addr; 2157296Ssam break; 2167632Ssam 2177632Ssam case PSIOAUTOREFRESH: 218*25472Ssam n = fuword((caddr_t)waddr++); 2198572Sroot if (n == -1) 2208572Sroot return (EFAULT); 2218572Sroot if (n < 0 || n > MAXAUTOREFRESH) 2228572Sroot return (EINVAL); 2238572Sroot for (i = 0; i < n; i++) { 224*25472Ssam if ((arg = fuword((caddr_t)waddr++)) == -1) 2258572Sroot return (EFAULT); 2268572Sroot psp->ps_refresh.sraddrs[i] = arg; 2277296Ssam } 2288572Sroot psp->ps_refresh.state = AUTO_RF; 2298572Sroot psp->ps_refresh.nsraddrs = n; 2308572Sroot psp->ps_refresh.srcntr = 0; 2318572Sroot psp->ps_refresh.mode = WAITING_MAP; 2327296Ssam break; 2337632Ssam 2347632Ssam case PSIOAUTOMAP: 235*25472Ssam n = fuword((caddr_t)waddr++); 2368572Sroot if (n == -1) 2378572Sroot return (EFAULT); 2388572Sroot if (n < 0 || n > MAXAUTOMAP) 2398572Sroot return (EINVAL); 2408572Sroot for (i = 0; i < n; i++) { 241*25472Ssam if ((arg = fuword((caddr_t)waddr++)) == -1) 2428572Sroot return (EFAULT); 2438572Sroot psp->ps_map.maddrs[i] = arg; 2447296Ssam } 245*25472Ssam if ((arg = fuword((caddr_t)waddr++)) == -1) 2468572Sroot return (EFAULT); 2478572Sroot psp->ps_map.outputstart = arg; 2488572Sroot psp->ps_map.state = AUTO_MAP; 2498572Sroot psp->ps_map.nmaddrs = n; 2508572Sroot psp->ps_map.mcntr = 0; 2518572Sroot psp->ps_map.mode = WAITING_START; 2527296Ssam break; 2537632Ssam 2547632Ssam case PSIOSINGLEREFRESH: 2557296Ssam psp->ps_refresh.state = SINGLE_STEP_RF; 2567296Ssam break; 2577632Ssam 2587632Ssam case PSIOSINGLEMAP: 2597296Ssam psp->ps_map.state = SINGLE_STEP_MAP; 2607296Ssam break; 2617632Ssam 2627632Ssam case PSIODOUBLEBUFFER: 263*25472Ssam if ((arg = fuword((caddr_t)waddr++)) == -1) 2648572Sroot return (EFAULT); 2658572Sroot psp->ps_dbuffer.dbaddrs[0] = arg; 266*25472Ssam if ((arg = fuword((caddr_t)waddr++)) == -1) 2678572Sroot return (EFAULT); 2688572Sroot if (arg <= 0 || arg > MAXDBSIZE) 2698572Sroot return (EINVAL); 2708572Sroot psp->ps_dbuffer.dbsize = arg; 2718572Sroot psp->ps_dbuffer.dbaddrs[1] = 2728572Sroot psp->ps_dbuffer.dbaddrs[0]+arg; 2738572Sroot psp->ps_dbuffer.state = ON_DB; 2748572Sroot psp->ps_dbuffer.rbuffer = 0; 2757296Ssam break; 2767632Ssam 2777632Ssam case PSIOSINGLEBUFFER: 2787296Ssam psp->ps_dbuffer.state = OFF_DB; 2797296Ssam break; 2807632Ssam 28114600Ssam case PSIOTIMEREFRESH: 28214600Ssam if (psp->ps_refresh.state != SINGLE_STEP_RF) 28314600Ssam return(EINVAL); 284*25472Ssam if ((arg = fuword((caddr_t)waddr++)) == -1) 28514600Ssam return(EFAULT); 28614600Ssam psp->ps_refresh.state = TIME_RF; 28714600Ssam psp->ps_refresh.timecnt = arg; 28814600Ssam break; 28914600Ssam 2907632Ssam case PSIOWAITREFRESH: 2918572Sroot if (psp->ps_refresh.mode != RUNNING_RF) /* not running */ 2928572Sroot return (0); /* dont wait */ 2938572Sroot /* fall into ... */ 2947632Ssam 29514600Ssam case PSIOSTOPREFRESH: 29614600Ssam if (cmd == PSIOSTOPREFRESH) { 29714600Ssam if (psp->ps_refresh.mode == STOPPED_RF 29814600Ssam && psp->ps_refresh.state != TIME_RF) 29914600Ssam return (0); 3007296Ssam psp->ps_refresh.stop = 1; 30114600Ssam } 3027296Ssam spl5(); 3037296Ssam psp->ps_refresh.waiting = 1; 3048572Sroot while (psp->ps_refresh.waiting) 3057296Ssam sleep(&psp->ps_refresh.waiting, PSPRI); 3067296Ssam spl0(); 30714600Ssam if (cmd == PSIOSTOPREFRESH) 30814600Ssam psp->ps_refresh.mode = STOPPED_RF; 30914600Ssam if (psp->ps_refresh.state == TIME_RF) 31014600Ssam psp->ps_refresh.state = SINGLE_STEP_RF; 3117296Ssam break; 3127632Ssam 3137632Ssam case PSIOWAITMAP: 3148572Sroot if (psp->ps_map.mode != RUNNING_MAP) /* not running */ 3158572Sroot return (0); /* dont wait */ 3168572Sroot /* fall into ... */ 3177632Ssam 3187632Ssam case PSIOSTOPMAP: 31914600Ssam if (cmd == PSIOSTOPMAP) 3207296Ssam psp->ps_map.stop = 1; 3217296Ssam spl5(); 3227296Ssam psp->ps_map.waiting = 1; 3238572Sroot while (psp->ps_map.waiting) 3247296Ssam sleep(&psp->ps_map.waiting, PSPRI); 3257296Ssam spl0(); 3267296Ssam break; 3277632Ssam 3287296Ssam default: 3298572Sroot return (ENOTTY); 3307296Ssam break; 3317296Ssam } 3328572Sroot return (0); 3337296Ssam } 3347296Ssam 335*25472Ssam #define SAVEPSADDR() {register short i,xx1;xx1=spl6();i=psaddr->ps_addr;\ 336*25472Ssam while(((psaddr->ps_iostat)&DIOREADY)==0);\ 337*25472Ssam savepsaddr=psaddr->ps_data;splx(xx1);} 338*25472Ssam #define RESTORPSADDR() {register short xx2;xx2=spl6();\ 339*25472Ssam while(((psaddr->ps_iostat)&DIOREADY)==0);\ 340*25472Ssam psaddr->ps_addr=savepsaddr;splx(xx2);} 3417296Ssam 3427296Ssam psclockintr(dev) 3437296Ssam dev_t dev; 3447296Ssam { 3457296Ssam register struct psdevice *psaddr = 3467296Ssam (struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr; 3477296Ssam register struct ps *psp = &ps[PSUNIT(dev)]; 3487296Ssam int savepsaddr; 3497296Ssam 3508572Sroot if (!psp->ps_open) 3517296Ssam return; 3527296Ssam psp->ps_clock.icnt++; 3537296Ssam SAVEPSADDR(); 3547296Ssam #ifndef EXTERNAL_SYNC 3558572Sroot if (psp->ps_refresh.state == AUTO_RF) { 35614600Ssam if (psp->ps_refresh.mode == SYNCING_RF 35714600Ssam && psp->ps_refresh.state != TIME_RF) { 358*25472Ssam (void) psrfnext(psp, psaddr); 3597296Ssam } else { 3607296Ssam psp->ps_clock.ticked++; 3617296Ssam psp->ps_clock.missed++; 3627296Ssam } 3637296Ssam } 3647296Ssam #endif 3657296Ssam PSWAIT(); 3667296Ssam psaddr->ps_addr = RTCREQ; 3677296Ssam PSWAIT(); 3687296Ssam psaddr->ps_data = 01; /* clear the request bits */ 3697296Ssam RESTORPSADDR(); 3707296Ssam } 3717296Ssam 3727296Ssam /*ARGSUSED*/ 3737296Ssam pssystemintr(dev) 3747296Ssam dev_t dev; 3757296Ssam { 3767296Ssam register struct psdevice *psaddr = 3777296Ssam (struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr; 3787296Ssam register struct ps *psp = &ps[PSUNIT(dev)]; 379*25472Ssam short int request, tmp; 3807296Ssam register int savepsaddr, x; 3817296Ssam 3828572Sroot if (!psp->ps_open) 3837296Ssam return; 38414600Ssam psp->ps_icnt++; 3857296Ssam SAVEPSADDR(); 3867296Ssam PSWAIT(); 3877296Ssam psaddr->ps_addr = SYSREQ; 3887296Ssam PSWAIT(); 389*25472Ssam request = psaddr->ps_data; 390*25472Ssam request = request&0377; 391*25472Ssam psp->last_request2 = psp->last_request; 3927296Ssam psp->last_request = request; 393*25472Ssam if(request&(~(HALT_REQ|RFSTOP_REQ|HIT_REQ))) { 394*25472Ssam psp->last_funnyrequest = request; 395*25472Ssam psp->funny_cnt++; 396*25472Ssam } 3977296Ssam PSWAIT(); 3987296Ssam psaddr->ps_addr = SYSREQ; 399*25472Ssam tmp = request&(~(HALT_REQ|MOSTOP_REQ)); /* acknowledge */ 4007296Ssam PSWAIT(); 401*25472Ssam psaddr->ps_data = tmp; 4027296Ssam 4038572Sroot if (request & (MOSTOP_REQ|HALT_REQ)) { /* Map stopped */ 4047296Ssam psp->ps_map.icnt++; 405*25472Ssam psmapstop(psaddr, psp, request); /* kill it dead */ 4068572Sroot if (psp->ps_map.waiting) { 4077296Ssam psp->ps_map.waiting = 0; 4087296Ssam wakeup(&psp->ps_map.waiting); 4098572Sroot if (psp->ps_map.stop) { 4107296Ssam psp->ps_map.stop = 0; 4117296Ssam goto tryrf; 4127296Ssam } 4137296Ssam } 414*25472Ssam if((psp->ps_map.state==AUTO_MAP) && (!psmapnext(psp, psaddr))){ 415*25472Ssam psp->ps_map.mcntr = 0; 416*25472Ssam /* prepare for next round */ 417*25472Ssam pssetmapbounds(psp, psaddr); 418*25472Ssam if (psp->ps_refresh.state == AUTO_RF) { 419*25472Ssam if(psp->ps_refresh.mode == WAITING_MAP){ 4208572Sroot if (psp->ps_dbuffer.state == ON_DB) 4217296Ssam /* fill other db */ 4227296Ssam psdbswitch(psp, psaddr); 4237296Ssam else 4247296Ssam psp->ps_map.mode = WAITING_RF; 425*25472Ssam #ifdef EXTERNAL_SYNC 426*25472Ssam x = spl6(); 427*25472Ssam #endif 428*25472Ssam (void) psrfnext(psp, psaddr); 429*25472Ssam #ifdef EXTERNAL_SYNC 430*25472Ssam splx(x); 431*25472Ssam #endif 4327296Ssam } else 4337296Ssam psp->ps_map.mode = WAITING_RF; 434*25472Ssam } else { /* no auto refresh */ 435*25472Ssam if (psp->ps_dbuffer.state == ON_DB) 436*25472Ssam /* fill other db */ 437*25472Ssam psdbswitch(psp, psaddr); 438*25472Ssam else 439*25472Ssam (void) psmapnext(psp, psaddr); 4407296Ssam } 441*25472Ssam } 4427296Ssam } 4437296Ssam tryrf: 4448572Sroot if (request & RFSTOP_REQ) { /* Refresh stopped */ 4457296Ssam psp->ps_refresh.icnt++; 44614600Ssam if (psp->ps_refresh.state == TIME_RF) 44714600Ssam if(--psp->ps_refresh.timecnt > 0) 44814600Ssam goto tryhit; 4497296Ssam psrfstop(psaddr, psp); 4508572Sroot if (psp->ps_refresh.waiting) { 4517296Ssam psp->ps_refresh.waiting = 0; 4527296Ssam wakeup(&psp->ps_refresh.waiting); 4538572Sroot if (psp->ps_refresh.stop) { 4547296Ssam psp->ps_refresh.stop = 0; 4557296Ssam goto tryhit; 4567296Ssam } 4577296Ssam } 4588572Sroot if (psp->ps_refresh.state == AUTO_RF) 4598572Sroot if (!psrfnext(psp, psaddr)) { /* at end of refresh cycle */ 4608572Sroot if (psp->ps_map.state == AUTO_MAP && 4617296Ssam psp->ps_map.mode==WAITING_RF) { 4628572Sroot if (psp->ps_dbuffer.state == ON_DB) 4637296Ssam psdbswitch(psp, psaddr); 4647296Ssam else 465*25472Ssam (void) psmapnext(psp, psaddr); 4667296Ssam } 4677296Ssam psp->ps_refresh.srcntr = 0; 4687296Ssam #ifdef EXTERNAL_SYNC 4697296Ssam x = spl6(); 4707296Ssam #endif 471*25472Ssam psp->ps_refresh.mode = SYNCING_RF; 472*25472Ssam if (psp->ps_clock.ticked) 473*25472Ssam (void) psrfnext(psp, psaddr); 4747296Ssam psp->ps_clock.ticked = 0; 4757296Ssam #ifdef EXTERNAL_SYNC 4767296Ssam splx(x); 4777296Ssam #endif 4787296Ssam } 4797296Ssam } 4807296Ssam tryhit: 4818572Sroot if (request & HIT_REQ) { /* Hit request */ 4827296Ssam psp->ps_hit.icnt++; 4837296Ssam } 4848572Sroot if (request == 0) 4857296Ssam psp->ps_strayintr++; 4867296Ssam RESTORPSADDR(); 4877296Ssam } 4887296Ssam 4897296Ssam psrfnext(psp, psaddr) 4907296Ssam register struct ps *psp; 4917296Ssam register struct psdevice *psaddr; 4927296Ssam { 493*25472Ssam unsigned short int start, last; 4947296Ssam 4958572Sroot if (psp->ps_refresh.srcntr < psp->ps_refresh.nsraddrs) 4967296Ssam psrfstart(psp->ps_refresh.sraddrs[psp->ps_refresh.srcntr++], 497*25472Ssam 0, psp, psaddr); 4988572Sroot else if (psp->ps_refresh.srcntr == psp->ps_refresh.nsraddrs 4997296Ssam && psp->ps_dbuffer.state == ON_DB) { 500*25472Ssam start = psp->ps_dbuffer.dbaddrs[psp->ps_dbuffer.rbuffer]; 501*25472Ssam last = start+psp->ps_dbuffer.dbsize; 502*25472Ssam psrfstart(start, last, psp, psaddr); 5037296Ssam psp->ps_refresh.srcntr++; /* flag for after dbuffer */ 5047296Ssam } else 5057296Ssam return(0); 5067296Ssam return(1); 5077296Ssam } 5087296Ssam 509*25472Ssam psrfstart(dfaddr, last, psp, psaddr) 510*25472Ssam unsigned short int dfaddr, last; 5117296Ssam register struct ps *psp; 5127296Ssam register struct psdevice *psaddr; 5137296Ssam { 514*25472Ssam short int dummy; 5157296Ssam 5167296Ssam PSWAIT(); 5177296Ssam psaddr->ps_addr = RFASA; 5187296Ssam PSWAIT(); 5197296Ssam psaddr->ps_data = dfaddr; 5207296Ssam PSWAIT(); 521*25472Ssam if(last != 0) 522*25472Ssam psaddr->ps_data = last; 523*25472Ssam else 524*25472Ssam dummy = psaddr->ps_data;/* just access to get to status reg */ 5257296Ssam PSWAIT(); 5267296Ssam psaddr->ps_data = RFSTART; /* may want to | this value in */ 5277296Ssam psp->ps_refresh.mode = RUNNING_RF; 5287296Ssam } 5297296Ssam 530*25472Ssam /*ARGSUSED*/ 5317296Ssam psrfstop(psaddr, psp) 5327296Ssam register struct psdevice *psaddr; 5337296Ssam register struct ps *psp; 5347296Ssam { 5357296Ssam 5367296Ssam PSWAIT(); 5377296Ssam psaddr->ps_addr = RFSR; 5387296Ssam PSWAIT(); 5397296Ssam psaddr->ps_data = 0; 5407296Ssam } 5417296Ssam 5427296Ssam psdbswitch(psp, psaddr) 5437296Ssam register struct ps *psp; 5447296Ssam register struct psdevice *psaddr; 5457296Ssam { 5467296Ssam 5477296Ssam psp->ps_dbuffer.rbuffer = !psp->ps_dbuffer.rbuffer; 5487296Ssam pssetmapbounds(psp, psaddr); 549*25472Ssam (void) psmapnext(psp, psaddr); 5507296Ssam } 5517296Ssam 5527296Ssam psmapnext(psp, psaddr) 5537296Ssam register struct ps *psp; 5547296Ssam register struct psdevice *psaddr; 5557296Ssam { 5567296Ssam 5578572Sroot if (psp->ps_map.mcntr < psp->ps_map.nmaddrs) 5587296Ssam psmapstart(psp->ps_map.maddrs[psp->ps_map.mcntr++], psp, psaddr); 5597296Ssam else 5607296Ssam return(0); 5617296Ssam return(1); 5627296Ssam } 5637296Ssam 5647296Ssam pssetmapbounds(psp, psaddr) 5657296Ssam register struct ps *psp; 5667296Ssam register struct psdevice *psaddr; 5677296Ssam { 568*25472Ssam unsigned short int start, last; 5697296Ssam 5707296Ssam PSWAIT(); 5717296Ssam psaddr->ps_addr = MAOL; 5727296Ssam PSWAIT(); 5738572Sroot if (psp->ps_dbuffer.state == ON_DB) { 574*25472Ssam start = psp->ps_dbuffer.dbaddrs[!psp->ps_dbuffer.rbuffer]; 575*25472Ssam last = start+psp->ps_dbuffer.dbsize-2; /* 2 for halt cmd */ 576*25472Ssam psaddr->ps_data = last; 5777296Ssam PSWAIT(); 5787296Ssam psaddr->ps_data = start; 5797296Ssam } else { 5807296Ssam start = psaddr->ps_data; /* dummy: don't update limit */ 5817296Ssam PSWAIT(); 5827296Ssam psaddr->ps_data = psp->ps_map.outputstart; 5837296Ssam } 5847296Ssam } 5857296Ssam 5867296Ssam psmapstart(dfaddr, psp, psaddr) 587*25472Ssam unsigned short int dfaddr; 5887296Ssam register struct ps *psp; 5897296Ssam register struct psdevice *psaddr; 5907296Ssam { 5917296Ssam 5927296Ssam PSWAIT(); 5937296Ssam psaddr->ps_addr = MAIA; 5947296Ssam PSWAIT(); 5957296Ssam psaddr->ps_data = dfaddr; 5967296Ssam PSWAIT(); 5977296Ssam psaddr->ps_data = MAO|MAI; /* may want more here */ 5987296Ssam psp->ps_map.mode = RUNNING_MAP; 5997296Ssam } 6007296Ssam 601*25472Ssam int pskillcnt = 1; 602*25472Ssam 603*25472Ssam psmapstop(psaddr, psp, request) 6047296Ssam register struct psdevice *psaddr; 605*25472Ssam register struct ps *psp; 606*25472Ssam short int request; 6077296Ssam { 608*25472Ssam register int i; 6097296Ssam 610*25472Ssam request = request&(HALT_REQ|MOSTOP_REQ); /* overkill?? */ 611*25472Ssam for(i = 0; i < pskillcnt; i++) { 612*25472Ssam PSWAIT(); 613*25472Ssam psaddr->ps_addr = MASR; 614*25472Ssam PSWAIT(); 615*25472Ssam psaddr->ps_data = IOUT; /* zero MAI & MAO bits */ 616*25472Ssam PSWAIT(); 617*25472Ssam psaddr->ps_addr = MAIA; 618*25472Ssam PSWAIT(); 619*25472Ssam psaddr->ps_data = 0; /* 0 input address register */ 620*25472Ssam PSWAIT(); 621*25472Ssam psaddr->ps_addr = MAOA; 622*25472Ssam PSWAIT(); 623*25472Ssam psaddr->ps_data = 0; /* 0 output address register */ 624*25472Ssam PSWAIT(); 625*25472Ssam psaddr->ps_addr = SYSREQ; 626*25472Ssam PSWAIT(); 627*25472Ssam psaddr->ps_data = request; 628*25472Ssam } 629*25472Ssam psp->ps_map.mode = STOPPED_MAP; 6307296Ssam } 6317296Ssam 6327296Ssam /*ARGSUSED*/ 6337296Ssam psdeviceintr(dev) 6347296Ssam dev_t dev; 6357296Ssam { 6367296Ssam 6377296Ssam printf("ps device intr\n"); 6387296Ssam } 6397296Ssam 6407296Ssam /*ARGSUSED*/ 6417296Ssam psdmaintr(dev) 6427296Ssam dev_t dev; 6437296Ssam { 6447296Ssam 6457296Ssam printf("ps dma intr\n"); 6467296Ssam } 6477296Ssam 648*25472Ssam /*ARGSUSED*/ 6497296Ssam psreset(uban) 6507296Ssam int uban; 6517296Ssam { 6527296Ssam } 6537296Ssam 654*25472Ssam /*ARGSUSED*/ 6557296Ssam psextsync(PC, PS) { 6567296Ssam register int n; 6577296Ssam register struct psdevice *psaddr; 6587296Ssam register struct ps *psp; 6597296Ssam register int savepsaddr; 6607296Ssam 6617296Ssam #ifdef EXTERNAL_SYNC 6628572Sroot for (psp = ps, n = 0; n < NPS; psp++, n++) { 6638572Sroot if (!psp->ps_open) 6647296Ssam continue; 66514600Ssam if(psp->ps_refresh.mode == SYNCING_RF 66614600Ssam && psp->ps_refresh.state != TIME_RF) { 6677296Ssam psaddr = (struct psdevice *) psdinfo[n]->ui_addr; 6687296Ssam SAVEPSADDR(); 669*25472Ssam (void) psrfnext(psp, psaddr); 6707296Ssam RESTORPSADDR(); 6717296Ssam } else { 6727296Ssam psp->ps_clock.ticked++; 6737296Ssam psp->ps_clock.missed++; 6747296Ssam } 6757296Ssam } 6767296Ssam #endif 6777296Ssam } 6787296Ssam #endif 679