mirror of
https://github.com/simh/simh.git
synced 2026-01-26 04:01:38 +00:00
Addition of MicroVAX I (VAX610) processor simulator from Matt Burke
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
24-Oct-12 MB Added working map base address
|
||||
09-Jan-03 RMS Tape read/write end pkt is longer than disk read/write
|
||||
20-Sep-02 RMS Merged TMSCP definitions
|
||||
*/
|
||||
@@ -412,6 +413,8 @@
|
||||
#define RW_WBAH 21
|
||||
#define RW_WBLL 22 /* working lbn */
|
||||
#define RW_WBLH 23
|
||||
#define RW_WMPL 24 /* working map */
|
||||
#define RW_WMPH 25
|
||||
|
||||
/* Tape specific status */
|
||||
|
||||
|
||||
114
PDP11/pdp11_rq.c
114
PDP11/pdp11_rq.c
@@ -26,6 +26,7 @@
|
||||
|
||||
rq RQDX3 disk controller
|
||||
|
||||
24-Oct-12 MB Added mapped transfers for VAX
|
||||
07-Mar-11 MP Added working behaviors for removable device types.
|
||||
This allows physical CDROM's to come online and be
|
||||
ejected.
|
||||
@@ -137,6 +138,8 @@ extern uint32 cpu_opt;
|
||||
#define RQ_NUMDR 4 /* # drives */
|
||||
#define RQ_NUMBY 512 /* bytes per block */
|
||||
#define RQ_MAXFR (1 << 16) /* max xfer */
|
||||
#define RQ_MAPXFER (1 << 31) /* mapped xfer */
|
||||
#define RQ_M_PFN 0x1FFFFF /* map entry PFN */
|
||||
|
||||
#define UNIT_V_ONL (UNIT_V_UF + 0) /* online */
|
||||
#define UNIT_V_WLK (UNIT_V_UF + 1) /* hwre write lock */
|
||||
@@ -707,6 +710,10 @@ t_bool rq_getdesc (MSC *cp, struct uq_ring *ring, uint32 *desc);
|
||||
t_bool rq_putdesc (MSC *cp, struct uq_ring *ring, uint32 desc);
|
||||
int32 rq_rw_valid (MSC *cp, int32 pkt, UNIT *uptr, uint32 cmd);
|
||||
t_bool rq_rw_end (MSC *cp, UNIT *uptr, uint32 flg, uint32 sts);
|
||||
uint32 rq_map_ba (uint32 ba, uint32 ma);
|
||||
int32 rq_readb (uint32 ba, int32 bc, uint32 ma, uint8 *buf);
|
||||
int32 rq_readw (uint32 ba, int32 bc, uint32 ma, uint16 *buf);
|
||||
int32 rq_writew (uint32 ba, int32 bc, uint32 ma, uint16 *buf);
|
||||
void rq_putr (MSC *cp, int32 pkt, uint32 cmd, uint32 flg,
|
||||
uint32 sts, uint32 lnt, uint32 typ);
|
||||
void rq_putr_unit (MSC *cp, int32 pkt, UNIT *uptr, uint32 lu, t_bool all);
|
||||
@@ -1737,6 +1744,8 @@ if ((uptr = rq_getucb (cp, lu))) { /* unit exist? */
|
||||
cp->pak[pkt].d[RW_WBCH] = cp->pak[pkt].d[RW_BCH];
|
||||
cp->pak[pkt].d[RW_WBLL] = cp->pak[pkt].d[RW_LBNL];
|
||||
cp->pak[pkt].d[RW_WBLH] = cp->pak[pkt].d[RW_LBNH];
|
||||
cp->pak[pkt].d[RW_WMPL] = cp->pak[pkt].d[RW_MAPL];
|
||||
cp->pak[pkt].d[RW_WMPH] = cp->pak[pkt].d[RW_MAPH];
|
||||
uptr->iostarttime = sim_grtime();
|
||||
sim_activate (uptr, 0); /* activate */
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_rw - started\n");
|
||||
@@ -1803,6 +1812,100 @@ uptr->io_complete = 1;
|
||||
sim_activate_notbefore (uptr, uptr->iostarttime+rq_xtime);
|
||||
}
|
||||
|
||||
/* Map buffer address */
|
||||
|
||||
uint32 rq_map_ba (uint32 ba, uint32 ma)
|
||||
{
|
||||
#if defined (VM_VAX) /* VAX version */
|
||||
int32 idx;
|
||||
uint32 rg;
|
||||
|
||||
idx = (VA_GETVPN(ba) << 2); /* map register index */
|
||||
rg = ReadL (ma + idx); /* map register */
|
||||
if (rg & PTE_V) /* valid? */
|
||||
return ((rg & RQ_M_PFN) << VA_N_OFF) | (ba & VA_M_OFF);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read byte buffer from memory */
|
||||
|
||||
int32 rq_readb (uint32 ba, int32 bc, uint32 ma, uint8 *buf)
|
||||
{
|
||||
#if defined (VM_VAX) /* VAX version */
|
||||
int32 lbc, t, tbc = 0;
|
||||
uint32 pba;
|
||||
|
||||
if (ba & RQ_MAPXFER) { /* mapped xfer? */
|
||||
while (tbc < bc) {
|
||||
if (!(pba = rq_map_ba (ba, ma))) /* get physical ba */
|
||||
return (bc - tbc);
|
||||
lbc = 0x200 - (ba & VA_M_OFF); /* bc for this tx */
|
||||
if (lbc > (bc - tbc)) lbc = (bc - tbc);
|
||||
t = Map_ReadB (pba, lbc, buf);
|
||||
tbc += (lbc - t); /* bytes xfer'd so far */
|
||||
if (t) return (bc - tbc); /* incomplete xfer? */
|
||||
ba += lbc;
|
||||
buf += lbc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return Map_ReadB (ba, bc, buf); /* unmapped xfer */
|
||||
}
|
||||
|
||||
/* Read word buffer from memory */
|
||||
|
||||
int32 rq_readw (uint32 ba, int32 bc, uint32 ma, uint16 *buf)
|
||||
{
|
||||
#if defined (VM_VAX) /* VAX version */
|
||||
int32 lbc, t, tbc = 0;
|
||||
uint32 pba;
|
||||
|
||||
if (ba & RQ_MAPXFER) { /* mapped xfer? */
|
||||
while (tbc < bc) {
|
||||
if (!(pba = rq_map_ba (ba, ma))) /* get physical ba */
|
||||
return (bc - tbc);
|
||||
lbc = 0x200 - (ba & VA_M_OFF); /* bc for this tx */
|
||||
if (lbc > (bc - tbc)) lbc = (bc - tbc);
|
||||
t = Map_ReadW (pba, lbc, buf);
|
||||
tbc += (lbc - t); /* bytes xfer'd so far */
|
||||
if (t) return (bc - tbc); /* incomplete xfer? */
|
||||
ba += lbc;
|
||||
buf += (lbc >> 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return Map_ReadW (ba, bc, buf); /* unmapped xfer */
|
||||
}
|
||||
|
||||
/* Write word buffer to memory */
|
||||
|
||||
int32 rq_writew (uint32 ba, int32 bc, uint32 ma, uint16 *buf)
|
||||
{
|
||||
#if defined (VM_VAX) /* VAX version */
|
||||
int32 lbc, t, tbc = 0;
|
||||
uint32 pba;
|
||||
|
||||
if (ba & RQ_MAPXFER) { /* mapped xfer? */
|
||||
while (tbc < bc) {
|
||||
if (!(pba = rq_map_ba (ba, ma))) /* get physical ba */
|
||||
return (bc - tbc);
|
||||
lbc = 0x200 - (ba & VA_M_OFF); /* bc for this tx */
|
||||
if (lbc > (bc - tbc)) lbc = (bc - tbc);
|
||||
t = Map_WriteW (pba, lbc, buf);
|
||||
tbc += (lbc - t); /* bytes xfer'd so far */
|
||||
if (t) return (bc - tbc); /* incomplete xfer? */
|
||||
ba += lbc;
|
||||
buf += (lbc >> 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return Map_WriteW (ba, bc, buf); /* unmapped xfer */
|
||||
}
|
||||
|
||||
/* Unit service for data transfer commands */
|
||||
|
||||
t_stat rq_svc (UNIT *uptr)
|
||||
@@ -1815,6 +1918,7 @@ uint32 cmd = GETP (pkt, CMD_OPC, OPC); /* get cmd */
|
||||
uint32 ba = GETP32 (pkt, RW_WBAL); /* buf addr */
|
||||
uint32 bc = GETP32 (pkt, RW_WBCL); /* byte count */
|
||||
uint32 bl = GETP32 (pkt, RW_WBLL); /* block addr */
|
||||
uint32 ma = GETP32 (pkt, RW_WMPL); /* block addr */
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_svc(unit=%d, pkt=%d, cmd=%s, lbn=%0X, bc=%0x, phase=%s)\n",
|
||||
uptr-rq_devmap[cp->cnum]->units, pkt, rq_cmdname[cp->pak[pkt].d[CMD_OPC]&0x3f], bl, bc,
|
||||
@@ -1853,7 +1957,7 @@ if (!uptr->io_complete) { /* Top End (I/O Initiation) Processing */
|
||||
}
|
||||
|
||||
else if (cmd == OP_WR) { /* write? */
|
||||
t = Map_ReadW (ba, tbc, uptr->rqxb); /* fetch buffer */
|
||||
t = rq_readw (ba, tbc, ma, uptr->rqxb); /* fetch buffer */
|
||||
if ((abc = tbc - t)) { /* any xfer? */
|
||||
wwc = ((abc + (RQ_NUMBY - 1)) & ~(RQ_NUMBY - 1)) >> 1;
|
||||
for (i = (abc >> 1); i < wwc; i++)
|
||||
@@ -1875,7 +1979,7 @@ else { /* Bottom End (After I/O processing) */
|
||||
}
|
||||
|
||||
else if (cmd == OP_WR) { /* write? */
|
||||
t = Map_ReadW (ba, tbc, uptr->rqxb); /* fetch buffer */
|
||||
t = rq_readw (ba, tbc, ma, uptr->rqxb); /* fetch buffer */
|
||||
abc = tbc - t; /* any xfer? */
|
||||
if (t) { /* nxm? */
|
||||
PUTP32 (pkt, RW_WBCL, bc - abc); /* adj bc */
|
||||
@@ -1889,7 +1993,7 @@ else { /* Bottom End (After I/O processing) */
|
||||
else {
|
||||
sim_disk_data_trace(uptr, uptr->rqxb, bl, tbc, "sim_disk_rdsect", DBG_DAT & rq_devmap[cp->cnum]->dctrl, DBG_REQ);
|
||||
if ((cmd == OP_RD) && !err) { /* read? */
|
||||
if ((t = Map_WriteW (ba, tbc, uptr->rqxb))) {/* store, nxm? */
|
||||
if ((t = rq_writew (ba, tbc, ma, uptr->rqxb))) {/* store, nxm? */
|
||||
PUTP32 (pkt, RW_WBCL, bc - (tbc - t)); /* adj bc */
|
||||
PUTP32 (pkt, RW_WBAL, ba + (tbc - t)); /* adj ba */
|
||||
if (rq_hbe (cp, uptr)) /* post err log */
|
||||
@@ -1900,7 +2004,7 @@ else { /* Bottom End (After I/O processing) */
|
||||
else if ((cmd == OP_CMP) && !err) { /* compare? */
|
||||
uint8 dby, mby;
|
||||
for (i = 0; i < tbc; i++) { /* loop */
|
||||
if (Map_ReadB (ba + i, 1, &mby)) { /* fetch, nxm? */
|
||||
if (rq_readb (ba + i, 1, ma, &mby)) { /* fetch, nxm? */
|
||||
PUTP32 (pkt, RW_WBCL, bc - i); /* adj bc */
|
||||
PUTP32 (pkt, RW_WBAL, bc - i); /* adj ba */
|
||||
if (rq_hbe (cp, uptr)) /* post err log */
|
||||
@@ -1957,6 +2061,8 @@ cp->pak[pkt].d[RW_WBCL] = 0;
|
||||
cp->pak[pkt].d[RW_WBCH] = 0;
|
||||
cp->pak[pkt].d[RW_WBLL] = 0;
|
||||
cp->pak[pkt].d[RW_WBLH] = 0;
|
||||
cp->pak[pkt].d[RW_WMPL] = 0;
|
||||
cp->pak[pkt].d[RW_WMPH] = 0;
|
||||
rq_putr (cp, pkt, cmd | OP_END, flg, sts, RW_LNT_D, UQ_TYP_SEQ); /* fill pkt */
|
||||
if (!rq_putpkt (cp, pkt, TRUE)) /* send pkt */
|
||||
return ERR;
|
||||
|
||||
Reference in New Issue
Block a user