diff --git a/PDP11/old/pdp11_defs.h b/PDP11/old/pdp11_defs.h deleted file mode 100644 index be281cb4..00000000 --- a/PDP11/old/pdp11_defs.h +++ /dev/null @@ -1,862 +0,0 @@ -/* pdp11_defs.h: PDP-11 simulator definitions - - Copyright (c) 1993-2012, Robert M Supnik - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the name of Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - The author gratefully acknowledges the help of Max Burnet, Megan Gentry, - and John Wilson in resolving questions about the PDP-11 - - 12-Dec-12 RMS Fixed base address for RQB, RQC, RQD - 11-Dec-11 RMS Fixed priority of PIRQ vs IO; added INT_INTERNALn - 22-May-10 RMS Added check for 64b definitions - 19-Nov-08 RMS Moved I/O support routines to I/O library - 16-May-08 RMS Added KE11A, DC11 support - 02-Feb-08 RMS Fixed DMA memory address limit test (found by John Dundas) - 25-Jan-08 RMS Added RC11, KG11A support (from John Dundas) - 16-Dec-06 RMS Added TA11 support - 29-Oct-06 RMS Added clock coscheduling - 06-Jul-06 RMS Added multiple KL11/DL11 support - 26-Jun-06 RMS Added RF11 support - 24-May-06 RMS Added 11/44 DR support (from CIS diagnostic) - 17-May-06 RMS Added CR11/CD11 support (from John Dundas) - 30-Sep-04 RMS Added Massbus support - Removed Map_Addr prototype - Removed map argument from Unibus routines - Added framework for model selection - 28-May-04 RMS Added DHQ support - 25-Jan-04 RMS Removed local debug logging support - 22-Dec-03 RMS Added second DEUNA/DELUA support - 18-Oct-03 RMS Added DECtape off reel message - 19-May-03 RMS Revised for new conditional compilation - 05-Apr-03 RMS Fixed bug in MMR1 update (found by Tim Stark) - 28-Feb-03 RMS Added TM logging support - 19-Jan-03 RMS Changed mode definitions for Apple Dev Kit conflict - 11-Nov-02 RMS Changed log definitions to be VAX compatible - 10-Oct-02 RMS Added vector information to DIB - Changed DZ11 vector to Unibus standard - Added DEQNA/DELQA, DEUNA/DELUA support - Added multiple RQDX3, autoconfigure support - 12-Sep-02 RMS Added TMSCP, KW11P,and RX211 support - 28-Apr-02 RMS Clarified PDF ACF mnemonics - 22-Apr-02 RMS Added HTRAP, BPOK maint register flags, MT_MAXFR - 06-Mar-02 RMS Changed system type to KDJ11A - 20-Jan-02 RMS Added multiboard DZ11 support - 09-Nov-01 RMS Added bus map support - 07-Nov-01 RMS Added RQDX3 support - 26-Oct-01 RMS Added symbolic definitions for IO page - 19-Oct-01 RMS Added DZ definitions - 15-Oct-01 RMS Added logging capabilities - 07-Sep-01 RMS Revised for multilevel interrupts - 01-Jun-01 RMS Added DZ11 support - 23-Apr-01 RMS Added RK611 support - 05-Apr-01 RMS Added TS11/TSV05 support - 10-Feb-01 RMS Added DECtape support -*/ - -#ifndef _PDP11_DEFS_H -#define _PDP11_DEFS_H 0 - -#ifndef VM_PDP11 -#define VM_PDP11 0 -#endif - -#include "sim_defs.h" /* simulator defns */ -#include - -#if defined(USE_INT64) || defined(USE_ADDR64) -#error "PDP-11 does not support 64b values!" -#endif - -/* Architectural constants */ - -#define STKL_R 0340 /* stack limit */ -#define STKL_Y 0400 -#define VASIZE 0200000 /* 2**16 */ -#define VAMASK (VASIZE - 1) /* 2**16 - 1 */ -#define MEMSIZE64K 0200000 /* 2**16 */ -#define INIMEMSIZE 001000000 /* 2**18 */ -#define UNIMEMSIZE 001000000 /* 2**18 */ -#define UNIMASK (UNIMEMSIZE - 1) /* 2**18 - 1 */ -#define IOPAGEBASE 017760000 /* 2**22 - 2**13 */ -#define IOPAGESIZE 000020000 /* 2**13 */ -#define IOPAGEMASK (IOPAGESIZE - 1) /* 2**13 - 1 */ -#define MAXMEMSIZE 020000000 /* 2**22 */ -#define PAMASK (MAXMEMSIZE - 1) /* 2**22 - 1 */ -#define MEMSIZE (cpu_unit.capac) -#define ADDR_IS_MEM(x) (((t_addr) (x)) < cpu_memsize) /* use only in sim! */ -#define DMASK 0177777 - -/* CPU models */ - -#define MOD_1103 0 -#define MOD_1104 1 -#define MOD_1105 2 -#define MOD_1120 3 -#define MOD_1123 4 -#define MOD_1123P 5 -#define MOD_1124 6 -#define MOD_1134 7 -#define MOD_1140 8 -#define MOD_1144 9 -#define MOD_1145 10 -#define MOD_1160 11 -#define MOD_1170 12 -#define MOD_1173 13 -#define MOD_1153 14 -#define MOD_1173B 15 -#define MOD_1183 16 -#define MOD_1184 17 -#define MOD_1193 18 -#define MOD_1194 19 -#define MOD_T 20 - -#define CPUT_03 (1u << MOD_1103) /* LSI-11 */ -#define CPUT_04 (1u << MOD_1104) /* 11/04 */ -#define CPUT_05 (1u << MOD_1105) /* 11/05 */ -#define CPUT_20 (1u << MOD_1120) /* 11/20 */ -#define CPUT_23 (1u << MOD_1123) /* 11/23 */ -#define CPUT_23P (1u << MOD_1123P) /* 11/23+ */ -#define CPUT_24 (1u << MOD_1124) /* 11/24 */ -#define CPUT_34 (1u << MOD_1134) /* 11/34 */ -#define CPUT_40 (1u << MOD_1140) /* 11/40 */ -#define CPUT_44 (1u << MOD_1144) /* 11/44 */ -#define CPUT_45 (1u << MOD_1145) /* 11/45 */ -#define CPUT_60 (1u << MOD_1160) /* 11/60 */ -#define CPUT_70 (1u << MOD_1170) /* 11/70 */ -#define CPUT_73 (1u << MOD_1173) /* 11/73 */ -#define CPUT_53 (1u << MOD_1153) /* 11/53 */ -#define CPUT_73B (1u << MOD_1173B) /* 11/73B */ -#define CPUT_83 (1u << MOD_1183) /* 11/83 */ -#define CPUT_84 (1u << MOD_1184) /* 11/84 */ -#define CPUT_93 (1u << MOD_1193) /* 11/93 */ -#define CPUT_94 (1u << MOD_1194) /* 11/94 */ -#define CPUT_T (1u << MOD_T) /* T-11 */ - -#define CPUT_F (CPUT_23|CPUT_23P|CPUT_24) /* all F11's */ -#define CPUT_J (CPUT_53|CPUT_73|CPUT_73B| \ - CPUT_83|CPUT_84|CPUT_93|CPUT_94) -#define CPUT_JB (CPUT_73B|CPUT_83|CPUT_84) /* KDJ11B */ -#define CPUT_JE (CPUT_93|CPUT_94) /* KDJ11E */ -#define CPUT_JU (CPUT_84|CPUT_94) /* KTJ11B UBA */ -#define CPUT_ALL 0xFFFFFFFF - -/* CPU options */ - -#define BUS_U (1u << 0) /* Unibus */ -#define BUS_Q (0) /* Qbus */ -#define OPT_EIS (1u << 1) /* EIS */ -#define OPT_FIS (1u << 2) /* FIS */ -#define OPT_FPP (1u << 3) /* FPP */ -#define OPT_CIS (1u << 4) /* CIS */ -#define OPT_MMU (1u << 5) /* MMU */ -#define OPT_RH11 (1u << 6) /* RH11 */ -#define OPT_PAR (1u << 7) /* parity */ -#define OPT_UBM (1u << 8) /* UBM */ - -#define CPUT(x) ((cpu_type & (x)) != 0) -#define CPUO(x) ((cpu_opt & (x)) != 0) -#define UNIBUS (cpu_opt & BUS_U) - -/* Feature sets - - SDSD source addr, dest addr, source fetch, dest fetch - SR switch register - DR display register - RTT RTT instruction - SXS SXT, XOR, SOB instructions - MARK MARK instruction - SPL SPL instruction - MXPY MTPI, MTPD, MFPI, MFPD instructions - MXPS MTPS, MFPS instructions - MFPT MFPT instruction - CSM CSM instruction - TSWLK TSTSET, WRLCK instructions - PSW PSW register - EXPT explicit PSW writes can alter T-bit - IOSR general registers readable from programs in IO space - 2REG dual register set - MMR3 MMR3 register - MMTR mem mgt traps - STKLR STKLIM register - STKLF fixed stack limit - SID supervisor mode, I/D spaces - ODD odd address trap - HALT4 halt in kernel mode traps to 4 - JREG4 JMP/JSR R traps to 4 - STKA stop on stack abort - LTCR LTC CSR - LTCM LTC CSR<7> -*/ - -#define IS_SDSD (CPUT_20|CPUT_F|CPUT_40|CPUT_60|CPUT_J|CPUT_T) -#define HAS_SR (CPUT_04|CPUT_05|CPUT_20|CPUT_34|CPUT_40| \ - CPUT_44|CPUT_45|CPUT_60|CPUT_70) -#define HAS_DR (CPUT_04|CPUT_05|CPUT_20|CPUT_24|CPUT_34| \ - CPUT_40|CPUT_44|CPUT_45|CPUT_60|CPUT_70) -#define HAS_RTT (CPUT_03|CPUT_04|CPUT_F|CPUT_34|CPUT_40| \ - CPUT_44|CPUT_45|CPUT_60|CPUT_70|CPUT_J|CPUT_T) -#define HAS_SXS (CPUT_03|CPUT_F|CPUT_34|CPUT_40|CPUT_44| \ - CPUT_45|CPUT_60|CPUT_70|CPUT_J|CPUT_T) -#define HAS_MARK (CPUT_03|CPUT_F|CPUT_34|CPUT_40|CPUT_44| \ - CPUT_45|CPUT_60|CPUT_70|CPUT_J) -#define HAS_SPL (CPUT_44|CPUT_45|CPUT_70|CPUT_J) -#define HAS_MXPY (CPUT_F|CPUT_34|CPUT_40|CPUT_44|CPUT_45| \ - CPUT_60|CPUT_70|CPUT_J) -#define HAS_MXPS (CPUT_03|CPUT_F|CPUT_34|CPUT_J|CPUT_T) -#define HAS_MFPT (CPUT_F|CPUT_44|CPUT_J|CPUT_T) -#define HAS_CSM (CPUT_44|CPUT_J) -#define HAS_TSWLK (CPUT_J) -#define HAS_PSW (CPUT_04|CPUT_05|CPUT_20|CPUT_F|CPUT_34|CPUT_40| \ - CPUT_44|CPUT_45|CPUT_60|CPUT_70|CPUT_J) -#define HAS_EXPT (CPUT_04|CPUT_05|CPUT_20) -#define HAS_IOSR (CPUT_04|CPUT_05) -#define HAS_2REG (CPUT_45|CPUT_70|CPUT_J) -#define HAS_MMR3 (CPUT_F|CPUT_44|CPUT_45|CPUT_70|CPUT_J) -#define HAS_MMTR (CPUT_45|CPUT_70) -#define HAS_STKLR (CPUT_45|CPUT_60|CPUT_70) -#define HAS_STKLF (CPUT_04|CPUT_05|CPUT_20|CPUT_F|CPUT_34| \ - CPUT_40|CPUT_44|CPUT_J) -#define HAS_SID (CPUT_44|CPUT_45|CPUT_70|CPUT_J) -#define HAS_ODD (CPUT_04|CPUT_05|CPUT_20|CPUT_34|CPUT_40| \ - CPUT_44|CPUT_45|CPUT_60|CPUT_70|CPUT_J) -#define HAS_HALT4 (CPUT_44|CPUT_45|CPUT_70|CPUT_J) -#define HAS_JREG4 (CPUT_03|CPUT_04|CPUT_05|CPUT_20|CPUT_F| \ - CPUT_34|CPUT_40|CPUT_60|CPUT_T) -#define STOP_STKA (CPUT_03|CPUT_04|CPUT_05|CPUT_20|CPUT_34|CPUT_44) -#define HAS_LTCR (CPUT_04|CPUT_05|CPUT_20|CPUT_23P|CPUT_24| \ - CPUT_34|CPUT_40|CPUT_44|CPUT_45|CPUT_60| \ - CPUT_70|CPUT_J) -#define HAS_LTCM (CPUT_04|CPUT_05|CPUT_20|CPUT_24|CPUT_34| \ - CPUT_40|CPUT_44|CPUT_45|CPUT_60|CPUT_70|CPUT_J) - -/* Protection modes */ - -#define MD_KER 0 -#define MD_SUP 1 -#define MD_UND 2 -#define MD_USR 3 - -/* I/O access modes */ - -#define READ 0 -#define READC 1 /* read console */ -#define WRITE 2 -#define WRITEC 3 /* write console */ -#define WRITEB 4 - -/* PSW */ - -#define PSW_V_C 0 /* condition codes */ -#define PSW_V_V 1 -#define PSW_V_Z 2 -#define PSW_V_N 3 -#define PSW_V_TBIT 4 /* trace trap */ -#define PSW_V_IPL 5 /* int priority */ -#define PSW_V_FPD 8 /* first part done */ -#define PSW_V_RS 11 /* register set */ -#define PSW_V_PM 12 /* previous mode */ -#define PSW_V_CM 14 /* current mode */ -#define PSW_CC 017 -#define PSW_TBIT (1 << PSW_V_TBIT) -#define PSW_PM (3 << PSW_V_PM) - -/* FPS */ - -#define FPS_V_C 0 /* condition codes */ -#define FPS_V_V 1 -#define FPS_V_Z 2 -#define FPS_V_N 3 -#define FPS_V_T 5 /* truncate */ -#define FPS_V_L 6 /* long */ -#define FPS_V_D 7 /* double */ -#define FPS_V_IC 8 /* ic err int */ -#define FPS_V_IV 9 /* overflo err int */ -#define FPS_V_IU 10 /* underflo err int */ -#define FPS_V_IUV 11 /* undef var err int */ -#define FPS_V_ID 14 /* int disable */ -#define FPS_V_ER 15 /* error */ - -/* PIRQ */ - -#define PIRQ_PIR1 0001000 -#define PIRQ_PIR2 0002000 -#define PIRQ_PIR3 0004000 -#define PIRQ_PIR4 0010000 -#define PIRQ_PIR5 0020000 -#define PIRQ_PIR6 0040000 -#define PIRQ_PIR7 0100000 -#define PIRQ_IMP 0177356 /* implemented bits */ -#define PIRQ_RW 0177000 /* read/write bits */ - -/* STKLIM */ - -#define STKLIM_RW 0177400 - -/* MMR0 */ - -#define MMR0_MME 0000001 /* mem mgt enable */ -#define MMR0_V_PAGE 1 /* offset to pageno */ -#define MMR0_M_PAGE 077 /* mask for pageno */ -#define MMR0_PAGE (MMR0_M_PAGE << MMR0_V_PAGE) -#define MMR0_IC 0000200 /* instr complete */ -#define MMR0_MAINT 0000400 /* maintenance */ -#define MMR0_TENB 0001000 /* trap enable */ -#define MMR0_TRAP 0010000 /* mem mgt trap */ -#define MMR0_RO 0020000 /* read only error */ -#define MMR0_PL 0040000 /* page lnt error */ -#define MMR0_NR 0100000 /* no access error */ -#define MMR0_FREEZE 0160000 /* if set, no update */ -#define MMR0_WR 0171401 /* writeable bits */ - -/* MMR3 */ - -#define MMR3_UDS 001 /* user dspace enbl */ -#define MMR3_SDS 002 /* super dspace enbl */ -#define MMR3_KDS 004 /* krnl dspace enbl */ -#define MMR3_CSM 010 /* CSM enable */ -#define MMR3_M22E 020 /* 22b mem mgt enbl */ -#define MMR3_BME 040 /* DMA bus map enbl */ - -/* PAR */ - -#define PAR_18B 0007777 /* 18b addressing */ -#define PAR_22B 0177777 /* 22b addressing */ - -/* PDR */ - -#define PDR_ACF 0000007 /* access control */ -#define PDR_ACS 0000006 /* 2b access control */ -#define PDR_ED 0000010 /* expansion dir */ -#define PDR_W 0000100 /* written flag */ -#define PDR_A 0000200 /* access flag */ -#define PDR_PLF 0077400 /* page lnt field */ -#define PDR_NOC 0100000 /* don't cache */ - -#define PDR_PRD 0000003 /* page readable if 2 */ - -/* Virtual address */ - -#define VA_DF 0017777 /* displacement */ -#define VA_BN 0017700 /* block number */ -#define VA_V_APF 13 /* offset to APF */ -#define VA_V_DS 16 /* offset to space */ -#define VA_V_MODE 17 /* offset to mode */ -#define VA_DS (1u << VA_V_DS) /* data space flag */ - -/* Unibus map (if present) */ - -#define UBM_LNT_LW 32 /* size in LW */ -#define UBM_V_PN 13 /* page number */ -#define UBM_M_PN 037 -#define UBM_V_OFF 0 /* offset */ -#define UBM_M_OFF 017777 -#define UBM_PAGSIZE (UBM_M_OFF + 1) /* page size */ -#define UBM_GETPN(x) (((x) >> UBM_V_PN) & UBM_M_PN) -#define UBM_GETOFF(x) ((x) & UBM_M_OFF) - -/* CPUERR */ - -#define CPUE_RED 0004 /* red stack */ -#define CPUE_YEL 0010 /* yellow stack */ -#define CPUE_TMO 0020 /* IO page nxm */ -#define CPUE_NXM 0040 /* memory nxm */ -#define CPUE_ODD 0100 /* odd address */ -#define CPUE_HALT 0200 /* HALT not kernel */ -#define CPUE_IMP 0374 /* implemented bits */ - -/* Floating point accumulators */ - -typedef struct { - uint32 l; /* low 32b */ - uint32 h; /* high 32b */ - } fpac_t; - -/* Device CSRs */ - -#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) - -/* Trap masks, descending priority order, following J-11 - An interrupt summary bit is kept with traps, to minimize overhead -*/ - -#define TRAP_V_RED 0 /* red stk abort 4 */ -#define TRAP_V_ODD 1 /* odd address 4 */ -#define TRAP_V_MME 2 /* mem mgt 250 */ -#define TRAP_V_NXM 3 /* nx memory 4 */ -#define TRAP_V_PAR 4 /* parity err 114 */ -#define TRAP_V_PRV 5 /* priv inst 4 */ -#define TRAP_V_ILL 6 /* illegal inst 10 */ -#define TRAP_V_BPT 7 /* BPT 14 */ -#define TRAP_V_IOT 8 /* IOT 20 */ -#define TRAP_V_EMT 9 /* EMT 30 */ -#define TRAP_V_TRAP 10 /* TRAP 34 */ -#define TRAP_V_TRC 11 /* T bit 14 */ -#define TRAP_V_YEL 12 /* stack 4 */ -#define TRAP_V_PWRFL 13 /* power fail 24 */ -#define TRAP_V_FPE 14 /* fpe 244 */ -#define TRAP_V_MAX 15 /* intr = max trp # */ -#define TRAP_RED (1u << TRAP_V_RED) -#define TRAP_ODD (1u << TRAP_V_ODD) -#define TRAP_MME (1u << TRAP_V_MME) -#define TRAP_NXM (1u << TRAP_V_NXM) -#define TRAP_PAR (1u << TRAP_V_PAR) -#define TRAP_PRV (1u << TRAP_V_PRV) -#define TRAP_ILL (1u << TRAP_V_ILL) -#define TRAP_BPT (1u << TRAP_V_BPT) -#define TRAP_IOT (1u << TRAP_V_IOT) -#define TRAP_EMT (1u << TRAP_V_EMT) -#define TRAP_TRAP (1u << TRAP_V_TRAP) -#define TRAP_TRC (1u << TRAP_V_TRC) -#define TRAP_YEL (1u << TRAP_V_YEL) -#define TRAP_PWRFL (1u << TRAP_V_PWRFL) -#define TRAP_FPE (1u << TRAP_V_FPE) -#define TRAP_INT (1u << TRAP_V_MAX) -#define TRAP_ALL ((1u << TRAP_V_MAX) - 1) /* all traps */ - -#define VEC_RED 0004 /* trap vectors */ -#define VEC_ODD 0004 -#define VEC_MME 0250 -#define VEC_NXM 0004 -#define VEC_PAR 0114 -#define VEC_PRV 0004 -#define VEC_ILL 0010 -#define VEC_BPT 0014 -#define VEC_IOT 0020 -#define VEC_EMT 0030 -#define VEC_TRAP 0034 -#define VEC_TRC 0014 -#define VEC_YEL 0004 -#define VEC_PWRFL 0024 -#define VEC_FPE 0244 - -/* Simulator stop codes; codes 1:TRAP_V_MAX correspond to traps 0:TRAPMAX-1 */ - -#define STOP_HALT (TRAP_V_MAX + 1) /* HALT instruction */ -#define STOP_IBKPT (TRAP_V_MAX + 2) /* instruction bkpt */ -#define STOP_WAIT (TRAP_V_MAX + 3) /* wait, no events */ -#define STOP_VECABORT (TRAP_V_MAX + 4) /* abort vector read */ -#define STOP_SPABORT (TRAP_V_MAX + 5) /* abort trap push */ -#define STOP_RQ (TRAP_V_MAX + 6) /* RQDX3 panic */ -#define STOP_SANITY (TRAP_V_MAX + 7) /* sanity timer exp */ -#define STOP_DTOFF (TRAP_V_MAX + 8) /* DECtape off reel */ -#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* cond error return */ - -/* Timers */ - -#define TMR_CLK 0 /* line clock */ -#define TMR_PCLK 1 /* KW11P */ - -/* IO parameters */ - -#define DZ_MUXES 4 /* max # of DZ muxes */ -#define DZ_LINES 8 /* lines per DZ mux */ -#define VH_MUXES 4 /* max # of VH 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 AUTO_LNT 34 /* autoconfig ranks */ -#define DIB_MAX 100 /* max DIBs */ - -#define DEV_V_UBUS (DEV_V_UF + 0) /* Unibus */ -#define DEV_V_QBUS (DEV_V_UF + 1) /* Qbus */ -#define DEV_V_Q18 (DEV_V_UF + 2) /* Qbus with <= 256KB */ -#define DEV_V_FLTA (DEV_V_UF + 3) /* flt addr */ -#define DEV_V_MBUS (DEV_V_UF + 4) /* Massbus */ -#define DEV_V_FFUF (DEV_V_UF + 5) /* first free flag */ -#define DEV_UBUS (1u << DEV_V_UBUS) -#define DEV_QBUS (1u << DEV_V_QBUS) -#define DEV_Q18 (1u << DEV_V_Q18) -#define DEV_FLTA (1u << DEV_V_FLTA) -#define DEV_MBUS (1u << DEV_V_MBUS) - -#define DEV_RDX 8 /* default device radix */ - -/* Device information block */ - -#define VEC_DEVMAX 4 /* max device vec */ - -struct pdp_dib { - 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 routines */ - }; - -typedef struct pdp_dib DIB; - -/* 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 (IOBA_RQB + IOLN_RQB) -#define IOLN_RQC 004 -#define IOBA_RQD (IOBA_RQC + IOLN_RQC) -#define IOLN_RQD 004 -#define IOBA_VH (IOPAGEBASE + 000440) /* DHQ11 */ -#define IOLN_VH 020 -#define IOBA_UBM (IOPAGEBASE + 010200) /* Unibus map */ -#define IOLN_UBM (UBM_LNT_LW * sizeof (int32)) -#define IOBA_KG (IOPAGEBASE + 010700) /* KG11-A */ -#define IOLN_KG 006 -#define IOBA_RQ (IOPAGEBASE + 012150) /* RQDX3 */ -#define IOLN_RQ 004 -#define IOBA_SUP (IOPAGEBASE + 012200) /* supervisor APR's */ -#define IOLN_SUP 0100 -#define IOBA_KIPDR (IOPAGEBASE + 012300) /* kernel APR's */ -#define IOLN_KIPDR 020 -#define IOBA_KDPDR (IOPAGEBASE + 012320) -#define IOLN_KDPDR 020 -#define IOBA_KIPAR (IOPAGEBASE + 012340) -#define IOLN_KIPAR 020 -#define IOBA_KDPAR (IOPAGEBASE + 012360) -#define IOLN_KDPAR 020 -#define IOBA_TU (IOPAGEBASE + 012440) /* TU */ -#define IOLN_TU 040 -#define IOBA_MMR3 (IOPAGEBASE + 012516) /* MMR3 */ -#define IOLN_MMR3 002 -#define IOBA_TM (IOPAGEBASE + 012520) /* TM11 */ -#define IOLN_TM 014 -#define IOBA_TS (IOPAGEBASE + 012520) /* TS11 */ -#define IOLN_TS 004 -#define IOBA_PCLK (IOPAGEBASE + 012540) /* KW11P */ -#define IOLN_PCLK 006 -#define IOBA_DC (IOPAGEBASE + 014000) /* DC11 */ -#define IOLN_DC (DCX_LINES * 010) -#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_DL (IOPAGEBASE + 016500) /* extra KL11/DL11 */ -#define IOLN_DL (DLX_LINES * 010) -#define IOBA_RP (IOPAGEBASE + 016700) /* RP/RM */ -#define IOLN_RP 054 -#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) /* RY11 */ -#define IOLN_RY 004 -#define IOBA_KE (IOPAGEBASE + 017300) /* KE11-A */ -#define IOLN_KE 020 -#define IOBA_TC (IOPAGEBASE + 017340) /* TC11 */ -#define IOLN_TC 012 -#define IOBA_QDSS (IOPAGEBASE + 017400) /* QDSS */ -#define IOLN_QDSS 002 -#define IOBA_RK (IOPAGEBASE + 017400) /* RK11 */ -#define IOLN_RK 020 -#define IOBA_RC (IOPAGEBASE + 017440) /* RC11/RS64 */ -#define IOLN_RC 020 -#define IOBA_HK (IOPAGEBASE + 017440) /* RK611 */ -#define IOLN_HK 040 -#define IOBA_RF (IOPAGEBASE + 017460) /* RF11 */ -#define IOLN_RF 020 -#define IOBA_TA (IOPAGEBASE + 017500) /* TA11 */ -#define IOLN_TA 004 -#define IOBA_LPT (IOPAGEBASE + 017514) /* LP11 */ -#define IOLN_LPT 004 -#define IOBA_CTL (IOPAGEBASE + 017520) /* board ctrl */ -#define IOLN_CTL 010 -#define IOBA_CLK (IOPAGEBASE + 017546) /* KW11L */ -#define IOLN_CLK 002 -#define IOBA_PTR (IOPAGEBASE + 017550) /* PC11 reader */ -#define IOLN_PTR 004 -#define IOBA_PTP (IOPAGEBASE + 017554) /* PC11 punch */ -#define IOLN_PTP 004 -#define IOBA_TTI (IOPAGEBASE + 017560) /* DL11 rcv */ -#define IOLN_TTI 004 -#define IOBA_TTO (IOPAGEBASE + 017564) /* DL11 xmt */ -#define IOLN_TTO 004 -#define IOBA_SR (IOPAGEBASE + 017570) /* SR */ -#define IOLN_SR 002 -#define IOBA_MMR012 (IOPAGEBASE + 017572) /* MMR0-2 */ -#define IOLN_MMR012 006 -#define IOBA_UIPDR (IOPAGEBASE + 017600) /* user APR's */ -#define IOLN_UIPDR 020 -#define IOBA_UDPDR (IOPAGEBASE + 017620) -#define IOLN_UDPDR 020 -#define IOBA_UIPAR (IOPAGEBASE + 017640) -#define IOLN_UIPAR 020 -#define IOBA_UDPAR (IOPAGEBASE + 017660) -#define IOLN_UDPAR 020 -#define IOBA_GPR (IOPAGEBASE + 017700) /* GPR's */ -#define IOLN_GPR 010 -#define IOBA_UCTL (IOPAGEBASE + 017730) /* UBA ctrl */ -#define IOLN_UCTL 010 -#define IOBA_CPU (IOPAGEBASE + 017740) /* CPU reg */ -#define IOLN_CPU 036 -#define IOBA_PSW (IOPAGEBASE + 017776) /* PSW */ -#define IOLN_PSW 002 - -/* Interrupt assignments; within each level, priority is right to left - PIRQn has the highest priority with a level and is always bit <0> - On level 6, the clock is second highest priority */ - -#define IPL_HLVL 8 /* # int levels */ -#define IPL_HMIN 4 /* lowest IO int level */ - -#define INT_V_PIR7 0 /* BR7 */ - -#define INT_V_PIR6 0 /* BR6 */ -#define INT_V_CLK 1 -#define INT_V_PCLK 2 -#define INT_V_DTA 3 -#define INT_V_TA 4 - -#define INT_V_PIR5 0 /* BR5 */ -#define INT_V_RK 1 -#define INT_V_RL 2 -#define INT_V_RX 3 -#define INT_V_TM 4 -#define INT_V_RP 5 -#define INT_V_TS 6 -#define INT_V_HK 7 -#define INT_V_RQ 8 -#define INT_V_DZRX 9 -#define INT_V_DZTX 10 -#define INT_V_TQ 11 -#define INT_V_RY 12 -#define INT_V_XQ 13 -#define INT_V_XU 14 -#define INT_V_TU 15 -#define INT_V_RF 16 -#define INT_V_RC 17 - -#define INT_V_PIR4 0 /* BR4 */ -#define INT_V_TTI 1 -#define INT_V_TTO 2 -#define INT_V_PTR 3 -#define INT_V_PTP 4 -#define INT_V_LPT 5 -#define INT_V_VHRX 6 -#define INT_V_VHTX 7 -#define INT_V_CR 8 -#define INT_V_DLI 9 -#define INT_V_DLO 10 -#define INT_V_DCI 11 -#define INT_V_DCO 12 - -#define INT_V_PIR3 0 /* BR3 */ -#define INT_V_PIR2 0 /* BR2 */ -#define INT_V_PIR1 0 /* BR1 */ - -#define INT_PIR7 (1u << INT_V_PIR7) -#define INT_PIR6 (1u << INT_V_PIR6) -#define INT_CLK (1u << INT_V_CLK) -#define INT_PCLK (1u << INT_V_PCLK) -#define INT_DTA (1u << INT_V_DTA) -#define INT_TA (1u << INT_V_TA) -#define INT_PIR5 (1u << INT_V_PIR5) -#define INT_RK (1u << INT_V_RK) -#define INT_RL (1u << INT_V_RL) -#define INT_RX (1u << INT_V_RX) -#define INT_TM (1u << INT_V_TM) -#define INT_RP (1u << INT_V_RP) -#define INT_TS (1u << INT_V_TS) -#define INT_HK (1u << INT_V_HK) -#define INT_RQ (1u << INT_V_RQ) -#define INT_DZRX (1u << INT_V_DZRX) -#define INT_DZTX (1u << INT_V_DZTX) -#define INT_TQ (1u << INT_V_TQ) -#define INT_RY (1u << INT_V_RY) -#define INT_XQ (1u << INT_V_XQ) -#define INT_XU (1u << INT_V_XU) -#define INT_TU (1u << INT_V_TU) -#define INT_RF (1u << INT_V_RF) -#define INT_RC (1u << INT_V_RC) -#define INT_PIR4 (1u << INT_V_PIR4) -#define INT_TTI (1u << INT_V_TTI) -#define INT_TTO (1u << INT_V_TTO) -#define INT_PTR (1u << INT_V_PTR) -#define INT_PTP (1u << INT_V_PTP) -#define INT_LPT (1u << INT_V_LPT) -#define INT_VHRX (1u << INT_V_VHRX) -#define INT_VHTX (1u << INT_V_VHTX) -#define INT_CR (1u << INT_V_CR) -#define INT_DLI (1u << INT_V_DLI) -#define INT_DLO (1u << INT_V_DLO) -#define INT_DCI (1u << INT_V_DCI) -#define INT_DCO (1u << INT_V_DCO) -#define INT_PIR3 (1u << INT_V_PIR3) -#define INT_PIR2 (1u << INT_V_PIR2) -#define INT_PIR1 (1u << INT_V_PIR1) - -#define INT_INTERNAL7 (INT_PIR7) -#define INT_INTERNAL6 (INT_PIR6 | INT_CLK) -#define INT_INTERNAL5 (INT_PIR5) -#define INT_INTERNAL4 (INT_PIR4) -#define INT_INTERNAL3 (INT_PIR3) -#define INT_INTERNAL2 (INT_PIR2) -#define INT_INTERNAL1 (INT_PIR1) - -#define IPL_CLK 6 /* int pri levels */ -#define IPL_PCLK 6 -#define IPL_DTA 6 -#define IPL_TA 6 -#define IPL_RK 5 -#define IPL_RL 5 -#define IPL_RX 5 -#define IPL_TM 5 -#define IPL_RP 5 -#define IPL_TS 5 -#define IPL_HK 5 -#define IPL_RQ 5 -#define IPL_DZRX 5 -#define IPL_DZTX 5 -#define IPL_TQ 5 -#define IPL_RY 5 -#define IPL_XQ 5 -#define IPL_XU 5 -#define IPL_TU 5 -#define IPL_RF 5 -#define IPL_RC 5 -#define IPL_PTR 4 -#define IPL_PTP 4 -#define IPL_TTI 4 -#define IPL_TTO 4 -#define IPL_LPT 4 -#define IPL_VHRX 4 -#define IPL_VHTX 4 -#define IPL_CR 4 -#define IPL_DLI 4 -#define IPL_DLO 4 -#define IPL_DCI 4 -#define IPL_DCO 4 - -#define IPL_PIR7 7 -#define IPL_PIR6 6 -#define IPL_PIR5 5 -#define IPL_PIR4 4 -#define IPL_PIR3 3 -#define IPL_PIR2 2 -#define IPL_PIR1 1 - -/* Device vectors */ - -#define VEC_Q 0000 /* vector base */ -#define VEC_PIRQ 0240 -#define VEC_TTI 0060 -#define VEC_TTO 0064 -#define VEC_PTR 0070 -#define VEC_PTP 0074 -#define VEC_CLK 0100 -#define VEC_PCLK 0104 -#define VEC_XQ 0120 -#define VEC_XU 0120 -#define VEC_RQ 0154 -#define VEC_RL 0160 -#define VEC_LPT 0200 -#define VEC_RF 0204 -#define VEC_HK 0210 -#define VEC_RC 0210 -#define VEC_RK 0220 -#define VEC_DTA 0214 -#define VEC_TM 0224 -#define VEC_TS 0224 -#define VEC_TU 0224 -#define VEC_CR 0230 -#define VEC_RP 0254 -#define VEC_TQ 0260 -#define VEC_TA 0260 -#define VEC_RX 0264 -#define VEC_RY 0264 -#define VEC_DLI 0300 -#define VEC_DLO 0304 -#define VEC_DCI 0300 -#define VEC_DCO 0304 -#define VEC_DZRX 0300 -#define VEC_DZTX 0304 -#define VEC_VHRX 0310 -#define VEC_VHTX 0314 - -/* Interrupt macros */ - -#define IVCL(dv) ((IPL_##dv * 32) + INT_V_##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) - -/* Massbus definitions */ - -#define MBA_NUM 2 /* number of MBA's */ -#define MBA_RP 0 /* MBA for RP */ -#define MBA_TU 1 /* MBA for TU */ -#define MBA_RMASK 037 /* max 32 reg */ -#define MBE_NXD 1 /* nx drive */ -#define MBE_NXR 2 /* nx reg */ -#define MBE_GOE 3 /* err on GO */ - -/* CPU and FPU macros */ - -#define update_MM ((MMR0 & MMR0_FREEZE) == 0) -#define setTRAP(name) trap_req = trap_req | (name) -#define setCPUERR(name) CPUERR = CPUERR | (name) -#define ABORT(val) longjmp (save_env, (val)) -#define SP R[6] -#define PC R[7] - -/* Function prototypes */ - -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); - -int32 mba_rdbufW (uint32 mbus, int32 bc, uint16 *buf); -int32 mba_wrbufW (uint32 mbus, int32 bc, uint16 *buf); -int32 mba_chbufW (uint32 mbus, int32 bc, uint16 *buf); -int32 mba_get_bc (uint32 mbus); -int32 mba_get_csr (uint32 mbus); -void mba_upd_ata (uint32 mbus, uint32 val); -void mba_set_exc (uint32 mbus); -void mba_set_don (uint32 mbus); -void mba_set_enbdis (uint32 mb, t_bool dis); -t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, void *desc); - -int32 clk_cosched (int32 wait); - -#include "pdp11_io_lib.h" - -#endif diff --git a/PDP11/old/pdp11_rh.c b/PDP11/old/pdp11_rh.c deleted file mode 100644 index efc7c043..00000000 --- a/PDP11/old/pdp11_rh.c +++ /dev/null @@ -1,856 +0,0 @@ -/* pdp11_rh.c: PDP-11 Massbus adapter simulator - - Copyright (c) 2005-2012, Robert M Supnik - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the name of Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - rha, rhb RH11/RH70 Massbus adapter - - 19-Mar-12 RMS Fixed declaration of cpu_opt (Mark Pizzolato) - 02-Feb-08 RMS Fixed DMA memory address limit test (John Dundas) - 17-May-07 RMS Moved CS1 drive enable to devices - 21-Nov-05 RMS Added enable/disable routine - 07-Jul-05 RMS Removed extraneous externs - - WARNING: The interupt logic of the RH11/RH70 is unusual and must be - simulated with great precision. The RH11 has an internal interrupt - request flop, CSTB INTR, which is controlled as follows: - - - Writing IE and DONE simultaneously sets CSTB INTR - - Controller clear, INIT, and interrupt acknowledge clear CSTB INTR - (and also clear IE) - - A transition of DONE from 0 to 1 sets CSTB INTR from IE - - The output of CSTB INTR is OR'd with the AND of RPCS1 to - create the interrupt request signal. Thus, - - - The DONE interrupt is edge sensitive, but the SC interrupt is - level sensitive. - - The DONE interrupt, once set, is not disabled if IE is cleared, - but the SC interrupt is. -*/ - -#if defined (VM_PDP10) /* PDP10 version */ -#error "PDP-10 uses pdp10_rp.c and pdp10_tu.c!" - -#elif defined (VM_VAX) /* VAX version */ -#error "VAX uses vax780_mba.c!" - -#else /* PDP-11 version */ -#include "pdp11_defs.h" -#endif - -/* CS1 - base + 000 - control/status 1 */ - -#define CS1_OF 0 -#define CS1_GO CSR_GO /* go */ -#define CS1_V_FNC 1 /* function pos */ -#define CS1_M_FNC 037 /* function mask */ -#define CS1_FNC (CS1_M_FNC << CS1_V_FNC) -#define FNC_XFER 024 /* >=? data xfr */ -#define CS1_IE CSR_IE /* int enable */ -#define CS1_DONE CSR_DONE /* ready */ -#define CS1_V_UAE 8 /* Unibus addr ext */ -#define CS1_M_UAE 03 -#define CS1_UAE (CS1_M_UAE << CS1_V_UAE) -#define CS1_MCPE 0020000 /* Mbus par err NI */ -#define CS1_TRE 0040000 /* transfer err */ -#define CS1_SC 0100000 /* special cond */ -#define CS1_MBZ 0012000 -#define CS1_DRV (CS1_FNC | CS1_GO) -#define GET_FNC(x) (((x) >> CS1_V_FNC) & CS1_M_FNC) - -/* WC - base + 002 - word count */ - -#define WC_OF 1 - -/* BA - base + 004 - base address */ - -#define BA_OF 2 -#define BA_MBZ 0000001 /* must be zero */ - -/* CS2 - base + 010 - control/status 2 */ - -#define CS2_OF 3 -#define CS2_V_UNIT 0 /* unit pos */ -#define CS2_M_UNIT 07 /* unit mask */ -#define CS2_UNIT (CS2_M_UNIT << CS2_V_UNIT) -#define CS2_UAI 0000010 /* addr inhibit */ -#define CS2_PAT 0000020 /* parity test NI */ -#define CS2_CLR 0000040 /* controller clear */ -#define CS2_IR 0000100 /* input ready */ -#define CS2_OR 0000200 /* output ready */ -#define CS2_MDPE 0000400 /* Mbus par err NI */ -#define CS2_MXF 0001000 /* missed xfer NI */ -#define CS2_PGE 0002000 /* program err */ -#define CS2_NEM 0004000 /* nx mem err */ -#define CS2_NED 0010000 /* nx drive err */ -#define CS2_PE 0020000 /* parity err NI */ -#define CS2_WCE 0040000 /* write check err */ -#define CS2_DLT 0100000 /* data late NI */ -#define CS2_MBZ (CS2_CLR) -#define CS2_RW (CS2_UNIT | CS2_UAI | CS2_PAT | CS2_MXF | CS2_PE) -#define CS2_ERR (CS2_MDPE | CS2_MXF | CS2_PGE | CS2_NEM | \ - CS2_NED | CS2_PE | CS2_WCE | CS2_DLT) -#define GET_UNIT(x) (((x) >> CS2_V_UNIT) & CS2_M_UNIT) - -/* DB - base + 022 - data buffer */ - -#define DB_OF 4 - -/* BAE - base + 050/34 - bus address extension */ - -#define BAE_OF 5 -#define AE_M_MAE 0 /* addr ext pos */ -#define AE_V_MAE 077 /* addr ext mask */ -#define AE_MBZ 0177700 - -/* CS3 - base + 052/36 - control/status 3 */ - -#define CS3_OF 6 -#define CS3_APE 0100000 /* addr perr - NI */ -#define CS3_DPO 0040000 /* data perr odd - NI */ -#define CS3_DPE 0020000 /* data perr even - NI */ -#define CS3_WCO 0010000 /* wchk err odd */ -#define CS3_WCE 0004000 /* wchk err even */ -#define CS3_DBL 0002000 /* dbl word xfer - NI */ -#define CS3_IPCK 0000017 /* wrong par - NI */ -#define CS3_ERR (CS3_APE|CS3_DPO|CS3_DPE|CS3_WCO|CS3_WCE) -#define CS3_MBZ 0001660 -#define CS3_RW (CS1_IE | CS3_IPCK) - -#define MBA_OFSMASK 077 /* max 32 reg */ -#define INT 0000 /* int reg flag */ -#define EXT 0100 /* ext reg flag */ - -/* Declarations */ - -#define RH11 (cpu_opt & OPT_RH11) - -typedef struct { - uint32 cs1; /* ctrl/status 1 */ - uint32 wc; /* word count */ - uint32 ba; /* bus addr */ - uint32 cs2; /* ctrl/status 2 */ - uint32 db; /* data buffer */ - uint32 bae; /* addr ext */ - uint32 cs3; /* ctrl/status 3 */ - uint32 iff; /* int flip flop */ - } MBACTX; - -MBACTX massbus[MBA_NUM]; - -extern uint32 cpu_opt; -extern int32 cpu_bme; -extern uint16 *M; -extern int32 int_req[IPL_HLVL]; -extern t_addr cpu_memsize; -extern FILE *sim_deb; -extern FILE *sim_log; -extern int32 sim_switches; - -t_stat mba_reset (DEVICE *dptr); -t_stat mba_rd (int32 *val, int32 pa, int32 access); -t_stat mba_wr (int32 val, int32 pa, int32 access); -t_stat mba_set_type (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat mba_show_type (FILE *st, UNIT *uptr, int32 val, void *desc); -int32 mba0_inta (void); -int32 mba1_inta (void); -void mba_set_int (uint32 mb); -void mba_clr_int (uint32 mb); -void mba_upd_cs1 (uint32 set, uint32 clr, uint32 mb); -void mba_set_cs2 (uint32 flg, uint32 mb); -uint32 mba_map_pa (int32 pa, int32 *ofs); -DEVICE mba0_dev, mba1_dev; - -extern uint32 Map_Addr (uint32 ba); - -/* Massbus register dispatches */ - -static t_stat (*mbregR[MBA_NUM])(int32 *dat, int32 ad, int32 md); -static t_stat (*mbregW[MBA_NUM])(int32 dat, int32 ad, int32 md); -static int32 (*mbabort[MBA_NUM])(void); - -/* Unibus to register offset map */ - -static int32 mba_mapofs[(MBA_OFSMASK + 1) >> 1] = { - INT|0, INT|1, INT|2, EXT|5, INT|3, EXT|1, EXT|2, EXT|4, - EXT|7, INT|4, EXT|3, EXT|6, EXT|8, EXT|9, EXT|10, EXT|11, - EXT|12, EXT|13, EXT|14, EXT|15, EXT|16, EXT|17, EXT|18, EXT|19, - EXT|20, EXT|21, EXT|22, EXT|23, EXT|24, EXT|25, EXT|26, EXT|27 - }; - -/* Massbus adapter data structures - - mbax_dev RHx device descriptor - mbax_unit RHx units - mbax_reg RHx register list -*/ - -DIB mba0_dib = { - IOBA_RP, IOLN_RP, &mba_rd, &mba_wr, - 1, IVCL (RP), VEC_RP, { &mba0_inta } - }; - -UNIT mba0_unit = { UDATA (NULL, 0, 0) }; - -REG mba0_reg[] = { - { ORDATA (CS1, massbus[0].cs1, 16) }, - { ORDATA (WC, massbus[0].wc, 16) }, - { ORDATA (BA, massbus[0].ba, 16) }, - { ORDATA (CS2, massbus[0].cs2, 16) }, - { ORDATA (DB, massbus[0].db, 16) }, - { ORDATA (BAE, massbus[0].bae, 6) }, - { ORDATA (CS3, massbus[0].cs3, 16) }, - { FLDATA (IFF, massbus[0].iff, 0) }, - { FLDATA (INT, IREQ (RP), INT_V_RP) }, - { FLDATA (SC, massbus[0].cs1, CSR_V_ERR) }, - { FLDATA (DONE, massbus[0].cs1, CSR_V_DONE) }, - { FLDATA (IE, massbus[0].cs1, CSR_V_IE) }, - { ORDATA (DEVADDR, mba0_dib.ba, 32), REG_HRO }, - { ORDATA (DEVVEC, mba0_dib.vec, 16), REG_HRO }, - { NULL } - }; - -MTAB mba0_mod[] = { - { MTAB_XTD|MTAB_VDV, 0100, "ADDRESS", "ADDRESS", - &set_addr, &show_addr, NULL }, - { MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR", - &set_vec, &show_vec, NULL }, - { 0 } - }; - -DIB mba1_dib = { - IOBA_TU, IOLN_TU, &mba_rd, &mba_wr, - 1, IVCL (TU), VEC_TU, { &mba1_inta } - }; - -UNIT mba1_unit = { UDATA (NULL, 0, 0) }; - -REG mba1_reg[] = { - { ORDATA (CS1, massbus[1].cs1, 16) }, - { ORDATA (WC, massbus[1].wc, 16) }, - { ORDATA (BA, massbus[1].ba, 16) }, - { ORDATA (CS2, massbus[1].cs2, 16) }, - { ORDATA (DB, massbus[1].db, 16) }, - { ORDATA (BAE, massbus[1].bae, 6) }, - { ORDATA (CS3, massbus[1].cs3, 16) }, - { FLDATA (IFF, massbus[1].iff, 0) }, - { FLDATA (INT, IREQ (TU), INT_V_TU) }, - { FLDATA (SC, massbus[1].cs1, CSR_V_ERR) }, - { FLDATA (DONE, massbus[1].cs1, CSR_V_DONE) }, - { FLDATA (IE, massbus[1].cs1, CSR_V_IE) }, - { ORDATA (DEVADDR, mba1_dib.ba, 32), REG_HRO }, - { ORDATA (DEVVEC, mba1_dib.vec, 16), REG_HRO }, - { NULL } - }; - -MTAB mba1_mod[] = { - { MTAB_XTD|MTAB_VDV, 0040, "ADDRESS", "ADDRESS", - &set_addr, &show_addr, NULL }, - { MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR", - &set_vec, &show_vec, NULL }, - { 0 } - }; - -DEVICE mba_dev[] = { - { - "RHA", &mba0_unit, mba0_reg, mba0_mod, - 1, 0, 0, 0, 0, 0, - NULL, NULL, &mba_reset, - NULL, NULL, NULL, - &mba0_dib, DEV_DEBUG | DEV_DISABLE | DEV_UBUS | DEV_QBUS - }, - { - "RHB", &mba1_unit, mba1_reg, mba1_mod, - 1, 0, 0, 0, 0, 0, - NULL, NULL, &mba_reset, - NULL, NULL, NULL, - &mba1_dib, DEV_DEBUG | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS - } - }; - -/* Read Massbus adapter register */ - -t_stat mba_rd (int32 *val, int32 pa, int32 mode) -{ -int32 ofs, dat, mb, drv; -t_stat r; - -mb = mba_map_pa (pa, &ofs); /* get mb number */ -if ((mb < 0) || (ofs < 0)) /* valid? */ - return SCPE_NXM; -drv = GET_UNIT (massbus[mb].cs2); /* get drive */ -mba_upd_cs1 (0, 0, mb); /* update CS1 */ - -if (ofs & EXT) { /* external? */ - if (!mbregR[mb]) /* device there? */ - return SCPE_NXM; - r = mbregR[mb] (val, ofs & ~EXT, drv); /* call device */ - if (r == MBE_NXD) /* nx drive? */ - mba_set_cs2 (CS2_NED, mb); - else if (r == MBE_NXR) /* nx reg? */ - return SCPE_NXM; - return SCPE_OK; - } - -switch (ofs) { /* case on reg */ - - case CS1_OF: /* CS1 */ - if (!mbregR[mb]) /* nx device? */ - return SCPE_NXM; - r = mbregR[mb] (&dat, ofs, drv); /* get dev cs1 */ - if (r == MBE_NXD) /* nx drive? */ - mba_set_cs2 (CS2_NED, mb); - *val = massbus[mb].cs1 | dat; - break; - - case WC_OF: /* WC */ - *val = massbus[mb].wc; - break; - - case BA_OF: /* BA */ - *val = massbus[mb].ba & ~BA_MBZ; - break; - - case CS2_OF: /* CS2 */ - *val = massbus[mb].cs2 = (massbus[mb].cs2 & ~CS2_MBZ) | CS2_IR | CS2_OR; - break; - - case DB_OF: /* DB */ - *val = massbus[mb].db; - break; - - case BAE_OF: /* BAE */ - *val = massbus[mb].bae = massbus[mb].bae & ~AE_MBZ; - break; - - case CS3_OF: /* CS3 */ - *val = massbus[mb].cs3 = (massbus[mb].cs3 & ~(CS1_IE | CS3_MBZ)) | - (massbus[mb].cs1 & CS1_IE); - break; - - default: /* huh? */ - return SCPE_NXM; - } - -return SCPE_OK; -} - -t_stat mba_wr (int32 val, int32 pa, int32 access) -{ -int32 ofs, cs1f, drv, mb; -t_stat r; -t_bool cs1dt; - -mb = mba_map_pa (pa, &ofs); /* get mb number */ -if ((mb < 0) || (ofs < 0)) /* valid? */ - return SCPE_NXM; -drv = GET_UNIT (massbus[mb].cs2); /* get drive */ - -if (ofs & EXT) { /* external? */ - if (!mbregW[mb]) /* device there? */ - return SCPE_NXM; - if ((access == WRITEB) && (pa & 1)) /* byte writes */ - val = val << 8; /* don't work */ - r = mbregW[mb] (val, ofs & ~EXT, drv); /* write dev reg */ - if (r == MBE_NXD) /* nx drive? */ - mba_set_cs2 (CS2_NED, mb); - else if (r == MBE_NXR) /* nx reg? */ - return SCPE_NXM; - mba_upd_cs1 (0, 0, mb); /* update status */ - return SCPE_OK; - } - -cs1f = 0; /* no int on cs1 upd */ -switch (ofs) { /* case on reg */ - - case CS1_OF: /* CS1 */ - if (!mbregW[mb]) /* device exist? */ - return SCPE_NXM; - if ((access == WRITEB) && (pa & 1)) - val = val << 8; - if (val & CS1_TRE) { /* error clear? */ - massbus[mb].cs1 &= ~CS1_TRE; /* clr CS1 */ - massbus[mb].cs2 &= ~CS2_ERR; /* clr CS2<15:8> */ - massbus[mb].cs3 &= ~CS3_ERR; /* clr CS3<15:11> */ - } - if ((access == WRITE) || (pa & 1)) { /* hi byte write? */ - if (massbus[mb].cs1 & CS1_DONE) /* done set? */ - massbus[mb].cs1 = (massbus[mb].cs1 & ~CS1_UAE) | (val & CS1_UAE); - } - if ((access == WRITE) || !(pa & 1)) { /* lo byte write? */ - if ((val & CS1_DONE) && (val & CS1_IE)) /* to DONE+IE? */ - massbus[mb].iff = 1; /* set CSTB INTR */ - massbus[mb].cs1 = (massbus[mb].cs1 & ~CS1_IE) | (val & CS1_IE); - cs1dt = (val & CS1_GO) && (GET_FNC (val) >= FNC_XFER); - if (cs1dt && ((massbus[mb].cs1 & CS1_DONE) == 0)) /* dt, done clr? */ - mba_set_cs2 (CS2_PGE, mb); /* prgm error */ - else { - r = mbregW[mb] (val & 077, ofs, drv); /* write dev CS1 */ - if (r == MBE_NXD) /* nx drive? */ - mba_set_cs2 (CS2_NED, mb); - else if (r == MBE_NXR) /* nx reg? */ - return SCPE_NXM; - else if (cs1dt && (r == SCPE_OK)) { /* xfer, no err? */ - massbus[mb].cs1 &= ~(CS1_TRE | CS1_MCPE | CS1_DONE); - massbus[mb].cs2 &= ~CS2_ERR; /* clear errors */ - massbus[mb].cs3 &= ~(CS3_ERR | CS3_DBL); - } - } - } - massbus[mb].cs3 = (massbus[mb].cs3 & ~CS1_IE) | /* update CS3 */ - (massbus[mb].cs1 & CS1_IE); - massbus[mb].bae = (massbus[mb].bae & ~CS1_M_UAE) | /* update BAE */ - ((massbus[mb].cs1 >> CS1_V_UAE) & CS1_M_UAE); - break; - - case WC_OF: /* WC */ - if (access == WRITEB) - val = (pa & 1)? - (massbus[mb].wc & 0377) | (val << 8): - (massbus[mb].wc & ~0377) | val; - massbus[mb].wc = val; - break; - - case BA_OF: /* BA */ - if (access == WRITEB) - val = (pa & 1)? - (massbus[mb].ba & 0377) | (val << 8): - (massbus[mb].ba & ~0377) | val; - massbus[mb].ba = val & ~BA_MBZ; - break; - - case CS2_OF: /* CS2 */ - if ((access == WRITEB) && (pa & 1)) - val = val << 8; - if (val & CS2_CLR) /* init? */ - mba_reset (&mba_dev[mb]); - else { - if ((val & ~massbus[mb].cs2) & (CS2_PE | CS2_MXF)) - cs1f = CS1_SC; /* diagn intr */ - if (access == WRITEB) /* merge val */ - val = (massbus[mb].cs2 & ((pa & 1)? 0377: 0177400)) | val; - massbus[mb].cs2 = (massbus[mb].cs2 & ~CS2_RW) | - (val & CS2_RW) | CS2_IR | CS2_OR; - } - break; - - case DB_OF: /* DB */ - if (access == WRITEB) - val = (pa & 1)? - (massbus[mb].db & 0377) | (val << 8): - (massbus[mb].db & ~0377) | val; - massbus[mb].db = val; - break; - - case BAE_OF: /* BAE */ - if ((access == WRITEB) && (pa & 1)) - break; - massbus[mb].bae = val & ~AE_MBZ; - massbus[mb].cs1 = (massbus[mb].cs1 & ~CS1_UAE) | /* update CS1 */ - ((massbus[mb].bae << CS1_V_UAE) & CS1_UAE); - break; - - case CS3_OF: /* CS3 */ - if ((access == WRITEB) && (pa & 1)) - break; - massbus[mb].cs3 = (massbus[mb].cs3 & ~CS3_RW) | (val & CS3_RW); - massbus[mb].cs1 = (massbus[mb].cs1 & ~CS1_IE) | /* update CS1 */ - (massbus[mb].cs3 & CS1_IE); - break; - - default: - return SCPE_NXM; - } - -mba_upd_cs1 (cs1f, 0, mb); /* update status */ -return SCPE_OK; -} - -/* Massbus I/O routines - - mb_rdbufW - fetch word buffer from memory - mb_wrbufW - store word buffer into memory - mb_chbufW - compare word buffer with memory - - Returns number of bytes successfully transferred/checked -*/ - -int32 mba_rdbufW (uint32 mb, int32 bc, uint16 *buf) -{ -int32 i, j, ba, mbc, pbc; -uint32 pa; - -bc = bc & ~1; /* bc even */ -if (mb >= MBA_NUM) /* valid MBA? */ - return 0; -ba = (massbus[mb].bae << 16) | massbus[mb].ba; /* get busaddr */ -mbc = (0200000 - massbus[mb].wc) << 1; /* MB byte count */ -if (bc > mbc) /* use smaller */ - bc = mbc; -for (i = 0; i < bc; i = i + pbc) { /* loop by pages */ - if (RH11 && cpu_bme) /* map addr */ - pa = Map_Addr (ba); - else pa = ba; - if (!ADDR_IS_MEM (pa)) { /* NXM? */ - mba_set_cs2 (CS2_NEM, mb); /* set error */ - break; - } - pbc = UBM_PAGSIZE - UBM_GETOFF (pa); /* left in page */ - if (pbc > (bc - i)) /* limit to rem xfr */ - pbc = bc - i; - for (j = 0; j < pbc; j = j + 2) { /* loop by words */ - *buf++ = M[pa >> 1]; /* fetch word */ - if (!(massbus[mb].cs2 & CS2_UAI)) { /* if not inhb */ - ba = ba + 2; /* incr ba, pa */ - pa = pa + 2; - } - } - } -massbus[mb].wc = (massbus[mb].wc + (bc >> 1)) & DMASK; /* update wc */ -massbus[mb].ba = ba & DMASK; /* update ba */ -massbus[mb].bae = (ba >> 16) & ~AE_MBZ; /* upper 6b */ -massbus[mb].cs1 = (massbus[mb].cs1 & ~ CS1_UAE) | /* update CS1 */ - ((massbus[mb].bae << CS1_V_UAE) & CS1_UAE); -return i; -} - -int32 mba_wrbufW (uint32 mb, int32 bc, uint16 *buf) -{ -int32 i, j, ba, mbc, pbc; -uint32 pa; - -bc = bc & ~1; /* bc even */ -if (mb >= MBA_NUM) /* valid MBA? */ - return 0; -ba = (massbus[mb].bae << 16) | massbus[mb].ba; /* get busaddr */ -mbc = (0200000 - massbus[mb].wc) << 1; /* MB byte count */ -if (bc > mbc) /* use smaller */ - bc = mbc; -for (i = 0; i < bc; i = i + pbc) { /* loop by pages */ - if (RH11 && cpu_bme) /* map addr */ - pa = Map_Addr (ba); - else pa = ba; - if (!ADDR_IS_MEM (pa)) { /* NXM? */ - mba_set_cs2 (CS2_NEM, mb); /* set error */ - break; - } - pbc = UBM_PAGSIZE - UBM_GETOFF (pa); /* left in page */ - if (pbc > (bc - i)) /* limit to rem xfr */ - pbc = bc - i; - for (j = 0; j < pbc; j = j + 2) { /* loop by words */ - M[pa >> 1] = *buf++; /* put word */ - if (!(massbus[mb].cs2 & CS2_UAI)) { /* if not inhb */ - ba = ba + 2; /* incr ba, pa */ - pa = pa + 2; - } - } - } -massbus[mb].wc = (massbus[mb].wc + (bc >> 1)) & DMASK; /* update wc */ -massbus[mb].ba = ba & DMASK; /* update ba */ -massbus[mb].bae = (ba >> 16) & ~AE_MBZ; /* upper 6b */ -massbus[mb].cs1 = (massbus[mb].cs1 & ~ CS1_UAE) | /* update CS1 */ - ((massbus[mb].bae << CS1_V_UAE) & CS1_UAE); -return i; -} - -int32 mba_chbufW (uint32 mb, int32 bc, uint16 *buf) -{ -int32 i, j, ba, mbc, pbc; -uint32 pa; - -bc = bc & ~1; /* bc even */ -if (mb >= MBA_NUM) /* valid MBA? */ - return 0; -ba = (massbus[mb].bae << 16) | massbus[mb].ba; /* get busaddr */ -mbc = (0200000 - massbus[mb].wc) << 1; /* MB byte count */ -if (bc > mbc) /* use smaller */ - bc = mbc; -for (i = 0; i < bc; i = i + pbc) { /* loop by pages */ - if (RH11 && cpu_bme) pa = Map_Addr (ba); /* map addr */ - else pa = ba; - if (!ADDR_IS_MEM (pa)) { /* NXM? */ - mba_set_cs2 (CS2_NEM, mb); /* set error */ - break; - } - pbc = UBM_PAGSIZE - UBM_GETOFF (pa); /* left in page */ - if (pbc > (bc - i)) /* limit to rem xfr */ - pbc = bc - i; - for (j = 0; j < pbc; j = j + 2) { /* loop by words */ - massbus[mb].db = *buf++; /* get dev word */ - if (M[pa >> 1] != massbus[mb].db) { /* miscompare? */ - mba_set_cs2 (CS2_WCE, mb); /* set error */ - massbus[mb].cs3 = massbus[mb].cs3 | /* set even/odd */ - ((pa & 1)? CS3_WCO: CS3_WCE); - break; - } - if (!(massbus[mb].cs2 & CS2_UAI)) { /* if not inhb */ - ba = ba + 2; /* incr ba, pa */ - pa = pa + 2; - } - } - } -massbus[mb].wc = (massbus[mb].wc + (bc >> 1)) & DMASK; /* update wc */ -massbus[mb].ba = ba & DMASK; /* update ba */ -massbus[mb].bae = (ba >> 16) & ~AE_MBZ; /* upper 6b */ -massbus[mb].cs1 = (massbus[mb].cs1 & ~ CS1_UAE) | /* update CS1 */ - ((massbus[mb].bae << CS1_V_UAE) & CS1_UAE); -return i; -} - -/* Device access, status, and interrupt routines */ - -void mba_set_don (uint32 mb) -{ -mba_upd_cs1 (CS1_DONE, 0, mb); -return; -} - -void mba_upd_ata (uint32 mb, uint32 val) -{ -if (val) - mba_upd_cs1 (CS1_SC, 0, mb); -else mba_upd_cs1 (0, CS1_SC, mb); -return; -} - -void mba_set_exc (uint32 mb) -{ -mba_upd_cs1 (CS1_TRE | CS1_DONE, 0, mb); -return; -} - -int32 mba_get_bc (uint32 mb) -{ -if (mb >= MBA_NUM) - return 0; -return ((0200000 - massbus[mb].wc) << 1); -} - -int32 mba_get_csr (uint32 mb) -{ -DIB *dibp; - -if (mb >= MBA_NUM) - return 0; -dibp = (DIB *) mba_dev[mb].ctxt; -return dibp->ba; -} - -void mba_set_int (uint32 mb) -{ -DIB *dibp; - -if (mb >= MBA_NUM) - return; -dibp = (DIB *) mba_dev[mb].ctxt; -int_req[dibp->vloc >> 5] |= (1 << (dibp->vloc & 037)); -return; -} - -void mba_clr_int (uint32 mb) -{ -DIB *dibp; - -if (mb >= MBA_NUM) - return; -dibp = (DIB *) mba_dev[mb].ctxt; -int_req[dibp->vloc >> 5] &= ~(1 << (dibp->vloc & 037)); -return; -} - -void mba_upd_cs1 (uint32 set, uint32 clr, uint32 mb) -{ -if (mb >= MBA_NUM) - return; -if ((set & ~massbus[mb].cs1) & CS1_DONE) /* DONE 0 to 1? */ - massbus[mb].iff = (massbus[mb].cs1 & CS1_IE)? 1: 0; /* CSTB INTR <- IE */ -massbus[mb].cs1 = (massbus[mb].cs1 & ~(clr | CS1_MCPE | CS1_MBZ | CS1_DRV)) | set; -if (massbus[mb].cs2 & CS2_ERR) - massbus[mb].cs1 = massbus[mb].cs1 | CS1_TRE | CS1_SC; -else if (massbus[mb].cs1 & CS1_TRE) - massbus[mb].cs1 = massbus[mb].cs1 | CS1_SC; -if (massbus[mb].iff || - ((massbus[mb].cs1 & CS1_SC) && - (massbus[mb].cs1 & CS1_DONE) && - (massbus[mb].cs1 & CS1_IE))) - mba_set_int (mb); -else mba_clr_int (mb); -return; -} - -void mba_set_cs2 (uint32 flag, uint32 mb) -{ -if (mb >= MBA_NUM) - return; -massbus[mb].cs2 = massbus[mb].cs2 | flag; -mba_upd_cs1 (0, 0, mb); -return; -} - -/* Interrupt acknowledge */ - -int32 mba0_inta (void) -{ -massbus[0].cs1 &= ~CS1_IE; /* clear int enable */ -massbus[0].cs3 &= ~CS1_IE; /* in both registers */ -massbus[0].iff = 0; /* clear CSTB INTR */ -return mba0_dib.vec; /* acknowledge */ -} - -int32 mba1_inta (void) -{ -massbus[1].cs1 &= ~CS1_IE; /* clear int enable */ -massbus[1].cs3 &= ~CS1_IE; /* in both registers */ -massbus[1].iff = 0; /* clear CSTB INTR */ -return mba1_dib.vec; /* acknowledge */ -} - -/* Map physical address to Massbus number, offset */ - -uint32 mba_map_pa (int32 pa, int32 *ofs) -{ -int32 i, uo, ba, lnt; -DIB *dibp; - -for (i = 0; i < MBA_NUM; i++) { /* loop thru ctrls */ - dibp = (DIB *) mba_dev[i].ctxt; /* get DIB */ - ba = dibp->ba; - lnt = dibp->lnt; - if ((pa >= ba) && /* in range? */ - (pa < (ba + lnt))) { - if (pa < (ba + (lnt - 4))) { /* not last two? */ - uo = ((pa - ba) & MBA_OFSMASK) >> 1; /* get Unibus offset */ - *ofs = mba_mapofs[uo]; /* map thru PROM */ - return i; /* return ctrl idx */ - } - else if (RH11) /* RH11? done */ - return -1; - else { /* RH70 */ - uo = (pa - (ba + (lnt - 4))) >> 1; /* offset relative */ - *ofs = BAE_OF + uo; /* to BAE */ - return i; - } - } - } -return -1; -} - -/* Reset Massbus adapter */ - -t_stat mba_reset (DEVICE *dptr) -{ -uint32 mb; - -mb = dptr - mba_dev; -if (mb >= MBA_NUM) - return SCPE_NOFNC; -massbus[mb].cs1 = CS1_DONE; -massbus[mb].wc = 0; -massbus[mb].ba = 0; -massbus[mb].cs2 = 0; -massbus[mb].db = 0; -massbus[mb].bae= 0; -massbus[mb].cs3 = 0; -massbus[mb].iff = 0; -mba_clr_int (mb); -if (mbabort[mb]) - mbabort[mb] (); -return SCPE_OK; -} - -/* Enable/disable Massbus adapter */ - -void mba_set_enbdis (uint32 mb, t_bool dis) -{ -if (mb >= MBA_NUM) /* valid MBA? */ - return; -if (dis) - mba_dev[mb].flags |= DEV_DIS; -else mba_dev[mb].flags &= ~DEV_DIS; -return; -} - -/* Show Massbus adapter number */ - -t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, void *desc) -{ -DEVICE *dptr = find_dev_from_unit (uptr); -DIB *dibp; - -if (dptr == NULL) - return SCPE_IERR; -dibp = (DIB *) dptr->ctxt; -if (dibp == NULL) - return SCPE_IERR; -fprintf (st, "Massbus adapter %d", dibp->ba); -return SCPE_OK; -} - -/* Init Mbus tables */ - -void init_mbus_tab (void) -{ -uint32 i; - -for (i = 0; i < MBA_NUM; i++) { - mbregR[i] = NULL; - mbregW[i] = NULL; - mbabort[i] = NULL; - } -return; -} - -/* Build dispatch tables */ - -t_stat build_mbus_tab (DEVICE *dptr, DIB *dibp) -{ -uint32 idx; - -if ((dptr == NULL) || (dibp == NULL)) /* validate args */ - return SCPE_IERR; -idx = dibp->ba; /* Mbus # */ -if (idx >= MBA_NUM) - return SCPE_STOP; -if ((mbregR[idx] && dibp->rd && /* conflict? */ - (mbregR[idx] != dibp->rd)) || - (mbregW[idx] && dibp->wr && - (mbregW[idx] != dibp->wr)) || - (mbabort[idx] && dibp->ack[0] && - (mbabort[idx] != dibp->ack[0]))) { - printf ("Massbus %s assignment conflict at %d\n", - sim_dname (dptr), dibp->ba); - if (sim_log) - fprintf (sim_log, "Massbus %s assignment conflict at %d\n", - sim_dname (dptr), dibp->ba); - return SCPE_STOP; - } -if (dibp->rd) /* set rd dispatch */ - mbregR[idx] = dibp->rd; -if (dibp->wr) /* set wr dispatch */ - mbregW[idx] = dibp->wr; -if (dibp->ack[0]) /* set abort dispatch */ - mbabort[idx] = dibp->ack[0]; -return SCPE_OK; -} - diff --git a/PDP11/old/pdp11_sys.c b/PDP11/old/pdp11_sys.c deleted file mode 100644 index b0b358cf..00000000 --- a/PDP11/old/pdp11_sys.c +++ /dev/null @@ -1,1089 +0,0 @@ -/* pdp11_sys.c: PDP-11 simulator interface - - Copyright (c) 1993-2012, Robert M Supnik - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the name of Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - 29-Apr-12 RMS Fixed compiler warning (Mark Pizzolato) - 19-Nov-08 RMS Moved I/O support routines to I/O library - 15-May-08 RMS Added KE11-A, DC11 support - Renamed DL11 - 04-Feb-08 RMS Modified to allow -A, -B use with 8b devices - 25-Jan-08 RMS Added RC11, KG11A support from John Dundas - 10-Sep-07 RMS Cleaned up binary loader - 20-Dec-06 RMS Added TA11 support - 12-Nov-06 RMS Fixed operand order in EIS instructions (W.F.J. Mueller) - 14-Jul-06 RMS Reordered device list - 06-Jul-06 RMS Added multiple KL11/DL11 support - 26-Jun-06 RMS Added RF11 support - 17-May-06 RMS Added CR11/CD11 support (John Dundas) - 16-Aug-05 RMS Fixed C++ declaration and cast problems - 22-Jul-05 RMS Fixed missing , in initializer (Doug Gwyn) - 22-Dec-03 RMS Added second DEUNA/DELUA support - 18-Oct-03 RMS Added DECtape off reel message - 06-May-03 RMS Added support for second DEQNA/DELQA - 09-Jan-03 RMS Added DELUA/DEUNA support - 17-Oct-02 RMS Fixed bugs in branch, SOB address parsing - 09-Oct-02 RMS Added DELQA support - 12-Sep-02 RMS Added TMSCP, KW11P, RX211 support, RAD50 examine - 29-Nov-01 RMS Added read only unit support - 17-Sep-01 RMS Removed multiconsole support - 26-Aug-01 RMS Added DZ11 - 20-Aug-01 RMS Updated bad block inquiry - 17-Jul-01 RMS Fixed warning from VC++ 6.0 - 27-May-01 RMS Added multiconsole support - 05-Apr-01 RMS Added support for TS11/TSV05 - 14-Mar-01 RMS Revised load/dump interface (again) - 11-Feb-01 RMS Added DECtape support - 30-Oct-00 RMS Added support for examine to file - 14-Apr-99 RMS Changed t_addr to unsigned - 09-Nov-98 RMS Fixed assignments of ROR/ROL (John Wilson) - 27-Oct-98 RMS V2.4 load interface - 08-Oct-98 RMS Fixed bug in bad block routine - 30-Mar-98 RMS Fixed bug in floating point display - 12-Nov-97 RMS Added bad block table routine -*/ - -#include "pdp11_defs.h" -#include - -extern DEVICE cpu_dev; -extern DEVICE sys_dev; -extern DEVICE ptr_dev; -extern DEVICE ptp_dev; -extern DEVICE tti_dev; -extern DEVICE tto_dev; -extern DEVICE lpt_dev; -extern DEVICE cr_dev; -extern DEVICE clk_dev; -extern DEVICE pclk_dev; -extern DEVICE dli_dev; -extern DEVICE dlo_dev; -extern DEVICE dci_dev; -extern DEVICE dco_dev; -extern DEVICE dz_dev; -extern DEVICE vh_dev; -extern DEVICE dt_dev; -extern DEVICE rc_dev; -extern DEVICE rf_dev; -extern DEVICE rk_dev; -extern DEVICE rl_dev; -extern DEVICE hk_dev; -extern DEVICE rx_dev; -extern DEVICE ry_dev; -extern DEVICE mba_dev[]; -extern DEVICE rp_dev; -extern DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev; -extern DEVICE tm_dev; -extern DEVICE tq_dev; -extern DEVICE ts_dev; -extern DEVICE tu_dev; -extern DEVICE ta_dev; -extern DEVICE xq_dev, xqb_dev; -extern DEVICE xu_dev, xub_dev; -extern DEVICE ke_dev; -extern DEVICE kg_dev; -extern UNIT cpu_unit; -extern REG cpu_reg[]; -extern uint16 *M; -extern int32 saved_PC; - -/* SCP data structures and interface routines - - sim_name simulator name string - sim_PC pointer to saved PC register descriptor - sim_emax number of words for examine - sim_devices array of pointers to simulated devices - sim_stop_messages array of pointers to stop messages - sim_load binary loader -*/ - -char sim_name[] = "PDP-11"; - -REG *sim_PC = &cpu_reg[0]; - -int32 sim_emax = 4; - -DEVICE *sim_devices[] = { - &cpu_dev, - &sys_dev, - &mba_dev[0], - &mba_dev[1], - &clk_dev, - &pclk_dev, - &ptr_dev, - &ptp_dev, - &tti_dev, - &tto_dev, - &cr_dev, - &lpt_dev, - &dli_dev, - &dlo_dev, - &dci_dev, - &dco_dev, - &dz_dev, - &vh_dev, - &rc_dev, - &rf_dev, - &rk_dev, - &rl_dev, - &hk_dev, - &rx_dev, - &ry_dev, - &rp_dev, - &rq_dev, - &rqb_dev, - &rqc_dev, - &rqd_dev, - &dt_dev, - &tm_dev, - &ts_dev, - &tq_dev, - &tu_dev, - &ta_dev, - &xq_dev, - &xqb_dev, - &xu_dev, - &xub_dev, - &ke_dev, - &kg_dev, - NULL - }; - -const char *sim_stop_messages[] = { - "Unknown error", - "Red stack trap", - "Odd address trap", - "Memory management trap", - "Non-existent memory trap", - "Parity error trap", - "Privilege trap", - "Illegal instruction trap", - "BPT trap", - "IOT trap", - "EMT trap", - "TRAP trap", - "Trace trap", - "Yellow stack trap", - "Powerfail trap", - "Floating point exception", - "HALT instruction", - "Breakpoint", - "Wait state", - "Trap vector fetch abort", - "Trap stack push abort", - "RQDX3 consistency error", - "Sanity timer expired", - "DECtape off reel" - }; - -/* Binary loader. - - Loader format consists of blocks, optionally preceded, separated, and - followed by zeroes. Each block consists of: - - 001 --- - xxx | - lo_count | - hi_count | - lo_origin > count bytes - hi_origin | - data byte | - : | - data byte --- - checksum - - If the byte count is exactly six, the block is the last on the tape, and - there is no checksum. If the origin is not 000001, then the origin is - the PC at which to start the program. -*/ - -t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag) -{ -int32 c[6], d, i, cnt, csum; -uint32 org; - -if ((*cptr != 0) || (flag != 0)) - return SCPE_ARG; -do { /* block loop */ - csum = 0; /* init checksum */ - for (i = 0; i < 6; ) { /* 6 char header */ - if ((c[i] = getc (fileref)) == EOF) - return SCPE_FMT; - if ((i != 0) || (c[i] == 1)) /* 1st must be 1 */ - csum = csum + c[i++]; /* add into csum */ - } - cnt = (c[3] << 8) | c[2]; /* count */ - org = (c[5] << 8) | c[4]; /* origin */ - if (cnt < 6) /* invalid? */ - return SCPE_FMT; - if (cnt == 6) { /* end block? */ - if (org != 1) /* set PC? */ - saved_PC = org & 0177776; - return SCPE_OK; - } - for (i = 6; i < cnt; i++) { /* exclude hdr */ - if ((d = getc (fileref)) == EOF) /* data char */ - return SCPE_FMT; - csum = csum + d; /* add into csum */ - if (org >= MEMSIZE) /* invalid addr? */ - return SCPE_NXM; - M[org >> 1] = (org & 1)? /* store data */ - (M[org >> 1] & 0377) | (d << 8): - (M[org >> 1] & 0177400) | d; - org = (org + 1) & 0177777; /* inc origin */ - } - if ((d = getc (fileref)) == EOF) /* get csum */ - return SCPE_FMT; - csum = csum + d; /* add in */ - } while ((csum & 0377) == 0); /* result mbz */ -return SCPE_CSUM; -} - -/* Symbol tables */ - -#define I_V_L 16 /* long mode */ -#define I_V_D 17 /* double mode */ -#define I_L (1 << I_V_L) -#define I_D (1 << I_V_D) - -/* Warning: for literals, the class number MUST equal the field width!! */ - -#define I_V_CL 18 /* class bits */ -#define I_M_CL 037 /* class mask */ -#define I_V_NPN 0 /* no operands */ -#define I_V_REG 1 /* reg */ -#define I_V_SOP 2 /* operand */ -#define I_V_3B 3 /* 3b literal */ -#define I_V_FOP 4 /* flt operand */ -#define I_V_AFOP 5 /* fac, flt operand */ -#define I_V_6B 6 /* 6b literal */ -#define I_V_BR 7 /* cond branch */ -#define I_V_8B 8 /* 8b literal */ -#define I_V_SOB 9 /* reg, disp */ -#define I_V_RSOP 10 /* reg, operand */ -#define I_V_ASOP 11 /* fac, operand */ -#define I_V_ASMD 12 /* fac, moded int op */ -#define I_V_DOP 13 /* double operand */ -#define I_V_CCC 14 /* CC clear */ -#define I_V_CCS 15 /* CC set */ -#define I_V_SOPR 16 /* operand, reg */ -#define I_NPN (I_V_NPN << I_V_CL) -#define I_REG (I_V_REG << I_V_CL) -#define I_3B (I_V_3B << I_V_CL) -#define I_SOP (I_V_SOP << I_V_CL) -#define I_FOP (I_V_FOP << I_V_CL) -#define I_6B (I_V_6B << I_V_CL) -#define I_BR (I_V_BR << I_V_CL) -#define I_8B (I_V_8B << I_V_CL) -#define I_AFOP (I_V_AFOP << I_V_CL) -#define I_ASOP (I_V_ASOP << I_V_CL) -#define I_RSOP (I_V_RSOP << I_V_CL) -#define I_SOB (I_V_SOB << I_V_CL) -#define I_ASMD (I_V_ASMD << I_V_CL) -#define I_DOP (I_V_DOP << I_V_CL) -#define I_CCC (I_V_CCC << I_V_CL) -#define I_CCS (I_V_CCS << I_V_CL) -#define I_SOPR (I_V_SOPR << I_V_CL) - -static const int32 masks[] = { -0177777, 0177770, 0177700, 0177770, -0177700+I_D, 0177400+I_D, 0177700, 0177400, -0177400, 0177000, 0177000, 0177400, -0177400+I_D+I_L, 0170000, 0177777, 0177777, -0177000 -}; - -static const char *opcode[] = { -"HALT","WAIT","RTI","BPT", -"IOT","RESET","RTT","MFPT", -"JMP","RTS","SPL", -"NOP","CLC","CLV","CLV CLC", -"CLZ","CLZ CLC","CLZ CLV","CLZ CLV CLC", -"CLN","CLN CLC","CLN CLV","CLN CLV CLC", -"CLN CLZ","CLN CLZ CLC","CLN CLZ CLC","CCC", -"NOP","SEC","SEV","SEV SEC", -"SEZ","SEZ SEC","SEZ SEV","SEZ SEV SEC", -"SEN","SEN SEC","SEN SEV","SEN SEV SEC", -"SEN SEZ","SEN SEZ SEC","SEN SEZ SEC","SCC", -"SWAB","BR","BNE","BEQ", -"BGE","BLT","BGT","BLE", -"JSR", -"CLR","COM","INC","DEC", -"NEG","ADC","SBC","TST", -"ROR","ROL","ASR","ASL", -"MARK","MFPI","MTPI","SXT", -"CSM", "TSTSET","WRTLCK", -"MOV","CMP","BIT","BIC", -"BIS","ADD", -"MUL","DIV","ASH","ASHC", -"XOR", -"FADD","FSUB","FMUL","FDIV", -"L2DR", -"MOVC","MOVRC","MOVTC", -"LOCC","SKPC","SCANC","SPANC", -"CMPC","MATC", -"ADDN","SUBN","CMPN","CVTNL", -"CVTPN","CVTNP","ASHN","CVTLN", -"L3DR", -"ADDP","SUBP","CMPP","CVTPL", -"MULP","DIVP","ASHP","CVTLP", -"MOVCI","MOVRCI","MOVTCI", -"LOCCI","SKPCI","SCANCI","SPANCI", -"CMPCI","MATCI", -"ADDNI","SUBNI","CMPNI","CVTNLI", -"CVTPNI","CVTNPI","ASHNI","CVTLNI", -"ADDPI","SUBPI","CMPPI","CVTPLI", -"MULPI","DIVPI","ASHPI","CVTLPI", -"SOB", -"BPL","BMI","BHI","BLOS", -"BVC","BVS","BCC","BCS", -"BHIS","BLO", /* encode only */ -"EMT","TRAP", -"CLRB","COMB","INCB","DECB", -"NEGB","ADCB","SBCB","TSTB", -"RORB","ROLB","ASRB","ASLB", -"MTPS","MFPD","MTPD","MFPS", -"MOVB","CMPB","BITB","BICB", -"BISB","SUB", -"CFCC","SETF","SETI","SETD","SETL", -"LDFPS","STFPS","STST", -"CLRF","CLRD","TSTF","TSTD", -"ABSF","ABSD","NEGF","NEGD", -"MULF","MULD","MODF","MODD", -"ADDF","ADDD","LDF","LDD", -"SUBF","SUBD","CMPF","CMPD", -"STF","STD","DIVF","DIVD", -"STEXP", -"STCFI","STCDI","STCFL","STCDL", -"STCFD","STCDF", -"LDEXP", -"LDCIF","LDCID","LDCLF","LDCLD", -"LDCFD","LDCDF", -NULL -}; - -static const int32 opc_val[] = { -0000000+I_NPN, 0000001+I_NPN, 0000002+I_NPN, 0000003+I_NPN, -0000004+I_NPN, 0000005+I_NPN, 0000006+I_NPN, 0000007+I_NPN, -0000100+I_SOP, 0000200+I_REG, 0000230+I_3B, -0000240+I_CCC, 0000241+I_CCC, 0000242+I_CCC, 0000243+I_NPN, -0000244+I_CCC, 0000245+I_NPN, 0000246+I_NPN, 0000247+I_NPN, -0000250+I_CCC, 0000251+I_NPN, 0000252+I_NPN, 0000253+I_NPN, -0000254+I_NPN, 0000255+I_NPN, 0000256+I_NPN, 0000257+I_CCC, -0000260+I_CCS, 0000261+I_CCS, 0000262+I_CCS, 0000263+I_NPN, -0000264+I_CCS, 0000265+I_NPN, 0000266+I_NPN, 0000267+I_NPN, -0000270+I_CCS, 0000271+I_NPN, 0000272+I_NPN, 0000273+I_NPN, -0000274+I_NPN, 0000275+I_NPN, 0000276+I_NPN, 0000277+I_CCS, -0000300+I_SOP, 0000400+I_BR, 0001000+I_BR, 0001400+I_BR, -0002000+I_BR, 0002400+I_BR, 0003000+I_BR, 0003400+I_BR, -0004000+I_RSOP, -0005000+I_SOP, 0005100+I_SOP, 0005200+I_SOP, 0005300+I_SOP, -0005400+I_SOP, 0005500+I_SOP, 0005600+I_SOP, 0005700+I_SOP, -0006000+I_SOP, 0006100+I_SOP, 0006200+I_SOP, 0006300+I_SOP, -0006400+I_6B, 0006500+I_SOP, 0006600+I_SOP, 0006700+I_SOP, -0007000+I_SOP, 0007200+I_SOP, 0007300+I_SOP, -0010000+I_DOP, 0020000+I_DOP, 0030000+I_DOP, 0040000+I_DOP, -0050000+I_DOP, 0060000+I_DOP, -0070000+I_SOPR, 0071000+I_SOPR, 0072000+I_SOPR, 0073000+I_SOPR, -0074000+I_RSOP, -0075000+I_REG, 0075010+I_REG, 0075020+I_REG, 0075030+I_REG, -0076020+I_REG, -0076030+I_NPN, 0076031+I_NPN, 0076032+I_NPN, -0076040+I_NPN, 0076041+I_NPN, 0076042+I_NPN, 0076043+I_NPN, -0076044+I_NPN, 0076045+I_NPN, -0076050+I_NPN, 0076051+I_NPN, 0076052+I_NPN, 0076053+I_NPN, -0076054+I_NPN, 0076055+I_NPN, 0076056+I_NPN, 0076057+I_NPN, -0076060+I_REG, -0076070+I_NPN, 0076071+I_NPN, 0076072+I_NPN, 0076073+I_NPN, -0076074+I_NPN, 0076075+I_NPN, 0076076+I_NPN, 0076077+I_NPN, -0076130+I_NPN, 0076131+I_NPN, 0076132+I_NPN, -0076140+I_NPN, 0076141+I_NPN, 0076142+I_NPN, 0076143+I_NPN, -0076144+I_NPN, 0076145+I_NPN, -0076150+I_NPN, 0076151+I_NPN, 0076152+I_NPN, 0076153+I_NPN, -0076154+I_NPN, 0076155+I_NPN, 0076156+I_NPN, 0076157+I_NPN, -0076170+I_NPN, 0076171+I_NPN, 0076172+I_NPN, 0076173+I_NPN, -0076174+I_NPN, 0076175+I_NPN, 0076176+I_NPN, 0076177+I_NPN, -0077000+I_SOB, -0100000+I_BR, 0100400+I_BR, 0101000+I_BR, 0101400+I_BR, -0102000+I_BR, 0102400+I_BR, 0103000+I_BR, 0103400+I_BR, -0103000+I_BR, 0103400+I_BR, -0104000+I_8B, 0104400+I_8B, -0105000+I_SOP, 0105100+I_SOP, 0105200+I_SOP, 0105300+I_SOP, -0105400+I_SOP, 0105500+I_SOP, 0105600+I_SOP, 0105700+I_SOP, -0106000+I_SOP, 0106100+I_SOP, 0106200+I_SOP, 0106300+I_SOP, -0106400+I_SOP, 0106500+I_SOP, 0106600+I_SOP, 0106700+I_SOP, -0110000+I_DOP, 0120000+I_DOP, 0130000+I_DOP, 0140000+I_DOP, -0150000+I_DOP, 0160000+I_DOP, -0170000+I_NPN, 0170001+I_NPN, 0170002+I_NPN, 0170011+I_NPN, 0170012+I_NPN, -0170100+I_SOP, 0170200+I_SOP, 0170300+I_SOP, -0170400+I_FOP, 0170400+I_FOP+I_D, 0170500+I_FOP, 0170500+I_FOP+I_D, -0170600+I_FOP, 0170600+I_FOP+I_D, 0170700+I_FOP, 0170700+I_FOP+I_D, -0171000+I_AFOP, 0171000+I_AFOP+I_D, 0171400+I_AFOP, 0171400+I_AFOP+I_D, -0172000+I_AFOP, 0172000+I_AFOP+I_D, 0172400+I_AFOP, 0172400+I_AFOP+I_D, -0173000+I_AFOP, 0173000+I_AFOP+I_D, 0173400+I_AFOP, 0173400+I_AFOP+I_D, -0174000+I_AFOP, 0174000+I_AFOP+I_D, 0174400+I_AFOP, 0174400+I_AFOP+I_D, -0175000+I_ASOP, -0175400+I_ASMD, 0175400+I_ASMD+I_D, 0175400+I_ASMD+I_L, 0175400+I_ASMD+I_D+I_L, -0176000+I_AFOP, 0176000+I_AFOP+I_D, -0176400+I_ASOP, -0177000+I_ASMD, 0177000+I_ASMD+I_D, 0177000+I_ASMD+I_L, 0177000+I_ASMD+I_D+I_L, -0177400+I_AFOP, 0177400+I_AFOP+I_D, --1 -}; - -static const char *rname [] = { - "R0", "R1", "R2", "R3", "R4", "R5", "SP", "PC" - }; - -static const char *fname [] = { - "F0", "F1", "F2", "F3", "F4", "F5", "?6", "?7" - }; - -static const char r50_to_asc[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$._0123456789"; - -/* Specifier decode - - Inputs: - *of = output stream - addr = current PC - spec = specifier - nval = next word - flag = TRUE if decoding for CPU - iflag = TRUE if decoding integer instruction - Outputs: - count = -number of extra words retired -*/ - -int32 fprint_spec (FILE *of, t_addr addr, int32 spec, t_value nval, - int32 flag, int32 iflag) -{ -int32 reg, mode; -static const int32 rgwd[8] = { 0, 0, 0, 0, 0, 0, -1, -1 }; -static const int32 pcwd[8] = { 0, 0, -1, -1, 0, 0, -1, -1 }; - -reg = spec & 07; -mode = ((spec >> 3) & 07); -switch (mode) { - - case 0: - if (iflag) - fprintf (of, "%s", rname[reg]); - else fprintf (of, "%s", fname[reg]); - break; - - case 1: - fprintf (of, "(%s)", rname[reg]); - break; - - case 2: - if (reg != 7) - fprintf (of, "(%s)+", rname[reg]); - else fprintf (of, "#%-o", nval); - break; - - case 3: - if (reg != 7) - fprintf (of, "@(%s)+", rname[reg]); - else fprintf (of, "@#%-o", nval); - break; - - case 4: - fprintf (of, "-(%s)", rname[reg]); - break; - - case 5: - fprintf (of, "@-(%s)", rname[reg]); - break; - - case 6: - if ((reg != 7) || !flag) - fprintf (of, "%-o(%s)", nval, rname[reg]); - else fprintf (of, "%-o", (nval + addr + 4) & 0177777); - break; - - case 7: - if ((reg != 7) || !flag) - fprintf (of, "@%-o(%s)", nval, rname[reg]); - else fprintf (of, "@%-o", (nval + addr + 4) & 0177777); - break; - } /* end case */ - -return ((reg == 07)? pcwd[mode]: rgwd[mode]); -} - -/* Symbolic decode - - Inputs: - *of = output stream - addr = current PC - *val = values to decode - *uptr = pointer to unit - sw = switches - Outputs: - return = if >= 0, error code - if < 0, number of extra words retired -*/ - -t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, - UNIT *uptr, int32 sw) -{ -int32 cflag, i, j, c1, c2, c3, inst, fac, srcm, srcr, dstm, dstr; -int32 bflag, l8b, brdisp, wd1, wd2; -extern int32 FPS; - -bflag = 0; /* assume 16b */ -cflag = (uptr == NULL) || (uptr == &cpu_unit); /* cpu? */ -if (!cflag) { /* not cpu? */ - DEVICE *dptr = find_dev_from_unit (uptr); - if (dptr == NULL) - return SCPE_IERR; - if (dptr->dwidth < 16) - bflag = 1; - } - -if (sw & SWMASK ('A')) { /* ASCII? */ - if (bflag) - c1 = val[0] & 0177; - else c1 = (val[0] >> ((addr & 1)? 8: 0)) & 0177; - fprintf (of, (c1 < 040)? "<%03o>": "%c", c1); - return 0; - } -if (sw & SWMASK ('B')) { /* byte? */ - if (bflag) - c1 = val[0] & 0177; - else c1 = (val[0] >> ((addr & 1)? 8: 0)) & 0377; - fprintf (of, "%o", c1); - return 0; - } -if (bflag) /* 16b only */ - return SCPE_ARG; - -if (sw & SWMASK ('C')) { /* character? */ - c1 = val[0] & 0177; - c2 = (val[0] >> 8) & 0177; - fprintf (of, (c1 < 040)? "<%03o>": "%c", c1); - fprintf (of, (c2 < 040)? "<%03o>": "%c", c2); - return -1; - } -if (sw & SWMASK ('R')) { /* radix 50? */ - if (val[0] > 0174777) /* max value */ - return SCPE_ARG; - c3 = val[0] % 050; - c2 = (val[0] / 050) % 050; - c1 = val[0] / (050 * 050); - fprintf (of, "%c%c%c", r50_to_asc[c1], - r50_to_asc[c2], r50_to_asc[c3]); - return -1; - } -if (!(sw & SWMASK ('M'))) - return SCPE_ARG; - -inst = val[0] | ((FPS << (I_V_L - FPS_V_L)) & I_L) | - ((FPS << (I_V_D - FPS_V_D)) & I_D); /* inst + fp mode */ -for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */ - j = (opc_val[i] >> I_V_CL) & I_M_CL; /* get class */ - if ((opc_val[i] & 0777777) == (inst & masks[j])) { /* match? */ - srcm = (inst >> 6) & 077; /* opr fields */ - srcr = srcm & 07; - fac = srcm & 03; - dstm = inst & 077; - dstr = dstm & 07; - l8b = inst & 0377; - wd1 = wd2 = 0; - switch (j) { /* case on class */ - - case I_V_NPN: case I_V_CCC: case I_V_CCS: /* no operands */ - fprintf (of, "%s", opcode[i]); - break; - - case I_V_REG: /* reg */ - fprintf (of, "%s %-s", opcode[i], rname[dstr]); - break; - - case I_V_SOP: /* sop */ - fprintf (of, "%s ", opcode[i]); - wd1 = fprint_spec (of, addr, dstm, val[1], cflag, TRUE); - break; - - case I_V_3B: /* 3b */ - fprintf (of, "%s %-o", opcode[i], dstr); - break; - - case I_V_FOP: /* fop */ - fprintf (of, "%s ", opcode[i]); - wd1 = fprint_spec (of, addr, dstm, val[1], cflag, FALSE); - break; - - case I_V_AFOP: /* afop */ - fprintf (of, "%s %s,", opcode[i], fname[fac]); - wd1 = fprint_spec (of, addr, dstm, val[1], cflag, FALSE); - break; - - case I_V_6B: /* 6b */ - fprintf (of, "%s %-o", opcode[i], dstm); - break; - - case I_V_BR: /* cond branch */ - fprintf (of, "%s ", opcode[i]); - brdisp = (l8b + l8b + ((l8b & 0200)? 0177002: 2)) & 0177777; - if (cflag) - fprintf (of, "%-o", (addr + brdisp) & 0177777); - else if (brdisp < 01000) - fprintf (of, ".+%-o", brdisp); - else fprintf (of, ".-%-o", 0200000 - brdisp); - break; - - case I_V_8B: /* 8b */ - fprintf (of, "%s %-o", opcode[i], l8b); - break; - - case I_V_SOB: /* sob */ - fprintf (of, "%s %s,", opcode[i], rname[srcr]); - brdisp = (dstm * 2) - 2; - if (cflag) - fprintf (of, "%-o", (addr - brdisp) & 0177777); - else if (brdisp <= 0) - fprintf (of, ".+%-o", -brdisp); - else fprintf (of, ".-%-o", brdisp); - break; - - case I_V_RSOP: /* rsop */ - fprintf (of, "%s %s,", opcode[i], rname[srcr]); - wd1 = fprint_spec (of, addr, dstm, val[1], cflag, TRUE); - break; - - case I_V_SOPR: /* sopr */ - fprintf (of, "%s ", opcode[i]); - wd1 = fprint_spec (of, addr, dstm, val[1], cflag, TRUE); - fprintf (of, ",%s", rname[srcr]); - break; - - case I_V_ASOP: case I_V_ASMD: /* asop, asmd */ - fprintf (of, "%s %s,", opcode[i], fname[fac]); - wd1 = fprint_spec (of, addr, dstm, val[1], cflag, TRUE); - break; - - case I_V_DOP: /* dop */ - fprintf (of, "%s ", opcode[i]); - wd1 = fprint_spec (of, addr, srcm, val[1], cflag, TRUE); - fprintf (of, ","); - wd2 = fprint_spec (of, addr - wd1 - wd1, dstm, - val[1 - wd1], cflag, TRUE); - break; - } /* end case */ - return ((wd1 + wd2) * 2) - 1; - } /* end if */ - } /* end for */ -return SCPE_ARG; /* no match */ -} - -#define A_PND 100 /* # seen */ -#define A_MIN 040 /* -( seen */ -#define A_PAR 020 /* (Rn) seen */ -#define A_REG 010 /* Rn seen */ -#define A_PLS 004 /* + seen */ -#define A_NUM 002 /* number seen */ -#define A_REL 001 /* relative addr seen */ - -/* Register number - - Inputs: - *cptr = pointer to input string - *strings = pointer to register names - mchar = character to match after register name - Outputs: - rnum = 0..7 if a legitimate register - < 0 if error -*/ - -int32 get_reg (char *cptr, const char *strings[], char mchar) -{ -int32 i; - -if (*(cptr + 2) != mchar) - return -1; -for (i = 0; i < 8; i++) { - if (strncmp (cptr, strings[i], 2) == 0) - return i; - } -return -1; -} - -/* Number or memory address - - Inputs: - *cptr = pointer to input string - *dptr = pointer to output displacement - *pflag = pointer to accumulating flags - Outputs: - cptr = pointer to next character in input string - NULL if parsing error - - Flags: 0 (no result), A_NUM (number), A_REL (relative) -*/ - -char *get_addr (char *cptr, int32 *dptr, int32 *pflag) -{ -int32 val, minus; -char *tptr; - -minus = 0; - -if (*cptr == '.') { /* relative? */ - *pflag = *pflag | A_REL; - cptr++; - } -if (*cptr == '+') { /* +? */ - *pflag = *pflag | A_NUM; - cptr++; - } -if (*cptr == '-') { /* -? */ - *pflag = *pflag | A_NUM; - minus = 1; - cptr++; - } -errno = 0; -val = strtoul (cptr, &tptr, 8); -if (cptr == tptr) { /* no number? */ - if (*pflag == (A_REL + A_NUM)) /* .+, .-? */ - return NULL; - *dptr = 0; - return cptr; - } -if (errno || (*pflag == A_REL)) /* .n? */ - return NULL; -*dptr = (minus? -val: val) & 0177777; -*pflag = *pflag | A_NUM; -return tptr; -} - -/* Specifier decode - - Inputs: - *cptr = pointer to input string - addr = current PC - n1 = 0 if no extra word used - -1 if extra word used in prior decode - *sptr = pointer to output specifier - *dptr = pointer to output displacement - cflag = true if parsing for the CPU - iflag = true if integer specifier - Outputs: - status = = -1 extra word decoded - = 0 ok - = +1 error -*/ - -t_stat get_spec (char *cptr, t_addr addr, int32 n1, int32 *sptr, t_value *dptr, - int32 cflag, int32 iflag) -{ -int32 reg, indir, pflag, disp; - -indir = 0; /* no indirect */ -pflag = 0; - -if (*cptr == '@') { /* indirect? */ - indir = 010; - cptr++; - } -if (*cptr == '#') { /* literal? */ - pflag = pflag | A_PND; - cptr++; - } -if (strncmp (cptr, "-(", 2) == 0) { /* autodecrement? */ - pflag = pflag | A_MIN; - cptr++; - } -else if ((cptr = get_addr (cptr, &disp, &pflag)) == NULL) - return 1; -if (*cptr == '(') { /* register index? */ - pflag = pflag | A_PAR; - if ((reg = get_reg (cptr + 1, rname, ')')) < 0) - return 1; - cptr = cptr + 4; - if (*cptr == '+') { /* autoincrement? */ - pflag = pflag | A_PLS; - cptr++; - } - } -else if ((reg = get_reg (cptr, iflag? rname: fname, 0)) >= 0) { - pflag = pflag | A_REG; - cptr = cptr + 2; - } -if (*cptr != 0) /* all done? */ - return 1; -switch (pflag) { /* case on syntax */ - - case A_REG: /* Rn, @Rn */ - *sptr = indir + reg; - return 0; - - case A_PAR: /* (Rn), @(Rn) */ - if (indir) { /* @(Rn) = @0(Rn) */ - *sptr = 070 + reg; - *dptr = 0; - return -1; - } - else *sptr = 010 + reg; - return 0; - - case A_PAR+A_PLS: /* (Rn)+, @(Rn)+ */ - *sptr = 020 + indir + reg; - return 0; - - case A_MIN+A_PAR: /* -(Rn), @-(Rn) */ - *sptr = 040 + indir + reg; - return 0; - - case A_NUM+A_PAR: /* d(Rn), @d(Rn) */ - *sptr = 060 + indir + reg; - *dptr = disp; - return -1; - - case A_PND+A_REL: case A_PND+A_REL+A_NUM: /* #.+n, @#.+n */ - if (!cflag) - return 1; - disp = (disp + addr) & 0177777; /* fall through */ - case A_PND+A_NUM: /* #n, @#n */ - *sptr = 027 + indir; - *dptr = disp; - return -1; - - case A_REL: case A_REL+A_NUM: /* .+n, @.+n */ - *sptr = 067 + indir; - *dptr = (disp - 4 + (2 * n1)) & 0177777; - return -1; - - case A_NUM: /* n, @n */ - if (cflag) { /* CPU - use rel */ - *sptr = 067 + indir; - *dptr = (disp - addr - 4 + (2 * n1)) & 0177777; - } - else { - if (indir) return 1; /* other - use abs */ - *sptr = 037; - *dptr = disp; - } - return -1; - - default: - return 1; - } /* end case */ -} - -/* Symbolic input - - Inputs: - *cptr = pointer to input string - addr = current PC - *uptr = pointer to unit - *val = pointer to output values - sw = switches - Outputs: - status = > 0 error code - <= 0 -number of extra words -*/ - -t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) -{ -int32 bflag, cflag, d, i, j, reg, spec, n1, n2, disp, pflag; -t_value by; -t_stat r; -char *tptr, gbuf[CBUFSIZE]; - -bflag = 0; /* assume 16b */ -cflag = (uptr == NULL) || (uptr == &cpu_unit); /* cpu? */ -if (!cflag) { /* not cpu? */ - DEVICE *dptr = find_dev_from_unit (uptr); - if (dptr == NULL) - return SCPE_IERR; - if (dptr->dwidth < 16) - bflag = 1; - } - -while (isspace (*cptr)) cptr++; /* absorb spaces */ -if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */ - if (cptr[0] == 0) /* must have 1 char */ - return SCPE_ARG; - if (bflag) - val[0] = (t_value) cptr[0]; - else val[0] = (addr & 1)? - (val[0] & 0377) | (((t_value) cptr[0]) << 8): - (val[0] & ~0377) | ((t_value) cptr[0]); - return 0; - } -if (sw & SWMASK ('B')) { /* byte? */ - by = get_uint (cptr, 8, 0377, &r); /* get byte */ - if (r != SCPE_OK) - return SCPE_ARG; - if (bflag) - val[0] = by; - else val[0] = (addr & 1)? - (val[0] & 0377) | (by << 8): - (val[0] & ~0377) | by; - return 0; - } -if (bflag) - return SCPE_ARG; - -if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* ASCII string? */ - if (cptr[0] == 0) /* must have 1 char */ - return SCPE_ARG; - val[0] = ((t_value) cptr[1] << 8) | (t_value) cptr[0]; - return -1; - } -if (sw & SWMASK ('R')) /* radix 50 */ - return SCPE_ARG; - -cptr = get_glyph (cptr, gbuf, 0); /* get opcode */ -n1 = n2 = pflag = 0; -for (i = 0; (opcode[i] != NULL) && (strcmp (opcode[i], gbuf) != 0) ; i++) ; -if (opcode[i] == NULL) - return SCPE_ARG; -val[0] = opc_val[i] & 0177777; /* get value */ -j = (opc_val[i] >> I_V_CL) & I_M_CL; /* get class */ - -switch (j) { /* case on class */ - - case I_V_NPN: /* no operand */ - break; - - case I_V_REG: /* register */ - cptr = get_glyph (cptr, gbuf, 0); /* get glyph */ - if ((reg = get_reg (gbuf, rname, 0)) < 0) - return SCPE_ARG; - val[0] = val[0] | reg; - break; - - case I_V_3B: case I_V_6B: case I_V_8B: /* xb literal */ - cptr = get_glyph (cptr, gbuf, 0); /* get literal */ - d = get_uint (gbuf, 8, (1 << j) - 1, &r); - if (r != SCPE_OK) - return SCPE_ARG; - val[0] = val[0] | d; /* put in place */ - break; - - case I_V_BR: /* cond br */ - cptr = get_glyph (cptr, gbuf, 0); /* get address */ - tptr = get_addr (gbuf, &disp, &pflag); /* parse */ - if ((tptr == NULL) || (*tptr != 0)) - return SCPE_ARG; - if ((pflag & A_REL) == 0) { - if (cflag) - disp = (disp - addr) & 0177777; - else return SCPE_ARG; - } - if ((disp & 1) || ((disp > 0400) && (disp < 0177402))) - return SCPE_ARG; - val[0] = val[0] | (((disp - 2) >> 1) & 0377); - break; - - case I_V_SOB: /* sob */ - cptr = get_glyph (cptr, gbuf, ','); /* get glyph */ - if ((reg = get_reg (gbuf, rname, 0)) < 0) - return SCPE_ARG; - val[0] = val[0] | (reg << 6); - cptr = get_glyph (cptr, gbuf, 0); /* get address */ - tptr = get_addr (gbuf, &disp, &pflag); /* parse */ - if ((tptr == NULL) || (*tptr != 0)) - return SCPE_ARG; - if ((pflag & A_REL) == 0) { - if (cflag) - disp = (disp - addr) & 0177777; - else return SCPE_ARG; - } - if ((disp & 1) || ((disp > 2) && (disp < 0177604))) - return SCPE_ARG; - val[0] = val[0] | (((2 - disp) >> 1) & 077); - break; - - case I_V_RSOP: /* reg, sop */ - cptr = get_glyph (cptr, gbuf, ','); /* get glyph */ - if ((reg = get_reg (gbuf, rname, 0)) < 0) - return SCPE_ARG; - val[0] = val[0] | (reg << 6); /* fall through */ - case I_V_SOP: /* sop */ - cptr = get_glyph (cptr, gbuf, 0); /* get glyph */ - if ((n1 = get_spec (gbuf, addr, 0, &spec, &val[1], cflag, TRUE)) > 0) - return SCPE_ARG; - val[0] = val[0] | spec; - break; - - case I_V_SOPR: /* dop, reg */ - cptr = get_glyph (cptr, gbuf, ','); /* get glyph */ - if ((n1 = get_spec (gbuf, addr, 0, &spec, &val[1], cflag, TRUE)) > 0) - return SCPE_ARG; - val[0] = val[0] | spec; - cptr = get_glyph (cptr, gbuf, 0); /* get glyph */ - if ((reg = get_reg (gbuf, rname, 0)) < 0) - return SCPE_ARG; - val[0] = val[0] | (reg << 6); - break; - - case I_V_AFOP: case I_V_ASOP: case I_V_ASMD: /* fac, (s)fop */ - cptr = get_glyph (cptr, gbuf, ','); /* get glyph */ - if ((reg = get_reg (gbuf, fname, 0)) < 0) - return SCPE_ARG; - if (reg > 3) - return SCPE_ARG; - val[0] = val[0] | (reg << 6); /* fall through */ - case I_V_FOP: /* fop */ - cptr = get_glyph (cptr, gbuf, 0); /* get glyph */ - if ((n1 = get_spec (gbuf, addr, 0, &spec, &val[1], cflag, - (j == I_V_ASOP) || (j == I_V_ASMD))) > 0) - return SCPE_ARG; - val[0] = val[0] | spec; - break; - - case I_V_DOP: /* double op */ - cptr = get_glyph (cptr, gbuf, ','); /* get glyph */ - if ((n1 = get_spec (gbuf, addr, 0, &spec, &val[1], cflag, TRUE)) > 0) - return SCPE_ARG; - val[0] = val[0] | (spec << 6); - cptr = get_glyph (cptr, gbuf, 0); /* get glyph */ - if ((n2 = get_spec (gbuf, addr, n1, &spec, &val[1 - n1], - cflag, TRUE)) > 0) - return SCPE_ARG; - val[0] = val[0] | spec; - break; - - case I_V_CCC: case I_V_CCS: /* cond code oper */ - for (cptr = get_glyph (cptr, gbuf, 0); gbuf[0] != 0; - cptr = get_glyph (cptr, gbuf, 0)) { - for (i = 0; (opcode[i] != NULL) && - (strcmp (opcode[i], gbuf) != 0) ; i++) ; - if ((((opc_val[i] >> I_V_CL) & I_M_CL) != j) || - (opcode[i] == NULL)) - return SCPE_ARG; - val[0] = val[0] | (opc_val[i] & 0177777); - } - break; - - default: - return SCPE_ARG; - } - -if (*cptr != 0) /* junk at end? */ - return SCPE_ARG; -return ((n1 + n2) * 2) - 1; -}