simh v2.7
This commit is contained in:
parent
89bcd020e1
commit
654937fc88
67 changed files with 4214 additions and 1693 deletions
|
@ -30,7 +30,6 @@ extern unsigned int32 get_uint (char *cptr, int32 radix, unsigned int32 max,
|
||||||
sim_PC pointer to saved PC register descriptor
|
sim_PC pointer to saved PC register descriptor
|
||||||
sim_emax number of words needed for examine
|
sim_emax number of words needed for examine
|
||||||
sim_devices array of pointers to simulated devices
|
sim_devices array of pointers to simulated devices
|
||||||
sim_consoles array of pointers to consoles (if more than one)
|
|
||||||
sim_stop_messages array of pointers to stop messages
|
sim_stop_messages array of pointers to stop messages
|
||||||
sim_load binary loader
|
sim_load binary loader
|
||||||
*/
|
*/
|
||||||
|
@ -44,8 +43,6 @@ int32 sim_emax = 4;
|
||||||
DEVICE *sim_devices[] = { &cpu_dev, &sio_dev, &ptr_dev,
|
DEVICE *sim_devices[] = { &cpu_dev, &sio_dev, &ptr_dev,
|
||||||
&ptp_dev, &dsk_dev, NULL };
|
&ptp_dev, &dsk_dev, NULL };
|
||||||
|
|
||||||
UNIT *sim_consoles = NULL;
|
|
||||||
|
|
||||||
const char *sim_stop_messages[] = {
|
const char *sim_stop_messages[] = {
|
||||||
"Unknown error",
|
"Unknown error",
|
||||||
"Unknown I/O Instruction",
|
"Unknown I/O Instruction",
|
||||||
|
|
438
dec_dz.h
Normal file
438
dec_dz.h
Normal file
|
@ -0,0 +1,438 @@
|
||||||
|
/* dec_dz.c: DZ11 terminal multiplexor simulator
|
||||||
|
|
||||||
|
Copyright (c) 2001, 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.
|
||||||
|
|
||||||
|
Based on the original DZ11 simulator by Thord Nilson, as updated by
|
||||||
|
Arthur Krewat.
|
||||||
|
|
||||||
|
dz DZ11 terminal multiplexor
|
||||||
|
|
||||||
|
20-Oct-01 RMS Moved getchar from sim_tmxr, changed interrupt
|
||||||
|
logic to use tmxr_rqln
|
||||||
|
06-Oct-01 RMS Fixed bug in carrier detect logic
|
||||||
|
03-Oct-01 RMS Added support for BSD-style "ringless" modems
|
||||||
|
27-Sep-01 RMS Fixed bug in xmte initialization
|
||||||
|
17-Sep-01 RMS Added separate autodisconnect switch
|
||||||
|
16-Sep-01 RMS Fixed modem control bit offsets
|
||||||
|
|
||||||
|
This file is intended to be included in a shell routine that invokes
|
||||||
|
a simulator definition file:
|
||||||
|
|
||||||
|
pdp11_dz.c = pdp11_defs.h + dec_dz.h
|
||||||
|
pdp10_dz.c = pdp10_defs.h + dec_dz.h
|
||||||
|
vax_dz.c = vax_defs.h + dec_dz.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sim_sock.h"
|
||||||
|
#include "sim_tmxr.h"
|
||||||
|
|
||||||
|
#define DZ_LNOMASK (DZ_LINES - 1) /* mask for lineno */
|
||||||
|
#define DZ_LMASK ((1 << DZ_LINES) - 1) /* mask of lines */
|
||||||
|
#define DZ_SILO_ALM 16 /* silo alarm level */
|
||||||
|
|
||||||
|
/* DZCSR - 160100 - control/status register */
|
||||||
|
|
||||||
|
#define CSR_MAINT 0000010 /* maint - NI */
|
||||||
|
#define CSR_CLR 0000020 /* clear */
|
||||||
|
#define CSR_MSE 0000040 /* master scan enb */
|
||||||
|
#define CSR_RIE 0000100 /* rcv int enb */
|
||||||
|
#define CSR_RDONE 0000200 /* rcv done - RO */
|
||||||
|
#define CSR_V_TLINE 8 /* xmit line - RO */
|
||||||
|
#define CSR_TLINE (DZ_LNOMASK << CSR_V_TLINE)
|
||||||
|
#define CSR_SAE 0010000 /* silo alm enb */
|
||||||
|
#define CSR_SA 0020000 /* silo alm - RO */
|
||||||
|
#define CSR_TIE 0040000 /* xmit int enb */
|
||||||
|
#define CSR_TRDY 0100000 /* xmit rdy - RO */
|
||||||
|
#define CSR_RW (CSR_MSE | CSR_RIE | CSR_SAE | CSR_TIE)
|
||||||
|
#define CSR_MBZ (0004003 | CSR_CLR | CSR_MAINT)
|
||||||
|
|
||||||
|
#define CSR_GETTL(x) (((x) >> CSR_V_TLINE) & DZ_LNOMASK)
|
||||||
|
#define CSR_PUTTL(x,y) x = ((x) & ~CSR_TLINE) | (((y) & DZ_LNOMASK) << CSR_V_TLINE)
|
||||||
|
|
||||||
|
/* DZRBUF - 160102 - receive buffer, read only */
|
||||||
|
|
||||||
|
#define RBUF_CHAR 0000377 /* rcv char */
|
||||||
|
#define RBUF_V_RLINE 8 /* rcv line */
|
||||||
|
#define RBUF_PARE 0010000 /* parity err - NI */
|
||||||
|
#define RBUF_FRME 0020000 /* frame err - NI */
|
||||||
|
#define RBUF_OVRE 0040000 /* overrun err - NI */
|
||||||
|
#define RBUF_VALID 0100000 /* rcv valid */
|
||||||
|
#define RBUF_MBZ 0004000
|
||||||
|
|
||||||
|
/* DZLPR - 160102 - line parameter register, write only, word access only */
|
||||||
|
|
||||||
|
#define LPR_V_LINE 0 /* line */
|
||||||
|
#define LPR_LPAR 0007770 /* line pars - NI */
|
||||||
|
#define LPR_RCVE 0010000 /* receive enb */
|
||||||
|
#define LPR_GETLN(x) (((x) >> LPR_V_LINE) & DZ_LNOMASK)
|
||||||
|
|
||||||
|
/* DZTCR - 160104 - transmission control register */
|
||||||
|
|
||||||
|
#define TCR_V_XMTE 0 /* xmit enables */
|
||||||
|
#define TCR_V_DTR 8 /* DTRs */
|
||||||
|
|
||||||
|
/* DZMSR - 160106 - modem status register, read only */
|
||||||
|
|
||||||
|
#define MSR_V_RI 0 /* ring indicators */
|
||||||
|
#define MSR_V_CD 8 /* carrier detect */
|
||||||
|
|
||||||
|
/* DZTDR - 160106 - transmit data, write only */
|
||||||
|
|
||||||
|
#define TDR_CHAR 0000377 /* xmit char */
|
||||||
|
#define TDR_V_TBR 8 /* xmit break - NI */
|
||||||
|
|
||||||
|
extern int32 IREQ (HLVL);
|
||||||
|
extern int32 sim_switches;
|
||||||
|
extern FILE *sim_log;
|
||||||
|
extern int32 tmxr_poll; /* calibrated delay */
|
||||||
|
int32 dz_csr = 0; /* csr */
|
||||||
|
int32 dz_rbuf = 0; /* rcv buffer */
|
||||||
|
int32 dz_lpr = 0; /* line param */
|
||||||
|
int32 dz_tcr = 0; /* xmit control */
|
||||||
|
int32 dz_msr = 0; /* modem status */
|
||||||
|
int32 dz_tdr = 0; /* xmit data */
|
||||||
|
int32 dz_mctl = 0; /* modem ctrl enabled */
|
||||||
|
int32 dz_auto = 0; /* autodiscon enabled */
|
||||||
|
int32 dz_sa_enb = 1; /* silo alarm enabled */
|
||||||
|
int32 dz_enb = 1; /* device enable */
|
||||||
|
TMLN dz_ldsc[DZ_LINES] = { /* line descriptors */
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 },
|
||||||
|
{ 0 }, { 0 }, { 0 }, { 0 } };
|
||||||
|
TMXR dz_desc = { /* mux descriptor */
|
||||||
|
DZ_LINES, 0,
|
||||||
|
&dz_ldsc[0], &dz_ldsc[1], &dz_ldsc[2], &dz_ldsc[3],
|
||||||
|
&dz_ldsc[4], &dz_ldsc[5], &dz_ldsc[6], &dz_ldsc[7] };
|
||||||
|
|
||||||
|
t_stat dz_svc (UNIT *uptr);
|
||||||
|
t_stat dz_reset (DEVICE *dptr);
|
||||||
|
t_stat dz_attach (UNIT *uptr, char *cptr);
|
||||||
|
t_stat dz_detach (UNIT *uptr);
|
||||||
|
t_stat dz_clear (t_bool flag);
|
||||||
|
int32 dz_getchar (TMXR *mp);
|
||||||
|
void dz_update_rcvi (void);
|
||||||
|
void dz_update_xmti (void);
|
||||||
|
t_stat dz_status (UNIT *uptr, FILE *st);
|
||||||
|
|
||||||
|
/* DZ data structures
|
||||||
|
|
||||||
|
dz_dev DZ device descriptor
|
||||||
|
dz_unit DZ unit list
|
||||||
|
dz_reg DZ register list
|
||||||
|
*/
|
||||||
|
|
||||||
|
UNIT dz_unit = { UDATA (&dz_svc, UNIT_ATTABLE, 0) };
|
||||||
|
|
||||||
|
REG dz_reg[] = {
|
||||||
|
{ ORDATA (CSR, dz_csr, 16) },
|
||||||
|
{ ORDATA (RBUF, dz_rbuf, 16) },
|
||||||
|
{ ORDATA (LPR, dz_lpr, 16) },
|
||||||
|
{ ORDATA (TCR, dz_tcr, 16) },
|
||||||
|
{ ORDATA (MSR, dz_msr, 16) },
|
||||||
|
{ ORDATA (TDR, dz_tdr, 16) },
|
||||||
|
{ FLDATA (SAENB, dz_sa_enb, 0) },
|
||||||
|
{ FLDATA (MDMCTL, dz_mctl, 0) },
|
||||||
|
{ FLDATA (AUTODS, dz_auto, 0) },
|
||||||
|
{ DRDATA (RPOS0, dz_ldsc[0].rxcnt, 32), PV_LEFT+REG_RO },
|
||||||
|
{ DRDATA (TPOS0, dz_ldsc[0].txcnt, 32), PV_LEFT+REG_RO },
|
||||||
|
{ DRDATA (RPOS1, dz_ldsc[1].rxcnt, 32), PV_LEFT+REG_RO },
|
||||||
|
{ DRDATA (TPOS1, dz_ldsc[1].txcnt, 32), PV_LEFT+REG_RO },
|
||||||
|
{ DRDATA (RPOS2, dz_ldsc[2].rxcnt, 32), PV_LEFT+REG_RO },
|
||||||
|
{ DRDATA (TPOS2, dz_ldsc[2].txcnt, 32), PV_LEFT+REG_RO },
|
||||||
|
{ DRDATA (RPOS3, dz_ldsc[3].rxcnt, 32), PV_LEFT+REG_RO },
|
||||||
|
{ DRDATA (TPOS3, dz_ldsc[3].txcnt, 32), PV_LEFT+REG_RO },
|
||||||
|
{ DRDATA (RPOS4, dz_ldsc[4].rxcnt, 32), PV_LEFT+REG_RO },
|
||||||
|
{ DRDATA (TPOS4, dz_ldsc[4].txcnt, 32), PV_LEFT+REG_RO },
|
||||||
|
{ DRDATA (RPOS5, dz_ldsc[5].rxcnt, 32), PV_LEFT+REG_RO },
|
||||||
|
{ DRDATA (TPOS5, dz_ldsc[5].txcnt, 32), PV_LEFT+REG_RO },
|
||||||
|
{ DRDATA (RPOS6, dz_ldsc[6].rxcnt, 32), PV_LEFT+REG_RO },
|
||||||
|
{ DRDATA (TPOS6, dz_ldsc[6].txcnt, 32), PV_LEFT+REG_RO },
|
||||||
|
{ DRDATA (RPOS7, dz_ldsc[7].rxcnt, 32), PV_LEFT+REG_RO },
|
||||||
|
{ DRDATA (TPOS7, dz_ldsc[7].txcnt, 32), PV_LEFT+REG_RO },
|
||||||
|
{ FLDATA (*DEVENB, dz_enb, 0) },
|
||||||
|
{ NULL } };
|
||||||
|
|
||||||
|
MTAB dz_mod[] = {
|
||||||
|
{ UNIT_ATT, UNIT_ATT, "line status:", NULL, &dz_status },
|
||||||
|
{ 0 } };
|
||||||
|
|
||||||
|
DEVICE dz_dev = {
|
||||||
|
"DZ", &dz_unit, dz_reg, dz_mod,
|
||||||
|
1, 8, 13, 1, 8, 8,
|
||||||
|
&tmxr_ex, &tmxr_dep, &dz_reset,
|
||||||
|
NULL, &dz_attach, &dz_detach };
|
||||||
|
|
||||||
|
/* IO dispatch routines, I/O addresses 17760100 - 17760107 */
|
||||||
|
|
||||||
|
t_stat dz_rd (int32 *data, int32 PA, int32 access)
|
||||||
|
{
|
||||||
|
switch ((PA >> 1) & 03) { /* case on PA<2:1> */
|
||||||
|
case 00: /* CSR */
|
||||||
|
*data = dz_csr = dz_csr & ~CSR_MBZ;
|
||||||
|
break;
|
||||||
|
case 01: /* RBUF */
|
||||||
|
dz_csr = dz_csr & ~CSR_SA; /* clr silo alarm */
|
||||||
|
if (dz_csr & CSR_MSE) { /* scanner on? */
|
||||||
|
dz_rbuf = dz_getchar (&dz_desc); /* get top of silo */
|
||||||
|
if (!dz_rbuf) dz_sa_enb = 1; /* empty? re-enable */
|
||||||
|
tmxr_poll_rx (&dz_desc); /* poll input */
|
||||||
|
dz_update_rcvi (); } /* update rx intr */
|
||||||
|
else { dz_rbuf = 0; /* no data */
|
||||||
|
dz_update_rcvi (); } /* no rx intr */
|
||||||
|
*data = dz_rbuf;
|
||||||
|
break;
|
||||||
|
case 02: /* TCR */
|
||||||
|
*data = dz_tcr;
|
||||||
|
break;
|
||||||
|
case 03: /* MSR */
|
||||||
|
*data = dz_msr;
|
||||||
|
break; }
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat dz_wr (int32 data, int32 PA, int32 access)
|
||||||
|
{
|
||||||
|
int32 i, line;
|
||||||
|
TMLN *lp;
|
||||||
|
|
||||||
|
switch ((PA >> 1) & 03) { /* case on PA<2:1> */
|
||||||
|
case 00: /* CSR */
|
||||||
|
if (access == WRITEB) data = (PA & 1)?
|
||||||
|
(dz_csr & 0377) | (data << 8): (dz_csr & ~0377) | data;
|
||||||
|
if (data & CSR_CLR) dz_clear (FALSE);
|
||||||
|
if (data & CSR_MSE) sim_activate (&dz_unit, tmxr_poll);
|
||||||
|
else { sim_cancel (&dz_unit);
|
||||||
|
dz_csr = dz_csr & ~(CSR_SA | CSR_RDONE | CSR_TRDY); }
|
||||||
|
if ((data & CSR_RIE) == 0) CLR_INT (DZRX);
|
||||||
|
else if (((dz_csr & CSR_IE) == 0) && /* RIE 0->1? */
|
||||||
|
((dz_csr & CSR_SAE)? (dz_csr & CSR_SA): (dz_csr & CSR_RDONE)))
|
||||||
|
SET_INT (DZRX);
|
||||||
|
if ((data & CSR_TIE) == 0) CLR_INT (DZTX);
|
||||||
|
else if (((dz_csr & CSR_TIE) == 0) && (dz_csr & CSR_TRDY))
|
||||||
|
SET_INT (DZTX);
|
||||||
|
dz_csr = (dz_csr & ~CSR_RW) | (data & CSR_RW);
|
||||||
|
break;
|
||||||
|
case 01: /* LPR */
|
||||||
|
dz_lpr = data;
|
||||||
|
line = LPR_GETLN (dz_lpr); /* get line */
|
||||||
|
lp = dz_desc.ldsc[line]; /* get line desc */
|
||||||
|
if (dz_lpr & LPR_RCVE) lp -> rcve = 1; /* rcv enb? on */
|
||||||
|
else lp -> rcve = 0; /* else line off */
|
||||||
|
tmxr_poll_rx (&dz_desc); /* poll input */
|
||||||
|
dz_update_rcvi (); /* update rx intr */
|
||||||
|
break;
|
||||||
|
case 02: /* TCR */
|
||||||
|
if (access == WRITEB) data = (PA & 1)?
|
||||||
|
(dz_tcr & 0377) | (data << 8): (dz_tcr & ~0377) | data;
|
||||||
|
if (dz_mctl) { /* modem ctl? */
|
||||||
|
dz_msr = dz_msr | ((data & 0177400) & /* dcd |= dtr & ring */
|
||||||
|
((dz_msr & DZ_LMASK) << MSR_V_CD));
|
||||||
|
dz_msr = dz_msr & ~(data >> TCR_V_DTR); /* ring = ring & ~dtr */
|
||||||
|
if (dz_auto) { /* auto disconnect? */
|
||||||
|
int32 drop;
|
||||||
|
drop = (dz_tcr & ~data) >> TCR_V_DTR; /* drop = dtr & ~data */
|
||||||
|
for (i = 0; i < DZ_LINES; i++) { /* drop hangups */
|
||||||
|
lp = dz_desc.ldsc[i]; /* get line desc */
|
||||||
|
if (lp -> conn && (drop & (1 << i))) {
|
||||||
|
tmxr_msg (lp -> conn, "\r\nLine hangup\r\n");
|
||||||
|
tmxr_reset_ln (lp); /* reset line, cdet */
|
||||||
|
dz_msr = dz_msr & ~(1 << (i + MSR_V_CD));
|
||||||
|
} /* end if drop */
|
||||||
|
} /* end for */
|
||||||
|
} /* end if auto */
|
||||||
|
} /* end if modem */
|
||||||
|
dz_tcr = data;
|
||||||
|
tmxr_poll_tx (&dz_desc); /* poll output */
|
||||||
|
dz_update_xmti (); /* update int */
|
||||||
|
break;
|
||||||
|
case 03: /* TDR */
|
||||||
|
if (PA & 1) { /* odd byte? */
|
||||||
|
dz_tdr = (dz_tdr & 0377) | (data << 8); /* just save */
|
||||||
|
break; }
|
||||||
|
dz_tdr = data;
|
||||||
|
if (dz_csr & CSR_MSE) { /* enabled? */
|
||||||
|
line = CSR_GETTL (dz_csr); /* get xmit line */
|
||||||
|
lp = dz_desc.ldsc[line]; /* get line desc */
|
||||||
|
tmxr_putc_ln (lp, dz_tdr & 0177); /* store char */
|
||||||
|
tmxr_poll_tx (&dz_desc); /* poll output */
|
||||||
|
dz_update_xmti (); } /* update int */
|
||||||
|
break; }
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unit service routine
|
||||||
|
|
||||||
|
The DZ11 polls to see if asynchronous activity has occurred and now
|
||||||
|
needs to be processed. The polling interval is controlled by the clock
|
||||||
|
simulator, so for most environments, it is calibrated to real time.
|
||||||
|
Typical polling intervals are 50-60 times per second.
|
||||||
|
*/
|
||||||
|
|
||||||
|
t_stat dz_svc (UNIT *uptr)
|
||||||
|
{
|
||||||
|
int32 newln;
|
||||||
|
|
||||||
|
if (dz_csr & CSR_MSE) { /* enabled? */
|
||||||
|
newln = tmxr_poll_conn (&dz_desc, uptr); /* poll connect */
|
||||||
|
if ((newln >= 0) && dz_mctl) { /* got a live one? */
|
||||||
|
if (dz_tcr & (1 << (newln + TCR_V_DTR))) /* DTR set? */
|
||||||
|
dz_msr = dz_msr | (1 << (newln + MSR_V_CD));
|
||||||
|
else dz_msr = dz_msr | (1 << newln); } /* set ring */
|
||||||
|
tmxr_poll_rx (&dz_desc); /* poll input */
|
||||||
|
dz_update_rcvi (); /* upd rcv intr */
|
||||||
|
tmxr_poll_tx (&dz_desc); /* poll output */
|
||||||
|
dz_update_xmti (); /* upd xmt intr */
|
||||||
|
sim_activate (uptr, tmxr_poll); } /* reactivate */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get first available character, if any */
|
||||||
|
|
||||||
|
int32 dz_getchar (TMXR *mp)
|
||||||
|
{
|
||||||
|
int32 i, val;
|
||||||
|
|
||||||
|
for (i = val = 0; (i < mp -> lines) && (val == 0); i++) { /* loop thru lines */
|
||||||
|
val = tmxr_getc_ln (mp -> ldsc[i]); /* test for input */
|
||||||
|
if (val) val = val | (i << RBUF_V_RLINE); /* or in line # */
|
||||||
|
} /* end for */
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update receive interrupts */
|
||||||
|
|
||||||
|
void dz_update_rcvi (void)
|
||||||
|
{
|
||||||
|
int32 i, scnt;
|
||||||
|
TMLN *lp;
|
||||||
|
|
||||||
|
for (i = scnt = 0; i < DZ_LINES; i++) { /* poll lines */
|
||||||
|
lp = dz_desc.ldsc[i]; /* get line desc */
|
||||||
|
scnt = scnt + tmxr_rqln (lp); /* sum buffers */
|
||||||
|
if (dz_mctl && !lp -> conn) /* if disconn */
|
||||||
|
dz_msr = dz_msr & ~(1 << (i + MSR_V_CD)); /* reset car det */
|
||||||
|
}
|
||||||
|
if (scnt && (dz_csr & CSR_MSE)) { /* input & enabled? */
|
||||||
|
dz_csr = dz_csr | CSR_RDONE; /* set done */
|
||||||
|
if (dz_sa_enb && (scnt >= DZ_SILO_ALM)) { /* alm enb & cnt hi? */
|
||||||
|
dz_csr = dz_csr | CSR_SA; /* set status */
|
||||||
|
dz_sa_enb = 0; } } /* disable alarm */
|
||||||
|
else dz_csr = dz_csr & ~CSR_RDONE; /* no, clear done */
|
||||||
|
if ((dz_csr & CSR_RIE) && /* int enable */
|
||||||
|
((dz_csr & CSR_SAE)? (dz_csr & CSR_SA): (dz_csr & CSR_RDONE)))
|
||||||
|
SET_INT (DZRX); /* and alm/done? */
|
||||||
|
else CLR_INT (DZRX); /* no, clear int */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update transmit interrupts */
|
||||||
|
|
||||||
|
void dz_update_xmti (void)
|
||||||
|
{
|
||||||
|
int32 linemask, i, j;
|
||||||
|
|
||||||
|
linemask = dz_tcr & DZ_LMASK; /* enabled lines */
|
||||||
|
dz_csr = dz_csr & ~CSR_TRDY; /* assume not rdy */
|
||||||
|
for (i = 0, j = CSR_GETTL (dz_csr); i < DZ_LINES; i++) {
|
||||||
|
j = (j + 1) & DZ_LNOMASK;
|
||||||
|
if ((linemask & (1 << j)) && dz_desc.ldsc[j] -> xmte) {
|
||||||
|
CSR_PUTTL (dz_csr, j); /* update CSR */
|
||||||
|
dz_csr = dz_csr | CSR_TRDY; /* set xmt rdy */
|
||||||
|
break; } }
|
||||||
|
if ((dz_csr & CSR_TIE) && (dz_csr & CSR_TRDY)) /* ready plus int? */
|
||||||
|
SET_INT (DZTX);
|
||||||
|
else CLR_INT (DZTX); /* no int req */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Device reset */
|
||||||
|
|
||||||
|
t_stat dz_clear (t_bool flag)
|
||||||
|
{
|
||||||
|
int32 i;
|
||||||
|
|
||||||
|
dz_csr = 0; /* clear CSR */
|
||||||
|
dz_rbuf = 0; /* silo empty */
|
||||||
|
dz_lpr = 0; /* no params */
|
||||||
|
if (flag) dz_tcr = 0; /* INIT? clr all */
|
||||||
|
else dz_tcr = dz_tcr & ~0377; /* else save dtr */
|
||||||
|
dz_tdr = 0;
|
||||||
|
dz_sa_enb = 1;
|
||||||
|
CLR_INT (DZRX);
|
||||||
|
CLR_INT (DZTX);
|
||||||
|
sim_cancel (&dz_unit); /* no polling */
|
||||||
|
for (i = 0; i < DZ_LINES; i++) {
|
||||||
|
if (!dz_desc.ldsc[i] -> conn) dz_desc.ldsc[i] -> xmte = 1;
|
||||||
|
dz_desc.ldsc[i] -> rcve = 0; } /* clr rcv enb */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat dz_reset (DEVICE *dptr)
|
||||||
|
{
|
||||||
|
return dz_clear (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attach */
|
||||||
|
|
||||||
|
t_stat dz_attach (UNIT *uptr, char *cptr)
|
||||||
|
{
|
||||||
|
t_stat r;
|
||||||
|
extern int32 sim_switches;
|
||||||
|
|
||||||
|
dz_mctl = dz_auto = 0; /* modem ctl off */
|
||||||
|
r = tmxr_attach (&dz_desc, uptr, cptr); /* attach mux */
|
||||||
|
if (r != SCPE_OK) return r; /* error? */
|
||||||
|
if (sim_switches & SWMASK ('M')) { /* modem control? */
|
||||||
|
dz_mctl = 1;
|
||||||
|
printf ("Modem control activated\n");
|
||||||
|
if (sim_log) fprintf (sim_log, "Modem control activated\n");
|
||||||
|
if (sim_switches & SWMASK ('A')) { /* autodisconnect? */
|
||||||
|
dz_auto = 1;
|
||||||
|
printf ("Auto disconnect activated\n");
|
||||||
|
if (sim_log) fprintf (sim_log, "Auto disconnect activated\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Detach */
|
||||||
|
|
||||||
|
t_stat dz_detach (UNIT *uptr)
|
||||||
|
{
|
||||||
|
return tmxr_detach (&dz_desc, uptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Status */
|
||||||
|
|
||||||
|
t_stat dz_status (UNIT *uptr, FILE *st)
|
||||||
|
{
|
||||||
|
int32 i;
|
||||||
|
|
||||||
|
for (i = 0; (i < DZ_LINES) && (dz_desc.ldsc[i] -> conn == 0); i++) ;
|
||||||
|
if (i < DZ_LINES) {
|
||||||
|
for (i = 0; i < DZ_LINES; i++) {
|
||||||
|
if (dz_desc.ldsc[i] -> conn)
|
||||||
|
tmxr_fstatus (st, dz_desc.ldsc[i], i); } }
|
||||||
|
else fprintf (st, " all disconnected");
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
|
@ -27,6 +27,8 @@
|
||||||
ptp 316/516-52 paper tape punch
|
ptp 316/516-52 paper tape punch
|
||||||
tty 316/516-33 teleprinter
|
tty 316/516-33 teleprinter
|
||||||
clk/options 316/516-12 real time clocks/internal options
|
clk/options 316/516-12 real time clocks/internal options
|
||||||
|
|
||||||
|
07-Sep-01 RMS Moved function prototypes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "h316_defs.h"
|
#include "h316_defs.h"
|
||||||
|
@ -54,9 +56,6 @@ t_stat tto_svc (UNIT *uptr);
|
||||||
t_stat tty_reset (DEVICE *dptr);
|
t_stat tty_reset (DEVICE *dptr);
|
||||||
t_stat clk_svc (UNIT *uptr);
|
t_stat clk_svc (UNIT *uptr);
|
||||||
t_stat clk_reset (DEVICE *dptr);
|
t_stat clk_reset (DEVICE *dptr);
|
||||||
extern t_stat sim_poll_kbd (void);
|
|
||||||
extern t_stat sim_putchar (int32 out);
|
|
||||||
extern t_bool hp_setdev (UNIT *uptr, int32 val);
|
|
||||||
|
|
||||||
/* PTR data structures
|
/* PTR data structures
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
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
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
17-Sep-01 RMS Removed multiconsole support
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "h316_defs.h"
|
#include "h316_defs.h"
|
||||||
|
@ -42,7 +44,6 @@ extern int32 sim_switches;
|
||||||
sim_PC pointer to saved PC register descriptor
|
sim_PC pointer to saved PC register descriptor
|
||||||
sim_emax maximum number of words for examine/deposit
|
sim_emax maximum number of words for examine/deposit
|
||||||
sim_devices array of pointers to simulated devices
|
sim_devices array of pointers to simulated devices
|
||||||
sim_consoles array of pointers to consoles (if more than one)
|
|
||||||
sim_stop_messages array of pointers to stop messages
|
sim_stop_messages array of pointers to stop messages
|
||||||
sim_load binary loader
|
sim_load binary loader
|
||||||
*/
|
*/
|
||||||
|
@ -59,8 +60,6 @@ DEVICE *sim_devices[] = { &cpu_dev,
|
||||||
&clk_dev,
|
&clk_dev,
|
||||||
NULL };
|
NULL };
|
||||||
|
|
||||||
UNIT *sim_consoles = NULL;
|
|
||||||
|
|
||||||
const char *sim_stop_messages[] = {
|
const char *sim_stop_messages[] = {
|
||||||
"Unknown error",
|
"Unknown error",
|
||||||
"Unimplemented instruction",
|
"Unimplemented instruction",
|
||||||
|
|
|
@ -175,3 +175,8 @@ struct hpdev {
|
||||||
|
|
||||||
#define IOT_V_REASON 16
|
#define IOT_V_REASON 16
|
||||||
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* stop on error */
|
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* stop on error */
|
||||||
|
|
||||||
|
/* Function prototypes */
|
||||||
|
|
||||||
|
t_bool hp_setdev (UNIT *uptr, int32 val);
|
||||||
|
t_bool hp_setdev2 (UNIT *uptr, int32 val);
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
dp 12557A cartridge disk system
|
dp 12557A cartridge disk system
|
||||||
|
|
||||||
|
07-Sep-01 RMS Moved function prototypes
|
||||||
29-Nov-00 RMS Made variable names unique
|
29-Nov-00 RMS Made variable names unique
|
||||||
21-Nov-00 RMS Fixed flag, buffer power up state
|
21-Nov-00 RMS Fixed flag, buffer power up state
|
||||||
*/
|
*/
|
||||||
|
@ -125,7 +126,6 @@ t_stat dpc_detach (UNIT *uptr);
|
||||||
t_stat dpd_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
|
t_stat dpd_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
|
||||||
t_stat dpd_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
|
t_stat dpd_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
|
||||||
void dp_go (int32 fnc, int32 drv, int32 time, int32 attdev);
|
void dp_go (int32 fnc, int32 drv, int32 time, int32 attdev);
|
||||||
extern t_bool hp_setdev2 (UNIT *uptr, int32 val);
|
|
||||||
|
|
||||||
/* DPD data structures
|
/* DPD data structures
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
lpt 12653A line printer
|
lpt 12653A line printer
|
||||||
|
|
||||||
|
07-Sep-01 RMS Moved function prototypes
|
||||||
21-Nov-00 RMS Fixed flag, fbf power up state
|
21-Nov-00 RMS Fixed flag, fbf power up state
|
||||||
Added command flop
|
Added command flop
|
||||||
15-Oct-00 RMS Added variable device number support
|
15-Oct-00 RMS Added variable device number support
|
||||||
|
@ -42,7 +43,6 @@ int32 lpt_stopioe = 0; /* stop on error */
|
||||||
t_stat lpt_svc (UNIT *uptr);
|
t_stat lpt_svc (UNIT *uptr);
|
||||||
t_stat lpt_reset (DEVICE *dptr);
|
t_stat lpt_reset (DEVICE *dptr);
|
||||||
extern struct hpdev infotab[];
|
extern struct hpdev infotab[];
|
||||||
extern t_bool hp_setdev (UNIT *uptr, int32 val);
|
|
||||||
|
|
||||||
/* LPT data structures
|
/* LPT data structures
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
mt 12559A nine track magnetic tape
|
mt 12559A nine track magnetic tape
|
||||||
|
|
||||||
|
07-Sep-01 RMS Moved function prototypes
|
||||||
30-Nov-00 RMS Made variable names unique
|
30-Nov-00 RMS Made variable names unique
|
||||||
04-Oct-98 RMS V2.4 magtape format
|
04-Oct-98 RMS V2.4 magtape format
|
||||||
|
|
||||||
|
@ -101,7 +102,6 @@ t_stat mtc_attach (UNIT *uptr, char *cptr);
|
||||||
t_stat mtc_detach (UNIT *uptr);
|
t_stat mtc_detach (UNIT *uptr);
|
||||||
t_stat mtd_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
|
t_stat mtd_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
|
||||||
t_stat mtd_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
|
t_stat mtd_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
|
||||||
extern t_bool hp_setdev2 (UNIT *uptr, int32 val);
|
|
||||||
|
|
||||||
/* MTD data structures
|
/* MTD data structures
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
tty 12531C buffered teleprinter interface
|
tty 12531C buffered teleprinter interface
|
||||||
clk 12539A/B/C time base generator
|
clk 12539A/B/C time base generator
|
||||||
|
|
||||||
|
07-Sep-01 RMS Moved function prototypes
|
||||||
21-Nov-00 RMS Fixed flag, buffer power up state
|
21-Nov-00 RMS Fixed flag, buffer power up state
|
||||||
Added status input for ptp, tty
|
Added status input for ptp, tty
|
||||||
15-Oct-00 RMS Added dynamic device number support
|
15-Oct-00 RMS Added dynamic device number support
|
||||||
|
@ -71,9 +72,6 @@ t_stat tto_svc (UNIT *uptr);
|
||||||
t_stat tty_reset (DEVICE *dptr);
|
t_stat tty_reset (DEVICE *dptr);
|
||||||
t_stat clk_svc (UNIT *uptr);
|
t_stat clk_svc (UNIT *uptr);
|
||||||
t_stat clk_reset (DEVICE *dptr);
|
t_stat clk_reset (DEVICE *dptr);
|
||||||
extern t_stat sim_poll_kbd (void);
|
|
||||||
extern t_stat sim_putchar (int32 out);
|
|
||||||
extern t_bool hp_setdev (UNIT *uptr, int32 val);
|
|
||||||
|
|
||||||
/* PTR data structures
|
/* PTR data structures
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
17-Sep-01 RMS Removed multiconsole support
|
||||||
27-May-01 RMS Added multiconsole support
|
27-May-01 RMS Added multiconsole support
|
||||||
14-Mar-01 RMS Revised load/dump interface (again)
|
14-Mar-01 RMS Revised load/dump interface (again)
|
||||||
30-Oct-00 RMS Added examine to file support
|
30-Oct-00 RMS Added examine to file support
|
||||||
|
@ -49,7 +50,6 @@ extern uint16 M[];
|
||||||
sim_PC pointer to saved PC register descriptor
|
sim_PC pointer to saved PC register descriptor
|
||||||
sim_emax maximum number of words for examine/deposit
|
sim_emax maximum number of words for examine/deposit
|
||||||
sim_devices array of pointers to simulated devices
|
sim_devices array of pointers to simulated devices
|
||||||
sim_consoles array of pointers to consoles (if more than one)
|
|
||||||
sim_stop_messages array of pointers to stop messages
|
sim_stop_messages array of pointers to stop messages
|
||||||
sim_load binary loader
|
sim_load binary loader
|
||||||
*/
|
*/
|
||||||
|
@ -69,8 +69,6 @@ DEVICE *sim_devices[] = { &cpu_dev,
|
||||||
&dpd_dev, &dpc_dev,
|
&dpd_dev, &dpc_dev,
|
||||||
NULL };
|
NULL };
|
||||||
|
|
||||||
UNIT *sim_consoles = NULL;
|
|
||||||
|
|
||||||
const char *sim_stop_messages[] = {
|
const char *sim_stop_messages[] = {
|
||||||
"Unknown error",
|
"Unknown error",
|
||||||
"Unimplemented instruction",
|
"Unimplemented instruction",
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
07-Sep-01 RMS Moved function prototypes
|
||||||
14-Apr-99 RMS Changed t_addr to unsigned
|
14-Apr-99 RMS Changed t_addr to unsigned
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -38,8 +39,6 @@ int32 inq_char = 033; /* request inq */
|
||||||
t_stat inq_svc (UNIT *uptr);
|
t_stat inq_svc (UNIT *uptr);
|
||||||
t_stat inq_reset (DEVICE *dptr);
|
t_stat inq_reset (DEVICE *dptr);
|
||||||
void puts_tty (char *cptr);
|
void puts_tty (char *cptr);
|
||||||
extern t_stat sim_poll_kbd (void);
|
|
||||||
extern t_stat sim_putchar (int32 out);
|
|
||||||
|
|
||||||
/* INQ data structures
|
/* INQ data structures
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
17-Sep-01 RMS Removed multiconsole support
|
||||||
13-Jul-01 RMS Fixed bug in symbolic output (found by Peter Schorn)
|
13-Jul-01 RMS Fixed bug in symbolic output (found by Peter Schorn)
|
||||||
27-May-01 RMS Added multiconsole support
|
27-May-01 RMS Added multiconsole support
|
||||||
14-Mar-01 RMS Revised load/dump interface (again)
|
14-Mar-01 RMS Revised load/dump interface (again)
|
||||||
|
@ -52,7 +53,6 @@ extern int32 store_addr_u (int32 addr);
|
||||||
sim_PC pointer to saved PC register descriptor
|
sim_PC pointer to saved PC register descriptor
|
||||||
sim_emax maximum number of words for examine/deposit
|
sim_emax maximum number of words for examine/deposit
|
||||||
sim_devices array of pointers to simulated devices
|
sim_devices array of pointers to simulated devices
|
||||||
sim_consoles array of pointers to consoles (if more than one)
|
|
||||||
sim_stop_messages array of pointers to stop messages
|
sim_stop_messages array of pointers to stop messages
|
||||||
sim_load binary loader
|
sim_load binary loader
|
||||||
*/
|
*/
|
||||||
|
@ -67,8 +67,6 @@ DEVICE *sim_devices[] = { &cpu_dev, &inq_dev,
|
||||||
&cdr_dev, &cdp_dev, &stack_dev, &lpt_dev,
|
&cdr_dev, &cdp_dev, &stack_dev, &lpt_dev,
|
||||||
&mt_dev, NULL };
|
&mt_dev, NULL };
|
||||||
|
|
||||||
UNIT *sim_consoles = NULL;
|
|
||||||
|
|
||||||
const char *sim_stop_messages[] = {
|
const char *sim_stop_messages[] = {
|
||||||
"Unknown error",
|
"Unknown error",
|
||||||
"Unimplemented instruction",
|
"Unimplemented instruction",
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
17-Sep-01 RMS Removed multiconsole support
|
||||||
17-Jul-01 RMS Fixed warning from VC++ 6.0
|
17-Jul-01 RMS Fixed warning from VC++ 6.0
|
||||||
27-May-01 RMS Added multiconsole support
|
27-May-01 RMS Added multiconsole support
|
||||||
14-Mar-01 RMS Revised load/dump interface (again)
|
14-Mar-01 RMS Revised load/dump interface (again)
|
||||||
|
@ -46,7 +47,6 @@ extern int32 saved_PC;
|
||||||
sim_PC pointer to saved PC register descriptor
|
sim_PC pointer to saved PC register descriptor
|
||||||
sim_emax number of words for examine
|
sim_emax number of words for examine
|
||||||
sim_devices array of pointers to simulated devices
|
sim_devices array of pointers to simulated devices
|
||||||
sim_consoles array of pointers to consoles (if more than one)
|
|
||||||
sim_stop_messages array of pointers to stop messages
|
sim_stop_messages array of pointers to stop messages
|
||||||
sim_load binary loader
|
sim_load binary loader
|
||||||
*/
|
*/
|
||||||
|
@ -61,8 +61,6 @@ DEVICE *sim_devices[] = { &cpu_dev,
|
||||||
&pt_dev, &tt_dev,
|
&pt_dev, &tt_dev,
|
||||||
NULL };
|
NULL };
|
||||||
|
|
||||||
UNIT *sim_consoles = NULL;
|
|
||||||
|
|
||||||
const char *sim_stop_messages[] = {
|
const char *sim_stop_messages[] = {
|
||||||
"Unknown error",
|
"Unknown error",
|
||||||
"Reserved instruction",
|
"Reserved instruction",
|
||||||
|
|
13
nova_clk.c
13
nova_clk.c
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
clk real-time clock
|
clk real-time clock
|
||||||
|
|
||||||
|
17-Sep-01 RMS Added terminal multiplexor support
|
||||||
17-Mar-01 RMS Moved function prototype
|
17-Mar-01 RMS Moved function prototype
|
||||||
05-Mar-01 RMS Added clock calibration
|
05-Mar-01 RMS Added clock calibration
|
||||||
24-Sep-97 RMS Fixed bug in unit service (found by Charles Owen)
|
24-Sep-97 RMS Fixed bug in unit service (found by Charles Owen)
|
||||||
|
@ -36,6 +37,8 @@ extern int32 int_req, dev_busy, dev_done, dev_disable;
|
||||||
int32 clk_sel = 0; /* selected freq */
|
int32 clk_sel = 0; /* selected freq */
|
||||||
int32 clk_time[4] = { 16000, 100000, 10000, 1000 }; /* freq table */
|
int32 clk_time[4] = { 16000, 100000, 10000, 1000 }; /* freq table */
|
||||||
int32 clk_tps[4] = { 60, 10, 100, 1000 }; /* ticks per sec */
|
int32 clk_tps[4] = { 60, 10, 100, 1000 }; /* ticks per sec */
|
||||||
|
int32 clk_adj[4] = { 1, -5, 2, 20 }; /* tmxr adjust */
|
||||||
|
int32 tmxr_poll = 16000; /* tmxr poll */
|
||||||
t_stat clk_svc (UNIT *uptr);
|
t_stat clk_svc (UNIT *uptr);
|
||||||
t_stat clk_reset (DEVICE *dptr);
|
t_stat clk_reset (DEVICE *dptr);
|
||||||
|
|
||||||
|
@ -95,11 +98,16 @@ return 0;
|
||||||
|
|
||||||
t_stat clk_svc (UNIT *uptr)
|
t_stat clk_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
|
int32 t;
|
||||||
|
|
||||||
dev_done = dev_done | INT_CLK; /* set done */
|
dev_done = dev_done | INT_CLK; /* set done */
|
||||||
dev_busy = dev_busy & ~INT_CLK; /* clear busy */
|
dev_busy = dev_busy & ~INT_CLK; /* clear busy */
|
||||||
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
|
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
|
||||||
sim_activate (&clk_unit, /* reactivate unit */
|
t = sim_rtc_calb (clk_tps[clk_sel]); /* calibrate delay */
|
||||||
sim_rtc_calb (clk_tps[clk_sel])); /* calibrate delay */
|
sim_activate (&clk_unit, t); /* reactivate unit */
|
||||||
|
if (clk_adj[clk_sel] > 0) /* clk >= 60Hz? */
|
||||||
|
tmxr_poll = t * clk_adj[clk_sel]; /* poll is longer */
|
||||||
|
else tmxr_poll = t / (-clk_adj[clk_sel]); /* poll is shorter */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,5 +120,6 @@ dev_busy = dev_busy & ~INT_CLK; /* clear busy */
|
||||||
dev_done = dev_done & ~INT_CLK; /* clear done, int */
|
dev_done = dev_done & ~INT_CLK; /* clear done, int */
|
||||||
int_req = int_req & ~INT_CLK;
|
int_req = int_req & ~INT_CLK;
|
||||||
sim_cancel (&clk_unit); /* deactivate unit */
|
sim_cancel (&clk_unit); /* deactivate unit */
|
||||||
|
tmxr_poll = clk_time[0]; /* poll is default */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
17-Sep-01 RMS Removed multiconsole support
|
||||||
31-May-01 RMS Added multiconsole support
|
31-May-01 RMS Added multiconsole support
|
||||||
14-Mar-01 RMS Revised load/dump interface (again)
|
14-Mar-01 RMS Revised load/dump interface (again)
|
||||||
22-Dec-00 RMS Added second terminal support
|
22-Dec-00 RMS Added second terminal support
|
||||||
|
@ -62,7 +63,6 @@ extern int32 saved_PC;
|
||||||
sim_PC pointer to saved PC register descriptor
|
sim_PC pointer to saved PC register descriptor
|
||||||
sim_emax number of words needed for examine
|
sim_emax number of words needed for examine
|
||||||
sim_devices array of pointers to simulated devices
|
sim_devices array of pointers to simulated devices
|
||||||
sim_consoles array of pointers to consoles (if more than one)
|
|
||||||
sim_stop_messages array of pointers to stop messages
|
sim_stop_messages array of pointers to stop messages
|
||||||
sim_load binary loader
|
sim_load binary loader
|
||||||
*/
|
*/
|
||||||
|
@ -90,11 +90,6 @@ DEVICE *sim_devices[] = {
|
||||||
&dkp_dev, &mta_dev,
|
&dkp_dev, &mta_dev,
|
||||||
NULL };
|
NULL };
|
||||||
|
|
||||||
UNIT *sim_consoles[] = {
|
|
||||||
&tti_unit, &tto_unit,
|
|
||||||
&tti1_unit, &tto1_unit,
|
|
||||||
NULL };
|
|
||||||
|
|
||||||
const char *sim_stop_messages[] = {
|
const char *sim_stop_messages[] = {
|
||||||
"Unknown error",
|
"Unknown error",
|
||||||
"Unknown I/O instruction",
|
"Unknown I/O instruction",
|
||||||
|
|
20
nova_tt.c
20
nova_tt.c
|
@ -26,6 +26,8 @@
|
||||||
tti terminal input
|
tti terminal input
|
||||||
tto terminal output
|
tto terminal output
|
||||||
|
|
||||||
|
17-Sep-01 RMS Removed multiconsole support
|
||||||
|
07-Sep-01 RMS Moved function prototypes
|
||||||
31-May-01 RMS Added multiconsole support
|
31-May-01 RMS Added multiconsole support
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -39,9 +41,6 @@ t_stat tto_svc (UNIT *uptr);
|
||||||
t_stat tti_reset (DEVICE *dptr);
|
t_stat tti_reset (DEVICE *dptr);
|
||||||
t_stat tto_reset (DEVICE *dptr);
|
t_stat tto_reset (DEVICE *dptr);
|
||||||
t_stat ttx_setmod (UNIT *uptr, int32 value);
|
t_stat ttx_setmod (UNIT *uptr, int32 value);
|
||||||
extern t_stat sim_poll_kbd (void);
|
|
||||||
extern t_stat sim_putchar (int32 out);
|
|
||||||
static uint8 tto_consout[CONS_SIZE];
|
|
||||||
|
|
||||||
/* TTI data structures
|
/* TTI data structures
|
||||||
|
|
||||||
|
@ -51,7 +50,7 @@ static uint8 tto_consout[CONS_SIZE];
|
||||||
ttx_mod TTI/TTO modifiers list
|
ttx_mod TTI/TTO modifiers list
|
||||||
*/
|
*/
|
||||||
|
|
||||||
UNIT tti_unit = { UDATA (&tti_svc, UNIT_CONS, 0), KBD_POLL_WAIT };
|
UNIT tti_unit = { UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT };
|
||||||
|
|
||||||
REG tti_reg[] = {
|
REG tti_reg[] = {
|
||||||
{ ORDATA (BUF, tti_unit.buf, 8) },
|
{ ORDATA (BUF, tti_unit.buf, 8) },
|
||||||
|
@ -62,12 +61,9 @@ REG tti_reg[] = {
|
||||||
{ DRDATA (POS, tti_unit.pos, 31), PV_LEFT },
|
{ DRDATA (POS, tti_unit.pos, 31), PV_LEFT },
|
||||||
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
|
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||||
{ FLDATA (MODE, tti_unit.flags, UNIT_V_DASHER), REG_HRO },
|
{ FLDATA (MODE, tti_unit.flags, UNIT_V_DASHER), REG_HRO },
|
||||||
{ FLDATA (CFLAG, tti_unit.flags, UNIT_V_CONS), REG_HRO },
|
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB ttx_mod[] = {
|
MTAB ttx_mod[] = {
|
||||||
{ UNIT_CONS, 0, "inactive", NULL, NULL },
|
|
||||||
{ UNIT_CONS, UNIT_CONS, "active console", "CONSOLE", &set_console },
|
|
||||||
{ UNIT_DASHER, 0, "ANSI", "ANSI", &ttx_setmod },
|
{ UNIT_DASHER, 0, "ANSI", "ANSI", &ttx_setmod },
|
||||||
{ UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx_setmod },
|
{ UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx_setmod },
|
||||||
{ 0 } };
|
{ 0 } };
|
||||||
|
@ -85,7 +81,7 @@ DEVICE tti_dev = {
|
||||||
tto_reg TTO register list
|
tto_reg TTO register list
|
||||||
*/
|
*/
|
||||||
|
|
||||||
UNIT tto_unit = { UDATA (&tto_svc, UNIT_CONS, 0), SERIAL_OUT_WAIT };
|
UNIT tto_unit = { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT };
|
||||||
|
|
||||||
REG tto_reg[] = {
|
REG tto_reg[] = {
|
||||||
{ ORDATA (BUF, tto_unit.buf, 8) },
|
{ ORDATA (BUF, tto_unit.buf, 8) },
|
||||||
|
@ -96,8 +92,6 @@ REG tto_reg[] = {
|
||||||
{ DRDATA (POS, tto_unit.pos, 31), PV_LEFT },
|
{ DRDATA (POS, tto_unit.pos, 31), PV_LEFT },
|
||||||
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
|
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
|
||||||
{ FLDATA (MODE, tto_unit.flags, UNIT_V_DASHER), REG_HRO },
|
{ FLDATA (MODE, tto_unit.flags, UNIT_V_DASHER), REG_HRO },
|
||||||
{ BRDATA (CONSOUT, tto_consout, 8, 8, CONS_SIZE), REG_HIDDEN },
|
|
||||||
{ FLDATA (CFLAG, tto_unit.flags, UNIT_V_CONS), REG_HRO },
|
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
DEVICE tto_dev = {
|
DEVICE tto_dev = {
|
||||||
|
@ -153,8 +147,7 @@ tti_unit.buf = 0;
|
||||||
dev_busy = dev_busy & ~INT_TTI; /* clear busy */
|
dev_busy = dev_busy & ~INT_TTI; /* clear busy */
|
||||||
dev_done = dev_done & ~INT_TTI; /* clear done, int */
|
dev_done = dev_done & ~INT_TTI; /* clear done, int */
|
||||||
int_req = int_req & ~INT_TTI;
|
int_req = int_req & ~INT_TTI;
|
||||||
if (tti_unit.flags & UNIT_CONS) /* if active console, */
|
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
|
||||||
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +183,7 @@ dev_done = dev_done | INT_TTO; /* set done */
|
||||||
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
|
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
|
||||||
c = tto_unit.buf & 0177;
|
c = tto_unit.buf & 0177;
|
||||||
if ((tto_unit.flags & UNIT_DASHER) && (c == 031)) c = '\b';
|
if ((tto_unit.flags & UNIT_DASHER) && (c == 031)) c = '\b';
|
||||||
if ((temp = sim_putcons (c, uptr)) != SCPE_OK) return temp;
|
if ((temp = sim_putchar (c)) != SCPE_OK) return temp;
|
||||||
tto_unit.pos = tto_unit.pos + 1;
|
tto_unit.pos = tto_unit.pos + 1;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -204,7 +197,6 @@ dev_busy = dev_busy & ~INT_TTO; /* clear busy */
|
||||||
dev_done = dev_done & ~INT_TTO; /* clear done, int */
|
dev_done = dev_done & ~INT_TTO; /* clear done, int */
|
||||||
int_req = int_req & ~INT_TTO;
|
int_req = int_req & ~INT_TTO;
|
||||||
sim_cancel (&tto_unit); /* deactivate unit */
|
sim_cancel (&tto_unit); /* deactivate unit */
|
||||||
tto_unit.filebuf = tto_consout; /* set buf pointer */
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
109
nova_tt1.c
109
nova_tt1.c
|
@ -27,23 +27,32 @@
|
||||||
tti1 second terminal input
|
tti1 second terminal input
|
||||||
tto1 second terminal output
|
tto1 second terminal output
|
||||||
|
|
||||||
|
17-Sep-01 RMS Changed to use terminal multiplexor library
|
||||||
|
07-Sep-01 RMS Moved function prototypes
|
||||||
31-May-01 RMS Added multiconsole support
|
31-May-01 RMS Added multiconsole support
|
||||||
26-Apr-01 RMS Added device enable/disable support
|
26-Apr-01 RMS Added device enable/disable support
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "nova_defs.h"
|
#include "nova_defs.h"
|
||||||
|
#include "sim_sock.h"
|
||||||
|
#include "sim_tmxr.h"
|
||||||
|
|
||||||
#define UNIT_V_DASHER (UNIT_V_UF + 0) /* Dasher mode */
|
#define UNIT_V_DASHER (UNIT_V_UF + 0) /* Dasher mode */
|
||||||
#define UNIT_DASHER (1 << UNIT_V_DASHER)
|
#define UNIT_DASHER (1 << UNIT_V_DASHER)
|
||||||
|
|
||||||
extern int32 int_req, dev_busy, dev_done, dev_disable, iot_enb;
|
extern int32 int_req, dev_busy, dev_done, dev_disable, iot_enb;
|
||||||
|
extern int32 tmxr_poll; /* calibrated poll */
|
||||||
|
TMLN tt1_ldsc = { 0 }; /* line descriptors */
|
||||||
|
TMXR tt_desc = { 1, 0, &tt1_ldsc }; /* mux descriptor */
|
||||||
|
|
||||||
t_stat tti1_svc (UNIT *uptr);
|
t_stat tti1_svc (UNIT *uptr);
|
||||||
t_stat tto1_svc (UNIT *uptr);
|
t_stat tto1_svc (UNIT *uptr);
|
||||||
t_stat tti1_reset (DEVICE *dptr);
|
t_stat tti1_reset (DEVICE *dptr);
|
||||||
t_stat tto1_reset (DEVICE *dptr);
|
t_stat tto1_reset (DEVICE *dptr);
|
||||||
t_stat ttx1_setmod (UNIT *uptr, int32 value);
|
t_stat ttx1_setmod (UNIT *uptr, int32 value);
|
||||||
extern t_stat sim_poll_kbd (void);
|
t_stat tti1_attach (UNIT *uptr, char *cptr);
|
||||||
static uint8 tto1_consout[CONS_SIZE];
|
t_stat tti1_detach (UNIT *uptr);
|
||||||
|
t_stat tti1_status (UNIT *uptr, FILE *st);
|
||||||
|
|
||||||
/* TTI1 data structures
|
/* TTI1 data structures
|
||||||
|
|
||||||
|
@ -53,7 +62,7 @@ static uint8 tto1_consout[CONS_SIZE];
|
||||||
ttx1_mod TTI1/TTO1 modifiers list
|
ttx1_mod TTI1/TTO1 modifiers list
|
||||||
*/
|
*/
|
||||||
|
|
||||||
UNIT tti1_unit = { UDATA (&tti1_svc, 0, 0), KBD_POLL_WAIT };
|
UNIT tti1_unit = { UDATA (&tti1_svc, UNIT_ATTABLE, 0), KBD_POLL_WAIT };
|
||||||
|
|
||||||
REG tti1_reg[] = {
|
REG tti1_reg[] = {
|
||||||
{ ORDATA (BUF, tti1_unit.buf, 8) },
|
{ ORDATA (BUF, tti1_unit.buf, 8) },
|
||||||
|
@ -61,16 +70,14 @@ REG tti1_reg[] = {
|
||||||
{ FLDATA (DONE, dev_done, INT_V_TTI1) },
|
{ FLDATA (DONE, dev_done, INT_V_TTI1) },
|
||||||
{ FLDATA (DISABLE, dev_disable, INT_V_TTI1) },
|
{ FLDATA (DISABLE, dev_disable, INT_V_TTI1) },
|
||||||
{ FLDATA (INT, int_req, INT_V_TTI1) },
|
{ FLDATA (INT, int_req, INT_V_TTI1) },
|
||||||
{ DRDATA (POS, tti1_unit.pos, 31), PV_LEFT },
|
{ DRDATA (POS, tt1_ldsc.rxcnt, 31), PV_LEFT },
|
||||||
{ DRDATA (TIME, tti1_unit.wait, 24), REG_NZ + PV_LEFT },
|
{ DRDATA (TIME, tti1_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||||
{ FLDATA (MODE, tti1_unit.flags, UNIT_V_DASHER), REG_HRO },
|
{ FLDATA (MODE, tti1_unit.flags, UNIT_V_DASHER), REG_HRO },
|
||||||
{ FLDATA (CFLAG, tti1_unit.flags, UNIT_V_CONS), REG_HRO },
|
|
||||||
{ FLDATA (*DEVENB, iot_enb, INT_V_TTI1), REG_HRO },
|
{ FLDATA (*DEVENB, iot_enb, INT_V_TTI1), REG_HRO },
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB ttx1_mod[] = {
|
MTAB ttx1_mod[] = {
|
||||||
{ UNIT_CONS, 0, "inactive", NULL, NULL },
|
{ UNIT_ATT, UNIT_ATT, "line status:", NULL, &tti1_status },
|
||||||
{ UNIT_CONS, UNIT_CONS, "active console", "CONSOLE", &set_console },
|
|
||||||
{ UNIT_DASHER, 0, "ANSI", "ANSI", &ttx1_setmod },
|
{ UNIT_DASHER, 0, "ANSI", "ANSI", &ttx1_setmod },
|
||||||
{ UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx1_setmod },
|
{ UNIT_DASHER, UNIT_DASHER, "Dasher", "DASHER", &ttx1_setmod },
|
||||||
{ 0 } };
|
{ 0 } };
|
||||||
|
@ -78,8 +85,8 @@ MTAB ttx1_mod[] = {
|
||||||
DEVICE tti1_dev = {
|
DEVICE tti1_dev = {
|
||||||
"TTI1", &tti1_unit, tti1_reg, ttx1_mod,
|
"TTI1", &tti1_unit, tti1_reg, ttx1_mod,
|
||||||
1, 10, 31, 1, 8, 8,
|
1, 10, 31, 1, 8, 8,
|
||||||
NULL, NULL, &tti1_reset,
|
&tmxr_ex, &tmxr_dep, &tti1_reset,
|
||||||
NULL, NULL, NULL };
|
NULL, &tti1_attach, &tti1_detach };
|
||||||
|
|
||||||
/* TTO1 data structures
|
/* TTO1 data structures
|
||||||
|
|
||||||
|
@ -96,11 +103,9 @@ REG tto1_reg[] = {
|
||||||
{ FLDATA (DONE, dev_done, INT_V_TTO1) },
|
{ FLDATA (DONE, dev_done, INT_V_TTO1) },
|
||||||
{ FLDATA (DISABLE, dev_disable, INT_V_TTO1) },
|
{ FLDATA (DISABLE, dev_disable, INT_V_TTO1) },
|
||||||
{ FLDATA (INT, int_req, INT_V_TTO1) },
|
{ FLDATA (INT, int_req, INT_V_TTO1) },
|
||||||
{ DRDATA (POS, tto1_unit.pos, 31), PV_LEFT },
|
{ DRDATA (POS, tt1_ldsc.txcnt, 31), PV_LEFT },
|
||||||
{ DRDATA (TIME, tto1_unit.wait, 24), PV_LEFT },
|
{ DRDATA (TIME, tto1_unit.wait, 24), PV_LEFT },
|
||||||
{ FLDATA (MODE, tto1_unit.flags, UNIT_V_DASHER), REG_HRO },
|
{ FLDATA (MODE, tto1_unit.flags, UNIT_V_DASHER), REG_HRO },
|
||||||
{ BRDATA (CONSOUT, tto1_consout, 8, 8, CONS_SIZE), REG_HIDDEN },
|
|
||||||
{ FLDATA (CFLAG, tto1_unit.flags, UNIT_V_CONS), REG_HRO },
|
|
||||||
{ FLDATA (*DEVENB, iot_enb, INT_V_TTI1), REG_HRO },
|
{ FLDATA (*DEVENB, iot_enb, INT_V_TTI1), REG_HRO },
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
|
@ -135,17 +140,25 @@ return iodata;
|
||||||
|
|
||||||
t_stat tti1_svc (UNIT *uptr)
|
t_stat tti1_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
int32 temp;
|
int32 temp, newln;
|
||||||
|
|
||||||
sim_activate (&tti1_unit, tti1_unit.wait); /* continue poll */
|
if (tt1_ldsc.conn) { /* connected? */
|
||||||
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */
|
tmxr_poll_rx (&tt_desc); /* poll for input */
|
||||||
tti1_unit.buf = temp & 0177;
|
if (temp = tmxr_getc_ln (&tt1_ldsc)) { /* get char */
|
||||||
if ((tti1_unit.flags & UNIT_DASHER) && (tti1_unit.buf == '\r'))
|
uptr -> buf = temp & 0177;
|
||||||
tti1_unit.buf = '\n'; /* Dasher: cr -> nl */
|
if ((uptr -> flags & UNIT_DASHER) &&
|
||||||
dev_busy = dev_busy & ~INT_TTI1; /* clear busy */
|
(uptr -> buf == '\r'))
|
||||||
dev_done = dev_done | INT_TTI1; /* set done */
|
uptr -> buf = '\n'; /* Dasher: cr -> nl */
|
||||||
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
|
dev_busy = dev_busy & ~INT_TTI1; /* clear busy */
|
||||||
tti1_unit.pos = tti1_unit.pos + 1;
|
dev_done = dev_done | INT_TTI1; /* set done */
|
||||||
|
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable); }
|
||||||
|
sim_activate (uptr, uptr -> wait); } /* continue poll */
|
||||||
|
if (uptr -> flags & UNIT_ATT) { /* attached? */
|
||||||
|
newln = tmxr_poll_conn (&tt_desc, uptr); /* poll connect */
|
||||||
|
if (newln >= 0) { /* got one? */
|
||||||
|
sim_activate (&tti1_unit, tti1_unit.wait);
|
||||||
|
tt1_ldsc.rcve = 1; } /* rcv enabled */
|
||||||
|
sim_activate (uptr, tmxr_poll); } /* sched poll */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,8 +170,12 @@ tti1_unit.buf = 0;
|
||||||
dev_busy = dev_busy & ~INT_TTI1; /* clear busy */
|
dev_busy = dev_busy & ~INT_TTI1; /* clear busy */
|
||||||
dev_done = dev_done & ~INT_TTI1; /* clear done, int */
|
dev_done = dev_done & ~INT_TTI1; /* clear done, int */
|
||||||
int_req = int_req & ~INT_TTI1;
|
int_req = int_req & ~INT_TTI1;
|
||||||
if (tti1_unit.flags & UNIT_CONS) /* active console? */
|
if (tt1_ldsc.conn) { /* if conn, */
|
||||||
sim_activate (&tti1_unit, tti1_unit.wait);
|
sim_activate (&tti1_unit, tti1_unit.wait); /* activate, */
|
||||||
|
tt1_ldsc.rcve = 1; } /* enable */
|
||||||
|
else if (tti1_unit.flags & UNIT_ATT) /* if attached, */
|
||||||
|
sim_activate (&tti1_unit, tmxr_poll); /* activate */
|
||||||
|
else sim_cancel (&tti1_unit); /* else stop */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,15 +204,20 @@ return 0;
|
||||||
|
|
||||||
t_stat tto1_svc (UNIT *uptr)
|
t_stat tto1_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
int32 c, temp;
|
int32 c;
|
||||||
|
|
||||||
dev_busy = dev_busy & ~INT_TTO1; /* clear busy */
|
dev_busy = dev_busy & ~INT_TTO1; /* clear busy */
|
||||||
dev_done = dev_done | INT_TTO1; /* set done */
|
dev_done = dev_done | INT_TTO1; /* set done */
|
||||||
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
|
int_req = (int_req & ~INT_DEV) | (dev_done & ~dev_disable);
|
||||||
c = tto1_unit.buf & 0177;
|
c = tto1_unit.buf & 0177;
|
||||||
if ((tto1_unit.flags & UNIT_DASHER) && (c == 031)) c = '\b';
|
if ((tto1_unit.flags & UNIT_DASHER) && (c == 031)) c = '\b';
|
||||||
if ((temp = sim_putcons (c, uptr)) != SCPE_OK) return temp;
|
if (tt1_ldsc.conn) { /* connected? */
|
||||||
tto1_unit.pos = tto1_unit.pos + 1;
|
if (tt1_ldsc.xmte) { /* tx enabled? */
|
||||||
|
tmxr_putc_ln (&tt1_ldsc, c); /* output char */
|
||||||
|
tmxr_poll_tx (&tt_desc); } /* poll xmt */
|
||||||
|
else { tmxr_poll_tx (&tt_desc); /* poll xmt */
|
||||||
|
sim_activate (&tto1_unit, tmxr_poll); /* wait */
|
||||||
|
return SCPE_OK; } }
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +230,6 @@ dev_busy = dev_busy & ~INT_TTO1; /* clear busy */
|
||||||
dev_done = dev_done & ~INT_TTO1; /* clear done, int */
|
dev_done = dev_done & ~INT_TTO1; /* clear done, int */
|
||||||
int_req = int_req & ~INT_TTO1;
|
int_req = int_req & ~INT_TTO1;
|
||||||
sim_cancel (&tto1_unit); /* deactivate unit */
|
sim_cancel (&tto1_unit); /* deactivate unit */
|
||||||
tto1_unit.filebuf = tto1_consout; /* set buf pointer */
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,3 +239,35 @@ tti1_unit.flags = (tti1_unit.flags & ~UNIT_DASHER) | value;
|
||||||
tto1_unit.flags = (tto1_unit.flags & ~UNIT_DASHER) | value;
|
tto1_unit.flags = (tto1_unit.flags & ~UNIT_DASHER) | value;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Attach routine */
|
||||||
|
|
||||||
|
t_stat tti1_attach (UNIT *uptr, char *cptr)
|
||||||
|
{
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
r = tmxr_attach (&tt_desc, uptr, cptr); /* attach */
|
||||||
|
if (r != SCPE_OK) return r; /* error */
|
||||||
|
sim_activate (uptr, tmxr_poll); /* start poll */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Detach routine */
|
||||||
|
|
||||||
|
t_stat tti1_detach (UNIT *uptr)
|
||||||
|
{
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
r = tmxr_detach (&tt_desc, uptr); /* detach */
|
||||||
|
tt1_ldsc.rcve = 0; /* disable rcv */
|
||||||
|
sim_cancel (uptr); /* stop poll */
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Status routine */
|
||||||
|
|
||||||
|
t_stat tti1_status (UNIT *uptr, FILE *st)
|
||||||
|
{
|
||||||
|
tmxr_fstatus (st, &tt1_ldsc, -1);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
cpu KS10 central processor
|
cpu KS10 central processor
|
||||||
|
|
||||||
|
31-Aug-01 RMS Changed int64 to t_int64 for Windoze
|
||||||
10-Aug-01 RMS Removed register in declarations
|
10-Aug-01 RMS Removed register in declarations
|
||||||
17-Jul-01 RMS Moved function prototype
|
17-Jul-01 RMS Moved function prototype
|
||||||
19-May-01 RMS Added workaround for TOPS-20 V4.1 boot bug
|
19-May-01 RMS Added workaround for TOPS-20 V4.1 boot bug
|
||||||
|
@ -531,7 +532,7 @@ void ashc (int32 ac, a10 ea);
|
||||||
void circ (int32 ac, a10 ea);
|
void circ (int32 ac, a10 ea);
|
||||||
void blt (int32 ac, a10 ea, int32 pflgs);
|
void blt (int32 ac, a10 ea, int32 pflgs);
|
||||||
void bltu (int32 ac, a10 ea, int32 pflgs, int dir);
|
void bltu (int32 ac, a10 ea, int32 pflgs, int dir);
|
||||||
a10 calc_ea (int64 inst, int32 prv);
|
a10 calc_ea (d10 inst, int32 prv);
|
||||||
a10 calc_ioea (d10 inst, int32 prv);
|
a10 calc_ioea (d10 inst, int32 prv);
|
||||||
d10 calc_jrstfea (d10 inst, int32 pflgs);
|
d10 calc_jrstfea (d10 inst, int32 pflgs);
|
||||||
void pi_dismiss (void);
|
void pi_dismiss (void);
|
||||||
|
|
73
pdp10_defs.h
73
pdp10_defs.h
|
@ -23,6 +23,11 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
23-Oct-01 RMS New IO page address constants
|
||||||
|
19-Oct-01 RMS Added DZ definitions
|
||||||
|
07-Sep-01 RMS Revised for PDP-11 multi-level interrupts
|
||||||
|
31-Aug-01 RMS Changed int64 to t_int64 for Windoze
|
||||||
|
29-Aug-01 RMS Corrected models and dates (found by Lars Brinkhoff)
|
||||||
01-Jun-01 RMS Updated DZ11 vector definitions
|
01-Jun-01 RMS Updated DZ11 vector definitions
|
||||||
19-May-01 RMS Added workaround for TOPS-20 V4.1 boot bug
|
19-May-01 RMS Added workaround for TOPS-20 V4.1 boot bug
|
||||||
*/
|
*/
|
||||||
|
@ -35,9 +40,9 @@
|
||||||
|
|
||||||
PDP-6 0.25 Original 36b implementation, 1964
|
PDP-6 0.25 Original 36b implementation, 1964
|
||||||
KA10 0.38 First PDP-10, flip chips, 1967
|
KA10 0.38 First PDP-10, flip chips, 1967
|
||||||
KI10 0.72 First paging system, flip chip + MSI, 1969
|
KI10 0.72 First paging system, flip chip + MSI, 1972
|
||||||
KL10 1.8 First ECL system, ECL 10K, 1972
|
KL10 1.8 First ECL system, ECL 10K, 1975
|
||||||
KL10X 1.8 Expanded addressing, ECL 10K, 1975
|
KL10B 1.8 Expanded addressing, ECL 10K, 1978
|
||||||
KS10 0.3 Last 36b system, 2901 based, 1979
|
KS10 0.3 Last 36b system, 2901 based, 1979
|
||||||
|
|
||||||
In addition, it ran four major (incompatible) operating systems:
|
In addition, it ran four major (incompatible) operating systems:
|
||||||
|
@ -69,8 +74,8 @@
|
||||||
|
|
||||||
/* Data types */
|
/* Data types */
|
||||||
|
|
||||||
typedef int32 a10; /* PDP-10 addr (30b) */
|
typedef int32 a10; /* PDP-10 addr (30b) */
|
||||||
typedef int64 d10; /* PDP-10 data (36b) */
|
typedef t_int64 d10; /* PDP-10 data (36b) */
|
||||||
|
|
||||||
/* Abort codes, used to sort out longjmp's back to the main loop
|
/* Abort codes, used to sort out longjmp's back to the main loop
|
||||||
Codes > 0 are simulator stop codes
|
Codes > 0 are simulator stop codes
|
||||||
|
@ -162,7 +167,7 @@ typedef int64 d10; /* PDP-10 data (36b) */
|
||||||
#define BP_S 0007700000000
|
#define BP_S 0007700000000
|
||||||
#define GET_P(x) ((int32) (((x) >> BP_V_P) & BP_M_P))
|
#define GET_P(x) ((int32) (((x) >> BP_V_P) & BP_M_P))
|
||||||
#define GET_S(x) ((int32) (((x) >> BP_V_S) & BP_M_S))
|
#define GET_S(x) ((int32) (((x) >> BP_V_S) & BP_M_S))
|
||||||
#define PUT_P(b,x) (((b) & ~BP_P) | ((((int64) (x)) & BP_M_P) << BP_V_P))
|
#define PUT_P(b,x) (((b) & ~BP_P) | ((((t_int64) (x)) & BP_M_P) << BP_V_P))
|
||||||
|
|
||||||
/* Flags (stored in their own halfword) */
|
/* Flags (stored in their own halfword) */
|
||||||
|
|
||||||
|
@ -567,17 +572,31 @@ typedef int64 d10; /* PDP-10 data (36b) */
|
||||||
#define IO_UBA3 (3 << IO_V_UBA)
|
#define IO_UBA3 (3 << IO_V_UBA)
|
||||||
#define GET_IOUBA(x) (((x) >> IO_V_UBA) & IO_M_UBA)
|
#define GET_IOUBA(x) (((x) >> IO_V_UBA) & IO_M_UBA)
|
||||||
|
|
||||||
|
/* DZ11 parameters */
|
||||||
|
|
||||||
|
#define DZ_MUXES 1 /* # of muxes */
|
||||||
|
#define DZ_LINES 8 /* lines per mux */
|
||||||
|
|
||||||
/* I/O page layout */
|
/* I/O page layout */
|
||||||
|
|
||||||
#define IO_DZBASE 0760010 /* DZ11 base */
|
#define IOBA_DZ 0760010 /* DZ11 */
|
||||||
#define IO_TCUBASE 0760770 /* TCU150 base */
|
#define IOLN_DZ (010 * DZ_MUXES)
|
||||||
#define IO_UBMAP 0763000 /* Unibus map base */
|
#define IOBA_TCU 0760770 /* TCU150 */
|
||||||
#define IO_UBCS 0763100 /* Unibus c/s reg */
|
#define IOLN_TCU 006
|
||||||
#define IO_UBMNT 0763101 /* Unibus maint reg */
|
#define IOBA_UBMAP 0763000 /* Unibus map */
|
||||||
#define IO_TMBASE 0772440 /* RH11/tape base */
|
#define IOLN_UBMAP 0100
|
||||||
#define IO_RHBASE 0776700 /* RH11/disk base */
|
#define IOBA_UBCS 0763100 /* Unibus c/s reg */
|
||||||
#define IO_LPBASE 0775400 /* LP20 base */
|
#define IOLN_UBCS 001
|
||||||
#define IO_PTBASE 0777550 /* PC11 base */
|
#define IOBA_UBMNT 0763101 /* Unibus maint reg */
|
||||||
|
#define IOLN_UBMNT 001
|
||||||
|
#define IOBA_TU 0772440 /* RH11/tape */
|
||||||
|
#define IOLN_TU 034
|
||||||
|
#define IOBA_RP 0776700 /* RH11/disk */
|
||||||
|
#define IOLN_RP 050
|
||||||
|
#define IOBA_LP20 0775400 /* LP20 */
|
||||||
|
#define IOLN_LP20 020
|
||||||
|
#define IOBA_PT 0777550 /* PC11 */
|
||||||
|
#define IOLN_PT 010
|
||||||
|
|
||||||
/* Common Unibus CSR flags */
|
/* Common Unibus CSR flags */
|
||||||
|
|
||||||
|
@ -603,20 +622,28 @@ typedef int64 d10; /* PDP-10 data (36b) */
|
||||||
|
|
||||||
#define INT_V_RP 6 /* RH11/RP,RM drives */
|
#define INT_V_RP 6 /* RH11/RP,RM drives */
|
||||||
#define INT_V_TU 7 /* RH11/TM03/TU45 */
|
#define INT_V_TU 7 /* RH11/TM03/TU45 */
|
||||||
#define INT_V_DZ0RX 16 /* DZ11 */
|
#define INT_V_DZRX 16 /* DZ11 */
|
||||||
#define INT_V_DZ0TX 17
|
#define INT_V_DZTX 17
|
||||||
#define INT_V_PTR 24 /* PC11 */
|
#define INT_V_PTR 24 /* PC11 */
|
||||||
#define INT_V_PTP 25
|
#define INT_V_PTP 25
|
||||||
#define INT_V_LP20 26 /* LPT20 */
|
#define INT_V_LP20 26 /* LPT20 */
|
||||||
|
|
||||||
#define INT_RP (1u << INT_V_RP)
|
#define INT_RP (1u << INT_V_RP)
|
||||||
#define INT_TU (1u << INT_V_TU)
|
#define INT_TU (1u << INT_V_TU)
|
||||||
#define INT_DZ0RX (1u << INT_V_DZ0RX)
|
#define INT_DZRX (1u << INT_V_DZRX)
|
||||||
#define INT_DZ0TX (1u << INT_V_DZ0TX)
|
#define INT_DZTX (1u << INT_V_DZTX)
|
||||||
#define INT_PTR (1u << INT_V_PTR)
|
#define INT_PTR (1u << INT_V_PTR)
|
||||||
#define INT_PTP (1u << INT_V_PTP)
|
#define INT_PTP (1u << INT_V_PTP)
|
||||||
#define INT_LP20 (1u << INT_V_LP20)
|
#define INT_LP20 (1u << INT_V_LP20)
|
||||||
|
|
||||||
|
#define IPL_RP 6 /* int levels */
|
||||||
|
#define IPL_TU 6
|
||||||
|
#define IPL_DZRX 5
|
||||||
|
#define IPL_DZTX 5
|
||||||
|
#define IPL_PTR 4
|
||||||
|
#define IPL_PTP 4
|
||||||
|
#define IPL_LP20 4
|
||||||
|
|
||||||
#define INT_UB1 INT_RP /* on Unibus 1 */
|
#define INT_UB1 INT_RP /* on Unibus 1 */
|
||||||
#define INT_UB3 (0xFFFFFFFFu & ~INT_UB1) /* on Unibus 3 */
|
#define INT_UB3 (0xFFFFFFFFu & ~INT_UB1) /* on Unibus 3 */
|
||||||
|
|
||||||
|
@ -629,6 +656,10 @@ typedef int64 d10; /* PDP-10 data (36b) */
|
||||||
#define VEC_PTP 0074
|
#define VEC_PTP 0074
|
||||||
#define VEC_TU 0224
|
#define VEC_TU 0224
|
||||||
#define VEC_RP 0254
|
#define VEC_RP 0254
|
||||||
#define VEC_DZ0RX 0340
|
#define VEC_DZRX 0340
|
||||||
#define VEC_DZ0TX 0344
|
#define VEC_DZTX 0344
|
||||||
#define VEC_LP20 0754
|
#define VEC_LP20 0754
|
||||||
|
|
||||||
|
#define IREQ(dv) int_req
|
||||||
|
#define SET_INT(dv) IREQ(dv) = IREQ(dv) | (INT_##dv)
|
||||||
|
#define CLR_INT(dv) IREQ(dv) = IREQ(dv) & ~(INT_##dv)
|
||||||
|
|
168
pdp10_dz.c
168
pdp10_dz.c
|
@ -1,6 +1,6 @@
|
||||||
/* pdp10_dz_stub.c: DZ11 terminal multiplexor simulator stub
|
/* pdp10_dz.c: DZ11 terminal multiplexor simulator
|
||||||
|
|
||||||
Copyright (c) 2001, Robert M Supnik
|
Copyright (c) 1993-2001, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -23,168 +23,8 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
dz DZ11 terminal multiplexor (stub)
|
dz DZ11 terminal multiplexor
|
||||||
|
|
||||||
This version of the DZ11 is a stub to allow operating systems to play
|
|
||||||
with the device registers. It is required for ITS, and not harmful to
|
|
||||||
TOPS-10 or TOPS-20.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pdp10_defs.h"
|
#include "pdp10_defs.h"
|
||||||
|
#include "dec_dz.h"
|
||||||
#define DZ_LINES 8 /* lines per DZ11 */
|
|
||||||
#define DZ_LMASK (DZ_LINES - 1)
|
|
||||||
#define DZ_SILO_ALM 16 /* silo alarm level */
|
|
||||||
#define MAXBUF 128 /* buffer size */
|
|
||||||
|
|
||||||
/* DZCSR - 160100 - control/status register */
|
|
||||||
|
|
||||||
#define CSR_MAINT 0000010 /* maint - NI */
|
|
||||||
#define CSR_CLR 0000020 /* clear */
|
|
||||||
#define CSR_MSE 0000040 /* master scan enb */
|
|
||||||
#define CSR_RIE 0000100 /* rcv int enb */
|
|
||||||
#define CSR_RDONE 0000200 /* rcv done - RO */
|
|
||||||
#define CSR_V_TLINE 8 /* xmit line - RO */
|
|
||||||
#define CSR_TLINE (DZ_LMASK << CSR_V_TLINE)
|
|
||||||
#define CSR_SAE 0010000 /* silo alm enb */
|
|
||||||
#define CSR_SA 0020000 /* silo alm - RO */
|
|
||||||
#define CSR_TIE 0040000 /* xmit int enb */
|
|
||||||
#define CSR_TRDY 0100000 /* xmit rdy - RO */
|
|
||||||
#define CSR_RW (CSR_MSE | CSR_RIE | CSR_SAE | CSR_TIE)
|
|
||||||
#define CSR_MBZ (0004003 | CSR_CLR | CSR_MAINT)
|
|
||||||
|
|
||||||
#define CSR_GETTL(x) (((x) >> CSR_V_TLINE) & DZ_LMASK)
|
|
||||||
#define CSR_PUTTL(x,y) x = ((x) & ~CSR_TLINE) | (((y) & DZ_LMASK) << CSR_V_TLINE)
|
|
||||||
|
|
||||||
/* DZRBUF - 160102 - receive buffer, read only */
|
|
||||||
|
|
||||||
#define RBUF_CHAR 0000377 /* rcv char */
|
|
||||||
#define RBUF_V_RLINE 8 /* rcv line */
|
|
||||||
#define RBUF_PARE 0010000 /* parity err - NI */
|
|
||||||
#define RBUF_FRME 0020000 /* frame err - NI */
|
|
||||||
#define RBUF_OVRE 0040000 /* overrun err - NI */
|
|
||||||
#define RBUF_VALID 0100000 /* rcv valid */
|
|
||||||
#define RBUF_MBZ 0004000
|
|
||||||
|
|
||||||
/* DZLPR - 160102 - line parameter register, write only, word access only */
|
|
||||||
|
|
||||||
#define LPR_V_LINE 0 /* line */
|
|
||||||
#define LPR_LPAR 0007770 /* line pars - NI */
|
|
||||||
#define LPR_RCVE 0010000 /* receive enb */
|
|
||||||
#define LPR_GETLN(x) (((x) >> LPR_V_LINE) & DZ_LMASK)
|
|
||||||
|
|
||||||
/* DZTCR - 160104 - transmission control register */
|
|
||||||
|
|
||||||
#define TCR_V_XMTE 0 /* xmit enables */
|
|
||||||
#define TCR_V_DTR 7 /* DTRs */
|
|
||||||
|
|
||||||
/* DZMSR - 160106 - modem status register, read only */
|
|
||||||
|
|
||||||
#define MSR_V_RI 0 /* ring indicators */
|
|
||||||
#define MSR_V_CD 7 /* carrier detect */
|
|
||||||
|
|
||||||
/* DZTDR - 160106 - transmit data, write only */
|
|
||||||
|
|
||||||
#define TDR_CHAR 0000377 /* xmit char */
|
|
||||||
#define TDR_V_TBR 7 /* xmit break - NI */
|
|
||||||
|
|
||||||
extern int32 int_req, dev_enb;
|
|
||||||
int32 dz_csr = 0; /* csr */
|
|
||||||
int32 dz_rbuf = 0; /* rcv buffer */
|
|
||||||
int32 dz_lpr = 0; /* line param */
|
|
||||||
int32 dz_tcr = 0; /* xmit control */
|
|
||||||
int32 dz_msr = 0; /* modem status */
|
|
||||||
int32 dz_tdr = 0; /* xmit data */
|
|
||||||
int32 dz_mctl = 0; /* modem ctrl enab */
|
|
||||||
int32 dz_sa_enb = 1; /* silo alarm enabled */
|
|
||||||
|
|
||||||
t_stat dz_reset (DEVICE *dptr);
|
|
||||||
t_stat dz_clear (t_bool flag);
|
|
||||||
|
|
||||||
/* DZ data structures
|
|
||||||
|
|
||||||
dz_dev DZ device descriptor
|
|
||||||
dz_unit DZ unit list
|
|
||||||
dz_reg DZ register list
|
|
||||||
*/
|
|
||||||
|
|
||||||
UNIT dz_unit = { UDATA (NULL, 0, 0) };
|
|
||||||
|
|
||||||
REG dz_reg[] = {
|
|
||||||
{ ORDATA (CSR, dz_csr, 16) },
|
|
||||||
{ ORDATA (RBUF, dz_rbuf, 16) },
|
|
||||||
{ ORDATA (LPR, dz_lpr, 16) },
|
|
||||||
{ ORDATA (TCR, dz_tcr, 16) },
|
|
||||||
{ ORDATA (MSR, dz_msr, 16) },
|
|
||||||
{ ORDATA (TDR, dz_tdr, 16) },
|
|
||||||
{ FLDATA (MDMCTL, dz_mctl, 0) },
|
|
||||||
{ FLDATA (SAENB, dz_sa_enb, 0) },
|
|
||||||
{ FLDATA (*DEVENB, dev_enb, INT_V_DZ0RX), REG_HRO },
|
|
||||||
{ NULL } };
|
|
||||||
|
|
||||||
DEVICE dz_dev = {
|
|
||||||
"DZ", &dz_unit, dz_reg, NULL,
|
|
||||||
1, 8, 13, 1, 8, 8,
|
|
||||||
NULL, NULL, &dz_reset,
|
|
||||||
NULL, NULL, NULL };
|
|
||||||
|
|
||||||
/* IO dispatch routines, I/O addresses 17760100 - 17760107 */
|
|
||||||
|
|
||||||
t_stat dz0_rd (int32 *data, int32 PA, int32 access)
|
|
||||||
{
|
|
||||||
switch ((PA >> 1) & 03) { /* case on PA<2:1> */
|
|
||||||
case 00: /* CSR */
|
|
||||||
*data = dz_csr = dz_csr & ~CSR_MBZ;
|
|
||||||
break;
|
|
||||||
case 01: /* RBUF */
|
|
||||||
dz_csr = dz_csr & ~CSR_SA; /* clr silo alarm */
|
|
||||||
*data = dz_rbuf;
|
|
||||||
break;
|
|
||||||
case 02: /* TCR */
|
|
||||||
*data = dz_tcr;
|
|
||||||
break;
|
|
||||||
case 03: /* MSR */
|
|
||||||
*data = dz_msr;
|
|
||||||
break; }
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
t_stat dz0_wr (int32 data, int32 PA, int32 access)
|
|
||||||
{
|
|
||||||
switch ((PA >> 1) & 03) { /* case on PA<2:1> */
|
|
||||||
case 00: /* CSR */
|
|
||||||
if (access == WRITEB) data = (PA & 1)?
|
|
||||||
(dz_csr & 0377) | (data << 8): (dz_csr & ~0377) | data;
|
|
||||||
dz_csr = (dz_csr & ~CSR_RW) | (data & CSR_RW);
|
|
||||||
break;
|
|
||||||
case 01: /* LPR */
|
|
||||||
dz_lpr = data;
|
|
||||||
break;
|
|
||||||
case 02: /* TCR */
|
|
||||||
if (access == WRITEB) data = (PA & 1)?
|
|
||||||
(dz_tcr & 0377) | (data << 8): (dz_tcr & ~0377) | data;
|
|
||||||
dz_tcr = data;
|
|
||||||
break;
|
|
||||||
case 03: /* TDR */
|
|
||||||
if (PA & 1) { /* odd byte? */
|
|
||||||
dz_tdr = (dz_tdr & 0377) | (data << 8); /* just save */
|
|
||||||
break; }
|
|
||||||
dz_tdr = data;
|
|
||||||
break; }
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Device reset */
|
|
||||||
|
|
||||||
t_stat dz_reset (DEVICE *dptr)
|
|
||||||
{
|
|
||||||
dz_csr = 0; /* clear CSR */
|
|
||||||
dz_rbuf = 0; /* silo empty */
|
|
||||||
dz_lpr = 0; /* no params */
|
|
||||||
dz_tcr = 0; /* clr all */
|
|
||||||
dz_tdr = 0;
|
|
||||||
dz_sa_enb = 1;
|
|
||||||
int_req = int_req & ~(INT_DZ0RX | INT_DZ0TX); /* clear int */
|
|
||||||
sim_cancel (&dz_unit); /* no polling */
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
fe KS10 console front end
|
fe KS10 console front end
|
||||||
|
|
||||||
|
23-Oct-01 RMS New IO page address constants
|
||||||
|
07-Sep-01 RMS Moved function prototypes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pdp10_defs.h"
|
#include "pdp10_defs.h"
|
||||||
|
@ -36,8 +39,6 @@ t_stat feo_svc (UNIT *uptr);
|
||||||
t_stat fe_reset (DEVICE *dptr);
|
t_stat fe_reset (DEVICE *dptr);
|
||||||
t_stat fe_stop_os (UNIT *uptr, int32 val);
|
t_stat fe_stop_os (UNIT *uptr, int32 val);
|
||||||
t_stat fe_ctrl_c (UNIT *uptr, int32 val);
|
t_stat fe_ctrl_c (UNIT *uptr, int32 val);
|
||||||
extern t_stat sim_poll_kbd (void);
|
|
||||||
extern t_stat sim_putchar (int32 out);
|
|
||||||
|
|
||||||
/* FE data structures
|
/* FE data structures
|
||||||
|
|
||||||
|
@ -147,7 +148,7 @@ return SCPE_OK;
|
||||||
|
|
||||||
t_stat fe_stop_os (UNIT *uptr, int32 val)
|
t_stat fe_stop_os (UNIT *uptr, int32 val)
|
||||||
{
|
{
|
||||||
M[FE_SWITCH] = IO_RHBASE; /* tell OS to stop */
|
M[FE_SWITCH] = IOBA_RP; /* tell OS to stop */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,4 +160,4 @@ fei_unit.buf = 003; /* control-C */
|
||||||
M[FE_CTYIN] = fei_unit.buf | FE_CVALID; /* put char in mem */
|
M[FE_CTYIN] = fei_unit.buf | FE_CVALID; /* put char in mem */
|
||||||
apr_flg = apr_flg | APRF_CON; /* interrupt KS10 */
|
apr_flg = apr_flg | APRF_CON; /* interrupt KS10 */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
72
pdp10_ksio.c
72
pdp10_ksio.c
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
uba Unibus adapters
|
uba Unibus adapters
|
||||||
|
|
||||||
|
23-Sep-01 RMS New IO page address constants
|
||||||
|
07-Sep-01 RMS Revised device disable mechanism
|
||||||
25-Aug-01 RMS Enabled DZ11
|
25-Aug-01 RMS Enabled DZ11
|
||||||
21-Aug-01 RMS Updated DZ11 disable
|
21-Aug-01 RMS Updated DZ11 disable
|
||||||
01-Jun-01 RMS Updated DZ11 vectors
|
01-Jun-01 RMS Updated DZ11 vectors
|
||||||
|
@ -77,7 +79,6 @@
|
||||||
int32 ubcs[UBANUM] = { 0 }; /* status registers */
|
int32 ubcs[UBANUM] = { 0 }; /* status registers */
|
||||||
int32 ubmap[UBANUM][UMAP_MEMSIZE] = { 0 }; /* Unibus maps */
|
int32 ubmap[UBANUM][UMAP_MEMSIZE] = { 0 }; /* Unibus maps */
|
||||||
int32 int_req = 0; /* interrupt requests */
|
int32 int_req = 0; /* interrupt requests */
|
||||||
int32 dev_enb = -1 & ~(INT_PTR | INT_PTP | INT_DZ0RX); /* device enables */
|
|
||||||
|
|
||||||
/* Map IO controller numbers to Unibus adapters: -1 = non-existent */
|
/* Map IO controller numbers to Unibus adapters: -1 = non-existent */
|
||||||
|
|
||||||
|
@ -97,10 +98,12 @@ extern jmp_buf save_env;
|
||||||
|
|
||||||
extern d10 Read (a10 ea);
|
extern d10 Read (a10 ea);
|
||||||
extern void pi_eval ();
|
extern void pi_eval ();
|
||||||
extern t_stat dz0_rd (int32 *data, int32 addr, int32 access);
|
extern t_stat dz_rd (int32 *data, int32 addr, int32 access);
|
||||||
extern t_stat dz0_wr (int32 data, int32 addr, int32 access);
|
extern t_stat dz_wr (int32 data, int32 addr, int32 access);
|
||||||
|
extern int32 dz_enb;
|
||||||
extern t_stat pt_rd (int32 *data, int32 addr, int32 access);
|
extern t_stat pt_rd (int32 *data, int32 addr, int32 access);
|
||||||
extern t_stat pt_wr (int32 data, int32 addr, int32 access);
|
extern t_stat pt_wr (int32 data, int32 addr, int32 access);
|
||||||
|
extern int32 pt_enb;
|
||||||
extern t_stat lp20_rd (int32 *data, int32 addr, int32 access);
|
extern t_stat lp20_rd (int32 *data, int32 addr, int32 access);
|
||||||
extern t_stat lp20_wr (int32 data, int32 addr, int32 access);
|
extern t_stat lp20_wr (int32 data, int32 addr, int32 access);
|
||||||
extern int32 lp20_inta (void);
|
extern int32 lp20_inta (void);
|
||||||
|
@ -138,7 +141,6 @@ REG uba_reg[] = {
|
||||||
{ ORDATA (INTREQ, int_req, 32), REG_RO },
|
{ ORDATA (INTREQ, int_req, 32), REG_RO },
|
||||||
{ ORDATA (UB1CS, ubcs[0], 18) },
|
{ ORDATA (UB1CS, ubcs[0], 18) },
|
||||||
{ ORDATA (UB3CS, ubcs[1], 18) },
|
{ ORDATA (UB3CS, ubcs[1], 18) },
|
||||||
{ ORDATA (DEVENB, dev_enb, 32), REG_HRO },
|
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
DEVICE uba_dev = {
|
DEVICE uba_dev = {
|
||||||
|
@ -152,7 +154,7 @@ DEVICE uba_dev = {
|
||||||
struct iolink { /* I/O page linkage */
|
struct iolink { /* I/O page linkage */
|
||||||
int32 low; /* low I/O addr */
|
int32 low; /* low I/O addr */
|
||||||
int32 high; /* high I/O addr */
|
int32 high; /* high I/O addr */
|
||||||
int32 enb; /* enable mask */
|
int32 *enb; /* enable flag */
|
||||||
t_stat (*read)(); /* read routine */
|
t_stat (*read)(); /* read routine */
|
||||||
t_stat (*write)(); }; /* write routine */
|
t_stat (*write)(); }; /* write routine */
|
||||||
|
|
||||||
|
@ -160,31 +162,31 @@ struct iolink { /* I/O page linkage */
|
||||||
The expected Unibus adapter number is included as the high 2 bits */
|
The expected Unibus adapter number is included as the high 2 bits */
|
||||||
|
|
||||||
struct iolink iotable[] = {
|
struct iolink iotable[] = {
|
||||||
{ IO_UBA1+IO_RHBASE, IO_UBA1+IO_RHBASE+047, 0,
|
{ IO_UBA1+IOBA_RP, IO_UBA1+IOBA_RP+IOLN_RP,
|
||||||
&rp_rd, &rp_wr }, /* disk */
|
NULL, &rp_rd, &rp_wr }, /* disk */
|
||||||
{ IO_UBA3+IO_TMBASE, IO_UBA3+IO_TMBASE+033, 0,
|
{ IO_UBA3+IOBA_TU, IO_UBA3+IOBA_TU+IOLN_TU,
|
||||||
&tu_rd, &tu_wr }, /* mag tape */
|
NULL, &tu_rd, &tu_wr }, /* mag tape */
|
||||||
{ IO_UBA3+IO_DZBASE, IO_UBA3+IO_DZBASE+07, INT_DZ0RX,
|
{ IO_UBA3+IOBA_DZ, IO_UBA3+IOBA_DZ+IOLN_DZ,
|
||||||
&dz0_rd, &dz0_wr }, /* terminal mux */
|
&dz_enb, &dz_rd, &dz_wr }, /* terminal mux */
|
||||||
{ IO_UBA3+IO_LPBASE, IO_UBA3+IO_LPBASE+017, 0,
|
{ IO_UBA3+IOBA_LP20, IO_UBA3+IOBA_LP20+IOLN_LP20,
|
||||||
&lp20_rd, &lp20_wr }, /* line printer */
|
NULL, &lp20_rd, &lp20_wr }, /* line printer */
|
||||||
{ IO_UBA3+IO_PTBASE, IO_UBA3+IO_PTBASE+07, INT_PTR,
|
{ IO_UBA3+IOBA_PT, IO_UBA3+IOBA_PT+IOLN_PT,
|
||||||
&pt_rd, &pt_wr }, /* paper tape */
|
&pt_enb, &pt_rd, &pt_wr }, /* paper tape */
|
||||||
{ IO_UBA1+IO_UBMAP, IO_UBA1+IO_UBMAP+077, 0,
|
{ IO_UBA1+IOBA_UBMAP, IO_UBA1+IOBA_UBMAP+IOLN_UBMAP,
|
||||||
&ubmap_rd, &ubmap_wr }, /* Unibus 1 map */
|
NULL, &ubmap_rd, &ubmap_wr }, /* Unibus 1 map */
|
||||||
{ IO_UBA3+IO_UBMAP, IO_UBA3+IO_UBMAP+077, 0,
|
{ IO_UBA3+IOBA_UBMAP, IO_UBA3+IOBA_UBMAP+IOLN_UBMAP,
|
||||||
&ubmap_rd, &ubmap_wr }, /* Unibus 3 map */
|
NULL, &ubmap_rd, &ubmap_wr }, /* Unibus 3 map */
|
||||||
{ IO_UBA1+IO_UBCS, IO_UBA1+IO_UBCS, 0,
|
{ IO_UBA1+IOBA_UBCS, IO_UBA1+IOBA_UBCS+IOLN_UBCS,
|
||||||
&ubs_rd, &ubs_wr }, /* Unibus 1 c/s */
|
NULL, &ubs_rd, &ubs_wr }, /* Unibus 1 c/s */
|
||||||
{ IO_UBA3+IO_UBCS, IO_UBA3+IO_UBCS, 0,
|
{ IO_UBA3+IOBA_UBCS, IO_UBA3+IOBA_UBCS+IOLN_UBCS,
|
||||||
&ubs_rd, &ubs_wr }, /* Unibus 3 c/s */
|
NULL, &ubs_rd, &ubs_wr }, /* Unibus 3 c/s */
|
||||||
{ IO_UBA1+IO_UBMNT, IO_UBA1+IO_UBMNT, 0,
|
{ IO_UBA1+IOBA_UBMNT, IO_UBA1+IOBA_UBMNT+IOLN_UBMNT,
|
||||||
&rd_zro, &wr_nop }, /* Unibus 1 maint */
|
NULL, &rd_zro, &wr_nop }, /* Unibus 1 maint */
|
||||||
{ IO_UBA3+IO_UBMNT, IO_UBA3+IO_UBMNT, 0,
|
{ IO_UBA3+IOBA_UBMNT, IO_UBA3+IOBA_UBMNT+IOLN_UBMNT,
|
||||||
&rd_zro, &wr_nop }, /* Unibus 3 maint */
|
NULL, &rd_zro, &wr_nop }, /* Unibus 3 maint */
|
||||||
{ IO_UBA3+IO_TCUBASE, IO_UBA3+IO_TCUBASE+05, 0,
|
{ IO_UBA3+IOBA_TCU, IO_UBA3+IOBA_TCU+IOLN_TCU,
|
||||||
&tcu_rd, &wr_nop }, /* TCU150 */
|
NULL, &tcu_rd, &wr_nop }, /* TCU150 */
|
||||||
{ 00100000, 00100000, 0, &rd_zro, &wr_nop }, /* Mem sys stat */
|
{ 00100000, 00100000, NULL, &rd_zro, &wr_nop }, /* Mem sys stat */
|
||||||
{ 0, 0, 0, NULL, NULL } };
|
{ 0, 0, 0, NULL, NULL } };
|
||||||
|
|
||||||
/* Interrupt request to interrupt action map */
|
/* Interrupt request to interrupt action map */
|
||||||
|
@ -200,7 +202,7 @@ int32 (*int_ack[32])() = { /* int ack routines */
|
||||||
int32 int_vec[32] = { /* int req to vector */
|
int32 int_vec[32] = { /* int req to vector */
|
||||||
0, 0, 0, 0, 0, 0, VEC_RP, VEC_TU,
|
0, 0, 0, 0, 0, 0, VEC_RP, VEC_TU,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
VEC_DZ0RX, VEC_DZ0TX, 0, 0, 0, 0, 0, 0,
|
VEC_DZRX, VEC_DZTX, 0, 0, 0, 0, 0, 0,
|
||||||
VEC_PTR, VEC_PTP, VEC_LP20, 0, 0, 0, 0, 0 };
|
VEC_PTR, VEC_PTP, VEC_LP20, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
/* IO 710 (DEC) TIOE - test I/O word, skip if zero
|
/* IO 710 (DEC) TIOE - test I/O word, skip if zero
|
||||||
|
@ -396,8 +398,8 @@ struct iolink *p;
|
||||||
|
|
||||||
pa = (int32) ea; /* cvt addr to 32b */
|
pa = (int32) ea; /* cvt addr to 32b */
|
||||||
for (p = &iotable[0]; p -> low != 0; p++ ) {
|
for (p = &iotable[0]; p -> low != 0; p++ ) {
|
||||||
if ((pa >= p -> low) && (pa <= p -> high) &&
|
if ((pa >= p -> low) && (pa < p -> high) &&
|
||||||
((p -> enb == 0) || (dev_enb & p -> enb))) {
|
((p -> enb == NULL) || *p -> enb)) {
|
||||||
p -> read (&val, pa, READ);
|
p -> read (&val, pa, READ);
|
||||||
pi_eval ();
|
pi_eval ();
|
||||||
return ((d10) val); } }
|
return ((d10) val); } }
|
||||||
|
@ -411,8 +413,8 @@ struct iolink *p;
|
||||||
|
|
||||||
pa = (int32) ea; /* cvt addr to 32b */
|
pa = (int32) ea; /* cvt addr to 32b */
|
||||||
for (p = &iotable[0]; p -> low != 0; p++ ) {
|
for (p = &iotable[0]; p -> low != 0; p++ ) {
|
||||||
if ((pa >= p -> low) && (pa <= p -> high) &&
|
if ((pa >= p -> low) && (pa < p -> high) &&
|
||||||
((p -> enb == 0) || (dev_enb & p -> enb))) {
|
((p -> enb == NULL) || *p -> enb)) {
|
||||||
p -> write ((int32) val, pa, mode);
|
p -> write ((int32) val, pa, mode);
|
||||||
pi_eval ();
|
pi_eval ();
|
||||||
return; } }
|
return; } }
|
||||||
|
|
37
pdp10_mdfp.c
37
pdp10_mdfp.c
|
@ -91,6 +91,7 @@
|
||||||
format (so-called G floating). These instructions were not
|
format (so-called G floating). These instructions were not
|
||||||
implemented in the KS10 and are treated as MUUO's.
|
implemented in the KS10 and are treated as MUUO's.
|
||||||
|
|
||||||
|
31-Aug-01 RMS Changed int64 to t_int64 for Windoze
|
||||||
10-Aug-01 RMS Removed register in declarations
|
10-Aug-01 RMS Removed register in declarations
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -98,10 +99,10 @@
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
struct ufp { /* unpacked fp number */
|
struct ufp { /* unpacked fp number */
|
||||||
int32 sign; /* sign */
|
int32 sign; /* sign */
|
||||||
int32 exp; /* exponent */
|
int32 exp; /* exponent */
|
||||||
uint64 fhi; /* fraction high */
|
t_uint64 fhi; /* fraction high */
|
||||||
uint64 flo; }; /* for double prec */
|
t_uint64 flo; }; /* for double prec */
|
||||||
|
|
||||||
typedef struct ufp UFP;
|
typedef struct ufp UFP;
|
||||||
|
|
||||||
|
@ -154,7 +155,7 @@ extern d10 *ac_cur; /* current AC block */
|
||||||
extern int32 flags; /* flags */
|
extern int32 flags; /* flags */
|
||||||
void mul (d10 a, d10 b, d10 *rs);
|
void mul (d10 a, d10 b, d10 *rs);
|
||||||
void funpack (d10 h, d10 l, UFP *r, t_bool sgn);
|
void funpack (d10 h, d10 l, UFP *r, t_bool sgn);
|
||||||
void fnorm (UFP *r, int64 rnd);
|
void fnorm (UFP *r, t_int64 rnd);
|
||||||
d10 fpack (UFP *r, d10 *lo, t_bool fdvneg);
|
d10 fpack (UFP *r, d10 *lo, t_bool fdvneg);
|
||||||
|
|
||||||
/* Integer multiply - checked against KS-10 ucode */
|
/* Integer multiply - checked against KS-10 ucode */
|
||||||
|
@ -197,9 +198,9 @@ return TRUE;
|
||||||
|
|
||||||
void mul (d10 s1, d10 s2, d10 *rs)
|
void mul (d10 s1, d10 s2, d10 *rs)
|
||||||
{
|
{
|
||||||
uint64 a = ABS (s1);
|
t_uint64 a = ABS (s1);
|
||||||
uint64 b = ABS (s2);
|
t_uint64 b = ABS (s2);
|
||||||
uint64 t, u, r;
|
t_uint64 t, u, r;
|
||||||
|
|
||||||
if ((a == 0) || (b == 0)) { /* operand = 0? */
|
if ((a == 0) || (b == 0)) { /* operand = 0? */
|
||||||
rs[0] = rs[1] = 0; /* result 0 */
|
rs[0] = rs[1] = 0; /* result 0 */
|
||||||
|
@ -232,7 +233,7 @@ t_bool divi (int32 ac, d10 b, d10 *rs)
|
||||||
{
|
{
|
||||||
int32 p1 = ADDAC (ac, 1);
|
int32 p1 = ADDAC (ac, 1);
|
||||||
d10 dvr = ABS (b); /* make divr positive */
|
d10 dvr = ABS (b); /* make divr positive */
|
||||||
int64 t;
|
t_int64 t;
|
||||||
int32 i;
|
int32 i;
|
||||||
d10 dvd[2];
|
d10 dvd[2];
|
||||||
|
|
||||||
|
@ -373,7 +374,7 @@ else { funpack (op1, 0, &a, SFRC); /* unpack operands */
|
||||||
b = t;
|
b = t;
|
||||||
ediff = -ediff; }
|
ediff = -ediff; }
|
||||||
if (ediff > 63) ediff = 63; /* cap diff at 63 */
|
if (ediff > 63) ediff = 63; /* cap diff at 63 */
|
||||||
if (ediff) b.fhi = (int64) b.fhi >> ediff; /* shift b (signed) */
|
if (ediff) b.fhi = (t_int64) b.fhi >> ediff; /* shift b (signed) */
|
||||||
a.fhi = a.fhi + b.fhi; /* add fractions */
|
a.fhi = a.fhi + b.fhi; /* add fractions */
|
||||||
if (a.sign ^ b.sign) { /* add or subtract? */
|
if (a.sign ^ b.sign) { /* add or subtract? */
|
||||||
if (a.fhi & FP_UCRY) { /* subtract, frac -? */
|
if (a.fhi & FP_UCRY) { /* subtract, frac -? */
|
||||||
|
@ -420,7 +421,7 @@ return fpack (&a, NULL, FALSE);
|
||||||
t_bool fdv (d10 op1, d10 op2, d10 *rs, t_bool rnd)
|
t_bool fdv (d10 op1, d10 op2, d10 *rs, t_bool rnd)
|
||||||
{
|
{
|
||||||
UFP a, b;
|
UFP a, b;
|
||||||
uint64 savhi;
|
t_uint64 savhi;
|
||||||
t_bool rem = FALSE;
|
t_bool rem = FALSE;
|
||||||
|
|
||||||
funpack (op1, 0, &a, AFRC); /* unpack operands */
|
funpack (op1, 0, &a, AFRC); /* unpack operands */
|
||||||
|
@ -479,7 +480,7 @@ return fpack (&a, NULL, FALSE); /* pack result */
|
||||||
void fix (int32 ac, d10 mb, t_bool rnd)
|
void fix (int32 ac, d10 mb, t_bool rnd)
|
||||||
{
|
{
|
||||||
int32 sc;
|
int32 sc;
|
||||||
uint64 so;
|
t_uint64 so;
|
||||||
UFP a;
|
UFP a;
|
||||||
|
|
||||||
funpack (mb, 0, &a, AFRC); /* unpack operand */
|
funpack (mb, 0, &a, AFRC); /* unpack operand */
|
||||||
|
@ -521,11 +522,11 @@ else {
|
||||||
ediff = -ediff; }
|
ediff = -ediff; }
|
||||||
if (ediff > 127) ediff = 127; /* cap diff at 127 */
|
if (ediff > 127) ediff = 127; /* cap diff at 127 */
|
||||||
if (ediff > 63) { /* diff > 63? */
|
if (ediff > 63) { /* diff > 63? */
|
||||||
a.flo = (int64) b.fhi >> (ediff - 64); /* b hi to a lo */
|
a.flo = (t_int64) b.fhi >> (ediff - 64); /* b hi to a lo */
|
||||||
b.fhi = b.sign? FP_ONES: 0; } /* hi = all sign */
|
b.fhi = b.sign? FP_ONES: 0; } /* hi = all sign */
|
||||||
else if (ediff) { /* diff <= 63 */
|
else if (ediff) { /* diff <= 63 */
|
||||||
a.flo = (b.flo >> ediff) | (b.fhi << (64 - ediff));
|
a.flo = (b.flo >> ediff) | (b.fhi << (64 - ediff));
|
||||||
b.fhi = (int64) b.fhi >> ediff; } /* shift b (signed) */
|
b.fhi = (t_int64) b.fhi >> ediff; } /* shift b (signed) */
|
||||||
a.fhi = a.fhi + b.fhi; /* do add */
|
a.fhi = a.fhi + b.fhi; /* do add */
|
||||||
if (a.sign ^ b.sign) { /* add or subtract? */
|
if (a.sign ^ b.sign) { /* add or subtract? */
|
||||||
if (a.fhi & FP_UCRY) { /* subtract, frac -? */
|
if (a.fhi & FP_UCRY) { /* subtract, frac -? */
|
||||||
|
@ -552,7 +553,7 @@ return;
|
||||||
void dfmp (int32 ac, d10 *rs)
|
void dfmp (int32 ac, d10 *rs)
|
||||||
{
|
{
|
||||||
int32 p1 = ADDAC (ac, 1);
|
int32 p1 = ADDAC (ac, 1);
|
||||||
uint64 xh, xl, yh, yl, mid;
|
t_uint64 xh, xl, yh, yl, mid;
|
||||||
UFP a, b;
|
UFP a, b;
|
||||||
|
|
||||||
funpack (AC(ac), AC(p1), &a, AFRC); /* unpack operands */
|
funpack (AC(ac), AC(p1), &a, AFRC); /* unpack operands */
|
||||||
|
@ -587,7 +588,7 @@ void dfdv (int32 ac, d10 *rs)
|
||||||
{
|
{
|
||||||
int32 p1 = ADDAC (ac, 1);
|
int32 p1 = ADDAC (ac, 1);
|
||||||
int32 i;
|
int32 i;
|
||||||
uint64 qu = 0;
|
t_uint64 qu = 0;
|
||||||
UFP a, b;
|
UFP a, b;
|
||||||
|
|
||||||
funpack (AC(ac), AC(p1), &a, AFRC); /* unpack operands */
|
funpack (AC(ac), AC(p1), &a, AFRC); /* unpack operands */
|
||||||
|
@ -636,10 +637,10 @@ return;
|
||||||
|
|
||||||
/* Normalize and optionally round floating point operand */
|
/* Normalize and optionally round floating point operand */
|
||||||
|
|
||||||
void fnorm (UFP *a, int64 rnd)
|
void fnorm (UFP *a, t_int64 rnd)
|
||||||
{
|
{
|
||||||
int32 i;
|
int32 i;
|
||||||
static uint64 normmask[6] = {
|
static t_uint64 normmask[6] = {
|
||||||
0x6000000000000000, 0x7800000000000000, 0x7F80000000000000,
|
0x6000000000000000, 0x7800000000000000, 0x7F80000000000000,
|
||||||
0x7FFF800000000000, 0x7FFFFFFF80000000, 0x7FFFFFFFFFFFFFFF };
|
0x7FFF800000000000, 0x7FFFFFFF80000000, 0x7FFFFFFFFFFFFFFF };
|
||||||
static int32 normtab[7] = { 1, 2, 4, 8, 16, 32, 63 };
|
static int32 normtab[7] = { 1, 2, 4, 8, 16, 32, 63 };
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
ptr paper tape reader
|
ptr paper tape reader
|
||||||
ptp paper tape punch
|
ptp paper tape punch
|
||||||
|
|
||||||
|
07-Sep-01 RMS Revised disable mechanism
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pdp10_defs.h"
|
#include "pdp10_defs.h"
|
||||||
|
@ -34,11 +36,12 @@
|
||||||
#define PTPCSR_IMP (CSR_ERR + CSR_DONE + CSR_IE) /* paper tape punch */
|
#define PTPCSR_IMP (CSR_ERR + CSR_DONE + CSR_IE) /* paper tape punch */
|
||||||
#define PTPCSR_RW (CSR_IE)
|
#define PTPCSR_RW (CSR_IE)
|
||||||
|
|
||||||
extern int32 int_req, dev_enb;
|
extern int32 int_req;
|
||||||
int32 ptr_csr = 0; /* control/status */
|
int32 ptr_csr = 0; /* control/status */
|
||||||
int32 ptr_stopioe = 0; /* stop on error */
|
int32 ptr_stopioe = 0; /* stop on error */
|
||||||
int32 ptp_csr = 0; /* control/status */
|
int32 ptp_csr = 0; /* control/status */
|
||||||
int32 ptp_stopioe = 0; /* stop on error */
|
int32 ptp_stopioe = 0; /* stop on error */
|
||||||
|
int32 pt_enb = 0; /* device enable */
|
||||||
t_stat ptr_svc (UNIT *uptr);
|
t_stat ptr_svc (UNIT *uptr);
|
||||||
t_stat ptp_svc (UNIT *uptr);
|
t_stat ptp_svc (UNIT *uptr);
|
||||||
t_stat ptr_reset (DEVICE *dptr);
|
t_stat ptr_reset (DEVICE *dptr);
|
||||||
|
@ -69,7 +72,7 @@ REG ptr_reg[] = {
|
||||||
{ DRDATA (POS, ptr_unit.pos, 31), PV_LEFT },
|
{ DRDATA (POS, ptr_unit.pos, 31), PV_LEFT },
|
||||||
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
|
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
|
||||||
{ FLDATA (STOP_IOE, ptr_stopioe, 0) },
|
{ FLDATA (STOP_IOE, ptr_stopioe, 0) },
|
||||||
{ FLDATA (*DEVENB, dev_enb, INT_V_PTR), REG_HRO },
|
{ FLDATA (*DEVENB, pt_enb, 0), REG_HRO },
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
DEVICE ptr_dev = {
|
DEVICE ptr_dev = {
|
||||||
|
@ -98,7 +101,7 @@ REG ptp_reg[] = {
|
||||||
{ DRDATA (POS, ptp_unit.pos, 31), PV_LEFT },
|
{ DRDATA (POS, ptp_unit.pos, 31), PV_LEFT },
|
||||||
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
|
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
|
||||||
{ FLDATA (STOP_IOE, ptp_stopioe, 0) },
|
{ FLDATA (STOP_IOE, ptp_stopioe, 0) },
|
||||||
{ FLDATA (*DEVENB, dev_enb, INT_V_PTR), REG_HRO },
|
{ FLDATA (*DEVENB, pt_enb, 0), REG_HRO },
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
DEVICE ptp_dev = {
|
DEVICE ptp_dev = {
|
||||||
|
|
157
pdp10_rp.c
157
pdp10_rp.c
|
@ -25,8 +25,14 @@
|
||||||
|
|
||||||
rp RH/RP/RM moving head disks
|
rp RH/RP/RM moving head disks
|
||||||
|
|
||||||
|
23-Oct-01 RMS Fixed bug in error interrupts
|
||||||
|
New IO page address constants
|
||||||
|
05-Oct-01 RMS Rewrote interrupt handling from schematics
|
||||||
|
02-Oct-01 RMS Revised CS1 write code
|
||||||
|
30-Sep-01 RMS Moved CS1<5:0> into drives
|
||||||
|
28-Sep-01 RMS Fixed interrupt handling for SC/ATA
|
||||||
23-Aug-01 RMS Added read/write header stubs for ITS
|
23-Aug-01 RMS Added read/write header stubs for ITS
|
||||||
(found by Mirian Crzig Lennox)
|
(found by Mirian Crzig Lennox)
|
||||||
13-Jul-01 RMS Changed fread call to fxread (found by Peter Schorn)
|
13-Jul-01 RMS Changed fread call to fxread (found by Peter Schorn)
|
||||||
14-May-01 RMS Added check for unattached drive
|
14-May-01 RMS Added check for unattached drive
|
||||||
|
|
||||||
|
@ -35,13 +41,19 @@
|
||||||
100% compatible) family of interfaces into the KS10 Unibus via
|
100% compatible) family of interfaces into the KS10 Unibus via
|
||||||
the RH11 disk controller.
|
the RH11 disk controller.
|
||||||
|
|
||||||
WARNING: This controller is somewhat abstract. It is intended to run
|
WARNING: The interupt logic of the RH11/RH70 is unusual and must be
|
||||||
the operating system drivers for the PDP-10 operating systems and
|
simulated with great precision. The RH11 has an internal interrupt
|
||||||
nothing more. Most error and all diagnostic functions have been
|
request flop, CSTB INTR, which is controlled as follows:
|
||||||
omitted. In addition, the controller conflates the RP04/05/06 series
|
- Writing IE and DONE simultaneously sets CSTB INTR
|
||||||
controllers with the RM02/03/05/80 series controllers and with the
|
- Controller clear, INIT, and interrupt acknowledge clear CSTB INTR
|
||||||
RP07 controller. There are actually significant differences, which
|
(and also clear IE)
|
||||||
have been highlighted where noticed.
|
- A transition of DONE from 0 to 1 sets CSTB from INTR
|
||||||
|
The output of INTR is OR'd with the AND of RPCS1<SC,DONE,IE> to
|
||||||
|
create the interrupt request signal. Thus,
|
||||||
|
- The DONE interrupt is edge sensitive, but the SC interrupt is
|
||||||
|
level sensitive.
|
||||||
|
- The DONE interrupt, once set, is not disabled if IE is cleared,
|
||||||
|
but the SC interrupt is.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pdp10_defs.h"
|
#include "pdp10_defs.h"
|
||||||
|
@ -89,6 +101,7 @@
|
||||||
#define FNC_PRESET 010 /* read-in preset */
|
#define FNC_PRESET 010 /* read-in preset */
|
||||||
#define FNC_PACK 011 /* pack acknowledge */
|
#define FNC_PACK 011 /* pack acknowledge */
|
||||||
#define FNC_SEARCH 014 /* search */
|
#define FNC_SEARCH 014 /* search */
|
||||||
|
#define FNC_XFER 024 /* >=? data xfr */
|
||||||
#define FNC_WCHK 024 /* write check */
|
#define FNC_WCHK 024 /* write check */
|
||||||
#define FNC_WRITE 030 /* write */
|
#define FNC_WRITE 030 /* write */
|
||||||
#define FNC_WRITEH 031 /* write w/ headers */
|
#define FNC_WRITEH 031 /* write w/ headers */
|
||||||
|
@ -104,7 +117,7 @@
|
||||||
#define CS1_TRE 0040000 /* transfer err */
|
#define CS1_TRE 0040000 /* transfer err */
|
||||||
#define CS1_SC 0100000 /* special cond */
|
#define CS1_SC 0100000 /* special cond */
|
||||||
#define CS1_MBZ 0012000
|
#define CS1_MBZ 0012000
|
||||||
#define CS1_RW (CS1_FNC | CS1_IE | CS1_UAE)
|
#define CS1_DRV (CS1_FNC | CS1_GO)
|
||||||
#define GET_FNC(x) (((x) >> CS1_V_FNC) & CS1_M_FNC)
|
#define GET_FNC(x) (((x) >> CS1_V_FNC) & CS1_M_FNC)
|
||||||
#define GET_UAE(x) (((x) & CS1_UAE) << (16 - CS1_V_UAE))
|
#define GET_UAE(x) (((x) & CS1_UAE) << (16 - CS1_V_UAE))
|
||||||
|
|
||||||
|
@ -211,7 +224,7 @@
|
||||||
#define GET_DA(c,fs,d) ((((GET_CY (c) * drv_tab[d].surf) + \
|
#define GET_DA(c,fs,d) ((((GET_CY (c) * drv_tab[d].surf) + \
|
||||||
GET_SF (fs)) * drv_tab[d].sect) + GET_SC (fs))
|
GET_SF (fs)) * drv_tab[d].sect) + GET_SC (fs))
|
||||||
|
|
||||||
/* RPCC - 176736 - current cylinder - unimplemented */
|
/* RPCC - 176736 - current cylinder */
|
||||||
/* RPER2 - 176740 - error status 2 - drive unsafe conditions - unimplemented */
|
/* RPER2 - 176740 - error status 2 - drive unsafe conditions - unimplemented */
|
||||||
/* RPER3 - 176742 - error status 3 - more unsafe conditions - unimplemented */
|
/* RPER3 - 176742 - error status 3 - more unsafe conditions - unimplemented */
|
||||||
/* RPEC1 - 176744 - ECC status 1 - unimplemented */
|
/* RPEC1 - 176744 - ECC status 1 - unimplemented */
|
||||||
|
@ -315,6 +328,7 @@ int32 rper2 = 0; /* error status 2 */
|
||||||
int32 rper3 = 0; /* error status 3 */
|
int32 rper3 = 0; /* error status 3 */
|
||||||
int32 rpec1 = 0; /* ECC correction 1 */
|
int32 rpec1 = 0; /* ECC correction 1 */
|
||||||
int32 rpec2 = 0; /* ECC correction 2 */
|
int32 rpec2 = 0; /* ECC correction 2 */
|
||||||
|
int32 rpiff = 0; /* INTR flip/flop */
|
||||||
int32 rp_stopioe = 1; /* stop on error */
|
int32 rp_stopioe = 1; /* stop on error */
|
||||||
int32 rp_swait = 10; /* seek time */
|
int32 rp_swait = 10; /* seek time */
|
||||||
int32 rp_rwait = 10; /* rotate time */
|
int32 rp_rwait = 10; /* rotate time */
|
||||||
|
@ -323,7 +337,7 @@ int reg_in_drive[32] = {
|
||||||
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
void update_rpcs (int32 flags, int32 drv);
|
void update_rpcs (int32 flags, int32 drv);
|
||||||
void rp_go (int32 drv);
|
void rp_go (int32 drv, int32 fnc);
|
||||||
t_stat rp_set_size (UNIT *uptr, int32 value);
|
t_stat rp_set_size (UNIT *uptr, int32 value);
|
||||||
t_stat rp_svc (UNIT *uptr);
|
t_stat rp_svc (UNIT *uptr);
|
||||||
t_stat rp_reset (DEVICE *dptr);
|
t_stat rp_reset (DEVICE *dptr);
|
||||||
|
@ -371,6 +385,7 @@ REG rp_reg[] = {
|
||||||
{ ORDATA (RPEC2, rpec2, 16) },
|
{ ORDATA (RPEC2, rpec2, 16) },
|
||||||
{ ORDATA (RPMR, rpmr, 16) },
|
{ ORDATA (RPMR, rpmr, 16) },
|
||||||
{ ORDATA (RPDB, rpdb, 16) },
|
{ ORDATA (RPDB, rpdb, 16) },
|
||||||
|
{ FLDATA (IFF, rpiff, 0) },
|
||||||
{ FLDATA (INT, int_req, INT_V_RP) },
|
{ FLDATA (INT, int_req, INT_V_RP) },
|
||||||
{ FLDATA (SC, rpcs1, CSR_V_ERR) },
|
{ FLDATA (SC, rpcs1, CSR_V_ERR) },
|
||||||
{ FLDATA (DONE, rpcs1, CSR_V_DONE) },
|
{ FLDATA (DONE, rpcs1, CSR_V_DONE) },
|
||||||
|
@ -393,6 +408,14 @@ REG rp_reg[] = {
|
||||||
{ ORDATA (RPDE5, rper1[5], 16) },
|
{ ORDATA (RPDE5, rper1[5], 16) },
|
||||||
{ ORDATA (RPDE6, rper1[6], 16) },
|
{ ORDATA (RPDE6, rper1[6], 16) },
|
||||||
{ ORDATA (RPDE7, rper1[7], 16) },
|
{ ORDATA (RPDE7, rper1[7], 16) },
|
||||||
|
{ ORDATA (RPFN0, rp_unit[0].FUNC, 5), REG_HRO },
|
||||||
|
{ ORDATA (RPFN1, rp_unit[1].FUNC, 5), REG_HRO },
|
||||||
|
{ ORDATA (RPFN2, rp_unit[2].FUNC, 5), REG_HRO },
|
||||||
|
{ ORDATA (RPFN3, rp_unit[3].FUNC, 5), REG_HRO },
|
||||||
|
{ ORDATA (RPFN4, rp_unit[4].FUNC, 5), REG_HRO },
|
||||||
|
{ ORDATA (RPFN5, rp_unit[5].FUNC, 5), REG_HRO },
|
||||||
|
{ ORDATA (RPFN6, rp_unit[6].FUNC, 5), REG_HRO },
|
||||||
|
{ ORDATA (RPFN7, rp_unit[7].FUNC, 5), REG_HRO },
|
||||||
{ GRDATA (FLG0, rp_unit[0].flags, 8, UNIT_W_UF, UNIT_V_UF - 1),
|
{ GRDATA (FLG0, rp_unit[0].flags, 8, UNIT_W_UF, UNIT_V_UF - 1),
|
||||||
REG_HRO },
|
REG_HRO },
|
||||||
{ GRDATA (FLG1, rp_unit[1].flags, 8, UNIT_W_UF, UNIT_V_UF - 1),
|
{ GRDATA (FLG1, rp_unit[1].flags, 8, UNIT_W_UF, UNIT_V_UF - 1),
|
||||||
|
@ -550,9 +573,11 @@ return SCPE_OK;
|
||||||
t_stat rp_wr (int32 data, int32 PA, int32 access)
|
t_stat rp_wr (int32 data, int32 PA, int32 access)
|
||||||
{
|
{
|
||||||
int32 cs1f, drv, i, j;
|
int32 cs1f, drv, i, j;
|
||||||
|
UNIT *uptr;
|
||||||
|
|
||||||
cs1f = 0; /* no int on cs1 upd */
|
cs1f = 0; /* no int on cs1 upd */
|
||||||
drv = GET_UNIT (rpcs2); /* get current unit */
|
drv = GET_UNIT (rpcs2); /* get current unit */
|
||||||
|
uptr = rp_dev.units + drv; /* get unit */
|
||||||
j = (PA >> 1) & 037; /* get reg offset */
|
j = (PA >> 1) & 037; /* get reg offset */
|
||||||
if (reg_in_drive[j] && (rp_unit[drv].flags & UNIT_DIS)) { /* nx disk */
|
if (reg_in_drive[j] && (rp_unit[drv].flags & UNIT_DIS)) { /* nx disk */
|
||||||
rpcs2 = rpcs2 | CS2_NED; /* set error flag */
|
rpcs2 = rpcs2 | CS2_NED; /* set error flag */
|
||||||
|
@ -566,17 +591,27 @@ if (reg_in_drive[j] && sim_is_active (&rp_unit[drv])) { /* unit busy? */
|
||||||
switch (j) { /* decode PA<5:1> */
|
switch (j) { /* decode PA<5:1> */
|
||||||
case 000: /* RPCS1 */
|
case 000: /* RPCS1 */
|
||||||
if ((access == WRITEB) && (PA & 1)) data = data << 8;
|
if ((access == WRITEB) && (PA & 1)) data = data << 8;
|
||||||
else { if ((data & CS1_IE) == 0) int_req = int_req & ~INT_RP;
|
|
||||||
else if (data & CS1_DONE) int_req = int_req | INT_RP; }
|
|
||||||
if (data & CS1_TRE) { /* error clear? */
|
if (data & CS1_TRE) { /* error clear? */
|
||||||
rpcs1 = rpcs1 & ~CS1_TRE; /* clr CS1<TRE> */
|
rpcs1 = rpcs1 & ~CS1_TRE; /* clr CS1<TRE> */
|
||||||
rpcs2 = rpcs2 & ~CS2_ERR; } /* clr CS2<15:8> */
|
rpcs2 = rpcs2 & ~CS2_ERR; } /* clr CS2<15:8> */
|
||||||
if (access == WRITEB) data = (rpcs1 & /* merge data */
|
if ((access == WRITE) || (PA & 1)) { /* hi byte write? */
|
||||||
((PA & 1)? 0377: 0177400)) | data;
|
if (rpcs1 & CS1_DONE) /* done set? */
|
||||||
rpcs1 = (rpcs1 & ~CS1_RW) | (data & CS1_RW);
|
rpcs1 = (rpcs1 & ~CS1_UAE) | (data & CS1_UAE); }
|
||||||
if (data & CS1_GO) { /* new command? */
|
if ((access == WRITE) || !(PA & 1)) { /* lo byte write? */
|
||||||
if (rpcs1 & CS1_DONE) rp_go (drv); /* start if not busy */
|
if ((data & CS1_DONE) && (data & CS1_IE)) /* to DONE+IE? */
|
||||||
else rpcs2 = rpcs2 | CS2_PGE; } /* else prog error */
|
rpiff = 1; /* set CSTB INTR */
|
||||||
|
rpcs1 = (rpcs1 & ~CS1_IE) | (data & CS1_IE);
|
||||||
|
if (uptr -> flags & UNIT_DIS) { /* nx disk? */
|
||||||
|
rpcs2 = rpcs2 | CS2_NED; /* set error flag */
|
||||||
|
cs1f = CS1_SC; } /* req interrupt */
|
||||||
|
else if (sim_is_active (uptr))
|
||||||
|
rper1[drv] = rper1[drv] | ER1_RMR; /* won't write */
|
||||||
|
else if (data & CS1_GO) { /* start op */
|
||||||
|
uptr -> FUNC = GET_FNC (data); /* set func */
|
||||||
|
if ((uptr -> FUNC >= FNC_XFER) && /* data xfer and */
|
||||||
|
((rpcs1 & CS1_DONE) == 0)) /* ~rdy? PGE */
|
||||||
|
rpcs2 = rpcs2 | CS2_PGE;
|
||||||
|
else rp_go (drv, uptr -> FUNC); } }
|
||||||
break;
|
break;
|
||||||
case 001: /* RPWC */
|
case 001: /* RPWC */
|
||||||
if (access == WRITEB) data = (PA & 1)?
|
if (access == WRITEB) data = (PA & 1)?
|
||||||
|
@ -650,29 +685,23 @@ update_rpcs (cs1f, drv); /* update status */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initiate operation */
|
/* Initiate operation - unit not busy, function set */
|
||||||
|
|
||||||
void rp_go (int32 drv)
|
void rp_go (int32 drv, int32 fnc)
|
||||||
{
|
{
|
||||||
int32 dc, dtype, fnc;
|
int32 dc, dtype, t;
|
||||||
UNIT *uptr;
|
UNIT *uptr;
|
||||||
|
|
||||||
fnc = GET_FNC (rpcs1); /* get function */
|
|
||||||
uptr = rp_dev.units + drv; /* get unit */
|
uptr = rp_dev.units + drv; /* get unit */
|
||||||
if (uptr -> flags & UNIT_DIS) { /* nx unit? */
|
if (uptr -> flags & UNIT_DIS) { /* nx unit? */
|
||||||
rpcs2 = rpcs2 | CS2_NED; /* set error flag */
|
rpcs2 = rpcs2 | CS2_NED; /* set error flag */
|
||||||
update_rpcs (CS1_SC, drv); /* request intr */
|
update_rpcs (CS1_SC, drv); /* request intr */
|
||||||
return; }
|
return; }
|
||||||
if (fnc != FNC_DCLR) { /* not clear? */
|
if ((fnc != FNC_DCLR) && (rpds[drv] & DS_ERR)) { /* err & ~clear? */
|
||||||
if ((rpds[drv] & DS_ERR) || /* error or */
|
rper1[drv] = rper1[drv] | ER1_ILF; /* not allowed */
|
||||||
((rpds[drv] & DS_RDY) == 0)) { /* not ready? */
|
rpds[drv] = rpds[drv] | DS_ATA; /* set attention */
|
||||||
rpcs2 = rpcs2 | CS2_PGE; /* set error flag */
|
update_rpcs (CS1_SC, drv); /* request intr */
|
||||||
update_rpcs (CS1_SC, drv); /* request intr */
|
return; }
|
||||||
return; }
|
|
||||||
if ((uptr -> flags & UNIT_ATT) == 0) { /* not attached? */
|
|
||||||
rper1[drv] = rper1[drv] | ER1_UNS; /* unsafe */
|
|
||||||
update_rpcs (CS1_SC, drv); /* request intr */
|
|
||||||
return; } }
|
|
||||||
dtype = GET_DTYPE (uptr -> flags); /* get drive type */
|
dtype = GET_DTYPE (uptr -> flags); /* get drive type */
|
||||||
rpds[drv] = rpds[drv] & ~DS_ATA; /* clear attention */
|
rpds[drv] = rpds[drv] & ~DS_ATA; /* clear attention */
|
||||||
dc = rpdc; /* assume seek, sch */
|
dc = rpdc; /* assume seek, sch */
|
||||||
|
@ -695,7 +724,9 @@ case FNC_PACK: /* pack acknowledge */
|
||||||
|
|
||||||
case FNC_OFFSET: /* offset mode */
|
case FNC_OFFSET: /* offset mode */
|
||||||
case FNC_RETURN:
|
case FNC_RETURN:
|
||||||
uptr -> FUNC = fnc; /* save function */
|
if ((uptr -> flags & UNIT_ATT) == 0) { /* not attached? */
|
||||||
|
rper1[drv] = rper1[drv] | ER1_UNS; /* unsafe */
|
||||||
|
break; }
|
||||||
rpds[drv] = (rpds[drv] & ~DS_RDY) | DS_PIP; /* set positioning */
|
rpds[drv] = (rpds[drv] & ~DS_RDY) | DS_PIP; /* set positioning */
|
||||||
sim_activate (uptr, rp_swait); /* time operation */
|
sim_activate (uptr, rp_swait); /* time operation */
|
||||||
return;
|
return;
|
||||||
|
@ -705,40 +736,46 @@ case FNC_RECAL: /* recalibrate */
|
||||||
dc = 0; /* seek to 0 */
|
dc = 0; /* seek to 0 */
|
||||||
case FNC_SEEK: /* seek */
|
case FNC_SEEK: /* seek */
|
||||||
case FNC_SEARCH: /* search */
|
case FNC_SEARCH: /* search */
|
||||||
|
if ((uptr -> flags & UNIT_ATT) == 0) { /* not attached? */
|
||||||
|
rper1[drv] = rper1[drv] | ER1_UNS; /* unsafe */
|
||||||
|
break; }
|
||||||
if ((GET_CY (dc) >= drv_tab[dtype].cyl) || /* bad cylinder */
|
if ((GET_CY (dc) >= drv_tab[dtype].cyl) || /* bad cylinder */
|
||||||
(GET_SF (rpda) >= drv_tab[dtype].surf) || /* bad surface */
|
(GET_SF (rpda) >= drv_tab[dtype].surf) || /* bad surface */
|
||||||
(GET_SC (rpda) >= drv_tab[dtype].sect)) { /* or bad sector? */
|
(GET_SC (rpda) >= drv_tab[dtype].sect)) { /* or bad sector? */
|
||||||
rper1[drv] = rper1[drv] | ER1_IAE;
|
rper1[drv] = rper1[drv] | ER1_IAE;
|
||||||
break; }
|
break; }
|
||||||
rpds[drv] = (rpds[drv] & ~DS_RDY) | DS_PIP; /* set positioning */
|
rpds[drv] = (rpds[drv] & ~DS_RDY) | DS_PIP; /* set positioning */
|
||||||
sim_activate (uptr, rp_swait * abs (dc - uptr -> CYL));
|
t = abs (dc - uptr -> CYL); /* cyl diff */
|
||||||
uptr -> FUNC = fnc; /* save function */
|
if (t == 0) t = 1; /* min time */
|
||||||
|
sim_activate (uptr, rp_swait * t); /* schedule */
|
||||||
uptr -> CYL = dc; /* save cylinder */
|
uptr -> CYL = dc; /* save cylinder */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case FNC_WRITEH: /* write headers */
|
case FNC_WRITEH: /* write headers */
|
||||||
case FNC_WRITE: /* write */
|
case FNC_WRITE: /* write */
|
||||||
case FNC_WCHK: /* write check */
|
case FNC_WCHK: /* write check */
|
||||||
case FNC_READ: /* read */
|
case FNC_READ: /* read */
|
||||||
case FNC_READH: /* read headers */
|
case FNC_READH: /* read headers */
|
||||||
|
if ((uptr -> flags & UNIT_ATT) == 0) { /* not attached? */
|
||||||
|
rper1[drv] = rper1[drv] | ER1_UNS; /* unsafe */
|
||||||
|
break; }
|
||||||
rpcs2 = rpcs2 & ~CS2_ERR; /* clear errors */
|
rpcs2 = rpcs2 & ~CS2_ERR; /* clear errors */
|
||||||
rpcs1 = rpcs1 & ~(CS1_TRE | CS1_MCPE | CS1_DONE);
|
rpcs1 = rpcs1 & ~(CS1_TRE | CS1_MCPE | CS1_DONE);
|
||||||
if ((GET_CY (dc) >= drv_tab[dtype].cyl) || /* bad cylinder */
|
if ((GET_CY (dc) >= drv_tab[dtype].cyl) || /* bad cylinder */
|
||||||
(GET_SF (rpda) >= drv_tab[dtype].surf) || /* bad surface */
|
(GET_SF (rpda) >= drv_tab[dtype].surf) || /* bad surface */
|
||||||
(GET_SC (rpda) >= drv_tab[dtype].sect)) { /* or bad sector? */
|
(GET_SC (rpda) >= drv_tab[dtype].sect)) { /* or bad sector? */
|
||||||
rper1[drv] = rper1[drv] | ER1_IAE;
|
rper1[drv] = rper1[drv] | ER1_IAE;
|
||||||
update_rpcs (CS1_DONE | CS1_TRE, drv); /* set done, err */
|
break; }
|
||||||
return; }
|
|
||||||
rpds[drv] = rpds[drv] & ~DS_RDY; /* clear drive rdy */
|
rpds[drv] = rpds[drv] & ~DS_RDY; /* clear drive rdy */
|
||||||
sim_activate (uptr, rp_rwait + (rp_swait * abs (dc - uptr -> CYL)));
|
sim_activate (uptr, rp_rwait + (rp_swait * abs (dc - uptr -> CYL)));
|
||||||
uptr -> FUNC = fnc; /* save function */
|
|
||||||
uptr -> CYL = dc; /* save cylinder */
|
uptr -> CYL = dc; /* save cylinder */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default: /* all others */
|
default: /* all others */
|
||||||
rper1[drv] = rper1[drv] | ER1_ILF; /* not supported */
|
rper1[drv] = rper1[drv] | ER1_ILF; /* not supported */
|
||||||
break; }
|
break; }
|
||||||
update_rpcs (CS1_SC, drv); /* error, interrupt */
|
rpds[drv] = rpds[drv] | DS_ATA; /* error, set attn */
|
||||||
|
update_rpcs (CS1_SC, drv); /* req intr */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -870,21 +907,28 @@ case FNC_READH: /* read headers */
|
||||||
perror ("RP I/O error");
|
perror ("RP I/O error");
|
||||||
clearerr (uptr -> fileref);
|
clearerr (uptr -> fileref);
|
||||||
return SCPE_IOERR; }
|
return SCPE_IOERR; }
|
||||||
case FNC_WRITEH: /* write headers stub */
|
case FNC_WRITEH: /* write headers stub */
|
||||||
update_rpcs (CS1_DONE, drv); /* set done */
|
update_rpcs (CS1_DONE, drv); /* set done */
|
||||||
break; } /* end case func */
|
break; } /* end case func */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Controller status update
|
/* Controller status update
|
||||||
First update drive status, then update RPCS1
|
|
||||||
If optional argument, request interrupt
|
Check for done transition
|
||||||
|
Update drive status
|
||||||
|
Update RPCS1
|
||||||
|
Update interrupt request
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void update_rpcs (int32 flag, int32 drv)
|
void update_rpcs (int32 flag, int32 drv)
|
||||||
{
|
{
|
||||||
int32 i;
|
int32 i;
|
||||||
|
UNIT *uptr;
|
||||||
|
|
||||||
|
if ((flag & ~rpcs1) & CS1_DONE) /* DONE 0 to 1? */
|
||||||
|
rpiff = (rpcs1 & CS1_IE)? 1: 0; /* CSTB INTR <- IE */
|
||||||
|
uptr = rp_dev.units + drv; /* get unit */
|
||||||
if (rp_unit[drv].flags & UNIT_DIS) rpds[drv] = rper1[drv] = 0;
|
if (rp_unit[drv].flags & UNIT_DIS) rpds[drv] = rper1[drv] = 0;
|
||||||
else rpds[drv] = (rpds[drv] | DS_DPR) & ~DS_PGM;
|
else rpds[drv] = (rpds[drv] | DS_DPR) & ~DS_PGM;
|
||||||
if (rp_unit[drv].flags & UNIT_ATT) rpds[drv] = rpds[drv] | DS_MOL;
|
if (rp_unit[drv].flags & UNIT_ATT) rpds[drv] = rpds[drv] | DS_MOL;
|
||||||
|
@ -892,13 +936,16 @@ else rpds[drv] = rpds[drv] & ~(DS_MOL | DS_VV | DS_RDY);
|
||||||
if (rper1[drv] | rper2 | rper3) rpds[drv] = rpds[drv] | DS_ERR | DS_ATA;
|
if (rper1[drv] | rper2 | rper3) rpds[drv] = rpds[drv] | DS_ERR | DS_ATA;
|
||||||
else rpds[drv] = rpds[drv] & ~DS_ERR;
|
else rpds[drv] = rpds[drv] & ~DS_ERR;
|
||||||
|
|
||||||
rpcs1 = (rpcs1 & ~(CS1_SC | CS1_MCPE | CS1_MBZ)) | CS1_DVA | flag;
|
rpcs1 = (rpcs1 & ~(CS1_SC | CS1_MCPE | CS1_MBZ | CS1_DRV)) | CS1_DVA | flag;
|
||||||
|
rpcs1 = rpcs1 | (uptr -> FUNC << CS1_V_FNC);
|
||||||
|
if (sim_is_active (uptr)) rpcs1 = rpcs1 | CS1_GO;
|
||||||
if (rpcs2 & CS2_ERR) rpcs1 = rpcs1 | CS1_TRE | CS1_SC;
|
if (rpcs2 & CS2_ERR) rpcs1 = rpcs1 | CS1_TRE | CS1_SC;
|
||||||
|
else if (rpcs1 & CS1_TRE) rpcs1 = rpcs1 | CS1_SC;
|
||||||
for (i = 0; i < RP_NUMDR; i++)
|
for (i = 0; i < RP_NUMDR; i++)
|
||||||
if (rpds[i] & DS_ATA) rpcs1 = rpcs1 | CS1_SC;
|
if (rpds[i] & DS_ATA) rpcs1 = rpcs1 | CS1_SC;
|
||||||
if (((rpcs1 & CS1_IE) == 0) || ((rpcs1 & CS1_DONE) == 0))
|
if (rpiff || ((rpcs1 & CS1_SC) && (rpcs1 & CS1_DONE) && (rpcs1 & CS1_IE)))
|
||||||
int_req = int_req & ~INT_RP;
|
int_req = int_req | INT_RP;
|
||||||
else if (flag) int_req = int_req | INT_RP;
|
else int_req = int_req & ~INT_RP;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -907,6 +954,7 @@ return;
|
||||||
int32 rp_inta (void)
|
int32 rp_inta (void)
|
||||||
{
|
{
|
||||||
rpcs1 = rpcs1 & ~CS1_IE; /* clear int enable */
|
rpcs1 = rpcs1 & ~CS1_IE; /* clear int enable */
|
||||||
|
rpiff = 0; /* clear CSTB INTR */
|
||||||
return VEC_RP; /* acknowledge */
|
return VEC_RP; /* acknowledge */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -923,7 +971,8 @@ rpba = rpda = 0;
|
||||||
rpof = rpdc = 0;
|
rpof = rpdc = 0;
|
||||||
rper2 = rper3 = 0;
|
rper2 = rper3 = 0;
|
||||||
rpec1 = rpec2 = 0;
|
rpec1 = rpec2 = 0;
|
||||||
int_req = int_req & ~INT_RP;
|
rpiff = 0; /* clear CSTB INTR */
|
||||||
|
int_req = int_req & ~INT_RP; /* clear intr req */
|
||||||
for (i = 0; i < RP_NUMDR; i++) {
|
for (i = 0; i < RP_NUMDR; i++) {
|
||||||
uptr = rp_dev.units + i;
|
uptr = rp_dev.units + i;
|
||||||
sim_cancel (uptr);
|
sim_cancel (uptr);
|
||||||
|
@ -998,8 +1047,8 @@ return SCPE_OK;
|
||||||
static const d10 boot_rom_dec[] = {
|
static const d10 boot_rom_dec[] = {
|
||||||
0515040000001, /* boot:hrlzi 1,1 ; uba # */
|
0515040000001, /* boot:hrlzi 1,1 ; uba # */
|
||||||
0201000140001, /* movei 0,140001 ; vld,fst,pg 1 */
|
0201000140001, /* movei 0,140001 ; vld,fst,pg 1 */
|
||||||
0713001000000+IO_UBMAP+1, /* wrio 0,763001(1); set ubmap */
|
0713001000000+IOBA_UBMAP+1, /* wrio 0,763001(1); set ubmap */
|
||||||
0435040000000+IO_RHBASE, /* iori 1,776700 ; rh addr */
|
0435040000000+IOBA_RP, /* iori 1,776700 ; rh addr */
|
||||||
0202040000000+FE_RHBASE, /* movem 1,FE_RHBASE */
|
0202040000000+FE_RHBASE, /* movem 1,FE_RHBASE */
|
||||||
0201000000040, /* movei 0,40 ; ctrl reset */
|
0201000000040, /* movei 0,40 ; ctrl reset */
|
||||||
0713001000010, /* wrio 0,10(1) ; ->RPCS2 */
|
0713001000010, /* wrio 0,10(1) ; ->RPCS2 */
|
||||||
|
@ -1045,8 +1094,8 @@ static const d10 boot_rom_dec[] = {
|
||||||
static const d10 boot_rom_its[] = {
|
static const d10 boot_rom_its[] = {
|
||||||
0515040000001, /* boot:hrlzi 1,1 ; uba # */
|
0515040000001, /* boot:hrlzi 1,1 ; uba # */
|
||||||
0201000140001, /* movei 0,140001 ; vld,fst,pg 1 */
|
0201000140001, /* movei 0,140001 ; vld,fst,pg 1 */
|
||||||
0715000000000+IO_UBMAP+1, /* iowrq 0,763001 ; set ubmap */
|
0715000000000+IOBA_UBMAP+1, /* iowrq 0,763001 ; set ubmap */
|
||||||
0435040000000+IO_RHBASE, /* iori 1,776700 ; rh addr */
|
0435040000000+IOBA_RP, /* iori 1,776700 ; rh addr */
|
||||||
0202040000000+FE_RHBASE, /* movem 1,FE_RHBASE */
|
0202040000000+FE_RHBASE, /* movem 1,FE_RHBASE */
|
||||||
0201000000040, /* movei 0,40 ; ctrl reset */
|
0201000000040, /* movei 0,40 ; ctrl reset */
|
||||||
0715001000010, /* iowrq 0,10(1) ; ->RPCS2 */
|
0715001000010, /* iowrq 0,10(1) ; ->RPCS2 */
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
17-Sep-01 RMS Removed multiconsole support
|
||||||
25-Aug-01 RMS Enabled DZ11
|
25-Aug-01 RMS Enabled DZ11
|
||||||
27-May-01 RMS Added multiconsole support
|
27-May-01 RMS Added multiconsole support
|
||||||
29-Apr-01 RMS Fixed format for RDPCST, WRPCST
|
29-Apr-01 RMS Fixed format for RDPCST, WRPCST
|
||||||
|
@ -52,7 +53,6 @@ extern a10 saved_PC;
|
||||||
sim_PC pointer to saved PC register descriptor
|
sim_PC pointer to saved PC register descriptor
|
||||||
sim_emax number of words for examine
|
sim_emax number of words for examine
|
||||||
sim_devices array of pointers to simulated devices
|
sim_devices array of pointers to simulated devices
|
||||||
sim_consoles array of pointers to consoles (if more than one)
|
|
||||||
sim_stop_messages array of pointers to stop messages
|
sim_stop_messages array of pointers to stop messages
|
||||||
sim_load binary loader
|
sim_load binary loader
|
||||||
*/
|
*/
|
||||||
|
@ -77,8 +77,6 @@ DEVICE *sim_devices[] = {
|
||||||
&tu_dev,
|
&tu_dev,
|
||||||
NULL };
|
NULL };
|
||||||
|
|
||||||
UNIT *sim_consoles = NULL;
|
|
||||||
|
|
||||||
const char *sim_stop_messages[] = {
|
const char *sim_stop_messages[] = {
|
||||||
"Unknown error",
|
"Unknown error",
|
||||||
"HALT instruction",
|
"HALT instruction",
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
tim timer subsystem
|
tim timer subsystem
|
||||||
|
|
||||||
|
31-Aug-01 RMS Changed int64 to t_int64 for Windoze
|
||||||
17-Jul-01 RMS Moved function prototype
|
17-Jul-01 RMS Moved function prototype
|
||||||
04-Jul-01 RMS Added DZ11 support
|
04-Jul-01 RMS Added DZ11 support
|
||||||
*/
|
*/
|
||||||
|
@ -45,12 +46,12 @@ extern int32 apr_flg, pi_act;
|
||||||
extern UNIT cpu_unit;
|
extern UNIT cpu_unit;
|
||||||
extern d10 pcst;
|
extern d10 pcst;
|
||||||
extern a10 pager_PC;
|
extern a10 pager_PC;
|
||||||
int64 timebase = 0; /* 71b timebase */
|
t_int64 timebase = 0; /* 71b timebase */
|
||||||
d10 ttg = 0; /* time to go */
|
d10 ttg = 0; /* time to go */
|
||||||
d10 period = 0; /* period */
|
d10 period = 0; /* period */
|
||||||
d10 quant = 0; /* ITS quantum */
|
d10 quant = 0; /* ITS quantum */
|
||||||
int32 diagflg = 0; /* diagnostics? */
|
int32 diagflg = 0; /* diagnostics? */
|
||||||
int32 dz_poll = TIM_DELAY * DZ_MULT; /* DZ11 poll */
|
int32 tmxr_poll = TIM_DELAY * DZ_MULT; /* term mux poll */
|
||||||
|
|
||||||
t_stat tim_svc (UNIT *uptr);
|
t_stat tim_svc (UNIT *uptr);
|
||||||
t_stat tim_reset (DEVICE *dptr);
|
t_stat tim_reset (DEVICE *dptr);
|
||||||
|
@ -132,7 +133,7 @@ int32 t;
|
||||||
|
|
||||||
t = diagflg? tim_unit.wait: sim_rtc_calb (TIM_TPS); /* calibrate clock */
|
t = diagflg? tim_unit.wait: sim_rtc_calb (TIM_TPS); /* calibrate clock */
|
||||||
sim_activate (&tim_unit, t); /* reactivate unit */
|
sim_activate (&tim_unit, t); /* reactivate unit */
|
||||||
dz_poll = t * DZ_MULT; /* set DZ poll */
|
tmxr_poll = t * DZ_MULT; /* set mux poll */
|
||||||
timebase = (timebase + 1) & TB_MASK; /* increment timebase */
|
timebase = (timebase + 1) & TB_MASK; /* increment timebase */
|
||||||
ttg = ttg - TIM_HWRE; /* decrement timer */
|
ttg = ttg - TIM_HWRE; /* decrement timer */
|
||||||
if (ttg <= 0) { /* timeout? */
|
if (ttg <= 0) { /* timeout? */
|
||||||
|
@ -152,7 +153,7 @@ t_stat tim_reset (DEVICE *dptr)
|
||||||
period = ttg = 0; /* clear timer */
|
period = ttg = 0; /* clear timer */
|
||||||
apr_flg = apr_flg & ~APRF_TIM; /* clear interrupt */
|
apr_flg = apr_flg & ~APRF_TIM; /* clear interrupt */
|
||||||
sim_activate (&tim_unit, tim_unit.wait); /* activate unit */
|
sim_activate (&tim_unit, tim_unit.wait); /* activate unit */
|
||||||
dz_poll = tim_unit.wait * DZ_MULT; /* set DZ poll */
|
tmxr_poll = tim_unit.wait * DZ_MULT; /* set mux poll */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
92
pdp10_tu.c
92
pdp10_tu.c
|
@ -25,6 +25,11 @@
|
||||||
|
|
||||||
tu RH11/TM03/TU45 magtape
|
tu RH11/TM03/TU45 magtape
|
||||||
|
|
||||||
|
23-Oct-01 RMS Fixed bug in error interrupts
|
||||||
|
New IO page address constants
|
||||||
|
05-Oct-01 RMS Rewrote interrupt handling from schematics
|
||||||
|
30-Sep-01 RMS Fixed handling of non-existent formatters
|
||||||
|
28-Sep-01 RMS Fixed interrupt handling for SC/ATA
|
||||||
4-May-01 RMS Fixed bug in odd address test
|
4-May-01 RMS Fixed bug in odd address test
|
||||||
3-May-01 RMS Fixed drive reset to clear SSC
|
3-May-01 RMS Fixed drive reset to clear SSC
|
||||||
|
|
||||||
|
@ -42,6 +47,20 @@
|
||||||
If the byte count is odd, the record is padded with an extra byte
|
If the byte count is odd, the record is padded with an extra byte
|
||||||
of junk. File marks are represented by a single record length of 0.
|
of junk. File marks are represented by a single record length of 0.
|
||||||
End of tape is two consecutive end of file marks.
|
End of tape is two consecutive end of file marks.
|
||||||
|
|
||||||
|
WARNING: The interupt logic of the RH11/RH70 is unusual and must be
|
||||||
|
simulated with great precision. The RH11 has an internal interrupt
|
||||||
|
request flop, CSTB INTR, which is controlled as follows:
|
||||||
|
- Writing IE and DONE simultaneously sets CSTB INTR
|
||||||
|
- Controller clear, INIT, and interrupt acknowledge clear CSTB INTR
|
||||||
|
(and also clear IE)
|
||||||
|
- A transition of DONE from 0 to 1 sets CSTB from INTR
|
||||||
|
The output of INTR is OR'd with the AND of RPCS1<SC,DONE,IE> to
|
||||||
|
create the interrupt request signal. Thus,
|
||||||
|
- The DONE interrupt is edge sensitive, but the SC interrupt is
|
||||||
|
level sensitive.
|
||||||
|
- The DONE interrupt, once set, is not disabled if IE is cleared,
|
||||||
|
but the SC interrupt is.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pdp10_defs.h"
|
#include "pdp10_defs.h"
|
||||||
|
@ -71,6 +90,7 @@
|
||||||
#define FNC_WREOF 013 /* write tape mark */
|
#define FNC_WREOF 013 /* write tape mark */
|
||||||
#define FNC_SPACEF 014 /* space forward */
|
#define FNC_SPACEF 014 /* space forward */
|
||||||
#define FNC_SPACER 015 /* space reverse */
|
#define FNC_SPACER 015 /* space reverse */
|
||||||
|
#define FNC_XFER 024 /* >=? data xfr */
|
||||||
#define FNC_WCHKF 024 /* write check */
|
#define FNC_WCHKF 024 /* write check */
|
||||||
#define FNC_WCHKR 027 /* write check rev */
|
#define FNC_WCHKR 027 /* write check rev */
|
||||||
#define FNC_WRITE 030 /* write */
|
#define FNC_WRITE 030 /* write */
|
||||||
|
@ -86,7 +106,7 @@
|
||||||
#define CS1_TRE 0040000 /* transfer err */
|
#define CS1_TRE 0040000 /* transfer err */
|
||||||
#define CS1_SC 0100000 /* special cond */
|
#define CS1_SC 0100000 /* special cond */
|
||||||
#define CS1_MBZ 0012000
|
#define CS1_MBZ 0012000
|
||||||
#define CS1_RW (CS1_FNC | CS1_IE | CS1_UAE | CS1_GO)
|
#define CS1_DRV (CS1_FNC | CS1_GO)
|
||||||
#define GET_FNC(x) (((x) >> CS1_V_FNC) & CS1_M_FNC)
|
#define GET_FNC(x) (((x) >> CS1_V_FNC) & CS1_M_FNC)
|
||||||
#define GET_UAE(x) (((x) & CS1_UAE) << (16 - CS1_V_UAE))
|
#define GET_UAE(x) (((x) & CS1_UAE) << (16 - CS1_V_UAE))
|
||||||
|
|
||||||
|
@ -224,6 +244,7 @@
|
||||||
(((b) & XBA_ODD) != ((od) << 1))) { \
|
(((b) & XBA_ODD) != ((od) << 1))) { \
|
||||||
tucs2 = tucs2 | CS2_NEM; \
|
tucs2 = tucs2 | CS2_NEM; \
|
||||||
ubcs[1] = ubcs[1] | UBCS_TMO; \
|
ubcs[1] = ubcs[1] | UBCS_TMO; \
|
||||||
|
tucs1 = tucs1 & ~CS1_GO; \
|
||||||
update_tucs (CS1_DONE, drv); \
|
update_tucs (CS1_DONE, drv); \
|
||||||
return SCPE_OK; }
|
return SCPE_OK; }
|
||||||
#define NEWPAGE(v,m) (((v) & PAG_M_OFF) == (m))
|
#define NEWPAGE(v,m) (((v) & PAG_M_OFF) == (m))
|
||||||
|
@ -257,6 +278,7 @@ int32 tucc = 0; /* check character */
|
||||||
int32 tudb = 0; /* data buffer */
|
int32 tudb = 0; /* data buffer */
|
||||||
int32 tumr = 0; /* maint register */
|
int32 tumr = 0; /* maint register */
|
||||||
int32 tutc = 0; /* tape control */
|
int32 tutc = 0; /* tape control */
|
||||||
|
int32 tuiff = 0; /* INTR flip/flop */
|
||||||
int32 tu_time = 10; /* record latency */
|
int32 tu_time = 10; /* record latency */
|
||||||
int32 tu_stopioe = 1; /* stop on error */
|
int32 tu_stopioe = 1; /* stop on error */
|
||||||
int32 tu_log = 0; /* debug */
|
int32 tu_log = 0; /* debug */
|
||||||
|
@ -310,6 +332,7 @@ REG tu_reg[] = {
|
||||||
{ ORDATA (MTDB, tudb, 16) },
|
{ ORDATA (MTDB, tudb, 16) },
|
||||||
{ ORDATA (MTMR, tumr, 16) },
|
{ ORDATA (MTMR, tumr, 16) },
|
||||||
{ ORDATA (MTTC, tutc, 16) },
|
{ ORDATA (MTTC, tutc, 16) },
|
||||||
|
{ FLDATA (IFF, tuiff, 0) },
|
||||||
{ FLDATA (INT, int_req, INT_V_TU) },
|
{ FLDATA (INT, int_req, INT_V_TU) },
|
||||||
{ FLDATA (DONE, tucs1, CSR_V_DONE) },
|
{ FLDATA (DONE, tucs1, CSR_V_DONE) },
|
||||||
{ FLDATA (IE, tucs1, CSR_V_IE) },
|
{ FLDATA (IE, tucs1, CSR_V_IE) },
|
||||||
|
@ -379,7 +402,8 @@ if (reg_in_fmtr[j] && (fmtr != 0)) { /* nx formatter */
|
||||||
update_tucs (0, drv); /* update status */
|
update_tucs (0, drv); /* update status */
|
||||||
switch (j) { /* decode PA<4:1> */
|
switch (j) { /* decode PA<4:1> */
|
||||||
case 000: /* MTCS1 */
|
case 000: /* MTCS1 */
|
||||||
*data = tucs1;
|
if (fmtr != 0) *data = tucs1 & ~CS1_DRV;
|
||||||
|
else *data = tucs1;
|
||||||
break;
|
break;
|
||||||
case 001: /* MTWC */
|
case 001: /* MTWC */
|
||||||
*data = tuwc;
|
*data = tuwc;
|
||||||
|
@ -448,21 +472,24 @@ if (reg_in_fmtr1[j] && ((tucs1 & CS1_DONE) == 0)) { /* formatter busy? */
|
||||||
switch (j) { /* decode PA<4:1> */
|
switch (j) { /* decode PA<4:1> */
|
||||||
case 000: /* MTCS1 */
|
case 000: /* MTCS1 */
|
||||||
if ((access == WRITEB) && (PA & 1)) data = data << 8;
|
if ((access == WRITEB) && (PA & 1)) data = data << 8;
|
||||||
else { if ((data & CS1_IE) == 0) int_req = int_req & ~INT_TU;
|
|
||||||
else if (data & CS1_DONE) int_req = int_req | INT_TU; }
|
|
||||||
if (data & CS1_TRE) { /* error clear? */
|
if (data & CS1_TRE) { /* error clear? */
|
||||||
tucs1 = tucs1 & ~CS1_TRE; /* clr CS1<TRE> */
|
tucs1 = tucs1 & ~CS1_TRE; /* clr CS1<TRE> */
|
||||||
tucs2 = tucs2 & ~CS2_ERR; } /* clr CS2<15:8> */
|
tucs2 = tucs2 & ~CS2_ERR; } /* clr CS2<15:8> */
|
||||||
if (access == WRITEB) data = (tucs1 & /* merge data */
|
if ((access == WRITE) || (PA & 1)) { /* hi byte write? */
|
||||||
((PA & 1)? 0377: 0177400)) | data;
|
if (tucs1 & CS1_DONE) /* done set? */
|
||||||
tucs1 = (tucs1 & ~CS1_RW) | (data & CS1_RW);
|
tucs1 = (tucs1 & ~CS1_UAE) | (data & CS1_UAE); }
|
||||||
if (data & CS1_GO) { /* new command? */
|
if ((access == WRITE) || !(PA & 1)) { /* lo byte write? */
|
||||||
|
if ((data & CS1_DONE) && (data & CS1_IE)) /* to DONE+IE? */
|
||||||
|
tuiff = 1; /* set CSTB INTR */
|
||||||
|
tucs1 = (tucs1 & ~CS1_IE) | (data & CS1_IE);
|
||||||
if (fmtr != 0) { /* nx formatter? */
|
if (fmtr != 0) { /* nx formatter? */
|
||||||
tucs2 = tucs2 | CS2_NEF; /* set error flag */
|
tucs2 = tucs2 | CS2_NEF; /* set error flag */
|
||||||
update_tucs (CS1_SC, drv); /* request intr */
|
cs1f = CS1_SC; } /* req interrupt */
|
||||||
return SCPE_OK; }
|
else if (tucs1 & CS1_GO) { /* busy? */
|
||||||
if (tucs1 & CS1_DONE) tu_go (drv); /* start if not busy */
|
if (tucs1 & CS1_DONE) tuer = tuer | ER_RMR;
|
||||||
else tucs2 = tucs2 | CS2_PGE; } /* else prog error */
|
else tucs2 = tucs2 | CS2_PGE; }
|
||||||
|
else { tucs1 = (tucs1 & ~CS1_DRV) | (data & CS1_DRV);
|
||||||
|
if (tucs1 & CS1_GO) tu_go (drv); } }
|
||||||
break;
|
break;
|
||||||
case 001: /* MTWC */
|
case 001: /* MTWC */
|
||||||
if (access == WRITEB) data = (PA & 1)?
|
if (access == WRITEB) data = (PA & 1)?
|
||||||
|
@ -533,8 +560,10 @@ fnc = GET_FNC (tucs1); /* get function */
|
||||||
den = GET_DEN (tutc); /* get density */
|
den = GET_DEN (tutc); /* get density */
|
||||||
uptr = tu_dev.units + drv; /* get unit */
|
uptr = tu_dev.units + drv; /* get unit */
|
||||||
if ((fnc != FNC_FCLR) && /* not clear & err */
|
if ((fnc != FNC_FCLR) && /* not clear & err */
|
||||||
((tufs & FS_ERR) || sim_is_active (uptr))) { /* or in motion? */
|
((tufs & FS_ERR) || sim_is_active (uptr))) { /* or in motion? */
|
||||||
tucs2 = tucs2 | CS2_PGE; /* set error flag */
|
tuer = tuer | ER_ILF; /* set error flag */
|
||||||
|
tufs = tufs | FS_ATA; /* exception */
|
||||||
|
tucs1 = tucs1 & ~CS1_GO; /* clear go */
|
||||||
update_tucs (CS1_SC, drv); /* request intr */
|
update_tucs (CS1_SC, drv); /* request intr */
|
||||||
return; }
|
return; }
|
||||||
tufs = tufs & ~FS_ATA; /* clear attention */
|
tufs = tufs & ~FS_ATA; /* clear attention */
|
||||||
|
@ -621,9 +650,10 @@ DATA_XFER:
|
||||||
/* tuer = tuer | ER_NXF;
|
/* tuer = tuer | ER_NXF;
|
||||||
/* break; } */
|
/* break; } */
|
||||||
uptr -> USTAT = 0;
|
uptr -> USTAT = 0;
|
||||||
|
tucs1 = tucs1 & ~CS1_DONE; /* clear done */
|
||||||
GO_XFER:
|
GO_XFER:
|
||||||
tucs2 = tucs2 & ~CS2_ERR; /* clear errors */
|
tucs2 = tucs2 & ~CS2_ERR; /* clear errors */
|
||||||
tucs1 = tucs1 & ~(CS1_TRE | CS1_MCPE | CS1_DONE);
|
tucs1 = tucs1 & ~(CS1_TRE | CS1_MCPE);
|
||||||
tufs = tufs & ~(FS_TMK | FS_ID); /* clear eof, id */
|
tufs = tufs & ~(FS_TMK | FS_ID); /* clear eof, id */
|
||||||
sim_activate (uptr, tu_time);
|
sim_activate (uptr, tu_time);
|
||||||
return;
|
return;
|
||||||
|
@ -631,7 +661,9 @@ GO_XFER:
|
||||||
default: /* all others */
|
default: /* all others */
|
||||||
tuer = tuer | ER_ILF; /* not supported */
|
tuer = tuer | ER_ILF; /* not supported */
|
||||||
break; } /* end case function */
|
break; } /* end case function */
|
||||||
update_tucs (CS1_SC, drv); /* error, set intr */
|
tucs1 = tucs1 & ~CS1_GO; /* clear go */
|
||||||
|
tufs = tufs | FS_ATA; /* set attn */
|
||||||
|
update_tucs (CS1_SC, drv); /* set intr */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -851,15 +883,20 @@ update_tucs (CS1_DONE, drv);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Controller status update
|
/* Controller status update
|
||||||
First update formatter status, then update MTCS1
|
|
||||||
If optional argument, request interrupt
|
Check for done transition
|
||||||
|
Update drive status
|
||||||
|
Update MTCS1
|
||||||
|
Update interrupt request
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void update_tucs (int32 flag, int32 drv)
|
void update_tucs (int32 flag, int32 drv)
|
||||||
{
|
{
|
||||||
int32 act = sim_is_active (&tu_unit[drv]);
|
int32 act = sim_is_active (&tu_unit[drv]);
|
||||||
|
|
||||||
|
if ((flag & ~tucs1) & CS1_DONE) /* DONE 0 to 1? */
|
||||||
|
tuiff = (tucs1 & CS1_IE)? 1: 0; /* CSTB INTR <- IE */
|
||||||
if (GET_FMTR (tucs2) == 0) { /* formatter present? */
|
if (GET_FMTR (tucs2) == 0) { /* formatter present? */
|
||||||
tufs = (tufs & ~FS_DYN) | FS_FPR;
|
tufs = (tufs & ~FS_DYN) | FS_FPR;
|
||||||
if (tu_unit[drv].flags & UNIT_ATT) {
|
if (tu_unit[drv].flags & UNIT_ATT) {
|
||||||
|
@ -871,10 +908,11 @@ if (GET_FMTR (tucs2) == 0) { /* formatter present? */
|
||||||
else tufs = 0;
|
else tufs = 0;
|
||||||
tucs1 = (tucs1 & ~(CS1_SC | CS1_MCPE | CS1_MBZ)) | CS1_DVA | flag;
|
tucs1 = (tucs1 & ~(CS1_SC | CS1_MCPE | CS1_MBZ)) | CS1_DVA | flag;
|
||||||
if (tucs2 & CS2_ERR) tucs1 = tucs1 | CS1_TRE | CS1_SC;
|
if (tucs2 & CS2_ERR) tucs1 = tucs1 | CS1_TRE | CS1_SC;
|
||||||
|
else if (tucs1 & CS1_TRE) tucs1 = tucs1 | CS1_SC;
|
||||||
if (tufs & FS_ATA) tucs1 = tucs1 | CS1_SC;
|
if (tufs & FS_ATA) tucs1 = tucs1 | CS1_SC;
|
||||||
if (((tucs1 & CS1_IE) == 0) || ((tucs1 & CS1_DONE) == 0))
|
if (tuiff || ((tucs1 & CS1_SC) && (tucs1 & CS1_DONE) && (tucs1 & CS1_IE)))
|
||||||
int_req = int_req & ~INT_TU;
|
int_req = int_req | INT_TU;
|
||||||
else if (flag) int_req = int_req | INT_TU;
|
else int_req = int_req & ~INT_TU;
|
||||||
if ((tucs1 & CS1_DONE) && tufs && !act) tufs = tufs | FS_RDY;
|
if ((tucs1 & CS1_DONE) && tufs && !act) tufs = tufs | FS_RDY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -884,6 +922,7 @@ return;
|
||||||
int32 tu_inta (void)
|
int32 tu_inta (void)
|
||||||
{
|
{
|
||||||
tucs1 = tucs1 & ~CS1_IE; /* clear int enable */
|
tucs1 = tucs1 & ~CS1_IE; /* clear int enable */
|
||||||
|
tuiff = 0; /* clear CSTB INTR */
|
||||||
return VEC_TU; /* acknowledge */
|
return VEC_TU; /* acknowledge */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -899,6 +938,7 @@ tucs2 = CS2_IR | CS2_OR;
|
||||||
tuba = tufc = 0;
|
tuba = tufc = 0;
|
||||||
tutc = tuer = 0;
|
tutc = tuer = 0;
|
||||||
tufs = FS_FPR | FS_RDY;
|
tufs = FS_FPR | FS_RDY;
|
||||||
|
tuiff = 0; /* clear CSTB INTR */
|
||||||
int_req = int_req & ~INT_TU; /* clear interrupt */
|
int_req = int_req & ~INT_TU; /* clear interrupt */
|
||||||
for (u = 0; u < TU_NUMDR; u++) { /* loop thru units */
|
for (u = 0; u < TU_NUMDR; u++) { /* loop thru units */
|
||||||
uptr = tu_dev.units + u;
|
uptr = tu_dev.units + u;
|
||||||
|
@ -958,8 +998,8 @@ return SCPE_OK;
|
||||||
static const d10 boot_rom_dec[] = {
|
static const d10 boot_rom_dec[] = {
|
||||||
0515040000003, /* boot:hrlzi 1,3 ; uba # */
|
0515040000003, /* boot:hrlzi 1,3 ; uba # */
|
||||||
0201000040001, /* movei 0,40001 ; vld,pg 1 */
|
0201000040001, /* movei 0,40001 ; vld,pg 1 */
|
||||||
0713001000000+IO_UBMAP+1, /* wrio 0,763001(1); set ubmap */
|
0713001000000+IOBA_UBMAP+1, /* wrio 0,763001(1); set ubmap */
|
||||||
0435040000000+IO_TMBASE, /* iori 1,772440 ; rh addr */
|
0435040000000+IOBA_TU, /* iori 1,772440 ; rh addr */
|
||||||
0202040000000+FE_RHBASE, /* movem 1,FE_RHBASE */
|
0202040000000+FE_RHBASE, /* movem 1,FE_RHBASE */
|
||||||
0201000000040, /* movei 0,40 ; ctrl reset */
|
0201000000040, /* movei 0,40 ; ctrl reset */
|
||||||
0713001000010, /* wrio 0,10(1) ; ->MTFS */
|
0713001000010, /* wrio 0,10(1) ; ->MTFS */
|
||||||
|
@ -996,8 +1036,8 @@ static const d10 boot_rom_dec[] = {
|
||||||
static const d10 boot_rom_its[] = {
|
static const d10 boot_rom_its[] = {
|
||||||
0515040000003, /* boot:hrlzi 1,3 ; uba # - not used */
|
0515040000003, /* boot:hrlzi 1,3 ; uba # - not used */
|
||||||
0201000040001, /* movei 0,40001 ; vld,pg 1 */
|
0201000040001, /* movei 0,40001 ; vld,pg 1 */
|
||||||
0714000000000+IO_UBMAP+1, /* iowri 0,763001 ; set ubmap */
|
0714000000000+IOBA_UBMAP+1, /* iowri 0,763001 ; set ubmap */
|
||||||
0435040000000+IO_TMBASE, /* iori 1,772440 ; rh addr */
|
0435040000000+IOBA_TU, /* iori 1,772440 ; rh addr */
|
||||||
0202040000000+FE_RHBASE, /* movem 1,FE_RHBASE */
|
0202040000000+FE_RHBASE, /* movem 1,FE_RHBASE */
|
||||||
0201000000040, /* movei 0,40 ; ctrl reset */
|
0201000000040, /* movei 0,40 ; ctrl reset */
|
||||||
0714001000010, /* iowri 0,10(1) ; ->MTFS */
|
0714001000010, /* iowri 0,10(1) ; ->MTFS */
|
||||||
|
|
208
pdp11_cpu.c
208
pdp11_cpu.c
|
@ -25,9 +25,13 @@
|
||||||
|
|
||||||
cpu PDP-11 CPU (J-11 microprocessor)
|
cpu PDP-11 CPU (J-11 microprocessor)
|
||||||
|
|
||||||
|
15-Oct-01 RMS Added debug logging
|
||||||
|
08-Oct-01 RMS Fixed bug in revised interrupt logic
|
||||||
|
07-Sep-01 RMS Revised device disable and interrupt mechanisms
|
||||||
|
26-Aug-01 RMS Added DZ11 support
|
||||||
10-Aug-01 RMS Removed register from declarations
|
10-Aug-01 RMS Removed register from declarations
|
||||||
17-Jul-01 RMS Fixed warning from VC++ 6.0
|
17-Jul-01 RMS Fixed warning from VC++ 6.0
|
||||||
01-Jun-01 RMS Added DZ11 support
|
01-Jun-01 RMS Added DZ11 interrupts
|
||||||
23-Apr-01 RMS Added RK611 support
|
23-Apr-01 RMS Added RK611 support
|
||||||
05-Apr-01 RMS Added TS11/TSV05 support
|
05-Apr-01 RMS Added TS11/TSV05 support
|
||||||
05-Mar-01 RMS Added clock calibration support
|
05-Mar-01 RMS Added clock calibration support
|
||||||
|
@ -151,8 +155,8 @@
|
||||||
lowest priority trap. Traps are processed by trap_vec and trap_clear,
|
lowest priority trap. Traps are processed by trap_vec and trap_clear,
|
||||||
which provide the vector and subordinate traps to clear, respectively.
|
which provide the vector and subordinate traps to clear, respectively.
|
||||||
|
|
||||||
Variable int_req bit encodes all possible interrupts. It is masked
|
Array int_req[0:7] bit encodes all possible interrupts. It is masked
|
||||||
under the interrupt masks, int_mask[ipl]. If any interrupt request
|
under the interrupt priority level, ipl. If any interrupt request
|
||||||
is not masked, the interrupt bit is set in trap_req. While most
|
is not masked, the interrupt bit is set in trap_req. While most
|
||||||
interrupts are handled centrally, a device can supply an interrupt
|
interrupts are handled centrally, a device can supply an interrupt
|
||||||
acknowledge routine.
|
acknowledge routine.
|
||||||
|
@ -176,8 +180,6 @@
|
||||||
#define calc_is(md) ((md) << VA_V_MODE)
|
#define calc_is(md) ((md) << VA_V_MODE)
|
||||||
#define calc_ds(md) (calc_is((md)) | ((MMR3 & dsmask[(md)])? VA_DS: 0))
|
#define calc_ds(md) (calc_is((md)) | ((MMR3 & dsmask[(md)])? VA_DS: 0))
|
||||||
#define calc_MMR1(val) (MMR1 = MMR1? ((val) << 8) | MMR1: (val))
|
#define calc_MMR1(val) (MMR1 = MMR1? ((val) << 8) | MMR1: (val))
|
||||||
#define calc_ints(lv,rq,tr) (((rq) & int_mask[(lv)])? \
|
|
||||||
((tr) | TRAP_INT) : ((tr) & ~TRAP_INT))
|
|
||||||
#define GET_SIGN_W(v) ((v) >> 15)
|
#define GET_SIGN_W(v) ((v) >> 15)
|
||||||
#define GET_SIGN_B(v) ((v) >> 7)
|
#define GET_SIGN_B(v) ((v) >> 7)
|
||||||
#define GET_Z(v) ((v) == 0)
|
#define GET_Z(v) ((v) == 0)
|
||||||
|
@ -196,6 +198,8 @@
|
||||||
|
|
||||||
/* Global state */
|
/* Global state */
|
||||||
|
|
||||||
|
extern FILE *sim_log;
|
||||||
|
|
||||||
uint16 *M = NULL; /* address of memory */
|
uint16 *M = NULL; /* address of memory */
|
||||||
int32 REGFILE[6][2] = { 0 }; /* R0-R5, two sets */
|
int32 REGFILE[6][2] = { 0 }; /* R0-R5, two sets */
|
||||||
int32 STACKFILE[4] = { 0 }; /* SP, four modes */
|
int32 STACKFILE[4] = { 0 }; /* SP, four modes */
|
||||||
|
@ -210,7 +214,7 @@ int32 PSW = 0; /* PSW */
|
||||||
int32 N = 0, Z = 0, V = 0, C = 0; /* condition codes */
|
int32 N = 0, Z = 0, V = 0, C = 0; /* condition codes */
|
||||||
int32 wait_state = 0; /* wait state */
|
int32 wait_state = 0; /* wait state */
|
||||||
int32 trap_req = 0; /* trap requests */
|
int32 trap_req = 0; /* trap requests */
|
||||||
int32 int_req = 0; /* interrupt requests */
|
int32 int_req[IPL_HLVL] = { 0 }; /* interrupt requests */
|
||||||
int32 PIRQ = 0; /* programmed int req */
|
int32 PIRQ = 0; /* programmed int req */
|
||||||
int32 SR = 0; /* switch register */
|
int32 SR = 0; /* switch register */
|
||||||
int32 DR = 0; /* display register */
|
int32 DR = 0; /* display register */
|
||||||
|
@ -235,13 +239,13 @@ int32 stop_trap = 1; /* stop on trap */
|
||||||
int32 stop_vecabort = 1; /* stop on vec abort */
|
int32 stop_vecabort = 1; /* stop on vec abort */
|
||||||
int32 stop_spabort = 1; /* stop on SP abort */
|
int32 stop_spabort = 1; /* stop on SP abort */
|
||||||
int32 wait_enable = 0; /* wait state enable */
|
int32 wait_enable = 0; /* wait state enable */
|
||||||
|
int32 pdp11_log = 0; /* logging */
|
||||||
int32 ibkpt_addr = ILL_ADR_FLAG | VAMASK; /* breakpoint addr */
|
int32 ibkpt_addr = ILL_ADR_FLAG | VAMASK; /* breakpoint addr */
|
||||||
int32 old_PC = 0; /* previous PC */
|
int32 old_PC = 0; /* previous PC */
|
||||||
int32 dev_enb = (-1) & ~INT_TS; /* dev enables */
|
int32 dev_enb = (-1) & ~INT_TS; /* dev enables */
|
||||||
jmp_buf save_env; /* abort handler */
|
jmp_buf save_env; /* abort handler */
|
||||||
int32 dsmask[4] = { MMR3_KDS, MMR3_SDS, 0, MMR3_UDS }; /* dspace enables */
|
int32 dsmask[4] = { MMR3_KDS, MMR3_SDS, 0, MMR3_UDS }; /* dspace enables */
|
||||||
uint32 int_mask[8] = { INT_IPL0, INT_IPL1, INT_IPL2, /* interrupt masks */
|
|
||||||
INT_IPL3, INT_IPL4, INT_IPL5, INT_IPL6, INT_IPL7 };
|
|
||||||
extern int32 sim_int_char;
|
extern int32 sim_int_char;
|
||||||
|
|
||||||
/* Function declarations */
|
/* Function declarations */
|
||||||
|
@ -265,6 +269,7 @@ void PWriteW (int32 data, int32 addr);
|
||||||
void PWriteB (int32 data, int32 addr);
|
void PWriteB (int32 data, int32 addr);
|
||||||
t_stat iopageR (int32 *data, int32 addr, int32 access);
|
t_stat iopageR (int32 *data, int32 addr, int32 access);
|
||||||
t_stat iopageW (int32 data, int32 addr, int32 access);
|
t_stat iopageW (int32 data, int32 addr, int32 access);
|
||||||
|
int32 calc_ints (int32 nipl, int32 trq);
|
||||||
|
|
||||||
t_stat CPU_rd (int32 *data, int32 addr, int32 access);
|
t_stat CPU_rd (int32 *data, int32 addr, int32 access);
|
||||||
t_stat CPU_wr (int32 data, int32 addr, int32 access);
|
t_stat CPU_wr (int32 data, int32 addr, int32 access);
|
||||||
|
@ -278,64 +283,87 @@ extern t_stat std_rd (int32 *data, int32 addr, int32 access);
|
||||||
extern t_stat std_wr (int32 data, int32 addr, int32 access);
|
extern t_stat std_wr (int32 data, int32 addr, int32 access);
|
||||||
extern t_stat lpt_rd (int32 *data, int32 addr, int32 access);
|
extern t_stat lpt_rd (int32 *data, int32 addr, int32 access);
|
||||||
extern t_stat lpt_wr (int32 data, int32 addr, int32 access);
|
extern t_stat lpt_wr (int32 data, int32 addr, int32 access);
|
||||||
|
extern t_stat dz_rd (int32 *data, int32 addr, int32 access);
|
||||||
|
extern t_stat dz_wr (int32 data, int32 addr, int32 access);
|
||||||
extern t_stat rk_rd (int32 *data, int32 addr, int32 access);
|
extern t_stat rk_rd (int32 *data, int32 addr, int32 access);
|
||||||
extern t_stat rk_wr (int32 data, int32 addr, int32 access);
|
extern t_stat rk_wr (int32 data, int32 addr, int32 access);
|
||||||
extern int32 rk_inta (void);
|
extern int32 rk_inta (void);
|
||||||
|
extern int32 rk_enb;
|
||||||
/* extern t_stat hk_rd (int32 *data, int32 addr, int32 access);
|
/* extern t_stat hk_rd (int32 *data, int32 addr, int32 access);
|
||||||
extern t_stat hk_wr (int32 data, int32 addr, int32 access);
|
extern t_stat hk_wr (int32 data, int32 addr, int32 access);
|
||||||
extern int32 hk_inta (void); */
|
extern int32 hk_inta (void);
|
||||||
|
extern int32 hk_enb; */
|
||||||
extern t_stat rl_rd (int32 *data, int32 addr, int32 access);
|
extern t_stat rl_rd (int32 *data, int32 addr, int32 access);
|
||||||
extern t_stat rl_wr (int32 data, int32 addr, int32 access);
|
extern t_stat rl_wr (int32 data, int32 addr, int32 access);
|
||||||
|
extern int32 rl_enb;
|
||||||
extern t_stat rp_rd (int32 *data, int32 addr, int32 access);
|
extern t_stat rp_rd (int32 *data, int32 addr, int32 access);
|
||||||
extern t_stat rp_wr (int32 data, int32 addr, int32 access);
|
extern t_stat rp_wr (int32 data, int32 addr, int32 access);
|
||||||
extern int32 rp_inta (void);
|
extern int32 rp_inta (void);
|
||||||
|
extern int32 rp_enb;
|
||||||
extern t_stat rx_rd (int32 *data, int32 addr, int32 access);
|
extern t_stat rx_rd (int32 *data, int32 addr, int32 access);
|
||||||
extern t_stat rx_wr (int32 data, int32 addr, int32 access);
|
extern t_stat rx_wr (int32 data, int32 addr, int32 access);
|
||||||
|
extern int32 rx_enb;
|
||||||
extern t_stat dt_rd (int32 *data, int32 addr, int32 access);
|
extern t_stat dt_rd (int32 *data, int32 addr, int32 access);
|
||||||
extern t_stat dt_wr (int32 data, int32 addr, int32 access);
|
extern t_stat dt_wr (int32 data, int32 addr, int32 access);
|
||||||
|
extern int32 dt_enb;
|
||||||
extern t_stat tm_rd (int32 *data, int32 addr, int32 access);
|
extern t_stat tm_rd (int32 *data, int32 addr, int32 access);
|
||||||
extern t_stat tm_wr (int32 data, int32 addr, int32 access);
|
extern t_stat tm_wr (int32 data, int32 addr, int32 access);
|
||||||
|
extern int32 tm_enb;
|
||||||
extern t_stat ts_rd (int32 *data, int32 addr, int32 access);
|
extern t_stat ts_rd (int32 *data, int32 addr, int32 access);
|
||||||
extern t_stat ts_wr (int32 data, int32 addr, int32 access);
|
extern t_stat ts_wr (int32 data, int32 addr, int32 access);
|
||||||
|
extern int32 ts_enb;
|
||||||
|
|
||||||
/* Auxiliary data structures */
|
/* Auxiliary data structures */
|
||||||
|
|
||||||
struct iolink { /* I/O page linkage */
|
struct iolink { /* I/O page linkage */
|
||||||
int32 low; /* low I/O addr */
|
int32 low; /* low I/O addr */
|
||||||
int32 high; /* high I/O addr */
|
int32 high; /* high I/O addr */
|
||||||
int32 enb; /* enable mask */
|
int32 *enb; /* enable flag */
|
||||||
t_stat (*read)(); /* read routine */
|
t_stat (*read)(); /* read routine */
|
||||||
t_stat (*write)(); }; /* write routine */
|
t_stat (*write)(); }; /* write routine */
|
||||||
|
|
||||||
struct iolink iotable[] = {
|
struct iolink iotable[] = {
|
||||||
{ 017777740, 017777777, 0, &CPU_rd, &CPU_wr },
|
{ 017777740, 017777777, NULL, &CPU_rd, &CPU_wr },
|
||||||
{ 017777546, 017777567, 0, &std_rd, &std_wr },
|
{ 017777546, 017777567, NULL, &std_rd, &std_wr },
|
||||||
{ 017777514, 017777517, 0, &lpt_rd, &lpt_wr },
|
{ 017777514, 017777517, NULL, &lpt_rd, &lpt_wr },
|
||||||
{ 017777400, 017777417, INT_RK, &rk_rd, &rk_wr },
|
{ 017760100, 017760107, NULL, &dz_rd, &dz_wr },
|
||||||
/* { 017777440, 017777477, INT_HK, &hk_rd, &hk_wr }, */
|
{ 017777400, 017777417, &rk_enb, &rk_rd, &rk_wr },
|
||||||
{ 017774400, 017774411, INT_RL, &rl_rd, &rl_wr },
|
/* { 017777440, 017777477, &hk_enb, &hk_rd, &hk_wr }, */
|
||||||
{ 017776700, 017776753, INT_RP, &rp_rd, &rp_wr },
|
{ 017774400, 017774411, &rl_enb, &rl_rd, &rl_wr },
|
||||||
{ 017777170, 017777173, INT_RX, &rx_rd, &rx_wr },
|
{ 017776700, 017776753, &rp_enb, &rp_rd, &rp_wr },
|
||||||
{ 017777340, 017777351, INT_DTA, &dt_rd, &dt_wr },
|
{ 017777170, 017777173, &rx_enb, &rx_rd, &rx_wr },
|
||||||
{ 017772520, 017772533, INT_TM, &tm_rd, &tm_wr },
|
{ 017777340, 017777351, &dt_enb, &dt_rd, &dt_wr },
|
||||||
{ 017772520, 017772523, INT_TS, &ts_rd, &ts_wr },
|
{ 017772520, 017772533, &tm_enb, &tm_rd, &tm_wr },
|
||||||
{ 017777600, 017777677, 0, &APR_rd, &APR_wr },
|
{ 017772520, 017772523, &ts_enb, &ts_rd, &ts_wr },
|
||||||
{ 017772200, 017772377, 0, &APR_rd, &APR_wr },
|
{ 017777600, 017777677, NULL, &APR_rd, &APR_wr },
|
||||||
{ 017777570, 017777577, 0, &SR_MMR012_rd, &SR_MMR012_wr },
|
{ 017772200, 017772377, NULL, &APR_rd, &APR_wr },
|
||||||
{ 017772516, 017772517, 0, &MMR3_rd, &MMR3_wr },
|
{ 017777570, 017777577, NULL, &SR_MMR012_rd, &SR_MMR012_wr },
|
||||||
{ 0, 0, 0, NULL, NULL } };
|
{ 017772516, 017772517, NULL, &MMR3_rd, &MMR3_wr },
|
||||||
|
{ 0, 0, NULL, NULL, NULL } };
|
||||||
|
|
||||||
int32 int_vec[32] = { /* int req to vector */
|
int32 int_vec[IPL_HLVL][32] = { /* int req to vector */
|
||||||
0, 0, 0, VEC_PIRQ, VEC_CLK, VEC_DTA, 0, VEC_PIRQ,
|
{ 0 }, /* IPL 0 */
|
||||||
VEC_RK, VEC_RL, VEC_RX, VEC_TM, VEC_RP, VEC_TS, VEC_HK, 0,
|
{ VEC_PIRQ }, /* IPL 1 */
|
||||||
VEC_DZ0RX, VEC_DZ0TX, 0, VEC_PIRQ, VEC_TTI, VEC_TTO, VEC_PTR, VEC_PTP,
|
{ VEC_PIRQ }, /* IPL 2 */
|
||||||
VEC_LPT, 0, 0, 0, VEC_PIRQ, VEC_PIRQ, VEC_PIRQ, VEC_PIRQ };
|
{ VEC_PIRQ }, /* IPL 3 */
|
||||||
|
{ VEC_TTI, VEC_TTO, VEC_PTR, VEC_PTP, /* IPL 4 */
|
||||||
|
VEC_LPT, VEC_PIRQ },
|
||||||
|
{ VEC_RK, VEC_RL, VEC_RX, VEC_TM, /* IPL 5 */
|
||||||
|
VEC_RP, VEC_TS, VEC_HK, VEC_DZRX,
|
||||||
|
VEC_DZTX, VEC_PIRQ },
|
||||||
|
{ VEC_CLK, VEC_DTA, VEC_PIRQ }, /* IPL 6 */
|
||||||
|
{ VEC_PIRQ } }; /* IPL 7 */
|
||||||
|
|
||||||
int32 (*int_ack[32])() = { /* int ack routines */
|
int32 (*int_ack[IPL_HLVL][32])() = { /* int ack routines */
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
{ NULL }, /* IPL 0 */
|
||||||
&rk_inta, NULL, NULL, NULL, &rp_inta, NULL, NULL, NULL,
|
{ NULL }, /* IPL 1 */
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
{ NULL }, /* IPL 2 */
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
{ NULL }, /* IPL 3 */
|
||||||
|
{ NULL }, /* IPL 4 */
|
||||||
|
{ &rk_inta, NULL, NULL, NULL, /* IPL 5 */
|
||||||
|
&rp_inta, NULL, NULL, NULL },
|
||||||
|
{ NULL }, /* IPL 6 */
|
||||||
|
{ NULL } }; /* IPL 7 */
|
||||||
|
|
||||||
int32 trap_vec[TRAP_V_MAX] = { /* trap req to vector */
|
int32 trap_vec[TRAP_V_MAX] = { /* trap req to vector */
|
||||||
VEC_RED, VEC_ODD, VEC_MME, VEC_NXM,
|
VEC_RED, VEC_ODD, VEC_MME, VEC_NXM,
|
||||||
|
@ -398,7 +426,7 @@ REG cpu_reg[] = {
|
||||||
{ ORDATA (MAINT, MAINT, 16) },
|
{ ORDATA (MAINT, MAINT, 16) },
|
||||||
{ ORDATA (HITMISS, HITMISS, 16) },
|
{ ORDATA (HITMISS, HITMISS, 16) },
|
||||||
{ ORDATA (CPUERR, CPUERR, 16) },
|
{ ORDATA (CPUERR, CPUERR, 16) },
|
||||||
{ ORDATA (INT, int_req, 32), REG_RO },
|
{ BRDATA (IREQ, int_req, 8, 32, IPL_HLVL), REG_RO },
|
||||||
{ ORDATA (TRAPS, trap_req, TRAP_V_MAX) },
|
{ ORDATA (TRAPS, trap_req, TRAP_V_MAX) },
|
||||||
{ ORDATA (PIRQ, PIRQ, 16) },
|
{ ORDATA (PIRQ, PIRQ, 16) },
|
||||||
{ FLDATA (WAIT, wait_state, 0) },
|
{ FLDATA (WAIT, wait_state, 0) },
|
||||||
|
@ -406,6 +434,7 @@ REG cpu_reg[] = {
|
||||||
{ ORDATA (STOP_TRAPS, stop_trap, TRAP_V_MAX) },
|
{ ORDATA (STOP_TRAPS, stop_trap, TRAP_V_MAX) },
|
||||||
{ FLDATA (STOP_VECA, stop_vecabort, 0) },
|
{ FLDATA (STOP_VECA, stop_vecabort, 0) },
|
||||||
{ FLDATA (STOP_SPA, stop_spabort, 0) },
|
{ FLDATA (STOP_SPA, stop_spabort, 0) },
|
||||||
|
{ ORDATA (DBGLOG, pdp11_log, 16), REG_HIDDEN },
|
||||||
{ ORDATA (FAC0H, FR[0].h, 32) },
|
{ ORDATA (FAC0H, FR[0].h, 32) },
|
||||||
{ ORDATA (FAC0L, FR[0].l, 32) },
|
{ ORDATA (FAC0L, FR[0].l, 32) },
|
||||||
{ ORDATA (FAC1H, FR[1].h, 32) },
|
{ ORDATA (FAC1H, FR[1].h, 32) },
|
||||||
|
@ -568,7 +597,7 @@ extern UNIT *sim_clock_queue;
|
||||||
extern UNIT clk_unit;
|
extern UNIT clk_unit;
|
||||||
int32 IR, srcspec, srcreg, dstspec, dstreg;
|
int32 IR, srcspec, srcreg, dstspec, dstreg;
|
||||||
int32 src, src2, dst;
|
int32 src, src2, dst;
|
||||||
int32 i, t, sign, oldrs, trapnum;
|
int32 i, j, t, sign, oldrs, trapnum;
|
||||||
int32 abortval;
|
int32 abortval;
|
||||||
volatile int32 trapea;
|
volatile int32 trapea;
|
||||||
t_stat reason;
|
t_stat reason;
|
||||||
|
@ -602,7 +631,7 @@ isenable = calc_is (cm);
|
||||||
dsenable = calc_ds (cm);
|
dsenable = calc_ds (cm);
|
||||||
|
|
||||||
CPU_wr (PIRQ, 017777772, WRITE); /* rewrite PIRQ */
|
CPU_wr (PIRQ, 017777772, WRITE); /* rewrite PIRQ */
|
||||||
trap_req = calc_ints (ipl, int_req, trap_req);
|
trap_req = calc_ints (ipl, trap_req);
|
||||||
trapea = 0;
|
trapea = 0;
|
||||||
reason = 0;
|
reason = 0;
|
||||||
sim_rtc_init (clk_unit.wait); /* init clock */
|
sim_rtc_init (clk_unit.wait); /* init clock */
|
||||||
|
@ -641,28 +670,38 @@ if (abortval != 0) {
|
||||||
while (reason == 0) {
|
while (reason == 0) {
|
||||||
if (sim_interval <= 0) { /* check clock queue */
|
if (sim_interval <= 0) { /* check clock queue */
|
||||||
reason = sim_process_event ();
|
reason = sim_process_event ();
|
||||||
trap_req = calc_ints (ipl, int_req, trap_req);
|
trap_req = calc_ints (ipl, trap_req);
|
||||||
continue; }
|
continue; }
|
||||||
if (trap_req) { /* check traps, ints */
|
if (trap_req) { /* check traps, ints */
|
||||||
trapea = 0; /* assume srch fails */
|
trapea = 0; /* assume srch fails */
|
||||||
if (t = trap_req & TRAP_ALL) { /* if a trap */
|
if (t = trap_req & TRAP_ALL) { /* if a trap */
|
||||||
for (trapnum = 0; trapnum < TRAP_V_MAX; trapnum++) {
|
for (trapnum = 0; trapnum < TRAP_V_MAX; trapnum++) {
|
||||||
if ((t >> trapnum) & 1) {
|
if ((t >> trapnum) & 1) {
|
||||||
trapea = trap_vec[trapnum];
|
trapea = trap_vec[trapnum];
|
||||||
trap_req = trap_req & ~trap_clear[trapnum];
|
trap_req = trap_req & ~trap_clear[trapnum];
|
||||||
if ((stop_trap >> trapnum) & 1)
|
if ((stop_trap >> trapnum) & 1)
|
||||||
reason = trapnum + 1;
|
reason = trapnum + 1;
|
||||||
break; } } }
|
break; } /* end if t & 1 */
|
||||||
else if (t = int_req & int_mask[ipl]) { /* if an interrupt */
|
} /* end for */
|
||||||
for (i = 0; i < 32; i++) {
|
} /* end if */
|
||||||
if ((t >> i) & 1) {
|
else {
|
||||||
int_req = int_req & ~(1u << i);
|
for (i = IPL_HLVL - 1; (trapea == 0) && (i > ipl); i--) {
|
||||||
if (int_ack[i]) trapea = int_ack[i]();
|
t = int_req[i]; /* get level */
|
||||||
else trapea = int_vec[i];
|
for (j = 0; t && (j < 32); j++) { /* srch level */
|
||||||
trapnum = TRAP_V_MAX;
|
if ((t >> j) & 1) { /* irq found? */
|
||||||
break; } } }
|
int_req[i] = int_req[i] & ~(1u << j);
|
||||||
|
if (int_ack[i][j]) trapea = int_ack[i][j]();
|
||||||
|
else trapea = int_vec[i][j];
|
||||||
|
trapnum = TRAP_V_MAX;
|
||||||
|
if (DBG_LOG (LOG_CPU_I)) fprintf (sim_log,
|
||||||
|
">>CPU, lvl=%d, flag=%d, vec=%o\n",
|
||||||
|
i, j, trapea);
|
||||||
|
break; } /* end if t & 1 */
|
||||||
|
} /* end for j */
|
||||||
|
} /* end for i */
|
||||||
|
} /* end else */
|
||||||
if (trapea == 0) { /* nothing to do? */
|
if (trapea == 0) { /* nothing to do? */
|
||||||
trap_req = calc_ints (ipl, int_req, 0); /* recalculate */
|
trap_req = calc_ints (ipl, 0); /* recalculate */
|
||||||
continue; } /* back to fetch */
|
continue; } /* back to fetch */
|
||||||
|
|
||||||
/* Process a trap or interrupt
|
/* Process a trap or interrupt
|
||||||
|
@ -707,7 +746,7 @@ if (trap_req) { /* check traps, ints */
|
||||||
JMP_PC (src);
|
JMP_PC (src);
|
||||||
isenable = calc_is (cm);
|
isenable = calc_is (cm);
|
||||||
dsenable = calc_ds (cm);
|
dsenable = calc_ds (cm);
|
||||||
trap_req = calc_ints (ipl, int_req, trap_req);
|
trap_req = calc_ints (ipl, trap_req);
|
||||||
if ((SP < STKLIM) && (cm == KERNEL) &&
|
if ((SP < STKLIM) && (cm == KERNEL) &&
|
||||||
(trapnum != TRAP_V_RED) && (trapnum != TRAP_V_YEL)) {
|
(trapnum != TRAP_V_RED) && (trapnum != TRAP_V_YEL)) {
|
||||||
setTRAP (TRAP_YEL);
|
setTRAP (TRAP_YEL);
|
||||||
|
@ -768,7 +807,8 @@ case 000:
|
||||||
if (cm == KERNEL) {
|
if (cm == KERNEL) {
|
||||||
reset_all (1);
|
reset_all (1);
|
||||||
PIRQ = 0;
|
PIRQ = 0;
|
||||||
int_req = 0;
|
for (i = 0; i < IPL_HLVL; i++)
|
||||||
|
int_req[i] = 0;
|
||||||
MMR0 = MMR0 & ~(MMR0_MME | MMR0_FREEZE);
|
MMR0 = MMR0 & ~(MMR0_MME | MMR0_FREEZE);
|
||||||
MMR3 = 0;
|
MMR3 = 0;
|
||||||
trap_req = trap_req & ~TRAP_INT;
|
trap_req = trap_req & ~TRAP_INT;
|
||||||
|
@ -796,7 +836,7 @@ case 000:
|
||||||
Z = (src2 >> PSW_V_Z) & 01;
|
Z = (src2 >> PSW_V_Z) & 01;
|
||||||
V = (src2 >> PSW_V_V) & 01;
|
V = (src2 >> PSW_V_V) & 01;
|
||||||
C = (src2 >> PSW_V_C) & 01;
|
C = (src2 >> PSW_V_C) & 01;
|
||||||
trap_req = calc_ints (ipl, int_req, trap_req);
|
trap_req = calc_ints (ipl, trap_req);
|
||||||
isenable = calc_is (cm);
|
isenable = calc_is (cm);
|
||||||
dsenable = calc_ds (cm);
|
dsenable = calc_ds (cm);
|
||||||
if (rs != oldrs) {
|
if (rs != oldrs) {
|
||||||
|
@ -830,7 +870,7 @@ case 000:
|
||||||
break; }
|
break; }
|
||||||
if (IR < 000240) { /* SPL */
|
if (IR < 000240) { /* SPL */
|
||||||
if (cm == KERNEL) ipl = IR & 07;
|
if (cm == KERNEL) ipl = IR & 07;
|
||||||
trap_req = calc_ints (ipl, int_req, trap_req);
|
trap_req = calc_ints (ipl, trap_req);
|
||||||
break; } /* end if SPL */
|
break; } /* end if SPL */
|
||||||
if (IR < 000260) { /* clear CC */
|
if (IR < 000260) { /* clear CC */
|
||||||
if (IR & 010) N = 0;
|
if (IR & 010) N = 0;
|
||||||
|
@ -1503,7 +1543,7 @@ case 010:
|
||||||
dst = dstreg? R[dstspec]: ReadB (GeteaB (dstspec));
|
dst = dstreg? R[dstspec]: ReadB (GeteaB (dstspec));
|
||||||
if (cm == KERNEL) {
|
if (cm == KERNEL) {
|
||||||
ipl = (dst >> PSW_V_IPL) & 07;
|
ipl = (dst >> PSW_V_IPL) & 07;
|
||||||
trap_req = calc_ints (ipl, int_req, trap_req); }
|
trap_req = calc_ints (ipl, trap_req); }
|
||||||
N = (dst >> PSW_V_N) & 01;
|
N = (dst >> PSW_V_N) & 01;
|
||||||
Z = (dst >> PSW_V_Z) & 01;
|
Z = (dst >> PSW_V_Z) & 01;
|
||||||
V = (dst >> PSW_V_V) & 01;
|
V = (dst >> PSW_V_V) & 01;
|
||||||
|
@ -2068,9 +2108,9 @@ struct iolink *p;
|
||||||
|
|
||||||
for (p = &iotable[0]; p -> low != 0; p++ ) {
|
for (p = &iotable[0]; p -> low != 0; p++ ) {
|
||||||
if ((pa >= p -> low) && (pa <= p -> high) &&
|
if ((pa >= p -> low) && (pa <= p -> high) &&
|
||||||
((p -> enb == 0) || (dev_enb & p -> enb))) {
|
((p -> enb == NULL) || *p -> enb)) {
|
||||||
stat = p -> read (data, pa, access);
|
stat = p -> read (data, pa, access);
|
||||||
trap_req = calc_ints (ipl, int_req, trap_req);
|
trap_req = calc_ints (ipl, trap_req);
|
||||||
return stat; } }
|
return stat; } }
|
||||||
return SCPE_NXM;
|
return SCPE_NXM;
|
||||||
}
|
}
|
||||||
|
@ -2082,12 +2122,23 @@ struct iolink *p;
|
||||||
|
|
||||||
for (p = &iotable[0]; p -> low != 0; p++ ) {
|
for (p = &iotable[0]; p -> low != 0; p++ ) {
|
||||||
if ((pa >= p -> low) && (pa <= p -> high) &&
|
if ((pa >= p -> low) && (pa <= p -> high) &&
|
||||||
((p -> enb == 0) || (dev_enb & p -> enb))) {
|
((p -> enb == NULL) || *p -> enb)) {
|
||||||
stat = p -> write (data, pa, access);
|
stat = p -> write (data, pa, access);
|
||||||
trap_req = calc_ints (ipl, int_req, trap_req);
|
trap_req = calc_ints (ipl, trap_req);
|
||||||
return stat; } }
|
return stat; } }
|
||||||
return SCPE_NXM;
|
return SCPE_NXM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calculate interrupt outstanding */
|
||||||
|
|
||||||
|
int32 calc_ints (int32 nipl, int32 trq)
|
||||||
|
{
|
||||||
|
int32 i;
|
||||||
|
|
||||||
|
for (i = IPL_HLVL - 1; i > nipl; i--) {
|
||||||
|
if (int_req[i]) return (trq | TRAP_INT); }
|
||||||
|
return (trq & ~TRAP_INT);
|
||||||
|
}
|
||||||
|
|
||||||
/* I/O page routines for CPU registers
|
/* I/O page routines for CPU registers
|
||||||
|
|
||||||
|
@ -2133,13 +2184,13 @@ default: /* MMR1, MMR2 */
|
||||||
return SCPE_OK; } /* end switch pa */
|
return SCPE_OK; } /* end switch pa */
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat MMR3_rd (int32 *data, int32 pa, int32 access) /* MMR3 */
|
t_stat MMR3_rd (int32 *data, int32 pa, int32 access) /* MMR3 */
|
||||||
{
|
{
|
||||||
*data = MMR3 & MMR3_IMP;
|
*data = MMR3 & MMR3_IMP;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat MMR3_wr (int32 data, int32 pa, int32 access) /* MMR3 */
|
t_stat MMR3_wr (int32 data, int32 pa, int32 access) /* MMR3 */
|
||||||
{
|
{
|
||||||
if (pa & 1) return SCPE_OK;
|
if (pa & 1) return SCPE_OK;
|
||||||
MMR3 = data & MMR3_RW;
|
MMR3 = data & MMR3_RW;
|
||||||
|
@ -2267,17 +2318,22 @@ case 015: /* PIRQ */
|
||||||
if (access == WRITEB) {
|
if (access == WRITEB) {
|
||||||
if (pa & 1) data = data << 8;
|
if (pa & 1) data = data << 8;
|
||||||
else return SCPE_OK; }
|
else return SCPE_OK; }
|
||||||
int_req = int_req & ~(INT_PIR7 + INT_PIR6 + INT_PIR5 + INT_PIR4 +
|
|
||||||
INT_PIR3 + INT_PIR2 + INT_PIR1);
|
|
||||||
PIRQ = data & PIRQ_RW;
|
PIRQ = data & PIRQ_RW;
|
||||||
pl = 0;
|
pl = 0;
|
||||||
if (PIRQ & PIRQ_PIR1) { int_req = int_req | INT_PIR1; pl = 0042; }
|
if (PIRQ & PIRQ_PIR1) { SET_INT (PIR1); pl = 0042; }
|
||||||
if (PIRQ & PIRQ_PIR2) { int_req = int_req | INT_PIR2; pl = 0104; }
|
else CLR_INT (PIR1);
|
||||||
if (PIRQ & PIRQ_PIR3) { int_req = int_req | INT_PIR3; pl = 0146; }
|
if (PIRQ & PIRQ_PIR2) { SET_INT (PIR2); pl = 0104; }
|
||||||
if (PIRQ & PIRQ_PIR4) { int_req = int_req | INT_PIR4; pl = 0210; }
|
else CLR_INT (PIR2);
|
||||||
if (PIRQ & PIRQ_PIR5) { int_req = int_req | INT_PIR5; pl = 0252; }
|
if (PIRQ & PIRQ_PIR3) { SET_INT (PIR3); pl = 0146; }
|
||||||
if (PIRQ & PIRQ_PIR6) { int_req = int_req | INT_PIR6; pl = 0314; }
|
else CLR_INT (PIR3);
|
||||||
if (PIRQ & PIRQ_PIR7) { int_req = int_req | INT_PIR7; pl = 0356; }
|
if (PIRQ & PIRQ_PIR4) { SET_INT (PIR4); pl = 0210; }
|
||||||
|
else CLR_INT (PIR4);
|
||||||
|
if (PIRQ & PIRQ_PIR5) { SET_INT (PIR5); pl = 0252; }
|
||||||
|
else CLR_INT (PIR5);
|
||||||
|
if (PIRQ & PIRQ_PIR6) { SET_INT (PIR6); pl = 0314; }
|
||||||
|
else CLR_INT (PIR6);
|
||||||
|
if (PIRQ & PIRQ_PIR7) { SET_INT (PIR7); pl = 0356; }
|
||||||
|
else CLR_INT (PIR7);
|
||||||
PIRQ = PIRQ | pl;
|
PIRQ = PIRQ | pl;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
|
|
127
pdp11_defs.h
127
pdp11_defs.h
|
@ -26,6 +26,9 @@
|
||||||
The author gratefully acknowledges the help of Max Burnet, Megan Gentry,
|
The author gratefully acknowledges the help of Max Burnet, Megan Gentry,
|
||||||
and John Wilson in resolving questions about the PDP-11
|
and John Wilson in resolving questions about the PDP-11
|
||||||
|
|
||||||
|
19-Oct-01 RMS Added DZ definitions
|
||||||
|
15-Oct-01 RMS Added logging capabilities
|
||||||
|
07-Sep-01 RMS Revised for multilevel interrupts
|
||||||
01-Jun-01 RMS Added DZ11 support
|
01-Jun-01 RMS Added DZ11 support
|
||||||
23-Apr-01 RMS Added RK611 support
|
23-Apr-01 RMS Added RK611 support
|
||||||
05-Apr-01 RMS Added TS11/TSV05 support
|
05-Apr-01 RMS Added TS11/TSV05 support
|
||||||
|
@ -237,40 +240,42 @@ typedef struct fpac fpac_t;
|
||||||
#define STOP_SPABORT TRAP_V_MAX + 5 /* abort trap push */
|
#define STOP_SPABORT TRAP_V_MAX + 5 /* abort trap push */
|
||||||
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* cond error return */
|
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* cond error return */
|
||||||
|
|
||||||
/* Interrupt assignments, priority is right to left
|
/* DZ11 parameters */
|
||||||
|
|
||||||
<3:0> = BR7, <3> = PIR7
|
#define DZ_MUXES 1 /* # of muxes */
|
||||||
<7:4> = BR6, <7> = PIR6
|
#define DZ_LINES 8 /* lines per mux */
|
||||||
<19:8> = BR5, <19> = PIR5
|
|
||||||
<28:20> = BR4, <28> = PIR4
|
|
||||||
<29> = PIR3
|
|
||||||
<30> = PIR2
|
|
||||||
<31> = PIR1
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define INT_V_PIR7 3
|
/* Interrupt assignments; within each level, priority is right to left */
|
||||||
#define INT_V_CLK 4
|
|
||||||
#define INT_V_DTA 5
|
#define IPL_HLVL 8 /* # int levels */
|
||||||
#define INT_V_PIR6 7
|
|
||||||
#define INT_V_RK 8
|
#define INT_V_PIR7 0 /* BR7 */
|
||||||
#define INT_V_RL 9
|
|
||||||
#define INT_V_RX 10
|
#define INT_V_CLK 0 /* BR6 */
|
||||||
#define INT_V_TM 11
|
#define INT_V_DTA 1
|
||||||
#define INT_V_RP 12
|
#define INT_V_PIR6 2
|
||||||
#define INT_V_TS 13
|
|
||||||
#define INT_V_HK 14
|
#define INT_V_RK 0 /* BR5 */
|
||||||
#define INT_V_DZ0RX 16
|
#define INT_V_RL 1
|
||||||
#define INT_V_DZ0TX 17
|
#define INT_V_RX 2
|
||||||
#define INT_V_PIR5 19
|
#define INT_V_TM 3
|
||||||
#define INT_V_TTI 20
|
#define INT_V_RP 4
|
||||||
#define INT_V_TTO 21
|
#define INT_V_TS 5
|
||||||
#define INT_V_PTR 22
|
#define INT_V_HK 6
|
||||||
#define INT_V_PTP 23
|
#define INT_V_DZRX 7
|
||||||
#define INT_V_LPT 24
|
#define INT_V_DZTX 8
|
||||||
#define INT_V_PIR4 28
|
#define INT_V_PIR5 9
|
||||||
#define INT_V_PIR3 29
|
|
||||||
#define INT_V_PIR2 30
|
#define INT_V_TTI 0 /* BR4 */
|
||||||
#define INT_V_PIR1 31
|
#define INT_V_TTO 1
|
||||||
|
#define INT_V_PTR 2
|
||||||
|
#define INT_V_PTP 3
|
||||||
|
#define INT_V_LPT 4
|
||||||
|
#define INT_V_PIR4 5
|
||||||
|
|
||||||
|
#define INT_V_PIR3 0 /* BR3 */
|
||||||
|
#define INT_V_PIR2 0 /* BR2 */
|
||||||
|
#define INT_V_PIR1 0 /* BR1 */
|
||||||
|
|
||||||
#define INT_PIR7 (1u << INT_V_PIR7)
|
#define INT_PIR7 (1u << INT_V_PIR7)
|
||||||
#define INT_CLK (1u << INT_V_CLK)
|
#define INT_CLK (1u << INT_V_CLK)
|
||||||
|
@ -283,8 +288,8 @@ typedef struct fpac fpac_t;
|
||||||
#define INT_RP (1u << INT_V_RP)
|
#define INT_RP (1u << INT_V_RP)
|
||||||
#define INT_TS (1u << INT_V_TS)
|
#define INT_TS (1u << INT_V_TS)
|
||||||
#define INT_HK (1u << INT_V_HK)
|
#define INT_HK (1u << INT_V_HK)
|
||||||
#define INT_DZ0RX (1u << INT_V_DZ0RX)
|
#define INT_DZRX (1u << INT_V_DZRX)
|
||||||
#define INT_DZ0TX (1u << INT_V_DZ0TX)
|
#define INT_DZTX (1u << INT_V_DZTX)
|
||||||
#define INT_PIR5 (1u << INT_V_PIR5)
|
#define INT_PIR5 (1u << INT_V_PIR5)
|
||||||
#define INT_PTR (1u << INT_V_PTR)
|
#define INT_PTR (1u << INT_V_PTR)
|
||||||
#define INT_PTP (1u << INT_V_PTP)
|
#define INT_PTP (1u << INT_V_PTP)
|
||||||
|
@ -296,14 +301,30 @@ typedef struct fpac fpac_t;
|
||||||
#define INT_PIR2 (1u << INT_V_PIR2)
|
#define INT_PIR2 (1u << INT_V_PIR2)
|
||||||
#define INT_PIR1 (1u << INT_V_PIR1)
|
#define INT_PIR1 (1u << INT_V_PIR1)
|
||||||
|
|
||||||
#define INT_IPL7 0x00000000 /* int level masks */
|
#define IPL_CLK 6 /* int pri levels */
|
||||||
#define INT_IPL6 0x0000000F
|
#define IPL_DTA 6
|
||||||
#define INT_IPL5 0x000000FF
|
#define IPL_RK 5
|
||||||
#define INT_IPL4 0x000FFFFF
|
#define IPL_RL 5
|
||||||
#define INT_IPL3 0x1FFFFFFF
|
#define IPL_RX 5
|
||||||
#define INT_IPL2 0x3FFFFFFF
|
#define IPL_TM 5
|
||||||
#define INT_IPL1 0x7FFFFFFF
|
#define IPL_RP 5
|
||||||
#define INT_IPL0 0xFFFFFFFF
|
#define IPL_TS 5
|
||||||
|
#define IPL_HK 5
|
||||||
|
#define IPL_DZRX 5
|
||||||
|
#define IPL_DZTX 5
|
||||||
|
#define IPL_PTR 4
|
||||||
|
#define IPL_PTP 4
|
||||||
|
#define IPL_TTI 4
|
||||||
|
#define IPL_TTO 4
|
||||||
|
#define IPL_LPT 4
|
||||||
|
|
||||||
|
#define IPL_PIR7 7
|
||||||
|
#define IPL_PIR6 6
|
||||||
|
#define IPL_PIR5 5
|
||||||
|
#define IPL_PIR4 4
|
||||||
|
#define IPL_PIR3 3
|
||||||
|
#define IPL_PIR2 2
|
||||||
|
#define IPL_PIR1 1
|
||||||
|
|
||||||
#define VEC_PIRQ 0240 /* interrupt vectors */
|
#define VEC_PIRQ 0240 /* interrupt vectors */
|
||||||
#define VEC_TTI 0060
|
#define VEC_TTI 0060
|
||||||
|
@ -320,8 +341,14 @@ typedef struct fpac fpac_t;
|
||||||
#define VEC_TS 0224
|
#define VEC_TS 0224
|
||||||
#define VEC_RP 0254
|
#define VEC_RP 0254
|
||||||
#define VEC_RX 0264
|
#define VEC_RX 0264
|
||||||
#define VEC_DZ0RX 0310
|
#define VEC_DZRX 0310
|
||||||
#define VEC_DZ0TX 0314
|
#define VEC_DZTX 0314
|
||||||
|
|
||||||
|
/* Interrupt macros */
|
||||||
|
|
||||||
|
#define IREQ(dv) int_req[IPL_##dv]
|
||||||
|
#define SET_INT(dv) IREQ(dv) = IREQ(dv) | (INT_##dv)
|
||||||
|
#define CLR_INT(dv) IREQ(dv) = IREQ(dv) & ~(INT_##dv)
|
||||||
|
|
||||||
/* CPU and FPU macros */
|
/* CPU and FPU macros */
|
||||||
|
|
||||||
|
@ -331,3 +358,15 @@ typedef struct fpac fpac_t;
|
||||||
#define ABORT(val) longjmp (save_env, (val))
|
#define ABORT(val) longjmp (save_env, (val))
|
||||||
#define SP R[6]
|
#define SP R[6]
|
||||||
#define PC R[7]
|
#define PC R[7]
|
||||||
|
|
||||||
|
/* Logging */
|
||||||
|
|
||||||
|
#define LOG_CPU_I 00000001
|
||||||
|
#define LOG_RP 00000010
|
||||||
|
#define LOG_TS 00000020
|
||||||
|
#define LOG_TC_MS 00000100
|
||||||
|
#define LOG_TC_RW 00000200
|
||||||
|
#define LOG_TC_RA 00000400
|
||||||
|
#define LOG_TC_BL 00001000
|
||||||
|
|
||||||
|
#define DBG_LOG(x) (sim_log && (pdp11_log & (x)))
|
||||||
|
|
30
pdp11_dz.c
Normal file
30
pdp11_dz.c
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/* pdp11_dz.c: DZ11 terminal multiplexor simulator
|
||||||
|
|
||||||
|
Copyright (c) 1993-2001, 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.
|
||||||
|
|
||||||
|
dz DZ11 terminal multiplexor
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pdp11_defs.h"
|
||||||
|
#include "dec_dz.h"
|
15
pdp11_lp.c
15
pdp11_lp.c
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
lpt LP11 line printer
|
lpt LP11 line printer
|
||||||
|
|
||||||
|
07-Sep-01 RMS Revised interrupt mechanism
|
||||||
30-Oct-00 RMS Standardized register naming
|
30-Oct-00 RMS Standardized register naming
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@
|
||||||
#define LPTCSR_IMP (CSR_ERR + CSR_DONE + CSR_IE) /* implemented */
|
#define LPTCSR_IMP (CSR_ERR + CSR_DONE + CSR_IE) /* implemented */
|
||||||
#define LPTCSR_RW (CSR_IE) /* read/write */
|
#define LPTCSR_RW (CSR_IE) /* read/write */
|
||||||
|
|
||||||
extern int32 int_req;
|
extern int32 int_req[IPL_HLVL];
|
||||||
int32 lpt_csr = 0; /* control/status */
|
int32 lpt_csr = 0; /* control/status */
|
||||||
int32 lpt_stopioe = 0; /* stop on error */
|
int32 lpt_stopioe = 0; /* stop on error */
|
||||||
t_stat lpt_svc (UNIT *uptr);
|
t_stat lpt_svc (UNIT *uptr);
|
||||||
|
@ -54,7 +55,7 @@ UNIT lpt_unit = {
|
||||||
REG lpt_reg[] = {
|
REG lpt_reg[] = {
|
||||||
{ ORDATA (BUF, lpt_unit.buf, 8) },
|
{ ORDATA (BUF, lpt_unit.buf, 8) },
|
||||||
{ ORDATA (CSR, lpt_csr, 16) },
|
{ ORDATA (CSR, lpt_csr, 16) },
|
||||||
{ FLDATA (INT, int_req, INT_V_LPT) },
|
{ FLDATA (INT, IREQ (LPT), INT_V_LPT) },
|
||||||
{ FLDATA (ERR, lpt_csr, CSR_V_ERR) },
|
{ FLDATA (ERR, lpt_csr, CSR_V_ERR) },
|
||||||
{ FLDATA (DONE, lpt_csr, CSR_V_DONE) },
|
{ FLDATA (DONE, lpt_csr, CSR_V_DONE) },
|
||||||
{ FLDATA (IE, lpt_csr, CSR_V_IE) },
|
{ FLDATA (IE, lpt_csr, CSR_V_IE) },
|
||||||
|
@ -90,13 +91,13 @@ t_stat lpt_wr (int32 data, int32 PA, int32 access)
|
||||||
{
|
{
|
||||||
if ((PA & 02) == 0) { /* csr */
|
if ((PA & 02) == 0) { /* csr */
|
||||||
if (PA & 1) return SCPE_OK;
|
if (PA & 1) return SCPE_OK;
|
||||||
if ((data & CSR_IE) == 0) int_req = int_req & ~INT_LPT;
|
if ((data & CSR_IE) == 0) CLR_INT (LPT);
|
||||||
else if ((lpt_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
|
else if ((lpt_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
|
||||||
int_req = int_req | INT_LPT;
|
SET_INT (LPT);
|
||||||
lpt_csr = (lpt_csr & ~LPTCSR_RW) | (data & LPTCSR_RW); }
|
lpt_csr = (lpt_csr & ~LPTCSR_RW) | (data & LPTCSR_RW); }
|
||||||
else { if ((PA & 1) == 0) lpt_unit.buf = data & 0177; /* buffer */
|
else { if ((PA & 1) == 0) lpt_unit.buf = data & 0177; /* buffer */
|
||||||
lpt_csr = lpt_csr & ~CSR_DONE;
|
lpt_csr = lpt_csr & ~CSR_DONE;
|
||||||
int_req = int_req & ~INT_LPT;
|
CLR_INT (LPT);
|
||||||
if ((lpt_unit.buf == 015) || (lpt_unit.buf == 014) ||
|
if ((lpt_unit.buf == 015) || (lpt_unit.buf == 014) ||
|
||||||
(lpt_unit.buf == 012)) sim_activate (&lpt_unit, lpt_unit.wait);
|
(lpt_unit.buf == 012)) sim_activate (&lpt_unit, lpt_unit.wait);
|
||||||
else sim_activate (&lpt_unit, 0); }
|
else sim_activate (&lpt_unit, 0); }
|
||||||
|
@ -106,7 +107,7 @@ return SCPE_OK;
|
||||||
t_stat lpt_svc (UNIT *uptr)
|
t_stat lpt_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
lpt_csr = lpt_csr | CSR_ERR | CSR_DONE;
|
lpt_csr = lpt_csr | CSR_ERR | CSR_DONE;
|
||||||
if (lpt_csr & CSR_IE) int_req = int_req | INT_LPT;
|
if (lpt_csr & CSR_IE) SET_INT (LPT);
|
||||||
if ((lpt_unit.flags & UNIT_ATT) == 0)
|
if ((lpt_unit.flags & UNIT_ATT) == 0)
|
||||||
return IORETURN (lpt_stopioe, SCPE_UNATT);
|
return IORETURN (lpt_stopioe, SCPE_UNATT);
|
||||||
if (putc (lpt_unit.buf & 0177, lpt_unit.fileref) == EOF) {
|
if (putc (lpt_unit.buf & 0177, lpt_unit.fileref) == EOF) {
|
||||||
|
@ -123,7 +124,7 @@ t_stat lpt_reset (DEVICE *dptr)
|
||||||
lpt_unit.buf = 0;
|
lpt_unit.buf = 0;
|
||||||
lpt_csr = CSR_DONE;
|
lpt_csr = CSR_DONE;
|
||||||
if ((lpt_unit.flags & UNIT_ATT) == 0) lpt_csr = lpt_csr | CSR_ERR;
|
if ((lpt_unit.flags & UNIT_ATT) == 0) lpt_csr = lpt_csr | CSR_ERR;
|
||||||
int_req = int_req & ~INT_LPT;
|
CLR_INT (LPT);
|
||||||
sim_cancel (&lpt_unit); /* deactivate unit */
|
sim_cancel (&lpt_unit); /* deactivate unit */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
32
pdp11_rk.c
32
pdp11_rk.c
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
rk RK11/RK05 cartridge disk
|
rk RK11/RK05 cartridge disk
|
||||||
|
|
||||||
|
07-Sep-01 RMS Revised device disable and interrupt mechanisms
|
||||||
26-Apr-01 RMS Added device enable/disable support
|
26-Apr-01 RMS Added device enable/disable support
|
||||||
25-Mar-01 RMS Fixed block fill calculation
|
25-Mar-01 RMS Fixed block fill calculation
|
||||||
15-Feb-01 RMS Corrected bootstrap string
|
15-Feb-01 RMS Corrected bootstrap string
|
||||||
|
@ -161,7 +162,7 @@
|
||||||
#define MAX(x,y) (((x) > (y))? (x): (y))
|
#define MAX(x,y) (((x) > (y))? (x): (y))
|
||||||
|
|
||||||
extern uint16 *M; /* memory */
|
extern uint16 *M; /* memory */
|
||||||
extern int32 int_req, dev_enb;
|
extern int32 int_req[IPL_HLVL];
|
||||||
extern UNIT cpu_unit;
|
extern UNIT cpu_unit;
|
||||||
int32 rkcs = 0; /* control/status */
|
int32 rkcs = 0; /* control/status */
|
||||||
int32 rkds = 0; /* drive status */
|
int32 rkds = 0; /* drive status */
|
||||||
|
@ -174,6 +175,7 @@ int32 last_drv = 0; /* last r/w drive */
|
||||||
int32 rk_stopioe = 1; /* stop on error */
|
int32 rk_stopioe = 1; /* stop on error */
|
||||||
int32 rk_swait = 10; /* seek time */
|
int32 rk_swait = 10; /* seek time */
|
||||||
int32 rk_rwait = 10; /* rotate time */
|
int32 rk_rwait = 10; /* rotate time */
|
||||||
|
int32 rk_enb = 1; /* device enable */
|
||||||
t_stat rk_svc (UNIT *uptr);
|
t_stat rk_svc (UNIT *uptr);
|
||||||
t_stat rk_reset (DEVICE *dptr);
|
t_stat rk_reset (DEVICE *dptr);
|
||||||
void rk_go (void);
|
void rk_go (void);
|
||||||
|
@ -208,7 +210,7 @@ REG rk_reg[] = {
|
||||||
{ ORDATA (RKER, rker, 16) },
|
{ ORDATA (RKER, rker, 16) },
|
||||||
{ ORDATA (INTQ, rkintq, 9) },
|
{ ORDATA (INTQ, rkintq, 9) },
|
||||||
{ ORDATA (DRVN, last_drv, 3) },
|
{ ORDATA (DRVN, last_drv, 3) },
|
||||||
{ FLDATA (INT, int_req, INT_V_RK) },
|
{ FLDATA (INT, IREQ (RK), INT_V_RK) },
|
||||||
{ FLDATA (ERR, rkcs, CSR_V_ERR) },
|
{ FLDATA (ERR, rkcs, CSR_V_ERR) },
|
||||||
{ FLDATA (DONE, rkcs, CSR_V_DONE) },
|
{ FLDATA (DONE, rkcs, CSR_V_DONE) },
|
||||||
{ FLDATA (IE, rkcs, CSR_V_IE) },
|
{ FLDATA (IE, rkcs, CSR_V_IE) },
|
||||||
|
@ -231,7 +233,7 @@ REG rk_reg[] = {
|
||||||
{ GRDATA (FLG7, rk_unit[7].flags, 8, UNIT_W_UF, UNIT_V_UF - 1),
|
{ GRDATA (FLG7, rk_unit[7].flags, 8, UNIT_W_UF, UNIT_V_UF - 1),
|
||||||
REG_HRO },
|
REG_HRO },
|
||||||
{ FLDATA (STOP_IOE, rk_stopioe, 0) },
|
{ FLDATA (STOP_IOE, rk_stopioe, 0) },
|
||||||
{ FLDATA (*DEVENB, dev_enb, INT_V_RK), REG_HRO },
|
{ FLDATA (*DEVENB, rk_enb, 0), REG_HRO },
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB rk_mod[] = {
|
MTAB rk_mod[] = {
|
||||||
|
@ -313,10 +315,10 @@ case 2: /* RKCS */
|
||||||
(rkcs & 0377) | (data << 8): (rkcs & ~0377) | data;
|
(rkcs & 0377) | (data << 8): (rkcs & ~0377) | data;
|
||||||
if ((data & CSR_IE) == 0) { /* int disable? */
|
if ((data & CSR_IE) == 0) { /* int disable? */
|
||||||
rkintq = 0; /* clr int queue */
|
rkintq = 0; /* clr int queue */
|
||||||
int_req = int_req & ~INT_RK; } /* clr int request */
|
CLR_INT (RK); } /* clr int request */
|
||||||
else if ((rkcs & (CSR_DONE + CSR_IE)) == CSR_DONE) {
|
else if ((rkcs & (CSR_DONE + CSR_IE)) == CSR_DONE) {
|
||||||
rkintq = rkintq | RK_CTLI; /* queue ctrl int */
|
rkintq = rkintq | RK_CTLI; /* queue ctrl int */
|
||||||
int_req = int_req | INT_RK; } /* set int request */
|
SET_INT (RK); } /* set int request */
|
||||||
rkcs = (rkcs & ~RKCS_RW) | (data & RKCS_RW);
|
rkcs = (rkcs & ~RKCS_RW) | (data & RKCS_RW);
|
||||||
if ((rkcs & CSR_DONE) && (data & CSR_GO)) rk_go (); /* new function? */
|
if ((rkcs & CSR_DONE) && (data & CSR_GO)) rk_go (); /* new function? */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
@ -354,7 +356,7 @@ if (func == RKCS_CTLRESET) { /* control reset? */
|
||||||
rkba = 0;
|
rkba = 0;
|
||||||
rkcs = CSR_DONE;
|
rkcs = CSR_DONE;
|
||||||
rkintq = 0; /* clr int queue */
|
rkintq = 0; /* clr int queue */
|
||||||
int_req = int_req & ~INT_RK; /* clr int request */
|
CLR_INT (RK); /* clr int request */
|
||||||
return; }
|
return; }
|
||||||
rker = rker & ~RKER_SOFT; /* clear soft errors */
|
rker = rker & ~RKER_SOFT; /* clear soft errors */
|
||||||
if (rker == 0) rkcs = rkcs & ~RKCS_ERR; /* redo summary */
|
if (rker == 0) rkcs = rkcs & ~RKCS_ERR; /* redo summary */
|
||||||
|
@ -420,9 +422,9 @@ if (uptr -> FUNC == RKCS_SEEK) { /* seek */
|
||||||
rkcs = rkcs | RKCS_SCP; /* set seek done */
|
rkcs = rkcs | RKCS_SCP; /* set seek done */
|
||||||
if (rkcs & CSR_IE) { /* ints enabled? */
|
if (rkcs & CSR_IE) { /* ints enabled? */
|
||||||
rkintq = rkintq | RK_SCPI (drv); /* queue request */
|
rkintq = rkintq | RK_SCPI (drv); /* queue request */
|
||||||
if (rkcs & CSR_DONE) int_req = int_req | INT_RK; }
|
if (rkcs & CSR_DONE) SET_INT (RK); }
|
||||||
else { rkintq = 0; /* clear queue */
|
else { rkintq = 0; /* clear queue */
|
||||||
int_req = int_req & ~INT_RK; } /* clear interrupt */
|
CLR_INT (RK); } /* clear interrupt */
|
||||||
return SCPE_OK; }
|
return SCPE_OK; }
|
||||||
|
|
||||||
if ((uptr -> flags & UNIT_ATT) == 0) { /* attached? */
|
if ((uptr -> flags & UNIT_ATT) == 0) { /* attached? */
|
||||||
|
@ -499,9 +501,9 @@ void rk_set_done (int32 error)
|
||||||
if (rker & RKER_HARD) rkcs = rkcs | RKCS_HERR; }
|
if (rker & RKER_HARD) rkcs = rkcs | RKCS_HERR; }
|
||||||
if (rkcs & CSR_IE) { /* int enable? */
|
if (rkcs & CSR_IE) { /* int enable? */
|
||||||
rkintq = rkintq | RK_CTLI; /* set ctrl int */
|
rkintq = rkintq | RK_CTLI; /* set ctrl int */
|
||||||
int_req = int_req | INT_RK; } /* request int */
|
SET_INT (RK); } /* request int */
|
||||||
else { rkintq = 0; /* clear queue */
|
else { rkintq = 0; /* clear queue */
|
||||||
int_req = int_req & ~INT_RK; }
|
CLR_INT (RK); }
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,7 +511,7 @@ void rk_clr_done (void)
|
||||||
{
|
{
|
||||||
rkcs = rkcs & ~CSR_DONE; /* clear done */
|
rkcs = rkcs & ~CSR_DONE; /* clear done */
|
||||||
rkintq = rkintq & ~RK_CTLI; /* clear ctl int */
|
rkintq = rkintq & ~RK_CTLI; /* clear ctl int */
|
||||||
int_req = int_req & ~INT_RK; /* clear int req */
|
CLR_INT (RK); /* clear int req */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,7 +522,7 @@ int32 i;
|
||||||
for (i = 0; i <= RK_NUMDR; i++) { /* loop thru intq */
|
for (i = 0; i <= RK_NUMDR; i++) { /* loop thru intq */
|
||||||
if (rkintq & (1u << i)) { /* bit i set? */
|
if (rkintq & (1u << i)) { /* bit i set? */
|
||||||
rkintq = rkintq & ~(1u << i); /* clear bit i */
|
rkintq = rkintq & ~(1u << i); /* clear bit i */
|
||||||
if (rkintq) int_req = int_req | INT_RK; /* queue next */
|
if (rkintq) SET_INT (RK); /* queue next */
|
||||||
rkds = (rkds & ~RKDS_ID) | /* id drive */
|
rkds = (rkds & ~RKDS_ID) | /* id drive */
|
||||||
(((i == 0)? last_drv: i - 1) << RKDS_V_ID);
|
(((i == 0)? last_drv: i - 1) << RKDS_V_ID);
|
||||||
return VEC_RK; } } /* return vector */
|
return VEC_RK; } } /* return vector */
|
||||||
|
@ -538,7 +540,7 @@ UNIT *uptr;
|
||||||
rkcs = CSR_DONE;
|
rkcs = CSR_DONE;
|
||||||
rkda = rkba = rker = rkds = 0;
|
rkda = rkba = rker = rkds = 0;
|
||||||
rkintq = last_drv = 0;
|
rkintq = last_drv = 0;
|
||||||
int_req = int_req & ~INT_RK;
|
CLR_INT (RK);
|
||||||
for (i = 0; i < RK_NUMDR; i++) {
|
for (i = 0; i < RK_NUMDR; i++) {
|
||||||
uptr = rk_dev.units + i;
|
uptr = rk_dev.units + i;
|
||||||
sim_cancel (uptr);
|
sim_cancel (uptr);
|
||||||
|
@ -549,8 +551,8 @@ return SCPE_OK;
|
||||||
|
|
||||||
/* Device bootstrap */
|
/* Device bootstrap */
|
||||||
|
|
||||||
#define BOOT_START 02000 /* start */
|
#define BOOT_START 02000 /* start */
|
||||||
#define BOOT_UNIT 02006 /* where to store unit number */
|
#define BOOT_UNIT 02006 /* unit number */
|
||||||
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int32))
|
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int32))
|
||||||
|
|
||||||
static const int32 boot_rom[] = {
|
static const int32 boot_rom[] = {
|
||||||
|
|
24
pdp11_rl.c
24
pdp11_rl.c
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
rl RL11(RLV12)/RL01/RL02 cartridge disk
|
rl RL11(RLV12)/RL01/RL02 cartridge disk
|
||||||
|
|
||||||
|
07-Sep-01 RMS Revised device disable and interrupt mechanisms
|
||||||
20-Aug-01 RMS Added bad block option in attach
|
20-Aug-01 RMS Added bad block option in attach
|
||||||
17-Jul-01 RMS Fixed warning from VC++ 6.0
|
17-Jul-01 RMS Fixed warning from VC++ 6.0
|
||||||
26-Apr-01 RMS Added device enable/disable support
|
26-Apr-01 RMS Added device enable/disable support
|
||||||
|
@ -156,7 +157,7 @@
|
||||||
#define RLBAE_IMP 0000077 /* implemented */
|
#define RLBAE_IMP 0000077 /* implemented */
|
||||||
|
|
||||||
extern uint16 *M; /* memory */
|
extern uint16 *M; /* memory */
|
||||||
extern int32 int_req, dev_enb;
|
extern int32 int_req[IPL_HLVL];
|
||||||
extern UNIT cpu_unit;
|
extern UNIT cpu_unit;
|
||||||
int32 rlcs = 0; /* control/status */
|
int32 rlcs = 0; /* control/status */
|
||||||
int32 rlba = 0; /* memory address */
|
int32 rlba = 0; /* memory address */
|
||||||
|
@ -166,6 +167,7 @@ int32 rlmp = 0, rlmp1 = 0, rlmp2 = 0; /* mp register queue */
|
||||||
int32 rl_swait = 10; /* seek wait */
|
int32 rl_swait = 10; /* seek wait */
|
||||||
int32 rl_rwait = 10; /* rotate wait */
|
int32 rl_rwait = 10; /* rotate wait */
|
||||||
int32 rl_stopioe = 1; /* stop on error */
|
int32 rl_stopioe = 1; /* stop on error */
|
||||||
|
int32 rl_enb = 1; /* device enable */
|
||||||
t_stat rl_svc (UNIT *uptr);
|
t_stat rl_svc (UNIT *uptr);
|
||||||
t_stat rl_reset (DEVICE *dptr);
|
t_stat rl_reset (DEVICE *dptr);
|
||||||
void rl_set_done (int32 error);
|
void rl_set_done (int32 error);
|
||||||
|
@ -201,7 +203,7 @@ REG rl_reg[] = {
|
||||||
{ ORDATA (RLMP, rlmp, 16) },
|
{ ORDATA (RLMP, rlmp, 16) },
|
||||||
{ ORDATA (RLMP1, rlmp1, 16) },
|
{ ORDATA (RLMP1, rlmp1, 16) },
|
||||||
{ ORDATA (RLMP2, rlmp2, 16) },
|
{ ORDATA (RLMP2, rlmp2, 16) },
|
||||||
{ FLDATA (INT, int_req, INT_V_RL) },
|
{ FLDATA (INT, IREQ (RL), INT_V_RL) },
|
||||||
{ FLDATA (ERR, rlcs, CSR_V_ERR) },
|
{ FLDATA (ERR, rlcs, CSR_V_ERR) },
|
||||||
{ FLDATA (DONE, rlcs, CSR_V_DONE) },
|
{ FLDATA (DONE, rlcs, CSR_V_DONE) },
|
||||||
{ FLDATA (IE, rlcs, CSR_V_IE) },
|
{ FLDATA (IE, rlcs, CSR_V_IE) },
|
||||||
|
@ -220,7 +222,7 @@ REG rl_reg[] = {
|
||||||
{ DRDATA (CAPAC2, rl_unit[2].capac, 32), PV_LEFT + REG_HRO },
|
{ DRDATA (CAPAC2, rl_unit[2].capac, 32), PV_LEFT + REG_HRO },
|
||||||
{ DRDATA (CAPAC3, rl_unit[3].capac, 32), PV_LEFT + REG_HRO },
|
{ DRDATA (CAPAC3, rl_unit[3].capac, 32), PV_LEFT + REG_HRO },
|
||||||
{ FLDATA (STOP_IOE, rl_stopioe, 0) },
|
{ FLDATA (STOP_IOE, rl_stopioe, 0) },
|
||||||
{ FLDATA (*DEVENB, dev_enb, INT_V_RL), REG_HRO },
|
{ FLDATA (*DEVENB, rl_enb, 0), REG_HRO },
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB rl_mod[] = {
|
MTAB rl_mod[] = {
|
||||||
|
@ -300,12 +302,12 @@ case 0: /* RLCS */
|
||||||
rlcs = (rlcs & ~RLCS_RW) | (data & RLCS_RW);
|
rlcs = (rlcs & ~RLCS_RW) | (data & RLCS_RW);
|
||||||
rlbae = (rlbae & ~RLCS_M_MEX) | ((rlcs >> RLCS_V_MEX) & RLCS_M_MEX);
|
rlbae = (rlbae & ~RLCS_M_MEX) | ((rlcs >> RLCS_V_MEX) & RLCS_M_MEX);
|
||||||
if (data & CSR_DONE) { /* ready set? */
|
if (data & CSR_DONE) { /* ready set? */
|
||||||
if ((data & CSR_IE) == 0) int_req = int_req & ~INT_RL;
|
if ((data & CSR_IE) == 0) CLR_INT (RL);
|
||||||
else if ((rlcs & (CSR_DONE + CSR_IE)) == CSR_DONE)
|
else if ((rlcs & (CSR_DONE + CSR_IE)) == CSR_DONE)
|
||||||
int_req = int_req | INT_RL;
|
SET_INT (RL);
|
||||||
return SCPE_OK; }
|
return SCPE_OK; }
|
||||||
|
|
||||||
int_req = int_req & ~INT_RL; /* clear interrupt */
|
CLR_INT (RL); /* clear interrupt */
|
||||||
rlcs = rlcs & ~RLCS_ALLERR; /* clear errors */
|
rlcs = rlcs & ~RLCS_ALLERR; /* clear errors */
|
||||||
switch (GET_FUNC (rlcs)) { /* case on RLCS<3:1> */
|
switch (GET_FUNC (rlcs)) { /* case on RLCS<3:1> */
|
||||||
case RLCS_NOP: /* nop */
|
case RLCS_NOP: /* nop */
|
||||||
|
@ -459,8 +461,8 @@ return SCPE_OK;
|
||||||
void rl_set_done (int32 status)
|
void rl_set_done (int32 status)
|
||||||
{
|
{
|
||||||
rlcs = rlcs | status | CSR_DONE; /* set done */
|
rlcs = rlcs | status | CSR_DONE; /* set done */
|
||||||
if (rlcs & CSR_IE) int_req = int_req | INT_RL;
|
if (rlcs & CSR_IE) SET_INT (RL);
|
||||||
else int_req = int_req & ~INT_RL;
|
else CLR_INT (RL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,7 +478,7 @@ UNIT *uptr;
|
||||||
|
|
||||||
rlcs = CSR_DONE;
|
rlcs = CSR_DONE;
|
||||||
rlda = rlba = rlbae = rlmp = rlmp1 = rlmp2 = 0;
|
rlda = rlba = rlbae = rlmp = rlmp1 = rlmp2 = 0;
|
||||||
int_req = int_req & ~INT_RL;
|
CLR_INT (RL);
|
||||||
for (i = 0; i < RL_NUMDR; i++) {
|
for (i = 0; i < RL_NUMDR; i++) {
|
||||||
uptr = rl_dev.units + i;
|
uptr = rl_dev.units + i;
|
||||||
sim_cancel (uptr);
|
sim_cancel (uptr);
|
||||||
|
@ -523,8 +525,8 @@ return pdp11_bad_block (uptr, RL_NUMSC, RL_NUMWD);
|
||||||
|
|
||||||
/* Device bootstrap */
|
/* Device bootstrap */
|
||||||
|
|
||||||
#define BOOT_START 02000 /* start */
|
#define BOOT_START 02000 /* start */
|
||||||
#define BOOT_UNIT 02006 /* where to store unit number */
|
#define BOOT_UNIT 02006 /* unit number */
|
||||||
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int32))
|
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int32))
|
||||||
|
|
||||||
static const int32 boot_rom[] = {
|
static const int32 boot_rom[] = {
|
||||||
|
|
178
pdp11_rp.c
178
pdp11_rp.c
|
@ -25,6 +25,13 @@
|
||||||
|
|
||||||
rp RH/RP/RM moving head disks
|
rp RH/RP/RM moving head disks
|
||||||
|
|
||||||
|
23-Oct-01 RMS Fixed bug in error interrupts
|
||||||
|
15-Oct-01 RMS Added debug logging
|
||||||
|
05-Oct-01 RMS Rewrote interrupt handling from schematics
|
||||||
|
02-Oct-01 RMS Revised CS1 write code
|
||||||
|
30-Sep-01 RMS Moved CS1<5:0> into drives
|
||||||
|
28-Sep-01 RMS Fixed interrupt handling for SC/ATA
|
||||||
|
07-Sep-01 RMS Revised device disable and interrupt mechanisms
|
||||||
20-Aug-01 RMS Added bad block option in attach
|
20-Aug-01 RMS Added bad block option in attach
|
||||||
13-Jul-01 RMS Changed fread call to fxread (found by Peter Schorn)
|
13-Jul-01 RMS Changed fread call to fxread (found by Peter Schorn)
|
||||||
14-May-01 RMS Added check for unattached drive
|
14-May-01 RMS Added check for unattached drive
|
||||||
|
@ -46,13 +53,19 @@
|
||||||
systems, this was through many different third party controllers
|
systems, this was through many different third party controllers
|
||||||
which emulated the Massbus interface.
|
which emulated the Massbus interface.
|
||||||
|
|
||||||
WARNING: This controller is somewhat abstract. It is intended to run
|
WARNING: The interupt logic of the RH11/RH70 is unusual and must be
|
||||||
the operating system drivers for the PDP-11 operating systems and
|
simulated with great precision. The RH11 has an internal interrupt
|
||||||
nothing more. Most error and all diagnostic functions have been
|
request flop, CSTB INTR, which is controlled as follows:
|
||||||
omitted. In addition, the controller conflates the RP04/05/06 series
|
- Writing IE and DONE simultaneously sets CSTB INTR
|
||||||
controllers with the RM02/03/05/80 series controllers and with the
|
- Controller clear, INIT, and interrupt acknowledge clear CSTB INTR
|
||||||
RP07 controller. There are actually significant differences, which
|
(and also clear IE)
|
||||||
have been highlighted where noticed.
|
- A transition of DONE from 0 to 1 sets CSTB from INTR
|
||||||
|
The output of INTR is OR'd with the AND of RPCS1<SC,DONE,IE> to
|
||||||
|
create the interrupt request signal. Thus,
|
||||||
|
- The DONE interrupt is edge sensitive, but the SC interrupt is
|
||||||
|
level sensitive.
|
||||||
|
- The DONE interrupt, once set, is not disabled if IE is cleared,
|
||||||
|
but the SC interrupt is.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pdp11_defs.h"
|
#include "pdp11_defs.h"
|
||||||
|
@ -100,9 +113,12 @@
|
||||||
#define FNC_PRESET 010 /* read-in preset */
|
#define FNC_PRESET 010 /* read-in preset */
|
||||||
#define FNC_PACK 011 /* pack acknowledge */
|
#define FNC_PACK 011 /* pack acknowledge */
|
||||||
#define FNC_SEARCH 014 /* search */
|
#define FNC_SEARCH 014 /* search */
|
||||||
|
#define FNC_XFER 024 /* >=? data xfr */
|
||||||
#define FNC_WCHK 024 /* write check */
|
#define FNC_WCHK 024 /* write check */
|
||||||
#define FNC_WRITE 030 /* write */
|
#define FNC_WRITE 030 /* write */
|
||||||
|
#define FNC_WRITEH 031 /* write w/ headers */
|
||||||
#define FNC_READ 034 /* read */
|
#define FNC_READ 034 /* read */
|
||||||
|
#define FNC_READH 035 /* read w/ headers */
|
||||||
#define CS1_IE CSR_IE /* int enable */
|
#define CS1_IE CSR_IE /* int enable */
|
||||||
#define CS1_DONE CSR_DONE /* ready */
|
#define CS1_DONE CSR_DONE /* ready */
|
||||||
#define CS1_V_UAE 8 /* Unibus addr ext */
|
#define CS1_V_UAE 8 /* Unibus addr ext */
|
||||||
|
@ -113,7 +129,7 @@
|
||||||
#define CS1_TRE 0040000 /* transfer err */
|
#define CS1_TRE 0040000 /* transfer err */
|
||||||
#define CS1_SC 0100000 /* special cond */
|
#define CS1_SC 0100000 /* special cond */
|
||||||
#define CS1_MBZ 0012000
|
#define CS1_MBZ 0012000
|
||||||
#define CS1_RW (CS1_FNC | CS1_IE | CS1_UAE)
|
#define CS1_DRV (CS1_FNC | CS1_GO)
|
||||||
#define GET_FNC(x) (((x) >> CS1_V_FNC) & CS1_M_FNC)
|
#define GET_FNC(x) (((x) >> CS1_V_FNC) & CS1_M_FNC)
|
||||||
|
|
||||||
/* RPWC - 176702 - word count */
|
/* RPWC - 176702 - word count */
|
||||||
|
@ -219,7 +235,7 @@
|
||||||
#define GET_DA(c,fs,d) ((((GET_CY (c) * drv_tab[d].surf) + \
|
#define GET_DA(c,fs,d) ((((GET_CY (c) * drv_tab[d].surf) + \
|
||||||
GET_SF (fs)) * drv_tab[d].sect) + GET_SC (fs))
|
GET_SF (fs)) * drv_tab[d].sect) + GET_SC (fs))
|
||||||
|
|
||||||
/* RPCC - 176736 - current cylinder - unimplemented */
|
/* RPCC - 176736 - current cylinder */
|
||||||
/* RPER2 - 176740 - error status 2 - drive unsafe conditions - unimplemented */
|
/* RPER2 - 176740 - error status 2 - drive unsafe conditions - unimplemented */
|
||||||
/* RPER3 - 176742 - error status 3 - more unsafe conditions - unimplemented */
|
/* RPER3 - 176742 - error status 3 - more unsafe conditions - unimplemented */
|
||||||
/* RPEC1 - 176744 - ECC status 1 - unimplemented */
|
/* RPEC1 - 176744 - ECC status 1 - unimplemented */
|
||||||
|
@ -312,8 +328,10 @@ struct drvtyp drv_tab[] = {
|
||||||
{ 0 } };
|
{ 0 } };
|
||||||
|
|
||||||
extern uint16 *M; /* memory */
|
extern uint16 *M; /* memory */
|
||||||
extern int32 int_req, dev_enb;
|
extern int32 int_req[IPL_HLVL];
|
||||||
extern UNIT cpu_unit;
|
extern UNIT cpu_unit;
|
||||||
|
extern int32 pdp11_log;
|
||||||
|
extern FILE *sim_log;
|
||||||
int32 rpcs1 = 0; /* control/status 1 */
|
int32 rpcs1 = 0; /* control/status 1 */
|
||||||
int32 rpwc = 0; /* word count */
|
int32 rpwc = 0; /* word count */
|
||||||
int32 rpba = 0; /* bus address */
|
int32 rpba = 0; /* bus address */
|
||||||
|
@ -331,15 +349,17 @@ int32 rpec1 = 0; /* ECC correction 1 */
|
||||||
int32 rpec2 = 0; /* ECC correction 2 */
|
int32 rpec2 = 0; /* ECC correction 2 */
|
||||||
int32 rpbae = 0; /* bus address ext */
|
int32 rpbae = 0; /* bus address ext */
|
||||||
int32 rpcs3 = 0; /* control/status 3 */
|
int32 rpcs3 = 0; /* control/status 3 */
|
||||||
|
int32 rpiff = 0; /* INTR flip/flop */
|
||||||
int32 rp_stopioe = 1; /* stop on error */
|
int32 rp_stopioe = 1; /* stop on error */
|
||||||
int32 rp_swait = 10; /* seek time */
|
int32 rp_swait = 10; /* seek time */
|
||||||
int32 rp_rwait = 10; /* rotate time */
|
int32 rp_rwait = 10; /* rotate time */
|
||||||
|
int32 rp_enb = 1; /* device enable */
|
||||||
int reg_in_drive[32] = {
|
int reg_in_drive[32] = {
|
||||||
0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1,
|
0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1,
|
||||||
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
void update_rpcs (int32 flags, int32 drv);
|
void update_rpcs (int32 flags, int32 drv);
|
||||||
void rp_go (int32 drv);
|
void rp_go (int32 drv, int32 fnc);
|
||||||
t_stat rp_set_size (UNIT *uptr, int32 value);
|
t_stat rp_set_size (UNIT *uptr, int32 value);
|
||||||
t_stat rp_set_bad (UNIT *uptr, int32 value);
|
t_stat rp_set_bad (UNIT *uptr, int32 value);
|
||||||
t_stat rp_svc (UNIT *uptr);
|
t_stat rp_svc (UNIT *uptr);
|
||||||
|
@ -391,7 +411,8 @@ REG rp_reg[] = {
|
||||||
{ ORDATA (RPDB, rpdb, 16) },
|
{ ORDATA (RPDB, rpdb, 16) },
|
||||||
{ ORDATA (RPBAE, rpbae, 6) },
|
{ ORDATA (RPBAE, rpbae, 6) },
|
||||||
{ ORDATA (RPCS3, rpcs3, 16) },
|
{ ORDATA (RPCS3, rpcs3, 16) },
|
||||||
{ FLDATA (INT, int_req, INT_V_RP) },
|
{ FLDATA (IFF, rpiff, 0) },
|
||||||
|
{ FLDATA (INT, IREQ (RP), INT_V_RP) },
|
||||||
{ FLDATA (SC, rpcs1, CSR_V_ERR) },
|
{ FLDATA (SC, rpcs1, CSR_V_ERR) },
|
||||||
{ FLDATA (DONE, rpcs1, CSR_V_DONE) },
|
{ FLDATA (DONE, rpcs1, CSR_V_DONE) },
|
||||||
{ FLDATA (IE, rpcs1, CSR_V_IE) },
|
{ FLDATA (IE, rpcs1, CSR_V_IE) },
|
||||||
|
@ -413,6 +434,14 @@ REG rp_reg[] = {
|
||||||
{ ORDATA (RPDE5, rper1[5], 16) },
|
{ ORDATA (RPDE5, rper1[5], 16) },
|
||||||
{ ORDATA (RPDE6, rper1[6], 16) },
|
{ ORDATA (RPDE6, rper1[6], 16) },
|
||||||
{ ORDATA (RPDE7, rper1[7], 16) },
|
{ ORDATA (RPDE7, rper1[7], 16) },
|
||||||
|
{ ORDATA (RPFN0, rp_unit[0].FUNC, 5), REG_HRO },
|
||||||
|
{ ORDATA (RPFN1, rp_unit[1].FUNC, 5), REG_HRO },
|
||||||
|
{ ORDATA (RPFN2, rp_unit[2].FUNC, 5), REG_HRO },
|
||||||
|
{ ORDATA (RPFN3, rp_unit[3].FUNC, 5), REG_HRO },
|
||||||
|
{ ORDATA (RPFN4, rp_unit[4].FUNC, 5), REG_HRO },
|
||||||
|
{ ORDATA (RPFN5, rp_unit[5].FUNC, 5), REG_HRO },
|
||||||
|
{ ORDATA (RPFN6, rp_unit[6].FUNC, 5), REG_HRO },
|
||||||
|
{ ORDATA (RPFN7, rp_unit[7].FUNC, 5), REG_HRO },
|
||||||
{ GRDATA (FLG0, rp_unit[0].flags, 8, UNIT_W_UF, UNIT_V_UF - 1),
|
{ GRDATA (FLG0, rp_unit[0].flags, 8, UNIT_W_UF, UNIT_V_UF - 1),
|
||||||
REG_HRO },
|
REG_HRO },
|
||||||
{ GRDATA (FLG1, rp_unit[1].flags, 8, UNIT_W_UF, UNIT_V_UF - 1),
|
{ GRDATA (FLG1, rp_unit[1].flags, 8, UNIT_W_UF, UNIT_V_UF - 1),
|
||||||
|
@ -430,7 +459,7 @@ REG rp_reg[] = {
|
||||||
{ GRDATA (FLG7, rp_unit[7].flags, 8, UNIT_W_UF, UNIT_V_UF - 1),
|
{ GRDATA (FLG7, rp_unit[7].flags, 8, UNIT_W_UF, UNIT_V_UF - 1),
|
||||||
REG_HRO },
|
REG_HRO },
|
||||||
{ FLDATA (STOP_IOE, rp_stopioe, 0) },
|
{ FLDATA (STOP_IOE, rp_stopioe, 0) },
|
||||||
{ FLDATA (*DEVENB, dev_enb, INT_V_RP), REG_HRO },
|
{ FLDATA (*DEVENB, rp_enb, 0), REG_HRO },
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB rp_mod[] = {
|
MTAB rp_mod[] = {
|
||||||
|
@ -578,9 +607,11 @@ return SCPE_OK;
|
||||||
t_stat rp_wr (int32 data, int32 PA, int32 access)
|
t_stat rp_wr (int32 data, int32 PA, int32 access)
|
||||||
{
|
{
|
||||||
int32 cs1f, drv, i, j;
|
int32 cs1f, drv, i, j;
|
||||||
|
UNIT *uptr;
|
||||||
|
|
||||||
cs1f = 0; /* no int on cs1 upd */
|
cs1f = 0; /* no int on cs1 upd */
|
||||||
drv = GET_UNIT (rpcs2); /* get current unit */
|
drv = GET_UNIT (rpcs2); /* get current unit */
|
||||||
|
uptr = rp_dev.units + drv; /* get unit */
|
||||||
j = (PA >> 1) & 037; /* get reg offset */
|
j = (PA >> 1) & 037; /* get reg offset */
|
||||||
if (reg_in_drive[j] && (rp_unit[drv].flags & UNIT_DIS)) { /* nx disk */
|
if (reg_in_drive[j] && (rp_unit[drv].flags & UNIT_DIS)) { /* nx disk */
|
||||||
rpcs2 = rpcs2 | CS2_NED; /* set error flag */
|
rpcs2 = rpcs2 | CS2_NED; /* set error flag */
|
||||||
|
@ -594,19 +625,29 @@ if (reg_in_drive[j] && sim_is_active (&rp_unit[drv])) { /* unit busy? */
|
||||||
switch (j) { /* decode PA<5:1> */
|
switch (j) { /* decode PA<5:1> */
|
||||||
case 000: /* RPCS1 */
|
case 000: /* RPCS1 */
|
||||||
if ((access == WRITEB) && (PA & 1)) data = data << 8;
|
if ((access == WRITEB) && (PA & 1)) data = data << 8;
|
||||||
else { if ((data & CS1_IE) == 0) int_req = int_req & ~INT_RP;
|
|
||||||
else if (data & CS1_DONE) int_req = int_req | INT_RP; }
|
|
||||||
if (data & CS1_TRE) { /* error clear? */
|
if (data & CS1_TRE) { /* error clear? */
|
||||||
rpcs1 = rpcs1 & ~CS1_TRE; /* clr CS1<TRE> */
|
rpcs1 = rpcs1 & ~CS1_TRE; /* clr CS1<TRE> */
|
||||||
rpcs2 = rpcs2 & ~CS2_ERR; } /* clr CS2<15:8> */
|
rpcs2 = rpcs2 & ~CS2_ERR; } /* clr CS2<15:8> */
|
||||||
if (access == WRITEB) data = (rpcs1 & /* merge data */
|
if ((access == WRITE) || (PA & 1)) { /* hi byte write? */
|
||||||
((PA & 1)? 0377: 0177400)) | data;
|
if (rpcs1 & CS1_DONE) /* done set? */
|
||||||
rpcs1 = (rpcs1 & ~CS1_RW) | (data & CS1_RW);
|
rpcs1 = (rpcs1 & ~CS1_UAE) | (data & CS1_UAE); }
|
||||||
rpbae = (rpbae & ~CS1_M_UAE) | ((rpcs1 >> CS1_V_UAE) & CS1_M_UAE);
|
if ((access == WRITE) || !(PA & 1)) { /* lo byte write? */
|
||||||
|
if ((data & CS1_DONE) && (data & CS1_IE)) /* to DONE+IE? */
|
||||||
|
rpiff = 1; /* set CSTB INTR */
|
||||||
|
rpcs1 = (rpcs1 & ~CS1_IE) | (data & CS1_IE);
|
||||||
|
if (uptr -> flags & UNIT_DIS) { /* nx disk? */
|
||||||
|
rpcs2 = rpcs2 | CS2_NED; /* set error flag */
|
||||||
|
cs1f = CS1_SC; } /* req interrupt */
|
||||||
|
else if (sim_is_active (uptr))
|
||||||
|
rper1[drv] = rper1[drv] | ER1_RMR; /* won't write */
|
||||||
|
else if (data & CS1_GO) { /* start op */
|
||||||
|
uptr -> FUNC = GET_FNC (data); /* set func */
|
||||||
|
if ((uptr -> FUNC >= FNC_XFER) && /* data xfer and */
|
||||||
|
((rpcs1 & CS1_DONE) == 0)) /* ~rdy? PGE */
|
||||||
|
rpcs2 = rpcs2 | CS2_PGE;
|
||||||
|
else rp_go (drv, uptr -> FUNC); } }
|
||||||
rpcs3 = (rpcs3 & ~CS1_IE) | (rpcs1 & CS1_IE);
|
rpcs3 = (rpcs3 & ~CS1_IE) | (rpcs1 & CS1_IE);
|
||||||
if (data & CS1_GO) { /* new command? */
|
rpbae = (rpbae & ~CS1_M_UAE) | ((rpcs1 >> CS1_V_UAE) & CS1_M_UAE);
|
||||||
if (rpcs1 & CS1_DONE) rp_go (drv); /* start if not busy */
|
|
||||||
else rpcs2 = rpcs2 | CS2_PGE; } /* else prog error */
|
|
||||||
break;
|
break;
|
||||||
case 001: /* RPWC */
|
case 001: /* RPWC */
|
||||||
if (access == WRITEB) data = (PA & 1)?
|
if (access == WRITEB) data = (PA & 1)?
|
||||||
|
@ -670,9 +711,6 @@ case 024: /* RPBAE */
|
||||||
case 025: /* RPCS3 */
|
case 025: /* RPCS3 */
|
||||||
if ((access == WRITEB) && (PA & 1)) break;
|
if ((access == WRITEB) && (PA & 1)) break;
|
||||||
rpcs3 = data & ~CS3_MBZ;
|
rpcs3 = data & ~CS3_MBZ;
|
||||||
if ((data & CS1_IE) == 0) int_req = int_req & ~INT_RP;
|
|
||||||
else if (((rpcs1 & CS1_IE) == 0) && (rpcs1 & CS1_DONE))
|
|
||||||
int_req = int_req | INT_RP;
|
|
||||||
rpcs1 = (rpcs1 & ~CS1_IE) | (rpcs3 & CS1_IE);
|
rpcs1 = (rpcs1 & ~CS1_IE) | (rpcs3 & CS1_IE);
|
||||||
break;
|
break;
|
||||||
case 005: /* RPDS */
|
case 005: /* RPDS */
|
||||||
|
@ -692,30 +730,27 @@ update_rpcs (cs1f, drv); /* update status */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initiate operation */
|
/* Initiate operation - unit not busy, function set */
|
||||||
|
|
||||||
void rp_go (int32 drv)
|
void rp_go (int32 drv, int32 fnc)
|
||||||
{
|
{
|
||||||
|
|
||||||
int32 dc, dtype, fnc;
|
int32 dc, dtype, t;
|
||||||
UNIT *uptr;
|
UNIT *uptr;
|
||||||
|
|
||||||
fnc = GET_FNC (rpcs1); /* get function */
|
if (DBG_LOG (LOG_RP)) fprintf (sim_log,
|
||||||
|
">>RP%d: fnc=%o, ds=%o, cyl=%o, da=%o, ba=%o, wc=%o\n",
|
||||||
|
drv, fnc, rpds[drv], rpdc, rpda, (rpbae << 16) | rpba, rpwc);
|
||||||
uptr = rp_dev.units + drv; /* get unit */
|
uptr = rp_dev.units + drv; /* get unit */
|
||||||
if (uptr -> flags & UNIT_DIS) { /* nx unit? */
|
if (uptr -> flags & UNIT_DIS) { /* nx unit? */
|
||||||
rpcs2 = rpcs2 | CS2_NED; /* set error flag */
|
rpcs2 = rpcs2 | CS2_NED; /* set error flag */
|
||||||
update_rpcs (CS1_SC, drv); /* request intr */
|
update_rpcs (CS1_SC, drv); /* request intr */
|
||||||
return; }
|
return; }
|
||||||
if (fnc != FNC_DCLR) { /* not clear? */
|
if ((fnc != FNC_DCLR) && (rpds[drv] & DS_ERR)) { /* err & ~clear? */
|
||||||
if ((rpds[drv] & DS_ERR) || /* error or */
|
rper1[drv] = rper1[drv] | ER1_ILF; /* not allowed */
|
||||||
((rpds[drv] & DS_RDY) == 0)) { /* not ready? */
|
rpds[drv] = rpds[drv] | DS_ATA; /* set attention */
|
||||||
rpcs2 = rpcs2 | CS2_PGE; /* set error flag */
|
update_rpcs (CS1_SC, drv); /* request intr */
|
||||||
update_rpcs (CS1_SC, drv); /* request intr */
|
return; }
|
||||||
return; }
|
|
||||||
if ((uptr -> flags & UNIT_ATT) == 0) { /* not attached? */
|
|
||||||
rper1[drv] = rper1[drv] | ER1_UNS; /* unsafe */
|
|
||||||
update_rpcs (CS1_SC, drv); /* request intr */
|
|
||||||
return; } }
|
|
||||||
dtype = GET_DTYPE (uptr -> flags); /* get drive type */
|
dtype = GET_DTYPE (uptr -> flags); /* get drive type */
|
||||||
rpds[drv] = rpds[drv] & ~DS_ATA; /* clear attention */
|
rpds[drv] = rpds[drv] & ~DS_ATA; /* clear attention */
|
||||||
dc = rpdc; /* assume seek, sch */
|
dc = rpdc; /* assume seek, sch */
|
||||||
|
@ -738,7 +773,9 @@ case FNC_PACK: /* pack acknowledge */
|
||||||
|
|
||||||
case FNC_OFFSET: /* offset mode */
|
case FNC_OFFSET: /* offset mode */
|
||||||
case FNC_RETURN:
|
case FNC_RETURN:
|
||||||
uptr -> FUNC = fnc; /* save function */
|
if ((uptr -> flags & UNIT_ATT) == 0) { /* not attached? */
|
||||||
|
rper1[drv] = rper1[drv] | ER1_UNS; /* unsafe */
|
||||||
|
break; }
|
||||||
rpds[drv] = (rpds[drv] & ~DS_RDY) | DS_PIP; /* set positioning */
|
rpds[drv] = (rpds[drv] & ~DS_RDY) | DS_PIP; /* set positioning */
|
||||||
sim_activate (uptr, rp_swait); /* time operation */
|
sim_activate (uptr, rp_swait); /* time operation */
|
||||||
return;
|
return;
|
||||||
|
@ -748,38 +785,47 @@ case FNC_RECAL: /* recalibrate */
|
||||||
dc = 0; /* seek to 0 */
|
dc = 0; /* seek to 0 */
|
||||||
case FNC_SEEK: /* seek */
|
case FNC_SEEK: /* seek */
|
||||||
case FNC_SEARCH: /* search */
|
case FNC_SEARCH: /* search */
|
||||||
|
if ((uptr -> flags & UNIT_ATT) == 0) { /* not attached? */
|
||||||
|
rper1[drv] = rper1[drv] | ER1_UNS; /* unsafe */
|
||||||
|
break; }
|
||||||
if ((GET_CY (dc) >= drv_tab[dtype].cyl) || /* bad cylinder */
|
if ((GET_CY (dc) >= drv_tab[dtype].cyl) || /* bad cylinder */
|
||||||
(GET_SF (rpda) >= drv_tab[dtype].surf) || /* bad surface */
|
(GET_SF (rpda) >= drv_tab[dtype].surf) || /* bad surface */
|
||||||
(GET_SC (rpda) >= drv_tab[dtype].sect)) { /* or bad sector? */
|
(GET_SC (rpda) >= drv_tab[dtype].sect)) { /* or bad sector? */
|
||||||
rper1[drv] = rper1[drv] | ER1_IAE;
|
rper1[drv] = rper1[drv] | ER1_IAE;
|
||||||
break; }
|
break; }
|
||||||
rpds[drv] = (rpds[drv] & ~DS_RDY) | DS_PIP; /* set positioning */
|
rpds[drv] = (rpds[drv] & ~DS_RDY) | DS_PIP; /* set positioning */
|
||||||
sim_activate (uptr, rp_swait * abs (dc - uptr -> CYL));
|
t = abs (dc - uptr -> CYL); /* cyl diff */
|
||||||
uptr -> FUNC = fnc; /* save function */
|
if (t == 0) t = 1; /* min time */
|
||||||
|
sim_activate (uptr, rp_swait * t); /* schedule */
|
||||||
uptr -> CYL = dc; /* save cylinder */
|
uptr -> CYL = dc; /* save cylinder */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case FNC_WRITEH: /* write headers */
|
||||||
case FNC_WRITE: /* write */
|
case FNC_WRITE: /* write */
|
||||||
case FNC_WCHK: /* write check */
|
case FNC_WCHK: /* write check */
|
||||||
case FNC_READ: /* read */
|
case FNC_READ: /* read */
|
||||||
|
case FNC_READH: /* read headers */
|
||||||
|
if ((uptr -> flags & UNIT_ATT) == 0) { /* not attached? */
|
||||||
|
rper1[drv] = rper1[drv] | ER1_UNS; /* unsafe */
|
||||||
|
break; }
|
||||||
rpcs2 = rpcs2 & ~CS2_ERR; /* clear errors */
|
rpcs2 = rpcs2 & ~CS2_ERR; /* clear errors */
|
||||||
rpcs1 = rpcs1 & ~(CS1_TRE | CS1_MCPE | CS1_DONE);
|
rpcs1 = rpcs1 & ~(CS1_TRE | CS1_MCPE | CS1_DONE);
|
||||||
if ((GET_CY (dc) >= drv_tab[dtype].cyl) || /* bad cylinder */
|
if ((GET_CY (dc) >= drv_tab[dtype].cyl) || /* bad cylinder */
|
||||||
(GET_SF (rpda) >= drv_tab[dtype].surf) || /* bad surface */
|
(GET_SF (rpda) >= drv_tab[dtype].surf) || /* bad surface */
|
||||||
(GET_SC (rpda) >= drv_tab[dtype].sect)) { /* or bad sector? */
|
(GET_SC (rpda) >= drv_tab[dtype].sect)) { /* or bad sector? */
|
||||||
rper1[drv] = rper1[drv] | ER1_IAE;
|
rper1[drv] = rper1[drv] | ER1_IAE;
|
||||||
update_rpcs (CS1_DONE | CS1_TRE, drv); /* set done, err */
|
break; }
|
||||||
return; }
|
|
||||||
rpds[drv] = rpds[drv] & ~DS_RDY; /* clear drive rdy */
|
rpds[drv] = rpds[drv] & ~DS_RDY; /* clear drive rdy */
|
||||||
sim_activate (uptr, rp_rwait + (rp_swait * abs (dc - uptr -> CYL)));
|
sim_activate (uptr, rp_rwait + (rp_swait * abs (dc - uptr -> CYL)));
|
||||||
uptr -> FUNC = fnc; /* save function */
|
|
||||||
uptr -> CYL = dc; /* save cylinder */
|
uptr -> CYL = dc; /* save cylinder */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default: /* all others */
|
default: /* all others */
|
||||||
rper1[drv] = rper1[drv] | ER1_ILF; /* not supported */
|
rper1[drv] = rper1[drv] | ER1_ILF; /* not supported */
|
||||||
|
rpds[drv] = rpds[drv] | DS_ATA; /* set attention */
|
||||||
break; }
|
break; }
|
||||||
update_rpcs (CS1_SC, drv); /* error, req intr */
|
rpds[drv] = rpds[drv] | DS_ATA; /* error, set attn */
|
||||||
|
update_rpcs (CS1_SC, drv); /* req intr */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -826,6 +872,7 @@ case FNC_WRITE: /* write */
|
||||||
break; }
|
break; }
|
||||||
case FNC_WCHK: /* write check */
|
case FNC_WCHK: /* write check */
|
||||||
case FNC_READ: /* read */
|
case FNC_READ: /* read */
|
||||||
|
case FNC_READH: /* read headers */
|
||||||
ba = (rpbae << 16) | rpba; /* get byte addr */
|
ba = (rpbae << 16) | rpba; /* get byte addr */
|
||||||
da = GET_DA (rpdc, rpda, dtype) * RP_NUMWD; /* get disk addr */
|
da = GET_DA (rpdc, rpda, dtype) * RP_NUMWD; /* get disk addr */
|
||||||
wc = 0200000 - rpwc; /* get true wc */
|
wc = 0200000 - rpwc; /* get true wc */
|
||||||
|
@ -882,20 +929,28 @@ case FNC_READ: /* read */
|
||||||
perror ("RP I/O error");
|
perror ("RP I/O error");
|
||||||
clearerr (uptr -> fileref);
|
clearerr (uptr -> fileref);
|
||||||
return SCPE_IOERR; }
|
return SCPE_IOERR; }
|
||||||
|
case FNC_WRITEH: /* write headers stub */
|
||||||
update_rpcs (CS1_DONE, drv); /* set done */
|
update_rpcs (CS1_DONE, drv); /* set done */
|
||||||
break; } /* end case function */
|
break; } /* end case func */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Controller status update
|
/* Controller status update
|
||||||
First update drive status, then update RPCS1
|
|
||||||
If optional argument, request interrupt
|
Check for done transition
|
||||||
|
Update drive status
|
||||||
|
Update RPCS1
|
||||||
|
Update interrupt request
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void update_rpcs (int32 flag, int32 drv)
|
void update_rpcs (int32 flag, int32 drv)
|
||||||
{
|
{
|
||||||
int32 i;
|
int32 i;
|
||||||
|
UNIT *uptr;
|
||||||
|
|
||||||
|
if ((flag & ~rpcs1) & CS1_DONE) /* DONE 0 to 1? */
|
||||||
|
rpiff = (rpcs1 & CS1_IE)? 1: 0; /* CSTB INTR <- IE */
|
||||||
|
uptr = rp_dev.units + drv; /* get unit */
|
||||||
if (rp_unit[drv].flags & UNIT_DIS) rpds[drv] = rper1[drv] = 0;
|
if (rp_unit[drv].flags & UNIT_DIS) rpds[drv] = rper1[drv] = 0;
|
||||||
else rpds[drv] = (rpds[drv] | DS_DPR) & ~DS_PGM;
|
else rpds[drv] = (rpds[drv] | DS_DPR) & ~DS_PGM;
|
||||||
if (rp_unit[drv].flags & UNIT_ATT) rpds[drv] = rpds[drv] | DS_MOL;
|
if (rp_unit[drv].flags & UNIT_ATT) rpds[drv] = rpds[drv] | DS_MOL;
|
||||||
|
@ -903,13 +958,16 @@ else rpds[drv] = rpds[drv] & ~(DS_MOL | DS_VV | DS_RDY);
|
||||||
if (rper1[drv] | rper2 | rper3) rpds[drv] = rpds[drv] | DS_ERR | DS_ATA;
|
if (rper1[drv] | rper2 | rper3) rpds[drv] = rpds[drv] | DS_ERR | DS_ATA;
|
||||||
else rpds[drv] = rpds[drv] & ~DS_ERR;
|
else rpds[drv] = rpds[drv] & ~DS_ERR;
|
||||||
|
|
||||||
rpcs1 = (rpcs1 & ~(CS1_SC | CS1_MCPE | CS1_MBZ)) | CS1_DVA | flag;
|
rpcs1 = (rpcs1 & ~(CS1_SC | CS1_MCPE | CS1_MBZ | CS1_DRV)) | CS1_DVA | flag;
|
||||||
|
rpcs1 = rpcs1 | (uptr -> FUNC << CS1_V_FNC);
|
||||||
|
if (sim_is_active (uptr)) rpcs1 = rpcs1 | CS1_GO;
|
||||||
if (rpcs2 & CS2_ERR) rpcs1 = rpcs1 | CS1_TRE | CS1_SC;
|
if (rpcs2 & CS2_ERR) rpcs1 = rpcs1 | CS1_TRE | CS1_SC;
|
||||||
|
else if (rpcs1 & CS1_TRE) rpcs1 = rpcs1 | CS1_SC;
|
||||||
for (i = 0; i < RP_NUMDR; i++)
|
for (i = 0; i < RP_NUMDR; i++)
|
||||||
if (rpds[i] & DS_ATA) rpcs1 = rpcs1 | CS1_SC;
|
if (rpds[i] & DS_ATA) rpcs1 = rpcs1 | CS1_SC;
|
||||||
if (((rpcs1 & CS1_IE) == 0) || ((rpcs1 & CS1_DONE) == 0))
|
if (rpiff || ((rpcs1 & CS1_SC) && (rpcs1 & CS1_DONE) && (rpcs1 & CS1_IE)))
|
||||||
int_req = int_req & ~INT_RP;
|
SET_INT (RP);
|
||||||
else if (flag) int_req = int_req | INT_RP;
|
else CLR_INT (RP);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -917,8 +975,9 @@ return;
|
||||||
|
|
||||||
int32 rp_inta (void)
|
int32 rp_inta (void)
|
||||||
{
|
{
|
||||||
/* rpcs1 = rpcs1 & ~CS1_IE; /* clear int enable */
|
rpcs1 = rpcs1 & ~CS1_IE; /* clear int enable */
|
||||||
/* rpcs3 = rpcs3 & ~CS1_IE; /* in both registers */
|
rpcs3 = rpcs3 & ~CS1_IE; /* in both registers */
|
||||||
|
rpiff = 0; /* clear CSTB INTR */
|
||||||
return VEC_RP; /* acknowledge */
|
return VEC_RP; /* acknowledge */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -936,7 +995,8 @@ rpof = rpdc = 0;
|
||||||
rper2 = rper3 = 0;
|
rper2 = rper3 = 0;
|
||||||
rpec1 = rpec2 = 0;
|
rpec1 = rpec2 = 0;
|
||||||
rpbae = rpcs3 = 0;
|
rpbae = rpcs3 = 0;
|
||||||
int_req = int_req & ~INT_RP;
|
rpiff = 0; /* clear CSTB INTR */
|
||||||
|
CLR_INT (RP); /* clear intr req */
|
||||||
for (i = 0; i < RP_NUMDR; i++) {
|
for (i = 0; i < RP_NUMDR; i++) {
|
||||||
uptr = rp_dev.units + i;
|
uptr = rp_dev.units + i;
|
||||||
sim_cancel (uptr);
|
sim_cancel (uptr);
|
||||||
|
@ -1013,8 +1073,8 @@ return pdp11_bad_block (uptr, drv_tab[GET_DTYPE (uptr -> flags)].sect, RP_NUMWD)
|
||||||
|
|
||||||
/* Device bootstrap */
|
/* Device bootstrap */
|
||||||
|
|
||||||
#define BOOT_START 02000 /* start */
|
#define BOOT_START 02000 /* start */
|
||||||
#define BOOT_UNIT 02006 /* where to store unit number */
|
#define BOOT_UNIT 02006 /* unit number */
|
||||||
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int32))
|
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int32))
|
||||||
|
|
||||||
static const int32 boot_rom[] = {
|
static const int32 boot_rom[] = {
|
||||||
|
|
16
pdp11_rx.c
16
pdp11_rx.c
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
rx RX11/RX01 floppy disk
|
rx RX11/RX01 floppy disk
|
||||||
|
|
||||||
|
07-Sep-01 RMS Revised device disable and interrupt mechanisms
|
||||||
17-Jul-01 RMS Fixed warning from VC++ 6.0
|
17-Jul-01 RMS Fixed warning from VC++ 6.0
|
||||||
26-Apr-01 RMS Added device enable/disable support
|
26-Apr-01 RMS Added device enable/disable support
|
||||||
13-Apr-01 RMS Revised for register arrays
|
13-Apr-01 RMS Revised for register arrays
|
||||||
|
@ -88,7 +89,7 @@
|
||||||
#define TRACK u3 /* current track */
|
#define TRACK u3 /* current track */
|
||||||
#define CALC_DA(t,s) (((t) * RX_NUMSC) + ((s) - 1)) * RX_NUMBY
|
#define CALC_DA(t,s) (((t) * RX_NUMSC) + ((s) - 1)) * RX_NUMBY
|
||||||
|
|
||||||
extern int32 int_req, dev_enb;
|
extern int32 int_req[IPL_HLVL];
|
||||||
int32 rx_csr = 0; /* control/status */
|
int32 rx_csr = 0; /* control/status */
|
||||||
int32 rx_dbr = 0; /* data buffer */
|
int32 rx_dbr = 0; /* data buffer */
|
||||||
int32 rx_esr = 0; /* error status */
|
int32 rx_esr = 0; /* error status */
|
||||||
|
@ -102,6 +103,7 @@ int32 rx_swait = 10; /* seek, per track */
|
||||||
int32 rx_xwait = 1; /* tr set time */
|
int32 rx_xwait = 1; /* tr set time */
|
||||||
unsigned int8 rx_buf[RX_NUMBY] = { 0 }; /* sector buffer */
|
unsigned int8 rx_buf[RX_NUMBY] = { 0 }; /* sector buffer */
|
||||||
int32 bptr = 0; /* buffer pointer */
|
int32 bptr = 0; /* buffer pointer */
|
||||||
|
int32 rx_enb = 1; /* device enable */
|
||||||
t_stat rx_svc (UNIT *uptr);
|
t_stat rx_svc (UNIT *uptr);
|
||||||
t_stat rx_reset (DEVICE *dptr);
|
t_stat rx_reset (DEVICE *dptr);
|
||||||
t_stat rx_boot (int32 unitno);
|
t_stat rx_boot (int32 unitno);
|
||||||
|
@ -129,7 +131,7 @@ REG rx_reg[] = {
|
||||||
{ ORDATA (RXSA, rx_sector, 8) },
|
{ ORDATA (RXSA, rx_sector, 8) },
|
||||||
{ ORDATA (STAPTR, rx_state, 3), REG_RO },
|
{ ORDATA (STAPTR, rx_state, 3), REG_RO },
|
||||||
{ ORDATA (BUFPTR, bptr, 7) },
|
{ ORDATA (BUFPTR, bptr, 7) },
|
||||||
{ FLDATA (INT, int_req, INT_V_RX) },
|
{ FLDATA (INT, IREQ (RX), INT_V_RX) },
|
||||||
{ FLDATA (ERR, rx_csr, CSR_V_ERR) },
|
{ FLDATA (ERR, rx_csr, CSR_V_ERR) },
|
||||||
{ FLDATA (TR, rx_csr, RXCS_V_TR) },
|
{ FLDATA (TR, rx_csr, RXCS_V_TR) },
|
||||||
{ FLDATA (IE, rx_csr, CSR_V_IE) },
|
{ FLDATA (IE, rx_csr, CSR_V_IE) },
|
||||||
|
@ -141,7 +143,7 @@ REG rx_reg[] = {
|
||||||
{ FLDATA (FLG1, rx_unit[1].flags, UNIT_V_WLK), REG_HRO },
|
{ FLDATA (FLG1, rx_unit[1].flags, UNIT_V_WLK), REG_HRO },
|
||||||
{ FLDATA (STOP_IOE, rx_stopioe, 0) },
|
{ FLDATA (STOP_IOE, rx_stopioe, 0) },
|
||||||
{ BRDATA (SBUF, rx_buf, 8, 8, RX_NUMBY) },
|
{ BRDATA (SBUF, rx_buf, 8, 8, RX_NUMBY) },
|
||||||
{ FLDATA (*DEVENB, dev_enb, INT_V_RX), REG_HRO },
|
{ FLDATA (*DEVENB, rx_enb, 0), REG_HRO },
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB rx_mod[] = {
|
MTAB rx_mod[] = {
|
||||||
|
@ -222,9 +224,9 @@ case 0: /* RXCS */
|
||||||
sim_activate (&rx_unit[drv], rx_cwait);
|
sim_activate (&rx_unit[drv], rx_cwait);
|
||||||
break; } /* end switch func */
|
break; } /* end switch func */
|
||||||
return SCPE_OK; } /* end if GO */
|
return SCPE_OK; } /* end if GO */
|
||||||
if ((data & CSR_IE) == 0) int_req = int_req & ~INT_RX;
|
if ((data & CSR_IE) == 0) CLR_INT (RX);
|
||||||
else if ((rx_csr & (RXCS_DONE + CSR_IE)) == RXCS_DONE)
|
else if ((rx_csr & (RXCS_DONE + CSR_IE)) == RXCS_DONE)
|
||||||
int_req = int_req | INT_RX;
|
SET_INT (RX);
|
||||||
rx_csr = (rx_csr & ~RXCS_RW) | (data & RXCS_RW);
|
rx_csr = (rx_csr & ~RXCS_RW) | (data & RXCS_RW);
|
||||||
break; /* end case RXCS */
|
break; /* end case RXCS */
|
||||||
|
|
||||||
|
@ -351,7 +353,7 @@ return IORETURN (rx_stopioe, rval);
|
||||||
void rx_done (int32 new_dbr, int32 new_ecode)
|
void rx_done (int32 new_dbr, int32 new_ecode)
|
||||||
{
|
{
|
||||||
rx_csr = rx_csr | RXCS_DONE; /* set done */
|
rx_csr = rx_csr | RXCS_DONE; /* set done */
|
||||||
if (rx_csr & CSR_IE) int_req = int_req | INT_RX; /* if ie, intr */
|
if (rx_csr & CSR_IE) SET_INT (RX); /* if ie, intr */
|
||||||
rx_dbr = new_dbr; /* update RXDB */
|
rx_dbr = new_dbr; /* update RXDB */
|
||||||
if (new_ecode != 0) { /* test for error */
|
if (new_ecode != 0) { /* test for error */
|
||||||
rx_ecode = new_ecode;
|
rx_ecode = new_ecode;
|
||||||
|
@ -368,7 +370,7 @@ t_stat rx_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
rx_csr = rx_dbr = 0; /* clear regs */
|
rx_csr = rx_dbr = 0; /* clear regs */
|
||||||
rx_esr = rx_ecode = 0; /* clear error */
|
rx_esr = rx_ecode = 0; /* clear error */
|
||||||
int_req = int_req & ~INT_RX; /* clear int req */
|
CLR_INT (RX); /* clear int req */
|
||||||
sim_cancel (&rx_unit[1]); /* cancel drive 1 */
|
sim_cancel (&rx_unit[1]); /* cancel drive 1 */
|
||||||
if (rx_unit[0].flags & UNIT_BUF) { /* attached? */
|
if (rx_unit[0].flags & UNIT_BUF) { /* attached? */
|
||||||
rx_state = INIT_COMPLETE; /* yes, sched init */
|
rx_state = INIT_COMPLETE; /* yes, sched init */
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
tti,tto DL11 terminal input/output
|
tti,tto DL11 terminal input/output
|
||||||
clk KW11L line frequency clock
|
clk KW11L line frequency clock
|
||||||
|
|
||||||
|
07-Oct-01 RMS Upgraded clock to full KW11L for RSTS/E autoconfigure
|
||||||
|
07-Sep-01 RMS Moved function prototypes, revised interrupt mechanism
|
||||||
17-Jul-01 RMS Moved function prototype
|
17-Jul-01 RMS Moved function prototype
|
||||||
04-Jul-01 RMS Added DZ11 support
|
04-Jul-01 RMS Added DZ11 support
|
||||||
05-Mar-01 RMS Added clock calibration support
|
05-Mar-01 RMS Added clock calibration support
|
||||||
|
@ -44,11 +46,11 @@
|
||||||
#define TTICSR_RW (CSR_IE)
|
#define TTICSR_RW (CSR_IE)
|
||||||
#define TTOCSR_IMP (CSR_DONE + CSR_IE) /* terminal output */
|
#define TTOCSR_IMP (CSR_DONE + CSR_IE) /* terminal output */
|
||||||
#define TTOCSR_RW (CSR_IE)
|
#define TTOCSR_RW (CSR_IE)
|
||||||
#define CLKCSR_IMP (CSR_IE) /* real-time clock */
|
#define CLKCSR_IMP (CSR_DONE + CSR_IE) /* real-time clock */
|
||||||
#define CLKCSR_RW (CSR_IE)
|
#define CLKCSR_RW (CSR_DONE + CSR_IE)
|
||||||
#define CLK_DELAY 8000
|
#define CLK_DELAY 8000
|
||||||
|
|
||||||
extern int32 int_req;
|
extern int32 int_req[IPL_HLVL];
|
||||||
int32 ptr_csr = 0; /* control/status */
|
int32 ptr_csr = 0; /* control/status */
|
||||||
int32 ptr_stopioe = 0; /* stop on error */
|
int32 ptr_stopioe = 0; /* stop on error */
|
||||||
int32 ptp_csr = 0; /* control/status */
|
int32 ptp_csr = 0; /* control/status */
|
||||||
|
@ -57,7 +59,7 @@ int32 tti_csr = 0; /* control/status */
|
||||||
int32 tto_csr = 0; /* control/status */
|
int32 tto_csr = 0; /* control/status */
|
||||||
int32 clk_csr = 0; /* control/status */
|
int32 clk_csr = 0; /* control/status */
|
||||||
int32 clk_tps = 60; /* ticks/second */
|
int32 clk_tps = 60; /* ticks/second */
|
||||||
int32 dz_poll = CLK_DELAY; /* DZ poll inteval */
|
int32 tmxr_poll = CLK_DELAY; /* term mux poll */
|
||||||
|
|
||||||
t_stat ptr_svc (UNIT *uptr);
|
t_stat ptr_svc (UNIT *uptr);
|
||||||
t_stat ptp_svc (UNIT *uptr);
|
t_stat ptp_svc (UNIT *uptr);
|
||||||
|
@ -73,8 +75,6 @@ t_stat ptr_attach (UNIT *uptr, char *ptr);
|
||||||
t_stat ptr_detach (UNIT *uptr);
|
t_stat ptr_detach (UNIT *uptr);
|
||||||
t_stat ptp_attach (UNIT *uptr, char *ptr);
|
t_stat ptp_attach (UNIT *uptr, char *ptr);
|
||||||
t_stat ptp_detach (UNIT *uptr);
|
t_stat ptp_detach (UNIT *uptr);
|
||||||
extern t_stat sim_poll_kbd (void);
|
|
||||||
extern t_stat sim_putchar (int32 out);
|
|
||||||
|
|
||||||
/* PTR data structures
|
/* PTR data structures
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ UNIT ptr_unit = {
|
||||||
REG ptr_reg[] = {
|
REG ptr_reg[] = {
|
||||||
{ ORDATA (BUF, ptr_unit.buf, 8) },
|
{ ORDATA (BUF, ptr_unit.buf, 8) },
|
||||||
{ ORDATA (CSR, ptr_csr, 16) },
|
{ ORDATA (CSR, ptr_csr, 16) },
|
||||||
{ FLDATA (INT, int_req, INT_V_PTR) },
|
{ FLDATA (INT, IREQ (PTR), INT_V_PTR) },
|
||||||
{ FLDATA (ERR, ptr_csr, CSR_V_ERR) },
|
{ FLDATA (ERR, ptr_csr, CSR_V_ERR) },
|
||||||
{ FLDATA (BUSY, ptr_csr, CSR_V_BUSY) },
|
{ FLDATA (BUSY, ptr_csr, CSR_V_BUSY) },
|
||||||
{ FLDATA (DONE, ptr_csr, CSR_V_DONE) },
|
{ FLDATA (DONE, ptr_csr, CSR_V_DONE) },
|
||||||
|
@ -118,7 +118,7 @@ UNIT ptp_unit = {
|
||||||
REG ptp_reg[] = {
|
REG ptp_reg[] = {
|
||||||
{ ORDATA (BUF, ptp_unit.buf, 8) },
|
{ ORDATA (BUF, ptp_unit.buf, 8) },
|
||||||
{ ORDATA (CSR, ptp_csr, 16) },
|
{ ORDATA (CSR, ptp_csr, 16) },
|
||||||
{ FLDATA (INT, int_req, INT_V_PTP) },
|
{ FLDATA (INT, IREQ (PTP), INT_V_PTP) },
|
||||||
{ FLDATA (ERR, ptp_csr, CSR_V_ERR) },
|
{ FLDATA (ERR, ptp_csr, CSR_V_ERR) },
|
||||||
{ FLDATA (DONE, ptp_csr, CSR_V_DONE) },
|
{ FLDATA (DONE, ptp_csr, CSR_V_DONE) },
|
||||||
{ FLDATA (IE, ptp_csr, CSR_V_IE) },
|
{ FLDATA (IE, ptp_csr, CSR_V_IE) },
|
||||||
|
@ -145,7 +145,7 @@ UNIT tti_unit = { UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT };
|
||||||
REG tti_reg[] = {
|
REG tti_reg[] = {
|
||||||
{ ORDATA (BUF, tti_unit.buf, 8) },
|
{ ORDATA (BUF, tti_unit.buf, 8) },
|
||||||
{ ORDATA (CSR, tti_csr, 16) },
|
{ ORDATA (CSR, tti_csr, 16) },
|
||||||
{ FLDATA (INT, int_req, INT_V_TTI) },
|
{ FLDATA (INT, IREQ (TTI), INT_V_TTI) },
|
||||||
{ FLDATA (ERR, tti_csr, CSR_V_ERR) },
|
{ FLDATA (ERR, tti_csr, CSR_V_ERR) },
|
||||||
{ FLDATA (DONE, tti_csr, CSR_V_DONE) },
|
{ FLDATA (DONE, tti_csr, CSR_V_DONE) },
|
||||||
{ FLDATA (IE, tti_csr, CSR_V_IE) },
|
{ FLDATA (IE, tti_csr, CSR_V_IE) },
|
||||||
|
@ -171,7 +171,7 @@ UNIT tto_unit = { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT };
|
||||||
REG tto_reg[] = {
|
REG tto_reg[] = {
|
||||||
{ ORDATA (BUF, tto_unit.buf, 8) },
|
{ ORDATA (BUF, tto_unit.buf, 8) },
|
||||||
{ ORDATA (CSR, tto_csr, 16) },
|
{ ORDATA (CSR, tto_csr, 16) },
|
||||||
{ FLDATA (INT, int_req, INT_V_TTO) },
|
{ FLDATA (INT, IREQ (TTO), INT_V_TTO) },
|
||||||
{ FLDATA (ERR, tto_csr, CSR_V_ERR) },
|
{ FLDATA (ERR, tto_csr, CSR_V_ERR) },
|
||||||
{ FLDATA (DONE, tto_csr, CSR_V_DONE) },
|
{ FLDATA (DONE, tto_csr, CSR_V_DONE) },
|
||||||
{ FLDATA (IE, tto_csr, CSR_V_IE) },
|
{ FLDATA (IE, tto_csr, CSR_V_IE) },
|
||||||
|
@ -196,7 +196,7 @@ UNIT clk_unit = { UDATA (&clk_svc, 0, 0), 8000 };
|
||||||
|
|
||||||
REG clk_reg[] = {
|
REG clk_reg[] = {
|
||||||
{ ORDATA (CSR, clk_csr, 16) },
|
{ ORDATA (CSR, clk_csr, 16) },
|
||||||
{ FLDATA (INT, int_req, INT_V_CLK) },
|
{ FLDATA (INT, IREQ (CLK), INT_V_CLK) },
|
||||||
{ FLDATA (DONE, clk_csr, CSR_V_DONE) },
|
{ FLDATA (DONE, clk_csr, CSR_V_DONE) },
|
||||||
{ FLDATA (IE, clk_csr, CSR_V_IE) },
|
{ FLDATA (IE, clk_csr, CSR_V_IE) },
|
||||||
{ DRDATA (TIME, clk_unit.wait, 24), REG_NZ + PV_LEFT },
|
{ DRDATA (TIME, clk_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||||
|
@ -236,7 +236,7 @@ case 04: /* ptr csr */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
case 05: /* ptr buf */
|
case 05: /* ptr buf */
|
||||||
ptr_csr = ptr_csr & ~CSR_DONE;
|
ptr_csr = ptr_csr & ~CSR_DONE;
|
||||||
int_req = int_req & ~INT_PTR;
|
CLR_INT (PTR);
|
||||||
*data = ptr_unit.buf & 0377;
|
*data = ptr_unit.buf & 0377;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
case 06: /* ptp csr */
|
case 06: /* ptp csr */
|
||||||
|
@ -250,7 +250,7 @@ case 010: /* tti csr */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
case 011: /* tti buf */
|
case 011: /* tti buf */
|
||||||
tti_csr = tti_csr & ~CSR_DONE;
|
tti_csr = tti_csr & ~CSR_DONE;
|
||||||
int_req = int_req & ~INT_TTI;
|
CLR_INT (TTI);
|
||||||
*data = tti_unit.buf & 0377;
|
*data = tti_unit.buf & 0377;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
case 012: /* tto csr */
|
case 012: /* tto csr */
|
||||||
|
@ -267,17 +267,20 @@ t_stat std_wr (int32 data, int32 PA, int32 access)
|
||||||
switch ((PA >> 1) & 017) { /* decode PA<4:1> */
|
switch ((PA >> 1) & 017) { /* decode PA<4:1> */
|
||||||
case 03: /* clk csr */
|
case 03: /* clk csr */
|
||||||
if (PA & 1) return SCPE_OK;
|
if (PA & 1) return SCPE_OK;
|
||||||
if ((data & CSR_IE) == 0) int_req = int_req & ~INT_CLK;
|
if (((data & CSR_IE) == 0) || /* clr IE, DONE? */
|
||||||
|
((data & CSR_DONE) == 0)) CLR_INT (CLK); /* clr intr */
|
||||||
|
else if (((clk_csr & CSR_IE) == 0) || /* setting both */
|
||||||
|
((clk_csr & CSR_DONE) == 0)) SET_INT (CLK); /* if prv clr, intr */
|
||||||
clk_csr = (clk_csr & ~CLKCSR_RW) | (data & CLKCSR_RW);
|
clk_csr = (clk_csr & ~CLKCSR_RW) | (data & CLKCSR_RW);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
case 04: /* ptr csr */
|
case 04: /* ptr csr */
|
||||||
if (PA & 1) return SCPE_OK;
|
if (PA & 1) return SCPE_OK;
|
||||||
if ((data & CSR_IE) == 0) int_req = int_req & ~INT_PTR;
|
if ((data & CSR_IE) == 0) CLR_INT (PTR);
|
||||||
else if (((ptr_csr & CSR_IE) == 0) && (ptr_csr & (CSR_ERR | CSR_DONE)))
|
else if (((ptr_csr & CSR_IE) == 0) && (ptr_csr & (CSR_ERR | CSR_DONE)))
|
||||||
int_req = int_req | INT_PTR;
|
SET_INT (PTR);
|
||||||
if (data & CSR_GO) {
|
if (data & CSR_GO) {
|
||||||
ptr_csr = (ptr_csr & ~CSR_DONE) | CSR_BUSY;
|
ptr_csr = (ptr_csr & ~CSR_DONE) | CSR_BUSY;
|
||||||
int_req = int_req & ~INT_PTR;
|
CLR_INT (PTR);
|
||||||
if (ptr_unit.flags & UNIT_ATT) /* data to read? */
|
if (ptr_unit.flags & UNIT_ATT) /* data to read? */
|
||||||
sim_activate (&ptr_unit, ptr_unit.wait);
|
sim_activate (&ptr_unit, ptr_unit.wait);
|
||||||
else sim_activate (&ptr_unit, 0); } /* error if not */
|
else sim_activate (&ptr_unit, 0); } /* error if not */
|
||||||
|
@ -287,39 +290,39 @@ case 05: /* ptr buf */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
case 06: /* ptp csr */
|
case 06: /* ptp csr */
|
||||||
if (PA & 1) return SCPE_OK;
|
if (PA & 1) return SCPE_OK;
|
||||||
if ((data & CSR_IE) == 0) int_req = int_req & ~INT_PTP;
|
if ((data & CSR_IE) == 0) CLR_INT (PTP);
|
||||||
else if (((ptp_csr & CSR_IE) == 0) && (ptp_csr & (CSR_ERR | CSR_DONE)))
|
else if (((ptp_csr & CSR_IE) == 0) && (ptp_csr & (CSR_ERR | CSR_DONE)))
|
||||||
int_req = int_req | INT_PTP;
|
SET_INT (PTP);
|
||||||
ptp_csr = (ptp_csr & ~PTPCSR_RW) | (data & PTPCSR_RW);
|
ptp_csr = (ptp_csr & ~PTPCSR_RW) | (data & PTPCSR_RW);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
case 07: /* ptp buf */
|
case 07: /* ptp buf */
|
||||||
if ((PA & 1) == 0) ptp_unit.buf = data & 0377;
|
if ((PA & 1) == 0) ptp_unit.buf = data & 0377;
|
||||||
ptp_csr = ptp_csr & ~CSR_DONE;
|
ptp_csr = ptp_csr & ~CSR_DONE;
|
||||||
int_req = int_req & ~INT_PTP;
|
CLR_INT (PTP);
|
||||||
if (ptp_unit.flags & UNIT_ATT) /* file to write? */
|
if (ptp_unit.flags & UNIT_ATT) /* file to write? */
|
||||||
sim_activate (&ptp_unit, ptp_unit.wait);
|
sim_activate (&ptp_unit, ptp_unit.wait);
|
||||||
else sim_activate (&ptp_unit, 0); /* error if not */
|
else sim_activate (&ptp_unit, 0); /* error if not */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
case 010: /* tti csr */
|
case 010: /* tti csr */
|
||||||
if (PA & 1) return SCPE_OK;
|
if (PA & 1) return SCPE_OK;
|
||||||
if ((data & CSR_IE) == 0) int_req = int_req & ~INT_TTI;
|
if ((data & CSR_IE) == 0) CLR_INT (TTI);
|
||||||
else if ((tti_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
|
else if ((tti_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
|
||||||
int_req = int_req | INT_TTI;
|
SET_INT (TTI);
|
||||||
tti_csr = (tti_csr & ~TTICSR_RW) | (data & TTICSR_RW);
|
tti_csr = (tti_csr & ~TTICSR_RW) | (data & TTICSR_RW);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
case 011: /* tti buf */
|
case 011: /* tti buf */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
case 012: /* tto csr */
|
case 012: /* tto csr */
|
||||||
if (PA & 1) return SCPE_OK;
|
if (PA & 1) return SCPE_OK;
|
||||||
if ((data & CSR_IE) == 0) int_req = int_req & ~INT_TTO;
|
if ((data & CSR_IE) == 0) CLR_INT (TTO);
|
||||||
else if ((tto_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
|
else if ((tto_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
|
||||||
int_req = int_req | INT_TTO;
|
SET_INT (TTO);
|
||||||
tto_csr = (tto_csr & ~TTOCSR_RW) | (data & TTOCSR_RW);
|
tto_csr = (tto_csr & ~TTOCSR_RW) | (data & TTOCSR_RW);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
case 013: /* tto buf */
|
case 013: /* tto buf */
|
||||||
if ((PA & 1) == 0) tto_unit.buf = data & 0377;
|
if ((PA & 1) == 0) tto_unit.buf = data & 0377;
|
||||||
tto_csr = tto_csr & ~CSR_DONE;
|
tto_csr = tto_csr & ~CSR_DONE;
|
||||||
int_req = int_req & ~INT_TTO;
|
CLR_INT (TTO);
|
||||||
sim_activate (&tto_unit, tto_unit.wait);
|
sim_activate (&tto_unit, tto_unit.wait);
|
||||||
return SCPE_OK; } /* end switch PA */
|
return SCPE_OK; } /* end switch PA */
|
||||||
return SCPE_NXM;
|
return SCPE_NXM;
|
||||||
|
@ -338,7 +341,7 @@ t_stat ptr_svc (UNIT *uptr)
|
||||||
int32 temp;
|
int32 temp;
|
||||||
|
|
||||||
ptr_csr = (ptr_csr | CSR_ERR) & ~CSR_BUSY;
|
ptr_csr = (ptr_csr | CSR_ERR) & ~CSR_BUSY;
|
||||||
if (ptr_csr & CSR_IE) int_req = int_req | INT_PTR;
|
if (ptr_csr & CSR_IE) SET_INT (PTR);
|
||||||
if ((ptr_unit.flags & UNIT_ATT) == 0)
|
if ((ptr_unit.flags & UNIT_ATT) == 0)
|
||||||
return IORETURN (ptr_stopioe, SCPE_UNATT);
|
return IORETURN (ptr_stopioe, SCPE_UNATT);
|
||||||
if ((temp = getc (ptr_unit.fileref)) == EOF) {
|
if ((temp = getc (ptr_unit.fileref)) == EOF) {
|
||||||
|
@ -359,7 +362,7 @@ t_stat ptr_reset (DEVICE *dptr)
|
||||||
ptr_unit.buf = 0;
|
ptr_unit.buf = 0;
|
||||||
ptr_csr = 0;
|
ptr_csr = 0;
|
||||||
if ((ptr_unit.flags & UNIT_ATT) == 0) ptr_csr = ptr_csr | CSR_ERR;
|
if ((ptr_unit.flags & UNIT_ATT) == 0) ptr_csr = ptr_csr | CSR_ERR;
|
||||||
int_req = int_req & ~INT_PTR;
|
CLR_INT (PTR);
|
||||||
sim_cancel (&ptr_unit);
|
sim_cancel (&ptr_unit);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -391,7 +394,7 @@ return detach_unit (uptr);
|
||||||
t_stat ptp_svc (UNIT *uptr)
|
t_stat ptp_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
ptp_csr = ptp_csr | CSR_ERR | CSR_DONE;
|
ptp_csr = ptp_csr | CSR_ERR | CSR_DONE;
|
||||||
if (ptp_csr & CSR_IE) int_req = int_req | INT_PTP;
|
if (ptp_csr & CSR_IE) SET_INT (PTP);
|
||||||
if ((ptp_unit.flags & UNIT_ATT) == 0)
|
if ((ptp_unit.flags & UNIT_ATT) == 0)
|
||||||
return IORETURN (ptp_stopioe, SCPE_UNATT);
|
return IORETURN (ptp_stopioe, SCPE_UNATT);
|
||||||
if (putc (ptp_unit.buf, ptp_unit.fileref) == EOF) {
|
if (putc (ptp_unit.buf, ptp_unit.fileref) == EOF) {
|
||||||
|
@ -408,7 +411,7 @@ t_stat ptp_reset (DEVICE *dptr)
|
||||||
ptp_unit.buf = 0;
|
ptp_unit.buf = 0;
|
||||||
ptp_csr = CSR_DONE;
|
ptp_csr = CSR_DONE;
|
||||||
if ((ptp_unit.flags & UNIT_ATT) == 0) ptp_csr = ptp_csr | CSR_ERR;
|
if ((ptp_unit.flags & UNIT_ATT) == 0) ptp_csr = ptp_csr | CSR_ERR;
|
||||||
int_req = int_req & ~INT_PTP;
|
CLR_INT (PTP);
|
||||||
sim_cancel (&ptp_unit); /* deactivate unit */
|
sim_cancel (&ptp_unit); /* deactivate unit */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -444,7 +447,7 @@ if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */
|
||||||
tti_unit.buf = temp & 0377;
|
tti_unit.buf = temp & 0377;
|
||||||
tti_unit.pos = tti_unit.pos + 1;
|
tti_unit.pos = tti_unit.pos + 1;
|
||||||
tti_csr = tti_csr | CSR_DONE;
|
tti_csr = tti_csr | CSR_DONE;
|
||||||
if (tti_csr & CSR_IE) int_req = int_req | INT_TTI;
|
if (tti_csr & CSR_IE) SET_INT (TTI);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +455,7 @@ t_stat tti_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
tti_unit.buf = 0;
|
tti_unit.buf = 0;
|
||||||
tti_csr = 0;
|
tti_csr = 0;
|
||||||
int_req = int_req & ~INT_TTI;
|
CLR_INT (TTI);
|
||||||
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
|
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -468,7 +471,7 @@ t_stat tto_svc (UNIT *uptr)
|
||||||
int32 temp;
|
int32 temp;
|
||||||
|
|
||||||
tto_csr = tto_csr | CSR_DONE;
|
tto_csr = tto_csr | CSR_DONE;
|
||||||
if (tto_csr & CSR_IE) int_req = int_req | INT_TTO;
|
if (tto_csr & CSR_IE) SET_INT (TTO);
|
||||||
if ((temp = sim_putchar (tto_unit.buf & 0177)) != SCPE_OK) return temp;
|
if ((temp = sim_putchar (tto_unit.buf & 0177)) != SCPE_OK) return temp;
|
||||||
tto_unit.pos = tto_unit.pos + 1;
|
tto_unit.pos = tto_unit.pos + 1;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
@ -478,7 +481,7 @@ t_stat tto_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
tto_unit.buf = 0;
|
tto_unit.buf = 0;
|
||||||
tto_csr = CSR_DONE;
|
tto_csr = CSR_DONE;
|
||||||
int_req = int_req & ~INT_TTO;
|
CLR_INT (TTO);
|
||||||
sim_cancel (&tto_unit); /* deactivate unit */
|
sim_cancel (&tto_unit); /* deactivate unit */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -493,18 +496,19 @@ t_stat clk_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
int32 t;
|
int32 t;
|
||||||
|
|
||||||
if (clk_csr & CSR_IE) int_req = int_req | INT_CLK;
|
clk_csr = clk_csr | CSR_DONE; /* set done */
|
||||||
|
if (clk_csr & CSR_IE) SET_INT (CLK);
|
||||||
t = sim_rtc_calb (clk_tps); /* calibrate clock */
|
t = sim_rtc_calb (clk_tps); /* calibrate clock */
|
||||||
sim_activate (&clk_unit, t); /* reactivate unit */
|
sim_activate (&clk_unit, t); /* reactivate unit */
|
||||||
dz_poll = t; /* set DZ poll */
|
tmxr_poll = t; /* set mux poll */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat clk_reset (DEVICE *dptr)
|
t_stat clk_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
clk_csr = 0;
|
clk_csr = 0;
|
||||||
int_req = int_req & ~INT_CLK;
|
CLR_INT (CLK);
|
||||||
sim_activate (&clk_unit, clk_unit.wait); /* activate unit */
|
sim_activate (&clk_unit, clk_unit.wait); /* activate unit */
|
||||||
dz_poll = clk_unit.wait; /* set DZ poll */
|
tmxr_poll = clk_unit.wait; /* set mux poll */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
17-Sep-01 RMS Removed multiconsole support
|
||||||
|
26-Aug-01 RMS Added DZ11
|
||||||
20-Aug-01 RMS Updated bad block inquiry
|
20-Aug-01 RMS Updated bad block inquiry
|
||||||
17-Jul-01 RMS Fixed warning from VC++ 6.0
|
17-Jul-01 RMS Fixed warning from VC++ 6.0
|
||||||
27-May-01 RMS Added multiconsole support
|
27-May-01 RMS Added multiconsole support
|
||||||
|
@ -45,6 +47,7 @@ extern DEVICE cpu_dev;
|
||||||
extern DEVICE ptr_dev, ptp_dev;
|
extern DEVICE ptr_dev, ptp_dev;
|
||||||
extern DEVICE tti_dev, tto_dev;
|
extern DEVICE tti_dev, tto_dev;
|
||||||
extern DEVICE lpt_dev, clk_dev;
|
extern DEVICE lpt_dev, clk_dev;
|
||||||
|
extern DEVICE dz_dev;
|
||||||
extern DEVICE rk_dev, rx_dev;
|
extern DEVICE rk_dev, rx_dev;
|
||||||
extern DEVICE rl_dev, rp_dev;
|
extern DEVICE rl_dev, rp_dev;
|
||||||
extern DEVICE dt_dev, tm_dev;
|
extern DEVICE dt_dev, tm_dev;
|
||||||
|
@ -61,7 +64,6 @@ extern int32 saved_PC;
|
||||||
sim_PC pointer to saved PC register descriptor
|
sim_PC pointer to saved PC register descriptor
|
||||||
sim_emax number of words for examine
|
sim_emax number of words for examine
|
||||||
sim_devices array of pointers to simulated devices
|
sim_devices array of pointers to simulated devices
|
||||||
sim_consoles array of pointers to consoles (if more than one)
|
|
||||||
sim_stop_messages array of pointers to stop messages
|
sim_stop_messages array of pointers to stop messages
|
||||||
sim_load binary loader
|
sim_load binary loader
|
||||||
*/
|
*/
|
||||||
|
@ -77,14 +79,13 @@ DEVICE *sim_devices[] = {
|
||||||
&ptr_dev, &ptp_dev,
|
&ptr_dev, &ptp_dev,
|
||||||
&tti_dev, &tto_dev,
|
&tti_dev, &tto_dev,
|
||||||
&lpt_dev, &clk_dev,
|
&lpt_dev, &clk_dev,
|
||||||
|
&dz_dev,
|
||||||
&rk_dev, /* &hk_dev, */
|
&rk_dev, /* &hk_dev, */
|
||||||
&rl_dev, &rp_dev,
|
&rl_dev, &rp_dev,
|
||||||
&rx_dev, &dt_dev,
|
&rx_dev, &dt_dev,
|
||||||
&tm_dev, &ts_dev,
|
&tm_dev, &ts_dev,
|
||||||
NULL };
|
NULL };
|
||||||
|
|
||||||
UNIT *sim_consoles = NULL;
|
|
||||||
|
|
||||||
const char *sim_stop_messages[] = {
|
const char *sim_stop_messages[] = {
|
||||||
"Unknown error",
|
"Unknown error",
|
||||||
"Red stack trap",
|
"Red stack trap",
|
||||||
|
@ -317,7 +318,7 @@ static const char *opcode[] = {
|
||||||
"SOB",
|
"SOB",
|
||||||
"BPL","BMI","BHI","BLOS",
|
"BPL","BMI","BHI","BLOS",
|
||||||
"BVC","BVS","BCC","BCS",
|
"BVC","BVS","BCC","BCS",
|
||||||
"BHIS","BLO", /* encode only */
|
"BHIS","BLO", /* encode only */
|
||||||
"EMT","TRAP",
|
"EMT","TRAP",
|
||||||
"CLRB","COMB","INCB","DECB",
|
"CLRB","COMB","INCB","DECB",
|
||||||
"NEGB","ADCB","SBCB","TSTB",
|
"NEGB","ADCB","SBCB","TSTB",
|
||||||
|
|
62
pdp11_tc.c
62
pdp11_tc.c
|
@ -25,6 +25,10 @@
|
||||||
|
|
||||||
tc TC11/TU56 DECtape
|
tc TC11/TU56 DECtape
|
||||||
|
|
||||||
|
15-Sep-01 RMS Integrated debug logging
|
||||||
|
27-Sep-01 RMS Fixed interrupt after stop for RSTS/E
|
||||||
|
07-Sep-01 RMS Revised device disable and interrupt mechanisms
|
||||||
|
29-Aug-01 RMS Added casts to PDP-8 unpack routine
|
||||||
17-Jul-01 RMS Moved function prototype
|
17-Jul-01 RMS Moved function prototype
|
||||||
11-May-01 RMS Fixed bug in reset
|
11-May-01 RMS Fixed bug in reset
|
||||||
26-Apr-01 RMS Added device enable/disable support
|
26-Apr-01 RMS Added device enable/disable support
|
||||||
|
@ -228,27 +232,30 @@
|
||||||
#define LOG_BL 010 /* block # lblk */
|
#define LOG_BL 010 /* block # lblk */
|
||||||
|
|
||||||
#define DT_SETDONE tccm = tccm | CSR_DONE; \
|
#define DT_SETDONE tccm = tccm | CSR_DONE; \
|
||||||
if (tccm & CSR_IE) int_req = int_req | INT_DTA
|
if (tccm & CSR_IE) SET_INT (DTA)
|
||||||
#define DT_CLRDONE tccm = tccm & ~CSR_DONE; \
|
#define DT_CLRDONE tccm = tccm & ~CSR_DONE; \
|
||||||
int_req = int_req & ~INT_DTA
|
CLR_INT (DTA)
|
||||||
#define ABS(x) (((x) < 0)? (-(x)): (x))
|
#define ABS(x) (((x) < 0)? (-(x)): (x))
|
||||||
|
|
||||||
extern uint16 *M; /* memory */
|
extern uint16 *M; /* memory */
|
||||||
extern int32 int_req, dev_enb;
|
extern int32 int_req[IPL_HLVL];
|
||||||
extern UNIT cpu_unit;
|
extern UNIT cpu_unit;
|
||||||
extern int32 sim_switches;
|
extern int32 sim_switches;
|
||||||
|
extern int32 pdp11_log;
|
||||||
|
extern FILE *sim_log;
|
||||||
int32 tcst = 0; /* status */
|
int32 tcst = 0; /* status */
|
||||||
int32 tccm = 0; /* command */
|
int32 tccm = 0; /* command */
|
||||||
int32 tcwc = 0; /* word count */
|
int32 tcwc = 0; /* word count */
|
||||||
int32 tcba = 0; /* bus address */
|
int32 tcba = 0; /* bus address */
|
||||||
int32 tcdt = 0; /* data */
|
int32 tcdt = 0; /* data */
|
||||||
int32 dt_ctime = 4; /* fast cmd time */
|
int32 dt_ctime = 100; /* fast cmd time */
|
||||||
int32 dt_ltime = 12; /* interline time */
|
int32 dt_ltime = 12; /* interline time */
|
||||||
int32 dt_actime = 54000; /* accel time */
|
int32 dt_actime = 54000; /* accel time */
|
||||||
int32 dt_dctime = 72000; /* decel time */
|
int32 dt_dctime = 72000; /* decel time */
|
||||||
int32 dt_substate = 0;
|
int32 dt_substate = 0;
|
||||||
int32 dt_log = 0;
|
|
||||||
int32 dt_logblk = 0;
|
int32 dt_logblk = 0;
|
||||||
|
int32 dt_enb = 1; /* device enable */
|
||||||
|
|
||||||
t_stat dt_svc (UNIT *uptr);
|
t_stat dt_svc (UNIT *uptr);
|
||||||
t_stat dt_svcdone (UNIT *uptr);
|
t_stat dt_svcdone (UNIT *uptr);
|
||||||
t_stat dt_reset (DEVICE *dptr);
|
t_stat dt_reset (DEVICE *dptr);
|
||||||
|
@ -294,7 +301,7 @@ REG dt_reg[] = {
|
||||||
{ ORDATA (TCWC, tcwc, 16) },
|
{ ORDATA (TCWC, tcwc, 16) },
|
||||||
{ ORDATA (TCBA, tcba, 16) },
|
{ ORDATA (TCBA, tcba, 16) },
|
||||||
{ ORDATA (TCDT, tcdt, 16) },
|
{ ORDATA (TCDT, tcdt, 16) },
|
||||||
{ FLDATA (INT, int_req, INT_V_DTA) },
|
{ FLDATA (INT, IREQ (DTA), INT_V_DTA) },
|
||||||
{ FLDATA (ERR, tccm, CSR_V_ERR) },
|
{ FLDATA (ERR, tccm, CSR_V_ERR) },
|
||||||
{ FLDATA (DONE, tccm, CSR_V_DONE) },
|
{ FLDATA (DONE, tccm, CSR_V_DONE) },
|
||||||
{ FLDATA (IE, tccm, CSR_V_DONE) },
|
{ FLDATA (IE, tccm, CSR_V_DONE) },
|
||||||
|
@ -303,7 +310,6 @@ REG dt_reg[] = {
|
||||||
{ DRDATA (ACTIME, dt_actime, 31), REG_NZ },
|
{ DRDATA (ACTIME, dt_actime, 31), REG_NZ },
|
||||||
{ DRDATA (DCTIME, dt_dctime, 31), REG_NZ },
|
{ DRDATA (DCTIME, dt_dctime, 31), REG_NZ },
|
||||||
{ ORDATA (SUBSTATE, dt_substate, 1) },
|
{ ORDATA (SUBSTATE, dt_substate, 1) },
|
||||||
{ ORDATA (LOG, dt_log, 4), REG_HIDDEN },
|
|
||||||
{ DRDATA (LBLK, dt_logblk, 12), REG_HIDDEN },
|
{ DRDATA (LBLK, dt_logblk, 12), REG_HIDDEN },
|
||||||
{ DRDATA (POS0, dt_unit[0].pos, 31), PV_LEFT + REG_RO },
|
{ DRDATA (POS0, dt_unit[0].pos, 31), PV_LEFT + REG_RO },
|
||||||
{ DRDATA (POS1, dt_unit[1].pos, 31), PV_LEFT + REG_RO },
|
{ DRDATA (POS1, dt_unit[1].pos, 31), PV_LEFT + REG_RO },
|
||||||
|
@ -345,7 +351,7 @@ REG dt_reg[] = {
|
||||||
REG_HRO },
|
REG_HRO },
|
||||||
{ GRDATA (FLG7, dt_unit[7].flags, 8, UNIT_W_UF, UNIT_V_UF - 1),
|
{ GRDATA (FLG7, dt_unit[7].flags, 8, UNIT_W_UF, UNIT_V_UF - 1),
|
||||||
REG_HRO },
|
REG_HRO },
|
||||||
{ FLDATA (*DEVENB, dev_enb, INT_V_DTA), REG_HRO },
|
{ FLDATA (*DEVENB, dt_enb, 0), REG_HRO },
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB dt_mod[] = {
|
MTAB dt_mod[] = {
|
||||||
|
@ -411,14 +417,14 @@ case 001: /* TCCM */
|
||||||
old_tccm = tccm; /* save prior */
|
old_tccm = tccm; /* save prior */
|
||||||
if (access == WRITEB) data = (PA & 1)?
|
if (access == WRITEB) data = (PA & 1)?
|
||||||
(tccm & 0377) | (data << 8): (tccm & ~0377) | data;
|
(tccm & 0377) | (data << 8): (tccm & ~0377) | data;
|
||||||
if ((data & CSR_IE) == 0) int_req = int_req & ~INT_DTA;
|
if ((data & CSR_IE) == 0) CLR_INT (DTA);
|
||||||
else if ((((tccm & CSR_IE) == 0) && (tccm & CSR_DONE)) ||
|
else if ((((tccm & CSR_IE) == 0) && (tccm & CSR_DONE)) ||
|
||||||
(data & CSR_DONE)) int_req = int_req | INT_DTA;
|
(data & CSR_DONE)) SET_INT (DTA);
|
||||||
tccm = (tccm & ~CSR_RW) | (data & CSR_RW);
|
tccm = (tccm & ~CSR_RW) | (data & CSR_RW);
|
||||||
if ((data & CSR_GO) && (tccm & CSR_DONE)) { /* new cmd? */
|
if ((data & CSR_GO) && (tccm & CSR_DONE)) { /* new cmd? */
|
||||||
tcst = tcst & ~STA_ALLERR; /* clear errors */
|
tcst = tcst & ~STA_ALLERR; /* clear errors */
|
||||||
tccm = tccm & ~(CSR_ERR | CSR_DONE); /* clear done, err */
|
tccm = tccm & ~(CSR_ERR | CSR_DONE); /* clear done, err */
|
||||||
int_req = int_req & ~INT_DTA; /* clear int */
|
CLR_INT (DTA); /* clear int */
|
||||||
if ((old_tccm ^ tccm) & CSR_UNIT) dt_deselect (old_tccm);
|
if ((old_tccm ^ tccm) & CSR_UNIT) dt_deselect (old_tccm);
|
||||||
unum = CSR_GETUNIT (tccm); /* get drive */
|
unum = CSR_GETUNIT (tccm); /* get drive */
|
||||||
fnc = CSR_GETFNC (tccm); /* get function */
|
fnc = CSR_GETFNC (tccm); /* get function */
|
||||||
|
@ -581,8 +587,8 @@ case FNC_SRCH: /* search */
|
||||||
DTU_TSIZE (uptr): blk), uptr) - DT_BLKLN - DT_WSIZE;
|
DTU_TSIZE (uptr): blk), uptr) - DT_BLKLN - DT_WSIZE;
|
||||||
else newpos = DT_BLK2LN ((DT_QREZ (uptr)?
|
else newpos = DT_BLK2LN ((DT_QREZ (uptr)?
|
||||||
0: blk + 1), uptr) + DT_BLKLN + (DT_WSIZE - 1);
|
0: blk + 1), uptr) + DT_BLKLN + (DT_WSIZE - 1);
|
||||||
if (dt_log & LOG_MS) printf ("[DT%d: searching %s]\n", unum,
|
if (DBG_LOG (LOG_TC_MS)) fprintf (sim_log, ">>DT%d: searching %s\n",
|
||||||
(dir? "backward": "forward"));
|
unum, (dir? "backward": "forward"));
|
||||||
break;
|
break;
|
||||||
case FNC_WRIT: /* write */
|
case FNC_WRIT: /* write */
|
||||||
case FNC_READ: /* read */
|
case FNC_READ: /* read */
|
||||||
|
@ -599,8 +605,8 @@ case FNC_READ: /* read */
|
||||||
blk + 1: blk), uptr) - DT_HTLIN - DT_WSIZE;
|
blk + 1: blk), uptr) - DT_HTLIN - DT_WSIZE;
|
||||||
else newpos = DT_BLK2LN (((relpos < DT_HTLIN)?
|
else newpos = DT_BLK2LN (((relpos < DT_HTLIN)?
|
||||||
blk: blk + 1), uptr) + DT_HTLIN + (DT_WSIZE - 1);
|
blk: blk + 1), uptr) + DT_HTLIN + (DT_WSIZE - 1);
|
||||||
if ((dt_log & LOG_RW) || ((dt_log & LOG_BL) && (blk == dt_logblk)))
|
if (DBG_LOG (LOG_TC_RW) || (DBG_LOG (LOG_TC_BL) && (blk == dt_logblk)))
|
||||||
printf ("[DT%d: %s block %d %s]\n",
|
fprintf (sim_log, ">>DT%d: %s block %d %s\n",
|
||||||
unum, ((fnc == FNC_READ)? "read": "write"),
|
unum, ((fnc == FNC_READ)? "read": "write"),
|
||||||
blk, (dir? "backward": "forward"));
|
blk, (dir? "backward": "forward"));
|
||||||
break;
|
break;
|
||||||
|
@ -618,8 +624,8 @@ case FNC_WALL: /* write all */
|
||||||
else newpos = DT_BLK2LN (blk, uptr) + DT_CSMLN + (DT_WSIZE - 1); }
|
else newpos = DT_BLK2LN (blk, uptr) + DT_CSMLN + (DT_WSIZE - 1); }
|
||||||
if (fnc == FNC_WALL) sim_activate /* write all? */
|
if (fnc == FNC_WALL) sim_activate /* write all? */
|
||||||
(&dt_dev.units[DT_TIMER], dt_ctime); /* sched done */
|
(&dt_dev.units[DT_TIMER], dt_ctime); /* sched done */
|
||||||
if ((dt_log & LOG_RA) || ((dt_log & LOG_BL) && (blk == dt_logblk)))
|
if (DBG_LOG (LOG_TC_RW) || (DBG_LOG (LOG_TC_BL) && (blk == dt_logblk)))
|
||||||
printf ("[DT%d: read all block %d %s]\n",
|
fprintf (sim_log, ">>DT%d: read all block %d %s\n",
|
||||||
unum, blk, (dir? "backward": "forward"));
|
unum, blk, (dir? "backward": "forward"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -685,11 +691,11 @@ if ((uptr -> pos < 0) ||
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Command timer service after stop - set done but not interrupt */
|
/* Command timer service after stop - set done */
|
||||||
|
|
||||||
t_stat dt_svcdone (UNIT *uptr)
|
t_stat dt_svcdone (UNIT *uptr)
|
||||||
{
|
{
|
||||||
tccm = tccm | CSR_DONE;
|
DT_SETDONE;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -932,7 +938,7 @@ int32 ba = blk * DTU_BSIZE (uptr);
|
||||||
int32 i, csum, wrd;
|
int32 i, csum, wrd;
|
||||||
|
|
||||||
csum = 077; /* init csum */
|
csum = 077; /* init csum */
|
||||||
for (i = 0; i < DTU_BSIZE (uptr); i++) { /* loop thru buf */
|
for (i = 0; i < DTU_BSIZE (uptr); i++) { /* loop thru buf */
|
||||||
wrd = bptr[ba + i] ^ 0777777; /* get ~word */
|
wrd = bptr[ba + i] ^ 0777777; /* get ~word */
|
||||||
csum = csum ^ (wrd >> 12) ^ (wrd >> 6) ^ wrd; }
|
csum = csum ^ (wrd >> 12) ^ (wrd >> 6) ^ wrd; }
|
||||||
return (csum & 077);
|
return (csum & 077);
|
||||||
|
@ -974,14 +980,14 @@ for (i = 0; i < DT_NUMDR; i++) { /* stop all activity */
|
||||||
uptr -> LASTT = sim_grtime (); } }
|
uptr -> LASTT = sim_grtime (); } }
|
||||||
tcst = tcwc = tcba = tcdt = 0; /* clear reg */
|
tcst = tcwc = tcba = tcdt = 0; /* clear reg */
|
||||||
tccm = CSR_DONE;
|
tccm = CSR_DONE;
|
||||||
int_req = int_req & ~INT_DTA; /* clear int req */
|
CLR_INT (DTA); /* clear int req */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Device bootstrap */
|
/* Device bootstrap */
|
||||||
|
|
||||||
#define BOOT_START 02000 /* start */
|
#define BOOT_START 02000 /* start */
|
||||||
#define BOOT_UNIT 02006 /* where to store unit number */
|
#define BOOT_UNIT 02006 /* unit number */
|
||||||
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int32))
|
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int32))
|
||||||
|
|
||||||
static const int32 boot_rom[] = {
|
static const int32 boot_rom[] = {
|
||||||
|
@ -1064,7 +1070,7 @@ uptr -> filebuf = calloc (uptr -> capac, sizeof (int32));
|
||||||
if (uptr -> filebuf == NULL) { /* can't alloc? */
|
if (uptr -> filebuf == NULL) { /* can't alloc? */
|
||||||
detach_unit (uptr);
|
detach_unit (uptr);
|
||||||
return SCPE_MEM; }
|
return SCPE_MEM; }
|
||||||
printf ("%TC: buffering file in memory\n");
|
printf ("TC: buffering file in memory\n");
|
||||||
rewind (uptr -> fileref); /* start of file */
|
rewind (uptr -> fileref); /* start of file */
|
||||||
if (uptr -> flags & UNIT_8FMT) { /* PDP-8? */
|
if (uptr -> flags & UNIT_8FMT) { /* PDP-8? */
|
||||||
bptr = uptr -> filebuf; /* file buffer */
|
bptr = uptr -> filebuf; /* file buffer */
|
||||||
|
@ -1073,10 +1079,10 @@ if (uptr -> flags & UNIT_8FMT) { /* PDP-8? */
|
||||||
if (k == 0) break;
|
if (k == 0) break;
|
||||||
for ( ; k < D8_NBSIZE; k++) pdp8b[k] = 0;
|
for ( ; k < D8_NBSIZE; k++) pdp8b[k] = 0;
|
||||||
for (k = 0; k < D8_NBSIZE; k = k + 3) { /* loop thru blk */
|
for (k = 0; k < D8_NBSIZE; k = k + 3) { /* loop thru blk */
|
||||||
bptr[ba] = ((pdp8b[k] & 07777) << 6) |
|
bptr[ba] = ((uint32) (pdp8b[k] & 07777) << 6) |
|
||||||
((pdp8b[k + 1] >> 6) & 077);
|
((uint32) (pdp8b[k + 1] >> 6) & 077);
|
||||||
bptr[ba + 1] = ((pdp8b[k + 1] & 077) << 12) |
|
bptr[ba + 1] = ((pdp8b[k + 1] & 077) << 12) |
|
||||||
(pdp8b[k + 2] & 07777);
|
((uint32) (pdp8b[k + 2] & 07777));
|
||||||
ba = ba + 2; } /* end blk loop */
|
ba = ba + 2; } /* end blk loop */
|
||||||
} /* end file loop */
|
} /* end file loop */
|
||||||
uptr -> hwmark = ba; } /* end if */
|
uptr -> hwmark = ba; } /* end if */
|
||||||
|
@ -1109,7 +1115,7 @@ if (sim_is_active (uptr)) { /* active? cancel op */
|
||||||
if ((unum == CSR_GETUNIT (tccm)) && ((tccm & CSR_DONE) == 0)) {
|
if ((unum == CSR_GETUNIT (tccm)) && ((tccm & CSR_DONE) == 0)) {
|
||||||
tcst = tcst | STA_SEL;
|
tcst = tcst | STA_SEL;
|
||||||
tccm = tccm | CSR_ERR | CSR_DONE;
|
tccm = tccm | CSR_ERR | CSR_DONE;
|
||||||
if (tccm & CSR_IE) int_req = int_req | INT_DTA; }
|
if (tccm & CSR_IE) SET_INT (DTA); }
|
||||||
uptr -> STATE = uptr -> pos = 0; }
|
uptr -> STATE = uptr -> pos = 0; }
|
||||||
if (uptr -> hwmark) { /* any data? */
|
if (uptr -> hwmark) { /* any data? */
|
||||||
printf ("TC: writing buffer to file\n");
|
printf ("TC: writing buffer to file\n");
|
||||||
|
|
65
pdp11_tm.c
65
pdp11_tm.c
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
tm TM11/TU10 magtape
|
tm TM11/TU10 magtape
|
||||||
|
|
||||||
|
18-Oct-01 RMS Added stub diagnostic register (found by Thord Nilson)
|
||||||
|
07-Sep-01 RMS Revised device disable and interrupt mechanisms
|
||||||
26-Apr-01 RMS Added device enable/disable support
|
26-Apr-01 RMS Added device enable/disable support
|
||||||
18-Apr-01 RMS Changed to rewind tape before boot
|
18-Apr-01 RMS Changed to rewind tape before boot
|
||||||
14-Apr-99 RMS Changed t_addr to unsigned
|
14-Apr-99 RMS Changed t_addr to unsigned
|
||||||
|
@ -124,17 +126,24 @@
|
||||||
#define STA_EFLGS (STA_ILL | STA_EOF | STA_CRC | STA_PAR | \
|
#define STA_EFLGS (STA_ILL | STA_EOF | STA_CRC | STA_PAR | \
|
||||||
STA_DLT | STA_EOT | STA_RLE | STA_BAD | STA_NXM)
|
STA_DLT | STA_EOT | STA_RLE | STA_BAD | STA_NXM)
|
||||||
/* set error */
|
/* set error */
|
||||||
|
|
||||||
|
/* Read lines - tm_rdl */
|
||||||
|
|
||||||
|
#define RDL_CLK 0100000 /* 10 Khz clock */
|
||||||
|
|
||||||
extern uint16 *M; /* memory */
|
extern uint16 *M; /* memory */
|
||||||
extern int32 int_req, dev_enb;
|
extern int32 int_req[IPL_HLVL];
|
||||||
extern UNIT cpu_unit;
|
extern UNIT cpu_unit;
|
||||||
int32 tm_sta = 0; /* status register */
|
int32 tm_sta = 0; /* status register */
|
||||||
int32 tm_cmd = 0; /* command register */
|
int32 tm_cmd = 0; /* command register */
|
||||||
int32 tm_ca = 0; /* current address */
|
int32 tm_ca = 0; /* current address */
|
||||||
int32 tm_bc = 0; /* byte count */
|
int32 tm_bc = 0; /* byte count */
|
||||||
int32 tm_db = 0; /* data buffer */
|
int32 tm_db = 0; /* data buffer */
|
||||||
|
int32 tm_rdl = 0; /* read lines */
|
||||||
int32 tm_time = 10; /* record latency */
|
int32 tm_time = 10; /* record latency */
|
||||||
int32 tm_stopioe = 1; /* stop on error */
|
int32 tm_stopioe = 1; /* stop on error */
|
||||||
|
int32 tm_enb = 1; /* device enable */
|
||||||
|
|
||||||
t_stat tm_svc (UNIT *uptr);
|
t_stat tm_svc (UNIT *uptr);
|
||||||
t_stat tm_reset (DEVICE *dptr);
|
t_stat tm_reset (DEVICE *dptr);
|
||||||
t_stat tm_attach (UNIT *uptr, char *cptr);
|
t_stat tm_attach (UNIT *uptr, char *cptr);
|
||||||
|
@ -169,7 +178,8 @@ REG tm_reg[] = {
|
||||||
{ ORDATA (MTBRC, tm_bc, 16) },
|
{ ORDATA (MTBRC, tm_bc, 16) },
|
||||||
{ ORDATA (MTCMA, tm_ca, 16) },
|
{ ORDATA (MTCMA, tm_ca, 16) },
|
||||||
{ ORDATA (MTD, tm_db, 8) },
|
{ ORDATA (MTD, tm_db, 8) },
|
||||||
{ FLDATA (INT, int_req, INT_V_TM) },
|
{ ORDATA (MTRD, tm_rdl, 16) },
|
||||||
|
{ FLDATA (INT, IREQ (TM), INT_V_TM) },
|
||||||
{ FLDATA (ERR, tm_cmd, CSR_V_ERR) },
|
{ FLDATA (ERR, tm_cmd, CSR_V_ERR) },
|
||||||
{ FLDATA (DONE, tm_cmd, CSR_V_DONE) },
|
{ FLDATA (DONE, tm_cmd, CSR_V_DONE) },
|
||||||
{ FLDATA (IE, tm_cmd, CSR_V_IE) },
|
{ FLDATA (IE, tm_cmd, CSR_V_IE) },
|
||||||
|
@ -207,7 +217,7 @@ REG tm_reg[] = {
|
||||||
REG_HRO },
|
REG_HRO },
|
||||||
{ GRDATA (FLG7, tm_unit[7].flags, 8, UNIT_W_UF, UNIT_V_UF - 1),
|
{ GRDATA (FLG7, tm_unit[7].flags, 8, UNIT_W_UF, UNIT_V_UF - 1),
|
||||||
REG_HRO },
|
REG_HRO },
|
||||||
{ FLDATA (*DEVENB, dev_enb, INT_V_TM), REG_HRO },
|
{ FLDATA (*DEVENB, tm_enb, 0), REG_HRO },
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB tm_mod[] = {
|
MTAB tm_mod[] = {
|
||||||
|
@ -229,7 +239,7 @@ DEVICE tm_dev = {
|
||||||
17772524 MTBRC read/write
|
17772524 MTBRC read/write
|
||||||
17772526 MTCMA read/write
|
17772526 MTCMA read/write
|
||||||
17772530 MTD read/write
|
17772530 MTD read/write
|
||||||
17772532 MTRD unimplemented
|
17772532 MTRD read only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t_stat tm_rd (int32 *data, int32 PA, int32 access)
|
t_stat tm_rd (int32 *data, int32 PA, int32 access)
|
||||||
|
@ -240,23 +250,28 @@ uptr = tm_dev.units + GET_UNIT (tm_cmd); /* get unit */
|
||||||
switch ((PA >> 1) & 07) { /* decode PA<3:1> */
|
switch ((PA >> 1) & 07) { /* decode PA<3:1> */
|
||||||
case 0: /* MTS */
|
case 0: /* MTS */
|
||||||
*data = tm_updcsta (uptr); /* update status */
|
*data = tm_updcsta (uptr); /* update status */
|
||||||
return SCPE_OK;
|
break;
|
||||||
case 1: /* MTC */
|
case 1: /* MTC */
|
||||||
tm_updcsta (uptr); /* update status */
|
tm_updcsta (uptr); /* update status */
|
||||||
*data = tm_cmd; /* return command */
|
*data = tm_cmd; /* return command */
|
||||||
return SCPE_OK;
|
break;
|
||||||
case 2: /* MTBRC */
|
case 2: /* MTBRC */
|
||||||
*data = tm_bc; /* return byte count */
|
*data = tm_bc; /* return byte count */
|
||||||
return SCPE_OK;
|
break;
|
||||||
case 3: /* MTCMA */
|
case 3: /* MTCMA */
|
||||||
*data = tm_ca; /* return mem addr */
|
*data = tm_ca; /* return mem addr */
|
||||||
return SCPE_OK;
|
break;
|
||||||
case 4: /* MTD */
|
case 4: /* MTD */
|
||||||
*data = tm_db; /* return data buffer */
|
*data = tm_db; /* return data buffer */
|
||||||
return SCPE_OK;
|
break;
|
||||||
|
case 5: /* MTRD */
|
||||||
|
tm_rdl = tm_rdl ^ RDL_CLK; /* "clock" ticks */
|
||||||
|
*data = tm_rdl;
|
||||||
|
break;
|
||||||
default: /* unimplemented */
|
default: /* unimplemented */
|
||||||
*data = 0;
|
*data = 0;
|
||||||
return SCPE_OK; }
|
break; }
|
||||||
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat tm_wr (int32 data, int32 PA, int32 access)
|
t_stat tm_wr (int32 data, int32 PA, int32 access)
|
||||||
|
@ -265,7 +280,7 @@ UNIT *uptr;
|
||||||
|
|
||||||
switch ((PA >> 1) & 07) { /* decode PA<3:1> */
|
switch ((PA >> 1) & 07) { /* decode PA<3:1> */
|
||||||
case 0: /* MTS: read only */
|
case 0: /* MTS: read only */
|
||||||
return SCPE_OK;
|
break;
|
||||||
case 1: /* MTC */
|
case 1: /* MTC */
|
||||||
uptr = tm_dev.units + GET_UNIT (tm_cmd); /* select unit */
|
uptr = tm_dev.units + GET_UNIT (tm_cmd); /* select unit */
|
||||||
if ((tm_cmd & MTC_DONE) == 0) tm_sta = tm_sta | STA_ILL;
|
if ((tm_cmd & MTC_DONE) == 0) tm_sta = tm_sta | STA_ILL;
|
||||||
|
@ -276,30 +291,29 @@ case 1: /* MTC */
|
||||||
tm_reset (&tm_dev); /* reset device */
|
tm_reset (&tm_dev); /* reset device */
|
||||||
return SCPE_OK; }
|
return SCPE_OK; }
|
||||||
if ((data & MTC_IE) == 0) /* int disable? */
|
if ((data & MTC_IE) == 0) /* int disable? */
|
||||||
int_req = int_req & ~INT_TM; /* clr int request */
|
CLR_INT (TM); /* clr int request */
|
||||||
else if ((tm_cmd & (MTC_ERR + MTC_DONE)) && !(tm_cmd & MTC_IE))
|
else if ((tm_cmd & (MTC_ERR + MTC_DONE)) && !(tm_cmd & MTC_IE))
|
||||||
int_req = int_req | INT_TM; /* set int request */
|
SET_INT (TM); /* set int request */
|
||||||
tm_cmd = (tm_cmd & ~MTC_RW) | (data & MTC_RW);
|
tm_cmd = (tm_cmd & ~MTC_RW) | (data & MTC_RW);
|
||||||
uptr = tm_dev.units + GET_UNIT (tm_cmd); /* new unit */
|
uptr = tm_dev.units + GET_UNIT (tm_cmd); /* new unit */
|
||||||
if (data & MTC_GO) tm_go (uptr); } /* new function? */
|
if (data & MTC_GO) tm_go (uptr); } /* new function? */
|
||||||
tm_updcsta (uptr); /* update status */
|
tm_updcsta (uptr); /* update status */
|
||||||
return SCPE_OK;
|
break;
|
||||||
case 2: /* MTBRC */
|
case 2: /* MTBRC */
|
||||||
if (access == WRITEB) data = (PA & 1)?
|
if (access == WRITEB) data = (PA & 1)?
|
||||||
(tm_bc & 0377) | (data << 8): (tm_bc & ~0377) | data;
|
(tm_bc & 0377) | (data << 8): (tm_bc & ~0377) | data;
|
||||||
tm_bc = data;
|
tm_bc = data;
|
||||||
return SCPE_OK;
|
break;
|
||||||
case 3: /* MTCMA */
|
case 3: /* MTCMA */
|
||||||
if (access == WRITEB) data = (PA & 1)?
|
if (access == WRITEB) data = (PA & 1)?
|
||||||
(tm_ca & 0377) | (data << 8): (tm_ca & ~0377) | data;
|
(tm_ca & 0377) | (data << 8): (tm_ca & ~0377) | data;
|
||||||
tm_ca = data;
|
tm_ca = data;
|
||||||
return SCPE_OK;
|
break;
|
||||||
case 4: /* MTD */
|
case 4: /* MTD */
|
||||||
if ((access == WRITEB) && (PA & 1)) return SCPE_OK;
|
if ((access == WRITEB) && (PA & 1)) return SCPE_OK;
|
||||||
tm_db = data & 0377;
|
tm_db = data & 0377;
|
||||||
return SCPE_OK;
|
break; } /* end switch */
|
||||||
default:
|
return SCPE_OK;
|
||||||
return SCPE_OK; } /* end switch */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* New magtape command */
|
/* New magtape command */
|
||||||
|
@ -325,7 +339,7 @@ else if (f == MTC_REWIND) /* rewind */
|
||||||
uptr -> USTAT = uptr -> USTAT | STA_REW; /* rewinding */
|
uptr -> USTAT = uptr -> USTAT | STA_REW; /* rewinding */
|
||||||
/* else /* uncomment this else if rewind/unload don't set done */
|
/* else /* uncomment this else if rewind/unload don't set done */
|
||||||
tm_cmd = tm_cmd & ~MTC_DONE; /* clear done */
|
tm_cmd = tm_cmd & ~MTC_DONE; /* clear done */
|
||||||
int_req = int_req & ~INT_TM; /* clear int */
|
CLR_INT (TM); /* clear int */
|
||||||
sim_activate (uptr, tm_time); /* start io */
|
sim_activate (uptr, tm_time); /* start io */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -501,7 +515,7 @@ if (sim_is_active (uptr)) tm_sta = tm_sta & ~STA_TUR;
|
||||||
else tm_sta = tm_sta | STA_TUR;
|
else tm_sta = tm_sta | STA_TUR;
|
||||||
if (tm_sta & STA_EFLGS) tm_cmd = tm_cmd | MTC_ERR;
|
if (tm_sta & STA_EFLGS) tm_cmd = tm_cmd | MTC_ERR;
|
||||||
else tm_cmd = tm_cmd & ~MTC_ERR;
|
else tm_cmd = tm_cmd & ~MTC_ERR;
|
||||||
if ((tm_cmd & MTC_IE) == 0) int_req = int_req & ~INT_TM;
|
if ((tm_cmd & MTC_IE) == 0) CLR_INT (TM);
|
||||||
return tm_sta;
|
return tm_sta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,7 +524,7 @@ return tm_sta;
|
||||||
void tm_set_done (void)
|
void tm_set_done (void)
|
||||||
{
|
{
|
||||||
tm_cmd = tm_cmd | MTC_DONE;
|
tm_cmd = tm_cmd | MTC_DONE;
|
||||||
if (tm_cmd & MTC_IE) int_req = int_req | INT_TM;
|
if (tm_cmd & MTC_IE) SET_INT (TM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,11 +534,12 @@ t_stat tm_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
int32 u;
|
int32 u;
|
||||||
UNIT *uptr;
|
UNIT *uptr;
|
||||||
|
extern int32 ts_enb;
|
||||||
|
|
||||||
if (dev_enb & INT_TM) dev_enb = dev_enb & ~INT_TS; /* TM or TS */
|
if (tm_enb) ts_enb = 0; /* TM or TS */
|
||||||
tm_cmd = MTC_DONE; /* set done */
|
tm_cmd = MTC_DONE; /* set done */
|
||||||
tm_bc = tm_ca = tm_db = tm_sta = 0;
|
tm_bc = tm_ca = tm_db = tm_sta = tm_rdl = 0;
|
||||||
int_req = int_req & ~INT_TM; /* clear interrupt */
|
CLR_INT (TM); /* clear interrupt */
|
||||||
for (u = 0; u < TM_NUMDR; u++) { /* loop thru units */
|
for (u = 0; u < TM_NUMDR; u++) { /* loop thru units */
|
||||||
uptr = tm_dev.units + u;
|
uptr = tm_dev.units + u;
|
||||||
uptr -> UNUM = u; /* init drive number */
|
uptr -> UNUM = u; /* init drive number */
|
||||||
|
|
77
pdp11_ts.c
77
pdp11_ts.c
|
@ -25,6 +25,12 @@
|
||||||
|
|
||||||
ts TS11/TSV05 magtape
|
ts TS11/TSV05 magtape
|
||||||
|
|
||||||
|
15-Oct-01 RMS Integrated debug logging across simulator
|
||||||
|
27-Sep-01 RMS Implemented extended characteristics and status
|
||||||
|
Fixed bug in write characteristics status return
|
||||||
|
19-Sep-01 RMS Fixed bug in bootstrap
|
||||||
|
15-Sep-01 RMS Fixed bug in NXM test
|
||||||
|
07-Sep-01 RMS Revised device disable and interrupt mechanism
|
||||||
13-Jul-01 RMS Fixed bug in space reverse (found by Peter Schorn)
|
13-Jul-01 RMS Fixed bug in space reverse (found by Peter Schorn)
|
||||||
|
|
||||||
Magnetic tapes are represented as a series of variable 8b records
|
Magnetic tapes are represented as a series of variable 8b records
|
||||||
|
@ -171,24 +177,28 @@
|
||||||
|
|
||||||
/* Extended status register 1 - none of these errors are ever set */
|
/* Extended status register 1 - none of these errors are ever set */
|
||||||
|
|
||||||
/* Extended status register 2 - none of these errors are ever set */
|
/* Extended status register 2 */
|
||||||
|
|
||||||
|
#define XS2_XTF 0000200 /* ext features */
|
||||||
|
|
||||||
/* Extended status register 3 */
|
/* Extended status register 3 */
|
||||||
|
|
||||||
#define XS3_XTF 0000200 /* ext features */
|
|
||||||
#define XS3_OPI 0000100 /* op incomplete */
|
#define XS3_OPI 0000100 /* op incomplete */
|
||||||
#define XS3_REV 0000040 /* reverse */
|
#define XS3_REV 0000040 /* reverse */
|
||||||
#define XS3_RIB 0000001 /* reverse to BOT */
|
#define XS3_RIB 0000001 /* reverse to BOT */
|
||||||
|
|
||||||
/* Extended status register 4 - none of these errors are ever set */
|
/* Extended status register 4 */
|
||||||
|
|
||||||
|
#define XS4_HDS 0100000 /* high density */
|
||||||
|
|
||||||
/* Write characteristics packet offsets */
|
/* Write characteristics packet offsets */
|
||||||
|
|
||||||
#define WCH_PLNT 4 /* packet length */
|
#define WCH_PLNT 5 /* packet length */
|
||||||
#define wchadl tswchp[0] /* address low */
|
#define wchadl tswchp[0] /* address low */
|
||||||
#define wchadh tswchp[1] /* address high */
|
#define wchadh tswchp[1] /* address high */
|
||||||
#define wchlnt tswchp[2] /* length */
|
#define wchlnt tswchp[2] /* length */
|
||||||
#define wchopt tswchp[3] /* options */
|
#define wchopt tswchp[3] /* options */
|
||||||
|
#define wchxopt tswchp[4] /* ext options */
|
||||||
|
|
||||||
/* Write characteristics options */
|
/* Write characteristics options */
|
||||||
|
|
||||||
|
@ -197,6 +207,10 @@
|
||||||
#define WCH_EAI 0000040 /* enb attn int */
|
#define WCH_EAI 0000040 /* enb attn int */
|
||||||
#define WCH_ERI 0000020 /* enb mrls int */
|
#define WCH_ERI 0000020 /* enb mrls int */
|
||||||
|
|
||||||
|
/* Write characteristics extended options */
|
||||||
|
|
||||||
|
#define WCHX_HDS 0000040 /* high density */
|
||||||
|
|
||||||
#define MAX(a,b) (((a) >= (b))? (a): (b))
|
#define MAX(a,b) (((a) >= (b))? (a): (b))
|
||||||
#define READ_BYTE(p) ((M[(p) >> 1] >> (((p) & 1)? 8: 0)) & 0377)
|
#define READ_BYTE(p) ((M[(p) >> 1] >> (((p) & 1)? 8: 0)) & 0377)
|
||||||
#define WRITE_BYTE(d,p) M[(p) >> 1] = (p & 1)? \
|
#define WRITE_BYTE(d,p) M[(p) >> 1] = (p & 1)? \
|
||||||
|
@ -204,8 +218,10 @@
|
||||||
((M[(p) >> 1] & ~0377) | (d))
|
((M[(p) >> 1] & ~0377) | (d))
|
||||||
|
|
||||||
extern uint16 *M; /* memory */
|
extern uint16 *M; /* memory */
|
||||||
extern int32 int_req, dev_enb;
|
extern int32 int_req[IPL_HLVL];
|
||||||
extern UNIT cpu_unit;
|
extern UNIT cpu_unit;
|
||||||
|
extern FILE *sim_log;
|
||||||
|
extern int32 pdp11_log;
|
||||||
int32 tssr = 0; /* status register */
|
int32 tssr = 0; /* status register */
|
||||||
int32 tsba = 0; /* mem addr */
|
int32 tsba = 0; /* mem addr */
|
||||||
int32 tsdbx = 0; /* data buf ext */
|
int32 tsdbx = 0; /* data buf ext */
|
||||||
|
@ -217,7 +233,7 @@ int32 ts_ownm = 0; /* tape owns msg */
|
||||||
int32 ts_qatn = 0; /* queued attn */
|
int32 ts_qatn = 0; /* queued attn */
|
||||||
int32 ts_bcmd = 0; /* boot cmd */
|
int32 ts_bcmd = 0; /* boot cmd */
|
||||||
int32 ts_time = 10; /* record latency */
|
int32 ts_time = 10; /* record latency */
|
||||||
int32 ts_log = 0;
|
int32 ts_enb = 0; /* device enable */
|
||||||
static uint8 dbuf[DBSIZE];
|
static uint8 dbuf[DBSIZE];
|
||||||
|
|
||||||
t_stat ts_svc (UNIT *uptr);
|
t_stat ts_svc (UNIT *uptr);
|
||||||
|
@ -259,6 +275,8 @@ REG ts_reg[] = {
|
||||||
{ ORDATA (WADH, wchadh, 16) },
|
{ ORDATA (WADH, wchadh, 16) },
|
||||||
{ ORDATA (WLNT, wchlnt, 16) },
|
{ ORDATA (WLNT, wchlnt, 16) },
|
||||||
{ ORDATA (WOPT, wchopt, 16) },
|
{ ORDATA (WOPT, wchopt, 16) },
|
||||||
|
{ ORDATA (WXOPT, wchxopt, 16) },
|
||||||
|
{ FLDATA (INT, IREQ (TS), INT_V_TS) },
|
||||||
{ FLDATA (ATTN, ts_qatn, 0) },
|
{ FLDATA (ATTN, ts_qatn, 0) },
|
||||||
{ FLDATA (BOOT, ts_bcmd, 0) },
|
{ FLDATA (BOOT, ts_bcmd, 0) },
|
||||||
{ FLDATA (OWNC, ts_ownc, 0) },
|
{ FLDATA (OWNC, ts_ownc, 0) },
|
||||||
|
@ -266,8 +284,7 @@ REG ts_reg[] = {
|
||||||
{ DRDATA (TIME, ts_time, 24), PV_LEFT + REG_NZ },
|
{ DRDATA (TIME, ts_time, 24), PV_LEFT + REG_NZ },
|
||||||
{ DRDATA (POS, ts_unit.pos, 31), PV_LEFT + REG_RO },
|
{ DRDATA (POS, ts_unit.pos, 31), PV_LEFT + REG_RO },
|
||||||
{ FLDATA (WLK, ts_unit.flags, UNIT_V_WLK), REG_HRO },
|
{ FLDATA (WLK, ts_unit.flags, UNIT_V_WLK), REG_HRO },
|
||||||
{ FLDATA (LOG, ts_log, 0), REG_HIDDEN },
|
{ FLDATA (*DEVENB, ts_enb, 0), REG_HRO },
|
||||||
{ FLDATA (*DEVENB, dev_enb, INT_V_TS), REG_HRO },
|
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB ts_mod[] = {
|
MTAB ts_mod[] = {
|
||||||
|
@ -314,10 +331,10 @@ case 0: /* TSDB */
|
||||||
tssr = ts_updtssr (tssr & TSSR_NBA); /* clr ssr, err */
|
tssr = ts_updtssr (tssr & TSSR_NBA); /* clr ssr, err */
|
||||||
msgxs0 = ts_updxs0 (msgxs0 & ~XS0_ALLERR); /* clr err, upd xs0 */
|
msgxs0 = ts_updxs0 (msgxs0 & ~XS0_ALLERR); /* clr err, upd xs0 */
|
||||||
msgrfc = msgxs1 = msgxs2 = msgxs3 = msgxs4 = 0; /* clr status */
|
msgrfc = msgxs1 = msgxs2 = msgxs3 = msgxs4 = 0; /* clr status */
|
||||||
int_req = int_req & ~INT_TS; /* clr int req */
|
CLR_INT (TS); /* clr int req */
|
||||||
for (i = 0; i < CMD_PLNT; i++) { /* get cmd pkt */
|
for (i = 0; i < CMD_PLNT; i++) { /* get cmd pkt */
|
||||||
if (ADDR_IS_MEM (tsba)) tscmdp[i] = M[(tsba >> 1)];
|
if (ADDR_IS_MEM (tsba)) tscmdp[i] = M[(tsba >> 1)];
|
||||||
else { ts_endcmd (TSSR_NXM + TC3, 0, MSG_ACK|MSG_MNEF|MSG_CFAIL);
|
else { ts_endcmd (TSSR_NXM + TC5, 0, MSG_ACK|MSG_MNEF|MSG_CFAIL);
|
||||||
return SCPE_OK; }
|
return SCPE_OK; }
|
||||||
tsba = tsba + 2; } /* incr tsba */
|
tsba = tsba + 2; } /* incr tsba */
|
||||||
ts_ownc = ts_ownm = 1; /* tape owns all */
|
ts_ownc = ts_ownm = 1; /* tape owns all */
|
||||||
|
@ -574,12 +591,12 @@ if (ts_bcmd) { /* boot? */
|
||||||
ts_readf (uptr, 512); /* read blk */
|
ts_readf (uptr, 512); /* read blk */
|
||||||
tssr = ts_updtssr (tssr | TSSR_SSR); }
|
tssr = ts_updtssr (tssr | TSSR_SSR); }
|
||||||
else tssr = ts_updtssr (tssr | TSSR_SSR | TC3);
|
else tssr = ts_updtssr (tssr | TSSR_SSR | TC3);
|
||||||
if (cmdhdr & CMD_IE) int_req = int_req | INT_TS;
|
if (cmdhdr & CMD_IE) SET_INT (TS);
|
||||||
return SCPE_OK; }
|
return SCPE_OK; }
|
||||||
|
|
||||||
if (!(cmdhdr & CMD_ACK)) { /* no acknowledge? */
|
if (!(cmdhdr & CMD_ACK)) { /* no acknowledge? */
|
||||||
tssr = ts_updtssr (tssr | TSSR_SSR); /* set rdy, int */
|
tssr = ts_updtssr (tssr | TSSR_SSR); /* set rdy, int */
|
||||||
if (cmdhdr & CMD_IE) int_req = int_req | INT_TS;
|
if (cmdhdr & CMD_IE) SET_INT (TS);
|
||||||
ts_ownc = ts_ownm = 0; /* CPU owns all */
|
ts_ownc = ts_ownm = 0; /* CPU owns all */
|
||||||
return SCPE_OK; }
|
return SCPE_OK; }
|
||||||
fnc = GET_FNC (cmdhdr); /* get fnc+mode */
|
fnc = GET_FNC (cmdhdr); /* get fnc+mode */
|
||||||
|
@ -589,7 +606,7 @@ if ((fnc != FNC_WCHR) && (tssr & TSSR_NBA)) { /* ~wr chr & nba? */
|
||||||
return SCPE_OK; }
|
return SCPE_OK; }
|
||||||
if (ts_qatn && (wchopt & WCH_EAI)) { /* attn pending? */
|
if (ts_qatn && (wchopt & WCH_EAI)) { /* attn pending? */
|
||||||
ts_endcmd (TC1, 0, MSG_MATN | MSG_CATN); /* send attn msg */
|
ts_endcmd (TC1, 0, MSG_MATN | MSG_CATN); /* send attn msg */
|
||||||
int_req = int_req | INT_TS; /* set interrupt */
|
SET_INT (TS); /* set interrupt */
|
||||||
ts_qatn = 0; /* not pending */
|
ts_qatn = 0; /* not pending */
|
||||||
return SCPE_OK; }
|
return SCPE_OK; }
|
||||||
if (cmdhdr & CMD_CVC) /* cvc? clr vck */
|
if (cmdhdr & CMD_CVC) /* cvc? clr vck */
|
||||||
|
@ -628,13 +645,13 @@ case FNC_WCHR: /* write char */
|
||||||
break; }
|
break; }
|
||||||
tsba = (cmdadh << 16) | cmdadl;
|
tsba = (cmdadh << 16) | cmdadl;
|
||||||
for (i = 0; (i < WCH_PLNT) && (i < (cmdlnt / 2)); i++) {
|
for (i = 0; (i < WCH_PLNT) && (i < (cmdlnt / 2)); i++) {
|
||||||
if (ADDR_IS_MEM (cmdadl)) tswchp[i] = M[tsba >> 1];
|
if (ADDR_IS_MEM (tsba)) tswchp[i] = M[tsba >> 1];
|
||||||
else { ts_endcmd (TSSR_NBA | TSSR_NXM | TC3, 0, 0);
|
else { ts_endcmd (TSSR_NBA | TSSR_NXM | TC5, 0, 0);
|
||||||
return SCPE_OK; }
|
return SCPE_OK; }
|
||||||
tsba = tsba + 2; }
|
tsba = tsba + 2; }
|
||||||
if ((wchlnt < ((MSG_PLNT - 1) * 2)) || (wchadh & 0177700) ||
|
if ((wchlnt < ((MSG_PLNT - 1) * 2)) || (wchadh & 0177700) ||
|
||||||
(wchadl & 1)) ts_endcmd (TSSR_NBA | TC3, 0, 0);
|
(wchadl & 1)) ts_endcmd (TSSR_NBA | TC3, 0, 0);
|
||||||
else { msgxs3 = msgxs3 | XS3_XTF | 1;
|
else { msgxs2 = msgxs2 | XS2_XTF | 1;
|
||||||
tssr = ts_updtssr (tssr & ~TSSR_NBA);
|
tssr = ts_updtssr (tssr & ~TSSR_NBA);
|
||||||
ts_endcmd (TC0, 0, MSG_ACK | MSG_CEND); }
|
ts_endcmd (TC0, 0, MSG_ACK | MSG_CEND); }
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
@ -642,7 +659,7 @@ case FNC_CTL: /* control */
|
||||||
switch (mod) { /* case mode */
|
switch (mod) { /* case mode */
|
||||||
case 00: /* msg buf rls */
|
case 00: /* msg buf rls */
|
||||||
tssr = ts_updtssr (tssr | TSSR_SSR); /* set SSR */
|
tssr = ts_updtssr (tssr | TSSR_SSR); /* set SSR */
|
||||||
if (wchopt & WCH_ERI) int_req = int_req | INT_TS;
|
if (wchopt & WCH_ERI) SET_INT (TS);
|
||||||
ts_ownc = 0; ts_ownm = 1; /* keep msg */
|
ts_ownc = 0; ts_ownm = 1; /* keep msg */
|
||||||
break;
|
break;
|
||||||
case 01: /* clean */
|
case 01: /* clean */
|
||||||
|
@ -728,7 +745,8 @@ case FNC_POS:
|
||||||
break; }
|
break; }
|
||||||
ts_cmpendcmd (st0, 0);
|
ts_cmpendcmd (st0, 0);
|
||||||
break; }
|
break; }
|
||||||
if (ts_log) printf ("Cmd=%o, mod=%o, buf=%o, lnt=%o, sta = %o, tc=%o, pos=%d\n",
|
if (DBG_LOG (LOG_TS))
|
||||||
|
fprintf (sim_log, ">>TS: cmd=%o, mod=%o, buf=%o, lnt=%o, sta = %o, tc=%o, pos=%d\n",
|
||||||
fnc, mod, cmdadl, cmdlnt, msgxs0, (tssr & TSSR_TC) >> 1, ts_unit.pos);
|
fnc, mod, cmdadl, cmdlnt, msgxs0, (tssr & TSSR_TC) >> 1, ts_unit.pos);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -776,6 +794,7 @@ void ts_endcmd (int32 tc, int32 xs0, int32 msg)
|
||||||
int32 i;
|
int32 i;
|
||||||
|
|
||||||
msgxs0 = ts_updxs0 (msgxs0 | xs0); /* update XS0 */
|
msgxs0 = ts_updxs0 (msgxs0 | xs0); /* update XS0 */
|
||||||
|
if (wchxopt & WCHX_HDS) msgxs4 = msgxs4 | XS4_HDS; /* update XS4 */
|
||||||
if (msg && !(tssr & TSSR_NBA)) { /* send end pkt */
|
if (msg && !(tssr & TSSR_NBA)) { /* send end pkt */
|
||||||
msghdr = msg;
|
msghdr = msg;
|
||||||
msglnt = wchlnt - 4; /* exclude hdr, bc */
|
msglnt = wchlnt - 4; /* exclude hdr, bc */
|
||||||
|
@ -787,7 +806,7 @@ if (msg && !(tssr & TSSR_NBA)) { /* send end pkt */
|
||||||
break; }
|
break; }
|
||||||
tsba = tsba + 2; } }
|
tsba = tsba + 2; } }
|
||||||
tssr = ts_updtssr (tssr | tc | TSSR_SSR | (tc? TSSR_SC: 0));
|
tssr = ts_updtssr (tssr | tc | TSSR_SSR | (tc? TSSR_SC: 0));
|
||||||
if (cmdhdr & CMD_IE) int_req = int_req | INT_TS;
|
if (cmdhdr & CMD_IE) SET_INT (TS);
|
||||||
ts_ownm = 0; ts_ownc = 0;
|
ts_ownm = 0; ts_ownc = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -797,8 +816,9 @@ return;
|
||||||
t_stat ts_reset (DEVICE *dptr)
|
t_stat ts_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
int32 i;
|
int32 i;
|
||||||
|
extern int32 tm_enb;
|
||||||
|
|
||||||
if (dev_enb & INT_TS) dev_enb = dev_enb & ~INT_TM; /* TM or TS */
|
if (ts_enb) tm_enb = 0; /* TM or TS */
|
||||||
ts_unit.pos = 0;
|
ts_unit.pos = 0;
|
||||||
tsba = tsdbx = 0;
|
tsba = tsdbx = 0;
|
||||||
ts_ownc = ts_ownm = 0;
|
ts_ownc = ts_ownm = 0;
|
||||||
|
@ -809,7 +829,7 @@ for (i = 0; i < CMD_PLNT; i++) tscmdp[i] = 0;
|
||||||
for (i = 0; i < WCH_PLNT; i++) tswchp[i] = 0;
|
for (i = 0; i < WCH_PLNT; i++) tswchp[i] = 0;
|
||||||
for (i = 0; i < MSG_PLNT; i++) tsmsgp[i] = 0;
|
for (i = 0; i < MSG_PLNT; i++) tsmsgp[i] = 0;
|
||||||
msgxs0 = ts_updxs0 (XS0_VCK);
|
msgxs0 = ts_updxs0 (XS0_VCK);
|
||||||
int_req = int_req & ~INT_TS;
|
CLR_INT (TS);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -825,7 +845,7 @@ tssr = tssr & ~TSSR_OFL; /* clr offline */
|
||||||
if ((tssr & TSSR_NBA) || !(wchopt & WCH_EAI)) return r; /* attn msg? */
|
if ((tssr & TSSR_NBA) || !(wchopt & WCH_EAI)) return r; /* attn msg? */
|
||||||
if (ts_ownm) { /* own msg buf? */
|
if (ts_ownm) { /* own msg buf? */
|
||||||
ts_endcmd (TC1, 0, MSG_MATN | MSG_CATN); /* send attn */
|
ts_endcmd (TC1, 0, MSG_MATN | MSG_CATN); /* send attn */
|
||||||
int_req = int_req | INT_TS; /* set interrupt */
|
SET_INT (TS); /* set interrupt */
|
||||||
ts_qatn = 0; } /* don't queue */
|
ts_qatn = 0; } /* don't queue */
|
||||||
else ts_qatn = 1; /* else queue */
|
else ts_qatn = 1; /* else queue */
|
||||||
return r;
|
return r;
|
||||||
|
@ -843,7 +863,7 @@ tssr = tssr | TSSR_OFL; /* set offline */
|
||||||
if ((tssr & TSSR_NBA) || !(wchopt & WCH_EAI)) return r; /* attn msg? */
|
if ((tssr & TSSR_NBA) || !(wchopt & WCH_EAI)) return r; /* attn msg? */
|
||||||
if (ts_ownm) { /* own msg buf? */
|
if (ts_ownm) { /* own msg buf? */
|
||||||
ts_endcmd (TC1, 0, MSG_MATN | MSG_CATN); /* send attn */
|
ts_endcmd (TC1, 0, MSG_MATN | MSG_CATN); /* send attn */
|
||||||
int_req = int_req | INT_TS; /* set interrupt */
|
SET_INT (TS); /* set interrupt */
|
||||||
ts_qatn = 0; } /* don't queue */
|
ts_qatn = 0; } /* don't queue */
|
||||||
else ts_qatn = 1; /* else queue */
|
else ts_qatn = 1; /* else queue */
|
||||||
return r;
|
return r;
|
||||||
|
@ -861,13 +881,13 @@ static const int32 boot_rom[] = {
|
||||||
0005011, /* clr (r1) ; init, rew */
|
0005011, /* clr (r1) ; init, rew */
|
||||||
0105711, /* tstb (r1) ; wait */
|
0105711, /* tstb (r1) ; wait */
|
||||||
0100376, /* bpl .-2 */
|
0100376, /* bpl .-2 */
|
||||||
0012710, 0001064, /* mov #pkt1, (r0) ; set char */
|
0012710, 0001070, /* mov #pkt1, (r0) ; set char */
|
||||||
0105711, /* tstb (r1) ; wait */
|
0105711, /* tstb (r1) ; wait */
|
||||||
0100376, /* bpl .-2 */
|
0100376, /* bpl .-2 */
|
||||||
0012710, 0001104, /* mov #pkt2, (r0) ; read, skip */
|
0012710, 0001110, /* mov #pkt2, (r0) ; read, skip */
|
||||||
0105711, /* tstb (r1) ; wait */
|
0105711, /* tstb (r1) ; wait */
|
||||||
0100376, /* bpl .-2 */
|
0100376, /* bpl .-2 */
|
||||||
0012710, 0001104, /* mov #pkt2, (r0) ; read */
|
0012710, 0001110, /* mov #pkt2, (r0) ; read */
|
||||||
0105711, /* tstb (r1) ; wait */
|
0105711, /* tstb (r1) ; wait */
|
||||||
0100376, /* bpl .-2 */
|
0100376, /* bpl .-2 */
|
||||||
0005711, /* tst (r1) ; err? */
|
0005711, /* tst (r1) ; err? */
|
||||||
|
@ -877,10 +897,10 @@ static const int32 boot_rom[] = {
|
||||||
0005007, /* clr r7 */
|
0005007, /* clr r7 */
|
||||||
0046523, /* pad */
|
0046523, /* pad */
|
||||||
0140004, /* pkt1: 140004, wcpk, 0, 8. */
|
0140004, /* pkt1: 140004, wcpk, 0, 8. */
|
||||||
0001074,
|
0001100,
|
||||||
0000000,
|
0000000,
|
||||||
0000010,
|
0000010,
|
||||||
0001116, /* wcpk: msg, 0, 14., 0 */
|
0001122, /* wcpk: msg, 0, 14., 0 */
|
||||||
0000000,
|
0000000,
|
||||||
0000016,
|
0000016,
|
||||||
0000000,
|
0000000,
|
||||||
|
@ -889,6 +909,7 @@ static const int32 boot_rom[] = {
|
||||||
0000000,
|
0000000,
|
||||||
0001000,
|
0001000,
|
||||||
0000000 /* hlt: halt */
|
0000000 /* hlt: halt */
|
||||||
|
/* msg: .blk 4 */
|
||||||
};
|
};
|
||||||
|
|
||||||
t_stat ts_boot (int32 unitno)
|
t_stat ts_boot (int32 unitno)
|
||||||
|
|
43
pdp18b_cpu.c
43
pdp18b_cpu.c
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
cpu PDP-4/7/9/15 central processor
|
cpu PDP-4/7/9/15 central processor
|
||||||
|
|
||||||
|
19-Sep-01 RMS Fixed bug in EAE (found by Dave Conroy)
|
||||||
|
17-Sep-01 RMS Fixed typo in conditional
|
||||||
10-Aug-01 RMS Removed register from declarations
|
10-Aug-01 RMS Removed register from declarations
|
||||||
17-Jul-01 RMS Moved function prototype
|
17-Jul-01 RMS Moved function prototype
|
||||||
27-May-01 RMS Added second Teletype support, fixed bug in API
|
27-May-01 RMS Added second Teletype support, fixed bug in API
|
||||||
|
@ -256,7 +258,7 @@
|
||||||
#else
|
#else
|
||||||
#define EAE_DFLT 0
|
#define EAE_DFLT 0
|
||||||
#endif
|
#endif
|
||||||
#if defined (PDP4) || (PDP7)
|
#if defined (PDP4) || defined (PDP7)
|
||||||
#define API_DFLT UNIT_NOAPI
|
#define API_DFLT UNIT_NOAPI
|
||||||
#else
|
#else
|
||||||
#define API_DFLT UNIT_NOAPI /* for now */
|
#define API_DFLT UNIT_NOAPI /* for now */
|
||||||
|
@ -612,7 +614,7 @@ api_cycle = 0; /* not API cycle */
|
||||||
/* Main instruction fetch/decode loop: check trap and interrupt */
|
/* Main instruction fetch/decode loop: check trap and interrupt */
|
||||||
|
|
||||||
while (reason == 0) { /* loop until halted */
|
while (reason == 0) { /* loop until halted */
|
||||||
int32 IR, MA, t, xct_count;
|
int32 IR, MA, esc, t, xct_count;
|
||||||
int32 link_init, fill;
|
int32 link_init, fill;
|
||||||
|
|
||||||
if (sim_interval <= 0) { /* check clock queue */
|
if (sim_interval <= 0) { /* check clock queue */
|
||||||
|
@ -1086,6 +1088,7 @@ case 033: case 032: /* EAE */
|
||||||
if (IR & 0001000) LAC = LAC & 01000000; /* IR<8>? clear AC */
|
if (IR & 0001000) LAC = LAC & 01000000; /* IR<8>? clear AC */
|
||||||
link_init = LAC & 01000000; /* link temporary */
|
link_init = LAC & 01000000; /* link temporary */
|
||||||
fill = link_init? 0777777: 0; /* fill = link */
|
fill = link_init? 0777777: 0; /* fill = link */
|
||||||
|
esc = (IR & 077)? IR & 077: 0100; /* get eff SC */
|
||||||
|
|
||||||
switch ((IR >> 6) & 07) { /* case on IR<9:11> */
|
switch ((IR >> 6) & 07) { /* case on IR<9:11> */
|
||||||
case 0: /* setup */
|
case 0: /* setup */
|
||||||
|
@ -1100,7 +1103,7 @@ case 033: case 032: /* EAE */
|
||||||
PC = INCR_ADDR (PC); /* increment PC */
|
PC = INCR_ADDR (PC); /* increment PC */
|
||||||
if (eae_ac_sign) MQ = MQ ^ 0777777; /* EAE AC sign? ~MQ */
|
if (eae_ac_sign) MQ = MQ ^ 0777777; /* EAE AC sign? ~MQ */
|
||||||
LAC = LAC & 0777777; /* clear link */
|
LAC = LAC & 0777777; /* clear link */
|
||||||
for (SC = IR & 077; SC != 0; SC--) { /* loop per step cnt */
|
for (SC = esc; SC != 0; SC--) { /* loop per step cnt */
|
||||||
if (MQ & 1) LAC = LAC + MA; /* MQ<17>? add */
|
if (MQ & 1) LAC = LAC + MA; /* MQ<17>? add */
|
||||||
MQ = (MQ >> 1) | ((LAC & 1) << 17);
|
MQ = (MQ >> 1) | ((LAC & 1) << 17);
|
||||||
LAC = LAC >> 1; } /* shift AC'MQ right */
|
LAC = LAC >> 1; } /* shift AC'MQ right */
|
||||||
|
@ -1130,7 +1133,7 @@ case 033: case 032: /* EAE */
|
||||||
break; }
|
break; }
|
||||||
LAC = LAC & 0777777; /* clear link */
|
LAC = LAC & 0777777; /* clear link */
|
||||||
t = 0; /* init loop */
|
t = 0; /* init loop */
|
||||||
for (SC = IR & 077; SC != 0; SC--) {
|
for (SC = esc; SC != 0; SC--) { /* loop per step cnt */
|
||||||
if (t) LAC = (LAC + MA) & 01777777;
|
if (t) LAC = (LAC + MA) & 01777777;
|
||||||
else LAC = (LAC - MA) & 01777777;
|
else LAC = (LAC - MA) & 01777777;
|
||||||
t = (LAC >> 18) & 1; /* quotient bit */
|
t = (LAC >> 18) & 1; /* quotient bit */
|
||||||
|
@ -1153,40 +1156,38 @@ case 033: case 032: /* EAE */
|
||||||
#if defined (PDP15)
|
#if defined (PDP15)
|
||||||
if (!usmd) ion_defer = 2; /* free cycles */
|
if (!usmd) ion_defer = 2; /* free cycles */
|
||||||
#endif
|
#endif
|
||||||
for (SC = IR & 077; ((LAC & 0400000) ==
|
for (SC = esc; (SC != 0) && ((LAC & 0400000) ==
|
||||||
((LAC << 1) & 0400000)) && (SC != 0); SC--) {
|
((LAC << 1) & 0400000)); SC--) {
|
||||||
LAC = (LAC << 1) | ((MQ >> 17) & 1);
|
LAC = (LAC << 1) | ((MQ >> 17) & 1);
|
||||||
MQ = (MQ << 1) | (link_init >> 18); }
|
MQ = (MQ << 1) | (link_init >> 18); }
|
||||||
LAC = link_init | (LAC & 0777777); /* trim AC, restore L */
|
LAC = link_init | (LAC & 0777777); /* trim AC, restore L */
|
||||||
MQ = MQ & 0777777; /* trim MQ */
|
MQ = MQ & 0777777; /* trim MQ */
|
||||||
|
SC = SC & 077; /* trim SC */
|
||||||
break;
|
break;
|
||||||
case 5: /* long right shift */
|
case 5: /* long right shift */
|
||||||
t = IR & 077; /* get shift count */
|
if (esc < 18) {
|
||||||
if (t < 18) {
|
MQ = ((LAC << (18 - esc)) | (MQ >> esc)) & 0777777;
|
||||||
MQ = ((LAC << (18 - t)) | (MQ >> t)) & 0777777;
|
LAC = ((fill << (18 - esc)) | (LAC >> esc)) & 01777777; }
|
||||||
LAC = ((fill << (18 - t)) | (LAC >> t)) & 01777777; }
|
else { if (esc < 36) MQ =
|
||||||
else { if (t < 36) MQ =
|
((fill << (36 - esc)) | (LAC >> (esc - 18))) & 0777777;
|
||||||
((fill << (36 - t)) | (LAC >> (t - 18))) & 0777777;
|
|
||||||
else MQ = fill;
|
else MQ = fill;
|
||||||
LAC = link_init | fill; }
|
LAC = link_init | fill; }
|
||||||
SC = 0; /* clear step count */
|
SC = 0; /* clear step count */
|
||||||
break;
|
break;
|
||||||
case 6: /* long left shift */
|
case 6: /* long left shift */
|
||||||
t = IR & 077; /* get shift count */
|
if (esc < 18) {
|
||||||
if (t < 18) {
|
|
||||||
LAC = link_init |
|
LAC = link_init |
|
||||||
(((LAC << t) | (MQ >> (18 - t))) & 0777777);
|
(((LAC << esc) | (MQ >> (18 - esc))) & 0777777);
|
||||||
MQ = ((MQ << t) | (fill >> (18 - t))) & 0777777; }
|
MQ = ((MQ << esc) | (fill >> (18 - esc))) & 0777777; }
|
||||||
else { if (t < 36) LAC = link_init |
|
else { if (esc < 36) LAC = link_init |
|
||||||
(((MQ << (t - 18)) | (fill >> (36 - t))) & 0777777);
|
(((MQ << (esc - 18)) | (fill >> (36 - esc))) & 0777777);
|
||||||
else LAC = link_init | fill;
|
else LAC = link_init | fill;
|
||||||
MQ = fill; }
|
MQ = fill; }
|
||||||
SC = 0; /* clear step count */
|
SC = 0; /* clear step count */
|
||||||
break;
|
break;
|
||||||
case 7: /* AC left shift */
|
case 7: /* AC left shift */
|
||||||
t = IR & 077; /* get shift count */
|
if (esc < 18) LAC = link_init |
|
||||||
if (t < 18) LAC = link_init |
|
(((LAC << esc) | (fill >> (18 - esc))) & 0777777);
|
||||||
(((LAC << t) | (fill >> (18 - t))) & 0777777);
|
|
||||||
else LAC = link_init | fill;
|
else LAC = link_init | fill;
|
||||||
SC = 0; /* clear step count */
|
SC = 0; /* clear step count */
|
||||||
break; } /* end switch IR */
|
break; } /* end switch IR */
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
dt (PDP-9) TC02/TU55 DECtape
|
dt (PDP-9) TC02/TU55 DECtape
|
||||||
(PDP-15) TC15/TU56 DECtape
|
(PDP-15) TC15/TU56 DECtape
|
||||||
|
|
||||||
|
29-Aug-01 RMS Added casts to PDP-8 unpack routine
|
||||||
17-Jul-01 RMS Moved function prototype
|
17-Jul-01 RMS Moved function prototype
|
||||||
11-May-01 RMS Fixed bug in reset
|
11-May-01 RMS Fixed bug in reset
|
||||||
26-Apr-01 RMS Added device enable/disable support
|
26-Apr-01 RMS Added device enable/disable support
|
||||||
|
@ -1008,10 +1009,10 @@ if (uptr -> flags & UNIT_8FMT) { /* PDP-8? */
|
||||||
if (k == 0) break;
|
if (k == 0) break;
|
||||||
for ( ; k < D8_NBSIZE; k++) pdp8b[k] = 0;
|
for ( ; k < D8_NBSIZE; k++) pdp8b[k] = 0;
|
||||||
for (k = 0; k < D8_NBSIZE; k = k + 3) { /* loop thru blk */
|
for (k = 0; k < D8_NBSIZE; k = k + 3) { /* loop thru blk */
|
||||||
bptr[ba] = ((pdp8b[k] & 07777) << 6) |
|
bptr[ba] = ((uint32) (pdp8b[k] & 07777) << 6) |
|
||||||
((pdp8b[k + 1] >> 6) & 077);
|
((uint32) (pdp8b[k + 1] >> 6) & 077);
|
||||||
bptr[ba + 1] = ((pdp8b[k + 1] & 077) << 12) |
|
bptr[ba + 1] = ((pdp8b[k + 1] & 077) << 12) |
|
||||||
(pdp8b[k + 2] & 07777);
|
((uint32) (pdp8b[k + 2] & 07777));
|
||||||
ba = ba + 2; } /* end blk loop */
|
ba = ba + 2; } /* end blk loop */
|
||||||
} /* end file loop */
|
} /* end file loop */
|
||||||
uptr -> hwmark = ba; } /* end if */
|
uptr -> hwmark = ba; } /* end if */
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
(PDP-7,9) Type 647 line printer
|
(PDP-7,9) Type 647 line printer
|
||||||
(PDP-15) LP15 line printer
|
(PDP-15) LP15 line printer
|
||||||
|
|
||||||
|
19-Sep-01 RMS Fixed bug in 647
|
||||||
13-Feb-01 RMS Revised for register arrays
|
13-Feb-01 RMS Revised for register arrays
|
||||||
15-Feb-01 RMS Fixed 3 cycle data break sequence
|
15-Feb-01 RMS Fixed 3 cycle data break sequence
|
||||||
30-Oct-00 RMS Standardized register naming
|
30-Oct-00 RMS Standardized register naming
|
||||||
|
@ -234,7 +235,7 @@ int32 lpt65 (int32 pulse, int32 AC)
|
||||||
{
|
{
|
||||||
int32 i;
|
int32 i;
|
||||||
|
|
||||||
if (pulse == 001) return (int_req & INT_LPT)? IOT_SKP + AC: AC; /* LPSF */
|
if (pulse == 001) return (lpt_done? IOT_SKP + AC: AC); /* LPSF */
|
||||||
if (pulse & 002) { /* pulse 02 */
|
if (pulse & 002) { /* pulse 02 */
|
||||||
lpt_done = 0; /* clear done */
|
lpt_done = 0; /* clear done */
|
||||||
int_req = int_req & ~INT_LPT; } /* clear int req */
|
int_req = int_req & ~INT_LPT; } /* clear int req */
|
||||||
|
@ -265,7 +266,7 @@ return AC;
|
||||||
|
|
||||||
int32 lpt66 (int32 pulse, int32 AC)
|
int32 lpt66 (int32 pulse, int32 AC)
|
||||||
{
|
{
|
||||||
if (pulse == 001) return lpt_err? IOT_SKP + AC: AC; /* LPSE */
|
if (pulse == 001) return (lpt_err? IOT_SKP + AC: AC); /* LPSE */
|
||||||
if (pulse & 002) { /* LPCF */
|
if (pulse & 002) { /* LPCF */
|
||||||
lpt_done = 0; /* clear done, int */
|
lpt_done = 0; /* clear done, int */
|
||||||
int_req = int_req & ~INT_LPT; }
|
int_req = int_req & ~INT_LPT; }
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
tto teleprinter
|
tto teleprinter
|
||||||
clk clock
|
clk clock
|
||||||
|
|
||||||
|
17-Sep-01 RMS Removed multiconsole support
|
||||||
|
07-Sep-01 RMS Added terminal multiplexor support
|
||||||
17-Jul-01 RMS Moved function prototype
|
17-Jul-01 RMS Moved function prototype
|
||||||
10-Jun-01 RMS Cleaned up IOT decoding to reflect hardware
|
10-Jun-01 RMS Cleaned up IOT decoding to reflect hardware
|
||||||
27-May-01 RMS Added multiconsole support
|
27-May-01 RMS Added multiconsole support
|
||||||
|
@ -52,10 +54,8 @@ int32 ptr_err = 0, ptr_stopioe = 0, ptr_state = 0;
|
||||||
int32 ptp_err = 0, ptp_stopioe = 0;
|
int32 ptp_err = 0, ptp_stopioe = 0;
|
||||||
int32 tti_state = 0;
|
int32 tti_state = 0;
|
||||||
int32 tto_state = 0;
|
int32 tto_state = 0;
|
||||||
int32 clk_tps = 60;
|
int32 clk_tps = 60; /* ticks/second */
|
||||||
#if defined (TTY1)
|
int32 tmxr_poll = 16000; /* term mux poll */
|
||||||
static uint8 tto_consout[CONS_SIZE];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
t_stat clk_svc (UNIT *uptr);
|
t_stat clk_svc (UNIT *uptr);
|
||||||
t_stat ptr_svc (UNIT *uptr);
|
t_stat ptr_svc (UNIT *uptr);
|
||||||
|
@ -72,8 +72,6 @@ t_stat ptp_attach (UNIT *uptr, char *cptr);
|
||||||
t_stat ptr_detach (UNIT *uptr);
|
t_stat ptr_detach (UNIT *uptr);
|
||||||
t_stat ptp_detach (UNIT *uptr);
|
t_stat ptp_detach (UNIT *uptr);
|
||||||
t_stat ptr_boot (int32 unitno);
|
t_stat ptr_boot (int32 unitno);
|
||||||
extern t_stat sim_poll_kbd (void);
|
|
||||||
extern t_stat sim_putchar (int32 out);
|
|
||||||
|
|
||||||
/* CLK data structures
|
/* CLK data structures
|
||||||
|
|
||||||
|
@ -200,9 +198,9 @@ static const int32 tti_trans[128] = {
|
||||||
#define UNIT_HDX (1 << UNIT_V_HDX)
|
#define UNIT_HDX (1 << UNIT_V_HDX)
|
||||||
|
|
||||||
#if defined (PDP4) || defined (PDP7)
|
#if defined (PDP4) || defined (PDP7)
|
||||||
UNIT tti_unit = { UDATA (&tti_svc, UNIT_UC+UNIT_CONS, 0), KBD_POLL_WAIT };
|
UNIT tti_unit = { UDATA (&tti_svc, UNIT_UC, 0), KBD_POLL_WAIT };
|
||||||
#else
|
#else
|
||||||
UNIT tti_unit = { UDATA (&tti_svc, UNIT_UC+UNIT_HDX+UNIT_CONS, 0), KBD_POLL_WAIT };
|
UNIT tti_unit = { UDATA (&tti_svc, UNIT_UC+UNIT_HDX, 0), KBD_POLL_WAIT };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
REG tti_reg[] = {
|
REG tti_reg[] = {
|
||||||
|
@ -217,16 +215,9 @@ REG tti_reg[] = {
|
||||||
#endif
|
#endif
|
||||||
{ DRDATA (POS, tti_unit.pos, 31), PV_LEFT },
|
{ DRDATA (POS, tti_unit.pos, 31), PV_LEFT },
|
||||||
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
|
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||||
#if defined (TTY1)
|
|
||||||
{ FLDATA (CFLAG, tti_unit.flags, UNIT_V_CONS), REG_HRO },
|
|
||||||
#endif
|
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB tti_mod[] = {
|
MTAB tti_mod[] = {
|
||||||
#if defined (TTY1)
|
|
||||||
{ UNIT_CONS, 0, "inactive", NULL, NULL },
|
|
||||||
{ UNIT_CONS, UNIT_CONS, "active console", "CONSOLE", &set_console },
|
|
||||||
#endif
|
|
||||||
#if !defined (KSR28)
|
#if !defined (KSR28)
|
||||||
{ UNIT_UC, 0, "lower case", "LC", NULL },
|
{ UNIT_UC, 0, "lower case", "LC", NULL },
|
||||||
{ UNIT_UC, UNIT_UC, "upper case", "UC", NULL },
|
{ UNIT_UC, UNIT_UC, "upper case", "UC", NULL },
|
||||||
|
@ -269,7 +260,7 @@ static const char tto_trans[64] = {
|
||||||
|
|
||||||
#define TTO_MASK ((1 << TTO_WIDTH) - 1)
|
#define TTO_MASK ((1 << TTO_WIDTH) - 1)
|
||||||
|
|
||||||
UNIT tto_unit = { UDATA (&tto_svc, UNIT_UC+UNIT_CONS, 0), SERIAL_OUT_WAIT };
|
UNIT tto_unit = { UDATA (&tto_svc, UNIT_UC, 0), SERIAL_OUT_WAIT };
|
||||||
|
|
||||||
REG tto_reg[] = {
|
REG tto_reg[] = {
|
||||||
{ ORDATA (BUF, tto_unit.buf, TTO_WIDTH) },
|
{ ORDATA (BUF, tto_unit.buf, TTO_WIDTH) },
|
||||||
|
@ -280,17 +271,9 @@ REG tto_reg[] = {
|
||||||
#endif
|
#endif
|
||||||
{ DRDATA (POS, tto_unit.pos, 31), PV_LEFT },
|
{ DRDATA (POS, tto_unit.pos, 31), PV_LEFT },
|
||||||
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
|
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
|
||||||
#if defined (TTY1)
|
|
||||||
{ BRDATA (CONSOUT, tto_consout, 8, 8, CONS_SIZE), REG_HIDDEN },
|
|
||||||
{ FLDATA (CFLAG, tto_unit.flags, UNIT_V_CONS), REG_HRO },
|
|
||||||
#endif
|
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB tto_mod[] = {
|
MTAB tto_mod[] = {
|
||||||
#if defined (TTY1)
|
|
||||||
{ UNIT_CONS, 0, "inactive", NULL, NULL },
|
|
||||||
{ UNIT_CONS, UNIT_CONS, "active console", "CONSOLE", &set_console },
|
|
||||||
#endif
|
|
||||||
#if !defined (KSR28)
|
#if !defined (KSR28)
|
||||||
{ UNIT_UC, 0, "lower case", "LC", NULL },
|
{ UNIT_UC, 0, "lower case", "LC", NULL },
|
||||||
{ UNIT_UC, UNIT_UC, "upper case", "UC", NULL },
|
{ UNIT_UC, UNIT_UC, "upper case", "UC", NULL },
|
||||||
|
@ -324,11 +307,14 @@ return AC;
|
||||||
|
|
||||||
t_stat clk_svc (UNIT *uptr)
|
t_stat clk_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
|
int32 t;
|
||||||
|
|
||||||
if (clk_state) { /* clock on? */
|
if (clk_state) { /* clock on? */
|
||||||
M[7] = (M[7] + 1) & 0777777; /* incr counter */
|
M[7] = (M[7] + 1) & 0777777; /* incr counter */
|
||||||
if (M[7] == 0) int_req = int_req | INT_CLK; /* ovrflo? set flag */
|
if (M[7] == 0) int_req = int_req | INT_CLK; /* ovrflo? set flag */
|
||||||
sim_activate (&clk_unit, /* reactivate unit */
|
t = sim_rtc_calb (clk_tps); /* calibrate clock */
|
||||||
sim_rtc_calb (clk_tps)); } /* calibr delay */
|
sim_activate (&clk_unit, t); /* reactivate unit */
|
||||||
|
tmxr_poll = t; } /* set mux poll */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,6 +325,7 @@ t_stat clk_reset (DEVICE *dptr)
|
||||||
int_req = int_req & ~INT_CLK; /* clear flag */
|
int_req = int_req & ~INT_CLK; /* clear flag */
|
||||||
clk_state = 0; /* clock off */
|
clk_state = 0; /* clock off */
|
||||||
sim_cancel (&clk_unit); /* stop clock */
|
sim_cancel (&clk_unit); /* stop clock */
|
||||||
|
tmxr_poll = clk_unit.wait; /* set mux poll */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,7 +333,7 @@ return SCPE_OK;
|
||||||
|
|
||||||
int32 std_iors (void)
|
int32 std_iors (void)
|
||||||
{
|
{
|
||||||
return ((int_req & INT_CLK)? IOS_CLK: 0) |
|
return ((int_req & INT_CLK)? IOS_CLK: 0) |
|
||||||
((int_req & INT_PTR)? IOS_PTR: 0) |
|
((int_req & INT_PTR)? IOS_PTR: 0) |
|
||||||
((int_req & INT_PTP)? IOS_PTP: 0) |
|
((int_req & INT_PTP)? IOS_PTP: 0) |
|
||||||
((int_req & INT_TTI)? IOS_TTI: 0) |
|
((int_req & INT_TTI)? IOS_TTI: 0) |
|
||||||
|
@ -714,7 +701,7 @@ if ((tti_unit.flags & UNIT_UC) && islower (temp)) temp = toupper (temp);
|
||||||
if ((tti_unit.flags & UNIT_HDX) &&
|
if ((tti_unit.flags & UNIT_HDX) &&
|
||||||
(!(tto_unit.flags & UNIT_UC) ||
|
(!(tto_unit.flags & UNIT_UC) ||
|
||||||
((temp >= 007) && (temp <= 0137)))) {
|
((temp >= 007) && (temp <= 0137)))) {
|
||||||
sim_putcons (temp, uptr);
|
sim_putchar (temp);
|
||||||
tto_unit.pos = tto_unit.pos + 1; }
|
tto_unit.pos = tto_unit.pos + 1; }
|
||||||
tti_unit.buf = temp | 0200; /* got char */
|
tti_unit.buf = temp | 0200; /* got char */
|
||||||
#endif
|
#endif
|
||||||
|
@ -730,9 +717,6 @@ t_stat tti_reset (DEVICE *dptr)
|
||||||
tti_unit.buf = 0; /* clear buffer */
|
tti_unit.buf = 0; /* clear buffer */
|
||||||
tti_state = 0; /* clear state */
|
tti_state = 0; /* clear state */
|
||||||
int_req = int_req & ~INT_TTI; /* clear flag */
|
int_req = int_req & ~INT_TTI; /* clear flag */
|
||||||
#if defined (TTY1)
|
|
||||||
if (tti_unit.flags & UNIT_CONS) /* if active cons */
|
|
||||||
#endif
|
|
||||||
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
|
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -770,7 +754,7 @@ out = tto_unit.buf & 0177; /* ASCII... */
|
||||||
#endif
|
#endif
|
||||||
if (!(tto_unit.flags & UNIT_UC) ||
|
if (!(tto_unit.flags & UNIT_UC) ||
|
||||||
((out >= 007) && (out <= 0137))) {
|
((out >= 007) && (out <= 0137))) {
|
||||||
temp = sim_putcons (out, uptr);
|
temp = sim_putchar (out);
|
||||||
if (temp != SCPE_OK) return temp;
|
if (temp != SCPE_OK) return temp;
|
||||||
tto_unit.pos = tto_unit.pos + 1; }
|
tto_unit.pos = tto_unit.pos + 1; }
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
@ -784,8 +768,5 @@ tto_unit.buf = 0; /* clear buffer */
|
||||||
tto_state = 0; /* clear state */
|
tto_state = 0; /* clear state */
|
||||||
int_req = int_req & ~INT_TTO; /* clear flag */
|
int_req = int_req & ~INT_TTO; /* clear flag */
|
||||||
sim_cancel (&tto_unit); /* deactivate unit */
|
sim_cancel (&tto_unit); /* deactivate unit */
|
||||||
#if defined (TTY1)
|
|
||||||
tto_unit.filebuf = tto_consout;
|
|
||||||
#endif
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
10
pdp18b_sys.c
10
pdp18b_sys.c
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
17-Sep-01 RMS Removed multiconsole support
|
||||||
27-May-01 RMS Added second Teletype support
|
27-May-01 RMS Added second Teletype support
|
||||||
18-May-01 RMS Added PDP-9,-15 API IOT's
|
18-May-01 RMS Added PDP-9,-15 API IOT's
|
||||||
12-May-01 RMS Fixed bug in RIM loaders
|
12-May-01 RMS Fixed bug in RIM loaders
|
||||||
|
@ -117,15 +118,6 @@ DEVICE *sim_devices[] = { &cpu_dev,
|
||||||
#endif
|
#endif
|
||||||
NULL };
|
NULL };
|
||||||
|
|
||||||
#if defined (TTY1)
|
|
||||||
UNIT *sim_consoles[] = {
|
|
||||||
&tti_unit, &tto_unit,
|
|
||||||
&tti1_unit, &tto1_unit,
|
|
||||||
NULL };
|
|
||||||
#else
|
|
||||||
UNIT *sim_consoles = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const char *sim_stop_messages[] = {
|
const char *sim_stop_messages[] = {
|
||||||
"Unknown error",
|
"Unknown error",
|
||||||
"Undefined instruction",
|
"Undefined instruction",
|
||||||
|
|
127
pdp18b_tt1.c
127
pdp18b_tt1.c
|
@ -26,23 +26,32 @@
|
||||||
tti1 keyboard
|
tti1 keyboard
|
||||||
tto1 teleprinter
|
tto1 teleprinter
|
||||||
|
|
||||||
|
19-Sep-01 RMS Fixed typo
|
||||||
|
17-Sep-01 RMS Changed to use terminal multiplexor library
|
||||||
|
07-Sep-01 RMS Moved function prototypes
|
||||||
10-Jun-01 RMS Cleaned up IOT decoding to reflect hardware
|
10-Jun-01 RMS Cleaned up IOT decoding to reflect hardware
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pdp18b_defs.h"
|
#include "pdp18b_defs.h"
|
||||||
|
#include "sim_sock.h"
|
||||||
|
#include "sim_tmxr.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#define UNIT_V_UC (UNIT_V_UF + 0) /* UC only */
|
#define UNIT_V_UC (UNIT_V_UF + 0) /* UC only */
|
||||||
#define UNIT_UC (1 << UNIT_V_UC)
|
#define UNIT_UC (1 << UNIT_V_UC)
|
||||||
|
|
||||||
extern int32 int_req, saved_PC;
|
extern int32 int_req, saved_PC;
|
||||||
|
extern int32 tmxr_poll; /* calibrated poll */
|
||||||
|
TMLN tt1_ldsc = { 0 }; /* line descriptors */
|
||||||
|
TMXR tt_desc = { 1, 0, &tt1_ldsc }; /* mux descriptor */
|
||||||
|
|
||||||
t_stat tti1_svc (UNIT *uptr);
|
t_stat tti1_svc (UNIT *uptr);
|
||||||
t_stat tto1_svc (UNIT *uptr);
|
t_stat tto1_svc (UNIT *uptr);
|
||||||
t_stat tti1_reset (DEVICE *dptr);
|
t_stat tti1_reset (DEVICE *dptr);
|
||||||
t_stat tto1_reset (DEVICE *dptr);
|
t_stat tto1_reset (DEVICE *dptr);
|
||||||
extern t_stat sim_poll_kbd (void);
|
t_stat tti1_attach (UNIT *uptr, char *cptr);
|
||||||
extern t_stat sim_putchar (int32 out);
|
t_stat tti1_detach (UNIT *uptr);
|
||||||
static uint8 tto1_consout[CONS_SIZE];
|
t_stat tti1_status (UNIT *uptr, FILE *st);
|
||||||
|
|
||||||
/* TTI1 data structures
|
/* TTI1 data structures
|
||||||
|
|
||||||
|
@ -52,30 +61,28 @@ static uint8 tto1_consout[CONS_SIZE];
|
||||||
tti1_reg TTI1 register list
|
tti1_reg TTI1 register list
|
||||||
*/
|
*/
|
||||||
|
|
||||||
UNIT tti1_unit = { UDATA (&tti1_svc, UNIT_UC, 0), KBD_POLL_WAIT };
|
UNIT tti1_unit = { UDATA (&tti1_svc, UNIT_ATTABLE+UNIT_UC, 0), KBD_POLL_WAIT };
|
||||||
|
|
||||||
REG tti1_reg[] = {
|
REG tti1_reg[] = {
|
||||||
{ ORDATA (BUF, tti1_unit.buf, 8) },
|
{ ORDATA (BUF, tti1_unit.buf, 8) },
|
||||||
{ FLDATA (INT, int_req, INT_V_TTI1) },
|
{ FLDATA (INT, int_req, INT_V_TTI1) },
|
||||||
{ FLDATA (DONE, int_req, INT_V_TTI1) },
|
{ FLDATA (DONE, int_req, INT_V_TTI1) },
|
||||||
{ FLDATA (UC, tti1_unit.flags, UNIT_V_UC), REG_HRO },
|
{ FLDATA (UC, tti1_unit.flags, UNIT_V_UC), REG_HRO },
|
||||||
{ DRDATA (POS, tti1_unit.pos, 31), PV_LEFT },
|
{ DRDATA (POS, tt1_ldsc.rxcnt, 31), PV_LEFT },
|
||||||
{ DRDATA (TIME, tti1_unit.wait, 24), REG_NZ + PV_LEFT },
|
{ DRDATA (TIME, tti1_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||||
{ FLDATA (CFLAG, tti1_unit.flags, UNIT_V_CONS), REG_HRO },
|
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB tti1_mod[] = {
|
MTAB ttx1_mod[] = {
|
||||||
{ UNIT_CONS, 0, "inactive", NULL, NULL },
|
{ UNIT_ATT, UNIT_ATT, "line status:", NULL, &tti1_status },
|
||||||
{ UNIT_CONS, UNIT_CONS, "active console", "CONSOLE", &set_console },
|
|
||||||
{ UNIT_UC, 0, "lower case", "LC", NULL },
|
{ UNIT_UC, 0, "lower case", "LC", NULL },
|
||||||
{ UNIT_UC, UNIT_UC, "upper case", "UC", NULL },
|
{ UNIT_UC, UNIT_UC, "upper case", "UC", NULL },
|
||||||
{ 0 } };
|
{ 0 } };
|
||||||
|
|
||||||
DEVICE tti1_dev = {
|
DEVICE tti1_dev = {
|
||||||
"TTI1", &tti1_unit, tti1_reg, tti1_mod,
|
"TTI1", &tti1_unit, tti1_reg, ttx1_mod,
|
||||||
1, 10, 31, 1, 8, 8,
|
1, 10, 31, 1, 8, 8,
|
||||||
NULL, NULL, &tti1_reset,
|
&tmxr_ex, &tmxr_dep, &tti1_reset,
|
||||||
NULL, NULL, NULL };
|
NULL, &tti1_attach, &tti1_detach };
|
||||||
|
|
||||||
/* TTO1 data structures
|
/* TTO1 data structures
|
||||||
|
|
||||||
|
@ -91,21 +98,12 @@ REG tto1_reg[] = {
|
||||||
{ ORDATA (BUF, tto1_unit.buf, 8) },
|
{ ORDATA (BUF, tto1_unit.buf, 8) },
|
||||||
{ FLDATA (INT, int_req, INT_V_TTO1) },
|
{ FLDATA (INT, int_req, INT_V_TTO1) },
|
||||||
{ FLDATA (DONE, int_req, INT_V_TTO1) },
|
{ FLDATA (DONE, int_req, INT_V_TTO1) },
|
||||||
{ DRDATA (POS, tto1_unit.pos, 31), PV_LEFT },
|
{ DRDATA (POS, tt1_ldsc.txcnt, 31), PV_LEFT },
|
||||||
{ DRDATA (TIME, tto1_unit.wait, 24), PV_LEFT },
|
{ DRDATA (TIME, tto1_unit.wait, 24), PV_LEFT },
|
||||||
{ BRDATA (CONSOUT, tto1_consout, 8, 8, CONS_SIZE), REG_HIDDEN },
|
|
||||||
{ FLDATA (CFLAG, tto1_unit.flags, UNIT_V_CONS), REG_HRO },
|
|
||||||
{ NULL } };
|
{ NULL } };
|
||||||
|
|
||||||
MTAB tto1_mod[] = {
|
|
||||||
{ UNIT_CONS, 0, "inactive", NULL, NULL },
|
|
||||||
{ UNIT_CONS, UNIT_CONS, "active console", "CONSOLE", &set_console },
|
|
||||||
{ UNIT_UC, 0, "lower case", "LC", NULL },
|
|
||||||
{ UNIT_UC, UNIT_UC, "upper case", "UC", NULL },
|
|
||||||
{ 0 } };
|
|
||||||
|
|
||||||
DEVICE tto1_dev = {
|
DEVICE tto1_dev = {
|
||||||
"TTO1", &tto1_unit, tto1_reg, tto1_mod,
|
"TTO1", &tto1_unit, tto1_reg, ttx1_mod,
|
||||||
1, 10, 31, 1, 8, 8,
|
1, 10, 31, 1, 8, 8,
|
||||||
NULL, NULL, &tto1_reset,
|
NULL, NULL, &tto1_reset,
|
||||||
NULL, NULL, NULL };
|
NULL, NULL, NULL };
|
||||||
|
@ -126,15 +124,23 @@ return AC;
|
||||||
|
|
||||||
t_stat tti1_svc (UNIT *uptr)
|
t_stat tti1_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
int32 temp;
|
int32 temp, newln;
|
||||||
|
|
||||||
sim_activate (&tti1_unit, tti1_unit.wait); /* continue poll */
|
if (tt1_ldsc.conn) { /* connected? */
|
||||||
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */
|
tmxr_poll_rx (&tt_desc); /* poll for input */
|
||||||
temp = temp & 0177;
|
if (temp = tmxr_getc_ln (&tt1_ldsc)) { /* get char */
|
||||||
if ((tti1_unit.flags & UNIT_UC) && islower (temp)) temp = toupper (temp);
|
temp = temp & 0177;
|
||||||
tti1_unit.buf = temp | 0200; /* got char */
|
if ((uptr -> flags & UNIT_UC) &&
|
||||||
int_req = int_req | INT_TTI1; /* set flag */
|
islower (temp)) temp = toupper (temp);
|
||||||
tti1_unit.pos = tti1_unit.pos + 1;
|
uptr -> buf = temp | 0200; /* got char */
|
||||||
|
int_req = int_req | INT_TTI1; } /* set flag */
|
||||||
|
sim_activate (uptr, uptr -> wait); } /* continue poll */
|
||||||
|
if (uptr -> flags & UNIT_ATT) { /* attached? */
|
||||||
|
newln = tmxr_poll_conn (&tt_desc, uptr); /* poll connect */
|
||||||
|
if (newln >= 0) { /* got one? */
|
||||||
|
sim_activate (&tti1_unit, tti1_unit.wait);
|
||||||
|
tt1_ldsc.rcve = 1; } /* rcv enabled */
|
||||||
|
sim_activate (uptr, tmxr_poll); } /* sched poll */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,9 +149,13 @@ return SCPE_OK;
|
||||||
t_stat tti1_reset (DEVICE *dptr)
|
t_stat tti1_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
tti1_unit.buf = 0; /* clear buffer */
|
tti1_unit.buf = 0; /* clear buffer */
|
||||||
int_req = int_req & ~INT_TTI; /* clear flag */
|
int_req = int_req & ~INT_TTI1; /* clear flag */
|
||||||
if (tti1_unit.flags & UNIT_CONS) /* if active console */
|
if (tt1_ldsc.conn) { /* if conn, */
|
||||||
sim_activate (&tti1_unit, tti1_unit.wait); /* activate unit */
|
sim_activate (&tti1_unit, tti1_unit.wait); /* activate, */
|
||||||
|
tt1_ldsc.rcve = 1; } /* enable */
|
||||||
|
else if (tti1_unit.flags & UNIT_ATT) /* if attached, */
|
||||||
|
sim_activate (&tti1_unit, tmxr_poll); /* activate */
|
||||||
|
else sim_cancel (&tti1_unit); /* else stop */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,15 +176,19 @@ return AC;
|
||||||
|
|
||||||
t_stat tto1_svc (UNIT *uptr)
|
t_stat tto1_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
int32 out, temp;
|
int32 out;
|
||||||
|
|
||||||
int_req = int_req | INT_TTO1; /* set flag */
|
int_req = int_req | INT_TTO1; /* set flag */
|
||||||
out = tto1_unit.buf & 0177;
|
out = tto1_unit.buf & 0177;
|
||||||
if (!(tto1_unit.flags & UNIT_UC) ||
|
if (tt1_ldsc.conn) { /* connected? */
|
||||||
((out >= 007) && (out <= 0137))) {
|
if (tt1_ldsc.xmte) { /* tx enabled? */
|
||||||
temp = sim_putcons (out, uptr);
|
if (!(tto1_unit.flags & UNIT_UC) ||
|
||||||
if (temp != SCPE_OK) return temp;
|
((out >= 007) && (out <= 0137)))
|
||||||
tto1_unit.pos = tto1_unit.pos + 1; }
|
tmxr_putc_ln (&tt1_ldsc, out); /* output char */
|
||||||
|
tmxr_poll_tx (&tt_desc); } /* poll xmt */
|
||||||
|
else { tmxr_poll_tx (&tt_desc); /* poll xmt */
|
||||||
|
sim_activate (&tto1_unit, tmxr_poll); /* wait */
|
||||||
|
return SCPE_OK; } }
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,6 +199,37 @@ t_stat tto1_reset (DEVICE *dptr)
|
||||||
tto1_unit.buf = 0; /* clear buffer */
|
tto1_unit.buf = 0; /* clear buffer */
|
||||||
int_req = int_req & ~INT_TTO1; /* clear flag */
|
int_req = int_req & ~INT_TTO1; /* clear flag */
|
||||||
sim_cancel (&tto1_unit); /* deactivate unit */
|
sim_cancel (&tto1_unit); /* deactivate unit */
|
||||||
tto1_unit.filebuf = tto1_consout; /* set buf pointer */
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attach routine */
|
||||||
|
|
||||||
|
t_stat tti1_attach (UNIT *uptr, char *cptr)
|
||||||
|
{
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
r = tmxr_attach (&tt_desc, uptr, cptr); /* attach */
|
||||||
|
if (r != SCPE_OK) return r; /* error */
|
||||||
|
sim_activate (uptr, tmxr_poll); /* start poll */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Detach routine */
|
||||||
|
|
||||||
|
t_stat tti1_detach (UNIT *uptr)
|
||||||
|
{
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
r = tmxr_detach (&tt_desc, uptr); /* detach */
|
||||||
|
tt1_ldsc.rcve = 0; /* disable rcv */
|
||||||
|
sim_cancel (uptr); /* stop poll */
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Status routine */
|
||||||
|
|
||||||
|
t_stat tti1_status (UNIT *uptr, FILE *st)
|
||||||
|
{
|
||||||
|
tmxr_fstatus (st, &tt1_ldsc, -1);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
tti keyboard
|
tti keyboard
|
||||||
tto teleprinter
|
tto teleprinter
|
||||||
|
|
||||||
|
07-Sep-01 RMS Moved function prototypes
|
||||||
10-Jun-01 RMS Fixed comment
|
10-Jun-01 RMS Fixed comment
|
||||||
30-Oct-00 RMS Standardized device naming
|
30-Oct-00 RMS Standardized device naming
|
||||||
*/
|
*/
|
||||||
|
@ -55,8 +56,6 @@ t_stat ptp_reset (DEVICE *dptr);
|
||||||
t_stat tti_reset (DEVICE *dptr);
|
t_stat tti_reset (DEVICE *dptr);
|
||||||
t_stat tto_reset (DEVICE *dptr);
|
t_stat tto_reset (DEVICE *dptr);
|
||||||
t_stat ptr_boot (int32 unitno);
|
t_stat ptr_boot (int32 unitno);
|
||||||
extern t_stat sim_poll_kbd (void);
|
|
||||||
extern t_stat sim_putchar (int32 out);
|
|
||||||
|
|
||||||
/* Character translation tables */
|
/* Character translation tables */
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
17-Sep-01 RMS Removed multiconsole support
|
||||||
13-Jul-01 RMS Fixed RIM loader format
|
13-Jul-01 RMS Fixed RIM loader format
|
||||||
27-May-01 RMS Added multiconsole support
|
27-May-01 RMS Added multiconsole support
|
||||||
14-Mar-01 RMS Revised load/dump interface (again)
|
14-Mar-01 RMS Revised load/dump interface (again)
|
||||||
|
@ -52,7 +53,6 @@ extern int32 sc_map[];
|
||||||
sim_PC pointer to saved PC register descriptor
|
sim_PC pointer to saved PC register descriptor
|
||||||
sim_emax number of words for examine
|
sim_emax number of words for examine
|
||||||
sim_devices array of pointers to simulated devices
|
sim_devices array of pointers to simulated devices
|
||||||
sim_consoles array of pointers to consoles (if more than one)
|
|
||||||
sim_stop_messages array of pointers to stop messages
|
sim_stop_messages array of pointers to stop messages
|
||||||
sim_load binary loader
|
sim_load binary loader
|
||||||
*/
|
*/
|
||||||
|
@ -67,8 +67,6 @@ DEVICE *sim_devices[] = { &cpu_dev,
|
||||||
&ptr_dev, &ptp_dev, &tti_dev, &tto_dev,
|
&ptr_dev, &ptp_dev, &tti_dev, &tto_dev,
|
||||||
&lpt_dev, NULL };
|
&lpt_dev, NULL };
|
||||||
|
|
||||||
UNIT *sim_consoles = NULL;
|
|
||||||
|
|
||||||
const char *sim_stop_messages[] = {
|
const char *sim_stop_messages[] = {
|
||||||
"Unknown error",
|
"Unknown error",
|
||||||
"Undefined instruction",
|
"Undefined instruction",
|
||||||
|
|
11
pdp8_clk.c
11
pdp8_clk.c
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
clk real time clock
|
clk real time clock
|
||||||
|
|
||||||
|
05-Sep-01 RMS Added terminal multiplexor support
|
||||||
17-Jul-01 RMS Moved function prototype
|
17-Jul-01 RMS Moved function prototype
|
||||||
05-Mar-01 RMS Added clock calibration support
|
05-Mar-01 RMS Added clock calibration support
|
||||||
|
|
||||||
|
@ -36,7 +37,8 @@
|
||||||
extern int32 int_req, int_enable, dev_done, stop_inst;
|
extern int32 int_req, int_enable, dev_done, stop_inst;
|
||||||
t_stat clk_svc (UNIT *uptr);
|
t_stat clk_svc (UNIT *uptr);
|
||||||
t_stat clk_reset (DEVICE *dptr);
|
t_stat clk_reset (DEVICE *dptr);
|
||||||
int32 clk_tps = 60;
|
int32 clk_tps = 60; /* ticks/second */
|
||||||
|
int32 tmxr_poll = 16000; /* term mux poll */
|
||||||
|
|
||||||
/* CLK data structures
|
/* CLK data structures
|
||||||
|
|
||||||
|
@ -103,9 +105,13 @@ default:
|
||||||
|
|
||||||
t_stat clk_svc (UNIT *uptr)
|
t_stat clk_svc (UNIT *uptr)
|
||||||
{
|
{
|
||||||
|
int32 t;
|
||||||
|
|
||||||
dev_done = dev_done | INT_CLK; /* set done */
|
dev_done = dev_done | INT_CLK; /* set done */
|
||||||
int_req = INT_UPDATE; /* update interrupts */
|
int_req = INT_UPDATE; /* update interrupts */
|
||||||
sim_activate (&clk_unit, sim_rtc_calb (clk_tps)); /* reactivate unit */
|
t = sim_rtc_calb (clk_tps); /* calibrate clock */
|
||||||
|
sim_activate (&clk_unit, t); /* reactivate unit */
|
||||||
|
tmxr_poll = t; /* set mux poll */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,5 +123,6 @@ dev_done = dev_done & ~INT_CLK; /* clear done, int */
|
||||||
int_req = int_req & ~INT_CLK;
|
int_req = int_req & ~INT_CLK;
|
||||||
int_enable = int_enable & ~INT_CLK; /* clear enable */
|
int_enable = int_enable & ~INT_CLK; /* clear enable */
|
||||||
sim_activate (&clk_unit, clk_unit.wait); /* activate unit */
|
sim_activate (&clk_unit, clk_unit.wait); /* activate unit */
|
||||||
|
tmxr_poll = clk_unit.wait; /* set mux poll */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
11
pdp8_cpu.c
11
pdp8_cpu.c
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
cpu central processor
|
cpu central processor
|
||||||
|
|
||||||
|
16-Sep-01 RMS Fixed bug in reset routine, added KL8A support
|
||||||
10-Aug-01 RMS Removed register from declarations
|
10-Aug-01 RMS Removed register from declarations
|
||||||
17-Jul-01 RMS Moved function prototype
|
17-Jul-01 RMS Moved function prototype
|
||||||
07-Jun-01 RMS Fixed bug in JMS to non-existent memory
|
07-Jun-01 RMS Fixed bug in JMS to non-existent memory
|
||||||
|
@ -284,6 +285,8 @@ extern int32 ptr (int32 pulse, int32 AC);
|
||||||
extern int32 ptp (int32 pulse, int32 AC);
|
extern int32 ptp (int32 pulse, int32 AC);
|
||||||
extern int32 clk (int32 pulse, int32 AC);
|
extern int32 clk (int32 pulse, int32 AC);
|
||||||
extern int32 lpt (int32 pulse, int32 AC);
|
extern int32 lpt (int32 pulse, int32 AC);
|
||||||
|
extern int32 ttix (int32 inst, int32 AC);
|
||||||
|
extern int32 ttox (int32 inst, int32 AC);
|
||||||
extern int32 rk (int32 pulse, int32 AC);
|
extern int32 rk (int32 pulse, int32 AC);
|
||||||
extern int32 rx (int32 pulse, int32 AC);
|
extern int32 rx (int32 pulse, int32 AC);
|
||||||
extern int32 df60 (int32 pulse, int32 AC);
|
extern int32 df60 (int32 pulse, int32 AC);
|
||||||
|
@ -1018,6 +1021,12 @@ case 030:case 031:case 032:case 033: /* IOT */
|
||||||
case 013: /* CLK */
|
case 013: /* CLK */
|
||||||
iot_data = clk (pulse, iot_data);
|
iot_data = clk (pulse, iot_data);
|
||||||
break;
|
break;
|
||||||
|
case 040: case 042: case 044: case 046: /* KL8A in */
|
||||||
|
iot_data = ttix (IR, iot_data);
|
||||||
|
break;
|
||||||
|
case 041: case 043: case 045: case 047: /* KL8A out */
|
||||||
|
iot_data = ttox (IR, iot_data);
|
||||||
|
break;
|
||||||
case 060: /* DF32/RF08 */
|
case 060: /* DF32/RF08 */
|
||||||
if (dev_enb & INT_DF) iot_data = df60 (pulse, iot_data);
|
if (dev_enb & INT_DF) iot_data = df60 (pulse, iot_data);
|
||||||
else if (dev_enb & INT_RF) iot_data = rf60 (pulse, iot_data);
|
else if (dev_enb & INT_RF) iot_data = rf60 (pulse, iot_data);
|
||||||
|
@ -1087,7 +1096,7 @@ return reason;
|
||||||
t_stat cpu_reset (DEVICE *dptr)
|
t_stat cpu_reset (DEVICE *dptr)
|
||||||
{
|
{
|
||||||
int_req = (int_req & ~INT_ION) | INT_NO_CIF_PENDING;
|
int_req = (int_req & ~INT_ION) | INT_NO_CIF_PENDING;
|
||||||
saved_DF = IB = (saved_PC >> 12) & 03;
|
saved_DF = IB = saved_PC & 070000;
|
||||||
UF = UB = gtf = emode = 0;
|
UF = UB = gtf = emode = 0;
|
||||||
return cpu_svc (&cpu_unit);
|
return cpu_svc (&cpu_unit);
|
||||||
}
|
}
|
||||||
|
|
22
pdp8_defs.h
22
pdp8_defs.h
|
@ -23,6 +23,7 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
16-Sep-01 RMS Added multiple KL support
|
||||||
18-Mar-01 RMS Added DF32 support
|
18-Mar-01 RMS Added DF32 support
|
||||||
15-Feb-01 RMS Added DECtape support
|
15-Feb-01 RMS Added DECtape support
|
||||||
14-Apr-99 RMS Changed t_addr to unsigned
|
14-Apr-99 RMS Changed t_addr to unsigned
|
||||||
|
@ -73,6 +74,9 @@
|
||||||
|
|
||||||
Because the PDP-8 does not have priority interrupts, the order
|
Because the PDP-8 does not have priority interrupts, the order
|
||||||
of devices within groups does not matter.
|
of devices within groups does not matter.
|
||||||
|
|
||||||
|
Note: all extra KL input and output interrupts must be assigned
|
||||||
|
to contiguous bits.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define INT_V_START 0 /* enable start */
|
#define INT_V_START 0 /* enable start */
|
||||||
|
@ -82,7 +86,15 @@
|
||||||
#define INT_V_TTO (INT_V_START+3) /* terminal */
|
#define INT_V_TTO (INT_V_START+3) /* terminal */
|
||||||
#define INT_V_TTI (INT_V_START+4) /* keyboard */
|
#define INT_V_TTI (INT_V_START+4) /* keyboard */
|
||||||
#define INT_V_CLK (INT_V_START+5) /* clock */
|
#define INT_V_CLK (INT_V_START+5) /* clock */
|
||||||
#define INT_V_DIRECT (INT_V_START+6) /* direct start */
|
#define INT_V_TTO1 (INT_V_START+6) /* tto1 */
|
||||||
|
#define INT_V_TTO2 (INT_V_START+7) /* tto2 */
|
||||||
|
#define INT_V_TTO3 (INT_V_START+8) /* tto3 */
|
||||||
|
#define INT_V_TTO4 (INT_V_START+9) /* tto4 */
|
||||||
|
#define INT_V_TTI1 (INT_V_START+10) /* tti1 */
|
||||||
|
#define INT_V_TTI2 (INT_V_START+11) /* tti2 */
|
||||||
|
#define INT_V_TTI3 (INT_V_START+12) /* tti3 */
|
||||||
|
#define INT_V_TTI4 (INT_V_START+13) /* tti4 */
|
||||||
|
#define INT_V_DIRECT (INT_V_START+14) /* direct start */
|
||||||
#define INT_V_RX (INT_V_DIRECT+0) /* RX8E */
|
#define INT_V_RX (INT_V_DIRECT+0) /* RX8E */
|
||||||
#define INT_V_RK (INT_V_DIRECT+1) /* RK8E */
|
#define INT_V_RK (INT_V_DIRECT+1) /* RK8E */
|
||||||
#define INT_V_RF (INT_V_DIRECT+2) /* RF08 */
|
#define INT_V_RF (INT_V_DIRECT+2) /* RF08 */
|
||||||
|
@ -102,6 +114,14 @@
|
||||||
#define INT_TTO (1 << INT_V_TTO)
|
#define INT_TTO (1 << INT_V_TTO)
|
||||||
#define INT_TTI (1 << INT_V_TTI)
|
#define INT_TTI (1 << INT_V_TTI)
|
||||||
#define INT_CLK (1 << INT_V_CLK)
|
#define INT_CLK (1 << INT_V_CLK)
|
||||||
|
#define INT_TTO1 (1 << INT_V_TTO1)
|
||||||
|
#define INT_TTO2 (1 << INT_V_TTO2)
|
||||||
|
#define INT_TTO3 (1 << INT_V_TTO3)
|
||||||
|
#define INT_TTO4 (1 << INT_V_TTO4)
|
||||||
|
#define INT_TTI1 (1 << INT_V_TTI1)
|
||||||
|
#define INT_TTI2 (1 << INT_V_TTI2)
|
||||||
|
#define INT_TTI3 (1 << INT_V_TTI3)
|
||||||
|
#define INT_TTI4 (1 << INT_V_TTI4)
|
||||||
#define INT_RX (1 << INT_V_RX)
|
#define INT_RX (1 << INT_V_RX)
|
||||||
#define INT_RK (1 << INT_V_RK)
|
#define INT_RK (1 << INT_V_RK)
|
||||||
#define INT_RF (1 << INT_V_RF)
|
#define INT_RF (1 << INT_V_RF)
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
dt TC08/TU56 DECtape
|
dt TC08/TU56 DECtape
|
||||||
|
|
||||||
|
29-Aug-01 RMS Added casts to PDP-18b packup routine
|
||||||
17-Jul-01 RMS Moved function prototype
|
17-Jul-01 RMS Moved function prototype
|
||||||
11-May-01 RMS Fixed bug in reset
|
11-May-01 RMS Fixed bug in reset
|
||||||
25-Apr-01 RMS Added device enable/disable support
|
25-Apr-01 RMS Added device enable/disable support
|
||||||
|
@ -1130,10 +1131,10 @@ if (uptr -> hwmark) { /* any data? */
|
||||||
else { /* PDP9/11/15 */
|
else { /* PDP9/11/15 */
|
||||||
for (ba = 0; ba < uptr -> hwmark; ) { /* loop thru buf */
|
for (ba = 0; ba < uptr -> hwmark; ) { /* loop thru buf */
|
||||||
for (k = 0; k < D18_NBSIZE; k = k + 2) {
|
for (k = 0; k < D18_NBSIZE; k = k + 2) {
|
||||||
pdp18b[k] = ((bptr[ba] & 07777) << 6) |
|
pdp18b[k] = ((uint32) (bptr[ba] & 07777) << 6) |
|
||||||
((bptr[ba + 1] >> 6) & 077);
|
((uint32) (bptr[ba + 1] >> 6) & 077);
|
||||||
pdp18b[k + 1] = ((bptr[ba + 1] & 077) << 12) |
|
pdp18b[k + 1] = ((uint32) (bptr[ba + 1] & 077) << 12) |
|
||||||
(bptr[ba + 2] & 07777);
|
((uint32) (bptr[ba + 2] & 07777));
|
||||||
ba = ba + 3; } /* end loop blk */
|
ba = ba + 3; } /* end loop blk */
|
||||||
fxwrite (pdp18b, sizeof (int32),
|
fxwrite (pdp18b, sizeof (int32),
|
||||||
D18_NBSIZE, uptr -> fileref);
|
D18_NBSIZE, uptr -> fileref);
|
||||||
|
|
22
pdp8_sys.c
22
pdp8_sys.c
|
@ -23,6 +23,8 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
17-Sep-01 RMS Removed multiconsole support
|
||||||
|
16-Sep-01 RMS Added TSS/8 packed char support, added KL8A support
|
||||||
27-May-01 RMS Added multiconsole support
|
27-May-01 RMS Added multiconsole support
|
||||||
18-Mar-01 RMS Added DF32 support
|
18-Mar-01 RMS Added DF32 support
|
||||||
14-Mar-01 RMS Added extension detection of RIM binary tapes
|
14-Mar-01 RMS Added extension detection of RIM binary tapes
|
||||||
|
@ -44,6 +46,10 @@ extern DEVICE clk_dev, lpt_dev;
|
||||||
extern DEVICE rk_dev, rx_dev;
|
extern DEVICE rk_dev, rx_dev;
|
||||||
extern DEVICE df_dev, rf_dev;
|
extern DEVICE df_dev, rf_dev;
|
||||||
extern DEVICE dt_dev, mt_dev;
|
extern DEVICE dt_dev, mt_dev;
|
||||||
|
extern DEVICE tti1_dev, tto1_dev;
|
||||||
|
extern DEVICE tti2_dev, tto2_dev;
|
||||||
|
extern DEVICE tti3_dev, tto3_dev;
|
||||||
|
extern DEVICE tti4_dev, tto4_dev;
|
||||||
extern REG cpu_reg[];
|
extern REG cpu_reg[];
|
||||||
extern uint16 M[];
|
extern uint16 M[];
|
||||||
extern int32 sim_switches;
|
extern int32 sim_switches;
|
||||||
|
@ -69,14 +75,16 @@ DEVICE *sim_devices[] = {
|
||||||
&cpu_dev,
|
&cpu_dev,
|
||||||
&ptr_dev, &ptp_dev,
|
&ptr_dev, &ptp_dev,
|
||||||
&tti_dev, &tto_dev,
|
&tti_dev, &tto_dev,
|
||||||
|
&tti1_dev, &tto1_dev,
|
||||||
|
&tti2_dev, &tto2_dev,
|
||||||
|
&tti3_dev, &tto3_dev,
|
||||||
|
&tti4_dev, &tto4_dev,
|
||||||
&clk_dev, &lpt_dev,
|
&clk_dev, &lpt_dev,
|
||||||
&rk_dev, &rx_dev,
|
&rk_dev, &rx_dev,
|
||||||
&df_dev, &rf_dev,
|
&df_dev, &rf_dev,
|
||||||
&dt_dev, &mt_dev,
|
&dt_dev, &mt_dev,
|
||||||
NULL };
|
NULL };
|
||||||
|
|
||||||
UNIT *sim_consoles = NULL;
|
|
||||||
|
|
||||||
const char *sim_stop_messages[] = {
|
const char *sim_stop_messages[] = {
|
||||||
"Unknown error",
|
"Unknown error",
|
||||||
"Unimplemented instruction",
|
"Unimplemented instruction",
|
||||||
|
@ -333,6 +341,7 @@ return sp;
|
||||||
|
|
||||||
#define FMTASC(x) ((x) < 040)? "<%03o>": "%c", (x)
|
#define FMTASC(x) ((x) < 040)? "<%03o>": "%c", (x)
|
||||||
#define SIXTOASC(x) (((x) >= 040)? (x): (x) + 0100)
|
#define SIXTOASC(x) (((x) >= 040)? (x): (x) + 0100)
|
||||||
|
#define TSSTOASC(x) ((x) + 040)
|
||||||
|
|
||||||
t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
|
t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
|
||||||
UNIT *uptr, int32 sw)
|
UNIT *uptr, int32 sw)
|
||||||
|
@ -350,6 +359,10 @@ if (sw & SWMASK ('C')) { /* characters? */
|
||||||
fprintf (of, "%c", SIXTOASC ((inst >> 6) & 077));
|
fprintf (of, "%c", SIXTOASC ((inst >> 6) & 077));
|
||||||
fprintf (of, "%c", SIXTOASC (inst & 077));
|
fprintf (of, "%c", SIXTOASC (inst & 077));
|
||||||
return SCPE_OK; }
|
return SCPE_OK; }
|
||||||
|
if (sw & SWMASK ('T')) { /* TSS8 packed? */
|
||||||
|
fprintf (of, "%c", TSSTOASC ((inst >> 6) & 077));
|
||||||
|
fprintf (of, "%c", TSSTOASC (inst & 077));
|
||||||
|
return SCPE_OK; }
|
||||||
if (!(sw & SWMASK ('M'))) return SCPE_ARG;
|
if (!(sw & SWMASK ('M'))) return SCPE_ARG;
|
||||||
|
|
||||||
/* Instruction decode */
|
/* Instruction decode */
|
||||||
|
@ -423,6 +436,11 @@ if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* sixbit string? */
|
||||||
val[0] = (((t_value) cptr[0] & 077) << 6) |
|
val[0] = (((t_value) cptr[0] & 077) << 6) |
|
||||||
((t_value) cptr[1] & 077);
|
((t_value) cptr[1] & 077);
|
||||||
return SCPE_OK; }
|
return SCPE_OK; }
|
||||||
|
if ((sw & SWMASK ('T')) || ((*cptr == '"') && cptr++)) { /* TSS8 string? */
|
||||||
|
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
|
||||||
|
val[0] = (((t_value) (cptr[0] - 040) & 077) << 6) |
|
||||||
|
((t_value) (cptr[1] - 040) & 077);
|
||||||
|
return SCPE_OK; }
|
||||||
|
|
||||||
/* Instruction parse */
|
/* Instruction parse */
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
tti,tto KL8E terminal input/output
|
tti,tto KL8E terminal input/output
|
||||||
|
|
||||||
|
07-Sep-01 RMS Moved function prototypes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pdp8_defs.h"
|
#include "pdp8_defs.h"
|
||||||
|
@ -36,8 +38,6 @@ t_stat tti_svc (UNIT *uptr);
|
||||||
t_stat tto_svc (UNIT *uptr);
|
t_stat tto_svc (UNIT *uptr);
|
||||||
t_stat tti_reset (DEVICE *dptr);
|
t_stat tti_reset (DEVICE *dptr);
|
||||||
t_stat tto_reset (DEVICE *dptr);
|
t_stat tto_reset (DEVICE *dptr);
|
||||||
extern t_stat sim_poll_kbd (void);
|
|
||||||
extern t_stat sim_putchar (int32 out);
|
|
||||||
|
|
||||||
/* TTI data structures
|
/* TTI data structures
|
||||||
|
|
||||||
|
|
423
pdp8_ttx.c
Normal file
423
pdp8_ttx.c
Normal file
|
@ -0,0 +1,423 @@
|
||||||
|
/* pdp8_ttx.c: PDP-8 additional terminals simulator
|
||||||
|
|
||||||
|
Copyright (c) 1993-2001, 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.
|
||||||
|
|
||||||
|
ttix,ttox PT08/KL8JA terminal input/output
|
||||||
|
|
||||||
|
This module implements four individual serial interfaces similar in function
|
||||||
|
to the console. These interfaces are mapped to Telnet based connections as
|
||||||
|
though they were the four lines of a terminal multiplexor. The connection
|
||||||
|
polling mechanism is superimposed onto the keyboard of the first interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pdp8_defs.h"
|
||||||
|
#include "sim_sock.h"
|
||||||
|
#include "sim_tmxr.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#define TTX_LINES 4
|
||||||
|
#define TTX_MASK (TTX_LINES - 1)
|
||||||
|
#define UNIT_V_UC (UNIT_V_UF + 0) /* UC only */
|
||||||
|
#define UNIT_UC (1 << UNIT_V_UC)
|
||||||
|
#define TTX_GETLN(x) (((x) >> 4) & TTX_MASK)
|
||||||
|
|
||||||
|
extern int32 int_req, int_enable, dev_done, stop_inst;
|
||||||
|
extern int32 tmxr_poll; /* calibrated poll */
|
||||||
|
TMLN tt1_ldsc = { 0 }; /* line descriptors */
|
||||||
|
TMLN tt2_ldsc = { 0 }; /* line descriptors */
|
||||||
|
TMLN tt3_ldsc = { 0 }; /* line descriptors */
|
||||||
|
TMLN tt4_ldsc = { 0 }; /* line descriptors */
|
||||||
|
|
||||||
|
TMXR ttx_desc = { /* mux descriptor */
|
||||||
|
TTX_LINES, 0, &tt1_ldsc, &tt2_ldsc, &tt3_ldsc, &tt4_ldsc };
|
||||||
|
|
||||||
|
t_stat ttix_svc (UNIT *uptr);
|
||||||
|
t_stat ttix_reset (DEVICE *dptr);
|
||||||
|
t_stat ttox_svc (UNIT *uptr);
|
||||||
|
t_stat ttox_reset (DEVICE *dptr);
|
||||||
|
t_stat ttx_attach (UNIT *uptr, char *cptr);
|
||||||
|
t_stat ttx_detach (UNIT *uptr);
|
||||||
|
t_stat ttx_status (UNIT *uptr, FILE *st);
|
||||||
|
|
||||||
|
/* TTIx data structures
|
||||||
|
|
||||||
|
ttix_dev TTIx device descriptor
|
||||||
|
ttix_unit TTIx unit descriptor
|
||||||
|
ttix_reg TTIx register list
|
||||||
|
ttix_mod TTIx modifiers list
|
||||||
|
*/
|
||||||
|
|
||||||
|
MTAB ttix_mod[] = {
|
||||||
|
{ UNIT_UC, 0, "lower case", "LC", NULL },
|
||||||
|
{ UNIT_UC, UNIT_UC, "upper case", "UC", NULL },
|
||||||
|
{ UNIT_ATT, UNIT_ATT, "line status:", NULL, &ttx_status },
|
||||||
|
{ 0 } };
|
||||||
|
|
||||||
|
UNIT ttix_unit[] = {
|
||||||
|
{ UDATA (&ttix_svc, UNIT_ATTABLE+UNIT_UC, 0), KBD_POLL_WAIT },
|
||||||
|
{ UDATA (&ttix_svc, UNIT_UC, 0), KBD_POLL_WAIT },
|
||||||
|
{ UDATA (&ttix_svc, UNIT_UC, 0), KBD_POLL_WAIT },
|
||||||
|
{ UDATA (&ttix_svc, UNIT_UC, 0), KBD_POLL_WAIT } };
|
||||||
|
|
||||||
|
#define tti1_unit ttix_unit[0]
|
||||||
|
#define tti2_unit ttix_unit[1]
|
||||||
|
#define tti3_unit ttix_unit[2]
|
||||||
|
#define tti4_unit ttix_unit[3]
|
||||||
|
|
||||||
|
REG tti1_reg[] = {
|
||||||
|
{ ORDATA (BUF, tti1_unit.buf, 8) },
|
||||||
|
{ FLDATA (DONE, dev_done, INT_V_TTI1) },
|
||||||
|
{ FLDATA (ENABLE, int_enable, INT_V_TTI1) },
|
||||||
|
{ FLDATA (INT, int_req, INT_V_TTI1) },
|
||||||
|
{ DRDATA (POS, tt1_ldsc.rxcnt, 32), PV_LEFT },
|
||||||
|
{ DRDATA (TIME, tti1_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||||
|
{ FLDATA (UC, tti1_unit.flags, UNIT_V_UC), REG_HRO },
|
||||||
|
{ NULL } };
|
||||||
|
|
||||||
|
DEVICE tti1_dev = {
|
||||||
|
"TTI1", &tti1_unit, tti1_reg, ttix_mod,
|
||||||
|
1, 10, 31, 1, 8, 8,
|
||||||
|
&tmxr_ex, &tmxr_dep, &ttix_reset,
|
||||||
|
NULL, &ttx_attach, &ttx_detach };
|
||||||
|
|
||||||
|
REG tti2_reg[] = {
|
||||||
|
{ ORDATA (BUF, tti2_unit.buf, 8) },
|
||||||
|
{ FLDATA (DONE, dev_done, INT_V_TTI2) },
|
||||||
|
{ FLDATA (ENABLE, int_enable, INT_V_TTI2) },
|
||||||
|
{ FLDATA (INT, int_req, INT_V_TTI2) },
|
||||||
|
{ DRDATA (POS, tt2_ldsc.rxcnt, 32), PV_LEFT },
|
||||||
|
{ DRDATA (TIME, tti2_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||||
|
{ FLDATA (UC, tti2_unit.flags, UNIT_V_UC), REG_HRO },
|
||||||
|
{ NULL } };
|
||||||
|
|
||||||
|
DEVICE tti2_dev = {
|
||||||
|
"TTI2", &tti2_unit, tti2_reg, ttix_mod,
|
||||||
|
1, 10, 31, 1, 8, 8,
|
||||||
|
NULL, NULL, &ttix_reset,
|
||||||
|
NULL, NULL, NULL };
|
||||||
|
|
||||||
|
REG tti3_reg[] = {
|
||||||
|
{ ORDATA (BUF, tti3_unit.buf, 8) },
|
||||||
|
{ FLDATA (DONE, dev_done, INT_V_TTI3) },
|
||||||
|
{ FLDATA (ENABLE, int_enable, INT_V_TTI3) },
|
||||||
|
{ FLDATA (INT, int_req, INT_V_TTI3) },
|
||||||
|
{ DRDATA (POS, tt3_ldsc.rxcnt, 32), PV_LEFT },
|
||||||
|
{ DRDATA (TIME, tti3_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||||
|
{ FLDATA (UC, tti3_unit.flags, UNIT_V_UC), REG_HRO },
|
||||||
|
{ NULL } };
|
||||||
|
|
||||||
|
DEVICE tti3_dev = {
|
||||||
|
"TTI3", &tti3_unit, tti3_reg, ttix_mod,
|
||||||
|
1, 10, 31, 1, 8, 8,
|
||||||
|
NULL, NULL, &ttix_reset,
|
||||||
|
NULL, NULL, NULL };
|
||||||
|
|
||||||
|
REG tti4_reg[] = {
|
||||||
|
{ ORDATA (BUF, tti4_unit.buf, 8) },
|
||||||
|
{ FLDATA (DONE, dev_done, INT_V_TTI4) },
|
||||||
|
{ FLDATA (ENABLE, int_enable, INT_V_TTI4) },
|
||||||
|
{ FLDATA (INT, int_req, INT_V_TTI4) },
|
||||||
|
{ DRDATA (POS, tt4_ldsc.rxcnt, 32), PV_LEFT },
|
||||||
|
{ DRDATA (TIME, tti4_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||||
|
{ FLDATA (UC, tti4_unit.flags, UNIT_V_UC), REG_HRO },
|
||||||
|
{ NULL } };
|
||||||
|
|
||||||
|
DEVICE tti4_dev = {
|
||||||
|
"TTI4", &tti4_unit, tti4_reg, ttix_mod,
|
||||||
|
1, 10, 31, 1, 8, 8,
|
||||||
|
NULL, NULL, &ttix_reset,
|
||||||
|
NULL, NULL, NULL };
|
||||||
|
|
||||||
|
/* TTOx data structures
|
||||||
|
|
||||||
|
ttox_dev TTOx device descriptor
|
||||||
|
ttox_unit TTOx unit descriptor
|
||||||
|
ttox_reg TTOx register list
|
||||||
|
*/
|
||||||
|
|
||||||
|
UNIT ttox_unit[] = {
|
||||||
|
{ UDATA (&ttox_svc, 0, 0), SERIAL_OUT_WAIT },
|
||||||
|
{ UDATA (&ttox_svc, 0, 0), SERIAL_OUT_WAIT },
|
||||||
|
{ UDATA (&ttox_svc, 0, 0), SERIAL_OUT_WAIT },
|
||||||
|
{ UDATA (&ttox_svc, 0, 0), SERIAL_OUT_WAIT } };
|
||||||
|
|
||||||
|
#define tto1_unit ttox_unit[0]
|
||||||
|
#define tto2_unit ttox_unit[0]
|
||||||
|
#define tto3_unit ttox_unit[0]
|
||||||
|
#define tto4_unit ttox_unit[0]
|
||||||
|
|
||||||
|
REG tto1_reg[] = {
|
||||||
|
{ ORDATA (BUF, tto1_unit.buf, 8) },
|
||||||
|
{ FLDATA (DONE, dev_done, INT_V_TTO1) },
|
||||||
|
{ FLDATA (ENABLE, int_enable, INT_V_TTO1) },
|
||||||
|
{ FLDATA (INT, int_req, INT_V_TTO1) },
|
||||||
|
{ DRDATA (POS, tt1_ldsc.txcnt, 32), PV_LEFT },
|
||||||
|
{ DRDATA (TIME, tto1_unit.wait, 24), PV_LEFT },
|
||||||
|
{ NULL } };
|
||||||
|
|
||||||
|
DEVICE tto1_dev = {
|
||||||
|
"TTO1", &tto1_unit, tto1_reg, NULL,
|
||||||
|
1, 10, 31, 1, 8, 8,
|
||||||
|
NULL, NULL, &ttox_reset,
|
||||||
|
NULL, NULL, NULL };
|
||||||
|
|
||||||
|
REG tto2_reg[] = {
|
||||||
|
{ ORDATA (BUF, tto2_unit.buf, 8) },
|
||||||
|
{ FLDATA (DONE, dev_done, INT_V_TTO2) },
|
||||||
|
{ FLDATA (ENABLE, int_enable, INT_V_TTO2) },
|
||||||
|
{ FLDATA (INT, int_req, INT_V_TTO2) },
|
||||||
|
{ DRDATA (POS, tt2_ldsc.txcnt, 32), PV_LEFT },
|
||||||
|
{ DRDATA (TIME, tto2_unit.wait, 24), PV_LEFT },
|
||||||
|
{ NULL } };
|
||||||
|
|
||||||
|
DEVICE tto2_dev = {
|
||||||
|
"TTO2", &tto2_unit, tto2_reg, NULL,
|
||||||
|
1, 10, 31, 1, 8, 8,
|
||||||
|
NULL, NULL, &ttox_reset,
|
||||||
|
NULL, NULL, NULL };
|
||||||
|
|
||||||
|
REG tto3_reg[] = {
|
||||||
|
{ ORDATA (BUF, tto3_unit.buf, 8) },
|
||||||
|
{ FLDATA (DONE, dev_done, INT_V_TTO3) },
|
||||||
|
{ FLDATA (ENABLE, int_enable, INT_V_TTO3) },
|
||||||
|
{ FLDATA (INT, int_req, INT_V_TTO3) },
|
||||||
|
{ DRDATA (POS, tt3_ldsc.txcnt, 32), PV_LEFT },
|
||||||
|
{ DRDATA (TIME, tto3_unit.wait, 24), PV_LEFT },
|
||||||
|
{ NULL } };
|
||||||
|
|
||||||
|
DEVICE tto3_dev = {
|
||||||
|
"TTO3", &tto3_unit, tto3_reg, NULL,
|
||||||
|
1, 10, 31, 1, 8, 8,
|
||||||
|
NULL, NULL, &ttox_reset,
|
||||||
|
NULL, NULL, NULL };
|
||||||
|
|
||||||
|
REG tto4_reg[] = {
|
||||||
|
{ ORDATA (BUF, tto4_unit.buf, 8) },
|
||||||
|
{ FLDATA (DONE, dev_done, INT_V_TTO4) },
|
||||||
|
{ FLDATA (ENABLE, int_enable, INT_V_TTO4) },
|
||||||
|
{ FLDATA (INT, int_req, INT_V_TTO4) },
|
||||||
|
{ DRDATA (POS, tt4_ldsc.txcnt, 32), PV_LEFT },
|
||||||
|
{ DRDATA (TIME, tto4_unit.wait, 24), PV_LEFT },
|
||||||
|
{ NULL } };
|
||||||
|
|
||||||
|
DEVICE tto4_dev = {
|
||||||
|
"TTO4", &tto4_unit, tto4_reg, NULL,
|
||||||
|
1, 10, 31, 1, 8, 8,
|
||||||
|
NULL, NULL, &ttox_reset,
|
||||||
|
NULL, NULL, NULL };
|
||||||
|
|
||||||
|
/* Terminal input: IOT routine */
|
||||||
|
|
||||||
|
int32 ttix (int32 inst, int32 AC)
|
||||||
|
{
|
||||||
|
int32 pulse = inst & 07; /* IOT pulse */
|
||||||
|
int32 ln = TTX_GETLN (inst); /* line # */
|
||||||
|
int32 itti = (INT_TTI1 << ln); /* rx intr */
|
||||||
|
int32 itto = (INT_TTO1 << ln); /* tx intr */
|
||||||
|
|
||||||
|
switch (pulse) { /* case IR<9:11> */
|
||||||
|
case 0: /* KCF */
|
||||||
|
dev_done = dev_done & ~itti; /* clear flag */
|
||||||
|
int_req = int_req & ~itti;
|
||||||
|
break;
|
||||||
|
case 1: /* KSF */
|
||||||
|
return (dev_done & itti)? IOT_SKP + AC: AC;
|
||||||
|
case 2: /* KCC */
|
||||||
|
dev_done = dev_done & ~itti; /* clear flag */
|
||||||
|
int_req = int_req & ~itti;
|
||||||
|
return 0; /* clear AC */
|
||||||
|
case 4: /* KRS */
|
||||||
|
return (AC | ttix_unit[ln].buf); /* return buf */
|
||||||
|
case 5: /* KIE */
|
||||||
|
if (AC & 1) int_enable = int_enable | (itti + itto);
|
||||||
|
else int_enable = int_enable & ~(itti + itto);
|
||||||
|
int_req = INT_UPDATE; /* update intr */
|
||||||
|
break;
|
||||||
|
case 6: /* KRB */
|
||||||
|
dev_done = dev_done & ~itti; /* clear flag */
|
||||||
|
int_req = int_req & ~itti;
|
||||||
|
return ttix_unit[ln].buf; /* return buf */
|
||||||
|
default:
|
||||||
|
return (stop_inst << IOT_V_REASON) + AC; } /* end switch */
|
||||||
|
return AC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unit service */
|
||||||
|
|
||||||
|
t_stat ttix_svc (UNIT *uptr)
|
||||||
|
{
|
||||||
|
int32 temp, newln;
|
||||||
|
int32 ln = uptr - ttix_unit; /* line # */
|
||||||
|
int32 itti = (INT_TTI1 << ln); /* rx intr */
|
||||||
|
|
||||||
|
if (ttx_desc.ldsc[ln] -> conn) { /* connected? */
|
||||||
|
tmxr_poll_rx (&ttx_desc); /* poll for input */
|
||||||
|
if (temp = tmxr_getc_ln (ttx_desc.ldsc[ln])) { /* get char */
|
||||||
|
temp = temp & 0177; /* mask to 7b */
|
||||||
|
if ((uptr -> flags & UNIT_UC) && islower (temp))
|
||||||
|
temp = toupper (temp);
|
||||||
|
uptr -> buf = temp | 0200; /* Teletype code */
|
||||||
|
dev_done = dev_done | itti; /* set done */
|
||||||
|
int_req = INT_UPDATE; } /* update intr */
|
||||||
|
sim_activate (uptr, uptr -> wait); } /* continue poll */
|
||||||
|
if (uptr -> flags & UNIT_ATT) { /* attached? */
|
||||||
|
newln = tmxr_poll_conn (&ttx_desc, uptr); /* poll connect */
|
||||||
|
if (newln >= 0) { /* got one? */
|
||||||
|
sim_activate (&ttix_unit[newln], ttix_unit[newln].wait);
|
||||||
|
ttx_desc.ldsc[newln] -> rcve = 1; } /* rcv enabled */
|
||||||
|
sim_activate (uptr, tmxr_poll); } /* sched poll */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset routine */
|
||||||
|
|
||||||
|
t_stat ttix_reset (DEVICE *dptr)
|
||||||
|
{
|
||||||
|
UNIT *uptr = dptr -> units; /* unit */
|
||||||
|
int32 ln = uptr - ttix_unit; /* line # */
|
||||||
|
int32 itti = (INT_TTI1 << ln); /* rx intr */
|
||||||
|
|
||||||
|
uptr -> buf = 0; /* clr buf */
|
||||||
|
dev_done = dev_done & ~itti; /* clr done, int */
|
||||||
|
int_req = int_req & ~itti;
|
||||||
|
int_enable = int_enable | itti; /* set enable */
|
||||||
|
if (ttx_desc.ldsc[ln] -> conn) { /* if conn, */
|
||||||
|
sim_activate (uptr, uptr -> wait); /* activate, */
|
||||||
|
ttx_desc.ldsc[ln] -> rcve = 1; } /* enable */
|
||||||
|
else if (uptr -> flags & UNIT_ATT) /* if attached, */
|
||||||
|
sim_activate (uptr, tmxr_poll); /* activate */
|
||||||
|
else sim_cancel (uptr); /* else stop */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Terminal output: IOT routine */
|
||||||
|
|
||||||
|
int32 ttox (int32 inst, int32 AC)
|
||||||
|
{
|
||||||
|
int32 pulse = inst & 07; /* pulse */
|
||||||
|
int32 ln = TTX_GETLN (inst); /* line # */
|
||||||
|
int32 itti = (INT_TTI1 << ln); /* rx intr */
|
||||||
|
int32 itto = (INT_TTO1 << ln); /* tx intr */
|
||||||
|
|
||||||
|
switch (pulse) { /* case IR<9:11> */
|
||||||
|
case 0: /* TLF */
|
||||||
|
dev_done = dev_done | itto; /* set flag */
|
||||||
|
int_req = INT_UPDATE; /* update intr */
|
||||||
|
break;
|
||||||
|
case 1: /* TSF */
|
||||||
|
return (dev_done & itto)? IOT_SKP + AC: AC;
|
||||||
|
case 2: /* TCF */
|
||||||
|
dev_done = dev_done & ~itto; /* clear flag */
|
||||||
|
int_req = int_req & ~itto; /* clear intr */
|
||||||
|
break;
|
||||||
|
case 5: /* SPI */
|
||||||
|
return (int_req & (itti | itto))? IOT_SKP + AC: AC;
|
||||||
|
case 6: /* TLS */
|
||||||
|
dev_done = dev_done & ~itto; /* clear flag */
|
||||||
|
int_req = int_req & ~itto; /* clear int req */
|
||||||
|
case 4: /* TPC */
|
||||||
|
sim_activate (&ttox_unit[ln], ttox_unit[ln].wait); /* activate */
|
||||||
|
ttox_unit[ln].buf = AC & 0377; /* load buffer */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (stop_inst << IOT_V_REASON) + AC; } /* end switch */
|
||||||
|
return AC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unit service */
|
||||||
|
|
||||||
|
t_stat ttox_svc (UNIT *uptr)
|
||||||
|
{
|
||||||
|
int32 ln = uptr - ttox_unit; /* line # */
|
||||||
|
int32 itto = (INT_TTO1 << ln); /* tx intr */
|
||||||
|
|
||||||
|
if (ttx_desc.ldsc[ln] -> conn) { /* connected? */
|
||||||
|
if (ttx_desc.ldsc[ln] -> xmte) { /* tx enabled? */
|
||||||
|
TMLN *lp = ttx_desc.ldsc[ln]; /* get line */
|
||||||
|
tmxr_putc_ln (lp, uptr -> buf & 0177); /* output char */
|
||||||
|
tmxr_poll_tx (&ttx_desc); } /* poll xmt */
|
||||||
|
else { tmxr_poll_tx (&ttx_desc); /* poll xmt */
|
||||||
|
sim_activate (uptr, tmxr_poll); /* wait */
|
||||||
|
return SCPE_OK; } }
|
||||||
|
dev_done = dev_done | itto; /* set done */
|
||||||
|
int_req = INT_UPDATE; /* update intr */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset routine */
|
||||||
|
|
||||||
|
t_stat ttox_reset (DEVICE *dptr)
|
||||||
|
{
|
||||||
|
UNIT *uptr = dptr -> units; /* unit */
|
||||||
|
int32 ln = uptr - ttox_unit; /* line # */
|
||||||
|
int32 itto = (INT_TTO1 << ln); /* tx intr */
|
||||||
|
|
||||||
|
uptr -> buf = 0; /* clr buf */
|
||||||
|
dev_done = dev_done & ~itto; /* clr done, int */
|
||||||
|
int_req = int_req & ~itto;
|
||||||
|
int_enable = int_enable | itto; /* set enable */
|
||||||
|
sim_cancel (uptr); /* deactivate */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attach master unit */
|
||||||
|
|
||||||
|
t_stat ttx_attach (UNIT *uptr, char *cptr)
|
||||||
|
{
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
r = tmxr_attach (&ttx_desc, uptr, cptr); /* attach */
|
||||||
|
if (r != SCPE_OK) return r; /* error */
|
||||||
|
sim_activate (uptr, tmxr_poll); /* start poll */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Detach master unit */
|
||||||
|
|
||||||
|
t_stat ttx_detach (UNIT *uptr)
|
||||||
|
{
|
||||||
|
int32 i;
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
r = tmxr_detach (&ttx_desc, uptr); /* detach */
|
||||||
|
for (i = 0; i < TTX_LINES; i++) { /* all lines, */
|
||||||
|
ttx_desc.ldsc[i] -> rcve = 0; /* disable rcv */
|
||||||
|
sim_cancel (&ttix_unit[i]); } /* stop poll */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Status */
|
||||||
|
|
||||||
|
t_stat ttx_status (UNIT *uptr, FILE *st)
|
||||||
|
{
|
||||||
|
int32 i;
|
||||||
|
|
||||||
|
for (i = 0; (i < TTX_LINES) && (ttx_desc.ldsc[i] -> conn == 0); i++) ;
|
||||||
|
if (i < TTX_LINES) {
|
||||||
|
for (i = 0; i < TTX_LINES; i++) {
|
||||||
|
if (ttx_desc.ldsc[i] -> conn)
|
||||||
|
tmxr_fstatus (st, ttx_desc.ldsc[i], i); } }
|
||||||
|
else fprintf (st, " all disconnected");
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
193
scp.c
193
scp.c
|
@ -23,6 +23,13 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
08-Oct-01 RMS Added SHOW VERSION
|
||||||
|
30-Sep-01 RMS Relaxed attach test in BOOT
|
||||||
|
27-Sep-01 RMS Added queue count routine, fixed typo in ex/mod
|
||||||
|
17-Sep-01 RMS Removed multiple console support
|
||||||
|
07-Sep-01 RMS Removed conditional externs on function prototypes
|
||||||
|
Added special modifier print
|
||||||
|
31-Aug-01 RMS Changed int64 to t_int64 for Windoze (V2.7)
|
||||||
18-Jul-01 RMS Minor changes for Macintosh port
|
18-Jul-01 RMS Minor changes for Macintosh port
|
||||||
12-Jun-01 RMS Fixed bug in big-endian I/O (found by Dave Conroy)
|
12-Jun-01 RMS Fixed bug in big-endian I/O (found by Dave Conroy)
|
||||||
27-May-01 RMS Added multiple console support
|
27-May-01 RMS Added multiple console support
|
||||||
|
@ -56,8 +63,8 @@
|
||||||
13-Apr-95 RMS Added symbolic printouts
|
13-Apr-95 RMS Added symbolic printouts
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SCP 1 /* defining module */
|
|
||||||
#include "sim_defs.h"
|
#include "sim_defs.h"
|
||||||
|
#include "sim_rev.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#define EX_D 0 /* deposit */
|
#define EX_D 0 /* deposit */
|
||||||
|
@ -87,7 +94,6 @@
|
||||||
|
|
||||||
extern char sim_name[];
|
extern char sim_name[];
|
||||||
extern DEVICE *sim_devices[];
|
extern DEVICE *sim_devices[];
|
||||||
extern UNIT *sim_consoles[];
|
|
||||||
extern REG *sim_PC;
|
extern REG *sim_PC;
|
||||||
extern char *sim_stop_messages[];
|
extern char *sim_stop_messages[];
|
||||||
extern t_stat sim_instr (void);
|
extern t_stat sim_instr (void);
|
||||||
|
@ -120,17 +126,17 @@ unsigned char sim_flip[FLIP_SIZE];
|
||||||
#define SZ_D(dp) (size_map[((dp) -> dwidth + CHAR_BIT - 1) / CHAR_BIT])
|
#define SZ_D(dp) (size_map[((dp) -> dwidth + CHAR_BIT - 1) / CHAR_BIT])
|
||||||
#define SZ_R(rp) \
|
#define SZ_R(rp) \
|
||||||
(size_map[((rp) -> width + (rp) -> offset + CHAR_BIT - 1) / CHAR_BIT])
|
(size_map[((rp) -> width + (rp) -> offset + CHAR_BIT - 1) / CHAR_BIT])
|
||||||
#if defined (int64)
|
#if defined (t_int64)
|
||||||
#define SZ_LOAD(sz,v,mb,j) \
|
#define SZ_LOAD(sz,v,mb,j) \
|
||||||
if (sz == sizeof (uint8)) v = *(((uint8 *) mb) + j); \
|
if (sz == sizeof (uint8)) v = *(((uint8 *) mb) + j); \
|
||||||
else if (sz == sizeof (uint16)) v = *(((uint16 *) mb) + j); \
|
else if (sz == sizeof (uint16)) v = *(((uint16 *) mb) + j); \
|
||||||
else if (sz == sizeof (uint32)) v = *(((uint32 *) mb) + j); \
|
else if (sz == sizeof (uint32)) v = *(((uint32 *) mb) + j); \
|
||||||
else v = *(((uint64 *) mb) + j);
|
else v = *(((t_uint64 *) mb) + j);
|
||||||
#define SZ_STORE(sz,v,mb,j) \
|
#define SZ_STORE(sz,v,mb,j) \
|
||||||
if (sz == sizeof (uint8)) *(((uint8 *) mb) + j) = (uint8) v; \
|
if (sz == sizeof (uint8)) *(((uint8 *) mb) + j) = (uint8) v; \
|
||||||
else if (sz == sizeof (uint16)) *(((uint16 *) mb) + j) = (uint16) v; \
|
else if (sz == sizeof (uint16)) *(((uint16 *) mb) + j) = (uint16) v; \
|
||||||
else if (sz == sizeof (uint32)) *(((uint32 *) mb) + j) = (uint32) v; \
|
else if (sz == sizeof (uint32)) *(((uint32 *) mb) + j) = (uint32) v; \
|
||||||
else *(((uint64 *) mb) + j) = v;
|
else *(((t_uint64 *) mb) + j) = v;
|
||||||
#else
|
#else
|
||||||
#define SZ_LOAD(sz,v,mb,j) \
|
#define SZ_LOAD(sz,v,mb,j) \
|
||||||
if (sz == sizeof (uint8)) v = *(((uint8 *) mb) + j); \
|
if (sz == sizeof (uint8)) v = *(((uint8 *) mb) + j); \
|
||||||
|
@ -161,14 +167,13 @@ t_stat get_aval (t_addr addr, DEVICE *dptr, UNIT *uptr);
|
||||||
t_value strtotv (char *inptr, char **endptr, int radix);
|
t_value strtotv (char *inptr, char **endptr, int radix);
|
||||||
t_stat fprint_val (FILE *stream, t_value val, int rdx, int wid, int fmt);
|
t_stat fprint_val (FILE *stream, t_value val, int rdx, int wid, int fmt);
|
||||||
void fprint_stopped (FILE *stream, t_stat r);
|
void fprint_stopped (FILE *stream, t_stat r);
|
||||||
void sim_chkcons (void);
|
|
||||||
char *read_line (char *ptr, int size, FILE *stream);
|
char *read_line (char *ptr, int size, FILE *stream);
|
||||||
DEVICE *find_dev (char *ptr);
|
DEVICE *find_dev (char *ptr);
|
||||||
DEVICE *find_unit (char *ptr, int32 *iptr);
|
DEVICE *find_unit (char *ptr, int32 *iptr);
|
||||||
DEVICE *find_dev_from_unit (UNIT *uptr);
|
DEVICE *find_dev_from_unit (UNIT *uptr);
|
||||||
REG *find_reg (char *ptr, char **optr, DEVICE *dptr);
|
REG *find_reg (char *ptr, char **optr, DEVICE *dptr);
|
||||||
t_bool qdisable (DEVICE *dptr);
|
t_bool qdisable (DEVICE *dptr);
|
||||||
t_stat detach_all (int start_device);
|
t_stat detach_all (int32 start_device, t_bool shutdown);
|
||||||
t_stat ex_reg (FILE *ofile, t_value val, int flag, REG *rptr, t_addr idx);
|
t_stat ex_reg (FILE *ofile, t_value val, int flag, REG *rptr, t_addr idx);
|
||||||
t_stat dep_reg (int flag, char *cptr, REG *rptr, t_addr idx);
|
t_stat dep_reg (int flag, char *cptr, REG *rptr, t_addr idx);
|
||||||
t_stat ex_addr (FILE *ofile, int flag, t_addr addr, DEVICE *dptr, UNIT *uptr);
|
t_stat ex_addr (FILE *ofile, int flag, t_addr addr, DEVICE *dptr, UNIT *uptr);
|
||||||
|
@ -179,6 +184,7 @@ char *get_range (char *cptr, t_addr *lo, t_addr *hi, int rdx,
|
||||||
SCHTAB *get_search (char *cptr, DEVICE *dptr, SCHTAB *schptr);
|
SCHTAB *get_search (char *cptr, DEVICE *dptr, SCHTAB *schptr);
|
||||||
int test_search (t_value val, SCHTAB *schptr);
|
int test_search (t_value val, SCHTAB *schptr);
|
||||||
t_stat step_svc (UNIT *ptr);
|
t_stat step_svc (UNIT *ptr);
|
||||||
|
t_stat show_version (FILE *st, int flag);
|
||||||
|
|
||||||
UNIT step_unit = { UDATA (&step_svc, 0, 0) };
|
UNIT step_unit = { UDATA (&step_svc, 0, 0) };
|
||||||
const char save_vercur[] = "V2.6";
|
const char save_vercur[] = "V2.6";
|
||||||
|
@ -217,8 +223,8 @@ const char *scp_error_messages[] = {
|
||||||
|
|
||||||
const size_t size_map[] = { sizeof (int8),
|
const size_t size_map[] = { sizeof (int8),
|
||||||
sizeof (int8), sizeof (int16), sizeof (int32), sizeof (int32)
|
sizeof (int8), sizeof (int16), sizeof (int32), sizeof (int32)
|
||||||
#if defined (int64)
|
#if defined (t_int64)
|
||||||
, sizeof (int64), sizeof (int64), sizeof (int64), sizeof (int64)
|
, sizeof (t_int64), sizeof (t_int64), sizeof (t_int64), sizeof (t_int64)
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -231,7 +237,7 @@ const t_value width_mask[] = { 0,
|
||||||
0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF,
|
0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF,
|
||||||
0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF,
|
0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF,
|
||||||
0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
|
0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
|
||||||
#if defined (int64)
|
#if defined (t_int64)
|
||||||
, 0x1FFFFFFFF, 0x3FFFFFFFF, 0x7FFFFFFFF, 0xFFFFFFFFF,
|
, 0x1FFFFFFFF, 0x3FFFFFFFF, 0x7FFFFFFFF, 0xFFFFFFFFF,
|
||||||
0x1FFFFFFFFF, 0x3FFFFFFFFF, 0x7FFFFFFFFF, 0xFFFFFFFFFF,
|
0x1FFFFFFFFF, 0x3FFFFFFFFF, 0x7FFFFFFFFF, 0xFFFFFFFFFF,
|
||||||
0x1FFFFFFFFFF, 0x3FFFFFFFFFF, 0x7FFFFFFFFFF, 0xFFFFFFFFFFF,
|
0x1FFFFFFFFFF, 0x3FFFFFFFFFF, 0x7FFFFFFFFFF, 0xFFFFFFFFFFF,
|
||||||
|
@ -312,7 +318,8 @@ if ((stat = ttinit ()) != SCPE_OK) {
|
||||||
printf ("Fatal terminal initialization error\n%s\n",
|
printf ("Fatal terminal initialization error\n%s\n",
|
||||||
scp_error_messages[stat - SCPE_BASE]);
|
scp_error_messages[stat - SCPE_BASE]);
|
||||||
return 0; }
|
return 0; }
|
||||||
printf ("\n%s simulator V2.6b\n", sim_name);
|
printf ("\n");
|
||||||
|
show_version (stdout, 0);
|
||||||
end_test.i = 1; /* test endian-ness */
|
end_test.i = 1; /* test endian-ness */
|
||||||
sim_end = end_test.c[0];
|
sim_end = end_test.c[0];
|
||||||
stop_cpu = 0;
|
stop_cpu = 0;
|
||||||
|
@ -363,7 +370,7 @@ do { printf ("sim> "); /* prompt */
|
||||||
scp_error_messages[stat - SCPE_BASE]); }
|
scp_error_messages[stat - SCPE_BASE]); }
|
||||||
} while (stat != SCPE_EXIT);
|
} while (stat != SCPE_EXIT);
|
||||||
|
|
||||||
detach_all (0); /* close files */
|
detach_all (0, TRUE); /* close files */
|
||||||
nolog_cmd (0, NULL); /* close log */
|
nolog_cmd (0, NULL); /* close log */
|
||||||
ttclose (); /* close console */
|
ttclose (); /* close console */
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -400,9 +407,11 @@ fprintf (st, "exi{t}|q{uit}|by{e} exit from simulation\n");
|
||||||
fprintf (st, "set <unit> <val> set unit parameter\n");
|
fprintf (st, "set <unit> <val> set unit parameter\n");
|
||||||
fprintf (st, "show <device> show device parameters\n");
|
fprintf (st, "show <device> show device parameters\n");
|
||||||
fprintf (st, "sh{ow} c{onfiguration} show configuration\n");
|
fprintf (st, "sh{ow} c{onfiguration} show configuration\n");
|
||||||
|
fprintf (st, "sh{ow} d{evices} show devices\n");
|
||||||
fprintf (st, "sh{ow} m{odifiers} show modifiers\n");
|
fprintf (st, "sh{ow} m{odifiers} show modifiers\n");
|
||||||
fprintf (st, "sh{ow} q{ueue} show event queue\n");
|
fprintf (st, "sh{ow} q{ueue} show event queue\n");
|
||||||
fprintf (st, "sh{ow} t{ime} show simulated time\n");
|
fprintf (st, "sh{ow} t{ime} show simulated time\n");
|
||||||
|
fprintf (st, "sh{ow} v{ersion} show simulator version\n");
|
||||||
fprintf (st, "en{able} <device> enable device\n");
|
fprintf (st, "en{able} <device> enable device\n");
|
||||||
fprintf (st, "di{sable} <device> disable device\n");
|
fprintf (st, "di{sable} <device> disable device\n");
|
||||||
fprintf (st, "ad{d} <unit> add unit to configuration\n");
|
fprintf (st, "ad{d} <unit> add unit to configuration\n");
|
||||||
|
@ -441,23 +450,24 @@ GET_SWITCHES (cptr, gbuf); /* test for switches */
|
||||||
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
|
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
|
||||||
dptr = find_unit (gbuf, &unitno); /* find dev+unit */
|
dptr = find_unit (gbuf, &unitno); /* find dev+unit */
|
||||||
if ((dptr == NULL) || (dptr -> units == NULL) ||
|
if ((dptr == NULL) || (dptr -> units == NULL) ||
|
||||||
(*cptr == 0)) return SCPE_ARG; /* argument? */
|
(*cptr == 0)) return SCPE_ARG; /* argument? */
|
||||||
cptr = get_glyph (cptr, gbuf, 0); /* get glyph */
|
cptr = get_glyph (cptr, gbuf, 0); /* get glyph */
|
||||||
if (*cptr != 0) return SCPE_ARG; /* now eol? */
|
|
||||||
uptr = dptr -> units + unitno;
|
uptr = dptr -> units + unitno;
|
||||||
if (uptr -> flags & UNIT_DIS) return SCPE_UDIS; /* disabled? */
|
if (uptr -> flags & UNIT_DIS) return SCPE_UDIS; /* disabled? */
|
||||||
for (i = 0; set_table[i].name != NULL; i++) { /* check globals */
|
for (i = 0; set_table[i].name != NULL; i++) { /* check globals */
|
||||||
if (MATCH_CMD (gbuf, set_table[i].name) == 0)
|
if (MATCH_CMD (gbuf, set_table[i].name) == 0) {
|
||||||
return set_table[i].action (dptr, set_table[i].arg); }
|
if (*cptr != 0) return SCPE_ARG; /* now eol? */
|
||||||
|
return set_table[i].action (dptr, set_table[i].arg); } }
|
||||||
if (dptr -> modifiers == NULL) return SCPE_NOPARAM; /* any modifiers? */
|
if (dptr -> modifiers == NULL) return SCPE_NOPARAM; /* any modifiers? */
|
||||||
for (mptr = dptr -> modifiers; mptr -> mask != 0; mptr++) {
|
for (mptr = dptr -> modifiers; mptr -> mask != 0; mptr++) {
|
||||||
if ((mptr -> mstring != NULL) &&
|
if ((mptr -> mstring != NULL) &&
|
||||||
(MATCH_CMD (gbuf, mptr -> mstring) == 0)) {
|
(MATCH_CMD (gbuf, mptr -> mstring) == 0)) {
|
||||||
|
if (*cptr != 0) return SCPE_ARG; /* now eol? */
|
||||||
if ((mptr -> valid != NULL) &&
|
if ((mptr -> valid != NULL) &&
|
||||||
((r = mptr -> valid (uptr, mptr -> match)) != SCPE_OK))
|
((r = mptr -> valid (uptr, mptr -> match)) != SCPE_OK))
|
||||||
return r; /* invalid? */
|
return r; /* invalid? */
|
||||||
uptr -> flags = (uptr -> flags & ~(mptr -> mask)) |
|
uptr -> flags = (uptr -> flags & ~(mptr -> mask)) |
|
||||||
(mptr -> match & mptr -> mask); /* set new value */
|
(mptr -> match & mptr -> mask); /* set new value */
|
||||||
return SCPE_OK; } }
|
return SCPE_OK; } }
|
||||||
return SCPE_ARG; /* no match */
|
return SCPE_ARG; /* no match */
|
||||||
}
|
}
|
||||||
|
@ -491,6 +501,7 @@ static CTAB show_table[] = {
|
||||||
{ "QUEUE", &show_queue, 0 },
|
{ "QUEUE", &show_queue, 0 },
|
||||||
{ "TIME", &show_time, 0 },
|
{ "TIME", &show_time, 0 },
|
||||||
{ "MODIFIERS", &show_modifiers, 0 },
|
{ "MODIFIERS", &show_modifiers, 0 },
|
||||||
|
{ "VERSION", &show_version, 0 },
|
||||||
{ NULL, NULL, 0 } };
|
{ NULL, NULL, 0 } };
|
||||||
|
|
||||||
GET_SWITCHES (cptr, gbuf); /* test for switches */
|
GET_SWITCHES (cptr, gbuf); /* test for switches */
|
||||||
|
@ -536,24 +547,34 @@ for (j = 0; j < dptr -> numunits; j++) {
|
||||||
if (uptr -> flags & UNIT_DIS) continue;
|
if (uptr -> flags & UNIT_DIS) continue;
|
||||||
if (ucnt > 1) fprintf (st, " unit %d", j);
|
if (ucnt > 1) fprintf (st, " unit %d", j);
|
||||||
if (uptr -> flags & UNIT_FIX) {
|
if (uptr -> flags & UNIT_FIX) {
|
||||||
if (uptr -> capac < kval)
|
if (uptr -> capac < kval)
|
||||||
fprintf (st, ", %d%s", uptr -> capac,
|
fprintf (st, ", %d%s", uptr -> capac,
|
||||||
((dptr -> dwidth / dptr -> aincr) > 8)? "W": "B");
|
((dptr -> dwidth / dptr -> aincr) > 8)? "W": "B");
|
||||||
else fprintf (st, ", %dK%s", uptr -> capac / kval,
|
else fprintf (st, ", %dK%s", uptr -> capac / kval,
|
||||||
((dptr -> dwidth / dptr -> aincr) > 8)? "W": "B"); }
|
((dptr -> dwidth / dptr -> aincr) > 8)? "W": "B"); }
|
||||||
if (uptr -> flags & UNIT_ATT)
|
if (uptr -> flags & UNIT_ATT)
|
||||||
fprintf (st, ", attached to %s", uptr -> filename);
|
fprintf (st, ", attached to %s", uptr -> filename);
|
||||||
else if (uptr -> flags & UNIT_ATTABLE)
|
else if (uptr -> flags & UNIT_ATTABLE)
|
||||||
fprintf (st, ", not attached");
|
fprintf (st, ", not attached");
|
||||||
if (dptr -> modifiers != NULL) {
|
if (dptr -> modifiers != NULL) {
|
||||||
for (mptr = dptr -> modifiers; mptr -> mask != 0; mptr++) {
|
for (mptr = dptr -> modifiers; mptr -> mask != 0; mptr++) {
|
||||||
if ((mptr -> pstring != NULL) &&
|
if ((mptr -> pstring != NULL) &&
|
||||||
((uptr -> flags & mptr -> mask) == mptr -> match))
|
((uptr -> flags & mptr -> mask) == mptr -> match)) {
|
||||||
fprintf (st, ", %s", mptr -> pstring); } }
|
fprintf (st, ", %s", mptr -> pstring);
|
||||||
|
if ((mptr -> mstring == NULL) && mptr -> valid)
|
||||||
|
mptr -> valid (uptr, st); } } }
|
||||||
fprintf (st, "\n"); }
|
fprintf (st, "\n"); }
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t_stat show_version (FILE *st, int flag)
|
||||||
|
{
|
||||||
|
int32 vmaj = SIM_MAJOR, vmin = SIM_MINOR, vpat = SIM_PATCH;
|
||||||
|
|
||||||
|
fprintf (st, "%s simulator V%d.%d-%d\n", sim_name, vmaj, vmin, vpat);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
t_stat show_config (FILE *st, int flag)
|
t_stat show_config (FILE *st, int flag)
|
||||||
{
|
{
|
||||||
int32 i;
|
int32 i;
|
||||||
|
@ -890,7 +911,7 @@ GET_SWITCHES (cptr, gbuf); /* test for switches */
|
||||||
if (*cptr == 0) return SCPE_ARG;
|
if (*cptr == 0) return SCPE_ARG;
|
||||||
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
|
cptr = get_glyph (cptr, gbuf, 0); /* get next glyph */
|
||||||
if (*cptr != 0) return SCPE_ARG;
|
if (*cptr != 0) return SCPE_ARG;
|
||||||
if (strcmp (gbuf, "ALL") == 0) return (detach_all (0));
|
if (strcmp (gbuf, "ALL") == 0) return (detach_all (0, FALSE));
|
||||||
dptr = find_unit (gbuf, &unitno); /* locate dev+unit# */
|
dptr = find_unit (gbuf, &unitno); /* locate dev+unit# */
|
||||||
if ((dptr == NULL) || (dptr -> units == NULL)) return SCPE_ARG;
|
if ((dptr == NULL) || (dptr -> units == NULL)) return SCPE_ARG;
|
||||||
uptr = (dptr -> units) + unitno;
|
uptr = (dptr -> units) + unitno;
|
||||||
|
@ -903,11 +924,12 @@ return detach_unit (uptr);
|
||||||
|
|
||||||
Inputs:
|
Inputs:
|
||||||
start = number of starting device
|
start = number of starting device
|
||||||
|
shutdown = TRUE if simulator shutting down
|
||||||
Outputs:
|
Outputs:
|
||||||
status = error status
|
status = error status
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t_stat detach_all (int start)
|
t_stat detach_all (int32 start, t_bool shutdown)
|
||||||
{
|
{
|
||||||
int32 i, j;
|
int32 i, j;
|
||||||
t_stat reason;
|
t_stat reason;
|
||||||
|
@ -918,9 +940,10 @@ if ((start < 0) || (start > 1)) return SCPE_ARG;
|
||||||
for (i = start; (dptr = sim_devices[i]) != NULL; i++) {
|
for (i = start; (dptr = sim_devices[i]) != NULL; i++) {
|
||||||
for (j = 0; j < dptr -> numunits; j++) {
|
for (j = 0; j < dptr -> numunits; j++) {
|
||||||
uptr = (dptr -> units) + j;
|
uptr = (dptr -> units) + j;
|
||||||
if (dptr -> detach != NULL) reason = dptr -> detach (uptr);
|
if ((uptr -> flags & UNIT_ATTABLE) || shutdown) {
|
||||||
else reason = detach_unit (uptr);
|
if (dptr -> detach != NULL) reason = dptr -> detach (uptr);
|
||||||
if (reason != SCPE_OK) return reason; } }
|
else reason = detach_unit (uptr);
|
||||||
|
if (reason != SCPE_OK) return reason; } } }
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1201,8 +1224,8 @@ if (flag == RU_BOOT) { /* boot */
|
||||||
(dptr -> boot == NULL)) return SCPE_ARG;
|
(dptr -> boot == NULL)) return SCPE_ARG;
|
||||||
uptr = dptr -> units + unitno;
|
uptr = dptr -> units + unitno;
|
||||||
if (uptr -> flags & UNIT_DIS) return SCPE_ARG; /* disabled? */
|
if (uptr -> flags & UNIT_DIS) return SCPE_ARG; /* disabled? */
|
||||||
if (!(uptr -> flags & UNIT_ATTABLE)) return SCPE_NOATT;
|
if ((uptr -> flags & UNIT_ATTABLE) &&
|
||||||
if (!(uptr -> flags & UNIT_ATT)) return SCPE_UNATT;
|
!(uptr -> flags & UNIT_ATT)) return SCPE_UNATT;
|
||||||
if ((r = dptr -> boot (unitno)) != SCPE_OK) return r; }
|
if ((r = dptr -> boot (unitno)) != SCPE_OK) return r; }
|
||||||
|
|
||||||
if (*cptr != 0) return SCPE_ARG;
|
if (*cptr != 0) return SCPE_ARG;
|
||||||
|
@ -1227,7 +1250,6 @@ if (ttrunstate () != SCPE_OK) { /* set console */
|
||||||
return SCPE_TTYERR; }
|
return SCPE_TTYERR; }
|
||||||
if (step) sim_activate (&step_unit, step); /* set step timer */
|
if (step) sim_activate (&step_unit, step); /* set step timer */
|
||||||
sim_is_running = 1; /* flag running */
|
sim_is_running = 1; /* flag running */
|
||||||
sim_chkcons (); /* check console buffer */
|
|
||||||
r = sim_instr();
|
r = sim_instr();
|
||||||
|
|
||||||
sim_is_running = 0; /* flag idle */
|
sim_is_running = 0; /* flag idle */
|
||||||
|
@ -1400,7 +1422,7 @@ for (gptr = gbuf, reason = SCPE_OK;
|
||||||
continue; }
|
continue; }
|
||||||
|
|
||||||
tptr = get_range (gptr, &low, &high, dptr -> aradix,
|
tptr = get_range (gptr, &low, &high, dptr -> aradix,
|
||||||
(((uptr -> capac == 0) | (flag == EX_E))? 0:
|
(((uptr -> capac == 0) || (flag == EX_E))? 0:
|
||||||
uptr -> capac - dptr -> aincr), 0);
|
uptr -> capac - dptr -> aincr), 0);
|
||||||
if (tptr == NULL) return SCPE_ARG;
|
if (tptr == NULL) return SCPE_ARG;
|
||||||
if (*tptr && (*tptr++ != ',')) return SCPE_ARG;
|
if (*tptr && (*tptr++ != ',')) return SCPE_ARG;
|
||||||
|
@ -1517,12 +1539,12 @@ if ((rptr -> depth > 1) && (sz == sizeof (uint8)))
|
||||||
val = *(((uint8 *) rptr -> loc) + idx);
|
val = *(((uint8 *) rptr -> loc) + idx);
|
||||||
else if ((rptr -> depth > 1) && (sz == sizeof (uint16)))
|
else if ((rptr -> depth > 1) && (sz == sizeof (uint16)))
|
||||||
val = *(((uint16 *) rptr -> loc) + idx);
|
val = *(((uint16 *) rptr -> loc) + idx);
|
||||||
#if !defined (int64)
|
#if !defined (t_int64)
|
||||||
else val = *(((uint32 *) rptr -> loc) + idx);
|
else val = *(((uint32 *) rptr -> loc) + idx);
|
||||||
#else
|
#else
|
||||||
else if (sz <= sizeof (uint32))
|
else if (sz <= sizeof (uint32))
|
||||||
val = *(((uint32 *) rptr -> loc) + idx);
|
val = *(((uint32 *) rptr -> loc) + idx);
|
||||||
else val = *(((uint64 *) rptr -> loc) + idx);
|
else val = *(((t_uint64 *) rptr -> loc) + idx);
|
||||||
#endif
|
#endif
|
||||||
val = (val >> rptr -> offset) & width_mask[rptr -> width];
|
val = (val >> rptr -> offset) & width_mask[rptr -> width];
|
||||||
return val;
|
return val;
|
||||||
|
@ -1589,12 +1611,12 @@ if ((rptr -> depth > 1) && (sz == sizeof (uint8)))
|
||||||
PUT_RVAL (uint8, rptr, idx, (uint32) val, (uint32) mask);
|
PUT_RVAL (uint8, rptr, idx, (uint32) val, (uint32) mask);
|
||||||
else if ((rptr -> depth > 1) && (sz == sizeof (uint16)))
|
else if ((rptr -> depth > 1) && (sz == sizeof (uint16)))
|
||||||
PUT_RVAL (uint16, rptr, idx, (uint32) val, (uint32) mask);
|
PUT_RVAL (uint16, rptr, idx, (uint32) val, (uint32) mask);
|
||||||
#if !defined (int64)
|
#if !defined (t_int64)
|
||||||
else PUT_RVAL (uint32, rptr, idx, val, mask);
|
else PUT_RVAL (uint32, rptr, idx, val, mask);
|
||||||
#else
|
#else
|
||||||
else if (sz <= sizeof (uint32))
|
else if (sz <= sizeof (uint32))
|
||||||
PUT_RVAL (uint32, rptr, idx, (int32) val, (uint32) mask);
|
PUT_RVAL (uint32, rptr, idx, (int32) val, (uint32) mask);
|
||||||
else PUT_RVAL (uint64, rptr, idx, val, mask);
|
else PUT_RVAL (t_uint64, rptr, idx, val, mask);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2182,6 +2204,7 @@ return SCPE_OK;
|
||||||
sim_is_active see if entry is on event queue
|
sim_is_active see if entry is on event queue
|
||||||
sim_atime return absolute time for an entry
|
sim_atime return absolute time for an entry
|
||||||
sim_gtime return global time
|
sim_gtime return global time
|
||||||
|
sim_qcount return event queue entry count
|
||||||
|
|
||||||
Asynchronous events are set up by queueing a unit data structure
|
Asynchronous events are set up by queueing a unit data structure
|
||||||
to the event queue with a timeout (in simulator units, relative
|
to the event queue with a timeout (in simulator units, relative
|
||||||
|
@ -2335,6 +2358,23 @@ if (sim_clock_queue == NULL) { UPDATE_SIM_TIME (noqueue_time); }
|
||||||
else { UPDATE_SIM_TIME (sim_clock_queue -> time); }
|
else { UPDATE_SIM_TIME (sim_clock_queue -> time); }
|
||||||
return sim_rtime;
|
return sim_rtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* sim_qcount - return queue entry count
|
||||||
|
|
||||||
|
Inputs: none
|
||||||
|
Outputs:
|
||||||
|
count = number of entries on the queue
|
||||||
|
*/
|
||||||
|
|
||||||
|
int32 sim_qcount (void)
|
||||||
|
{
|
||||||
|
int32 cnt;
|
||||||
|
UNIT *uptr;
|
||||||
|
|
||||||
|
cnt = 0;
|
||||||
|
for (uptr = sim_clock_queue; uptr != NULL; uptr = uptr -> next) cnt++;
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
/* Endian independent binary I/O package
|
/* Endian independent binary I/O package
|
||||||
|
|
||||||
|
@ -2456,77 +2496,4 @@ rtc_currdelay = (int32) (((double) rtc_basedelay * (double) rtc_nextintv) /
|
||||||
1000.0); /* next delay */
|
1000.0); /* next delay */
|
||||||
return rtc_currdelay;
|
return rtc_currdelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OS independent multiconsole package
|
|
||||||
|
|
||||||
set_console make unit the active console
|
|
||||||
sim_putcons output character in a multiconsole simulator
|
|
||||||
sim_chkcons check for buffered output in a multiconsole simulator
|
|
||||||
*/
|
|
||||||
|
|
||||||
t_stat set_console (UNIT *uptr, int32 flag)
|
|
||||||
{
|
|
||||||
int32 i;
|
|
||||||
DEVICE *idptr, *odptr;
|
|
||||||
UNIT *wuptr, *iuptr = NULL, *ouptr = NULL;
|
|
||||||
|
|
||||||
if (sim_consoles == NULL) return SCPE_NOFNC;
|
|
||||||
for (i = 0; sim_consoles[i] != NULL; i++) {
|
|
||||||
if (uptr == sim_consoles[i]) {
|
|
||||||
iuptr = sim_consoles[i & ~1];
|
|
||||||
ouptr = sim_consoles[i | 1]; } }
|
|
||||||
if ((iuptr == NULL) || (ouptr == NULL)) return SCPE_ARG;
|
|
||||||
idptr = find_dev_from_unit (iuptr);
|
|
||||||
odptr = find_dev_from_unit (ouptr);
|
|
||||||
if ((idptr == NULL) || (odptr == NULL)) return SCPE_ARG;
|
|
||||||
for (i = 0; sim_consoles[i] != NULL; i++) {
|
|
||||||
wuptr = sim_consoles[i];
|
|
||||||
wuptr -> flags = wuptr -> flags & ~UNIT_CONS;
|
|
||||||
if (!(i & 1)) sim_cancel (wuptr); }
|
|
||||||
iuptr -> flags = iuptr -> flags | UNIT_CONS;
|
|
||||||
ouptr -> flags = ouptr -> flags | UNIT_CONS;
|
|
||||||
sim_activate (iuptr, iuptr -> wait);
|
|
||||||
if (idptr == odptr) {
|
|
||||||
printf ("Active console is %s\n", idptr -> name);
|
|
||||||
if (sim_log) fprintf (sim_log, "Active console is %s\n", idptr -> name); }
|
|
||||||
else { printf ("Active console is %s/%s\n", idptr -> name, odptr -> name);
|
|
||||||
if (sim_log) fprintf (sim_log,
|
|
||||||
"Active console is %s/%s\n", idptr -> name, odptr -> name); }
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
t_stat sim_putcons (int32 out, UNIT *uptr)
|
|
||||||
{
|
|
||||||
uint8 *consbuf;
|
|
||||||
|
|
||||||
if ((uptr -> flags & UNIT_CONS) || (uptr -> filebuf == NULL))
|
|
||||||
return sim_putchar (out);
|
|
||||||
if (uptr -> u4 < CONS_SIZE) {
|
|
||||||
consbuf = (uint8 *) uptr -> filebuf;
|
|
||||||
consbuf[uptr -> u4] = out; }
|
|
||||||
uptr -> u4 = uptr -> u4 + 1;
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sim_chkcons (void)
|
|
||||||
{
|
|
||||||
int32 i, j, limit;
|
|
||||||
uint8 *consbuf;
|
|
||||||
UNIT *uptr;
|
|
||||||
|
|
||||||
if (sim_consoles == NULL) return;
|
|
||||||
for (i = 0; sim_consoles[i] != NULL; i++) {
|
|
||||||
uptr = sim_consoles[i];
|
|
||||||
if ((i & 1) && (uptr -> flags & UNIT_CONS) &&
|
|
||||||
(uptr -> filebuf) && (uptr -> u4)) {
|
|
||||||
consbuf = (uint8 *) uptr -> filebuf;
|
|
||||||
limit = (uptr -> u4 < CONS_SIZE)? uptr -> u4: CONS_SIZE;
|
|
||||||
for (j = 0; j < limit; j++) sim_putchar (consbuf[j]);
|
|
||||||
if (uptr -> u4 >= CONS_SIZE) {
|
|
||||||
printf ("\n[Buffered output lost]\n");
|
|
||||||
if (sim_log) fprintf (sim_log, "\n[Buffered output lost]\n"); }
|
|
||||||
uptr -> u4 = 0;
|
|
||||||
return; } }
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
10
scp_tty.c
10
scp_tty.c
|
@ -23,6 +23,8 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
19-Sep-01 RMS More Mac changes
|
||||||
|
31-Aug-01 RMS Changed int64 to t_int64 for Windoze
|
||||||
20-Jul-01 RMS Added Macintosh support (from Louis Chretien, Peter Schorn,
|
20-Jul-01 RMS Added Macintosh support (from Louis Chretien, Peter Schorn,
|
||||||
and Ben Supnik)
|
and Ben Supnik)
|
||||||
15-May-01 RMS Added logging support
|
15-May-01 RMS Added logging support
|
||||||
|
@ -50,7 +52,6 @@
|
||||||
The POSIX UNIX version works with LINUX.
|
The POSIX UNIX version works with LINUX.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#undef USE_INT64 /* hack for Windows */
|
|
||||||
#include "sim_defs.h"
|
#include "sim_defs.h"
|
||||||
int32 sim_int_char = 005; /* interrupt character */
|
int32 sim_int_char = 005; /* interrupt character */
|
||||||
extern FILE *sim_log;
|
extern FILE *sim_log;
|
||||||
|
@ -190,7 +191,7 @@ return quo;
|
||||||
|
|
||||||
/* Win32 routines */
|
/* Win32 routines */
|
||||||
|
|
||||||
#if defined (WIN32)
|
#if defined (_WIN32)
|
||||||
#define __TTYROUTINES 0
|
#define __TTYROUTINES 0
|
||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -326,6 +327,7 @@ return 0;
|
||||||
#include <sioux.h>
|
#include <sioux.h>
|
||||||
#include <siouxglobals.h>
|
#include <siouxglobals.h>
|
||||||
#include <Traps.h>
|
#include <Traps.h>
|
||||||
|
#include <LowMem.h>
|
||||||
|
|
||||||
extern char sim_name[];
|
extern char sim_name[];
|
||||||
extern pSIOUXWin SIOUXTextWindow;
|
extern pSIOUXWin SIOUXTextWindow;
|
||||||
|
@ -339,7 +341,11 @@ static void updateCursor(void) {
|
||||||
Point localMouse;
|
Point localMouse;
|
||||||
GetPort(&savePort);
|
GetPort(&savePort);
|
||||||
SetPort(window);
|
SetPort(window);
|
||||||
|
#if !TARGET_API_MAC_CARBON
|
||||||
|
localMouse = LMGetMouseLocation();
|
||||||
|
#else
|
||||||
GetGlobalMouse(&localMouse);
|
GetGlobalMouse(&localMouse);
|
||||||
|
#endif
|
||||||
GlobalToLocal(&localMouse);
|
GlobalToLocal(&localMouse);
|
||||||
if (PtInRect(localMouse, &(*SIOUXTextWindow->edit)->viewRect) && iBeamCursorH) {
|
if (PtInRect(localMouse, &(*SIOUXTextWindow->edit)->viewRect) && iBeamCursorH) {
|
||||||
SetCursor(*iBeamCursorH);
|
SetCursor(*iBeamCursorH);
|
||||||
|
|
76
sim_defs.h
76
sim_defs.h
|
@ -23,6 +23,10 @@
|
||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
27-Sep-01 RMS Added queue count prototype
|
||||||
|
17-Sep-01 RMS Removed multiple console support
|
||||||
|
07-Sep-01 RMS Removed conditional externs on function prototypes
|
||||||
|
31-Aug-01 RMS Changed int64 to t_int64 for Windoze
|
||||||
17-Jul-01 RMS Added additional function prototypes
|
17-Jul-01 RMS Added additional function prototypes
|
||||||
27-May-01 RMS Added multiple console support
|
27-May-01 RMS Added multiple console support
|
||||||
15-May-01 RMS Increased string buffer size
|
15-May-01 RMS Increased string buffer size
|
||||||
|
@ -73,16 +77,18 @@ typedef int t_bool; /* boolean */
|
||||||
typedef unsigned int8 uint8;
|
typedef unsigned int8 uint8;
|
||||||
typedef unsigned int16 uint16;
|
typedef unsigned int16 uint16;
|
||||||
typedef unsigned int32 uint32, t_addr; /* address */
|
typedef unsigned int32 uint32, t_addr; /* address */
|
||||||
#if defined (USE_INT64) && defined (WIN32)
|
#if defined (USE_INT64) && defined (_WIN32)
|
||||||
#define int64 __int64 /* for Windows */
|
#define t_int64 __int64 /* for Windows */
|
||||||
#elif defined (USE_INT64) && defined (__digital__) && defined (__unix__)
|
#elif defined (USE_INT64) && defined (VMS) && defined (__ALPHA)
|
||||||
#define int64 long /* for DUNIX */
|
#define t_int64 __int64 /* for AVMS */
|
||||||
|
#elif defined (USE_INT64) && defined (__ALPHA) && defined (__unix__)
|
||||||
|
#define t_int64 long /* for DUNIX */
|
||||||
#elif defined (USE_INT64)
|
#elif defined (USE_INT64)
|
||||||
#define int64 long long /* for GCC */
|
#define t_int64 long long /* for GCC */
|
||||||
#endif
|
#endif
|
||||||
#if defined (int64)
|
#if defined (t_int64)
|
||||||
typedef unsigned int64 uint64, t_value; /* value */
|
typedef unsigned t_int64 t_uint64, t_value; /* value */
|
||||||
typedef int64 t_svalue; /* signed value */
|
typedef t_int64 t_svalue; /* signed value */
|
||||||
#else
|
#else
|
||||||
typedef unsigned int32 t_value;
|
typedef unsigned int32 t_value;
|
||||||
typedef int32 t_svalue;
|
typedef int32 t_svalue;
|
||||||
|
@ -221,8 +227,6 @@ struct unit {
|
||||||
#define UNIT_BUF 000400 /* buffered */
|
#define UNIT_BUF 000400 /* buffered */
|
||||||
#define UNIT_DISABLE 001000 /* disable-able */
|
#define UNIT_DISABLE 001000 /* disable-able */
|
||||||
#define UNIT_DIS 002000 /* disabled */
|
#define UNIT_DIS 002000 /* disabled */
|
||||||
#define UNIT_CONS 004000 /* active console */
|
|
||||||
#define UNIT_V_CONS 11
|
|
||||||
#define UNIT_V_UF 12 /* device specific */
|
#define UNIT_V_UF 12 /* device specific */
|
||||||
|
|
||||||
/* Register data structure */
|
/* Register data structure */
|
||||||
|
@ -254,8 +258,8 @@ struct ctab {
|
||||||
/* Modifier table */
|
/* Modifier table */
|
||||||
|
|
||||||
struct mtab {
|
struct mtab {
|
||||||
int32 mask; /* mask */
|
int32 mask; /* mask or radix */
|
||||||
int32 match; /* match */
|
int32 match; /* match or max */
|
||||||
char *pstring; /* print string */
|
char *pstring; /* print string */
|
||||||
char *mstring; /* match string */
|
char *mstring; /* match string */
|
||||||
t_stat (*valid)(); /* validation routine */
|
t_stat (*valid)(); /* validation routine */
|
||||||
|
@ -301,30 +305,24 @@ typedef struct schtab SCHTAB;
|
||||||
|
|
||||||
/* Function prototypes */
|
/* Function prototypes */
|
||||||
|
|
||||||
#if defined (SCP) /* defining routine? */
|
t_stat sim_process_event (void);
|
||||||
#define EXTERN
|
t_stat sim_activate (UNIT *uptr, int32 interval);
|
||||||
#else /* referencing routine */
|
t_stat sim_cancel (UNIT *uptr);
|
||||||
#define EXTERN extern
|
int32 sim_is_active (UNIT *uptr);
|
||||||
#endif
|
double sim_gtime (void);
|
||||||
|
uint32 sim_grtime (void);
|
||||||
EXTERN t_stat sim_process_event (void);
|
int32 sim_qcount (void);
|
||||||
EXTERN t_stat sim_activate (UNIT *uptr, int32 interval);
|
t_stat attach_unit (UNIT *uptr, char *cptr);
|
||||||
EXTERN t_stat sim_cancel (UNIT *uptr);
|
t_stat detach_unit (UNIT *uptr);
|
||||||
EXTERN int32 sim_is_active (UNIT *uptr);
|
t_stat reset_all (int start_device);
|
||||||
EXTERN double sim_gtime (void);
|
size_t fxread (void *bptr, size_t size, size_t count, FILE *fptr);
|
||||||
EXTERN uint32 sim_grtime (void);
|
size_t fxwrite (void *bptr, size_t size, size_t count, FILE *fptr);
|
||||||
EXTERN t_stat attach_unit (UNIT *uptr, char *cptr);
|
t_stat get_yn (char *ques, t_stat deflt);
|
||||||
EXTERN t_stat detach_unit (UNIT *uptr);
|
char *get_glyph (char *iptr, char *optr, char mchar);
|
||||||
EXTERN t_stat reset_all (int start_device);
|
char *get_glyph_nc (char *iptr, char *optr, char mchar);
|
||||||
EXTERN size_t fxread (void *bptr, size_t size, size_t count, FILE *fptr);
|
t_value get_uint (char *cptr, int radix, t_value max, t_stat *status);
|
||||||
EXTERN size_t fxwrite (void *bptr, size_t size, size_t count, FILE *fptr);
|
t_value strtotv (char *cptr, char **endptr, int radix);
|
||||||
EXTERN t_stat get_yn (char *ques, t_stat deflt);
|
int32 sim_rtc_init (int32 time);
|
||||||
EXTERN char *get_glyph (char *iptr, char *optr, char mchar);
|
int32 sim_rtc_calb (int32 ticksper);
|
||||||
EXTERN char *get_glyph_nc (char *iptr, char *optr, char mchar);
|
t_stat sim_poll_kbd (void);
|
||||||
EXTERN t_value get_uint (char *cptr, int radix, t_value max, t_stat *status);
|
t_stat sim_putchar (int32 out);
|
||||||
EXTERN t_value strtotv (char *cptr, char **endptr, int radix);
|
|
||||||
EXTERN int32 sim_rtc_init (int32 time);
|
|
||||||
EXTERN int32 sim_rtc_calb (int32 ticksper);
|
|
||||||
EXTERN t_stat set_console (UNIT *uptr, int32 flag);
|
|
||||||
EXTERN t_stat sim_putcons (int32 out, UNIT *uptr);
|
|
||||||
|
|
||||||
|
|
123
sim_rev.h
Normal file
123
sim_rev.h
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/* sim_rev.h: simulator revisions and current rev level
|
||||||
|
|
||||||
|
Copyright (c) 1993-2001, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SIM_MAJOR 2
|
||||||
|
#define SIM_MINOR 7
|
||||||
|
#define SIM_PATCH 15
|
||||||
|
|
||||||
|
/* SIMH detailed revision list, starting with V2.7
|
||||||
|
|
||||||
|
patch date module(s) and fix(es)
|
||||||
|
|
||||||
|
15 23-Oct-01 pdp11_rp.c, pdp10_rp.c, pdp10_tu.c: fixed bugs
|
||||||
|
error interrupt handling
|
||||||
|
|
||||||
|
pdp10_defs.h, pdp10_ksio.c, pdp10_fe.c, pdp10_fe.c,
|
||||||
|
pdp10_rp.c, pdp10_tu.c: reworked I/O page interface
|
||||||
|
to use symbolic base addresses and lengths
|
||||||
|
|
||||||
|
14 20-Oct-01 dec_dz.h, sim_tmxr_h, sim_tmxr.c: fixed bug in Telnet
|
||||||
|
state handling (found by Thord Nilson), removed
|
||||||
|
tmxr_getchar, added tmxr_rqln and tmxr_tqln
|
||||||
|
|
||||||
|
13 18-Oct-01 pdp11_tm.c: added stub diagnostic register clock
|
||||||
|
for RSTS/E (found by Thord Nilson)
|
||||||
|
|
||||||
|
12 15-Oct-01 pdp11_defs.h, pdp11_cpu.c, pdp11_tc.c, pdp11_ts.c,
|
||||||
|
pdp11_rp.c: added operations logging
|
||||||
|
|
||||||
|
11 8-Oct-01 scp.c: added sim_rev.h include and version print
|
||||||
|
|
||||||
|
pdp11_cpu.c: fixed bug in interrupt acknowledge,
|
||||||
|
multiple outstanding interrupts caused the lowest
|
||||||
|
rather than the highest to be acknowledged
|
||||||
|
|
||||||
|
10 7-Oct-01 pdp11_stddev.c: added monitor bits (CSR<7>) for full
|
||||||
|
KW11L compatibility, needed for RSTS/E autoconfiguration
|
||||||
|
|
||||||
|
9 6-Oct-01 pdp11_rp.c, pdp10_rp.c, pdp10_tu.c: rewrote interrupt
|
||||||
|
logic from RH11/RH70 schematics, to mimic hardware quirks
|
||||||
|
|
||||||
|
dec_dz.c: fixed bug in carrier detect logic, carrier
|
||||||
|
detect was being cleared on next modem poll
|
||||||
|
|
||||||
|
8 4-Oct-01 pdp11_rp.c, pdp10_rp.c, pdp10_tu.c: undid edit of
|
||||||
|
28-Sep-01; real problem was level-sensitive nature of
|
||||||
|
CS1_SC, but CS1_SC can only trigger an interrupt if
|
||||||
|
DONE is set
|
||||||
|
|
||||||
|
7 2-Oct-01 pdp11_rp.c, pdp10_rp.c: CS1_SC is evaluated as a level-
|
||||||
|
sensitive, rather than an edge-sensitive, input to
|
||||||
|
interrupt request
|
||||||
|
|
||||||
|
6 30-Sep-01 pdp11_rp.c, pdp10_rp.c: separated out CS1<5:0> to per-
|
||||||
|
drive registers
|
||||||
|
|
||||||
|
pdp10_tu.c: based on above, cleaned up handling of
|
||||||
|
non-existent formatters, fixed non-data transfer commands
|
||||||
|
clearing DONE
|
||||||
|
|
||||||
|
5 28-Sep-01 pdp11_rp.c, pdp10_rp.c, pdp10_tu.c: controller should
|
||||||
|
interrupt if ATA or SC sets when IE is set, was
|
||||||
|
interrupting only if DON = 1 as well
|
||||||
|
|
||||||
|
4 27-Sep-01 pdp11_ts.c:
|
||||||
|
-- NXM errors should return TC4 or TC5; were returning TC3
|
||||||
|
-- extended features is part of XS2; was returned in XS3
|
||||||
|
-- extended characteristics (fifth) word needed for RSTS/E
|
||||||
|
|
||||||
|
pdp11_tc.c: stop, stop all do cause an interrupt
|
||||||
|
|
||||||
|
dec_dz.h: scanner should find a ready output line, even
|
||||||
|
if there are no connections; needed for RSTS/E autoconfigure
|
||||||
|
|
||||||
|
scp.c:
|
||||||
|
-- added routine sim_qcount for 1130
|
||||||
|
-- added "simulator exit" detach routine for 1130
|
||||||
|
|
||||||
|
sim_defs.h: added header for sim_qcount
|
||||||
|
|
||||||
|
3 20-Sep-01 pdp11_ts.c: boot code binary was incorrect
|
||||||
|
|
||||||
|
2 19-Sep-01 pdp18b_cpu.c: EAE should interpret initial count of 00
|
||||||
|
as 100
|
||||||
|
|
||||||
|
scp.c: modified Macintosh support
|
||||||
|
|
||||||
|
1 17-Sep-01 pdp8_ttx.c: new module for PDP-8 multi-terminal support
|
||||||
|
|
||||||
|
pdp18b_tt1.c: modified to use sim_tmxr library
|
||||||
|
|
||||||
|
nova_tt1.c: modified to use sim_tmxr library
|
||||||
|
|
||||||
|
dec_dz.h: added autodisconnect support
|
||||||
|
|
||||||
|
scp.c: removed old multiconsole support
|
||||||
|
|
||||||
|
sim_tmxr.c: modified calling sequence for sim_putchar_ln
|
||||||
|
|
||||||
|
sim_sock.c: added Macintosh sockets support
|
||||||
|
*/
|
210
sim_sock.c
Normal file
210
sim_sock.c
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
/* scp_sock.c: OS-dependent socket routines
|
||||||
|
|
||||||
|
Copyright (c) 2001, 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.
|
||||||
|
|
||||||
|
16-Sep-01 RMS Added Macintosh support from Peter Schorn
|
||||||
|
02-Sep-01 RMS Fixed UNIX bugs found by Mirian Lennox and Tom Markson
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sim_defs.h"
|
||||||
|
#include "sim_sock.h"
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
/* OS dependent routines
|
||||||
|
|
||||||
|
sim_master_sock create master socket
|
||||||
|
sim_accept_conn accept connection
|
||||||
|
sim_read_sock read from socket
|
||||||
|
sim_write_sock write from socket
|
||||||
|
sim_close_sock close socket
|
||||||
|
sim_setnonblock set socket non-blocking
|
||||||
|
sim_msg_sock send message to socket
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* First, all the non-implemented versions */
|
||||||
|
|
||||||
|
#if defined (VMS) || defined (__OS2__)
|
||||||
|
|
||||||
|
SOCKET sim_master_sock (int32 port)
|
||||||
|
{
|
||||||
|
return INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
SOCKET sim_accept_conn (SOCKET master, UNIT *uptr)
|
||||||
|
{
|
||||||
|
return INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 sim_read_sock (SOCKET sock, char *buf, int32 nbytes)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 sim_write_sock (SOCKET sock, char *msg, int32 nbytes)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sim_close_sock (SOCKET sock)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SOCKET sim_setnonblock (SOCKET sock)
|
||||||
|
{
|
||||||
|
return SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* endif unimpl */
|
||||||
|
|
||||||
|
/* UNIX, Win32, Macintosh (Berkeley socket) routines */
|
||||||
|
|
||||||
|
SOCKET sim_master_sock (int32 port)
|
||||||
|
{
|
||||||
|
SOCKET newsock;
|
||||||
|
struct sockaddr_in name;
|
||||||
|
int32 sta;
|
||||||
|
|
||||||
|
#if defined (_WIN32)
|
||||||
|
WORD wVersionRequested;
|
||||||
|
WSADATA wsaData;
|
||||||
|
wVersionRequested = MAKEWORD(1, 1);
|
||||||
|
|
||||||
|
sta = WSAStartup(wVersionRequested, &wsaData); /* start Winsock */
|
||||||
|
if (sta != 0) {
|
||||||
|
printf ("Winsock: startup error %d\n", sta);
|
||||||
|
return sta; }
|
||||||
|
#endif /* endif Win32 */
|
||||||
|
|
||||||
|
newsock = socket (AF_INET, SOCK_STREAM, 0); /* create socket */
|
||||||
|
if (newsock == INVALID_SOCKET) { /* socket error? */
|
||||||
|
perror ("Sockets: socket error");
|
||||||
|
return INVALID_SOCKET; }
|
||||||
|
|
||||||
|
name.sin_family = AF_INET; /* name socket */
|
||||||
|
name.sin_port = htons ((unsigned short) port); /* insert port */
|
||||||
|
name.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||||
|
sta = bind (newsock, (struct sockaddr *) &name, sizeof (name));
|
||||||
|
if (sta == SOCKET_ERROR) { /* bind error? */
|
||||||
|
perror ("Sockets: bind error");
|
||||||
|
sim_close_sock (newsock, 1);
|
||||||
|
return INVALID_SOCKET; }
|
||||||
|
|
||||||
|
sta = sim_setnonblock (newsock); /* set nonblocking */
|
||||||
|
if (sta == SOCKET_ERROR) { /* fcntl error? */
|
||||||
|
perror ("Sockets: fcntl error");
|
||||||
|
sim_close_sock (newsock, 1);
|
||||||
|
return INVALID_SOCKET; }
|
||||||
|
|
||||||
|
sta = listen (newsock, 1); /* listen on socket */
|
||||||
|
if (sta == SOCKET_ERROR) { /* listen error? */
|
||||||
|
perror ("Sockets: listen error");
|
||||||
|
sim_close_sock (newsock, 1);
|
||||||
|
return INVALID_SOCKET; }
|
||||||
|
return newsock; /* got it! */
|
||||||
|
}
|
||||||
|
|
||||||
|
SOCKET sim_accept_conn (SOCKET master, UNIT *uptr, uint32 *ipaddr)
|
||||||
|
{
|
||||||
|
int32 sta;
|
||||||
|
#if defined (macintosh)
|
||||||
|
socklen_t size;
|
||||||
|
#else
|
||||||
|
size_t size;
|
||||||
|
#endif
|
||||||
|
SOCKET newsock;
|
||||||
|
struct sockaddr_in clientname;
|
||||||
|
|
||||||
|
if ((uptr -> flags & UNIT_ATT) == 0) /* not attached? */
|
||||||
|
return INVALID_SOCKET;
|
||||||
|
size = sizeof (clientname);
|
||||||
|
newsock = accept (master, (struct sockaddr *) &clientname, &size);
|
||||||
|
if (newsock == INVALID_SOCKET) { /* error? */
|
||||||
|
if (WSAGetLastError () != WSAEWOULDBLOCK)
|
||||||
|
perror ("Sockets: accept error");
|
||||||
|
return INVALID_SOCKET; }
|
||||||
|
if (ipaddr != NULL) *ipaddr = ntohl (clientname.sin_addr.s_addr);
|
||||||
|
|
||||||
|
sta = sim_setnonblock (newsock); /* set nonblocking */
|
||||||
|
if (sta == SOCKET_ERROR) { /* fcntl error? */
|
||||||
|
perror ("Sockets: fcntl error");
|
||||||
|
sim_close_sock (newsock, 0);
|
||||||
|
return INVALID_SOCKET; }
|
||||||
|
return newsock;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 sim_read_sock (SOCKET sock, char *buf, int32 nbytes)
|
||||||
|
{
|
||||||
|
int32 rbytes;
|
||||||
|
|
||||||
|
rbytes = recv (sock, buf, nbytes, 0);
|
||||||
|
if (rbytes == 0) return -1; /* disconnect */
|
||||||
|
if (rbytes == SOCKET_ERROR) {
|
||||||
|
if (WSAGetLastError () == WSAEWOULDBLOCK) return 0; /* no data */
|
||||||
|
perror("Sockets: read error");
|
||||||
|
return -1; }
|
||||||
|
return rbytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 sim_write_sock (SOCKET sock, char *msg, int32 nbytes)
|
||||||
|
{
|
||||||
|
return send (sock, msg, nbytes, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sim_close_sock (SOCKET sock, t_bool master)
|
||||||
|
{
|
||||||
|
#if defined (_WIN32)
|
||||||
|
closesocket (sock);
|
||||||
|
if (master) WSACleanup ();
|
||||||
|
#else
|
||||||
|
close (sock);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (_WIN32)
|
||||||
|
SOCKET sim_setnonblock (SOCKET sock)
|
||||||
|
{
|
||||||
|
unsigned long non_block = 1;
|
||||||
|
|
||||||
|
return ioctlsocket (sock, FIONBIO, &non_block); /* set nonblocking */
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int32 sim_setnonblock (SOCKET sock)
|
||||||
|
{
|
||||||
|
int32 fl, sta;
|
||||||
|
|
||||||
|
fl = fcntl (sock, F_GETFL,0); /* get flags */
|
||||||
|
if (fl == -1) return SOCKET_ERROR;
|
||||||
|
sta = fcntl (sock, F_SETFL, fl | O_NONBLOCK); /* set nonblock */
|
||||||
|
if (sta == -1) return SOCKET_ERROR;
|
||||||
|
#if !defined (macintosh)
|
||||||
|
sta = fcntl (sock, F_SETOWN, getpid()); /* set ownership */
|
||||||
|
if (sta == -1) return SOCKET_ERROR;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* endif Win32 */
|
||||||
|
|
||||||
|
#endif /* endif Win32/UNIX/Mac */
|
64
sim_sock.h
Normal file
64
sim_sock.h
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/* scp_sock.h: OS-dependent socket routines header file
|
||||||
|
|
||||||
|
Copyright (c) 2001, 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.
|
||||||
|
|
||||||
|
16-Sep-01 RMS Added Macintosh support from Peter Schorn
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined (WIN32)
|
||||||
|
#undef INT_PTR /* hack, hack */
|
||||||
|
#include <winsock.h>
|
||||||
|
#else
|
||||||
|
#define WSAGetLastError() errno
|
||||||
|
#if !defined (VMS) && !defined (__OS2__)
|
||||||
|
#include <sys/types.h> /* for fcntl, getpid */
|
||||||
|
#include <sys/socket.h> /* for sockets */
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <netinet/in.h> /* for sockaddr_in */
|
||||||
|
#include <netdb.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Code uses Windows-specific defs that are undefined for most systems */
|
||||||
|
|
||||||
|
#if !defined (SOCKET)
|
||||||
|
#define SOCKET int32
|
||||||
|
#endif
|
||||||
|
#if !defined (WSAEWOULDBLOCK)
|
||||||
|
#define WSAEWOULDBLOCK EWOULDBLOCK
|
||||||
|
#endif
|
||||||
|
#if !defined (INVALID_SOCKET)
|
||||||
|
#define INVALID_SOCKET -1
|
||||||
|
#endif
|
||||||
|
#if !defined (SOCKET_ERROR)
|
||||||
|
#define SOCKET_ERROR -1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SOCKET sim_master_sock (int32 port);
|
||||||
|
SOCKET sim_accept_conn (SOCKET master, UNIT *uptr, uint32 *ipaddr);
|
||||||
|
int32 sim_read_sock (SOCKET sock, char *buf, int32 nbytes);
|
||||||
|
int32 sim_write_sock (SOCKET sock, char *msg, int32 nbytes);
|
||||||
|
void sim_close_sock (SOCKET sock, t_bool master);
|
||||||
|
SOCKET sim_setnonblock (SOCKET sock);
|
403
sim_tmxr.c
Normal file
403
sim_tmxr.c
Normal file
|
@ -0,0 +1,403 @@
|
||||||
|
/* sim_tmxr.c: Telnet terminal multiplexor library
|
||||||
|
|
||||||
|
Copyright (c) 2001, 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.
|
||||||
|
|
||||||
|
Based on the original DZ11 simulator by Thord Nilson, as updated by
|
||||||
|
Arthur Krewat.
|
||||||
|
|
||||||
|
20-Oct-01 RMS Fixed bugs in read logic (found by Thord Nilson).
|
||||||
|
added tmxr_rqln, tmxr_tqln
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sim_defs.h"
|
||||||
|
#include "sim_sock.h"
|
||||||
|
#include "sim_tmxr.h"
|
||||||
|
|
||||||
|
/* Telnet protocol constants - negatives are for init'ing signed char data */
|
||||||
|
|
||||||
|
#define TN_IAC -1 /* protocol delim */
|
||||||
|
#define TN_DONT -2 /* dont */
|
||||||
|
#define TN_DO -3 /* do */
|
||||||
|
#define TN_WONT -4 /* wont */
|
||||||
|
#define TN_WILL -5 /* will */
|
||||||
|
#define TN_BIN 0 /* bin */
|
||||||
|
#define TN_ECHO 1 /* echo */
|
||||||
|
#define TN_SGA 3 /* sga */
|
||||||
|
#define TN_LINE 34 /* line mode */
|
||||||
|
#define TN_CR 015 /* carriage return */
|
||||||
|
|
||||||
|
/* Telnet line states */
|
||||||
|
|
||||||
|
#define TNS_NORM 000 /* normal */
|
||||||
|
#define TNS_IAC 001 /* IAC seen */
|
||||||
|
#define TNS_WILL 002 /* WILL seen */
|
||||||
|
#define TNS_WONT 003 /* WONT seen */
|
||||||
|
#define TNS_SKIP 004 /* skip next */
|
||||||
|
|
||||||
|
void tmxr_rmvrc (TMLN *lp, int32 p);
|
||||||
|
extern int32 sim_switches;
|
||||||
|
extern char sim_name[];
|
||||||
|
extern FILE *sim_log;
|
||||||
|
extern uint32 sim_os_msec (void);
|
||||||
|
|
||||||
|
/* Poll for new connection
|
||||||
|
|
||||||
|
Called from unit service routine to test for new connection
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
*mp = pointer to terminal multiplexor descriptor
|
||||||
|
Outputs:
|
||||||
|
line number activated, -1 if none
|
||||||
|
*/
|
||||||
|
|
||||||
|
int32 tmxr_poll_conn (TMXR *mp, UNIT *uptr)
|
||||||
|
{
|
||||||
|
SOCKET newsock;
|
||||||
|
TMLN *lp;
|
||||||
|
int32 i;
|
||||||
|
uint32 ipaddr;
|
||||||
|
static char mantra[] = {
|
||||||
|
TN_IAC, TN_WILL, TN_LINE,
|
||||||
|
TN_IAC, TN_WILL, TN_SGA,
|
||||||
|
TN_IAC, TN_WILL, TN_ECHO,
|
||||||
|
TN_IAC, TN_WILL, TN_BIN,
|
||||||
|
TN_IAC, TN_DO, TN_BIN };
|
||||||
|
|
||||||
|
newsock = sim_accept_conn (mp -> master, uptr, &ipaddr);/* poll connect */
|
||||||
|
if (newsock != INVALID_SOCKET) { /* got a live one? */
|
||||||
|
for (i = 0; i < mp -> lines; i++) { /* find avail line */
|
||||||
|
lp = mp -> ldsc[i]; /* ptr to ln desc */
|
||||||
|
if (lp -> conn == 0) break; } /* available? */
|
||||||
|
if (i >= mp -> lines) { /* all busy? */
|
||||||
|
tmxr_msg (newsock, "All connections busy... please try later\r\n");
|
||||||
|
sim_close_sock (newsock, 0); }
|
||||||
|
else { lp = mp -> ldsc[i]; /* get line desc */
|
||||||
|
lp -> conn = newsock; /* record connection */
|
||||||
|
lp -> ipad = ipaddr; /* ip address */
|
||||||
|
lp -> cnms = sim_os_msec (); /* time of conn */
|
||||||
|
lp -> rxbpr = lp -> rxbpi = 0; /* init buf pointers */
|
||||||
|
lp -> txbpr = lp -> txbpi = 0;
|
||||||
|
lp -> rxcnt = lp -> txcnt = 0; /* init counters */
|
||||||
|
lp -> tsta = 0; /* init telnet state */
|
||||||
|
lp -> xmte = 1; /* enable transmit */
|
||||||
|
lp -> dstb = 0; /* default bin mode */
|
||||||
|
sim_write_sock (newsock, mantra, 15);
|
||||||
|
tmxr_msg (newsock, "\n\r\nWelcome to the ");
|
||||||
|
tmxr_msg (newsock, sim_name);
|
||||||
|
tmxr_msg (newsock, " simulator\r\n\n");
|
||||||
|
return i; }
|
||||||
|
} /* end if newsock */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset line */
|
||||||
|
|
||||||
|
void tmxr_reset_ln (TMLN *lp)
|
||||||
|
{
|
||||||
|
sim_close_sock (lp -> conn, 0); /* reset conn */
|
||||||
|
lp -> conn = lp -> tsta = 0; /* reset state */
|
||||||
|
lp -> rxbpr = lp -> rxbpi = 0;
|
||||||
|
lp -> txbpr = lp -> txbpi = 0;
|
||||||
|
lp -> xmte = 1;
|
||||||
|
lp -> dstb = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get character from specific line
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
*lp = pointer to terminal line descriptor
|
||||||
|
Output:
|
||||||
|
valid + char, 0 if line
|
||||||
|
*/
|
||||||
|
|
||||||
|
int32 tmxr_getc_ln (TMLN *lp)
|
||||||
|
{
|
||||||
|
int32 j, val = 0;
|
||||||
|
uint32 tmp;
|
||||||
|
|
||||||
|
if (lp -> conn && lp -> rcve) { /* conn & enb? */
|
||||||
|
j = lp -> rxbpi - lp -> rxbpr; /* # input chrs */
|
||||||
|
if (j) { /* any? */
|
||||||
|
tmp = lp -> rxb[lp -> rxbpr]; /* get char */
|
||||||
|
lp -> rxbpr = lp -> rxbpr + 1; /* adv pointer */
|
||||||
|
val = TMXR_VALID | (tmp & 0377); } /* valid + chr */
|
||||||
|
} /* end if conn */
|
||||||
|
if (lp -> rxbpi == lp -> rxbpr) /* empty? zero ptrs */
|
||||||
|
lp -> rxbpi = lp -> rxbpr = 0;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Poll for input
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
*mp = pointer to terminal multiplexor descriptor
|
||||||
|
Outputs: none
|
||||||
|
*/
|
||||||
|
|
||||||
|
void tmxr_poll_rx (TMXR *mp)
|
||||||
|
{
|
||||||
|
int32 i, nbytes, j;
|
||||||
|
TMLN *lp;
|
||||||
|
|
||||||
|
for (i = 0; i < mp -> lines; i++) { /* loop thru lines */
|
||||||
|
lp = mp -> ldsc[i]; /* get line desc */
|
||||||
|
if (!lp -> conn || !lp -> rcve) continue; /* skip if !conn */
|
||||||
|
|
||||||
|
nbytes = 0;
|
||||||
|
if (lp -> rxbpi == 0) /* need input? */
|
||||||
|
nbytes = sim_read_sock (lp -> conn, /* yes, read */
|
||||||
|
&(lp -> rxb[lp -> rxbpi]), /* leave spc for */
|
||||||
|
TMXR_MAXBUF - TMXR_GUARD); /* Telnet cruft */
|
||||||
|
else if (lp -> tsta) /* in Telnet seq? */
|
||||||
|
nbytes = sim_read_sock (lp -> conn, /* yes, read to end */
|
||||||
|
&(lp -> rxb[lp -> rxbpi]),
|
||||||
|
TMXR_MAXBUF - lp -> rxbpi);
|
||||||
|
if (nbytes < 0) tmxr_reset_ln (lp); /* closed? reset ln */
|
||||||
|
else if (nbytes > 0) { /* if data rcvd */
|
||||||
|
j = lp -> rxbpi; /* start of data */
|
||||||
|
lp -> rxbpi = lp -> rxbpi + nbytes; /* adv pointers */
|
||||||
|
lp -> rxcnt = lp -> rxcnt + nbytes;
|
||||||
|
|
||||||
|
/* Examine new data, remove TELNET cruft before making input available */
|
||||||
|
|
||||||
|
for (; j < lp -> rxbpi; ) { /* loop thru char */
|
||||||
|
char tmp = lp -> rxb[j]; /* get char */
|
||||||
|
switch (lp -> tsta) { /* case tlnt state */
|
||||||
|
case TNS_NORM: /* normal */
|
||||||
|
if (tmp == TN_IAC) { /* IAC? */
|
||||||
|
lp -> tsta = TNS_IAC; /* change state */
|
||||||
|
tmxr_rmvrc (lp, j); /* remove char */
|
||||||
|
break; }
|
||||||
|
if ((tmp == TN_CR) && lp -> dstb) /* CR, no bin */
|
||||||
|
lp -> tsta = TNS_SKIP; /* skip next */
|
||||||
|
j = j + 1; /* advance j */
|
||||||
|
break;
|
||||||
|
case TNS_IAC: /* IAC prev */
|
||||||
|
if (tmp == TN_WILL) /* IAC + WILL? */
|
||||||
|
lp -> tsta = TNS_WILL;
|
||||||
|
else if (tmp == TN_WONT) /* IAC + WONT? */
|
||||||
|
lp -> tsta = TNS_WONT;
|
||||||
|
else lp -> tsta = TNS_SKIP; /* IAC + other */
|
||||||
|
tmxr_rmvrc (lp, j); /* remove char */
|
||||||
|
break;
|
||||||
|
case TNS_WILL: case TNS_WONT: /* IAC+WILL/WONT prev */
|
||||||
|
if (tmp == TN_BIN) { /* BIN? */
|
||||||
|
if (lp -> tsta == TNS_WILL) lp -> dstb = 0;
|
||||||
|
else lp -> dstb = 1; }
|
||||||
|
case TNS_SKIP: default: /* skip char */
|
||||||
|
lp -> tsta = TNS_NORM; /* next normal */
|
||||||
|
tmxr_rmvrc (lp, j); /* remove char */
|
||||||
|
break; } /* end case state */
|
||||||
|
} /* end for char */
|
||||||
|
} /* end else nbytes */
|
||||||
|
} /* end for lines */
|
||||||
|
for (i = 0; i < mp -> lines; i++) { /* loop thru lines */
|
||||||
|
lp = mp -> ldsc[i]; /* get line desc */
|
||||||
|
if (lp -> rxbpi == lp -> rxbpr) /* if buf empty, */
|
||||||
|
lp -> rxbpi = lp -> rxbpr = 0; /* reset pointers */
|
||||||
|
} /* end for */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return count of available characters for line */
|
||||||
|
|
||||||
|
int32 tmxr_rqln (TMLN *lp)
|
||||||
|
{
|
||||||
|
return (lp -> rxbpi - lp -> rxbpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove character p from line l input buffer */
|
||||||
|
|
||||||
|
void tmxr_rmvrc (TMLN *lp, int32 p)
|
||||||
|
{
|
||||||
|
for ( ; p < lp -> rxbpi; p++) lp -> rxb[p] = lp -> rxb[p + 1];
|
||||||
|
lp -> rxbpi = lp -> rxbpi - 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store character in line buffer
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
*lp = pointer to line descriptor
|
||||||
|
chr = characters
|
||||||
|
Outputs:
|
||||||
|
none
|
||||||
|
*/
|
||||||
|
|
||||||
|
void tmxr_putc_ln (TMLN *lp, int32 chr)
|
||||||
|
{
|
||||||
|
if (lp -> conn == 0) return; /* no conn? done */
|
||||||
|
if (lp -> txbpi < TMXR_MAXBUF) { /* room for char? */
|
||||||
|
lp -> txb[lp -> txbpi] = (char) chr; /* buffer char */
|
||||||
|
lp -> txbpi = lp -> txbpi + 1; /* adv pointer */
|
||||||
|
if (lp -> txbpi > (TMXR_MAXBUF - TMXR_GUARD)) /* near full? */
|
||||||
|
lp -> xmte = 0; } /* disable line */
|
||||||
|
else lp -> xmte = 0; /* disable line */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Poll for output
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
*mp = pointer to terminal multiplexor descriptor
|
||||||
|
Outputs:
|
||||||
|
none
|
||||||
|
*/
|
||||||
|
|
||||||
|
void tmxr_poll_tx (TMXR *mp)
|
||||||
|
{
|
||||||
|
int32 i, nbytes, sbytes;
|
||||||
|
TMLN *lp;
|
||||||
|
|
||||||
|
for (i = 0; i < mp -> lines; i++) { /* loop thru lines */
|
||||||
|
lp = mp -> ldsc[i]; /* get line desc */
|
||||||
|
if (lp -> conn == 0) continue; /* skip if !conn */
|
||||||
|
nbytes = lp -> txbpi - lp -> txbpr; /* avail bytes */
|
||||||
|
if (nbytes) { /* >0? write */
|
||||||
|
sbytes = sim_write_sock (lp -> conn,
|
||||||
|
&(lp -> txb[lp -> txbpr]), nbytes);
|
||||||
|
if (sbytes != SOCKET_ERROR) { /* update ptrs */
|
||||||
|
lp -> txbpr = lp -> txbpr + sbytes;
|
||||||
|
lp -> txcnt = lp -> txcnt + sbytes;
|
||||||
|
nbytes = nbytes - sbytes; }
|
||||||
|
}
|
||||||
|
if (nbytes == 0) { /* buf empty? */
|
||||||
|
lp -> xmte = 1; /* enable this line */
|
||||||
|
lp -> txbpr = lp -> txbpi = 0; }
|
||||||
|
} /* end for */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return count of buffered characters for line */
|
||||||
|
|
||||||
|
int32 tmxr_tqln (TMLN *lp)
|
||||||
|
{
|
||||||
|
return (lp -> txbpi - lp -> txbpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attach */
|
||||||
|
|
||||||
|
t_stat tmxr_attach (TMXR *mp, UNIT *uptr, char *cptr)
|
||||||
|
{
|
||||||
|
char* tptr;
|
||||||
|
int32 i, port;
|
||||||
|
SOCKET sock;
|
||||||
|
TMLN *lp;
|
||||||
|
t_stat r;
|
||||||
|
extern int32 sim_switches;
|
||||||
|
|
||||||
|
port = (int32) get_uint (cptr, 10, 65535, &r); /* get port */
|
||||||
|
if ((r != SCPE_OK) || (port == 0)) return SCPE_ARG;
|
||||||
|
tptr = malloc (strlen (cptr) + 1); /* get string buf */
|
||||||
|
if (tptr == NULL) return SCPE_MEM; /* no more mem? */
|
||||||
|
|
||||||
|
sock = sim_master_sock (port); /* make master socket */
|
||||||
|
if (sock == INVALID_SOCKET) { /* open error */
|
||||||
|
free (tptr); /* release buf */
|
||||||
|
return SCPE_OPENERR; }
|
||||||
|
printf ("Listening on socket %d\n", sock);
|
||||||
|
if (sim_log) fprintf (sim_log, "Listening on socket %d\n", sock);
|
||||||
|
mp -> master = sock; /* save master socket */
|
||||||
|
strcpy (tptr, cptr); /* copy port */
|
||||||
|
uptr -> filename = tptr; /* save */
|
||||||
|
uptr -> flags = uptr -> flags | UNIT_ATT; /* no more errors */
|
||||||
|
|
||||||
|
for (i = 0; i < mp -> lines; i++) { /* initialize lines */
|
||||||
|
lp = mp -> ldsc[i];
|
||||||
|
lp -> conn = lp -> tsta = 0;
|
||||||
|
lp -> rxbpi = lp -> rxbpr = 0;
|
||||||
|
lp -> txbpi = lp -> txbpr = 0;
|
||||||
|
lp -> rxcnt = lp -> txcnt = 0;
|
||||||
|
lp -> xmte = 1;
|
||||||
|
lp -> dstb = 0; }
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Detach */
|
||||||
|
|
||||||
|
t_stat tmxr_detach (TMXR *mp, UNIT *uptr)
|
||||||
|
{
|
||||||
|
int32 i;
|
||||||
|
TMLN *lp;
|
||||||
|
|
||||||
|
if ((uptr -> flags & UNIT_ATT) == 0) return SCPE_OK; /* attached? */
|
||||||
|
for (i = 0; i < mp -> lines; i++) { /* loop thru conn */
|
||||||
|
lp = mp -> ldsc[i];
|
||||||
|
if (lp -> conn) {
|
||||||
|
tmxr_msg (lp -> conn, "\r\n");
|
||||||
|
tmxr_msg (lp -> conn, sim_name);
|
||||||
|
tmxr_msg (lp -> conn, " simulator shutting down... please come back later\r\n\n");
|
||||||
|
tmxr_reset_ln (lp); } /* end if conn */
|
||||||
|
} /* end for */
|
||||||
|
sim_close_sock (mp -> master, 1); /* close master socket */
|
||||||
|
mp -> master = 0;
|
||||||
|
free (uptr -> filename); /* free port string */
|
||||||
|
uptr -> filename = NULL;
|
||||||
|
uptr -> flags = uptr -> flags & ~UNIT_ATT; /* not attached */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stub examine and deposit */
|
||||||
|
|
||||||
|
t_stat tmxr_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)
|
||||||
|
{
|
||||||
|
return SCPE_NOFNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat tmxr_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw)
|
||||||
|
{
|
||||||
|
return SCPE_NOFNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output message */
|
||||||
|
|
||||||
|
void tmxr_msg (SOCKET sock, char *msg)
|
||||||
|
{
|
||||||
|
if (sock) sim_write_sock (sock, msg, strlen (msg));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print line status */
|
||||||
|
|
||||||
|
void tmxr_fstatus (FILE *st, TMLN *lp, int32 ln)
|
||||||
|
{
|
||||||
|
if (ln >= 0) fprintf (st, "\n line %d", ln);
|
||||||
|
if (lp -> conn) {
|
||||||
|
int32 o1, o2, o3, o4, hr, mn, sc;
|
||||||
|
uint32 ctime;
|
||||||
|
|
||||||
|
o1 = (lp -> ipad >> 24) & 0xFF;
|
||||||
|
o2 = (lp -> ipad >> 16) & 0xFF;
|
||||||
|
o3 = (lp -> ipad >> 8) & 0xFF;
|
||||||
|
o4 = (lp -> ipad) & 0xFF;
|
||||||
|
ctime = (sim_os_msec () - lp -> cnms) / 1000;
|
||||||
|
hr = ctime / 3600;
|
||||||
|
mn = (ctime / 60) % 60;
|
||||||
|
sc = ctime % 3600;
|
||||||
|
fprintf (st, ": IP address %d.%d.%d.%d", o1, o2, o3, o4);
|
||||||
|
if (ctime) fprintf (st, ", connected %02d:%02d:%02d", hr, mn, sc); }
|
||||||
|
else fprintf (st, ": disconnected");
|
||||||
|
return;
|
||||||
|
}
|
81
sim_tmxr.h
Normal file
81
sim_tmxr.h
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/* sim_tmxr.h: terminal multiplexor definitions
|
||||||
|
|
||||||
|
Copyright (c) 2001, 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.
|
||||||
|
|
||||||
|
Based on the original DZ11 simulator by Thord Nilson, as updated by
|
||||||
|
Arthur Krewat.
|
||||||
|
|
||||||
|
20-Oct-01 RMS Removed tmxr_getchar, formalized buffer guard,
|
||||||
|
added tmxr_rqln, tmxr_tqln
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TMXR_V_VALID 15
|
||||||
|
#define TMXR_VALID (1 << TMXR_V_VALID)
|
||||||
|
#define TMXR_MAXBUF 128 /* buffer size */
|
||||||
|
#define TMXR_GUARD 8 /* buffer guard */
|
||||||
|
#define TMXR_MAXLIN 64 /* max lines */
|
||||||
|
|
||||||
|
struct tmln {
|
||||||
|
SOCKET conn; /* line conn */
|
||||||
|
uint32 ipad; /* IP address */
|
||||||
|
uint32 cnms; /* conn time */
|
||||||
|
int32 tsta; /* Telnet state */
|
||||||
|
int32 rcve; /* rcv enable */
|
||||||
|
int32 xmte; /* xmt enable */
|
||||||
|
int32 dstb; /* disable Tlnt bin */
|
||||||
|
int32 rxbpr; /* rcv buf remove */
|
||||||
|
int32 rxbpi; /* rcv buf insert */
|
||||||
|
int32 rxcnt; /* rcv count */
|
||||||
|
int32 txbpr; /* xmt buf remove */
|
||||||
|
int32 txbpi; /* xmt buf insert */
|
||||||
|
int32 txcnt; /* xmt count */
|
||||||
|
char rxb[TMXR_MAXBUF]; /* rcv buffer */
|
||||||
|
char txb[TMXR_MAXBUF]; /* xmt buffer */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct tmln TMLN;
|
||||||
|
|
||||||
|
struct tmxr {
|
||||||
|
int32 lines; /* # lines */
|
||||||
|
SOCKET master; /* master socket */
|
||||||
|
TMLN *ldsc[TMXR_MAXLIN]; /* line descriptors */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct tmxr TMXR;
|
||||||
|
|
||||||
|
int32 tmxr_poll_conn (TMXR *mp, UNIT *uptr);
|
||||||
|
void tmxr_reset_ln (TMLN *lp);
|
||||||
|
int32 tmxr_getc_ln (TMLN *lp);
|
||||||
|
void tmxr_poll_rx (TMXR *mp);
|
||||||
|
void tmxr_putc_ln (TMLN *lp, int32 chr);
|
||||||
|
void tmxr_poll_tx (TMXR *mp);
|
||||||
|
t_stat tmxr_attach (TMXR *mp, UNIT *uptr, char *cptr);
|
||||||
|
t_stat tmxr_detach (TMXR *mp, UNIT *uptr);
|
||||||
|
t_stat tmxr_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
|
||||||
|
t_stat tmxr_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
|
||||||
|
void tmxr_msg (SOCKET sock, char *msg);
|
||||||
|
void tmxr_fstatus (FILE *st, TMLN *lp, int32 ln);
|
||||||
|
int32 tmxr_rqln (TMLN *lp);
|
||||||
|
int32 tmxr_tqln (TMLN *lp);
|
||||||
|
|
580
simh_doc.txt
580
simh_doc.txt
|
@ -1,7 +1,7 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: Simulator Usage, V2.6b
|
Subj: Simulator Usage, V2.7
|
||||||
Date: 15-Sep-01
|
Date: 30-Sep-01
|
||||||
|
|
||||||
COPYRIGHT NOTICE
|
COPYRIGHT NOTICE
|
||||||
|
|
||||||
|
@ -54,30 +54,33 @@ in scp_tty.c and scp_sock.c.
|
||||||
To compile the simulators on VMS, use these commands (note that separate
|
To compile the simulators on VMS, use these commands (note that separate
|
||||||
compilations are required for each of the 18b PDP's):
|
compilations are required for each of the 18b PDP's):
|
||||||
|
|
||||||
$ cc pdp8_*.c,scp.c,scp_tty.c ! PDP-8
|
$ cc pdp8_*.c,scp.c,scp_tty.c,sim_*.c ! PDP-8
|
||||||
$ link/exec=pdp8 pdp8_*.obj,scp.obj,scp_tty.obj
|
$ link/exec=pdp8 pdp8_*.obj,scp.obj,scp_tty.obj,sim_*.obj
|
||||||
|
|
||||||
$ cc pdp11_*.c,scp.c,scp_tty.c ! PDP-11
|
$ cc pdp11_*.c,scp.c,scp_tty.c,sim_*.c ! PDP-11
|
||||||
$ link/exec=pdp11 pdp11_*.obj,scp.obj,scp_tty.obj
|
$ link/exec=pdp11 pdp11_*.obj,scp.obj,scp_tty.obj,sim_*.obj
|
||||||
|
|
||||||
$ cc nova_*.c,scp.c,scp_tty.c ! Nova
|
$ cc nova_*.c,scp.c,scp_tty.c,sim_*.c ! Nova
|
||||||
$ link/exec=nova nova_*.obj,scp.obj,scp_tty.obj
|
$ link/exec=nova nova_*.obj,scp.obj,scp_tty.obj,sim_*.obj
|
||||||
|
|
||||||
$ cc pdp1_*.c,scp.c,scp_tty.c ! PDP-1
|
$ cc pdp1_*.c,scp.c,scp_tty.c ! PDP-1
|
||||||
$ link/exec=pdp1 pdp1_*.obj,scp.obj,scp_tty.obj
|
$ link/exec=pdp1 pdp1_*.obj,scp.obj,scp_tty.obj
|
||||||
|
|
||||||
$ cc/define=PDP{4,7,9,15} pdp18b_*.c,scp.c,scp_tty.c
|
$ cc/define=PDP{4,7,9,15} pdp18b_*.c,scp.c,scp_tty.c,sim_*.c
|
||||||
$ link/exec=pdp{4,7,9,15} pdp18b_*.obj,scp.obj,scp_tty.obj
|
$ link/exec=pdp{4,7,9,15} pdp18b_*.obj,scp.obj,scp_tty.obj,sim_*.obj
|
||||||
|
|
||||||
$ cc i1401_*.c,scp.c,scp_tty.c ! IBM 1401
|
$ cc i1401_*.c,scp.c,scp_tty.c ! IBM 1401
|
||||||
$ link/exec=i1401 i1401_*.obj,scp.obj,scp_tty.obj
|
$ link/exec=i1401 i1401_*.obj,scp.obj,scp_tty.obj
|
||||||
|
|
||||||
$ cc hp2100_*.c,scp.c,scp_tty.c ! HP 2100
|
$ cc hp2100_*.c,scp.c,scp_tty.c ! HP 2100
|
||||||
$ link/exec=hp2100 hp2100_*.obj,scp.obj,scp_tty.obj
|
$ link/exec=hp2100 hp2100_*.obj,scp.obj,scp_tty.obj
|
||||||
|
|
||||||
$ cc id4_*.c,scp.c,scp_tty.c ! Interdata 4
|
$ cc id4_*.c,scp.c,scp_tty.c ! Interdata 4
|
||||||
$ link/exec=id4 id4_*.obj,scp.obj,scp_tty.obj
|
$ link/exec=id4 id4_*.obj,scp.obj,scp_tty.obj
|
||||||
|
|
||||||
|
$ cc h316_*.c,scp.c,scp_tty.c ! Honeywell 316
|
||||||
|
$ link/exec=h316 h316_*.obj,scp.obj,scp_tty.obj
|
||||||
|
|
||||||
On version of VMS prior to 6.2, the simulators must then be defined as
|
On version of VMS prior to 6.2, the simulators must then be defined as
|
||||||
foreign commands so that they can be started by name.
|
foreign commands so that they can be started by name.
|
||||||
|
|
||||||
|
@ -86,14 +89,15 @@ the POSIX compliant TERMIOS interface (including Linux and Mac OS X), use
|
||||||
the following commands (note that separate compilations are required for
|
the following commands (note that separate compilations are required for
|
||||||
each of the 18b PDP's):
|
each of the 18b PDP's):
|
||||||
|
|
||||||
% cc pdp8_*.c scp*.c -lm -o pdp8
|
% cc pdp8_*.c scp*.c sim_*.c -lm -o pdp8
|
||||||
% cc pdp11_*.c scp*.c -lm -o pdp11
|
% cc pdp11_*.c scp*.c sim_*.c -lm -o pdp11
|
||||||
% cc nova_*.c scp*.c -lm -o nova
|
% cc nova_*.c scp*.c sim_*.c -lm -o nova
|
||||||
% cc pdp1_*.c scp*.c -o pdp1
|
% cc pdp1_*.c scp*.c -o pdp1
|
||||||
% cc -DPDP{4,7,9,15} pdp18b_*.c scp*.c -lm -o pdp{4,7,9,15}
|
% cc -DPDP{4,7,9,15} pdp18b_*.c scp*.c sim_*.c -lm -o pdp{4,7,9,15}
|
||||||
% cc i1401_*.c scp*.c -o i1401
|
% cc i1401_*.c scp*.c -o i1401
|
||||||
% cc hp2100_*.c scp*.c -o hp2100
|
% cc hp2100_*.c scp*.c -o hp2100
|
||||||
% cc id4_*.c scp*.c -o id4
|
% cc id4_*.c scp*.c -o id4
|
||||||
|
% cc h316_*.c scp*.c -o h316
|
||||||
|
|
||||||
These commands should work with most UNIX variants. If your UNIX only
|
These commands should work with most UNIX variants. If your UNIX only
|
||||||
supports the old BSD terminal interface, add -DBSDTTY to each command.
|
supports the old BSD terminal interface, add -DBSDTTY to each command.
|
||||||
|
@ -104,7 +108,7 @@ The PDP-10 simulator requires 64b support in the simulator and in the
|
||||||
simulator control package (SCP). To turn on 64b support, add the symbol
|
simulator control package (SCP). To turn on 64b support, add the symbol
|
||||||
USE_INT64 to the command line:
|
USE_INT64 to the command line:
|
||||||
|
|
||||||
% cc -DUSE_INT64 pdp10_*.c,scp*.c -lm -o pdp10
|
% cc -DUSE_INT64 pdp10_*.c scp*.c sim_*.c -lm -o pdp10
|
||||||
|
|
||||||
Since 64b integer declarations vary, sim_defs.h has conditional
|
Since 64b integer declarations vary, sim_defs.h has conditional
|
||||||
declarations for Windows (_int64) and Digital UNIX (long). The default
|
declarations for Windows (_int64) and Digital UNIX (long). The default
|
||||||
|
@ -115,12 +119,20 @@ To compile the simulators on Windows 9x/ME/NT/2000 and Visual C++,
|
||||||
each simulator must be set up as a separate project. Under the VC++
|
each simulator must be set up as a separate project. Under the VC++
|
||||||
file menu, select New, select Project Workspace, select Console
|
file menu, select New, select Project Workspace, select Console
|
||||||
Application, and type in the name of the simulator. In the project
|
Application, and type in the name of the simulator. In the project
|
||||||
files view, select Add Files To Project and add in all the files for
|
files view, select Add Files To Project and add in the required files:
|
||||||
that simulator (e.g., all files beginning nova_ for the Nova), plus
|
|
||||||
sim_defs.h, scp.c, and scp_tty.c. If the project requires the DZ11,
|
- all simulators: sim_defs.h, sim_rev.h, scp.c, scp_tty
|
||||||
also add in scp_sock.h and scp_sock.c. If the project requires a
|
- all simulators: simulator specific files (e.g., all
|
||||||
command line switch, add the switches to the C/C++ tab of the
|
files beginning with nova_* for the Nova)
|
||||||
Configuration dialog. The simulator should then build properly.
|
- PDP-10, PDP-11: dec_dz.h
|
||||||
|
- PDP-8, PDP-10, PDP-11, PDP-18b, Nova: sim_sock.h,
|
||||||
|
sim_sock.c, sim_txmr.h, sim_txmr.c
|
||||||
|
|
||||||
|
If the project requires 64b support, add the switch -DUSE_INT64 to
|
||||||
|
the C/C++ tab of the Configuration dialog. If the project includes
|
||||||
|
Telnet-based terminals, add the appropriate Winsock library to the
|
||||||
|
library search list (Wsock32.dll for VC++ V4.) The simulator should
|
||||||
|
then build properly.
|
||||||
|
|
||||||
To start the simulator, simply type its name. The simulator takes
|
To start the simulator, simply type its name. The simulator takes
|
||||||
one optional argument, a startup command file. If specified, this
|
one optional argument, a startup command file. If specified, this
|
||||||
|
@ -136,6 +148,7 @@ for example, disk sizes.
|
||||||
% i1401 <startup file>(cr) or
|
% i1401 <startup file>(cr) or
|
||||||
% hp2100 <startup file>(cr) or
|
% hp2100 <startup file>(cr) or
|
||||||
% id4 <startup file>(cr) or
|
% id4 <startup file>(cr) or
|
||||||
|
% h316 <startup file>(cr) or
|
||||||
% pdp10 <startup file>(cr)
|
% pdp10 <startup file>(cr)
|
||||||
|
|
||||||
The simulator types out its name and version, executes the commands
|
The simulator types out its name and version, executes the commands
|
||||||
|
@ -234,8 +247,16 @@ unit. The ATTACH (abbreviation AT) command associates a unit and a file:
|
||||||
If the file does not exist, it is created, and an appropriate message
|
If the file does not exist, it is created, and an appropriate message
|
||||||
is printed.
|
is printed.
|
||||||
|
|
||||||
|
For Telnet-based terminal emulators, the ATTACH command associates the
|
||||||
|
master unit with a TCP/IP port:
|
||||||
|
|
||||||
|
sim> ATTACH <device><unit number> <port>(cr)
|
||||||
|
|
||||||
|
The port is a decimal number between 1 and 65535 and should not used
|
||||||
|
by standard TCP/IP protocols.
|
||||||
|
|
||||||
The DETACH (abbreviation DET) command breaks the association between a
|
The DETACH (abbreviation DET) command breaks the association between a
|
||||||
unit and a file and closes the file:
|
unit and a file, or between a unit and a port:
|
||||||
|
|
||||||
sim> DETACH ALL(cr) -- detach all units
|
sim> DETACH ALL(cr) -- detach all units
|
||||||
sim> DETACH <device><unit number>(cr) -- detach specified unit
|
sim> DETACH <device><unit number>(cr) -- detach specified unit
|
||||||
|
@ -463,6 +484,7 @@ CPU PDP-8/E CPU with 32KW of memory
|
||||||
- KM8E memory management and timeshare control
|
- KM8E memory management and timeshare control
|
||||||
PTR,PTP PC8E paper tape reader/punch
|
PTR,PTP PC8E paper tape reader/punch
|
||||||
TTI,TTO KL8E console terminal
|
TTI,TTO KL8E console terminal
|
||||||
|
TTI1-4,TTO1-4 KL8JA additional terminals
|
||||||
LPT LE8E line printer
|
LPT LE8E line printer
|
||||||
CLK DK8E line frequency clock (also PDP-8/A compatible)
|
CLK DK8E line frequency clock (also PDP-8/A compatible)
|
||||||
RK RK8E/RK05 cartridge disk controller with four drives
|
RK RK8E/RK05 cartridge disk controller with four drives
|
||||||
|
@ -605,7 +627,7 @@ Error handling is as follows:
|
||||||
|
|
||||||
4.2.3 KL8E Terminal Input (TTI)
|
4.2.3 KL8E Terminal Input (TTI)
|
||||||
|
|
||||||
The terminal input (TTI) reads from the controling console port. The
|
The terminal input (TTI) polls the console keyboard for input. The
|
||||||
input side has one option, UC; when set, it automatically converts lower
|
input side has one option, UC; when set, it automatically converts lower
|
||||||
case input to upper case. This is required by OS/8 and is on by default.
|
case input to upper case. This is required by OS/8 and is on by default.
|
||||||
|
|
||||||
|
@ -622,7 +644,7 @@ The terminal input implements these registers:
|
||||||
|
|
||||||
4.2.4 KL8E Terminal Output (TTO)
|
4.2.4 KL8E Terminal Output (TTO)
|
||||||
|
|
||||||
The terminal output (TTO) writes to the controling console port. It
|
The terminal output (TTO) writes to the simulator console window. It
|
||||||
implements these registers:
|
implements these registers:
|
||||||
|
|
||||||
name size comments
|
name size comments
|
||||||
|
@ -676,6 +698,52 @@ The real-time clock (CLK) implements these registers:
|
||||||
The real-time clock autocalibrates; the clock interval is adjusted up or
|
The real-time clock autocalibrates; the clock interval is adjusted up or
|
||||||
down so that the clock tracks actual elapsed time.
|
down so that the clock tracks actual elapsed time.
|
||||||
|
|
||||||
|
4.2.7 KL8JA Additional Terminals (TTI1-4, TTO1-4)
|
||||||
|
|
||||||
|
Each additional terminal consists of two independent devices, TTIn and
|
||||||
|
TTOn. The entire set is modelled as a terminal multiplexor, with TTI1
|
||||||
|
as the master unit. The additional terminals perform input and output
|
||||||
|
through Telnet sessions connected to a user-specified port. The ATTACH
|
||||||
|
command specifies the port to be used:
|
||||||
|
|
||||||
|
ATTACH TTI1 <port>(cr) -- set up listening port
|
||||||
|
|
||||||
|
where port is a decimal number between 1 and 65535 that is not being used
|
||||||
|
for other TCP/IP activities.
|
||||||
|
|
||||||
|
Once TTI1 is attached and the simulator is running, the terminals listen
|
||||||
|
for connections on the specified port. They assume that the incoming
|
||||||
|
connections are Telnet connections. The connections remain open until
|
||||||
|
disconnected either by the Telnet client, or by a DETACH TTI1 command.
|
||||||
|
|
||||||
|
The SHOW TTI1 command displays the current connections to the additional
|
||||||
|
terminals.
|
||||||
|
|
||||||
|
The input devices (TTI1-4) implement these registers:
|
||||||
|
|
||||||
|
name size comments
|
||||||
|
|
||||||
|
BUF 8 last data item processed
|
||||||
|
DONE 1 device done flag
|
||||||
|
ENABLE 1 interrupt enable flag
|
||||||
|
INT 1 interrupt pending flag
|
||||||
|
POS 31 number of characters input
|
||||||
|
TIME 24 keyboard polling interval
|
||||||
|
|
||||||
|
The output devices (TTO1-4) implement these registers:
|
||||||
|
|
||||||
|
name size comments
|
||||||
|
|
||||||
|
BUF 8 last data item processed
|
||||||
|
DONE 1 device done flag
|
||||||
|
ENABLE 1 interrupt enable flag
|
||||||
|
INT 1 interrupt pending flag
|
||||||
|
POS 31 number of characters output
|
||||||
|
TIME 24 time from I/O initiation to interrupt
|
||||||
|
|
||||||
|
The additional terminals do not support save and restore. All open
|
||||||
|
connections are lost when the simulator shuts down or TTI1 is detached.
|
||||||
|
|
||||||
4.3 RK8E Cartridge Disk (RK)
|
4.3 RK8E Cartridge Disk (RK)
|
||||||
|
|
||||||
RK8E options include the ability to make units write enabled or write locked:
|
RK8E options include the ability to make units write enabled or write locked:
|
||||||
|
@ -923,6 +991,7 @@ controlled by command line switches:
|
||||||
|
|
||||||
-a display as ASCII character
|
-a display as ASCII character
|
||||||
-c display as (sixbit) character string
|
-c display as (sixbit) character string
|
||||||
|
-t display as (TSS/8 sixbit) character string
|
||||||
-m display instruction mnemonics
|
-m display instruction mnemonics
|
||||||
|
|
||||||
Input parsing is controlled by the first character typed in or by command
|
Input parsing is controlled by the first character typed in or by command
|
||||||
|
@ -930,6 +999,7 @@ line switches:
|
||||||
|
|
||||||
' or -a ASCII character
|
' or -a ASCII character
|
||||||
" or -c two character sixbit string
|
" or -c two character sixbit string
|
||||||
|
# or -t two character TSS/8 sixbit string
|
||||||
alphabetic instruction mnemonic
|
alphabetic instruction mnemonic
|
||||||
numeric octal number
|
numeric octal number
|
||||||
|
|
||||||
|
@ -985,6 +1055,7 @@ PTR,PTP PC11 paper tape reader/punch
|
||||||
TTI,TTO DL11 console terminal
|
TTI,TTO DL11 console terminal
|
||||||
LPT LP11 line printer
|
LPT LP11 line printer
|
||||||
CLK line frequency clock
|
CLK line frequency clock
|
||||||
|
DZ DZ11 8-line terminal multiplexor
|
||||||
RK RK11/RK05 cartridge disk controller with eight drives
|
RK RK11/RK05 cartridge disk controller with eight drives
|
||||||
RL RLV12/RL01(2) cartridge disk controller with four drives
|
RL RLV12/RL01(2) cartridge disk controller with four drives
|
||||||
RP RM02/03/05/80, RP04/05/06/07 Massbus style controller
|
RP RM02/03/05/80, RP04/05/06/07 Massbus style controller
|
||||||
|
@ -994,9 +1065,9 @@ TC TC11/TU56 DECtape controller with eight drives
|
||||||
TM TM11/TU10 magnetic tape controller with eight drives
|
TM TM11/TU10 magnetic tape controller with eight drives
|
||||||
TS TS11/TSV05 magnetic tape controller with one drive
|
TS TS11/TSV05 magnetic tape controller with one drive
|
||||||
|
|
||||||
The RK, RL, RP, RX, TC, TM, and TS devices can be DISABLEd. The PDP-11 can
|
The DZ, RK, RL, RP, RX, TC, TM, and TS devices can be DISABLEd. The PDP-11
|
||||||
support either a TM11 or a TS11, but not both, since they use the same I/O
|
can support either a TM11 or a TS11, but not both, since they use the same
|
||||||
addresses. The simulator defaults to the TM11. To change the magtape,
|
I/O addresses. The simulator defaults to the TM11. To change the magtape,
|
||||||
|
|
||||||
ENABLE TM11 enable TM11 and disable TS11
|
ENABLE TM11 enable TM11 and disable TS11
|
||||||
ENABLE TS11 enable TS11 and disable TM11
|
ENABLE TS11 enable TS11 and disable TM11
|
||||||
|
@ -1164,7 +1235,7 @@ Error handling is as follows:
|
||||||
|
|
||||||
5.2.3 KL11 Terminal Input (TTI)
|
5.2.3 KL11 Terminal Input (TTI)
|
||||||
|
|
||||||
The terminal input (TTI) reads from the controling console port. It
|
The terminal input (TTI) polls the console keyboard for input. It
|
||||||
implements these registers:
|
implements these registers:
|
||||||
|
|
||||||
name size comments
|
name size comments
|
||||||
|
@ -1180,7 +1251,7 @@ implements these registers:
|
||||||
|
|
||||||
5.2.4 KL11 Terminal Output (TTO)
|
5.2.4 KL11 Terminal Output (TTO)
|
||||||
|
|
||||||
The terminal output (TTO) writes to the controling console port. It
|
The terminal output (TTO) writes to the simulator console window. It
|
||||||
implements these registers:
|
implements these registers:
|
||||||
|
|
||||||
name size comments
|
name size comments
|
||||||
|
@ -1239,6 +1310,45 @@ The clock (CLK) implements these registers:
|
||||||
The real-time clock autocalibrates; the clock interval is adjusted up or
|
The real-time clock autocalibrates; the clock interval is adjusted up or
|
||||||
down so that the clock tracks actual elapsed time.
|
down so that the clock tracks actual elapsed time.
|
||||||
|
|
||||||
|
5.2.7 DZ11 Terminal Multiplexor (DZ)
|
||||||
|
|
||||||
|
The DZ11 is an 8-line terminal multiplexor. The terminal lines perform
|
||||||
|
input and output through Telnet sessions connected to a user-specified
|
||||||
|
port. The ATTACH command specifies the port to be used:
|
||||||
|
|
||||||
|
ATTACH {-am} DZ <port>(cr) -- set up listening port
|
||||||
|
|
||||||
|
where port is a decimal number between 1 and 65535 that is not being used
|
||||||
|
for other TCP/IP activities. The optional switch -m turns on the DZ11's
|
||||||
|
modem controls; the optional switch -a turns on active disconnects
|
||||||
|
(disconnect session if computer clears Data Terminal Ready).
|
||||||
|
|
||||||
|
Once the DZ is attached and the simulator is running, the DZ will listen
|
||||||
|
for connections on the specified port. It assumes that the incoming
|
||||||
|
connections are Telnet connections. The connection remains open until
|
||||||
|
disconnected either by the simulated program or by the Telnet client.
|
||||||
|
|
||||||
|
The SHOW DZ command displays the current connections to the DZ.
|
||||||
|
|
||||||
|
The DZ11 implements these registers:
|
||||||
|
|
||||||
|
name size comments
|
||||||
|
|
||||||
|
CSR 16 control/status register
|
||||||
|
RBUF 16 receive buffer
|
||||||
|
LPR 16 line parameter register
|
||||||
|
TCR 16 transmission control register
|
||||||
|
MSR 16 modem status register
|
||||||
|
TDR 16 transmit data register
|
||||||
|
SAENB 1 silo alarm enabled
|
||||||
|
MDMTCL 1 modem control enabled
|
||||||
|
AUTODS 1 autodisconnect enabled
|
||||||
|
RPOS0..7 32 count of characters received
|
||||||
|
TPOS0..7 32 count of characters transmitted
|
||||||
|
|
||||||
|
The DZ11 does not support save and restore. All open connections are
|
||||||
|
lost when the simulator shuts down or the DZ is detached.
|
||||||
|
|
||||||
5.3 RK11/RK05 Cartridge Disk (RK)
|
5.3 RK11/RK05 Cartridge Disk (RK)
|
||||||
|
|
||||||
RK11 options include the ability to make units write enabled or write locked:
|
RK11 options include the ability to make units write enabled or write locked:
|
||||||
|
@ -1390,7 +1500,7 @@ a DEC standard 044 compliant bad block table on the last track:
|
||||||
SET RPn RP06 set size to RP06
|
SET RPn RP06 set size to RP06
|
||||||
SET RPn RP07 set size to RP07
|
SET RPn RP07 set size to RP07
|
||||||
SET RPn AUTOSIZE set size based on file size at attach
|
SET RPn AUTOSIZE set size based on file size at attach
|
||||||
SET RLn BADBLOCK write bad block table on last track
|
SET RPn BADBLOCK write bad block table on last track
|
||||||
|
|
||||||
The size options can be used only when a unit is not attached to a file. The
|
The size options can be used only when a unit is not attached to a file. The
|
||||||
bad block option can be used only when a unit is attached to a file. Units
|
bad block option can be used only when a unit is attached to a file. Units
|
||||||
|
@ -1402,26 +1512,29 @@ The RP controller implements these registers:
|
||||||
name size comments
|
name size comments
|
||||||
|
|
||||||
RPCS1 16 control/status 1
|
RPCS1 16 control/status 1
|
||||||
RPCS2 16 control/status 2
|
|
||||||
RPCS3 16 control/status 3
|
|
||||||
RPWC 16 word count
|
RPWC 16 word count
|
||||||
RPBA 16 bus address
|
RPBA 16 bus address
|
||||||
RPBAE 6 bus address extension
|
|
||||||
RPDA 16 desired surface, sector
|
RPDA 16 desired surface, sector
|
||||||
RPDC 8 desired cylinder
|
RPCS2 16 control/status 2
|
||||||
RPOF 16 offset
|
RPOF 16 offset
|
||||||
RPDS0..7 16 drive status, drives 0-7
|
RPDC 8 desired cylinder
|
||||||
RPDE0..7 16 drive error, drives 0-7
|
|
||||||
RPER2 16 error status 2
|
RPER2 16 error status 2
|
||||||
RPER3 16 error status 3
|
RPER3 16 error status 3
|
||||||
RPDB 16 data buffer
|
RPEC1 16 ECC syndrome 1
|
||||||
|
RPEC2 16 ECC syndrome 2
|
||||||
RPMR 16 maintenance register
|
RPMR 16 maintenance register
|
||||||
|
RPDB 16 data buffer
|
||||||
|
RPBAE 6 bus address extension
|
||||||
|
RPCS3 16 control/status 3
|
||||||
|
RPIFF 1 transfer complete interrupt request flop
|
||||||
INT 1 interrupt pending flag
|
INT 1 interrupt pending flag
|
||||||
SC 1 special condition (CSR1<15>)
|
SC 1 special condition (CSR1<15>)
|
||||||
DONE 1 device done flag (CSR1<7>)
|
DONE 1 device done flag (CSR1<7>)
|
||||||
IE 1 interrupt enable flag (CSR1<6>)
|
IE 1 interrupt enable flag (CSR1<6>)
|
||||||
STIME 24 seek time, per cylinder
|
STIME 24 seek time, per cylinder
|
||||||
RTIME 24 rotational delay
|
RTIME 24 rotational delay
|
||||||
|
RPDS0..7 16 drive status, drives 0-7
|
||||||
|
RPDE0..7 16 drive error, drives 0-7
|
||||||
STOP_IOE 1 stop on I/O error
|
STOP_IOE 1 stop on I/O error
|
||||||
|
|
||||||
Error handling is as follows:
|
Error handling is as follows:
|
||||||
|
@ -1568,6 +1681,7 @@ The magnetic tape controller implements these registers:
|
||||||
WADH 16 write char packet high address
|
WADH 16 write char packet high address
|
||||||
WLNT 16 write char packet length
|
WLNT 16 write char packet length
|
||||||
WOPT 16 write char packet options
|
WOPT 16 write char packet options
|
||||||
|
WXOPT 16 write char packet extended options
|
||||||
ATTN 1 attention message pending
|
ATTN 1 attention message pending
|
||||||
BOOT 1 boot request pending
|
BOOT 1 boot request pending
|
||||||
OWNC 1 if set, tape owns command buffer
|
OWNC 1 if set, tape owns command buffer
|
||||||
|
@ -1732,22 +1846,6 @@ control registers for the interrupt system.
|
||||||
|
|
||||||
6.2 Programmed I/O Devices
|
6.2 Programmed I/O Devices
|
||||||
|
|
||||||
The Nova can have two terminals (TTI/TTO, TTI1/TTO1). At any moment
|
|
||||||
only one terminal is active. It can receive input from the keyboard;
|
|
||||||
it can output to the simulator window. The inactive console cannot
|
|
||||||
receive input from the keyboard and outputs to an internal buffer
|
|
||||||
(maximum 4K characters).
|
|
||||||
|
|
||||||
Control is switched among terminals with a SET TTI{n} CONSOLE or SET
|
|
||||||
TTO{n} CONSOLE command:
|
|
||||||
|
|
||||||
At startup, active console is TTI/TTO
|
|
||||||
SET TTI1 CONSOLE Active console is now TTI1/TTO1
|
|
||||||
SET TTO CONSOLE Active console is now TTI/TTO
|
|
||||||
|
|
||||||
When control is switched to an inactive terminal, any buffered output
|
|
||||||
is printed when simulation resumes.
|
|
||||||
|
|
||||||
6.2.1 Paper Tape Reader (PTR)
|
6.2.1 Paper Tape Reader (PTR)
|
||||||
|
|
||||||
The paper tape reader (PTR) reads data from a disk file. The POS
|
The paper tape reader (PTR) reads data from a disk file. The POS
|
||||||
|
@ -1807,23 +1905,19 @@ Error handling is as follows:
|
||||||
|
|
||||||
OS I/O error x report error and stop
|
OS I/O error x report error and stop
|
||||||
|
|
||||||
6.2.3 Terminal Input (TTI, TTI1)
|
6.2.3 Terminal Input (TTI)
|
||||||
|
|
||||||
The active terminal input polls the console keyboard for input. The
|
The terminal input polls the console keyboard for input. Terminal
|
||||||
inactive terminal input cannot receive characters. Terminal input
|
input options include the ability to set ANSI mode or limited Dasher
|
||||||
options include the ability to set limited Dasher compatibility mode
|
compatibility mode:
|
||||||
or ANSI standard mode:
|
|
||||||
|
|
||||||
SET TTI ANSI normal mode
|
SET TTI ANSI normal mode
|
||||||
SET TTI DASHER Dasher mode
|
SET TTI DASHER Dasher mode
|
||||||
SET TTO ANSI normal mode
|
|
||||||
SET TTO DASHER Dasher mode
|
|
||||||
|
|
||||||
Setting either TTI (TTI1) or TTO (TTO1) changes both devices. In Dasher
|
Setting either TTI or TTO changes both devices. In Dasher mode, carriage
|
||||||
mode, carriage return is changed to newline on input, and ^X is changed
|
return is changed to newline on input, and ^X is changed to backspace.
|
||||||
to backspace.
|
|
||||||
|
|
||||||
The terminal inputs implement these registers:
|
The terminal input implements these registers:
|
||||||
|
|
||||||
name size comments
|
name size comments
|
||||||
|
|
||||||
|
@ -1835,22 +1929,19 @@ The terminal inputs implement these registers:
|
||||||
POS 31 number of characters input
|
POS 31 number of characters input
|
||||||
TIME 24 keyboard polling interval
|
TIME 24 keyboard polling interval
|
||||||
|
|
||||||
6.2.4 Terminal Output (TTO, TTO1)
|
6.2.4 Terminal Output (TTO)
|
||||||
|
|
||||||
The active terminal output writes to the simulator window. The inactive
|
The terminal output writes to the simulator console window. Terminal
|
||||||
terminal output buffers characters. Terminal output options include the
|
output options include the the ability to set ANSI mode or limited
|
||||||
the ability to set limited Dasher compatibility mode or ANSI mode:
|
Dasher compatibility mode:
|
||||||
|
|
||||||
SET TTI ANSI normal mode
|
|
||||||
SET TTI DASHER Dasher mode
|
|
||||||
SET TTO ANSI normal mode
|
SET TTO ANSI normal mode
|
||||||
SET TTO DASHER Dasher mode
|
SET TTO DASHER Dasher mode
|
||||||
|
|
||||||
Setting either TTI (TTI1) or TTO (TTO1) changes both devices. In Dasher
|
Setting either TTI or TTO changes both devices. In Dasher mode, carriage
|
||||||
mode, carriage return is changed to newline on input, and ^X is changed
|
return is changed to newline on input, and ^X is changed to backspace.
|
||||||
to backspace.
|
|
||||||
|
|
||||||
The terminal outputs implement these registers:
|
The terminal output implements these registers:
|
||||||
|
|
||||||
name size comments
|
name size comments
|
||||||
|
|
||||||
|
@ -1937,6 +2028,61 @@ Error handling is as follows:
|
||||||
|
|
||||||
OS I/O error x report error and stop
|
OS I/O error x report error and stop
|
||||||
|
|
||||||
|
6.2.8 Second Terminal (TTI1, TTO1)
|
||||||
|
|
||||||
|
The second terminal consists of two independent devices, TTI1 and TTO1.
|
||||||
|
The additional terminal performs input and output through a Telnet session
|
||||||
|
connecting into a user-specified port. The ATTACH command specifies the
|
||||||
|
port to be used:
|
||||||
|
|
||||||
|
ATTACH TTI1 <port>(cr) -- set up listening port
|
||||||
|
|
||||||
|
where port is a decimal number between 1 and 65535 that is not being used
|
||||||
|
for other TCP/IP activities.
|
||||||
|
|
||||||
|
Once TTI1 is attached and the simulator is running, the terminal listens
|
||||||
|
for a connection on the specified port. It assumes that the incoming
|
||||||
|
connection is a Telnet connection. The connection remain opens until
|
||||||
|
disconnected by the Telnet client, or by a DETACH TTI1 command.
|
||||||
|
|
||||||
|
The second terminal has two options, recognized on both devices, for
|
||||||
|
setting limited Dasher-compatibility mode or ANSI mode:
|
||||||
|
|
||||||
|
SET TTI1 ANSI normal mode
|
||||||
|
SET TTI1 DASHER Dasher mode
|
||||||
|
SET TTO1 ANSI normal mode
|
||||||
|
SET TTO1 DASHER Dasher mode
|
||||||
|
|
||||||
|
Setting either TTI1 or TTO1 changes both devices. In Dasher mode, carriage
|
||||||
|
return is changed to newline on input, and ^X is changed to backspace.
|
||||||
|
|
||||||
|
The SHOW TTI1 command displays the current connection to the second
|
||||||
|
terminal.
|
||||||
|
|
||||||
|
The second terminal input implements these registers:
|
||||||
|
|
||||||
|
name size comments
|
||||||
|
|
||||||
|
BUF 8 last data item processed
|
||||||
|
BUSY 1 device busy flag
|
||||||
|
DONE 1 device done flag
|
||||||
|
DISABLE 1 interrupt disable flag
|
||||||
|
INT 1 interrupt pending flag
|
||||||
|
POS 31 number of characters input
|
||||||
|
TIME 24 keyboard polling interval
|
||||||
|
|
||||||
|
The second terminal output implements these registers:
|
||||||
|
|
||||||
|
name size comments
|
||||||
|
|
||||||
|
BUF 8 last data item processed
|
||||||
|
BUSY 1 device busy flag
|
||||||
|
DONE 1 device done flag
|
||||||
|
DISABLE 1 interrupt disable flag
|
||||||
|
INT 1 interrupt pending flag
|
||||||
|
POS 31 number of characters output
|
||||||
|
TIME 24 time from I/O initiation to interrupt
|
||||||
|
|
||||||
6.3 Fixed Head Disk (DK)
|
6.3 Fixed Head Disk (DK)
|
||||||
|
|
||||||
The fixed head disk controller implements these registers:
|
The fixed head disk controller implements these registers:
|
||||||
|
@ -2261,8 +2407,8 @@ Error handling is as follows:
|
||||||
|
|
||||||
7.2.3 Terminal Input (TTI)
|
7.2.3 Terminal Input (TTI)
|
||||||
|
|
||||||
The terminal input (TTO) reads from the controling console port.
|
The terminal input (TTI) polls the console keyboard for input. It
|
||||||
It implements these registers:
|
implements these registers:
|
||||||
|
|
||||||
name size comments
|
name size comments
|
||||||
|
|
||||||
|
@ -2273,7 +2419,7 @@ It implements these registers:
|
||||||
|
|
||||||
7.2.4 Terminal Output (TTO)
|
7.2.4 Terminal Output (TTO)
|
||||||
|
|
||||||
The terminal output (TTO) writes to the controling console port.
|
The terminal output (TTO) writes to the simulator console window.
|
||||||
It implements these registers:
|
It implements these registers:
|
||||||
|
|
||||||
name size comments
|
name size comments
|
||||||
|
@ -2629,22 +2775,6 @@ the PDP-7 and PDP-9, 17b for the PDP-15).
|
||||||
|
|
||||||
8.2 Programmed I/O Devices
|
8.2 Programmed I/O Devices
|
||||||
|
|
||||||
The PDP-9 and PDP-15 have two terminals (TTI/TTO, TTI1/TTO1). At any
|
|
||||||
moment, only one terminal is active. It can receive input from the
|
|
||||||
keyboard; it can output to the simulator window. The inactive console
|
|
||||||
cannot receive input from the keyboard and outputs to an internal buffer
|
|
||||||
(maximum 4K characters).
|
|
||||||
|
|
||||||
Control is switched among terminals with a SET TTI{n} CONSOLE or SET
|
|
||||||
TTO{n} CONSOLE command:
|
|
||||||
|
|
||||||
At startup, active console is TTI/TTO
|
|
||||||
SET TTI1 CONSOLE Active console is now TTI1/TTO1
|
|
||||||
SET TTO CONSOLE Active console is now TTI/TTO
|
|
||||||
|
|
||||||
When control is switched to an inactive terminal, any buffered output
|
|
||||||
is printed when simulation resumes.
|
|
||||||
|
|
||||||
8.2.1 Paper Tape Reader (PTR)
|
8.2.1 Paper Tape Reader (PTR)
|
||||||
|
|
||||||
The paper tape reader (PTR) reads data from a disk file. The POS
|
The paper tape reader (PTR) reads data from a disk file. The POS
|
||||||
|
@ -2707,20 +2837,19 @@ Error handling is as follows:
|
||||||
|
|
||||||
OS I/O error x report error and stop
|
OS I/O error x report error and stop
|
||||||
|
|
||||||
8.2.3 Terminal Input (TTI, TTI1)
|
8.2.3 Terminal Input (TTI)
|
||||||
|
|
||||||
The active terminal input polls the console keyboard for input. The
|
The terminal input (TTI) polls the console keyboard for input. The
|
||||||
inactive terminal input cannot receive characters. The terminal inputs
|
input side has one option, UC; when set, it automatically converts lower
|
||||||
have one option, UC; when set, it automatically converts lower case input
|
case input to upper case.
|
||||||
to upper case.
|
|
||||||
|
|
||||||
The PDP-9 and PDP-15 operated the primary terminal (TTI/TTO), by default,
|
The PDP-9 and PDP-15 operate the console terminal (TTI/TTO), by default,
|
||||||
as half-duplex. For backward compatibility, on the PDP-9 and PDP-15
|
as half duplex. For backward compatibility, on the PDP-9 and PDP-15
|
||||||
the first terminal input has a second option, FDX; when set, it operates
|
the first terminal input has a second option, FDX; when set, it operates
|
||||||
the terminal input in full-duplex mode. The second terminal is always
|
the terminal input in full-duplex mode. The second terminal is always
|
||||||
full duplex.
|
full duplex.
|
||||||
|
|
||||||
The terminal inputs implement these registers:
|
The terminal input implements these registers:
|
||||||
|
|
||||||
name size comments
|
name size comments
|
||||||
|
|
||||||
|
@ -2730,14 +2859,13 @@ The terminal inputs implement these registers:
|
||||||
POS 31 number of characters input
|
POS 31 number of characters input
|
||||||
TIME 24 keyboard polling interval
|
TIME 24 keyboard polling interval
|
||||||
|
|
||||||
8.2.4 Terminal Output (TTO, TTO1)
|
8.2.4 Terminal Output (TTO)
|
||||||
|
|
||||||
The active terminal output writes to the simulator window. The inactive
|
The terminal output (TTO) writes to the simulator console window. The
|
||||||
terminal output buffers characters. The terminal outputs have one option,
|
terminal output has one option, UC; when set, it suppresses lower case
|
||||||
UC; when set, it suppresses lower case output (so that ALTMODE is not
|
output (so that ALTMODE is not echoed as }).
|
||||||
echoed as }).
|
|
||||||
|
|
||||||
The terminal outputs implement these registers:
|
The terminal output implements these registers:
|
||||||
|
|
||||||
name size comments
|
name size comments
|
||||||
|
|
||||||
|
@ -2822,6 +2950,51 @@ The real-time clock (CLK) implements these registers:
|
||||||
The real-time clock autocalibrates; the clock interval is adjusted up or
|
The real-time clock autocalibrates; the clock interval is adjusted up or
|
||||||
down so that the clock tracks actual elapsed time.
|
down so that the clock tracks actual elapsed time.
|
||||||
|
|
||||||
|
8.2.7 Second Terminal (TTI1, TTO1)
|
||||||
|
|
||||||
|
The second terminal consists of two independent devices, TTI1 and TTO1.
|
||||||
|
The second terminal performs input and output through a Telnet session
|
||||||
|
connected to a user-specified port. The ATTACH command specifies the
|
||||||
|
port to be used:
|
||||||
|
|
||||||
|
ATTACH TTI1 <port>(cr) -- set up listening port
|
||||||
|
|
||||||
|
where port is a decimal number between 1 and 65535 that is not being used
|
||||||
|
for other TCP/IP activities.
|
||||||
|
|
||||||
|
Once TTI1 is attached and the simulator is running, the terminal listens
|
||||||
|
for a connection on the specified port. It assumes that the incoming
|
||||||
|
connection is a Telnet connection. The connection remain opens until
|
||||||
|
disconnected by the Telnet client, or by a DETACH TTI1 command.
|
||||||
|
|
||||||
|
The second terminal input has one option, UC; when set, it automatically
|
||||||
|
converts lower case input to upper case. The second terminal output also
|
||||||
|
has one option, UC; when set, it suppresses lower case output (so that
|
||||||
|
ALTMODE is not echoed as }).
|
||||||
|
|
||||||
|
The SHOW TTI1 command displays the current connection to the second
|
||||||
|
terminal.
|
||||||
|
|
||||||
|
The second terminal input implements these registers:
|
||||||
|
|
||||||
|
name size comments
|
||||||
|
|
||||||
|
BUF 8 last data item processed
|
||||||
|
INT 1 interrupt pending flag
|
||||||
|
DONE 1 device done flag
|
||||||
|
POS 31 number of characters input
|
||||||
|
TIME 24 keyboard polling interval
|
||||||
|
|
||||||
|
The second terminal output implements these registers:
|
||||||
|
|
||||||
|
name size comments
|
||||||
|
|
||||||
|
BUF 8 last data item processed
|
||||||
|
INT 1 interrupt pending flag
|
||||||
|
DONE 1 device done flag
|
||||||
|
POS 31 number of chararacters output
|
||||||
|
TIME 24 time from I/O initiation to interrupt
|
||||||
|
|
||||||
8.3 RP15/RP02 Disk Pack (RP)
|
8.3 RP15/RP02 Disk Pack (RP)
|
||||||
|
|
||||||
RP15 options include the ability to make units write enabled or write locked:
|
RP15 options include the ability to make units write enabled or write locked:
|
||||||
|
@ -3384,8 +3557,8 @@ Error handling is as follows:
|
||||||
9.4 1407 Inquiry Terminal (INQ)
|
9.4 1407 Inquiry Terminal (INQ)
|
||||||
|
|
||||||
The IBM 1407 inquiry terminal (INQ) is a half-duplex console. It polls
|
The IBM 1407 inquiry terminal (INQ) is a half-duplex console. It polls
|
||||||
the controling keyboard of the simulator periodically for inquiry requests.
|
the console keyboard periodically for inquiry requests. The inquiry
|
||||||
The inquiry terminal registers are:
|
terminal registers are:
|
||||||
|
|
||||||
name size comments
|
name size comments
|
||||||
|
|
||||||
|
@ -3725,11 +3898,11 @@ Error handling is as follows:
|
||||||
10.4.3 12631C Buffered Teleprinter (TTY)
|
10.4.3 12631C Buffered Teleprinter (TTY)
|
||||||
|
|
||||||
The console teleprinter has three units: keyboard (unit 0), printer
|
The console teleprinter has three units: keyboard (unit 0), printer
|
||||||
(unit 1), and punch (unit 2). The keyboard reads from, and the
|
(unit 1), and punch (unit 2). The keyboard reads from the console
|
||||||
printer writes to, the controlling console port. The punch writes
|
keyboard; the printer writes to the simulator console window. The
|
||||||
to a disk file. The keyboard has one option, UC; when set, it
|
punch writes to a disk file. The keyboard has one option, UC; when
|
||||||
automatically converts lower case input to upper case. This is on
|
set, it automatically converts lower case input to upper case. This
|
||||||
by default.
|
is on by default.
|
||||||
|
|
||||||
The terminal implements these registers:
|
The terminal implements these registers:
|
||||||
|
|
||||||
|
@ -4076,9 +4249,10 @@ Error handling is as follows:
|
||||||
|
|
||||||
11.3 Teletype (TT)
|
11.3 Teletype (TT)
|
||||||
|
|
||||||
The teletype reads and writes to the controlling console port. The
|
The teletype keyboard reads from the console keyboard; the teletype
|
||||||
keyboard has one option, UC; when set, it automatically converts lower
|
printer writes to the simulator console window. The keyboard has
|
||||||
case input to upper case. This is on by default.
|
one option, UC; when set, it automatically converts lower case
|
||||||
|
input to upper case. This is on by default.
|
||||||
|
|
||||||
name size comments
|
name size comments
|
||||||
|
|
||||||
|
@ -4158,12 +4332,13 @@ UBA Unibus adapters (translation maps)
|
||||||
FE console
|
FE console
|
||||||
TIM timer
|
TIM timer
|
||||||
PTR,PTP PC11 paper tape reader/punch
|
PTR,PTP PC11 paper tape reader/punch
|
||||||
|
DZ DZ11 8-line terminal multiplexor
|
||||||
LP20 LP20 line printer
|
LP20 LP20 line printer
|
||||||
RP RH11/RP04/RP05/RP06/RP07/RM03/RM05/RM80 controller with
|
RP RH11/RP04/RP05/RP06/RP07/RM03/RM05/RM80 controller with
|
||||||
eight drives
|
eight drives
|
||||||
TU RH11/TM02/TU45 controller with eight drives
|
TU RH11/TM02/TU45 controller with eight drives
|
||||||
|
|
||||||
The PTR/PTP are initially DISABLEd. No other device can be DISABLEd.
|
The PTR/PTP are initially DISABLEd. The DZ11 can also be DISABLEd.
|
||||||
|
|
||||||
The PDP-10 simulator implements several unique stop condition:
|
The PDP-10 simulator implements several unique stop condition:
|
||||||
|
|
||||||
|
@ -4371,7 +4546,54 @@ Error handling is as follows:
|
||||||
|
|
||||||
OS I/O error x report error and stop
|
OS I/O error x report error and stop
|
||||||
|
|
||||||
12.8 RH11 Adapter, RM02/03/05/80, RP04/05/06/07 drives (RP)
|
12.8 DZ11 Terminal Multiplexor (DZ)
|
||||||
|
|
||||||
|
The DZ11 is an 8-line terminal multiplexor. The terminal lines perform
|
||||||
|
input and output through Telnet sessions connected to a user-specified
|
||||||
|
port. The ATTACH command specifies the port to be used:
|
||||||
|
|
||||||
|
ATTACH {-am} DZ <port>(cr) -- set up listening port
|
||||||
|
|
||||||
|
where port is a decimal number between 1 and 65535 that is not being used
|
||||||
|
for other TCP/IP activities. The optional switch -m turns on the DZ11's
|
||||||
|
modem controls; the optional switch -a turns on active disconnects
|
||||||
|
(disconnect session if computer clears Data Terminal Ready).
|
||||||
|
|
||||||
|
|
||||||
|
ATTACH {-m} DZ <port>(cr) -- set up listening port
|
||||||
|
|
||||||
|
where port is a decimal number between 1 and 65535 that is not being used
|
||||||
|
for other TCP/IP activities. The optional switch -m turns on the DZ11's
|
||||||
|
modem controls; the optional switch -a turns on active disconnects
|
||||||
|
(disconnect session if computer clears Data Terminal Ready).
|
||||||
|
|
||||||
|
Once the DZ is attached and the simulator is running, the DZ will listen
|
||||||
|
for connections on the specified port. It assumes that the incoming
|
||||||
|
connections are Telnet connections. The connection remains open until
|
||||||
|
disconnected either by the simulated program or by the Telnet client.
|
||||||
|
|
||||||
|
The SHOW DZ command displays the current connections to the DZ.
|
||||||
|
|
||||||
|
The DZ11 implements these registers:
|
||||||
|
|
||||||
|
name size comments
|
||||||
|
|
||||||
|
CSR 16 control/status register
|
||||||
|
RBUF 16 receive buffer
|
||||||
|
LPR 16 line parameter register
|
||||||
|
TCR 16 transmission control register
|
||||||
|
MSR 16 modem status register
|
||||||
|
TDR 16 transmit data register
|
||||||
|
SAENB 1 silo alarm enabled
|
||||||
|
MDMTCL 1 modem control enabled
|
||||||
|
AUTODS 1 autodisconnect enabled
|
||||||
|
RPOS0..7 32 count of characters received
|
||||||
|
TPOS0..7 32 count of characters transmitted
|
||||||
|
|
||||||
|
The DZ11 does not support save and restore. All open connections are
|
||||||
|
lost when the simulator shuts down or the DZ is detached.
|
||||||
|
|
||||||
|
12.9 RH11 Adapter, RM02/03/05/80, RP04/05/06/07 drives (RP)
|
||||||
|
|
||||||
The RP controller implements the Massbus 18b (RH11) direct interface for
|
The RP controller implements the Massbus 18b (RH11) direct interface for
|
||||||
large disk drives. It is more abstract than other device simulators, with
|
large disk drives. It is more abstract than other device simulators, with
|
||||||
|
@ -4401,26 +4623,27 @@ The RP controller implements these registers:
|
||||||
name size comments
|
name size comments
|
||||||
|
|
||||||
RPCS1 16 control/status 1
|
RPCS1 16 control/status 1
|
||||||
RPCS2 16 control/status 2
|
|
||||||
RPCS3 16 control/status 3
|
|
||||||
RPWC 16 word count
|
RPWC 16 word count
|
||||||
RPBA 16 bus address
|
RPBA 16 bus address
|
||||||
RPBAE 6 bus address extension
|
|
||||||
RPDA 16 desired surface, sector
|
RPDA 16 desired surface, sector
|
||||||
RPDC 8 desired cylinder
|
RPCS2 16 control/status 2
|
||||||
RPOF 16 offset
|
RPOF 16 offset
|
||||||
RPDS0..7 16 drive status, drives 0-7
|
RPDC 8 desired cylinder
|
||||||
RPDE0..7 16 drive error, drives 0-7
|
|
||||||
RPER2 16 error status 2
|
RPER2 16 error status 2
|
||||||
RPER3 16 error status 3
|
RPER3 16 error status 3
|
||||||
RPDB 16 data buffer
|
RPEC1 16 ECC syndrome 1
|
||||||
|
RPEC2 16 ECC syndrome 2
|
||||||
RPMR 16 maintenance register
|
RPMR 16 maintenance register
|
||||||
|
RPDB 16 data buffer
|
||||||
|
RPIFF 1 transfer complete interrupt request flop
|
||||||
INT 1 interrupt pending flag
|
INT 1 interrupt pending flag
|
||||||
SC 1 special condition (CSR1<15>)
|
SC 1 special condition (CSR1<15>)
|
||||||
DONE 1 device done flag (CSR1<7>)
|
DONE 1 device done flag (CSR1<7>)
|
||||||
IE 1 interrupt enable flag (CSR1<6>)
|
IE 1 interrupt enable flag (CSR1<6>)
|
||||||
STIME 24 seek time, per cylinder
|
STIME 24 seek time, per cylinder
|
||||||
RTIME 24 rotational delay
|
RTIME 24 rotational delay
|
||||||
|
RPDS0..7 16 drive status, drives 0-7
|
||||||
|
RPDE0..7 16 drive error, drives 0-7
|
||||||
STOP_IOE 1 stop on I/O error
|
STOP_IOE 1 stop on I/O error
|
||||||
|
|
||||||
Error handling is as follows:
|
Error handling is as follows:
|
||||||
|
@ -4434,11 +4657,11 @@ Error handling is as follows:
|
||||||
|
|
||||||
OS I/O error x report error and stop
|
OS I/O error x report error and stop
|
||||||
|
|
||||||
12.9 RH11/TM02/TU45 Magnetic Tape (TU)
|
12.10 RH11 Adapter, TM02 Formatter, TU45 Magnetic Tape (TU)
|
||||||
|
|
||||||
The magnetic tape simulator simulates an RH11 Massbus adapter with one
|
The magnetic tape simulator simulates an RH11 Massbus adapter with one
|
||||||
TM02 formatter and up to eight TU45. Magnetic tape options include the
|
TM02 formatter and up to eight TU45 drives. Magnetic tape options include
|
||||||
ability to make units write enabled or locked.
|
the ability to make units write enabled or locked.
|
||||||
|
|
||||||
SET TUn LOCKED set unit n write locked
|
SET TUn LOCKED set unit n write locked
|
||||||
SET TUn ENABLED set unit n write enabled
|
SET TUn ENABLED set unit n write enabled
|
||||||
|
@ -4479,7 +4702,7 @@ Error handling is as follows:
|
||||||
|
|
||||||
OS I/O error report error and stop
|
OS I/O error report error and stop
|
||||||
|
|
||||||
12.10 LP20 DMA Line Printer (LP20)
|
12.11 LP20 DMA Line Printer (LP20)
|
||||||
|
|
||||||
The LP20 is a DMA-based line printer controller. There is one
|
The LP20 is a DMA-based line printer controller. There is one
|
||||||
line printer option to clear the vertical forms unit (VFU).
|
line printer option to clear the vertical forms unit (VFU).
|
||||||
|
@ -4521,7 +4744,7 @@ Error handling is as follows:
|
||||||
|
|
||||||
OS I/O error x report error and stop
|
OS I/O error x report error and stop
|
||||||
|
|
||||||
12.11 Symbolic Display and Input
|
12.12 Symbolic Display and Input
|
||||||
|
|
||||||
The PDP-10 simulator implements symbolic display and input. Display is
|
The PDP-10 simulator implements symbolic display and input. Display is
|
||||||
controlled by command line switches:
|
controlled by command line switches:
|
||||||
|
@ -4701,9 +4924,10 @@ Error handling is as follows:
|
||||||
|
|
||||||
13.2.3 316/516-33 Console Teletype (TTY)
|
13.2.3 316/516-33 Console Teletype (TTY)
|
||||||
|
|
||||||
The terminal reads and writes to the controlling console port. It has
|
The terminal reads from the console keyboard and writes to the
|
||||||
one option, UC; when set, it automatically converts lower case input
|
simulator console window. The terminal has one option, UC; when
|
||||||
to upper case. This is on by default.
|
set, the terminal automatically converts lower case input to upper
|
||||||
|
case. This is on by default.
|
||||||
|
|
||||||
The terminal these registers:
|
The terminal these registers:
|
||||||
|
|
||||||
|
@ -4865,7 +5089,7 @@ use 578 blocks of 256 32b words. Each 32b word contains 18b (6 lines)
|
||||||
of data. PDP-8 DECtapes use 1474 blocks of 129 16b words. Each 16b
|
of data. PDP-8 DECtapes use 1474 blocks of 129 16b words. Each 16b
|
||||||
word contains 12b (4 lines) of data. Note that PDP-8 OS/8 does not use
|
word contains 12b (4 lines) of data. Note that PDP-8 OS/8 does not use
|
||||||
the 129th word of each block, and OS/8 DECtape dumps contain only 128
|
the 129th word of each block, and OS/8 DECtape dumps contain only 128
|
||||||
words per block. A utility, DSOS8CVT.C, is provided to convert OS/8
|
words per block. A utility, DTOS8CVT.C, is provided to convert OS/8
|
||||||
DECtape dumps to simulator format.
|
DECtape dumps to simulator format.
|
||||||
|
|
||||||
A known problem in DECtape format is that when a block is recorded in
|
A known problem in DECtape format is that when a block is recorded in
|
||||||
|
@ -4932,28 +5156,47 @@ legend: y = runs operating system or sample program
|
||||||
|
|
||||||
Revision History (since Rev 1.1)
|
Revision History (since Rev 1.1)
|
||||||
|
|
||||||
Rev 2.6b, Jul, 01
|
Rev 2.7, Sep, 01
|
||||||
|
Added DZ11 (from Thord Nilson and Art Krewat)
|
||||||
|
to PDP-11, PDP-10
|
||||||
|
Added additional terminals to PDP-8
|
||||||
|
Added TSS/8 packed character format to PDP-8
|
||||||
|
Added sim_sock and sim_tmxr libraries
|
||||||
|
Added sim_qcount and simulator exit detach all facilities
|
||||||
|
Added Macintosh sim_sock support (from Peter Schorn)
|
||||||
|
Added simulator revision level, SHOW version
|
||||||
|
Changed int64/uint64 to t_int64/t_uint64 for Windoze
|
||||||
|
Fixed bug in PDP-11 interrupt acknowledge
|
||||||
|
Fixed bugs in PDP-11 TS NXM check, boot code, error status;
|
||||||
|
added extended characteristics and status
|
||||||
|
Fixed bug in PDP-11 TC stop, stop all functions
|
||||||
|
Fixed receive interrupt while disconnected bug in DZ11
|
||||||
|
Fixed multi-unit operation bugs, interrupt bugs in
|
||||||
|
PDP-11 RP, PDP-10 RP, PDP-10 TU
|
||||||
|
Fixed carrier detect bug in PDP-11, PDP-10 DZ
|
||||||
|
Fixed bug in PDP-8 reset routine
|
||||||
|
Fixed conditional in PDP-18b CPU
|
||||||
|
Fixed SC = 0 bug in PDP-18b EAE
|
||||||
|
Fixed bug in PDP-7 LPT
|
||||||
|
Upgraded Nova second terminal to use sim_tmxr
|
||||||
|
Upgraded PDP-18b second terminal to use sim_tmxr
|
||||||
|
Upgraded PDP-11 LTC to full KW11-L
|
||||||
|
Removed hack multiple console support
|
||||||
|
|
||||||
|
Rev 2.6b, Aug, 01
|
||||||
Added H316/516 simulator
|
Added H316/516 simulator
|
||||||
Added Macintosh support from Louis Chrétien, Peter Schorn,
|
Added Macintosh support from Louis Chrétien, Peter Schorn,
|
||||||
and Ben Supnik
|
and Ben Supnik
|
||||||
Added bad block table option to PDP-11 RL, RP
|
Added bad block table option to PDP-11 RL, RP
|
||||||
|
Removed register in declarations
|
||||||
Fixed bugs found by Peter Schorn
|
Fixed bugs found by Peter Schorn
|
||||||
Endian error in PDP-10, PDP-11 RP
|
-- endian error in PDP-10, PDP-11 RP
|
||||||
Space reverse error in PDP-11 TS
|
-- space reverse error in PDP-11 TS
|
||||||
Symbolic input in 1401
|
-- symbolic input in 1401
|
||||||
Fixed bug in PDP-1 RIM loader found by Derek Peschel
|
Fixed bug in PDP-1 RIM loader found by Derek Peschel
|
||||||
Fixed bug in Nova fixed head disk
|
Fixed bug in Nova fixed head disk
|
||||||
Removed register in declarations
|
|
||||||
|
|
||||||
Rev 2.6a, Jun, 01
|
Rev 2.6a, Jun, 01
|
||||||
Fixed bug (found by Dave Conroy) in big-endian I/O
|
|
||||||
Fixed DECtape reset in PDP-8, PDP-11, PDP-9/15
|
|
||||||
Fixed RIM loader PC handling in PDP-9/15
|
|
||||||
Fixed indirect pointers in PDP-10 paging
|
|
||||||
Fixed SSC handling in PDP-10 TM02/TU45
|
|
||||||
Fixed JMS to non-existent memory in PDP-8
|
|
||||||
Fixed error handling on command file
|
|
||||||
Increased size of string buffers for long path names
|
|
||||||
Added PDP-9, PDP-15 API option
|
Added PDP-9, PDP-15 API option
|
||||||
Added PDP-9, PDP-15 second terminal
|
Added PDP-9, PDP-15 second terminal
|
||||||
Added PDP-10 option for TOPS-20 V4.1 bug fix
|
Added PDP-10 option for TOPS-20 V4.1 bug fix
|
||||||
|
@ -4961,6 +5204,14 @@ Rev 2.6a, Jun, 01
|
||||||
Added console logging
|
Added console logging
|
||||||
Added multiple console support
|
Added multiple console support
|
||||||
Added comment recognition
|
Added comment recognition
|
||||||
|
Increased size of string buffers for long path names
|
||||||
|
Fixed bug in big-endian I/O found by Dave Conroy
|
||||||
|
Fixed DECtape reset in PDP-8, PDP-11, PDP-9/15
|
||||||
|
Fixed RIM loader PC handling in PDP-9/15
|
||||||
|
Fixed indirect pointers in PDP-10 paging
|
||||||
|
Fixed SSC handling in PDP-10 TM02/TU45
|
||||||
|
Fixed JMS to non-existent memory in PDP-8
|
||||||
|
Fixed error handling on command file
|
||||||
|
|
||||||
Rev 2.6, May, 01
|
Rev 2.6, May, 01
|
||||||
Added ENABLE/DISABLE devices
|
Added ENABLE/DISABLE devices
|
||||||
|
@ -4989,31 +5240,31 @@ Rev 2.6, May, 01
|
||||||
Updated copyright notices, fixed comments
|
Updated copyright notices, fixed comments
|
||||||
|
|
||||||
Rev 2.5a, Dec, 00
|
Rev 2.5a, Dec, 00
|
||||||
Fixed SCP handling of devices without units
|
|
||||||
Fixed FLG, FBF initialization in many HP peripherals
|
|
||||||
Added CMD flop to HP paper tape and line printer
|
Added CMD flop to HP paper tape and line printer
|
||||||
Added status input for HP paper tape punch and TTY
|
Added status input for HP paper tape punch and TTY
|
||||||
|
Added Dutch Owens' 1401 mag tape boot routine
|
||||||
|
Added Bruce Ray's Nova plotter and second terminal modules
|
||||||
|
Added Charles Owen's Eclipse CPU support
|
||||||
|
Added PDP-9/PDP-15 RIM/BIN loader support
|
||||||
|
Added PDP-9/PDP-15 extend/bank initial state registers
|
||||||
|
Added PDP-9/PDP-15 half/full duplex support
|
||||||
|
Moved software documentation to a separate file
|
||||||
|
Fixed SCP handling of devices without units
|
||||||
|
Fixed FLG, FBF initialization in many HP peripherals
|
||||||
Fixed 1401 bugs found by Dutch Owens
|
Fixed 1401 bugs found by Dutch Owens
|
||||||
-- 4, 7 char NOPs are legal
|
-- 4, 7 char NOPs are legal
|
||||||
-- 1 char B is chained BCE
|
-- 1 char B is chained BCE
|
||||||
-- MCE moves whole character, not digit, after first
|
-- MCE moves whole character, not digit, after first
|
||||||
Added Dutch Owens' 1401 mag tape boot routine
|
|
||||||
Fixed Nova bugs found by Bruce Ray
|
Fixed Nova bugs found by Bruce Ray
|
||||||
-- traps implemented on Nova 3 as well as Nova 4
|
-- traps implemented on Nova 3 as well as Nova 4
|
||||||
-- DIV and DIVS 0/0 set carry
|
-- DIV and DIVS 0/0 set carry
|
||||||
-- RETN sets SP from FP at outset
|
-- RETN sets SP from FP at outset
|
||||||
-- IORST does not clear carry
|
-- IORST does not clear carry
|
||||||
-- Nova 4 implements two undocumented instructions
|
-- Nova 4 implements two undocumented instructions
|
||||||
Added Bruce Ray's Nova plotter and second terminal modules
|
|
||||||
Added Charles Owen's Eclipse CPU support
|
|
||||||
Fixed bugs in 18b PDP's
|
Fixed bugs in 18b PDP's
|
||||||
-- XCT indirect address calculation
|
-- XCT indirect address calculation
|
||||||
-- missing index instructions in PDP-15
|
-- missing index instructions in PDP-15
|
||||||
-- bank mode handling in PDP-15
|
-- bank mode handling in PDP-15
|
||||||
Added PDP-9/PDP-15 RIM/BIN loader support
|
|
||||||
Added PDP-9/PDP-15 extend/bank initial state registers
|
|
||||||
Added PDP-9/PDP-15 half/full duplex support
|
|
||||||
Moved software documentation to a separate file
|
|
||||||
|
|
||||||
Rev 2.5, Nov, 00
|
Rev 2.5, Nov, 00
|
||||||
Removed Digital and Compaq from copyrights, as
|
Removed Digital and Compaq from copyrights, as
|
||||||
|
@ -5072,6 +5323,8 @@ Rev 2.3a, Nov, 97
|
||||||
Fixed endian dependence in 18b PDP RIM loader
|
Fixed endian dependence in 18b PDP RIM loader
|
||||||
|
|
||||||
Rev 2.3, Mar, 97
|
Rev 2.3, Mar, 97
|
||||||
|
Added PDP-11 RP
|
||||||
|
Added PDP-1
|
||||||
Changed UNIX terminal I/O to TERMIOS
|
Changed UNIX terminal I/O to TERMIOS
|
||||||
Changed magtape format to double ended
|
Changed magtape format to double ended
|
||||||
Changed PDP-8 current page mnemonic from T to C
|
Changed PDP-8 current page mnemonic from T to C
|
||||||
|
@ -5085,8 +5338,6 @@ Rev 2.3, Mar, 97
|
||||||
Fixed bug in 18b PDP paper tape reader
|
Fixed bug in 18b PDP paper tape reader
|
||||||
Fixed bug in PDP-4 console
|
Fixed bug in PDP-4 console
|
||||||
Fixed bug in PDP-4,7 line printer
|
Fixed bug in PDP-4,7 line printer
|
||||||
Added PDP-11 RP
|
|
||||||
Added PDP-1
|
|
||||||
|
|
||||||
Rev 2.2d, Dec, 96
|
Rev 2.2d, Dec, 96
|
||||||
Added ADD/REMOVE commands
|
Added ADD/REMOVE commands
|
||||||
|
@ -5171,9 +5422,11 @@ Jay Jaeger IBM 1401 information
|
||||||
Doug Jones PDP-8 information, simulator, and software
|
Doug Jones PDP-8 information, simulator, and software
|
||||||
Al Kossow HP 21xx, Varian 620, TI 990, DEC documentation and software
|
Al Kossow HP 21xx, Varian 620, TI 990, DEC documentation and software
|
||||||
Arthur Krewat DZ11 update for the PDP-10
|
Arthur Krewat DZ11 update for the PDP-10
|
||||||
|
Mirian Crzig Lennox ITS and DZ11 debugging
|
||||||
Don Lewine Nova documentation and legal permissions
|
Don Lewine Nova documentation and legal permissions
|
||||||
Tim Litt PDP-10 hardware documentation and schematics,
|
Tim Litt PDP-10 hardware documentation and schematics,
|
||||||
tape images, and software sources
|
tape images, and software sources
|
||||||
|
Tim Markson DZ11 debugging
|
||||||
Scott McGregor PDP-11 UNIX legal permissions
|
Scott McGregor PDP-11 UNIX legal permissions
|
||||||
Jeff Moffatt HP 2100 information, documentation, and software
|
Jeff Moffatt HP 2100 information, documentation, and software
|
||||||
Alec Muffett Solaris port testing
|
Alec Muffett Solaris port testing
|
||||||
|
@ -5209,6 +5462,7 @@ David Waks PDP-8 ESI-X and PDP-7 SIM8 software
|
||||||
Tom West Nova documentation
|
Tom West Nova documentation
|
||||||
Adrian Wise H316 simulator, documentation, and software
|
Adrian Wise H316 simulator, documentation, and software
|
||||||
John Wilson PDP-11 simulator and software
|
John Wilson PDP-11 simulator and software
|
||||||
|
Joe Young RP debugging on Ultrix-11 and BSD
|
||||||
|
|
||||||
In addition, the following companies have graciously licensed their
|
In addition, the following companies have graciously licensed their
|
||||||
software at no cost for hobbyist use:
|
software at no cost for hobbyist use:
|
||||||
|
|
134
simh_swre.txt
134
simh_swre.txt
|
@ -1,7 +1,7 @@
|
||||||
To: Users
|
To: Users
|
||||||
From: Bob Supnik
|
From: Bob Supnik
|
||||||
Subj: Sample Software Packages
|
Subj: Sample Software Packages
|
||||||
Date: 31-May-01
|
Date: 30-Sep-01
|
||||||
|
|
||||||
This memorandum documents the sample software packages available to run
|
This memorandum documents the sample software packages available to run
|
||||||
with the SIMH simulators. Many of these packages are available under
|
with the SIMH simulators. Many of these packages are available under
|
||||||
|
@ -88,6 +88,75 @@ Note that OS/8 only recognizes upper case characters. The first disk
|
||||||
(drive 0) is the system disk; it also includes BASIC. The second disk
|
(drive 0) is the system disk; it also includes BASIC. The second disk
|
||||||
(drive 1) includes FORTRAN.
|
(drive 1) includes FORTRAN.
|
||||||
|
|
||||||
|
1.4 PDP-8 TSS/8
|
||||||
|
|
||||||
|
TSS/8 is the PDP-8's timesharing system. It provides a program development
|
||||||
|
and execution environment for assembler, BASIC, and FORTRAN programs. TSS/8
|
||||||
|
is provided as is, without fee, by Digital Equipment Corporation, for non-
|
||||||
|
commercial use only. My thanks to John Wilson of Dbit Inc, who provided
|
||||||
|
the disk image and the initialization tape source.
|
||||||
|
|
||||||
|
Loading TSS/8
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Note: your environment must have a functioning second Teletype; that is, you cannot
|
||||||
|
at present run Foreground/Background if your host system is VMS or OS/2.
|
||||||
|
|
||||||
|
- Load the paper-tape bootstrap:
|
||||||
|
|
||||||
|
sim> load tss8_init.bin
|
||||||
|
|
||||||
|
- Mount the TSS/8 disk image of the RF08:
|
||||||
|
|
||||||
|
sim> attach rf tss8_rf.dsk
|
||||||
|
|
||||||
|
- Assign a TCP/IP port to the Telnet listener for the extra terminals:
|
||||||
|
|
||||||
|
sim> attach tti1 <port #> -- 4000 typically works
|
||||||
|
|
||||||
|
- Run the bootstrap:
|
||||||
|
|
||||||
|
sim> run 24200
|
||||||
|
|
||||||
|
- TSS/8 will boot and go through its startup dialog
|
||||||
|
|
||||||
|
LOAD, DUMP, START, ETC? START
|
||||||
|
MONTH-DAY-YEAR: mm:dd:yy -- numeric, yy in range [74:85]
|
||||||
|
HR:MIN - hh:mm -- numeric, 24 hour format
|
||||||
|
(type cr to get attention)
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
and is now ready for login. The list of accounts and passwords:
|
||||||
|
|
||||||
|
PPN Password
|
||||||
|
[0,1] VH3M
|
||||||
|
[0,2] LXHE
|
||||||
|
[0,3] SHUG
|
||||||
|
[77,77]
|
||||||
|
[1,10] WBCN
|
||||||
|
[20,1] DT
|
||||||
|
[20,2] PT
|
||||||
|
[20,3] TSS8
|
||||||
|
[20,4] EDIT
|
||||||
|
[20,5] 4TH
|
||||||
|
[1,50] JERK
|
||||||
|
|
||||||
|
- Login using one of the existing accounts. The login command won't echo:
|
||||||
|
|
||||||
|
.LOGIN 2 LXHE -- privileged library account
|
||||||
|
|
||||||
|
TSS/8.24 JOB 01 [00,02] K00 23:23:06
|
||||||
|
|
||||||
|
SYSTEM IS DOWN, INC.
|
||||||
|
|
||||||
|
- The system is now ready for commands. To get a directory listing:
|
||||||
|
|
||||||
|
.R CAT
|
||||||
|
|
||||||
|
- Other users can log in by connecting, from a Telnet client, to localhost
|
||||||
|
on the port specified in the attach tti1 command.
|
||||||
|
|
||||||
2. PDP-11
|
2. PDP-11
|
||||||
|
|
||||||
2.1 UNIX V5, V6, V7
|
2.1 UNIX V5, V6, V7
|
||||||
|
@ -301,6 +370,69 @@ execution capabilities. To load and run ADSS/KM-15:
|
||||||
4.0000
|
4.0000
|
||||||
*
|
*
|
||||||
|
|
||||||
|
6.3 Advanced Software System/Foreground Background
|
||||||
|
|
||||||
|
Foreground/Background System
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Note: your environment must have a functioning second Teletype; that is, you cannot
|
||||||
|
at present run Foreground/Background if your host system is VMS or OS/2.
|
||||||
|
|
||||||
|
- Load the paper-tape bootstrap into upper memory:
|
||||||
|
|
||||||
|
sim> load dec-15u.rim 77637
|
||||||
|
|
||||||
|
You <must> specify the load address.
|
||||||
|
|
||||||
|
- Verify that the bootstrap loaded correctly:
|
||||||
|
|
||||||
|
sim> ex pc
|
||||||
|
PC: 077646
|
||||||
|
|
||||||
|
- Mount the Advanced Software System DECtape image on DECtape unit 0:
|
||||||
|
|
||||||
|
sim> attach dt fb15_32k.dtp
|
||||||
|
|
||||||
|
- Turn on the API option:
|
||||||
|
|
||||||
|
sim> set cpu api
|
||||||
|
|
||||||
|
- Assign a TCP/IP port to the Telnet listener for the second terminal:
|
||||||
|
|
||||||
|
sim> assign tti1 <port #> -- 4000 typically works
|
||||||
|
|
||||||
|
- Start a Telnet client to act as the second terminal and connect to
|
||||||
|
localhost on the specified port.
|
||||||
|
|
||||||
|
- Run the bootstrap:
|
||||||
|
|
||||||
|
sim> run
|
||||||
|
|
||||||
|
- The DECtape will boot and print out
|
||||||
|
|
||||||
|
F9/15 V4A
|
||||||
|
$
|
||||||
|
|
||||||
|
and is now ready for commands. Recognized commands include:
|
||||||
|
|
||||||
|
D 0 list system device directory
|
||||||
|
R list device assignments
|
||||||
|
|
||||||
|
- To activate the background, load IDLE into the foreground:
|
||||||
|
|
||||||
|
$A DTA0 -4
|
||||||
|
$GLOAD
|
||||||
|
FGLOAD V2A
|
||||||
|
>_IDLE<altmode = control-[>
|
||||||
|
|
||||||
|
Background terminal responds with
|
||||||
|
|
||||||
|
B9/15 V4A
|
||||||
|
$
|
||||||
|
|
||||||
|
and is now ready for commands.
|
||||||
|
|
||||||
|
|
||||||
7. IBM 1401
|
7. IBM 1401
|
||||||
|
|
||||||
7.1 Single Card "Koans"
|
7.1 Single Card "Koans"
|
||||||
|
|
Loading…
Add table
Reference in a new issue