1*7296Ssam /* ps.c 4.1 82/06/26 */ 2*7296Ssam 3*7296Ssam /* 4*7296Ssam * Evans and Sutherland Picture System 2 driver 5*7296Ssam */ 6*7296Ssam 7*7296Ssam /* 8*7296Ssam * Still to be done: 9*7296Ssam * WAIT_HIT 10*7296Ssam */ 11*7296Ssam 12*7296Ssam #include "ps.h" 13*7296Ssam #if NPS > 0 14*7296Ssam 15*7296Ssam #define EXTERNAL_SYNC 16*7296Ssam 17*7296Ssam #include "../h/param.h" 18*7296Ssam #include "../h/systm.h" 19*7296Ssam #include "../h/tty.h" 20*7296Ssam #include "../h/pte.h" 21*7296Ssam #include "../h/map.h" 22*7296Ssam #include "../h/buf.h" 23*7296Ssam #include "../h/ubareg.h" 24*7296Ssam #include "../h/ubavar.h" 25*7296Ssam #include "../h/conf.h" 26*7296Ssam #include "../h/dir.h" 27*7296Ssam #include "../h/user.h" 28*7296Ssam #include "../h/psreg.h" 29*7296Ssam 30*7296Ssam int psprobe(), psattach(), psintr(); 31*7296Ssam struct uba_device *psdinfo[NPS]; 32*7296Ssam u_short psstd[] = { 0 }; 33*7296Ssam struct uba_driver psdriver = 34*7296Ssam { psprobe, 0, psattach, 0, psstd, "ps", psdinfo }; 35*7296Ssam 36*7296Ssam #define PSUNIT(dev) (minor(dev)) 37*7296Ssam 38*7296Ssam #define MAXAUTOREFRESH (4) 39*7296Ssam #define MAXAUTOMAP (4) 40*7296Ssam #define MAXDBSIZE (0177777/2) 41*7296Ssam 42*7296Ssam #define PSPRI (PZERO+1) 43*7296Ssam 44*7296Ssam #define PSWAIT() {register short int i, j; i=20000; while((i-- != 0)\ 45*7296Ssam && (((j=psaddr->ps_iostat)&DIOREADY)==0));} 46*7296Ssam 47*7296Ssam struct ps { 48*7296Ssam char ps_open; 49*7296Ssam short int ps_uid; 50*7296Ssam struct { 51*7296Ssam enum { SINGLE_STEP_RF, AUTO_RF } state; 52*7296Ssam enum { RUNNING_RF, SYNCING_RF, WAITING_MAP } mode; 53*7296Ssam unsigned short int sraddrs[MAXAUTOREFRESH]; 54*7296Ssam short int nsraddrs; 55*7296Ssam short int srcntr; 56*7296Ssam char waiting; 57*7296Ssam char stop; 58*7296Ssam int icnt; 59*7296Ssam } ps_refresh; 60*7296Ssam struct { 61*7296Ssam enum { ON_DB, OFF_DB } state; 62*7296Ssam unsigned short int dbaddrs[2]; 63*7296Ssam unsigned short int dbsize; 64*7296Ssam short int rbuffer; 65*7296Ssam } ps_dbuffer; 66*7296Ssam struct { 67*7296Ssam enum { SINGLE_STEP_MAP, AUTO_MAP } state; 68*7296Ssam enum { RUNNING_MAP, WAITING_RF, WAITING_START } mode; 69*7296Ssam unsigned short int maddrs[MAXAUTOMAP]; 70*7296Ssam short int nmaddrs; 71*7296Ssam short int mcntr; 72*7296Ssam short int outputstart; 73*7296Ssam char waiting; 74*7296Ssam char stop; 75*7296Ssam int icnt; 76*7296Ssam } ps_map; 77*7296Ssam struct { 78*7296Ssam short int ticked; 79*7296Ssam short int missed; 80*7296Ssam int icnt; 81*7296Ssam } ps_clock; 82*7296Ssam struct { 83*7296Ssam int icnt; 84*7296Ssam } ps_hit; 85*7296Ssam int ps_strayintr; 86*7296Ssam int last_request; 87*7296Ssam int strayrequest; 88*7296Ssam } ps[NPS]; 89*7296Ssam 90*7296Ssam psprobe(reg) 91*7296Ssam caddr_t reg; 92*7296Ssam { 93*7296Ssam register int br, cvec; 94*7296Ssam register struct psdevice *psaddr = (struct psdevice *) reg; 95*7296Ssam 96*7296Ssam psaddr->ps_iostat = PSRESET; 97*7296Ssam DELAY(200); 98*7296Ssam psaddr->ps_addr = RTCIE; 99*7296Ssam PSWAIT(); 100*7296Ssam psaddr->ps_data = 01; 101*7296Ssam psaddr->ps_iostat = PSIE; 102*7296Ssam psaddr->ps_addr = RTCSR; 103*7296Ssam PSWAIT(); 104*7296Ssam psaddr->ps_data = (SYNC|RUN); 105*7296Ssam DELAY(200000); 106*7296Ssam psaddr->ps_addr = RTCREQ; 107*7296Ssam PSWAIT(); 108*7296Ssam psaddr->ps_data = 01; 109*7296Ssam psaddr->ps_iostat = 0; 110*7296Ssam psaddr->ps_iostat = PSRESET; 111*7296Ssam } 112*7296Ssam 113*7296Ssam /*ARGSUSED*/ 114*7296Ssam psattach(ui) 115*7296Ssam register struct uba_device *ui; 116*7296Ssam { 117*7296Ssam } 118*7296Ssam 119*7296Ssam 120*7296Ssam psopen(dev) 121*7296Ssam dev_t dev; 122*7296Ssam { 123*7296Ssam register struct ps *psp; 124*7296Ssam register struct uba_device *ui; 125*7296Ssam register int unit = PSUNIT(dev); 126*7296Ssam 127*7296Ssam if(unit >= NPS || (psp = &ps[minor(dev)])->ps_open || 128*7296Ssam (ui = psdinfo[unit]) == 0 || ui->ui_alive == 0) { 129*7296Ssam u.u_error = ENXIO; 130*7296Ssam return; 131*7296Ssam } 132*7296Ssam psp->ps_open = 1; 133*7296Ssam psp->ps_uid = u.u_uid; 134*7296Ssam psp->ps_strayintr = 0; 135*7296Ssam psp->ps_refresh.state = SINGLE_STEP_RF; 136*7296Ssam psp->ps_refresh.waiting = 0; 137*7296Ssam psp->ps_refresh.stop = 0; 138*7296Ssam psp->ps_dbuffer.state = OFF_DB; 139*7296Ssam psp->ps_map.state = SINGLE_STEP_MAP; 140*7296Ssam psp->ps_map.waiting = 0; 141*7296Ssam psp->ps_map.stop = 0; 142*7296Ssam psp->ps_clock.ticked = 0; 143*7296Ssam psp->ps_refresh.icnt = psp->ps_map.icnt = psp->ps_clock.icnt = 0; 144*7296Ssam maptouser(ui->ui_addr); 145*7296Ssam } 146*7296Ssam 147*7296Ssam psclose(dev) 148*7296Ssam dev_t dev; 149*7296Ssam { 150*7296Ssam register struct psdevice *psaddr = 151*7296Ssam (struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr; 152*7296Ssam 153*7296Ssam ps[PSUNIT(dev)].ps_open = 0; 154*7296Ssam psaddr->ps_iostat = 0; /* clear IENABLE */ 155*7296Ssam PSWAIT(); 156*7296Ssam psaddr->ps_addr = RFSR; /* set in auto refresh mode */ 157*7296Ssam PSWAIT(); 158*7296Ssam psaddr->ps_data = AUTOREF; 159*7296Ssam unmaptouser(psaddr); 160*7296Ssam } 161*7296Ssam 162*7296Ssam /*ARGSUSED*/ 163*7296Ssam psread(dev) 164*7296Ssam dev_t dev; 165*7296Ssam { 166*7296Ssam } 167*7296Ssam 168*7296Ssam /*ARGSUSED*/ 169*7296Ssam pswrite(dev) 170*7296Ssam dev_t dev; 171*7296Ssam { 172*7296Ssam } 173*7296Ssam 174*7296Ssam /*ARGSUSED*/ 175*7296Ssam psioctl(dev, cmd, addr, flag) 176*7296Ssam register caddr_t addr; 177*7296Ssam { 178*7296Ssam register struct uba_device *ui = psdinfo[PSUNIT(dev)]; 179*7296Ssam register struct ps *psp = &ps[PSUNIT(dev)]; 180*7296Ssam int *waddr = (int *) addr; 181*7296Ssam int n, arg, i; 182*7296Ssam 183*7296Ssam switch (cmd) { 184*7296Ssam case PSGETADDR: 185*7296Ssam (void) suword(addr, ui->ui_addr); 186*7296Ssam break; 187*7296Ssam case PSAUTOREFRESH: 188*7296Ssam n = fuword(waddr++); 189*7296Ssam if(n == -1) 190*7296Ssam u.u_error = EFAULT; 191*7296Ssam else if(n < 0 || n > MAXAUTOREFRESH) 192*7296Ssam u.u_error = EINVAL; 193*7296Ssam else { 194*7296Ssam for(i = 0; i < n; i++) 195*7296Ssam if((arg = fuword(waddr++)) == -1) { 196*7296Ssam u.u_error = EFAULT; 197*7296Ssam break; 198*7296Ssam } 199*7296Ssam else 200*7296Ssam psp->ps_refresh.sraddrs[i] = arg; 201*7296Ssam if(!u.u_error) { 202*7296Ssam psp->ps_refresh.state = AUTO_RF; 203*7296Ssam psp->ps_refresh.nsraddrs = n; 204*7296Ssam psp->ps_refresh.srcntr = 0; 205*7296Ssam psp->ps_refresh.mode = WAITING_MAP; 206*7296Ssam } 207*7296Ssam } 208*7296Ssam break; 209*7296Ssam case PSAUTOMAP: 210*7296Ssam n = fuword(waddr++); 211*7296Ssam if(n == -1) 212*7296Ssam u.u_error = EFAULT; 213*7296Ssam else if(n < 0 || n > MAXAUTOMAP) 214*7296Ssam u.u_error = EINVAL; 215*7296Ssam else { 216*7296Ssam for(i = 0; i < n; i++) 217*7296Ssam if((arg = fuword(waddr++)) == -1) { 218*7296Ssam u.u_error = EFAULT; 219*7296Ssam break; 220*7296Ssam } 221*7296Ssam else 222*7296Ssam psp->ps_map.maddrs[i] = arg; 223*7296Ssam if(!u.u_error) 224*7296Ssam if((arg = fuword(waddr++)) == -1) 225*7296Ssam u.u_error = EFAULT; 226*7296Ssam else 227*7296Ssam psp->ps_map.outputstart = arg; 228*7296Ssam if(!u.u_error) { 229*7296Ssam psp->ps_map.state = AUTO_MAP; 230*7296Ssam psp->ps_map.nmaddrs = n; 231*7296Ssam psp->ps_map.mcntr = 0; 232*7296Ssam psp->ps_map.mode = WAITING_START; 233*7296Ssam } 234*7296Ssam } 235*7296Ssam break; 236*7296Ssam case PSSINGLEREFRESH: 237*7296Ssam psp->ps_refresh.state = SINGLE_STEP_RF; 238*7296Ssam break; 239*7296Ssam case PSSINGLEMAP: 240*7296Ssam psp->ps_map.state = SINGLE_STEP_MAP; 241*7296Ssam break; 242*7296Ssam case PSDOUBLEBUFFER: 243*7296Ssam if((arg = fuword(waddr++)) == -1) 244*7296Ssam u.u_error = EFAULT; 245*7296Ssam else { 246*7296Ssam psp->ps_dbuffer.dbaddrs[0] = arg; 247*7296Ssam if((arg = fuword(waddr++)) == -1) 248*7296Ssam u.u_error = EFAULT; 249*7296Ssam else if(arg <= 0 || arg > MAXDBSIZE) 250*7296Ssam u.u_error = EINVAL; 251*7296Ssam else { 252*7296Ssam psp->ps_dbuffer.dbsize = arg; 253*7296Ssam psp->ps_dbuffer.dbaddrs[1] = 254*7296Ssam psp->ps_dbuffer.dbaddrs[0]+arg; 255*7296Ssam psp->ps_dbuffer.state = ON_DB; 256*7296Ssam psp->ps_dbuffer.rbuffer = 0; 257*7296Ssam } 258*7296Ssam } 259*7296Ssam break; 260*7296Ssam case PSSINGLEBUFFER: 261*7296Ssam psp->ps_dbuffer.state = OFF_DB; 262*7296Ssam break; 263*7296Ssam case PSWAITREFRESH: 264*7296Ssam if(psp->ps_refresh.mode != RUNNING_RF) /* not running */ 265*7296Ssam return; /* dont wait */ 266*7296Ssam case PSSTOPREFRESH: 267*7296Ssam if(cmd == PSSTOPREFRESH) 268*7296Ssam psp->ps_refresh.stop = 1; 269*7296Ssam spl5(); 270*7296Ssam psp->ps_refresh.waiting = 1; 271*7296Ssam while(psp->ps_refresh.waiting) 272*7296Ssam sleep(&psp->ps_refresh.waiting, PSPRI); 273*7296Ssam spl0(); 274*7296Ssam break; 275*7296Ssam case PSWAITMAP: 276*7296Ssam if(psp->ps_map.mode != RUNNING_MAP) /* not running */ 277*7296Ssam return; /* dont wait */ 278*7296Ssam case PSSTOPMAP: 279*7296Ssam if(cmd == PSSTOPMAP) 280*7296Ssam psp->ps_map.stop = 1; 281*7296Ssam spl5(); 282*7296Ssam psp->ps_map.waiting = 1; 283*7296Ssam while(psp->ps_map.waiting) 284*7296Ssam sleep(&psp->ps_map.waiting, PSPRI); 285*7296Ssam spl0(); 286*7296Ssam break; 287*7296Ssam default: 288*7296Ssam u.u_error = ENOTTY; /* Not a legal ioctl cmd. */ 289*7296Ssam break; 290*7296Ssam } 291*7296Ssam } 292*7296Ssam 293*7296Ssam #define SAVEPSADDR() {register short int i, x;x=spl6();i=psaddr->ps_addr;\ 294*7296Ssam while(((i=psaddr->ps_iostat)&DIOREADY)==0);\ 295*7296Ssam savepsaddr=psaddr->ps_data;splx(x);} 296*7296Ssam #define RESTORPSADDR() {register int x,i;x=spl6();\ 297*7296Ssam while(((i=psaddr->ps_iostat)&DIOREADY)==0);\ 298*7296Ssam psaddr->ps_addr=savepsaddr;splx(x);} 299*7296Ssam 300*7296Ssam psclockintr(dev) 301*7296Ssam dev_t dev; 302*7296Ssam { 303*7296Ssam register struct psdevice *psaddr = 304*7296Ssam (struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr; 305*7296Ssam register struct ps *psp = &ps[PSUNIT(dev)]; 306*7296Ssam int savepsaddr; 307*7296Ssam 308*7296Ssam if(!psp->ps_open) 309*7296Ssam return; 310*7296Ssam psp->ps_clock.icnt++; 311*7296Ssam SAVEPSADDR(); 312*7296Ssam #ifndef EXTERNAL_SYNC 313*7296Ssam if(psp->ps_refresh.state == AUTO_RF) { 314*7296Ssam if(psp->ps_refresh.mode == SYNCING_RF) { 315*7296Ssam psrfnext(psp, psaddr); 316*7296Ssam } else { 317*7296Ssam psp->ps_clock.ticked++; 318*7296Ssam psp->ps_clock.missed++; 319*7296Ssam } 320*7296Ssam } 321*7296Ssam #endif 322*7296Ssam PSWAIT(); 323*7296Ssam psaddr->ps_addr = RTCREQ; 324*7296Ssam PSWAIT(); 325*7296Ssam psaddr->ps_data = 01; /* clear the request bits */ 326*7296Ssam RESTORPSADDR(); 327*7296Ssam } 328*7296Ssam 329*7296Ssam /*ARGSUSED*/ 330*7296Ssam pssystemintr(dev) 331*7296Ssam dev_t dev; 332*7296Ssam { 333*7296Ssam register struct psdevice *psaddr = 334*7296Ssam (struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr; 335*7296Ssam register struct ps *psp = &ps[PSUNIT(dev)]; 336*7296Ssam short int request; 337*7296Ssam register int savepsaddr, x; 338*7296Ssam 339*7296Ssam if(!psp->ps_open) 340*7296Ssam return; 341*7296Ssam SAVEPSADDR(); 342*7296Ssam PSWAIT(); 343*7296Ssam psaddr->ps_addr = SYSREQ; 344*7296Ssam PSWAIT(); 345*7296Ssam request = psaddr->ps_data; 346*7296Ssam psp->last_request = request; 347*7296Ssam PSWAIT(); 348*7296Ssam psaddr->ps_addr = SYSREQ; 349*7296Ssam PSWAIT(); 350*7296Ssam psaddr->ps_data = request&(~(HALT_REQ|MOSTOP_REQ)); /* acknowledge */ 351*7296Ssam 352*7296Ssam if(request & (MOSTOP_REQ|HALT_REQ)) { /* Map stopped */ 353*7296Ssam psp->ps_map.icnt++; 354*7296Ssam psmapstop(psaddr); /* kill it dead */ 355*7296Ssam if(psp->ps_map.waiting) { 356*7296Ssam psp->ps_map.waiting = 0; 357*7296Ssam wakeup(&psp->ps_map.waiting); 358*7296Ssam if(psp->ps_map.stop) { 359*7296Ssam psp->ps_map.stop = 0; 360*7296Ssam goto tryrf; 361*7296Ssam } 362*7296Ssam } 363*7296Ssam if(psp->ps_map.state == AUTO_MAP) 364*7296Ssam if(!psmapnext(psp, psaddr)) { 365*7296Ssam psp->ps_map.mcntr = 0; 366*7296Ssam /* prepare for next round */ 367*7296Ssam pssetmapbounds(psp, psaddr); 368*7296Ssam if(psp->ps_refresh.mode == WAITING_MAP) { 369*7296Ssam if(psp->ps_dbuffer.state == ON_DB) 370*7296Ssam /* fill other db */ 371*7296Ssam psdbswitch(psp, psaddr); 372*7296Ssam else 373*7296Ssam psp->ps_map.mode = WAITING_RF; 374*7296Ssam psrfnext(psp, psaddr); /* start rf */ 375*7296Ssam } else 376*7296Ssam psp->ps_map.mode = WAITING_RF; 377*7296Ssam } 378*7296Ssam } 379*7296Ssam tryrf: 380*7296Ssam if(request & RFSTOP_REQ) { /* Refresh stopped */ 381*7296Ssam psp->ps_refresh.icnt++; 382*7296Ssam psrfstop(psaddr, psp); 383*7296Ssam if(psp->ps_refresh.waiting) { 384*7296Ssam psp->ps_refresh.waiting = 0; 385*7296Ssam wakeup(&psp->ps_refresh.waiting); 386*7296Ssam if(psp->ps_refresh.stop) { 387*7296Ssam psp->ps_refresh.stop = 0; 388*7296Ssam goto tryhit; 389*7296Ssam } 390*7296Ssam } 391*7296Ssam if(psp->ps_refresh.state == AUTO_RF) 392*7296Ssam if(!psrfnext(psp, psaddr)) { /* at end of refresh cycle */ 393*7296Ssam if(psp->ps_map.state == AUTO_MAP && 394*7296Ssam psp->ps_map.mode==WAITING_RF) { 395*7296Ssam if(psp->ps_dbuffer.state == ON_DB) 396*7296Ssam psdbswitch(psp, psaddr); 397*7296Ssam else 398*7296Ssam psmapnext(psp, psaddr); 399*7296Ssam } 400*7296Ssam psp->ps_refresh.srcntr = 0; 401*7296Ssam #ifdef EXTERNAL_SYNC 402*7296Ssam x = spl6(); 403*7296Ssam #endif 404*7296Ssam if(!psp->ps_clock.ticked || 405*7296Ssam !psrfnext(psp, psaddr)) { 406*7296Ssam psp->ps_refresh.mode = SYNCING_RF; 407*7296Ssam } 408*7296Ssam psp->ps_clock.ticked = 0; 409*7296Ssam psp->ps_refresh.mode = SYNCING_RF; 410*7296Ssam #ifdef EXTERNAL_SYNC 411*7296Ssam splx(x); 412*7296Ssam #endif 413*7296Ssam } 414*7296Ssam } 415*7296Ssam tryhit: 416*7296Ssam if(request & HIT_REQ) { /* Hit request */ 417*7296Ssam psp->ps_hit.icnt++; 418*7296Ssam } 419*7296Ssam if(request == 0) 420*7296Ssam psp->ps_strayintr++; 421*7296Ssam RESTORPSADDR(); 422*7296Ssam } 423*7296Ssam 424*7296Ssam psrfnext(psp, psaddr) 425*7296Ssam register struct ps *psp; 426*7296Ssam register struct psdevice *psaddr; 427*7296Ssam { 428*7296Ssam 429*7296Ssam if(psp->ps_refresh.srcntr < psp->ps_refresh.nsraddrs) 430*7296Ssam psrfstart(psp->ps_refresh.sraddrs[psp->ps_refresh.srcntr++], 431*7296Ssam psp, psaddr); 432*7296Ssam else if(psp->ps_refresh.srcntr == psp->ps_refresh.nsraddrs 433*7296Ssam && psp->ps_dbuffer.state == ON_DB) { 434*7296Ssam psrfstart(psp->ps_dbuffer.dbaddrs[psp->ps_dbuffer.rbuffer], 435*7296Ssam psp, psaddr); 436*7296Ssam psp->ps_refresh.srcntr++; /* flag for after dbuffer */ 437*7296Ssam } else 438*7296Ssam return(0); 439*7296Ssam return(1); 440*7296Ssam } 441*7296Ssam 442*7296Ssam psrfstart(dfaddr, psp, psaddr) 443*7296Ssam short int dfaddr; 444*7296Ssam register struct ps *psp; 445*7296Ssam register struct psdevice *psaddr; 446*7296Ssam { 447*7296Ssam int dummy; 448*7296Ssam 449*7296Ssam PSWAIT(); 450*7296Ssam psaddr->ps_addr = RFASA; 451*7296Ssam PSWAIT(); 452*7296Ssam psaddr->ps_data = dfaddr; 453*7296Ssam PSWAIT(); 454*7296Ssam dummy = psaddr->ps_data; /* just access to get to status reg */ 455*7296Ssam PSWAIT(); 456*7296Ssam psaddr->ps_data = RFSTART; /* may want to | this value in */ 457*7296Ssam psp->ps_refresh.mode = RUNNING_RF; 458*7296Ssam } 459*7296Ssam 460*7296Ssam psrfstop(psaddr, psp) 461*7296Ssam register struct psdevice *psaddr; 462*7296Ssam register struct ps *psp; 463*7296Ssam { 464*7296Ssam 465*7296Ssam PSWAIT(); 466*7296Ssam psaddr->ps_addr = RFSR; 467*7296Ssam PSWAIT(); 468*7296Ssam psaddr->ps_data = 0; 469*7296Ssam } 470*7296Ssam 471*7296Ssam psdbswitch(psp, psaddr) 472*7296Ssam register struct ps *psp; 473*7296Ssam register struct psdevice *psaddr; 474*7296Ssam { 475*7296Ssam 476*7296Ssam psp->ps_dbuffer.rbuffer = !psp->ps_dbuffer.rbuffer; 477*7296Ssam pssetmapbounds(psp, psaddr); 478*7296Ssam psmapnext(psp, psaddr); 479*7296Ssam } 480*7296Ssam 481*7296Ssam psmapnext(psp, psaddr) 482*7296Ssam register struct ps *psp; 483*7296Ssam register struct psdevice *psaddr; 484*7296Ssam { 485*7296Ssam 486*7296Ssam if(psp->ps_map.mcntr < psp->ps_map.nmaddrs) 487*7296Ssam psmapstart(psp->ps_map.maddrs[psp->ps_map.mcntr++], psp, psaddr); 488*7296Ssam else 489*7296Ssam return(0); 490*7296Ssam return(1); 491*7296Ssam } 492*7296Ssam 493*7296Ssam pssetmapbounds(psp, psaddr) 494*7296Ssam register struct ps *psp; 495*7296Ssam register struct psdevice *psaddr; 496*7296Ssam { 497*7296Ssam unsigned short int start; 498*7296Ssam 499*7296Ssam PSWAIT(); 500*7296Ssam psaddr->ps_addr = MAOL; 501*7296Ssam PSWAIT(); 502*7296Ssam if(psp->ps_dbuffer.state == ON_DB) { 503*7296Ssam psaddr->ps_data = (start = psp->ps_dbuffer.dbaddrs[!psp->ps_dbuffer.rbuffer]) 504*7296Ssam +psp->ps_dbuffer.dbsize-2; /* 2 for a refresh halt command */ 505*7296Ssam PSWAIT(); 506*7296Ssam psaddr->ps_data = start; 507*7296Ssam } else { 508*7296Ssam start = psaddr->ps_data; /* dummy: don't update limit */ 509*7296Ssam PSWAIT(); 510*7296Ssam psaddr->ps_data = psp->ps_map.outputstart; 511*7296Ssam } 512*7296Ssam } 513*7296Ssam 514*7296Ssam psmapstart(dfaddr, psp, psaddr) 515*7296Ssam int dfaddr; 516*7296Ssam register struct ps *psp; 517*7296Ssam register struct psdevice *psaddr; 518*7296Ssam { 519*7296Ssam int data; 520*7296Ssam 521*7296Ssam PSWAIT(); 522*7296Ssam psaddr->ps_addr = MAIA; 523*7296Ssam PSWAIT(); 524*7296Ssam psaddr->ps_data = dfaddr; 525*7296Ssam PSWAIT(); 526*7296Ssam psaddr->ps_data = MAO|MAI; /* may want more here */ 527*7296Ssam psp->ps_map.mode = RUNNING_MAP; 528*7296Ssam } 529*7296Ssam 530*7296Ssam psmapstop(psaddr) 531*7296Ssam register struct psdevice *psaddr; 532*7296Ssam { 533*7296Ssam 534*7296Ssam PSWAIT(); 535*7296Ssam psaddr->ps_addr = MASR; 536*7296Ssam PSWAIT(); 537*7296Ssam psaddr->ps_data = 0; /* zero MAI bit */ 538*7296Ssam PSWAIT(); 539*7296Ssam psaddr->ps_addr = MAIA; 540*7296Ssam PSWAIT(); 541*7296Ssam psaddr->ps_data = 0; /* zero input address register */ 542*7296Ssam PSWAIT(); 543*7296Ssam psaddr->ps_addr = SYSREQ; 544*7296Ssam PSWAIT(); 545*7296Ssam psaddr->ps_data = HALT_REQ|MOSTOP_REQ; /* overkill?? */ 546*7296Ssam } 547*7296Ssam 548*7296Ssam /*ARGSUSED*/ 549*7296Ssam psdeviceintr(dev) 550*7296Ssam dev_t dev; 551*7296Ssam { 552*7296Ssam 553*7296Ssam printf("ps device intr\n"); 554*7296Ssam } 555*7296Ssam 556*7296Ssam /*ARGSUSED*/ 557*7296Ssam psdmaintr(dev) 558*7296Ssam dev_t dev; 559*7296Ssam { 560*7296Ssam 561*7296Ssam printf("ps dma intr\n"); 562*7296Ssam } 563*7296Ssam 564*7296Ssam psreset(uban) 565*7296Ssam int uban; 566*7296Ssam { 567*7296Ssam } 568*7296Ssam 569*7296Ssam psextsync(PC, PS) { 570*7296Ssam register int n; 571*7296Ssam register struct psdevice *psaddr; 572*7296Ssam register struct ps *psp; 573*7296Ssam register int savepsaddr; 574*7296Ssam 575*7296Ssam #ifdef EXTERNAL_SYNC 576*7296Ssam for(psp = ps, n = 0; n < NPS; psp++, n++) { 577*7296Ssam if(!psp->ps_open) 578*7296Ssam continue; 579*7296Ssam if(psp->ps_refresh.mode == SYNCING_RF) { 580*7296Ssam psaddr = (struct psdevice *) psdinfo[n]->ui_addr; 581*7296Ssam SAVEPSADDR(); 582*7296Ssam psrfnext(psp, psaddr); 583*7296Ssam RESTORPSADDR(); 584*7296Ssam } else { 585*7296Ssam psp->ps_clock.ticked++; 586*7296Ssam psp->ps_clock.missed++; 587*7296Ssam } 588*7296Ssam } 589*7296Ssam #endif 590*7296Ssam } 591*7296Ssam #endif 592