mirror of
https://github.com/prirun/p50em.git
synced 2026-01-13 23:26:13 +00:00
condition code macros
mem array is segment addressable start of boot support use CC macros and BCxx to emulate Bxyy (eg, BFLT) use CC macros and LCxx to emulate Lxyy (eg, LFLT) shift instruction work
This commit is contained in:
parent
9291d9e864
commit
ff3fd68935
150
emdev.h
150
emdev.h
@ -1,3 +1,62 @@
|
||||
/* emdev.h, Jim Wilcoxson, April 17, 2005
|
||||
Device handlers for pio instructions. Use devnull as a template for
|
||||
new handlers.
|
||||
NOTES:
|
||||
|
||||
OCP instructions never skip
|
||||
SKS instructions skip on specified conditions
|
||||
INA/OTA instructions skip if they succeed (data was read/written)
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
void devnull (short class, short func, short device) {
|
||||
|
||||
switch (class) {
|
||||
|
||||
case 0:
|
||||
fprintf(stderr," OCP '%2#0o%2#0o\n", func, device);
|
||||
if (func == 0) {
|
||||
;
|
||||
} else {
|
||||
fprintf(stderr," unimplemented OCP device %2#0o function\n", device);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
fprintf(stderr," SKS '%2#0o%2#0o\n", func, device);
|
||||
if (func == 0)
|
||||
mem[P]++; /* assume it's always ready */
|
||||
else {
|
||||
fprintf(stderr," unimplemented SKS device %2#0o function\n", device);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
fprintf(stderr," INA '%2#0o%2#0o\n", func, device);
|
||||
if (func == 0) {
|
||||
;
|
||||
} else {
|
||||
fprintf(stderr," unimplemented INA device %2#0o function\n", device);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
fprintf(stderr," OTA '%2#0o%2#0o\n", func, device);
|
||||
if (func == 0 | func == 1) {
|
||||
mem[P]++; /* OTA '0004 always works on Unix */
|
||||
} else {
|
||||
fprintf(stderr," unimplemented OTA device %2#0o function\n", device);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Device '4: system console
|
||||
|
||||
OCP '0004 = initialize for input only, echoplex, 110 baud, 8-bit, no parity
|
||||
@ -10,16 +69,15 @@
|
||||
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
void devasr (unsigned short class, unsigned short func) {
|
||||
void devasr (short class, short func, short device) {
|
||||
|
||||
static int ttydev=-1;
|
||||
unsigned char ch;
|
||||
int ttyflags, newflags;
|
||||
int n;
|
||||
|
||||
if (ttydev < 0) {
|
||||
ttydev = open("/dev/tty", O_RDWR+O_NONBLOCK, 0);
|
||||
ttydev = open("/dev/tty", O_RDWR, 0);
|
||||
if (ttydev < 0) {
|
||||
perror(" error opening /dev/tty");
|
||||
exit(1);
|
||||
@ -29,11 +87,11 @@ void devasr (unsigned short class, unsigned short func) {
|
||||
switch (class) {
|
||||
|
||||
case 0:
|
||||
fprintf(stderr," OCP '%o04\n", func);
|
||||
fprintf(stderr," OCP '%2#0o%2#0o\n", func, device);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
fprintf(stderr," SKS\n");
|
||||
fprintf(stderr," SKS '%2#0o%2#0o\n", func, device);
|
||||
if (func <= 7)
|
||||
mem[P]++; /* assume it's always ready */
|
||||
else {
|
||||
@ -43,9 +101,20 @@ void devasr (unsigned short class, unsigned short func) {
|
||||
break;
|
||||
|
||||
case 2:
|
||||
fprintf(stderr," INA\n");
|
||||
fprintf(stderr," INA '%2#0o%2#0o\n", func, device);
|
||||
if (func == 0 || func == 010) {
|
||||
usleep(100000);
|
||||
if (fcntl(ttydev, F_GETFL, ttyflags) == -1) {
|
||||
perror(" unable to get tty flags");
|
||||
exit(1);
|
||||
}
|
||||
if (mem[mem[P]] == 03776) /* JMP *-1 -> blocking read */
|
||||
newflags = ttyflags & ~O_NONBLOCK;
|
||||
else
|
||||
newflags = ttyflags | O_NONBLOCK;
|
||||
if (fcntl(ttydev, F_SETFL, newflags) == -1) {
|
||||
perror(" unable to set tty flags");
|
||||
exit(1);
|
||||
}
|
||||
n = read(ttydev, &ch, 1);
|
||||
if (n < 0) {
|
||||
if (errno != EAGAIN) {
|
||||
@ -53,13 +122,19 @@ void devasr (unsigned short class, unsigned short func) {
|
||||
exit(1);
|
||||
}
|
||||
} else if (n == 1) {
|
||||
mem[A] = ch | 0x80;
|
||||
if (func >= 010)
|
||||
mem[A] = 0;
|
||||
mem[A] = mem[A] | ch | 0x80;
|
||||
mem[P]++;
|
||||
} else if (n != 0) {
|
||||
fprintf(stderr," unexpected error reading from tty, n=%d", n);
|
||||
exit(1);
|
||||
}
|
||||
} else if (func == 012) { /* no idea what this does... */
|
||||
} else if (func == 011) { /* read device id? */
|
||||
mem[A] = 4;
|
||||
mem[P]++;
|
||||
} else if (func == 012) { /* read control word */
|
||||
mem[A] = 04110;
|
||||
mem[P]++;
|
||||
} else {
|
||||
fprintf(stderr," unimplemented INA '04 function\n");
|
||||
@ -68,12 +143,14 @@ void devasr (unsigned short class, unsigned short func) {
|
||||
break;
|
||||
|
||||
case 3:
|
||||
fprintf(stderr," OTA\n");
|
||||
if (func == 0 | func == 1) {
|
||||
fprintf(stderr," OTA '%2#0o%2#0o\n", func, device);
|
||||
if (func == 0) {
|
||||
fprintf(stderr," char to write=%o\n", mem[A]);
|
||||
putchar(mem[A] & 0x7f);
|
||||
fflush(stdout);
|
||||
mem[P]++; /* OTA '0004 always works on Unix */
|
||||
} else if (func == 1) { /* write control word */
|
||||
mem[P]++;
|
||||
} else {
|
||||
fprintf(stderr," unimplemented OTA '04 function\n");
|
||||
exit(1);
|
||||
@ -82,3 +159,52 @@ void devasr (unsigned short class, unsigned short func) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Device '20: control panel switches and lights
|
||||
|
||||
OTA '1720 = write to lights (sets CP fetch address)
|
||||
INA '1420 = read location from CP ROM (not implemented, used to boot)
|
||||
INA '1620 = read control panel switches
|
||||
*/
|
||||
|
||||
void devcp (short class, short func, short device) {
|
||||
|
||||
switch (class) {
|
||||
|
||||
case 0:
|
||||
fprintf(stderr," OCP '%2#0o%2#0o\n", func, device);
|
||||
fprintf(stderr," unimplemented OCP device %2#0o function\n", device);
|
||||
exit(1);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
fprintf(stderr," SKS '%2#0o%2#0o\n", func, device);
|
||||
fprintf(stderr," unimplemented SKS device %2#0o function\n", device);
|
||||
exit(1);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
fprintf(stderr," INA '%2#0o%2#0o\n", func, device);
|
||||
if (func == 016) {
|
||||
mem[A] = 0;
|
||||
} else {
|
||||
fprintf(stderr," unimplemented INA device %2#0o function\n", device);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
fprintf(stderr," OTA '%2#0o%2#0o\n", func, device);
|
||||
if (func == 017) { /* write lights */
|
||||
mem[P]++;
|
||||
} else {
|
||||
fprintf(stderr," unimplemented OTA device %2#0o function\n", device);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
180
os.c
Normal file
180
os.c
Normal file
@ -0,0 +1,180 @@
|
||||
/* os.c, Jim Wilcoxson, 4/15/2005
|
||||
Emulations of Primos Operating System routines for Unix.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <sys/times.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "syscom/keys.ins.cc"
|
||||
#include "syscom/errd.ins.cc"
|
||||
|
||||
|
||||
os_init() {
|
||||
|
||||
os.ttydev = open("/dev/tty", O_RDWR, 0);
|
||||
if (os.ttydev < 0) {
|
||||
perror(" error opening /dev/tty");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
os_break$(short *onoff) {
|
||||
}
|
||||
|
||||
os_c1in(short *charg) {
|
||||
unsigned char ch;
|
||||
int n;
|
||||
|
||||
fprintf(stderr," c1in waiting for data\n");
|
||||
n = read(os.ttydev, &ch, 1);
|
||||
if (n < 0) {
|
||||
perror(" error reading from tty");
|
||||
exit(1);
|
||||
}
|
||||
if (n != 1) {
|
||||
fprintf(stderr," unexpected error reading from tty, n=%d", n);
|
||||
exit(1);
|
||||
}
|
||||
*charg = ch | 0x80;
|
||||
}
|
||||
|
||||
|
||||
os_comanl() {
|
||||
}
|
||||
|
||||
|
||||
os_cnin$(unsigned char *buf, short *maxchars, short *n) {
|
||||
short ch;
|
||||
|
||||
*n = 0;
|
||||
while (*n < *maxchars) {
|
||||
os_c1in(&ch);
|
||||
buf[*n] = ch;
|
||||
(*n)++;
|
||||
if (ch == 0212) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
os_exit() {
|
||||
fprintf(stderr,"\nProgram called EXIT\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
os_erkl$$(short *key, short *erasech, short *killch, short *code) {
|
||||
if (*key == k$read) {
|
||||
*erasech = 0210;
|
||||
*killch = 0377;
|
||||
*code = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
os_errpr$ (short *key, short *code, char *msg, short *msglen, char *prog, short *proglen) {
|
||||
if (*code == 0) return;
|
||||
fprintf (stderr, " key=%d, code=%d, msglen=%d, proglen=%d\n", *key, *code, *msglen, *proglen);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
os_ginfo (short *buf, short *bufsiz) {
|
||||
int i;
|
||||
|
||||
fprintf(stderr," ginfo bufsiz=%d\n", *bufsiz);
|
||||
if (*bufsiz <= 0) return;
|
||||
buf[0] = 0;
|
||||
if (*bufsiz > 1) buf[1] = 0;
|
||||
if (*bufsiz > 2) buf[2] = 61; /* max device # */
|
||||
for (i=0; i < *bufsiz-3; i++)
|
||||
buf[i+3] = 440; /* disk record size */
|
||||
}
|
||||
|
||||
/* RDTK$$
|
||||
|
||||
key - 1=read UC, 2=read, 3=reset, 4=rest, 5=init
|
||||
info - output array
|
||||
[0] = type - 1=normal, 2=regular, 5=null, 6=eol
|
||||
info[1] = length
|
||||
info[2] = flags
|
||||
:100000=decimal, :40000=octal, :20000=dash, :10000=info[3] < 8
|
||||
info[3] = positional token's position 0-9 (1/44, 4/20, etc)
|
||||
info[4] = positional token's value
|
||||
buf - output token buffer
|
||||
buflen - size in words of buf (in)
|
||||
code - return code
|
||||
|
||||
*/
|
||||
|
||||
os_rdtk$$(short *key, short *info, char *buf, short *buflen, short *code) {
|
||||
fprintf(stderr," key=%d\n", *key);
|
||||
*code = 0;
|
||||
if (*key = 1) {
|
||||
info[0] = 6;
|
||||
info[1] = 0;
|
||||
info[2] = 0;
|
||||
info[3] = 0;
|
||||
info[4] = 0;
|
||||
} else {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
os_t1ou(short *charg) {
|
||||
putchar(*charg & 0x7f);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
os_timdat(short *userbuf, short *n) {
|
||||
clock_t tod;
|
||||
struct tm tms;
|
||||
struct {
|
||||
char mmddyy[6];
|
||||
short timemins; /* minutes since midnight */
|
||||
short timesecs; /* plus seconds (0-50) */
|
||||
short timeticks; /* plus ticks (0-329 330ths of a second) */
|
||||
short cpusecs;
|
||||
short cputicks;
|
||||
short iosecs;
|
||||
short ioticks;
|
||||
short tickspersec;
|
||||
short userno;
|
||||
char username[32];
|
||||
} timbuf;
|
||||
|
||||
if (sizeof(timbuf) != sizeof(short)*28) {
|
||||
fprintf(stderr," sizeof(timebuf)=%d, size of 28-word array=%d\n",
|
||||
sizeof(timbuf), sizeof(short)*28);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
tod = time(NULL);
|
||||
localtime_r(&tod, &tms);
|
||||
strncpy(timbuf.mmddyy,"042105",6);
|
||||
timbuf.timemins = tms.tm_hour*60 + tms.tm_min;
|
||||
timbuf.timesecs = tms.tm_sec;
|
||||
timbuf.timeticks = 0;
|
||||
timbuf.cpusecs = timbuf.cputicks = timbuf.iosecs = timbuf.ioticks = 0;
|
||||
timbuf.tickspersec = 330;
|
||||
timbuf.userno = 1;
|
||||
strncpy(timbuf.username,"SYSTEM ",32);
|
||||
memcpy(userbuf, &timbuf, *n*2);
|
||||
}
|
||||
|
||||
|
||||
os_tnoua(unsigned char *s, short *len) {
|
||||
int i;
|
||||
fprintf(stderr," writing %d char string \"", *len);
|
||||
for (i=0; i < *len; i++)
|
||||
fputc(s[i] & 0x7f,stderr);
|
||||
fprintf(stderr,"\"\n");
|
||||
|
||||
for (i=0; i < *len; i++)
|
||||
putchar(s[i] & 0x7f);
|
||||
fflush(stdout);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user