Merge of VAX 11/730 Simulator from Matt Burke

This commit is contained in:
Mark Pizzolato 2011-09-23 16:21:03 -07:00
parent cb35f6c97b
commit a6b8d63f10
14 changed files with 4375 additions and 6 deletions

400
VAX/vax730_defs.h Normal file
View file

@ -0,0 +1,400 @@
/* vax730_defs.h: VAX 730 model-specific definitions file
Copyright (c) 2010-2011, Matt Burke
This module incorporates code from SimH, Copyright (c) 2004-2008, 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
THE AUTHOR(S) 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(s) of the author(s) shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author(s).
29-Mar-2011 MB First Version
This file covers the VAX 11/730, the third VAX.
System memory map
00 0000 - EF FFFF main memory
F0 0000 - F1 FFFF reserved
F2 0000 - F3 FFFF nexus register space
F4 0000 - FB FFFF reserved
FC 0000 - FF FFFF Unibus address space
*/
#ifndef FULL_VAX
#define FULL_VAX 1
#endif
#ifndef _VAX_730_DEFS_H_
#define _VAX_730_DEFS_H_ 1
/* Microcode constructs */
#define VAX730_SID (3 << 24) /* system ID */
#define VAX730_MICRO (123 << 8) /* ucode revision */
#define CON_HLTPIN 0x0200 /* external CPU halt */
#define CON_HLTINS 0x0600 /* HALT instruction */
#define MCHK_NXM 0x08 /* NXM */
#define MCHK_IIA 0x0A /* illegal i/o addr */
#define MCHK_IUA 0x0B /* illegal unibus addr */
/* Interrupts */
#define IPL_HMAX 0x17 /* highest hwre level */
#define IPL_HMIN 0x14 /* lowest hwre level */
#define IPL_HLVL (IPL_HMAX - IPL_HMIN + 1) /* # hardware levels */
#define IPL_SMAX 0xF /* highest swre level */
/* Nexus constants */
#define NEXUS_NUM 16 /* number of nexus */
#define TR_MCTL 0 /* nexus assignments */
#define TR_UBA 3
#define NEXUS_HLVL (IPL_HMAX - IPL_HMIN + 1)
#define SCB_NEXUS 0x100 /* nexus intr base */
/* Internal I/O interrupts - relative except for clock and console */
#define IPL_CLKINT 0x18 /* clock IPL */
#define IPL_TTINT 0x14 /* console IPL */
#define IPL_CSINT 0x14 /* console storage IPL */
#define IPL_UBA (0x15 - IPL_HMIN)
/* Machine specific IPRs */
#define MT_CSRS 28 /* Console storage */
#define MT_CSRD 29
#define MT_CSTS 30
#define MT_CSTD 31
#define MT_CDR 37 /* Cache disable */
#define MT_MCESR 38 /* MCHK err sts */
#define MT_ACCS 40 /* FPA control */
#define MT_ACCR 41 /* FPA maint */
#define MT_SBIFS 48 /* SBI fault status */
#define MT_SBIS 49 /* SBI silo */
#define MT_SBISC 50 /* SBI silo comparator */
#define MT_SBIMT 51 /* SBI maint */
#define MT_SBIER 52 /* SBI error */
#define MT_SBITA 53 /* SBI timeout addr */
#define MT_SBIQC 54 /* SBI timeout clear */
#define MT_UBINIT 55 /* Unibus Init */
/* Machine specific reserved operand tests */
/* 780 microcode patch 37 - only test LR<23:0> for appropriate length */
#define ML_LR_TEST(r) if ((uint32)((r) & 0xFFFFFF) > 0x200000) RSVD_OPND_FAULT
/* 780 microcode patch 38 - only test PxBR<31>=1 and xBR<1:0> = 0 */
#define ML_PXBR_TEST(r) if ((((r) & 0x80000000) == 0) || \
((r) & 0x00000003)) RSVD_OPND_FAULT
#define ML_SBR_TEST(r) if ((r) & 0x00000003) RSVD_OPND_FAULT
/* 780 microcode patch 78 - only test xCBB<1:0> = 0 */
#define ML_PA_TEST(r) if ((r) & 0x00000003) RSVD_OPND_FAULT
#define LP_AST_TEST(r) if ((r) > AST_MAX) RSVD_OPND_FAULT
#define LP_MBZ84_TEST(r) if ((r) & 0xF8C00000) RSVD_OPND_FAULT
#define LP_MBZ92_TEST(r) if ((r) & 0x7FC00000) RSVD_OPND_FAULT
/* Memory */
#define MAXMEMWIDTH 21 /* max mem, 16k chips */
#define MAXMEMSIZE (1 << MAXMEMWIDTH)
#define MAXMEMWIDTH_X 23 /* max mem, 64k chips */
#define MAXMEMSIZE_X (1 << MAXMEMWIDTH_X)
#define INITMEMSIZE (1 << MAXMEMWIDTH) /* initial memory size */
#define MEMSIZE (cpu_unit.capac)
#define ADDR_IS_MEM(x) (((uint32) (x)) < MEMSIZE)
/* Unibus I/O registers */
#define UBADDRWIDTH 18 /* Unibus addr width */
#define UBADDRSIZE (1u << UBADDRWIDTH) /* Unibus addr length */
#define UBADDRMASK (UBADDRSIZE - 1) /* Unibus addr mask */
#define IOPAGEAWIDTH 13 /* IO addr width */
#define IOPAGESIZE (1u << IOPAGEAWIDTH) /* IO page length */
#define IOPAGEMASK (IOPAGESIZE - 1) /* IO addr mask */
#define UBAMAPWIDTH 11 /* Unibus map width */
#define UBAMAPSIZE 0x7FC /* Unibus map length */
#define UBADDRBASE 0xFC0000 /* Unibus addr base */
#define IOPAGEBASE 0xFFE000 /* IO page base */
#define UBAMAPBASE 0xF26800 /* Unibus map base */
#define ADDR_IS_IO(x) ((((uint32) (x)) >= UBADDRBASE) && \
(((uint32) (x)) < (UBADDRBASE + UBADDRSIZE)))
#define ADDR_IS_IOP(x) (((uint32) (x)) >= IOPAGEBASE)
#define ADDR_IS_IOM(x) ((((uint32) (x)) >= UBAMAPBASE) && \
(((uint32) (x)) < (UBAMAPBASE + UBAMAPSIZE)))
/* Nexus register space */
#define REGAWIDTH 19 /* REG addr width */
#define REG_V_NEXUS 13 /* nexus number */
#define REG_M_NEXUS 0xF
#define REG_V_OFS 2 /* register number */
#define REG_M_OFS 0x7FF
#define REGSIZE (1u << REGAWIDTH) /* REG length */
#define REGBASE 0xF00000 /* REG addr base */
#define ADDR_IS_REG(x) ((((uint32) (x)) >= REGBASE) && \
(((uint32) (x)) < (REGBASE + REGSIZE)))
#define NEXUS_GETNEX(x) (((x) >> REG_V_NEXUS) & REG_M_NEXUS)
#define NEXUS_GETOFS(x) (((x) >> REG_V_OFS) & REG_M_OFS)
/* Other address spaces */
#define ADDR_IS_ROM(x) (0)
#define ADDR_IS_CDG(x) (0)
#define ADDR_IS_NVR(x) (0)
/* Unibus I/O modes */
#define READ 0 /* PDP-11 compatibility */
#define WRITE (L_WORD)
#define WRITEB (L_BYTE)
/* Common CSI flags */
#define CSR_V_GO 0 /* go */
#define CSR_V_IE 6 /* interrupt enable */
#define CSR_V_DONE 7 /* done */
#define CSR_V_BUSY 11 /* busy */
#define CSR_V_ERR 15 /* error */
#define CSR_GO (1u << CSR_V_GO)
#define CSR_IE (1u << CSR_V_IE)
#define CSR_DONE (1u << CSR_V_DONE)
#define CSR_BUSY (1u << CSR_V_BUSY)
#define CSR_ERR (1u << CSR_V_ERR)
/* Timers */
#define TMR_CLK 0 /* 100Hz clock */
/* I/O system definitions */
#define DZ_MUXES 4 /* max # of DZV muxes */
#define DZ_LINES 8 /* lines per DZV mux */
#define VH_MUXES 4 /* max # of DHQ muxes */
#define DLX_LINES 16 /* max # of KL11/DL11's */
#define DCX_LINES 16 /* max # of DC11's */
#define MT_MAXFR (1 << 16) /* magtape max rec */
#define DEV_V_UBUS (DEV_V_UF + 0) /* Unibus */
#define DEV_V_NEXUS (DEV_V_UF + 1) /* Nexus */
#define DEV_V_FLTA (DEV_V_UF + 2) /* flt addr */
#define DEV_V_FFUF (DEV_V_UF + 3) /* first free flag */
#define DEV_UBUS (1u << DEV_V_UBUS)
#define DEV_NEXUS (1u << DEV_V_NEXUS)
#define DEV_FLTA (1u << DEV_V_FLTA)
#define DEV_QBUS (0)
#define DEV_Q18 (0)
#define UNIBUS TRUE /* Unibus only */
#define DEV_RDX 16 /* default device radix */
/* Device information block
For Nexus devices,
ba = Nexus number
lnt = number of consecutive nexi */
#define VEC_DEVMAX 4 /* max device vec */
typedef struct {
uint32 ba; /* base addr */
uint32 lnt; /* length */
t_stat (*rd)(int32 *dat, int32 ad, int32 md);
t_stat (*wr)(int32 dat, int32 ad, int32 md);
int32 vnum; /* vectors: number */
int32 vloc; /* locator */
int32 vec; /* value */
int32 (*ack[VEC_DEVMAX])(void); /* ack routine */
} DIB;
/* Unibus I/O page layout - XUB,RQB,RQC,RQD float based on number of DZ's */
#define IOBA_DZ (IOPAGEBASE + 000100) /* DZ11 */
#define IOLN_DZ 010
#define IOBA_XUB (IOPAGEBASE + 000330 + (020 * (DZ_MUXES / 2)))
#define IOLN_XUB 010
#define IOBA_RQB (IOPAGEBASE + 000334 + (020 * (DZ_MUXES / 2)))
#define IOLN_RQB 004
#define IOBA_RQC (IOPAGEBASE + IOBA_RQB + IOLN_RQB)
#define IOLN_RQC 004
#define IOBA_RQD (IOPAGEBASE + IOBA_RQC + IOLN_RQC)
#define IOLN_RQD 004
#define IOBA_RQ (IOPAGEBASE + 012150) /* UDA50 */
#define IOLN_RQ 004
#define IOBA_TS (IOPAGEBASE + 012520) /* TS11 */
#define IOLN_TS 004
#define IOBA_RL (IOPAGEBASE + 014400) /* RL11 */
#define IOLN_RL 012
#define IOBA_XQ (IOPAGEBASE + 014440) /* DEQNA/DELQA */
#define IOLN_XQ 020
#define IOBA_XQB (IOPAGEBASE + 014460) /* 2nd DEQNA/DELQA */
#define IOLN_XQB 020
#define IOBA_TQ (IOPAGEBASE + 014500) /* TMSCP */
#define IOLN_TQ 004
#define IOBA_XU (IOPAGEBASE + 014510) /* DEUNA/DELUA */
#define IOLN_XU 010
#define IOBA_RB (IOPAGEBASE + 015606) /* RB730 */
#define IOLN_RB 002
#define IOBA_CR (IOPAGEBASE + 017160) /* CD/CR/CM */
#define IOLN_CR 010
#define IOBA_RX (IOPAGEBASE + 017170) /* RX11 */
#define IOLN_RX 004
#define IOBA_RY (IOPAGEBASE + 017170) /* RXV21 */
#define IOLN_RY 004
#define IOBA_QDSS (IOPAGEBASE + 017400) /* QDSS */
#define IOLN_QDSS 002
#define IOBA_HK (IOPAGEBASE + 017440) /* RK611 */
#define IOLN_HK 040
#define IOBA_LPT (IOPAGEBASE + 017514) /* LP11 */
#define IOLN_LPT 004
#define IOBA_PTR (IOPAGEBASE + 017550) /* PC11 reader */
#define IOLN_PTR 004
#define IOBA_PTP (IOPAGEBASE + 017554) /* PC11 punch */
#define IOLN_PTP 004
/* Interrupt assignments; within each level, priority is right to left */
#define INT_V_DZRX 0 /* BR5 */
#define INT_V_DZTX 1
#define INT_V_HK 2
#define INT_V_RL 3
#define INT_V_RB 4
#define INT_V_RQ 5
#define INT_V_TQ 6
#define INT_V_TS 7
#define INT_V_RY 8
#define INT_V_XU 9
#define INT_V_LPT 0 /* BR4 */
#define INT_V_PTR 1
#define INT_V_PTP 2
#define INT_V_CR 3
#define INT_DZRX (1u << INT_V_DZRX)
#define INT_DZTX (1u << INT_V_DZTX)
#define INT_HK (1u << INT_V_HK)
#define INT_RL (1u << INT_V_RL)
#define INT_RQ (1u << INT_V_RQ)
#define INT_TQ (1u << INT_V_TQ)
#define INT_TS (1u << INT_V_TS)
#define INT_RY (1u << INT_V_RY)
#define INT_XU (1u << INT_V_XU)
#define INT_RB (1u << INT_V_RB)
#define INT_LPT (1u << INT_V_LPT)
#define INT_PTR (1u << INT_V_PTR)
#define INT_PTP (1u << INT_V_PTP)
#define INT_CR (1u << INT_V_CR)
#define IPL_DZRX (0x15 - IPL_HMIN)
#define IPL_DZTX (0x15 - IPL_HMIN)
#define IPL_HK (0x15 - IPL_HMIN)
#define IPL_RL (0x15 - IPL_HMIN)
#define IPL_RQ (0x15 - IPL_HMIN)
#define IPL_TQ (0x15 - IPL_HMIN)
#define IPL_TS (0x15 - IPL_HMIN)
#define IPL_RY (0x15 - IPL_HMIN)
#define IPL_XU (0x15 - IPL_HMIN)
#define IPL_RB (0x15 - IPL_HMIN)
#define IPL_LPT (0x14 - IPL_HMIN)
#define IPL_PTR (0x14 - IPL_HMIN)
#define IPL_PTP (0x14 - IPL_HMIN)
#define IPL_CR (0x14 - IPL_HMIN)
/* Device vectors */
#define VEC_Q 0x200
#define VEC_PTR (VEC_Q + 0070)
#define VEC_PTP (VEC_Q + 0074)
#define VEC_XQ (VEC_Q + 0120)
#define VEC_XU (VEC_Q + 0120)
#define VEC_RQ (VEC_Q + 0154)
#define VEC_RL (VEC_Q + 0160)
#define VEC_LPT (VEC_Q + 0200)
#define VEC_HK (VEC_Q + 0210)
#define VEC_TS (VEC_Q + 0224)
#define VEC_CR (VEC_Q + 0230)
#define VEC_RB (VEC_Q + 0250)
#define VEC_TQ (VEC_Q + 0260)
#define VEC_RX (VEC_Q + 0264)
#define VEC_RY (VEC_Q + 0264)
#define VEC_DZRX (VEC_Q + 0300)
#define VEC_DZTX (VEC_Q + 0304)
/* Interrupt macros */
#define IVCL(dv) ((IPL_##dv * 32) + INT_V_##dv)
#define NVCL(dv) ((IPL_##dv * 32) + TR_##dv)
#define IREQ(dv) int_req[IPL_##dv]
#define SET_INT(dv) int_req[IPL_##dv] = int_req[IPL_##dv] | (INT_##dv)
#define CLR_INT(dv) int_req[IPL_##dv] = int_req[IPL_##dv] & ~(INT_##dv)
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* cond error return */
/* Logging */
#define LOG_CPU_I 0x1 /* intexc */
#define LOG_CPU_R 0x2 /* REI */
#define LOG_CPU_P 0x4 /* context */
/* Boot definitions */
#define BOOT_MB 0 /* device codes */
#define BOOT_HK 1 /* for VMB */
#define BOOT_RL 2
#define BOOT_RB 3
#define BOOT_UDA 17
#define BOOT_TK 18
#define BOOT_TD 64
/* Function prototypes for virtual memory interface */
int32 Read (uint32 va, int32 lnt, int32 acc);
void Write (uint32 va, int32 val, int32 lnt, int32 acc);
/* Function prototypes for physical memory interface (inlined) */
SIM_INLINE int32 ReadB (uint32 pa);
SIM_INLINE int32 ReadW (uint32 pa);
SIM_INLINE int32 ReadL (uint32 pa);
SIM_INLINE int32 ReadLP (uint32 pa);
SIM_INLINE void WriteB (uint32 pa, int32 val);
SIM_INLINE void WriteW (uint32 pa, int32 val);
SIM_INLINE void WriteL (uint32 pa, int32 val);
void WriteLP (uint32 pa, int32 val);
/* Function prototypes for I/O */
int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf);
int32 Map_ReadW (uint32 ba, int32 bc, uint16 *buf);
int32 Map_WriteB (uint32 ba, int32 bc, uint8 *buf);
int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf);
t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, void *desc);
void sbi_set_errcnf (void);
int32 clk_cosched (int32 wait);
#include "pdp11_io_lib.h"
#endif

