1
0
mirror of https://github.com/aap/pdp6.git synced 2026-02-27 01:10:14 +00:00

committing old stuff

This commit is contained in:
aap
2018-02-07 01:37:09 +01:00
parent a47c3c2bd4
commit 88875b87ce
17 changed files with 920 additions and 18 deletions

View File

@@ -1,8 +1,11 @@
test.rim: main.rel tty.rel pt.rel
ld6 -o test.rim main.rel tty.rel pt.rel
test.rim: main.rel tty.rel pt.rel dt.rel
ld6 -o test.rim main.rel tty.rel pt.rel dt.rel
test.sav: main.rel tty.rel pt.rel
ld6 -f sav -o test.sav main.rel tty.rel pt.rel
test.sav: main.rel tty.rel pt.rel dt.rel
ld6 -f sav -o test.sav main.rel tty.rel pt.rel dt.rel
dtboot.rim: dtboot.rel
ld6 -o dtboot.rim dtboot.rel
%.rel: %.s
as6 -o $@ $<

65
code/bootstrap.txt Normal file
View File

@@ -0,0 +1,65 @@
PAPER TAPE RIM LOADER (AT 20):
LOC 20
CONO PTR,60 ; 710600 000060
A: CONSO PTR,10 ; 710740 000010
JRST .-1 ; 254000 000021
DATAI PTR,B ; 710440 000026
CONSO PTR,10 ; 710740 000010
JRST .-1 ; 254000 000024
B: 0 ; 000000 000000
JRST A ; 254000 000021
DECTAPE RIM LOADER AT 0 (SHADOW) 014 INSTRUCTIONS
MY DECTAPE LOADER:
CONO DC,4010 ; 720200 004010
CONO UTC,220300 ; 721200 220300
MOVE 17,12 ; 200740 000012
CONSO DC,1000 ; 720340 001000
JRST .-1 ; 254000 000003
BLKI DC,17 ; 720000 000017
JRST DONE ; 254000 000010
JRST .-1 ; 254000 000003
DONE: CONO DC,0 ; 720200 000000
HALT 300 ; 254200 000300
777600000277 ; 777600 000277
PDP-10 RIM10 LOADER:
003110' R1BLDR:
000000 PHASE 0
003110' 777762 000000 IOWD $ADR,$ST
003111' 710600 000060 $ST: CONO PTR,60
003112' 541400 000004 HRRI $A,$RD+1
003113' 710740 000010 $RD: CONSO PTR,10
003114' 254000 000003 JRST .-1
003115' 710470 000007 DATAI PTR,@$TBL1-$RD+1($A)
003116' 256010 000007 XCT $TBL1-$RD+1($A)
003117' 256010 000012 XCT $TBL2-$RD+1($A)
003120' 364400 000000 $A: SOJA $A,
003121' 312740 000016 $TBL1: CAME $CKSM,$ADR
003122' 270756 000001 ADD $CKSM,1($ADR)
003123' 331740 000016 SKIPL $CKSM,$ADR
003124' 254200 000001 $TBL2: JRST 4,$ST
003125' 253700 000003 AOBJN $ADR,$RD
003126' 254000 000002 $ADR: JRST $ST+1
000017 $CKSM:
003127' DEPHASE
MAC DECtape RIM loader:
000000 JFCL
000001 MOVSI (JFCL)
000002 CONO 635550
000003 CONO PI,11577
000004 CONO UTC,223110
000005 CONO DC,4010
000006 CONSO DC,1000
000007 JRST 6
000010 DATAI DC,13
000011 AOJGE 13,6
000012 TRNE 13,-1
000013 .
000014 JRST 6

23
code/dtboot.s Normal file
View File

@@ -0,0 +1,23 @@
DC==200
UTC==210
UTS==214
DACI==04010
SL==220000
RD==300
LOC 0
ENTRY:
CONO DC,DACI
CONO UTC,SL+RD
MOVE 17,[ IOWD 200,300 ]
CONSO DC,1000
JRST .-1
BLKI DC,17
JRST DONE
JRST .-4
DONE: CONO DC,0
HALT 300
END ENTRY

View File

