From 191566fdd8f2506dbb2313aefe445339a40c977f Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Fri, 16 Jan 2015 12:03:07 -0800 Subject: [PATCH] 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. --- NOVA/nova_tt.c | 16 ++++++++++++++-- sim_console.c | 15 +++++++++++++++ sim_console.h | 21 ++++++++++++++++++--- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/NOVA/nova_tt.c b/NOVA/nova_tt.c index 8d5abff3..b9a0b03d 100644 --- a/NOVA/nova_tt.c +++ b/NOVA/nova_tt.c @@ -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 and - 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; +} diff --git a/sim_console.c b/sim_console.c index 3c325d00..4688190a 100644 --- a/sim_console.c +++ b/sim_console.c @@ -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; diff --git a/sim_console.h b/sim_console.h index 03c95d1f..00d58424 100644 --- a/sim_console.h +++ b/sim_console.h @@ -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);