196
VAX/vax730_mem.c Normal file
View file

@ -0,0 +1,196 @@
/* vax730_mem.c: VAX 11/730 memory adapter
Copyright (c) 2010-2011, Matt Burke
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 the author shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author.
This module contains the VAX 11/730 memory controller registers.
mctl MS730 memory adapter
29-Mar-2011 MB First Version
*/
#include "vax_defs.h"
/* Memory adapter register 0 */
#define MCSR0_OF 0x00
#define MCSR0_ES 0x0000007F /* Error syndrome */
#define MCSR0_V_FPN 9
#define MCSR0_M_FPN 0x7FFF
#define MCSR0_FPN (MCSR0_M_FPN << MCSR0_V_FPN) /* Failing page number */
/* Memory adapter register 1 */
#define MCSR1_OF 0x01
#define MCSR1_RW 0x3E000000
#define MCSR1_MBZ 0x01FFFF80
/* Memory adapter register 2 */
#define MCSR2_OF 0x02
#define MCSR2_M_MAP 0xFFFF;
#define MCSR2_V_CS 24
#define MCSR2_CS (1u << MCSR2_V_CS)
#define MCSR2_MBZ 0xFEFF0000
/* Debug switches */
#define MCTL_DEB_RRD 0x01 /* reg reads */
#define MCTL_DEB_RWR 0x02 /* reg writes */
#define MEM_SIZE_16K (1u << 17) /* Board size (16k chips) */
#define MEM_SIZE_64K (1u << 19) /* Board size (64k chips) */
#define MEM_BOARD_MASK(x,y) ((1u << (uint32)(x/y)) - 1)
extern UNIT cpu_unit;
extern FILE *sim_log, *sim_deb;
uint32 mcsr0 = 0;
uint32 mcsr1 = 0;
uint32 mcsr2 = 0;
t_stat mctl_reset (DEVICE *dptr);
t_stat mctl_rdreg (int32 *val, int32 pa, int32 mode);
t_stat mctl_wrreg (int32 val, int32 pa, int32 mode);
/* MCTLx data structures
mctlx_dev MCTLx device descriptor
mctlx_unit MCTLx unit
mctlx_reg MCTLx register list
*/
DIB mctl_dib[] = { TR_MCTL, 0, &mctl_rdreg, &mctl_wrreg, 0 };
UNIT mctl_unit = { UDATA (NULL, 0, 0) };
REG mctl_reg[] = {
{ HRDATA (CSR0, mcsr0, 32) },
{ HRDATA (CSR1, mcsr1, 32) },
{ HRDATA (CSR2, mcsr2, 32) },
{ NULL }
};
MTAB mctl_mod[] = {
{ MTAB_XTD|MTAB_VDV, TR_MCTL, "NEXUS", NULL,
NULL, &show_nexus },
{ 0 }
};
DEBTAB mctl_deb[] = {
{ "REGREAD", MCTL_DEB_RRD },
{ "REGWRITE", MCTL_DEB_RWR },
{ NULL, 0 }
};
DEVICE mctl_dev = {
"MCTL", &mctl_unit, mctl_reg, mctl_mod,
1, 16, 16, 1, 16, 8,
NULL, NULL, &mctl_reset,
NULL, NULL, NULL,
&mctl_dib, DEV_NEXUS | DEV_DEBUG, 0,
mctl_deb, 0, 0
};
/* Memory controller register read */
t_stat mctl_rdreg (int32 *val, int32 pa, int32 lnt)
{
int32 ofs;
ofs = NEXUS_GETOFS (pa); /* get offset */
switch (ofs) { /* case on offset */
case MCSR0_OF: /* CSR0 */
*val = mcsr0;
break;
case MCSR1_OF: /* CSR1 */
*val = mcsr1 & ~MCSR1_MBZ;
break;
case MCSR2_OF: /* CSR2 */
*val = mcsr2 & ~MCSR2_MBZ;
break;
default:
return SCPE_NXM;
}
if (DEBUG_PRI (mctl_dev, MCTL_DEB_RRD))
fprintf (sim_deb, ">>MCTL: reg %d read, value = %X\n", ofs, *val);
return SCPE_OK;
}
/* Memory controller register write */
t_stat mctl_wrreg (int32 val, int32 pa, int32 lnt)
{
int32 ofs;
ofs = NEXUS_GETOFS (pa); /* get offset */
switch (ofs) { /* case on offset */
case MCSR0_OF: /* CSR0 */
break;
case MCSR1_OF: /* CSR1 */
mcsr1 = val & MCSR1_RW;
break;
case MCSR2_OF: /* CSR2 */
break;
default:
return SCPE_NXM;
}
if (DEBUG_PRI (mctl_dev, MCTL_DEB_RWR))
fprintf (sim_deb, ">>MCTL: reg %d write, value = %X\n", ofs, val);
return SCPE_OK;
}
/* Used by CPU and loader */
void rom_wr_B (int32 pa, int32 val)
{
return;
}
/* MEMCTL reset */
t_stat mctl_reset (DEVICE *dptr)
{
mcsr0 = 0;
mcsr1 = 0;
mcsr2 = 0;
if (MEMSIZE > MAXMEMSIZE) /* More than 2MB? */
mcsr2 = mcsr2 | MEM_BOARD_MASK(MEMSIZE, MEM_SIZE_64K) | MCSR2_CS; /* Use 64k chips */
else
mcsr2 = mcsr2 | MEM_BOARD_MASK(MEMSIZE, MEM_SIZE_16K); /* Use 16k chips */
return SCPE_OK;
}

670
VAX/vax730_rb.c Normal file
View file

