Merge of VAX 11/730 Simulator from Matt Burke
This commit is contained in:
parent
cb35f6c97b
commit
a6b8d63f10
14 changed files with 4375 additions and 6 deletions
400
VAX/vax730_defs.h
Normal file
400
VAX/vax730_defs.h
Normal 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
196
VAX/vax730_mem.c
Normal 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
670
VAX/vax730_rb.c
Normal 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
1107
VAX/vax730_stddev.c
Normal file
File diff suppressed because it is too large
Load diff
665
VAX/vax730_sys.c
Normal file
665
VAX/vax730_sys.c
Normal 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
130
VAX/vax730_syslist.c
Normal 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
667
VAX/vax730_uba.c
Normal 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;
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
431
Visual Studio Projects/VAX730.vcproj
Normal file
431
Visual Studio Projects/VAX730.vcproj
Normal 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 ..
$(TargetDir)BuildROMs
popd
"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;../../winpcap/Wpdpack/Include;"../../pthreads/Pre-built.2/include""
|
||||
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/;"../../pthreads/Pre-built.2/lib/""
|
||||
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 ..
$(TargetDir)BuildROMs
popd
"
|
||||
/>
|
||||
<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;"../../pthreads/Pre-built.2/include""
|
||||
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/;"../../pthreads/Pre-built.2/lib/""
|
||||
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>
|
72
descrip.mms
72
descrip.mms
|
@ -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
|
||||
|
||||
|
|
25
makefile
25
makefile
|
@ -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}
|
||||
|
|
Loading…
Add table
Reference in a new issue