[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Rsconf problems under MiNT 1.10h6



In <memo.716071@cix.compulink.co.uk> you write:
>Thanks to everybody who pointed me in the right direction for h6 patches.
>I have now successfully built a h6 MTOS kernel.
>
>All seems to work fine except Rsconf().
>
>I first noticed this when MODEM.CPX displayed rubbish instead of the baud
>rate. ...

hmm.  does this fix it?  (needs my later patches at least for the other parts)

1. init_xbios gets called pretty late (after biosfs_init), move some
initialisation code...

Index: biosfs.c
@@ -261,7 +261,7 @@
 {
 	struct bios_file *b, *c;
 	int majdev, mindev;
-	int i;
+	int i, oldmap = 1;
 
 	broot = BDEV;
 
@@ -301,9 +301,10 @@
 		--b;
 		b->next = 0;
 	}
+	if (has_bconmap)
+		oldmap = Bconmap(-1);
 	/* Initialize bios_tty structures */
 	for (i=0;c && i<MAX_BTTY;c=c->next, i++) {
-		unsigned r;
 		if (has_bconmap)
 			Bconmap(c->private);
 		bttys[i].irec = Iorec(0);
@@ -312,10 +313,9 @@
 		bttys[i].wsel = &(c->tty->wsel);
 		bttys[i].baudmap = baudmap;
 		bttys[i].maxbaud = MAXBAUD;
-		r = (int)rsconf(-2, -1, -1, -1, -1, -1);
-		Rsconf(r, -1, -1, -1, -1, -1);
-		bttys[i].ospeed = bttys[i].ispeed = r<MAXBAUD ? baudmap[r] : -1;
 	}
+	if (has_bconmap)
+		Bconmap(oldmap);
 	btty_max = i;
 
 	defaultaux = new_fileptr();
Index: proc.c
@@ -270,7 +270,8 @@
 	curproc->starttime = Tgettime();
 	curproc->startdate = Tgetdate();
 	if (has_bconmap)
-		curproc->bconmap = curbconmap;
+/* init_xbios not happened yet */
+		curproc->bconmap = (int) Bconmap(-1);
 	else
 		curproc->bconmap = 1;
 
Index: xbios.c
@@ -10,6 +10,11 @@
 
 #include "mint.h"
 
+/* tty structures for the BIOS devices -- see biosfs.c */
+extern struct tty ttmfp_tty;
+extern struct bios_tty bttys[];
+extern short btty_max;
+
 extern int tosvers;	/* from main.c */
 
 #define XBIOS_MAX 0x80
@@ -160,8 +165,6 @@
 uiorec(dev)
 	int dev;
 {
-	extern short btty_max;
-
 	TRACE(("Iorec(%d)", dev));
 	if (dev == 0 && has_bconmap) {
 /* get around another BIOS Bug:  in (at least) TOS 2.05 Iorec(0) is broken */
@@ -179,9 +182,6 @@
 	long rsval;
 	static int oldbaud = -1;
 	int b, ret_oldbaud = 0;
-	extern struct tty ttmfp_tty;
-	extern struct bios_tty bttys[];
-	extern short btty_max;
 
 	TRACE(("Rsconf(%d,%d,%d,%d,%d,%d)", baud, flow,
 		uc, rs, ts, sc));
@@ -330,6 +330,8 @@
 void
 init_xbios()
 {
+	int i, oldmap;
+
 	curbconmap = (has_bconmap) ? (int) Bconmap(-1) : 1;
 
 	xbios_tab[0x0c] = midiws;
@@ -339,4 +341,17 @@
 	xbios_tab[0x20] = dosound;
 	xbios_tab[0x26] = supexec;
 	xbios_tab[0x2c] = bconmap;
+
+	oldmap = curproc->bconmap = curbconmap;
+	for (i=0; i<btty_max; i++) {
+		int r;
+		if (has_bconmap)
+			curproc->bconmap = i+6;
+		r = (int)rsconf(-2, -1, -1, -1, -1, -1);
+		if (r < 0)
+			Rsconf((r=0), -1, -1, -1, -1, -1);
+		rsconf(r, -1, -1, -1, -1, -1);
+	}
+	if (has_bconmap)
+		mapin (curproc->bconmap = oldmap);
 }

2. default no XDEF _bcopy, for gcc 2.3.3 you can -DXDEF_BCOPY
(and save 1 more word)

Index: quickmov.spp
@@ -14,6 +14,8 @@
 	XDEF	_quickmove
 	XDEF	_quickmovb
 
+;*sigh* gcc 2.5.8 wants the libs one...
+%ifdef XDEF_BCOPY
 ;%ifdef OWN_LIB
 	XDEF	_bcopy
 	XDEF	__bcopy
@@ -24,6 +26,7 @@
 	move.l	4(sp),a1		; get src
 	bra.s	_quickmovb1
 ;%endif
+%endif
 
 _quickmovb:
 	move.l	4(sp),a0		; get dst
@@ -51,8 +54,7 @@
 	and.w	d0,d1			; d1 = nbytes % 512
 	lsr.l	#8,d0			; 
 	lsr.l	#1,d0			; d0 = nbytes / 512
-	subq.l	#1,d0			; prepare for dbra loop
-	bmi.s	Leftover		; if < 0, skip
+	ble.s	Leftover		; if <= 0, skip
 	movem.l	d1-d7/a2-a6,-(sp)	; save regs
 L1:
 	movem.l	(a1)+,d1-d7/a2-a6	; read 12*4 = 48 bytes
@@ -80,7 +82,7 @@
 
 	lea	512(a0),a0
 	subq.l	#1,d0
-	bge.s	L1
+	bgt.s	L1
 
 	movem.l	(sp)+,d1-d7/a2-a6	; pop registers
 
3. TOS 1.(0)2 had xcon* already...  (or was it too buggy? :)

Index: bios.c
@@ -74,22 +74,22 @@
 
 /* and then do BCOSTAT ourselves, the BIOS SCC ones are often broken */
 #define BCOSTAT(dev) \
-	(((unsigned)dev <= 4) ? ((tosvers > 0x0102) ? \
+	(((unsigned)dev <= 4) ? ((tosvers >= 0x0102) ? \
 	   (int)callout1(xcostat[dev], dev) : Bcostat(dev)) : \
 	   ((has_bconmap && (unsigned)dev-SERDEV < btty_max) ? \
 		bcxstat(MAPTAB[dev-SERDEV].iorec+1) : Bcostat(dev)))
 #define BCONOUT(dev, c) \
-	(((unsigned)dev <= 4) ? ((tosvers > 0x0102) ? \
+	(((unsigned)dev <= 4) ? ((tosvers >= 0x0102) ? \
 	   callout2(xconout[dev], dev, c) : Bconout(dev, c)) : \
 	   ((has_bconmap && (unsigned)dev-SERDEV < btty_max) ? \
 		callout2(MAPTAB[dev-SERDEV].bconout, dev, c) : Bconout(dev, c)))
 #define BCONSTAT(dev) \
-	(((unsigned)dev <= 4) ? ((tosvers > 0x0102) ? \
+	(((unsigned)dev <= 4) ? ((tosvers >= 0x0102) ? \
 	   (int)callout1(xconstat[dev], dev) : Bconstat(dev)) : \
 	   ((has_bconmap && (unsigned)dev-SERDEV < btty_max) ? \
 		(int)callout1(MAPTAB[dev-SERDEV].bconstat, dev) : Bconstat(dev)))
 #define BCONIN(dev) \
-	(((unsigned)dev <= 4) ? ((tosvers > 0x0102) ? \
+	(((unsigned)dev <= 4) ? ((tosvers >= 0x0102) ? \
 	   callout1(xconin[dev], dev) : Bconin(dev)) : \
 	   ((has_bconmap && (unsigned)dev-SERDEV < btty_max) ? \
 		callout1(MAPTAB[dev-SERDEV].bconin, dev) : Bconin(dev)))
Index: biosfs.c
@@ -1357,7 +1357,7 @@
 			cout = &MAPTAB[bdev-6].bconout;
 			ospeed = &bttys[bdev-6].ospeed;
 		}
-	} else if (bdev == 1 && tosvers > 0x0102) {
+	} else if (bdev == 1 && tosvers >= 0x0102) {
 		ior = bttys[0].orec;
 		cout = &xconout[1];
 		ospeed = &bttys[0].ospeed;
@@ -1534,7 +1537,7 @@
 	unsigned short head, bsize, wrap;
 	long left;
 
-	if (bdev == 3 && tosvers > 0x0102) {
+	if (bdev == 3 && tosvers >= 0x0102) {
 		/* midi */
 		ior = (IOREC_T *) uiorec(2);
 		cin = &xconin[3];
@@ -1545,7 +1548,7 @@
 			cin = &MAPTAB[bdev-6].bconin;
 			cinstat = &MAPTAB[bdev-6].bconstat;
 		}
-	} else if (bdev == 1 && tosvers > 0x0102) {
+	} else if (bdev == 1 && tosvers >= 0x0102) {
 		ior = bttys[0].irec;
 		cin = &xconin[1];
 		cinstat = &xconstat[1];

4. fix ^S on ptys, allow sleeping for TS_HOLD (only on devices that have
writeb for compatibility with older ones so it currently only works on
ptys), and some more things like pty master read end looks at TS_HOLD too
to reduce delay.  devices that have writeb are now notified when TS_HOLD
changes (ioctl TIOCSTART/STOP) but they still don't need to wake writers
themselves unless they change TS_HOLD themselves.

Index: pipefs.c
@@ -471,6 +471,7 @@
 			return ENSMEM;
 		}
 		tty->use_cnt = 0;
+		tty->rsel = tty->wsel = 0;
 		    /* do_open does the rest of tty initialization */
 	} else tty = 0;
 
@@ -615,6 +616,13 @@
 
 	if (nbytes > 0 && nbytes <= PIPE_BUF) {
 check_atomicity:
+		if (is_terminal(f) && !(f->flags & O_HEAD) &&
+		    (this->tty->state & TS_HOLD)) {
+			if (f->flags & O_NDELAY)
+				return 0;
+			sleep (IO_Q, (long)&this->tty->state);
+			goto check_atomicity;
+		}
 		r = p->tail - p->head;
 		if (r < 0) r += PIPESIZ+4;
 		r = PIPESIZ - r; /* r is the number of bytes we can write */
@@ -647,6 +655,13 @@
 #if 1
 			int free, wrap;
 
+			if (is_terminal(f) && !(f->flags & O_HEAD) &&
+			    (this->tty->state & TS_HOLD)) {
+				if (f->flags & O_NDELAY)
+					break;
+				sleep (IO_Q, (long)&this->tty->state);
+				continue;
+			}
 			pbuf = p->buf + ptail;
 			if ((free = phead - j) < 0)
 				free += PIPESIZ+4;
@@ -673,8 +688,8 @@
 			} else {
 				if (wrap <= free) {
 					memcpy (pbuf, buf, wrap);
-					memcpy (p->buf, buf + wrap, free - wrap);
 					ptail = free - wrap;
+					memcpy (p->buf, buf + wrap, ptail);
 				} else {
 					memcpy (pbuf, buf, free);
 					ptail += free;
@@ -760,6 +775,13 @@
 				left += PIPESIZ+4;
 			if (left > nbytes)
 				left = nbytes;
+/* if pty master and TS_HOLD set stop reading (makes ^S work faster) */
+			if (is_terminal(f) && (f->flags & O_HEAD) &&
+			    (this->tty->state & TS_HOLD)) {
+				if (bytes_read || (f->flags & O_NDELAY))
+					break;
+				left = 1;
+			}
 			nbytes -= left;
 			bytes_read += left;
 
@@ -774,8 +796,8 @@
 			} else {
 				if (wrap <= left) {
 					memcpy (buf, pbuf, wrap);
-					memcpy (buf + wrap, p->buf, left - wrap);
 					phead = left - wrap;
+					memcpy (buf + wrap, p->buf, phead);
 				} else {
 					memcpy (buf, pbuf, left);
 					phead += left;
@@ -909,8 +931,12 @@
 			} else {
 				r = p->tail - p->head;
 				if (r < 0) r += PIPESIZ+4;
-				if (is_terminal(f) && !(f->flags & O_HEAD))
-					r = r >> 2;	/* r /= 4 */
+				if (is_terminal(f)) {
+					if (!(f->flags & O_HEAD))
+						r = r >> 2;	/* r /= 4 */
+					else if (this->tty->state & TS_HOLD)
+						r = 0;
+				}
 				if (!r && p->writers <= 0) {
 					DEBUG(("pipe FIONREAD: no writers"));
 					r = -1;
@@ -927,8 +953,12 @@
 				r = p->tail - p->head;
 				if (r < 0) r += PIPESIZ+4;
 				r = PIPESIZ - r;
-				if (is_terminal(f) && (f->flags & O_HEAD))
-					r = r >> 2;	/* r /= 4 */
+				if (is_terminal(f)) {
+					if (f->flags & O_HEAD)
+						r = r >> 2;	/* r /= 4 */
+					else if (this->tty->state & TS_HOLD)
+						r = 0;
+				}
 			}
 			*((long *) buf) = r;
 			break;
@@ -975,6 +1005,11 @@
 		else
 			lck->l_type = F_UNLCK;
 		break;
+	case TIOCSTART:
+		if (is_terminal(f) && !(f->flags & O_HEAD) &&
+		    (p = this->outp) && p->rsel && p->tail != p->head)
+			wakeselect (p->rsel);
+		break;
 	case TIOCFLUSH:
 	    {
 		long flushtype;
@@ -1203,13 +1238,18 @@
 		}
 
 /* NOTE: if p->writers <= 0 then reads won't block (they'll fail) */
-		if (p->tail != p->head || p->writers <= 0) {
+		if ((p->tail != p->head &&
+			(!is_terminal(f) || !(f->flags & O_HEAD) ||
+			 !(this->tty->state & TS_HOLD))) ||
+		    p->writers <= 0) {
 			return 1;
 		}
 
 		if (p->rsel)
 			return 2;	/* collision */
 		p->rsel = proc;
+		if (is_terminal(f) && !(f->flags & O_HEAD))
+			this->tty->rsel = proc;
 		return 0;
 	} else if (mode == O_WRONLY) {
 		p = (f->flags & O_HEAD) ? this->inp : this->outp;
@@ -1219,11 +1259,16 @@
 		}
 		j = p->tail+4;
 		if (j >= PIPESIZ+4) j -= PIPESIZ+4;
-		if (j != p->head || p->readers <= 0)
+		if ((j != p->head &&
+			(!is_terminal(f) || (f->flags & O_HEAD) ||
+			 !(this->tty->state & TS_HOLD))) ||
+		    p->readers <= 0)
 			return 1;	/* data may be written */
 		if (p->wsel)
 			return 2;	/* collision */
 		p->wsel = proc;
+		if (is_terminal(f) && !(f->flags & O_HEAD))
+			this->tty->wsel = proc;
 		return 0;
 	}
 	return 0;
Index: tty.c
@@ -16,6 +16,11 @@
 /* setting a special character to this value disables it */
 #define UNDEF 0
 
+#define HAS_WRITEB(f)	(((f)->fc.fs != &bios_filesys || \
+			 (((struct bios_file *)(f)->fc.index)->drvsize > \
+				offsetof (DEVDRV, writeb))) && \
+			 *(f)->dev->writeb)
+extern FILESYS bios_filesys;
 
 /* default terminal characteristics */
 
@@ -87,7 +92,6 @@
 	unsigned char ch, *ptr;
 	int rdmode, mode;
 	struct tty *tty;
-	extern FILESYS bios_filesys;
 
 	tty = (struct tty *)f->devinfo;
 	assert(tty != 0);
@@ -117,8 +121,8 @@
 		 ((struct bios_file *)f->fc.index)->drvsize >
 			offsetof (DEVDRV, readb))) &&
 	    *f->dev->readb &&
-	    ((f->flags & O_HEAD) ||
-		!tty->pgrp || tty->pgrp == curproc->pgrp ||
+	    ((f->flags & O_HEAD) || ((tty->state &= ~TS_COOKED), !tty->pgrp) ||
+		tty->pgrp == curproc->pgrp ||
 		f->fc.dev != curproc->control->fc.dev ||
 		f->fc.index != curproc->control->fc.index) &&
 	    (bytes_read = (*f->dev->readb)(f, buf, nbytes)) != EUNDEV)
@@ -299,7 +303,6 @@
 	static long cr_char = '\r';
 #define LBUFSIZ 128
 	long lbuf[LBUFSIZ];
-	extern FILESYS bios_filesys;
 
 	tty = (struct tty *)f->devinfo;
 	assert(tty != 0);
@@ -330,12 +333,13 @@
 
 #if 1
 	/* see if we can do fast RAW byte IO thru the device driver... */
-	if (!use_putchar &&
-	    (f->fc.fs != &bios_filesys ||
-		(((struct bios_file *)f->fc.index)->drvsize >
-			offsetof (DEVDRV, writeb))) && *f->dev->writeb) {
+	if (!use_putchar && HAS_WRITEB(f)) {
 
 		tty_checkttou (f, tty);
+		if (rwmode & COOKED)
+			tty->state |= TS_COOKED;
+		else
+			tty->state &= ~TS_COOKED;
 		if (mode) {	/* i.e. T_CRMODE */
 			if ((*f->dev->writeb)(f, buf, 0L) != EUNDEV) {
 	/* write in big chunks if possible; lines if CRMODE
@@ -637,9 +641,26 @@
 		tty->pgrp = (*((long *)arg) & 0x00007fffL);
 		return 0;
 	case TIOCSTART:
+/* if the device has writeb writers may sleep for TS_HOLD (instead of polling),
+ * tell the device and wake them up
+ */
+		if (HAS_WRITEB(f)) {
+			(void)(*f->dev->ioctl)(f, TIOCSTART, &tty->state);
+			tty->state &= ~TS_HOLD;
+			wake (IO_Q, (long)&tty->state);
+			if (tty->wsel) {
+				long r = 0;
+
+				(void)(*f->dev->ioctl)(f, FIONWRITE, &r);
+				if (r)
+					wakeselect (tty->wsel);
+			}
+		}
 		tty->state &= ~TS_HOLD;
 		return 0;
 	case TIOCSTOP:
+		if (HAS_WRITEB(f))
+			(void)(*f->dev->ioctl)(f, TIOCSTOP, &tty->state);
 		tty->state |= TS_HOLD;
 		return 0;
 	case TIOCGXKEY:
@@ -824,9 +845,9 @@
 			else if (c == tty->tc.t_quitc)
 				killgroup(curproc->pgrp, SIGQUIT);
 			else if (c == tty->tc.t_stopc)
-				tty->state |= TS_HOLD;
+				tty_ioctl (f, TIOCSTOP, 0);
 			else if (c == tty->tc.t_startc)
-				tty->state &= ~TS_HOLD;
+				tty_ioctl (f, TIOCSTART, 0);
 			else
 				c = UNDEF;
 		}
@@ -863,28 +884,36 @@
 		ch = data & 0xff;
 
 		if ( (tty->state & TS_COOKED) && ch != UNDEF) {
+			long r = 1;
+
 /* see if we're putting control characters into the buffer */
 			if (ch == tty->tc.t_intrc) {
-				tty->state &= ~TS_HOLD;
 				killgroup(tty->pgrp, SIGINT);
+				if (!(tty->sg.sg_flags & T_NOFLSH))
+					(void)(*f->dev->ioctl)(f, TIOCFLUSH, &r);
+				tty_ioctl (f, TIOCSTART, 0);
 				return 4L;
 			}
 			else if (ch == tty->tc.t_quitc) {
-				tty->state &= ~TS_HOLD;
 				killgroup(tty->pgrp, SIGQUIT);
+				if (!(tty->sg.sg_flags & T_NOFLSH))
+					(void)(*f->dev->ioctl)(f, TIOCFLUSH, &r);
+				tty_ioctl (f, TIOCSTART, 0);
 				return 4L;
 			}
 			else if (ch == tty->ltc.t_suspc) {
-				tty->state &= ~TS_HOLD;
 				killgroup(tty->pgrp, SIGTSTP);
+				if (!(tty->sg.sg_flags & T_NOFLSH))
+					(void)(*f->dev->ioctl)(f, TIOCFLUSH, &r);
+				tty_ioctl (f, TIOCSTART, 0);
 				return 4L;
 			}
 			else if (ch == tty->tc.t_stopc) {
-				tty->state |= TS_HOLD;
+				tty_ioctl (f, TIOCSTOP, 0);
 				return 4L;
 			}
 			else if (ch == tty->tc.t_startc) {
-				tty->state &= ~TS_HOLD;
+				tty_ioctl (f, TIOCSTART, 0);
 				return 4L;
 			}
 			else if (tty->state & TS_HOLD) {
@@ -947,7 +976,13 @@
 				} else if (c == tty->tc.t_startc)
 					tty->state &= ~TS_HOLD;
 			}
+			else
 #endif
+			if (HAS_WRITEB(f)) {
+/* if the device has writeb assume it wakes us when TS_HOLD resets */
+				sleep (IO_Q, (long)&tty->state);
+				continue;
+			}
 			nap(60);	/* sleep for 60 milliseconds */
 		}
 	}
Index: biosfs.c
@@ -1519,7 +1519,10 @@
 {
 	int bdev = f->fc.aux;
 	struct bios_file *b = (struct bios_file *)f->fc.index;
+	struct tty *tty = (struct tty *)f->devinfo;
 
+	if (!(tty->sg.sg_flags & T_RAW) || (tty->sg.sg_flags & T_ECHO))
+		return EUNDEV;
 	return iread (bdev, buf, bytes, (f->flags & O_NDELAY), b);
 }
 
5. that silly ENOMEM-because-process-did-not-Mshrink-yet `feature' again...
will this be finally enough so i don't see it again? :)

Index: proc.c
@@ -322,9 +323,10 @@
 fresh_slices(slices)
 	int slices;
 {
+	reset_priorities();
 	curproc->slices = 0;
 	curproc->curpri = MAX_NICE+1;
-	proc_clock = slices;
+	proc_clock = TIME_SLICE+slices;
 }
 
 /*
@@ -460,7 +462,7 @@
 	if (p->slices >= 0) {
 		proc_clock = TIME_SLICE;	/* get a fresh time slice */
 	} else {
-		proc_clock = -p->slices;	/* slices set by run_next */
+		proc_clock = TIME_SLICE-p->slices; /* slices set by run_next */
 		p->curpri = p->pri;
 	}
 	p->slices = SLICES(p->curpri);

 all the best...
	Juergen