RESTRICTION: The HP DS disk is not debugged. DO NOT enable this feature for normal operations. WARNING: Massive changes in the PDP-11 make all previous SAVEd file obsolete. Do not attempt to use a PDP-11 SAVE file from a prior release with V3.3! 1. New Features in 3.3 1.1 SCP - Added -p (powerup) qualifier to RESET - Changed SET <unit> ONLINE/OFFLINE to SET <unit> ENABLED/DISABLED - Moved SET DEBUG under SET CONSOLE hierarchy - Added optional parameter value to SHOW command - Added output file option to SHOW command 1.2 PDP-11 - Separated RH Massbus adapter from RP controller - Added TU tape support - Added model emulation framework - Added model details 1.3 VAX - Separated out CVAX-specific features from core instruction simulator - Implemented capability for CIS, octaword, compatibility mode instructions - Added instruction display and parse for compatibility mode - Changed SET CPU VIRTUAL=n to SHOW CPU VIRTUAL=n - Added =n optional parameter to SHOW CPU HISTORY 1.4 Unibus/Qbus simulators (PDP-11, VAX, PDP-10) - Simplified DMA API's - Modified DMA peripherals to use simplified API's 1.5 HP2100 (all changes from Dave Bryan) CPU - moved MP into its own device; added MP option jumpers - modified DMA to allow disabling - modified SET CPU 2100/2116 to truncate memory > 32K - added -F switch to SET CPU to force memory truncation - modified WRU to be REG_HRO - added BRK and DEL to save console settings DR - provided protected tracks and "Writing Enabled" status bit - added "parity error" status return on writes for 12606 - added track origin test for 12606 - added SCP test for 12606 - added "Sector Flag" status bit - added "Read Inhibit" status bit for 12606 - added TRACKPROT modifier LPS - added SET OFFLINE/ONLINE, POWEROFF/POWERON - added fast/realistic timing - added debug printouts LPT - added SET OFFLINE/ONLINE, POWEROFF/POWERON PTR - added paper tape loop mode, DIAG/READER modifiers to PTR - added PV_LEFT to PTR TRLLIM register CLK - modified CLK to permit disable 1.6 IBM 1401, IBM 1620, Interdata 16b, SDS 940, PDP-10 - Added instruction history 1.7 H316, PDP-15, PDP-8 - Added =n optional value to SHOW CPU HISTORY 2. Bugs Fixed in 3.3 2.1 SCP - Fixed comma-separated SET options (from Dave Bryan) - Fixed duplicate HELP displays with user-specified commands 2.2 PDP-10 - Replicated RP register state per drive - Fixed TU to set FCE on short record - Fixed TU to return bit<15> in drive type - Fixed TU format specification, 1:0 are don't cares - Fixed TU handling of TMK status - Fixed TU handling of DONE, ATA at end of operation - Implemented TU write check 2.3 PDP-11 - Replicated RP register state per drive - Fixed RQ, TQ to report correct controller type and stage 1 configuration flags on a Unibus system - Fixed HK CS2<output_ready> flag 2.4 VAX - Fixed parsing of indirect displacement modes in instruction input 2.5 HP2100 (all fixes from Dave Bryan) CPU - fixed S-register behavior on 2116 - fixed LIx/MIx behavior for DMA on 2116 and 2100 - fixed LIx/MIx behavior for empty I/O card slots DP - fixed enable/disable from either device - fixed ANY ERROR status for 12557A interface - fixed unattached drive status for 12557A interface - status cmd without prior STC DC now completes (12557A) - OTA/OTB CC on 13210A interface also does CLC CC - fixed RAR model - fixed seek check on 13210 if sector out of range DQ - fixed enable/disable from either device - shortened xtime from 5 to 3 (drive avg 156KW/second) - fixed not ready/any error status - fixed RAR model DR - fixed enable/disable from either device - fixed sector return in status word - fixed DMA last word write, incomplete sector fill value - fixed 12610 SFC operation - fixed current-sector determination IPL - fixed enable/disable from either device LPS - fixed status returns for error conditions - fixed handling of non-printing characters - fixed handling of characters after column 80 - improved timing model accuracy for RTE LPT - fixed status returns for error conditions - fixed TOF handling so form remains on line 0 SYS - fixed display of CCA/CCB/CCE instructions 2.5 PDP-15 FPP - fixed URFST to mask low 9b of fraction - fixed exception PC setting
347 lines
11 KiB
C
347 lines
11 KiB
C
/* i1620_tty.c: IBM 1620 typewriter
|
||
|
||
Copyright (c) 2002-2004, 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"),
|
||
to deal in the Software without restriction, including without limitation
|
||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||
and/or sell copies of the Software, and to permit persons to whom the
|
||
Software is furnished to do so, subject to the following conditions:
|
||
|
||
The above copyright notice and this permission notice shall be included in
|
||
all copies or substantial portions of the Software.
|
||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
||
Except as contained in this notice, the name of Robert M Supnik shall not
|
||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||
in this Software without prior written authorization from Robert M Supnik.
|
||
|
||
tty console typewriter
|
||
|
||
22-Dec-02 RMS Added break test
|
||
*/
|
||
|
||
#include "i1620_defs.h"
|
||
|
||
#define TTO_COLMAX 80
|
||
|
||
int32 tto_col = 0;
|
||
|
||
extern uint8 M[MAXMEMSIZE];
|
||
extern uint8 ind[NUM_IND];
|
||
extern UNIT cpu_unit;
|
||
extern uint32 io_stop;
|
||
|
||
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_write (uint32 c);
|
||
t_stat tty_svc (UNIT *uptr);
|
||
t_stat tty_reset (DEVICE *dptr);
|
||
|
||
/* TTY data structures
|
||
|
||
tty_dev TTY device descriptor
|
||
tty_unit TTY unit descriptor
|
||
tty_reg TTY register list
|
||
*/
|
||
|
||
UNIT tty_unit = { UDATA (&tty_svc, 0, 0), KBD_POLL_WAIT };
|
||
|
||
REG tty_reg[] = {
|
||
{ DRDATA (COL, tto_col, 7) },
|
||
{ DRDATA (TIME, tty_unit.wait, 24), REG_NZ + PV_LEFT },
|
||
{ NULL } };
|
||
|
||
DEVICE tty_dev = {
|
||
"TTY", &tty_unit, tty_reg, NULL,
|
||
1, 10, 31, 1, 8, 7,
|
||
NULL, NULL, &tty_reset,
|
||
NULL, NULL, NULL };
|
||
|
||
/* Data tables */
|
||
|
||
/* Keyboard to numeric */
|
||
|
||
const char *tti_to_num = "0123456789'=@:;\"";
|
||
|
||
/* Keyboard to alphameric (digit pair) - translates LC to UC */
|
||
|
||
const int8 tti_to_alp[128] = {
|
||
-1, -1, -1, -1, -1, -1, -1, -1, /* 00 */
|
||
-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, 0x0F, -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[\]^_ */
|
||
-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, -1, -1, -1 }; /* xyz */
|
||
|
||
/* Numeric (digit) to typewriter */
|
||
|
||
const char num_to_tto[16] = {
|
||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||
'8', '9', '\'', '=', '@', ':', ';', '"' };
|
||
|
||
/* Alphameric (digit pair) to typewriter */
|
||
|
||
const char alp_to_tto[256] = {
|
||
' ', -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, -1, -1, -1, -1,
|
||
-1, -1, '0', '=', '@', ':', -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 */
|
||
'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 */
|
||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||
-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, /* B0 */
|
||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||
-1, -1, -1, -1, -1, -1, -1, -1, /* C0 */
|
||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||
-1, -1, -1, -1, -1, -1, -1, -1, /* D0 */
|
||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||
-1, -1, -1, -1, -1, -1, -1, -1, /* E0 */
|
||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||
-1, -1, -1, -1, -1, -1, -1, -1, /* F0 */
|
||
-1, -1, -1, -1, -1, -1, -1, -1 };
|
||
|
||
/* Terminal IO
|
||
|
||
- On input, parity errors cannot occur.
|
||
- On input, release-start does NOT cause a record mark to be stored.
|
||
- On output, invalid characters type an invalid character and set WRCHK.
|
||
If IO stop is set, the system halts at the end of the operation.
|
||
*/
|
||
|
||
t_stat tty (uint32 op, uint32 pa, uint32 f0, uint32 f1)
|
||
{
|
||
t_addr i;
|
||
uint8 d;
|
||
int8 ttc;
|
||
t_stat r, inv = SCPE_OK;
|
||
|
||
switch (op) { /* case on op */
|
||
case OP_K: /* control */
|
||
switch (f1) { /* case on control */
|
||
case 1: /* space */
|
||
tto_write (' ');
|
||
break;
|
||
case 2: /* return */
|
||
tto_write ('\r');
|
||
break;
|
||
case 3: /* backspace */
|
||
if ((cpu_unit.flags & IF_MII) == 0) return STOP_INVFNC;
|
||
tto_write ('\b');
|
||
break;
|
||
case 4: /* index */
|
||
if ((cpu_unit.flags & IF_MII) == 0) return STOP_INVFNC;
|
||
tto_write ('\n');
|
||
break;
|
||
case 8: /* tab */
|
||
tto_write ('\t');
|
||
break;
|
||
default:
|
||
return STOP_INVFNC; }
|
||
return SCPE_OK;
|
||
case OP_RN: /* read numeric */
|
||
tti_unlock (); /* unlock keyboard */
|
||
for (i = 0; i < MEMSIZE; i++) { /* (stop runaway) */
|
||
r = tti_rnum (&ttc); /* read char */
|
||
if (r != SCPE_OK) return r; /* error? */
|
||
if (ttc == 0x7F) return SCPE_OK; /* end record? */
|
||
M[pa] = ttc & (FLAG | DIGIT); /* store char */
|
||
PP (pa); } /* incr mem addr */
|
||
break;
|
||
case OP_RA: /* read alphameric */
|
||
tti_unlock ();
|
||
for (i = 0; i < MEMSIZE; i = i + 2) { /* (stop runaway) */
|
||
r = tti_ralp (&ttc); /* read char */
|
||
if (r != SCPE_OK) return r; /* error? */
|
||
if (ttc == 0x7F) return SCPE_OK; /* end record? */
|
||
M[pa] = (M[pa] & FLAG) | (ttc & DIGIT); /* store 2 digits */
|
||
M[pa - 1] = (M[pa - 1] & FLAG) | ((ttc >> 4) & DIGIT);
|
||
pa = ADDR_A (pa, 2); } /* incr mem addr */
|
||
break;
|
||
case OP_DN:
|
||
return tto_num (pa, 20000 - (pa % 20000)); /* dump numeric */
|
||
case OP_WN:
|
||
return tto_num (pa, 0); /* type numeric */
|
||
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? */
|
||
CRETIOE (io_stop, inv); /* end record */
|
||
d = ((M[pa - 1] & DIGIT) << 4) | d; /* get digit pair */
|
||
ttc = alp_to_tto[d]; /* translate */
|
||
if (ttc < 0) { /* bad char? */
|
||
ind[IN_WRCHK] = 1; /* set write check */
|
||
inv = STOP_INVCHR; } /* set return status */
|
||
tto_write (ttc & 0x7F); /* write */
|
||
pa = ADDR_A (pa, 2); } /* incr mem addr */
|
||
break;
|
||
default: /* invalid function */
|
||
return STOP_INVFNC; }
|
||
return STOP_RWRAP;
|
||
}
|
||
|
||
/* Read numerically - cannot generate parity errors */
|
||
|
||
t_stat tti_rnum (int8 *c)
|
||
{
|
||
int8 raw, flg = 0;
|
||
char *cp;
|
||
t_stat r;
|
||
|
||
*c = -1; /* no char yet */
|
||
do { r = tti_read (&raw); /* get char */
|
||
if (r != SCPE_OK) return r; /* error? */
|
||
if (raw == '\r') *c = 0x7F; /* return? mark */
|
||
else if (raw == '~') flg = FLAG; /* flag? mark */
|
||
else if (cp = strchr (tti_to_num, raw)) /* legal? */
|
||
*c = ((int8) (cp - tti_to_num)) | flg; /* assemble char */
|
||
else raw = 007; /* beep! */
|
||
tto_write (raw); } /* echo */
|
||
while (*c == -1);
|
||
return SCPE_OK;
|
||
}
|
||
|
||
/* Read alphamerically - cannot generate parity errors */
|
||
|
||
t_stat tti_ralp (int8 *c)
|
||
{
|
||
int8 raw;
|
||
t_stat r;
|
||
|
||
*c = -1; /* no char yet */
|
||
do { r = tti_read (&raw); /* get char */
|
||
if (r != SCPE_OK) return r; /* error? */
|
||
if (raw == '\r') *c = 0x7F; /* return? mark */
|
||
else if (tti_to_alp[raw] >= 0) /* legal char? */
|
||
*c = tti_to_alp[raw]; /* xlate */
|
||
else raw = 007; /* beep! */
|
||
tto_write (raw); } /* echo */
|
||
while (*c == -1);
|
||
return SCPE_OK;
|
||
}
|
||
|
||
/* Read from keyboard */
|
||
|
||
t_stat tti_read (int8 *c)
|
||
{
|
||
int32 t;
|
||
|
||
do { t = sim_poll_kbd (); } /* get character */
|
||
while ((t == SCPE_OK) || (t & SCPE_BREAK)); /* ignore break */
|
||
if (t < SCPE_KFLAG) return t; /* error? */
|
||
*c = t & 0177; /* store character */
|
||
return SCPE_OK;
|
||
}
|
||
|
||
/* Write numerically - cannot generate parity errors */
|
||
|
||
t_stat tto_num (uint32 pa, uint32 len)
|
||
{
|
||
t_stat r;
|
||
uint8 d;
|
||
uint32 i, end;
|
||
|
||
end = pa + len;
|
||
for (i = 0; i < MEMSIZE; i++) { /* (stop runaway) */
|
||
d = M[pa]; /* get char */
|
||
if (len? (pa >= end): /* dump: end reached? */
|
||
((d & REC_MARK) == REC_MARK)) /* write: rec mark? */
|
||
return SCPE_OK; /* end operation */
|
||
if (d & FLAG) tto_write ('~'); /* flag? */
|
||
r = tto_write (num_to_tto[d & DIGIT]); /* write */
|
||
if (r != SCPE_OK) return r; /* error? */
|
||
PP (pa); } /* incr mem addr */
|
||
return STOP_RWRAP;
|
||
}
|
||
|
||
/* Write, maintaining position */
|
||
|
||
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) sim_putchar (' '); /* use spaces */
|
||
return SCPE_OK; }
|
||
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? */
|
||
sim_putchar (c);
|
||
return SCPE_OK; }
|
||
if (c == '\b') tto_col = tto_col? tto_col - 1: 0; /* backspace? */
|
||
else tto_col++; /* normal */
|
||
if (tto_col > TTO_COLMAX) { /* line wrap? */
|
||
sim_putchar ('\r');
|
||
sim_putchar ('\n');
|
||
tto_col = 0; }
|
||
sim_putchar (c);
|
||
return SCPE_OK;
|
||
}
|
||
|
||
/* Unit service - polls for WRU */
|
||
|
||
t_stat tty_svc (UNIT *uptr)
|
||
{
|
||
int32 temp;
|
||
|
||
sim_activate (&tty_unit, tty_unit.wait); /* continue poll */
|
||
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */
|
||
return SCPE_OK;
|
||
}
|
||
|
||
/* Reset routine */
|
||
|
||
t_stat tty_reset (DEVICE *dptr)
|
||
{
|
||
sim_activate (&tty_unit, tty_unit.wait); /* activate poll */
|
||
tto_col = 0;
|
||
return SCPE_OK;
|
||
}
|
||
|
||
/* TTI unlock - signals that we are ready for keyboard input */
|
||
|
||
void tti_unlock (void)
|
||
{
|
||
tto_write ('`');
|
||
return;
|
||
}
|