Because some key files have changed, V3.0 should be unzipped to a clean directory. 1. New Features in 3.0-0 1.1 SCP and Libraries - Added ASSIGN/DEASSIGN (logical name) commands. - Changed RESTORE to unconditionally detach files. - Added E11 and TPC format support to magtape library. - Fixed bug in SHOW CONNECTIONS. - Added USE_ADDR64 support 1.2 All magtapes - Magtapes support SIMH format, E11 format, and TPC format (read only). - SET <tape_unit> FORMAT=format sets the specified tape unit's format. - SHOW <tape_unit> FORMAT displays the specified tape unit's format. - Tape format can also be set as part of the ATTACH command, using the -F switch. 1.3 VAX - VAX can be compiled without USE_INT64. - If compiled with USE_INT64 and USE_ADDR64, RQ and TQ controllers support files > 2GB. - VAX ROM has speed control (SET ROM DELAY/NODELAY). 2. Bugs Fixed in 3.01-0 2.1 VAX - Fixed CVTfi bug: integer overflow not set if exponent out of range - Fixed EMODx bugs: o First and second operands reversed o Separated fraction received wrong exponent o Overflow calculation on separated integer incorrect o Fraction not set to zero if exponent out of range - Fixed interval timer and ROM access to pass power-up self-test even on very fast host processors (fixes from Mark Pizzolato). 2.2 1401 - Fixed mnemonic, instruction lengths, and reverse scan length check bug for MCS. - Fixed MCE bug, BS off by 1 if zero suppress. - Fixed chaining bug, D lost if return to SCP. - Fixed H branch, branch occurs after continue. - Added check for invalid 8 character MCW, LCA. - Fixed magtape load-mode end of record response. 2.3 Nova - Fixed DSK variable size interaction with restore. 2.4 PDP-1 - Fixed DT variable size interaction with restore. 2.5 PDP-11 - Fixed DT variable size interaction with restore. - Fixed bug in MMR1 update (found by Tim Stark). - Added XQ features and fixed bugs: o Corrected XQ interrupts on IE state transition (code by Tom Evans). o Added XQ interrupt clear on soft reset. o Removed XQ interrupt when setting XL or RL (multiple people). o Added SET/SHOW XQ STATS. o Added SHOW XQ FILTERS. o Added ability to split received packet into multiple buffers. o Added explicit runt and giant packet processing. 2.6 PDP-18B - Fixed DT, RF variable size interaction with restore. - Fixed MT bug in MTTR. 2.7 PDP-8 - Fixed DT, DF, RF, RX variable size interaction with restore. - Fixed MT bug in SKTR. 2.8 HP2100 - Fixed bug in DP (13210A controller only), DQ read status. - Fixed bug in DP, DQ seek complete. 2.9 GRI - Fixed bug in SC queue pointer management. 3. New Features in 3.0 vs prior releases N/A 4. Bugs Fixed in 3.0 vs prior releases N/A 5. General Notes WARNING: The RESTORE command has changed. RESTORE will now detach an attached file on a unit, if that unit did not have an attached file in the saved configuration. This is required to assure that the unit flags and the file state are consistent. WARNING: The compilation scheme for the PDP-10, PDP-11, and VAX has changed. Use one of the supplied build files, or read the documentation carefully, before compiling any of these simulators.
316 lines
8.1 KiB
C
316 lines
8.1 KiB
C
/* ibm1130_stddev.c: IBM 1130 standard I/O devices simulator
|
|
|
|
Based on the SIMH simulator package written by Robert M Supnik
|
|
|
|
Brian Knittel
|
|
|
|
Revision History:
|
|
2002.09.13 - pulled 1132 printer out of this file into ibm1130_prt.c
|
|
|
|
* (C) Copyright 2002, Brian Knittel.
|
|
* You may freely use this program, but: it offered strictly on an AS-IS, AT YOUR OWN
|
|
* RISK basis, there is no warranty of fitness for any purpose, and the rest of the
|
|
* usual yada-yada. Please keep this notice and the copyright in any distributions
|
|
* or modifications.
|
|
*
|
|
* This is not a supported product, but I welcome bug reports and fixes.
|
|
* Mail to sim@ibm1130.org
|
|
*/
|
|
|
|
#include "ibm1130_defs.h"
|
|
|
|
/* ---------------------------------------------------------------------------- */
|
|
|
|
static void badio (char *dev)
|
|
{
|
|
// the real 1130 just ignores attempts to use uninstalled devices. They get tested
|
|
// at times, so it's best to be quiet about this
|
|
// printf("%s I/O is not yet supported", dev);
|
|
// wait_state = WAIT_INVALID_OP;
|
|
}
|
|
|
|
void xio_1134_papertape (int32 addr, int32 func, int32 modify) {badio("papertape");}
|
|
void xio_1627_plotter (int32 addr, int32 func, int32 modify) {badio("plotter");}
|
|
void xio_1231_optical (int32 addr, int32 func, int32 modify) {badio("optical mark");}
|
|
void xio_2501_card (int32 addr, int32 func, int32 modify) {badio("2501 card");}
|
|
void xio_1131_synch (int32 addr, int32 func, int32 modify) {badio("SCA");}
|
|
void xio_system7 (int32 addr, int32 func, int32 modify) {badio("System 7");}
|
|
|
|
/* ---------------------------------------------------------------------------- */
|
|
|
|
static int32 tti_dsw = 0; /* device status words */
|
|
static int32 tto_dsw = 0;
|
|
static int32 con_dsw = 0;
|
|
|
|
static t_stat tti_svc (UNIT *uptr);
|
|
static t_stat tto_svc (UNIT *uptr);
|
|
static t_stat tti_reset (DEVICE *dptr);
|
|
static t_stat tto_reset (DEVICE *dptr);
|
|
|
|
extern t_stat sim_poll_kbd (void);
|
|
extern t_stat sim_wait_kbd (void);
|
|
extern t_stat sim_putchar (int32 out);
|
|
|
|
extern UNIT *sim_clock_queue;
|
|
extern int cgi;
|
|
|
|
#define CSET_MASK 1 /* character set */
|
|
#define CSET_NORMAL 0
|
|
#define CSET_ASCII 1
|
|
|
|
#define IRQ_KEY 0x11 /* ctrl-Q */
|
|
#define PROGRAM_STOP_KEY 0x10 /* ctrl-P */
|
|
|
|
#include "ibm1130_conout.h" /* conout_to_ascii table */
|
|
#include "ibm1130_conin.h" /* ascii_to_conin table */
|
|
|
|
/* TTI data structures
|
|
|
|
tti_dev TTI device descriptor
|
|
tti_unit TTI unit descriptor
|
|
tti_reg TTI register list
|
|
*/
|
|
|
|
UNIT tti_unit = { UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT };
|
|
|
|
REG tti_reg[] = {
|
|
{ ORDATA (BUF, tti_unit.buf, 8) },
|
|
{ ORDATA (DSW, tti_dsw, 16) },
|
|
{ DRDATA (POS, tti_unit.pos, 31), PV_LEFT },
|
|
{ DRDATA (STIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
|
|
{ NULL } };
|
|
|
|
MTAB tti_mod[] = {
|
|
{ CSET_MASK, CSET_NORMAL, NULL, "1130", NULL},
|
|
{ CSET_MASK, CSET_ASCII, NULL, "ASCII", NULL},
|
|
{ 0 } };
|
|
|
|
DEVICE tti_dev = {
|
|
"KEYBOARD", &tti_unit, tti_reg, tti_mod,
|
|
1, 10, 31, 1, 8, 8,
|
|
NULL, NULL, &tti_reset,
|
|
NULL, NULL, NULL };
|
|
|
|
/* TTO data structures
|
|
|
|
tto_dev TTO device descriptor
|
|
tto_unit TTO unit descriptor
|
|
tto_reg TTO register list
|
|
*/
|
|
|
|
UNIT tto_unit = { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT };
|
|
|
|
REG tto_reg[] = {
|
|
{ ORDATA (BUF, tto_unit.buf, 8) },
|
|
{ ORDATA (DSW, tto_dsw, 16) },
|
|
{ DRDATA (POS, tto_unit.pos, 31), PV_LEFT },
|
|
{ DRDATA (STIME, tto_unit.wait, 24), PV_LEFT },
|
|
{ NULL } };
|
|
|
|
MTAB tto_mod[] = {
|
|
{ CSET_MASK, CSET_NORMAL, NULL, "1130", NULL},
|
|
{ CSET_MASK, CSET_ASCII, NULL, "ASCII", NULL},
|
|
{ 0 } };
|
|
|
|
DEVICE tto_dev = {
|
|
"TTO", &tto_unit, tto_reg, tto_mod,
|
|
1, 10, 31, 1, 8, 8,
|
|
NULL, NULL, &tto_reset,
|
|
NULL, NULL, NULL };
|
|
|
|
/* Terminal input routines
|
|
|
|
tti_svc process event (character ready)
|
|
tti_reset process reset
|
|
tto_svc process event (print character)
|
|
tto_reset process reset
|
|
*/
|
|
|
|
#define TT_DSW_PRINTER_RESPONSE 0x8000
|
|
#define TT_DSW_KEYBOARD_RESPONSE 0x4000
|
|
#define TT_DSW_INTERRUPT_REQUEST 0x2000
|
|
#define TT_DSW_KEYBOARD_CONSOLE 0x1000
|
|
#define TT_DSW_PRINTER_BUSY 0x0800
|
|
#define TT_DSW_PRINTER_NOT_READY 0x0400
|
|
#define TT_DSW_KEYBOARD_BUSY 0x0200
|
|
|
|
void xio_1131_console (int32 iocc_addr, int32 func, int32 modify)
|
|
{
|
|
int ch;
|
|
char msg[80];
|
|
|
|
switch (func) {
|
|
case XIO_CONTROL:
|
|
SETBIT(tti_dsw, TT_DSW_KEYBOARD_BUSY);
|
|
keyboard_selected(TRUE);
|
|
// sim_activate(&tti_unit, tti_unit.wait); /* poll keyboard never stops */
|
|
break;
|
|
|
|
case XIO_READ:
|
|
WriteW(iocc_addr, tti_unit.buf);
|
|
CLRBIT(tti_dsw, TT_DSW_KEYBOARD_BUSY);
|
|
keyboard_selected(FALSE);
|
|
break;
|
|
|
|
case XIO_WRITE:
|
|
ch = (ReadW(iocc_addr) >> 8) & 0xFF; /* get character to write */
|
|
|
|
if ((tto_unit.flags & CSET_MASK) == CSET_NORMAL)
|
|
ch = conout_to_ascii[ch]; /* convert to ASCII */
|
|
|
|
if (ch == 0)
|
|
ch = '?'; /* hmmm, unknown character */
|
|
|
|
tto_unit.buf = ch; /* save character to write */
|
|
SETBIT(tto_dsw, TT_DSW_PRINTER_BUSY);
|
|
sim_activate(&tto_unit, tto_unit.wait); /* schedule interrupt */
|
|
break;
|
|
|
|
case XIO_SENSE_DEV:
|
|
ACC = tto_dsw | tti_dsw;
|
|
if (modify & 0x01) { /* reset interrupts */
|
|
CLRBIT(tto_dsw, TT_DSW_PRINTER_RESPONSE);
|
|
CLRBIT(tti_dsw, TT_DSW_KEYBOARD_RESPONSE);
|
|
CLRBIT(ILSW[4], ILSW_4_CONSOLE);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
sprintf(msg, "Invalid console XIO function %x", func);
|
|
xio_error(msg);
|
|
}
|
|
}
|
|
|
|
static void Beep (void) // notify user keyboard was locked or key was bad
|
|
{
|
|
sim_putchar(7);
|
|
}
|
|
|
|
// tti_svc - keyboard polling (never stops)
|
|
|
|
static t_stat tti_svc (UNIT *uptr)
|
|
{
|
|
int32 temp;
|
|
|
|
sim_activate(&tti_unit, tti_unit.wait); /* continue polling */
|
|
|
|
temp = sim_poll_kbd();
|
|
|
|
if (temp < SCPE_KFLAG)
|
|
return temp; /* no char or error? */
|
|
|
|
temp &= 0xFF; /* remove SCPE_KFLAG */
|
|
|
|
if (temp == IRQ_KEY) { /* interrupt request key */
|
|
SETBIT(tti_dsw, TT_DSW_INTERRUPT_REQUEST); /* queue interrupt */
|
|
SETBIT(ILSW[4], ILSW_4_CONSOLE);
|
|
calc_ints();
|
|
|
|
return SCPE_OK;
|
|
}
|
|
|
|
if (temp == PROGRAM_STOP_KEY) { /* simulate the program stop button */
|
|
SETBIT(con_dsw, CPU_DSW_PROGRAM_STOP);
|
|
SETBIT(ILSW[5], ILSW_5_PROGRAM_STOP);
|
|
calc_ints();
|
|
|
|
return SCPE_OK;
|
|
}
|
|
|
|
if (tti_dsw & TT_DSW_KEYBOARD_BUSY) { /* only store character if it was requested (keyboard unlocked) */
|
|
if ((uptr->flags & CSET_MASK) == CSET_NORMAL)
|
|
temp = ascii_to_conin[temp];
|
|
|
|
if (temp == 0) { /* ignore invalid characters */
|
|
Beep();
|
|
calc_ints();
|
|
return SCPE_OK;
|
|
}
|
|
|
|
tti_unit.buf = temp & 0xFFFE; /* save keystroke except last bit (not defined, */
|
|
tti_unit.pos = tti_unit.pos + 1; /* but it lets us distinguish 0 from no punch ' ' */
|
|
|
|
CLRBIT(tti_dsw, TT_DSW_KEYBOARD_BUSY); /* clear busy flag (relock keyboard) */
|
|
keyboard_selected(FALSE);
|
|
|
|
SETBIT(tti_dsw, TT_DSW_KEYBOARD_RESPONSE); /* queue interrupt */
|
|
SETBIT(ILSW[4], ILSW_4_CONSOLE);
|
|
calc_ints();
|
|
}
|
|
else
|
|
Beep();
|
|
|
|
return SCPE_OK;
|
|
}
|
|
|
|
static t_stat tti_reset (DEVICE *dptr)
|
|
{
|
|
tti_unit.buf = 0;
|
|
tti_dsw = 0;
|
|
|
|
CLRBIT(ILSW[4], ILSW_4_CONSOLE);
|
|
calc_ints();
|
|
keyboard_selected(FALSE);
|
|
|
|
sim_activate(&tti_unit, tti_unit.wait); /* always poll keyboard */
|
|
|
|
return SCPE_OK;
|
|
}
|
|
|
|
t_bool keyboard_is_locked (void) /* return TRUE if keyboard is not expecting a character */
|
|
{
|
|
return (tti_dsw & TT_DSW_KEYBOARD_BUSY) == 0;
|
|
}
|
|
|
|
static t_stat tto_svc (UNIT *uptr)
|
|
{
|
|
int32 temp;
|
|
int ch;
|
|
|
|
CLRBIT(tto_dsw, TT_DSW_PRINTER_BUSY);
|
|
SETBIT(tto_dsw, TT_DSW_PRINTER_RESPONSE);
|
|
|
|
SETBIT(ILSW[4], ILSW_4_CONSOLE);
|
|
calc_ints();
|
|
|
|
ch = tto_unit.buf & 0xFF;
|
|
|
|
switch (ch) {
|
|
case IGNR:
|
|
break;
|
|
|
|
case CRLF:
|
|
if (! cgi)
|
|
if ((temp = sim_putchar('\r')) != SCPE_OK)
|
|
return temp;
|
|
if ((temp = sim_putchar('\n')) != SCPE_OK)
|
|
return temp;
|
|
|
|
break;
|
|
|
|
default:
|
|
if ((temp = sim_putchar(ch)) != SCPE_OK)
|
|
return temp;
|
|
|
|
break;
|
|
}
|
|
|
|
tto_unit.pos = tto_unit.pos + 1; /* hmm, why do we count these? */
|
|
|
|
return SCPE_OK;
|
|
}
|
|
|
|
static t_stat tto_reset (DEVICE *dptr)
|
|
{
|
|
tto_unit.buf = 0;
|
|
tto_dsw = 0;
|
|
|
|
CLRBIT(ILSW[4], ILSW_4_CONSOLE);
|
|
calc_ints();
|
|
|
|
sim_cancel(&tto_unit); /* deactivate unit */
|
|
|
|
return SCPE_OK;
|
|
}
|
|
|
|
|