From 51aad45cdc5dac9feea2a11bb3a4f6d94b758dc2 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Tue, 1 Mar 2016 08:33:28 -0800 Subject: [PATCH] PDP18B: Add RB disk to PDP7 and DRM drum to PDP9 and -u, -p examine/deposit switches in PDP7, PDP9 and PDP15 This merges the latest PDP18B changes from Bob Supnik: - It adds the RB disk to the PDP-7 and the drum (DRM) to the PDP-9, per the discoveries in the 18b services listing. - It tweaks the switches for examine and deposit to support Unix v0 and (eventually) the Unichannel. --- PDP18B/pdp18b_cpu.c | 2 +- PDP18B/pdp18b_defs.h | 23 ++++- PDP18B/pdp18b_drm.c | 11 ++- PDP18B/pdp18b_dt.c | 10 ++- PDP18B/pdp18b_lp.c | 8 +- PDP18B/pdp18b_mt.c | 5 +- PDP18B/pdp18b_rf.c | 5 +- PDP18B/pdp18b_rp.c | 5 +- PDP18B/pdp18b_stddev.c | 7 +- PDP18B/pdp18b_sys.c | 130 +++++++++++++++++++++++------ PDP18B/pdp18b_tt1.c | 10 ++- Visual Studio Projects/PDP7.vcproj | 4 + doc/pdp18b_doc.doc | Bin 103424 -> 100352 bytes 13 files changed, 181 insertions(+), 39 deletions(-) diff --git a/PDP18B/pdp18b_cpu.c b/PDP18B/pdp18b_cpu.c index fe799ae3..b2a7562f 100644 --- a/PDP18B/pdp18b_cpu.c +++ b/PDP18B/pdp18b_cpu.c @@ -433,7 +433,7 @@ static const int32 api_ffo[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static const int32 api_vec[API_HLVL][32] = { +int32 api_vec[API_HLVL][32] = { { ACH_PWRFL }, /* API 0 */ { ACH_DTA, ACH_MTA, ACH_DRM, ACH_RF, ACH_RP, ACH_RB }, /* API 1 */ { ACH_PTR, ACH_LPT, ACH_LPT }, /* API 2 */ diff --git a/PDP18B/pdp18b_defs.h b/PDP18B/pdp18b_defs.h index 0bdce5f9..411cb9b5 100644 --- a/PDP18B/pdp18b_defs.h +++ b/PDP18B/pdp18b_defs.h @@ -1,6 +1,6 @@ /* pdp18b_defs.h: 18b PDP simulator definitions - Copyright (c) 1993-2012, Robert M Supnik + Copyright (c) 1993-2016, 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-Feb-16 RMS Added RB09 to PDP-7 for Unix "v0" and RM09 to PDP-9 + 13-Sep-15 RMS Added DR15C 18-Apr-12 RMS Added clk_cosched prototype 22-May-10 RMS Added check for 64b definitions 30-Oct-06 RMS Added infinite loop stop @@ -82,6 +84,7 @@ Type 647B line printer (sixbit) Type 550/555 DECtape Type 24 serial drum + RB09 fixed head disk (Unix V0 only) PDP9 32K KE09A EAE KSR-33 Teletype KF09A auto pri intr PC09A paper tape reader and punch @@ -90,6 +93,7 @@ KX09A mem protection LP09 line printer (ASCII) RF09/RS09 fixed head disk RB09 fixed head disk + RM09 drum TC59 magnetic tape TC02/TU55 DECtape LT09A additional Teletypes @@ -139,12 +143,14 @@ #define TYPE647 0 /* sixbit printer */ #define TYPE550 0 /* DECtape */ #define DRM 0 /* drum */ +#define RB 0 /* fixed head disk */ #elif defined (PDP9) #define ADDRSIZE 15 #define TYPE647 0 /* sixbit printer */ #define LP09 0 /* ASCII printer */ #define RB 0 /* fixed head disk */ #define RF 0 /* fixed head disk */ +#define DRM 0 /* drum */ #define MTA 0 /* magtape */ #define TC02 0 /* DECtape */ #define TTY1 4 /* second Teletype(s) */ @@ -158,6 +164,7 @@ #define MTA 0 /* magtape */ #define TC02 0 /* DECtape */ #define TTY1 16 /* second Teletype(s) */ +#define DR 0 /* DR15C */ #define BRMASK 0377400 /* bounds mask */ #define BRMASK_XVM 0777400 /* bounds mask, XVM */ #endif @@ -275,6 +282,7 @@ typedef struct { #define DEV_TTI1 041 /* extra terminals */ #define DEV_TTO1 040 #define DEV_DRM 060 /* drum */ +#define DEV_DR 060 /* DR15 */ #define DEV_RP 063 /* RP15 */ #define DEV_LPT 065 /* line printer */ #define DEV_RF 070 /* RF09 */ @@ -324,6 +332,8 @@ typedef struct { 36 - 37 - + The DR15C uses four API channels that are assigned by software. + On the PDP-9, any API level active masks PI, and PI does not mask API. On the PDP-15, only the hardware API levels active mask PI, and PI masks the API software levels. */ @@ -441,6 +451,17 @@ typedef struct { #define CLR_INT(dv) int_hwre[API_##dv] = int_hwre[API_##dv] & ~INT_##dv #define TST_INT(dv) (int_hwre[API_##dv] & INT_##dv) +/* The DR15C uses the same relative bit position in all four interrupt levels. + This allows software to have a single definition for the interrupt bit position, + regardless of level. The standard macros cannot be used. */ + +#define INT_V_DR 7 /* to left of all */ +#define INT_DR (1 << INT_V_DR) +#define API_DR0 0 +#define API_DR1 1 +#define API_DR2 2 +#define API_DR3 3 + /* I/O status flags for the IORS instruction bit PDP-4 PDP-7 PDP-9 PDP-15 diff --git a/PDP18B/pdp18b_drm.c b/PDP18B/pdp18b_drm.c index d0448003..f65a053a 100644 --- a/PDP18B/pdp18b_drm.c +++ b/PDP18B/pdp18b_drm.c @@ -1,6 +1,6 @@ -/* pdp18b_drm.c: drum/fixed head disk simulator +/* pdp18b_drm.c: drum head disk simulator - Copyright (c) 1993-2013, Robert M Supnik + Copyright (c) 1993-2016, 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,8 +23,9 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. - drm (PDP-4,PDP-7) Type 24 serial drum + drm (PDP-4,PDP-7) Type 24 serial drum; (PDP-9) RM09 drum + 26-Feb-16 RMS Added PDP-9 support; set default state to disabled 03-Sep-13 RMS Added explicit void * cast 14-Jan-04 RMS Revised IO device call interface 26-Oct-03 RMS Cleaned up buffer copy code @@ -37,6 +38,8 @@ 10-Jun-01 RMS Cleaned up IOT decoding to reflect hardware 26-Apr-01 RMS Added device enable/disable support 14-Apr-99 RMS Changed t_addr to unsigned + + Variable drum sizes are not supported. */ #include "pdp18b_defs.h" @@ -118,7 +121,7 @@ DEVICE drm_dev = { 1, 8, 20, 1, 8, 18, NULL, NULL, &drm_reset, &drm_boot, NULL, NULL, - &drm_dib, DEV_DISABLE + &drm_dib, DEV_DISABLE + DEV_DIS }; /* IOT routines */ diff --git a/PDP18B/pdp18b_dt.c b/PDP18B/pdp18b_dt.c index 8cfcc276..e3a9e948 100644 --- a/PDP18B/pdp18b_dt.c +++ b/PDP18B/pdp18b_dt.c @@ -1,6 +1,6 @@ /* pdp18b_dt.c: 18b DECtape simulator - Copyright (c) 1993-2008, Robert M Supnik + Copyright (c) 1993-2015, 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"), @@ -27,6 +27,8 @@ (PDP-9) TC02/TU55 DECtape (PDP-15) TC15/TU56 DECtape + 13-Mar-15 RMS Added APIVEC register + 28-Mar-15 RMS Revised to use sim_printf 23-Jun-06 RMS Fixed switch conflict in ATTACH Revised Type 550 header based on DECTOG formatter 13-Jun-06 RMS Fixed checksum calculation bug in Type 550 @@ -327,6 +329,7 @@ extern int32 M[]; extern int32 int_hwre[API_HLVL+1]; +extern int32 api_vec[API_HLVL][32]; extern UNIT cpu_unit; int32 dtsa = 0; /* status A */ @@ -419,6 +422,9 @@ REG dt_reg[] = { DT_NUMDR, REG_HRO) }, { ORDATA (DEVNO, dt_dib.dev, 6), REG_HRO }, { FLDATA (STOP_OFFR, dt_stopoffr, 0) }, +#if defined (TC02) + { ORDATA (APIVEC, api_vec[API_DTA][INT_V_DTA], 6), REG_HRO }, +#endif { NULL } }; @@ -1508,7 +1514,7 @@ if (uptr->WRITTEN && uptr->hwmark && ((uptr->flags & UNIT_RO)== 0)) { /* any ((fbuf[ba + 1] >> 12) & 077); pdp8b[k + 2] = fbuf[ba + 1] & 07777; ba = ba + 2; - } /* end loop blk */ + } /* end loop blk */ fxwrite (pdp8b, sizeof (uint16), D8_NBSIZE, uptr->fileref); if (ferror (uptr->fileref)) break; diff --git a/PDP18B/pdp18b_lp.c b/PDP18B/pdp18b_lp.c index 7588ff09..03d66bbf 100644 --- a/PDP18B/pdp18b_lp.c +++ b/PDP18B/pdp18b_lp.c @@ -1,6 +1,6 @@ /* pdp18b_lp.c: 18b PDP's line printer simulator - Copyright (c) 1993-2008, Robert M Supnik + Copyright (c) 1993-2015, 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"), @@ -28,6 +28,7 @@ lp09 (PDP-9,15) LP09 line printer lp15 (PDP-15) LP15 line printer + 13-Sep-15 RMS Added APIVEC register 19-Jan-07 RMS Added UNIT_TEXT flag 11-Jun-06 RMS Made character translation table global scope 14-Jan-04 RMS Revised IO device call interface @@ -47,7 +48,10 @@ */ #include "pdp18b_defs.h" + extern int32 int_hwre[API_HLVL+1]; +extern int32 api_vec[API_HLVL][32]; + const char fio_to_asc[64] = { ' ','1','2','3','4','5','6','7','8','9','\'','~','#','V','^','<', '0','/','S','T','U','V','W','X','Y','Z','"',',','>','^','-','?', @@ -534,6 +538,7 @@ REG lp09_reg[] = { { DRDATA (TIME, lp09_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, lp09_stopioe, 0) }, { ORDATA (DEVNO, lp09_dib.dev, 6), REG_HRO }, + { ORDATA (APIVEC, api_vec[API_LPT][INT_V_LPT], 6), REG_HRO }, { NULL } }; @@ -720,6 +725,7 @@ REG lp15_reg[] = { { FLDATA (STOP_IOE, lp15_stopioe, 0) }, { BRDATA (LBUF, lp15_buf, 8, 8, LP15_BSIZE) }, { ORDATA (DEVNO, lp15_dib.dev, 6), REG_HRO }, + { ORDATA (APIVEC, api_vec[API_LPT][INT_V_LPT], 6), REG_HRO }, { NULL } }; diff --git a/PDP18B/pdp18b_mt.c b/PDP18B/pdp18b_mt.c index 7f552741..ed7eb53f 100644 --- a/PDP18B/pdp18b_mt.c +++ b/PDP18B/pdp18b_mt.c @@ -1,6 +1,6 @@ /* pdp18b_mt.c: 18b PDP magnetic tape simulator - Copyright (c) 1993-2008, Robert M Supnik + Copyright (c) 1993-2015, 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 @@ mt (PDP-9) TC59 magtape (PDP-15) TC59D magtape + 13-Sep-15 RMS Added APIVEC register 14-Nov-08 RMS Replaced mt_log with standard debug facility 16-Feb-06 RMS Added tape capacity checking 16-Aug-05 RMS Fixed C++ declaration and cast problems @@ -126,6 +127,7 @@ extern int32 M[]; extern int32 int_hwre[API_HLVL+1]; +extern int32 api_vec[API_HLVL][32]; extern UNIT cpu_unit; int32 mt_cu = 0; /* command/unit */ @@ -178,6 +180,7 @@ REG mt_reg[] = { { URDATA (POS, mt_unit[0].pos, 10, T_ADDR_W, 0, MT_NUMDR, PV_LEFT | REG_RO) }, { ORDATA (DEVNO, mt_dib.dev, 6), REG_HRO }, + { ORDATA (APIVEC, api_vec[API_MTA][INT_V_MTA], 6), REG_HRO }, { NULL } }; diff --git a/PDP18B/pdp18b_rf.c b/PDP18B/pdp18b_rf.c index 9f78c285..583942e0 100644 --- a/PDP18B/pdp18b_rf.c +++ b/PDP18B/pdp18b_rf.c @@ -1,6 +1,6 @@ /* pdp18b_rf.c: fixed head disk simulator - Copyright (c) 1993-2013, Robert M Supnik + Copyright (c) 1993-2015, 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 @@ rf (PDP-9) RF09/RF09 (PDP-15) RF15/RS09 + 13-Sep-15 RMS Added APIVEC register 03-Sep-13 RMS Added explicit void * cast 04-Oct-06 RMS Fixed bug, DSCD does not clear function register 15-May-06 RMS Fixed bug in autosize attach (David Gesswein) @@ -110,6 +111,7 @@ extern int32 M[]; extern int32 int_hwre[API_HLVL+1]; +extern int32 api_vec[API_HLVL][32]; extern UNIT cpu_unit; int32 rf_sta = 0; /* status register */ @@ -157,6 +159,7 @@ REG rf_reg[] = { { FLDATA (STOP_IOE, rf_stopioe, 0) }, { DRDATA (CAPAC, rf_unit.capac, 31), PV_LEFT + REG_HRO }, { ORDATA (DEVNO, rf_dib.dev, 6), REG_HRO }, + { ORDATA (APIVEC, api_vec[API_RF][INT_V_RF], 6), REG_HRO }, { NULL } }; diff --git a/PDP18B/pdp18b_rp.c b/PDP18B/pdp18b_rp.c index 398061da..8cfad45d 100644 --- a/PDP18B/pdp18b_rp.c +++ b/PDP18B/pdp18b_rp.c @@ -1,6 +1,6 @@ /* pdp18b_rp.c: RP15/RP02 disk pack simulator - Copyright (c) 1993-2008, Robert M Supnik + Copyright (c) 1993-2015, 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,7 @@ rp RP15/RP02 disk pack + 13-Sep-15 RMS Added APIVEC register 14-Jan-04 RMS Revised IO device call interface 06-Feb-03 RMS Revised IOT decoding, fixed bug in initiation 05-Oct-02 RMS Added DIB, device number support @@ -133,6 +134,7 @@ extern int32 M[]; extern int32 int_hwre[API_HLVL+1], nexm; +extern int32 api_vec[API_HLVL][32]; extern UNIT cpu_unit; int32 rp_sta = 0; /* status A */ @@ -188,6 +190,7 @@ REG rp_reg[] = { { DRDATA (STIME, rp_swait, 24), PV_LEFT }, { DRDATA (RTIME, rp_rwait, 24), PV_LEFT }, { ORDATA (DEVNO, rp_dib.dev, 6), REG_HRO }, + { ORDATA (APIVEC, api_vec[API_RP][INT_V_RP], 6), REG_HRO }, { NULL } }; diff --git a/PDP18B/pdp18b_stddev.c b/PDP18B/pdp18b_stddev.c index 5d217714..1437c927 100644 --- a/PDP18B/pdp18b_stddev.c +++ b/PDP18B/pdp18b_stddev.c @@ -1,6 +1,6 @@ /* pdp18b_stddev.c: 18b PDP's standard devices - Copyright (c) 1993-2012, Robert M Supnik + Copyright (c) 1993-2015, 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"), @@ -29,6 +29,8 @@ tto teleprinter clk clock + 13-Sep-15 RMS Added APIVEC register to PTR, CLK only + 28-Mar-15 RMS Revised to use sim_printf 18-Apr-12 RMS Added clk_cosched routine Revised clk and tti scheduling 18-Jun-07 RMS Added UNIT_IDLE to console input, clock @@ -86,6 +88,7 @@ extern int32 M[]; extern int32 int_hwre[API_HLVL+1], PC, ASW; +extern int32 api_vec[API_HLVL][32]; extern UNIT cpu_unit; int32 clk_state = 0; @@ -181,6 +184,7 @@ REG clk_reg[] = { #endif { DRDATA (TIME, clk_unit.wait, 24), REG_NZ + PV_LEFT }, { DRDATA (TPS, clk_tps, 8), PV_LEFT + REG_HRO }, + { ORDATA (APIVEC, api_vec[API_CLK][INT_V_CLK], 6), REG_HRO }, { NULL } }; @@ -228,6 +232,7 @@ REG ptr_reg[] = { { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT }, { FLDATA (STOP_IOE, ptr_stopioe, 0) }, + { ORDATA (APIVEC, api_vec[API_PTR][INT_V_PTR], 6), REG_HRO }, { NULL } }; diff --git a/PDP18B/pdp18b_sys.c b/PDP18B/pdp18b_sys.c index ecb10bb8..fe619e1f 100644 --- a/PDP18B/pdp18b_sys.c +++ b/PDP18B/pdp18b_sys.c @@ -1,6 +1,6 @@ /* pdp18b_sys.c: 18b PDP's simulator interface - Copyright (c) 1993-2008, Robert M Supnik + Copyright (c) 1993-2016, 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-Feb-15 RMS Added support for -u modifier (UC15 and Unix v0) + 13-Sep-15 RMS Added DR15C instructions 30-Oct-06 RMS Added infinite loop stop 18-Oct-06 RMS Re-ordered device list 02-Oct-06 RMS Added RDCLK instruction @@ -103,6 +105,8 @@ extern int32 PC; extern const char asc_to_baud[128]; extern const char baud_to_asc[64]; extern const char fio_to_asc[64]; +extern t_stat fprint_sym_cm_w (FILE *of, t_addr addr, t_value *val, int32 sw); +extern t_stat parse_sym_cm_w (char *cptr, t_addr addr, t_value *val, int32 sw); /* SCP data structures and interface routines @@ -126,7 +130,7 @@ char sim_name[] = "PDP-15"; REG *sim_PC = &cpu_reg[0]; -int32 sim_emax = 2; +int32 sim_emax = 3; DEVICE *sim_devices[] = { &cpu_dev, @@ -501,6 +505,12 @@ static const char *opcode[] = { "DTCA", "DTRA", "DTXA", "DTLA", "DTEF", "DTRB", "DTDF", #endif +#if defined (DR) /* DR15C */ + "SIOA", "CIOD", "LIOR", + "RDRS", "LDRS", + "SAPI0", "SAPI1", "SAPI2", "SAPI3", + "CAPI0", "CAPI1", "CAPI2", "CAPI3", +#endif #if defined (TTY1) "KSF1", "KRB1", "TSF1", "TCF1", "TLS1", "TCF1!TLS1", @@ -738,6 +748,12 @@ static const int32 opc_val[] = { 0704101+I_NPI, 0704112+I_NPN, 0704001+I_NPI, 0704002+I_NPI, 0704004+I_NPI, 0704006+I_NPI, #endif +#if defined (DR) + 0706001+I_NPI, 0706002+I_NPI, 0706006+I_NPI, + 0706112+I_NPI, 0706122+I_NPI, + 0706101+I_NPI, 0706121+I_NPI, 0706141+I_NPI, 0706161+I_NPI, + 0706104+I_NPI, 0706124+I_NPI, 0706144+I_NPI, 0706164+I_NPI, +#endif #if defined (PDP7) 0703201+I_NPI, 0703301+I_NPI, 0703341+I_NPI, 0703302+I_NPI, 0707701+I_NPI, 0707702+I_NPI, 0707742+I_NPI, 0707704+I_NPI, @@ -885,13 +901,13 @@ static const int32 opc_val[] = { #define fputs(_s,f) Fprintf(f,"%s",_s) #define fputc(_c,f) Fprintf(f,"%c",_c) -int32 fprint_opr (FILE *of, int32 inst, int32 class, int32 sp) +int32 fprint_opr (FILE *of, int32 inst, int32 clss, int32 sp) { int32 i, j; for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */ j = (opc_val[i] >> I_V_FL) & I_M_FL; /* get class */ - if ((j == class) && (opc_val[i] & inst)) { /* same class? */ + if ((j == clss) && (opc_val[i] & inst)) { /* same class? */ inst = inst & ~opc_val[i]; /* mask bit set? */ fprintf (of, (sp? " %s": "%s"), opcode[i]); sp = 1; @@ -924,52 +940,78 @@ return (c >> 1) | (c << 5); t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw) { -int32 cflag, i, j, k, sp, inst, disp, ma; +int32 i, j, k, sp, inst, disp, ma; +t_bool cflag; +DEVICE *dptr; + +if (uptr == NULL) + uptr = &cpu_unit; +dptr = find_dev_from_unit (uptr); +if (dptr == NULL) + return SCPE_IERR; inst = val[0]; -cflag = (uptr == NULL) || (uptr == &cpu_unit); -if (sw & SWMASK ('A')) { /* ASCII? */ +if ((sw & SWMASK ('A')) != 0) { /* ASCII? */ if (inst > 0377) return SCPE_ARG; fprintf (of, FMTASC (inst & 0177)); return SCPE_OK; } -if (sw & SWMASK ('C')) { /* character? */ +#if defined (UC15) +if (dptr->dwidth == 16) /* 16b device? */ + return fprint_sym_cm_w (of, addr, val, sw); +#endif + +if (dptr->dwidth < 18) /* 18b device? */ + return SCPE_ARG; + +if ((sw & SWMASK ('C')) != 0) { /* character? */ fprintf (of, "%c", SIXTOASC ((inst >> 12) & 077)); fprintf (of, "%c", SIXTOASC ((inst >> 6) & 077)); fprintf (of, "%c", SIXTOASC (inst & 077)); return SCPE_OK; } -#if defined (PDP4) || defined (PDP7) -if (sw & SWMASK ('F')) { /* FIODEC? */ +if ((sw & SWMASK ('F')) != 0) { /* FIODEC? */ fprintf (of, "%c", fio_to_asc[(inst >> 12) & 077]); fprintf (of, "%c", fio_to_asc[(inst >> 6) & 077]); fprintf (of, "%c", fio_to_asc[inst & 077]); return SCPE_OK; } -if (sw & SWMASK ('B')) { /* Baudot? */ +if ((sw & SWMASK ('B')) != 0) { /* Baudot? */ fprintf (of, "%c", baud_to_asc[rar (inst >> 12) & 077]); fprintf (of, "%c", baud_to_asc[rar (inst >> 6) & 077]); fprintf (of, "%c", baud_to_asc[rar (inst) & 077]); return SCPE_OK; } -#endif -#if defined (PDP15) -if (sw & SWMASK ('P')) { /* packed ASCII? */ - i = val[1]; +#if defined (PDP7) || defined (PDP9) +if ((sw & SWMASK ('U')) != 0) { /* Unix v0 ASCII? */ + fprintf (of, FMTASC ((inst >> 9) & 0177)); + fprintf (of, FMTASC (inst & 0177)); + return SCPE_OK; + } +#elif defined (PDP15) +if ((sw & SWMASK ('P')) != 0) { /* packed ASCII? */ + int32 t = val[1]; fprintf (of, FMTASC ((inst >> 11) & 0177)); fprintf (of, FMTASC ((inst >> 4) & 0177)); - fprintf (of, FMTASC (((inst << 3) | (i >> 15)) & 0177)); - fprintf (of, FMTASC ((i >> 8) & 0177)); - fprintf (of, FMTASC ((i >> 1) & 0177)); + fprintf (of, FMTASC (((inst << 3) | (t >> 15)) & 0177)); + fprintf (of, FMTASC ((t >> 8) & 0177)); + fprintf (of, FMTASC ((t >> 1) & 0177)); return -1; } +if ((sw & SWMASK ('U')) != 0) { /* Unibus ASCII? */ + fprintf (of, FMTASC (inst & 0177)); + fprintf (of, FMTASC ((inst >> 8) & 0177)); + return SCPE_OK; + } #endif -if (!(sw & SWMASK ('M'))) +if ((sw & SWMASK ('M')) == 0) /* symbolic? */ return SCPE_ARG; /* Instruction decode */ +cflag = (uptr == &cpu_unit); +inst = val[0]; for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */ j = (opc_val[i] >> I_V_FL) & I_M_FL; /* get class */ if ((opc_val[i] & DMASK) == (inst & masks[j])) { /* match? */ @@ -1099,15 +1141,22 @@ return get_uint (cptr, 8, 0777777, status); Outputs: status = error status */ - t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) { -int32 cflag, d, i, j, k, sign, damask, epcmask; +int32 d, i, j, k, sign, damask, epcmask; t_stat r, sta = SCPE_OK; char gbuf[CBUFSIZE]; +t_bool cflag; +DEVICE *dptr; -cflag = (uptr == NULL) || (uptr == &cpu_unit); -while (isspace (*cptr)) cptr++; +if (uptr == NULL) + uptr = &cpu_unit; +dptr = find_dev_from_unit (uptr); +if (dptr == NULL) + return SCPE_IERR; + +while (isspace (*cptr)) + cptr++; for (i = 1; (i < 5) && (cptr[i] != 0); i++) { if (cptr[i] == 0) { for (j = i + 1; j <= 5; j++) @@ -1120,6 +1169,21 @@ if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */ val[0] = (t_value) cptr[0] | 0200; return SCPE_OK; } +#if defined (UC15) +if (dptr->dwidth == 16) { /* 16b decode? */ + if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* char string? */ + if (cptr[0] == 0) /* must have 1 char */ + return SCPE_ARG; + val[0] = (((t_value) cptr[1] & 0377) << 8) | + ((t_value) cptr[0] & 0377); + return SCPE_OK; + } + return fparse_sym_cm_w (of, addr, val, uptr, sw); + } +#endif +if (dptr->dwidth < 18) /* 18b decode? */ + return SCPE_ARG; /* no, fail */ + if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* sixbit string? */ if (cptr[0] == 0) /* must have 1 char */ return SCPE_ARG; @@ -1128,8 +1192,16 @@ if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* sixbit string? */ ((t_value) cptr[2] & 077); return SCPE_OK; } -#if defined (PDP15) -if ((sw & SWMASK ('P')) || ((*cptr == '#') && cptr++)) { /* packed string? */ +#if defined (PDP7) || defined (PDP9) +if (sw & SWMASK ('U')) { /* Unix v0 ASCII? */ + if (cptr[0] == 0) /* must have 1 char */ + return SCPE_ARG; + val[0] = (((t_value) cptr[0] & 0177) << 9) | + ((t_value) cptr[1] & 0177); + return SCPE_OK; + } +#elif defined (PDP15) +if (sw & SWMASK ('P')) { /* packed string? */ if (cptr[0] == 0) /* must have 1 char */ return SCPE_ARG; val[0] = (((t_value) cptr[0] & 0177) << 11) | @@ -1140,6 +1212,13 @@ if ((sw & SWMASK ('P')) || ((*cptr == '#') && cptr++)) { /* packed string? */ (((t_value) cptr[4] & 0177) << 1); return -1; } +if (sw & SWMASK ('U')) { /* Unibus ASCII? */ + if (cptr[0] == 0) /* must have 1 char */ + return SCPE_ARG; + val[0] = (((t_value) cptr[1] & 0377) << 8) | + ((t_value) cptr[0] & 0377); + return SCPE_OK; + } #endif cptr = get_glyph (cptr, gbuf, 0); /* get opcode */ @@ -1149,6 +1228,7 @@ if (opcode[i] == NULL) val[0] = opc_val[i] & DMASK; /* get value */ j = (opc_val[i] >> I_V_FL) & I_M_FL; /* get class */ +cflag = (uptr == &cpu_unit); switch (j) { /* case on class */ case I_V_XR: /* index */ diff --git a/PDP18B/pdp18b_tt1.c b/PDP18B/pdp18b_tt1.c index 41cff857..17d37f3e 100644 --- a/PDP18B/pdp18b_tt1.c +++ b/PDP18B/pdp18b_tt1.c @@ -1,6 +1,6 @@ /* pdp18b_ttx.c: PDP-9/15 additional terminals simulator - Copyright (c) 1993-2013, Robert M Supnik + Copyright (c) 1993-2015, 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,7 @@ ttix,ttox LT15/LT19 terminal input/output + 13-Sep-15 RMS Added APIVEC register 11-Oct-13 RMS Poll TTIX immediately to pick up initial connect 18-Apr-12 RMS Revised to use clock coscheduling 19-Nov-08 RMS Revised for common TMXR show routines @@ -63,6 +64,7 @@ TMXR ttx_desc = { 1, 0, 0, ttx_ldsc }; /* mux descriptor */ #define ttx_lines ttx_desc.lines /* current number of lines */ extern int32 int_hwre[API_HLVL+1]; +extern int32 api_vec[API_HLVL][32]; extern int32 tmxr_poll; extern int32 stop_inst; @@ -105,6 +107,9 @@ REG ttix_reg[] = { { FLDATA (INT, int_hwre[API_TTI1], INT_V_TTI1) }, { DRDATA (TIME, ttix_unit.wait, 24), REG_NZ + PV_LEFT }, { ORDATA (DEVNUM, ttix_dib.dev, 6), REG_HRO }, +#if defined (PDP15) + { ORDATA (APIVEC, api_vec[API_TTI1][INT_V_TTI1], 6), REG_HRO }, +#endif { NULL } }; @@ -164,6 +169,9 @@ REG ttox_reg[] = { { FLDATA (INT, int_hwre[API_TTO1], INT_V_TTO1) }, { URDATA (TIME, ttox_unit[0].wait, 10, 24, 0, TTX_MAXL, PV_LEFT) }, +#if defined (PDP15) + { ORDATA (APIVEC, api_vec[API_TTO1][INT_V_TTO1], 6), REG_HRO }, +#endif { NULL } }; diff --git a/Visual Studio Projects/PDP7.vcproj b/Visual Studio Projects/PDP7.vcproj index 4897908a..a82ee620 100644 --- a/Visual Studio Projects/PDP7.vcproj +++ b/Visual Studio Projects/PDP7.vcproj @@ -212,6 +212,10 @@ RelativePath="..\PDP18B\pdp18b_mt.c" > + + diff --git a/doc/pdp18b_doc.doc b/doc/pdp18b_doc.doc index 4ebc50135cf0250394442bc28a8d6aa2ee068bf6..beacda79c02ee7fefdf82b46a04ef4a348fafd7e 100644 GIT binary patch delta 24496 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 delta 25668 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