diff --git a/I1620/i1620_cd.c b/I1620/i1620_cd.c index 5d93dcf7..5f539300 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-2013, Robert M. Supnik + Copyright (c) 2002-2015, 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,7 @@ cdr 1622 card reader cdp 1622 card punch + 31-Jan-15 TFM Changes to translation tables (Tom McBride) 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) @@ -107,10 +108,38 @@ DEVICE cdp_dev = { }; /* Data tables. The card reader presents unusual problems. - - Unique codes needed for 11-2-8 (uses !) and 12-7-8 (uses ") . - - Can punch both 11 (-) and 11-0 (uses ]). - On input, the nul and nl generated by C are converted to - spaces; tabs and line feeds are also converted to spaces. + + Some of these translations may seem strange. The 1620 could + read and punch cards numerically (one 1620 storage location + per card column) or alphabetically (two 1620 storage locations + per card column). Even though a card might have contained any + possible character (digit, letter, special character), it + could still be read numerically. In this case, some characters + behaved the same as numbers or as record marks. The results + are well defined in IBM documentation. + + In order to make it possible to prepare card decks for input + using normal text editors, ASCII characters have been assigned + to represent 1620 characters that could appear on cards. In most + cases, this was easy since the letters, digits and punctuation + characters all have equivalent ASCII assignments. Five 1620 + characters do not have equivalent ASCII graphics and are + assigned as follows: + + ] is used to represent a flagged zero + | is used to represent a record mark + ! is used to represent a flagged record mark + } is used to represent a group mark + " is used to represent a flagged group mark + + As a concession to some editors, ASCII nul, nl, tab, and lf + characters are accepted and converted to blanks. Also, for + the same reason, lower case letters are treated the same as + upper case on input. All other ASCII characters not in the + 1620 character set are treated as errors. + + (Tom McBride) + */ /* Card reader (ASCII) to numeric (one digit) */ @@ -119,36 +148,47 @@ const int8 cdr_to_num[128] = { -1, 0x00, 0x00, -1, -1, 0x00, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10 */ -1, -1, -1, -1, -1, -1, -1, -1, - 0x00, 0x1A, 0x0F, 0x0B, 0x1B, 0x0C, 0x00, 0x0C, /* !"#$%&' */ - 0x0C, 0x0C, 0x1C, 0x00, 0x0B, 0x10, 0x1B, 0x01, /* ()*+,-./ */ + 0x00, 0x1A, 0x1F, -1, 0x1B, -1, -1, -1, /* !" $ */ + 0x0C, 0x0C, 0x1C, 0x00, 0x0B, 0x10, 0x0B, 0x01, /* ()*+,-./ */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 01234567 */ - 0x08, 0x09, 0x00, 0x1E, 0x1E, 0x0B, 0x0E, 0x1A, /* 89:;<=>? */ + 0x08, 0x09, -1, -1, -1, 0x0B, -1, -1, /* 89 = */ 0x0C, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* @ABCDEFG */ 0x08, 0x09, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, /* HIJKLMNO */ 0x17, 0x18, 0x19, 0x02, 0x03, 0x04, 0x05, 0x06, /* PQRSTUVW */ - 0x07, 0x08, 0x09, 0x00, 0x0E, 0x10, 0x0A, 0x1F, /* XYZ[\]^_ */ + 0x07, 0x08, 0x09, -1, -1, 0x10, -1, -1, /* XYZ ] */ -1, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* `abcdefg */ 0x08, 0x09, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, /* hijklmno */ 0x17, 0x18, 0x19, 0x02, 0x03, 0x04, 0x05, 0x06, /* pqrstuvw */ - 0x07, 0x08, 0x09, 0x0F, 0x0A, 0x1F, 0x00, -1 /* xyz{|}~ */ + 0x07, 0x08, 0x09, -1, 0x0A, 0x0F, -1, -1 /* xyz |} */ }; /* Numeric (flag + digit) to card punch (ASCII) */ +/* Note that all valid digits produce different + codes except that both numeric blanks and flagged + numeric blanks both produce a blank column. (tfm) */ + const int8 num_to_cdp[32] = { '0', '1', '2', '3', '4', '5', '6', '7', /* 0 */ - '8', '9', '|', ',', ' ', '"', ' ', '"', + '8', '9', '|', -1, ' ', -1, -1, '}', ']', 'J', 'K', 'L', 'M', 'N', 'O', 'P', /* F + 0 */ - 'Q', 'R', '!', '$', -1, -1, -1, '"' + 'Q', 'R', '!', -1, ' ', -1, -1, '"' }; /* Card reader (ASCII) to alphameric (two digits) - 11-2-8 (!) reads as 5A - 11-7-8 (_) reads as 5F - 12-2-8 (?) reads inconsistently (here 02) - 12-6-8 (<) reads inconsistently (here 5E) - 12-7-8 (}) reads as 5F + ] reads as 50 (flagged zero) + | reads as 0A (record mark) + ! reads as 5A (flagged record mark) + } reads as 0F (group mark) + " reads as 5F (flagged group mark) + + As a concession to some editors, ASCII nul, nl, tab, and lf + characters are accepted and converted to blanks. Also, for + the same reason, lower case letters are treated the same as + upper case on input. All other ASCII characters not in the + 1620 character set are treated as errors. + */ const int8 cdr_to_alp[128] = { @@ -156,63 +196,58 @@ const int8 cdr_to_alp[128] = { -1, 0x00, 0x00, -1, -1, 0x00, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10 */ -1, -1, -1, -1, -1, -1, -1, -1, - 0x00, 0x5A, 0x0F, 0x33, 0x13, 0x24, 0x10, 0x34, /* !"#$%&' */ + 0x00, 0x5A, 0x5F, -1, 0x13, -1, -1, -1, /* !" $ */ 0x24, 0x04, 0x14, 0x10, 0x23, 0x20, 0x03, 0x21, /* ()*+,-./ */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 01234567 */ - 0x78, 0x79, 0x70, 0x5E, 0x5E, 0x33, 0x0E, 0x02, /* 89:;<=>? */ + 0x78, 0x79, -1, -1, -1, 0x33, -1, -1, /* 89 = */ 0x34, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* @ABCDEFG */ 0x48, 0x49, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, /* HIJKLMNO */ 0x57, 0x58, 0x59, 0x62, 0x63, 0x64, 0x65, 0x66, /* PQRSTUVW */ - 0x67, 0x68, 0x69, 0x40, 0x0E, 0x50, 0x0A, 0x5F, /* XYZ[\]^_ */ - 0x50, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* `abcdefg */ + 0x67, 0x68, 0x69, -1, -1, 0x50, -1, -1, /* XYZ ] */ + -1, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* abcdefg */ 0x48, 0x49, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, /* hijklmno */ 0x57, 0x58, 0x59, 0x62, 0x63, 0x64, 0x65, 0x66, /* pqrstuvw */ - 0x67, 0x68, 0x69, 0x0F, 0x0A, 0x5F, 0x60, -1 /* xyz{|}~ */ + 0x67, 0x68, 0x69, -1, 0x0A, 0x0F, -1, -1 /* xyz |} */ }; -/* Alphameric (two digits) to card punch (ASCII). Oddities: +/* Alphameric (two digits) to card punch (ASCII). - 02 -> 12-2-8 (?), symmetric - 07 -> 12-7-8 (}), reads as 5F - 12 -> 11-2-8 (!), reads as 5A - 15 -> 11,0 (`), reads as 50 - 22 -> 0-2-8 (|), reads as 0A - 32 -> 2-8 (^), reads as 0A - 5B -> 11-3-8 (=), reads as 13 - 6A -> 0-2-8 (|), reads as 0A - 6B -> 0-3-8 (,), reads as 23 - AA -> 0-2-8 (|), reads as 0A - - 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 + All 1620 compilers are know to punch 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. + or otherwise we won't be able to load the object decks. - 50 - must "punch" as ] (flagged zero) (used to be "_") - 0A - must "punch" as | (record mark) (used to be "'") + 50 - punches as ] (flagged zero) + 0A - punches as | (record mark) + 0F - punches as } (group mark) + + If a program punches alphameric data that includes a flagged + record mark or flagged group mark, they will be punched + as below. No known IBM compiler punches any of these but + some application programs do. The mapping of characters for + the card reader and punch is such that a card deck can be + duplicated with a RACD, WACD loop. + + 5A - punches as ! (flagged record mark) + 5F - punches as " (flagged group mark) */ const int8 alp_to_cdp[256] = { - ' ', -1, '?', '.', ')', -1, -1, '}', /* 00 */ - -1, -1, '|', -1, -1, -1, -1, '"', - '+', -1, '!', '$', '*', ']', -1, -1, /* 10 */ + ' ', -1, -1, '.', ')', -1, -1, -1, /* 00 */ + -1, -1, '|', -1, -1, -1, -1, '}', + '+', -1, -1, '$', '*', -1, -1, -1, /* 10 */ -1, -1, -1, -1, -1, -1, -1, -1, - '-', '/', '|', ',', '(', -1, -1, -1, /* 20 */ + '-', '/', -1, ',', '(', -1, -1, -1, /* 20 */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, '=', '@', -1, -1, -1, /* 30 */ -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, '^', '=', '@', ':', ' ', -1, /* 30 */ - -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 */ - 'Q', 'R', '?', '=', -1, -1, -1, '}', + 'Q', 'R', '!', -1, -1, -1, -1, '"', -1, '/', 'S', 'T', 'U', 'V', 'W', 'X', /* 60 */ - 'Y', 'Z', '|', ',', -1, -1, -1, -1, + 'Y', 'Z', -1, -1, -1, -1, -1, -1, '0', '1', '2', '3', '4', '5', '6', '7', /* 70 */ '8', '9', -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80 */ @@ -220,7 +255,7 @@ const int8 alp_to_cdp[256] = { -1, -1, -1, -1, -1, -1, -1, -1, /* 90 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* A0 */ - -1, -1, '|', -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* B0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* C0 */ @@ -315,7 +350,7 @@ if (feof (cdr_unit.fileref)) /* eof? */ return STOP_NOCD; if (ferror (cdr_unit.fileref)) { /* error? */ ind[IN_RDCHK] = 1; /* set read check */ - perror ("CDR I/O error"); + sim_printf ("CDR I/O error: %s", strerror (errno)); clearerr (cdr_unit.fileref); return SCPE_IOERR; } @@ -331,7 +366,7 @@ if ((i = strlen (cdr_buf)) > 0) { /* anything at all? */ } else { /* line too long */ ind[IN_RDCHK] = 1; - perror ("CDR line too long"); + sim_printf ("CDR line too long"); return SCPE_IOERR; } } @@ -395,12 +430,38 @@ uint8 z, d; switch (op) { /* decode op */ case OP_DN: - return cdp_num (pa, 20000 - (pa % 20000), TRUE);/* dump numeric */ + + /* DN punches all characters the same as WN except that a flagged + zero is punched as a hypehen (-) instead of a flagged + zero ([). Punching begins at the P address and continues until + the last digit of the storage module containing the P address + has been punched. If the amount of data to be punched is an + exact multiple of 80, the operation ends there. If the last + character of the module does not fill out the card, additional + characters from the next higher addresses (addressing wraps to + back to zero if the operation started in the highest module) are + used to fill out the card. (Tom McBride) */ + + return cdp_num (pa, /* dump numeric */ + ((20000 - (pa % 20000) + 79) / 80) * 80, + TRUE); case OP_WN: + + /* WN always punches exactly 80 characters. If the highest address + in the machine is reached before the card is full, addressing + wraps around to zero and continues. The PP function handles + this correctly. (Tom McBride) */ + return cdp_num (pa, CD_LEN, FALSE); /* write numeric */ - case OP_WA: + case OP_WA: /* write alphanumerically */ + + /* WA always punches exactly 80 characters. If the highest address + in the machine is reached before the card is full, addressing + wraps around to zero and continues. The ADDR_A function handles + this correctly. (Tom McBride) */ + for (i = 0; i < CD_LEN; i++) { /* one card */ d = M[pa] & DIGIT; /* get digit pair */ z = M[pa - 1] & DIGIT; @@ -437,8 +498,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)) /* dump? F+0 is diff */ - cdc = '-'; + if (dump && (d == FLAG)) /* dump? F+0 is diff .. */ + cdc = '-'; /* .. punch as hyphen */ else cdc = num_to_cdp[d]; /* translate */ if (cdc < 0) { /* bad char? */ ind[IN_WRCHK] = 1; /* set write check */ @@ -472,7 +533,7 @@ fputs (cdp_buf, cdp_unit.fileref); /* write card */ cdp_unit.pos = ftell (cdp_unit.fileref); /* count char */ if (ferror (cdp_unit.fileref)) { /* error? */ ind[IN_WRCHK] = 1; - perror ("CDP I/O error"); + sim_printf ("CDR I/O error: %s", strerror (errno)); clearerr (cdp_unit.fileref); return SCPE_IOERR; } diff --git a/I1620/i1620_cpu.c b/I1620/i1620_cpu.c index eb294b77..e37562d6 100644 --- a/I1620/i1620_cpu.c +++ b/I1620/i1620_cpu.c @@ -26,6 +26,7 @@ This CPU module incorporates code and comments from the 1620 simulator by Geoff Kuenning, with his permission. + 28-Mar-15 RMS Revised to use sim_printf 26-Mar-15 RMS Separated compare from add/sub flows (Tom McBride) Removed ADD_SIGNC return from add/sub flows 10-Dec-13 RMS Fixed several bugs in add and compare (Bob Armstrong) diff --git a/I1620/i1620_defs.h b/I1620/i1620_defs.h index 5faa1043..521b5a66 100644 --- a/I1620/i1620_defs.h +++ b/I1620/i1620_defs.h @@ -1,6 +1,6 @@ /* i1620_defs.h: IBM 1620 simulator definitions - Copyright (c) 2002-2010, Robert M. Supnik + Copyright (c) 2002-2015, 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"), @@ -27,6 +27,7 @@ I am grateful to Al Kossow, the Computer History Museum, and the IBM Corporate Archives for their help in gathering documentation about the IBM 1620. + 05-Feb-15 TFM Added definitions for flagged RM, GM, NB 22-May-10 RMS Added check for 64b definitions 18-Oct-02 RMS Fixed bug in ADDR_S macro (found by Hans Pufal) */ @@ -158,6 +159,9 @@ #define REC_MARK 0xA #define NUM_BLANK 0xC #define GRP_MARK 0xF +#define FLG_REC_MARK 0x1A +#define FLG_NUM_BLANK 0x1C +#define FLG_GRP_MARK 0x1F #define BAD_DIGIT(x) ((x) > 9) /* Instruction format */ diff --git a/I1620/i1620_dp.c b/I1620/i1620_dp.c index c524eac7..1f908414 100644 --- a/I1620/i1620_dp.c +++ b/I1620/i1620_dp.c @@ -1,6 +1,6 @@ /* i1620_dp.c: IBM 1311 disk simulator - Copyright (c) 2002-2008, Robert M. Supnik + Copyright (c) 2002-2015, 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"), diff --git a/I1620/i1620_lp.c b/I1620/i1620_lp.c index 147b8e8e..aedc55ca 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-2013, Robert M. Supnik + Copyright (c) 2002-2015, 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,7 @@ lpt 1443 line printer + 31-Jan-15 TFM Fixed various problems ... see comments in code 10-Dec-13 RMS Fixed DN wraparound (Bob Armstrong) Fixed test on VFU 10 (Bob Armstrong) 19-Jan-07 RMS Added UNIT_TEXT flag @@ -58,7 +59,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_bool dump); +t_stat lpt_num(uint32 pa, uint32 f1, t_bool dump); /* tfm: length parameter removed, not needed */ t_stat lpt_print (void); t_stat lpt_space (int32 lines, int32 lflag); @@ -101,29 +102,29 @@ DEVICE lpt_dev = { /* Numeric (flag plus digit) to lineprinter (ASCII) */ -const char num_to_lpt[32] = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '|', ' ', '@', ':', ' ', 'G', +const int8 num_to_lpt[32] = { + '0', '1', '2', '3', '4', '5', '6', '7', /* tfm: All invalid char treated as errors */ + '8', '9', '|', -1, '@', -1, -1, 'G', /* tfm: @, G only print on DN; else NB is blank */ '-', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'W', ' ', '*', ' ', -1, 'X' + 'Q', 'R', 'W', -1, '*', -1, -1, 'X' /* tfm: W, *, X only print on DN */ }; /* Alphameric (digit pair) to lineprinter (ASCII) */ -const char alp_to_lpt[256] = { - ' ', -1, '?', '.', ')', -1, -1, -1, /* 00 */ +const int8 alp_to_lpt[256] = { /* tfm: invalid codes 02, 12, 15, 32, 35, 61 removed */ + ' ', -1, -1, '.', ')', -1, -1, -1, /* 00 */ -1, -1, -1, -1, -1, -1, -1, -1, - '+', -1, '!', '$', '*', ' ', -1, -1, /* 10 */ + '+', -1, -1, '$', '*', -1, -1, -1, /* 10 */ -1, -1, -1, -1, -1, -1, -1, -1, '-', '/', '|', ',', '(', -1, -1, -1, /* 20 */ -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, '0', '=', '@', ':', -1, -1, /* 30 */ + -1, -1, -1, '=', '@', -1, -1, -1, /* 30 */ -1, -1, -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 */ 'Q', 'R', -1, -1, -1, -1, -1, -1, - -1, '/', 'S', 'T', 'U', 'V', 'W', 'X', /* 60 */ + -1, -1, 'S', 'T', 'U', 'V', 'W', 'X', /* 60 */ 'Y', 'Z', -1, -1, -1, -1, -1, -1, '0', '1', '2', '3', '4', '5', '6', '7', /* 70 */ '8', '9', -1, -1, -1, -1, -1, -1, @@ -171,10 +172,10 @@ switch (op) { /* decode op */ break; case OP_DN: - return lpt_num (pa, 20000 - (pa % 20000), f1, TRUE); /* dump numeric */ + return lpt_num (pa, f1, TRUE); /* dump numeric (tfm: removed len parm ) */ case OP_WN: - return lpt_num (pa, 0, f1, FALSE); /* write numeric */ + return lpt_num (pa, f1, FALSE); /* write numeric (tfm: removed len parm ) */ case OP_WA: for ( ; lpt_bptr < LPT_BSIZE; lpt_bptr++) { /* only fill buf */ @@ -207,7 +208,7 @@ return SCPE_OK; /* Print numeric */ -t_stat lpt_num (uint32 pa, uint32 len, uint32 f1, t_bool dump) +t_stat lpt_num (uint32 pa, uint32 f1, t_bool dump) /* tfm: removed len parm and reorganized code */ { uint8 d; int8 lpc; @@ -215,17 +216,20 @@ t_stat r, sta; sta = SCPE_OK; for ( ; lpt_bptr < LPT_BSIZE; lpt_bptr++) { /* only fill buf */ - d = M[pa]; /* get digit */ - if (dump? (len-- == 0): /* end reached? */ - ((d & REC_MARK) == REC_MARK)) + d = M[pa]; /* get data char */ + if (!dump && /* not dumping? */ + ((d & REC_MARK) == REC_MARK)) /* quit on RM or GM */ break; - lpc = num_to_lpt[d]; /* translate */ + lpc = num_to_lpt[d]; /* translate digit */ + if (!dump && /* if not dumping */ + ((d & DIGIT) == NUM_BLANK)) /* translate numeric blank */ + lpc = ' '; /* to normal space */ if (lpc < 0) { /* bad char? */ ind[IN_WRCHK] = ind[IN_PRCHK] = 1; /* wr chk */ if (io_stop) /* set return status */ sta = STOP_INVCHR; } - lpt_buf[lpt_bptr++] = lpc & 0x7F; /* fill buffer */ + lpt_buf[lpt_bptr] = lpc & 0x7F; /* put char into buffer (tfm: correct increment)*/ PP (pa); /* incr mem addr */ } if ((f1 & 1) == 0) { /* print now? */ @@ -260,7 +264,7 @@ if (lpt_bptr) { /* any line? */ lpt_buf_init (); /* reinit buf */ if (ferror (lpt_unit.fileref)) { /* error? */ ind[IN_PRCHK] = ind[IN_WRCHK] = 1; /* wr, pri check */ - perror ("LPT I/O error"); + sim_printf ("LPT I/O error: %s", strerror (errno)); clearerr (lpt_unit.fileref); return SCPE_IOERR; } @@ -311,7 +315,7 @@ ind[IN_PRCH9] = CHP (9, cct[cct_ptr]) != 0; /* set indicators */ ind[IN_PRCH12] = CHP (12, cct[cct_ptr]) != 0; if (ferror (lpt_unit.fileref)) { /* error? */ ind[IN_PRCHK] = ind[IN_WRCHK] = 1; /* wr, pri check */ - perror ("LPT I/O error"); + sim_printf ("LPT I/O error: %s", strerror (errno)); clearerr (lpt_unit.fileref); return SCPE_IOERR; } diff --git a/I1620/i1620_pt.c b/I1620/i1620_pt.c index a41084c7..935d0ac2 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-2013, Robert M Supnik + Copyright (c) 2002-2015, 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,9 @@ ptr 1621 paper tape reader ptp 1624 paper tape punch + 23-Feb-15 TFM Fixed RA, RBPT to preserve flags on RM at end (Tom McBride) + 09-Feb-15 TFM Fixed numerous translation problems (Tom McBride) + 09-Feb-15 TFM Fixed pack/unpack errors in binary r/w (Tom McBride) 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) @@ -117,75 +120,73 @@ const int8 bad_par[128] = { /* Paper tape read (7b) to numeric (one digit) */ const int8 ptr_to_num[128] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* - */ - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x00, 0x0E, 0x0F, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* C */ - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x00, 0x0E, 0x0F, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* O */ - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x00, 0x0E, 0x0F, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* OC */ - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x00, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* X */ - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x10, 0x1E, 0x1F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* XC */ - 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, - 0x10, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* XOC */ - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x00, 0x0E, 0x0F + -1, 0x01, 0x02, -1, 0x04, -1, -1, 0x07, /* - */ + 0x08, -1, -1, 0x0B, -1, -1, -1, -1, + 0x00, -1, -1, 0x03, -1, 0x05, 0x06, -1, /* C */ + -1, 0x09, -1, -1, 0x0C, -1, -1, -1, + 0x00, -1, -1, 0x03, -1, 0x05, 0x06, -1, /* O */ + -1, 0x09, 0x0A, -1, 0x0C, -1, -1, 0x0F, + -1, 0x01, 0x02, -1, 0x04, -1, -1, 0x07, /* OC */ + 0x08, -1, -1, 0x0B, -1, -1, -1, -1, + 0x10, -1, -1, 0x13, -1, 0x15, 0x16, -1, /* X */ + -1, 0x19, 0x1A, -1, 0x1C, -1, -1, 0x1F, + -1, 0x11, 0x12, -1, 0x14, -1, -1, 0x17, /* XC */ + 0x18, -1, -1, 0x1B, -1, -1, -1, -1, + -1, 0x01, 0x02, -1, 0x04, -1, -1, 0x07, /* XO */ + 0x08, -1, -1, 0x0B, -1, -1, -1, -1, + 0x10, -1, -1, 0x03, -1, 0x05, 0x06, -1, /* XOC */ + -1, 0x09, 0x0A, -1, 0x0C, -1, -1, -1 /* X0C82 is not defined but will treat as RM (tfm) */ }; -/* Paper tape read (7b) to alphameric (two digits) - Codes XO82, 82, XO842, 842 do not have consistent translations -*/ +/* Paper tape read (7b) to alphameric (two digits) */ const int8 ptr_to_alp[128] = { 0x00, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* - */ - 0x78, 0x79, -1, 0x33, 0x34, 0x70, -1, 0x0F, + 0x78, 0x79, -1, 0x33, 0x34, -1, -1, -1, 0x00, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* C */ - 0x78, 0x79, -1, 0x33, 0x34, 0x70, -1, 0x0F, - 0x70, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* O */ - 0x68, 0x69, 0x0A, 0x23, 0x24, 0x60, 0x0E, 0x0F, - 0x70, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* OC */ - 0x68, 0x69, 0x0A, 0x23, 0x24, 0x60, 0x0E, 0x0F, + 0x78, 0x79, -1, 0x33, 0x34, -1, -1, -1, + 0x70, 0x21, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* O */ + 0x68, 0x69, 0x0A, 0x23, 0x24, -1, -1, 0x0F, + 0x70, 0x21, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* OC */ + 0x68, 0x69, 0x0A, 0x23, 0x24, -1, -1, 0x0F, 0x20, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* X */ - 0x58, 0x59, 0x5A, 0x13, 0x14, 0x50, 0x5E, 0x5F, + 0x58, 0x59, 0x5A, 0x13, 0x14, -1, -1, 0x5F, 0x20, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* XC */ - 0x58, 0x59, 0x5A, 0x13, 0x14, 0x50, 0x5E, 0x5F, + 0x58, 0x59, 0x5A, 0x13, 0x14, -1, -1, 0x5F, 0x10, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* XO */ - 0x48, 0x49, -1, 0x03, 0x04, 0x40, -1, 0x7F, + 0x48, 0x49, -1, 0x03, 0x04, -1, -1, -1, 0x10, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* XOC */ - 0x48, 0x49, -1, 0x03, 0x04, 0x40, -1, 0x7F + 0x48, 0x49, -1, 0x03, 0x04, -1, -1, -1 }; /* Numeric (flag + digit) to paper tape punch */ const int8 num_to_ptp[32] = { 0x20, 0x01, 0x02, 0x13, 0x04, 0x15, 0x16, 0x07, /* 0 */ - 0x08, 0x19, 0x2A, 0x3B, 0x1C, 0x0D, 0x3E, 0x3F, + 0x08, 0x19, 0x2A, -1, 0x1C, -1, -1, 0x2F, 0x40, 0x51, 0x52, 0x43, 0x54, 0x45, 0x46, 0x57, /* F + 0 */ - 0x58, 0x49, 0x4A, 0x5B, 0x4C, 0x5D, 0x5E, 0x4F + 0x58, 0x49, 0x4A, -1, 0x4C, -1, -1, 0x4F }; /* Alphameric (two digits) to paper tape punch */ const int8 alp_to_ptp[256] = { - 0x10, -1, 0x7A, 0x6B, 0x7C, -1, -1, 0x7F, /* 00 */ - -1, -1, 0x2A, -1, -1, -1, -1, 0x1F, - 0x70, -1, 0x4A, 0x5B, 0x4C, -1, -1, -1, /* 10 */ + 0x10, -1, -1, 0x6B, 0x7C, -1, -1, -1, /* 00 */ -1, -1, -1, -1, -1, -1, -1, -1, - 0x40, 0x31, 0x2A, 0x3B, 0x2C, -1, -1, -1, /* 20 */ + 0x70, -1, -1, 0x5B, 0x4C, -1, -1, -1, /* 10 */ -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 0x1A, 0x0B, 0x1C, 0x0D, 0x0E, -1, /* 30 */ + 0x40, 0x31, -1, 0x3B, 0x2C, -1, -1, -1, /* 20 */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 0x0B, 0x1C, -1, -1, -1, /* 30 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x61, 0x62, 0x73, 0x64, 0x75, 0x76, 0x67, /* 40 */ 0x68, 0x79, -1, -1, -1, -1, -1, -1, 0x40, 0x51, 0x52, 0x43, 0x54, 0x45, 0x46, 0x57, /* 50 */ - 0x58, 0x49, 0x4A, -1, -1, -1, -1, 0x4F, - -1, 0x31, 0x32, 0x23, 0x34, 0x25, 0x26, 0x37, /* 60 */ + 0x58, 0x49, -1, -1, -1, -1, -1, -1, + -1, -1, 0x32, 0x23, 0x34, 0x25, 0x26, 0x37, /* 60 */ 0x38, 0x29, -1, -1, -1, -1, -1, -1, 0x20, 0x01, 0x02, 0x13, 0x04, 0x15, 0x16, 0x07, /* 70 */ - 0x08, 0x19, 0x7A, -1, -1, -1, -1, 0x7F, + 0x08, 0x19, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 90 */ @@ -214,7 +215,7 @@ const int8 alp_to_ptp[256] = { t_stat ptr (uint32 op, uint32 pa, uint32 f0, uint32 f1) { -uint32 i, q = 0; +uint32 i = 0; int8 mc; uint8 ptc; t_stat r, sta; @@ -231,15 +232,14 @@ 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? */ + mc = ptr_to_num[ptc]; /* translate char */ + if ((bad_par[ptc]) || (mc < 0)) { /* bad par. or char? */ ind[IN_RDCHK] = 1; /* set read check */ if (io_stop) /* set return status */ sta = STOP_INVCHR; M[pa] = 0; /* store zero */ } - else M[pa] = ptr_to_num[ptc]; /* translate, store */ + else M[pa] = mc; /* stor translated char */ PP (pa); /* incr mem addr */ } break; @@ -250,8 +250,8 @@ switch (op) { /* case on op */ if (r != SCPE_OK) /* error? */ return r; if (ptc & PT_EL) { /* end record? */ - M[pa] = REC_MARK; /* store rec mark */ - M[pa - 1] = 0; + M[pa] = (M[pa] & FLAG) | REC_MARK; /* store alpha RM .. */ + M[pa - 1] = M[pa - 1] & FLAG; /* ..and preserve flags */ return sta; /* done */ } mc = ptr_to_alp[ptc]; /* translate */ @@ -294,8 +294,8 @@ switch (op) { /* case on op */ if (r != SCPE_OK) /* error? */ return r; if (ptc & PT_EL) { /* end record? */ - M[pa] = REC_MARK; /* store rec mark */ - M[pa - 1] = 0; + M[pa] = (M[pa] & FLAG) | REC_MARK; /* store alpha RM .. */ + M[pa - 1] = M[pa - 1] & FLAG; /* ..and preserve flags */ return sta; /* done */ } if (bad_par[ptc]) { /* bad parity? */ @@ -305,7 +305,7 @@ switch (op) { /* case on op */ } M[pa] = (M[pa] & FLAG) | (ptc & 07); /* store 2 digits */ M[pa - 1] = (M[pa - 1] & FLAG) | - (((ptc >> 5) & 06) | ((ptc >> 3) & 1)); + (((ptc >> 4) & 06) | ((ptc >> 3) & 1)); pa = ADDR_A (pa, 2); /* incr mem addr */ } break; @@ -334,7 +334,7 @@ do { if (feof (ptr_unit.fileref)) sim_printf ("PTR end of file\n"); else - sim_printf ("PTR I/O error: %d\n", errno); + sim_printf ("PTR I/O error: %s", strerror (errno)); clearerr (ptr_unit.fileref); return SCPE_IOERR; } @@ -354,13 +354,7 @@ return SCPE_OK; /* Bootstrap routine */ static const uint8 boot_rom[] = { - 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* NOP */ - 3, 6, 0, 0, 0, 3, 1, 0, 0, 3, 0, 0, /* RNPT 31 */ - 2, 5, 0, 0, 0, 7, 1, 0, 0, 0, 0, 0, /* TD 71,loc */ - 3, 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, /* RNPT loc1 */ - 2, 6, 0, 0, 0, 6, 6, 0, 0, 0, 3, 5, /* TF 66,35 */ - 1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* TDM loc2,loc3 */ - 4, 9, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0 /* BR 12 */ + 3, 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, /* RNPT 0 */ }; #define BOOT_START 0 @@ -442,7 +436,7 @@ switch (op) { /* decode op */ z = M[pa - 1] & DIGIT; /* get zone */ if ((d & REC_MARK) == REC_MARK) /* 8-2 char? */ return ptp_write (PT_EL); /* end record */ - ptc = ((z & 06) << 5) | ((z & 01) << 3) | (d & 07); + ptc = ((z & 06) << 4) | ((z & 01) << 3) | (d & 07); if (bad_par[ptc]) /* set parity */ ptc = ptc | PT_C; r = ptp_write (ptc); /* write char */ @@ -466,13 +460,19 @@ t_stat ptp_num (uint32 pa, uint32 len, t_bool dump) t_stat r; uint8 d; uint32 i; +int8 ptc; for (i = 0; i < MEMSIZE; i++) { /* stop runaway */ d = M[pa] & (FLAG | DIGIT); /* get char */ 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 */ + ptc = num_to_ptp[d]; /* translate digit */ + if (ptc < 0) { /* bad char? */ + ind[IN_WRCHK] = 1; /* write check */ + CRETIOE(io_stop, STOP_INVCHR); + } + r = ptp_write(ptc); /* write char */ if (r != SCPE_OK) /* error? */ return r; PP (pa); /* incr mem addr */ @@ -490,7 +490,7 @@ if ((ptp_unit.flags & UNIT_ATT) == 0) { /* attached? */ } if (putc (c, ptp_unit.fileref) == EOF) { /* write char */ ind[IN_WRCHK] = 1; /* error? */ - perror ("PTP I/O error"); + sim_printf ("PTP I/O error: %s", strerror (errno)); clearerr (ptp_unit.fileref); return SCPE_IOERR; } diff --git a/I1620/i1620_sys.c b/I1620/i1620_sys.c index f7e8c7bb..c2543bca 100644 --- a/I1620/i1620_sys.c +++ b/I1620/i1620_sys.c @@ -1,6 +1,6 @@ /* i1620_sys.c: IBM 1620 simulator interface - Copyright (c) 2002-2008, Robert M. Supnik + Copyright (c) 2002-2015, 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"), diff --git a/I1620/i1620_tty.c b/I1620/i1620_tty.c index bf5d53b4..d2a029cf 100644 --- a/I1620/i1620_tty.c +++ b/I1620/i1620_tty.c @@ -1,6 +1,6 @@ /* i1620_tty.c: IBM 1620 typewriter - Copyright (c) 2002-2014, Robert M. Supnik + Copyright (c) 2002-2015, 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 + 21-Feb-15 TFM Option to provide single digit numeric output + 05-Feb-15 TFM Changes to translate tables and valid input char. 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 @@ -33,7 +35,11 @@ #include "i1620_defs.h" +#define NUM_1_DIGIT TRUE /* Indicate numeric output will use single digit format (tfm) */ + #define TTO_COLMAX 80 +#define UF_V_1DIG (UNIT_V_UF) +#define UF_1DIG (1 << UF_V_1DIG) int32 tto_col = 0; uint8 tto_tabs[TTO_COLMAX + 1] = { @@ -89,6 +95,8 @@ MTAB tty_mod[] = { &tty_set_fixtabs, NULL, NULL }, { MTAB_XTD|MTAB_VDV, 8, NULL, "DEFAULTTABS", &tty_set_fixtabs, NULL, NULL }, + { UF_1DIG, UF_1DIG, "combined digits and flags", "1DIGIT", NULL }, + { UF_1DIG, 0 , "separate digits and flags", "2DIGIT", NULL }, { 0 } }; @@ -103,7 +111,39 @@ DEVICE tty_dev = { /* Keyboard to numeric */ -const char *tti_to_num = "0123456789|=@:;}"; +/* The following constant is a list of valid 1620 numeric characters + that can be entered from the keyboard. They are the digits 0-9, + record mark(|), numeric blank(@) and group mark(}). All others + are cosidered invalid. When entering data, these characters may + all be preceeded by tilde(~) or accent(`) to indicate that the + following character should be entered into storage with a flag. + + Alternatively, ] can be entered for flagged 0, + J-R or j-r can be entered for flagged 1-9, + ! for flagged RM, * for flagged numeric blank, + " for flagged GM. + + These different methods of entering numeric data represent + compromises since there is no practical way to exactly emulate + the 1620 typewriter capability of entering a flag but not + spacing the carriage. Entering a flag symbol in front of a + character is easier and sometimes more readable; using the + letters j-r is useful if column alignment is important on + the screen or when copying data that has printed letters in + place of flagged digits. This also matches the output of WN + or DN to the line printer. + + *tti_to_num is the string of valid characters + tti_position_to_internal[] are the matching internal codes + (Tom McBride)*/ + +const char *tti_to_num = "0123456789|@}]jklmnopqr!*\"JKLMNOPQR"; +const char tti_position_to_internal[35] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, REC_MARK, NUM_BLANK, GRP_MARK, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + FLG_REC_MARK, FLG_NUM_BLANK, FLG_GRP_MARK, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19 +}; /* Keyboard to alphameric (digit pair) - translates LC to UC */ @@ -112,43 +152,55 @@ const int8 tti_to_alp[128] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10 */ -1, -1, -1, -1, -1, -1, -1, -1, - 0x00, 0x02, -1, 0x33, 0x13, 0x24, 0x10, 0x34, /* !"#$%&' */ + 0x00, 0x5A, 0x5F, -1, 0x13, -1, -1, -1, /* !"#$%&' */ 0x24, 0x04, 0x14, 0x10, 0x23, 0x20, 0x03, 0x21, /* ()*+,-./ */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 01234567 */ 0x78, 0x79, -1, -1, -1, 0x33, -1, -1, /* 89:;<=>? */ 0x34, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* @ABCDEFG */ 0x48, 0x49, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, /* HIJKLMNO */ 0x57, 0x58, 0x59, 0x62, 0x63, 0x64, 0x65, 0x66, /* PQRSTUVW */ - 0x67, 0x68, 0x69, -1, -1, -1, -1, -1, /* XYZ[\]^_ */ + 0x67, 0x68, 0x69, -1, -1, 0x50, -1, -1, /* XYZ[\]^_ */ -1, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* `abcdefg */ 0x48, 0x49, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, /* hijklmno */ 0x57, 0x58, 0x59, 0x62, 0x63, 0x64, 0x65, 0x66, /* pqrstuvw */ - 0x67, 0x68, 0x69, -1, -1, 0x0F, -1, -1 /* xyz{|}~ */ + 0x67, 0x68, 0x69, -1, 0x0A, 0x0F, -1, -1 /* xyz{|}~ */ }; /* Numeric (digit) to typewriter */ -const char num_to_tto[16] = { +/* Digits with values of 11, 13 and 14 should never occur and will be typed as :'s + if they ever do. These are really errors. (Tom McBride) */ + +/* If flagged digits are being printed with preceeding ` characters only the first + half of this table is actually used. If digits are being printed one char per + digit the whole table is used. (Tom McBride) */ + +const char num_to_tto[32] = { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '|', '=', '@', ':', ';', '}' + '8', '9', '|', ':', '@', ':', ':', '}', + + ']', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', '!', ':', '*', ':', ':', '"' }; /* Alphameric (digit pair) to typewriter */ +/* Characters not in 1620 set have been removed from table (tfm) */ + const char alp_to_tto[256] = { - ' ', -1, '?', '.', ')', -1, -1, -1, /* 00 */ + ' ', -1, -1, '.', ')', -1, -1, -1, /* 00 */ -1, -1, -1, -1, -1, -1, -1, -1, - '+', -1, '!', '$', '*', ' ', -1, -1, /* 10 */ + '+', -1, -1, '$', '*', -1, -1, -1, /* 10 */ -1, -1, -1, -1, -1, -1, -1, -1, - '-', '/', '|', ',', '(', -1, -1, -1, /* 20 */ + '-', '/', -1, ',', '(', -1, -1, -1, /* 20 */ -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, '0', '=', '@', ':', -1, -1, /* 30 */ + -1, -1, -1, '=', '@', -1, -1, -1, /* 30 */ -1, -1, -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 */ 'Q', 'R', -1, -1, -1, -1, -1, -1, - -1, '/', 'S', 'T', 'U', 'V', 'W', 'X', /* 60 */ + -1, -1, 'S', 'T', 'U', 'V', 'W', 'X', /* 60 */ 'Y', 'Z', -1, -1, -1, -1, -1, -1, '0', '1', '2', '3', '4', '5', '6', '7', /* 70 */ '8', '9', -1, -1, -1, -1, -1, -1, @@ -250,7 +302,7 @@ switch (op) { /* case on op */ case OP_WA: for (i = 0; i < MEMSIZE; i = i + 2) { /* stop runaway */ d = M[pa] & DIGIT; /* get digit */ - if ((d & 0xA) == REC_MARK) /* 8-2 char? done */ + if ((d & REC_MARK) == REC_MARK) /* 8-2 char? done */ return sta; d = ((M[pa - 1] & DIGIT) << 4) | d; /* get digit pair */ ttc = alp_to_tto[d]; /* translate */ @@ -276,7 +328,7 @@ return STOP_RWRAP; t_stat tti_rnum (int8 *c) { int8 raw, flg = 0; -char *cp; +const char *cp; t_stat r; *c = -1; /* no char yet */ @@ -288,8 +340,8 @@ do { *c = 0x7F; else if ((raw == '~') || (raw == '`')) /* flag? mark */ flg = FLAG; - else if ((cp = strchr (tti_to_num, raw))) /* legal? */ - *c = ((int8) (cp - tti_to_num)) | flg; /* assemble char */ + else if ((cp = strchr (tti_to_num, raw)) != 0) /* legal? */ + *c = tti_position_to_internal[(cp - tti_to_num)] | flg; /* assemble char */ else raw = 007; /* beep! */ tto_write (raw); /* echo */ } while (*c == -1); @@ -346,10 +398,14 @@ for (i = 0; i < MEMSIZE; i++) { /* (stop runaway) */ if (dump? (len-- == 0): /* dump: end reached? */ ((d & REC_MARK) == REC_MARK)) /* write: rec mark? */ return SCPE_OK; /* end operation */ - if (d & FLAG) /* flag? */ - tto_write ('`'); - r = tto_write (num_to_tto[d & DIGIT]); /* write */ - if (r != SCPE_OK) /* error? */ + if (tty_unit.flags & UF_1DIG) /* how display flagged digits? */ + r = tto_write (num_to_tto[d]); /* single digit display */ + else { + if (d & FLAG) /* flag? */ + tto_write ('`'); /* write flag indicator */ + r = tto_write (num_to_tto[d & DIGIT]); /* write the digit */ + } + if (r != SCPE_OK) /* write error? */ return r; PP (pa); /* incr mem addr */ }