@ -0,0 +1,670 @@
/* vax730_rb.c: RB730 disk simulator
Copyright (c) 2010-2011, Matt Burke
This module incorporates code from SimH, Copyright (c) 1993-2008, 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
THE AUTHOR(S) 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(s) of the author(s) shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author(s).
rb RB730 - RB02/RB80 disk controller
29-Mar-2011 MB First Version
The RB730 is a four drive disk subsystem consisting of up to three RL02
drives (known as RB02) and one optional RA80 drive (known as RB80).
Unlike the RL11 controller seeks are not done relative to the current
disk address.
The RB730 has two regiter address spaces:
- One dummy 16-bit register in unibus I/O space to allow the controller to
be detected by SYSGEN autoconfigure (and others).
- Eight 32-bit registers in the unibus controller space for the actual
device control.
*/
#include "vax_defs.h"
/* Constants */
#define RB02_NUMWD 128 /* words/sector */
#define RB02_NUMSC 40 /* sectors/track */
#define RB02_NUMSF 2 /* tracks/cylinder */
#define RB02_NUMCY 512 /* cylinders/drive */
#define RB02_SIZE (RB02_NUMCY * RB02_NUMSF * \
RB02_NUMSC * RB02_NUMWD) /* words/drive */
#define RB80_NUMWD 256 /* words/sector */
#define RB80_NUMSC 32 /* sectors/track */
#define RB80_NUMSF 14 /* tracks/cylinder */
#define RB80_NUMCY 559 /* cylinders/drive */
#define RB80_SIZE (RB80_NUMCY * RB80_NUMSF * \
RB80_NUMSC * RB80_NUMWD) /* words/drive */
#define RB_NUMWD(u) ((u->flags & UNIT_RB80) ? RB80_NUMWD : RB02_NUMWD)
#define RB_NUMSC(u) ((u->flags & UNIT_RB80) ? RB80_NUMSC : RB02_NUMSC)
#define RB_NUMSF(u) ((u->flags & UNIT_RB80) ? RB80_NUMSF : RB02_NUMSF)
#define RB_NUMCY(u) ((u->flags & UNIT_RB80) ? RB80_NUMCY : RB02_NUMCY)
#define RB_SIZE(u) ((u->flags & UNIT_RB80) ? RB80_SIZE : RB02_SIZE)
#define RB_NUMDR 4 /* drives/controller */
#define RB_MAXFR (1 << 16) /* max transfer */
/* Flags in the unit flags word */
#define UNIT_V_WLK (UNIT_V_UF + 0) /* hwre write lock */
#define UNIT_V_RB80 (UNIT_V_UF + 1) /* RB02 vs RB80 */
#define UNIT_V_DUMMY (UNIT_V_UF + 2) /* dummy flag */
#define UNIT_DUMMY (1 << UNIT_V_DUMMY)
#define UNIT_WLK (1u << UNIT_V_WLK)
#define UNIT_RB80 (1u << UNIT_V_RB80)
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protected */
/* Parameters in the unit descriptor */
#define TRK u3 /* current track */
#define STAT u4 /* status */
#define SIP u5 /* seek in progress */
/* RBDS, NI = not implemented, * = kept in STAT, ^ = kept in TRK */
#define RB02DS_LOAD 0 /* no cartridge */
#define RB02DS_LOCK 5 /* lock on */
#define RB02DS_BHO 0000010 /* brushes home NI */
#define RB02DS_HDO 0000020 /* heads out NI */
#define RB02DS_CVO 0000040 /* cover open NI */
#define RB02DS_HD 0000100 /* head select ^ */
#define RB02DS_DSE 0000400 /* drv sel err NI */
#define RB02DS_VCK 0001000 /* vol check * */
#define RB02DS_WGE 0002000 /* wr gate err * */
#define RB02DS_SPE 0004000 /* spin err * */
#define RB02DS_STO 0010000 /* seek time out NI */
#define RB02DS_WLK 0020000 /* wr locked */
#define RB02DS_HCE 0040000 /* hd curr err NI */
#define RB02DS_WDE 0100000 /* wr data err NI */
#define RB02DS_ATT (RB02DS_HDO+RB02DS_BHO+RB02DS_LOCK) /* att status */
#define RB02DS_UNATT (RB02DS_CVO+RB02DS_LOAD) /* unatt status */
#define RB02DS_ERR (RB02DS_WDE+RB02DS_HCE+RB02DS_STO+RB02DS_SPE+RB02DS_WGE+ \
RB02DS_VCK+RB02DS_DSE) /* errors bits */
#define RB80DS_SCNT 0x0000000F
#define RB80DS_FLT 0x00000100
#define RB80DS_PLV 0x00000200
#define RB80DS_SKE 0x00000400
#define RB80DS_OCY 0x00000800
#define RB80DS_RDY 0x00001000
#define RB80DS_WLK 0x00002000
/* RBCS */
#define RBCS_DRDY 0x00000001 /* drive ready */
#define RBCS_M_FUNC 0x7 /* function */
#define RBCS_NOP 0
#define RBCS_WCHK 1
#define RBCS_GSTA 2
#define RBCS_SEEK 3
#define RBCS_RHDR 4
#define RBCS_WRITE 5
#define RBCS_READ 6
#define RBCS_RNOHDR 7
#define RBCS_V_FUNC 1
#define RBCS_M_DRIVE 0x3
#define RBCS_V_DRIVE 8
#define RBCS_INCMP 0x00000400 /* incomplete */
#define RBCS_CRC 0x00000800 /* CRC error */
#define RBCS_DLT 0x00001000 /* data late */
#define RBCS_HDE 0x00001400 /* header error */
#define RBCS_NXM 0x00002000 /* non-exist memory */
#define RBCS_DRE 0x00004000 /* drive error */
#define RBCS_ERR 0x00008000 /* error summary */
#define RBCS_ALLERR (RBCS_ERR+RBCS_DRE+RBCS_NXM+RBCS_CRC+RBCS_INCMP)
#define RBCS_M_ATN 0xF
#define RBCS_V_ATN 16
#define RBCS_ATN (RBCS_M_ATN << RBCS_V_ATN)
#define RBCS_M_ECC 0x2
#define RBCS_V_ECC 20
#define RBCS_SSI 0x00400000
#define RBCS_SSE 0x00800000
#define RBCS_IRQ 0x01000000
#define RBCS_MTN 0x02000000
#define RBCS_R80 0x04000000
#define RBCS_ASI 0x08000000
#define RBCS_TOI 0x10000000
#define RBCS_FMT 0x20000000
#define RBCS_MATN 0x80000000
//#define RBCS_RW 0001716 /* read/write */
#define RBCS_RW ((RBCS_M_FUNC << RBCS_V_FUNC) + \
CSR_IE + CSR_DONE + \
(RBCS_M_DRIVE << RBCS_V_DRIVE) + \
RBCS_SSI + RBCS_MTN + RBCS_ASI + \
RBCS_TOI + RBCS_FMT + RBCS_MATN)
#define RBCS_C0 RBCS_SSE
#define RBCS_C1 (rbcs & RBCS_MATN) ? RBCS_IRQ : \
((RBCS_M_ATN << RBCS_V_ATN) + RBCS_IRQ)
#define GET_FUNC(x) (((x) >> RBCS_V_FUNC) & RBCS_M_FUNC)
#define GET_DRIVE(x) (((x) >> RBCS_V_DRIVE) & RBCS_M_DRIVE)
/* RBBA */
#define RBBA_RW 0x0003FFFF
/* RBBC */
/* RBMP */
#define RBMP_MRK 0x00000001
#define RBMP_GST 0x00000002
#define RBMP_RST 0x00000008
/* RBDA */
#define RBDA_V_SECT 0 /* sector */
#define RBDA_M_SECT 0xFF
#define RBDA_V_TRACK 8 /* track */
#define RBDA_M_TRACK 0xFF
#define RBDA_V_CYL 16 /* cylinder */
#define RBDA_M_CYL 0xFFFF
#define RBDA_TRACK (RBDA_M_TRACK << RBDA_V_TRACK)
#define RBDA_CYL (RBDA_M_CYL << RBDA_V_CYL)
#define GET_SECT(x) (((x) >> RBDA_V_SECT) & RBDA_M_SECT)
#define GET_CYL(x) (((x) >> RBDA_V_CYL) & RBDA_M_CYL)
#define GET_TRACK(x) (((x) >> RBDA_V_TRACK) & RBDA_M_TRACK)
//#define GET_DA(x) ((GET_CYL(x) * RB02_NUMSF * GET_TRACK (x) * RB02_NUMSC) + GET_SECT (x))
#define GET_DA(x,u) ((GET_TRACK (x) * RB_NUMCY(u) * RB_NUMSC(u) * RB_NUMWD(u)) + \
(GET_CYL(x) * RB_NUMSC(u) * RB_NUMWD(u)) + \
(GET_SECT (x) * RB_NUMWD(u)))
#define DBG_REG 0x0001 /* registers */
#define DBG_CMD 0x0002 /* commands */
#define DBG_RD 0x0004 /* disk reads */
#define DBG_WR 0x0008 /* disk writes */
extern int32 int_req[IPL_HLVL];
uint16 *rbxb = NULL; /* xfer buffer */
int32 rbcs = 0; /* control/status */
int32 rbba = 0; /* memory address */
int32 rbbc = 0; /* bytes count */
int32 rbda = 0; /* disk addr */
int32 rbmp = 0, rbmp1 = 0, rbmp2 = 0; /* mp register queue */
int32 rb_swait = 150; /* seek wait */
int32 rb_mwait = 300; /* seek wait */
int32 rb_cwait = 50; /* seek wait */
t_stat rb_rd16 (int32 *data, int32 PA, int32 access);
t_stat rb_wr16 (int32 data, int32 PA, int32 access);
t_stat rb_rd32 (int32 *data, int32 PA, int32 access);
t_stat rb_wr32 (int32 data, int32 PA, int32 access);
t_stat rb_svc (UNIT *uptr);
t_stat rb_reset (DEVICE *dptr);
void rb_set_done (int32 error);
t_stat rb_attach (UNIT *uptr, char *cptr);
t_stat rb_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat rb_set_bad (UNIT *uptr, int32 val, char *cptr, void *desc);
/* RB730 data structures
rb_dev RB device descriptor
rb_unit RB unit list
rb_reg RB register list
rb_mod RB modifier list
*/
DIB rb_dib = {
IOBA_RB, IOLN_RB, &rb_rd16, &rb_wr16,
1, IVCL (RB), VEC_RB, { NULL } };
UNIT rb_unit[] = {
{ UDATA (&rb_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
UNIT_ROABLE+UNIT_RB80, RB80_SIZE) },
{ UDATA (&rb_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
UNIT_ROABLE, RB02_SIZE) },
{ UDATA (&rb_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
UNIT_ROABLE, RB02_SIZE) },
{ UDATA (&rb_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
UNIT_ROABLE, RB02_SIZE) },
};
REG rb_reg[] = {
{ NULL }
};
DEBTAB rb_debug[] = {
{"REG", DBG_REG},
{"CMD", DBG_CMD},
{"RD", DBG_RD},
{"WR", DBG_WR},
{0}
};
MTAB rb_mod[] = {
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
{ UNIT_DUMMY, 0, NULL, "BADBLOCK", &rb_set_bad },
{ (UNIT_RB80+UNIT_ATT), UNIT_ATT, "RB02", NULL, NULL },
{ (UNIT_RB80+UNIT_ATT), (UNIT_RB80+UNIT_ATT), "RB80", NULL, NULL },
{ (UNIT_RB80+UNIT_ATT), 0, "RB02", NULL, NULL },
{ (UNIT_RB80+UNIT_ATT), UNIT_RB80, "RB80", NULL, NULL },
{ (UNIT_RB80), 0, NULL, "RB02", &rb_set_size },
{ (UNIT_RB80), UNIT_RB80, NULL, "RB80", &rb_set_size },
{ MTAB_XTD|MTAB_VDV, 010, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL },
{ 0 }
};
DEVICE rb_dev = {
"RB", rb_unit, rb_reg, rb_mod,
RB_NUMDR, DEV_RDX, T_ADDR_W, 1, DEV_RDX, 16,
NULL, NULL, &rb_reset,
NULL, &rb_attach, NULL,
&rb_dib, DEV_DISABLE | DEV_UBUS | DEV_DEBUG, 0,
rb_debug, 0, 0
};
/* I/O dispatch routines
17775606 RBDCS dummy csr to trigger sysgen
*/
t_stat rb_rd16 (int32 *data, int32 PA, int32 access)
{
*data = 0;
return SCPE_OK;
}
t_stat rb_wr16 (int32 data, int32 PA, int32 access)
{
return SCPE_OK;
}
t_stat rb_rd32 (int32 *data, int32 PA, int32 access)
{
UNIT *uptr;
switch ((PA >> 2) & 07) {
case 0: /* RBCS */
if (rbcs & RBCS_ALLERR)
rbcs = rbcs | RBCS_ERR;
uptr = rb_dev.units + GET_DRIVE (rbcs);
if ((sim_is_active (uptr)) || (uptr->flags & UNIT_DIS))
rbcs = rbcs & ~RBCS_DRDY;
else rbcs = rbcs | RBCS_DRDY; /* see if ready */
if (uptr->flags & UNIT_RB80)
rbcs = rbcs | RBCS_R80;
else rbcs = rbcs & ~RBCS_R80;
*data = rbcs;
break;
case 1: /* RBBA */
*data = rbba & RBBA_RW;
break;
case 2: /* RBBC */
*data = rbbc;
break;
case 3: /* RBDA */
*data = rbda;
break;
case 4: /* RBMP */
*data = rbmp;
rbmp = rbmp1; /* ripple data */
rbmp1 = rbmp2;
break;
case 5: /* ECCPS */
case 6: /* ECCPT */
case 7: /* INIT */
*data = 0;
break;
}
sim_debug(DBG_REG, &rb_dev, "reg %d read, value = %X\n", (PA >> 2) & 07, *data);
return SCPE_OK;
}
t_stat rb_wr32 (int32 data, int32 PA, int32 access)
{
UNIT *uptr;
sim_debug(DBG_REG, &rb_dev, "reg %d write, value = %X\n", (PA >> 2) & 07, data);
switch ((PA >> 2) & 07) {
case 0: /* CSR */
if (rbcs & RBCS_ALLERR)
rbcs = rbcs | RBCS_ERR;
uptr = rb_dev.units + GET_DRIVE (data);
if ((sim_is_active (uptr)) || (uptr->flags & UNIT_DIS))
rbcs = rbcs & ~RBCS_DRDY;
else rbcs = rbcs | RBCS_DRDY; /* see if ready */
if (uptr->flags & UNIT_RB80)
rbcs = rbcs | RBCS_R80;
else rbcs = rbcs & ~RBCS_R80;
rbcs = rbcs & ~(data & RBCS_C1);
rbcs = rbcs & ~(~data & RBCS_C0);
rbcs = (rbcs & ~RBCS_RW) | (data & RBCS_RW);
if (data & RBCS_ATN) CLR_INT (RB);
if ((data & CSR_DONE) || (sim_is_active (uptr))) /* ready set? */
return SCPE_OK;
CLR_INT (RB); /* clear interrupt */
rbcs = rbcs & ~RBCS_ALLERR; /* clear errors */
uptr->SIP = 0;
if (uptr->flags & UNIT_DIS) {
rbcs = rbcs | (1u << (RBCS_V_ATN + GET_DRIVE (rbcs)));
rb_set_done (RBCS_ERR | RBCS_INCMP);
break;
}
switch (GET_FUNC (rbcs)) { /* case on RBCS<3:1> */
case RBCS_NOP: /* nop */
rb_set_done (0);
break;
case RBCS_SEEK: /* seek */
sim_activate (uptr, rb_swait);
break;
default: /* data transfer */
sim_activate (uptr, rb_cwait); /* activate unit */
break;
} /* end switch func */
break;
case 1: /* BAR */
rbba = data & RBBA_RW;
break;
case 2: /* BCR */
rbbc = data;
break;
case 3: /* DAR */
rbda = data;
break;
case 4: /* MPR */
rbmp = rbmp1 = rbmp2 = data;
break;
case 5: /* ECCPS */
case 6: /* ECCPT */
break;
case 7: /* INIT */
return rb_reset(&rb_dev);
}
return SCPE_OK;
}
/* Service unit timeout
If seek in progress, complete seek command
Else complete data transfer command
The unit control block contains the function and cylinder for
the current command.
*/
t_stat rb_svc (UNIT *uptr)
{
int32 curr, newc, swait;
int32 err, wc, maxwc, t;
int32 i, func, da, awc;
uint32 ma;
uint16 comp;
func = GET_FUNC (rbcs); /* get function */
if (func == RBCS_GSTA) { /* get status */
sim_debug(DBG_CMD, &rb_dev, "Get Status\n");
if (uptr->flags & UNIT_RB80) {
rbmp = uptr->STAT | RB80DS_PLV;
if (uptr->flags & UNIT_ATT)
rbmp = rbmp | RB80DS_RDY | RB80DS_OCY;
if (uptr->flags & UNIT_WPRT)
rbmp = rbmp | RB80DS_WLK;
}
else {
if (rbmp & RBMP_RST)
uptr->STAT = uptr->STAT & ~RB02DS_ERR;
rbmp = uptr->STAT | (uptr->flags & UNIT_ATT)? RB02DS_ATT: RB02DS_UNATT;
if (uptr->flags & UNIT_WPRT)
rbmp = rbmp | RB02DS_WLK;
}
rbmp2 = rbmp1 = rbmp;
rb_set_done (0); /* done */
return SCPE_OK;
}
if (func == RBCS_RHDR) { /* read header? */
sim_debug(DBG_CMD, &rb_dev, "Read Header\n");
rbmp = (uptr->TRK & RBDA_TRACK) | GET_SECT (rbda);
rbmp1 = rbmp2 = 0;
rbcs = rbcs | (1 << (RBCS_V_ATN + GET_DRIVE (rbcs)));
rb_set_done (0); /* done */
return SCPE_OK;
}
if ((uptr->flags & UNIT_ATT) == 0) { /* attached? */
rbcs = rbcs & ~RBCS_DRDY; /* clear drive ready */
rbcs = rbcs | (1u << (RBCS_V_ATN + GET_DRIVE (rbcs)));
if ((uptr->flags & UNIT_RB80) == 0)
uptr->STAT = uptr->STAT | RB02DS_SPE; /* spin error */
rb_set_done (RBCS_ERR | RBCS_INCMP); /* flag error */
//return IORETURN (rl_stopioe, SCPE_UNATT);
return SCPE_OK;
}
if ((func == RBCS_WRITE) && (uptr->flags & UNIT_WPRT)) {
if ((uptr->flags & UNIT_RB80) == 0)
uptr->STAT = uptr->STAT | RB02DS_WGE; /* write and locked */
rb_set_done (RBCS_ERR | RBCS_DRE);
return SCPE_OK;
}
if (func == RBCS_SEEK) { /* seek? */
if (uptr->SIP == 0) {
sim_debug(DBG_CMD, &rb_dev, "Seek, CYL=%d, TRK=%d, SECT=%d\n", GET_CYL(rbda), GET_TRACK(rbda), GET_SECT(rbda));
uptr->SIP = 1;
if (rbda == 0xFFFFFFFF) swait = rb_swait;
else {
curr = GET_CYL (uptr->TRK); /* current cylinder */
newc = GET_CYL (rbda); /* offset */
uptr->TRK = (newc << RBDA_V_CYL); /* put on track */
swait = rb_cwait * abs (newc - curr);
if (swait < rb_mwait) swait = rb_mwait;
}
sim_activate (uptr, swait);
rbcs = rbcs | (1 << (RBCS_V_ATN + GET_DRIVE (rbcs)));
rbcs = rbcs | RBCS_IRQ;
rb_set_done(0);
return SCPE_OK;
}
else {
sim_debug(DBG_CMD, &rb_dev, "Seek done\n");
rbcs = rbcs | (1 << (RBCS_V_ATN + GET_DRIVE (rbcs)));
uptr->SIP = 0;
rb_set_done (0); /* done */
return SCPE_OK;
}
}
if (((func != RBCS_RNOHDR) && ((uptr->TRK & RBDA_CYL) != (rbda & RBDA_CYL)))
|| (GET_SECT (rbda) >= RB_NUMSC(uptr))) { /* bad cyl or sector? */
sim_debug(DBG_CMD, &rb_dev, "Invalid cylinder or sector, CYL=%d, TRK=%d, SECT=%d\n", GET_CYL(rbda), GET_TRACK(rbda), GET_SECT(rbda));
rb_set_done (RBCS_ERR | RBCS_HDE | RBCS_INCMP); /* wrong cylinder? */
return SCPE_OK;
}
ma = rbba; /* get mem addr */
da = GET_DA (rbda, uptr); /* get disk addr */
wc = ((rbbc * -1) >> 1); /* get true wc */
maxwc = (RB_NUMSC(uptr) - GET_SECT (rbda)) * RB_NUMWD(uptr); /* max transfer */
if (wc > maxwc) /* track overrun? */
wc = maxwc;
err = sim_fseek (uptr->fileref, da * sizeof (int16), SEEK_SET);
if ((func >= RBCS_READ) && (err == 0)) { /* read (no hdr)? */
sim_debug(DBG_CMD, &rb_dev, "Read, CYL=%d, TRK=%d, SECT=%d, WC=%d, DA=%d\n", GET_CYL(rbda), GET_TRACK(rbda), GET_SECT(rbda), wc, da);
i = sim_fread (rbxb, sizeof (uint16), wc, uptr->fileref);
err = ferror (uptr->fileref);
for ( ; i < wc; i++) /* fill buffer */
rbxb[i] = 0;
if (t = Map_WriteW (ma, wc << 1, rbxb)) { /* store buffer */
rbcs = rbcs | RBCS_ERR | RBCS_NXM; /* nxm */
wc = wc - t; /* adjust wc */
}
} /* end read */
if ((func == RBCS_WRITE) && (err == 0)) { /* write? */
sim_debug(DBG_CMD, &rb_dev, "Write, CYL=%d, TRK=%d, SECT=%d, WC=%d, DA=%d\n", GET_CYL(rbda), GET_TRACK(rbda), GET_SECT(rbda), wc, da);
if (t = Map_ReadW (ma, wc << 1, rbxb)) { /* fetch buffer */
rbcs = rbcs | RBCS_ERR | RBCS_NXM; /* nxm */
wc = wc - t; /* adj xfer lnt */
}
if (wc) { /* any xfer? */
awc = (wc + (RB_NUMWD(uptr) - 1)) & ~(RB_NUMWD(uptr) - 1); /* clr to */
for (i = wc; i < awc; i++) /* end of blk */
rbxb[i] = 0;
sim_fwrite (rbxb, sizeof (uint16), awc, uptr->fileref);
err = ferror (uptr->fileref);
}
} /* end write */
if ((func == RBCS_WCHK) && (err == 0)) { /* write check? */
sim_debug(DBG_CMD, &rb_dev, "WCheck, CYL=%d, TRK=%d, SECT=%d, WC=%d, DA=%d\n", GET_CYL(rbda), GET_TRACK(rbda), GET_SECT(rbda), wc, da);
i = sim_fread (rbxb, sizeof (uint16), wc, uptr->fileref);
err = ferror (uptr->fileref);
for ( ; i < wc; i++) /* fill buffer */
rbxb[i] = 0;
awc = wc; /* save wc */
for (wc = 0; (err == 0) && (wc < awc); wc++) { /* loop thru buf */
if (Map_ReadW (ma + (wc << 1), 2, &comp)) { /* mem wd */
rbcs = rbcs | RBCS_ERR | RBCS_NXM; /* nxm */
break;
}
if (comp != rbxb[wc]) /* check to buf */
rbcs = rbcs | RBCS_ERR | RBCS_CRC;
} /* end for */
} /* end wcheck */
rbbc = (rbbc + (wc << 1)); /* final byte count */
if (rbbc != 0) { /* completed? */
rbcs = rbcs | RBCS_ERR | RBCS_INCMP;
}
ma = ma + (wc << 1); /* final byte addr */
rbba = ma & RBBA_RW;
rbda = rbda + ((wc + (RB_NUMWD(uptr) - 1)) / RB_NUMWD(uptr));
rb_set_done (0);
if (err != 0) { /* error? */
perror ("RB I/O error");
clearerr (uptr->fileref);
return SCPE_IOERR;
}
return SCPE_OK;
}
/* Set done and possibly errors */
void rb_set_done (int32 status)
{
rbcs = rbcs | status | CSR_DONE; /* set done */
rbcs = rbcs | RBCS_IRQ;
if (rbcs & CSR_IE) {
sim_debug(DBG_CMD, &rb_dev, "Done, INT\n");
SET_INT (RB);
}
else {
sim_debug(DBG_CMD, &rb_dev, "Done, no INT\n");
CLR_INT (RB);
}
return;
}
/* Device reset */
t_stat rb_reset (DEVICE *dptr)
{
int32 i;
UNIT *uptr;
rbcs = CSR_DONE;
rbda = rbba = rbbc = rbmp = 0;
CLR_INT (RB);
for (i = 0; i < RB_NUMDR; i++) {
uptr = rb_dev.units + i;
sim_cancel (uptr);
uptr->STAT = 0;
uptr->SIP = 0;
}
if (rbxb == NULL)
rbxb = (uint16 *) calloc (RB_MAXFR, sizeof (uint16));
if (rbxb == NULL)
return SCPE_MEM;
return SCPE_OK;
}
/* Attach routine */
t_stat rb_attach (UNIT *uptr, char *cptr)
{
uint32 p;
t_stat r;
uptr->capac = (uptr->flags & UNIT_RB80)? RB80_SIZE: RB02_SIZE;
r = attach_unit (uptr, cptr); /* attach unit */
if (r != SCPE_OK) /* error? */
return r;
uptr->TRK = 0; /* cylinder 0 */
if ((uptr->flags & UNIT_RB80) == 0)
uptr->STAT = RB02DS_VCK; /* new volume */
if ((p = sim_fsize (uptr->fileref)) == 0) { /* new disk image? */
if (uptr->flags & UNIT_RO) /* if ro, done */
return SCPE_OK;
return pdp11_bad_block (uptr, RB_NUMSC(uptr), RB_NUMWD(uptr));
}
return SCPE_OK;
}
/* Set size routine */
t_stat rb_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (uptr->flags & UNIT_ATT)
return SCPE_ALATT;
uptr->capac = (val & UNIT_RB80)? RB80_SIZE: RB02_SIZE;
return SCPE_OK;
}
/* Set bad block routine */
t_stat rb_set_bad (UNIT *uptr, int32 val, char *cptr, void *desc)
{
return pdp11_bad_block (uptr, RB_NUMSC(uptr), RB_NUMWD(uptr));
}