@@ -10,7 +10,9 @@ PTP==100
EXTERN PUTC,PUTS
EXTERN GETCH,GETC
EXTERN PUTN
EXTERN PTPUT
EXTERN DTTEST
ENTRY: JRST START
@@ -19,16 +21,30 @@ SP: XWD -100,PDL-1
START: MOVE PDP,SP
;; NUMBER TEST
; MOVE AC1,[-1234]
; PUSHJ PDP,PUTN
; MOVE AC1,[1234]
; PUSHJ PDP,PUTN
;; DECTAPE TEST
JRST DTTEST
;; UUO TEST
; UUO1 123
;; ENABLE CLOCK PI ON CHANNEL 1
; CONO CPA,2001
;; ENABLE PI ON CHANNEL 1
; CONO PRS,2300
; JRST .
;; WRITE MESSAGE TO TTY
MOVSI AC2,440700
HRRI AC2,MSG
PUSHJ PDP,PUTS
;; WRITE FROM TTY TO PTP
PUSHJ PDP,GETC
; CONO PTP,20
PUSHJ PDP,PTPUT

View File

@@ -7,6 +7,7 @@ PDP==17
INTERNAL PUTC,PUTS
; PRINT CHAR IN AC1 ON TTY
PUTC:
CONSZ TTY,20 ; wait until not busy
JRST .-1
@@ -31,6 +32,7 @@ PUTS:
INTERNAL GETCH,GETC
; READ CHAR FROM TTY INTO AC1
GETCH:
CONSO TTY,40 ; wait for flag
JRST .-1
@@ -42,3 +44,24 @@ GETC:
PUSHJ PDP,GETCH
PUSHJ PDP,PUTC
POPJ PDP,
BASE: 10
DIGITS: EXP "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
; PRINT NUMBER IN AC!
INTERNAL PUTN
PUTN:
JUMPGE AC1,UPUTN
PUSH PDP,AC1
MOVEI AC1, "-"
PUSHJ PDP,PUTC
POP PDP,AC1
MOVM AC1,AC1
UPUTN:
IDIV AC1,BASE
JUMPE AC1,UPR1
PUSH PDP,AC2
PUSHJ PDP,UPUTN
POP PDP,AC2
UPR1:
MOVE AC1,DIGITS(AC2)
JRST PUTC

View File

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

View File

