zs.c revision 1.35
1/*	$NetBSD: zs.c,v 1.35 2002/03/17 19:40:36 atatat Exp $	*/
2
3/*
4 * Copyright (c) 1995 L. Weppelman (Atari modifications)
5 * Copyright (c) 1992, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * This software was developed by the Computer Systems Engineering group
9 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
10 * contributed to Berkeley.
11 *
12 *
13 * All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Lawrence Berkeley Laboratory.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 *    notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 *    notice, this list of conditions and the following disclaimer in the
25 *    documentation and/or other materials provided with the distribution.
26 * 3. All advertising materials mentioning features or use of this software
27 *    must display the following acknowledgement:
28 *	This product includes software developed by the University of
29 *	California, Berkeley and its contributors.
30 * 4. Neither the name of the University nor the names of its contributors
31 *    may be used to endorse or promote products derived from this software
32 *    without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
35 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * SUCH DAMAGE.
45 *
46 *	@(#)zs.c	8.1 (Berkeley) 7/19/93
47 */
48
49/*
50 * Zilog Z8530 (ZSCC) driver.
51 *
52 * Runs two tty ports (modem2 and serial2) on zs0.
53 *
54 * This driver knows far too much about chip to usage mappings.
55 */
56#include <sys/param.h>
57#include <sys/systm.h>
58#include <sys/proc.h>
59#include <sys/device.h>
60#include <sys/conf.h>
61#include <sys/file.h>
62#include <sys/ioctl.h>
63#include <sys/malloc.h>
64#include <sys/tty.h>
65#include <sys/time.h>
66#include <sys/kernel.h>
67#include <sys/syslog.h>
68
69#include <machine/cpu.h>
70#include <machine/iomap.h>
71#include <machine/scu.h>
72#include <machine/mfp.h>
73#include <atari/dev/ym2149reg.h>
74
75#include <dev/ic/z8530reg.h>
76#include <atari/dev/zsvar.h>
77#include "zs.h"
78#if NZS > 1
79#error "This driver supports only 1 85C30!"
80#endif
81
82#if NZS > 0
83
84#define PCLK	(8053976)	/* PCLK pin input clock rate */
85#define PCLK_HD	(9600 * 1536)	/* PCLK on Hades pin input clock rate */
86
87#define splzs	spl5
88
89/*
90 * Software state per found chip.
91 */
92struct zs_softc {
93    struct	device		zi_dev;    /* base device		  */
94    volatile struct zsdevice	*zi_zs;    /* chip registers		  */
95    struct	zs_chanstate	zi_cs[2];  /* chan A and B software state */
96};
97
98static u_char	cb_scheduled = 0;	/* Already asked for callback? */
99/*
100 * Define the registers for a closed port
101 */
102static u_char zs_init_regs[16] = {
103/*  0 */	0,
104/*  1 */	0,
105/*  2 */	0x60,
106/*  3 */	0,
107/*  4 */	0,
108/*  5 */	0,
109/*  6 */	0,
110/*  7 */	0,
111/*  8 */	0,
112/*  9 */	ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT,
113/* 10 */	ZSWR10_NRZ,
114/* 11 */	ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD,
115/* 12 */	0,
116/* 13 */	0,
117/* 14 */	ZSWR14_BAUD_FROM_PCLK | ZSWR14_BAUD_ENA,
118/* 15 */	0
119};
120
121/*
122 * Define the machine dependant clock frequencies
123 * If BRgen feeds sender/receiver we always use a
124 * divisor 16, therefor the division by 16 can as
125 * well be done here.
126 */
127static u_long zs_freqs_tt[] = {
128	/*
129	 * Atari TT, RTxCB is generated by TT-MFP timer C,
130	 * which is set to 307.2KHz during initialisation
131	 * and never changed afterwards.
132	 */
133	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
134	 229500,	/* BRgen, RTxCA, divisor 16	*/
135	3672000,	/* RTxCA, from PCLK4		*/
136	      0,	/* TRxCA, external		*/
137
138	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
139	  19200,	/* BRgen, RTxCB, divisor 16	*/
140	 307200,	/* RTxCB, from TT-MFP TCO	*/
141	2457600		/* TRxCB, from BCLK		*/
142};
143
144static u_long zs_freqs_falcon[] = {
145	/*
146	 * Atari Falcon, XXX no specs available, this might be wrong
147	 */
148	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
149	 229500,	/* BRgen, RTxCA, divisor 16	*/
150	3672000,	/* RTxCA, ???			*/
151	      0,	/* TRxCA, external		*/
152
153	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
154	 229500,	/* BRgen, RTxCB, divisor 16	*/
155	3672000,	/* RTxCB, ???			*/
156	2457600		/* TRxCB, ???			*/
157};
158
159static u_long zs_freqs_hades[] = {
160	/*
161	 * XXX: Channel-A unchecked!!!!!
162	 */
163     PCLK_HD/16,	/* BRgen, PCLK,  divisor 16	*/
164	 229500,	/* BRgen, RTxCA, divisor 16	*/
165	3672000,	/* RTxCA, from PCLK4		*/
166	      0,	/* TRxCA, external		*/
167
168     PCLK_HD/16,	/* BRgen, PCLK,  divisor 16	*/
169	 235550,	/* BRgen, RTxCB, divisor 16	*/
170	3768800,	/* RTxCB, 3.7688MHz		*/
171	3768800		/* TRxCB, 3.7688MHz		*/
172};
173
174static u_long zs_freqs_generic[] = {
175	/*
176	 * other machines, assume only PCLK is available
177	 */
178	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
179	      0,	/* BRgen, RTxCA, divisor 16	*/
180	      0,	/* RTxCA, unknown		*/
181	      0,	/* TRxCA, unknown		*/
182
183	PCLK/16,	/* BRgen, PCLK,  divisor 16	*/
184	      0,	/* BRgen, RTxCB, divisor 16	*/
185	      0,	/* RTxCB, unknown		*/
186	      0		/* TRxCB, unknown		*/
187};
188static u_long *zs_frequencies;
189
190/* Definition of the driver for autoconfig. */
191static int	zsmatch __P((struct device *, struct cfdata *, void *));
192static void	zsattach __P((struct device *, struct device *, void *));
193
194struct cfattach zs_ca = {
195	sizeof(struct zs_softc), zsmatch, zsattach
196};
197
198extern struct cfdriver zs_cd;
199
200/* {b,c}devsw[] function prototypes */
201dev_type_open(zsopen);
202dev_type_close(zsclose);
203dev_type_read(zsread);
204dev_type_write(zswrite);
205dev_type_poll(zspoll);
206dev_type_ioctl(zsioctl);
207dev_type_tty(zstty);
208
209/* Interrupt handlers. */
210int		zshard __P((long));
211static int	zssoft __P((long));
212static int	zsrint __P((struct zs_chanstate *, volatile struct zschan *));
213static int	zsxint __P((struct zs_chanstate *, volatile struct zschan *));
214static int	zssint __P((struct zs_chanstate *, volatile struct zschan *));
215
216static struct zs_chanstate *zslist;
217
218/* Routines called from other code. */
219static void	zsstart __P((struct tty *));
220void		zsstop __P((struct tty *, int));
221
222/* Routines purely local to this driver. */
223static void	zsoverrun __P((int, long *, char *));
224static int	zsparam __P((struct tty *, struct termios *));
225static int	zsbaudrate __P((int, int, int *, int *, int *, int *));
226static int	zs_modem __P((struct zs_chanstate *, int, int));
227static void	zs_loadchannelregs __P((volatile struct zschan *, u_char *));
228static void	zs_shutdown __P((struct zs_chanstate *));
229
230static int zsshortcuts;	/* number of "shortcut" software interrupts */
231
232static int
233zsmatch(pdp, cfp, auxp)
234struct device	*pdp;
235struct cfdata	*cfp;
236void		*auxp;
237{
238	static int	zs_matched = 0;
239
240	if(strcmp("zs", auxp) || zs_matched)
241		return(0);
242	zs_matched = 1;
243	return(1);
244}
245
246/*
247 * Attach a found zs.
248 */
249static void
250zsattach(parent, dev, aux)
251struct device	*parent;
252struct device	*dev;
253void		*aux;
254{
255	register struct zs_softc		*zi;
256	register struct zs_chanstate		*cs;
257	register volatile struct zsdevice	*addr;
258		 char				tmp;
259
260	addr      = (struct zsdevice *)AD_SCC;
261	zi        = (struct zs_softc *)dev;
262	zi->zi_zs = addr;
263	cs        = zi->zi_cs;
264
265	/*
266	 * Get the command register into a known state.
267	 */
268	tmp = addr->zs_chan[ZS_CHAN_A].zc_csr;
269	tmp = addr->zs_chan[ZS_CHAN_A].zc_csr;
270	tmp = addr->zs_chan[ZS_CHAN_B].zc_csr;
271	tmp = addr->zs_chan[ZS_CHAN_B].zc_csr;
272
273	/*
274	 * Do a hardware reset.
275	 */
276	ZS_WRITE(&addr->zs_chan[ZS_CHAN_A], 9, ZSWR9_HARD_RESET);
277	delay(50000);	/*enough ? */
278	ZS_WRITE(&addr->zs_chan[ZS_CHAN_A], 9, 0);
279
280	/*
281	 * Initialize both channels
282	 */
283	zs_loadchannelregs(&addr->zs_chan[ZS_CHAN_A], zs_init_regs);
284	zs_loadchannelregs(&addr->zs_chan[ZS_CHAN_B], zs_init_regs);
285
286	if(machineid & ATARI_TT) {
287		/*
288		 * ininitialise TT-MFP timer C: 307200Hz
289		 * timer C and D share one control register:
290		 *	bits 0-2 control timer D
291		 *	bits 4-6 control timer C
292		 */
293		int cr = MFP2->mf_tcdcr & 7;
294		MFP2->mf_tcdcr = cr;		/* stop timer C  */
295		MFP2->mf_tcdr  = 1;		/* counter 1     */
296		cr |= T_Q004 << 4;		/* divisor 4     */
297		MFP2->mf_tcdcr = cr;		/* start timer C */
298		/*
299		 * enable scc related interrupts
300		 */
301		SCU->vme_mask |= SCU_SCC;
302
303		zs_frequencies = zs_freqs_tt;
304	} else if (machineid & ATARI_FALCON) {
305		zs_frequencies = zs_freqs_falcon;
306	} else if (machineid & ATARI_HADES) {
307		zs_frequencies = zs_freqs_hades;
308	} else {
309		zs_frequencies = zs_freqs_generic;
310	}
311
312	/* link into interrupt list with order (A,B) (B=A+1) */
313	cs[0].cs_next = &cs[1];
314	cs[1].cs_next = zslist;
315	zslist        = cs;
316
317	cs->cs_unit  = 0;
318	cs->cs_zc    = &addr->zs_chan[ZS_CHAN_A];
319	cs++;
320	cs->cs_unit  = 1;
321	cs->cs_zc    = &addr->zs_chan[ZS_CHAN_B];
322
323	printf(": serial2 on channel a and modem2 on channel b\n");
324}
325
326/*
327 * Open a zs serial port.
328 */
329int
330zsopen(dev, flags, mode, p)
331dev_t		dev;
332int		flags;
333int		mode;
334struct proc	*p;
335{
336	register struct tty		*tp;
337	register struct zs_chanstate	*cs;
338		 struct zs_softc	*zi;
339		 int			unit = ZS_UNIT(dev);
340		 int			zs = unit >> 1;
341		 int			error, s;
342
343	if(zs >= zs_cd.cd_ndevs || (zi = zs_cd.cd_devs[zs]) == NULL)
344		return (ENXIO);
345	cs = &zi->zi_cs[unit & 1];
346
347	/*
348	 * When port A (ser02) is selected on the TT, make sure
349	 * the port is enabled.
350	 */
351	if((machineid & ATARI_TT) && !(unit & 1))
352		ym2149_ser2(1);
353
354	if (cs->cs_rbuf == NULL) {
355		cs->cs_rbuf = malloc(ZLRB_RING_SIZE * sizeof(int), M_DEVBUF,
356								   M_WAITOK);
357	}
358
359	tp = cs->cs_ttyp;
360	if(tp == NULL) {
361		cs->cs_ttyp = tp = ttymalloc();
362		tty_attach(tp);
363		tp->t_dev   = dev;
364		tp->t_oproc = zsstart;
365		tp->t_param = zsparam;
366	}
367
368	if ((tp->t_state & TS_ISOPEN) &&
369	    (tp->t_state & TS_XCLUDE) &&
370	    p->p_ucred->cr_uid != 0)
371		return (EBUSY);
372
373	s  = spltty();
374
375	/*
376	 * Do the following iff this is a first open.
377	 */
378	if (!(tp->t_state & TS_ISOPEN) && tp->t_wopen == 0) {
379		if(tp->t_ispeed == 0) {
380			tp->t_iflag = TTYDEF_IFLAG;
381			tp->t_oflag = TTYDEF_OFLAG;
382			tp->t_cflag = TTYDEF_CFLAG;
383			tp->t_lflag = TTYDEF_LFLAG;
384			tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
385		}
386		ttychars(tp);
387		ttsetwater(tp);
388
389		(void)zsparam(tp, &tp->t_termios);
390
391		/*
392		 * Turn on DTR.  We must always do this, even if carrier is not
393		 * present, because otherwise we'd have to use TIOCSDTR
394		 * immediately after setting CLOCAL, which applications do not
395		 * expect.  We always assert DTR while the device is open
396		 * unless explicitly requested to deassert it.
397		 */
398		zs_modem(cs, ZSWR5_RTS|ZSWR5_DTR, DMSET);
399		/* May never get a status intr. if DCD already on. -gwr */
400		if((cs->cs_rr0 = cs->cs_zc->zc_csr) & ZSRR0_DCD)
401			tp->t_state |= TS_CARR_ON;
402		if(cs->cs_softcar)
403			tp->t_state |= TS_CARR_ON;
404	}
405
406	splx(s);
407
408	error = ttyopen(tp, ZS_DIALOUT(dev), (flags & O_NONBLOCK));
409	if (error)
410		goto bad;
411
412	error = tp->t_linesw->l_open(dev, tp);
413	if(error)
414		goto bad;
415	return (0);
416
417bad:
418	if (!(tp->t_state & TS_ISOPEN) && tp->t_wopen == 0) {
419		/*
420		 * We failed to open the device, and nobody else had it opened.
421		 * Clean up the state as appropriate.
422		 */
423		zs_shutdown(cs);
424	}
425	return(error);
426}
427
428/*
429 * Close a zs serial port.
430 */
431int
432zsclose(dev, flags, mode, p)
433dev_t		dev;
434int		flags;
435int		mode;
436struct proc	*p;
437{
438	register struct zs_chanstate	*cs;
439	register struct tty		*tp;
440		 struct zs_softc	*zi;
441		 int			unit = ZS_UNIT(dev);
442
443	zi = zs_cd.cd_devs[unit >> 1];
444	cs = &zi->zi_cs[unit & 1];
445	tp = cs->cs_ttyp;
446
447	tp->t_linesw->l_close(tp, flags);
448	ttyclose(tp);
449
450	if (!(tp->t_state & TS_ISOPEN) && tp->t_wopen == 0) {
451		/*
452		 * Although we got a last close, the device may still be in
453		 * use; e.g. if this was the dialout node, and there are still
454		 * processes waiting for carrier on the non-dialout node.
455		 */
456		zs_shutdown(cs);
457	}
458	return (0);
459}
460
461/*
462 * Read/write zs serial port.
463 */
464int
465zsread(dev, uio, flags)
466dev_t		dev;
467struct uio	*uio;
468int		flags;
469{
470	register struct zs_chanstate	*cs;
471	register struct zs_softc	*zi;
472	register struct tty		*tp;
473		 int			unit;
474
475	unit = ZS_UNIT(dev);
476	zi   = zs_cd.cd_devs[unit >> 1];
477	cs   = &zi->zi_cs[unit & 1];
478	tp   = cs->cs_ttyp;
479
480	return(tp->t_linesw->l_read(tp, uio, flags));
481}
482
483int
484zswrite(dev, uio, flags)
485dev_t		dev;
486struct uio	*uio;
487int		flags;
488{
489	register struct zs_chanstate	*cs;
490	register struct zs_softc	*zi;
491	register struct tty		*tp;
492		 int			unit;
493
494	unit = ZS_UNIT(dev);
495	zi   = zs_cd.cd_devs[unit >> 1];
496	cs   = &zi->zi_cs[unit & 1];
497	tp   = cs->cs_ttyp;
498
499	return(tp->t_linesw->l_write(tp, uio, flags));
500}
501
502int
503zspoll(dev, events, p)
504dev_t		dev;
505int		events;
506struct proc	*p;
507{
508	register struct zs_chanstate	*cs;
509	register struct zs_softc	*zi;
510	register struct tty		*tp;
511		 int			unit;
512
513	unit = ZS_UNIT(dev);
514	zi   = zs_cd.cd_devs[unit >> 1];
515	cs   = &zi->zi_cs[unit & 1];
516	tp   = cs->cs_ttyp;
517
518	return ((*tp->t_linesw->l_poll)(tp, events, p));
519}
520
521struct tty *
522zstty(dev)
523dev_t	dev;
524{
525	register struct zs_chanstate	*cs;
526	register struct zs_softc	*zi;
527		 int			unit;
528
529	unit = ZS_UNIT(dev);
530	zi   = zs_cd.cd_devs[unit >> 1];
531	cs   = &zi->zi_cs[unit & 1];
532	return(cs->cs_ttyp);
533}
534
535/*
536 * ZS hardware interrupt.  Scan all ZS channels.  NB: we know here that
537 * channels are kept in (A,B) pairs.
538 *
539 * Do just a little, then get out; set a software interrupt if more
540 * work is needed.
541 *
542 * We deliberately ignore the vectoring Zilog gives us, and match up
543 * only the number of `reset interrupt under service' operations, not
544 * the order.
545 */
546
547int
548zshard(sr)
549long sr;
550{
551	register struct zs_chanstate	*a;
552#define	b (a + 1)
553	register volatile struct zschan *zc;
554	register int			rr3, intflags = 0, v, i;
555
556	do {
557	    intflags &= ~4;
558	    for(a = zslist; a != NULL; a = b->cs_next) {
559		rr3 = ZS_READ(a->cs_zc, 3);
560		if(rr3 & (ZSRR3_IP_A_RX|ZSRR3_IP_A_TX|ZSRR3_IP_A_STAT)) {
561			intflags |= 4|2;
562			zc = a->cs_zc;
563			i  = a->cs_rbput;
564			if(rr3 & ZSRR3_IP_A_RX && (v = zsrint(a, zc)) != 0) {
565				a->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
566				intflags |= 1;
567			}
568			if(rr3 & ZSRR3_IP_A_TX && (v = zsxint(a, zc)) != 0) {
569				a->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
570				intflags |= 1;
571			}
572			if(rr3 & ZSRR3_IP_A_STAT && (v = zssint(a, zc)) != 0) {
573				a->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
574				intflags |= 1;
575			}
576			a->cs_rbput = i;
577		}
578		if(rr3 & (ZSRR3_IP_B_RX|ZSRR3_IP_B_TX|ZSRR3_IP_B_STAT)) {
579			intflags |= 4|2;
580			zc = b->cs_zc;
581			i  = b->cs_rbput;
582			if(rr3 & ZSRR3_IP_B_RX && (v = zsrint(b, zc)) != 0) {
583				b->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
584				intflags |= 1;
585			}
586			if(rr3 & ZSRR3_IP_B_TX && (v = zsxint(b, zc)) != 0) {
587				b->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
588				intflags |= 1;
589			}
590			if(rr3 & ZSRR3_IP_B_STAT && (v = zssint(b, zc)) != 0) {
591				b->cs_rbuf[i++ & ZLRB_RING_MASK] = v;
592				intflags |= 1;
593			}
594			b->cs_rbput = i;
595		}
596	    }
597	} while(intflags & 4);
598#undef b
599
600	if(intflags & 1) {
601		if(BASEPRI(sr)) {
602			spl1();
603			zsshortcuts++;
604			return(zssoft(sr));
605		}
606		else if(!cb_scheduled) {
607			cb_scheduled++;
608			add_sicallback((si_farg)zssoft, 0, 0);
609		}
610	}
611	return(intflags & 2);
612}
613
614static int
615zsrint(cs, zc)
616register struct zs_chanstate	*cs;
617register volatile struct zschan	*zc;
618{
619	register int c;
620
621	/*
622	 * First read the status, because read of the received char
623	 * destroy the status of this char.
624	 */
625	c = ZS_READ(zc, 1);
626	c |= (zc->zc_data << 8);
627
628	/* clear receive error & interrupt condition */
629	zc->zc_csr = ZSWR0_RESET_ERRORS;
630	zc->zc_csr = ZSWR0_CLR_INTR;
631
632	return(ZRING_MAKE(ZRING_RINT, c));
633}
634
635static int
636zsxint(cs, zc)
637register struct zs_chanstate	*cs;
638register volatile struct zschan	*zc;
639{
640	register int i = cs->cs_tbc;
641
642	if(i == 0) {
643		zc->zc_csr = ZSWR0_RESET_TXINT;
644		zc->zc_csr = ZSWR0_CLR_INTR;
645		return(ZRING_MAKE(ZRING_XINT, 0));
646	}
647	cs->cs_tbc = i - 1;
648	zc->zc_data = *cs->cs_tba++;
649	zc->zc_csr = ZSWR0_CLR_INTR;
650	return (0);
651}
652
653static int
654zssint(cs, zc)
655register struct zs_chanstate	*cs;
656register volatile struct zschan	*zc;
657{
658	register int rr0;
659
660	rr0 = zc->zc_csr;
661	zc->zc_csr = ZSWR0_RESET_STATUS;
662	zc->zc_csr = ZSWR0_CLR_INTR;
663	/*
664	 * The chip's hardware flow control is, as noted in zsreg.h,
665	 * busted---if the DCD line goes low the chip shuts off the
666	 * receiver (!).  If we want hardware CTS flow control but do
667	 * not have it, and carrier is now on, turn HFC on; if we have
668	 * HFC now but carrier has gone low, turn it off.
669	 */
670	if(rr0 & ZSRR0_DCD) {
671		if(cs->cs_ttyp->t_cflag & CCTS_OFLOW &&
672		    (cs->cs_creg[3] & ZSWR3_HFC) == 0) {
673			cs->cs_creg[3] |= ZSWR3_HFC;
674			ZS_WRITE(zc, 3, cs->cs_creg[3]);
675		}
676	}
677	else {
678		if (cs->cs_creg[3] & ZSWR3_HFC) {
679			cs->cs_creg[3] &= ~ZSWR3_HFC;
680			ZS_WRITE(zc, 3, cs->cs_creg[3]);
681		}
682	}
683	return(ZRING_MAKE(ZRING_SINT, rr0));
684}
685
686/*
687 * Print out a ring or fifo overrun error message.
688 */
689static void
690zsoverrun(unit, ptime, what)
691int	unit;
692long	*ptime;
693char	*what;
694{
695
696	if(*ptime != time.tv_sec) {
697		*ptime = time.tv_sec;
698		log(LOG_WARNING, "zs%d%c: %s overrun\n", unit >> 1,
699		    (unit & 1) + 'a', what);
700	}
701}
702
703/*
704 * ZS software interrupt.  Scan all channels for deferred interrupts.
705 */
706int
707zssoft(sr)
708long sr;
709{
710    register struct zs_chanstate	*cs;
711    register volatile struct zschan	*zc;
712    register struct linesw		*line;
713    register struct tty			*tp;
714    register int			get, n, c, cc, unit, s;
715 	     int			retval = 0;
716
717    cb_scheduled = 0;
718    s = spltty();
719    for(cs = zslist; cs != NULL; cs = cs->cs_next) {
720	get = cs->cs_rbget;
721again:
722	n = cs->cs_rbput;	/* atomic			*/
723	if(get == n)		/* nothing more on this line	*/
724		continue;
725	retval = 1;
726	unit   = cs->cs_unit;	/* set up to handle interrupts	*/
727	zc     = cs->cs_zc;
728	tp     = cs->cs_ttyp;
729	line   = tp->t_linesw;
730	/*
731	 * Compute the number of interrupts in the receive ring.
732	 * If the count is overlarge, we lost some events, and
733	 * must advance to the first valid one.  It may get
734	 * overwritten if more data are arriving, but this is
735	 * too expensive to check and gains nothing (we already
736	 * lost out; all we can do at this point is trade one
737	 * kind of loss for another).
738	 */
739	n -= get;
740	if(n > ZLRB_RING_SIZE) {
741		zsoverrun(unit, &cs->cs_rotime, "ring");
742		get += n - ZLRB_RING_SIZE;
743		n    = ZLRB_RING_SIZE;
744	}
745	while(--n >= 0) {
746		/* race to keep ahead of incoming interrupts */
747		c = cs->cs_rbuf[get++ & ZLRB_RING_MASK];
748		switch (ZRING_TYPE(c)) {
749
750		case ZRING_RINT:
751			c = ZRING_VALUE(c);
752			if(c & ZSRR1_DO)
753				zsoverrun(unit, &cs->cs_fotime, "fifo");
754			cc = c >> 8;
755			if(c & ZSRR1_FE)
756				cc |= TTY_FE;
757			if(c & ZSRR1_PE)
758				cc |= TTY_PE;
759			line->l_rint(cc, tp);
760			break;
761
762		case ZRING_XINT:
763			/*
764			 * Transmit done: change registers and resume,
765			 * or clear BUSY.
766			 */
767			if(cs->cs_heldchange) {
768				int sps;
769
770				sps = splzs();
771				c = zc->zc_csr;
772				if((c & ZSRR0_DCD) == 0)
773					cs->cs_preg[3] &= ~ZSWR3_HFC;
774				bcopy((caddr_t)cs->cs_preg,
775				    (caddr_t)cs->cs_creg, 16);
776				zs_loadchannelregs(zc, cs->cs_creg);
777				splx(sps);
778				cs->cs_heldchange = 0;
779				if(cs->cs_heldtbc
780					&& (tp->t_state & TS_TTSTOP) == 0) {
781					cs->cs_tbc = cs->cs_heldtbc - 1;
782					zc->zc_data = *cs->cs_tba++;
783					goto again;
784				}
785			}
786			tp->t_state &= ~TS_BUSY;
787			if(tp->t_state & TS_FLUSH)
788				tp->t_state &= ~TS_FLUSH;
789			else ndflush(&tp->t_outq,cs->cs_tba
790						- (caddr_t)tp->t_outq.c_cf);
791			line->l_start(tp);
792			break;
793
794		case ZRING_SINT:
795			/*
796			 * Status line change.  HFC bit is run in
797			 * hardware interrupt, to avoid locking
798			 * at splzs here.
799			 */
800			c = ZRING_VALUE(c);
801			if((c ^ cs->cs_rr0) & ZSRR0_DCD) {
802				cc = (c & ZSRR0_DCD) != 0;
803				if(line->l_modem(tp, cc) == 0)
804					zs_modem(cs, ZSWR5_RTS|ZSWR5_DTR,
805							cc ? DMBIS : DMBIC);
806			}
807			cs->cs_rr0 = c;
808			break;
809
810		default:
811			log(LOG_ERR, "zs%d%c: bad ZRING_TYPE (%x)\n",
812			    unit >> 1, (unit & 1) + 'a', c);
813			break;
814		}
815	}
816	cs->cs_rbget = get;
817	goto again;
818    }
819    splx(s);
820    return (retval);
821}
822
823int
824zsioctl(dev, cmd, data, flag, p)
825dev_t		dev;
826u_long		cmd;
827caddr_t		data;
828int		flag;
829struct proc	*p;
830{
831		 int			unit = ZS_UNIT(dev);
832		 struct zs_softc	*zi = zs_cd.cd_devs[unit >> 1];
833	register struct tty		*tp = zi->zi_cs[unit & 1].cs_ttyp;
834	register int			error, s;
835	register struct zs_chanstate	*cs = &zi->zi_cs[unit & 1];
836
837	error = tp->t_linesw->l_ioctl(tp, cmd, data, flag, p);
838	if(error != EPASSTHROUGH)
839		return(error);
840
841	error = ttioctl(tp, cmd, data, flag, p);
842	if(error !=EPASSTHROUGH)
843		return (error);
844
845	switch (cmd) {
846	case TIOCSBRK:
847		s = splzs();
848		cs->cs_preg[5] |= ZSWR5_BREAK;
849		cs->cs_creg[5] |= ZSWR5_BREAK;
850		ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
851		splx(s);
852		break;
853	case TIOCCBRK:
854		s = splzs();
855		cs->cs_preg[5] &= ~ZSWR5_BREAK;
856		cs->cs_creg[5] &= ~ZSWR5_BREAK;
857		ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
858		splx(s);
859		break;
860	case TIOCGFLAGS: {
861		int bits = 0;
862
863		if(cs->cs_softcar)
864			bits |= TIOCFLAG_SOFTCAR;
865		if(cs->cs_creg[15] & ZSWR15_DCD_IE)
866			bits |= TIOCFLAG_CLOCAL;
867		if(cs->cs_creg[3] & ZSWR3_HFC)
868			bits |= TIOCFLAG_CRTSCTS;
869		*(int *)data = bits;
870		break;
871	}
872	case TIOCSFLAGS: {
873		int userbits = 0;
874
875		error = suser(p->p_ucred, &p->p_acflag);
876		if(error != 0)
877			return (EPERM);
878
879		userbits = *(int *)data;
880
881		/*
882		 * can have `local' or `softcar', and `rtscts' or `mdmbuf'
883		 # defaulting to software flow control.
884		 */
885		if(userbits & TIOCFLAG_SOFTCAR && userbits & TIOCFLAG_CLOCAL)
886			return(EINVAL);
887		if(userbits & TIOCFLAG_MDMBUF)	/* don't support this (yet?) */
888			return(ENODEV);
889
890		s = splzs();
891		if((userbits & TIOCFLAG_SOFTCAR)) {
892			cs->cs_softcar = 1;	/* turn on softcar */
893			cs->cs_preg[15] &= ~ZSWR15_DCD_IE; /* turn off dcd */
894			cs->cs_creg[15] &= ~ZSWR15_DCD_IE;
895			ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
896		}
897		else if(userbits & TIOCFLAG_CLOCAL) {
898			cs->cs_softcar = 0; 	/* turn off softcar */
899			cs->cs_preg[15] |= ZSWR15_DCD_IE; /* turn on dcd */
900			cs->cs_creg[15] |= ZSWR15_DCD_IE;
901			ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
902			tp->t_termios.c_cflag |= CLOCAL;
903		}
904		if(userbits & TIOCFLAG_CRTSCTS) {
905			cs->cs_preg[15] |= ZSWR15_CTS_IE;
906			cs->cs_creg[15] |= ZSWR15_CTS_IE;
907			ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
908			cs->cs_preg[3] |= ZSWR3_HFC;
909			cs->cs_creg[3] |= ZSWR3_HFC;
910			ZS_WRITE(cs->cs_zc, 3, cs->cs_creg[3]);
911			tp->t_termios.c_cflag |= CRTSCTS;
912		}
913		else {
914			/* no mdmbuf, so we must want software flow control */
915			cs->cs_preg[15] &= ~ZSWR15_CTS_IE;
916			cs->cs_creg[15] &= ~ZSWR15_CTS_IE;
917			ZS_WRITE(cs->cs_zc, 15, cs->cs_creg[15]);
918			cs->cs_preg[3] &= ~ZSWR3_HFC;
919			cs->cs_creg[3] &= ~ZSWR3_HFC;
920			ZS_WRITE(cs->cs_zc, 3, cs->cs_creg[3]);
921			tp->t_termios.c_cflag &= ~CRTSCTS;
922		}
923		splx(s);
924		break;
925	}
926	case TIOCSDTR:
927		zs_modem(cs, ZSWR5_DTR, DMBIS);
928		break;
929	case TIOCCDTR:
930		zs_modem(cs, ZSWR5_DTR, DMBIC);
931		break;
932	case TIOCMGET:
933		zs_modem(cs, 0, DMGET);
934		break;
935	case TIOCMSET:
936	case TIOCMBIS:
937	case TIOCMBIC:
938	default:
939		return (EPASSTHROUGH);
940	}
941	return (0);
942}
943
944/*
945 * Start or restart transmission.
946 */
947static void
948zsstart(tp)
949register struct tty *tp;
950{
951	register struct zs_chanstate	*cs;
952	register int			s, nch;
953		 int			unit = ZS_UNIT(tp->t_dev);
954		 struct zs_softc	*zi = zs_cd.cd_devs[unit >> 1];
955
956	cs = &zi->zi_cs[unit & 1];
957	s  = spltty();
958
959	/*
960	 * If currently active or delaying, no need to do anything.
961	 */
962	if(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
963		goto out;
964
965	/*
966	 * If there are sleepers, and output has drained below low
967	 * water mark, awaken.
968	 */
969	if(tp->t_outq.c_cc <= tp->t_lowat) {
970		if(tp->t_state & TS_ASLEEP) {
971			tp->t_state &= ~TS_ASLEEP;
972			wakeup((caddr_t)&tp->t_outq);
973		}
974		selwakeup(&tp->t_wsel);
975	}
976
977	nch = ndqb(&tp->t_outq, 0);	/* XXX */
978	if(nch) {
979		register char *p = tp->t_outq.c_cf;
980
981		/* mark busy, enable tx done interrupts, & send first byte */
982		tp->t_state |= TS_BUSY;
983		(void) splzs();
984		cs->cs_preg[1] |= ZSWR1_TIE;
985		cs->cs_creg[1] |= ZSWR1_TIE;
986		ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]);
987		cs->cs_zc->zc_data = *p;
988		cs->cs_tba = p + 1;
989		cs->cs_tbc = nch - 1;
990	} else {
991		/*
992		 * Nothing to send, turn off transmit done interrupts.
993		 * This is useful if something is doing polled output.
994		 */
995		(void) splzs();
996		cs->cs_preg[1] &= ~ZSWR1_TIE;
997		cs->cs_creg[1] &= ~ZSWR1_TIE;
998		ZS_WRITE(cs->cs_zc, 1, cs->cs_creg[1]);
999	}
1000out:
1001	splx(s);
1002}
1003
1004/*
1005 * Stop output, e.g., for ^S or output flush.
1006 */
1007void
1008zsstop(tp, flag)
1009register struct tty	*tp;
1010	 int		flag;
1011{
1012	register struct zs_chanstate	*cs;
1013	register int			s, unit = ZS_UNIT(tp->t_dev);
1014		 struct zs_softc	*zi = zs_cd.cd_devs[unit >> 1];
1015
1016	cs = &zi->zi_cs[unit & 1];
1017	s  = splzs();
1018	if(tp->t_state & TS_BUSY) {
1019		/*
1020		 * Device is transmitting; must stop it.
1021		 */
1022		cs->cs_tbc = 0;
1023		if ((tp->t_state & TS_TTSTOP) == 0)
1024			tp->t_state |= TS_FLUSH;
1025	}
1026	splx(s);
1027}
1028
1029static void
1030zs_shutdown(cs)
1031	struct zs_chanstate	*cs;
1032{
1033	struct tty	*tp = cs->cs_ttyp;
1034	int		s;
1035
1036	s = splzs();
1037
1038	/*
1039	 * Hang up if necessary.  Wait a bit, so the other side has time to
1040	 * notice even if we immediately open the port again.
1041	 */
1042	if(tp->t_cflag & HUPCL) {
1043		zs_modem(cs, 0, DMSET);
1044		(void)tsleep((caddr_t)cs, TTIPRI, ttclos, hz);
1045	}
1046
1047	/* Clear any break condition set with TIOCSBRK. */
1048	if(cs->cs_creg[5] & ZSWR5_BREAK) {
1049		cs->cs_preg[5] &= ~ZSWR5_BREAK;
1050		cs->cs_creg[5] &= ~ZSWR5_BREAK;
1051		ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
1052	}
1053
1054	/*
1055	 * Drop all lines and cancel interrupts
1056	 */
1057	zs_loadchannelregs(cs->cs_zc, zs_init_regs);
1058	splx(s);
1059}
1060
1061/*
1062 * Set ZS tty parameters from termios.
1063 *
1064 * This routine makes use of the fact that only registers
1065 * 1, 3, 4, 5, 9, 10, 11, 12, 13, 14, and 15 are written.
1066 */
1067static int
1068zsparam(tp, t)
1069register struct tty	*tp;
1070register struct termios	*t;
1071{
1072		 int			unit = ZS_UNIT(tp->t_dev);
1073		 struct zs_softc	*zi = zs_cd.cd_devs[unit >> 1];
1074	register struct zs_chanstate	*cs = &zi->zi_cs[unit & 1];
1075		 int			cdiv, clkm, brgm, tcon;
1076	register int			tmp, tmp5, cflag, s;
1077
1078	tmp  = t->c_ospeed;
1079	tmp5 = t->c_ispeed;
1080	if(tmp < 0 || (tmp5 && tmp5 != tmp))
1081		return(EINVAL);
1082	if(tmp == 0) {
1083		/* stty 0 => drop DTR and RTS */
1084		zs_modem(cs, 0, DMSET);
1085		return(0);
1086	}
1087	tmp = zsbaudrate(unit, tmp, &cdiv, &clkm, &brgm, &tcon);
1088	if (tmp < 0)
1089		return(EINVAL);
1090	tp->t_ispeed = tp->t_ospeed = tmp;
1091
1092	cflag = tp->t_cflag = t->c_cflag;
1093	if (cflag & CSTOPB)
1094		cdiv |= ZSWR4_TWOSB;
1095	else
1096		cdiv |= ZSWR4_ONESB;
1097	if (!(cflag & PARODD))
1098		cdiv |= ZSWR4_EVENP;
1099	if (cflag & PARENB)
1100		cdiv |= ZSWR4_PARENB;
1101
1102	switch(cflag & CSIZE) {
1103	case CS5:
1104		tmp  = ZSWR3_RX_5;
1105		tmp5 = ZSWR5_TX_5;
1106		break;
1107	case CS6:
1108		tmp  = ZSWR3_RX_6;
1109		tmp5 = ZSWR5_TX_6;
1110		break;
1111	case CS7:
1112		tmp  = ZSWR3_RX_7;
1113		tmp5 = ZSWR5_TX_7;
1114		break;
1115	case CS8:
1116	default:
1117		tmp  = ZSWR3_RX_8;
1118		tmp5 = ZSWR5_TX_8;
1119		break;
1120	}
1121	tmp  |= ZSWR3_RX_ENABLE;
1122	tmp5 |= ZSWR5_TX_ENABLE | ZSWR5_DTR | ZSWR5_RTS;
1123
1124	/*
1125	 * Block interrupts so that state will not
1126	 * be altered until we are done setting it up.
1127	 */
1128	s = splzs();
1129	cs->cs_preg[4]  = cdiv;
1130	cs->cs_preg[11] = clkm;
1131	cs->cs_preg[12] = tcon;
1132	cs->cs_preg[13] = tcon >> 8;
1133	cs->cs_preg[14] = brgm;
1134	cs->cs_preg[1]  = ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE;
1135	cs->cs_preg[9]  = ZSWR9_MASTER_IE | ZSWR9_VECTOR_INCL_STAT;
1136	cs->cs_preg[10] = ZSWR10_NRZ;
1137	cs->cs_preg[15] = ZSWR15_BREAK_IE | ZSWR15_DCD_IE;
1138
1139	/*
1140	 * Output hardware flow control on the chip is horrendous: if
1141	 * carrier detect drops, the receiver is disabled.  Hence we
1142	 * can only do this when the carrier is on.
1143	 */
1144	if(cflag & CCTS_OFLOW && cs->cs_zc->zc_csr & ZSRR0_DCD)
1145		tmp |= ZSWR3_HFC;
1146	cs->cs_preg[3] = tmp;
1147	cs->cs_preg[5] = tmp5;
1148
1149	/*
1150	 * If nothing is being transmitted, set up new current values,
1151	 * else mark them as pending.
1152	 */
1153	if(cs->cs_heldchange == 0) {
1154		if (cs->cs_ttyp->t_state & TS_BUSY) {
1155			cs->cs_heldtbc = cs->cs_tbc;
1156			cs->cs_tbc = 0;
1157			cs->cs_heldchange = 1;
1158		} else {
1159			bcopy((caddr_t)cs->cs_preg, (caddr_t)cs->cs_creg, 16);
1160			zs_loadchannelregs(cs->cs_zc, cs->cs_creg);
1161		}
1162	}
1163	splx(s);
1164	return (0);
1165}
1166
1167/*
1168 * search for the best matching baudrate
1169 */
1170static int
1171zsbaudrate(unit, wanted, divisor, clockmode, brgenmode, timeconst)
1172int	unit, wanted, *divisor, *clockmode, *brgenmode, *timeconst;
1173{
1174	int	bestdiff, bestbps, source;
1175
1176	bestdiff = bestbps = 0;
1177	unit = (unit & 1) << 2;
1178	for (source = 0; source < 4; ++source) {
1179		long	freq = zs_frequencies[unit + source];
1180		int	diff, bps, div, clkm, brgm, tcon;
1181
1182		bps = div = clkm = brgm = tcon = 0;
1183		switch (source) {
1184			case 0:	/* BRgen, PCLK */
1185				brgm = ZSWR14_BAUD_ENA|ZSWR14_BAUD_FROM_PCLK;
1186				break;
1187			case 1:	/* BRgen, RTxC */
1188				brgm = ZSWR14_BAUD_ENA;
1189				break;
1190			case 2: /* RTxC */
1191				clkm = ZSWR11_RXCLK_RTXC|ZSWR11_TXCLK_RTXC;
1192				break;
1193			case 3: /* TRxC */
1194				clkm = ZSWR11_RXCLK_TRXC|ZSWR11_TXCLK_TRXC;
1195				break;
1196		}
1197		switch (source) {
1198			case 0:
1199			case 1:
1200				div  = ZSWR4_CLK_X16;
1201				clkm = ZSWR11_RXCLK_BAUD|ZSWR11_TXCLK_BAUD;
1202				tcon = BPS_TO_TCONST(freq, wanted);
1203				if (tcon < 0)
1204					tcon = 0;
1205				bps  = TCONST_TO_BPS(freq, tcon);
1206				break;
1207			case 2:
1208			case 3:
1209			{	int	b1 = freq / 16, d1 = abs(b1 - wanted);
1210				int	b2 = freq / 32, d2 = abs(b2 - wanted);
1211				int	b3 = freq / 64, d3 = abs(b3 - wanted);
1212
1213				if (d1 < d2 && d1 < d3) {
1214					div = ZSWR4_CLK_X16;
1215					bps = b1;
1216				} else if (d2 < d3 && d2 < d1) {
1217					div = ZSWR4_CLK_X32;
1218					bps = b2;
1219				} else {
1220					div = ZSWR4_CLK_X64;
1221					bps = b3;
1222				}
1223				brgm = tcon = 0;
1224				break;
1225			}
1226		}
1227		diff = abs(bps - wanted);
1228		if (!source || diff < bestdiff) {
1229			*divisor   = div;
1230			*clockmode = clkm;
1231			*brgenmode = brgm;
1232			*timeconst = tcon;
1233			bestbps    = bps;
1234			bestdiff   = diff;
1235			if (diff == 0)
1236				break;
1237		}
1238	}
1239	/* Allow deviations upto 5% */
1240	if (20 * bestdiff > wanted)
1241		return -1;
1242	return bestbps;
1243}
1244
1245/*
1246 * Raise or lower modem control (DTR/RTS) signals.  If a character is
1247 * in transmission, the change is deferred.
1248 */
1249static int
1250zs_modem(cs, bits, how)
1251struct zs_chanstate	*cs;
1252int			bits, how;
1253{
1254	int s, mbits;
1255
1256	bits  &= ZSWR5_DTR | ZSWR5_RTS;
1257
1258	s = splzs();
1259	mbits  = cs->cs_preg[5] &  (ZSWR5_DTR | ZSWR5_RTS);
1260
1261	switch(how) {
1262		case DMSET:
1263				mbits  = bits;
1264				break;
1265		case DMBIS:
1266				mbits |= bits;
1267				break;
1268		case DMBIC:
1269				mbits &= ~bits;
1270				break;
1271		case DMGET:
1272				splx(s);
1273				return(mbits);
1274	}
1275
1276	cs->cs_preg[5] = (cs->cs_preg[5] & ~(ZSWR5_DTR | ZSWR5_RTS)) | mbits;
1277	if(cs->cs_heldchange == 0) {
1278		if(cs->cs_ttyp->t_state & TS_BUSY) {
1279			cs->cs_heldtbc = cs->cs_tbc;
1280			cs->cs_tbc = 0;
1281			cs->cs_heldchange = 1;
1282		}
1283		else {
1284			ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
1285		}
1286	}
1287	splx(s);
1288	return(0);
1289}
1290
1291/*
1292 * Write the given register set to the given zs channel in the proper order.
1293 * The channel must not be transmitting at the time.  The receiver will
1294 * be disabled for the time it takes to write all the registers.
1295 */
1296static void
1297zs_loadchannelregs(zc, reg)
1298volatile struct zschan	*zc;
1299u_char			*reg;
1300{
1301	int i;
1302
1303	zc->zc_csr = ZSM_RESET_ERR;	/* reset error condition */
1304	i = zc->zc_data;		/* drain fifo */
1305	i = zc->zc_data;
1306	i = zc->zc_data;
1307	ZS_WRITE(zc,  4, reg[4]);
1308	ZS_WRITE(zc, 10, reg[10]);
1309	ZS_WRITE(zc,  3, reg[3] & ~ZSWR3_RX_ENABLE);
1310	ZS_WRITE(zc,  5, reg[5] & ~ZSWR5_TX_ENABLE);
1311	ZS_WRITE(zc,  1, reg[1]);
1312	ZS_WRITE(zc,  9, reg[9]);
1313	ZS_WRITE(zc, 11, reg[11]);
1314	ZS_WRITE(zc, 12, reg[12]);
1315	ZS_WRITE(zc, 13, reg[13]);
1316	ZS_WRITE(zc, 14, reg[14]);
1317	ZS_WRITE(zc, 15, reg[15]);
1318	ZS_WRITE(zc,  3, reg[3]);
1319	ZS_WRITE(zc,  5, reg[5]);
1320}
1321#endif /* NZS > 1 */
1322