1
0
mirror of https://github.com/aap/pdp6.git synced 2026-02-07 17:01:50 +00:00

lots of additions and changes

This commit is contained in:
aap
2019-12-05 00:31:20 +01:00
parent 207c7fde95
commit 716317c8ce
35 changed files with 3156 additions and 93 deletions

View File

@@ -477,6 +477,8 @@ cpu_printflags(void)
void fe_svc(void) {}
void initcrt(const char *host) {}
void
init6(void)
{

View File

@@ -81,12 +81,17 @@ enum
REG6_PTR = 035,
REG6_PTR_LT = 036,
REG6_PTR_RT = 037,
REG6_DIS1 = 040,
REG6_DIS2 = 041,
REG6_DIS3 = 042,
};
enum {
FEREG_REQ = 0,
FEREG_PTR,
FEREG_PTP
FEREG_PTP,
FEREG_DIS
};
@@ -106,6 +111,7 @@ static volatile u32 *h2f_cmemif, *h2f_cmemif2;
static volatile u32 *h2f_fmemif, *h2f_fmemif2;
static volatile u32 *h2f_apr;
static volatile u32 *h2f_fe;
static volatile u32 *h2f_csl;
static volatile u32 *h2f_lw_led_addr;
static volatile u32 *h2f_lw_sw_addr;
@@ -137,13 +143,16 @@ deposit(hword a, word w)
h2f_fmemif[1] = w & RT;
h2f_fmemif[2] = (w >> 18) & RT;
}else if(a < 01000020){
void dep64(u32, u64);
if(0 && a < 01000){
printf("dep %o %llo\r\n", a, w);
fflush(stdout);
}
// dep64(a, w);
h2f_cmemif[0] = a & RT;
h2f_cmemif[1] = w & RT;
h2f_cmemif[2] = (w >> 18) & RT;
}else if(a >= 02000000){
h2f_cmemif2[0] = a & 01777777;
h2f_cmemif2[1] = w & RT;
h2f_cmemif2[2] = (w >> 18) & RT;
}else switch(a){
case APR_DS:
h2f_apr[REG6_DSLT] = w>>18 & RT;
@@ -179,6 +188,8 @@ deposit(hword a, word w)
*h2f_lw_led_addr = w;
break;
}
// usleep(5);
}
word
@@ -217,15 +228,13 @@ examine(hword a)
w <<= 18;
w |= h2f_fmemif[1] & RT;
}else if(a < 01000020){
//u64 ex64(u32);
// w = ex64(a);
h2f_cmemif[0] = a & RT;
w = h2f_cmemif[2] & RT;
w <<= 18;
w |= h2f_cmemif[1] & RT;
}else if(a >= 02000000){
h2f_cmemif2[0] = a & 01777777;
w = h2f_cmemif2[2] & RT;
w <<= 18;
w |= h2f_cmemif2[1] & RT;
}else switch(a){
case APR_DS:
w = h2f_apr[REG6_DSLT];
@@ -556,6 +565,33 @@ prflags(const char *fmt, u8 flags)
l[!!(flags&02)], l[!!(flags&01)]);
}
void
prdis(void)
{
u32 dis1, dis2, dis3;
dis1 = h2f_apr[REG6_DIS1];
dis2 = h2f_apr[REG6_DIS2];
dis3 = h2f_apr[REG6_DIS3];
printf("\r\nDIS\r\n");
printf("BR/%06o\r\n", dis1);
printf("X/%04o Y/%04o BRM/%03o S/%02o I/%o SZ/%o MODE/%o\r\n",
dis2&01777, (dis2>>10)&01777, (dis2>>20)&0177,
(dis3>>8)&017, (dis3>>5)&7, (dis3>>3)&3, dis3&7);
printf("DATA REQ/%o STOP/%o EDGE/%o LP/%o LP ON/%o LP FIND/%o\r\n",
!!(dis3 & 04000000),
!!(dis3 & 0400000),
!!(dis3 & 02000000),
!!(dis3 & 040000),
!!(dis3 & 020000),
!!(dis3 & 010000));
printf("MOVE/%o HALT/%o\r\n",
!!(dis3 & 0200000),
!!(dis3 & 0100000));
dis3 = h2f_apr[REG6_DIS3+1];
printf("%X\r\n", dis3);
}
void
cpu_printflags(void)
{
@@ -589,6 +625,8 @@ cpu_printflags(void)
printf("RUN/%o MEM STOP/%o\r\n",
!!(ctl1 & MM6_RUN), !!(ctl1 & MM6_MCSTOP));
prdis();
fflush(stdout);
}
@@ -628,6 +666,25 @@ fflush(stdout);
write(fd, &c, 1);
}
int dis_fd = -1;
static void
svc_dis(void)
{
u32 pnt;
pnt = h2f_fe[FEREG_DIS];
if((pnt & 0x80000000) == 0)
return;
if(dis_fd >= 0)
write(dis_fd, &pnt, 4);
/*
else{
printf("%X\r\n", pnt);
fflush(stdout);
}
*/
}
void
fe_svc(void)
{
@@ -637,8 +694,30 @@ fe_svc(void)
if(req & 1) svc_ptr();
if(req & 2) svc_ptp();
// if(req & 4) svc_dis();
svc_dis();
}
void*
wcsl_thread(void *arg)
{
u32 ctl;
while(readn(dis_fd, &ctl, 4) == 0){
// printf("%o\r\n", ctl);
// fflush(stdout);
h2f_csl[ctl>>24] = ctl;
}
}
void
initcrt(const char *host)
{
dis_fd = dial(host, 3400);
if(dis_fd >= 0){
printf("display connected\n");
threadcreate(wcsl_thread, nil);
}
}
void
init6(void)
@@ -668,11 +747,17 @@ init6(void)
h2f_fmemif = getLWH2Faddr(0x10010);
h2f_fmemif2 = getLWH2Faddr(0x20010);
// enable sdram bridge (???)
*(u32*)((u8*)virtual_base + 0x5080) = 0xFFFF;
h2f_apr = getLWH2Faddr(0x10100);
h2f_fe = getLWH2Faddr(0x20000);
h2f_csl = getLWH2Faddr(0x30000);
h2f_lw_sw_addr = getLWH2Faddr(0x10020);
h2f_lw_led_addr = getLWH2Faddr(0x10040);
// testshit();
}
void