@@ -211,6 +211,8 @@ DevDef definitions[] = {
{ PTR_IDENT, makeptr },
{ PTP_IDENT, makeptp },
{ DC_IDENT, makedc },
{ DT_IDENT, makedt },
{ DX_IDENT, makedx },
{ nil, nil }
};
@@ -318,6 +320,44 @@ c_memconnect(int argc, char *argv[])
attachmem((Mem*)dev, proc, &((Apr*)busdev)->membus, addr);
}
/* devconnect dev1 dev2 */
// TODO: not quite sure this is the right way to do it
static void
c_devconnect(int argc, char *argv[])
{
Device *dev1, *dev2;
if(argc < 3){
args:
printf("Not enough arguments\n");
return;
}
dev1 = getdevice(argv[1]);
if(dev1 == nil){
printf("No device: %s\n", argv[1]);
return;
}
dev2 = getdevice(argv[2]);
if(dev2 == nil){
printf("No device: %s\n", argv[2]);
return;
}
if(dev1->type == dc_ident && dev2->type == dt_ident)
dtconn((Dc136*)dev1, (Dt551*)dev2);
else if(dev1->type == dt_ident && dev2->type == dx_ident){
int n;
if(argc < 4)
goto args;
n = atoi(argv[3]);
if(n < 1 || n > 8){
printf("Invalid device number %d\n", n);
return;
}
dxconn((Dt551*)dev1, (Dx555*)dev2, n);
}else
printf("Cannot connect %s to %s\n", dev2->type, dev1->type);
}
static void
c_ex(int argc, char *argv[])
{
@@ -423,6 +463,8 @@ c_load(int argc, char *argv[])
static void
c_show(int argc, char *argv[])
{
printf("Devices:\n");
showdevices();
printf("Memory:\n");
showmem(&apr->membus);
}
@@ -441,6 +483,7 @@ struct {
{ "attach", c_attach },
{ "ioconnect", c_ioconnect },
{ "memconnect", c_memconnect },
{ "devconnect", c_devconnect },
{ "examine", c_ex },
{ "deposit", c_dep },
{ "load", c_load },

18
emu/cmds.txt Normal file
View File

@@ -0,0 +1,18 @@
mkdev name type
creates a device and gives it a name
attach name path
attaches a file to a device
ioconnect name busdevname
connects a device to the IO bus of a processor
memconnect name procnum busdevname addr
connects a memory module to the memory bus of a processor
examine [-sm] address(range)
examines memory (s: shadow mode, m: mnemonic)
deposit [-sm] address(range) word
deposits word into memory (s: shadow mode, m: mnemonic)
load filename
loads file into memory (see source for which format)
show
shows device configuration
quit
take a guess

View File

@@ -47,6 +47,7 @@ cp0:
// 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;
@@ -73,8 +74,9 @@ cp0:
}
void
dcgv(Dc136 *dc, word c, int n, int rev)
dcgv(Dc136 *dc, int n, word c, int rev)
{
//printf("DC Taking %06lo from dev %d\n", c, n);
switch(n){
case 1: case 2:
if(rev)
@@ -121,6 +123,7 @@ dctk(Dc136 *dc, int n, int rev)
}
dash_cp0(dc);
recalc_dc_req(dc);
//printf("DC Giving %06lo to dev %d\n", c, n);
return c;
}

577
emu/dt.c Normal file
View File

@@ -0,0 +1,577 @@
#include "pdp6.h"
#include <fcntl.h>
#include <unistd.h>
char *dt_ident = DT_IDENT;
char *dx_ident = DX_IDENT;
// TODO: find out how this should be controlled
#define DEVNO 1
enum
{
DTSIZE = 922512
};
/* Transport */
static uchar
dxread(Dx555 *dx)
{
if(dx->dt->ut_rev)
return *dx->cur ^ 010;
else
return *dx->cur;
}
static void
dxwrite(Dx555 *dx, uchar d)
{
if(dx->dt->ut_rev)
*dx->cur = d ^ 010;
else
*dx->cur = d;
}
static void
dxmove(Dx555 *dx)
{
// At end of tape read the last word forever
if(dx->dt->ut_rev){
dx->cur--;
if(dx->cur < dx->start)
dx->cur = dx->start+5;
}else{
dx->cur++;
if(dx->cur >= dx->end)
dx->cur = dx->end-6;
}
}
static void
dxattach(Device *dev, const char *path)
{
Dx555 *dx;
int fd;
dx = (Dx555*)dev;
fd = dx->fd;
if(fd >= 0){
dx->fd = -1;
close(dx->fd);
}
memset(dx->start, 0, DTSIZE);
dx->fd = open(path, O_RDWR | O_CREAT, 0666);
if(dx->fd < 0)
fprintf(stderr, "couldn't open file %s\n", path);
else
read(dx->fd, dx->start, DTSIZE);
}
/* Connect a transport to a control */
void
dxconn(Dt551 *dt, Dx555 *dx, int n)
{
dt->dx[n%8] = dx;
dx->dt = dt;
dx->unit = n;
}
Device*
makedx(int argc, char *argv[])
{
Dx555 *dx;
dx = malloc(sizeof(Dx555));
memset(dx, 0, sizeof(Dx555));
dx->dev.type = dx_ident;
dx->dev.name = "";
dx->dev.attach = dxattach;
dx->dev.ioconnect = nil;
dx->start = malloc(DTSIZE);
dx->cur = dx->start;
dx->end = dx->start + DTSIZE;
memset(dx->start, 0, DTSIZE);
return &dx->dev;
}
/* Control */
enum
{
TapeEndF = 022,
TapeEndR = 055,
BlockSpace = 025,
BlockEndF = 026,
BlockEndR = 045,
DataSync = 032, /* rev guard */
BlockSync = 051, /* guard */
DataEndF = 073, /* pre-final, final, ck, rev lock */
DataEndR = 010, /* lock, rev ck, rev final, rev pre-final */
Data = 070,
RW_NULL = 0,
RW_RQ = 1,
RW_ACTIVE = 2,
};
#define DATA_SYNC (dt->tmk == (0600|DataSync))
#define END_ZONE (dt->tmk == (0600|TapeEndF))
#define BM_SPACE (dt->tmk == (0400|BlockSpace) ||\
dt->tmk == (0500|BlockSpace) ||\
dt->tmk == (0600|BlockSpace) ||\
dt->tmk == (0700|BlockSpace))
#define BM_END (dt->tmk == (0500|BlockEndF))
#define DATA_SYNC (dt->tmk == (0600|DataSync))
#define BM_SYNC (dt->tmk == (0700|BlockSync))
#define FWD_DATA_END (dt->tmk == (0400|DataEndF) ||\
dt->tmk == (0700|DataEndF))
#define REV_DATA_END (dt->tmk == (0400|DataEndR) ||\
dt->tmk == (0600|DataEndR))
#define DATA (dt->tmk == (0400|Data))
#define STOP (dt->tdata == 0 || dt->tdata == 1)
#define SYNC (dt->tdata == 0200)
#define REV_CKS (dt->tdata == 0100)
#define BLOCK (dt->tdata == 040 || dt->tdata == 020 || dt->tdata == 010)
#define PRE_FINAL (dt->tdata == 004)
#define FWD_CKS (dt->tdata == 002)
#define UT_WRITE ((dt->ut_fcn & 04) == 04)
#define UT_READ ((dt->ut_fcn & 04) == 0)
#define UT_ALL ((dt->ut_fcn & 03) == 01)
#define UT_BM ((dt->ut_fcn & 03) == 02)
#define UT_DATA ((dt->ut_fcn & 03) == 03)
#define UT_DN (dt->ut_fcn == 0)
#define UT_WRTM (dt->ut_fcn == 04)
#define DC_SELECT1 (dt->dc->devp[dt->dc->device] == dt)
#define UTE_DC_DISCONNECT (!(DC_SELECT1 && !dt->dc->da_rq))
#define UT_WRITE_PREVENT (dt->seldx->wrlock)
#define UT_WREN_DATA (UT_WRITE && dt->ut_wren && !UT_WRITE_PREVENT)
#define RW_ODD (!dt->tct && dt->rw_state == RW_ACTIVE)
#define RW_BM_DONE (UT_BM && BM_END)
#define RW_DATA_CONT (DC_SELECT1 && !dt->dc->da_rq && UT_DATA && dt->rw_state == RW_ACTIVE)
#define RW_DATA_STOP (UTE_DC_DISCONNECT && UT_DATA && dt->rw_state == RW_ACTIVE)
#define TBM0 (dt->tbm == 10)
#define TBM3 (dt->tbm == 1)
// all but block space
#define UTE_MK (DATA_SYNC || END_ZONE || BM_END ||\
DATA_SYNC || BM_SYNC || FWD_DATA_END || REV_DATA_END || DATA)
#define UTE_ERROR (dt->uteck && (dt->utek == 040) != UTE_MK)
// not sure if BM SYNC || DATA SYNC is correct
#define UTE_ACTIVE_ERROR (!UT_ALL && dt->rw_state == RW_ACTIVE && (BM_SYNC || DATA_SYNC))
#define PRINT1 \
printf("%c%02o(%o,%02o,%d)", dt->rw_state == RW_ACTIVE ? '+' : dt->rw_state == RW_RQ ? '-' : ' ', \
dt->tmk&077, l&07, dt->rwb, dt->tct); \
putchar(' '); \
if(STOP) \
printf(" [STOP] "); \
else if(SYNC) \
printf(" [SYNC] "); \
else if(REV_CKS) \
printf(" [REV_CKS] "); \
else if(BLOCK) \
printf(" [BLOCK] "); \
else if(PRE_FINAL) \
printf(" [PRE FINAL] "); \
else if(FWD_CKS) \
printf(" [FWD CKS %02o] ", dt->lb);
#define PRINT2 \
if(END_ZONE) \
printf("TapeEndF "); \
else if(BM_SPACE) \
printf("BlockSpace %o ", dt->tbm); \
else if(BM_END) \
printf("BlockEndF "); \
else if(DATA_SYNC) \
printf("DataSync "); \
else if(BM_SYNC) \
printf("BlockSync "); \
else if(FWD_DATA_END) \
printf("DataEndF "); \
else if(REV_DATA_END) \
printf("DataEndR "); \
else if(DATA) \
printf("Data ");
static void
recalc_dt_req(Dt551 *dt)
{
int req;
if(dt->ut_jb_done_flag && dt->ut_jb_done_enable ||
dt->ut_tape_end_flag && dt->ut_tape_end_enable ||
dt->time_flag && dt->time_enable ||
dt->ut_info_error ||
dt->ut_illegal_op)
req = dt->ut_pia;
else
req = 0;
setreq(dt->bus, UTC, req);
}
static void
dtcycle(void *p)
{
Dt551 *dt;
dt = (Dt551*)p;
uchar l, wb;
int data1edge, data7edge;
int bm0edge, bm3edge;
// TODO: maybe do something else here?
if(dt->seldx == nil)
return;
if(!dt->ut_go)
return;
if(dt->rw_state != RW_ACTIVE)
dt->tct = 0;
l = dxread(dt->seldx);
/* TP0 */
if(dt->rw_state == RW_ACTIVE)
dt->ut_wren = 1;
if(UT_WRITE){
if(UT_WRITE_PREVENT)
dt->ut_illegal_op = 1;
if(dt->tct)
wb = l&010 | dt->rwb&07;
else
wb = l&010 | dt->rwb>>3 & 07;
}
if(UT_WREN_DATA)
dxwrite(dt->seldx, wb);
/* TP1 */
//**/ PRINT1
//**/ PRINT2
dt->tmk = ((dt->tmk << 1) | !!(l&010)) & 0377 |
dt->tmk&0400 | (dt->tmk<<1)&0400;
if(UT_READ){
if(dt->tct != dt->ut_rev)
dt->rwb |= l&07;
else
dt->rwb |= (l&07) << 3;
}
/* TP2 */
///**/ printf("%2o%c%c%c ", dt->utek, UTE_MK ? 'M' : ' ', UTE_ERROR ? 'E' : ' ', dt->uteck ? 'C' : ' ');
if(UTE_ERROR || UTE_ACTIVE_ERROR)
printf("UT INFO ERROR\n"),
dt->ut_info_error = 1;
if(!BM_SPACE){
if(dt->utek == 1)
dt->utek = 040;
else
dt->utek >>= 1;
}
if(dt->tct)
dt->lb ^= ~dt->rwb & 077;
//**/ if(dt->rw_state == RW_ACTIVE && dt->tct)
//**/ printf("(%02o, %02o) ", dt->rwb, dt->lb);
if(UT_READ && dt->rw_state == RW_ACTIVE && dt->tct){
// before tct complement
if(!(UT_DATA && dt->tdata & 0102)){
dcgv(dt->dc, DEVNO, dt->rwb, dt->ut_rev);
if(UTE_DC_DISCONNECT)
dt->ut_incomp_block = 1;
}
}
if(END_ZONE){
dt->ut_tape_end_flag = 1;
dt->ut_go = 0;
}
bm0edge = 0;
bm3edge = 0;
if(BM_SYNC)
dt->tbm |= 020; // shifted to 010 (TBM0) now
if(BM_SPACE || BM_SYNC){
dt->tbm >>= 1;
if(TBM0)
bm0edge = 1;
else if(TBM3)
bm3edge = 1;
}
data1edge = 0; // goes up before rev checksum is expected
data7edge = 0; // goes up when checksum is seen
if(DATA_SYNC)
dt->tdata |= 0400; // shifted to 0200 now
if(FWD_DATA_END || REV_DATA_END || DATA_SYNC){
dt->tdata >>= 1;
if(dt->tdata == 0100)
data1edge = 1;
else if(dt->tdata == 1)
data7edge = 1;
}
if(data1edge)
dt->lb = 0;
// TODO: not sure about rw_active
if(data7edge && dt->rw_state == RW_ACTIVE)
if(dt->lb != 077)
printf("UT INFO ERROR\n"),
dt->ut_info_error = 1;
// before active is set below
if(dt->rw_state == RW_ACTIVE)
dt->tct = !dt->tct;
// manual mentions tdata6(0) going to 0???
if(dt->rw_state == RW_ACTIVE){
if(data7edge && RW_DATA_STOP ||
RW_BM_DONE){
printf("FINISHING JOB\n");
dt->ut_jb_done_flag = 1;
dt->rw_state = RW_NULL;
}
if(UTE_ACTIVE_ERROR)
dt->rw_state = RW_NULL;
if(data7edge && RW_DATA_CONT)
dt->rw_state = RW_RQ;
}else if(dt->rw_state == RW_RQ){
if(UT_BM && bm3edge ||
UT_DATA && data1edge ||
UT_ALL && bm0edge)
dt->rw_state = RW_ACTIVE;
}
/* TP3 */
if(RW_ODD)
dt->rwb = 0;
if(TBM3 && BM_SPACE)
dt->utek = 040;
if(BM_SYNC)
dt->uteck = 0;
if(TBM3 && !BM_SPACE)
dt->uteck = 1;
/* TP4 */
if(UT_WRITE && RW_ODD){
/* Take checksum data from LB */
if(UT_DATA && dt->tdata & 0102)
dt->rwb = dt->lb;
else{
dt->rwb |= dctk(dt->dc, DEVNO, dt->ut_rev);
if(UTE_DC_DISCONNECT)
dt->ut_incomp_block = 1;
}
if(dt->ut_rev)
dt->rwb = dt->rwb>>3 & 07 | dt->rwb<<3 & 070;
}
if(dt->rw_state == RW_ACTIVE)
dt->ut_wren = 0;
//**/ printf("\n");
dxmove(dt->seldx);
recalc_dt_req(dt);
}
static void
wake_dt(void *dev)
{
Dt551 *dt;
IOBus *bus;
dt = (Dt551*)dev;
bus = dt->bus;
if(IOB_RESET){
dt->ut_incomp_block = 0;
dt->ut_pia = 0;
dt->ut_units = 0;
dt->ut_units_select = 0;
dt->ut_fcn = 0;
dt->ut_time = 0;
dt->ut_wren = 0;
dt->ut_go = 0;
dt->ut_rev = 0;
dt->ut_tape_end_flag = 0;
dt->ut_tape_end_enable = 0;
dt->ut_jb_done_flag = 0;
dt->ut_jb_done_enable = 0;
dt->time_enable = 0;
dt->time_flag = 0;
dt->ut_illegal_op = 0;
dt->ut_info_error = 0;
dt->tmk = 0;
dt->rwb = 0;
dt->tbm = 0;
dt->tdata = 0;
dt->utek = 0;
dt->uteck = 0;
dt->rw_state = RW_NULL;
}
if(bus->devcode == UTS){
if(IOB_STATUS){
//printf("UTS STATUS\n");
// we have no delays (yet?) F25
if(dt->rw_state == RW_RQ) bus->c12 |= F26;
if(dt->rw_state == RW_ACTIVE) bus->c12 |= F27;
if(dt->rw_state == RW_NULL) bus->c12 |= F28;
if(dt->ut_incomp_block) bus->c12 |= F29;
if(dt->ut_wren) bus->c12 |= F30;
if(dt->time_flag) bus->c12 |= F31;
if(dt->ut_info_error) bus->c12 |= F32;
if(dt->ut_illegal_op) bus->c12 |= F33;
if(dt->ut_tape_end_flag) bus->c12 |= F34;
if(dt->ut_jb_done_flag) bus->c12 |= F35;
}
}
if(bus->devcode == UTC){
if(IOB_STATUS){
//printf("UTC STATUS\n");
if(dt->ut_units_select) bus->c12 |= F19;
if(dt->ut_tape_end_enable) bus->c12 |= F20;
if(dt->ut_jb_done_enable) bus->c12 |= F21;
if(dt->ut_go) bus->c12 |= F22;
if(dt->ut_rev) bus->c12 |= F23;
if(dt->time_enable) bus->c12 |= F24;
bus->c12 |= (dt->ut_time & 03) << 9;
bus->c12 |= (dt->ut_fcn & 07) << 6;
bus->c12 |= (dt->ut_units & 07) << 3;
bus->c12 |= dt->ut_pia & 07;
}
if(IOB_CONO_CLEAR){
//printf("UTC CONO CLEAR\n");
dt->ut_incomp_block = 0;
dt->ut_wren = 0;
dt->time_flag = 0;
dt->ut_info_error = 0;
dt->ut_illegal_op = 0;
dt->ut_tape_end_flag = 0;
dt->ut_jb_done_flag = 0;
dt->rw_state = RW_NULL;
}
if(IOB_CONO_SET){
//printf("UTC CONO SET\n");
int i, n, nunits;
dt->ut_pia = bus->c12 & 07;
dt->ut_units = bus->c12>>3 & 07;
dt->ut_fcn = bus->c12>>6 & 07;
dt->ut_time = bus->c12>>9 & 03;
dt->time_enable = bus->c12>>11 & 1;
dt->ut_rev = bus->c12>>12 & 1;
dt->ut_go = bus->c12>>13 & 1;
dt->ut_jb_done_enable = bus->c12>>14 & 1;
dt->ut_tape_end_enable = bus->c12>>15 & 1;
dt->ut_units_select = bus->c12>>16 & 1;
// UT CONO SET LONG
// triggers UT START level until end of delay
// find selected transport unit
n = dt->ut_units == 0 ? 8 : dt->ut_units;
dt->seldx = nil;
nunits = 0;
if(dt->ut_units_select)
for(i = 0; i < 8; i++)
if(dt->dx[i] && dt->dx[i]->unit == n){
dt->seldx = dt->dx[i];
nunits++;
}
if(dt->ut_time){
// wait delay
dt->time_flag = 1;
dt->uteck = 0;
if(nunits != 1){
dt->ut_go = 0;
dt->ut_illegal_op = 1;
goto ret;
}
if(dt->ut_btm_switch != UT_WRTM)
dt->ut_illegal_op = 1;
}
if(!UT_DN){
if(UT_WRTM)
dt->rw_state = RW_ACTIVE;
else
dt->rw_state = RW_RQ;
}
}
}
ret:
recalc_dt_req(dt);
}
static void
dtioconnect(Device *dev, IOBus *bus)
{
Dt551 *dt;
dt = (Dt551*)dev;
dt->bus = bus;
bus->dev[UTC] = (Busdev){ dt, wake_dt, 0 };
bus->dev[UTS] = (Busdev){ dt, wake_dt, 0 };
}
/* Connect a dt control to a data control */
void
dtconn(Dc136 *dc, Dt551 *dt)
{
dt->dc = dc;
dc->devp[DEVNO] = dt;
}
Device*
makedt(int argc, char *argv[])
{
Dt551 *dt;
Thread th;
dt = malloc(sizeof(Dt551));
memset(dt, 0, sizeof(Dt551));
dt->dev.type = dt_ident;
dt->dev.name = "";
dt->dev.attach = nil;
dt->dev.ioconnect = dtioconnect;
// should have 30000 cycles per second
th = (Thread){ nil, dtcycle, dt, 1000, 0 };
addthread(th);
return &dt->dev;
}

