PDP1: Add Expensive Typewriter support and paper tape additions from Bob Supnik
1. Implemented Expensive Typewriter mode for TTO. 2. Added ASCII conversion on paper tape punch as well as reader. 3. Changed conversion tables to recognize form feed (014) as FIODEC STOP.
This commit is contained in:
parent
4065f47f8c
commit
db3000086e
1 changed files with 82 additions and 15 deletions
|
@ -1,6 +1,6 @@
|
||||||
/* pdp1_stddev.c: PDP-1 standard devices
|
/* pdp1_stddev.c: PDP-1 standard devices
|
||||||
|
|
||||||
Copyright (c) 1993-2015, Robert M. Supnik
|
Copyright (c) 1993-2016, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -28,6 +28,8 @@
|
||||||
tti keyboard
|
tti keyboard
|
||||||
tto teleprinter
|
tto teleprinter
|
||||||
|
|
||||||
|
13-Jul-16 RMS Added Expensive Typewriter ribbon color support
|
||||||
|
18-May-16 RMS Added FIODEC-to-ASCII mode for paper tape punch
|
||||||
28-Mar-15 RMS Revised to use sim_printf
|
28-Mar-15 RMS Revised to use sim_printf
|
||||||
21-Mar-12 RMS Fixed unitialized variable in tto_svc (Michael Bloom)
|
21-Mar-12 RMS Fixed unitialized variable in tto_svc (Michael Bloom)
|
||||||
21-Dec-06 RMS Added 16-channel sequence break support
|
21-Dec-06 RMS Added 16-channel sequence break support
|
||||||
|
@ -55,8 +57,12 @@
|
||||||
#include "sim_tmxr.h"
|
#include "sim_tmxr.h"
|
||||||
|
|
||||||
#define FIODEC_STOP 013 /* stop code */
|
#define FIODEC_STOP 013 /* stop code */
|
||||||
#define FIODEC_UC 074
|
#define FIODEC_BLACK 034 /* TTY black ribbon */
|
||||||
#define FIODEC_LC 072
|
#define FIODEC_RED 035 /* TTY red ribbon */
|
||||||
|
#define FIODEC_UC 074 /* upper case */
|
||||||
|
#define FIODEC_LC 072 /* lower case */
|
||||||
|
#define FIODEC_CR 077 /* carriage return */
|
||||||
|
|
||||||
#define UC_V 6 /* upper case */
|
#define UC_V 6 /* upper case */
|
||||||
#define UC (1 << UC_V)
|
#define UC (1 << UC_V)
|
||||||
#define BOTH (1 << (UC_V + 1)) /* both cases */
|
#define BOTH (1 << (UC_V + 1)) /* both cases */
|
||||||
|
@ -64,12 +70,15 @@
|
||||||
#define TT_WIDTH 077
|
#define TT_WIDTH 077
|
||||||
#define UNIT_V_ASCII (UNIT_V_UF + 0) /* ASCII/binary mode */
|
#define UNIT_V_ASCII (UNIT_V_UF + 0) /* ASCII/binary mode */
|
||||||
#define UNIT_ASCII (1 << UNIT_V_ASCII)
|
#define UNIT_ASCII (1 << UNIT_V_ASCII)
|
||||||
|
#define UNIT_V_ET (UNIT_V_UF + 1) /* expensive typewriter mode */
|
||||||
|
#define UNIT_ET (1 << UNIT_V_ET)
|
||||||
#define PTR_LEADER 20 /* ASCII leader chars */
|
#define PTR_LEADER 20 /* ASCII leader chars */
|
||||||
|
|
||||||
int32 ptr_state = 0;
|
int32 ptr_state = 0;
|
||||||
int32 ptr_wait = 0;
|
int32 ptr_wait = 0;
|
||||||
int32 ptr_stopioe = 0;
|
int32 ptr_stopioe = 0;
|
||||||
int32 ptr_uc = 0; /* upper/lower case */
|
int32 ptr_uc = 0; /* upper/lower case */
|
||||||
|
int32 ptp_uc = 0;
|
||||||
int32 ptr_hold = 0; /* holding buffer */
|
int32 ptr_hold = 0; /* holding buffer */
|
||||||
int32 ptr_leader = PTR_LEADER; /* leader count */
|
int32 ptr_leader = PTR_LEADER; /* leader count */
|
||||||
int32 ptr_sbs = 0; /* SBS level */
|
int32 ptr_sbs = 0; /* SBS level */
|
||||||
|
@ -79,6 +88,7 @@ int32 tti_hold = 0; /* tti hold buf */
|
||||||
int32 tti_sbs = 0; /* SBS level */
|
int32 tti_sbs = 0; /* SBS level */
|
||||||
int32 tty_buf = 0; /* tty buffer */
|
int32 tty_buf = 0; /* tty buffer */
|
||||||
int32 tty_uc = 0; /* tty uc/lc */
|
int32 tty_uc = 0; /* tty uc/lc */
|
||||||
|
int32 tty_ribbon = FIODEC_BLACK; /* ribbon color */
|
||||||
int32 tto_sbs = 0;
|
int32 tto_sbs = 0;
|
||||||
|
|
||||||
extern int32 ios, ioh, cpls, iosta;
|
extern int32 ios, ioh, cpls, iosta;
|
||||||
|
@ -95,18 +105,19 @@ t_stat ptp_reset (DEVICE *dptr);
|
||||||
t_stat tty_reset (DEVICE *dptr);
|
t_stat tty_reset (DEVICE *dptr);
|
||||||
t_stat ptr_boot (int32 unitno, DEVICE *dptr);
|
t_stat ptr_boot (int32 unitno, DEVICE *dptr);
|
||||||
t_stat ptr_attach (UNIT *uptr, CONST char *cptr);
|
t_stat ptr_attach (UNIT *uptr, CONST char *cptr);
|
||||||
|
t_stat ptp_attach (UNIT *uptr, CONST char *cptr);
|
||||||
|
|
||||||
/* Character translation tables */
|
/* Character translation tables */
|
||||||
|
|
||||||
int32 fiodec_to_ascii[128] = {
|
int32 fiodec_to_ascii[128] = {
|
||||||
' ', '1', '2', '3', '4', '5', '6', '7', /* lower case */
|
' ', '1', '2', '3', '4', '5', '6', '7', /* lower case */
|
||||||
'8', '9', 0, 0, 0, 0, 0, 0,
|
'8', '9', 0, '\f', 0, 0, 0, 0,
|
||||||
'0', '/', 's', 't', 'u', 'v', 'w', 'x',
|
'0', '/', 's', 't', 'u', 'v', 'w', 'x',
|
||||||
'y', 'z', 0, ',', 0, 0, '\t', 0,
|
'y', 'z', 0, ',', 0, 0, '\t', 0,
|
||||||
'@', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
|
'@', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
|
||||||
'q', 'r', 0, 0, '-', ')', '\\', '(',
|
'q', 'r', 0, 0, '-', ')', '\\', '(',
|
||||||
0, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
0, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||||
'h', 'i', '{', '.', '}', '\b', 0, '\r',
|
'h', 'i', 0, '.', 0, '\b', 0, '\n',
|
||||||
' ', '"', '\'', '~', '#', '!', '&', '<', /* upper case */
|
' ', '"', '\'', '~', '#', '!', '&', '<', /* upper case */
|
||||||
'>', '^', 0, 0, 0, 0, 0, 0,
|
'>', '^', 0, 0, 0, 0, 0, 0,
|
||||||
'`', '?', 'S', 'T', 'U', 'V', 'W', 'X',
|
'`', '?', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||||
|
@ -114,12 +125,12 @@ int32 fiodec_to_ascii[128] = {
|
||||||
'_', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
'_', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||||
'Q', 'R', 0, 0, '+', ']', '|', '[',
|
'Q', 'R', 0, 0, '+', ']', '|', '[',
|
||||||
0, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
0, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
|
||||||
'H', 'I', '{', '*', '}', '\b', 0, '\r'
|
'H', 'I', 0, '*', 0, '\b', 0, '\n'
|
||||||
};
|
};
|
||||||
|
|
||||||
int32 ascii_to_fiodec[128] = {
|
int32 ascii_to_fiodec[128] = {
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
BOTH+075, BOTH+036, 0, 0, 0, BOTH+077, 0, 0,
|
BOTH+075, BOTH+036, 0, 0, BOTH+FIODEC_STOP, BOTH+FIODEC_CR, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
BOTH+0, UC+005, UC+001, UC+004, 0, 0, UC+006, UC+002,
|
BOTH+0, UC+005, UC+001, UC+004, 0, 0, UC+006, UC+002,
|
||||||
|
@ -205,6 +216,8 @@ REG ptp_reg[] = {
|
||||||
MTAB ptp_mod[] = {
|
MTAB ptp_mod[] = {
|
||||||
{ MTAB_XTD|MTAB_VDV, 0, "SBSLVL", "SBSLVL",
|
{ MTAB_XTD|MTAB_VDV, 0, "SBSLVL", "SBSLVL",
|
||||||
&dev_set_sbs, &dev_show_sbs, (void *) &ptp_sbs },
|
&dev_set_sbs, &dev_show_sbs, (void *) &ptp_sbs },
|
||||||
|
{ UNIT_ASCII, UNIT_ASCII, "ASCII", "ASCII", NULL },
|
||||||
|
{ UNIT_ASCII, 0, "FIODEC", "FIODEC", NULL },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -212,7 +225,7 @@ DEVICE ptp_dev = {
|
||||||
"PTP", &ptp_unit, ptp_reg, ptp_mod,
|
"PTP", &ptp_unit, ptp_reg, ptp_mod,
|
||||||
1, 10, 31, 1, 8, 8,
|
1, 10, 31, 1, 8, 8,
|
||||||
NULL, NULL, &ptp_reset,
|
NULL, NULL, &ptp_reset,
|
||||||
NULL, NULL, NULL,
|
NULL, &ptp_attach, NULL,
|
||||||
NULL, 0
|
NULL, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -267,12 +280,15 @@ REG tto_reg[] = {
|
||||||
{ DRDATAD (POS, tto_unit.pos, T_ADDR_W, "number of characters output"), PV_LEFT },
|
{ DRDATAD (POS, tto_unit.pos, T_ADDR_W, "number of characters output"), PV_LEFT },
|
||||||
{ DRDATAD (TIME, tto_unit.wait, 24, "time from I/O initiation interrupt"), PV_LEFT },
|
{ DRDATAD (TIME, tto_unit.wait, 24, "time from I/O initiation interrupt"), PV_LEFT },
|
||||||
{ DRDATA (SBSLVL, tto_sbs, 4), REG_HRO },
|
{ DRDATA (SBSLVL, tto_sbs, 4), REG_HRO },
|
||||||
|
{ ORDATA (RIBBON, tty_ribbon, 6), REG_HRO },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
MTAB tto_mod[] = {
|
MTAB tto_mod[] = {
|
||||||
{ MTAB_XTD|MTAB_VDV, 0, "SBSLVL", "SBSLVL",
|
{ MTAB_XTD|MTAB_VDV, 0, "SBSLVL", "SBSLVL",
|
||||||
&dev_set_sbs, &dev_show_sbs, (void *) &tto_sbs },
|
&dev_set_sbs, &dev_show_sbs, (void *) &tto_sbs },
|
||||||
|
{ UNIT_ET, UNIT_ET, "Expensive Typewriter mode", "ET", NULL },
|
||||||
|
{ UNIT_ET, UNIT_ET, "normal mode", "NOET", NULL },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -437,6 +453,9 @@ return SCPE_OK;
|
||||||
t_stat ptr_attach (UNIT *uptr, CONST char *cptr)
|
t_stat ptr_attach (UNIT *uptr, CONST char *cptr)
|
||||||
{
|
{
|
||||||
ptr_leader = PTR_LEADER; /* set up leader */
|
ptr_leader = PTR_LEADER; /* set up leader */
|
||||||
|
if (sim_switches & SWMASK ('A'))
|
||||||
|
uptr->flags = uptr->flags | UNIT_ASCII;
|
||||||
|
else uptr->flags = uptr->flags & ~UNIT_ASCII;
|
||||||
return attach_unit (uptr, cptr);
|
return attach_unit (uptr, cptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,6 +520,8 @@ return dat;
|
||||||
|
|
||||||
t_stat ptp_svc (UNIT *uptr)
|
t_stat ptp_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
|
int32 c;
|
||||||
|
|
||||||
if (cpls & CPLS_PTP) { /* completion pulse? */
|
if (cpls & CPLS_PTP) { /* completion pulse? */
|
||||||
ios = 1; /* restart */
|
ios = 1; /* restart */
|
||||||
cpls = cpls & ~CPLS_PTP;
|
cpls = cpls & ~CPLS_PTP;
|
||||||
|
@ -509,7 +530,26 @@ iosta = iosta | IOS_PTP; /* set flag */
|
||||||
dev_req_int (ptp_sbs); /* req interrupt */
|
dev_req_int (ptp_sbs); /* req interrupt */
|
||||||
if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */
|
if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */
|
||||||
return IORETURN (ptp_stopioe, SCPE_UNATT);
|
return IORETURN (ptp_stopioe, SCPE_UNATT);
|
||||||
if (putc (uptr->buf, uptr->fileref) == EOF) { /* I/O error? */
|
if ((uptr->flags & UNIT_ASCII) != 0) { /* ASCII mode? */
|
||||||
|
int32 c1 = uptr->buf & 077;
|
||||||
|
if (c1 == FIODEC_UC) {
|
||||||
|
ptp_uc = UC;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
else if (c1 == FIODEC_LC) {
|
||||||
|
ptp_uc = 0;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
else c = fiodec_to_ascii[c1 | ptp_uc];
|
||||||
|
if (c == 0)
|
||||||
|
return SCPE_OK;
|
||||||
|
if (c == '\n') { /* new line? */
|
||||||
|
putc ('\r', uptr->fileref); /* cr first */
|
||||||
|
uptr->pos = uptr->pos + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else c = uptr->buf;
|
||||||
|
if (putc (c, uptr->fileref) == EOF) { /* I/O error? */
|
||||||
sim_perror ("PTP I/O error");
|
sim_perror ("PTP I/O error");
|
||||||
clearerr (uptr->fileref);
|
clearerr (uptr->fileref);
|
||||||
return SCPE_IOERR;
|
return SCPE_IOERR;
|
||||||
|
@ -523,12 +563,23 @@ return SCPE_OK;
|
||||||
t_stat ptp_reset (DEVICE *dptr)
|
t_stat ptp_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
ptp_unit.buf = 0; /* clear state */
|
ptp_unit.buf = 0; /* clear state */
|
||||||
|
ptp_uc = 0;
|
||||||
cpls = cpls & ~CPLS_PTP;
|
cpls = cpls & ~CPLS_PTP;
|
||||||
iosta = iosta & ~IOS_PTP; /* clear flag */
|
iosta = iosta & ~IOS_PTP; /* clear flag */
|
||||||
sim_cancel (&ptp_unit); /* deactivate unit */
|
sim_cancel (&ptp_unit); /* deactivate unit */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Attach routine */
|
||||||
|
|
||||||
|
t_stat ptp_attach (UNIT *uptr, CONST char *cptr)
|
||||||
|
{
|
||||||
|
if (sim_switches & SWMASK ('A'))
|
||||||
|
uptr->flags = uptr->flags | UNIT_ASCII;
|
||||||
|
else uptr->flags = uptr->flags & ~UNIT_ASCII;
|
||||||
|
return attach_unit (uptr, cptr);
|
||||||
|
}
|
||||||
|
|
||||||
/* Typewriter IOT routines */
|
/* Typewriter IOT routines */
|
||||||
|
|
||||||
int32 tti (int32 inst, int32 dev, int32 dat)
|
int32 tti (int32 inst, int32 dev, int32 dat)
|
||||||
|
@ -592,25 +643,40 @@ uptr->pos = uptr->pos + 1;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tto_puts (const char *cptr)
|
||||||
|
{
|
||||||
|
int32 c;
|
||||||
|
|
||||||
|
while ((c = *cptr++) != 0)
|
||||||
|
sim_putchar (c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
t_stat tto_svc (UNIT *uptr)
|
t_stat tto_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
t_stat r;
|
t_stat r;
|
||||||
|
int32 c;
|
||||||
|
static const char *red_str = "[red]\r\n";
|
||||||
|
static const char *black_str = "[black]\r\n";
|
||||||
|
|
||||||
if (tty_buf == FIODEC_UC) /* upper case? */
|
if (tty_buf == FIODEC_UC) /* upper case? */
|
||||||
tty_uc = UC;
|
tty_uc = UC;
|
||||||
else if (tty_buf == FIODEC_LC) /* lower case? */
|
else if (tty_buf == FIODEC_LC) /* lower case? */
|
||||||
tty_uc = 0;
|
tty_uc = 0;
|
||||||
|
else if (((uptr->flags & UNIT_ET) != 0) && /* ET ribbon chg? */
|
||||||
|
((tty_buf == FIODEC_BLACK) || (tty_buf == FIODEC_RED)) &&
|
||||||
|
(tty_buf != tty_ribbon)) {
|
||||||
|
tto_puts ((tty_buf == FIODEC_RED)? red_str: black_str);
|
||||||
|
tty_ribbon = tty_buf;
|
||||||
|
}
|
||||||
|
else if (tty_buf == FIODEC_CR)
|
||||||
|
tto_puts ("\r\n");
|
||||||
else {
|
else {
|
||||||
int32 c;
|
|
||||||
c = fiodec_to_ascii[tty_buf | tty_uc]; /* translate */
|
c = fiodec_to_ascii[tty_buf | tty_uc]; /* translate */
|
||||||
if (c && ((r = sim_putchar_s (c)) != SCPE_OK)) { /* output; error? */
|
if ((c != 0) && ((r = sim_putchar_s (c)) != SCPE_OK)) { /* output; error? */
|
||||||
sim_activate (uptr, uptr->wait); /* retry */
|
sim_activate (uptr, uptr->wait); /* retry */
|
||||||
return ((r == SCPE_STALL)? SCPE_OK: r);
|
return ((r == SCPE_STALL)? SCPE_OK: r);
|
||||||
}
|
}
|
||||||
if (c == '\r') { /* cr? add lf */
|
|
||||||
sim_putchar ('\n');
|
|
||||||
uptr->pos = uptr->pos + 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (cpls & CPLS_TTO) { /* completion pulse? */
|
if (cpls & CPLS_TTO) { /* completion pulse? */
|
||||||
ios = 1; /* restart */
|
ios = 1; /* restart */
|
||||||
|
@ -628,6 +694,7 @@ t_stat tty_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
tmxr_set_console_units (&tti_unit, &tto_unit);
|
tmxr_set_console_units (&tti_unit, &tto_unit);
|
||||||
tty_buf = 0; /* clear buffer */
|
tty_buf = 0; /* clear buffer */
|
||||||
|
tty_ribbon = FIODEC_BLACK; /* start black */
|
||||||
tty_uc = 0; /* clear case */
|
tty_uc = 0; /* clear case */
|
||||||
tti_hold = 0; /* clear hold buf */
|
tti_hold = 0; /* clear hold buf */
|
||||||
cpls = cpls & ~CPLS_TTO;
|
cpls = cpls & ~CPLS_TTO;
|
||||||
|
|
Loading…
Add table
Reference in a new issue