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
This commit is contained in:
parent
c6eef85850
commit
ae8bcecd29
9 changed files with 244 additions and 59 deletions
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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? */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue