blob: cbb9e928e48968fc094de0d21c893f70c1ebf8fe [file] [log] [blame] [raw]
/* i7094_defs.h: IBM 7094 simulator definitions
Copyright (c) 2003-2011, 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.
This simulator incorporates prior work by Paul Pierce, Dave Pitts, and Rob
Storey. Tom Van Vleck, Stan Dunten, Jerry Saltzer, and other CTSS veterans
helped to reconstruct the CTSS hardware RPQ's. Dave Pitts gets special
thanks for patiently coaching me through IBSYS debug.
25-Mar-11 RMS Updated SDC mask based on 7230 documentation
22-May-10 RMS Added check for 64b addresses
*/
#ifndef I7094_DEFS_H_
#define I7094_DEFS_H_ 0
#include "sim_defs.h" /* simulator defns */
/* Rename of global PC variable to avoid namespace conflicts on some platforms */
#define PC PC_Global
#if defined(USE_ADDR64)
#error "7094 does not support 64b addresses!"
#endif
/* Simulator stop codes */
#define STOP_HALT 1 /* halted */
#define STOP_IBKPT 2 /* breakpoint */
#define STOP_ILLEG 3 /* illegal instr */
#define STOP_DIVCHK 4 /* divide check */
#define STOP_XEC 5 /* XCT loop */
#define STOP_ASTOP 6 /* address stop */
#define STOP_NXCHN 7 /* nx channel */
#define STOP_7909 8 /* ill inst to 7909 */
#define STOP_NT7909 9 /* ill inst to !7909 */
#define STOP_NXDEV 10 /* nx device */
#define STOP_ILLCHI 11 /* illegal channel op */
#define STOP_WRP 12 /* write protect */
#define STOP_ILLIOP 13 /* illegal I/O op */
#define STOP_INVFMT 14 /* invalid disk format */
#define STOP_NOIFREE 15 /* 7750: no buf for inp */
#define STOP_NOOFREE 16 /* 7750: no buf for out */
#define STOP_INVLIN 17 /* 7750: invalid line# */
#define STOP_INVMSG 18 /* 7750: invalid message */
#define STOP_CHBKPT 19 /* channel breakpoint */
/* Simulator error codes */
#define ERR_STALL 40 /* stall */
#define ERR_ENDRC 41 /* end rec */
#define ERR_NRCF 42 /* no record found */
/* Instruction history - flags in left half of pc entry */
#define HIST_PC 0x04000000 /* CPU */
#define HIST_V_CH 28 /* chan + 1 */
#define HIST_M_CH 0xF
#define HIST_CH(x) (((x) >> HIST_V_CH) & HIST_M_CH)
typedef struct {
uint32 pc;
uint32 ea;
uint32 rpt;
t_uint64 ir;
t_uint64 ac;
t_uint64 mq;
t_uint64 si;
t_uint64 opnd;
} InstHistory;
/* Architectural constants */
#define A704_SIZE 14 /* addr width, 704 mode */
#define ASIZE 15 /* inst addr width */
#define PASIZE 16 /* phys addr width */
#define STDMEMSIZE (1u << ASIZE) /* standard memory */
#define MAXMEMSIZE (1u << PASIZE) /* maximum memory */
#define A704_MASK ((1u << A704_SIZE) - 1)
#define PAMASK ((1u << PASIZE) - 1)
#define MEMSIZE (cpu_unit.capac)
#define BCORE_V (ASIZE) /* (CTSS) A/B core sel */
#define BCORE_BASE (1u << BCORE_V) /* (CTSS) B core base */
/* Traps */
#define TRAP_STD_SAV 000000 /* trap save location */
#define TRAP_TRA_PC 000001 /* trap PC: transfer */
#define TRAP_STR_PC 000002 /* trap PC: STR */
#define TRAP_FP_PC 000010 /* trap PC: flt point */
#define TRAP_PROT_SAV 000032 /* protection trap save */
#define TRAP_PROT_PC 000033 /* protection trap PC */
#define TRAP_704_SAV 040000 /* 704 compat trap */
#define TRAP_SEL_PC 040001 /* 704 trap PC: select */
#define TRAP_CPY_PC 040002 /* 704 trap PC: copy */
#define TRAP_F_MQ 000001 /* MQ error */
#define TRAP_F_AC 000002 /* AC error */
#define TRAP_F_OVF 000004 /* overflow */
#define TRAP_F_SGL 000010 /* single precision */
#define TRAP_F_DVC 000020 /* fake: divide check */
#define TRAP_F_ODD 000040 /* odd address */
#define TRAP_F_BDATA 020000 /* (CTSS) data B core */
#define TRAP_F_BINST 040000 /* (CTSS) inst B core */
/* Integer */
#define DMASK INT64_C(0777777777777) /* data mask */
#define SIGN INT64_C(0400000000000) /* sign */
#define MMASK INT64_C(0377777777777) /* magnitude mask */
#define LMASK INT64_C(0777777000000) /* left mask */
#define RMASK INT64_C(0000000777777) /* right mask */
#define PMASK INT64_C(0700000000000) /* prefix */
#define XMASK INT64_C(0077777000000) /* decrement */
#define TMASK INT64_C(0000000700000) /* tag */
#define AMASK INT64_C(0000000077777) /* address */
#define SCMASK INT64_C(0000000000377) /* shift count mask */
#define B1 INT64_C(0200000000000) /* bit 1 */
#define B9 INT64_C(0000400000000) /* bit 9 */
/* Accumulator is actually 38b wide */
#define AC_S INT64_C(02000000000000) /* sign */
#define AC_Q INT64_C(01000000000000) /* Q */
#define AC_P INT64_C(00400000000000) /* P */
#define AC_MMASK INT64_C(01777777777777) /* Q+P+magnitude */
/* Floating point */
#define FP_N_FR 27 /* fraction bits */
#define FP_FMASK ((1u << FP_N_FR) - 1)
#define FP_N_DFR 54 /* double fraction bits */
#define FP_DFMASK ((((t_uint64) 1) << FP_N_DFR) - 1)
#define FP_FNORM (((t_uint64) 1u) << (FP_N_DFR - 1)) /* normalized bit */
#define FP_FCRY (((t_uint64) 1u) << FP_N_DFR) /* fraction carry */
#define FP_BIAS 0200 /* exponent bias */
#define FP_V_CH (FP_N_FR) /* exponent */
#define FP_M_CH 0377 /* SR char mask */
#define FP_M_ACCH 01777 /* AC char mask incl Q,P */
/* Instruction format */
#define INST_T_DEC INT64_C(0300000000000) /* if nz, takes decr */
#define INST_T_CXR1 INT64_C(0000000100000) /* if nz, update XR1 */
#define INST_V_OPD 33 /* decrement opcode */
#define INST_M_OPD 07
#define INST_V_DEC 18 /* decrement */
#define INST_M_DEC 077777
#define INST_V_OPC 24 /* normal opcode */
#define INST_M_OPC 0777
#define INST_V_IND 22 /* indirect */
#define INST_IND (3 << INST_V_IND)
#define INST_V_CCNT 18 /* convert count */
#define INST_M_CCNT 0377
#define INST_V_VCNT 18 /* vlm/vdh count */
#define INST_M_VCNT 077
#define INST_V_TAG 15 /* index */
#define INST_M_TAG 07
#define INST_V_ADDR 0
#define INST_M_ADDR 077777
#define INST_V_4B 0
#define INST_M_4B 017
#define GET_OPD(x) ((uint32) (((x) >> INST_V_OPD) & INST_M_OPD))
#define GET_DEC(x) ((uint32) (((x) >> INST_V_DEC) & INST_M_DEC))
#define GET_OPC(x) (((uint32) (((x) >> INST_V_OPC) & INST_M_OPC)) | \
(((x) & SIGN)? 01000: 0))
#define TST_IND(x) (((x) & INST_IND) == INST_IND)
#define GET_CCNT(x) ((uint32) (((x) >> INST_V_CCNT) & INST_M_CCNT))
#define GET_VCNT(x) ((uint32) (((x) >> INST_V_VCNT) & INST_M_VCNT))
#define GET_TAG(x) ((uint32) (((x) >> INST_V_TAG) & INST_M_TAG))
/* Instruction decode flags */
#define I_4X 0x01 /* 7040, 7044 */
#define I_9X 0x02 /* 7090, 7094, CTSS */
#define I_94 0x04 /* 7094, CTSS */
#define I_CT 0x08 /* CTSS */
#define I_MODEL 0x0F /* option mask */
#define I_X 0x10 /* indexed */
#define I_N 0x20 /* indirect */
#define I_R 0x40 /* read */
#define I_D 0x80 /* double read */
#define I_XN (I_X|I_N)
#define I_XNR (I_X|I_N|I_R)
#define I_XND (I_X|I_N|I_D)
/* Memory protection (CTSS) */
#define VA_V_OFF 0 /* offset in block */
#define VA_N_OFF 8 /* width of offset */
#define VA_M_OFF ((1u << VA_N_OFF) - 1)
#define VA_OFF (VA_M_OFF << VA_V_OFF)
#define VA_V_BLK (VA_N_OFF) /* block */
#define VA_N_BLK (ASIZE - VA_N_OFF) /* width of block */
#define VA_M_BLK ((1u << VA_N_BLK) - 1)
#define VA_BLK (VA_M_BLK << VA_V_BLK)
/* Unsigned operations */
#define NEG(x) (~(x) + 1)
#define BIT_TST(w,b) (((w) >> (b)) & 1)
/* Device information block */
typedef struct {
t_stat (*chsel)(uint32 ch, uint32 sel, uint32 u);
t_stat (*write)(uint32 ch, t_uint64 val, uint32 flags);
} DIB;
/* BCD digits */
#define BCD_MASK 017
#define BCD_ZERO 012
#define BCD_ONE 001
#define BCD_TWO 002
#define BCD_AT 014
/* Channels */
#define NUM_CHAN 8 /* # channels */
#define CH_A 0 /* channel A */
#define CH_B 1
#define CH_C 2
#define CH_D 3
#define CH_E 4
#define CH_F 5
#define CH_G 6
#define CH_H 7
#define REQ_CH(x) (1u << (x))
/* All channel commands */
#define CHI_IND 0000000400000 /* ch inst indirect */
/* Channel selects - all channels */
#define CHSL_RDS 0001 /* data selects */
#define CHSL_WRS 0002
#define CHSL_SNS 0003
#define CHSL_CTL 0004
#define CHSL_FMT 0005
#define CHSL_WEF 0010 /* non-data selects */
#define CHSL_WBT 0011 /* 704X only */
#define CHSL_BSR 0012
#define CHSL_BSF 0013
#define CHSL_REW 0014
#define CHSL_RUN 0015
#define CHSL_SDN 0016
#define CHSL_2ND 0020 /* second state */
#define CHSL_3RD 0040 /* etc */
#define CHSL_4TH 0060
#define CHSL_5TH 0100
#define CHSL_NDS 0010 /* non-data sel flag */
#define CHSL_NUM 16
/* Channel commands - 7607/7289 - S12'19 */
#define CH6I_NST 0000000200000 /* ch inst no store */
#define CH6_IOCD 000
#define CH6_TCH 002
#define CH6_IORP 004
#define CH6_IORT 006
#define CH6_IOCP 010
#define CH6_IOCT 012
#define CH6_IOSP 014
#define CH6_IOST 016
#define CH6_OPMASK 016 /* without nostore */
#define TCH_LIMIT 5 /* TCH autoresolve limit */
/* Channel data flags - 7607 */
#define CH6DF_EOR 1 /* end of record */
#define CH6DF_VLD 2 /* input valid */
/* Channel commands - 7909 - S123'19 */
#define CH9_WTR 000
#define CH9_XMT 001
#define CH9_TCH 004
#define CH9_LIPT 005
#define CH9_CTL 010
#define CH9_CTLR 011
#define CH9_CTLW 012
#define CH9_SNS 013
#define CH9_LAR 014
#define CH9_SAR 015
#define CH9_TWT 016
#define CH9_CPYP 020
#define CH9_CPYD 024
#define CH9_TCM 025
#define CH9_LIP 031
#define CH9_TDC 032
#define CH9_LCC 033
#define CH9_SMS 034
#define CH9_ICC 035
#define CH9_ICCA 037 /* ignores bit <3> */
#define CH9_OPMASK 037
/* Channel data flags - 7909 */
#define CH9DF_STOP 1 /* stop */
#define CH9DF_VLD 2 /* input valid */
/* Extended parts of the command come from the decrement, stored in ch_wc */
#define CH9D_V_MASK 0 /* condition mask */
#define CH9D_M_MASK 077
#define CH9D_V_COND 12 /* condition select */
#define CH9D_M_COND 07
#define CH9D_MASK(x) (((x) >> CH9D_V_MASK) & CH9D_M_MASK)
#define CH9D_COND(x) (((x) >> CH9D_V_COND) & CH9D_M_COND)
#define CH9D_NST 020000 /* no store */
#define CH9D_B11 000100
/* Or from the effective address, stored in ch_ca */
#define CH9A_V_LCC 0 /* counter */
#define CH9A_M_LCC 077
#define CH9A_V_SMS 0 /* system mask */
#define CH9A_M_SMS 0177
#define CH9A_LCC(x) (((x) >> CH9A_V_LCC) & CH9A_M_LCC)
#define CH9A_SMS(x) (((x) >> CH9A_V_SMS) & CH9A_M_SMS)
/* Channel states - common */
#define CHXS_IDLE 0 /* idle */
#define CHXS_DSX 1 /* executing */
/* Channel states - 7607/7289 */
#define CH6S_PNDS 2 /* polling NDS */
#define CH6S_PDS 3 /* polling DS */
#define CH6S_NDS 4 /* nds, executing */
#define CH6S_DSW 5 /* ds, chan wait */
/* Channel traps - 7909 has only CMD (== TWT) */
#define CHTR_V_CME 0 /* cmd/eof enable */
#define CHTR_V_CLK 17 /* clock */
#define CHTR_V_TRC 18 /* tape check */
#define CHTR_V_TWT (CHTR_V_CME)
#define CHTR_CLK_SAV 006 /* clock */
#define CHTR_CHA_SAV 012 /* start of chan block */
#define CHTR_F_CMD 1 /* CMD flag (in decr) */
#define CHTR_F_TRC 2 /* TRC flag (in decr) */
#define CHTR_F_EOF 4 /* EOF flag (in decr) */
/* Channel interrupts - 7909 only */
#define CHINT_CHA_SAV 042 /* start of chan block */
/* Channel interrupt conditions - 7909 only */
#define CHINT_ADPC 001 /* adapter check */
#define CHINT_ATN2 002 /* attention 2 - ni */
#define CHINT_ATN1 004 /* attention 1 */
#define CHINT_UEND 010 /* unusual end */
#define CHINT_SEQC 020 /* sequence check */
#define CHINT_IOC 040 /* IO check */
/* Channel SMS flags - 7909 only */
#define CHSMS_SEL2 0001 /* select 2nd - ni */
#define CHSMS_IATN2 0002 /* inhibit atn2 - ni */
#define CHSMS_IATN1 0004 /* inhibit atn1 */
#define CHSMS_IUEND 0010 /* inhibit uend */
#define CHSMS_BCD 0020 /* BCD conversion - ni */
#define CHSMS_RBCK 0040 /* read backwards - ni */
#define CHSMS_ENCI 0100 /* enable noncon - ni */
/* Channel flags (7607 in right half, 7909 in left half) */
#define CHF_CMD 00000000001 /* cmd done */
#define CHF_TWT (CHF_CMD)
#define CHF_TRC 00000000002 /* tape check */
#define CHF_EOF 00000000004 /* end of file */
#define CHF_BOT 00000000010 /* beginning of tape */
#define CHF_EOT 00000000020 /* end of tape */
#define CHF_LDW 00000000040 /* LCH waiting */
#define CHF_EOR 00000000100 /* end of record */
#define CHF_IRQ 00001000000 /* intr request */
#define CHF_INT 00002000000 /* intr in prog */
#define CHF_WRS 00004000000 /* write */
#define CHF_RDS 00010000000 /* read */
#define CHF_PWR 00020000000 /* prepare to write */
#define CHF_PRD 00040000000 /* prepare to read */
#define CHF_V_COND 24 /* cond register */
#define CHF_M_COND 077
#define CHF_ADPC (CHINT_ADPC << CHF_V_COND) /* adapter check */
#define CHF_ATN2 (CHINT_ATN2 << CHF_V_COND) /* attention 2 */
#define CHF_ATN1 (CHINT_ATN1 << CHF_V_COND) /* attention 1 */
#define CHF_UEND (CHINT_UEND << CHF_V_COND) /* unusual end */
#define CHF_SEQC (CHINT_SEQC << CHF_V_COND) /* sequence check */
#define CHF_IOC (CHINT_IOC << CHF_V_COND) /* IO check */
#define CHF_V_LCC 30 /* loop ctrl counter */
#define CHF_M_LCC 077
#define CHF_CLR_7909 INT64_C(07775000177) /* 7909 clear flags */
#define CHF_SDC_7909 INT64_C(07777600000) /* 7909 SDC flags */
/* Channel characteristics (in dev.flags) */
#define DEV_7909 (1u << (DEV_V_UF + 0))
#define DEV_7289 (1u << (DEV_V_UF + 1))
#define DEV_CDLP (1u << (DEV_V_UF + 2))
#define DEV_7750 (1u << (DEV_V_UF + 3))
#define DEV_7631 (1u << (DEV_V_UF + 4))
/* Unit addresses - 7607/7289 only */
#define U_V_CH 9 /* channel number */
#define U_M_CH 077
#define U_V_UNIT 0
#define U_M_UNIT 0777
#define GET_U_CH(x) (((((uint32) (x)) >> U_V_CH) & U_M_CH) - 1)
#define GET_U_UNIT(x) ((((uint32) (x)) >> U_V_UNIT) & U_M_UNIT)
#define U_MTBCD 0201 /* BCD tape */
#define U_MTBIN 0221 /* binary tape */
#define U_CDR 0321 /* card reader */
#define U_CDP 0341 /* card punch */
#define U_LPBCD 0361 /* BCD print */
#define U_LPBIN 0362 /* binary print */
#define U_DRM 0330 /* 7320A drum */
#define MT_NUMDR 10
/* CTSS Chronolog clock */
#define CHRONO_CH (CH_A) /* channel A */
#define CHRONO_UNIT (7) /* unit 7 */
/* Interval timer */
#define CLK_CTR 05 /* counter */
#define CLK_TPS 60 /* 60Hz */
#define TMR_CLK 0 /* use timer 0 */
#define TMR_COM 1 /* 7750 timer */
/* Function prototypes and macros */
#define ReadP(p) M[p]
#define WriteP(p,d) M[p] = d
void cpu_ent_hist (uint32 pc, uint32 ea, t_uint64 ir, t_uint64 opnd);
t_stat ch_show_chan (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat ch6_end_nds (uint32 ch);
uint32 ch6_set_flags (uint32 ch, uint32 unit, uint32 flags);
t_stat ch6_err_disc (uint32 ch, uint32 unit, uint32 flags);
t_stat ch6_req_rd (uint32 ch, uint32 unit, t_uint64 val, uint32 flags);
t_stat ch6_req_wr (uint32 ch, uint32 unit);
t_bool ch6_qconn (uint32 ch, uint32 unit);
t_stat ch9_req_rd (uint32 ch, t_uint64 val);
void ch9_set_atn (uint32 ch);
void ch9_set_ioc (uint32 ch);
void ch9_set_end (uint32 ch, uint32 ireq);
t_bool ch9_qconn (uint32 ch);
void ch_set_map (void);
t_bool ch_qidle (void);
#endif