1107
VAX/vax730_stddev.c Normal file

File diff suppressed because it is too large Load diff

665
VAX/vax730_sys.c Normal file
View file

@ -0,0 +1,665 @@
/* vax730_sys.c: VAX 11/730 system-specific logic
Copyright (c) 2010-2011, Matt Burke
This module incorporates code from SimH, Copyright (c) 2004-2008, 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
THE AUTHOR(S) 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(s) of the author(s) shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author(s).
This module contains the VAX 11/730 system-specific registers and devices.
sysb system bus controller
29-Mar-2011 MB First Version
*/
#include "vax_defs.h"
#ifndef DONT_USE_INTERNAL_ROM
#include "vax780_vmb_exe.h"
#endif
static char cpu_boot_cmd[CBUFSIZE] = { 0 }; /* boot command */
/* VAX-11/730 boot device definitions */
struct boot_dev {
char *name;
int32 code;
int32 let;
};
static t_stat (*nexusR[NEXUS_NUM])(int32 *dat, int32 ad, int32 md);
static t_stat (*nexusW[NEXUS_NUM])(int32 dat, int32 ad, int32 md);
static struct boot_dev boot_tab[] = {
{ "HK", BOOT_HK, 0 },
{ "RL", BOOT_RL, 0 },
{ "RQ", BOOT_UDA, 1 << 24 },
{ "RQB", BOOT_UDA, 1 << 24 },
{ "RQC", BOOT_UDA, 1 << 24 },
{ "RQD", BOOT_UDA, 1 << 24 },
{ "TQ", BOOT_TK, 1 << 24 },
{ "TD", BOOT_TD, 0 },
{ "RB", BOOT_RB, 0 },
{ NULL }
};
extern int32 R[16];
extern int32 PSL;
extern int32 ASTLVL, SISR;
extern int32 mapen, pme, trpirq;
extern int32 in_ie;
extern int32 mchk_va, mchk_ref;
extern int32 crd_err, mem_err, hlt_pin;
extern int32 tmr_int, tti_int, tto_int, csi_int, cso_int;
extern jmp_buf save_env;
extern int32 p1;
extern int32 sim_switches;
extern DEVICE *sim_devices[];
extern FILE *sim_log;
extern CTAB *sim_vm_cmd;
t_stat sysb_reset (DEVICE *dptr);
t_stat vax730_boot (int32 flag, char *ptr);
t_stat vax730_boot_parse (int32 flag, char *ptr);
t_stat cpu_boot (int32 unitno, DEVICE *dptr);
extern int32 intexc (int32 vec, int32 cc, int32 ipl, int ei);
extern int32 iccs_rd (void);
extern int32 nicr_rd (void);
extern int32 icr_rd (t_bool interp);
extern int32 todr_rd (void);
extern int32 rxcs_rd (void);
extern int32 rxdb_rd (void);
extern int32 txcs_rd (void);
extern int32 csrs_rd (void);
extern int32 csrd_rd (void);
extern int32 csts_rd (void);
extern void iccs_wr (int32 dat);
extern void nicr_wr (int32 dat);
extern void todr_wr (int32 dat);
extern void rxcs_wr (int32 dat);
extern void txcs_wr (int32 dat);
extern void txdb_wr (int32 dat);
extern void csrs_wr (int32 dat);
extern void csts_wr (int32 dat);
extern void cstd_wr (int32 dat);
extern void init_ubus_tab (void);
extern t_stat build_ubus_tab (DEVICE *dptr, DIB *dibp);
extern int32 ubamap_rd (int32 pa);
extern void ubamap_wr (int32 pa, int32 val, int32 lnt);
extern t_bool uba_eval_int (int32 lvl);
extern int32 uba_get_ubvector (int32 lvl);
/* SYSB data structures
sysb_dev SYSB device descriptor
sysb_unit SYSB unit
sysb_reg SYSB register list
*/
UNIT sysb_unit = { UDATA (NULL, 0, 0) };
REG sysb_reg[] = {
{ BRDATA (BOOTCMD, cpu_boot_cmd, 16, 8, CBUFSIZE), REG_HRO },
{ NULL }
};
DEVICE sysb_dev = {
"SYSB", &sysb_unit, sysb_reg, NULL,
1, 16, 16, 1, 16, 8,
NULL, NULL, &sysb_reset,
NULL, NULL, NULL,
NULL, 0
};
/* Special boot command, overrides regular boot */
CTAB vax730_cmd[] = {
{ "BOOT", &vax730_boot, RU_BOOT,
"bo{ot} <device>{/R5:flg} boot device\n" },
{ NULL }
};
/* The VAX 11/730 has two sources of interrupts
- internal device interrupts (CPU, console, clock, console storage)
- external device interrupts (Unibus)
/* Find highest priority vectorable interrupt */
int32 eval_int (void)
{
int32 ipl = PSL_GETIPL (PSL);
int32 i, t;
static const int32 sw_int_mask[IPL_SMAX] = {
0xFFFE, 0xFFFC, 0xFFF8, 0xFFF0, /* 0 - 3 */
0xFFE0, 0xFFC0, 0xFF80, 0xFF00, /* 4 - 7 */
0xFE00, 0xFC00, 0xF800, 0xF000, /* 8 - B */
0xE000, 0xC000, 0x8000 /* C - E */
};
if (hlt_pin) /* hlt pin int */
return IPL_HLTPIN;
if ((ipl < IPL_CLKINT) && tmr_int) /* clock int */
return IPL_CLKINT;
for (i = IPL_HMAX; i >= IPL_HMIN; i--) { /* chk hwre int */
if (i <= ipl) /* at ipl? no int */
return 0;
if (uba_eval_int(i - IPL_HMIN))
return i;
}
if ((ipl < IPL_TTINT) && (tti_int || tto_int)) /* console int */
return IPL_TTINT;
if ((ipl < IPL_CSINT) && (csi_int || cso_int)) /* console storage int */
return IPL_CSINT;
if (ipl >= IPL_SMAX) /* ipl >= sw max? */
return 0;
if ((t = SISR & sw_int_mask[ipl]) == 0) /* eligible req */
return 0;
for (i = IPL_SMAX; i > ipl; i--) { /* check swre int */
if ((t >> i) & 1) /* req != 0? int */
return i;
}
return 0;
}
/* Return vector for highest priority hardware interrupt at IPL lvl */
int32 get_vector (int32 lvl)
{
int32 l;
if (lvl == IPL_CLKINT) { /* clock? */
tmr_int = 0; /* clear req */
return SCB_INTTIM; /* return vector */
}
if (lvl > IPL_HMAX) { /* error req lvl? */
ABORT (STOP_UIPL); /* unknown intr */
}
if ((lvl <= IPL_HMAX) && (lvl >= IPL_HMIN)) { /* nexus? */
l = lvl - IPL_HMIN;
if (uba_eval_int(l))
return uba_get_ubvector(l);
}
if (lvl == IPL_TTINT) { /* console? */
if (tti_int) { /* input? */
tti_int = 0; /* clear req */
return SCB_TTI; /* return vector */
}
if (tto_int) { /* output? */
tto_int = 0; /* clear req */
return SCB_TTO; /* return vector */
}
}
if (lvl == IPL_CSINT) { /* console storage? */
if (csi_int) { /* input? */
csi_int = 0; /* clear req */
return SCB_CSI; /* return vector */
}
if (cso_int) { /* output? */
cso_int = 0; /* clear req */
return SCB_CSO; /* return vector */
}
}
return 0;
}
/* Read 730-specific IPR's */
int32 ReadIPR (int32 rg)
{
int32 val;
switch (rg) {
case MT_ICCS: /* ICCS */
val = iccs_rd ();
break;
case MT_NICR: /* NICR */
val = nicr_rd ();
break;
case MT_ICR: /* ICR */
val = icr_rd (FALSE);
break;
case MT_TODR: /* TODR */
val = todr_rd ();
break;
case MT_ACCS: /* ACCS (not impl) */
val = 0;
break;
case MT_RXCS: /* RXCS */
val = rxcs_rd ();
break;
case MT_RXDB: /* RXDB */
val = rxdb_rd ();
break;
case MT_TXCS: /* TXCS */
val = txcs_rd ();
break;
case MT_SID: /* SID */
val = VAX730_SID | VAX730_MICRO;
break;
case MT_MCESR: /* MCESR (not impl) */
val = 0;
break;
case MT_CSRS: /* CSRS */
val = csrs_rd ();
break;
case MT_CSRD: /* CSRD */
val = csrd_rd ();
break;
case MT_CSTS: /* CSTS */
val = csts_rd ();
break;
case MT_CDR: /* CDR */
case MT_SBIFS: /* SBIFS */
case MT_SBIS: /* SBIS */
case MT_SBISC: /* SBISC */
case MT_SBIMT: /* SBIMT */
case MT_SBIER: /* SBIER */
case MT_SBITA: /* SBITA */
val = 0;
break;
default:
RSVD_OPND_FAULT;
}
return val;
}
/* Write 730-specific IPR's */
void WriteIPR (int32 rg, int32 val)
{
switch (rg) {
case MT_ICCS: /* ICCS */
iccs_wr (val);
break;
case MT_NICR: /* NICR */
nicr_wr (val);
break;
case MT_TODR: /* TODR */
todr_wr (val);
break;
case MT_ACCS: /* ACCS (not impl) */
break;
case MT_RXCS: /* RXCS */
rxcs_wr (val);
break;
case MT_TXCS: /* TXCS */
txcs_wr (val);
break;
case MT_TXDB: /* TXDB */
txdb_wr (val);
break;
case MT_MCESR: /* MCESR (not impl) */
break;
case MT_UBINIT: /* UBINIT (not impl) */
break;
case MT_CSRS: /* CSRS */
csrs_wr (val);
break;
case MT_CSTS: /* CSTS */
csts_wr (val);
break;
case MT_CSTD: /* CSTD */
cstd_wr (val);
break;
case MT_CDR: /* CDR */
case MT_SBIFS: /* SBIFS */
case MT_SBISC: /* SBISC */
case MT_SBIMT: /* SBIMT */
case MT_SBIER: /* SBIER */
case MT_SBIQC: /* SBIQC */
break;
default:
RSVD_OPND_FAULT;
}
return;
}
/* ReadReg - read register space
Inputs:
pa = physical address
lnt = length (BWLQ)
Output:
longword of data
*/
int32 ReadReg (int32 pa, int32 lnt)
{
int32 nexus, val;
if (ADDR_IS_REG (pa)) { /* reg space? */
nexus = NEXUS_GETNEX (pa); /* get nexus */
if (nexusR[nexus] && /* valid? */
(nexusR[nexus] (&val, pa, lnt) == SCPE_OK)) {
SET_IRQL;
return val;
}
}
MACH_CHECK (MCHK_NXM);
return 0;
}
/* WriteReg - write register space
Inputs:
pa = physical address
val = data to write, right justified in 32b longword
lnt = length (BWLQ)
Outputs:
none
*/
void WriteReg (int32 pa, int32 val, int32 lnt)
{
int32 nexus;
if (ADDR_IS_REG (pa)) { /* reg space? */
nexus = NEXUS_GETNEX (pa); /* get nexus */
if (nexusW[nexus] && /* valid? */
(nexusW[nexus] (val, pa, lnt) == SCPE_OK)) {
SET_IRQL;
return;
}
}
MACH_CHECK (MCHK_NXM);
return;
}
/* Machine check
Error status word format
<2:0> = ASTLVL
<3> = PME
<6:4> = arith trap code
Rest will be zero
*/
int32 machine_check (int32 p1, int32 opc, int32 cc, int32 delta)
{
int32 acc, nxm;
nxm = ((p1 == MCHK_NXM) || (p1 == MCHK_IIA) || (p1 == MCHK_IUA));
if (nxm)
cc = intexc (SCB_MCHK, cc, 0, IE_EXC); /* take normal exception */
else
cc = intexc (SCB_MCHK, cc, 0, IE_SVE); /* take severe exception */
acc = ACC_MASK (KERN); /* in kernel mode */
in_ie = 1;
SP = SP - 16; /* push 4 words */
Write (SP, 12, L_LONG, WA); /* # bytes */
Write (SP + 4, p1, L_LONG, WA); /* mcheck type */
if (nxm)
Write (SP + 8, mchk_va, L_LONG, WA); /* NXM addr */
else
Write (SP + 8, 0, L_LONG, WA); /* first parameter */
Write (SP + 12, 0, L_LONG, WA); /* second parameter */
in_ie = 0;
return cc;
}
/* Console entry - only reached if CONHALT is set (AUTORESTART is set */
int32 con_halt (int32 code, int32 cc)
{
if ((cpu_boot_cmd[0] == 0) || /* saved boot cmd? */
(vax730_boot_parse (0, cpu_boot_cmd) != SCPE_OK) || /* reparse the boot cmd */
(reset_all (0) != SCPE_OK) || /* reset the world */
(cpu_boot (0, NULL) != SCPE_OK)) /* set up boot code */
ABORT (STOP_BOOT); /* any error? */
printf ("Rebooting...\n");
if (sim_log)
fprintf (sim_log, "Rebooting...\n");
return cc;
}
/* Special boot command - linked into SCP by initial reset
Syntax: BOOT <device>{/R5:val}
Sets up R0-R5, calls SCP boot processor with effective BOOT CPU
*/
t_stat vax730_boot (int32 flag, char *ptr)
{
t_stat r;
r = vax730_boot_parse (flag, ptr); /* parse the boot cmd */
if (r != SCPE_OK) /* error? */
return r;
strncpy (cpu_boot_cmd, ptr, CBUFSIZE); /* save for reboot */
return run_cmd (flag, "CPU");
}
/* Parse boot command, set up registers - also used on reset */
t_stat vax730_boot_parse (int32 flag, char *ptr)
{
char gbuf[CBUFSIZE];
char *slptr, *regptr;
int32 i, r5v, unitno;
DEVICE *dptr;
UNIT *uptr;
DIB *dibp;
uint32 ba;
t_stat r;
regptr = get_glyph (ptr, gbuf, 0); /* get glyph */
if (slptr = strchr (gbuf, '/')) { /* found slash? */
regptr = strchr (ptr, '/'); /* locate orig */
*slptr = 0; /* zero in string */
}
dptr = find_unit (gbuf, &uptr); /* find device */
if ((dptr == NULL) || (uptr == NULL))
return SCPE_ARG;
dibp = (DIB *) dptr->ctxt; /* get DIB */
if (dibp == NULL)
ba = 0;
else
ba = dibp->ba;
unitno = (int32) (uptr - dptr->units);
r5v = 0;
if ((strncmp (regptr, "/R5:", 4) == 0) ||
(strncmp (regptr, "/R5=", 4) == 0) ||
(strncmp (regptr, "/r5:", 4) == 0) ||
(strncmp (regptr, "/r5=", 4) == 0)) {
r5v = (int32) get_uint (regptr + 4, 16, LMASK, &r);
if (r != SCPE_OK)
return r;
}
else if (*regptr != 0)
return SCPE_ARG;
for (i = 0; boot_tab[i].name != NULL; i++) {
if (strcmp (dptr->name, boot_tab[i].name) == 0) {
R[0] = boot_tab[i].code;
if (boot_tab[i].code == BOOT_RB) /* vector set by console for RB730 */
R[0] = R[0] | ((VEC_RB - VEC_Q) << 16);
R[1] = TR_UBA;
R[2] = boot_tab[i].let | (ba & UBADDRMASK);
R[3] = unitno;
R[4] = 0;
R[5] = r5v;
return SCPE_OK;
}
}
return SCPE_NOFNC;
}
/* Bootstrap - finish up bootstrap process */
t_stat cpu_boot (int32 unitno, DEVICE *dptr)
{
t_stat r;
printf ("Loading boot code from vmb.exe\n");
if (sim_log) fprintf (sim_log,
"Loading boot code from vmb.exe\n");
r = load_cmd (0, "-O vmb.exe 200");
if (r != SCPE_OK) {
#ifndef DONT_USE_INTERNAL_ROM
FILE *f;
if (f = sim_fopen ("vmb.exe", "wb")) {
printf ("Saving boot code to vmb.exe\n");
if (sim_log)
fprintf (sim_log, "Saving boot code to vmb.exe\n");
sim_fwrite (vax780_vmb_exe, sizeof(vax780_vmb_exe[0]), sizeof(vax780_vmb_exe)/sizeof(vax780_vmb_exe[0]), f);
fclose (f);
printf ("Loading boot code from vmb.exe\n");
if (sim_log)
fprintf (sim_log, "Loading boot code from vmb.exe\n");
r = load_cmd (0, "-O vmb.exe 200");
if (r == SCPE_OK)
SP = PC = 512;
}
#endif
return r;
}
SP = PC = 512;
return SCPE_OK;
}
/* SYSB reset */
t_stat sysb_reset (DEVICE *dptr)
{
sim_vm_cmd = vax730_cmd;
return SCPE_OK;
}
/* Show nexus */
t_stat show_nexus (FILE *st, UNIT *uptr, int32 val, void *desc)
{
fprintf (st, "nexus=%d", val);
return SCPE_OK;
}
/* Init nexus tables */
void init_nexus_tab (void)
{
uint32 i;
for (i = 0; i < NEXUS_NUM; i++) {
nexusR[i] = NULL;
nexusW[i] = NULL;
}
return;
}
/* Build nexus tables
Inputs:
dptr = pointer to device
dibp = pointer to DIB
Outputs:
status
*/
t_stat build_nexus_tab (DEVICE *dptr, DIB *dibp)
{
uint32 idx;
if ((dptr == NULL) || (dibp == NULL))
return SCPE_IERR;
idx = dibp->ba;
if (idx >= NEXUS_NUM)
return SCPE_IERR;
if ((nexusR[idx] && dibp->rd && /* conflict? */
(nexusR[idx] != dibp->rd)) ||
(nexusW[idx] && dibp->wr &&
(nexusW[idx] != dibp->wr))) {
printf ("Nexus %s conflict at %d\n", sim_dname (dptr), dibp->ba);
if (sim_log)
fprintf (sim_log, "Nexus %s conflict at %d\n", sim_dname (dptr), dibp->ba);
return SCPE_STOP;
}
if (dibp->rd) /* set rd dispatch */
nexusR[idx] = dibp->rd;
if (dibp->wr) /* set wr dispatch */
nexusW[idx] = dibp->wr;
return SCPE_OK;
}
/* Build dib_tab from device list */
t_stat build_dib_tab (void)
{
uint32 i;
DEVICE *dptr;
DIB *dibp;
t_stat r;
init_nexus_tab ();
init_ubus_tab ();
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
dibp = (DIB *) dptr->ctxt; /* get DIB */
if (dibp && !(dptr->flags & DEV_DIS)) { /* defined, enabled? */
if (dptr->flags & DEV_NEXUS) { /* Nexus? */
if (r = build_nexus_tab (dptr, dibp)) /* add to dispatch table */
return r;
}
else { /* no, Unibus device */
if (r = build_ubus_tab (dptr, dibp)) /* add to dispatch tab */
return r;
} /* end else */
} /* end if enabled */
} /* end for */
return SCPE_OK;
}

