From 58ed88675f14ae6e5863d163253b7e038b7cf6af Mon Sep 17 00:00:00 2001 From: Lars Brinkhoff Date: Sun, 6 Oct 2019 11:23:06 -0700 Subject: [PATCH] PDP7: Add Type 340 display. --- PDP18B/pdp18b_cpu.c | 12 ++ PDP18B/pdp18b_defs.h | 4 + PDP18B/pdp18b_dpy.c | 217 +++++++++++++++++++++++++++++ PDP18B/pdp18b_sys.c | 14 ++ PDP18B/tests/test340.simh | 27 ++++ Visual Studio Projects/PDP7.vcproj | 28 +++- display/type340.c | 46 +++++- display/type340.h | 6 + makefile | 14 +- 9 files changed, 360 insertions(+), 8 deletions(-) create mode 100644 PDP18B/pdp18b_dpy.c create mode 100644 PDP18B/tests/test340.simh diff --git a/PDP18B/pdp18b_cpu.c b/PDP18B/pdp18b_cpu.c index 43681ad1..7ae54a04 100644 --- a/PDP18B/pdp18b_cpu.c +++ b/PDP18B/pdp18b_cpu.c @@ -1390,6 +1390,18 @@ while (reason == 0) { /* loop until halted */ 700042 ION ION ION ION 700024 undefined undefined undefined LDMM (XVM) 700062 undefined ITON undefined undefined + 700501 undefined IDVE undefined undefined + 700601 undefined IDSI undefined undefined + 700701 undefined IDSP undefined undefined + 701001 undefined IDHE undefined undefined + 700504 undefined IDRS undefined undefined + 700512 undefined IDRA undefined undefined + 700606 undefined IDLA undefined undefined + 700614 undefined IDRD undefined undefined + 700704 undefined IDCF undefined undefined + 700712 undefined IDRC undefined undefined + 701012 undefined IDSC undefined undefined + 701014 undefined IDRP undefined undefined 701701 undefined undefined MPSK MPSK 701741 undefined undefined MPSNE MPSNE 701702 undefined undefined MPCV MPCV diff --git a/PDP18B/pdp18b_defs.h b/PDP18B/pdp18b_defs.h index a95d28e4..1122860b 100644 --- a/PDP18B/pdp18b_defs.h +++ b/PDP18B/pdp18b_defs.h @@ -149,6 +149,9 @@ #define DRM 0 /* drum */ #define RB 0 /* fixed head disk */ #define GRAPHICS2 0 /* BTL display */ +#ifdef USE_DISPLAY +#define TYPE340 0 /* Type 340 display */ +#endif #elif defined (PDP9) #define ADDRSIZE 15 #define TYPE647 0 /* sixbit printer */ @@ -284,6 +287,7 @@ typedef struct { #define DEV_PTP 002 /* paper tape punch */ #define DEV_TTI 003 /* console input */ #define DEV_TTO 004 /* console output */ +#define DEV_DPY 005 /* Type 340 */ #define DEV_TTI1 041 /* extra terminals */ #define DEV_TTO1 040 #define DEV_DRM 060 /* drum */ diff --git a/PDP18B/pdp18b_dpy.c b/PDP18B/pdp18b_dpy.c new file mode 100644 index 00000000..2f52a3b1 --- /dev/null +++ b/PDP18B/pdp18b_dpy.c @@ -0,0 +1,217 @@ +/* pdp18b_dpy.c: PDP-7 Type 340 interface + + Copyright (c) 2019, Lars Brinkhoff + + 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 + LARS BRINKHOFF 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 Lars Brinkhoff shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Lars Brinkhoff. + + dpy (PDP-7) Type 340 Precision Incremental CRT Display, with + Type 341 Interface, Type 347 Subroutine Interface, + and Type 342 Symbol Generator. +*/ + + +#include "pdp18b_defs.h" + +#if defined(TYPE340) +#include "display/type340.h" +#include "display/display.h" + +#define DBG_IOT 001 /* IOT instructions. */ +#define DBG_IRQ 002 /* Interrupts. */ +#define DBG_INS 004 /* 340 instructions. */ + +/* + * Number of microseconds between svc calls. Used to age display and + * poll for WS events. + */ +#define DPY_CYCLE_US 100 + +int32 dpy05 (int32 dev, int32 pulse, int32 dat); +int32 dpy06 (int32 dev, int32 pulse, int32 dat); +int32 dpy07 (int32 dev, int32 pulse, int32 dat); +int32 dpy10 (int32 dev, int32 pulse, int32 dat); +int32 dpy_iors (void); +t_stat dpy_svc (UNIT *uptr); +t_stat dpy_reset (DEVICE *dptr); + +DIB dpy_dib = { DEV_DPY, 4, &dpy_iors, { &dpy05, &dpy06, &dpy07, &dpy10 } }; + +UNIT dpy_unit[] = { + { UDATA (&dpy_svc, 0, 0) }, +}; + +DEBTAB dpy_deb[] = { + { "IOT", DBG_IOT }, + { "IRQ", DBG_IRQ }, + { "INS", DBG_INS }, + { NULL, 0 } + }; + +DEVICE dpy_dev = { + "DPY", dpy_unit, NULL, NULL, + 1, 8, 12, 1, 8, 18, + NULL, NULL, &dpy_reset, + NULL, NULL, NULL, + &dpy_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG, 0, + dpy_deb, NULL, NULL + }; + +t_stat dpy_svc (UNIT *uptr) +{ + sim_activate_after(uptr, DPY_CYCLE_US); + display_age(DPY_CYCLE_US, 0); + ty340_cycle(); + return SCPE_OK; +} + +ty340word ty340_fetch(ty340word addr) +{ + extern int32 *M; + return (ty340word)M[addr]; +} + +t_stat dpy_reset (DEVICE *dptr) +{ + if (!(dptr->flags & DEV_DIS)) { + display_reset(); + ty340_reset(dptr); + } + sim_cancel (&dpy_unit[0]); + return SCPE_OK; +} + +void +cpu_get_switches(unsigned long *p1, unsigned long *p2) +{ +} + +void +cpu_set_switches(unsigned long w1, unsigned long w2) +{ +} + +void +ty340_lp_int(ty340word x, ty340word y) +{ +} + +void +ty340_rfd(void) +{ +} + +int32 dpy_iors (void) +{ +#if defined IOS_LPEN + return IOS_LPEN; +#else + return 0; +#endif +} + +int32 dpy05 (int32 dev, int32 pulse, int32 dat) +{ + sim_debug(DBG_IOT, &dpy_dev, "7005%02o, %06o\n", pulse, dat); + + if (pulse & 001) { + if (ty340_sense(ST340_VEDGE)) + dat |= IOT_SKP; + } + + if (pulse & 002) { + dat |= ty340_get_dac(); + } + + if (pulse & 004) { + ty340_clear (ST340_LPHIT); + sim_activate_abs (dpy_unit, 0); + } + + return dat; +} + +int32 dpy06 (int32 dev, int32 pulse, int32 dat) +{ + sim_debug(DBG_IOT, &dpy_dev, "7006%02o, %06o\n", pulse, dat); + + if (pulse & 001) { + if (ty340_sense(ST340_STOPPED)) + dat |= IOT_SKP; + } + + if (pulse & 002) { + ty340_set_dac (0); + } + + if (pulse & 004) { + if ((pulse & 010) == 0) + ty340_set_dac (dat & 07777); + ty340_clear (ST340_STOPPED|ST340_STOP_INT); + sim_activate_abs (dpy_unit, 0); + } + + return dat; +} + +int32 dpy07 (int32 dev, int32 pulse, int32 dat) +{ + sim_debug(DBG_IOT, &dpy_dev, "7007%02o, %06o\n", pulse, dat); + + if (pulse & 001) { + if (ty340_sense(ST340_LPHIT)) + dat |= IOT_SKP; + } + + if (pulse & 002) { + dat |= 0; // X, Y + } + + if (pulse & 004) { + ty340_clear(~0); + } + + return dat; +} + +int32 dpy10 (int32 dev, int32 pulse, int32 dat) +{ + sim_debug(DBG_IOT, &dpy_dev, "7010%02o, %06o\n", pulse, dat); + + if (pulse & 001) { + if (ty340_sense(ST340_HEDGE)) + dat |= IOT_SKP; + } + + if (pulse & 002) { + dat |= ty340_get_asr(); + } + + if (pulse & 004) { + dat |= 0; // Light pen. + } + + return dat; +} + +#else /* !TYPE340 */ +char pdp18b_dpy_unused; /* sometimes empty object modules cause problems */ +#endif /* !TYPE340 */ diff --git a/PDP18B/pdp18b_sys.c b/PDP18B/pdp18b_sys.c index b611843d..a4b01321 100644 --- a/PDP18B/pdp18b_sys.c +++ b/PDP18B/pdp18b_sys.c @@ -108,6 +108,9 @@ extern DEVICE dr15_dev; #if defined (GRAPHICS2) extern DEVICE g2out_dev, g2in_dev; #endif +#if defined (TYPE340) +extern DEVICE dpy_dev; +#endif extern UNIT cpu_unit; extern REG cpu_reg[]; extern int32 *M; @@ -184,6 +187,9 @@ DEVICE *sim_devices[] = { #endif #if defined (GRAPHICS2) &g2out_dev, &g2in_dev, +#endif +#if defined (TYPE340) + &dpy_dev, #endif NULL }; @@ -460,6 +466,10 @@ static const char *opcode[] = { "PSF", "PCF", "PSA", "PSB", "PLS", "KSF", "KRB", "KCF", "IORS", "IOOS", "TSF", "TCF", "TPC", "TLS", + "IDVE", "IDRA", "IDRS", "IDRA", + "IDSI", "IDCA", "IDRD", "IDLA", "IDRD", + "IDSP", "IDRC", "IDCF", "IDRC", + "IDHE", "IDSC", "IDRP", "IDSC", "IDRP", #if defined (TYPE62) /* Type 62 */ "LPSF", "LPCF", "LPLD", "LPSE", "LSSF", "LSCF", "LSPR", @@ -699,6 +709,10 @@ static const int32 opc_val[] = { 0700201+I_NPI, 0700202+I_NPI, 0700204+I_NPI, 0700244+I_NPI, 0700206+I_NPI, 0700301+I_NPI, 0700312+I_NPN, 0700302+I_NPI, 0700314+I_NPN, 0700304+I_NPI, 0700401+I_NPI, 0700402+I_NPI, 0700404+I_NPI, 0700406+I_NPI, + 0700501+I_NPI, 0700502+I_NPI, 0700504+I_NPI, 0700512+I_NPI, + 0700601+I_NPI, 0700602+I_NPI, 0700604+I_NPI, 0700606+I_NPI, 0700614+I_NPI, + 0700701+I_NPI, 0700702+I_NPI, 0700704+I_NPI, 0700712+I_NPI, + 0701001+I_NPI, 0701002+I_NPI, 0701004+I_NPI, 0701012+I_NPI, 0701014+I_NPI, #if defined (TYPE62) 0706501+I_NPI, 0706502+I_NPI, 0706542+I_NPI, 0706506+I_NPI, 0706601+I_NPI, 0706602+I_NPI, 0706606+I_NPI, diff --git a/PDP18B/tests/test340.simh b/PDP18B/tests/test340.simh new file mode 100644 index 00000000..55e1ff90 --- /dev/null +++ b/PDP18B/tests/test340.simh @@ -0,0 +1,27 @@ +set g2out disabled + +set debug stdout +set dpy enabled +set dpy debug + +# Small test program. +dep -m 100 law 1000 +dep -m 101 idla +dep -m 102 idsi +dep -m 103 jmp 102 +dep -m 104 jmp 100 + +# Small display list. +#Go to point mode, set scale, set intensity. +dep 1000 020117 +#Stay in point mode, set x=1000. +dep 1001 021000 +#Go to vector mode, set y=1000. +dep 1002 301000 +#Escape, intensify, delta x=100. +dep 1003 600100 +#Stop. +dep 1004 003000 + +dep pc 100 +# Ready to go or single step. diff --git a/Visual Studio Projects/PDP7.vcproj b/Visual Studio Projects/PDP7.vcproj index b809f8d5..84ce040f 100644 --- a/Visual Studio Projects/PDP7.vcproj +++ b/Visual Studio Projects/PDP7.vcproj @@ -41,7 +41,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../PDP18B/;./;../;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include;../../windows-build/include;;../../windows-build/include/SDL2" - PreprocessorDefinitions="PDP7;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC" + PreprocessorDefinitions="PDP7;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;USE_DISPLAY;USE_SIM_VIDEO;HAVE_LIBSDL;HAVE_LIBPNG" KeepComments="false" BasicRuntimeChecks="0" RuntimeLibrary="1" @@ -125,7 +125,7 @@ OmitFramePointers="true" WholeProgramOptimization="true" AdditionalIncludeDirectories="../PDP18B/;./;../;../slirp;../slirp_glue;../slirp_glue/qemu;../slirp_glue/qemu/win32/include;../../windows-build/include;;../../windows-build/include/SDL2" - PreprocessorDefinitions="PDP7;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC" + PreprocessorDefinitions="PDP7;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;USE_DISPLAY;USE_SIM_VIDEO;HAVE_LIBSDL;HAVE_LIBPNG" StringPooling="true" RuntimeLibrary="0" EnableFunctionLevelLinking="true" @@ -191,10 +191,18 @@ Name="Source Files" Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" > + + + + @@ -287,11 +295,23 @@ RelativePath="..\sim_video.c" > + + + + + + @@ -348,6 +368,10 @@ RelativePath="..\sim_video.h" > + + status = 0; /* XXX just clear stopped? */ ty340_rfd(); /* ready for data */ } + +void +ty340_cycle(void) +{ + struct type340 *u = UNIT(0); + + if (u->status == 0) { + ty340word insn = ty340_fetch(u->DAC); + u->status = ty340_instruction (insn); + u->DAC = (u->DAC + 1) & 07777; + } +} + +ty340word +ty340_get_dac(void) +{ + struct type340 *u = UNIT(0); + return u->DAC; +} + +ty340word +ty340_get_asr(void) +{ +#if TYPE347 + struct type340 *u = UNIT(0); + return u->ASR; +#else + return 0; #endif +} + +ty340word +ty340_sense(ty340word flags) +{ + struct type340 *u = UNIT(0); + return u->status & flags; +} + +void +ty340_clear(ty340word flags) +{ + struct type340 *u = UNIT(0); + u->status &= ~flags; +} ty340word ty340_reset(void *dptr) diff --git a/display/type340.h b/display/type340.h index 1c39dc1a..5caf06d6 100644 --- a/display/type340.h +++ b/display/type340.h @@ -49,7 +49,13 @@ typedef unsigned int ty340word; ty340word ty340_reset(void *); ty340word ty340_status(void); ty340word ty340_instruction(ty340word inst); +ty340word ty340_get_dac(void); +ty340word ty340_get_asr(void); +ty340word ty340_sense(ty340word); void ty340_set_dac(ty340word addr); +void ty340_clear(ty340word addr); +void ty340_cycle(void); +void ty340_set_status(ty340word); void ty342_set_grid(int, int); /* diff --git a/makefile b/makefile index 8b30f740..18a890f2 100644 --- a/makefile +++ b/makefile @@ -114,6 +114,10 @@ endif ifneq (,$(or $(findstring pdp10-ka,$(MAKECMDGOALS)),$(findstring pdp10-ki,$(MAKECMDGOALS)))) NETWORK_USEFUL = true endif +# building the PDP-7 needs video support +ifneq (,$(findstring pdp7,$(MAKECMDGOALS))) + VIDEO_USEFUL = true +endif # building the pdp11, pdp10, or any vax simulator could use networking support ifneq (,$(or $(findstring pdp11,$(MAKECMDGOALS)),$(findstring pdp10,$(MAKECMDGOALS)),$(findstring vax,$(MAKECMDGOALS)),$(findstring 3b2,$(MAKECMDGOALS))$(findstring all,$(MAKECMDGOALS)))) NETWORK_USEFUL = true @@ -1283,8 +1287,12 @@ PDP18B = ${PDP18BD}/pdp18b_dt.c ${PDP18BD}/pdp18b_drm.c ${PDP18BD}/pdp18b_cpu.c ${PDP18BD}/pdp18b_rb.c ${PDP18BD}/pdp18b_tt1.c ${PDP18BD}/pdp18b_fpp.c \ ${PDP18BD}/pdp18b_g2tty.c ${PDP18BD}/pdp18b_dr15.c +ifneq (,$(DISPLAY_OPT)) + PDP7_DISPLAY_OPT = -DDISPLAY_TYPE=DIS_TYPE30 -DPIX_SCALE=RES_HALF +endif + PDP4_OPT = -DPDP4 -I ${PDP18BD} -PDP7_OPT = -DPDP7 -I ${PDP18BD} +PDP7_OPT = -DPDP7 -I ${PDP18BD} $(DISPLAY_OPT) $(PDP7_DISPLAY_OPT) PDP9_OPT = -DPDP9 -I ${PDP18BD} PDP15_OPT = -DPDP15 -I ${PDP18BD} @@ -2062,9 +2070,9 @@ endif pdp7 : ${BIN}pdp7${EXE} -${BIN}pdp7${EXE} : ${PDP18B} ${SIM} +${BIN}pdp7${EXE} : ${PDP18B} ${PDP18BD}/pdp18b_dpy.c ${DISPLAYL} $(DISPLAY340) ${SIM} ${MKDIRBIN} - ${CC} ${PDP18B} ${SIM} ${PDP7_OPT} $(CC_OUTSPEC) ${LDFLAGS} + ${CC} ${PDP18B} ${PDP18BD}/pdp18b_dpy.c ${DISPLAYL} $(DISPLAY340) ${SIM} ${PDP7_OPT} $(CC_OUTSPEC) ${LDFLAGS} ifneq (,$(call find_test,${PDP18BD},pdp7)) $@ $(call find_test,${PDP18BD},pdp7) $(TEST_ARG) endif