NOVA: Add parity generation for input characters on the TTI device

John Kichury revived Startrek II running under DCC Basic which originally ran on  the Digital Computer Controls (DCC) D-116 DG Nova clone

This program (or the Basic interpreter) requires console input with even parity.

SET TTI EVEN

will now enable that.
This commit is contained in:
Mark Pizzolato 2015-01-16 12:03:07 -08:00
parent 136f5867b6
commit 191566fdd8
3 changed files with 47 additions and 5 deletions

View file

@ -43,7 +43,6 @@
- TTO output is always masked to 7 bits in this rev
- TTO "Dasher" attribute sends '\b' to console instead of '\031'
- TTO may be disabled
- TTI input is always masked to 7 bits in this rev
- TTI "Dasher" attribute swaps <CR> and <LF>
- TTI may not be disabled
*/
@ -51,7 +50,7 @@
#include "nova_defs.h"
#include "sim_tmxr.h"
#define UNIT_V_DASHER (UNIT_V_UF + 0) /* Dasher mode */
#define UNIT_V_DASHER (TTUF_V_UF) /* Dasher mode */
#define UNIT_DASHER (1 << UNIT_V_DASHER)
extern int32 int_req, dev_busy, dev_done, dev_disable;
@ -63,6 +62,7 @@ t_stat tto_svc (UNIT *uptr);
t_stat tti_reset (DEVICE *dptr);
t_stat tto_reset (DEVICE *dptr);
t_stat ttx_setmod (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat ttx_setpar (UNIT *uptr, int32 val, char *cptr, void *desc);
/* TTI data structures
@ -90,6 +90,10 @@ REG tti_reg[] = {
MTAB ttx_mod[] = {
{ UNIT_DASHER, 0, "ANSI", "ANSI", &ttx_setmod },
{ UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx_setmod },
{ TT_PAR, TT_PAR_EVEN, "Even Parity", "EVEN", &ttx_setpar },
{ TT_PAR, TT_PAR_ODD, "Odd Parity", "ODD", &ttx_setpar },
{ TT_PAR, TT_PAR_MARK, "Mark Parity", "MARK", &ttx_setpar },
{ TT_PAR, TT_PAR_SPACE, "No Parity", "NONE", &ttx_setpar },
{ 0 }
} ;
@ -176,6 +180,7 @@ if (tti_unit.flags & UNIT_DASHER) {
else if (tti_unit.buf == '\n')
tti_unit.buf = '\r' ; /* Dasher: nl -> cr */
}
tti_unit.buf = sim_tt_inpcvt (tti_unit.buf, TT_GET_MODE (uptr->flags));
DEV_CLR_BUSY( INT_TTI ) ;
DEV_SET_DONE( INT_TTI ) ;
DEV_UPDATE_INTR ;
@ -262,3 +267,10 @@ tti_unit.flags = (tti_unit.flags & ~UNIT_DASHER) | val;
tto_unit.flags = (tto_unit.flags & ~UNIT_DASHER) | val;
return SCPE_OK;
}
t_stat ttx_setpar (UNIT *uptr, int32 val, char *cptr, void *desc)
{
tti_unit.flags = (tti_unit.flags & ~TT_PAR) | val;
tto_unit.flags = (tto_unit.flags & ~TT_PAR) | val;
return SCPE_OK;
}

View file

@ -1844,6 +1844,10 @@ int32 sim_tt_inpcvt (int32 c, uint32 mode)
uint32 md = mode & TTUF_M_MODE;
if (md != TTUF_MODE_8B) {
uint32 par_bit = 0;
uint32 par_mode = (mode >> TTUF_W_MODE) & TTUF_M_PAR;
static int32 nibble_even_parity = 0x699600; /* bit array indicating the even parity for each index (offset by 8) */
c = c & 0177;
if (md == TTUF_MODE_UC) {
if (islower (c))
@ -1851,6 +1855,17 @@ if (md != TTUF_MODE_8B) {
if (mode & TTUF_KSR)
c = c | 0200;
}
switch (par_mode) {
case TTUF_PAR_EVEN:
c |= (((nibble_even_parity >> ((c & 0xF) + 1)) ^ (nibble_even_parity >> (((c >> 4) & 0xF) + 1))) & 0x80);
break;
case TTUF_PAR_ODD:
c |= ((~((nibble_even_parity >> ((c & 0xF) + 1)) ^ (nibble_even_parity >> (((c >> 4) & 0xF) + 1)))) & 0x80);
break;
case TTUF_PAR_MARK:
c = c | 0x80;
break;
}
}
else c = c & 0377;
return c;

View file

@ -41,16 +41,31 @@
#define TTUF_MODE_8B 1
#define TTUF_MODE_UC 2
#define TTUF_MODE_7P 3
#define TTUF_KSR (1u << TTUF_W_MODE)
#define TTUF_M_MODE ((1u << TTUF_W_MODE) - 1)
#define TTUF_V_UF (TTUF_V_MODE + TTUF_W_MODE)
#define TTUF_V_PAR (TTUF_V_MODE + TTUF_W_MODE)
#define TTUF_W_PAR 2
#define TTUF_PAR_SPACE 0
#define TTUF_PAR_MARK 1
#define TTUF_PAR_EVEN 2
#define TTUF_PAR_ODD 3
#define TTUF_M_PAR ((1u << TTUF_W_PAR) - 1)
#define TTUF_KSR (1u << (TTUF_W_MODE + TTUF_W_PAR))
#define TTUF_V_UF (TTUF_V_MODE + TTUF_W_MODE + TTUF_W_PAR)
#define TT_MODE (TTUF_M_MODE << TTUF_V_MODE)
#define TT_MODE_7B (TTUF_MODE_7B << TTUF_V_MODE)
#define TT_MODE_8B (TTUF_MODE_8B << TTUF_V_MODE)
#define TT_MODE_UC (TTUF_MODE_UC << TTUF_V_MODE)
#define TT_MODE_7P (TTUF_MODE_7P << TTUF_V_MODE)
#define TT_MODE_KSR (TT_MODE_UC)
#define TT_GET_MODE(x) (((x) >> TTUF_V_MODE) & TTUF_M_MODE)
/* 7 bit modes allow for an 8th bit parity mode */
#define TT_PAR (TTUF_M_PAR << TTUF_V_PAR)
#define TT_PAR_SPACE (TTUF_PAR_SPACE << TTUF_V_PAR)
#define TT_PAR_MARK (TTUF_PAR_MARK << TTUF_V_PAR)
#define TT_PAR_EVEN (TTUF_PAR_EVEN << TTUF_V_PAR)
#define TT_PAR_ODD (TTUF_PAR_ODD << TTUF_V_PAR)
/* TT_GET_MODE returns both the TT_MODE and TT_PAR fields
since they together are passed into sim_tt_inpcvt() */
#define TT_GET_MODE(x) (((x) >> TTUF_V_MODE) & (TTUF_M_MODE | (TTUF_M_PAR << TTUF_W_MODE)))
t_stat sim_set_console (int32 flag, char *cptr);
t_stat sim_set_remote_console (int32 flag, char *cptr);