547 lines
16 KiB
C
547 lines
16 KiB
C
/* pdp10_ksio.c: PDP-10 KS10 I/O subsystem 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.
|
||
|
||
uba Unibus adapters
|
||
|
||
1-Jun-01 RMS Updated DZ11 vectors
|
||
12-May-01 RMS Fixed typo
|
||
|
||
The KS10 uses the PDP-11 Unibus for its I/O, via adapters. While
|
||
nominally four adapters are supported, in practice only 1 and 3
|
||
are implemented. The disks are placed on adapter 1, the rest of
|
||
the I/O devices on adapter 3.
|
||
|
||
In theory, we should maintain completely separate Unibuses, with
|
||
distinct PI systems. In practice, this simulator has so few devices
|
||
that we can get away with a single PI system, masking for which
|
||
devices are on adapter 1, and which on adapter 3. The Unibus
|
||
implementation is modeled on the Qbus in the PDP-11 simulator and
|
||
is described there.
|
||
|
||
The I/O subsystem is programmed by I/O instructions which create
|
||
Unibus operations (read, read pause, write, write byte). DMA is
|
||
the responsibility of the I/O device simulators, which also implement
|
||
Unibus to physical memory mapping.
|
||
|
||
The priority interrupt subsystem (and other privileged functions)
|
||
is programmed by I/O instructions with internal devices codes
|
||
(opcodes 700-702). These are dispatched here, although many are
|
||
handled in the memory management unit or elsewhere.
|
||
|
||
The ITS instructions are significantly different from the TOPS-10/20
|
||
instructions. They do not use the extended address calculation but
|
||
instead provide instruction variants (Q for Unibus adapter 1, I for
|
||
Unibus adapter 3) which insert the Unibus adapter number into the
|
||
effective address.
|
||
*/
|
||
|
||
#include "pdp10_defs.h"
|
||
#include <setjmp.h>
|
||
|
||
#define eaRB (ea & ~1)
|
||
#define GETBYTE(ea,x) ((((ea) & 1)? (x) >> 8: (x)) & 0377)
|
||
#define UBNXM_FAIL(pa,op) \
|
||
n = iocmap[GET_IOUBA (pa)]; \
|
||
if (n >= 0) ubcs[n] = ubcs[n] | UBCS_TMO | UBCS_NXD; \
|
||
pager_word = PF_HARD | PF_VIRT | PF_IO | \
|
||
((op == WRITEB)? PF_BYTE: 0) | \
|
||
(TSTF (F_USR)? PF_USER: 0) | (pa); \
|
||
ABORT (PAGE_FAIL)
|
||
|
||
/* Unibus adapter data */
|
||
|
||
int32 ubcs[UBANUM] = { 0 }; /* status registers */
|
||
int32 ubmap[UBANUM][UMAP_MEMSIZE] = { 0 }; /* Unibus maps */
|
||
int32 int_req = 0; /* interrupt requests */
|
||
int32 dev_enb = -1 & ~(INT_PTR | INT_PTP); /* device enables */
|
||
|
||
/* Map IO controller numbers to Unibus adapters: -1 = non-existent */
|
||
|
||
static int iocmap[IO_N_UBA] = { /* map I/O ext to UBA # */
|
||
-1, 0, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
|
||
|
||
static const int32 ubabr76[UBANUM] = {
|
||
INT_UB1 & (INT_IPL7 | INT_IPL6), INT_UB3 & (INT_IPL7 | INT_IPL6) };
|
||
static const int32 ubabr54[UBANUM] = {
|
||
INT_UB1 & (INT_IPL5 | INT_IPL4), INT_UB3 & (INT_IPL5 | INT_IPL4) };
|
||
|
||
extern d10 *ac_cur;
|
||
extern d10 pager_word;
|
||
extern int32 flags, pi_l2bit[8];
|
||
extern UNIT cpu_unit;
|
||
extern jmp_buf save_env;
|
||
|
||
extern d10 Read (a10 ea);
|
||
extern void pi_eval ();
|
||
extern t_stat dz0_rd (int32 *data, int32 addr, int32 access);
|
||
extern t_stat dz0_wr (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 lp20_rd (int32 *data, int32 addr, int32 access);
|
||
extern t_stat lp20_wr (int32 data, int32 addr, int32 access);
|
||
extern int32 lp20_inta (void);
|
||
extern t_stat rp_rd (int32 *data, int32 addr, int32 access);
|
||
extern t_stat rp_wr (int32 data, int32 addr, int32 access);
|
||
extern int32 rp_inta (void);
|
||
extern t_stat tu_rd (int32 *data, int32 addr, int32 access);
|
||
extern t_stat tu_wr (int32 data, int32 addr, int32 access);
|
||
extern int32 tu_inta (void);
|
||
extern t_stat tcu_rd (int32 *data, int32 addr, int32 access);
|
||
t_stat ubmap_rd (int32 *data, int32 addr, int32 access);
|
||
t_stat ubmap_wr (int32 data, int32 addr, int32 access);
|
||
t_stat ubs_rd (int32 *data, int32 addr, int32 access);
|
||
t_stat ubs_wr (int32 data, int32 addr, int32 access);
|
||
t_stat rd_zro (int32 *data, int32 addr, int32 access);
|
||
t_stat wr_nop (int32 data, int32 addr, int32 access);
|
||
t_stat uba_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
|
||
t_stat uba_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
|
||
t_stat uba_reset (DEVICE *dptr);
|
||
d10 ReadIO (a10 ea);
|
||
void WriteIO (a10 ea, d10 val, int32 mode);
|
||
|
||
/* Unibus adapter data structures
|
||
|
||
uba_dev UBA device descriptor
|
||
uba_unit UBA units
|
||
uba_reg UBA register list
|
||
*/
|
||
|
||
UNIT uba_unit[] = {
|
||
{ UDATA (NULL, UNIT_FIX, UMAP_MEMSIZE) },
|
||
{ UDATA (NULL, UNIT_FIX, UMAP_MEMSIZE) } };
|
||
|
||
REG uba_reg[] = {
|
||
{ ORDATA (INTREQ, int_req, 32), REG_RO },
|
||
{ ORDATA (UB1CS, ubcs[0], 18) },
|
||
{ ORDATA (UB3CS, ubcs[1], 18) },
|
||
{ ORDATA (DEVENB, dev_enb, 32), REG_HRO },
|
||
{ NULL } };
|
||
|
||
DEVICE uba_dev = {
|
||
"UBA", uba_unit, uba_reg, NULL,
|
||
UBANUM, 8, UMAP_ASIZE, 1, 8, 32,
|
||
&uba_ex, &uba_dep, &uba_reset,
|
||
NULL, NULL, NULL };
|
||
|
||
/* PDP-11 I/O structures */
|
||
|
||
struct iolink { /* I/O page linkage */
|
||
int32 low; /* low I/O addr */
|
||
int32 high; /* high I/O addr */
|
||
int32 enb; /* enable mask */
|
||
t_stat (*read)(); /* read routine */
|
||
t_stat (*write)(); }; /* write routine */
|
||
|
||
/* Table of I/O devices and corresponding read/write routines
|
||
The expected Unibus adapter number is included as the high 2 bits */
|
||
|
||
struct iolink iotable[] = {
|
||
{ IO_UBA1+IO_RHBASE, IO_UBA1+IO_RHBASE+047, 0,
|
||
&rp_rd, &rp_wr }, /* disk */
|
||
{ IO_UBA3+IO_TMBASE, IO_UBA3+IO_TMBASE+033, 0,
|
||
&tu_rd, &tu_wr }, /* mag tape */
|
||
/* { IO_UBA3+IO_DZBASE, IO_UBA3+IO_DZBASE+07, INT_DZ,
|
||
&dz0_rd, &dz0_wr }, /* terminal mux */
|
||
{ IO_UBA3+IO_LPBASE, IO_UBA3+IO_LPBASE+017, 0,
|
||
&lp20_rd, &lp20_wr }, /* line printer */
|
||
{ IO_UBA3+IO_PTBASE, IO_UBA3+IO_PTBASE+07, INT_PTR,
|
||
&pt_rd, &pt_wr }, /* paper tape */
|
||
{ IO_UBA1+IO_UBMAP, IO_UBA1+IO_UBMAP+077, 0,
|
||
&ubmap_rd, &ubmap_wr }, /* Unibus 1 map */
|
||
{ IO_UBA3+IO_UBMAP, IO_UBA3+IO_UBMAP+077, 0,
|
||
&ubmap_rd, &ubmap_wr }, /* Unibus 3 map */
|
||
{ IO_UBA1+IO_UBCS, IO_UBA1+IO_UBCS, 0,
|
||
&ubs_rd, &ubs_wr }, /* Unibus 1 c/s */
|
||
{ IO_UBA3+IO_UBCS, IO_UBA3+IO_UBCS, 0,
|
||
&ubs_rd, &ubs_wr }, /* Unibus 3 c/s */
|
||
{ IO_UBA1+IO_UBMNT, IO_UBA1+IO_UBMNT, 0,
|
||
&rd_zro, &wr_nop }, /* Unibus 1 maint */
|
||
{ IO_UBA3+IO_UBMNT, IO_UBA3+IO_UBMNT, 0,
|
||
&rd_zro, &wr_nop }, /* Unibus 3 maint */
|
||
{ IO_UBA3+IO_TCUBASE, IO_UBA3+IO_TCUBASE+05, 0,
|
||
&tcu_rd, &wr_nop }, /* TCU150 */
|
||
{ 00100000, 00100000, 0, &rd_zro, &wr_nop }, /* Mem sys stat */
|
||
{ 0, 0, 0, NULL, NULL } };
|
||
|
||
/* Interrupt request to interrupt action map */
|
||
|
||
int32 (*int_ack[32])() = { /* int ack routines */
|
||
NULL, NULL, NULL, NULL, NULL, NULL, &rp_inta, &tu_inta,
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
NULL, NULL, &lp20_inta, NULL, NULL, NULL, NULL, NULL };
|
||
|
||
/* Interrupt request to vector map */
|
||
|
||
int32 int_vec[32] = { /* int req to vector */
|
||
0, 0, 0, 0, 0, 0, VEC_RP, VEC_TU,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
VEC_DZ0RX, VEC_DZ0TX, 0, 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
|
||
(ITS) IORDI - read word from Unibus 3
|
||
returns TRUE if skip, FALSE otherwise
|
||
*/
|
||
|
||
t_bool io710 (int32 ac, a10 ea)
|
||
{
|
||
d10 val;
|
||
|
||
if (ITS) AC(ac) = ReadIO (IO_UBA3 | ea); /* IORDI */
|
||
else { /* TIOE */
|
||
val = ReadIO (ea); /* read word */
|
||
if ((AC(ac) & val) == 0) return TRUE; }
|
||
return FALSE;
|
||
}
|
||
|
||
/* IO 711 (DEC) TION - test I/O word, skip if non-zero
|
||
(ITS) IORDQ - read word from Unibus 1
|
||
returns TRUE if skip, FALSE otherwise
|
||
*/
|
||
|
||
t_bool io711 (int32 ac, a10 ea)
|
||
{
|
||
d10 val;
|
||
|
||
if (ITS) AC(ac) = ReadIO (IO_UBA1 | ea); /* IORDQ */
|
||
else { /* TION */
|
||
val = ReadIO (ea); /* read word */
|
||
if ((AC(ac) & val) != 0) return TRUE; }
|
||
return FALSE;
|
||
}
|
||
|
||
/* IO 712 (DEC) RDIO - read I/O word, addr in ea
|
||
(ITS) IORD - read I/O word, addr in M[ea]
|
||
*/
|
||
|
||
d10 io712 (a10 ea)
|
||
{
|
||
return ReadIO (ea); /* RDIO, IORD */
|
||
}
|
||
|
||
/* IO 713 (DEC) WRIO - write I/O word, addr in ea
|
||
(ITS) IOWR - write I/O word, addr in M[ea]
|
||
*/
|
||
|
||
void io713 (d10 val, a10 ea)
|
||
{
|
||
WriteIO (ea, val & 0177777, WRITE); /* WRIO, IOWR */
|
||
return;
|
||
}
|
||
|
||
/* IO 714 (DEC) BSIO - set bit in I/O address
|
||
(ITS) IOWRI - write word to Unibus 3
|
||
*/
|
||
|
||
void io714 (d10 val, a10 ea)
|
||
{
|
||
d10 temp;
|
||
|
||
val = val & 0177777;
|
||
if (ITS) WriteIO (IO_UBA3 | ea, val, WRITE); /* IOWRI */
|
||
else {
|
||
temp = ReadIO (ea); /* BSIO */
|
||
temp = temp | val;
|
||
WriteIO (ea, temp, WRITE); }
|
||
return;
|
||
}
|
||
|
||
/* IO 715 (DEC) BCIO - clear bit in I/O address
|
||
(ITS) IOWRQ - write word to Unibus 1
|
||
*/
|
||
|
||
void io715 (d10 val, a10 ea)
|
||
{
|
||
d10 temp;
|
||
|
||
val = val & 0177777;
|
||
if (ITS) WriteIO (IO_UBA1 | ea, val, WRITE); /* IOWRQ */
|
||
else {
|
||
temp = ReadIO (ea); /* BCIO */
|
||
temp = temp & ~val;
|
||
WriteIO (ea, temp, WRITE); }
|
||
return;
|
||
}
|
||
|
||
/* IO 720 (DEC) TIOEB - test I/O byte, skip if zero
|
||
(ITS) IORDBI - read byte from Unibus 3
|
||
returns TRUE if skip, FALSE otherwise
|
||
*/
|
||
|
||
t_bool io720 (int32 ac, a10 ea)
|
||
{
|
||
d10 val;
|
||
|
||
if (ITS) { /* IORDBI */
|
||
val = ReadIO (IO_UBA3 | eaRB);
|
||
AC(ac) = GETBYTE (ea, val); }
|
||
else { /* TIOEB */
|
||
val = ReadIO (eaRB);
|
||
val = GETBYTE (ea, val);
|
||
if ((AC(ac) & val) == 0) return TRUE; }
|
||
return FALSE;
|
||
}
|
||
|
||
/* IO 721 (DEC) TIONB - test I/O word, skip if non-zero
|
||
(ITS) IORDBQ - read word from Unibus 1
|
||
returns TRUE if skip, FALSE otherwise
|
||
*/
|
||
|
||
t_bool io721 (int32 ac, a10 ea)
|
||
{
|
||
d10 val;
|
||
|
||
if (ITS) { /* IORDBQ */
|
||
val = ReadIO (IO_UBA1 | eaRB);
|
||
AC(ac) = GETBYTE (ea, val); }
|
||
else { /* TIONB */
|
||
val = ReadIO (eaRB);
|
||
val = GETBYTE (ea, val);
|
||
if ((AC(ac) & val) != 0) return TRUE; }
|
||
return FALSE;
|
||
}
|
||
|
||
/* IO 722 (DEC) RDIOB - read I/O byte, addr in ea
|
||
(ITS) IORDB - read I/O byte, addr in M[ea]
|
||
*/
|
||
|
||
d10 io722 (a10 ea)
|
||
{
|
||
d10 val;
|
||
|
||
val = ReadIO (eaRB); /* RDIOB, IORDB */
|
||
return GETBYTE (ea, val);
|
||
}
|
||
|
||
/* IO 723 (DEC) WRIOB - write I/O byte, addr in ea
|
||
(ITS) IOWRB - write I/O byte, addr in M[ea]
|
||
*/
|
||
|
||
void io723 (d10 val, a10 ea)
|
||
{
|
||
WriteIO (ea, val & 0377, WRITEB); /* WRIOB, IOWRB */
|
||
return;
|
||
}
|
||
|
||
/* IO 724 (DEC) BSIOB - set bit in I/O byte address
|
||
(ITS) IOWRBI - write byte to Unibus 3
|
||
*/
|
||
|
||
void io724 (d10 val, a10 ea)
|
||
{
|
||
d10 temp;
|
||
|
||
val = val & 0377;
|
||
if (ITS) WriteIO (IO_UBA3 | ea, val, WRITEB); /* IOWRBI */
|
||
else {
|
||
temp = ReadIO (eaRB); /* BSIOB */
|
||
temp = GETBYTE (ea, temp);
|
||
temp = temp | val;
|
||
WriteIO (ea, temp, WRITEB); }
|
||
return;
|
||
}
|
||
|
||
/* IO 725 (DEC) BCIOB - clear bit in I/O byte address
|
||
(ITS) IOWRBQ - write byte to Unibus 1
|
||
*/
|
||
|
||
void io725 (d10 val, a10 ea)
|
||
{
|
||
d10 temp;
|
||
|
||
val = val & 0377;
|
||
if (ITS) WriteIO (IO_UBA1 | ea, val, WRITEB); /* IOWRBQ */
|
||
else {
|
||
temp = ReadIO (eaRB); /* BCIOB */
|
||
temp = GETBYTE (ea, temp);
|
||
temp = temp & ~val;
|
||
WriteIO (ea, temp, WRITEB); }
|
||
return;
|
||
}
|
||
|
||
/* Read and write I/O devices.
|
||
These routines are the linkage between the 64b world of the main
|
||
simulator and the 32b world of the device simulators.
|
||
*/
|
||
|
||
d10 ReadIO (a10 ea)
|
||
{
|
||
int32 n, pa, val;
|
||
struct iolink *p;
|
||
|
||
pa = (int32) ea; /* cvt addr to 32b */
|
||
for (p = &iotable[0]; p -> low != 0; p++ ) {
|
||
if ((pa >= p -> low) && (pa <= p -> high) &&
|
||
((p -> enb == 0) || (dev_enb & p -> enb))) {
|
||
p -> read (&val, pa, READ);
|
||
pi_eval ();
|
||
return ((d10) val); } }
|
||
UBNXM_FAIL (pa, READ);
|
||
}
|
||
|
||
void WriteIO (a10 ea, d10 val, int32 mode)
|
||
{
|
||
int32 n, pa;
|
||
struct iolink *p;
|
||
|
||
pa = (int32) ea; /* cvt addr to 32b */
|
||
for (p = &iotable[0]; p -> low != 0; p++ ) {
|
||
if ((pa >= p -> low) && (pa <= p -> high) &&
|
||
((p -> enb == 0) || (dev_enb & p -> enb))) {
|
||
p -> write ((int32) val, pa, mode);
|
||
pi_eval ();
|
||
return; } }
|
||
UBNXM_FAIL (pa, mode);
|
||
}
|
||
|
||
/* Evaluate Unibus priority interrupts */
|
||
|
||
int32 pi_ub_eval ()
|
||
{
|
||
int32 i, lvl;
|
||
|
||
for (i = lvl = 0; i < UBANUM; i++) {
|
||
if (int_req & ubabr76[i])
|
||
lvl = lvl | pi_l2bit[UBCS_GET_HI (ubcs[i])];
|
||
if (int_req & ubabr54[i])
|
||
lvl = lvl | pi_l2bit[UBCS_GET_LO (ubcs[i])]; }
|
||
return lvl;
|
||
}
|
||
|
||
/* Return Unibus device vector
|
||
|
||
Takes as input the request level calculated by pi_eval
|
||
If there is an interrupting Unibus device at that level, return its vector,
|
||
otherwise, returns 0
|
||
*/
|
||
|
||
int32 pi_ub_vec (int32 rlvl, int32 *uba)
|
||
{
|
||
int32 i, masked_irq;
|
||
|
||
for (i = masked_irq = 0; i < UBANUM; i++) {
|
||
if ((rlvl == UBCS_GET_HI (ubcs[i])) && /* req on hi level? */
|
||
(masked_irq = int_req & ubabr76[i])) break;
|
||
if ((rlvl == UBCS_GET_LO (ubcs[i])) && /* req on lo level? */
|
||
(masked_irq = int_req & ubabr54[i])) break; }
|
||
*uba = (i << 1) + 1; /* store uba # */
|
||
for (i = 0; (i < 32) && masked_irq; i++) { /* find hi pri req */
|
||
if ((masked_irq >> i) & 1) {
|
||
int_req = int_req & ~(1u << i); /* clear req */
|
||
if (int_ack[i]) return int_ack[i]();
|
||
return int_vec[i]; } } /* return vector */
|
||
return 0;
|
||
}
|
||
|
||
/* Unibus adapter map routines */
|
||
|
||
t_stat ubmap_rd (int32 *val, int32 pa, int32 mode)
|
||
{
|
||
int32 n = iocmap[GET_IOUBA (pa)];
|
||
|
||
if (n < 0) ABORT (STOP_ILLIOC);
|
||
*val = ubmap[n][pa & UMAP_AMASK];
|
||
return SCPE_OK;
|
||
}
|
||
|
||
t_stat ubmap_wr (int32 val, int32 pa, int32 mode)
|
||
{
|
||
int32 n = iocmap[GET_IOUBA (pa)];
|
||
|
||
if (n < 0) ABORT (STOP_ILLIOC);
|
||
ubmap[n][pa & UMAP_AMASK] = UMAP_POSFL (val) | UMAP_POSPN (val);
|
||
return SCPE_OK;
|
||
}
|
||
|
||
/* Unibus adapter control/status routines */
|
||
|
||
t_stat ubs_rd (int32 *val, int32 pa, int32 mode)
|
||
{
|
||
int32 n = iocmap[GET_IOUBA (pa)];
|
||
|
||
if (n < 0) ABORT (STOP_ILLIOC);
|
||
if (int_req & ubabr76[n]) ubcs[n] = ubcs[n] | UBCS_HI;
|
||
if (int_req & ubabr54[n]) ubcs[n] = ubcs[n] | UBCS_LO;
|
||
*val = ubcs[n] = ubcs[n] & ~UBCS_RDZ;
|
||
return SCPE_OK;
|
||
}
|
||
|
||
t_stat ubs_wr (int32 val, int32 pa, int32 mode)
|
||
{
|
||
int32 n = iocmap[GET_IOUBA (pa)];
|
||
|
||
if (n < 0) ABORT (STOP_ILLIOC);
|
||
if (val & UBCS_INI) {
|
||
reset_all (5); /* start after UBA */
|
||
ubcs[n] = val & UBCS_DXF; }
|
||
else ubcs[n] = val & UBCS_RDW;
|
||
if (int_req & ubabr76[n]) ubcs[n] = ubcs[n] | UBCS_HI;
|
||
if (int_req & ubabr54[n]) ubcs[n] = ubcs[n] | UBCS_LO;
|
||
return SCPE_OK;
|
||
}
|
||
|
||
/* Unibus adapter read zero/write ignore routines */
|
||
|
||
t_stat rd_zro (int32 *val, int32 pa, int32 mode)
|
||
{
|
||
*val = 0;
|
||
return SCPE_OK;
|
||
}
|
||
|
||
t_stat wr_nop (int32 val, int32 pa, int32 mode)
|
||
{
|
||
return SCPE_OK;
|
||
}
|
||
|
||
t_stat uba_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)
|
||
{
|
||
int32 uba = uptr - uba_unit;
|
||
|
||
if (addr >= UMAP_MEMSIZE) return SCPE_NXM;
|
||
*vptr = ubmap[uba][addr];
|
||
return SCPE_OK;
|
||
}
|
||
|
||
t_stat uba_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw)
|
||
{
|
||
int32 uba = uptr - uba_unit;
|
||
|
||
if (addr >= UMAP_MEMSIZE) return SCPE_NXM;
|
||
ubmap[uba][addr] = (int32) val & UMAP_MASK;
|
||
return SCPE_OK;
|
||
}
|
||
|
||
t_stat uba_reset (DEVICE *dptr)
|
||
{
|
||
int32 i, uba;
|
||
|
||
int_req = 0;
|
||
for (uba = 0; uba < UBANUM; uba++) {
|
||
ubcs[uba] = 0;
|
||
for (i = 0; i < UMAP_MEMSIZE; i++) ubmap[uba][i] = 0; }
|
||
pi_eval ();
|
||
return SCPE_OK;
|
||
}
|