[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