130
VAX/vax730_syslist.c Normal file
View file

@ -0,0 +1,130 @@
/* vax730_syslist.c: VAX 730 device list
Copyright (c) 2010-2011, Matt Burke
This module incorporates code from SimH, Copyright (c) 1998-2008, 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
THE AUTHOR(S) 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(s) of the author(s) shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author(s).
29-Mar-2011 MB First Version
*/
#include "vax_defs.h"
char sim_name[] = "VAX730";
extern DEVICE cpu_dev;
extern DEVICE tlb_dev;
extern DEVICE sysb_dev;
extern DEVICE mctl_dev;
extern DEVICE uba_dev;
extern DEVICE clk_dev;
extern DEVICE tmr_dev;
extern DEVICE tti_dev, tto_dev;
extern DEVICE td_dev;
extern DEVICE cr_dev;
extern DEVICE lpt_dev;
extern DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev;
extern DEVICE rb_dev;
extern DEVICE rl_dev;
extern DEVICE hk_dev;
extern DEVICE ry_dev;
extern DEVICE ts_dev;
extern DEVICE tq_dev;
extern DEVICE dz_dev;
extern DEVICE xu_dev, xub_dev;
extern int32 sim_switches;
extern UNIT cpu_unit;
extern void WriteB (uint32 pa, int32 val);
DEVICE *sim_devices[] = {
&cpu_dev,
&tlb_dev,
&sysb_dev,
&mctl_dev,
&uba_dev,
&clk_dev,
&tmr_dev,
&tti_dev,
&tto_dev,
&td_dev,
&dz_dev,
&cr_dev,
&lpt_dev,
&rl_dev,
&hk_dev,
&rq_dev,
&rqb_dev,
&rqc_dev,
&rqd_dev,
&rb_dev,
&ry_dev,
&ts_dev,
&tq_dev,
&xu_dev,
&xub_dev,
NULL
};
/* Binary loader
The binary loader handles absolute system images, that is, system
images linked /SYSTEM. These are simply a byte stream, with no
origin or relocation information.
-r load ROM0
-s load ROM1
-o for memory, specify origin
*/
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
{
t_stat r;
int32 val;
uint32 origin, limit;
if (flag) /* dump? */
return SCPE_ARG;
origin = 0; /* memory */
limit = (uint32) cpu_unit.capac;
if (sim_switches & SWMASK ('O')) { /* origin? */
origin = (int32) get_uint (cptr, 16, 0xFFFFFFFF, &r);
if (r != SCPE_OK)
return SCPE_ARG;
}
while ((val = getc (fileref)) != EOF) { /* read byte stream */
if (sim_switches & SWMASK ('R')) { /* ROM0? */
return SCPE_NXM;
}
else if (sim_switches & SWMASK ('S')) { /* ROM1? */
return SCPE_NXM;
}
else {
if (origin >= limit) /* NXM? */
return SCPE_NXM;
WriteB (origin, val); /* memory */
}
origin = origin + 1;
}
return SCPE_OK;
}

