M gnot/devcons.c => gnot/devcons.c +20 -0
@@ 348,6 348,7 @@ enum{
Qppid,
Qrcons,
Qrs232,
+ Qrs232ctl,
Qtime,
Quser,
Qklog,
@@ 362,6 363,7 @@ Dirtab consdir[]={
"ppid", Qppid, 12, 0600,
"rcons", Qrcons, 0, 0600,
"rs232", Qrs232, 0, 0600,
+ "rs232ctl", Qrs232ctl, 0, 0600,
"time", Qtime, 12, 0600,
"user", Quser, 0, 0600,
"klog", Qklog, 0, 0400,
@@ 574,6 576,9 @@ consread(Chan *c, void *buf, long n)
qunlock(&rs232iq);
return i;
+ case Qrs232ctl:
+ return 0;
+
case Qcputime:
k = c->offset;
if(k >= sizeof tmp)
@@ 676,6 681,21 @@ conswrite(Chan *c, void *va, long n)
qunlock(&rs232oq);
break;
+ case Qrs232ctl:
+ qlock(&rs232oq);
+ if(waserror()){
+ qunlock(&rs232oq);
+ nexterror();
+ }
+ if(n>2 && n<sizeof buf && *a=='B'){
+ strncpy(buf, a, n);
+ buf[n] = 0;
+ duartbaud(strtoul(buf+1, 0, 0));
+ }else
+ error(0, Ebadarg);
+ qunlock(&rs232oq);
+ break;
+
case Qtime:
if(n<=0 || boottime!=0) /* only one write please */
return 0;
M gnot/fns.h => gnot/fns.h +1 -0
@@ 31,6 31,7 @@ int devno(int, int);
Chan* devopen(Chan*, int, Dirtab*, int, Devgen*);
void devstat(Chan*, char*, Dirtab*, int, Devgen*);
int devwalk(Chan*, char*, Dirtab*, int, Devgen*);
+void duartbaud(int);
void duartstartrs232o(void);
void duartstarttimer(void);
void duartstoptimer(void);
M gnot/screen.c => gnot/screen.c +50 -4
@@ 5,6 5,7 @@
#include "fns.h"
#include "io.h"
#include "ureg.h"
+#include "errno.h"
#include "gnot.h"
@@ 20,6 21,7 @@ struct{
}out;
void duartinit(void);
+int duartacr;
Bitmap screen =
{
@@ 132,9 134,13 @@ enum{
PAR_ERR =0x20,
FRM_ERR =0x40,
RCVD_BRK =0x80,
- BD9600 =0xBB,
- BD4800 =0x99,
- BD2400 =0x88,
+ BD38400 =0xCC|0x0000,
+ BD19200 =0xCC|0x0100,
+ BD9600 =0xBB|0x0000,
+ BD4800 =0x99|0x0000,
+ BD2400 =0x88|0x0000,
+ BD1200 =0x66|0x0000,
+ BD300 =0x44|0x0000,
IM_IPC =0x80, /* IMRx/ISRx - Interrupt Mask/Interrupt Status */
IM_DBB =0x40,
IM_RRDYB =0x20,
@@ 196,7 202,7 @@ duartinit(void)
/*
* Output port
*/
- duart[0].ipc_acr = 0xB7; /* allow change of state interrupt */
+ duart[0].ipc_acr = duartacr = 0xB7; /* allow change of state interrupt */
duart[1].ip_opcr = 0x00;
duart[1].scc_ropbc = 0xFF; /* make sure the port is reset first */
duart[1].scc_sopbc = 0x04; /* dtr = 1, pp = 01 */
@@ 212,6 218,46 @@ duartinit(void)
duart[0].data = 0x02;
}
+void
+duartbaud(int b)
+{
+ int x;
+ Duart *duart;
+
+ duart = DUARTREG;
+
+ switch(b){
+ case 38400:
+ x = BD38400;
+ break;
+ case 19200:
+ x = BD19200;
+ break;
+ case 9600:
+ x = BD9600;
+ break;
+ case 4800:
+ x = BD4800;
+ break;
+ case 2400:
+ x = BD2400;
+ break;
+ case 1200:
+ x = BD1200;
+ break;
+ case 300:
+ x = BD300;
+ break;
+ default:
+ error(0, Ebadarg);
+ }
+ if(x & 0x0100)
+ duart[0].ipc_acr = duartacr |= 0x80;
+ else
+ duart[0].ipc_acr = duartacr &= ~0x80;
+ duart[1].sr_csr = x;
+}
+
enum{
Kptime=200 /* about once per ms */
};