From ae8bcecd29f91e657825e255baa36009551a7808 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Sun, 5 Jan 2014 14:45:08 -0800 Subject: [PATCH] I1620 : Changes from Bob Supnik re: Bob Armstrong has been running diagnostics and software, and these changes reflect fixes to bugs that were found. We're not absolutely sure that all of the changes are correct - in particular the treatment of record marks in add/compare - but they do make the diagnostics pass, which they didn't before. Bob asked for variable tab stops on the typewriter, and those are implemented as well. The routines were general enough that I put the SET/SHOW processors in sim_console.c, so I'm enclosing that and its header file. Conflicts: I1620/i1620_cpu.c sim_console.c sim_console.h --- I1620/i1620_cd.c | 48 ++++++++++++++++++++++++---- I1620/i1620_cpu.c | 70 +++++++++++++++++++++++++++++++++------- I1620/i1620_lp.c | 18 +++++------ I1620/i1620_pt.c | 23 ++++++++------ I1620/i1620_sys.c | 2 +- I1620/i1620_tty.c | 79 +++++++++++++++++++++++++++++++++++----------- doc/i1620_doc.doc | Bin 68096 -> 64000 bytes sim_console.c | 58 ++++++++++++++++++++++++++++++++-- sim_console.h | 5 ++- 9 files changed, 244 insertions(+), 59 deletions(-) diff --git a/I1620/i1620_cd.c b/I1620/i1620_cd.c index 3faa69dc..5d93dcf7 100644 --- a/I1620/i1620_cd.c +++ b/I1620/i1620_cd.c @@ -1,6 +1,6 @@ /* i1620_cd.c: IBM 1622 card reader/punch - Copyright (c) 2002-2012, Robert M. Supnik + Copyright (c) 2002-2013, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,6 +26,8 @@ cdr 1622 card reader cdp 1622 card punch + 10-Dec-13 RMS Fixed WA card punch translations (Bob Armstrong) + Fixed card reader EOL processing (Bob Armstrong) 19-Mar-12 RMS Fixed declarations of saved_pc, io_stop (Mark Pizzolato) 19-Jan-07 RMS Set UNIT_TEXT flag 13-Jul-06 RMS Fixed card reader fgets call (Tom McBride) @@ -112,7 +114,7 @@ DEVICE cdp_dev = { */ /* Card reader (ASCII) to numeric (one digit) */ -const char cdr_to_num[128] = { +const int8 cdr_to_num[128] = { 0x00, -1, -1, -1, -1, -1, -1, -1, /* 00 */ -1, 0x00, 0x00, -1, -1, 0x00, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10 */ @@ -184,11 +186,21 @@ const int8 cdr_to_alp[128] = { There is no way to punch 0-5-8 (~), 0-6-8 (\), 11-5-8 (]), 11-6-8 (;), 11-7-8 (_), 12-5-8 ([), or 12-6-8 (<) + +According to Bob Armstrong, + the FORTRAN compiler is sneaky and actually punches numeric + data (i.e. data that it knows will be read back using RNCD) + in alphameric mode with WACD. Because of that there are some + alpha to ASCII translations that absolutely MUST work out right + or otherwise we won't be able to load FORTRAN object decks. + + 50 - must "punch" as ] (flagged zero) (used to be "_") + 0A - must "punch" as | (record mark) (used to be "'") */ const int8 alp_to_cdp[256] = { ' ', -1, '?', '.', ')', -1, -1, '}', /* 00 */ - -1, -1, '\'', -1, -1, -1, -1, '"', + -1, -1, '|', -1, -1, -1, -1, '"', '+', -1, '!', '$', '*', ']', -1, -1, /* 10 */ -1, -1, -1, -1, -1, -1, -1, -1, '-', '/', '|', ',', '(', -1, -1, -1, /* 20 */ @@ -197,7 +209,7 @@ const int8 alp_to_cdp[256] = { -1, -1, '|', -1, -1, -1, -1, '"', -1, 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* 40 */ 'H', 'I', -1, -1, -1, -1, -1, -1, - '_', 'J', 'K', 'L', 'M', 'N', 'O', 'P', /* 50 */ + ']', 'J', 'K', 'L', 'M', 'N', 'O', 'P', /* 50 */ 'Q', 'R', '?', '=', -1, -1, -1, '}', -1, '/', 'S', 'T', 'U', 'V', 'W', 'X', /* 60 */ 'Y', 'Z', '|', ',', -1, -1, -1, -1, @@ -279,7 +291,12 @@ switch (op) { /* case on op */ return sta; } -/* Fill card reader buffer - all errors are hard errors */ +/* Fill card reader buffer - all errors are hard errors + + As Bob Armstrong pointed out, this routines needs to account + for variants in text file formats, which may terminate lines + with cr-lf (Windows), lf (UNIX), or cr (Mac). +*/ t_stat cdr_read (void) { @@ -302,6 +319,22 @@ if (ferror (cdr_unit.fileref)) { /* error? */ clearerr (cdr_unit.fileref); return SCPE_IOERR; } +if ((i = strlen (cdr_buf)) > 0) { /* anything at all? */ + if (cdr_buf[i-1] == '\n') { /* line end in \n? */ + cdr_buf[i-1] = 0; /* remove it */ + } + else if (cdr_buf[i-1] == '\r') { /* line end in \r? */ + cdr_buf[i-1] = 0; /* remove it */ + cdr_unit.pos = ftell (cdr_unit.fileref); /* save position */ + if (fgetc (cdr_unit.fileref) != '\n') /* next char not \n? */ + fseek (cdr_unit.fileref, cdr_unit.pos, SEEK_SET); /* then rewind */ + } + else { /* line too long */ + ind[IN_RDCHK] = 1; + perror ("CDR line too long"); + return SCPE_IOERR; + } + } cdr_unit.pos = ftell (cdr_unit.fileref); /* update position */ getc (cdr_unit.fileref); /* see if more */ if (feof (cdr_unit.fileref)) /* eof? set last */ @@ -362,7 +395,7 @@ uint8 z, d; switch (op) { /* decode op */ case OP_DN: - return cdp_num (pa, 20000 - (pa % 20000), TRUE); /* dump numeric */ + return cdp_num (pa, 20000 - (pa % 20000), TRUE);/* dump numeric */ case OP_WN: return cdp_num (pa, CD_LEN, FALSE); /* write numeric */ @@ -404,7 +437,8 @@ while (ncd-- >= 0) { /* until done */ break; for (i = 0; i < len; i++) { /* one card */ d = M[pa] & (FLAG | DIGIT); /* get char */ - if (dump && (d == FLAG)) cdc = '-'; /* dump? F+0 is diff */ + if (dump && (d == FLAG)) /* dump? F+0 is diff */ + cdc = '-'; else cdc = num_to_cdp[d]; /* translate */ if (cdc < 0) { /* bad char? */ ind[IN_WRCHK] = 1; /* set write check */ diff --git a/I1620/i1620_cpu.c b/I1620/i1620_cpu.c index 5ef99843..343ddc02 100644 --- a/I1620/i1620_cpu.c +++ b/I1620/i1620_cpu.c @@ -1,6 +1,6 @@ /* i1620_cpu.c: IBM 1620 CPU simulator - Copyright (c) 2002-2008, Robert M. Supnik + Copyright (c) 2002-2013, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,7 +26,9 @@ This CPU module incorporates code and comments from the 1620 simulator by Geoff Kuenning, with his permission. - 28-May-06 RMS Fixed bug in cpu history Peter Schorn) + 10-Dec-13 RMS Fixed several bugs in add and compare (Bob Armstrong) + Fixed handling of P field in K instruction (Bob Armstrong) + 28-May-06 RMS Fixed bug in cpu history (Peter Schorn) 22-Sep-05 RMS Fixed declarations (Sterling Garwood) 16-Aug-05 RMS Fixed C++ declaration and cast problems 07-Nov-04 RMS Added instruction history @@ -291,7 +293,7 @@ const int32 op_table[100] = { IF_VPA + IF_VQA, /* TR */ IF_VPA, /* SF */ IF_VPA, /* CF */ - IF_VPA, /* K */ + 0, /* K */ IF_VPA, /* DN */ IF_VPA, /* RN */ IF_VPA, /* RA */ @@ -384,6 +386,21 @@ t_stat (*iodisp[NUM_IO])(uint32 op, uint32 pa, uint32 f0, uint32 f1) = { NULL, NULL, NULL, NULL, NULL }; +/* K instruction validate P field table */ + +const uint8 k_valid_p[NUM_IO] = { + 0, 0, 0, 0, 0, 0, 0, 1, 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, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + /* Indicator table: -1 = illegal, +1 = resets when tested */ const int32 ind_table[NUM_IND] = { @@ -687,11 +704,12 @@ while (reason == 0) { /* loop until halted */ reason = STOP_OVERFL; break; +/* IBM's diagnostics try a compare that generates a carry out; it does not + generate overflow. Therefore, do not set overflow on a carry out status. */ + case OP_C: case OP_CM: reason = add_field (PAR, QAR, TRUE, FALSE, 0, &sta); /* sub, nostore */ - if (sta == ADD_CARRY) /* cout => ovflo */ - ind[IN_OVF] = 1; if (ar_stop && ind[IN_OVF]) reason = STOP_OVERFL; break; @@ -703,7 +721,7 @@ while (reason == 0) { /* loop until halted */ reason = mul_field (PAR, QAR); /* multiply */ break; -/* IO instructions - P is valid */ +/* IO instructions - P is valid, except for K */ case OP_RA: case OP_WA: @@ -711,7 +729,6 @@ while (reason == 0) { /* loop until halted */ reason = STOP_INVEAD; /* stop */ break; } - case OP_K: case OP_DN: case OP_RN: case OP_WN: @@ -723,6 +740,21 @@ while (reason == 0) { /* loop until halted */ else reason = iodisp[dev] (op, PAR, f0, f1); /* call device */ break; + case OP_K: + dev = get_2d (ADDR_A (saved_PC, I_IO)); /* get IO dev */ + if (k_valid_p[dev]) { /* validate P? */ + reason = get_addr (pla, 5, TRUE, &PAR); /* get P addr */ + if (reason != SCPE_OK) /* stop if error */ + break; + } + else PAR = 0; + f0 = M[ADDR_A (saved_PC, I_CTL)] & DIGIT; /* get function */ + f1 = M[ADDR_A (saved_PC, I_CTL + 1)] & DIGIT; + if ((dev < 0) || (iodisp[dev] == NULL)) /* undefined dev? */ + reason = STOP_INVIO; /* stop */ + else reason = iodisp[dev] (op, PAR, f0, f1); /* call device */ + break; + /* Divide special feature instructions */ case OP_LD: @@ -1296,7 +1328,8 @@ return SCPE_OK; Reference Manual: "When the sum is zero, the sign of the P field is retained." -*/ + + Bob Armstrong: record marks are treated by add as though they were zero */ t_stat add_field (uint32 d, uint32 s, t_bool sub, t_bool sto, uint32 skp, int32 *sta) { @@ -1312,6 +1345,10 @@ ind[IN_EZ] = 1; /* assume zero */ dst = M[d] & DIGIT; /* 1st digits */ src = M[s] & DIGIT; +if (dst == REC_MARK) /* chk for rec mark */ + dst = 0; +if (src == REC_MARK) + src = 0; if (BAD_DIGIT (dst) || BAD_DIGIT (src)) /* bad digit? */ return STOP_INVDIG; if (comp) /* complement? */ @@ -1322,11 +1359,15 @@ if (sto) /* store */ MM (d); MM (s); /* decr mem addrs */ do { dst = M[d] & DIGIT; /* get dst digit */ + if (dst == REC_MARK) + dst = 0; dst_f = M[d] & FLAG; /* get dst flag */ if (src_f) /* src done? src = 0 */ src = 0; else { src = M[s] & DIGIT; /* get src digit */ + if (src == REC_MARK) + src = 0; if (cnt >= skp) /* get src flag */ src_f = M[s] & FLAG; MM (s); /* decr src addr */ @@ -1344,12 +1385,18 @@ do { } while (dst_f == 0); /* until dst done */ if (!src_f) /* !src done? ovf */ ind[IN_OVF] = 1; + +/* Because recomplement is done (model 1) with table lookup, the first digit + must be explicitly 10s complemented, and not 9s complemented with a carry + in of 1. (Bob Armstrong) */ + if (comp && !cry && !ind[IN_EZ]) { /* recomp needed? */ ind[IN_HP] = ind[IN_HP] ^ 1; /* flip indicator */ if (sto) { /* storing? */ - for (cry = 1, dp = dsv; dp != d; ) { /* rescan */ + for (cry = 0, dp = dsv; dp != d; ) { /* rescan */ dst = M[dp] & DIGIT; /* get dst digit */ - res = add_one_digit (9 - dst, 0, &cry); /* "add" */ + dst = (dp == dsv)? (10 - dst): (9 - dst); /* 10 or 9s comp */ + res = add_one_digit (0, dst, &cry); /* "add" */ M[dp] = (M[dp] & FLAG) | res; /* store */ MM (dp); /* decr dst addr */ } @@ -1371,7 +1418,8 @@ uint32 add_one_digit (uint32 dst, uint32 src, uint32 *cry) { uint32 res; -if (*cry) src = src + 1; /* cry in? incr src */ +if (*cry) /* cry in? incr src */ + src = src + 1; if (src >= 10) { /* src > 10? */ src = src - 10; /* src -= 10 */ *cry = 1; /* carry out */ diff --git a/I1620/i1620_lp.c b/I1620/i1620_lp.c index 4254bf09..147b8e8e 100644 --- a/I1620/i1620_lp.c +++ b/I1620/i1620_lp.c @@ -1,6 +1,6 @@ /* i1620_lp.c: IBM 1443 line printer simulator - Copyright (c) 2002-2008, Robert M. Supnik + Copyright (c) 2002-2013, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,8 @@ lpt 1443 line printer + 10-Dec-13 RMS Fixed DN wraparound (Bob Armstrong) + Fixed test on VFU 10 (Bob Armstrong) 19-Jan-07 RMS Added UNIT_TEXT flag 21-Sep-05 RMS Revised translation tables for 7094/1401 compatibility 29-Dec-03 RMS Fixed bug in scheduling @@ -56,7 +58,7 @@ t_stat lpt_svc (UNIT *uptr); t_stat lpt_reset (DEVICE *dptr); t_stat lpt_attach (UNIT *uptr, char *cptr); void lpt_buf_init (void); -t_stat lpt_num (uint32 pa, uint32 len, uint32 f1); +t_stat lpt_num (uint32 pa, uint32 len, uint32 f1, t_bool dump); t_stat lpt_print (void); t_stat lpt_space (int32 lines, int32 lflag); @@ -169,10 +171,10 @@ switch (op) { /* decode op */ break; case OP_DN: - return lpt_num (pa, 20000 - (pa % 20000), f1); /* dump numeric */ + return lpt_num (pa, 20000 - (pa % 20000), f1, TRUE); /* dump numeric */ case OP_WN: - return lpt_num (pa, 0, f1); /* write numeric */ + return lpt_num (pa, 0, f1, FALSE); /* write numeric */ case OP_WA: for ( ; lpt_bptr < LPT_BSIZE; lpt_bptr++) { /* only fill buf */ @@ -205,18 +207,16 @@ return SCPE_OK; /* Print numeric */ -t_stat lpt_num (uint32 pa, uint32 len, uint32 f1) +t_stat lpt_num (uint32 pa, uint32 len, uint32 f1, t_bool dump) { -uint32 end; uint8 d; int8 lpc; t_stat r, sta; sta = SCPE_OK; -end = pa + len; for ( ; lpt_bptr < LPT_BSIZE; lpt_bptr++) { /* only fill buf */ d = M[pa]; /* get digit */ - if (len? (pa >= end): /* end reached? */ + if (dump? (len-- == 0): /* end reached? */ ((d & REC_MARK) == REC_MARK)) break; lpc = num_to_lpt[d]; /* translate */ @@ -270,7 +270,7 @@ lpt_savctrl = 0x61; /* reset ctrl */ if ((ctrl & K_LIN) == ((ctrl & K_IMM)? 0: K_LIN)) /* space lines? */ return lpt_space (ctrl & K_LCNT, FALSE); chan = lpt_savctrl & K_CHAN; /* basic chan */ -if (lpt_savctrl & K_CH10) { /* chan 10-12? */ +if ((lpt_savctrl & K_CH10) == 0) { /* chan 10-12? */ if (chan == 0) chan = 10; else if (chan == 3) diff --git a/I1620/i1620_pt.c b/I1620/i1620_pt.c index 88323ade..a16dacfd 100644 --- a/I1620/i1620_pt.c +++ b/I1620/i1620_pt.c @@ -1,6 +1,6 @@ /* i1620_pt.c: IBM 1621/1624 paper tape reader/punch simulator - Copyright (c) 2002-2012, Robert M Supnik + Copyright (c) 2002-2013, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,6 +26,8 @@ ptr 1621 paper tape reader ptp 1624 paper tape punch + 21-Dec-13 RMS Fixed translation of paper tape code X0C + 10-Dec-13 RMS Fixed DN wraparound (Bob Armstrong) 19-Mar-12 RMS Fixed declaration of io_stop (Mark Pizzolato) 21-Sep-05 RMS Revised translation tables for 7094/1401 compatibility 25-Apr-03 RMS Revised for extended file support @@ -49,7 +51,7 @@ t_stat ptr_boot (int32 unitno, DEVICE *dptr); t_stat ptr_read (uint8 *c, t_bool ignfeed); t_stat ptp_reset (DEVICE *dptr); t_stat ptp_write (uint32 c); -t_stat ptp_num (uint32 pa, uint32 len); +t_stat ptp_num (uint32 pa, uint32 len, t_bool dump); /* PTR data structures @@ -129,7 +131,7 @@ const int8 ptr_to_num[128] = { 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x10, 0x1E, 0x1F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* XO */ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x00, 0x0E, 0x0F, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* XOC */ + 0x10, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* XOC */ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x00, 0x0E, 0x0F }; @@ -212,7 +214,7 @@ const int8 alp_to_ptp[256] = { t_stat ptr (uint32 op, uint32 pa, uint32 f0, uint32 f1) { -uint32 i; +uint32 i, q = 0; int8 mc; uint8 ptc; t_stat r, sta; @@ -229,6 +231,8 @@ switch (op) { /* case on op */ M[pa] = REC_MARK; /* store rec mark */ return sta; /* done */ } + if (pa == 18976) + q++; if (bad_par[ptc]) { /* bad parity? */ ind[IN_RDCHK] = 1; /* set read check */ if (io_stop) /* set return status */ @@ -389,10 +393,10 @@ t_stat r; switch (op) { /* decode op */ case OP_DN: - return ptp_num (pa, 20000 - (pa % 20000)); /* dump numeric */ + return ptp_num (pa, 20000 - (pa % 20000), TRUE);/* dump numeric */ case OP_WN: - return ptp_num (pa, 0); /* punch numeric */ + return ptp_num (pa, 0, FALSE); /* punch numeric */ case OP_WA: for (i = 0; i < MEMSIZE; i = i + 2) { /* stop runaway */ @@ -456,16 +460,15 @@ return STOP_RWRAP; /* Punch tape numeric - cannot generate parity errors */ -t_stat ptp_num (uint32 pa, uint32 len) +t_stat ptp_num (uint32 pa, uint32 len, t_bool dump) { t_stat r; uint8 d; -uint32 i, end; +uint32 i; -end = pa + len; for (i = 0; i < MEMSIZE; i++) { /* stop runaway */ d = M[pa] & (FLAG | DIGIT); /* get char */ - if (len? (pa >= end): /* dump: end reached? */ + if (dump? (len-- == 0): /* dump: end reached? */ ((d & REC_MARK) == REC_MARK)) /* write: rec mark? */ return ptp_write (PT_EL); /* end record */ r = ptp_write (num_to_ptp[d]); /* write */ diff --git a/I1620/i1620_sys.c b/I1620/i1620_sys.c index e9c501b0..c25e9052 100644 --- a/I1620/i1620_sys.c +++ b/I1620/i1620_sys.c @@ -394,7 +394,7 @@ if (opcode[i].str == NULL) if (I_GETQP (opfl) == I_M_QNP) /* Q no print? */ qmp = 0; -fprintf (of, "%s", opcode[i].str); /* print opcode */ +fprintf (of, "%s", opcode[i].str); /* print opcode */ if (I_GETPP (opfl) == I_M_PP) /* P required? */ fprint_addr (of, ' ', &val[I_P], I_M_QX); else if ((I_GETPP (opfl) == I_M_PCP) && (pmp || qmp)) /* P opt & needed? */ diff --git a/I1620/i1620_tty.c b/I1620/i1620_tty.c index ac4a1021..aefa0ba5 100644 --- a/I1620/i1620_tty.c +++ b/I1620/i1620_tty.c @@ -1,6 +1,6 @@ /* i1620_tty.c: IBM 1620 typewriter - Copyright (c) 2002-2008, Robert M. Supnik + Copyright (c) 2002-2014, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,8 @@ tty console typewriter + 02-Jan-14 RMS Added variable tab stops + 10-Dec-13 RMS Fixed DN wraparound (Bob Armstrong) 21-Sep-05 RMS Revised translation tables for 7094/1401 compatibility 22-Dec-02 RMS Added break test */ @@ -34,6 +36,19 @@ #define TTO_COLMAX 80 int32 tto_col = 0; +uint8 tto_tabs[TTO_COLMAX + 1] = { + 0,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0, + 1 +}; extern uint8 M[MAXMEMSIZE]; extern uint8 ind[NUM_IND]; @@ -44,10 +59,11 @@ void tti_unlock (void); t_stat tti_rnum (int8 *c); t_stat tti_ralp (int8 *c); t_stat tti_read (int8 *c); -t_stat tto_num (uint32 pa, uint32 len); +t_stat tto_num (uint32 pa, uint32 len, t_bool dump); t_stat tto_write (uint32 c); t_stat tty_svc (UNIT *uptr); t_stat tty_reset (DEVICE *dptr); +t_stat tty_set_fixtabs (UNIT *uptr, int32 val, char *cptr, void *desc); /* TTY data structures @@ -64,8 +80,20 @@ REG tty_reg[] = { { NULL } }; +MTAB tty_mod[] = { + { MTAB_XTD|MTAB_VDV, TTO_COLMAX, NULL, "TABS", + &sim_tt_settabs, NULL, (void *) tto_tabs }, + { MTAB_XTD|MTAB_VDV|MTAB_NMO, TTO_COLMAX, "TABS", NULL, + NULL, &sim_tt_showtabs, (void *) tto_tabs }, + { MTAB_XTD|MTAB_VDV, 0, NULL, "NOTABS", + &tty_set_fixtabs, NULL, NULL }, + { MTAB_XTD|MTAB_VDV, 8, NULL, "DEFAULTTABS", + &tty_set_fixtabs, NULL, NULL }, + { 0 } + }; + DEVICE tty_dev = { - "TTY", &tty_unit, tty_reg, NULL, + "TTY", &tty_unit, tty_reg, tty_mod, 1, 10, 31, 1, 8, 7, NULL, NULL, &tty_reset, NULL, NULL, NULL @@ -214,10 +242,10 @@ switch (op) { /* case on op */ break; case OP_DN: - return tto_num (pa, 20000 - (pa % 20000)); /* dump numeric */ + return tto_num (pa, 20000 - (pa % 20000), TRUE);/* dump numeric */ case OP_WN: - return tto_num (pa, 0); /* type numeric */ + return tto_num (pa, 0, FALSE); /* type numeric */ case OP_WA: for (i = 0; i < MEMSIZE; i = i + 2) { /* stop runaway */ @@ -307,16 +335,15 @@ return SCPE_OK; /* Write numerically - cannot generate parity errors */ -t_stat tto_num (uint32 pa, uint32 len) +t_stat tto_num (uint32 pa, uint32 len, t_bool dump) { t_stat r; uint8 d; -uint32 i, end; +uint32 i; -end = pa + len; for (i = 0; i < MEMSIZE; i++) { /* (stop runaway) */ d = M[pa]; /* get char */ - if (len? (pa >= end): /* dump: end reached? */ + if (dump? (len-- == 0): /* dump: end reached? */ ((d & REC_MARK) == REC_MARK)) /* write: rec mark? */ return SCPE_OK; /* end operation */ if (d & FLAG) /* flag? */ @@ -336,23 +363,23 @@ t_stat tto_write (uint32 c) int32 rpt; if (c == '\t') { /* tab? */ - rpt = 8 - (tto_col % 8); /* distance to next */ - tto_col = tto_col + rpt; /* tab over */ - while (rpt-- > 0) /* use spaces */ - sim_putchar (' '); - return SCPE_OK; + for (rpt = tto_col + 1; /* find tab stop */ + (tto_tabs[rpt] == 0) && (rpt <= TTO_COLMAX); + rpt++) ; + for ( ; tto_col < rpt; tto_col++) + sim_putchar (' '); /* use spaces */ } -if (c == '\r') { /* return? */ +else if (c == '\r') { /* return? */ sim_putchar ('\r'); /* crlf */ sim_putchar ('\n'); tto_col = 0; /* clear colcnt */ return SCPE_OK; } -if ((c == '\n') || (c == 007)) { /* non-spacing? */ +else if ((c == '\n') || (c == 007)) { /* non-spacing? */ sim_putchar (c); return SCPE_OK; } -if (c == '\b') /* backspace? */ +else if (c == '\b') /* backspace? */ tto_col = tto_col? tto_col - 1: 0; else tto_col++; /* normal */ if (tto_col > TTO_COLMAX) { /* line wrap? */ @@ -360,7 +387,8 @@ if (tto_col > TTO_COLMAX) { /* line wrap? */ sim_putchar ('\n'); tto_col = 0; } -sim_putchar (c); +if (c != '\t') + sim_putchar (c); return SCPE_OK; } @@ -382,6 +410,7 @@ t_stat tty_reset (DEVICE *dptr) { sim_activate (&tty_unit, tty_unit.wait); /* activate poll */ tto_col = 0; +tto_tabs[TTO_COLMAX] = 1; /* tab stop at limit */ return SCPE_OK; } @@ -392,3 +421,17 @@ void tti_unlock (void) tto_write ('>'); return; } + +/* Set tab stops at fixed modulus */ + +t_stat tty_set_fixtabs (UNIT *uptr, int32 val, char *cptr, void *desc) +{ +int32 i; + +for (i = 0; i < TTO_COLMAX; i++) { + if ((val != 0) && (i != 0) && ((i % val) == 0)) + tto_tabs[i] = 1; + else tto_tabs[i] = 0; + } +return SCPE_OK; +} diff --git a/doc/i1620_doc.doc b/doc/i1620_doc.doc index bdb40704eb5bdc60f2deadef8f244cdcea7feee9..cee20c3744978a9a7f299810a366a53c43c93715 100644 GIT binary patch delta 15865 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 JT#|K;^?&Eryh#86 literal 68096 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 baZ;U0e&;yXb4rcZ7u_kwN&54#E`k3Kk^!4Z diff --git a/sim_console.c b/sim_console.c index f861ffdc..deff8c36 100644 --- a/sim_console.c +++ b/sim_console.c @@ -1,6 +1,6 @@ /* sim_console.c: simulator console I/O library - Copyright (c) 1993-2012, Robert M Supnik + Copyright (c) 1993-2014, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,7 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 02-Jan-14 RMS Added tab stop routines 18-Mar-12 RMS Removed unused reference to sim_switches (Dave Bryan) 07-Dec-11 MP Added sim_ttisatty to support reasonable behaviour (i.e. avoid in infinite loop) in the main command input @@ -75,7 +76,7 @@ 01-Feb-02 RMS Added VAX fix (Robert Alan Byer) 19-Sep-01 RMS More MacOS changes 31-Aug-01 RMS Changed int64 to t_int64 for Windoze - 20-Jul-01 RMS Added Macintosh support (Louis Chretien, Peter Schorn, Ben Supnik) + 20-Jul-01 RMS Added MacOS support (Louis Chretien, Peter Schorn, Ben Supnik) 15-May-01 RMS Added logging support 05-Mar-01 RMS Added clock calibration support 08-Dec-00 BKR Added OS/2 support (Bruce Ray) @@ -1599,6 +1600,59 @@ else c = c & 0377; return c; } +/* Tab stop array handling + + *desc points to a uint8 array of length val + + Columns with tabs set are non-zero; columns without tabs are 0 */ + +t_stat sim_tt_settabs (UNIT *uptr, int32 val, char *cptr, void *desc) +{ +uint8 *temptabs, *tabs = (uint8 *) desc; +int32 i, d; +t_stat r; +char gbuf[CBUFSIZE]; + +if ((cptr == NULL) || (tabs == NULL) || (val <= 1)) + return SCPE_IERR; +if (*cptr == 0) + return SCPE_2FARG; +if ((temptabs = (uint8 *)malloc (val)) == NULL) + return SCPE_MEM; +for (i = 0; i < val; i++) + temptabs[i] = 0; +do { + cptr = get_glyph (cptr, gbuf, ';'); + d = get_uint (gbuf, 10, val, &r); + if ((r != SCPE_OK) || (d == 0)) { + free (temptabs); + return SCPE_ARG; + } + temptabs[d - 1] = 1; + } while (*cptr != 0); +for (i = 0; i < val; i++) + tabs[i] = temptabs[i]; +free (temptabs); +return SCPE_OK; +} + +t_stat sim_tt_showtabs (FILE *st, UNIT *uptr, int32 val, void *desc) +{ +uint8 *tabs = (uint8 *) desc; +int32 i, any; + +if ((st == NULL) || (val == 0) || (desc == NULL)) + return SCPE_IERR; +for (i = any = 0; i < val; i++) { + if (tabs[i] != 0) { + fprintf (st, (any? ";%d": "%d"), i + 1); + any = 1; + } + } +fprintf (st, (any? "\n": "no tabs set\n")); +return SCPE_OK; +} + #if defined(SIM_ASYNCH_IO) && defined(SIM_ASYNCH_MUX) extern pthread_mutex_t sim_tmxr_poll_lock; diff --git a/sim_console.h b/sim_console.h index f33e31ec..a9d02290 100644 --- a/sim_console.h +++ b/sim_console.h @@ -1,6 +1,6 @@ /* sim_console.h: simulator console I/O library headers - Copyright (c) 1993-2008, Robert M Supnik + Copyright (c) 1993-2014, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,7 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 02-Jan-14 RMS Added tab stop routines 17-Jan-11 MP Added buffered line capabilities 22-Jun-06 RMS Implemented SET/SHOW PCHAR 22-Nov-05 RMS Added central input/output conversion support @@ -92,6 +93,8 @@ t_stat sim_ttclose (void); t_bool sim_ttisatty (void); int32 sim_tt_inpcvt (int32 c, uint32 mode); int32 sim_tt_outcvt (int32 c, uint32 mode); +t_stat sim_tt_settabs (UNIT *uptr, int32 val, char *cptr, void *desc); +t_stat sim_tt_showtabs (FILE *st, UNIT *uptr, int32 val, void *desc); extern int32 sim_int_char; /* interrupt character */ extern int32 sim_brk_char; /* break character */