1
0
mirror of https://github.com/aap/pdp6.git synced 2026-03-03 02:08:32 +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

@@ -364,7 +364,7 @@ static int char_q[] = {
static int char_r[] = {
I, U|I, U|I, U|I, U|I,
D|R|I, U|R|I, R|I, D|R|I,
D|R, D|R, D|R,
D|R, D|R, D,
0
};

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>

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>

View File

@@ -1195,8 +1195,8 @@ opline(word w, int io)
w |= 0000020000000;
w = fw(left(w), right(w)+right(y.val));
/* TODO: really warn about this? */
if(left(y.val))
err(0, "warning: address too large");
// if(left(y.val))
// err(0, "warning: address too large");
w = fw(left(w)+left(x.val), right(w)+right(x.val));
if(x.rel)
err(0, "warning: X relocation ignored");
@@ -1732,9 +1732,9 @@ checkundef(int glob)
s->type != Operator && s->type != IoOperator && s->type != Pseudo){
unsixbit(s->name, name);
if(s->type == Undef){
if(glob)
s->type |= Extern;
else
// if(glob)
// s->type |= Extern;
// else
err(1, "undefined symbol: %s\n", name);
}
}
@@ -1909,6 +1909,7 @@ main(int argc, char *argv[])
pass2 = 1;
radix = 8;
// printf("\n PASS2\n\n");
startitem(Name);

111
tools/scon33.c Normal file
View File

@@ -0,0 +1,111 @@
#define _XOPEN_SOURCE 600 /* for ptys */
#define _DEFAULT_SOURCE /* for cfmakeraw */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <poll.h>
#include <errno.h>
#include <time.h>
struct termios tiosaved;
int
raw(int fd)
{
struct termios tio;
if(tcgetattr(fd, &tio) < 0) return -1;
tiosaved = tio;
cfsetispeed(&tio, B110);
cfsetospeed(&tio, B110);
cfmakeraw(&tio);
tio.c_cflag |= CSTOPB;
if(tcsetattr(fd, TCSAFLUSH, &tio) < 0) return -1;
return 0;
}
int
reset(int fd)
{
if(tcsetattr(0, TCSAFLUSH, &tiosaved) < 0) return -1;
return 0;
}
/* tty1: unix tty
* tty2: serial port */
void
readwrite(int tty1in, int tty1out, int tty2in, int tty2out)
{
int n;
struct pollfd pfd[2];
char c;
pfd[0].fd = tty2in;
pfd[0].events = POLLIN;
pfd[1].fd = tty1in;
pfd[1].events = POLLIN;
while(pfd[0].fd != -1){
n = poll(pfd, 2, -1);
if(n < 0){
perror("error poll");
return;
}
if(n == 0)
return;
if(pfd[0].revents & POLLHUP)
return;
/* read from tty2, write to tty1 */
if(pfd[0].revents & POLLIN){
if(n = read(tty2in, &c, 1), n <= 0)
return;
else{
c &= 0177;
//if(c == '\a') c = '.';
if(c < 0140)
write(tty1out, &c, 1);
}
}
/* read from tty1, write to tty2 */
if(pfd[1].revents & POLLIN){
if(n = read(tty1in, &c, 1), n <= 0)
return;
else{
if(c == 035)
return;
/* map character reasonably */
if(c == 033) c = 0175; // esc to altmode
if(c >= 'a' && c <= 'z') // to upper
c &= ~040;
c |= 0200; // needed?
write(tty2out, &c, 1);
}
}
}
}
int
main(int argc, char *argv[])
{
int fd;
if(argc < 2)
return 1;
fd = open(argv[1], O_RDWR);
if(fd < 0)
return 1;
raw(fd);
raw(0);
readwrite(0, 1, fd, fd);
printf("\r\n\r\n");
close(fd);
reset(0);
return 0;
}

View File

