mirror of
https://github.com/aap/pdp6.git
synced 2026-02-26 17:03:52 +00:00
emu: tweaked and fixed the DC, wrote some simple tests
This commit is contained in:
10
emu/Makefile
10
emu/Makefile
@@ -3,12 +3,14 @@ H=pdp6.h ../tools/pdp6common.h
|
||||
# clang
|
||||
#CFLAGS= -Wno-shift-op-parentheses -Wno-logical-op-parentheses \
|
||||
# -Wno-bitwise-op-parentheses
|
||||
CFLAGS= -g -Wall -Wno-parentheses -fno-diagnostics-show-caret \
|
||||
`sdl-config --cflags` `pkg-config SDL_image --cflags`
|
||||
CFLAGS= -g -Wall -Wno-parentheses -fno-diagnostics-show-caret
|
||||
SDLFLAGS=`sdl-config --cflags` `pkg-config SDL_image --cflags`
|
||||
|
||||
LIBS= `sdl-config --libs` `pkg-config SDL_image --libs` -lpthread
|
||||
LIBS=`sdl-config --libs` `pkg-config SDL_image --libs` -lpthread
|
||||
|
||||
|
||||
pdp6: $(SRC) $(H)
|
||||
$(CC) $(CFLAGS) $(SRC) $(LIBS) -o pdp6
|
||||
$(CC) -o $@ $(CFLAGS) $(SDLFLAGS) $(SRC) $(LIBS)
|
||||
|
||||
test_dc: test_dc.c dc.c $(H)
|
||||
$(CC) -o $@ $(CFLAGS) test_dc.c dc.c
|
||||
|
||||
154
emu/dc.c
154
emu/dc.c
@@ -9,13 +9,17 @@ char *dc_ident = DC_IDENT;
|
||||
* 18 1 1 3 2
|
||||
* 36 0 1 0 1
|
||||
*/
|
||||
#define NSHIFT ((0x70 >> (dc->ch_mode*2)) & 03)
|
||||
#define NSHIFT ((0xE0 >> (dc->ch_mode*2)) & 03)
|
||||
#define NCHARS ((02316 >> (dc->ch_mode*3)) & 07)
|
||||
#define DC_SCT_DONE (dc->sct == NSHIFT)
|
||||
#define DC_CCT_DONE (dc->cct == NCHARS-1)
|
||||
//#define DC_CCT_CONT (DC_SCT_DONE && !(DC_CCT_DONE))
|
||||
//#define DC_SCT_CONT (!(DC_SCT_DONE) && !(DC_CCT_DONE))
|
||||
|
||||
#define DB_JM_DA (dc->db = dc->da), dc->da = 0
|
||||
#define DA_JM_DB (dc->da = dc->db)
|
||||
#define DB_CLR dc->db = dc->db_rq = 0
|
||||
|
||||
static void
|
||||
recalc_dc_req(Dc136 *dc)
|
||||
{
|
||||
@@ -23,18 +27,38 @@ recalc_dc_req(Dc136 *dc)
|
||||
}
|
||||
|
||||
static void
|
||||
dbdamove(Dc136 *dc)
|
||||
db_da_swap(Dc136 *dc)
|
||||
{
|
||||
dc->da_rq = 0;
|
||||
dc->dbda_move = 0;
|
||||
dc->db_rq = 1;
|
||||
|
||||
if(dc->inout)
|
||||
dc->da = dc->db; // out
|
||||
else{
|
||||
dc->db = dc->da; // in
|
||||
dc->da = 0;
|
||||
}
|
||||
DA_JM_DB; // out
|
||||
else
|
||||
DB_JM_DA; // in
|
||||
}
|
||||
|
||||
/* TODO: maybe make these two a bit nicer?? */
|
||||
static void
|
||||
set_da_rq(Dc136 *dc)
|
||||
{
|
||||
int prev;
|
||||
|
||||
prev = dc->da_rq && dc->dbda_move;
|
||||
dc->da_rq = 1;
|
||||
if(!prev && dc->da_rq && dc->dbda_move)
|
||||
db_da_swap(dc);
|
||||
}
|
||||
static void
|
||||
set_dbda_move(Dc136 *dc)
|
||||
{
|
||||
int prev;
|
||||
|
||||
prev = dc->da_rq && dc->dbda_move;
|
||||
dc->dbda_move = 1;
|
||||
if(!prev && dc->da_rq && dc->dbda_move)
|
||||
db_da_swap(dc);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -45,39 +69,37 @@ cp0:
|
||||
if(dc->da_rq)
|
||||
dc->data_clbd = 1;
|
||||
|
||||
// 1ms delay
|
||||
|
||||
// DASH CP1
|
||||
if(DC_CCT_DONE){
|
||||
//printf("Full DA: %012lo\n", dc->da);
|
||||
dc->cct = 0;
|
||||
if(dc->da_rq == 0){
|
||||
dc->da_rq = 1;
|
||||
if(dc->dbda_move)
|
||||
dbdamove(dc);
|
||||
}else
|
||||
dc->da_rq = 1;
|
||||
set_da_rq(dc);
|
||||
}else if(DC_SCT_DONE){
|
||||
// CCT CONT
|
||||
dc->sct = 0;
|
||||
dc->cct = (dc->cct+1) & 7;
|
||||
}else{
|
||||
if(DC_SCT_DONE){
|
||||
// CCT CONT
|
||||
dc->cct++;
|
||||
// this shouldn't be under the !CCT_DONE branch
|
||||
// but the flow diagram FD1 does it too
|
||||
dc->sct = 0;
|
||||
}else{
|
||||
// SCT CONT
|
||||
dc->sct++;
|
||||
// SCT CONT
|
||||
dc->sct = (dc->sct+1) & 3;
|
||||
|
||||
// DASH LT
|
||||
dc->da <<= 6;
|
||||
goto cp0;
|
||||
}
|
||||
// DASH LT
|
||||
dc->da = (dc->da << 6) & FW;
|
||||
goto cp0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Give TO DC, this is the TK signal in the DC.
|
||||
* NB: for dev 5/6 give only the lower N bits. */
|
||||
void
|
||||
dcgv(Dc136 *dc, int n, word c, int rev)
|
||||
{
|
||||
//printf("DC Taking %06lo from dev %d\n", c, n);
|
||||
switch(n){
|
||||
|
||||
if(n != dc->device)
|
||||
return;
|
||||
switch(dc->device){
|
||||
case 1: case 2:
|
||||
if(rev)
|
||||
dc->da = (dc->da >> 6 | (c&077)<<30) & FW;
|
||||
@@ -97,11 +119,16 @@ dcgv(Dc136 *dc, int n, word c, int rev)
|
||||
recalc_dc_req(dc);
|
||||
}
|
||||
|
||||
/* Take FROM DC, this is the GV signal in the DC.
|
||||
* NB: for dev 5/6 read only the upper N bits. */
|
||||
word
|
||||
dctk(Dc136 *dc, int n, int rev)
|
||||
{
|
||||
word c;
|
||||
switch(n){
|
||||
|
||||
if(n != dc->device)
|
||||
return 0;
|
||||
switch(dc->device){
|
||||
case 1: case 2:
|
||||
if(rev){
|
||||
c = dc->da & 077;
|
||||
@@ -127,36 +154,38 @@ dctk(Dc136 *dc, int n, int rev)
|
||||
return c;
|
||||
}
|
||||
|
||||
static void
|
||||
ic_clr(Dc136 *dc)
|
||||
{
|
||||
DB_JM_DA;
|
||||
|
||||
dc->cct = 0;
|
||||
dc->sct = 0;
|
||||
dc->data_clbd = 0;
|
||||
dc->dbda_move = 0;
|
||||
dc->da_rq = 0;
|
||||
dc->db_rq = 0;
|
||||
dc->inout = 0;
|
||||
dc->ch_mode = 0;
|
||||
dc->device = 0;
|
||||
dc->pia = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
wake_dc(void *dev)
|
||||
{
|
||||
Dc136 *dc;
|
||||
IOBus *bus;
|
||||
int dbda_move_old, da_rq_old;
|
||||
|
||||
dc = dev;
|
||||
bus = dc->bus;
|
||||
|
||||
if(IOB_RESET){
|
||||
dc->db = 0;
|
||||
dc->da = 0;
|
||||
|
||||
dc->cct = 0;
|
||||
dc->sct = 0;
|
||||
dc->data_clbd = 0;
|
||||
dc->dbda_move = 0;
|
||||
dc->da_rq = 0;
|
||||
dc->db_rq = 0;
|
||||
dc->inout = 0;
|
||||
dc->ch_mode = 0;
|
||||
dc->device = 0;
|
||||
dc->pia = 0;
|
||||
ic_clr(dc);
|
||||
DB_CLR;
|
||||
}
|
||||
|
||||
if(bus->devcode == DC){
|
||||
dbda_move_old = dc->dbda_move;
|
||||
da_rq_old = dc->da_rq;
|
||||
|
||||
if(IOB_STATUS){
|
||||
bus->c12 |= (dc->cct&7) << 13;
|
||||
if(dc->data_clbd) bus->c12 |= F23;
|
||||
@@ -171,46 +200,27 @@ wake_dc(void *dev)
|
||||
if(IOB_DATAI){
|
||||
bus->c12 |= dc->db;
|
||||
dc->db_rq = 0;
|
||||
dc->dbda_move = 1;
|
||||
}
|
||||
if(IOB_CONO_CLEAR){
|
||||
dc->db = dc->da;
|
||||
dc->da = 0;
|
||||
|
||||
dc->cct = 0;
|
||||
dc->sct = 0;
|
||||
dc->data_clbd = 0;
|
||||
dc->dbda_move = 0;
|
||||
dc->da_rq = 0;
|
||||
dc->db_rq = 0;
|
||||
dc->inout = 0;
|
||||
dc->ch_mode = 0;
|
||||
dc->device = 0;
|
||||
dc->pia = 0;
|
||||
set_dbda_move(dc);
|
||||
}
|
||||
if(IOB_CONO_CLEAR)
|
||||
ic_clr(dc);
|
||||
if(IOB_CONO_SET){
|
||||
if(bus->c12 & F23) dc->data_clbd = 1;
|
||||
if(bus->c12 & F24) dc->dbda_move = 1;
|
||||
if(bus->c12 & F25) dc->da_rq = 1;
|
||||
if(bus->c12 & F24) set_dbda_move(dc);
|
||||
if(bus->c12 & F25) set_da_rq(dc);
|
||||
if(bus->c12 & F26) dc->db_rq = 1;
|
||||
if(bus->c12 & F27) dc->inout = 1;
|
||||
dc->ch_mode |= bus->c12>>6 & 03;
|
||||
dc->device |= bus->c12>>3 & 07;
|
||||
dc->pia |= bus->c12 & 07;
|
||||
}
|
||||
if(IOB_DATAO_CLEAR){
|
||||
dc->db = 0;
|
||||
dc->db_rq = 0;
|
||||
}
|
||||
if(IOB_DATAO_CLEAR)
|
||||
DB_CLR;
|
||||
if(IOB_DATAO_SET){
|
||||
dc->db |= bus->c12;
|
||||
dc->dbda_move = 1;
|
||||
set_dbda_move(dc);
|
||||
}
|
||||
|
||||
if(dc->dbda_move && dc->da_rq &&
|
||||
!(dbda_move_old && da_rq_old))
|
||||
dbdamove(dc);
|
||||
|
||||
recalc_dc_req(dc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ mkdev cmem1 cmem161C mem_1
|
||||
mkdev cmem2 cmem161C mem_2
|
||||
mkdev cmem3 cmem161C mem_3
|
||||
#mkdev netmem netmem its.pdp10.se 10006
|
||||
mkdev netmem netmem localhost 10006
|
||||
|
||||
connectdev dc dt0
|
||||
connectdev dt0 dx0 8
|
||||
|
||||
@@ -120,6 +120,7 @@ makenetmem(int argc, char *argv[])
|
||||
nm->fd = dial(host, port);
|
||||
if(nm->fd < 0)
|
||||
printf("couldn't connect\n");
|
||||
printf("netmem fd: %d\n", nm->fd);
|
||||
|
||||
th = (Thread){ nil, netmemcycle, nm, 50, 0 };
|
||||
addthread(th);
|
||||
|
||||
234
emu/test_dc.c
Normal file
234
emu/test_dc.c
Normal file
@@ -0,0 +1,234 @@
|
||||
#include "pdp6.h"
|
||||
|
||||
Dc136 *dc;
|
||||
IOBus iobus;
|
||||
IOBus *bus = &iobus;
|
||||
int pireq;
|
||||
|
||||
void
|
||||
setreq(IOBus *bus, int dev, u8 pia)
|
||||
{
|
||||
pireq = pia;
|
||||
}
|
||||
|
||||
void
|
||||
wakedev(IOBus *bus, int d)
|
||||
{
|
||||
Busdev *dev;
|
||||
bus->devcode = d;
|
||||
dev = &bus->dev[d];
|
||||
if(dev->wake)
|
||||
dev->wake(dev->dev);
|
||||
}
|
||||
|
||||
void
|
||||
bus_reset(IOBus *bus)
|
||||
{
|
||||
int d;
|
||||
bus->c34 |= IOBUS_IOB_RESET;
|
||||
for(d = 0; d < 128; d++)
|
||||
wakedev(bus, d);
|
||||
bus->c34 &= ~IOBUS_IOB_RESET;
|
||||
}
|
||||
|
||||
void
|
||||
cono(IOBus *bus, int d, hword w)
|
||||
{
|
||||
bus->c34 |= IOBUS_CONO_CLEAR;
|
||||
wakedev(bus, d);
|
||||
bus->c34 &= ~IOBUS_CONO_CLEAR;
|
||||
|
||||
bus->c34 |= IOBUS_CONO_SET;
|
||||
bus->c12 = w;
|
||||
wakedev(bus, d);
|
||||
bus->c34 &= ~IOBUS_CONO_SET;
|
||||
bus->c12 = 0;
|
||||
}
|
||||
|
||||
void
|
||||
datao(IOBus *bus, int d, word w)
|
||||
{
|
||||
bus->c34 |= IOBUS_DATAO_CLEAR;
|
||||
wakedev(bus, d);
|
||||
bus->c34 &= ~IOBUS_DATAO_CLEAR;
|
||||
|
||||
bus->c34 |= IOBUS_DATAO_SET;
|
||||
bus->c12 = w;
|
||||
wakedev(bus, d);
|
||||
bus->c34 &= ~IOBUS_DATAO_SET;
|
||||
bus->c12 = 0;
|
||||
}
|
||||
|
||||
word
|
||||
coni(IOBus *bus, int d)
|
||||
{
|
||||
word w;
|
||||
bus->c34 |= IOBUS_IOB_STATUS;
|
||||
wakedev(bus, d);
|
||||
bus->c34 &= ~IOBUS_IOB_STATUS;
|
||||
w = bus->c12;
|
||||
bus->c12 = 0;
|
||||
return w;
|
||||
}
|
||||
|
||||
word
|
||||
datai(IOBus *bus, int d)
|
||||
{
|
||||
word w;
|
||||
bus->c34 |= IOBUS_IOB_DATAI;
|
||||
wakedev(bus, d);
|
||||
bus->c34 &= ~IOBUS_IOB_DATAI;
|
||||
w = bus->c12;
|
||||
bus->c12 = 0;
|
||||
return w;
|
||||
}
|
||||
|
||||
void
|
||||
printdc(Dc136 *dc)
|
||||
{
|
||||
printf("DB/%012lo DA/%012lo CCT/%o SCT/%o CHMOD/%o\n",
|
||||
dc->db, dc->da, dc->cct, dc->sct, dc->ch_mode);
|
||||
printf(" CLBD/%o DBDAMOVE/%o DARQ/%o DBRQ/%o INOUT/%o DEV/%o PIA/%o\n",
|
||||
dc->data_clbd, dc->dbda_move, dc->da_rq, dc->db_rq,
|
||||
dc->inout, dc->device, dc->pia);
|
||||
}
|
||||
|
||||
enum {
|
||||
CLBD = 010000,
|
||||
|
||||
DBDAMOVE = 04000,
|
||||
DARQ = 02000,
|
||||
DBRQ = 01000,
|
||||
|
||||
IN = 0000,
|
||||
OUT = 0400,
|
||||
|
||||
CHMOD_6 = 0000,
|
||||
CHMOD_36 = 0100,
|
||||
CHMOD_12 = 0200,
|
||||
CHMOD_18 = 0300,
|
||||
|
||||
DEV1 = 010,
|
||||
DEV2 = 020,
|
||||
DEV3 = 030,
|
||||
DEV4 = 040,
|
||||
DEV5 = 050,
|
||||
DEV6 = 060,
|
||||
};
|
||||
|
||||
/*
|
||||
* output:
|
||||
* DARQ: DA empty, need new data
|
||||
* DBRQ: DB empty, need new data
|
||||
* DBDA MOVE: DB waiting to send data to DA
|
||||
* input:
|
||||
* DARQ: DA full, need to empty
|
||||
* DBRQ: DB full, need to empty
|
||||
* DBDA MOVE: DB waiting to get data from DA
|
||||
*/
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
dc = (Dc136*)makedc(0, nil);
|
||||
dc->dev.ioconnect((Device*)dc, bus);
|
||||
|
||||
bus_reset(bus);
|
||||
assert(coni(bus, DC) == 0);
|
||||
|
||||
// output test
|
||||
cono(bus, DC, DARQ|DBRQ|OUT|CHMOD_6|DEV1|7); // 3417
|
||||
assert(pireq == 7);
|
||||
printdc(dc);
|
||||
datao(bus, DC, 0123456000001);
|
||||
assert(pireq == 7);
|
||||
printdc(dc);
|
||||
datao(bus, DC, 0123456000002);
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
assert(dctk(dc, 1, 0) == 012);
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
assert(dctk(dc, 1, 0) == 034);
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
assert(dctk(dc, 1, 0) == 056);
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
assert(dctk(dc, 1, 0) == 000);
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
assert(dctk(dc, 1, 0) == 000);
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
assert(dctk(dc, 1, 0) == 001);
|
||||
assert(pireq == 7);
|
||||
printdc(dc);
|
||||
|
||||
printf("\n\n");
|
||||
|
||||
cono(bus, DC, DARQ|DBRQ|OUT|CHMOD_12|DEV5|7); // 3657
|
||||
assert(pireq == 7);
|
||||
printdc(dc);
|
||||
datao(bus, DC, 0123456112233);
|
||||
assert(pireq == 7);
|
||||
printdc(dc);
|
||||
datao(bus, DC, 0123456445566);
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
assert((dctk(dc, 5, 0)&0777700000000) == 0123400000000);
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
assert((dctk(dc, 5, 0)&0777700000000) == 0561100000000);
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
assert((dctk(dc, 5, 0)&0777700000000) == 0223300000000);
|
||||
assert(pireq == 7);
|
||||
printdc(dc);
|
||||
|
||||
printf("\n\n");
|
||||
|
||||
// input test
|
||||
cono(bus, DC, DBDAMOVE|IN|CHMOD_6|DEV1|7); // 4017
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
dcgv(dc, 1, 012, 0);
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
dcgv(dc, 1, 034, 0);
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
dcgv(dc, 1, 056, 0);
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
dcgv(dc, 1, 011, 0);
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
dcgv(dc, 1, 022, 0);
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
dcgv(dc, 1, 033, 0);
|
||||
assert(pireq == 7);
|
||||
printdc(dc);
|
||||
assert(datai(bus, DC) == 0123456112233);
|
||||
printdc(dc);
|
||||
|
||||
|
||||
printf("\n\n");
|
||||
|
||||
|
||||
cono(bus, DC, DBDAMOVE|IN|CHMOD_12|DEV5|7); // 4017
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
dcgv(dc, 5, 01234, 0);
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
dcgv(dc, 5, 05611, 0);
|
||||
assert(pireq == 0);
|
||||
printdc(dc);
|
||||
dcgv(dc, 5, 02233, 0);
|
||||
assert(pireq == 7);
|
||||
printdc(dc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user