mirror of
https://github.com/aap/pdp6.git
synced 2026-02-27 09:19:45 +00:00
committing old stuff
This commit is contained in:
@@ -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
65
code/bootstrap.txt
Normal 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
23
code/dtboot.s
Normal 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
|
||||
16
code/main.s
16
code/main.s
@@ -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
|
||||
|
||||
23
code/tty.s
23
code/tty.s
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
43
emu/cmd.c
43
emu/cmd.c
@@ -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
18
emu/cmds.txt
Normal 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
|
||||
5
emu/dc.c
5
emu/dc.c
@@ -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
577
emu/dt.c
Normal 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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
24
emu/mem_0
Normal 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
|
||||
97
emu/pdp6.h
97
emu/pdp6.h
@@ -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);
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
|
||||
18
tools/ld6.c
18
tools/ld6.c
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user