View File

@@ -4,16 +4,21 @@ mkdev tty tty626
mkdev ptr ptr760
mkdev ptp ptp761
mkdev dc dc136
mkdev dt0 dt551
mkdev dx0 dx555
mkdev fmem fmem162 0
mkdev cmem0 cmem161C mem_0
mkdev cmem1 cmem161C mem_1
mkdev cmem2 cmem161C mem_2
mkdev cmem3 cmem161C mem_3
devconnect dc dt0
devconnect dt0 dx0 8
ioconnect tty apr
ioconnect ptr apr
ioconnect ptp apr
ioconnect dc apr
ioconnect dt0 apr
memconnect fmem 0 apr -1
memconnect cmem0 0 apr 0
memconnect cmem1 0 apr 1
@@ -23,3 +28,4 @@ memconnect cmem3 0 apr 3
attach tty /tmp/6tty
attach ptr ../code/test.rim
attach ptp ../code/ptp.out
attach dx0 ../test/out.dt6

View File

@@ -597,7 +597,7 @@ getdevice(const char *name)
}
void
printdevices(void)
showdevices(void)
{
Device *dev;
for(dev = devlist; dev; dev = dev->next)
@@ -762,8 +762,6 @@ main(int argc, char *argv[])
ptr = (Ptr*)getdevice("ptr");
ptp = (Ptp*)getdevice("ptp");
printdevices();
pthread_create(&sim_thread, nil, simthread, apr);
pthread_create(&cmd_thread, nil, cmdthread, nil);

View File

@@ -242,8 +242,7 @@ makecoremem(const char *file)
core = malloc(sizeof(CMem));
memset(core, 0, sizeof(CMem));
core->filename = file;
core->filename = strdup(file);
mem = malloc(sizeof(Mem));
mem->dev.type = cmem_ident;
mem->dev.name = "";

24
emu/mem_0 Normal file
View File

@@ -0,0 +1,24 @@
720200004010
721200220300
200740000012
720340001000
254000000003
720000000017
254000000010
254000000003
720200000000
254200000300
777600000277
0
0
0
0
0
710600000060
710740000010
254000000021
710440000026
710740000010
254000000024
0
254000000021

View File

@@ -90,7 +90,6 @@ struct Thread
extern Thread *threads;
void addthread(Thread th);
/* not used yet */
typedef struct Device Device;
struct Device
{
@@ -106,6 +105,7 @@ struct Device
extern Device *devlist;
void adddevice(Device *dev);
Device *getdevice(const char *name);
void showdevices(void);
/*
@@ -493,5 +493,98 @@ struct Dc136
#define DC_IDENT "dc136"
extern char *dc_ident;
Device *makedc(int argc, char *argv[]);
void dcgv(Dc136 *dc, word c, int n, int rev);
void dcgv(Dc136 *dc, int n, word c, int rev);
word dctk(Dc136 *dc, int n, int rev);
/* Microtape/DECtape */
/* 555 has:
* move tape fwd, rev, auto
* unit selection (1-8)
* motor off, write lock on/off
*/
typedef struct Dx555 Dx555;
typedef struct Dt551 Dt551;
/* Transport 555,
* a half of it really */
struct Dx555
{
Device dev;
Dt551 *dt;
int unit;
int wrlock;
int fd;
uchar *start;
uchar *cur;
uchar *end;
};
#define DX_IDENT "dx555"
extern char *dx_ident;
Device *makedx(int argc, char *argv[]);
void dxconn(Dt551 *dt, Dx555 *dx, int n);
/*
void dxatt(Dx555 *dx, uchar *buf, int size);
void dxff(Dx555 *dx);
void dxrew(Dx555 *dx);
*/
/* Control 551 */
#define UTC (0210>>2)
#define UTS (0214>>2)
struct Dt551
{
Device dev;
IOBus *bus;
Dc136 *dc;
Dx555 *dx[8];
Dx555 *seldx;
/* enable time and mark track writing */
int ut_btm_switch;
int ut_pia;
int ut_units;
int ut_units_select;
int ut_fcn;
int ut_time;
int ut_wren;
int ut_go;
int ut_rev;
int ut_tape_end_flag;
int ut_tape_end_enable;
int ut_jb_done_flag;
int ut_jb_done_enable;
int time_enable;
int time_flag;
int ut_illegal_op;
int ut_info_error;
int ut_incomp_block;
int tmk; /* 9 bits */
int rwb; /* 6 bits */
int lb; /* 6 bits */
int tbm; /* 4 bits */
int tdata; /* 8 bits */
int tct; /* 1 bit */
int utek; /* 6 bits */
int uteck;
int rw_state; /* null, rq, active */
// int req;
};
#define DT_IDENT "dt551"
extern char *dt_ident;
Device *makedt(int argc, char *argv[]);
void dtconn(Dc136 *dc, Dt551 *dt);
/*
void dtcono(Dt551 *dt, word iob);
void dtcycle(Dt551 *dt);
*/

View File

@@ -37,6 +37,7 @@ reset(int fd)
#define BAUD 30
struct timespec slp = { 0, 1000*1000*1000 / BAUD };
struct timespec hupslp = { 0, 100*1000*1000 };
//#define SLEEP nanosleep(&slp, NULL)
#define SLEEP
@@ -60,6 +61,8 @@ readwrite(int ttyin, int ttyout, int ptyin, int ptyout)
}
if(n == 0)
return;
if(pfd[0].revents & POLLHUP)
nanosleep(&hupslp, NULL);
/* read from pty, write to tty */
if(pfd[0].revents & POLLIN){
if(n = read(ptyin, &c, 1), n <= 0)

View File

@@ -179,9 +179,13 @@ fixadd(void)
continue;
}
if(a->l)
mem[a->addr] += fw(right(s[1]), 0);
mem[a->addr] = fw(
left(mem[a->addr]) + right(s[1]),
right(mem[a->addr]));
else
mem[a->addr] += fw(0, right(s[1]));
mem[a->addr] = fw(
left(mem[a->addr]),
right(mem[a->addr]) + right(s[1]));
}
}
@@ -299,9 +303,13 @@ readblock(int doreloc)
reloc <<= 2;
if(doreloc){
if(bits & 1)
block[i] += fw(0, rel);
block[i] = fw(
left(block[i]),
right(block[i]) + rel);
if(bits & 2)
block[i] += fw(rel, 0);
block[i] = fw(
left(block[i]) + rel,
right(block[i]));
}
}
}
@@ -570,7 +578,7 @@ main(int argc, char *argv[])
}
fixadd();
// dumpsym();
dumpsym();
checkundef();
if(error)