667
VAX/vax730_uba.c Normal file
View file

@ -0,0 +1,667 @@
/* vax730_uba.c: VAX 11/730 Unibus adapter
Copyright (c) 2010-2011, Matt Burke
This module incorporates code from SimH, Copyright (c) 2004-2008, 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
THE AUTHOR(S) 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(s) of the author(s) shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author(s).
uba DW730 Unibus adapter
29-Mar-2011 MB First Version
*/
#include "vax_defs.h"
/* Unibus adapter */
#define UBA_NMAPR 496 /* number of map reg */
/* Unibus configuration register */
#define UBACNF_OF 0x00
#define UBACNF_CODE 0x00000028 /* adapter code */
/* Data path registers */
#define UBADPR_OF 0x01
/* Control & Status register */
#define UBACSR_OF 0x04
#define UBACSR_WNV 0x00004000 /* write not valid */
#define UBACSR_TBPAR 0x00008000 /* TB parity err */
#define UBACSR_NXM 0x00010000 /* UB NXM */
#define UBACSR_RDS 0x80000000 /* UB read data subs */
/* Vector registers - read only */
#define UBA_UVEC 0x80000000
/* RB730 registers */
#define RB730_OF 0x80
#define RB730_LN 8
/* Map registers */
#define UBAMAP_OF 0x200
#define UBAMAP_VLD 0x80000000 /* valid */
#define UBAMAP_LWAE 0x04000000 /* LW access enb - ni */
#define UBAMAP_ODD 0x02000000 /* odd byte */
#define UBAMAP_V_DP 21 /* data path */
#define UBAMAP_M_DP 0xF
#define UBAMAP_DP (UBAMAP_M_DP << UBAMAP_V_DP)
#define UBAMAP_GETDP(x) (((x) >> UBAMAP_V_DP) & UBAMAP_M_DP)
#define UBAMAP_PAG 0x001FFFFF
#define UBAMAP_RD (0x86000000 | UBAMAP_DP | UBAMAP_PAG)
#define UBAMAP_WR (UBAMAP_RD)
/* Debug switches */
#define UBA_DEB_RRD 0x01 /* reg reads */
#define UBA_DEB_RWR 0x02 /* reg writes */
#define UBA_DEB_MRD 0x04 /* map reads */
#define UBA_DEB_MWR 0x08 /* map writes */
#define UBA_DEB_XFR 0x10 /* transfers */
#define UBA_DEB_ERR 0x20 /* errors */
int32 int_req[IPL_HLVL] = { 0 }; /* intr, IPL 14-17 */
uint32 uba_csr = 0; /* control & status reg */
uint32 uba_fmer = 0; /* failing map reg */
uint32 uba_map[UBA_NMAPR] = { 0 }; /* map registers */
int32 autcon_enb = 1; /* autoconfig enable */
extern int32 trpirq;
extern int32 autcon_enb;
extern jmp_buf save_env;
extern DEVICE *sim_devices[];
extern UNIT cpu_unit;
extern int32 sim_switches;
extern FILE *sim_log, *sim_deb;
extern int32 p1;
t_stat uba_reset (DEVICE *dptr);
t_stat uba_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw);
t_stat uba_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw);
t_stat uba_rdreg (int32 *val, int32 pa, int32 mode);
t_stat uba_wrreg (int32 val, int32 pa, int32 lnt);
int32 uba_get_ubvector (int32 lvl);
t_bool uba_eval_int (int32 lvl);
void uba_ubpdn (int32 time);
t_bool uba_map_addr (uint32 ua, uint32 *ma);
t_stat set_autocon (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat show_autocon (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat show_iospace (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat uba_show_virt (FILE *st, UNIT *uptr, int32 val, void *desc);
extern int32 eval_int (void);
extern t_stat build_dib_tab (void);
extern t_stat rb_rd32 (int32 *data, int32 PA, int32 access);
extern t_stat rb_wr32 (int32 data, int32 PA, int32 access);
/* Unibus IO page dispatches */
t_stat (*iodispR[IOPAGESIZE >> 1])(int32 *dat, int32 ad, int32 md);
t_stat (*iodispW[IOPAGESIZE >> 1])(int32 dat, int32 ad, int32 md);
/* Unibus interrupt request to interrupt action map */
int32 (*int_ack[IPL_HLVL][32])(); /* int ack routines */
/* Unibus interrupt request to vector map */
int32 int_vec[IPL_HLVL][32]; /* int req to vector */
/* Unibus adapter data structures
uba_dev UBA device descriptor
uba_unit UBA units
uba_reg UBA register list
*/
DIB uba_dib = { TR_UBA, 0, &uba_rdreg, &uba_wrreg, 0, 0 };
UNIT uba_unit = { UDATA (0, 0, 0) };
REG uba_reg[] = {
{ HRDATA (IPL14, int_req[0], 32), REG_RO },
{ HRDATA (IPL15, int_req[1], 32), REG_RO },
{ HRDATA (IPL16, int_req[2], 32), REG_RO },
{ HRDATA (IPL17, int_req[3], 32), REG_RO },
{ HRDATA (CSR, uba_csr, 32) },
{ BRDATA (MAP, uba_map, 16, 32, 496) },
{ FLDATA (AUTOCON, autcon_enb, 0), REG_HRO },
{ NULL }
};
MTAB uba_mod[] = {
{ MTAB_XTD|MTAB_VDV, TR_UBA, "NEXUS", NULL,
NULL, &show_nexus },
{ MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "IOSPACE", NULL,
NULL, &show_iospace },
{ MTAB_XTD|MTAB_VDV, 1, "AUTOCONFIG", "AUTOCONFIG",
&set_autocon, &show_autocon },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "NOAUTOCONFIG",
&set_autocon, NULL },
{ MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "VIRTUAL", NULL,
NULL, &uba_show_virt },
{ 0 }
};
DEBTAB uba_deb[] = {
{ "REGREAD", UBA_DEB_RRD },
{ "REGWRITE", UBA_DEB_RWR },
{ "MAPREAD", UBA_DEB_MRD },
{ "MAPWRITE", UBA_DEB_MWR },
{ "XFER", UBA_DEB_XFR },
{ "ERROR", UBA_DEB_ERR },
{ NULL, 0 }
};
DEVICE uba_dev = {
"UBA", &uba_unit, uba_reg, uba_mod,
1, 16, UBADDRWIDTH, 2, 16, 16,
&uba_ex, &uba_dep, &uba_reset,
NULL, NULL, NULL,
&uba_dib, DEV_NEXUS | DEV_DEBUG, 0,
uba_deb, 0, 0
};
/* Read Unibus adapter register - aligned lw only */
t_stat uba_rdreg (int32 *val, int32 pa, int32 lnt)
{
int32 idx, ofs;
if ((pa & 3) || (lnt != L_LONG)) { /* unaligned or not lw? */
printf (">>UBA: invalid adapter read mask, pa = %X, lnt = %d\r\n", pa, lnt);
// **FIXME** - Set error bit?
return SCPE_OK;
}
ofs = NEXUS_GETOFS (pa); /* get offset */
if (ofs >= UBAMAP_OF) { /* map? */
idx = ofs - UBAMAP_OF;
if (idx >= UBA_NMAPR) return SCPE_NXM; /* valid? */
*val = uba_map[idx] & UBAMAP_RD;
if (DEBUG_PRI (uba_dev, UBA_DEB_MRD))
fprintf (sim_deb, ">>UBA: map %d read, value = %X\n", idx, *val);
return SCPE_OK;
}
if (ofs >= RB730_OF) { /* RB730? */
idx = ofs - RB730_OF;
if (idx >= RB730_LN) return SCPE_NXM; /* valid? */
return rb_rd32 (val, pa, lnt);
}
switch (ofs) { /* case on offset */
case UBACNF_OF: /* Config Reg */
*val = UBACNF_CODE;
break;
case UBADPR_OF + 0: /* DP Regs */
case UBADPR_OF + 1:
case UBADPR_OF + 2:
*val = 0x0; /* Not used on 11/730 */
break;
case UBACSR_OF: /* CSR */
*val = uba_csr;
break;
default:
return SCPE_NXM;
}
if (DEBUG_PRI (uba_dev, UBA_DEB_RRD))
fprintf (sim_deb, ">>UBA: reg %d read, value = %X\n", ofs, *val);
return SCPE_OK;
}
/* Write Unibus adapter register */
t_stat uba_wrreg (int32 val, int32 pa, int32 lnt)
{
int32 idx, ofs;
if ((pa & 3) || (lnt != L_LONG)) { /* unaligned or not lw? */
printf (">>UBA: invalid adapter write mask, pa = %X, lnt = %d\r\n", pa, lnt);
// **FIXME** - Set error bit?
return SCPE_OK;
}
ofs = NEXUS_GETOFS (pa); /* get offset */
if (ofs >= UBAMAP_OF) { /* map? */
idx = ofs - UBAMAP_OF;
if (idx >= UBA_NMAPR) return SCPE_NXM; /* valid? */
uba_map[idx] = val & UBAMAP_WR;
if (DEBUG_PRI (uba_dev, UBA_DEB_MWR))
fprintf (sim_deb, ">>UBA: map %d write, value = %X\n", idx, val);
return SCPE_OK;
}
if (ofs >= RB730_OF) { /* RB730? */
idx = ofs - RB730_OF;
if (idx >= RB730_LN) return SCPE_NXM; /* valid? */
return rb_wr32 (val, pa, lnt);
}
switch (ofs) { /* case on offset */
case UBACNF_OF: /* Config Reg */
case UBADPR_OF + 0: /* DP Regs */
case UBADPR_OF + 1:
case UBADPR_OF + 2:
break; /* ignore writes */
case UBACSR_OF: /* CSR */
if(val & 0x10000) uba_csr = 0;
break;
default:
return SCPE_NXM;
}
if (DEBUG_PRI (uba_dev, UBA_DEB_RWR))
fprintf (sim_deb, ">>UBA: reg %d write, value = %X\n", ofs, val);
return SCPE_OK;
}
/* Read and write Unibus I/O space */
int32 ReadUb (uint32 pa)
{
int32 idx, val;
if (ADDR_IS_IOP (pa)) { /* iopage */
idx = (pa & IOPAGEMASK) >> 1;
if (iodispR[idx]) {
iodispR[idx] (&val, pa, READ);
return val;
}
}
MACH_CHECK(MCHK_IIA);
return 0;
}
void WriteUb (uint32 pa, int32 val, int32 mode)
{
int32 idx;
if (ADDR_IS_IOP (pa)) { /* iopage */
idx = (pa & IOPAGEMASK) >> 1;
if (iodispW[idx]) {
iodispW[idx] (val, pa, mode);
return;
}
}
MACH_CHECK(MCHK_IIA);
return;
}
/* ReadIO - read from IO - UBA only responds to byte, aligned word
Inputs:
pa = physical address
lnt = length (BWLQ)
Output:
longword of data
*/
int32 ReadIO (uint32 pa, int32 lnt)
{
uint32 iod;
if ((lnt == L_BYTE) || /* byte? */
((lnt == L_WORD) && ((pa & 1) == 0))) { /* aligned word? */
iod = ReadUb (pa); /* DATI from Unibus */
if (pa & 2) /* position */
iod = iod << 16;
}
else {
printf (">>UBA: invalid read mask, pa = %x, lnt = %d\n", pa, lnt);
// **FIXME** - Set error bit?
iod = 0;
}
SET_IRQL;
return iod;
}
/* WriteIO - write to IO - UBA only responds to byte, aligned word
Inputs:
pa = physical address
val = data to write, right justified in 32b longword
lnt = length (BWL)
Outputs:
none
*/
void WriteIO (uint32 pa, int32 val, int32 lnt)
{
if (lnt == L_BYTE) /* byte? DATOB */
WriteUb (pa, val, WRITEB);
else if ((lnt == L_WORD) && ((pa & 1) == 0)) /* aligned word? */
WriteUb (pa, val, WRITE); /* DATO */
else {
printf (">>UBA: invalid write mask, pa = %x, lnt = %d\n", pa, lnt);
// **FIXME** - Set error bit?
}
SET_IRQL; /* update ints */
return;
}
/* Update UBA nexus interrupts */
t_bool uba_eval_int (int32 lvl)
{
return (int_req[lvl] != 0);
}
/* Return vector for Unibus interrupt at relative IPL level [0-3] */
int32 uba_get_ubvector (int32 lvl)
{
int32 i, vec;
vec = 0;
for (i = 0; int_req[lvl] && (i < 32); i++) {
if ((int_req[lvl] >> i) & 1) {
int_req[lvl] = int_req[lvl] & ~(1u << i);
if (int_ack[lvl][i])
return (vec | int_ack[lvl][i]());
return (vec | int_vec[lvl][i]);
}
}
return vec;
}
/* Unibus I/O buffer routines
Map_ReadB - fetch byte buffer from memory
Map_ReadW - fetch word buffer from memory
Map_WriteB - store byte buffer into memory
Map_WriteW - store word buffer into memory
*/
int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf)
{
int32 i, j, pbc;
uint32 ma, dat;
ba = ba & UBADDRMASK; /* mask UB addr */
for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
if (!uba_map_addr (ba + i, &ma)) /* page inv or NXM? */
return (bc - i);
pbc = VA_PAGSIZE - VA_GETOFF (ma); /* left in page */
if (pbc > (bc - i)) /* limit to rem xfr */
pbc = bc - i;
if (DEBUG_PRI (uba_dev, UBA_DEB_XFR))
fprintf (sim_deb, ">>UBA: 8b read, ma = %X, bc = %X\n", ma, pbc);
if ((ma | pbc) & 3) { /* aligned LW? */
for (j = 0; j < pbc; ma++, j++) { /* no, do by bytes */
*buf++ = ReadB (ma);
}
}
else { /* yes, do by LW */
for (j = 0; j < pbc; ma = ma + 4, j = j + 4) {
dat = ReadL (ma); /* get lw */
*buf++ = dat & BMASK; /* low 8b */
*buf++ = (dat >> 8) & BMASK; /* next 8b */
*buf++ = (dat >> 16) & BMASK; /* next 8b */
*buf++ = (dat >> 24) & BMASK;
}
}
}
return 0;
}
int32 Map_ReadW (uint32 ba, int32 bc, uint16 *buf)
{
int32 i, j, pbc;
uint32 ma, dat;
ba = ba & UBADDRMASK; /* mask UB addr */
bc = bc & ~01;
for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
if (!uba_map_addr (ba + i, &ma)) /* page inv or NXM? */
return (bc - i);
pbc = VA_PAGSIZE - VA_GETOFF (ma); /* left in page */
if (pbc > (bc - i)) /* limit to rem xfr */
pbc = bc - i;
if (DEBUG_PRI (uba_dev, UBA_DEB_XFR))
fprintf (sim_deb, ">>UBA: 16b read, ma = %X, bc = %X\n", ma, pbc);
if ((ma | pbc) & 1) { /* aligned word? */
for (j = 0; j < pbc; ma++, j++) { /* no, do by bytes */
if ((i + j) & 1) { /* odd byte? */
*buf = (*buf & BMASK) | (ReadB (ma) << 8);
buf++;
}
else *buf = (*buf & ~BMASK) | ReadB (ma);
}
}
else if ((ma | pbc) & 3) { /* aligned LW? */
for (j = 0; j < pbc; ma = ma + 2, j = j + 2) { /* no, words */
*buf++ = ReadW (ma); /* get word */
}
}
else { /* yes, do by LW */
for (j = 0; j < pbc; ma = ma + 4, j = j + 4) {
dat = ReadL (ma); /* get lw */
*buf++ = dat & WMASK; /* low 16b */
*buf++ = (dat >> 16) & WMASK; /* high 16b */
}
}
}
return 0;
}
int32 Map_WriteB (uint32 ba, int32 bc, uint8 *buf)
{
int32 i, j, pbc;
uint32 ma, dat;
ba = ba & UBADDRMASK; /* mask UB addr */
for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
if (!uba_map_addr (ba + i, &ma)) /* page inv or NXM? */
return (bc - i);
pbc = VA_PAGSIZE - VA_GETOFF (ma); /* left in page */
if (pbc > (bc - i)) /* limit to rem xfr */
pbc = bc - i;
if (DEBUG_PRI (uba_dev, UBA_DEB_XFR))
fprintf (sim_deb, ">>UBA: 8b write, ma = %X, bc = %X\n", ma, pbc);
if ((ma | pbc) & 3) { /* aligned LW? */
for (j = 0; j < pbc; ma++, j++) { /* no, do by bytes */
WriteB (ma, *buf);
buf++;
}
}
else { /* yes, do by LW */
for (j = 0; j < pbc; ma = ma + 4, j = j + 4) {
dat = (uint32) *buf++; /* get low 8b */
dat = dat | (((uint32) *buf++) << 8); /* merge next 8b */
dat = dat | (((uint32) *buf++) << 16); /* merge next 8b */
dat = dat | (((uint32) *buf++) << 24); /* merge hi 8b */
WriteL (ma, dat); /* store lw */
}
}
}
return 0;
}
int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf)
{
int32 i, j, pbc;
uint32 ma, dat;
ba = ba & UBADDRMASK; /* mask UB addr */
bc = bc & ~01;
for (i = 0; i < bc; i = i + pbc) { /* loop by pages */
if (!uba_map_addr (ba + i, &ma)) /* page inv or NXM? */
return (bc - i);
pbc = VA_PAGSIZE - VA_GETOFF (ma); /* left in page */
if (pbc > (bc - i)) /* limit to rem xfr */
pbc = bc - i;
if (DEBUG_PRI (uba_dev, UBA_DEB_XFR))
fprintf (sim_deb, ">>UBA: 16b write, ma = %X, bc = %X\n", ma, pbc);
if ((ma | pbc) & 1) { /* aligned word? */
for (j = 0; j < pbc; ma++, j++) { /* no, bytes */
if ((i + j) & 1) {
WriteB (ma, (*buf >> 8) & BMASK);
buf++;
}
else WriteB (ma, *buf & BMASK);
}
}
else if ((ma | pbc) & 3) { /* aligned LW? */
for (j = 0; j < pbc; ma = ma + 2, j = j + 2) { /* no, words */
WriteW (ma, *buf); /* write word */
buf++;
}
}
else { /* yes, do by LW */
for (j = 0; j < pbc; ma = ma + 4, j = j + 4) {
dat = (uint32) *buf++; /* get low 16b */
dat = dat | (((uint32) *buf++) << 16); /* merge hi 16b */
WriteL (ma, dat); /* store LW */
}
}
}
return 0;
}
/* Map an address via the translation map */
t_bool uba_map_addr (uint32 ua, uint32 *ma)
{
uint32 ublk, umap;
ublk = ua >> VA_V_VPN; /* Unibus blk */
if (ublk >= UBA_NMAPR) /* unimplemented? */
return FALSE;
umap = uba_map[ublk]; /* get map */
if (umap & UBAMAP_VLD) { /* valid? */
*ma = ((umap & UBAMAP_PAG) << VA_V_VPN) + VA_GETOFF (ua);
if ((umap & UBAMAP_DP) && (umap & UBAMAP_ODD)) /* buffered dp? */
*ma = *ma + 1; /* byte offset? */
return (ADDR_IS_MEM (*ma)); /* legit addr */
}
return FALSE;
}
/* Map an address via the translation map - console version (no status changes) */
t_bool uba_map_addr_c (uint32 ua, uint32 *ma)
{
uint32 ublk, umap;
ublk = ua >> VA_V_VPN; /* Unibus blk */
if (ublk >= UBA_NMAPR) /* unimplemented? */
return FALSE;
umap = uba_map[ublk]; /* get map */
if (umap & UBAMAP_VLD) { /* valid? */
*ma = ((umap & UBAMAP_PAG) << VA_V_VPN) + VA_GETOFF (ua);
if ((umap & UBAMAP_DP) && (umap & UBAMAP_ODD)) /* buffered dp? */
*ma = *ma + 1; /* byte offset? */
return TRUE; /* legit addr */
}
return FALSE;
}
/* Unibus power fail routines */
void uba_ubpdn (int32 time)
{
int32 i;
DEVICE *dptr;
for (i = 0; sim_devices[i] != NULL; i++) { /* reset Unibus */
dptr = sim_devices[i];
if (dptr->reset && (dptr->flags & DEV_UBUS))
dptr->reset (dptr);
}
return;
}
/* Reset Unibus adapter */
t_stat uba_reset (DEVICE *dptr)
{
int32 i;
for (i = 0; i < IPL_HLVL; i++) {
int_req[i] = 0;
}
for (i = 0; i < UBA_NMAPR; i++)
uba_map[i] = 0;
uba_csr = 0;
return SCPE_OK;
}
/* Memory examine via map (word only) */
t_stat uba_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw)
{
uint32 ua = (uint32) exta, pa;
if ((vptr == NULL) || (ua >= UBADDRSIZE))
return SCPE_ARG;
if (uba_map_addr_c (ua, &pa) && ADDR_IS_MEM (pa)) {
*vptr = (uint32) ReadW (pa);
return SCPE_OK;
}
return SCPE_NXM;
}
/* Memory deposit via map (word only) */
t_stat uba_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw)
{
uint32 ua = (uint32) exta, pa;
if (ua >= UBADDRSIZE)
return SCPE_ARG;
if (uba_map_addr_c (ua, &pa) && ADDR_IS_MEM (pa)) {
WriteW (pa, (int32) val);
return SCPE_OK;
}
return SCPE_NXM;
}
/* Show UBA virtual address */
t_stat uba_show_virt (FILE *of, UNIT *uptr, int32 val, void *desc)
{
t_stat r;
char *cptr = (char *) desc;
uint32 ua, pa;
if (cptr) {
ua = (uint32) get_uint (cptr, 16, UBADDRSIZE - 1, &r);
if (r == SCPE_OK) {
if (uba_map_addr_c (ua, &pa))
fprintf (of, "Unibus %-X = physical %-X\n", ua, pa);
else fprintf (of, "Unibus %-X: invalid mapping\n", ua);
return SCPE_OK;
}
}
fprintf (of, "Invalid argument\n");
return SCPE_OK;
}

