mirror of
https://github.com/rcornwell/sims.git
synced 2026-04-26 20:18:04 +00:00
KA10: Updated KS10 devices.
This commit is contained in:
@@ -137,7 +137,7 @@ t_stat ctyi_svc (UNIT *uptr)
|
||||
while (!full(&cty_in)) {
|
||||
ch = sim_poll_kbd ();
|
||||
if (ch & SCPE_KFLAG) {
|
||||
ch = 0177 & sim_tt_inpcvt(ch, TT_GET_MODE (uptr->flags));
|
||||
ch = 0177 & sim_tt_inpcvt(ch, TT_GET_MODE (cty_unit[0].flags));
|
||||
cty_in.buff[cty_in.in_ptr] =ch & 0377;
|
||||
inci(&cty_in);
|
||||
sim_debug(DEBUG_DETAIL, &cty_dev, "CTY char %o '%c'\n", ch,
|
||||
@@ -176,6 +176,7 @@ t_stat ctyo_svc (UNIT *uptr)
|
||||
sim_debug(DEBUG_DETAIL, &cty_dev, "CTY Write %012llo\n", buffer);
|
||||
if (buffer & CTY_CHAR) {
|
||||
if (!full(&cty_out)) {
|
||||
buffer = sim_tt_outcvt ( buffer, TT_GET_MODE (uptr->flags));
|
||||
cty_out.buff[cty_out.in_ptr] = (uint8)(buffer & 0377);
|
||||
buffer = 0;
|
||||
if (Mem_write_word(CTY_OUT, &buffer, 0) == 0) {
|
||||
|
||||
545
PDP10/ks10_dz.c
Normal file
545
PDP10/ks10_dz.c
Normal file
@@ -0,0 +1,545 @@
|
||||
/* ks10_dz.c: PDP-10 DZ11 communication server simulator
|
||||
|
||||
Copyright (c) 2021, Richard Cornwell
|
||||
|
||||
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
|
||||
RICHARD CORNWELL 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 Richard Cornwell shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Richard Cornwell.
|
||||
|
||||
*/
|
||||
|
||||
#include "kx10_defs.h"
|
||||
#include "sim_sock.h"
|
||||
#include "sim_tmxr.h"
|
||||
|
||||
#ifndef NUM_DEVS_DZ
|
||||
#define NUM_DEVS_DZ 0
|
||||
#endif
|
||||
|
||||
#if (NUM_DEVS_DZ > 0)
|
||||
|
||||
|
||||
#define DC10_LINES 8
|
||||
|
||||
#define STATUS u3
|
||||
|
||||
#define DTS_LINE 007700 /* Scanner line number in STATUS */
|
||||
#define PI_CHN 000007 /* IN STATUS. */
|
||||
#define RCV_PI 000010 /* IN STATUS. */
|
||||
#define XMT_PI 000020 /* IN STATUS. */
|
||||
#define DTR_DIS 000040 /* DTR FLAG */
|
||||
#define RST_SCN 000010 /* CONO */
|
||||
#define DTR_SET 000020 /* CONO */
|
||||
#define CLR_SCN 000040 /* CONO */
|
||||
|
||||
#define DATA 0000377
|
||||
#define FLAG 0000400 /* Recieve data/ transmit disable */
|
||||
#define LINE 0000077 /* Line number in Left */
|
||||
#define LFLAG 0000100 /* Direct line number flag */
|
||||
|
||||
/* DC10E flags */
|
||||
#define CTS 0000004 /* Clear to send */
|
||||
#define RES_DET 0000002 /* Ring detect */
|
||||
#define DLO 0000040 /* (ACU) Data line occupied */
|
||||
#define PND 0000020 /* (ACU) Present next digit */
|
||||
#define ACR 0000010 /* (ACU) Abandon Call and retry */
|
||||
#define CRQ 0000040 /* (ACU) Call Request */
|
||||
#define DPR 0000020 /* (ACU) Digit Presented */
|
||||
#define NB 0000017 /* (ACU) Number */
|
||||
#define OFF_HOOK 0000100 /* Off Hook (CD) */
|
||||
#define CAUSE_PI 0000200 /* Cause PI */
|
||||
|
||||
uint64 dz_l_status; /* Line status */
|
||||
int dz_l_count = 0; /* Scan counter */
|
||||
int dz_modem = DC10_MLINES; /* Modem base address */
|
||||
uint8 dcix_buf[DC10_MLINES] = { 0 }; /* Input buffers */
|
||||
uint8 dcox_buf[DC10_MLINES] = { 0 }; /* Output buffers */
|
||||
TMLN dz_ldsc[DC10_MLINES] = { 0 }; /* Line descriptors */
|
||||
TMXR dz_desc = { DC10_LINES, 0, 0, dz_ldsc };
|
||||
uint32 tx_enable, rx_rdy; /* Flags */
|
||||
uint32 dz_enable; /* Enable line */
|
||||
uint32 dz_ring; /* Connection pending */
|
||||
uint32 rx_conn; /* Connection flags */
|
||||
extern int32 tmxr_poll;
|
||||
|
||||
int dz_write(t_addr addr, uint16 data, int32 access);
|
||||
int dz_read(t_addr addr, uint16 *data, int32 access);
|
||||
t_stat dz_svc (UNIT *uptr);
|
||||
t_stat dz_doscan (UNIT *uptr);
|
||||
t_stat dz_reset (DEVICE *dptr);
|
||||
t_stat dz_set_modem (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat dz_show_modem (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat dz_setnl (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat dz_set_log (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat dz_set_nolog (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat dz_show_log (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat dz_attach (UNIT *uptr, CONST char *cptr);
|
||||
t_stat dz_detach (UNIT *uptr);
|
||||
t_stat dz_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag,
|
||||
const char *cptr);
|
||||
const char *dz_description (DEVICE *dptr);
|
||||
|
||||
/* DC10 data structures
|
||||
|
||||
dz_dev DC10 device descriptor
|
||||
dz_unit DC10 unit descriptor
|
||||
dz_reg DC10 register list
|
||||
*/
|
||||
|
||||
DIB dz_dib = { 0776000, 077, 0340, 5, 3, &dz_read, &dz_write, 0 }
|
||||
|
||||
UNIT dz_unit = {
|
||||
UDATA (&dz_svc, TT_MODE_7B+UNIT_IDLE+UNIT_DISABLE+UNIT_ATTABLE, 0), KBD_POLL_WAIT
|
||||
};
|
||||
|
||||
REG dz_reg[] = {
|
||||
{ DRDATA (TIME, dz_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (STATUS, dz_unit.STATUS, 18), PV_LEFT },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
MTAB dz_mod[] = {
|
||||
{ TT_MODE, TT_MODE_KSR, "KSR", "KSR", NULL },
|
||||
{ TT_MODE, TT_MODE_7B, "7b", "7B", NULL },
|
||||
{ TT_MODE, TT_MODE_8B, "8b", "8B", NULL },
|
||||
{ TT_MODE, TT_MODE_7P, "7p", "7P", NULL },
|
||||
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 1, NULL, "DISCONNECT",
|
||||
&tmxr_dscln, NULL, &dz_desc, "Disconnect a specific line" },
|
||||
{ UNIT_ATT, UNIT_ATT, "SUMMARY", NULL,
|
||||
NULL, &tmxr_show_summ, (void *) &dz_desc, "Display a summary of line states" },
|
||||
{ MTAB_XTD|MTAB_VDV|MTAB_NMO, 1, "CONNECTIONS", NULL,
|
||||
NULL, &tmxr_show_cstat, (void *) &dz_desc, "Display current connections" },
|
||||
{ MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "STATISTICS", NULL,
|
||||
NULL, &tmxr_show_cstat, (void *) &dz_desc, "Display multiplexer statistics" },
|
||||
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "LINES", "LINES=n",
|
||||
&dz_setnl, &tmxr_show_lines, (void *) &dz_desc, "Set number of lines" },
|
||||
{ MTAB_XTD|MTAB_VDV|MTAB_NC, 0, NULL, "LOG=n=file",
|
||||
&dz_set_log, NULL, (void *)&dz_desc },
|
||||
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, NULL, "NOLOG",
|
||||
&dz_set_nolog, NULL, (void *)&dz_desc, "Disable logging on designated line" },
|
||||
{ MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "LOG", NULL,
|
||||
NULL, &dz_show_log, (void *)&dz_desc, "Display logging for all lines" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE dz_dev = {
|
||||
"DZ", &dz_unit, dz_reg, dz_mod,
|
||||
1, 10, 31, 1, 8, 8,
|
||||
&tmxr_ex, &tmxr_dep, &dz_reset,
|
||||
NULL, &dz_attach, &dz_detach,
|
||||
&dz_dib, DEV_MUX | DEV_DISABLE | DEV_DEBUG, 0, dev_debug,
|
||||
NULL, NULL, &dz_help, NULL, NULL, &dz_description
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* IOT routine */
|
||||
t_stat dz_devio(uint32 dev, uint64 *data) {
|
||||
UNIT *uptr = &dz_unit;
|
||||
TMLN *lp;
|
||||
int ln;
|
||||
|
||||
switch(dev & 3) {
|
||||
case CONI:
|
||||
/* Check if we might have any interrupts pending */
|
||||
if ((uptr->STATUS & (RCV_PI|XMT_PI)) == 0)
|
||||
dz_doscan(uptr);
|
||||
*data = uptr->STATUS & (PI_CHN|RCV_PI|XMT_PI);
|
||||
sim_debug(DEBUG_CONI, &dz_dev, "DC %03o CONI %06o PC=%o\n",
|
||||
dev, (uint32)*data, PC);
|
||||
break;
|
||||
|
||||
case CONO:
|
||||
/* Set PI */
|
||||
uptr->STATUS &= ~PI_CHN;
|
||||
uptr->STATUS |= PI_CHN & *data;
|
||||
if (*data & RST_SCN)
|
||||
dz_l_count = 0;
|
||||
if (*data & DTR_SET)
|
||||
uptr->STATUS |= DTR_SET;
|
||||
if (*data & CLR_SCN) {
|
||||
uptr->STATUS &= PI_CHN;
|
||||
for (ln = 0; ln < dz_desc.lines; ln++) {
|
||||
lp = &dz_ldsc[ln];
|
||||
if (lp->conn) {
|
||||
tmxr_linemsg (lp, "\r\nLine Hangup\r\n");
|
||||
tmxr_reset_ln(lp);
|
||||
}
|
||||
}
|
||||
tx_enable = 0;
|
||||
dz_enable = 0;
|
||||
rx_rdy = 0; /* Flags */
|
||||
rx_conn = 0;
|
||||
dz_ring = 0;
|
||||
dz_l_status = 0;
|
||||
}
|
||||
|
||||
sim_debug(DEBUG_CONO, &dz_dev, "DC %03o CONO %06o PC=%06o\n",
|
||||
dev, (uint32)*data, PC);
|
||||
dz_doscan(uptr);
|
||||
break;
|
||||
|
||||
case DATAO:
|
||||
if (*data & (LFLAG << 18))
|
||||
ln = (*data >> 18) & 077;
|
||||
else
|
||||
ln = dz_l_count;
|
||||
if (ln >= dz_modem) {
|
||||
if (*data & CAUSE_PI)
|
||||
dz_l_status |= (1LL << ln);
|
||||
else
|
||||
dz_l_status &= ~(1LL << ln);
|
||||
ln -= dz_modem;
|
||||
sim_debug(DEBUG_DETAIL, &dz_dev, "DC line modem %d %03o\n",
|
||||
ln, (uint32)(*data & 0777));
|
||||
if ((*data & OFF_HOOK) == 0) {
|
||||
uint32 mask = ~(1 << ln);
|
||||
rx_rdy &= mask;
|
||||
tx_enable &= mask;
|
||||
dz_enable &= mask;
|
||||
lp = &dz_ldsc[ln];
|
||||
if (rx_conn & (1 << ln) && lp->conn) {
|
||||
sim_debug(DEBUG_DETAIL, &dz_dev, "DC line hangup %d\n", ln);
|
||||
tmxr_linemsg (lp, "\r\nLine Hangup\r\n");
|
||||
tmxr_reset_ln(lp);
|
||||
rx_conn &= mask;
|
||||
}
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, &dz_dev, "DC line off-hook %d\n", ln);
|
||||
dz_enable |= 1<<ln;
|
||||
if (dz_ring & (1 << ln)) {
|
||||
dz_l_status |= (1LL << (ln + dz_modem));
|
||||
dz_ring &= ~(1 << ln);
|
||||
rx_conn |= (1 << ln);
|
||||
}
|
||||
}
|
||||
} else if (ln < dz_desc.lines) {
|
||||
lp = &dz_ldsc[ln];
|
||||
if (*data & FLAG) {
|
||||
tx_enable &= ~(1 << ln);
|
||||
dz_l_status &= ~(1LL << ln);
|
||||
} else if (lp->conn) {
|
||||
int32 ch = *data & DATA;
|
||||
ch = sim_tt_outcvt(ch, TT_GET_MODE (dz_unit.flags) | TTUF_KSR);
|
||||
tmxr_putc_ln (lp, ch);
|
||||
if (lp->xmte)
|
||||
tx_enable |= (1 << ln);
|
||||
else
|
||||
tx_enable &= ~(1 << ln);
|
||||
dz_l_status |= (1LL << ln);
|
||||
}
|
||||
}
|
||||
dz_doscan(uptr);
|
||||
sim_debug(DEBUG_DATAIO, &dz_dev, "DC %03o DATO %012llo PC=%06o\n",
|
||||
dev, *data, PC);
|
||||
break;
|
||||
|
||||
case DATAI:
|
||||
ln = dz_l_count;
|
||||
*data = (uint64)(ln) << 18;
|
||||
if (ln >= dz_modem) {
|
||||
dz_l_status &= ~(1LL << ln);
|
||||
ln = ln - dz_modem;
|
||||
lp = &dz_ldsc[ln];
|
||||
if (dz_enable & (1 << ln))
|
||||
*data |= FLAG|OFF_HOOK;
|
||||
if (rx_conn & (1 << ln) && lp->conn)
|
||||
*data |= FLAG|CTS;
|
||||
if (dz_ring & (1 << ln))
|
||||
*data |= FLAG|RES_DET;
|
||||
} else if (ln < dz_desc.lines) {
|
||||
/* Nothing happens if no recieve data, which is transmit ready */
|
||||
lp = &dz_ldsc[ln];
|
||||
if (tmxr_rqln (lp) > 0) {
|
||||
int32 ch = tmxr_getc_ln (lp);
|
||||
if (ch & SCPE_BREAK) /* break? */
|
||||
ch = 0;
|
||||
else
|
||||
ch = sim_tt_inpcvt (ch, TT_GET_MODE(dz_unit.flags) | TTUF_KSR);
|
||||
*data |= FLAG | (uint64)(ch & DATA);
|
||||
}
|
||||
if (tmxr_rqln (lp) > 0) {
|
||||
rx_rdy |= 1 << ln;
|
||||
dz_l_status |= (1LL << ln);
|
||||
} else {
|
||||
rx_rdy &= ~(1 << ln);
|
||||
dz_l_status &= ~(1LL << ln);
|
||||
}
|
||||
}
|
||||
dz_doscan(uptr);
|
||||
sim_debug(DEBUG_DATAIO, &dz_dev, "DC %03o DATI %012llo PC=%06o\n",
|
||||
dev, *data, PC);
|
||||
break;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Unit service */
|
||||
|
||||
t_stat dz_svc (UNIT *uptr)
|
||||
{
|
||||
int32 ln;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
|
||||
return SCPE_OK;
|
||||
ln = tmxr_poll_conn (&dz_desc); /* look for connect */
|
||||
if (ln >= 0) { /* got one? rcv enb*/
|
||||
dz_ldsc[ln].rcve = 1;
|
||||
dz_ring |= (1 << ln);
|
||||
dz_l_status |= (1LL << (ln + dz_modem)); /* Flag modem line */
|
||||
sim_debug(DEBUG_DETAIL, &dz_dev, "DC line connect %d\n", ln);
|
||||
}
|
||||
tmxr_poll_tx(&dz_desc);
|
||||
tmxr_poll_rx(&dz_desc);
|
||||
for (ln = 0; ln < dz_desc.lines; ln++) {
|
||||
/* Check if buffer empty */
|
||||
if (dz_ldsc[ln].xmte && ((dz_l_status & (1ll << ln)) != 0)) {
|
||||
tx_enable |= 1 << ln;
|
||||
}
|
||||
|
||||
/* Check to see if any pending data for this line */
|
||||
if (tmxr_rqln(&dz_ldsc[ln]) > 0) {
|
||||
rx_rdy |= (1 << ln);
|
||||
dz_l_status |= (1LL << ln); /* Flag line */
|
||||
sim_debug(DEBUG_DETAIL, &dz_dev, "DC recieve %d\n", ln);
|
||||
}
|
||||
/* Check if disconnect */
|
||||
if ((rx_conn & (1 << ln)) != 0 && dz_ldsc[ln].conn == 0) {
|
||||
rx_conn &= ~(1 << ln);
|
||||
dz_l_status |= (1LL << (ln + dz_modem)); /* Flag modem line */
|
||||
sim_debug(DEBUG_DETAIL, &dz_dev, "DC line disconnect %d\n", ln);
|
||||
}
|
||||
}
|
||||
|
||||
/* If any pending status request, raise the PI signal */
|
||||
if (dz_l_status)
|
||||
set_interrupt(DC_DEVNUM, uptr->STATUS);
|
||||
sim_clock_coschedule(uptr, tmxr_poll); /* continue poll */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Scan to see if something to do */
|
||||
t_stat dz_doscan (UNIT *uptr) {
|
||||
int32 lmask;
|
||||
|
||||
uptr->STATUS &= ~(RCV_PI|XMT_PI);
|
||||
clr_interrupt(DC_DEVNUM);
|
||||
for (;dz_l_status != 0; dz_l_count++) {
|
||||
dz_l_count &= 077;
|
||||
/* Check if we found it */
|
||||
if (dz_l_status & (1LL << dz_l_count)) {
|
||||
/* Check if modem control or data line */
|
||||
if (dz_l_count >= dz_modem) {
|
||||
uptr->STATUS |= RCV_PI;
|
||||
} else {
|
||||
/* Must be data line */
|
||||
lmask = 1 << dz_l_count;
|
||||
if (rx_rdy & lmask)
|
||||
uptr->STATUS |= RCV_PI;
|
||||
if (tx_enable & lmask)
|
||||
uptr->STATUS |= XMT_PI;
|
||||
}
|
||||
/* Stop scanner */
|
||||
set_interrupt(DC_DEVNUM, uptr->STATUS);
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat dz_reset (DEVICE *dptr)
|
||||
{
|
||||
|
||||
if (dz_unit.flags & UNIT_ATT) /* if attached, */
|
||||
sim_activate (&dz_unit, tmxr_poll); /* activate */
|
||||
else
|
||||
sim_cancel (&dz_unit); /* else stop */
|
||||
tx_enable = 0;
|
||||
rx_rdy = 0; /* Flags */
|
||||
rx_conn = 0;
|
||||
dz_l_status = 0;
|
||||
dz_l_count = 0;
|
||||
dz_unit.STATUS = 0;
|
||||
clr_interrupt(DC_DEVNUM);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* SET LINES processor */
|
||||
|
||||
t_stat dz_setnl (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
int32 newln, i, t;
|
||||
t_stat r;
|
||||
|
||||
if (cptr == NULL)
|
||||
return SCPE_ARG;
|
||||
newln = (int32) get_uint (cptr, 10, DC10_MLINES, &r);
|
||||
if ((r != SCPE_OK) || (newln == dz_desc.lines))
|
||||
return r;
|
||||
if (newln > dz_modem)
|
||||
return SCPE_ARG;
|
||||
if ((newln == 0) || (newln > DC10_MLINES) || (newln % 8) != 0)
|
||||
return SCPE_ARG;
|
||||
if (newln < dz_desc.lines) {
|
||||
for (i = newln - 1, t = 0; i < dz_desc.lines; i++)
|
||||
t = t | dz_ldsc[i].conn;
|
||||
if (t && !get_yn ("This will disconnect users; proceed [N]?", FALSE))
|
||||
return SCPE_OK;
|
||||
for (i = newln - 1; i < dz_desc.lines; i++) {
|
||||
if (dz_ldsc[i].conn) {
|
||||
tmxr_linemsg (&dz_ldsc[i], "\r\nOperator disconnected line\r\n");
|
||||
tmxr_send_buffered_data (&dz_ldsc[i]);
|
||||
}
|
||||
tmxr_detach_ln (&dz_ldsc[i]); /* completely reset line */
|
||||
}
|
||||
}
|
||||
if (dz_desc.lines < newln)
|
||||
memset (dz_ldsc + dz_desc.lines, 0, sizeof(*dz_ldsc)*(newln-dz_desc.lines));
|
||||
dz_desc.lines = newln;
|
||||
return dz_reset (&dz_dev); /* setup lines and auto config */
|
||||
}
|
||||
|
||||
/* SET LOG processor */
|
||||
|
||||
t_stat dz_set_log (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
t_stat r;
|
||||
char gbuf[CBUFSIZE];
|
||||
int32 ln;
|
||||
|
||||
if (cptr == NULL)
|
||||
return SCPE_ARG;
|
||||
cptr = get_glyph (cptr, gbuf, '=');
|
||||
if ((cptr == NULL) || (*cptr == 0) || (gbuf[0] == 0))
|
||||
return SCPE_ARG;
|
||||
ln = (int32) get_uint (gbuf, 10, dz_desc.lines, &r);
|
||||
if ((r != SCPE_OK) || (ln > dz_desc.lines))
|
||||
return SCPE_ARG;
|
||||
return tmxr_set_log (NULL, ln, cptr, desc);
|
||||
}
|
||||
|
||||
/* SET NOLOG processor */
|
||||
|
||||
t_stat dz_set_nolog (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
t_stat r;
|
||||
int32 ln;
|
||||
|
||||
if (cptr == NULL)
|
||||
return SCPE_ARG;
|
||||
ln = (int32) get_uint (cptr, 10, dz_desc.lines, &r);
|
||||
if ((r != SCPE_OK) || (ln > dz_desc.lines))
|
||||
return SCPE_ARG;
|
||||
return tmxr_set_nolog (NULL, ln, NULL, desc);
|
||||
}
|
||||
|
||||
/* SHOW LOG processor */
|
||||
|
||||
t_stat dz_show_log (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
|
||||
{
|
||||
int32 i;
|
||||
|
||||
for (i = 0; i < dz_desc.lines; i++) {
|
||||
fprintf (st, "line %d: ", i);
|
||||
tmxr_show_log (st, NULL, i, desc);
|
||||
fprintf (st, "\n");
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Attach routine */
|
||||
|
||||
t_stat dz_attach (UNIT *uptr, CONST char *cptr)
|
||||
{
|
||||
t_stat reason;
|
||||
|
||||
reason = tmxr_attach (&dz_desc, uptr, cptr);
|
||||
if (reason != SCPE_OK)
|
||||
return reason;
|
||||
sim_activate (uptr, tmxr_poll);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Detach routine */
|
||||
|
||||
t_stat dz_detach (UNIT *uptr)
|
||||
{
|
||||
int32 i;
|
||||
t_stat reason;
|
||||
reason = tmxr_detach (&dz_desc, uptr);
|
||||
for (i = 0; i < dz_desc.lines; i++)
|
||||
dz_ldsc[i].rcve = 0;
|
||||
sim_cancel (uptr);
|
||||
return reason;
|
||||
}
|
||||
|
||||
t_stat dz_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
|
||||
{
|
||||
fprintf (st, "DC10E Terminal Interfaces\n\n");
|
||||
fprintf (st, "The DC10 supported up to 8 blocks of 8 lines. Modem control was on a seperate\n");
|
||||
fprintf (st, "line. The simulator supports this by setting modem control to a fixed offset\n");
|
||||
fprintf (st, "from the given line. The number of lines is specified with a SET command:\n\n");
|
||||
fprintf (st, " sim> SET DC LINES=n set number of additional lines to n [8-32]\n\n");
|
||||
fprintf (st, "Lines must be set in multiples of 8.\n");
|
||||
fprintf (st, "The default offset for modem lines is 32. This can be changed with\n\n");
|
||||
fprintf (st, " sim> SET DC MODEM=n set offset for modem control to n [8-32]\n\n");
|
||||
fprintf (st, "Modem control must be set larger then the number of lines\n");
|
||||
fprintf (st, "The ATTACH command specifies the port to be used:\n\n");
|
||||
tmxr_attach_help (st, dptr, uptr, flag, cptr);
|
||||
fprintf (st, "The additional terminals can be set to one of four modes: UC, 7P, 7B, or 8B.\n\n");
|
||||
fprintf (st, " mode input characters output characters\n\n");
|
||||
fprintf (st, " UC lower case converted lower case converted to upper case,\n");
|
||||
fprintf (st, " to upper case, high-order bit cleared,\n");
|
||||
fprintf (st, " high-order bit cleared non-printing characters suppressed\n");
|
||||
fprintf (st, " 7P high-order bit cleared high-order bit cleared,\n");
|
||||
fprintf (st, " non-printing characters suppressed\n");
|
||||
fprintf (st, " 7B high-order bit cleared high-order bit cleared\n");
|
||||
fprintf (st, " 8B no changes no changes\n\n");
|
||||
fprintf (st, "The default mode is 7P.\n");
|
||||
fprintf (st, "Finally, each line supports output logging. The SET DCn LOG command enables\n");
|
||||
fprintf (st, "logging on a line:\n\n");
|
||||
fprintf (st, " sim> SET DCn LOG=filename log output of line n to filename\n\n");
|
||||
fprintf (st, "The SET DCn NOLOG command disables logging and closes the open log file,\n");
|
||||
fprintf (st, "if any.\n\n");
|
||||
fprintf (st, "Once DC is attached and the simulator is running, the terminals listen for\n");
|
||||
fprintf (st, "connections on the specified port. They assume that the incoming connections\n");
|
||||
fprintf (st, "are Telnet connections. The connections remain open until disconnected either\n");
|
||||
fprintf (st, "by the Telnet client, a SET DC DISCONNECT command, or a DETACH DC command.\n\n");
|
||||
fprintf (st, "Other special commands:\n\n");
|
||||
fprintf (st, " sim> SHOW DC CONNECTIONS show current connections\n");
|
||||
fprintf (st, " sim> SHOW DC STATISTICS show statistics for active connections\n");
|
||||
fprintf (st, " sim> SET DCn DISCONNECT disconnects the specified line.\n");
|
||||
fprint_reg_help (st, &dz_dev);
|
||||
fprintf (st, "\nThe additional terminals do not support save and restore. All open connections\n");
|
||||
fprintf (st, "are lost when the simulator shuts down or DC is detached.\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
const char *dz_description (DEVICE *dptr)
|
||||
{
|
||||
return "DZ11 asynchronous line interface";
|
||||
}
|
||||
|
||||
#endif
|
||||
294
PDP10/ks10_rp.c
294
PDP10/ks10_rp.c
@@ -75,10 +75,10 @@
|
||||
#define CS1_RDY 0000200 /* Drive ready */
|
||||
#define CS1_UBA 0001400 /* High order UBA bits */
|
||||
#define CS1_PSEL 0002000 /* */
|
||||
#define CS1_DVA 0004000 /* drive avail NI */
|
||||
#define CS1_DVA 0004000 /* drive avail */
|
||||
#define CS1_MCPE 0020000 /* */
|
||||
#define CS1_TRE 0040000 /* */
|
||||
#define CS1_SC 0100000 /* */
|
||||
#define CS1_TRE 0040000 /* Set if CS2 0177400 */
|
||||
#define CS1_SC 0100000 /* Set if TRE or ATTN */
|
||||
|
||||
|
||||
/* RPWC - 176702 - word count */
|
||||
@@ -116,10 +116,15 @@
|
||||
#define CS2_WCE 0040000 /* write check err */
|
||||
#define CS2_DLT 0100000 /* data late NI */
|
||||
|
||||
/* u3 low */
|
||||
/* RPDS - 176712 - drive status */
|
||||
#define STATUS us9
|
||||
|
||||
#define DS_OFF 0000001 /* offset mode */
|
||||
#define DS_DF5 0000001 /* Drive forward 5in/sec */
|
||||
#define DS_DF20 0000002 /* Drive forward 20in/sec */
|
||||
#define DS_DIGB 0000004 /* Drive inner gaurd band */
|
||||
#define DS_GRV 0000010 /* Go reverse read */
|
||||
#define DS_DL64 0000020 /* Difference less 64 */
|
||||
#define DS_DE1 0000040 /* Difference equal 1 */
|
||||
#define DS_VV 0000100 /* volume valid */
|
||||
#define DS_DRY 0000200 /* drive ready */
|
||||
#define DS_DPR 0000400 /* drive present */
|
||||
@@ -130,7 +135,6 @@
|
||||
#define DS_PIP 0020000 /* pos in progress */
|
||||
#define DS_ERR 0040000 /* error */
|
||||
#define DS_ATA 0100000 /* attention active */
|
||||
#define DS_MBZ 0000076
|
||||
|
||||
/* u3 high */
|
||||
/* RPER1 - 176714 - error status 1 */
|
||||
@@ -189,11 +193,11 @@
|
||||
/* u5 low */
|
||||
/* RPCC - 176736 - current cylinder */
|
||||
|
||||
/* RPER2 - 176740 - error status 2 - drive unsafe conditions */
|
||||
/* RPER2 - 176740 - error status 2 - drive unsafe conditions - unimplemented */
|
||||
/* RPER3 - 176742 - error status 3 - more unsafe conditions - unimplemented */
|
||||
#define ERR2 us9
|
||||
//#define ERR2 us9
|
||||
/* us9 */
|
||||
#define ERR3 us10
|
||||
//#define ERR3 us10
|
||||
|
||||
|
||||
#define DATAPTR u6
|
||||
@@ -272,8 +276,7 @@ uint64 rp_buf[RP_NUMWD];
|
||||
uint16 rp_wc;
|
||||
uint16 rp_db;
|
||||
t_addr rp_ba;
|
||||
uint8 rp_attn;
|
||||
int rp_unit;
|
||||
uint16 rp_cs2;
|
||||
uint8 rp_ie;
|
||||
|
||||
|
||||
@@ -321,8 +324,7 @@ MTAB rp_mod[] = {
|
||||
REG rpa_reg[] = {
|
||||
{ORDATA(WC, rp_wc, 16)},
|
||||
{ORDATA(BA, rp_ba, 18)},
|
||||
{ORDATA(ATTN, rp_attn, 8)},
|
||||
{ORDATA(UNIT, rp_unit, 3)},
|
||||
{ORDATA(UNIT, rp_cs2, 16)},
|
||||
{ORDATA(IE, rp_ie, 8), REG_HRO},
|
||||
{BRDATA(BUFF, rp_buf, 16, 64, RP_NUMWD), REG_HRO},
|
||||
{0}
|
||||
@@ -339,6 +341,7 @@ DEVICE rpa_dev = {
|
||||
int
|
||||
rp_write(t_addr addr, uint16 data, int32 access) {
|
||||
int i;
|
||||
int rp_unit = rp_cs2 & 07;
|
||||
UNIT *uptr = &rpa_unit[rp_unit];
|
||||
int dtype = GET_DTYPE(uptr->flags);
|
||||
|
||||
@@ -352,29 +355,26 @@ rp_write(t_addr addr, uint16 data, int32 access) {
|
||||
return 0;
|
||||
|
||||
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o Status=%06o\n", rp_unit, uptr->CMD);
|
||||
/* Set if drive not writable */
|
||||
if (uptr->flags & UNIT_WLK)
|
||||
uptr->CMD |= DS_WRL;
|
||||
/* If drive not ready don't do anything */
|
||||
if ((uptr->CMD & DS_DRY) == 0) {
|
||||
uptr->CMD |= (ER1_RMR << 16)|DS_ERR;
|
||||
if ((rp_ie & CS1_GO) != 0|| (uptr->STATUS & DS_PIP) != 0) {
|
||||
uptr->CMD |= (ER1_RMR << 16);
|
||||
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o not ready\n", rp_unit);
|
||||
return 0;
|
||||
}
|
||||
rp_ba = ((data << 7) & 0600000) | (rp_ba & 0177777);
|
||||
rp_ie = data & CS1_IE;
|
||||
rp_ie = data & (CS1_IE|CS1_GO);
|
||||
/* Check if GO bit set */
|
||||
uptr->CMD = data & 076;
|
||||
if ((data & 1) == 0) {
|
||||
uptr->CMD &= ~076;
|
||||
uptr->CMD |= data & 076;
|
||||
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o no go\n", rp_unit);
|
||||
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o no go %06o\n", rp_unit, data);
|
||||
return 0; /* No, nop */
|
||||
}
|
||||
if ((uptr->flags & UNIT_ATT) == 0) {
|
||||
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o unattached %06o\n", rp_unit, data);
|
||||
return 0; /* No, nop */
|
||||
}
|
||||
uptr->CMD &= DS_ATA|DS_VV|DS_DPR|DS_MOL|DS_WRL;
|
||||
uptr->CMD |= data & 076;
|
||||
switch (GET_FNC(data)) {
|
||||
case FNC_NOP:
|
||||
uptr->CMD |= DS_DRY;
|
||||
break;
|
||||
|
||||
case FNC_RECAL: /* recalibrate */
|
||||
@@ -384,7 +384,6 @@ rp_write(t_addr addr, uint16 data, int32 access) {
|
||||
case FNC_RETURN: /* return to center */
|
||||
case FNC_OFFSET: /* offset */
|
||||
case FNC_UNLOAD: /* unload */
|
||||
uptr->CMD &= ~DS_OFF;
|
||||
/* Fall through */
|
||||
|
||||
case FNC_SEARCH: /* search */
|
||||
@@ -394,56 +393,52 @@ rp_write(t_addr addr, uint16 data, int32 access) {
|
||||
case FNC_WRITEH: /* write w/ headers */
|
||||
case FNC_READ: /* read */
|
||||
case FNC_READH: /* read w/ headers */
|
||||
uptr->CMD |= DS_PIP;
|
||||
uptr->STATUS |= DS_PIP;
|
||||
|
||||
if (GET_CY(uptr->DA) >= rp_drv_tab[dtype].cyl ||
|
||||
GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect ||
|
||||
GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) {
|
||||
rp_attn &= ~(1<<rp_unit);
|
||||
uptr->CMD |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA;
|
||||
uptr->CMD &= ~DS_PIP;
|
||||
uptr->CMD |= (ER1_IAE << 16);
|
||||
uptr->STATUS |= DS_ATA;
|
||||
uptr->STATUS &= ~DS_PIP;
|
||||
break;
|
||||
}
|
||||
|
||||
uptr->CMD |= CS1_GO;
|
||||
rp_ie |= CS1_GO;
|
||||
CLR_BUF(uptr);
|
||||
uptr->DATAPTR = 0;
|
||||
break;
|
||||
|
||||
|
||||
case FNC_DCLR: /* drive clear */
|
||||
uptr->CMD |= DS_DRY;
|
||||
uptr->CMD &= ~(DS_ATA|CS1_GO);
|
||||
uptr->STATUS &= ~(DS_ATA);
|
||||
rp_ie &= ~(CS1_GO);
|
||||
uptr->DA &= 003400177777;
|
||||
uptr->CCYL &= 0177777;
|
||||
uptr->ERR2 = 0;
|
||||
uptr->ERR3 = 0;
|
||||
// uptr->ERR2 = 0;
|
||||
// uptr->ERR3 = 0;
|
||||
rp_ie = 0;
|
||||
rp_attn &= ~(1<<rp_unit);
|
||||
break;
|
||||
|
||||
case FNC_PRESET: /* read-in preset */
|
||||
uptr->DA = 0;
|
||||
uptr->CCYL &= 0177777;
|
||||
uptr->CMD &= ~DS_OFF;
|
||||
/* Fall through */
|
||||
|
||||
case FNC_RELEASE: /* port release */
|
||||
case FNC_PACK: /* pack acknowledge */
|
||||
if ((uptr->flags & UNIT_ATT) != 0)
|
||||
uptr->CMD |= DS_VV;
|
||||
uptr->CMD |= DS_DRY;
|
||||
break;
|
||||
|
||||
default:
|
||||
uptr->CMD |= DS_DRY|DS_ERR|DS_ATA;
|
||||
uptr->STATUS |= DS_ATA;
|
||||
uptr->CMD |= (ER1_ILF << 16);
|
||||
rp_attn |= (1<<rp_unit);
|
||||
}
|
||||
if (uptr->CMD & CS1_GO)
|
||||
if (GET_FNC(data) >= FNC_XFER)
|
||||
uptr->STATUS = rp_cs2 = 0;
|
||||
if (rp_ie & CS1_GO)
|
||||
sim_activate(uptr, 1000);
|
||||
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o AStatus=%06o\n", rp_unit, uptr->CMD);
|
||||
return 0;
|
||||
break;
|
||||
case 002: /* RPWC - 176702 - word count */
|
||||
if (access == BYTE) {
|
||||
if (addr & 1)
|
||||
@@ -476,12 +471,13 @@ rp_write(t_addr addr, uint16 data, int32 access) {
|
||||
case 010: /* RPCS2 - 176710 - Control and Status register 2 */
|
||||
if (access == BYTE) {
|
||||
if (addr & 1)
|
||||
data = data | rp_unit;
|
||||
data = data | rp_cs2;
|
||||
}
|
||||
rp_unit = data & 07;
|
||||
rp_cs2 = (CS2_UAI|CS2_PAT|07) & data;
|
||||
if (data & 040) {
|
||||
rp_reset(&rpa_dev);
|
||||
}
|
||||
rp_cs2 |= CS2_IR;
|
||||
break;
|
||||
|
||||
case 012: /* RPDS - 176712 - drive status */
|
||||
@@ -496,17 +492,17 @@ rp_write(t_addr addr, uint16 data, int32 access) {
|
||||
}
|
||||
uptr->CMD &= 0177777;
|
||||
uptr->CMD |= data << 16;
|
||||
uptr->CMD &= ~DS_ERR;
|
||||
if ((((uptr->CMD >> 16) & 0177777) | uptr->ERR2 | uptr->ERR3) != 0)
|
||||
uptr->CMD |= DS_ERR;
|
||||
// uptr->CMD &= ~DS_ERR;
|
||||
// if ((((uptr->CMD >> 16) & 0177777) | uptr->ERR2 | uptr->ERR3) != 0)
|
||||
// if ((((uptr->CMD >> 16) & 0177777)) != 0)
|
||||
// uptr->CMD |= DS_ERR;
|
||||
break;
|
||||
|
||||
case 016: /* RPAS - 176716 - attention summary */
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (data & (1<<i)) {
|
||||
UNIT *u = &rpa_unit[i];
|
||||
u->CMD &= ~DS_ATA;
|
||||
rp_attn &= ~(1<<i);
|
||||
u->STATUS &= ~DS_ATA;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -517,6 +513,8 @@ rp_write(t_addr addr, uint16 data, int32 access) {
|
||||
break;
|
||||
case 022: /* RPDB - 176722 - data buffer */
|
||||
rp_db = data;
|
||||
rp_cs2 |= CS2_OR;
|
||||
rp_cs2 &= ~CS2_IR;
|
||||
break;
|
||||
/* RPCS2 - 176710 - control/status 2 */
|
||||
case 032: /* RPOF - 176732 - offset register */
|
||||
@@ -534,16 +532,18 @@ rp_write(t_addr addr, uint16 data, int32 access) {
|
||||
uptr->DA |= data;
|
||||
break;
|
||||
case 040: /* RPER2 - 176740 - error status 2 - drive unsafe conditions */
|
||||
uptr->ERR2 = data;
|
||||
uptr->CMD &= ~DS_ERR;
|
||||
if ((((uptr->CMD >> 16) & 0177777) | uptr->ERR2 | uptr->ERR3) != 0)
|
||||
uptr->CMD |= DS_ERR;
|
||||
// uptr->ERR2 = data;
|
||||
// uptr->CMD &= ~DS_ERR;
|
||||
// if ((((uptr->CMD >> 16) & 0177777) | uptr->ERR2 | uptr->ERR3) != 0)
|
||||
// if ((((uptr->CMD >> 16) & 0177777)) != 0)
|
||||
// uptr->CMD |= DS_ERR;
|
||||
break;
|
||||
case 042: /* RPER3 - 176742 - error status 3 - more unsafe conditions */
|
||||
uptr->ERR3 = data;
|
||||
uptr->CMD &= ~DS_ERR;
|
||||
if ((((uptr->CMD >> 16) & 0177777) | uptr->ERR2 | uptr->ERR3) != 0)
|
||||
uptr->CMD |= DS_ERR;
|
||||
// uptr->ERR3 = data;
|
||||
// uptr->CMD &= ~DS_ERR;
|
||||
// if ((((uptr->CMD >> 16) & 0177777) | uptr->ERR2 | uptr->ERR3) != 0)
|
||||
// if ((((uptr->CMD >> 16) & 0177777)) != 0)
|
||||
// uptr->CMD |= DS_ERR;
|
||||
break;
|
||||
case 030: /* RPSN - 176730 - serial number */
|
||||
case 036: /* RPCC - 176736 - current cylinder */
|
||||
@@ -558,6 +558,7 @@ rp_write(t_addr addr, uint16 data, int32 access) {
|
||||
|
||||
int
|
||||
rp_read(t_addr addr, uint16 *data, int32 access) {
|
||||
int rp_unit = rp_cs2 & 07;
|
||||
UNIT *uptr = &rpa_unit[rp_unit];
|
||||
uint16 temp = 0;
|
||||
int i;
|
||||
@@ -565,15 +566,16 @@ rp_read(t_addr addr, uint16 *data, int32 access) {
|
||||
/* RPDB - 176722 - data buffer */
|
||||
switch(addr & 076) {
|
||||
case 000: /* RPC - 176700 - control */
|
||||
temp = uptr->CMD & (DS_DRY|076);
|
||||
temp = uptr->CMD & 077;
|
||||
temp |= (uint16)rp_ie;
|
||||
temp |= (rp_ba & 0600000) >> 7;
|
||||
if (uptr->flags & UNIT_ATT)
|
||||
if (uptr->flags & UNIT_ATT) {
|
||||
temp |= CS1_DVA;
|
||||
if (uptr->CMD & CS1_GO)
|
||||
temp |= CS1_GO;
|
||||
else if (GET_FNC(uptr->CMD) < FNC_XFER)
|
||||
temp |= CS1_RDY;
|
||||
if (rp_ie & CS1_GO)
|
||||
temp |= CS1_GO;
|
||||
if ((rp_ie & CS1_GO) == 0 && (uptr->STATUS & DS_PIP) == 0)
|
||||
temp |= CS1_RDY;
|
||||
}
|
||||
break;
|
||||
case 002: /* RPWC - 176702 - word count */
|
||||
temp = rp_wc;
|
||||
@@ -585,14 +587,22 @@ rp_read(t_addr addr, uint16 *data, int32 access) {
|
||||
temp = (uptr->DA >> 16) & 0177777;
|
||||
break;
|
||||
case 010: /* RPCS2 - 176710 - control/status 2 */
|
||||
temp = rp_unit;
|
||||
temp = rp_cs2;
|
||||
if (uptr->flags & UNIT_DIS)
|
||||
temp |= CS2_NED;
|
||||
break;
|
||||
case 012: /* RPDS - 176712 - drive status */
|
||||
temp = uptr->CMD & 0177600;
|
||||
temp = uptr->STATUS;
|
||||
if (((uptr->CMD >> 16) & 0177777) != 0)
|
||||
temp |= DS_ERR;
|
||||
if ((uptr->flags & UNIT_DIS) == 0)
|
||||
temp |= DS_DPR;
|
||||
if ((uptr->flags & UNIT_ATT) != 0)
|
||||
temp |= DS_VV;
|
||||
temp |= DS_VV|DS_MOL;
|
||||
if ((uptr->flags & UNIT_WLK) != 0)
|
||||
temp |= DS_WRL;
|
||||
if ((rp_ie & CS1_GO) == 0 && (uptr->STATUS & DS_PIP) == 0)
|
||||
temp |= DS_DRY;
|
||||
break;
|
||||
case 014: /* RPER1 - 176714 - error status 1 */
|
||||
temp = (uptr->CMD >> 16) & 0177777;
|
||||
@@ -600,7 +610,7 @@ rp_read(t_addr addr, uint16 *data, int32 access) {
|
||||
case 016: /* RPAS - 176716 - attention summary */
|
||||
for (i = 0; i < 8; i++) {
|
||||
UNIT *u = &rpa_unit[i];
|
||||
if (u->CMD & DS_ATA) {
|
||||
if (u->STATUS & DS_ATA) {
|
||||
temp |= 1 << i;
|
||||
}
|
||||
}
|
||||
@@ -612,6 +622,8 @@ rp_read(t_addr addr, uint16 *data, int32 access) {
|
||||
break;
|
||||
case 022: /* RPDB - 176722 - data buffer */
|
||||
temp = rp_db;
|
||||
rp_cs2 &= ~CS2_OR;
|
||||
rp_cs2 |= CS2_IR;
|
||||
break;
|
||||
case 024: /* RPMR - 176724 - maintenace register */
|
||||
break;
|
||||
@@ -631,18 +643,18 @@ rp_read(t_addr addr, uint16 *data, int32 access) {
|
||||
temp = uptr->CCYL & 0177777;
|
||||
break;
|
||||
case 040: /* RPER2 - 176740 - error status 2 - drive unsafe conditions */
|
||||
temp = uptr->ERR2;
|
||||
// temp = uptr->ERR2;
|
||||
break;
|
||||
case 042: /* RPER3 - 176742 - error status 3 - more unsafe conditions */
|
||||
temp = uptr->ERR3;
|
||||
// temp = uptr->ERR3;
|
||||
break;
|
||||
case 044: /* RPEC1 - 176744 - ECC status 1 - unimplemented */
|
||||
case 046: /* RPEC2 - 176746 - ECC status 2 - unimplemented */
|
||||
break;
|
||||
}
|
||||
*data = temp;
|
||||
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o read %02o %06o\n", rp_unit,
|
||||
addr & 076, temp);
|
||||
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o read %02o %06o %06o\n", rp_unit,
|
||||
addr & 076, temp, PC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -650,7 +662,6 @@ rp_read(t_addr addr, uint16 *data, int32 access) {
|
||||
/* Set the attention flag for a unit */
|
||||
void rp_setattn(int unit)
|
||||
{
|
||||
rp_attn |= 1<<unit;
|
||||
if (rp_ie)
|
||||
uba_set_irq(&rpa_dib);
|
||||
}
|
||||
@@ -671,7 +682,9 @@ t_stat rp_svc (UNIT *uptr)
|
||||
dptr = uptr->dptr;
|
||||
unit = uptr - dptr->units;
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
||||
uptr->CMD |= (ER1_UNS << 16) | DS_ATA|DS_ERR; /* set drive error */
|
||||
uptr->CMD |= (ER1_UNS << 16); /* set drive error */
|
||||
uptr->STATUS |= DS_ATA;
|
||||
rp_ie &= ~(CS1_GO);
|
||||
if (GET_FNC(uptr->CMD) >= FNC_XFER) { /* xfr? set done */
|
||||
if (rp_ie)
|
||||
uba_set_irq(&rpa_dib);
|
||||
@@ -682,11 +695,13 @@ t_stat rp_svc (UNIT *uptr)
|
||||
}
|
||||
|
||||
/* Check if seeking */
|
||||
if (uptr->CMD & DS_PIP) {
|
||||
if (uptr->STATUS & DS_PIP) {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o seek %d %d\n", dptr->name, unit, cyl, uptr->CCYL);
|
||||
if (cyl >= rp_drv_tab[dtype].cyl) {
|
||||
uptr->CMD &= ~DS_PIP;
|
||||
uptr->CMD |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA;
|
||||
uptr->STATUS &= ~DS_PIP;
|
||||
uptr->STATUS |= DS_ATA;
|
||||
uptr->CMD |= (ER1_IAE << 16);
|
||||
rp_ie &= ~CS1_GO;
|
||||
rp_setattn(unit);
|
||||
}
|
||||
diff = cyl - (uptr->CCYL & 01777);
|
||||
@@ -715,7 +730,7 @@ t_stat rp_svc (UNIT *uptr)
|
||||
}
|
||||
return SCPE_OK;
|
||||
} else {
|
||||
uptr->CMD &= ~DS_PIP;
|
||||
uptr->STATUS &= ~DS_PIP;
|
||||
uptr->DATAPTR = 0;
|
||||
}
|
||||
}
|
||||
@@ -730,7 +745,6 @@ t_stat rp_svc (UNIT *uptr)
|
||||
rp_detach(uptr);
|
||||
/* Fall through */
|
||||
case FNC_OFFSET: /* offset */
|
||||
uptr->CMD |= DS_OFF;
|
||||
/* Fall through */
|
||||
case FNC_RETURN: /* return to center */
|
||||
case FNC_PRESET: /* read-in preset */
|
||||
@@ -738,9 +752,9 @@ t_stat rp_svc (UNIT *uptr)
|
||||
case FNC_SEEK: /* seek */
|
||||
if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect ||
|
||||
GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf)
|
||||
uptr->CMD |= (ER1_IAE << 16)|DS_ERR;
|
||||
uptr->CMD |= DS_DRY|DS_ATA;
|
||||
uptr->CMD &= ~CS1_GO;
|
||||
uptr->CMD |= (ER1_IAE << 16);
|
||||
uptr->STATUS |= DS_ATA;
|
||||
rp_ie &= ~CS1_GO;
|
||||
rp_setattn(unit);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o seekdone %d %o\n", dptr->name, unit, cyl, uptr->CMD);
|
||||
break;
|
||||
@@ -748,9 +762,9 @@ t_stat rp_svc (UNIT *uptr)
|
||||
case FNC_SEARCH: /* search */
|
||||
if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect ||
|
||||
GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf)
|
||||
uptr->CMD |= (ER1_IAE << 16)|DS_ERR;
|
||||
uptr->CMD |= DS_DRY|DS_ATA;
|
||||
uptr->CMD &= ~CS1_GO;
|
||||
uptr->CMD |= (ER1_IAE << 16);
|
||||
uptr->STATUS |= DS_ATA;
|
||||
rp_ie &= ~CS1_GO;
|
||||
rp_setattn(unit);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o searchdone %d %o\n", dptr->name, unit, cyl, uptr->CMD);
|
||||
break;
|
||||
@@ -758,15 +772,12 @@ t_stat rp_svc (UNIT *uptr)
|
||||
case FNC_READ: /* read */
|
||||
case FNC_READH: /* read w/ headers */
|
||||
case FNC_WCHK: /* write check */
|
||||
if (uptr->CMD & DS_ERR) {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read error\n", dptr->name, unit);
|
||||
goto rd_end;
|
||||
}
|
||||
|
||||
if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect ||
|
||||
GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) {
|
||||
uptr->CMD |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA;
|
||||
uptr->CMD &= ~CS1_GO;
|
||||
uptr->CMD |= (ER1_IAE << 16);
|
||||
uptr->STATUS |= DS_ATA;
|
||||
rp_ie &= ~CS1_GO;
|
||||
if (uptr->CMD & CS1_IE)
|
||||
uba_set_irq(&rpa_dib);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o readx done\n", dptr->name, unit);
|
||||
@@ -787,22 +798,24 @@ t_stat rp_svc (UNIT *uptr)
|
||||
dptr->name, unit, buf, rp_ba, rp_wc);
|
||||
if ((sts = uba_write_npr(rp_ba, rpa_dib.uba_ctl, buf)) == 0)
|
||||
goto rd_end;
|
||||
rp_ba += 4;
|
||||
if ((rp_cs2 & CS2_UAI) == 0)
|
||||
rp_ba += 4;
|
||||
rp_wc = (rp_wc + 2) & 0177777;
|
||||
if (rp_wc == 0) {
|
||||
sts = 0;
|
||||
goto rd_end;
|
||||
sts = 0;
|
||||
goto rd_end;
|
||||
}
|
||||
buf = (((uint64)(unit + 1)) << 18) | (uint64)(unit);
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o read word h2 %012llo %09o %06o\n",
|
||||
dptr->name, unit, buf, rp_ba, rp_wc);
|
||||
if ((sts = uba_write_npr(rp_ba, rpa_dib.uba_ctl, buf)) == 0)
|
||||
goto rd_end;
|
||||
rp_ba += 4;
|
||||
if ((rp_cs2 & CS2_UAI) == 0)
|
||||
rp_ba += 4;
|
||||
rp_wc = (rp_wc + 2) & 0177777;
|
||||
if (rp_wc == 0) {
|
||||
sts = 0;
|
||||
goto rd_end;
|
||||
sts = 0;
|
||||
goto rd_end;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -811,11 +824,12 @@ t_stat rp_svc (UNIT *uptr)
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o read word %d %012llo %09o %06o\n",
|
||||
dptr->name, unit, uptr->DATAPTR, buf, rp_ba, rp_wc);
|
||||
sts = uba_write_npr(rp_ba, rpa_dib.uba_ctl, buf);
|
||||
rp_ba += 4;
|
||||
if ((rp_cs2 & CS2_UAI) == 0)
|
||||
rp_ba += 4;
|
||||
rp_wc = (rp_wc + 2) & 0177777;
|
||||
if (rp_wc == 0) {
|
||||
sts = 0;
|
||||
goto rd_end;
|
||||
sts = 0;
|
||||
goto rd_end;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -830,7 +844,7 @@ t_stat rp_svc (UNIT *uptr)
|
||||
if (GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) {
|
||||
uptr->DA &= (DC_M_CY << DC_V_CY);
|
||||
uptr->DA += 1 << DC_V_CY;
|
||||
uptr->CMD |= DS_PIP;
|
||||
uptr->STATUS |= DS_PIP;
|
||||
}
|
||||
}
|
||||
sim_activate(uptr, 10);
|
||||
@@ -838,23 +852,18 @@ t_stat rp_svc (UNIT *uptr)
|
||||
}
|
||||
rd_end:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read done\n", dptr->name, unit);
|
||||
uptr->CMD |= DS_DRY;
|
||||
uptr->CMD &= ~CS1_GO;
|
||||
rp_ie &= ~CS1_GO;
|
||||
if (rp_ie)
|
||||
uba_set_irq(&rpa_dib);
|
||||
return SCPE_OK;
|
||||
|
||||
case FNC_WRITE: /* write */
|
||||
case FNC_WRITEH: /* write w/ headers */
|
||||
if (uptr->CMD & DS_ERR) {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read error\n", dptr->name, unit);
|
||||
goto wr_end;
|
||||
}
|
||||
|
||||
if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect ||
|
||||
GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) {
|
||||
uptr->CMD |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA;
|
||||
uptr->CMD &= ~CS1_GO;
|
||||
uptr->CMD |= (ER1_IAE << 16);
|
||||
uptr->STATUS |= DS_ATA;
|
||||
rp_ie &= ~CS1_GO;
|
||||
uba_set_irq(&rpa_dib);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o writex done\n", dptr->name, unit);
|
||||
return SCPE_OK;
|
||||
@@ -863,22 +872,24 @@ rd_end:
|
||||
/* On Write headers, transfer 2 words to start */
|
||||
if (GET_FNC(uptr->CMD) == FNC_WRITEH) {
|
||||
if (uba_read_npr(rp_ba, rpa_dib.uba_ctl, &buf) == 0)
|
||||
goto wr_end;
|
||||
rp_ba += 4;
|
||||
goto wr_done;
|
||||
if ((rp_cs2 & CS2_UAI) == 0)
|
||||
rp_ba += 4;
|
||||
rp_wc = (rp_wc + 2) & 0177777;
|
||||
if (rp_wc == 0) {
|
||||
sts = 0;
|
||||
goto wr_end;
|
||||
sts = 0;
|
||||
goto wr_done;
|
||||
}
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o write word h1 %012llo %07o\n",
|
||||
dptr->name, unit, buf, rp_wc);
|
||||
if (uba_read_npr(rp_ba, rpa_dib.uba_ctl, &buf) == 0)
|
||||
goto wr_end;
|
||||
rp_ba += 4;
|
||||
goto wr_done;
|
||||
if ((rp_cs2 & CS2_UAI) == 0)
|
||||
rp_ba += 4;
|
||||
rp_wc = (rp_wc + 2) & 0177777;
|
||||
if (rp_wc == 0) {
|
||||
sts = 0;
|
||||
goto wr_end;
|
||||
sts = 0;
|
||||
goto wr_done;
|
||||
}
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o write word h2 %012llo %07o\n",
|
||||
dptr->name, unit, buf, rp_wc);
|
||||
@@ -886,23 +897,24 @@ rd_end:
|
||||
uptr->DATAPTR = 0;
|
||||
uptr->hwmark = 0;
|
||||
buf = 0;
|
||||
while (uptr->DATAPTR < RP_NUMWD &&
|
||||
(sts = uba_read_npr(rp_ba, rpa_dib.uba_ctl, &buf)) != 0) {
|
||||
rp_buf[uptr->DATAPTR++] = buf;
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o write word %d %012llo %07o %06o\n",
|
||||
while (uptr->DATAPTR < RP_NUMWD) {
|
||||
if ((sts = uba_read_npr(rp_ba, rpa_dib.uba_ctl, &buf)) == 0)
|
||||
break;
|
||||
rp_buf[uptr->DATAPTR++] = buf;
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o write word %d %012llo %07o %06o\n",
|
||||
dptr->name, unit, uptr->DATAPTR, buf, rp_ba, rp_wc);
|
||||
rp_ba += 4;
|
||||
if ((rp_cs2 & CS2_UAI) == 0)
|
||||
rp_ba += 4;
|
||||
rp_wc = (rp_wc + 2) & 0177777;
|
||||
if (rp_wc == 0) {
|
||||
sts = 0;
|
||||
goto wr_end;
|
||||
sts = 0;
|
||||
goto wr_done;
|
||||
}
|
||||
}
|
||||
rp_buf[uptr->DATAPTR++] = buf;
|
||||
wr_done:
|
||||
while (uptr->DATAPTR < RP_NUMWD) {
|
||||
rp_buf[uptr->DATAPTR++] = 0;
|
||||
}
|
||||
wr_done:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o write (%d,%d,%d)\n", dptr->name,
|
||||
unit, cyl, GET_SF(uptr->DA), GET_SC(uptr->DA));
|
||||
da = GET_DA(uptr->DA, dtype);
|
||||
@@ -916,17 +928,16 @@ wr_done:
|
||||
if (GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) {
|
||||
uptr->DA &= (DC_M_CY << DC_V_CY);
|
||||
uptr->DA += 1 << DC_V_CY;
|
||||
uptr->CMD |= DS_PIP;
|
||||
uptr->STATUS |= DS_PIP;
|
||||
}
|
||||
}
|
||||
|
||||
if (sts) {
|
||||
sim_activate(uptr, 10);
|
||||
} else {
|
||||
wr_end:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RP%o write done\n", unit);
|
||||
uptr->CMD |= DS_DRY;
|
||||
uptr->CMD &= ~CS1_GO;
|
||||
uptr->STATUS &= ~DS_PIP;
|
||||
rp_ie &= ~CS1_GO;
|
||||
if (rp_ie)
|
||||
uba_set_irq(&rpa_dib);
|
||||
}
|
||||
@@ -951,18 +962,17 @@ rp_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
|
||||
|
||||
t_stat
|
||||
rp_reset(DEVICE * rptr)
|
||||
rp_reset(DEVICE * dptr)
|
||||
{
|
||||
int i;
|
||||
rp_attn = 0;
|
||||
rp_ba = 0;
|
||||
rp_wc = 0177777;
|
||||
rp_cs2 = CS2_IR;
|
||||
for (i = 0; i < 8; i++) {
|
||||
UNIT *u = &rpa_unit[i];
|
||||
u->CMD &= DS_VV|DS_DRY|DS_DPR|DS_MOL;
|
||||
rp_attn &= ~(1<<i);
|
||||
u->ERR2 = u->ERR3 = 0;
|
||||
u->STATUS = 0;
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RP reset done\n");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -1055,13 +1065,13 @@ t_stat rp_attach (UNIT *uptr, CONST char *cptr)
|
||||
if (rptr == 0)
|
||||
return SCPE_OK;
|
||||
dib = (DIB *) rptr->ctxt;
|
||||
if (uptr->flags & UNIT_WLK)
|
||||
uptr->CMD |= DS_WRL;
|
||||
// if (uptr->flags & UNIT_WLK)
|
||||
// uptr->CMD |= DS_WRL;
|
||||
if (sim_switches & SIM_SW_REST)
|
||||
return SCPE_OK;
|
||||
uptr->DA = 0;
|
||||
uptr->CMD &= ~DS_VV;
|
||||
uptr->CMD |= DS_DPR|DS_MOL|DS_DRY;
|
||||
// uptr->CMD &= ~DS_VV;
|
||||
// uptr->CMD |= DS_DPR|DS_MOL|DS_DRY;
|
||||
rp_setattn(uptr - &rpa_unit[0]);
|
||||
return SCPE_OK;
|
||||
}
|
||||
@@ -1074,7 +1084,7 @@ t_stat rp_detach (UNIT *uptr)
|
||||
return SCPE_OK;
|
||||
if (sim_is_active (uptr)) /* unit active? */
|
||||
sim_cancel (uptr); /* cancel operation */
|
||||
uptr->CMD &= ~(DS_VV|DS_WRL|DS_DPR|DS_DRY);
|
||||
// uptr->CMD &= ~(DS_VV|DS_WRL|DS_DPR|DS_DRY);
|
||||
return disk_detach (uptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
#if (NUM_DEVS_TU > 0)
|
||||
|
||||
#define NUM_UNITS_TU 8
|
||||
#define NUM_UNITS_TU 4
|
||||
#define TU_NUMFR (64*1024)
|
||||
|
||||
#define BUF_EMPTY(u) (u->hwmark == 0xFFFFFFFF)
|
||||
@@ -215,10 +215,6 @@ UNIT tua_unit[] = {
|
||||
{ UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) },
|
||||
{ UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) },
|
||||
{ UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) },
|
||||
{ UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) },
|
||||
{ UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) },
|
||||
{ UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) },
|
||||
{ UDATA (&tu_srv, TU_UNIT+CNTRL_RH(0), 0) },
|
||||
};
|
||||
|
||||
DIB tua_dib = {0772440, 037, 0224, 6, 3, &tu_read, &tu_write, 0};
|
||||
@@ -279,11 +275,11 @@ tu_write(t_addr addr, uint16 data, int32 access) {
|
||||
|
||||
switch(addr & 036) {
|
||||
case 000: /* TUCS - control */
|
||||
sim_debug(DEBUG_DETAIL, &tua_dev, "TU %d Status=%06o\n", unit, uptr->STATUS);
|
||||
sim_debug(DEBUG_DETAIL, &tua_dev, "TU %d Status=%06o %08o\n", unit, uptr->STATUS,
|
||||
uptr->CMD);
|
||||
if (access == BYTE && addr & 1)
|
||||
return 0;
|
||||
|
||||
sim_debug(DEBUG_DETAIL, &tua_dev, "TU %d Status=%06o\n", unit, uptr->CMD);
|
||||
tu_ba = ((data << 7) & 0600000) | (tu_ba & 0177777);
|
||||
tu_ie = data & CS1_IE;
|
||||
uptr->CMD = data & 076;
|
||||
@@ -316,9 +312,9 @@ tu_write(t_addr addr, uint16 data, int32 access) {
|
||||
case FNC_UNLOAD: /* unload */
|
||||
case FNC_WCHKREV: /* write w/ headers */
|
||||
uptr->CMD |= CS1_GO;
|
||||
uptr->STATUS |= DS_PIP;
|
||||
uptr->STATUS = DS_PIP;
|
||||
tu_attn = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (i = 0; i < NUM_UNITS_TU; i++) {
|
||||
if (tua_unit[i].STATUS & DS_ATA)
|
||||
tu_attn = 1;
|
||||
}
|
||||
@@ -332,7 +328,7 @@ tu_write(t_addr addr, uint16 data, int32 access) {
|
||||
uptr->STATUS = 0;
|
||||
tu_ie = 0;
|
||||
tu_attn = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (i = 0; i < NUM_UNITS_TU; i++) {
|
||||
if (tua_unit[i].STATUS & DS_ATA)
|
||||
tu_attn = 1;
|
||||
}
|
||||
@@ -342,6 +338,8 @@ tu_write(t_addr addr, uint16 data, int32 access) {
|
||||
tu_attn = 1;
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, &tua_dev, "TU %o AStatus=%06o\n", unit, uptr->CMD);
|
||||
if (tu_attn && tu_ie)
|
||||
uba_set_irq(&tua_dib);
|
||||
}
|
||||
break;
|
||||
case 002: /* TUWC - 172442 - word count */
|
||||
@@ -379,7 +377,6 @@ tu_write(t_addr addr, uint16 data, int32 access) {
|
||||
tu_cs2 = data & (CS2_PAT|CS2_UAI|CS2_UNIT);
|
||||
break;
|
||||
|
||||
|
||||
case 012: /* 772452 status */
|
||||
break;
|
||||
|
||||
@@ -390,7 +387,7 @@ tu_write(t_addr addr, uint16 data, int32 access) {
|
||||
case 016: /* 772456 atten summary */
|
||||
tu_attn = 0;
|
||||
if (data & 1) {
|
||||
for (i = 0; i < 8; i++)
|
||||
for (i = 0; i < NUM_UNITS_TU; i++)
|
||||
tua_unit[i].STATUS &= ~DS_ATA;
|
||||
}
|
||||
break;
|
||||
@@ -410,16 +407,16 @@ tu_write(t_addr addr, uint16 data, int32 access) {
|
||||
tu_tcr = data;
|
||||
break;
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, &tua_dev, "TU %o write %02o %06o\n", tu_tcr & 7,
|
||||
addr & 036, data);
|
||||
sim_debug(DEBUG_DETAIL, &tua_dev, "TU %o write %02o %06o %06o %06o\n", unit,
|
||||
addr & 036, data, PC, tu_tcr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
tu_read(t_addr addr, uint16 *data, int32 access)
|
||||
{
|
||||
UNIT *uptr = &tua_unit[tu_tcr & 07];
|
||||
int tu_drive = tu_tcr & 07;
|
||||
UNIT *uptr = &tua_unit[tu_drive];
|
||||
uint16 temp = 0;
|
||||
int i;
|
||||
|
||||
@@ -427,7 +424,8 @@ tu_read(t_addr addr, uint16 *data, int32 access)
|
||||
switch(addr & 036) {
|
||||
case 000: /* 772440 control */
|
||||
temp = uptr->CMD & 076;
|
||||
temp |= CS1_DVA;
|
||||
if ((tu_cs2 & 07) == 0)
|
||||
temp |= CS1_DVA;
|
||||
temp |= (uint16)tu_ie;
|
||||
temp |= (tu_ba & 0600000) << 7;
|
||||
if (uptr->CMD & CS1_GO)
|
||||
@@ -455,25 +453,29 @@ tu_read(t_addr addr, uint16 *data, int32 access)
|
||||
break;
|
||||
case 012: /* 772452 - status */
|
||||
temp = uptr->STATUS & 0177777;
|
||||
temp |= DS_PES;
|
||||
temp |= ((tu_cs2 & 07) == 0) ? DS_DPR : 0;
|
||||
if (((uptr->STATUS >> 16) & 0177777) != 0)
|
||||
temp |= DS_ERR;
|
||||
if ((uptr->flags & UNIT_ATT) != 0) {
|
||||
if ((tu_cs2 & 07) == 0) {
|
||||
temp |= DS_MOL;
|
||||
if (uptr->flags & MTUF_WLK)
|
||||
temp |= DS_WRL;
|
||||
if ((uptr->CMD & CS1_GO) == 0 && (uptr->STATUS & DS_PIP) == 0)
|
||||
temp |= DS_DRY;
|
||||
if (sim_tape_bot(uptr))
|
||||
temp |= DS_BOT;
|
||||
if (sim_tape_eot(uptr))
|
||||
temp |= DS_EOT;
|
||||
if ((uptr->flags & UNIT_ATT) != 0) {
|
||||
if (uptr->flags & MTUF_WLK)
|
||||
temp |= DS_WRL;
|
||||
if ((uptr->CMD & CS1_GO) == 0 && (uptr->STATUS & DS_PIP) == 0)
|
||||
temp |= DS_DRY;
|
||||
if (sim_tape_bot(uptr))
|
||||
temp |= DS_BOT;
|
||||
if (sim_tape_eot(uptr))
|
||||
temp |= DS_EOT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 014: /* 772454 - error register 1 */
|
||||
temp = (uptr->STATUS >> 16) & 0177777;
|
||||
break;
|
||||
case 016: /* 772456 - atten summary */
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (i = 0; i < NUM_UNITS_TU; i++) {
|
||||
if (tua_unit[i].STATUS & DS_ATA)
|
||||
temp |= 1;
|
||||
}
|
||||
@@ -489,13 +491,15 @@ tu_read(t_addr addr, uint16 *data, int32 access)
|
||||
break;
|
||||
case 026: /* 772466 - drive type */
|
||||
if ((uptr->flags & UNIT_DIS) == 0)
|
||||
temp = 042054;
|
||||
temp = 0142054;
|
||||
break;
|
||||
case 030: /* 772470 - serial no */
|
||||
temp = 020 + (tu_drive + 1);
|
||||
if ((tu_cs2 & 07) == 0)
|
||||
temp = 020 + (tu_drive + 1);
|
||||
break;
|
||||
case 032: /* 772472 - tape control register */
|
||||
temp = tu_tcr;
|
||||
if ((tu_cs2 & 07) == 0)
|
||||
temp = tu_tcr;
|
||||
break;
|
||||
default:
|
||||
uptr->STATUS |= (ER1_ILR << 16);
|
||||
@@ -503,8 +507,10 @@ tu_read(t_addr addr, uint16 *data, int32 access)
|
||||
tu_attn = 1;
|
||||
}
|
||||
*data = temp;
|
||||
sim_debug(DEBUG_DETAIL, &tua_dev, "TU %o read %02o %06o\n", tu_tcr & 7,
|
||||
addr & 036, *data);
|
||||
sim_debug(DEBUG_DETAIL, &tua_dev, "TU %o read %02o %06o %06o %o\n", tu_tcr & 7,
|
||||
addr & 036, *data, PC, tu_cs2);
|
||||
if (tu_attn && tu_ie)
|
||||
uba_set_irq(&tua_dib);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -697,9 +703,8 @@ t_stat tu_srv(UNIT * uptr)
|
||||
tu_error(uptr, MTSE_OK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o read %012llo %d\n",
|
||||
dptr->name, unit, tu_cbuf, uptr->DATAPTR);
|
||||
tu_cbuf = 0;
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o read %012llo %d %06o\n",
|
||||
dptr->name, unit, tu_cbuf, uptr->DATAPTR, tu_tcr);
|
||||
tu_cbuf = 0;
|
||||
if ((tu_cs2 & CS2_UAI) == 0)
|
||||
tu_ba += 4;
|
||||
@@ -709,8 +714,8 @@ t_stat tu_srv(UNIT * uptr)
|
||||
}
|
||||
} else {
|
||||
if (uptr->CPOS != 0) {
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o readf %012llo\n",
|
||||
dptr->name, unit, tu_cbuf);
|
||||
sim_debug(DEBUG_DATA, dptr, "%s%o readf %012llo %d\n",
|
||||
dptr->name, unit, tu_cbuf, uptr->DATAPTR);
|
||||
uba_write_npr(tu_ba, tua_dib.uba_ctl, tu_cbuf);
|
||||
}
|
||||
rd_end:
|
||||
@@ -724,8 +729,7 @@ rd_end:
|
||||
case FNC_WRITE:
|
||||
if (BUF_EMPTY(uptr)) {
|
||||
if (tu_frame == 0) {
|
||||
uptr->STATUS |= ER1_NEF << 16;
|
||||
uptr->CMD |= DS_ATA;
|
||||
uptr->STATUS |= (ER1_NEF << 16) | DS_ATA;
|
||||
tu_error(uptr, MTSE_OK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
@@ -788,7 +792,7 @@ wr_end:
|
||||
break;
|
||||
|
||||
case FNC_WTM:
|
||||
uptr->CMD |= DS_ATA;
|
||||
uptr->STATUS |= DS_ATA;
|
||||
if ((uptr->flags & MTUF_WLK) != 0) {
|
||||
tu_error(uptr, MTSE_WRP);
|
||||
} else {
|
||||
@@ -860,7 +864,7 @@ tu_reset(DEVICE * dptr)
|
||||
tu_ba = tu_frame = tu_tcr = 0;
|
||||
tu_wc = 0177777;
|
||||
tu_cs2 = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (i = 0; i < NUM_UNITS_TU; i++) {
|
||||
tua_unit[i].STATUS = 0;
|
||||
}
|
||||
return SCPE_OK;
|
||||
@@ -917,7 +921,7 @@ tu_boot(int32 unit_num, DEVICE * dptr)
|
||||
addr ++;
|
||||
}
|
||||
M[036] = tua_dib.uba_addr | (tua_dib.uba_ctl << 18);
|
||||
M[037] = unit_num;
|
||||
M[037] = 0;
|
||||
M[040] = tu_tcr;
|
||||
PC = 01000;
|
||||
return SCPE_OK;
|
||||
|
||||
@@ -112,7 +112,7 @@ uba_write(t_addr addr, int ctl, uint64 data, int access)
|
||||
uint32 map = (uint32)(data & 03777) << 9;
|
||||
map |= (uint32)(data & 0740000) << 13;
|
||||
uba_map[ubm][addr & 077] = map;
|
||||
//fprintf(stderr, "Wr MAP %02o %012llo %06o\n\r", addr & 077, data, map);
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "Wr MAP %02o %012llo %06o\n\r", addr & 077, data, map);
|
||||
return 0;
|
||||
} else if ((addr & 077) == 0) {
|
||||
uba_status[ubm] &= (uint32)(074000 ^ data) | 0746000;
|
||||
@@ -160,8 +160,7 @@ uba_read_npr(t_addr addr, uint16 ctl, uint64 *data)
|
||||
return 0;
|
||||
if ((map & MAP_VALID) == 0)
|
||||
return 0;
|
||||
map |= (addr >> 2) & 0777;
|
||||
addr = (map & (PAGE_MASK|0777));
|
||||
addr = (map & PAGE_MASK) | (addr >> 2) & 0777;
|
||||
*data = M[addr];
|
||||
if (map & MAP_EN16)
|
||||
*data &= 0177777177777;
|
||||
@@ -178,11 +177,10 @@ t_addr oaddr = addr;
|
||||
return 0;
|
||||
if ((map & MAP_VALID) == 0)
|
||||
return 0;
|
||||
map |= (addr >> 2) & 0777;
|
||||
addr = (map & (PAGE_MASK|0777));
|
||||
addr = (map & PAGE_MASK) | (addr >> 2) & 0777;
|
||||
if (map & MAP_EN16)
|
||||
data &= 0177777177777;
|
||||
//fprintf(stderr, "Wr NPR %08o %08o %012llo\n\r", oaddr, addr, data);
|
||||
sim_debug(DEBUG_DATA, &cpu_dev, "Wr NPR %08o %08o %012llo\n\r", oaddr, addr, data);
|
||||
M[addr] = data;
|
||||
return 1;
|
||||
}
|
||||
@@ -219,6 +217,7 @@ uba_set_irq(DIB *dibp)
|
||||
|
||||
if (ubm < 0)
|
||||
return;
|
||||
/* Figure out what channel device should IRQ on */
|
||||
if (dibp->uba_br > 5) {
|
||||
pi = uba_status[ubm] >> 3;
|
||||
uba_status[ubm] |= UBST_INTH;
|
||||
@@ -226,8 +225,9 @@ uba_set_irq(DIB *dibp)
|
||||
pi = uba_status[ubm];
|
||||
uba_status[ubm] |= UBST_INTL;
|
||||
}
|
||||
dibp->uba_irq_pend |= 0200 >> pi;
|
||||
set_interrupt(dibp->uba_ctl, pi);
|
||||
/* Save in device temp the irq value */
|
||||
dibp->uba_irq_pend = 0200 >> (pi & 07);
|
||||
set_interrupt(dibp->uba_ctl << 2, pi);
|
||||
}
|
||||
|
||||
t_addr
|
||||
@@ -236,43 +236,62 @@ uba_get_vect(t_addr addr, int lvl)
|
||||
DEVICE *dptr;
|
||||
DIB *idev = NULL;
|
||||
uint64 buffer;
|
||||
uint8 ivect;
|
||||
int i;
|
||||
int high = 0;
|
||||
int ctl = 17;
|
||||
int msk[16] = {0};
|
||||
int pi;
|
||||
int ubm;
|
||||
|
||||
/* Look for device */
|
||||
for(i = 0; (dptr = sim_devices[i]) != NULL; i++) {
|
||||
DIB *dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
continue;
|
||||
/* If device is pending on this level save */
|
||||
if ((dibp->uba_irq_pend & lvl) != 0) {
|
||||
if (dibp->uba_ctl < ctl)
|
||||
/* But only if it is highest UBA */
|
||||
if (dibp->uba_ctl < ctl) {
|
||||
ctl = dibp->uba_ctl;
|
||||
idev = dibp;
|
||||
continue;
|
||||
}
|
||||
msk[dibp->uba_ctl] |= dibp->uba_irq_pend;
|
||||
}
|
||||
if (idev != NULL) {
|
||||
if (idev->uba_br > 5) {
|
||||
pi = uba_status[idev->uba_ctl] >> 3;
|
||||
uba_status[idev->uba_ctl] &= ~UBST_INTH;
|
||||
if (msk[idev->uba_ctl] & (0200 >> pi))
|
||||
uba_status[idev->uba_ctl] |= UBST_INTH;
|
||||
} else {
|
||||
pi = uba_status[idev->uba_ctl];
|
||||
uba_status[idev->uba_ctl] &= ~UBST_INTL;
|
||||
if (msk[idev->uba_ctl] & (0200 >> pi))
|
||||
uba_status[idev->uba_ctl] |= UBST_INTL;
|
||||
idev = dibp;
|
||||
}
|
||||
}
|
||||
idev->uba_irq_pend &= ~(0200 >> pi);
|
||||
if (msk[idev->uba_ctl] & (0200 >> pi))
|
||||
set_interrupt(idev->uba_ctl, pi);
|
||||
else
|
||||
clr_interrupt(idev->uba_ctl);
|
||||
}
|
||||
/* Should have a device */
|
||||
if (idev != NULL) {
|
||||
/* Figure out what pi channel this will interrupt on */
|
||||
ubm = uba_device[idev->uba_ctl];
|
||||
if (idev->uba_br > 5) {
|
||||
pi = (uba_status[ubm] >> 3) & 07;
|
||||
high = 1;
|
||||
uba_status[ubm] &= ~UBST_INTH;
|
||||
} else {
|
||||
pi = uba_status[ubm] & 07;
|
||||
uba_status[ubm] &= ~UBST_INTL;
|
||||
}
|
||||
/* Clear interrupts */
|
||||
idev->uba_irq_pend = 0;
|
||||
/* Any other devices waiting on this PI channel? */
|
||||
clr_interrupt(idev->uba_ctl << 2);
|
||||
for(i = 0; (dptr = sim_devices[i]) != NULL; i++) {
|
||||
DIB *dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
continue;
|
||||
/* If device is pending on this level save */
|
||||
if (dibp->uba_ctl == idev->uba_ctl &&
|
||||
(dibp->uba_irq_pend & lvl) != 0) {
|
||||
set_interrupt(idev->uba_ctl << 2, pi);
|
||||
uba_status[ubm] |= UBST_INTL << high;
|
||||
/* At least one, no need to continue */
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Fetch vector */
|
||||
if (Mem_read_word(0100 | idev->uba_ctl, &buffer, 1))
|
||||
return addr;
|
||||
ivect = idev->uba_vect;
|
||||
if (idev->irqv != NULL)
|
||||
ivect = (idev->irqv)(idev);
|
||||
addr = (buffer & RMASK) + (idev->uba_vect >> 2);
|
||||
}
|
||||
return addr;
|
||||
|
||||
@@ -314,17 +314,13 @@ extern DEBTAB crd_debug[];
|
||||
|
||||
#if KI_22BIT|KI
|
||||
#define MAXMEMSIZE 4096 * 1024
|
||||
#else
|
||||
#if PDP6
|
||||
#elif PDP6
|
||||
#define MAXMEMSIZE 256 * 1024
|
||||
#else
|
||||
#if KS
|
||||
#define MAXMEMSIZE 512 * 1024
|
||||
#elif KS
|
||||
#define MAXMEMSIZE 1024 * 1024
|
||||
#else
|
||||
#define MAXMEMSIZE 1024 * 1024
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#define MEMSIZE (cpu_unit[0].capac)
|
||||
|
||||
#define ICWA 0000000000776
|
||||
@@ -527,6 +523,7 @@ struct pdp_dib {
|
||||
uint16 uba_ctl; /* Unibus controller number */
|
||||
t_stat (*rd_io)(t_addr addr, uint16 *data, int32 access);
|
||||
t_stat (*wr_io)(t_addr addr, uint16 data, int32 access);
|
||||
uint8 (*irqv)(struct pdp_dib *dibp);
|
||||
uint8 uba_irq_pend; /* Device has pending */
|
||||
};
|
||||
typedef struct pdp_dib DIB;
|
||||
|
||||
Reference in New Issue
Block a user