V10/cmd/vsw/dynasty.c
#include <libc.h>
#include <fio.h>
#include <sysent.h>
#include <string.h>
#include <errno.h>
#include "crossbar.h"
extern int verbose;
static ntilt;
#define MAXTILT 5
Dynasty::Dynasty(char *dkname, int n, int depth) : (dkname, n, depth)
{
}
void
Dynasty::startup()
{
char buf[256];
extern int opendk(char *);
fd = opendk(dial);
tocontrol();
}
void
Dynasty::tocontrol()
{
for(;;){
put1(0xAC);
if(get1(0xFB) == 0)
break;
sleep(1);
}
}
void
Dynasty::config()
{
int i, j;
imap = new int[nouts];
ntilt = 0;
for(i = 0; i < nouts; i++){
again:
if(ntilt > MAXTILT){
fprint(2, "vsw: too many (%d) tilts, exiting\n", ntilt);
exit(1);
}
put1(0xDA);
putn(i);
if(get1(0xAB)){
sleep(1);
tocontrol();
goto again;
}
j = getn(8);
put1(0xFB);
imap[i] = j;
}
}
int
Dynasty::connect(int input, Crossbar *c, int output, int nw)
{
char buf[256];
if(fd < 0)
startup();
if(c != this){
if(nextc->connect(nextl, c, output, nw) == 0)
return(0);
output = froml;
}
nw = (nw+nwires-1)/nwires;
while(nw-- > 0){
put1(0xCF);
putn(output);
putn(input);
if(get1(0xFB)){
fprint(2, "%s.con %d->%d failed\n", name(), input, output);
return(0);
}
input++, output++;
}
return(1);
}
void
Dynasty::put1(unsigned char x)
{
if(write(fd, (char *)&x, 1) != 1)
perror("WRITE");
}
void
Dynasty::putn(int i)
{
unsigned char wbuf[2];
wbuf[0] = i/100;
wbuf[1] = i%10 | (((i/10)%10)<<4);
if(write(fd, (char *)wbuf, 2) != 2)
perror("putn");
}
int
Dynasty::get1(unsigned char x)
{
unsigned char r;
char buf[60];
alarm(2);
if(read(fd, (char *)&r, 1) != 1){
if(errno != EINTR)
perror("READ");
else
fprint(2, "vsw: timeout, retrying\n"), tocontrol();
return(1);
}
alarm(0);
if(r != x){
switch(r)
{
case 0xF0:
ntilt++;
break;
case 0xAB:
alarm(2);
read(fd, buf, 8);
alarm(0);
print("continue(#%ux#%ux#%ux#%ux#%ux#%ux#%ux#%ux)\n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]);
break;
case 0xAD:
alarm(2);
read(fd, buf, 10);
alarm(0);
print("autostatus(#%ux#%ux#%ux#%ux#%ux#%ux#%ux#%ux#%ux#%ux)\n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9]);
break;
default:
fprint(2, "READ(#%2.2x): got #%2.2x\n", x, r);
break;
}
return(1);
}
return(0);
}
int
Dynasty::getn(int n)
{
unsigned char r[64];
if(read(fd, (char *)r, n) != n)
perror("getn");
return((r[0]&0xF)*100 + ((r[1]>>4)&0xF)*10 + (r[1]&0xF));
}
#ifdef CRAP
int verbose;
int rfs;
#define WRITE(x) { char wbuf[1]; wbuf[0] = x; if(write(rfs, wbuf, 1) != 1) perror("WRITE"); }
WRITEN(i)
{
unsigned char wbuf[2];
wbuf[0] = i/100;
wbuf[1] = i%10 | (((i/10)%10)<<4);
if(write(rfs, wbuf, 2) != 2)
perror("WRITEN");
}
READ(x)
{
unsigned char rbuf[1];
if(read(rfs, rbuf, 1) != 1)
perror("READ");
if(rbuf[0] != x){
fprint(2, "READ(#%2.2x): got #%2.2x\n", x, rbuf[0]);
return(1);
}
return(0);
}
READN(buf, n)
unsigned char buf[];
{
int i;
for(i = 0; i < n; i++)
if(read(rfs, &buf[i], 1) != 1){
perror("READ");
return(1);
}
return(0);
}
main(argc, argv)
char **argv;
{
int i, n, in, out;
char buf[256];
struct sgttyb vvec;
extern int tty_ld;
if((argc = getflags(argc, argv, "dcrvpPi", 0)) < 0)
usage("[ iopair ... ]");
verbose = flag['v'] != 0;
sprint(buf, "/cs/dk!%s", "vswrgb2");
rfs = ipcopen(buf, "light");
if(rfs < 0){
perror(buf);
exit(1);
}
if(ioctl(rfs, FIOLOOKLD, 0) != tty_ld){
if(ioctl(rfs, FIOPUSHLD, &tty_ld) < 0){
perror("tty_ld");
exit(1);
}
}
vvec.sg_flags = RAW;
vvec.sg_erase = 0;
vvec.sg_kill = 0;
if(ioctl(rfs, TIOCSETP, &vvec) < 0){
perror("ioctl");
exit(1);
}
tocontrol();
print("in control:\n");
status();
exit(0);
}
tocontrol()
{
WRITE(0xAC);
return(READ(0xFB));
}
status()
{
int i, n;
unsigned char buf[8];
for(i = 0; i < 5; i++){
n = status1(i, buf);
print("%d: status1 ret=%d; %x %x %x %x %x %x %x %x\n", i, n, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
}
}
status1(i, buf)
unsigned char *buf;
{
WRITE(0xDA);
WRITEN(i);
if(i = READ(0xAB))
return(i);
if(i = READN(buf, 8))
return(i);
WRITE(0xFB);
sleep(1);
return(0);
}
#endif