View File

@@ -1,21 +1,22 @@
XX=/u/aap/de0-nano-soc/gcc-linaro-6.5.0-2018.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
CFLAGS=-DTEST
LDFLAGS=-lpthread
SRC=fe.c cmd.c util.c pdp6common.c
SRC=fe.c cmd.c util.c netmem.c pdp6common.c threading.c
all: fe6_emu fe6_fake fe6 feka
clean:
rm fe6_emu fe6_fake fe6
fe6: $(SRC) 6/real6.c
$(XX)gcc -I6 $(CFLAGS) -o $@ $^
$(XX)gcc -I6 $(CFLAGS) $(LDFLAGS) -o $@ $^
fe6_fake: $(SRC) fake.c
$(CC) -I6 $(CFLAGS) -o $@ $^
$(CC) -I6 $(CFLAGS) $(LDFLAGS) -o $@ $^
fe6_emu: $(SRC) 6/emu6.c
$(CC) -I6 $(CFLAGS) -o $@ $^
$(CC) -I6 $(CFLAGS) $(LDFLAGS) -o $@ $^
feka: $(SRC) ka/real.c
$(XX)gcc -Ika $(CFLAGS) -o $@ $^
$(XX)gcc -Ika $(CFLAGS) $(LDFLAGS) -o $@ $^

View File

@@ -114,8 +114,9 @@ sblk:
chk = (chk<<1 | chk>>35) + w & FW;
if(d)
if(d){
deposit(right(iowd), w);
}
iowd += 01000001;
}
if(readwits(fp) != chk)

View File

