WDOS Software
This commit is contained in:
parent
55769aa2cd
commit
df41260ac5
|
|
@ -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");
|
||||
}
|
||||
Loading…
Reference in New Issue