View file

@ -106,7 +106,7 @@ uint32 sbi_sc = 0; /* SBI silo comparator *
uint32 sbi_mt = 0; /* SBI maintenance */
uint32 sbi_er = 0; /* SBI error status */
uint32 sbi_tmo = 0; /* SBI timeout addr */
char cpu_boot_cmd[CBUFSIZE] = { 0 }; /* boot command */
static char cpu_boot_cmd[CBUFSIZE] = { 0 }; /* boot command */
static t_stat (*nexusR[NEXUS_NUM])(int32 *dat, int32 ad, int32 md);
static t_stat (*nexusW[NEXUS_NUM])(int32 dat, int32 ad, int32 md);

View file

@ -473,6 +473,11 @@ MTAB cpu_mod[] = {
{ UNIT_CONH, UNIT_CONH, "HALT to console", "CONHALT", NULL },
{ MTAB_XTD|MTAB_VDV, 0, "IDLE", "IDLE", &cpu_set_idle, &cpu_show_idle },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "NOIDLE", &sim_clr_idle, NULL },
#if defined (VAX_730)
{ UNIT_MSIZE, (1u << 20), NULL, "1M", &cpu_set_size },
{ UNIT_MSIZE, (1u << 21), NULL, "2M", &cpu_set_size },
{ UNIT_MSIZE, (1u << 22), NULL, "4M", &cpu_set_size },
#endif
{ UNIT_MSIZE, (1u << 23), NULL, "8M", &cpu_set_size },
{ UNIT_MSIZE, (1u << 24), NULL, "16M", &cpu_set_size },
{ UNIT_MSIZE, (1u << 25), NULL, "32M", &cpu_set_size },

View file

