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*23511Ssam * @(#)ps.c 6.4 (Berkeley) 06/16/85 723334Smckusick */ 87296Ssam 97296Ssam /* 10*23511Ssam * 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 397296Ssam int psprobe(), psattach(), psintr(); 407296Ssam struct uba_device *psdinfo[NPS]; 417296Ssam u_short psstd[] = { 0 }; 427296Ssam struct uba_driver psdriver = 437296Ssam { psprobe, 0, psattach, 0, psstd, "ps", psdinfo }; 447296Ssam 457296Ssam #define PSUNIT(dev) (minor(dev)) 467296Ssam 477296Ssam #define MAXAUTOREFRESH (4) 487296Ssam #define MAXAUTOMAP (4) 497296Ssam #define MAXDBSIZE (0177777/2) 507296Ssam 517296Ssam #define PSPRI (PZERO+1) 527296Ssam 537296Ssam #define PSWAIT() {register short int i, j; i=20000; while((i-- != 0)\ 547296Ssam && (((j=psaddr->ps_iostat)&DIOREADY)==0));} 557296Ssam 567296Ssam struct ps { 577296Ssam char ps_open; 587296Ssam short int ps_uid; 597296Ssam struct { 6014600Ssam enum { SINGLE_STEP_RF, AUTO_RF, TIME_RF } state; 6114600Ssam enum { RUNNING_RF, SYNCING_RF, WAITING_MAP, STOPPED_RF } mode; 627296Ssam unsigned short int sraddrs[MAXAUTOREFRESH]; 637296Ssam short int nsraddrs; 647296Ssam short int srcntr; 657296Ssam char waiting; 667296Ssam char stop; 677296Ssam int icnt; 6814600Ssam int timecnt; 697296Ssam } ps_refresh; 707296Ssam struct { 717296Ssam enum { ON_DB, OFF_DB } state; 727296Ssam unsigned short int dbaddrs[2]; 737296Ssam unsigned short int dbsize; 747296Ssam short int rbuffer; 757296Ssam } ps_dbuffer; 767296Ssam struct { 777296Ssam enum { SINGLE_STEP_MAP, AUTO_MAP } state; 787296Ssam enum { RUNNING_MAP, WAITING_RF, WAITING_START } mode; 797296Ssam unsigned short int maddrs[MAXAUTOMAP]; 807296Ssam short int nmaddrs; 817296Ssam short int mcntr; 827296Ssam short int outputstart; 837296Ssam char waiting; 847296Ssam char stop; 857296Ssam int icnt; 867296Ssam } ps_map; 877296Ssam struct { 887296Ssam short int ticked; 897296Ssam short int missed; 907296Ssam int icnt; 917296Ssam } ps_clock; 927296Ssam struct { 937296Ssam int icnt; 947296Ssam } ps_hit; 957296Ssam int ps_strayintr; 967296Ssam int last_request; 977296Ssam int strayrequest; 9814600Ssam int ps_icnt; 997296Ssam } ps[NPS]; 1007296Ssam 1017296Ssam psprobe(reg) 1027296Ssam caddr_t reg; 1037296Ssam { 1047296Ssam register int br, cvec; 1057296Ssam register struct psdevice *psaddr = (struct psdevice *) reg; 1067296Ssam 1077296Ssam psaddr->ps_iostat = PSRESET; 1087296Ssam DELAY(200); 1097296Ssam psaddr->ps_addr = RTCIE; 1107296Ssam PSWAIT(); 1117296Ssam psaddr->ps_data = 01; 1127296Ssam psaddr->ps_iostat = PSIE; 1137296Ssam psaddr->ps_addr = RTCSR; 1147296Ssam PSWAIT(); 1157296Ssam psaddr->ps_data = (SYNC|RUN); 1167296Ssam DELAY(200000); 1177296Ssam psaddr->ps_addr = RTCREQ; 1187296Ssam PSWAIT(); 1197296Ssam psaddr->ps_data = 01; 1207296Ssam psaddr->ps_iostat = 0; 1217296Ssam psaddr->ps_iostat = PSRESET; 1227418Skre return (sizeof (struct psdevice)); 1237296Ssam } 1247296Ssam 1257296Ssam /*ARGSUSED*/ 1267296Ssam psattach(ui) 1277296Ssam register struct uba_device *ui; 1287296Ssam { 1298572Sroot 1307296Ssam } 1317296Ssam 1327296Ssam psopen(dev) 1337296Ssam dev_t dev; 1347296Ssam { 1357296Ssam register struct ps *psp; 1367296Ssam register struct uba_device *ui; 1377296Ssam register int unit = PSUNIT(dev); 1387296Ssam 1398572Sroot if (unit >= NPS || (psp = &ps[minor(dev)])->ps_open || 1408572Sroot (ui = psdinfo[unit]) == 0 || ui->ui_alive == 0) 1418572Sroot return (ENXIO); 1427296Ssam psp->ps_open = 1; 1437296Ssam psp->ps_uid = u.u_uid; 1447296Ssam psp->ps_strayintr = 0; 1457296Ssam psp->ps_refresh.state = SINGLE_STEP_RF; 1467296Ssam psp->ps_refresh.waiting = 0; 1477296Ssam psp->ps_refresh.stop = 0; 1487296Ssam psp->ps_dbuffer.state = OFF_DB; 1497296Ssam psp->ps_map.state = SINGLE_STEP_MAP; 1507296Ssam psp->ps_map.waiting = 0; 1517296Ssam psp->ps_map.stop = 0; 1527296Ssam psp->ps_clock.ticked = 0; 1537296Ssam psp->ps_refresh.icnt = psp->ps_map.icnt = psp->ps_clock.icnt = 0; 15414600Ssam psp->ps_icnt = 0; 1557296Ssam maptouser(ui->ui_addr); 1568572Sroot return (0); 1577296Ssam } 1587296Ssam 1597296Ssam psclose(dev) 1607296Ssam dev_t dev; 1617296Ssam { 1627296Ssam register struct psdevice *psaddr = 1637296Ssam (struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr; 1647296Ssam 1657296Ssam ps[PSUNIT(dev)].ps_open = 0; 1667296Ssam psaddr->ps_iostat = 0; /* clear IENABLE */ 1677296Ssam PSWAIT(); 1687296Ssam psaddr->ps_addr = RFSR; /* set in auto refresh mode */ 1697296Ssam PSWAIT(); 1707296Ssam psaddr->ps_data = AUTOREF; 1717296Ssam unmaptouser(psaddr); 1727296Ssam } 1737296Ssam 1747296Ssam /*ARGSUSED*/ 1757730Sroot psread(dev, uio) 1767296Ssam dev_t dev; 1777730Sroot struct uio *uio; 1787296Ssam { 1797296Ssam } 1807296Ssam 1817296Ssam /*ARGSUSED*/ 1827730Sroot pswrite(dev, uio) 1837296Ssam dev_t dev; 1847730Sroot struct uio *uio; 1857296Ssam { 1867296Ssam } 1877296Ssam 1887296Ssam /*ARGSUSED*/ 1897632Ssam psioctl(dev, cmd, data, flag) 1907632Ssam register caddr_t data; 1917296Ssam { 1927296Ssam register struct uba_device *ui = psdinfo[PSUNIT(dev)]; 1937296Ssam register struct ps *psp = &ps[PSUNIT(dev)]; 1947632Ssam int *waddr = *(int **)data; 1957296Ssam int n, arg, i; 1967296Ssam 1977296Ssam switch (cmd) { 1987632Ssam 1997632Ssam case PSIOGETADDR: 2007632Ssam *(caddr_t *)data = ui->ui_addr; 2017296Ssam break; 2027632Ssam 2037632Ssam case PSIOAUTOREFRESH: 2047296Ssam n = fuword(waddr++); 2058572Sroot if (n == -1) 2068572Sroot return (EFAULT); 2078572Sroot if (n < 0 || n > MAXAUTOREFRESH) 2088572Sroot return (EINVAL); 2098572Sroot for (i = 0; i < n; i++) { 2108572Sroot if ((arg = fuword(waddr++)) == -1) 2118572Sroot return (EFAULT); 2128572Sroot psp->ps_refresh.sraddrs[i] = arg; 2137296Ssam } 2148572Sroot psp->ps_refresh.state = AUTO_RF; 2158572Sroot psp->ps_refresh.nsraddrs = n; 2168572Sroot psp->ps_refresh.srcntr = 0; 2178572Sroot psp->ps_refresh.mode = WAITING_MAP; 2187296Ssam break; 2197632Ssam 2207632Ssam case PSIOAUTOMAP: 2217296Ssam n = fuword(waddr++); 2228572Sroot if (n == -1) 2238572Sroot return (EFAULT); 2248572Sroot if (n < 0 || n > MAXAUTOMAP) 2258572Sroot return (EINVAL); 2268572Sroot for (i = 0; i < n; i++) { 2278572Sroot if ((arg = fuword(waddr++)) == -1) 2288572Sroot return (EFAULT); 2298572Sroot psp->ps_map.maddrs[i] = arg; 2307296Ssam } 2318572Sroot if ((arg = fuword(waddr++)) == -1) 2328572Sroot return (EFAULT); 2338572Sroot psp->ps_map.outputstart = arg; 2348572Sroot psp->ps_map.state = AUTO_MAP; 2358572Sroot psp->ps_map.nmaddrs = n; 2368572Sroot psp->ps_map.mcntr = 0; 2378572Sroot psp->ps_map.mode = WAITING_START; 2387296Ssam break; 2397632Ssam 2407632Ssam case PSIOSINGLEREFRESH: 2417296Ssam psp->ps_refresh.state = SINGLE_STEP_RF; 2427296Ssam break; 2437632Ssam 2447632Ssam case PSIOSINGLEMAP: 2457296Ssam psp->ps_map.state = SINGLE_STEP_MAP; 2467296Ssam break; 2477632Ssam 2487632Ssam case PSIODOUBLEBUFFER: 2498572Sroot if ((arg = fuword(waddr++)) == -1) 2508572Sroot return (EFAULT); 2518572Sroot psp->ps_dbuffer.dbaddrs[0] = arg; 2528572Sroot if ((arg = fuword(waddr++)) == -1) 2538572Sroot return (EFAULT); 2548572Sroot if (arg <= 0 || arg > MAXDBSIZE) 2558572Sroot return (EINVAL); 2568572Sroot psp->ps_dbuffer.dbsize = arg; 2578572Sroot psp->ps_dbuffer.dbaddrs[1] = 2588572Sroot psp->ps_dbuffer.dbaddrs[0]+arg; 2598572Sroot psp->ps_dbuffer.state = ON_DB; 2608572Sroot psp->ps_dbuffer.rbuffer = 0; 2617296Ssam break; 2627632Ssam 2637632Ssam case PSIOSINGLEBUFFER: 2647296Ssam psp->ps_dbuffer.state = OFF_DB; 2657296Ssam break; 2667632Ssam 26714600Ssam case PSIOTIMEREFRESH: 26814600Ssam if (psp->ps_refresh.state != SINGLE_STEP_RF) 26914600Ssam return(EINVAL); 27014600Ssam if ((arg = fuword(waddr++)) == -1) 27114600Ssam return(EFAULT); 27214600Ssam psp->ps_refresh.state = TIME_RF; 27314600Ssam psp->ps_refresh.timecnt = arg; 27414600Ssam break; 27514600Ssam 2767632Ssam case PSIOWAITREFRESH: 2778572Sroot if (psp->ps_refresh.mode != RUNNING_RF) /* not running */ 2788572Sroot return (0); /* dont wait */ 2798572Sroot /* fall into ... */ 2807632Ssam 28114600Ssam case PSIOSTOPREFRESH: 28214600Ssam if (cmd == PSIOSTOPREFRESH) { 28314600Ssam if (psp->ps_refresh.mode == STOPPED_RF 28414600Ssam && psp->ps_refresh.state != TIME_RF) 28514600Ssam return (0); 2867296Ssam psp->ps_refresh.stop = 1; 28714600Ssam } 2887296Ssam spl5(); 2897296Ssam psp->ps_refresh.waiting = 1; 2908572Sroot while (psp->ps_refresh.waiting) 2917296Ssam sleep(&psp->ps_refresh.waiting, PSPRI); 2927296Ssam spl0(); 29314600Ssam if (cmd == PSIOSTOPREFRESH) 29414600Ssam psp->ps_refresh.mode = STOPPED_RF; 29514600Ssam if (psp->ps_refresh.state == TIME_RF) 29614600Ssam psp->ps_refresh.state = SINGLE_STEP_RF; 2977296Ssam break; 2987632Ssam 2997632Ssam case PSIOWAITMAP: 3008572Sroot if (psp->ps_map.mode != RUNNING_MAP) /* not running */ 3018572Sroot return (0); /* dont wait */ 3028572Sroot /* fall into ... */ 3037632Ssam 3047632Ssam case PSIOSTOPMAP: 30514600Ssam if (cmd == PSIOSTOPMAP) 3067296Ssam psp->ps_map.stop = 1; 3077296Ssam spl5(); 3087296Ssam psp->ps_map.waiting = 1; 3098572Sroot while (psp->ps_map.waiting) 3107296Ssam sleep(&psp->ps_map.waiting, PSPRI); 3117296Ssam spl0(); 3127296Ssam break; 3137632Ssam 3147296Ssam default: 3158572Sroot return (ENOTTY); 3167296Ssam break; 3177296Ssam } 3188572Sroot return (0); 3197296Ssam } 3207296Ssam 3217296Ssam #define SAVEPSADDR() {register short int i, x;x=spl6();i=psaddr->ps_addr;\ 3227296Ssam while(((i=psaddr->ps_iostat)&DIOREADY)==0);\ 3237296Ssam savepsaddr=psaddr->ps_data;splx(x);} 3247296Ssam #define RESTORPSADDR() {register int x,i;x=spl6();\ 3257296Ssam while(((i=psaddr->ps_iostat)&DIOREADY)==0);\ 3267296Ssam psaddr->ps_addr=savepsaddr;splx(x);} 3277296Ssam 3287296Ssam psclockintr(dev) 3297296Ssam dev_t dev; 3307296Ssam { 3317296Ssam register struct psdevice *psaddr = 3327296Ssam (struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr; 3337296Ssam register struct ps *psp = &ps[PSUNIT(dev)]; 3347296Ssam int savepsaddr; 3357296Ssam 3368572Sroot if (!psp->ps_open) 3377296Ssam return; 3387296Ssam psp->ps_clock.icnt++; 3397296Ssam SAVEPSADDR(); 3407296Ssam #ifndef EXTERNAL_SYNC 3418572Sroot if (psp->ps_refresh.state == AUTO_RF) { 34214600Ssam if (psp->ps_refresh.mode == SYNCING_RF 34314600Ssam && psp->ps_refresh.state != TIME_RF) { 3447296Ssam psrfnext(psp, psaddr); 3457296Ssam } else { 3467296Ssam psp->ps_clock.ticked++; 3477296Ssam psp->ps_clock.missed++; 3487296Ssam } 3497296Ssam } 3507296Ssam #endif 3517296Ssam PSWAIT(); 3527296Ssam psaddr->ps_addr = RTCREQ; 3537296Ssam PSWAIT(); 3547296Ssam psaddr->ps_data = 01; /* clear the request bits */ 3557296Ssam RESTORPSADDR(); 3567296Ssam } 3577296Ssam 3587296Ssam /*ARGSUSED*/ 3597296Ssam pssystemintr(dev) 3607296Ssam dev_t dev; 3617296Ssam { 3627296Ssam register struct psdevice *psaddr = 3637296Ssam (struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr; 3647296Ssam register struct ps *psp = &ps[PSUNIT(dev)]; 3657296Ssam short int request; 3667296Ssam register int savepsaddr, x; 3677296Ssam 3688572Sroot if (!psp->ps_open) 3697296Ssam return; 37014600Ssam psp->ps_icnt++; 3717296Ssam SAVEPSADDR(); 3727296Ssam PSWAIT(); 3737296Ssam psaddr->ps_addr = SYSREQ; 3747296Ssam PSWAIT(); 37514600Ssam request = psaddr->ps_data&0377; 3767296Ssam psp->last_request = request; 3777296Ssam PSWAIT(); 3787296Ssam psaddr->ps_addr = SYSREQ; 3797296Ssam PSWAIT(); 3807296Ssam psaddr->ps_data = request&(~(HALT_REQ|MOSTOP_REQ)); /* acknowledge */ 3817296Ssam 3828572Sroot if (request & (MOSTOP_REQ|HALT_REQ)) { /* Map stopped */ 3837296Ssam psp->ps_map.icnt++; 3847296Ssam psmapstop(psaddr); /* kill it dead */ 3858572Sroot if (psp->ps_map.waiting) { 3867296Ssam psp->ps_map.waiting = 0; 3877296Ssam wakeup(&psp->ps_map.waiting); 3888572Sroot if (psp->ps_map.stop) { 3897296Ssam psp->ps_map.stop = 0; 3907296Ssam goto tryrf; 3917296Ssam } 3927296Ssam } 3938572Sroot if (psp->ps_map.state == AUTO_MAP) 3948572Sroot if (!psmapnext(psp, psaddr)) { 3957296Ssam psp->ps_map.mcntr = 0; 3967296Ssam /* prepare for next round */ 3977296Ssam pssetmapbounds(psp, psaddr); 3988572Sroot if (psp->ps_refresh.mode == WAITING_MAP) { 3998572Sroot if (psp->ps_dbuffer.state == ON_DB) 4007296Ssam /* fill other db */ 4017296Ssam psdbswitch(psp, psaddr); 4027296Ssam else 4037296Ssam psp->ps_map.mode = WAITING_RF; 4047296Ssam psrfnext(psp, psaddr); /* start rf */ 4057296Ssam } else 4067296Ssam psp->ps_map.mode = WAITING_RF; 4077296Ssam } 4087296Ssam } 4097296Ssam tryrf: 4108572Sroot if (request & RFSTOP_REQ) { /* Refresh stopped */ 4117296Ssam psp->ps_refresh.icnt++; 41214600Ssam if (psp->ps_refresh.state == TIME_RF) 41314600Ssam if(--psp->ps_refresh.timecnt > 0) 41414600Ssam goto tryhit; 4157296Ssam psrfstop(psaddr, psp); 4168572Sroot if (psp->ps_refresh.waiting) { 4177296Ssam psp->ps_refresh.waiting = 0; 4187296Ssam wakeup(&psp->ps_refresh.waiting); 4198572Sroot if (psp->ps_refresh.stop) { 4207296Ssam psp->ps_refresh.stop = 0; 4217296Ssam goto tryhit; 4227296Ssam } 4237296Ssam } 4248572Sroot if (psp->ps_refresh.state == AUTO_RF) 4258572Sroot if (!psrfnext(psp, psaddr)) { /* at end of refresh cycle */ 4268572Sroot if (psp->ps_map.state == AUTO_MAP && 4277296Ssam psp->ps_map.mode==WAITING_RF) { 4288572Sroot if (psp->ps_dbuffer.state == ON_DB) 4297296Ssam psdbswitch(psp, psaddr); 4307296Ssam else 4317296Ssam psmapnext(psp, psaddr); 4327296Ssam } 4337296Ssam psp->ps_refresh.srcntr = 0; 4347296Ssam #ifdef EXTERNAL_SYNC 4357296Ssam x = spl6(); 4367296Ssam #endif 4378572Sroot if (!psp->ps_clock.ticked || 4387296Ssam !psrfnext(psp, psaddr)) { 4397296Ssam psp->ps_refresh.mode = SYNCING_RF; 4407296Ssam } 4417296Ssam psp->ps_clock.ticked = 0; 4427296Ssam psp->ps_refresh.mode = SYNCING_RF; 4437296Ssam #ifdef EXTERNAL_SYNC 4447296Ssam splx(x); 4457296Ssam #endif 4467296Ssam } 4477296Ssam } 4487296Ssam tryhit: 4498572Sroot if (request & HIT_REQ) { /* Hit request */ 4507296Ssam psp->ps_hit.icnt++; 4517296Ssam } 4528572Sroot if (request == 0) 4537296Ssam psp->ps_strayintr++; 4547296Ssam RESTORPSADDR(); 4557296Ssam } 4567296Ssam 4577296Ssam psrfnext(psp, psaddr) 4587296Ssam register struct ps *psp; 4597296Ssam register struct psdevice *psaddr; 4607296Ssam { 4617296Ssam 4628572Sroot if (psp->ps_refresh.srcntr < psp->ps_refresh.nsraddrs) 4637296Ssam psrfstart(psp->ps_refresh.sraddrs[psp->ps_refresh.srcntr++], 4647296Ssam psp, psaddr); 4658572Sroot else if (psp->ps_refresh.srcntr == psp->ps_refresh.nsraddrs 4667296Ssam && psp->ps_dbuffer.state == ON_DB) { 4677296Ssam psrfstart(psp->ps_dbuffer.dbaddrs[psp->ps_dbuffer.rbuffer], 4687296Ssam psp, psaddr); 4697296Ssam psp->ps_refresh.srcntr++; /* flag for after dbuffer */ 4707296Ssam } else 4717296Ssam return(0); 4727296Ssam return(1); 4737296Ssam } 4747296Ssam 4757296Ssam psrfstart(dfaddr, psp, psaddr) 4767296Ssam short int dfaddr; 4777296Ssam register struct ps *psp; 4787296Ssam register struct psdevice *psaddr; 4797296Ssam { 4807296Ssam int dummy; 4817296Ssam 4827296Ssam PSWAIT(); 4837296Ssam psaddr->ps_addr = RFASA; 4847296Ssam PSWAIT(); 4857296Ssam psaddr->ps_data = dfaddr; 4867296Ssam PSWAIT(); 4877296Ssam dummy = psaddr->ps_data; /* just access to get to status reg */ 4887296Ssam PSWAIT(); 4897296Ssam psaddr->ps_data = RFSTART; /* may want to | this value in */ 4907296Ssam psp->ps_refresh.mode = RUNNING_RF; 4917296Ssam } 4927296Ssam 4937296Ssam psrfstop(psaddr, psp) 4947296Ssam register struct psdevice *psaddr; 4957296Ssam register struct ps *psp; 4967296Ssam { 4977296Ssam 4987296Ssam PSWAIT(); 4997296Ssam psaddr->ps_addr = RFSR; 5007296Ssam PSWAIT(); 5017296Ssam psaddr->ps_data = 0; 5027296Ssam } 5037296Ssam 5047296Ssam psdbswitch(psp, psaddr) 5057296Ssam register struct ps *psp; 5067296Ssam register struct psdevice *psaddr; 5077296Ssam { 5087296Ssam 5097296Ssam psp->ps_dbuffer.rbuffer = !psp->ps_dbuffer.rbuffer; 5107296Ssam pssetmapbounds(psp, psaddr); 5117296Ssam psmapnext(psp, psaddr); 5127296Ssam } 5137296Ssam 5147296Ssam psmapnext(psp, psaddr) 5157296Ssam register struct ps *psp; 5167296Ssam register struct psdevice *psaddr; 5177296Ssam { 5187296Ssam 5198572Sroot if (psp->ps_map.mcntr < psp->ps_map.nmaddrs) 5207296Ssam psmapstart(psp->ps_map.maddrs[psp->ps_map.mcntr++], psp, psaddr); 5217296Ssam else 5227296Ssam return(0); 5237296Ssam return(1); 5247296Ssam } 5257296Ssam 5267296Ssam pssetmapbounds(psp, psaddr) 5277296Ssam register struct ps *psp; 5287296Ssam register struct psdevice *psaddr; 5297296Ssam { 5307296Ssam unsigned short int start; 5317296Ssam 5327296Ssam PSWAIT(); 5337296Ssam psaddr->ps_addr = MAOL; 5347296Ssam PSWAIT(); 5358572Sroot if (psp->ps_dbuffer.state == ON_DB) { 5367296Ssam psaddr->ps_data = (start = psp->ps_dbuffer.dbaddrs[!psp->ps_dbuffer.rbuffer]) 5377296Ssam +psp->ps_dbuffer.dbsize-2; /* 2 for a refresh halt command */ 5387296Ssam PSWAIT(); 5397296Ssam psaddr->ps_data = start; 5407296Ssam } else { 5417296Ssam start = psaddr->ps_data; /* dummy: don't update limit */ 5427296Ssam PSWAIT(); 5437296Ssam psaddr->ps_data = psp->ps_map.outputstart; 5447296Ssam } 5457296Ssam } 5467296Ssam 5477296Ssam psmapstart(dfaddr, psp, psaddr) 5487296Ssam int dfaddr; 5497296Ssam register struct ps *psp; 5507296Ssam register struct psdevice *psaddr; 5517296Ssam { 5527296Ssam int data; 5537296Ssam 5547296Ssam PSWAIT(); 5557296Ssam psaddr->ps_addr = MAIA; 5567296Ssam PSWAIT(); 5577296Ssam psaddr->ps_data = dfaddr; 5587296Ssam PSWAIT(); 5597296Ssam psaddr->ps_data = MAO|MAI; /* may want more here */ 5607296Ssam psp->ps_map.mode = RUNNING_MAP; 5617296Ssam } 5627296Ssam 5637296Ssam psmapstop(psaddr) 5647296Ssam register struct psdevice *psaddr; 5657296Ssam { 5667296Ssam 5677296Ssam PSWAIT(); 5687296Ssam psaddr->ps_addr = MASR; 5697296Ssam PSWAIT(); 5707296Ssam psaddr->ps_data = 0; /* zero MAI bit */ 5717296Ssam PSWAIT(); 5727296Ssam psaddr->ps_addr = MAIA; 5737296Ssam PSWAIT(); 5747296Ssam psaddr->ps_data = 0; /* zero input address register */ 5757296Ssam PSWAIT(); 5767296Ssam psaddr->ps_addr = SYSREQ; 5777296Ssam PSWAIT(); 5787296Ssam psaddr->ps_data = HALT_REQ|MOSTOP_REQ; /* overkill?? */ 5797296Ssam } 5807296Ssam 5817296Ssam /*ARGSUSED*/ 5827296Ssam psdeviceintr(dev) 5837296Ssam dev_t dev; 5847296Ssam { 5857296Ssam 5867296Ssam printf("ps device intr\n"); 5877296Ssam } 5887296Ssam 5897296Ssam /*ARGSUSED*/ 5907296Ssam psdmaintr(dev) 5917296Ssam dev_t dev; 5927296Ssam { 5937296Ssam 5947296Ssam printf("ps dma intr\n"); 5957296Ssam } 5967296Ssam 5977296Ssam psreset(uban) 5987296Ssam int uban; 5997296Ssam { 6007296Ssam } 6017296Ssam 6027296Ssam psextsync(PC, PS) { 6037296Ssam register int n; 6047296Ssam register struct psdevice *psaddr; 6057296Ssam register struct ps *psp; 6067296Ssam register int savepsaddr; 6077296Ssam 6087296Ssam #ifdef EXTERNAL_SYNC 6098572Sroot for (psp = ps, n = 0; n < NPS; psp++, n++) { 6108572Sroot if (!psp->ps_open) 6117296Ssam continue; 61214600Ssam if(psp->ps_refresh.mode == SYNCING_RF 61314600Ssam && psp->ps_refresh.state != TIME_RF) { 6147296Ssam psaddr = (struct psdevice *) psdinfo[n]->ui_addr; 6157296Ssam SAVEPSADDR(); 6167296Ssam psrfnext(psp, psaddr); 6177296Ssam RESTORPSADDR(); 6187296Ssam } else { 6197296Ssam psp->ps_clock.ticked++; 6207296Ssam psp->ps_clock.missed++; 6217296Ssam } 6227296Ssam } 6237296Ssam #endif 6247296Ssam } 6257296Ssam #endif 626