@@ -155,10 +155,11 @@ module apr(
wire key_dp_OR_dp_nxt = key_dep_sync | key_dep_nxt;
wire key_run_AND_NOT_ex_OR_dep = run & ~key_ex_OR_dep_st;
wire key_ex_OR_ex_nxt = key_ex_sync | key_ex_nxt;
wire key_manual = key_ex | key_ex_nxt |
wire key_manual = ~key_pwr_clr_enbl &
(key_ex | key_ex_nxt |
key_dep | key_dep_nxt |
key_start | key_inst_cont | key_mem_cont |
key_io_reset | key_execute | key_read_in;
key_io_reset | key_execute | key_read_in);
wire key_ex_OR_dep_st = key_ex_st | key_dep_st;
wire key_run_AND_ex_OR_dep = run & key_ex_OR_dep_st;
wire key_execute_OR_dp_OR_dp_nxt = key_execute | key_dp_OR_dp_nxt;
@@ -185,6 +186,7 @@ module apr(
wire kt0a_D, kt1_D, kt2_D, kt3_D;
`ifdef simulation
wire key_pwr_clr_enbl = 0;
pg key_pg0(.clk(clk), .reset(reset), .in(sw_power), .p(mr_pwr_clr));
`else
wire sw_power_pulse;
@@ -1207,7 +1209,7 @@ module apr(
wire ar_jrst_AND_ir11 = ir_jrst & ir[11];
wire ar_flag_set = et1 & ar_jrst_AND_ir11;
wire ar_jfcl_clr = et10 & ir_jfcl;
wire ar_eq_fp_half = ar == 36'o000400000000;
wire ar_eq_fp_half = ar[9:35] == 27'o400000000;
wire ar_eq_0 = ar == 0;
wire ar0_xor_ar1 = ar[0] ^ ar[1];
wire ar_ov_set = ar_cry0 ^ ar_cry1;

404
verilog/core256k_x.v Normal file
View File

@@ -0,0 +1,404 @@
module core256k(
input wire clk,
input wire reset,
input wire power,
input wire sw_single_step,
input wire sw_restart,
input wire membus_wr_rs_p0,
input wire membus_rq_cyc_p0,
input wire membus_rd_rq_p0,
input wire membus_wr_rq_p0,
input wire [21:35] membus_ma_p0,
input wire [18:21] membus_sel_p0,
input wire membus_fmc_select_p0,
input wire [0:35] membus_mb_in_p0,
output wire membus_addr_ack_p0,
output wire membus_rd_rs_p0,
output wire [0:35] membus_mb_out_p0,
input wire membus_wr_rs_p1,
input wire membus_rq_cyc_p1,
input wire membus_rd_rq_p1,
input wire membus_wr_rq_p1,
input wire [21:35] membus_ma_p1,
input wire [18:21] membus_sel_p1,
input wire membus_fmc_select_p1,
input wire [0:35] membus_mb_in_p1,
output wire membus_addr_ack_p1,
output wire membus_rd_rs_p1,
output wire [0:35] membus_mb_out_p1,
input wire membus_wr_rs_p2,
input wire membus_rq_cyc_p2,
input wire membus_rd_rq_p2,
input wire membus_wr_rq_p2,
input wire [21:35] membus_ma_p2,
input wire [18:21] membus_sel_p2,
input wire membus_fmc_select_p2,
input wire [0:35] membus_mb_in_p2,
output wire membus_addr_ack_p2,
output wire membus_rd_rs_p2,
output wire [0:35] membus_mb_out_p2,
input wire membus_wr_rs_p3,
input wire membus_rq_cyc_p3,
input wire membus_rd_rq_p3,
input wire membus_wr_rq_p3,
input wire [21:35] membus_ma_p3,
input wire [18:21] membus_sel_p3,
input wire membus_fmc_select_p3,
input wire [0:35] membus_mb_in_p3,
output wire membus_addr_ack_p3,
output wire membus_rd_rs_p3,
output wire [0:35] membus_mb_out_p3,
// 36 bit Avalon Master
output wire [17:0] m_address,
output reg m_write,
output reg m_read,
output wire [35:0] m_writedata,
input wire [35:0] m_readdata,
input wire m_waitrequest
);
// TODO: SP
wire cmc_sp = 0;
reg [18:35] cma;
reg cma_rd_rq, cma_wr_rq;
reg [0:35] cmb;
// TODO: interleave
wire cmpc_p0_rq =
~membus_fmc_select_p0 &
membus_rq_cyc_p0 &
cmc_await_rq;
wire cmpc_p1_rq =
~membus_fmc_select_p1 &
membus_rq_cyc_p1 &
cmc_await_rq;
wire cmpc_p2_rq =
~membus_fmc_select_p2 &
membus_rq_cyc_p2 &
cmc_await_rq;
wire cmpc_p3_rq =
~membus_fmc_select_p3 &
membus_rq_cyc_p3 &
cmc_await_rq;
wire [18:35] ma_p0 = { membus_sel_p0[18:21], membus_ma_p0[22:35] };
wire [18:35] ma_p1 = { membus_sel_p1[18:21], membus_ma_p1[22:35] };
wire [18:35] ma_p2 = { membus_sel_p2[18:21], membus_ma_p2[22:35] };
wire [18:35] ma_p3 = { membus_sel_p3[18:21], membus_ma_p3[22:35] };
wire [18:35] ma_in =
{18{cmc_p0_sel}}&ma_p0 |
{18{cmc_p1_sel}}&ma_p1 |
{18{cmc_p2_sel}}&ma_p2 |
{18{cmc_p3_sel}}&ma_p3;
wire rd_rq_in =
cmc_p0_sel&membus_rd_rq_p0 |
cmc_p1_sel&membus_rd_rq_p1 |
cmc_p2_sel&membus_rd_rq_p2 |
cmc_p3_sel&membus_rd_rq_p3;
wire wr_rq_in =
cmc_p0_sel&membus_wr_rq_p0 |
cmc_p1_sel&membus_wr_rq_p1 |
cmc_p2_sel&membus_wr_rq_p2 |
cmc_p3_sel&membus_wr_rq_p3;
wire [0:35] mb_in =
{36{cmc_p0_sel}}&membus_mb_in_p0 |
{36{cmc_p1_sel}}&membus_mb_in_p1 |
{36{cmc_p2_sel}}&membus_mb_in_p2 |
{36{cmc_p3_sel}}&membus_mb_in_p3;
pa cmpc_pa0(clk, reset, cmc_t1b&cmc_p0_sel, membus_addr_ack_p0);
pa cmpc_pa1(clk, reset, cmc_t1b&cmc_p1_sel, membus_addr_ack_p1);
pa cmpc_pa2(clk, reset, cmc_t1b&cmc_p2_sel, membus_addr_ack_p2);
pa cmpc_pa3(clk, reset, cmc_t1b&cmc_p3_sel, membus_addr_ack_p3);
assign membus_rd_rs_p0 = cmc_rd_rs&cmc_p0_sel;
assign membus_rd_rs_p1 = cmc_rd_rs&cmc_p1_sel;
assign membus_rd_rs_p2 = cmc_rd_rs&cmc_p2_sel;
assign membus_rd_rs_p3 = cmc_rd_rs&cmc_p3_sel;
assign membus_mb_out_p0 = sa & {36{stb_pulse & cmc_p0_sel}};
assign membus_mb_out_p1 = sa & {36{stb_pulse & cmc_p1_sel}};
assign membus_mb_out_p2 = sa & {36{stb_pulse & cmc_p2_sel}};
assign membus_mb_out_p3 = sa & {36{stb_pulse & cmc_p3_sel}};
wire cmpc_rs_set = membus_wr_rs_p0 & cmc_p0_sel |
membus_wr_rs_p1 & cmc_p1_sel |
membus_wr_rs_p2 & cmc_p2_sel |
membus_wr_rs_p3 & cmc_p3_sel;
// TODO: this is all wrong
wire pwr_t1, pwr_t2, pwr_t3;
wire cmc_await_rq_reset, cmc_pwr_clr, cmc_pwr_start;
pg pg0(clk, reset, power, pwr_t1);
// 200ms
ldly1us dly0(clk, reset, pwr_t1, pwr_t2, cmc_await_rq_reset);
// 100μs
ldly1us dly1(clk, reset, pwr_t2, pwr_t3, cmc_pwr_clr);
pa pa0(clk, reset, pwr_t3, cmc_pwr_start);
// core control, we don't really have a use for it
reg cmc_read, cmc_write, cmc_inh;
reg cmc_rq_sync, cmc_cyc_done;
reg cmc_await_rq, cmc_pse_sync, cmc_proc_rs, cmc_stop;
reg cmc_p0_act, cmc_p1_act, cmc_p2_act, cmc_p3_act;
reg cmc_last_proc;
// TODO: SP
wire cmc_p0_sel = cmc_p0_act;
wire cmc_p1_sel = cmc_p1_act;
wire cmc_p2_sel = cmc_p2_act;
wire cmc_p3_sel = cmc_p3_act;
wire cmc_t0, cmc_t1b, cmc_t1a, cmc_t2, cmc_t3;
wire cmc_t4, cmc_t5, cmc_t6, cmc_t6p;
wire cmc_t0_D, cmc_t2_D1;
wire cmc_t3_D1, cmc_t3_D2;
wire cmc_restart;
wire cmc_start;
wire cmc_state_clr;
wire cmc_pn_act = cmc_p0_act | cmc_p1_act | cmc_p2_act | cmc_p3_act;
wire cmc_aw_rq_set = cmc_t0_D & ~cmc_pn_act;
wire cmc_rq_sync_set = cmc_t0_D & ~cmc_sp & cmc_pn_act;
wire cmc_jam_cma = cmc_t1b;
wire cmc_cmb_clr;
wire cmc_read_off;
wire cmc_pse_sync_set;
wire strobe_sense;
wire cmc_rd_rs;
wire cmpc_rs_set_D;
wire cmc_proc_rs_pulse;
pa pa1(clk, reset,
(cmpc_p0_rq | cmpc_p1_rq | cmpc_p2_rq | cmpc_p3_rq),
cmc_t0);
pa pa2(clk, reset, cmc_restart | cmc_pwr_start, cmc_start);
pa pa3(clk, reset, cmc_start | cmc_t3_D1, cmc_t5);
pa pa4(clk, reset, cmc_start | cmc_t3_D2, cmc_t6p);
pa pa5(clk, reset,
cmc_start | cmc_t3 & ~cma_wr_rq | cmc_proc_rs_pulse,
cmc_state_clr);
pa pa6(clk, reset, cmc_rq_sync&cmc_cyc_done, cmc_t1b);
pa pa7(clk, reset, cmc_t1b, cmc_t1a);
pa pa9(clk, reset,
cmc_t1b | cmc_pse_sync_set&cma_rd_rq&cma_wr_rq,
cmc_cmb_clr);
pa pa11(clk, reset, cmc_t2_D1&cma_rd_rq, strobe_sense);
pa pa12(clk, reset, stb_pulse, cmc_rd_rs);
pa pa13(clk, reset, cmc_pse_sync&(cmc_proc_rs | ~cma_wr_rq), cmc_t3);
pa pa14(clk, reset, cmc_proc_rs, cmc_proc_rs_pulse);
// probably wrong
pa pa15(clk, reset, sw_restart, cmc_restart);
dly250ns dly2(clk, reset, cmc_t6p, cmc_t6);
dly100ns dly3(clk, reset, cmc_t0, cmc_t0_D);
dly250ns dly4(clk, reset, cmc_t1a, cmc_t2);
dly200ns dly5(clk, reset, cmc_t2, cmc_read_off);
dly100ns dly6(clk, reset, rd_pulse, cmc_pse_sync_set);
// Variable 35-100ns
dly70ns dly7(clk, reset, cmc_t2, cmc_t2_D1);
dly50ns dly9(clk, reset, cmc_t3, cmc_t4);
dly500ns dly10(clk, reset, cmc_t4, cmc_t3_D1);
dly200ns dly11(clk, reset, cmc_t3_D1, cmc_t3_D2);
dly50ns dly12(clk, reset, cmpc_rs_set, cmpc_rs_set_D);
reg [0:35] sa; // "sense amplifiers"
wire [17:0] core_addr = cma[18:35];
assign m_address = core_addr;
assign m_writedata = cmb;
reg stb_sync, stb_done;
wire stb_pulse;
pa pa100(clk, reset, stb_sync&stb_done, stb_pulse);
reg rd_sync, rd_done;
wire rd_pulse;
pa pa101(clk, reset, rd_sync&rd_done, rd_pulse);
reg wr_sync, wr_done;
wire wr_pulse;
pa pa102(clk, reset, wr_sync&wr_done, wr_pulse);
always @(posedge clk or posedge reset) begin
if(reset) begin
m_read <= 0;
m_write <= 0;
sa <= 0;
stb_sync <= 0;
stb_done <= 0;
rd_sync <= 0;
rd_done <= 0;
wr_sync <= 0;
wr_done <= 0;
// value doesn't matter
cmc_last_proc <= 0;
// these should probably be reset but aren't
cmc_proc_rs <= 0;
cmc_pse_sync <= 0;
end else begin
if(m_write & ~m_waitrequest) begin
m_write <= 0;
wr_done <= 1;
end
if(m_read & ~m_waitrequest) begin
m_read <= 0;
sa <= m_readdata;
stb_done <= 1;
end
if(cmc_start)
wr_done <= 1;
if(cmc_state_clr) begin
cmc_p0_act <= 0;
cmc_p1_act <= 0;
cmc_p2_act <= 0;
cmc_p3_act <= 0;
end
if(cmpc_p0_rq | cmpc_p1_rq | cmpc_p2_rq | cmpc_p3_rq) begin
if(cmpc_p0_rq) begin
cmc_p0_act <= 1;
cmc_p1_act <= 0;
cmc_p2_act <= 0;
cmc_p3_act <= 0;
end else if(cmpc_p1_rq) begin
cmc_p0_act <= 0;
cmc_p1_act <= 1;
cmc_p2_act <= 0;
cmc_p3_act <= 0;
end else if(cmpc_p2_rq & cmpc_p3_rq) begin
cmc_p0_act <= 0;
cmc_p1_act <= 0;
cmc_p2_act <= cmc_last_proc;
cmc_p3_act <= ~cmc_last_proc;
cmc_last_proc <= ~cmc_last_proc;
end else if(cmpc_p2_rq) begin
cmc_p0_act <= 0;
cmc_p1_act <= 0;
cmc_p2_act <= 1;
cmc_p3_act <= 0;
end else if(cmpc_p3_rq) begin
cmc_p0_act <= 0;
cmc_p1_act <= 0;
cmc_p2_act <= 0;
cmc_p3_act <= 1;
end
end
if(cmc_t2) begin
if(cmc_p2_act)
cmc_last_proc <= 0;
if(cmc_p3_act)
cmc_last_proc <= 1;
end
if(cmc_t0 | cmc_await_rq_reset)
cmc_await_rq <= 0;
if(cmc_t5 | cmc_aw_rq_set)
cmc_await_rq <= 1;
if(cmc_start | cmc_pwr_clr)
cmc_rq_sync <= 0;
if(cmc_rq_sync_set | cmc_t0 & cmc_sp)
cmc_rq_sync <= 1;
if(cmc_pwr_clr)
cmc_cyc_done <= 0;
if(wr_pulse & ~cmc_stop)
cmc_cyc_done <= 1;
if(cmc_t6)
wr_sync <= 1;
if(cmc_t1b) begin
cmc_pse_sync <= 0;
cmc_proc_rs <= 0;
cmc_stop <= 0;
end
// actually through another PA
if(cmc_pse_sync_set)
cmc_pse_sync <= 1;
if(cmpc_rs_set_D)
cmc_proc_rs <= 1;
if(cmc_start)
cmc_stop <= 0;
if(cmc_t2 & sw_single_step)
cmc_stop <= 1;
if(cmc_t2) begin
cmc_rq_sync <= 0;
cmc_cyc_done <= 0;
end
if(cmc_jam_cma) begin
cma <= ma_in;
cma_rd_rq <= rd_rq_in;
cma_wr_rq <= wr_rq_in;
end
cmb <= cmb | mb_in;
if(cmc_cmb_clr)
cmb <= 0;
if(strobe_sense)
stb_sync <= 1;
if(stb_pulse) begin
stb_sync <= 0;
stb_done <= 0;
rd_done <= 1;
cmb <= cmb | sa;
end
/* Core */
if(cmc_pwr_clr | cmc_t5) begin
cmc_read <= 0;
cmc_write <= 0;
cmc_inh <= 0;
end
if(cmc_t1a) begin
cmc_read <= 1;
m_read <= cma_rd_rq;
stb_done <= 0;
rd_done <= ~cma_rd_rq;
cmc_write <= 0;
end
if(cmc_read_off) begin
cmc_read <= 0;
rd_sync <= 1;
end
if(rd_pulse) begin
rd_sync <= 0;
rd_done <= 0;
end
if(cmc_t3) begin
cmc_inh <= 1;
m_write <= cma_wr_rq;
wr_done <= ~cma_wr_rq;
end
if(cmc_t4) begin
cmc_write <= 1;
cmc_read <= 0;
end
if(wr_pulse) begin
wr_sync <= 0;
wr_done <= 0;
end
end
end
endmodule

0
verilog/core32k.v Normal file → Executable file
View File

405
verilog/core32k_x.v Normal file
View File

@@ -0,0 +1,405 @@
module core32k(
input wire clk,
input wire reset,
input wire power,
input wire sw_single_step,
input wire sw_restart,
input wire membus_wr_rs_p0,
input wire membus_rq_cyc_p0,
input wire membus_rd_rq_p0,
input wire membus_wr_rq_p0,
input wire [21:35] membus_ma_p0,
input wire [18:21] membus_sel_p0,
input wire membus_fmc_select_p0,
input wire [0:35] membus_mb_in_p0,
output wire membus_addr_ack_p0,
output wire membus_rd_rs_p0,
output wire [0:35] membus_mb_out_p0,
input wire membus_wr_rs_p1,
input wire membus_rq_cyc_p1,
input wire membus_rd_rq_p1,
input wire membus_wr_rq_p1,
input wire [21:35] membus_ma_p1,
input wire [18:21] membus_sel_p1,
input wire membus_fmc_select_p1,
input wire [0:35] membus_mb_in_p1,
output wire membus_addr_ack_p1,
output wire membus_rd_rs_p1,
output wire [0:35] membus_mb_out_p1,
input wire membus_wr_rs_p2,
input wire membus_rq_cyc_p2,
input wire membus_rd_rq_p2,
input wire membus_wr_rq_p2,
input wire [21:35] membus_ma_p2,
input wire [18:21] membus_sel_p2,
input wire membus_fmc_select_p2,
input wire [0:35] membus_mb_in_p2,
output wire membus_addr_ack_p2,
output wire membus_rd_rs_p2,
output wire [0:35] membus_mb_out_p2,
input wire membus_wr_rs_p3,
input wire membus_rq_cyc_p3,
input wire membus_rd_rq_p3,
input wire membus_wr_rq_p3,
input wire [21:35] membus_ma_p3,
input wire [18:21] membus_sel_p3,
input wire membus_fmc_select_p3,
input wire [0:35] membus_mb_in_p3,
output wire membus_addr_ack_p3,
output wire membus_rd_rs_p3,
output wire [0:35] membus_mb_out_p3,
// 36 bit Avalon Master
output wire [17:0] m_address,
output reg m_write,
output reg m_read,
output wire [35:0] m_writedata,
input wire [35:0] m_readdata,
input wire m_waitrequest
);
/* Jumpers */
parameter [3:0] memsel_p0 = 4'b0;
parameter [3:0] memsel_p1 = 4'b0;
parameter [3:0] memsel_p2 = 4'b0;
parameter [3:0] memsel_p3 = 4'b0;
// TODO: SP
wire cmc_sp = 0;
reg [21:35] cma;
reg cma_rd_rq, cma_wr_rq;
reg [0:35] cmb;
// TODO: interleave
wire cmpc_p0_rq = (membus_sel_p0[18:20] == memsel_p0[3:1]) &
~membus_fmc_select_p0 &
membus_rq_cyc_p0 &
cmc_await_rq;
wire cmpc_p1_rq = (membus_sel_p1[18:20] == memsel_p1[3:1]) &
~membus_fmc_select_p1 &
membus_rq_cyc_p1 &
cmc_await_rq;
wire cmpc_p2_rq = (membus_sel_p2[18:20] == memsel_p2[3:1]) &
~membus_fmc_select_p2 &
membus_rq_cyc_p2 &
cmc_await_rq;
wire cmpc_p3_rq = (membus_sel_p3[18:20] == memsel_p3[3:1]) &
~membus_fmc_select_p3 &
membus_rq_cyc_p3 &
cmc_await_rq;
wire [21:35] ma_in =
{15{cmc_p0_sel}}&membus_ma_p0 |
{15{cmc_p1_sel}}&membus_ma_p1 |
{15{cmc_p2_sel}}&membus_ma_p2 |
{15{cmc_p3_sel}}&membus_ma_p3;
wire rd_rq_in =
cmc_p0_sel&membus_rd_rq_p0 |
cmc_p1_sel&membus_rd_rq_p1 |
cmc_p2_sel&membus_rd_rq_p2 |
cmc_p3_sel&membus_rd_rq_p3;
wire wr_rq_in =
cmc_p0_sel&membus_wr_rq_p0 |
cmc_p1_sel&membus_wr_rq_p1 |
cmc_p2_sel&membus_wr_rq_p2 |
cmc_p3_sel&membus_wr_rq_p3;
wire [0:35] mb_in =
{36{cmc_p0_sel}}&membus_mb_in_p0 |
{36{cmc_p1_sel}}&membus_mb_in_p1 |
{36{cmc_p2_sel}}&membus_mb_in_p2 |
{36{cmc_p3_sel}}&membus_mb_in_p3;
pa cmpc_pa0(clk, reset, cmc_t1b&cmc_p0_sel, membus_addr_ack_p0);
pa cmpc_pa1(clk, reset, cmc_t1b&cmc_p1_sel, membus_addr_ack_p1);
pa cmpc_pa2(clk, reset, cmc_t1b&cmc_p2_sel, membus_addr_ack_p2);
pa cmpc_pa3(clk, reset, cmc_t1b&cmc_p3_sel, membus_addr_ack_p3);
assign membus_rd_rs_p0 = cmc_rd_rs&cmc_p0_sel;
assign membus_rd_rs_p1 = cmc_rd_rs&cmc_p1_sel;
assign membus_rd_rs_p2 = cmc_rd_rs&cmc_p2_sel;
assign membus_rd_rs_p3 = cmc_rd_rs&cmc_p3_sel;
assign membus_mb_out_p0 = sa & {36{stb_pulse & cmc_p0_sel}};
assign membus_mb_out_p1 = sa & {36{stb_pulse & cmc_p1_sel}};
assign membus_mb_out_p2 = sa & {36{stb_pulse & cmc_p2_sel}};
assign membus_mb_out_p3 = sa & {36{stb_pulse & cmc_p3_sel}};
wire cmpc_rs_set = membus_wr_rs_p0 & cmc_p0_sel |
membus_wr_rs_p1 & cmc_p1_sel |
membus_wr_rs_p2 & cmc_p2_sel |
membus_wr_rs_p3 & cmc_p3_sel;
// TODO: this is all wrong
wire pwr_t1, pwr_t2, pwr_t3;
wire cmc_await_rq_reset, cmc_pwr_clr, cmc_pwr_start;
pg pg0(clk, reset, power, pwr_t1);
// 200ms
ldly1us dly0(clk, reset, pwr_t1, pwr_t2, cmc_await_rq_reset);
// 100μs
ldly1us dly1(clk, reset, pwr_t2, pwr_t3, cmc_pwr_clr);
pa pa0(clk, reset, pwr_t3, cmc_pwr_start);
// core control, we don't really have a use for it
reg cmc_read, cmc_write, cmc_inh;
reg cmc_rq_sync, cmc_cyc_done;
reg cmc_await_rq, cmc_pse_sync, cmc_proc_rs, cmc_stop;
reg cmc_p0_act, cmc_p1_act, cmc_p2_act, cmc_p3_act;
reg cmc_last_proc;
// TODO: SP
wire cmc_p0_sel = cmc_p0_act;
wire cmc_p1_sel = cmc_p1_act;
wire cmc_p2_sel = cmc_p2_act;
wire cmc_p3_sel = cmc_p3_act;
wire cmc_t0, cmc_t1b, cmc_t1a, cmc_t2, cmc_t3;
wire cmc_t4, cmc_t5, cmc_t6, cmc_t6p;
wire cmc_t0_D, cmc_t2_D1;
wire cmc_t3_D1, cmc_t3_D2;
wire cmc_restart;
wire cmc_start;
wire cmc_state_clr;
wire cmc_pn_act = cmc_p0_act | cmc_p1_act | cmc_p2_act | cmc_p3_act;
wire cmc_aw_rq_set = cmc_t0_D & ~cmc_pn_act;
wire cmc_rq_sync_set = cmc_t0_D & ~cmc_sp & cmc_pn_act;
wire cmc_jam_cma = cmc_t1b;
wire cmc_cmb_clr;
wire cmc_read_off;
wire cmc_pse_sync_set;
wire strobe_sense;
wire cmc_rd_rs;
wire cmpc_rs_set_D;
wire cmc_proc_rs_pulse;
pa pa1(clk, reset,
(cmpc_p0_rq | cmpc_p1_rq | cmpc_p2_rq | cmpc_p3_rq),
cmc_t0);
pa pa2(clk, reset, cmc_restart | cmc_pwr_start, cmc_start);
pa pa3(clk, reset, cmc_start | cmc_t3_D1, cmc_t5);
pa pa4(clk, reset, cmc_start | cmc_t3_D2, cmc_t6p);
pa pa5(clk, reset,
cmc_start | cmc_t3 & ~cma_wr_rq | cmc_proc_rs_pulse,
cmc_state_clr);
pa pa6(clk, reset, cmc_rq_sync&cmc_cyc_done, cmc_t1b);
pa pa7(clk, reset, cmc_t1b, cmc_t1a);
pa pa9(clk, reset,
cmc_t1b | cmc_pse_sync_set&cma_rd_rq&cma_wr_rq,
cmc_cmb_clr);
pa pa11(clk, reset, cmc_t2_D1&cma_rd_rq, strobe_sense);
pa pa12(clk, reset, stb_pulse, cmc_rd_rs);
pa pa13(clk, reset, cmc_pse_sync&(cmc_proc_rs | ~cma_wr_rq), cmc_t3);
pa pa14(clk, reset, cmc_proc_rs, cmc_proc_rs_pulse);
// probably wrong
pa pa15(clk, reset, sw_restart, cmc_restart);
dly250ns dly2(clk, reset, cmc_t6p, cmc_t6);
dly100ns dly3(clk, reset, cmc_t0, cmc_t0_D);
dly250ns dly4(clk, reset, cmc_t1a, cmc_t2);
dly200ns dly5(clk, reset, cmc_t2, cmc_read_off);
dly100ns dly6(clk, reset, rd_pulse, cmc_pse_sync_set);
// Variable 35-100ns
dly70ns dly7(clk, reset, cmc_t2, cmc_t2_D1);
dly50ns dly9(clk, reset, cmc_t3, cmc_t4);
dly500ns dly10(clk, reset, cmc_t4, cmc_t3_D1);
dly200ns dly11(clk, reset, cmc_t3_D1, cmc_t3_D2);
dly50ns dly12(clk, reset, cmpc_rs_set, cmpc_rs_set_D);
reg [0:35] sa; // "sense amplifiers"
wire [14:0] core_addr = cma[21:35];
assign m_address = { 3'b0, core_addr };
assign m_writedata = cmb;
reg stb_sync, stb_done;
wire stb_pulse;
pa pa100(clk, reset, stb_sync&stb_done, stb_pulse);
reg rd_sync, rd_done;
wire rd_pulse;
pa pa101(clk, reset, rd_sync&rd_done, rd_pulse);
reg wr_sync, wr_done;
wire wr_pulse;
pa pa102(clk, reset, wr_sync&wr_done, wr_pulse);
always @(posedge clk or posedge reset) begin
if(reset) begin
m_read <= 0;
m_write <= 0;
sa <= 0;
stb_sync <= 0;
stb_done <= 0;
rd_sync <= 0;
rd_done <= 0;
wr_sync <= 0;
wr_done <= 0;
// value doesn't matter
cmc_last_proc <= 0;
// these should probably be reset but aren't
cmc_proc_rs <= 0;
cmc_pse_sync <= 0;
end else begin
if(m_write & ~m_waitrequest) begin
m_write <= 0;
wr_done <= 1;
end
if(m_read & ~m_waitrequest) begin
m_read <= 0;
sa <= m_readdata;
stb_done <= 1;
end
if(cmc_start)
wr_done <= 1;
if(cmc_state_clr) begin
cmc_p0_act <= 0;
cmc_p1_act <= 0;
cmc_p2_act <= 0;
cmc_p3_act <= 0;
end
if(cmpc_p0_rq | cmpc_p1_rq | cmpc_p2_rq | cmpc_p3_rq) begin
if(cmpc_p0_rq) begin
cmc_p0_act <= 1;
cmc_p1_act <= 0;
cmc_p2_act <= 0;
cmc_p3_act <= 0;
end else if(cmpc_p1_rq) begin
cmc_p0_act <= 0;
cmc_p1_act <= 1;
cmc_p2_act <= 0;
cmc_p3_act <= 0;
end else if(cmpc_p2_rq & cmpc_p3_rq) begin
cmc_p0_act <= 0;
cmc_p1_act <= 0;
cmc_p2_act <= cmc_last_proc;
cmc_p3_act <= ~cmc_last_proc;
cmc_last_proc <= ~cmc_last_proc;
end else if(cmpc_p2_rq) begin
cmc_p0_act <= 0;
cmc_p1_act <= 0;
cmc_p2_act <= 1;
cmc_p3_act <= 0;
end else if(cmpc_p3_rq) begin
cmc_p0_act <= 0;
cmc_p1_act <= 0;
cmc_p2_act <= 0;
cmc_p3_act <= 1;
end
end
if(cmc_t2) begin
if(cmc_p2_act)
cmc_last_proc <= 0;
if(cmc_p3_act)
cmc_last_proc <= 1;
end
if(cmc_t0 | cmc_await_rq_reset)
cmc_await_rq <= 0;
if(cmc_t5 | cmc_aw_rq_set)
cmc_await_rq <= 1;
if(cmc_start | cmc_pwr_clr)
cmc_rq_sync <= 0;
if(cmc_rq_sync_set | cmc_t0 & cmc_sp)
cmc_rq_sync <= 1;
if(cmc_pwr_clr)
cmc_cyc_done <= 0;
if(wr_pulse & ~cmc_stop)
cmc_cyc_done <= 1;
if(cmc_t6)
wr_sync <= 1;
if(cmc_t1b) begin
cmc_pse_sync <= 0;
cmc_proc_rs <= 0;
cmc_stop <= 0;
end
// actually through another PA
if(cmc_pse_sync_set)
cmc_pse_sync <= 1;
if(cmpc_rs_set_D)
cmc_proc_rs <= 1;
if(cmc_start)
cmc_stop <= 0;
if(cmc_t2 & sw_single_step)
cmc_stop <= 1;
if(cmc_t2) begin
cmc_rq_sync <= 0;
cmc_cyc_done <= 0;
end
if(cmc_jam_cma) begin
cma <= ma_in;
cma_rd_rq <= rd_rq_in;
cma_wr_rq <= wr_rq_in;
end
cmb <= cmb | mb_in;
if(cmc_cmb_clr)
cmb <= 0;
if(strobe_sense)
stb_sync <= 1;
if(stb_pulse) begin
stb_sync <= 0;
stb_done <= 0;
rd_done <= 1;
cmb <= cmb | sa;
end
/* Core */
if(cmc_pwr_clr | cmc_t5) begin
cmc_read <= 0;
cmc_write <= 0;
cmc_inh <= 0;
end
if(cmc_t1a) begin
cmc_read <= 1;
m_read <= cma_rd_rq;
stb_done <= 0;
rd_done <= ~cma_rd_rq;
cmc_write <= 0;
end
if(cmc_read_off) begin
cmc_read <= 0;
rd_sync <= 1;
end
if(rd_pulse) begin
rd_sync <= 0;
rd_done <= 0;
end
if(cmc_t3) begin
cmc_inh <= 1;
m_write <= cma_wr_rq;
wr_done <= ~cma_wr_rq;
end
if(cmc_t4) begin
cmc_write <= 1;
cmc_read <= 0;
end
if(wr_pulse) begin
wr_sync <= 0;
wr_done <= 0;
end
end
end
endmodule

View File

@@ -93,10 +93,10 @@ module core64k(
membus_rq_cyc_p3 &
cmc_await_rq;
wire ma_p0 = { membus_sel_p0[18:21], membus_ma_p0[22:35] };
wire ma_p1 = { membus_sel_p1[18:21], membus_ma_p1[22:35] };
wire ma_p2 = { membus_sel_p2[18:21], membus_ma_p2[22:35] };
wire ma_p3 = { membus_sel_p3[18:21], membus_ma_p3[22:35] };
wire [18:35] ma_p0 = { membus_sel_p0[18:21], membus_ma_p0[22:35] };
wire [18:35] ma_p1 = { membus_sel_p1[18:21], membus_ma_p1[22:35] };
wire [18:35] ma_p2 = { membus_sel_p2[18:21], membus_ma_p2[22:35] };
wire [18:35] ma_p3 = { membus_sel_p3[18:21], membus_ma_p3[22:35] };
wire [20:35] ma_in =
{16{cmc_p0_sel}}&ma_p0 |

581
verilog/dis340.v Normal file
View File

@@ -0,0 +1,581 @@
module dis340(
input wire clk,
input wire reset,
/* IO bus - 344 interface */
input wire iobus_iob_poweron,
input wire iobus_iob_reset,
input wire iobus_datao_clear,
input wire iobus_datao_set,
input wire iobus_cono_clear,
input wire iobus_cono_set,
input wire iobus_iob_fm_datai,
input wire iobus_iob_fm_status,
input wire iobus_rdi_pulse, // unused on 6
input wire [3:9] iobus_ios,
input wire [0:35] iobus_iob_in,
output wire [1:7] iobus_pi_req,
output wire [0:35] iobus_iob_out,
output wire iobus_dr_split,
output wire iobus_rdi_data, // unused on 6
/* Indicators */
output wire [0:17] br_ind,
output wire [0:6] brm_ind,
output wire [0:9] x_ind,
output wire [0:9] y_ind,
output wire [1:4] s_ind,
output wire [0:2] i_ind,
output wire [0:2] mode_ind,
output wire [0:1] sz_ind,
output wire [0:8] flags_ind,
output wire [0:4] fe_ind,
output wire [31:0] foo_ind,
/* Avalon slave */
input wire s_read,
output wire [31:0] s_readdata,
output wire fe_data_rq
);
assign iobus_dr_split = 0;
assign iobus_rdi_data = 0;
assign br_ind = br;
assign brm_ind = brm;
assign x_ind = x;
assign y_ind = y;
assign s_ind = s;
assign i_ind = i;
assign mode_ind = mode;
assign sz_ind = sz;
assign flags_ind = {
rfd, cf, 1'b0, // TODO: CONT?
stop, move, halt,
lp_flag, lp_enable, lp_find
};
/* 344 - fantasy */
wire dis_sel = iobus_ios == 7'b001_011_0;
wire dis_data_clr;
wire dis_data_set;
wire dis_ic_clr;
wire dis_ic_set;
wire iob_reset;
wire dis_datai = dis_sel & iobus_iob_fm_datai;
wire dis_status = dis_sel & iobus_iob_fm_status;
pa ptr_pa0(clk, reset, dis_sel & iobus_datao_clear, dis_data_clr);
pa ptr_pa1(clk, reset, dis_sel & iobus_datao_set, dis_data_set);
pa ptr_pa2(clk, reset, dis_sel & iobus_cono_clear | iob_reset, dis_ic_clr);
pa ptr_pa3(clk, reset, dis_sel & iobus_cono_set, dis_ic_set);
pa ptr_pa4(clk, reset, iobus_iob_reset, iob_reset);
assign iobus_iob_out =
dis_datai ? { y, 9'b0, x } :
dis_status ? { edge_flag_vert, lp_flag, edge_flag_horiz,
stop_inter, done_flag, 1'b0,
dis_pia_spec, dis_pia_data } :
36'b0;
wire dis_flag_spec = edge_flag_vert | edge_flag_horiz |
lp_flag | stop_inter;
wire dis_flag_data = done_flag;
wire [1:7] dis_req_spec = { dis_flag_spec, 7'b0 } >> dis_pia_spec;
wire [1:7] dis_req_data = { dis_flag_data, 7'b0 } >> dis_pia_data;
assign iobus_pi_req = dis_req_spec | dis_req_data;
reg [30:32] dis_pia_spec;
reg [33:35] dis_pia_data;
reg [0:35] dis_ib;
reg [0:1] dis_ibc;
always @(posedge clk) begin
if(dis_ic_clr) begin
dis_pia_spec <= 0;
dis_pia_data <= 0;
// not quite sure..
dis_ib <= 0;
dis_ibc <= 0;
end
if(dis_ic_set) begin
dis_pia_spec <= iobus_iob_in[30:32];
dis_pia_data <= iobus_iob_in[33:35];
end
if(dis_data_clr) begin
dis_ib <= 0;
dis_ibc <= 0;
end
if(dis_data_set) begin
dis_ib <= dis_ib | iobus_iob_in;
dis_ibc <= 2'b11;
end
if(shift_ib) begin
dis_ib[0:17] <= dis_ib[18:35];
dis_ibc <= { dis_ibc[1], 1'b0 };
end
end
wire done_flag = rfd & ~dis_ibc[0];
pa dpy_pa100(clk, reset, rfd & dis_ibc[0], data_sync);
// from interface (?)
wire dpy_go = dis_ic_set & iobus_iob_in[29];
wire resume = dis_ic_set & ~iobus_iob_in[29];
wire data_sync;
wire [0:17] br_input = dis_ib[0:17];
// ??
wire clr_flags = 0;
/* light pen */
wire lp_pulse = 0;
/* 340 */
`ifdef simulation
initial begin
rfd <= 0;
halt <= 0;
end
`endif
reg rfd;
reg stop;
reg halt;
reg move;
wire initiate;
wire escape_pulse;
wire rfd_pulse;
wire idp;
wire pm_pulse;
wire x_start_pulse;
wire y_start_pulse;
wire cg_end_pulse;
wire next_char;
wire stop_inter = stop & br[8];
wire [0:3] inc =
{4{s[1]}} & br[2:5] |
{4{s[2]}} & br[6:9] |
{4{s[3]}} & br[10:13] |
{4{s[4]}} & br[14:17];
wire l = (vm | vcm) & horiz_vec & br[10] |
im & inc[0] & inc[1] |
cg_l;
wire r = (vm | vcm) & horiz_vec & ~br[10] |
im & inc[0] & ~inc[1] |
cg_r;
wire d = (vm | vcm) & vert_vec & br[2] |
im & inc[2] & inc[3] |
cg_d;
wire u = (vm | vcm) & vert_vec & ~br[2] |
im & inc[2] & ~inc[3] |
cg_u;
pa dpy_pa0(clk, reset, dpy_go, initiate);
pa dpy_pa1(clk, reset,
initiate | cg_escape |
count_x & br[0] & halt |
dly1_pulse & cf,
escape_pulse);
pa dpy_pa2(clk, reset,
dly6_pulse | initiate | cg_escape |
count_x & halt |
dly1_pulse & cf & vcm | // TODO: ???
pm_pulse & ~br[7] |
next_char & s[4],
rfd_pulse);
pa dpy_pa3(clk, reset, data_sync, clr_br);
pa dpy_pa4(clk, reset, clr_br, clr_brm);
pa dpy_pa5(clk, reset, read_to_s, load_br);
wire shift_ib = load_br;
// TODO: what's RI?
pa dpy_pa7(clk, reset, idp & pm, pm_pulse);
pa dpy_pa8(clk, reset, idp & xym & ~lp_flag & br[1], y_start_pulse);
pa dpy_pa9(clk, reset, idp & xym & ~lp_flag & ~br[1], x_start_pulse);
pa dpy_pa10(clk, reset,
pm_pulse | x_start_pulse | y_start_pulse,
read_to_mode);
pa dpy_pa11(clk, reset, pm_pulse & br[11], store_scale);
pa dpy_pa12(clk, reset, pm_pulse & br[14], store_int_level);
pa dpy_pa13(clk, reset, y_start_pulse, clr_y);
pa dpy_pa14(clk, reset, x_start_pulse | cg_cr, clr_x);
pa dpy_pa15(clk, reset, idp & (im | vm | vcm), count_brm);
pa dpy_pa16(clk, reset, count_brm | cg_count, count_x);
pa dpy_pa17(clk, reset, count_brm | cg_count, count_y);
pa dpy_pa18(clk, reset, count_brm | next_char, shift_s);
pa dpy_pa6(clk, reset, cg_end_level, cg_end_pulse);
assign next_char = cg_end_pulse & cm;
wire int_dly1, int_dly2;
wire int_dly = int_dly1 | int_dly2 | cg_intens;
wire intensify =
int_dly1 & move & br[1] |
int_dly2 & br[7] |
cg_intens & cg_int;
wire dly1_pulse; // sequence delay
wire dly4_pulse; // 35 deflection delay
wire dly6_pulse; // 0.5 after xy intensify
ldly500ns intdly_1(clk, reset,
load_br | // actually through PA
dly1_pulse & ~cf & ~lp_flag & ~rfd |
next_char & ~s[4],
intdly1_pulse /* idp */, int_dly1);
dly2_8us dpy_dly3(clk, reset, clr_br, read_to_s);
dly200ns dpy_dly5(clk, reset, x_start_pulse, load_x);
dly200ns dpy_dly7(clk, reset, y_start_pulse, load_y);
`ifdef simulation
dly2_8us dpy_dly4(clk, reset,
`else
dly35us dpy_dly4(clk, reset,
`endif
x_start_pulse | y_start_pulse & br[7],
dly4_pulse);
ldly500ns intdly_2(clk, reset,
dly4_pulse | y_start_pulse & ~br[7],
intdly2_pulse /* dly6_pulse */, int_dly2);
dly1us dpy_dly1(clk, reset,
count_brm & ~halt |
resume & ~cm,
dly1_pulse);
always @(posedge clk) begin
if(clr_brm) begin
halt <= 0;
move <= 0;
end
if(count_x & im & s[4] |
dly1_pulse & vm & brm == 'o177)
halt <= 1;
if(count_x & (l|r|u|d))
move <= ~cm;
if(initiate | clr_flags)
stop <= 0;
if(pm_pulse & br[7])
stop <= 1;
if(clr_flags | clr_br)
rfd <= 0;
if(rfd_pulse)
rfd <= 1;
end
reg [0:17] br;
wire clr_br;
wire load_br;
reg [0:2] mode;
wire read_to_mode;
wire pm = mode == 3'b000;
wire xym = mode == 3'b001;
wire sm = mode == 3'b010;
wire cm = mode == 3'b011;
wire vm = mode == 3'b100;
wire vcm = mode == 3'b101;
wire im = mode == 3'b110;
reg [0:1] sz;
wire store_scale;
wire scx8 = sz == 2'b11;
wire scx4 = sz == 2'b10;
wire sc = sz[0] | sz[1];
reg [0:2] i;
wire store_int_level;
reg lp_find;
reg lp_enable;
reg lp_flag;
always @(posedge clk) begin
if(clr_br)
br <= 0;
if(load_br)
br <= br | br_input;
if(escape_pulse) begin
mode <= 0;
lp_find <= 0;
end
if(read_to_mode)
mode <= br[2:4];
if(store_int_level)
i <= br[15:17];
if(store_scale)
sz <= br[12:13];
if(initiate | resume) // initiate not in drawings
lp_enable <= 0;
if(read_to_mode & br[5])
lp_enable <= br[6];
if(initiate | clr_flags | resume)
lp_flag <= 0;
if((count_y | read_to_s) & lp_enable & lp_find)
lp_flag <= 1;
if(initiate | resume)
lp_find <= 0;
if(lp_pulse & lp_enable)
lp_find <= 1;
end
reg [0:6] brm;
wire [0:6] brm_comp;
wire clr_brm;
wire count_brm;
assign brm_comp[6] = 1;
assign brm_comp[5] = brm[6] | ~br[3]&~br[11];
assign brm_comp[4] = (&brm[5:6]) | (&(~br[3:4]))&(&(~br[11:12]));
assign brm_comp[3] = (&brm[4:6]) | (&(~br[3:5]))&(&(~br[11:13]));
assign brm_comp[2] = (&brm[3:6]) | (&(~br[3:6]))&(&(~br[11:14]));
assign brm_comp[1] = (&brm[2:6]);
assign brm_comp[0] = (&brm[1:6]);
wire horiz_vec = (|(~brm[0:6] & brm_comp[0:6] &
{ br[17], br[16], br[15], br[14], br[13], br[12], br[11] }));
wire vert_vec = (|(~brm[0:6] & brm_comp[0:6] &
{ br[9], br[8], br[7], br[6], br[5], br[4], br[3] }));
always @(posedge clk) begin
if(clr_brm)
brm <= 0;
if(count_brm)
brm <= brm ^ brm_comp;
end
reg [1:4] s;
wire clr_s = clr_brm; // not on drawings
wire shift_s;
wire read_to_s;
always @(posedge clk) begin
if(clr_s)
s <= 0;
if(read_to_s & cm)
s[2] <= 1;
if(read_to_s & im)
s[1] <= 1;
if(shift_s)
s <= { 1'b0, s[1:3] };
end
reg [0:9] x;
reg [0:9] y;
reg edge_flag_vert;
reg edge_flag_horiz;
wire clr_x, load_x, count_x;
wire clr_y, load_y, count_y;
wire clr_cf = clr_brm; // not on drawings
wire cf = edge_flag_vert | edge_flag_horiz;
wire [0:9] xyinc = 1<<sz;
wire [0:9] xinc = r ? xyinc : l ? -xyinc : 0;
wire [0:9] yinc = u ? xyinc : d ? -xyinc : 0;
wire [0:9] xsum = x + xinc;
wire [0:9] ysum = y + yinc;
always @(posedge clk) begin
if(clr_y)
y <= 0;
if(load_y)
y <= y | br[8:17];
if(count_y) begin
y <= ysum;
if((y[0] ^ ysum[0]) & (y[0] ^ yinc[0]))
edge_flag_vert <= 1;
end
if(clr_x)
x <= 0;
if(load_x)
x <= x | br[8:17];
if(count_x) begin
x <= xsum;
if((x[0] ^ xsum[0]) & (x[0] ^ xinc[0]))
edge_flag_horiz <= 1;
end
if(clr_cf | clr_flags | rfd_pulse) begin
edge_flag_vert <= 0;
edge_flag_horiz <= 0;
end
end
/* 342 char gen - fantasy */
wire cg_end_level = cg_end;
wire cg_cr;
wire cg_count;
wire cg_escape;
wire cg_intens;
wire [0:5] cg_char =
{6{s[2]}} & br[0:5] |
{6{s[3]}} & br[6:11] |
{6{s[4]}} & br[12:17];
reg cg_l;
reg cg_r;
reg cg_d;
reg cg_u;
reg cg_int;
reg cg_end;
reg cg_so;
reg [0:4] cg_pulse;
reg [31:0] rom_u [0:127];
reg [31:0] rom_d [0:127];
reg [31:0] rom_l [0:127];
reg [31:0] rom_r [0:127];
reg [31:0] rom_i [0:127];
reg [31:0] rom_end [0:127];
reg [29:0] rom_u_q, rom_d_q, rom_l_q, rom_r_q, rom_i_q, rom_end_q;
initial begin
$readmemh("roms/u.rom", rom_u);
$readmemh("roms/d.rom", rom_d);
$readmemh("roms/l.rom", rom_l);
$readmemh("roms/r.rom", rom_r);
$readmemh("roms/in.rom", rom_i);
$readmemh("roms/end.rom", rom_end);
end
always @(posedge clk) begin
rom_l_q <= rom_l[{cg_so, cg_char}];
rom_r_q <= rom_r[{cg_so, cg_char}];
rom_d_q <= rom_d[{cg_so, cg_char}];
rom_u_q <= rom_u[{cg_so, cg_char}];
rom_i_q <= rom_i[{cg_so, cg_char}];
rom_end_q <= rom_end[{cg_so, cg_char}];
end
wire cg_start;
wire cg_strobe, cg_strobe_0, cg_strobe_1;
wire cg_count_0, cg_count_1;
pa pa_cg0(clk, reset, idp & cm, cg_start);
pa pa_cg1(clk, reset, cg_start | cg_count_1, cg_strobe);
pa pa_cg2(clk, reset, cg_strobe, cg_strobe_0);
pa pa_cg6(clk, reset, cg_strobe_0, cg_strobe_1);
pa pa_cg3(clk, reset, cg_strobe_1 & ~cg_end, cg_count);
pa pa_cg4(clk, reset, cg_start & (cg_char == 6'o37), cg_escape);
pa pa_cg5(clk, reset, cg_start & (cg_char == 6'o34), cg_cr);
dly1us dly_cg0(clk, reset, cg_count, cg_count_0);
ldly500ns intdly_3(clk, reset,
cg_count_0, intdly3_pulse /* cg_count_1 */, cg_intens);
always @(posedge clk) begin
if(iob_reset | reset) begin
cg_l <= 0;
cg_r <= 0;
cg_d <= 0;
cg_u <= 0;
cg_int <= 0;
cg_end <= 0;
cg_so <= 0;
end
// TODO: figure out how shift is set
if(initiate)
cg_so <= 0;
if(cg_start) begin
cg_pulse <= 0;
cg_end <= 0; // has to be set before strobe so we can detect an edge
if(cg_char == 6'o35)
cg_so <= 0;
if(cg_char == 6'o36)
cg_so <= 1;
end
if(cg_strobe_0) begin
cg_l <= rom_l_q[cg_pulse];
cg_r <= rom_r_q[cg_pulse];
cg_d <= rom_d_q[cg_pulse];
cg_u <= rom_u_q[cg_pulse];
cg_int <= rom_i_q[cg_pulse];
cg_end <= rom_end_q[cg_pulse];
cg_pulse <= cg_pulse + 1;
end
end
/* FE interface */
assign fe_data_rq = fe_req;
// assign s_readdata = fe_data;
assign s_readdata = { fe_req, 8'b0, i, y, x };
reg fe_req;
reg fe_rs;
// reg [31:0] fe_data;
wire int_start;
wire intdly1_pulse, intdly2_pulse, intdly3_pulse;
reg intdly1_sync, intdly2_sync, intdly3_sync;
assign fe_ind = { intdly1_sync, intdly2_sync, intdly3_sync, fe_rs, fe_req };
reg [29:0] foo;
always @(posedge clk)
foo <= rom_end[{cg_so, cg_char}];
assign foo_ind = foo;
wire fe_reset = reset | iob_reset;
pa fe_pa0(clk, fe_reset, int_dly, int_start);
pa fe_pa1(clk, fe_reset, intdly1_sync & fe_rs, idp);
pa fe_pa2(clk, fe_reset, intdly2_sync & fe_rs, dly6_pulse);
pa fe_pa3(clk, fe_reset, intdly3_sync & fe_rs, cg_count_1);
always @(posedge clk) begin
if(fe_reset) begin
intdly1_sync <= 0;
intdly2_sync <= 0;
intdly3_sync <= 0;
fe_req <= 0;
fe_rs <= 0;
end else begin
if(int_start & intensify) begin
fe_req <= 1;
fe_rs <= 0;
// fe_data <= { 1'b1, 8'b0, i, y, x };
end
if(int_start & ~intensify | s_read) begin
fe_req <= 0;
fe_rs <= 1;
// fe_data <= 0;
end
if(intdly1_pulse)
intdly1_sync <= 1;
if(idp)
intdly1_sync <= 0;
if(intdly2_pulse)
intdly2_sync <= 1;
if(dly6_pulse)
intdly2_sync <= 0;
if(intdly3_pulse)
intdly3_sync <= 1;
if(cg_count_1)
intdly3_sync <= 0;
end
end
endmodule

View File

@@ -143,6 +143,45 @@ module dly450ns(input clk, input reset, input in, output p);
endmodule
module dly500ns(input clk, input reset, input in, output p);
reg [5-1:0] r;
always @(posedge clk or posedge reset) begin
if(reset)
r <= 0;
else begin
if(r)
r <= r + 5'b1;
if(in)
r <= 1;
end
end
assign p = r == 25;
endmodule
module ldly500ns(input clk, input reset, input in, output p, output reg l);
reg [5-1:0] r;
always @(posedge clk or posedge reset) begin
if(reset) begin
r <= 0;
l <= 0;
end else begin
if(r)
r <= r + 5'b1;
if(in) begin
r <= 1;
l <= 1;
end
if(p) begin
r <= 0;
l <= 0;
end
end
end
assign p = r == 25;
endmodule
module dly550ns(input clk, input reset, input in, output p);
reg [5-1:0] r;
always @(posedge clk or posedge reset) begin
@@ -276,6 +315,38 @@ module ldly2us(input clk, input reset, input in, output p, output reg l);
endmodule
module dly2_8us(input clk, input reset, input in, output p);
reg [8-1:0] r;
always @(posedge clk or posedge reset) begin
if(reset)
r <= 0;
else begin
if(r)
r <= r + 8'b1;
if(in)
r <= 1;
end
end
assign p = r == 140;
endmodule
module dly35us(input clk, input reset, input in, output p);
reg [11-1:0] r;
always @(posedge clk or posedge reset) begin
if(reset)
r <= 0;
else begin
if(r)
r <= r + 11'b1;
if(in)
r <= 1;
end
end
assign p = r == 1750;
endmodule
module dly100us(input clk, input reset, input in, output p);
reg [13-1:0] r;
always @(posedge clk or posedge reset) begin

View File

@@ -52,6 +52,12 @@ def gendlyns(ns):
nb = ceil(log(n+1,2))
print(dly.format(type='%sns' % t, width=nb, n=n))
def genldlyns(ns):
t = str(ns).replace('.', '_')
n = int(ns//clock)
nb = ceil(log(n+1,2))
print(ldly.format(type='%sns' % t, width=nb, n=n))
def gendlyus(us):
t = str(us).replace('.', '_')
n = int(us*1000//clock)
@@ -93,6 +99,8 @@ gendlyns(250)
gendlyns(300)
gendlyns(400)
gendlyns(450)
gendlyns(500)
genldlyns(500)
gendlyns(550)
gendlyns(750)
gendlyns(800)
@@ -102,6 +110,8 @@ gendlyus(1)
genldlyus(1)
genldlyus(1.5)
genldlyus(2)
gendlyus(2.8)
gendlyus(35)
gendlyus(100)
genldlyus(100)

145
verilog/iobus_4_connect.v Normal file
View File

@@ -0,0 +1,145 @@
// AUTOGEN
module iobus_4_connect(
// unused
input wire clk,
input wire reset,
// Master
input wire m_iob_poweron,
input wire m_iob_reset,
input wire m_datao_clear,
input wire m_datao_set,
input wire m_cono_clear,
input wire m_cono_set,
input wire m_iob_fm_datai,
input wire m_iob_fm_status,
input wire m_rdi_pulse,
input wire [3:9] m_ios,
input wire [0:35] m_iob_write,
output wire [1:7] m_pi_req,
output wire [0:35] m_iob_read,
output wire m_dr_split,
output wire m_rdi_data,
// Slave 0
output wire s0_iob_poweron,
output wire s0_iob_reset,
output wire s0_datao_clear,
output wire s0_datao_set,
output wire s0_cono_clear,
output wire s0_cono_set,
output wire s0_iob_fm_datai,
output wire s0_iob_fm_status,
output wire s0_rdi_pulse,
output wire [3:9] s0_ios,
output wire [0:35] s0_iob_write,
input wire [1:7] s0_pi_req,
input wire [0:35] s0_iob_read,
input wire s0_dr_split,
input wire s0_rdi_data,
// Slave 1
output wire s1_iob_poweron,
output wire s1_iob_reset,
output wire s1_datao_clear,
output wire s1_datao_set,
output wire s1_cono_clear,
output wire s1_cono_set,
output wire s1_iob_fm_datai,
output wire s1_iob_fm_status,
output wire s1_rdi_pulse,
output wire [3:9] s1_ios,
output wire [0:35] s1_iob_write,
input wire [1:7] s1_pi_req,
input wire [0:35] s1_iob_read,
input wire s1_dr_split,
input wire s1_rdi_data,
// Slave 2
output wire s2_iob_poweron,
output wire s2_iob_reset,
output wire s2_datao_clear,
output wire s2_datao_set,
output wire s2_cono_clear,
output wire s2_cono_set,
output wire s2_iob_fm_datai,
output wire s2_iob_fm_status,
output wire s2_rdi_pulse,
output wire [3:9] s2_ios,
output wire [0:35] s2_iob_write,
input wire [1:7] s2_pi_req,
input wire [0:35] s2_iob_read,
input wire s2_dr_split,
input wire s2_rdi_data,
// Slave 3
output wire s3_iob_poweron,
output wire s3_iob_reset,
output wire s3_datao_clear,
output wire s3_datao_set,
output wire s3_cono_clear,
output wire s3_cono_set,
output wire s3_iob_fm_datai,
output wire s3_iob_fm_status,
output wire s3_rdi_pulse,
output wire [3:9] s3_ios,
output wire [0:35] s3_iob_write,
input wire [1:7] s3_pi_req,
input wire [0:35] s3_iob_read,
input wire s3_dr_split,
input wire s3_rdi_data
);
assign m_pi_req = 0 | s0_pi_req | s1_pi_req | s2_pi_req | s3_pi_req;
assign m_iob_read = m_iob_write | s0_iob_read | s1_iob_read | s2_iob_read | s3_iob_read;
assign m_dr_split = 0 | s0_dr_split | s1_dr_split | s2_dr_split | s3_dr_split;
assign m_rdi_data = 0 | s0_rdi_data | s1_rdi_data | s2_rdi_data | s3_rdi_data;
assign s0_iob_poweron = m_iob_poweron;
assign s0_iob_reset = m_iob_reset;
assign s0_datao_clear = m_datao_clear;
assign s0_datao_set = m_datao_set;
assign s0_cono_clear = m_cono_clear;
assign s0_cono_set = m_cono_set;
assign s0_iob_fm_datai = m_iob_fm_datai;
assign s0_iob_fm_status = m_iob_fm_status;
assign s0_rdi_pulse = m_rdi_pulse;
assign s0_ios = m_ios;
assign s0_iob_write = m_iob_write;
assign s1_iob_poweron = m_iob_poweron;
assign s1_iob_reset = m_iob_reset;
assign s1_datao_clear = m_datao_clear;
assign s1_datao_set = m_datao_set;
assign s1_cono_clear = m_cono_clear;
assign s1_cono_set = m_cono_set;
assign s1_iob_fm_datai = m_iob_fm_datai;
assign s1_iob_fm_status = m_iob_fm_status;
assign s1_rdi_pulse = m_rdi_pulse;
assign s1_ios = m_ios;
assign s1_iob_write = m_iob_write;
assign s2_iob_poweron = m_iob_poweron;
assign s2_iob_reset = m_iob_reset;
assign s2_datao_clear = m_datao_clear;
assign s2_datao_set = m_datao_set;
assign s2_cono_clear = m_cono_clear;
assign s2_cono_set = m_cono_set;
assign s2_iob_fm_datai = m_iob_fm_datai;
assign s2_iob_fm_status = m_iob_fm_status;
assign s2_rdi_pulse = m_rdi_pulse;
assign s2_ios = m_ios;
assign s2_iob_write = m_iob_write;
assign s3_iob_poweron = m_iob_poweron;
assign s3_iob_reset = m_iob_reset;
assign s3_datao_clear = m_datao_clear;
assign s3_datao_set = m_datao_set;
assign s3_cono_clear = m_cono_clear;
assign s3_cono_set = m_cono_set;
assign s3_iob_fm_datai = m_iob_fm_datai;
assign s3_iob_fm_status = m_iob_fm_status;
assign s3_rdi_pulse = m_rdi_pulse;
assign s3_ios = m_ios;
assign s3_iob_write = m_iob_write;
endmodule

203
verilog/iobus_6_connect.v Normal file
View File

@@ -0,0 +1,203 @@
// AUTOGEN
module iobus_6_connect(
// unused
input wire clk,
input wire reset,
// Master
input wire m_iob_poweron,
input wire m_iob_reset,
input wire m_datao_clear,
input wire m_datao_set,
input wire m_cono_clear,
input wire m_cono_set,
input wire m_iob_fm_datai,
input wire m_iob_fm_status,
input wire m_rdi_pulse,
input wire [3:9] m_ios,
input wire [0:35] m_iob_write,
output wire [1:7] m_pi_req,
output wire [0:35] m_iob_read,
output wire m_dr_split,
output wire m_rdi_data,
// Slave 0
output wire s0_iob_poweron,
output wire s0_iob_reset,
output wire s0_datao_clear,
output wire s0_datao_set,
output wire s0_cono_clear,
output wire s0_cono_set,
output wire s0_iob_fm_datai,
output wire s0_iob_fm_status,
output wire s0_rdi_pulse,
output wire [3:9] s0_ios,
output wire [0:35] s0_iob_write,
input wire [1:7] s0_pi_req,
input wire [0:35] s0_iob_read,
input wire s0_dr_split,
input wire s0_rdi_data,
// Slave 1
output wire s1_iob_poweron,
output wire s1_iob_reset,
output wire s1_datao_clear,
output wire s1_datao_set,
output wire s1_cono_clear,
output wire s1_cono_set,
output wire s1_iob_fm_datai,
output wire s1_iob_fm_status,
output wire s1_rdi_pulse,
output wire [3:9] s1_ios,
output wire [0:35] s1_iob_write,
input wire [1:7] s1_pi_req,
input wire [0:35] s1_iob_read,
input wire s1_dr_split,
input wire s1_rdi_data,
// Slave 2
output wire s2_iob_poweron,
output wire s2_iob_reset,
output wire s2_datao_clear,
output wire s2_datao_set,
output wire s2_cono_clear,
output wire s2_cono_set,
output wire s2_iob_fm_datai,
output wire s2_iob_fm_status,
output wire s2_rdi_pulse,
output wire [3:9] s2_ios,
output wire [0:35] s2_iob_write,
input wire [1:7] s2_pi_req,
input wire [0:35] s2_iob_read,
input wire s2_dr_split,
input wire s2_rdi_data,
// Slave 3
output wire s3_iob_poweron,
output wire s3_iob_reset,
output wire s3_datao_clear,
output wire s3_datao_set,
output wire s3_cono_clear,
output wire s3_cono_set,
output wire s3_iob_fm_datai,
output wire s3_iob_fm_status,
output wire s3_rdi_pulse,
output wire [3:9] s3_ios,
output wire [0:35] s3_iob_write,
input wire [1:7] s3_pi_req,
input wire [0:35] s3_iob_read,
input wire s3_dr_split,
input wire s3_rdi_data,
// Slave 4
output wire s4_iob_poweron,
output wire s4_iob_reset,
output wire s4_datao_clear,
output wire s4_datao_set,
output wire s4_cono_clear,
output wire s4_cono_set,
output wire s4_iob_fm_datai,
output wire s4_iob_fm_status,
output wire s4_rdi_pulse,
output wire [3:9] s4_ios,
output wire [0:35] s4_iob_write,
input wire [1:7] s4_pi_req,
input wire [0:35] s4_iob_read,
input wire s4_dr_split,
input wire s4_rdi_data,
// Slave 5
output wire s5_iob_poweron,
output wire s5_iob_reset,
output wire s5_datao_clear,
output wire s5_datao_set,
output wire s5_cono_clear,
output wire s5_cono_set,
output wire s5_iob_fm_datai,
output wire s5_iob_fm_status,
output wire s5_rdi_pulse,
output wire [3:9] s5_ios,
output wire [0:35] s5_iob_write,
input wire [1:7] s5_pi_req,
input wire [0:35] s5_iob_read,
input wire s5_dr_split,
input wire s5_rdi_data
);
assign m_pi_req = 0 | s0_pi_req | s1_pi_req | s2_pi_req | s3_pi_req | s4_pi_req | s5_pi_req;
assign m_iob_read = m_iob_write | s0_iob_read | s1_iob_read | s2_iob_read | s3_iob_read | s4_iob_read | s5_iob_read;
assign m_dr_split = 0 | s0_dr_split | s1_dr_split | s2_dr_split | s3_dr_split | s4_dr_split | s5_dr_split;
assign m_rdi_data = 0 | s0_rdi_data | s1_rdi_data | s2_rdi_data | s3_rdi_data | s4_rdi_data | s5_rdi_data;
assign s0_iob_poweron = m_iob_poweron;
assign s0_iob_reset = m_iob_reset;
assign s0_datao_clear = m_datao_clear;
assign s0_datao_set = m_datao_set;
assign s0_cono_clear = m_cono_clear;
assign s0_cono_set = m_cono_set;
assign s0_iob_fm_datai = m_iob_fm_datai;
assign s0_iob_fm_status = m_iob_fm_status;
assign s0_rdi_pulse = m_rdi_pulse;
assign s0_ios = m_ios;
assign s0_iob_write = m_iob_write;
assign s1_iob_poweron = m_iob_poweron;
assign s1_iob_reset = m_iob_reset;
assign s1_datao_clear = m_datao_clear;
assign s1_datao_set = m_datao_set;
assign s1_cono_clear = m_cono_clear;
assign s1_cono_set = m_cono_set;
assign s1_iob_fm_datai = m_iob_fm_datai;
assign s1_iob_fm_status = m_iob_fm_status;
assign s1_rdi_pulse = m_rdi_pulse;
assign s1_ios = m_ios;
assign s1_iob_write = m_iob_write;
assign s2_iob_poweron = m_iob_poweron;
assign s2_iob_reset = m_iob_reset;
assign s2_datao_clear = m_datao_clear;
assign s2_datao_set = m_datao_set;
assign s2_cono_clear = m_cono_clear;
assign s2_cono_set = m_cono_set;
assign s2_iob_fm_datai = m_iob_fm_datai;
assign s2_iob_fm_status = m_iob_fm_status;
assign s2_rdi_pulse = m_rdi_pulse;
assign s2_ios = m_ios;
assign s2_iob_write = m_iob_write;
assign s3_iob_poweron = m_iob_poweron;
assign s3_iob_reset = m_iob_reset;
assign s3_datao_clear = m_datao_clear;
assign s3_datao_set = m_datao_set;
assign s3_cono_clear = m_cono_clear;
assign s3_cono_set = m_cono_set;
assign s3_iob_fm_datai = m_iob_fm_datai;
assign s3_iob_fm_status = m_iob_fm_status;
assign s3_rdi_pulse = m_rdi_pulse;
assign s3_ios = m_ios;
assign s3_iob_write = m_iob_write;
assign s4_iob_poweron = m_iob_poweron;
assign s4_iob_reset = m_iob_reset;
assign s4_datao_clear = m_datao_clear;
assign s4_datao_set = m_datao_set;
assign s4_cono_clear = m_cono_clear;
assign s4_cono_set = m_cono_set;
assign s4_iob_fm_datai = m_iob_fm_datai;
assign s4_iob_fm_status = m_iob_fm_status;
assign s4_rdi_pulse = m_rdi_pulse;
assign s4_ios = m_ios;
assign s4_iob_write = m_iob_write;
assign s5_iob_poweron = m_iob_poweron;
assign s5_iob_reset = m_iob_reset;
assign s5_datao_clear = m_datao_clear;
assign s5_datao_set = m_datao_set;
assign s5_cono_clear = m_cono_clear;
assign s5_cono_set = m_cono_set;
assign s5_iob_fm_datai = m_iob_fm_datai;
assign s5_iob_fm_status = m_iob_fm_status;
assign s5_rdi_pulse = m_rdi_pulse;
assign s5_ios = m_ios;
assign s5_iob_write = m_iob_write;
endmodule

80
verilog/memif_d.v Normal file
View File

@@ -0,0 +1,80 @@
module memif_d(
input wire clk,
input wire reset,
// Avalon Slave
input wire [1:0] s_address,
input wire s_write,
input wire s_read,
input wire [31:0] s_writedata,
output reg [31:0] s_readdata,
output wire s_waitrequest,
// 64 bit Avalon Master
output wire [31:0] m_address,
output reg m_write,
output reg m_read,
output wire [63:0] m_writedata,
input wire [63:0] m_readdata,
input wire m_waitrequest
);
reg [31:0] addr;
reg [63:0] word;
assign m_address = addr;
assign m_writedata = word;
wire write_edge, read_edge;
edgedet e0(clk, reset, s_write, write_edge);
edgedet e1(clk, reset, s_read, read_edge);
reg waiting;
wire req = (write_edge|read_edge) & s_address == 2'h2;
assign s_waitrequest = req | waiting;
always @(posedge clk or negedge reset) begin
if(~reset) begin
m_write <= 0;
m_read <= 0;
waiting <= 0;
addr <= 0;
word <= 0;
end else begin
if(write_edge) begin
case(s_address)
2'h0: addr <= s_writedata[31:0];
2'h1: word[31:0] <= s_writedata[31:0];
2'h2: word[63:32] <= s_writedata[31:0];
endcase
end
if(req) begin
waiting <= 1;
if(s_write)
m_write <= 1;
else if(s_read)
m_read <= 1;
end
if(m_write & ~m_waitrequest) begin
m_write <= 0;
waiting <= 0;
end
if(m_read & ~m_waitrequest) begin
m_read <= 0;
waiting <= 0;
word <= m_readdata;
end
end
end
always @(*) begin
case(s_address)
2'h1: s_readdata <= word[31:0];
2'h2: s_readdata <= word[63:32];
default: s_readdata <= 32'b0;
endcase
end
endmodule

29
verilog/memory_256k_dram.v Executable file
View File

@@ -0,0 +1,29 @@
module memory_256k(
input wire clk,
input wire reset,
// 36 bit Slave
input wire [17:0] s_address,
input wire s_write,
input wire s_read,
input wire [35:0] s_writedata,
output wire [35:0] s_readdata,
output wire s_waitrequest,
// 64 bit Avalon Master
output wire [31:0] m_address,
output wire m_write,
output wire m_read,
output wire [63:0] m_writedata,
input wire [63:0] m_readdata,
input wire m_waitrequest
);
parameter [31:0] base_addr = 32'h30000000;
assign m_address = base_addr | { s_address, 3'b0 };
assign m_write = s_write;
assign m_read = s_read;
assign m_writedata = s_writedata;
assign s_readdata = m_readdata;
assign s_waitrequest = m_waitrequest;
endmodule

View File

@@ -46,7 +46,7 @@ module panel_6(
input wire reset,
// Avalon Slave
input wire [4:0] s_address,
input wire [5:0] s_address,
input wire s_write,
input wire s_read,
input wire [31:0] s_writedata,
@@ -141,6 +141,21 @@ module panel_6(
input wire [7:0] ptp,
input wire [6:0] ptp_status, // also includes motor on
/*
* 340 display
*/
input wire [0:17] dis_br,
input wire [0:6] dis_brm,
input wire [0:9] dis_x,
input wire [0:9] dis_y,
input wire [1:4] dis_s,
input wire [0:2] dis_i,
input wire [0:2] dis_mode,
input wire [0:1] dis_sz,
input wire [0:8] dis_flags,
input wire [0:4] dis_fe,
input wire [31:0] dis_foo,
/*
* External panel
*/
@@ -159,8 +174,11 @@ module panel_6(
3'b010: leds <= tty_status;
3'b011: leds <= ptr;
3'b100: leds <= ptr_status;
3'b101: leds <= ptp;
3'b110: leds <= ptp_status;
// 3'b101: leds <= ptp;
// 3'b110: leds <= ptp_status;
3'b101: leds <= dis_fe;
3'b111: leds <= ext;
default: leds <= 0;
endcase
@@ -169,57 +187,62 @@ module panel_6(
always @(*) begin
case(s_address)
5'o00: s_readdata <=
6'o00: s_readdata <=
{ 20'b0,
power, mc_stop, run, sw_addr_stop,
key_exec, key_io_reset, key_mem_stop, key_inst_stop,
key_mem_cont, key_inst_cont, key_read_in, key_start
};
5'o01: s_readdata <= 0;
6'o01: s_readdata <= 0;
5'o02: s_readdata <=
6'o02: s_readdata <=
{ 22'b0,
sw_mem_disable, sw_repeat,
ptr_key_tape_feed, ptp_key_tape_feed,
ptr_key_start, ptr_key_stop,
key_ex_nxt, key_ex, key_dep_nxt, key_dep
};
5'o03: s_readdata <= 0;
6'o03: s_readdata <= 0;
5'o04: s_readdata <=
6'o04: s_readdata <=
{ 26'b0,
sw_split_cyc, sw_sct_maint,
sw_art3_maint, sw_repeat_bypass, sw_rim_maint,
1'b0 // spare?
};
5'o05: s_readdata <= 0;
6'o05: s_readdata <= 0;
5'o06: s_readdata <= { 14'b0, datasw[0:17] };
5'o07: s_readdata <= { 14'b0, datasw[18:35] };
5'o10: s_readdata <= { 14'b0, mas };
5'o11: s_readdata <= 0; // TODO: repeat
5'o12: s_readdata <= { 14'b0, ir };
5'o13: s_readdata <= { 14'b0, mi[0:17] };
5'o14: s_readdata <= { 14'b0, mi[18:35] };
5'o15: s_readdata <= { 14'b0, pc };
5'o16: s_readdata <= { 14'b0, ma };
5'o17: s_readdata <= { 10'b0, pih, pir, pio, pi_active };
5'o20: s_readdata <= { 14'b0, mb[0:17] };
5'o21: s_readdata <= { 14'b0, mb[18:35] };
5'o22: s_readdata <= { 14'b0, ar[0:17] };
5'o23: s_readdata <= { 14'b0, ar[18:35] };
5'o24: s_readdata <= { 14'b0, mq[0:17] };
5'o25: s_readdata <= { 14'b0, mq[18:35] };
5'o26: s_readdata <= { ff0, ff1, ff2, ff3 };
5'o27: s_readdata <= { ff4, ff5, ff6, ff7 };
5'o30: s_readdata <= { ff8, ff9, ff10, ff11 };
5'o31: s_readdata <= { ff12, ff13, 16'b0 };
5'o32: s_readdata <= { 8'b0, rla, rlr, pr };
5'o33: s_readdata <= { tty_tti, 2'b0, tty_status };
5'o34: s_readdata <= { ptp, 2'b0, ptp_status };
5'o35: s_readdata <= ptr_status;
5'o36: s_readdata <= ptr[35:18];
5'o37: s_readdata <= ptr[17:0];
6'o06: s_readdata <= { 14'b0, datasw[0:17] };
6'o07: s_readdata <= { 14'b0, datasw[18:35] };
6'o10: s_readdata <= { 14'b0, mas };
6'o11: s_readdata <= 0; // TODO: repeat
6'o12: s_readdata <= { 14'b0, ir };
6'o13: s_readdata <= { 14'b0, mi[0:17] };
6'o14: s_readdata <= { 14'b0, mi[18:35] };
6'o15: s_readdata <= { 14'b0, pc };
6'o16: s_readdata <= { 14'b0, ma };
6'o17: s_readdata <= { 10'b0, pih, pir, pio, pi_active };
6'o20: s_readdata <= { 14'b0, mb[0:17] };
6'o21: s_readdata <= { 14'b0, mb[18:35] };
6'o22: s_readdata <= { 14'b0, ar[0:17] };
6'o23: s_readdata <= { 14'b0, ar[18:35] };
6'o24: s_readdata <= { 14'b0, mq[0:17] };
6'o25: s_readdata <= { 14'b0, mq[18:35] };
6'o26: s_readdata <= { ff0, ff1, ff2, ff3 };
6'o27: s_readdata <= { ff4, ff5, ff6, ff7 };
6'o30: s_readdata <= { ff8, ff9, ff10, ff11 };
6'o31: s_readdata <= { ff12, ff13, 16'b0 };
6'o32: s_readdata <= { 8'b0, rla, rlr, pr };
6'o33: s_readdata <= { tty_tti, 2'b0, tty_status };
6'o34: s_readdata <= { ptp, 2'b0, ptp_status };
6'o35: s_readdata <= ptr_status;
6'o36: s_readdata <= ptr[35:18];
6'o37: s_readdata <= ptr[17:0];
6'o40: s_readdata <= dis_br;
6'o41: s_readdata <= { dis_brm, dis_y, dis_x };
6'o42: s_readdata <= { dis_flags, dis_s, dis_i,
dis_sz, dis_mode };
6'o43: s_readdata <= dis_foo;
default: s_readdata <= 0;
endcase
end
@@ -266,7 +289,7 @@ module panel_6(
sw_power <= ext_sw_power;
if(s_write) case(s_address)
5'o00: begin
6'o00: begin
if(s_writedata[0])
{ key_read_in, key_start } <= 2'b01;
if(s_writedata[1])
@@ -286,7 +309,7 @@ module panel_6(
if(s_writedata[8])
sw_addr_stop <= 1;
end
5'o01: begin
6'o01: begin
if(s_writedata[0] | s_writedata[1])
{ key_read_in, key_start } <= 2'b00;
if(s_writedata[2] | s_writedata[3])
@@ -298,7 +321,7 @@ module panel_6(
if(s_writedata[8])
sw_addr_stop <= 0;
end
5'o02: begin
6'o02: begin
if(s_writedata[0])
{ key_dep_nxt, key_dep } <= 2'b01;
if(s_writedata[1])
@@ -320,7 +343,7 @@ module panel_6(
if(s_writedata[9])
sw_mem_disable <= 1;
end
5'o03: begin
6'o03: begin
if(s_writedata[0] | s_writedata[1])
{ key_dep_nxt, key_dep } <= 2'b00;
if(s_writedata[2] | s_writedata[3])
@@ -334,7 +357,7 @@ module panel_6(
if(s_writedata[9])
sw_mem_disable <= 0;
end
5'o04: begin
6'o04: begin
if(s_writedata[1])
sw_rim_maint <= 1;
if(s_writedata[2])
@@ -346,7 +369,7 @@ module panel_6(
if(s_writedata[5])
sw_split_cyc <= 1;
end
5'o05: begin
6'o05: begin
if(s_writedata[1])
sw_rim_maint <= 0;
if(s_writedata[2])
@@ -358,9 +381,9 @@ module panel_6(
if(s_writedata[5])
sw_split_cyc <= 0;
end
5'o06: datasw[0:17] <= s_writedata;
5'o07: datasw[18:35] <= s_writedata;
5'o10: mas <= s_writedata;
6'o06: datasw[0:17] <= s_writedata;
6'o07: datasw[18:35] <= s_writedata;
6'o10: mas <= s_writedata;
// TODO: 11 REPEAT
endcase
end

View File

@@ -1,12 +1,15 @@
DEP=
V=../clk.v ../memory.v ../arbiter.v ../memif.v ../membusif.v ../testcore161c.v ../core161c.v \
../core164.v ../core32k.v ../fast162.v ../fast162_dp.v ../modules_50.v \
../core164.v ../core32k_x.v ../fast162.v ../fast162_dp.v ../modules_50.v \
../dly_50.v ../onchip_ram.v ../memory_16.v ../memory_16k.v ../memory_32k.v \
../panel_6.v ../fakeapr.v ../apr.v ../ptr.v ../ptp.v
../panel_6.v ../fakeapr.v ../apr.v ../ptr.v ../ptp.v ../dis340.v
tb_apr: tb_apr.v $(V) $(DEP)
iverilog -o $@ tb_apr.v $(V)
tb_dis: tb_dis.v $(V) $(DEP)
iverilog -o $@ tb_dis.v $(V)
tb_ptp: tb_ptp.v $(V) $(DEP)
iverilog -o $@ tb_ptp.v $(V)

View File

@@ -108,11 +108,28 @@ module tb_apr();
.iobus_iob_in(iobus_iob_in)
);
wire [17:0] av_address;
wire av_write;
wire av_read;
wire [35:0] av_writedata;
wire [35:0] av_readdata;
wire av_waitrequest;
memory_32k mem(
.i_clk(clk),
.i_reset_n(reset),
.i_address(av_address),
.i_write(av_write),
.i_read(av_read),
.i_writedata(av_writedata),
.o_readdata(av_readdata),
.o_waitrequest(av_waitrequest)
);
wire [0:35] membus_mb_read_0;
wire membus_addr_ack_0;
wire membus_rd_rs_0;
core161c cmem(
core32k cmem(
.clk(clk),
.reset(~reset),
.power(1'b1),
@@ -156,7 +173,14 @@ module tb_apr();
.membus_ma_p3(15'b0),
.membus_sel_p3(4'b0),
.membus_fmc_select_p3(1'b0),
.membus_mb_in_p3(36'b0)
.membus_mb_in_p3(36'b0),
.m_address(av_address),
.m_write(av_write),
.m_read(av_read),
.m_writedata(av_writedata),
.m_readdata(av_readdata),
.m_waitrequest(av_waitrequest)
);
wire [0:35] membus_mb_read_1;
@@ -216,26 +240,29 @@ module tb_apr();
$dumpvars();
for(i = 0; i < 'o40000; i = i + 1)
cmem.core[i] <= 0;
mem.ram.ram[i] <= 0;
#10;
cmem.core['o42] <= 36'o334000_000000;
cmem.core['o43] <= 36'o000000_000000;
cmem.core['o44] <= 36'o334000_000000;
cmem.core['o45] <= 36'o000000_000000;
cmem.core['o46] <= 36'o334000_000000;
cmem.core['o47] <= 36'o000000_000000;
cmem.core['o50] <= 36'o334000_000000;
cmem.core['o51] <= 36'o000000_000000;
cmem.core['o52] <= 36'o334000_000000;
cmem.core['o53] <= 36'o000000_000000;
mem.ram.ram['o42] <= 36'o334000_000000;
mem.ram.ram['o43] <= 36'o000000_000000;
mem.ram.ram['o44] <= 36'o334000_000000;
mem.ram.ram['o45] <= 36'o000000_000000;
mem.ram.ram['o46] <= 36'o334000_000000;
mem.ram.ram['o47] <= 36'o000000_000000;
mem.ram.ram['o50] <= 36'o334000_000000;
mem.ram.ram['o51] <= 36'o000000_000000;
mem.ram.ram['o52] <= 36'o334000_000000;
mem.ram.ram['o53] <= 36'o000000_000000;
cmem.core['o100] <= 36'o173040000000;
cmem.core['o101] <= 36'o254200000000;
mem.ram.ram['o100] <= 36'o202000001000;
mem.ram.ram['o101] <= 36'o254200000000;
mem.ram.ram['o1000] <= 36'o123321456654;
fmem.ff[0] <= 36'o611042323251;
fmem.ff[1] <= 36'o472340710317;
fmem.ff[2] <= 36'o545777777776;
mas <= 'o100;
#200;

183
verilog/tb/tb_dis.v Normal file
View File

@@ -0,0 +1,183 @@
`default_nettype none
`timescale 1ns/1ns
`define simulation
module tb_dis();
wire clk, reset;
clock clock(clk, reset);
reg iobus_iob_poweron = 1;
reg iobus_iob_reset = 0;
reg iobus_datao_clear = 0;
reg iobus_datao_set = 0;
reg iobus_cono_clear = 0;
reg iobus_cono_set = 0;
reg iobus_iob_fm_datai = 0;
reg iobus_iob_fm_status = 0;
reg [3:9] iobus_ios = 0;
reg [0:35] iobus_iob_in = 0;
wire [1:7] iobus_pi_req;
wire [0:35] iobus_iob_out;
reg read = 0;
dis340 dis(.clk(clk), .reset(~reset),
.iobus_iob_poweron(iobus_iob_poweron),
.iobus_iob_reset(iobus_iob_reset),
.iobus_datao_clear(iobus_datao_clear),
.iobus_datao_set(iobus_datao_set),
.iobus_cono_clear(iobus_cono_clear),
.iobus_cono_set(iobus_cono_set),
.iobus_iob_fm_datai(iobus_iob_fm_datai),
.iobus_iob_fm_status(iobus_iob_fm_status),
.iobus_ios(iobus_ios),
.iobus_iob_in(iobus_iob_in),
.iobus_pi_req(iobus_pi_req),
.iobus_iob_out(iobus_iob_out),
.s_read(read));
task cono;
input [18:35] data;
begin
iobus_iob_in <= data;
iobus_cono_clear <= 1;
#20;
iobus_cono_clear <= 0;
#20;
iobus_cono_set <= 1;
#20;
iobus_cono_set <= 0;
#20;
end
endtask
task datao;
input [0:35] data;
begin
@(posedge dis.dis_flag_data);
#600;
@(posedge clk);
iobus_iob_in <= data;
iobus_datao_clear <= 1;
#20;
iobus_datao_clear <= 0;
#20;
iobus_datao_set <= 1;
#20;
iobus_datao_set <= 0;
#20;
end
endtask
task disp;
input [0:17] word;
begin
list[i] = word;
i = i + 1;
end
endtask
reg [0:17] list[0:1000];
integer i, n;
wire [0:18] Esc = 18'o400000;
wire [0:18] Vert = 18'o200000;
wire [0:18] Iv = 18'o200000;
wire [0:18] Ixy = 18'o002000;
wire [0:18] Stop = 18'o002000;
wire [0:18] PM = 18'o000000;
wire [0:18] XYM = 18'o020000;
wire [0:18] CM = 18'o060000;
wire [0:18] VM = 18'o100000;
wire [0:18] VCM = 18'o120000;
wire [0:18] IM = 18'o140000;
initial begin
$dumpfile("dump.vcd");
$dumpvars();
for(i = 0; i < 1000; i = i + 1)
list[i] = 0;
i = 0;
/*
disp(XYM | 'o100 | 'o17);
disp(XYM | 'o77);
disp(XYM | Vert | 'o66 | Ixy);
disp(VM | Vert | 'o55 | Ixy);
disp(Esc | Iv | { 8'o100, 8'o25 });
disp(XYM | 'o160);
disp(XYM | 'o1000);
disp(IM | 'o1000 | Vert);
disp(Iv | { 4'b1000, 4'b1000, 4'b1000, 4'b1000 });
disp(Iv | { 4'b0010, 4'b0010, 4'b0010, 4'b0010 });
disp(Iv | { 4'b1100, 4'b1100, 4'b1100, 4'b1100 });
disp(Iv | { 4'b0011, 4'b0011, 4'b0011, 4'b0011 } | Esc);
disp(VCM);
disp(Esc | Iv | { 8'b1, 8'b1 });
*/
disp(XYM | 'o160 | 'o17);
disp(XYM | 'o400 | Vert);
disp(CM | 'o1000);
disp({ 6'o01, 6'o36, 6'o03 });
disp({ 6'o37, 6'o02, 6'o03 });
disp(Stop | 'o1000);
n = i;
for(i = 0; i < n; i = i + 1)
$display("list[%d] = %o", i, list[i]);
#100;
iobus_iob_reset <= 1;
#100;
iobus_iob_reset <= 0;
#100;
iobus_ios <= 7'b001_011_0;
#200;
cono(18'o100);
for(i = 0; i < n; i = i + 2)
datao({ list[i], list[i+1] });
/*
#2000;
$display("");
cono(18'o100);
for(i = 0; i < n; i = i + 2)
datao({ list[i], list[i+1] });
*/
end
initial begin
while(1) begin
// @(posedge dis.intensify);
// $display("%o %o %o", dis.i, dis.x, dis.y);
@(posedge dis.fe_data_rq);
#700;
read <= 1;
#1;
$display("0x%X, // %t", dis.s_readdata, $time);
// $display("%o %o %o", dis.i, dis.x, dis.y);
@(posedge clk);
read <= 0;
end
end
initial begin
@(posedge dis.stop);
#100;
$finish;
end
initial begin
#2000000;
$finish;
end
endmodule

59
verilog/wcsl420.v Normal file
View File

@@ -0,0 +1,59 @@
module wcsl420(
input wire clk,
input wire reset,
/* IO bus */
input wire iobus_iob_poweron,
input wire iobus_iob_reset,
input wire iobus_datao_clear,
input wire iobus_datao_set,
input wire iobus_cono_clear,
input wire iobus_cono_set,
input wire iobus_iob_fm_datai,
input wire iobus_iob_fm_status,
input wire iobus_rdi_pulse, // unused on 6
input wire [3:9] iobus_ios,
input wire [0:35] iobus_iob_in,
output wire [1:7] iobus_pi_req,
output wire [0:35] iobus_iob_out,
output wire iobus_dr_split,
output wire iobus_rdi_data, // unused on 6
/* Externals */
input wire [0:17] ctl1,
input wire [0:17] ctl2,
input wire [0:17] ctl3,
input wire [0:17] ctl4
);
assign iobus_dr_split = 0;
assign iobus_rdi_data = 0;
assign iobus_pi_req = 0;
wire wcnsls_sel = iobus_ios == 7'b100_010_0;
wire wcnsls_datai = wcnsls_sel & iobus_iob_fm_datai;
wire [0:8] ctl1n = {
ctl1[12], ctl1[13], ctl1[10]|ctl1[11],
ctl1[15], ctl1[14], 1'b0,
3'b0
};
wire [0:8] ctl2n = {
ctl2[12], ctl2[13], ctl2[10]|ctl2[11],
ctl2[15], ctl2[14], 1'b0,
3'b0
};
wire [0:8] ctl3n = {
ctl3[12], ctl3[13], ctl3[10]|ctl3[11],
ctl3[15], ctl3[14], 1'b0,
3'b0
};
wire [0:8] ctl4n = {
ctl4[12], ctl4[13], ctl4[10]|ctl4[11],
ctl4[15], ctl4[14], 1'b0,
3'b0
};
assign iobus_iob_out =
wcnsls_datai ? ~{ ctl4n, ctl3n, ctl2n, ctl1n } :
36'b0;
endmodule

36
verilog/wcsl724.v Normal file
View File

@@ -0,0 +1,36 @@
module wcsl724(
input wire clk,
input wire reset,
/* IO bus */
input wire iobus_iob_poweron,
input wire iobus_iob_reset,
input wire iobus_datao_clear,
input wire iobus_datao_set,
input wire iobus_cono_clear,
input wire iobus_cono_set,
input wire iobus_iob_fm_datai,
input wire iobus_iob_fm_status,
input wire iobus_rdi_pulse, // unused on 6
input wire [3:9] iobus_ios,
input wire [0:35] iobus_iob_in,
output wire [1:7] iobus_pi_req,
output wire [0:35] iobus_iob_out,
output wire iobus_dr_split,
output wire iobus_rdi_data, // unused on 6
/* Externals */
input wire [0:17] ctl1,
input wire [0:17] ctl2
);
assign iobus_dr_split = 0;
assign iobus_rdi_data = 0;
assign iobus_pi_req = 0;
wire wcnsls_sel = iobus_ios == 7'b111_010_1;
wire wcnsls_datai = wcnsls_sel & iobus_iob_fm_datai;
assign iobus_iob_out =
wcnsls_datai ? { ctl2, ctl1 } :
36'b0;
endmodule

32
verilog/wcsl_av.v Normal file
View File

@@ -0,0 +1,32 @@
module wcsl_av(
input wire clk,
input wire reset,
/* Avalon slave */
input wire s_write,
input wire [1:0] s_address,
input wire [31:0] s_writedata,
/* Externals */
output reg [0:17] ctl1,
output reg [0:17] ctl2,
output reg [0:17] ctl3,
output reg [0:17] ctl4
);
always @(posedge clk) begin
if(reset) begin
ctl1 <= 0;
ctl2 <= 0;
ctl3 <= 0;
ctl4 <= 0;
end else begin
if(s_write) case(s_address)
2'b00: ctl1 <= s_writedata;
2'b01: ctl2 <= s_writedata;
2'b10: ctl3 <= s_writedata;
2'b11: ctl4 <= s_writedata;
endcase
end
end
endmodule