WDOS Software

This commit is contained in:
Oliver Lehmann 1990-03-12 06:42:18 +00:00
parent 55769aa2cd
commit df41260ac5
1 changed files with 499 additions and 0 deletions

View File

@ -0,0 +1,499 @@
/**************************************************************************
***************************************************************************
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1988
Programm: wdos.c
Bearbeiter : P. Hoge
Datum : 24.9.89
Version : 1.3
***************************************************************************
Koppelprogramm zu MP600-Erweiterungskarten
***************************************************************************
**************************************************************************/
#include <stdio.h>
#include <termio.h>
#include <signal.h>
#include <time.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
extern errno;
extern char *getenv();
extern char *malloc();
#define BUFLEN 512
#define DISKBUF 40*512
int timeout; /* Signal-Flag */
int parent, child1, child2, child3; /* Prozess-Id's */
int cpu2tty, cpu2lp, cpu2disk, cpu2ram;
int fddisk[6];
struct diskrq {
char rcode;
char drive;
long blkoff;
long addr;
unsigned len;
} diskrq;
char *tty, *ttyname();
char *term;
char *lp;
unsigned termtyp = 0;
char *pname;
struct termio targ; /* definiert in termio.h */
struct termio savterm; /* original tty-Flags */
int lpopenflg;
struct stat stbuf;
char mname[7][50];
char buffer[BUFLEN];
/*
* Terminal Write-Protected setzen
* tty-Parameter sichern und "Raw"-Mode setzen
*/
settty()
{
tty = ttyname(1); /* Terminal-Namen ermitteln */
chmod(tty, 0600);
ioctl(0, TCGETA, &savterm);
ioctl(0, TCGETA, &targ);
targ.c_iflag = IGNBRK|IGNPAR;
if (termtyp != 2)
targ.c_iflag |= IXON;
targ.c_oflag = 0;
targ.c_cflag &= ~PARENB;
targ.c_cflag |= (CS8|CSTOPB|CLOCAL|CREAD);
targ.c_lflag = 0;
targ.c_cc[VMIN] = 1;
targ.c_cc[VTIME] = 0;
ioctl(0, TCSETA, &targ);
if (termtyp == 1) { /* P8000/WDOS-Terminal */
putchar(0x1b);
putchar('m');
sleep(3);
}
if (termtyp == 2) { /* Wyse WY-99GT */
putchar(0x1b);
putchar('~');
putchar('5');
}
}
/*
* Restore tty-Parameter
*/
restty()
{
if (termtyp == 1) {
putchar(0x1b);
putchar('1');
sleep(2);
}
if (termtyp == 2) {
printf("%s","\033G0\033.1\033v");
putchar('+');
}
ioctl(0, TCSETA, &savterm);
chmod(tty, 0622);
}
/*
* Eingabe vom Terminal zu CPU2 senden
*/
term_to_cpu2()
{
char c;
while (1) { /* Schleife endet nie */
read(0, &c, 1);
if ((termtyp && c == 0x58) || /* F12 beendet Programm */
(termtyp == 0 && c == 0x1c)) /* ^\ beendet Programm */
intrupt();
else
write(cpu2tty, &c, 1);
}
}
/*
* CPU2-Terminalasgabe zum Terminal senden
*/
cpu2_to_term()
{
register n_read;
register char *buf;
buf = malloc(0x800);
while (1) {
n_read = read(cpu2tty, buf, 0x800);
write(1, buf, n_read);
}
}
/*
* CPU2-Druckerausgabe zum Drucker senden
*/
cpu2_to_lp()
{
register n_read;
register FILE *fp;
n_read = read(cpu2lp, buffer, BUFLEN);
if (lp) {
if (fp = fopen(lp, "r+")) {
if (strncmp(lp, "/dev", 4) == 0)
setbuf(fp, (char *)0);
goto lpwrite;
}
printf("\r\n%s: kann %s nicht oeffnen\r\n", pname, lp);
printf("Druckerausgaben erfolgen zur Datei /tmp/wdoslp\r\n");
}
fp = fopen("/tmp/wdoslp", "w+");
lpwrite:
while (1) {
fwrite(buffer, sizeof(*buffer), n_read, fp);
n_read = read(cpu2lp, buffer, BUFLEN);
}
}
/*
* Disk-Arbeit realisieren
*/
cpu2_disk()
{
register struct diskrq *prq = &diskrq;
register d;
register unsigned len;
register n_read;
char comcode;
char *buf;
buf = malloc(DISKBUF);
if (buf == 0) {
printf("Malloc\n");
sleep(4);
}
while (1) {
read(cpu2disk, &diskrq, sizeof(struct diskrq));
comcode = 0;
if (((d = prq->drive) > 5) || prq->len == 0) {
comcode = 1;
goto diskend;
}
if (fddisk[d] == 0) {
if (mname[d][0]==0 || (fddisk[d]=open(mname[d],O_RDWR))==-1) {
fddisk[d] = 0;
comcode = 0x80;
goto diskend;
}
}
lseek(fddisk[d], prq->blkoff, 0);
lseek(cpu2ram, prq->addr, 0);
while (prq->len != 0) {
len = prq->len;
if (len > DISKBUF)
len = DISKBUF;
prq->len -= len;
switch (prq->rcode) {
case 1: /* Read */
n_read = read(fddisk[d], buf, len);
if (n_read == -1) {
comcode = 0x10; /* Fehler */
goto diskend;
}
while (len > n_read) {
buf[n_read] = 0;
n_read++;
}
if (write(cpu2ram, buf, n_read) != n_read) {
comcode = 0x08;
goto diskend;
}
break;
case 2: /* Write */
n_read = read(cpu2ram, buf, len);
if (n_read != len) {
comcode = 0x08;
goto diskend;
}
if (write(fddisk[d], buf, n_read) != n_read) {
comcode = 0x10;
goto diskend;
}
break;
default:
comcode = 1;
goto diskend;
}
}
diskend:
write(cpu2disk, &comcode, 1);
}
}
/*
* Behandlung Alarm-Interrupt
*/
time_out()
{
signal(SIGALRM, time_out);
timeout++;
}
/*
* benutzt von Vater und Soehnen
*/
intrupt(sig)
int sig;
{
int status;
if (child1 && child2 && child3) { /* Vaterprozess */
signal(SIGINT, SIG_IGN); /* ignoriere weiterer SIGINT */
kill(child1, SIGINT); /* Soehne beenden */
kill(child2, SIGINT);
kill(child3, SIGINT);
/*
wait(&status);
wait(&status);
wait(&status);
*/
restty();
print();
} else /* einer der Sohnprozesse */
kill(parent, SIGINT); /* Vater beendet dann alle */
/* Soehne und sich selbst */
exit(0);
}
main(argc, argv)
register argc;
register char *argv[];
{
register char *filname = (char *)0;
unsigned oflag;
pname = argv[0];
oflag = O_RDWR;
term = getenv("TERM");
lp = getenv("WDOS_LP");
if (strncmp(term,"w8",2) == 0 || strncmp(term,"W8",2) == 0)
termtyp = 1;
else if (strncmp(term,"WY",2) == 0)
termtyp = 2;
else if (strncmp(term,"p8",2) != 0 && strncmp(term,"P8",2) != 0) {
printf("%s: Falscher Terminaltyp\n", pname);
exit(1);
}
switch (--argc) { /* Kommandozeilen-Argumente auswerten */
case 0:
filname = "/z/wdoslib/bios.p8";
if (termtyp == 1)
filname = "/z/wdoslib/bios";
if (termtyp == 2)
filname = "/z/wdoslib/bios.wy";
break;
case 1:
if ((*++argv)[0] != '-') { /* Optionen ? */
filname = *argv; /* Argument ist Dateiname */
break;
} else {
if ((*argv)[1] == 'r') {
oflag = O_RDWR | O_NDELAY; /* O_NDELAY hier: */
break; /* kein Reset fuer CPU */
}
}
default:
printf("Usage: %s [-resume | proto_file]\n", pname);
exit(1);
}
if ((cpu2ram = open("/dev/cpu2rram", oflag)) == -1) {
printf("%s: kann /dev/cpu2rram nicht oeffnen\n",pname);
exit(1);
}
if (filname)
load(filname);
else
setreturn();
disknames();
setdate();
if ((cpu2tty = open("/dev/cpu2tty", O_RDWR)) == -1) {
printf("%s: kann /dev/cpu2tty nicht oeffnen\n", pname);
exit(1);
}
if ((cpu2lp = open("/dev/cpu2lp", O_RDONLY)) == -1) {
printf("%s: kann /dev/cpu2lp nicht oeffnen\n", pname);
exit(1);
}
if ((cpu2disk = open("/dev/cpu2disk", O_RDWR)) == -1) {
printf("%s: kann /dev/cpu2disk nicht oeffnen\n",pname);
exit(1);
}
settty();
signal(SIGALRM, time_out);
signal(SIGHUP, intrupt);
signal(SIGINT, intrupt);
signal(SIGQUIT, intrupt);
signal(SIGTERM, intrupt);
parent = getpid(); /* Prozess-Id dieses Prozesses */
if ((child1 = fork()) == 0) /* Sohnprozess 1 */
cpu2_to_term();
if ((child2 = fork()) == 0) /* Sohnprozess 2 */
cpu2_to_lp();
if ((child3 = fork()) == 0) /* Sohnprozess 3 */
cpu2_disk();
term_to_cpu2(); /* Vater */
}
/*
* WDOS-BIOS (Datei proto.file)
* in den RAM der Erweiterungskarten laden
*/
load(filname)
register char *filname;
{
register int fdr;
register int n_read;
if ((fdr = open(filname, O_RDONLY)) == -1) {
printf("%s: kann %s nicht oeffnen\n", pname, filname);
exit(1);
}
fstat(fdr, &stbuf);
if ((stbuf.st_mode & S_IFDIR)|| /* ist es ein Directory ? */
stbuf.st_size == 0L || /* Test der Laenge */
stbuf.st_size > 0x10000L) {
printf("%s: Fehler in %s\n", pname, filname);
exit(1);
}
/* Datei lesen und zu CPU2-RAM schreiben */
lseek(cpu2ram, 0x100000L-stbuf.st_size, 0); /* RAM-Adresse einstellen */
while ((n_read = read(fdr, buffer, BUFLEN)) > 0)
write(cpu2ram, buffer, n_read);
close(fdr); /* Close Files */
}
/*
* Return zu WDOS an CPU2 uebermitteln
*/
setreturn()
{
lseek(cpu2ram, 0xfd000L, 0); /* Adresse reset */
buffer[0] = 1;
write(cpu2ram, buffer, 1);
}
/*
* Datum fuer CPU2 setzen
*/
setdate()
{
register struct tm *tp;
long clock;
struct tm *localtime();
lseek(cpu2ram, 0xfd026L, 0); /* Adresse struct dos_date */
time(&clock);
tp = localtime(&clock);
buffer[0] = tp->tm_sec;
buffer[1] = tp->tm_min;
buffer[2] = tp->tm_hour;
buffer[3] = tp->tm_mday;
buffer[4] = tp->tm_mon;
buffer[5] = tp->tm_year;
write(cpu2ram, buffer, 6);
}
/*
* Ermitteln der gemounteten Disketten aus der Datei $HOME/.dos
*/
disknames()
{
register FILE *fp;
register i, m;
register hd0 = 0;
register hd1 = 0;
char *p;
char *strrchr();
strcpy(buffer, getenv("HOME"));
strcat(buffer, "/.dos");
if ((fp = fopen(buffer, "r")) == NULL) {
printf("%s: kann %s nicht oeffnen\n", pname,buffer);
exit(1);
}
for (i = 0; i < 6; i++) {
if (fgets(&mname[6][0], 50, fp) == NULL ||
(i < 6 && mname[6][0] != i+'A')) {
printf("%s: Fehler in %s\n", pname, buffer);
exit(1);
}
mname[6][strlen(mname[6])-1] = 0;
if (mname[6][2] == 0)
continue;
strcpy(mname[i], &mname[6][2]);
if (strncmp(&mname[6][2], "/dev/", 5) == 0) {
mname[i][5] = 'r'; /* raw-Device benutzen */
strcpy(&mname[i][6], &mname[6][7]);
}
m = 3;
if ((p = strrchr(mname[i], '_'))) {
if (strncmp(p, "_5", 2) == 0)
m = 0;
if (strncmp(p, "_10", 3) == 0)
m = 1;
if (strncmp(p, "_20", 3) == 0)
m = 2;
}
if (i == 2 || i == 3) { /* Harddisk Laufwerke */
if (m == 3) {
printf("%s: Mount-Fehler Harddisk-Laufwerk %c\n", pname,i+'A');
exit(1);
}
if (i == 2)
hd0 = m;
else
hd1 = m;
} else {
if (m != 3) {
printf("%s: Mount-Fehler Floppy-Laufwerk %c\n", pname,i+'A');
exit(1);
}
}
}
fclose(fp);
lseek(cpu2ram, 0xfd024L, 0); /* Adresse hd0/hd1type */
buffer[0] = hd0;
buffer[1] = hd1;
write(cpu2ram, buffer, 2);
}
/*
* Ausgabe der Datei /tmp/wdoslp zum Drucker
*/
print()
{
if (stat("/tmp/wdoslp", &stbuf) == -1)
return; /* keine Daten vorhanden */
printf("\nEs wurden %D Byte zum Drucken angesammelt, ausdrucken ? (j/n): ", stbuf.st_size);
if (getchar() != 'j') {
unlink("/tmp/wdoslp");
return;
}
system("/z/wdoslib/run_lpr /tmp/wdoslp");
}