diff --git a/H316/h316_cpu.c b/H316/h316_cpu.c index 4f3d64ed..e8576105 100644 --- a/H316/h316_cpu.c +++ b/H316/h316_cpu.c @@ -1,6 +1,6 @@ /* h316_cpu.c: Honeywell 316/516 CPU simulator - Copyright (c) 1999-2010, Robert M. Supnik + Copyright (c) 1999-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"), @@ -25,6 +25,8 @@ cpu H316/H516 CPU + 19-Nov-11 RMS Fixed XR behavior (from Adrian Wise) + 19-Nov-11 RMS Fixed bugs in double precision, normalization, SC (from Adrian Wise) 10-Jan-10 RMS Fixed bugs in LDX, STX introduced in 3.8-1 (from Theo Engel) 28-Apr-07 RMS Removed clock initialization 03-Apr-06 RMS Fixed bugs in LLL, LRL (from Theo Engel) @@ -51,7 +53,7 @@ C overflow flag EXT extend mode flag DP double precision mode flag - SC<1:5> shift count + SC<1:6> shift count SR[1:4]<0> sense switches 1-4 The Honeywell 316/516 has six instruction formats: memory reference, @@ -195,6 +197,18 @@ h316_defs.h add interrupt request definition h316_cpu.c add device dispatch table entry h316_sys.c add sim_devices table entry + + Notes on the behavior of XR: + + - XR is "shadowed" by memory location 0 as seen by the program currently + executing. Thus, in extend mode, this is always absolute location 0. + However, if extend mode is off, this is location 0, if the program is + executing in the lower bank, or location 040000, if the program is + executing in the upper bank. Writing XR writes the shadowed memory + location, and vice versa. + - However, the front panel console always equates XR to absolute location + 0, regardless of extend mode. There is no direct examine or deposit + to XR; the user must examine or deposit location 0. */ #include "h316_defs.h" @@ -234,6 +248,7 @@ uint16 M[MAXMEMSIZE] = { 0 }; /* memory */ int32 saved_AR = 0; /* A register */ int32 saved_BR = 0; /* B register */ int32 saved_XR = 0; /* X register */ +int32 XR = 0; /* live copy - must be global */ int32 PC = 0; /* P register */ int32 C = 0; /* C register */ int32 ext = 0; /* extend mode */ @@ -302,7 +317,7 @@ REG cpu_reg[] = { { ORDATA (P, PC, 15) }, { ORDATA (A, saved_AR, 16) }, { ORDATA (B, saved_BR, 16) }, - { ORDATA (X, XR, 16) }, + { ORDATA (X, saved_XR, 16) }, { ORDATA (SC, sc, 16) }, { FLDATA (C, C, 0) }, { FLDATA (EXT, ext, 0) }, @@ -388,6 +403,8 @@ int32 Operate (int32 MB, int32 AR); BR = (BR & SIGN) | ((x) & MMASK) #define PUTDBL_U(x) AR = ((x) >> 16) & DMASK; \ BR = (x) & DMASK +#define PUTDBL_Z(x) AR = ((x) >> 15) & DMASK; \ + BR = (x) & MMASK #define SEXT(x) (((x) & SIGN)? ((x) | ~DMASK): ((x) & DMASK)) #define NEWA(c,n) (ext? (((c) & ~X_AMASK) | ((n) & X_AMASK)): \ (((c) & ~NX_AMASK) | ((n) & NX_AMASK))) @@ -559,7 +576,7 @@ switch (I_GETOP (MB)) { /* case on <1:6> */ t1 = GETDBL_S (AR, BR); /* get A'B */ t2 = GETDBL_S (Read (Y & ~1), Read (Y | 1)); t1 = Add31 (t1, t2); /* 31b add */ - PUTDBL_S (t1); + PUTDBL_Z (t1); sc = 0; } else AR = Add16 (AR, Read (Y)); /* no, 16b add */ @@ -572,7 +589,7 @@ switch (I_GETOP (MB)) { /* case on <1:6> */ t1 = GETDBL_S (AR, BR); /* get A'B */ t2 = GETDBL_S (Read (Y & ~1), Read (Y | 1)); t1 = Add31 (t1, -t2); /* 31b sub */ - PUTDBL_S (t1); + PUTDBL_Z (t1); sc = 0; } else AR = Add16 (AR, (-Read (Y)) & DMASK); /* no, 16b sub */ @@ -624,6 +641,7 @@ switch (I_GETOP (MB)) { /* case on <1:6> */ if (reason = Ea (MB & ~IDX, &Y)) /* eff addr */ break; XR = Read (Y); /* load XR */ + M[M_XR] = XR; /* update mem too */ break; case 016: case 036: case 056: case 076: /* MPY */ @@ -631,7 +649,7 @@ switch (I_GETOP (MB)) { /* case on <1:6> */ if (reason = Ea (MB, &Y)) /* eff addr */ break; t1 = SEXT (AR) * SEXT (Read (Y)); - PUTDBL_S (t1); + PUTDBL_Z (t1); sc = 0; } else reason = stop_inst; @@ -719,15 +737,15 @@ switch (I_GETOP (MB)) { /* case on <1:6> */ CLR_INT (INT_MPE); if (MB & m11) { /* SCA, INK */ if (MB & m15) /* INK */ - AR = (C << 15) | (dp << 14) | (pme << 13) | (sc & 037); + AR = (C << 15) | (dp << 14) | (pme << 13) | (sc & 077); else if (cpu_unit.flags & UNIT_HSA) /* SCA */ - AR = sc & 037; + AR = sc & 077; else reason = stop_inst; } else if (MB & m10) { /* NRM */ if (cpu_unit.flags & UNIT_HSA) { for (sc = 0; - (sc <= 32) && ((AR & SIGN) != ((AR << 1) & SIGN)); + (sc < 32) && ((AR & SIGN) == ((AR << 1) & SIGN)); sc++) { AR = (AR & SIGN) | ((AR << 1) & MMASK) | ((BR >> 14) & 1); @@ -1050,6 +1068,8 @@ void Write (int32 addr, int32 val) { if (((addr == 0) || (addr >= 020)) && MEM_ADDR_OK (addr)) M[addr] = val; +if (addr == M_XR) /* write XR loc? */ + XR = val; /* update XR */ return; } @@ -1292,15 +1312,10 @@ return SCPE_OK; t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) { -int32 d; - if (addr >= MEMSIZE) return SCPE_NXM; -if (addr == 0) - d = saved_XR; -else d = M[addr]; if (vptr != NULL) - *vptr = d & DMASK; + *vptr = M[addr] & DMASK; return SCPE_OK; } @@ -1312,7 +1327,7 @@ if (addr >= MEMSIZE) return SCPE_NXM; if (addr == 0) saved_XR = val & DMASK; -else M[addr] = val & DMASK; +M[addr] = val & DMASK; return SCPE_OK; } diff --git a/H316/h316_defs.h b/H316/h316_defs.h index 00952096..d647742a 100644 --- a/H316/h316_defs.h +++ b/H316/h316_defs.h @@ -1,6 +1,6 @@ /* h316_defs.h: Honeywell 316/516 simulator definitions - Copyright (c) 1999-2010, Robert M. Supnik + Copyright (c) 1999-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"), @@ -23,6 +23,7 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 19-Nov-11 RMS Removed XR macro, added XR_LOC macro (from Adrian Wise) 22-May-10 RMS Added check for 64b definitions 15-Feb-05 RMS Added start button interrupt 01-Dec-04 RMS Added double precision constants @@ -65,10 +66,10 @@ #define DP_SIGN 010000000000 #define DMASK 0177777 /* data mask */ #define MMASK (DMASK & ~SIGN) /* magnitude mask */ -#define XR M[0] #define M_CLK 061 /* clock location */ #define M_RSTINT 062 /* restrict int */ #define M_INT 063 /* int location */ +#define M_XR (ext? 0: (PC & 040000)) /* XR location */ /* CPU options */ diff --git a/PDP11/pdp11_defs.h b/PDP11/pdp11_defs.h index 269c1cd3..8f2d07ab 100644 --- a/PDP11/pdp11_defs.h +++ b/PDP11/pdp11_defs.h @@ -1,6 +1,6 @@ /* pdp11_defs.h: PDP-11 simulator definitions - Copyright (c) 1993-2010, Robert M Supnik + Copyright (c) 1993-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"), @@ -26,6 +26,7 @@ The author gratefully acknowledges the help of Max Burnet, Megan Gentry, and John Wilson in resolving questions about the PDP-11 + 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 @@ -628,61 +629,65 @@ typedef struct pdp_dib DIB; #define IOBA_PSW (IOPAGEBASE + 017776) /* PSW */ #define IOLN_PSW 002 -/* Interrupt assignments; within each level, priority is right to left */ +/* 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_CLK 0 /* BR6 */ -#define INT_V_PCLK 1 -#define INT_V_DTA 2 -#define INT_V_TA 3 -#define INT_V_PIR6 4 +#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_RK 0 /* BR5 */ -#define INT_V_RL 1 -#define INT_V_RX 2 -#define INT_V_TM 3 -#define INT_V_RP 4 -#define INT_V_TS 5 -#define INT_V_HK 6 -#define INT_V_RQ 7 -#define INT_V_DZRX 8 -#define INT_V_DZTX 9 -#define INT_V_TQ 10 -#define INT_V_RY 11 -#define INT_V_XQ 12 -#define INT_V_XU 13 -#define INT_V_TU 14 -#define INT_V_RF 15 -#define INT_V_RC 16 -#define INT_V_PIR5 17 +#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_TTI 0 /* BR4 */ -#define INT_V_TTO 1 -#define INT_V_PTR 2 -#define INT_V_PTP 3 -#define INT_V_LPT 4 -#define INT_V_VHRX 5 -#define INT_V_VHTX 6 -#define INT_V_CR 7 -#define INT_V_DLI 8 -#define INT_V_DLO 9 -#define INT_V_DCI 10 -#define INT_V_DCO 11 -#define INT_V_PIR4 12 +#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_PIR6 (1u << INT_V_PIR6) +#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) @@ -700,11 +705,11 @@ typedef struct pdp_dib DIB; #define INT_TU (1u << INT_V_TU) #define INT_RF (1u << INT_V_RF) #define INT_RC (1u << INT_V_RC) -#define INT_PIR5 (1u << INT_V_PIR5) -#define INT_PTR (1u << INT_V_PTR) -#define INT_PTP (1u << INT_V_PTP) +#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) @@ -713,11 +718,18 @@ typedef struct pdp_dib DIB; #define INT_DLO (1u << INT_V_DLO) #define INT_DCI (1u << INT_V_DCI) #define INT_DCO (1u << INT_V_DCO) -#define INT_PIR4 (1u << INT_V_PIR4) #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 diff --git a/PDP11/pdp11_io.c b/PDP11/pdp11_io.c index 4ddea2a0..45c08891 100644 --- a/PDP11/pdp11_io.c +++ b/PDP11/pdp11_io.c @@ -1,6 +1,6 @@ /* pdp11_io.c: PDP-11 I/O simulator - Copyright (c) 1993-2008, Robert M Supnik + Copyright (c) 1993-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"), @@ -23,6 +23,7 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 12-Dec-11 RMS Fixed interrupts to treat all Qbus devices as BR4 19-Nov-08 RMS Moved I/O support routines to I/O library 16-May-08 RMS Added multiple DC11 support Renamed DL11 in autoconfigure @@ -79,6 +80,11 @@ static const int32 pirq_bit[7] = { INT_V_PIR5, INT_V_PIR6, INT_V_PIR7 }; +static const int32 int_internal[IPL_HLVL] = { + INT_INTERNAL7, INT_INTERNAL6, INT_INTERNAL5, INT_INTERNAL4, + INT_INTERNAL3, INT_INTERNAL2, INT_INTERNAL1, 0 + }; + /* I/O page lookup and linkage routines Inputs: @@ -118,27 +124,32 @@ if (iodispW[idx]) { return SCPE_NXM; } -/* Calculate interrupt outstanding */ +/* Calculate interrupt outstanding + In a Qbus system, all device interrupts are treated as BR4 */ int32 calc_ints (int32 nipl, int32 trq) { -int32 i; +int32 i, t; +t_bool all_int = (UNIBUS || (nipl < IPL_HMIN)); for (i = IPL_HLVL - 1; i > nipl; i--) { - if (int_req[i]) + t = all_int? int_req[i]: (int_req[i] & int_internal[i]); + if (t) return (trq | TRAP_INT); } return (trq & ~TRAP_INT); } -/* Find vector for highest priority interrupt */ +/* Find vector for highest priority interrupt + In a Qbus system, all device interrupts are treated as BR4 */ int32 get_vector (int32 nipl) { int32 i, j, t, vec; +t_bool all_int = (UNIBUS || (nipl < IPL_HMIN)); for (i = IPL_HLVL - 1; i > nipl; i--) { /* loop thru lvls */ - t = int_req[i]; /* get level */ + t = all_int? int_req[i]: (int_req[i] & int_internal[i]); for (j = 0; t && (j < 32); j++) { /* srch level */ if ((t >> j) & 1) { /* irq found? */ int_req[i] = int_req[i] & ~(1u << j); /* clr irq */ diff --git a/VAX/vax780_defs.h b/VAX/vax780_defs.h index dc36d211..548630c0 100644 --- a/VAX/vax780_defs.h +++ b/VAX/vax780_defs.h @@ -1,6 +1,6 @@ /* vax780_defs.h: VAX 780 model-specific definitions file - Copyright (c) 2004-2008, Robert M Supnik + Copyright (c) 2004-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"), @@ -23,6 +23,8 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 26-Nov-11 MP Changed RQ amd TQ BR levels to BR4 to reflect real hardware + 25-Nov-11 RMS Added VEC_QBUS definition 19-Nov-08 RMS Moved I/O support routines to I/O library 29-Apr-07 RMS Modified model-specific reserved operand check macros to reflect 780 microcode patches (found by Naoki Hamada) @@ -317,16 +319,16 @@ typedef struct { #define INT_V_DZTX 1 #define INT_V_HK 2 #define INT_V_RL 3 -#define INT_V_RQ 4 -#define INT_V_TQ 5 -#define INT_V_TS 6 -#define INT_V_RY 7 -#define INT_V_XU 8 +#define INT_V_TS 4 +#define INT_V_RY 5 +#define INT_V_XU 6 #define INT_V_LPT 0 /* BR4 */ #define INT_V_PTR 1 #define INT_V_PTP 2 #define INT_V_CR 3 +#define INT_V_RQ 4 +#define INT_V_TQ 5 #define INT_DZRX (1u << INT_V_DZRX) #define INT_DZTX (1u << INT_V_DZTX) @@ -346,8 +348,8 @@ typedef struct { #define IPL_DZTX (0x15 - IPL_HMIN) #define IPL_HK (0x15 - IPL_HMIN) #define IPL_RL (0x15 - IPL_HMIN) -#define IPL_RQ (0x15 - IPL_HMIN) -#define IPL_TQ (0x15 - IPL_HMIN) +#define IPL_RQ (0x14 - IPL_HMIN) +#define IPL_TQ (0x14 - IPL_HMIN) #define IPL_TS (0x15 - IPL_HMIN) #define IPL_RY (0x15 - IPL_HMIN) #define IPL_XU (0x15 - IPL_HMIN) @@ -358,6 +360,7 @@ typedef struct { /* Device vectors */ +#define VEC_QBUS 0 #define VEC_Q 0000 #define VEC_PTR 0070 #define VEC_PTP 0074 diff --git a/VAX/vax_cpu1.c b/VAX/vax_cpu1.c index 1f0243bf..8eeac8d9 100644 --- a/VAX/vax_cpu1.c +++ b/VAX/vax_cpu1.c @@ -23,6 +23,7 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 25-Nov-11 RMS Added VEC_QBUS test in interrupt handler 23-Mar-11 RMS Revised idle design (from Mark Pizzolato) 28-May-08 RMS Inlined physical memory routines 29-Apr-07 RMS Separated base register access checks for 11/780 @@ -860,7 +861,7 @@ else { else R[5] = MVC_FILL; /* fill, set state */ R[5] = R[5] | (cc << MVC_V_CC); /* pack with state */ PSL = PSL | PSL_FPD; /* set FPD */ - } + } /* At this point, @@ -1099,7 +1100,7 @@ return (R[0]? 0: CC_Z); /* Interrupt or exception - vec = SCB vector + vec = SCB vector (bit<0> = interrupt in Qbus mode) cc = condition codes ipl = new IPL if interrupt ei = -1: severe exception @@ -1118,8 +1119,8 @@ int32 acc; in_ie = 1; /* flag int/exc */ CLR_TRAPS; /* clear traps */ -newpc = ReadLP ((SCBB + vec) & PAMASK); /* read new PC */ -if (ei < 0) /* severe? on istk */ +newpc = ReadLP ((SCBB + vec) & (PAMASK & ~3)); /* read new PC */ +if (ei == IE_SVE) /* severe? on istk */ newpc = newpc | 1; if (newpc & 2) /* bad flags? */ ABORT (STOP_ILLVEC); @@ -1136,8 +1137,13 @@ else { SP = KSP; /* new stack */ } } -if (ei > 0) /* if int, new IPL */ - PSL = newpsl | (ipl << PSL_V_IPL); +if (ei == IE_INT) { /* if int, new IPL */ + int32 newipl; + if (VEC_QBUS && ((vec & VEC_Q) != 0)) /* Qbus and Qbus vector? */ + newipl = PSL_IPL17; /* force IPL 17 */ + else newipl = ipl << PSL_V_IPL; /* otherwise, int IPL */ + PSL = newpsl | newipl; + } else PSL = newpsl | /* exc, old IPL/1F */ ((newpc & 1)? PSL_IPL1F: (oldpsl & PSL_IPL)) | (oldcur << PSL_V_PRV); if (DEBUG_PRI (cpu_dev, LOG_CPU_I)) diff --git a/VAX/vax_defs.h b/VAX/vax_defs.h index bc825598..64e8ec33 100644 --- a/VAX/vax_defs.h +++ b/VAX/vax_defs.h @@ -188,6 +188,7 @@ #define PSL_M_IPL 0x1F #define PSL_IPL (PSL_M_IPL << PSL_V_IPL) #define PSL_IPL1 (0x01 << PSL_V_IPL) +#define PSL_IPL17 (0x17 << PSL_V_IPL) #define PSL_IPL1F (0x1F << PSL_V_IPL) #define PSL_MBZ (0x30200000 | PSW_MBZ) /* must be zero */ #define PSW_MBZ 0xFF00 /* must be zero */ diff --git a/VAX/vaxmod_defs.h b/VAX/vaxmod_defs.h index c8584397..85e9459d 100644 --- a/VAX/vaxmod_defs.h +++ b/VAX/vaxmod_defs.h @@ -1,6 +1,6 @@ /* vaxmod_defs.h: VAX model-specific definitions file - Copyright (c) 1998-2007, Robert M Supnik + Copyright (c) 1998-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"), @@ -23,6 +23,8 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 11-Dec-11 RMS Moved all Qbus devices to BR4; deleted RP definitions + 25-Nov-11 RMS Added VEC_QBUS definition 29-Apr-07 RMS Separated checks for PxBR and SBR 17-May-06 RMS Added CR11/CD11 support 10-May-06 RMS Added NOP'd reserved operand checking macros @@ -317,7 +319,8 @@ typedef struct { #define IOBA_PTP (IOPAGEBASE + 017554) /* PC11 punch */ #define IOLN_PTP 004 -/* The KA65x maintains 4 separate hardware IPL levels, IPL 17 to IPL 14 +/* The KA65x maintains 4 separate hardware IPL levels, IPL 17 to IPL 14; + however, DEC Qbus controllers all interrupt on IPL 14 Within each IPL, priority is right to left */ @@ -329,38 +332,36 @@ typedef struct { /* IPL 15 */ +/* IPL 14 - devices through RY are IPL 15 on Unibus systems */ + #define INT_V_RQ 0 /* RQDX3 */ #define INT_V_RL 1 /* RLV12/RL02 */ #define INT_V_DZRX 2 /* DZ11 */ #define INT_V_DZTX 3 -#define INT_V_RP 4 /* RP,RM drives */ -#define INT_V_TS 5 /* TS11/TSV05 */ -#define INT_V_TQ 6 /* TMSCP */ -#define INT_V_XQ 7 /* DEQNA/DELQA */ -#define INT_V_RY 8 /* RXV21 */ +#define INT_V_TS 4 /* TS11/TSV05 */ +#define INT_V_TQ 5 /* TMSCP */ +#define INT_V_XQ 6 /* DEQNA/DELQA */ +#define INT_V_RY 7 /* RXV21 */ -/* IPL 14 */ - -#define INT_V_TTI 0 /* console */ -#define INT_V_TTO 1 -#define INT_V_PTR 2 /* PC11 */ -#define INT_V_PTP 3 -#define INT_V_LPT 4 /* LP11 */ -#define INT_V_CSI 5 /* SSC cons UART */ -#define INT_V_CSO 6 -#define INT_V_TMR0 7 /* SSC timers */ -#define INT_V_TMR1 8 -#define INT_V_VHRX 9 /* DHQ11 */ -#define INT_V_VHTX 10 -#define INT_V_QDSS 11 /* QDSS */ -#define INT_V_CR 12 +#define INT_V_TTI 8 /* console */ +#define INT_V_TTO 9 +#define INT_V_PTR 10 /* PC11 */ +#define INT_V_PTP 11 +#define INT_V_LPT 12 /* LP11 */ +#define INT_V_CSI 13 /* SSC cons UART */ +#define INT_V_CSO 14 +#define INT_V_TMR0 15 /* SSC timers */ +#define INT_V_TMR1 16 +#define INT_V_VHRX 17 /* DHQ11 */ +#define INT_V_VHTX 18 +#define INT_V_QDSS 19 /* QDSS */ +#define INT_V_CR 20 #define INT_CLK (1u << INT_V_CLK) #define INT_RQ (1u << INT_V_RQ) #define INT_RL (1u << INT_V_RL) #define INT_DZRX (1u << INT_V_DZRX) #define INT_DZTX (1u << INT_V_DZTX) -#define INT_RP (1u << INT_V_RP) #define INT_TS (1u << INT_V_TS) #define INT_TQ (1u << INT_V_TQ) #define INT_XQ (1u << INT_V_XQ) @@ -380,15 +381,14 @@ typedef struct { #define INT_CR (1u << INT_V_CR) #define IPL_CLK (0x16 - IPL_HMIN) /* relative IPL */ -#define IPL_RQ (0x15 - IPL_HMIN) -#define IPL_RL (0x15 - IPL_HMIN) -#define IPL_DZRX (0x15 - IPL_HMIN) -#define IPL_DZTX (0x15 - IPL_HMIN) -#define IPL_RP (0x15 - IPL_HMIN) -#define IPL_TS (0x15 - IPL_HMIN) -#define IPL_TQ (0x15 - IPL_HMIN) -#define IPL_XQ (0x15 - IPL_HMIN) -#define IPL_RY (0x15 - IPL_HMIN) +#define IPL_RQ (0x14 - IPL_HMIN) +#define IPL_RL (0x14 - IPL_HMIN) +#define IPL_DZRX (0x14 - IPL_HMIN) +#define IPL_DZTX (0x14 - IPL_HMIN) +#define IPL_TS (0x14 - IPL_HMIN) +#define IPL_TQ (0x14 - IPL_HMIN) +#define IPL_XQ (0x14 - IPL_HMIN) +#define IPL_RY (0x14 - IPL_HMIN) #define IPL_TTI (0x14 - IPL_HMIN) #define IPL_TTO (0x14 - IPL_HMIN) #define IPL_PTR (0x14 - IPL_HMIN) @@ -410,6 +410,7 @@ typedef struct { /* Device vectors */ +#define VEC_QBUS 1 /* Qbus system */ #define VEC_Q 0x200 /* Qbus vector offset */ #define VEC_PTR (VEC_Q + 0070) #define VEC_PTP (VEC_Q + 0074) @@ -420,7 +421,6 @@ typedef struct { #define VEC_LPT (VEC_Q + 0200) #define VEC_TS (VEC_Q + 0224) #define VEC_CR (VEC_Q + 0230) -#define VEC_RP (VEC_Q + 0254) #define VEC_TQ (VEC_Q + 0260) #define VEC_RX (VEC_Q + 0264) #define VEC_RY (VEC_Q + 0264) diff --git a/makefile b/makefile index e9083995..41166175 100644 --- a/makefile +++ b/makefile @@ -17,7 +17,7 @@ # # Dynamic loading of libpcap is the default behavior if pcap.h is # available at build time. Direct calls to libpcap can be enabled -# if GNU make is invoked with USE_NETWORK on the command line. +# if GNU make is invoked with USE_NETWORK=1 on the command line. # # Internal ROM support can be disabled if GNU make is invoked with # DONT_USE_ROMS=1 on the command line. @@ -37,22 +37,18 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin) OS_CCDEFS = -D_GNU_SOURCE -DSIM_ASYNCH_IO OS_LDFLAGS = -lm else # Non-Android Builds - INCPATH=/usr/include - LIBPATH=/usr/lib + INCPATH:=/usr/include + LIBPATH:=/usr/lib OS_CCDEFS = -D_GNU_SOURCE ifeq (Darwin,$(shell uname)) LIBEXT = dylib else ifeq (Linux,$(shell uname)) + LIBPATH := $(sort $(foreach lib,$(shell ldconfig -p | grep ' => /' | sed 's/^.* => //'),$(dir $(lib)))) LIBEXT = so - ifeq (usrlib64,$(shell if $(TEST) -d /usr/lib64; then echo usrlib64; fi)) - LIBPATH += /usr/lib64 - endif - ifeq (lib32,$(shell if $(TEST) -d /usr/lib32; then echo lib32; fi)) - LIBPATH += /usr/lib32 - endif else ifeq (SunOS,$(shell uname)) + LIBPATH := $(shell crle | grep 'Default Library Path' | awk '{ print $$5 }' | sed 's/:/ /g') LIBEXT = so OS_LDFLAGS += -lsocket -lnsl ifeq (incsfw,$(shell if $(TEST) -d /opt/sfw/include; then echo incsfw; fi)) @@ -64,6 +60,10 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin) OS_LDFLAGS += -L/opt/sfw/lib -R/opt/sfw/lib endif else + LDSEARCH :=$(shell ldconfig -r | grep 'search directories' | awk '{print $$3}' | sed 's/:/ /g') + ifneq (,$(LDSEARCH)) + LIBPATH := $(LDSEARCH) + endif ifeq (usrpkglib,$(shell if $(TEST) -d /usr/pkg/lib; then echo usrpkglib; fi)) LIBPATH += /usr/pkg/lib OS_LDFLAGS += -L/usr/pkg/lib -R/usr/pkg/lib @@ -77,6 +77,7 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin) endif endif endif + $(info lib paths are: $(LIBPATH)) ifeq (cygwin,$(findstring cygwin,$(OSTYPE))) OS_CCDEFS += -O2 endif diff --git a/scp.c b/scp.c index b70905be..65ff2658 100644 --- a/scp.c +++ b/scp.c @@ -434,7 +434,8 @@ FILE *sim_log = NULL; /* log file */ FILEREF *sim_log_ref = NULL; /* log file file reference */ FILE *sim_deb = NULL; /* debug file */ FILEREF *sim_deb_ref = NULL; /* debug file file reference */ -static FILE *sim_gotofile; +static FILE *sim_gotofile; /* the currently open do file */ +static int32 sim_do_echo = 0; /* the echo status of the currently open do file */ static int32 sim_do_depth = 0; static int32 sim_on_check[MAX_DO_NEST_LVL+1]; @@ -620,6 +621,7 @@ static CTAB cmd_table[] = { "set nothrottle set simulation rate to maximum\n" "set asynch enable asynchronous I/O\n" "set noasynch disable asynchronous I/O\n" + "set environment name=val set environment variable\n" "set OCT|DEC|HEX set device display radix\n" "set ENABLED enable device\n" "set DISABLED disable device\n" @@ -676,6 +678,21 @@ static CTAB cmd_table[] = { { NULL, NULL, 0 } }; +#if defined(_WIN32) +static +int setenv(const char *envname, const char *envval, int overwrite) + { + char *envstr = malloc(strlen(envname)+strlen(envval)+2); + int r; + + sprintf(envstr, "%s=%s", envname, envval); + r = _putenv(envstr); + free(envstr); + return r; + } +#endif + + /* Main command loop */ int main (int argc, char *argv[]) @@ -720,6 +737,7 @@ AIO_INIT; /* init Asynch I/O */ if (sim_vm_init != NULL) /* call once only */ (*sim_vm_init)(); sim_finit (); /* init fio package */ +setenv ("SIM_NAME", sim_name, 1); /* Publish simulator name */ stop_cpu = 0; sim_interval = 0; sim_time = sim_rtime = 0; @@ -777,10 +795,12 @@ while (stat != SCPE_EXIT) { /* in case exit */ cptr = (*sim_vm_read) (cbuf, CBUFSIZE, stdin); } else cptr = read_line_p ("sim> ", cbuf, CBUFSIZE, stdin);/* read with prmopt*/ - if (cptr == NULL) /* ignore EOF */ - continue; + if (cptr == NULL) /* EOF? */ + if (sim_ttisatty()) continue; /* ignore tty EOF */ + else break; /* otherwise exit */ if (*cptr == 0) /* ignore blank */ continue; + sub_args (cbuf, gbuf, CBUFSIZE, argv); if (sim_log) /* log cmd */ fprintf (sim_log, "sim> %s\n", cptr); cptr = get_glyph (cptr, gbuf, 0); /* get command glyph */ @@ -935,7 +955,7 @@ t_stat do_cmd (int32 flag, char *fcptr) char *cptr, cbuf[CBUFSIZE], gbuf[CBUFSIZE], *c, quote, *do_arg[10]; FILE *fpin; CTAB *cmdp; -int32 echo, nargs, errabort, i; +int32 echo = sim_do_echo, nargs, errabort, i; t_bool interactive, isdo, staying; t_stat stat; char *ocptr; @@ -946,7 +966,8 @@ interactive = (flag > 0); /* issued interactively? if (interactive) { /* get switches */ GET_SWITCHES (fcptr); } -echo = sim_switches & SWMASK ('V'); /* -v means echo */ +if (sim_switches & SWMASK ('V')) /* -v means echo */ + echo = 1; errabort = sim_switches & SWMASK ('E'); /* -e means abort on error */ c = fcptr; @@ -1004,6 +1025,7 @@ do { sim_switches = 0; /* init switches */ isdo = FALSE; sim_gotofile = fpin; + sim_do_echo = echo; if (cmdp = find_cmd (gbuf)) { /* lookup command */ if ((cmdp->action == &return_cmd)) /* RETURN command? */ break; /* done! */ @@ -1067,6 +1089,7 @@ do { fclose (fpin); /* close file */ sim_gotofile = NULL; +sim_do_echo = 0; for (i=0; i %s\n", cbuf); + if (sim_do_echo && sim_log) + fprintf (sim_log, "do> %s\n", cbuf); return SCPE_OK; } } +sim_do_echo = saved_do_echo; /* restore echo mode */ fseek(sim_gotofile, fpos, SEEK_SET); /* resture start position */ return SCPE_ARG; } @@ -1360,6 +1391,19 @@ fprintf (st, "Asynchronous I/O is not available in this simulator\n"); return SCPE_OK; } +/* Set environment routine */ + +t_stat sim_set_environment (int32 flag, char *cptr) +{ +char varname[CBUFSIZE]; + +if ((!cptr) || (*cptr == 0)) /* now eol? */ + return SCPE_2FARG; +cptr = get_glyph_gen (cptr, varname, '=', FALSE); /* get environment variable name */ +setenv(varname, cptr, 1); +return SCPE_OK; +} + /* Set command */ t_stat set_cmd (int32 flag, char *cptr) @@ -1376,6 +1420,7 @@ C1TAB *ctbr, *glbr; static CTAB set_glob_tab[] = { { "CONSOLE", &sim_set_console, 0 }, { "BREAK", &brk_cmd, SSH_ST }, + { "NOBREAK", &brk_cmd, SSH_CL }, { "TELNET", &sim_set_telnet, 0 }, /* deprecated */ { "NOTELNET", &sim_set_notelnet, 0 }, /* deprecated */ { "LOG", &sim_set_logon, 0 }, /* deprecated */ @@ -1386,6 +1431,7 @@ static CTAB set_glob_tab[] = { { "NOTHROTTLE", &sim_set_throt, 0 }, { "ASYNCH", &sim_set_asynch, 1 }, { "NOASYNCH", &sim_set_asynch, 0 }, + { "ENV", &sim_set_environment, 1 }, { "ON", &set_on, 1 }, { "NOON", &set_on, 0 }, { NULL, NULL, 0 } @@ -3081,6 +3127,9 @@ if (signal (SIGTERM, int_handler) == SIG_ERR) { /* set WRU */ } if (sim_step) /* set step timer */ sim_activate (&sim_step_unit, sim_step); +fflush(stdout); /* flush stdout */ +if (sim_log) /* flush log if enabled */ + fflush (sim_log); sim_throt_sched (); /* set throttle */ sim_is_running = 1; /* flag running */ sim_brk_clract (); /* defang actions */ @@ -3896,8 +3945,13 @@ for (tptr = cptr; tptr < (cptr + size); tptr++) { /* remove cr or nl */ } while (isspace (*cptr)) /* trim leading spc */ cptr++; -if (*cptr == ';') /* ignore comment */ +if (*cptr == ';') { /* ignore comment */ + if (sim_do_echo) /* echo comments if -v */ + printf("do> %s\n", cptr); + if (sim_do_echo && sim_log) + fprintf (sim_log, "do> %s\n", cptr); *cptr = 0; + } #if defined (HAVE_DLOPEN) if (prompt && p_add_history && *cptr) /* Save non blank lines in history */ diff --git a/sim_console.c b/sim_console.c index 03fc07e8..bf023c49 100644 --- a/sim_console.c +++ b/sim_console.c @@ -23,6 +23,12 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 07-Dec-11 MP Added sim_ttisatty to support reasonable behaviour (i.e. + avoid in infinite loop) in the main command input + loop when EOF is detected and input is coming from + a file (or a null device: /dev/null or NUL:) This may + happen when a simulator is running in a background + process. 17-Apr-11 MP Cleaned up to support running in a background/detached process 20-Jan-11 MP Fixed support for BREAK key on Windows to account @@ -98,6 +104,7 @@ sim_ttrun - called to put terminal into run state sim_ttcmd - called to return terminal to command state sim_ttclose - called once before the simulator exits + sim_ttisatty - called to determine if running interactively sim_os_poll_kbd - poll for keyboard input sim_os_putchar - output character to console @@ -867,6 +874,11 @@ t_stat sim_ttclose (void) return sim_ttcmd (); } +t_bool sim_ttisatty (void) +{ +return isatty (fileno (stdin)); +} + t_stat sim_os_poll_kbd (void) { unsigned int status, term[2]; @@ -986,6 +998,13 @@ t_stat sim_ttclose (void) return SCPE_OK; } +t_bool sim_ttisatty (void) +{ +DWORD Mode; + +return (std_input) && (std_input != INVALID_HANDLE_VALUE) && GetConsoleMode (std_input, &Mode); +} + t_stat sim_os_poll_kbd (void) { int c = -1; @@ -1063,6 +1082,11 @@ t_stat sim_ttclose (void) return SCPE_OK; } +t_bool sim_ttisatty (void) +{ +return 1; +} + t_stat sim_os_poll_kbd (void) { int c; @@ -1259,6 +1283,11 @@ t_stat sim_ttclose (void) return SCPE_OK; } +t_bool sim_ttisatty (void) +{ +return 1; +} + t_stat sim_os_poll_kbd (void) { int c; @@ -1355,6 +1384,11 @@ t_stat sim_ttclose (void) return sim_ttcmd (); } +t_bool sim_ttisatty (void) +{ +return isatty (0); +} + t_stat sim_os_poll_kbd (void) { int status; @@ -1462,6 +1496,11 @@ t_stat sim_ttclose (void) return sim_ttcmd (); } +t_bool sim_ttisatty(void) +{ +return isatty (fileno (stdin)); +} + t_stat sim_os_poll_kbd (void) { int status; diff --git a/sim_console.h b/sim_console.h index 6c64dd31..78d51dd7 100644 --- a/sim_console.h +++ b/sim_console.h @@ -83,6 +83,7 @@ t_stat sim_ttinit (void); t_stat sim_ttrun (void); t_stat sim_ttcmd (void); t_stat sim_ttclose (void); +t_bool sim_ttisatty(void); t_stat sim_os_poll_kbd (void); t_stat sim_os_putchar (int32 out); int32 sim_tt_inpcvt (int32 c, uint32 mode); diff --git a/sim_disk.c b/sim_disk.c index cf5ff17c..2325aa19 100644 --- a/sim_disk.c +++ b/sim_disk.c @@ -2609,7 +2609,7 @@ RPC_STATUS if (!UuidCreate_c) { HINSTANCE hDll; - hDll = LoadLibrary("rpcrt4.dll"); + hDll = LoadLibraryA("rpcrt4.dll"); UuidCreate_c = (void *)GetProcAddress(hDll, "UuidCreate"); } if (UuidCreate_c) @@ -2617,13 +2617,26 @@ if (UuidCreate_c) else _rand_uuid_gen (uuidaddr); } -#elif defined (USE_LIBUUID) -#include +#elif defined (HAVE_DLOPEN) +#include static void uuid_gen (void *uuidaddr) { -uuid_generate((uuid_t)uuidaddr); +void (*uuid_generate_c) (void *) = NULL; +void *handle; + +#define __STR_QUOTE(tok) #tok +#define __STR(tok) __STR_QUOTE(tok) + handle = dlopen("libuuid." __STR(HAVE_DLOPEN), RTLD_NOW|RTLD_GLOBAL); + if (handle) + uuid_generate_c = dlsym(handle, "uuid_generate"); +if (uuid_generate_c) + uuid_generate_c(uuidaddr); +else + _rand_uuid_gen (uuidaddr); + if (handle) + dlclose(handle); } #else static void diff --git a/sim_ether.c b/sim_ether.c index e428360c..5f33416a 100644 --- a/sim_ether.c +++ b/sim_ether.c @@ -961,7 +961,12 @@ void pcap_close(pcap_t* a) { } } +/* OpenBSD has an ancient declaration of pcap_compile which doesn't have a const in the bpf string argument */ +#if defined (__OpenBSD__) +int pcap_compile(pcap_t* a, struct bpf_program* b, char* c, int d, bpf_u_int32 e) { +#else int pcap_compile(pcap_t* a, struct bpf_program* b, const char* c, int d, bpf_u_int32 e) { +#endif if (load_pcap() != 0) { return p_pcap_compile(a, b, c, d, e); } else {