@ -720,6 +720,8 @@ enum opcodes {
#if defined (VAX_780)
#include "vax780_defs.h"
#elif defined (VAX_730)
#include "vax730_defs.h"
#else
#include "vaxmod_defs.h"
#endif

View file

@ -65,6 +65,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SWTP", "SWTP.vcproj", "{0AB
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BuildROMs", "BuildROMs.vcproj", "{D40F3AF1-EEE7-4432-9807-2AD287B490F8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VAX730", "VAX730.vcproj", "{C526F7F2-9476-44BC-B1E9-9522B693BEA7}"
ProjectSection(ProjectDependencies) = postProject
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -187,6 +192,10 @@ Global
{D40F3AF1-EEE7-4432-9807-2AD287B490F8}.Debug|Win32.Build.0 = Debug|Win32
{D40F3AF1-EEE7-4432-9807-2AD287B490F8}.Release|Win32.ActiveCfg = Release|Win32
{D40F3AF1-EEE7-4432-9807-2AD287B490F8}.Release|Win32.Build.0 = Release|Win32
{C526F7F2-9476-44BC-B1E9-9522B693BEA7}.Debug|Win32.ActiveCfg = Debug|Win32
{C526F7F2-9476-44BC-B1E9-9522B693BEA7}.Debug|Win32.Build.0 = Debug|Win32
{C526F7F2-9476-44BC-B1E9-9522B693BEA7}.Release|Win32.ActiveCfg = Release|Win32
{C526F7F2-9476-44BC-B1E9-9522B693BEA7}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View file

@ -0,0 +1,431 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="VAX730"
ProjectGUID="{C526F7F2-9476-44BC-B1E9-9522B693BEA7}"
RootNamespace="VAX730"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\VAX730\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
Description="Build Dependent ROM include File(s)"
CommandLine="pushd ..&#x0D;&#x0A;$(TargetDir)BuildROMs&#x0D;&#x0A;popd&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;../../winpcap/Wpdpack/Include;&quot;../../pthreads/Pre-built.2/include&quot;"
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_730;USE_SHARED;_CRT_SECURE_NO_WARNINGS;USE_READER_THREAD;SIM_ASYNCH_IO"
MinimalRebuild="true"
BasicRuntimeChecks="0"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
CompileAs="1"
ShowIncludes="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/fixed:no"
AdditionalDependencies="pthreadVC2.lib wsock32.lib packet.lib winmm.lib"
OutputFile="$(OutDir)\VAX730.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../winpcap/Wpdpack/Lib/;&quot;../../pthreads/Pre-built.2/lib/&quot;"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)\VAX730.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\VAX730\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
Description="Build Dependent ROM include File(s)"
CommandLine="pushd ..&#x0D;&#x0A;$(TargetDir)BuildROMs&#x0D;&#x0A;popd&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;../../winpcap/Wpdpack/Include;&quot;../../pthreads/Pre-built.2/include&quot;"
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_730;USE_SHARED;_CRT_SECURE_NO_WARNINGS;USE_READER_THREAD"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/fixed:no"
AdditionalDependencies="pthreadVC2.lib wsock32.lib packet.lib winmm.lib"
OutputFile="$(OutDir)\VAX730.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../winpcap/Wpdpack/Lib/;&quot;../../pthreads/Pre-built.2/lib/&quot;"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\PDP11\pdp11_cr.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_dz.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_hk.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_io_lib.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_lp.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_rl.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_rq.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_ry.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_tq.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_ts.c"
>
</File>
<File
RelativePath="..\PDP11\pdp11_xu.c"
>
</File>
<File
RelativePath="..\scp.c"
>
</File>
<File
RelativePath="..\sim_console.c"
>
</File>
<File
RelativePath="..\sim_disk.c"
>
</File>
<File
RelativePath="..\sim_ether.c"
>
</File>
<File
RelativePath="..\sim_fio.c"
>
</File>
<File
RelativePath="..\sim_sock.c"
>
</File>
<File
RelativePath="..\sim_tape.c"
>
</File>
<File
RelativePath="..\sim_timer.c"
>
</File>
<File
RelativePath="..\sim_tmxr.c"
>
</File>
<File
RelativePath="..\VAX\vax730_mem.c"
>
</File>
<File
RelativePath="..\VAX\vax730_rb.c"
>
</File>
<File
RelativePath="..\VAX\vax730_stddev.c"
>
</File>
<File
RelativePath="..\VAX\vax730_sys.c"
>
</File>
<File
RelativePath="..\VAX\vax730_syslist.c"
>
</File>
<File
RelativePath="..\VAX\vax730_uba.c"
>
</File>
<File
RelativePath="..\VAX\vax_cis.c"
>
</File>
<File
RelativePath="..\VAX\vax_cmode.c"
>
</File>
<File
RelativePath="..\VAX\vax_cpu.c"
>
</File>
<File
RelativePath="..\VAX\vax_cpu1.c"
>
</File>
<File
RelativePath="..\VAX\vax_fpa.c"
>
</File>
<File
RelativePath="..\VAX\vax_mmu.c"
>
</File>
<File
RelativePath="..\VAX\vax_octa.c"
>
</File>
<File
RelativePath="..\VAX\vax_sys.c"
>
</File>
<File
RelativePath="..\VAX\vax_syscm.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc"
>
<File
RelativePath="..\dec_dz.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_io_lib.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_mscp.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_uqssp.h"
>
</File>
<File
RelativePath="..\PDP11\pdp11_xu.h"
>
</File>
<File
RelativePath="..\scp.h"
>
</File>
<File
RelativePath="..\sim_console.h"
>
</File>
<File
RelativePath="..\sim_defs.h"
>
</File>
<File
RelativePath="..\sim_disk.h"
>
</File>
<File
RelativePath="..\sim_ether.h"
>
</File>
<File
RelativePath="..\sim_fio.h"
>
</File>
<File
RelativePath="..\sim_rev.h"
>
</File>
<File
RelativePath="..\sim_sock.h"
>
</File>
<File
RelativePath="..\sim_tape.h"
>
</File>
<File
RelativePath="..\sim_timer.h"
>
</File>
<File
RelativePath="..\sim_tmxr.h"
>
</File>
<File
RelativePath="..\VAX\VAX730_defs.h"
>
</File>
<File
RelativePath="..\VAX\vax_defs.h"
>
</File>
<File
RelativePath="..\VAX\vaxmod_defs.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -3,6 +3,7 @@
# Modified By: Mark Pizzolato / mark@infocomm.com
# Norman Lastovica / norman.lastovica@oracle.com
# Camiel Vanderhoeven / camiel@camicom.com
# Matt Burke / scope.matthew@btinternet.com
#
# This MMS/MMK build script is used to compile the various simulators in
# the SIMH package for OpenVMS using DEC C v6.0-001(AXP), v6.5-001(AXP),
@ -40,6 +41,7 @@
# SDS Just Build The SDS 940.
# SWTP Just Build The SWTP.
# VAX Just Build The DEC VAX.
# VAX730 Just Build The DEC VAX730.
# VAX780 Just Build The DEC VAX780.
# CLEAN Will Clean Files Back To Base Kit.
#
@ -551,6 +553,35 @@ VAX_OPTIONS = /INCL=($(SIMH_DIR),$(VAX_DIR),$(PDP11_DIR)$(PCAP_INC))\
VAX_SIMH_LIB = $(SIMH_LIB)
.ENDIF
# Digital Equipment VAX730 Simulator Definitions.
#
VAX730_DIR = SYS$DISK:[.VAX]
VAX730_LIB1 = $(LIB_DIR)VAX730L1-$(ARCH).OLB
VAX730_SOURCE1 = $(VAX730_DIR)VAX_CPU.C,$(VAX730_DIR)VAX_CPU1.C,\
$(VAX730_DIR)VAX_FPA.C,$(VAX730_DIR)VAX_CIS.C,\
$(VAX730_DIR)VAX_OCTA.C,$(VAX730_DIR)VAX_CMODE.C,\
$(VAX730_DIR)VAX_MMU.C,$(VAX730_DIR)VAX_SYS.C,\
$(VAX730_DIR)VAX_SYSCM.C,$(VAX730_DIR)VAX730_STDDEV.C,\
$(VAX730_DIR)VAX730_SYS.C,$(VAX730_DIR)VAX730_MEM.C,\
$(VAX730_DIR)VAX730_UBA.C,$(VAX730_DIR)VAX730_RB.C,\
$(VAX730_DIR)VAX730_SYSLIST.C
VAX730_LIB2 = $(LIB_DIR)VAX730L2-$(ARCH).OLB
VAX730_SOURCE2 = $(PDP11_DIR)PDP11_RL.C,$(PDP11_DIR)PDP11_RQ.C,\
$(PDP11_DIR)PDP11_TS.C,$(PDP11_DIR)PDP11_DZ.C,\
$(PDP11_DIR)PDP11_LP.C,$(PDP11_DIR)PDP11_TQ.C,\
$(PDP11_DIR)PDP11_XU.C,$(PDP11_DIR)PDP11_RY.C,\
$(PDP11_DIR)PDP11_CR.C,$(PDP11_DIR)PDP11_HK.C,\
$(PDP11_DIR)PDP11_IO_LIB.C
.IFDEF ALPHA_OR_IA64
VAX730_OPTIONS = /INCL=($(SIMH_DIR),$(VAX730_DIR),$(PDP11_DIR)$(PCAP_INC))\
/DEF=($(CC_DEFS),"VM_VAX=1","USE_ADDR64=1","USE_INT64=1"$(PCAP_DEFS),"VAX_730=1")
VAX730_SIMH_LIB = $(SIMH_LIB64)
.ELSE
VAX730_OPTIONS = /INCL=($(SIMH_DIR),$(VAX730_DIR),$(PDP11_DIR)$(PCAP_INC))\
/DEF=($(CC_DEFS),"VM_VAX=1"$(PCAP_DEFS),"VAX_730=1")
VAX730_SIMH_LIB = $(SIMH_LIB)
.ENDIF
# Digital Equipment VAX780 Simulator Definitions.
#
VAX780_DIR = SYS$DISK:[.VAX]
@ -597,8 +628,8 @@ I7094_OPTIONS = /INCL=($(SIMH_DIR),$(I7094_DIR))/DEF=($(CC_DEFS))
#
.IFDEF ALPHA_OR_IA64
ALL : ALTAIR ALTAIRZ80 ECLIPSE GRI LGP H316 HP2100 I1401 I1620 IBM1130 ID16 \
ID32 NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP10 PDP11 PDP15 S3 VAX VAX780 SDS \
I7094 SWTP
ID32 NOVA PDP1 PDP4 PDP7 PDP8 PDP9 PDP10 PDP11 PDP15 S3 VAX VAX730 VAX780 \
SDS I7094 SWTP
$! No further actions necessary
.ELSE
#
@ -1011,6 +1042,28 @@ $(VAX_LIB2) : $(VAX_SOURCE2)
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
$(VAX730_LIB1) : $(VAX730_SOURCE1)
$!
$! Building The $(VAX730_LIB1) Library.
$!
$ $(CC)$(VAX780_OPTIONS)/OBJ=$(VAX730_DIR) -
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
LIBRARY/CREATE $(MMS$TARGET)
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
$(VAX730_LIB2) : $(VAX730_SOURCE2)
$!
$! Building The $(VAX730_LIB2) Library.
$!
$ $(CC)$(VAX780_OPTIONS)/OBJ=$(VAX730_DIR) -
/OBJ=$(BLD_DIR) $(MMS$CHANGED_LIST)
$ IF (F$SEARCH("$(MMS$TARGET)").EQS."") THEN -
LIBRARY/CREATE $(MMS$TARGET)
$ LIBRARY/REPLACE $(MMS$TARGET) $(BLD_DIR)*.OBJ
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
$(VAX780_LIB1) : $(VAX780_SOURCE1)
$!
$! Building The $(VAX780_LIB1) Library.
@ -1401,6 +1454,21 @@ $(BIN_DIR)VAX-$(ARCH).EXE : $(SIMH_MAIN) $(VAX_SIMH_LIB) $(PCAP_LIBD) $(VAX_LIB1
$(VAX_SIMH_LIB)/LIBRARY$(PCAP_LIBR)
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
VAX730 : $(BIN_DIR)VAX730-$(ARCH).EXE
$! VAX730 done
$(BIN_DIR)VAX730-$(ARCH).EXE : $(SIMH_MAIN) $(VAX730_SIMH_LIB) $(PCAP_LIBD) $(VAX730_LIB1) $(VAX730_LIB2) $(PCAP_EXECLET)
$!
$! Building The $(BIN_DIR)VAX730-$(ARCH).EXE Simulator.
$!
$ $(CC)$(VAX730_OPTIONS)/OBJ=$(BLD_DIR) SCP.C
$ LINK $(LINK_DEBUG)$(LINK_SECTION_BINDING)-
/EXE=$(BIN_DIR)VAX730-$(ARCH).EXE -
$(BLD_DIR)SCP.OBJ,-
$(VAX730_LIB1)/LIBRARY,$(VAX730_LIB2)/LIBRARY,-
$(VAX730_SIMH_LIB)/LIBRARY$(PCAP_LIBR)
$ DELETE/NOLOG/NOCONFIRM $(BLD_DIR)*.OBJ;*
VAX780 : $(BIN_DIR)VAX780-$(ARCH).EXE
$! VAX780 done

View file

@ -45,8 +45,8 @@ ifeq ($(WIN32),)
OS_CCDEFS += -DSIM_ASYNCH_IO -DUSE_READER_THREAD
OS_LDFLAGS += -lpthread
endif
ifeq (readline,$(shell if $(TEST) -e /usr/lib/libreadline.$(LIBEXT) -o -e /opt/sfw/lib/libreadline.a; then echo readline; fi))
ifeq (readline_h,$(shell if $(TEST) -e /usr/include/readline/readline.h; then echo readline_h; fi))
ifeq (readline,$(shell if $(TEST) -e /usr/lib/libreadline.$(LIBEXT) -o -e /usr/lib64/libreadline.$(LIBEXT) -o -e /opt/sfw/lib/libreadline.a; then echo readline; fi))
ifeq (readline_h,$(shell if $(TEST) -e /usr/include/readline/readline.h -o -e /usr/include/readline.h; then echo readline_h; fi))
# Use Locally installed and available readline support
ifeq (ncurses,$(shell if $(TEST) -e /usr/lib/libncurses.$(LIBEXT) -o -e /opt/sfw/lib/libncurses.a; then echo ncurses; fi))
OS_CCDEFS += -DHAVE_READLINE
@ -194,6 +194,19 @@ VAX = ${VAXD}/vax_cpu.c ${VAXD}/vax_cpu1.c ${VAXD}/vax_fpa.c ${VAXD}/vax_io.c \
VAX_OPT = -DVM_VAX -DUSE_INT64 -DUSE_ADDR64 -I ${VAXD} -I ${PDP11D} ${NETWORK_OPT}
VAX730 = ${VAXD}/vax_cpu.c ${VAXD}/vax_cpu1.c ${VAXD}/vax_fpa.c \
${VAXD}/vax_cis.c ${VAXD}/vax_octa.c ${VAXD}/vax_cmode.c \
${VAXD}/vax_mmu.c ${VAXD}/vax_sys.c ${VAXD}/vax_syscm.c \
${VAXD}/vax730_stddev.c ${VAXD}/vax730_sys.c \
${VAXD}/vax730_mem.c ${VAXD}/vax730_uba.c ${VAXD}/vax730_rb.c \
${VAXD}/vax730_syslist.c \
${PDP11D}/pdp11_rl.c ${PDP11D}/pdp11_rq.c ${PDP11D}/pdp11_ts.c \
${PDP11D}/pdp11_dz.c ${PDP11D}/pdp11_lp.c ${PDP11D}/pdp11_tq.c \
${PDP11D}/pdp11_xu.c ${PDP11D}/pdp11_ry.c ${PDP11D}/pdp11_cr.c \
${PDP11D}/pdp11_hk.c ${PDP11D}/pdp11_io_lib.c
VAX730_OPT = -DVM_VAX -DVAX_730 -DUSE_INT64 -DUSE_ADDR64 -I VAX -I ${PDP11D} ${NETWORK_OPT}
VAX780 = ${VAXD}/vax_cpu.c ${VAXD}/vax_cpu1.c ${VAXD}/vax_fpa.c \
${VAXD}/vax_cis.c ${VAXD}/vax_octa.c ${VAXD}/vax_cmode.c \
${VAXD}/vax_mmu.c ${VAXD}/vax_sys.c ${VAXD}/vax_syscm.c \
@ -355,7 +368,7 @@ SWTP_OPT = -I ${SWTPD}
# Build everything
#
ALL = pdp1 pdp4 pdp7 pdp8 pdp9 pdp15 pdp11 pdp10 \
vax vax780 nova eclipse hp2100 i1401 i1620 s3 \
vax vax730 vax780 nova eclipse hp2100 i1401 i1620 s3 \
altair altairz80 gri i7094 ibm1130 id16 \
id32 sds lgp h316 swtp
@ -437,6 +450,12 @@ ${BIN}vax${EXE} : ${VAX} ${SIM} ${BUILD_ROMS}
${MKDIRBIN}
${CC} ${VAX} ${SIM} ${VAX_OPT} -o $@ ${LDFLAGS}
vax730 : ${BIN}vax730${EXE}
${BIN}vax730${EXE} : ${VAX730} ${SIM} ${BUILD_ROMS}
${MKDIRBIN}
${CC} ${VAX730} ${SIM} ${VAX730_OPT} -o $@ ${LDFLAGS}
vax780 : ${BIN}vax780${EXE}
${BIN}vax780${EXE} : ${VAX780} ${SIM} ${BUILD_ROMS}