@@ -188,6 +188,8 @@ cpu_printflags(void)
void fe_svc(void) {}
void initcrt(const char *host) {}
void
init6(void)
{

View File

@@ -87,6 +87,7 @@ enum {
MODE_ASCII,
MODE_SIXBIT,
MODE_SQUOZE,
MODE_FLOAT,
/* flags */
CF = 1, // one altmode
@@ -404,6 +405,7 @@ prword(int mode, word wd)
int i;
char c;
char s[7];
double f;
switch(mode){
case MODE_ASCII:
@@ -453,6 +455,12 @@ prword(int mode, word wd)
typenum((wd>>18)&0777777);
break;
case MODE_FLOAT:
f = pdptod(wd);
printf("%lf", f);
fflush(stdout);
break;
default:
typenum(wd);
}
@@ -553,12 +561,14 @@ quit(void)
int started;
int
main()
threadmain(int argc, char *argv[])
{
char chu;
word t;
init6();
initcrt("soma");
// initnetmem("10.0.0.222", 10006);
raw(0);
erasec = tiosaved.c_cc[VERASE];
@@ -603,6 +613,7 @@ main()
typestr("/ ");
t = examine(t);
prword(MODE_SYM, t);
q = t;
typestr(" ");
started = 0;
@@ -898,6 +909,9 @@ main()
case '=':
typeout(MODE_NUM);
break;
case ';':
typeout(MODE_FLOAT);
break;
case '"':
if(flags & CF)
modechange(MODE_ASCII);

View File

@@ -5,6 +5,7 @@
#include <ctype.h>
#include "util.h"
#include "pdp6common.h"
#include "threading.h"
#define nil NULL
@@ -18,7 +19,8 @@ typedef uint8_t u8;
#define FW (LT|RT)
#define F0 0400000000000
#define MAXMEM (16*1024)
//#define MAXMEM (16*1024)
#define MAXMEM (256*1024)
#include "regs.h"
@@ -83,5 +85,8 @@ void cpu_printflags(void);
void fe_svc(void);
void initcrt(const char *host);
void initnetmem(const char *host, int port);
void init6(void);
void deinit6(void);

View File

@@ -96,7 +96,8 @@ enum
enum {
FEREG_REQ = 0,
FEREG_PTR,
FEREG_PTP
FEREG_PTP,
FEREG_DIS
};
@@ -116,6 +117,7 @@ static volatile u32 *h2f_cmemif;
static volatile u32 *h2f_fmemif;
static volatile u32 *h2f_apr;
static volatile u32 *h2f_fe;
static volatile u32 *h2f_csl;
void
deposit(hword a, word w)
@@ -661,6 +663,23 @@ fflush(stdout);
write(fd, &c, 1);
}
int dis_fd;
static void
svc_dis(void)
{
u32 pnt;
pnt = h2f_fe[FEREG_DIS];
if((pnt & 0x80000000) == 0)
return;
if(dis_fd >= 0)
write(dis_fd, &pnt, 4);
else{
printf("%X\r\n", pnt);
fflush(stdout);
}
}
void
fe_svc(void)
{
@@ -670,8 +689,30 @@ fe_svc(void)
if(req & 1) svc_ptr();
if(req & 2) svc_ptp();
// if(req & 4) svc_dis();
svc_dis();
}
void*
wcsl_thread(void *arg)
{
u32 ctl;
while(readn(dis_fd, &ctl, 4) == 0){
// printf("%o\r\n", ctl);
// fflush(stdout);
h2f_csl[ctl>>24] = ctl;
}
}
void
initcrt(const char *host)
{
dis_fd = dial(host, 3400);
if(dis_fd >= 0){
printf("display connected\n");
threadcreate(wcsl_thread, nil);
}
}
void
init6(void)
@@ -699,6 +740,7 @@ init6(void)
h2f_fmemif = getLWH2Faddr(0x10010);
h2f_apr = getLWH2Faddr(0x10100);
h2f_fe = getLWH2Faddr(0x20000);
h2f_csl = getLWH2Faddr(0x30000);
}
void

81
fe6/netmem.c Normal file
View File

@@ -0,0 +1,81 @@
#include "fe.h"
#include <unistd.h>
int netmemfd = -1;
enum
{
WRRQ = 1,
RDRQ = 2,
ACK = 3,
ERR = 4,
};
void*
netmemthread(void *arg)
{
u16 len;
word a, d;
u8 buf[9];
while(readn(netmemfd, buf, 2) == 0){
len = buf[0]<<8 | buf[1];
if(len > 9){
fprintf(stderr, "netmem botch(%d), closing\n", len);
close(netmemfd);
netmemfd = -1;
return nil;
}
memset(buf, 0, sizeof(buf));
readn(netmemfd, buf, len);
a = buf[1] | buf[2]<<8 | buf[3]<<16;
d = buf[4] | buf[5]<<8 | buf[6]<<16 |
(word)buf[7]<<24 | (word)buf[8]<<32;
a &= 0777777;
d &= 0777777777777;
switch(buf[0]){
case WRRQ:
deposit(a, d);
printf("write %06lo %012lo\r\n", a, d);
fflush(stdout);
buf[0] = 0;
buf[1] = 1;
buf[2] = ACK;
writen(netmemfd, buf, buf[1]+2);
break;
case RDRQ:
d = examine(a);
printf("read %06lo %012lo\r\n", a, d);
fflush(stdout);
buf[0] = 0;
buf[1] = 6;
buf[2] = ACK;
buf[3] = d;
buf[4] = d>>8;
buf[5] = d>>16;
buf[6] = d>>24;
buf[7] = d>>32;
writen(netmemfd, buf, buf[1]+2);
break;
default:
fprintf(stderr, "unknown netmem message %d\n", buf[0]);
break;
}
}
fprintf(stderr, "netmem fd closed\n");
netmemfd = -1;
return nil;
}
void
initnetmem(const char *host, int port)
{
netmemfd = dial(host, port);
if(netmemfd >= 0){
printf("netmem connected\n");
threadcreate(netmemthread, nil);
}
}

361
fe6/threading.c Normal file
View File

@@ -0,0 +1,361 @@
#include "threading.h"
#include <assert.h>
#define USED(x) (void)(x)
/*
* Locks
*/
static pthread_mutex_t initmutex = PTHREAD_MUTEX_INITIALIZER;
static void
lockinit(Lock *lk)
{
pthread_mutexattr_t attr;
pthread_mutex_lock(&initmutex);
if(lk->init == 0){
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
pthread_mutex_init(&lk->mutex, &attr);
pthread_mutexattr_destroy(&attr);
lk->init = 1;
}
pthread_mutex_unlock(&initmutex);
}
void
lock(Lock *lk)
{
if(!lk->init)
lockinit(lk);
if(pthread_mutex_lock(&lk->mutex) != 0)
abort();
}
int
canlock(Lock *lk)
{
int r;
if(!lk->init)
lockinit(lk);
r = pthread_mutex_trylock(&lk->mutex);
if(r == 0)
return 1;
if(r == EBUSY)
return 0;
abort();
}
void
unlock(Lock *lk)
{
if(pthread_mutex_unlock(&lk->mutex) != 0)
abort();
}
static void
rendinit(Rendez *r)
{
pthread_condattr_t attr;
pthread_mutex_lock(&initmutex);
if(r->init == 0){
pthread_condattr_init(&attr);
pthread_cond_init(&r->cond, &attr);
pthread_condattr_destroy(&attr);
r->init = 1;
}
pthread_mutex_unlock(&initmutex);
}
void
rsleep(Rendez *r)
{
if(!r->init)
rendinit(r);
if(pthread_cond_wait(&r->cond, &r->l->mutex) != 0)
abort();
}
void
rwakeup(Rendez *r)
{
if(!r->init)
return;
if(pthread_cond_signal(&r->cond) != 0)
abort();
}
void
rwakeupall(Rendez *r)
{
if(!r->init)
return;
if(pthread_cond_broadcast(&r->cond) != 0)
abort();
}
/*
* Threads
*/
static Lock idlock;
static pthread_t *threads;
static int numthreads;
static int maxthreads;
static __thread int myid;
static __thread void *mypointer;
static int
addthreadid(void)
{
int id;
if(numthreads >= maxthreads){
maxthreads += 64;
threads = realloc(threads, maxthreads*sizeof(*threads));
}
id = numthreads++;
threads[id] = 0;
return id;
}
static pthread_t
gethandle(int id)
{
pthread_t th;
lock(&idlock);
th = threads[id];
unlock(&idlock);
return th;
}
struct ThreadArg
{
int id;
void *(*f)(void*);
void *arg;
};
static void*
trampoline(void *p)
{
struct ThreadArg *args;
void *(*f)(void*);
void *arg;
args = p;
myid = args->id;
f = args->f;
arg = args->arg;
free(args);
return f(arg);
}
int
threadcreate(void *(*f)(void*), void *arg)
{
struct ThreadArg *args;
int id;
lock(&idlock);
id = addthreadid();
args = malloc(sizeof(*args));
args->id = id;
args->f = f;
args->arg = arg;
pthread_create(&threads[id], nil, trampoline, args);
unlock(&idlock);
return id;
}
void
threadexits(void *ret)
{
pthread_exit(ret);
}
int
threadid(void)
{
return myid;
}
void**
threaddata(void)
{
return &mypointer;
}
void
threadkill(int id)
{
assert(id >= 0 && id < numthreads);
pthread_cancel(gethandle(id));
}
void
threadwait(int id)
{
pthread_join(gethandle(id), nil);
}
int
main(int argc, char *argv[])
{
int id;
id = addthreadid();
threads[id] = pthread_self();
return threadmain(argc, argv);
}
/*
* Channels
*/
Channel*
chancreate(int elemsize, int bufsize)
{
Channel *c;
c = malloc(sizeof(Channel) + bufsize*elemsize);
if(c == nil)
return nil;
memset(c, 0, sizeof(Channel));
c->elemsize = elemsize;
c->bufsize = bufsize;
c->nbuf = 0;
c->buf = (uchar*)(c+1);
c->full.l = &c->lock;
c->empty.l = &c->lock;
return c;
}
void
chanclose(Channel *c)
{
lock(&c->lock);
c->closed = 1;
rwakeupall(&c->full);
rwakeupall(&c->empty);
unlock(&c->lock);
}
void
chanfree(Channel *c)
{
// TODO: don't free chans still in use
free(c);
}
static int cansend(Channel *c) { return c->nbuf < c->bufsize; }
static int canrecv(Channel *c) { return c->nbuf > 0; }
static void
chansend_(Channel *c, void *p)
{
uchar *pp;
assert(cansend(c));
pp = c->buf + (c->off+c->nbuf)%c->bufsize * c->elemsize;
memmove(pp, p, c->elemsize);
c->nbuf++;
}
static void
chanrecv_(Channel *c, void *p)
{
uchar *pp;
assert(canrecv(c));
pp = c->buf + c->off*c->elemsize;
memmove(p, pp, c->elemsize);
c->nbuf--;
if(++c->off == c->bufsize)
c->off = 0;
}
int
chansend(Channel *c, void *p)
{
lock(&c->lock);
while(!(c->closed || cansend(c)))
rsleep(&c->full);
/* closed or can send */
if(c->closed){
/* can never send to closed chan */
unlock(&c->lock);
return -1;
}
chansend_(c, p);
rwakeup(&c->empty);
unlock(&c->lock);
return 1;
}
int
chanrecv(Channel *c, void *p)
{
lock(&c->lock);
while(!(c->closed || canrecv(c)))
rsleep(&c->empty);
/* closed or can receive */
if(canrecv(c)){
/* can still receive from closed chan */
chanrecv_(c, p);
rwakeup(&c->full);
unlock(&c->lock);
return 1;
}
unlock(&c->lock);
return -1;
}
int
channbsend(Channel *c, void *p)
{
lock(&c->lock);
if(c->closed){
/* can never send to closed chan */
unlock(&c->lock);
return -1;
}
if(cansend(c)){
chansend_(c, p);
rwakeup(&c->empty);
unlock(&c->lock);
return 1;
}
unlock(&c->lock);
return 0;
}
int
channbrecv(Channel *c, void *p)
{
lock(&c->lock);
if(canrecv(c)){
/* can still receive from closed chan */
chanrecv_(c, p);
rwakeup(&c->full);
unlock(&c->lock);
return 1;
}
if(c->closed){
unlock(&c->lock);
return -1;
}
unlock(&c->lock);
return 0;
}

60
fe6/threading.h Normal file
View File

@@ -0,0 +1,60 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#define nil NULL
typedef unsigned char uchar;
typedef unsigned int uint;
typedef struct Lock Lock;
struct Lock
{
int init;
pthread_mutex_t mutex;
};
void lock(Lock *lk);
int canlock(Lock *lk);
void unlock(Lock *lk);
typedef struct Rendez Rendez;
struct Rendez
{
int init;
Lock *l;
pthread_cond_t cond;
};
void rsleep(Rendez *r);
void rwakeup(Rendez *r);
void rwakeupall(Rendez *r);
typedef struct Channel Channel;
struct Channel
{
int bufsize;
int elemsize;
uchar *buf;
int nbuf;
int off;
int closed;
Lock lock;
Rendez full, empty;
};
Channel *chancreate(int elemsize, int bufsize);
void chanclose(Channel *chan);
void chanfree(Channel *c);
int chansend(Channel *c, void *p);
int chanrecv(Channel *c, void *p);
int channbsend(Channel *c, void *p);
int channbrecv(Channel *c, void *p);
int threadmain(int argc, char *argv[]);
int threadcreate(void *(*f)(void*), void *arg);
void threadexits(void *ret);
int threadid(void);
void **threaddata(void);
void threadkill(int id);
void threadwait(int id);

View File

@@ -2,6 +2,8 @@
#include <string.h>
#include <ctype.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <unistd.h>
#include <netdb.h>