1
0
mirror of https://github.com/aap/pdp6.git synced 2026-01-17 08:44:04 +00:00

emu: implemented Data Control (untested)

This commit is contained in:
aap 2017-10-10 21:29:30 +02:00
parent 74e046d2ae
commit a47c3c2bd4
7 changed files with 285 additions and 8 deletions

View File

@ -1,4 +1,4 @@
SRC=main.c cmd.c apr.c mem.c tty.c pt.c ../tools/pdp6common.c
SRC=main.c cmd.c apr.c mem.c tty.c pt.c dc.c ../tools/pdp6common.c
H=pdp6.h ../tools/pdp6common.h
# clang
#CFLAGS= -Wno-shift-op-parentheses -Wno-logical-op-parentheses \

View File

@ -210,6 +210,7 @@ DevDef definitions[] = {
{ TTY_IDENT, maketty },
{ PTR_IDENT, makeptr },
{ PTP_IDENT, makeptp },
{ DC_IDENT, makedc },
{ nil, nil }
};

238
emu/dc.c Normal file
View File

@ -0,0 +1,238 @@
#include "pdp6.h"
char *dc_ident = DC_IDENT;
/* table from DC1:
* bits per char ch mode shifts per char chars per word
* 6 0 0 0 6
* 12 1 0 2 3
* 18 1 1 3 2
* 36 0 1 0 1
*/
#define NSHIFT ((0x70 >> (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))
static void
recalc_dc_req(Dc136 *dc)
{
setreq(dc->bus, DC, dc->db_rq ? dc->pia : 0);
}
static void
dbdamove(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;
}
}
static void
dash_cp0(Dc136 *dc)
{
cp0:
// DASH CP0
if(dc->da_rq)
dc->data_clbd = 1;
// DASH CP1
if(DC_CCT_DONE){
dc->cct = 0;
if(dc->da_rq == 0){
dc->da_rq = 1;
if(dc->dbda_move)
dbdamove(dc);
}else
dc->da_rq = 1;
}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++;
// DASH LT
dc->da <<= 6;
goto cp0;
}
}
}
void
dcgv(Dc136 *dc, word c, int n, int rev)
{
switch(n){
case 1: case 2:
if(rev)
dc->da = (dc->da >> 6 | (c&077)<<30) & FW;
else
dc->da = (dc->da << 6 | c&077) & FW;
break;
case 3: case 4:
dc->da = (dc->da << 6 | c&077) & FW;
break;
case 5: case 6:
dc->da |= c & FW;
break;
default:
return;
}
dash_cp0(dc);
recalc_dc_req(dc);
}
word
dctk(Dc136 *dc, int n, int rev)
{
word c;
switch(n){
case 1: case 2:
if(rev){
c = dc->da & 077;
dc->da = (dc->da >> 6) & FW;
}else{
c = (dc->da >> 30) & 077;
dc->da = (dc->da << 6) & FW;
}
break;
case 3: case 4:
c = (dc->da >> 30) & 077;
dc->da = (dc->da << 6) & FW;
break;
case 5: case 6:
c = dc->da & FW;
break;
default:
return 0;
}
dash_cp0(dc);
recalc_dc_req(dc);
return c;
}
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;
}
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;
if(dc->dbda_move) bus->c12 |= F24;
if(dc->da_rq) bus->c12 |= F25;
if(dc->db_rq) bus->c12 |= F26;
if(dc->inout) bus->c12 |= F27;
bus->c12 |= (dc->ch_mode & 3) << 6;
bus->c12 |= (dc->device & 7) << 3;
bus->c12 |= dc->pia & 7;
}
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;
}
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 & 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_SET){
dc->db |= bus->c12;
dc->dbda_move = 1;
}
if(dc->dbda_move && dc->da_rq &&
!(dbda_move_old && da_rq_old))
dbdamove(dc);
recalc_dc_req(dc);
}
}
static void
dcioconnect(Device *dev, IOBus *bus)
{
Dc136 *dc;
dc = (Dc136*)dev;
dc->bus = bus;
bus->dev[DC] = (Busdev){ dc, wake_dc, 0 };
}
Device*
makedc(int argc, char *argv[])
{
Dc136 *dc;
dc = malloc(sizeof(Dc136));
memset(dc, 0, sizeof(Dc136));
dc->dev.type = dc_ident;
dc->dev.name = "";
dc->dev.attach = nil;
dc->dev.ioconnect = dcioconnect;
return &dc->dev;
}

View File

@ -3,6 +3,7 @@ mkdev apr apr166
mkdev tty tty626
mkdev ptr ptr760
mkdev ptp ptp761
mkdev dc dc136
mkdev fmem fmem162 0
mkdev cmem0 cmem161C mem_0
mkdev cmem1 cmem161C mem_1
@ -12,6 +13,7 @@ mkdev cmem3 cmem161C mem_3
ioconnect tty apr
ioconnect ptr apr
ioconnect ptp apr
ioconnect dc apr
memconnect fmem 0 apr -1
memconnect cmem0 0 apr 0
memconnect cmem1 0 apr 1

View File

@ -458,3 +458,40 @@ struct Tty
#define TTY_IDENT "tty626"
extern char *tty_ident;
Device *maketty(int argc, char *argv[]);
/* Data Control 136 */
#define DC (0200>>2)
typedef struct Dc136 Dc136;
struct Dc136
{
Device dev;
IOBus *bus;
int pia;
int device;
int ch_mode;
void *devp[8];
word da;
word db;
int cct;
int sct;
int data_clbd; /* data clobbered */
int dbda_move;
int da_rq;
int db_rq;
int inout;
/* lines between dc and devices 1/2:
* tk/gv rt
* tk/gv lt
* clr cct 1
* darq(1)
* sel 1
*/
};
#define DC_IDENT "dc136"
extern char *dc_ident;
Device *makedc(int argc, char *argv[]);
void dcgv(Dc136 *dc, word c, int n, int rev);
word dctk(Dc136 *dc, int n, int rev);

View File

@ -1,11 +1,7 @@
#include "pdp6.h"
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <poll.h>
#include <unistd.h>
/* TODO? implement motor delays */

View File

@ -38,6 +38,9 @@ reset(int fd)
struct timespec slp = { 0, 1000*1000*1000 / BAUD };
//#define SLEEP nanosleep(&slp, NULL)
#define SLEEP
void
readwrite(int ttyin, int ttyout, int ptyin, int ptyout)
{
@ -63,7 +66,7 @@ readwrite(int ttyin, int ttyout, int ptyin, int ptyout)
return;
else{
write(ttyout, &c, 1);
nanosleep(&slp, NULL);
SLEEP;
}
}
/* read from tty, write to pty */
@ -74,7 +77,7 @@ readwrite(int ttyin, int ttyout, int ptyin, int ptyout)
if(c == 035)
return;
write(ptyout, &c, 1);
nanosleep(&slp, NULL);
SLEEP;
}
}
}