From 5aa8454ab5a94096ba2463f29147c1ca66a45b85 Mon Sep 17 00:00:00 2001 From: Lars Brinkhoff Date: Thu, 7 Feb 2019 08:16:31 +0100 Subject: [PATCH] PDP11: NG, Knight display. --- PDP11/pdp11_ch.c | 9 ++ PDP11/pdp11_defs.h | 3 + PDP11/pdp11_io_lib.c | 2 + PDP11/pdp11_ng.c | 296 +++++++++++++++++++++++++++++++++++++ PDP11/pdp11_sys.c | 2 + PDP11/pdp11_vt.c | 8 + display/display.c | 16 +- display/display.h | 3 +- display/ng.c | 340 +++++++++++++++++++++++++++++++++++++++++++ display/ng.h | 64 ++++++++ makefile | 5 +- 11 files changed, 745 insertions(+), 3 deletions(-) create mode 100644 PDP11/pdp11_ng.c create mode 100644 display/ng.c create mode 100644 display/ng.h diff --git a/PDP11/pdp11_ch.c b/PDP11/pdp11_ch.c index c0aa1e76..586b124d 100644 --- a/PDP11/pdp11_ch.c +++ b/PDP11/pdp11_ch.c @@ -442,6 +442,15 @@ t_stat ch_detach (UNIT *uptr) t_stat ch_reset (DEVICE *dptr) { + DEVICE *ng_dptr = find_dev ("NG"); + + if ((ng_dptr != NULL) && + !(ng_dptr->flags & DEV_DIS) && + !(dptr->flags & DEV_DIS)) { + dptr->flags |= DEV_DIS; + return sim_messagef (SCPE_ALATT, "CH device in conflict with NG.\n"); + } + ch_clear (); return auto_config (dptr->name, (dptr->flags & DEV_DIS)? 0 : 1); /* auto config */ } diff --git a/PDP11/pdp11_defs.h b/PDP11/pdp11_defs.h index fb0a86f0..d5559427 100644 --- a/PDP11/pdp11_defs.h +++ b/PDP11/pdp11_defs.h @@ -632,6 +632,7 @@ typedef struct pdp_dib DIB; #define INT_V_KMCB 24 #define INT_V_UCB 25 #define INT_V_CH 26 +#define INT_V_NG 27 #define INT_V_PIR4 0 /* BR4 */ #define INT_V_TTI 1 @@ -718,6 +719,7 @@ typedef struct pdp_dib DIB; #define INT_TDRX (1u << INT_V_TDRX) #define INT_TDTX (1u << INT_V_TDTX) #define INT_CH (1u << INT_V_CH) +#define INT_NG (1u << INT_V_NG) #define INT_INTERNAL7 (INT_PIR7) #define INT_INTERNAL6 (INT_PIR6 | INT_CLK) @@ -759,6 +761,7 @@ typedef struct pdp_dib DIB; #define IPL_DUPRX 5 #define IPL_DUPTX 5 #define IPL_UCA 5 +#define IPL_NG 5 #define IPL_PTR 4 #define IPL_PTP 4 #define IPL_TTI 4 diff --git a/PDP11/pdp11_io_lib.c b/PDP11/pdp11_io_lib.c index 8ca3b9c7..5ab21328 100644 --- a/PDP11/pdp11_io_lib.c +++ b/PDP11/pdp11_io_lib.c @@ -779,6 +779,8 @@ AUTO_CON auto_tab[] = {/*c #v am vm fxa fxv */ { { NULL }, 1, 1, 64, 4 }, /* QZA */ { { "CH" }, 1, 1, 0, 0, {04140}, {0270} }, /* CH11 - CHAOS Net - fx CSR, fx VEC */ + { { "NG" }, 1, 1, 0, 0, + {04040}, {0270} }, /* NG - vector display */ { { NULL }, -1 } /* end table */ }; diff --git a/PDP11/pdp11_ng.c b/PDP11/pdp11_ng.c new file mode 100644 index 00000000..643fa112 --- /dev/null +++ b/PDP11/pdp11_ng.c @@ -0,0 +1,296 @@ +#ifdef USE_DISPLAY +/* pdp11_ng.c: NG, Knight vector display + + Copyright (c) 2018, 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 + THE AUTHORS 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 names of the authors shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from the authors. +*/ + +#include "pdp11_defs.h" +#include "display/display.h" +#include "display/ng.h" +#include "sim_video.h" + +/* Run a NG cycle every this many PDP-11 "cycle" times. */ +#define NG_DELAY 1 + +/* Memory cycle time. */ +#define MEMORY_CYCLE 1 + +#define CYCLE_US (MEMORY_CYCLE*(NG_DELAY*2+1)) + +t_stat ng_rd(int32 *data, int32 PA, int32 access); +t_stat ng_wr(int32 data, int32 PA, int32 access); +t_stat ng_svc(UNIT *uptr); +t_stat ng_reset(DEVICE *dptr); +t_stat ng_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat ng_show_type(FILE *st, UNIT *uptr, int32 val, CONST void *desc); +t_stat ng_set_scale(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat ng_show_scale(FILE *st, UNIT *uptr, int32 val, CONST void *desc); +t_stat ng_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); +const char *ng_description (DEVICE *dptr); + +#define IOLN_NG 4 +DIB ng_dib = { + IOBA_AUTO, IOLN_NG, &ng_rd, &ng_wr, + 4, IVCL(NG), VEC_AUTO, {NULL}, IOLN_NG +}; + +UNIT ng_unit = { + UDATA (&ng_svc, 0, 0), NG_DELAY +}; + +REG ng_reg[] = { + { DRDATAD (CYCLE, ng_unit.wait, 24, "NG cycle"), REG_NZ + PV_LEFT }, + { GRDATAD(TYPE, ng_type, 16, 16, 0, "Hardware type"), REG_FIT}, + { GRDATAD(SCALE, ng_scale, 16, 16, 0, "Hardware type"), REG_FIT}, + { NULL } +}; + +MTAB ng_mod[] = { + { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "TYPE", "TYPE={DAZZLE|LOGO}", + &ng_set_type, &ng_show_type, NULL, "Hardware Type" }, + { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "SCALE", "SCALE={1|2|4|8}", + &ng_set_scale, &ng_show_scale, NULL, "Pixel Scale Factor" }, + { MTAB_XTD|MTAB_VDV|MTAB_VALR, 020, "ADDRESS", "ADDRESS", + &set_addr, &show_addr, NULL, "Bus address" }, + { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "VECTOR", "VECTOR", + &set_vec, &show_vec, NULL, "Interrupt vector" }, + { MTAB_XTD|MTAB_VDV, 0, NULL, "AUTOCONFIGURE", + &set_addr_flt, NULL, NULL, "Enable autoconfiguration of address & vector" }, + { 0 } }; + + +static t_bool ng_stop_flag = FALSE; +static t_bool ng_inited = FALSE; + +static void ng_quit_callback (void) +{ + ng_stop_flag = TRUE; +} + +/* Debug detail levels */ + +#define DEB_TRC 0001 +#define DEB_INT 0002 + +DEBTAB ng_deb[] = { + { "TRC", DEB_TRC, "trace" }, + { "INT", DEB_INT, "interrupts" }, + { NULL, 0 } +}; + +DEVICE ng_dev = { + "NG", &ng_unit, ng_reg, ng_mod, + 1, 8, 16, 1, 8, 16, + NULL, NULL, &ng_reset, + NULL, NULL, NULL, + &ng_dib, DEV_DIS | DEV_DISABLE | DEV_UBUS | DEV_DEBUG, + 0, ng_deb, NULL, NULL, NULL, &ng_help, NULL, + &ng_description +}; + +const char *ng_regnam[] = { + "CSR", + "REL", +}; + +t_stat +ng_rd(int32 *data, int32 PA, int32 access) +{ + t_stat stat = SCPE_OK; + + switch (PA & 002) { + case 000: *data = ng_get_csr(); break; + case 002: *data = ng_get_reloc(); break; + default: stat = SCPE_NXM; + } + return stat; +} + +t_stat +ng_wr(int32 data, int32 PA, int32 access) +{ + switch (PA & 002) { + case 000: ng_set_csr(data); return SCPE_OK; + case 002: ng_set_reloc(data); return SCPE_OK; + } + return SCPE_NXM; +} + +t_stat +ng_svc(UNIT *uptr) +{ + if (ng_cycle(uptr->wait, 0)) + sim_activate_after (uptr, uptr->wait); + if (ng_stop_flag) { + ng_stop_flag = FALSE; + return SCPE_STOP; + } + return SCPE_OK; +} + +t_stat +ng_reset(DEVICE *dptr) +{ + DEVICE *dptr2; + t_stat r; + + if (dptr->flags & DEV_DIS) { + sim_cancel (dptr->units); + return auto_config ("NG", (dptr->flags & DEV_DIS) ? 0 : 1);; + } + + dptr2 = find_dev ("VT"); + if ((dptr2 != NULL) && !(dptr2->flags & DEV_DIS)) { + dptr->flags |= DEV_DIS; + return sim_messagef (SCPE_NOFNC, "NG and VT device can't both be enabled\n"); + } + dptr2 = find_dev ("CH"); + if ((dptr2 != NULL) && !(dptr2->flags & DEV_DIS)) { + dptr->flags |= DEV_DIS; + return sim_messagef (SCPE_ALATT, "NG device in conflict with CH.\n"); + } + + r = auto_config ("NG", (dptr->flags & DEV_DIS) ? 0 : 1);; + if (r != SCPE_OK) { + dptr->flags |= DEV_DIS; + return r; + } + + if (!ng_inited && !ng_init(dptr, DEB_TRC)) + return sim_messagef (SCPE_ALATT, "Display already in use.\n"); + ng_inited = TRUE; + + CLR_INT (NG); + ng_unit.wait = 100; + sim_activate (dptr->units, 1); + + set_cmd (0, "DZ DISABLED"); /* Conflict with NG. */ + set_cmd (0, "HK DISABLED"); /* Conflict with RF. */ + + vid_register_quit_callback (&ng_quit_callback); + + return SCPE_OK; +} + +t_stat +ng_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + //if ((uptr->flags & DEV_DIS) == 0) + //return SCPE_ALATT; + if (strcasecmp (cptr, "dazzle") == 0) + ng_type = TYPE_DAZZLE; + else if (strcasecmp (cptr, "logo") == 0) + ng_type = TYPE_LOGO; + else + return SCPE_ARG; + return SCPE_OK; +} + +t_stat +ng_show_type(FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + if (ng_type == TYPE_DAZZLE) + fprintf(st, "type=DAZZLE"); + else if (ng_type == TYPE_LOGO) + fprintf(st, "type=LOGO"); + else + fprintf(st, "type=unknown"); + return SCPE_OK; +} + +t_stat +ng_set_scale(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + t_stat r; + t_value v; + if ((uptr->flags & UNIT_DIS) == 0) + return SCPE_ALATT; + if (cptr == NULL) + return SCPE_ARG; + v = get_uint(cptr, 10, 8, &r); + if (r != SCPE_OK) + return r; + if (v != 1 && v != 2 && v != 4 && v != 8) + return SCPE_ARG; + ng_scale = v; + return SCPE_OK; +} + +t_stat +ng_show_scale(FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + fprintf(st, "scale=%d", (int)ng_scale); + return SCPE_OK; +} + +void +ng_nxm_intr(void) +{ + sim_debug (DEB_INT, &ng_dev, "NXM interrup\n"); + SET_INT (NG); +} + +int +ng_store(uint32 addr, uint16 x) +{ + uint16 word = x; + if (Map_WriteW(addr, 2, &word) == 0) + return 0; + return 1; +} + +int +ng_fetch(uint32 addr, uint16 *wp) +{ + if (Map_ReadW(addr, 2, wp) == 0) + return 0; + *wp = 0; + return 1; +} + +const char *ng_description (DEVICE *dptr) +{ + return "Vector display controller for MIT Logo PDP-11/45"; +} + +t_stat ng_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + /* The '*'s in the next line represent the standard text width of a help line */ + /****************************************************************************/ + fprintf(st, "%s\n\n", ng_description (dptr)); + fprintf(st, "The NG is a Unibus device which can control up to eight XY displays.\n"); + fprintf(st, "This simulation only supports one, which is also what the available\n"); + fprintf(st, "software uses. Configurable options are TYPE and SCALE.\n\n"); + fprintf(st, "To select the hardware type compatible with Dazzle Dart, type\n\n"); + fprintf(st, " sim> SET NG TYPE=DAZZLE\n\n"); + fprintf(st, "To select the hardware type compatible with Logo, type\n\n"); + fprintf(st, " sim> SET NG TYPE=LOGO\n\n"); + fprintf(st, "Set SCALE to one of 1, 2, 3, or 4 to select full size, half size,\n"); + fprintf(st, "quarter size, or eighth size.\n\n"); + + return SCPE_OK; +} +#else /* USE_DISPLAY not defined */ +char pdp11_ng_unused; /* sometimes empty object modules cause problems */ +#endif /* USE_DISPLAY not defined */ diff --git a/PDP11/pdp11_sys.c b/PDP11/pdp11_sys.c index 8d791ba9..40581e73 100644 --- a/PDP11/pdp11_sys.c +++ b/PDP11/pdp11_sys.c @@ -118,6 +118,7 @@ extern DEVICE kmc_dev; extern DEVICE uca_dev, ucb_dev; extern DEVICE rom_dev; extern DEVICE ch_dev; +extern DEVICE ng_dev; extern REG cpu_reg[]; extern int32 saved_PC; @@ -197,6 +198,7 @@ DEVICE *sim_devices[] = { &ke_dev, &rom_dev, &ch_dev, + &ng_dev, #else &clk_dev, &tti_dev, diff --git a/PDP11/pdp11_vt.c b/PDP11/pdp11_vt.c index 481176ae..88d36373 100644 --- a/PDP11/pdp11_vt.c +++ b/PDP11/pdp11_vt.c @@ -323,6 +323,14 @@ vt_svc(UNIT *uptr) t_stat vt_reset(DEVICE *dptr) { + DEVICE *ng_dptr; + + ng_dptr = find_dev ("NG"); + if (!(dptr->flags & DEV_DIS) && + (ng_dptr != NULL) && !(ng_dptr->flags & DEV_DIS)) { + dptr->flags |= DEV_DIS; + return sim_messagef (SCPE_NOFNC, "VT and NG device can't both be enabled\n"); + } if (!(dptr->flags & DEV_DIS)) vt11_reset(dptr, DEB_VT11); vid_register_quit_callback (&vt_quit_callback); diff --git a/display/display.c b/display/display.c index 81813e90..94bf86c4 100644 --- a/display/display.c +++ b/display/display.c @@ -123,6 +123,10 @@ static struct color color_p7 = { p7, ELEMENTS(p7), 125000 }; static struct phosphor p29[] = {{0.0260, 1.0, 0.00121, 0.5, 0.025}}; struct color color_p29 = { p29, ELEMENTS(p29), 25000 }; +/* green phosphor for Tek 611 */ +static struct phosphor p31[] = {{0.0, 1.0, 0.77, 0.5, .1}}; +struct color color_p31 = { p31, ELEMENTS(p31), 25000 }; + static struct phosphor p40[] = { /* P40 blue-white spot with yellow-green decay (.045s to 10%?) */ {0.4, 0.2, 0.924, 0.5, 0.0135}, @@ -227,7 +231,17 @@ static struct display displays[] = { * 0,0 at lower left * 8 intensity levels */ - { DIS_TYPE340, "Type 340", &color_p7, NULL, 1024, 1024 } + { DIS_TYPE340, "Type 340", &color_p7, NULL, 1024, 1024 }, + + /* + * NG display + * on PDP-11/45 + * + * Tektronix 611 + * 512x512, out of 800x600 + * 0,0 at middle + */ + { DIS_NG, "NG Display", &color_p31, NULL, 512, 512 } }; /* diff --git a/display/display.h b/display/display.h index 345102cb..0470f465 100644 --- a/display/display.h +++ b/display/display.h @@ -47,7 +47,8 @@ enum display_type { DIS_VR20 = 20, DIS_TYPE30 = 30, DIS_VR48 = 48, - DIS_TYPE340 = 340 + DIS_TYPE340 = 340, + DIS_NG = 999, }; /* diff --git a/display/ng.c b/display/ng.c new file mode 100644 index 00000000..5ffde512 --- /dev/null +++ b/display/ng.c @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2018 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 + * THE AUTHORS 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 names of the authors shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization + * from the authors. + */ + +#include "display.h" /* XY plot interface */ +#include "ng.h" + + +/* Bits in the CSR register, type Dazzle. */ +#define TKRUN 004000 +#define TKGO 010000 +#define TKSTOP 020000 + + +static void *ng_dptr; +static int ng_dbit; + +#define DEVICE void +extern void _sim_debug_device (unsigned int dbits, DEVICE* dptr, const char* fmt, ...); + +#define DEBUGF(...) _sim_debug_device (ng_dbit, ng_dptr, ## __VA_ARGS__) + +int ng_type = 0; +int ng_scale = PIX_SCALE; + +static uint16 status = 0; +static int reloc = 0; +static int console = 0; +static int dpc[8]; +static int x[8]; +static int y[8]; + +static unsigned char sync_period = 0; +static unsigned char time_out = 0; + +int32 +ng_get_csr(void) +{ + if (ng_type == TYPE_DAZZLE) { + DEBUGF("[%d] Get CSR: ", 0); + if (status & TKRUN) + DEBUGF("running\n"); + else + DEBUGF("stopped\n"); + } else if (ng_type == TYPE_LOGO) { + DEBUGF("Get CSR: %06o\n", status); + } + return status; +} + +int32 +ng_get_reloc(void) +{ + return reloc & 0177777; +} + +void +ng_set_csr(uint16 d) +{ + if (ng_type == TYPE_DAZZLE) { + console = d & 0377; + + if (d & TKGO) { + DEBUGF("[%d] Set CSR: GO\n", console); + if ((status & TKRUN) == 0) + dpc[console] = 2*console; + status |= TKRUN; + } + if (d & TKSTOP) { + DEBUGF("[%d] Set CSR: STOP\n", console); + status &= ~TKRUN; + } + } else if (ng_type == TYPE_LOGO) { + DEBUGF("Set CSR: %06o\n", d); + if ((status & 1) == 0 && (d & 1)) + dpc[0] = 2*0; + status = d; + } +} + +void +ng_set_reloc(uint16 d) +{ + reloc = d; + DEBUGF("Set REL: %06o\n", d); +} + +int +ng_init(void *dev, int debug) +{ + ng_dptr = dev; + ng_dbit = debug; + return display_init(DIS_NG, ng_scale, ng_dptr); +} + +static int fetch (int a, uint16 *x) +{ + return ng_fetch (a + reloc, x); +} + +static int store (int a, uint16 x) +{ + return ng_store (a + reloc, x); +} + +static void point (void) +{ + int x1 = x[console]; + int y1 = y[console]; + + DEBUGF("[%d] POINT %d %d\n", console, x[console], y[console]); + display_point(x1 + 256, y1 + 256, DISPLAY_INT_MAX, 0); +} + +void increment (uint16 inst) +{ + int n = (inst >> 8) & 7; + int i, mask; + + if (n == 0) + n = 8; + + DEBUGF("[%d] Increment %d, direction %d, bits %o\n", + console, n, (inst >> 11) & 7, inst & 0377); + + mask = 0200; + if (ng_type == TYPE_DAZZLE) + mask = 0200 >> (8 - n); + + for (i = 0; i < n; i++, mask >>= 1) { + switch (inst & 034000) { + case 000000: + if (inst & mask) + x[console]++; + y[console]++; + break; + case 004000: + if (inst & mask) + y[console]++; + x[console]++; + break; + case 010000: + if (inst & mask) + y[console]--; + x[console]++; + break; + case 014000: + if (inst & mask) + x[console]++; + y[console]--; + break; + case 020000: + if (inst & mask) + x[console]--; + y[console]--; + break; + case 024000: + if (inst & mask) + y[console]--; + x[console]--; + break; + case 030000: + if (inst & mask) + y[console]++; + x[console]--; + break; + case 034000: + if (inst & mask) + x[console]--; + y[console]++; + break; + } + point (); + } +} + +void pushj (uint16 inst) +{ + uint16 a; + fetch (16 + 2*console, &a); + store (16 + 2*console, a + 1); + store (2*a, dpc[console]); + DEBUGF("[%d] PUSHJ %06o -> %06o (%06o->%06o)\n", + console, dpc[console], inst << 1, a, a+1); + dpc[console] = inst << 1; +} + +void stop (void) +{ + DEBUGF("[%d] STOP\n", console); + if (ng_type == TYPE_DAZZLE) + status &= ~TKRUN; + else if (ng_type == TYPE_LOGO) + dpc[0] = 2*0; +} + +uint16 pop (void) +{ + uint16 a; + fetch (16 + 2*console, &a); + store (16 + 2*console, a - 1); + DEBUGF("[%d] POP (%06o -> %06o)\n", console, a, a - 1); + return a - 1; +} + +void popj (void) +{ + uint16 a, x; + a = pop (); + fetch (2*a, &x); + DEBUGF("[%d] POPJ %06o -> %06o\n", console, dpc[console], x); + dpc[console] = x; +} + +void resetx (void) +{ + DEBUGF("[%d] RESET X\n", console); + x[console] = 0; +} + +void resety (void) +{ + DEBUGF("[%d] RESET Y\n", console); + y[console] = 0; +} + +void delta (uint16 inst) +{ + int delta = inst & 01777; + + if (inst & 01000) + delta |= -1 << 10; + + switch (inst & 014000) { + case 000000: + if (inst & 02000) + resetx (); + if (inst & 01000) + resety (); + if (inst & 00400) + stop (); + if (inst & 00200) + pop (); + if (inst & 00100) + popj (); + return; + case 004000: + y[console] += delta; + break; + case 010000: + x[console] += delta; + break; + case 014000: + x[console] += delta; + y[console] += delta; + break; + } + + DEBUGF("[%d] DELTA %d\n", console, delta); + + if (inst & 02000) { + point (); + } +} + +int +ng_cycle(int us, int slowdown) +{ + uint16 inst; + static uint32 usec = 0; + static uint32 msec = 0; + uint32 new_msec; + + new_msec = (usec += us) / 1000; + + /* if awaiting sync, look for next frame start */ + if (sync_period && (msec / sync_period != new_msec / sync_period)) + sync_period = 0; /* start next frame */ + + msec = new_msec; + + if (ng_type == TYPE_DAZZLE) { + if ((status & TKRUN) == 0) + goto age_ret; + } else if (ng_type == TYPE_LOGO) { + DEBUGF("STATUS %06o\n", status); + if ((status & 1) == 0) + goto age_ret; + } else + return 1; + + if (sync_period) + goto age_ret; + + for (console = 0; console < 1; console++) { + time_out = fetch(dpc[console], &inst); + DEBUGF("[%d] PC %06o, INSTR %06o\n", console, dpc[console], inst); + dpc[console] += 2; + + switch (inst & 0160000) { + case 0040000: + case 0060000: + increment (inst); + break; + case 0100000: + case 0120000: + pushj (inst & 037777); + break; + case 0140000: + delta (inst); + break; + } + } + + age_ret: + display_age(us, slowdown); + return 1; +} diff --git a/display/ng.h b/display/ng.h new file mode 100644 index 00000000..4ebbf8fc --- /dev/null +++ b/display/ng.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018 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 + * THE AUTHORS 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 names of the authors shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization + * from the authors. + */ + +#if defined(__cplusplus) +extern "C" { +#endif +#ifndef SIM_DEFS_H_ +typedef unsigned short uint16; +typedef int int32; +typedef unsigned int uint32; +#endif /* SIM_DEFS_H_ */ + +/* Hardware type. */ +#define TYPE_DAZZLE 1 +#define TYPE_LOGO 2 + +/* + * The PIX_SCALE #define establishes the initial default display scale + * factor; to change from the default scale factor, set ng_scale + * before calling ng_init(). + */ +#ifndef PIX_SCALE +#define PIX_SCALE RES_FULL +#endif +extern int ng_type; +extern int ng_scale; + +extern int32 ng_get_csr(void); +extern int32 ng_get_reloc(void); +extern void ng_set_csr(uint16); +extern void ng_set_reloc(uint16); + +extern int ng_init(void *, int); +extern int ng_cycle(int, int); + +extern int ng_fetch(uint32, uint16 *); /* get a display-file word */ +extern int ng_store(uint32, uint16); + +#if defined(__cplusplus) +} +#endif diff --git a/makefile b/makefile index 27e2ecad..de6db9a8 100644 --- a/makefile +++ b/makefile @@ -581,6 +581,7 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin) VIDEO_FEATURES = - video capabilities provided by libSDL2 (Simple Directmedia Layer) DISPLAYL = ${DISPLAYD}/display.c $(DISPLAYD)/sim_ws.c DISPLAYVT = ${DISPLAYD}/vt11.c + DISPLAYNG = ${DISPLAYD}/ng.c DISPLAY_OPT += -DUSE_DISPLAY $(VIDEO_CCDEFS) $(VIDEO_LDFLAGS) $(info using libSDL2: $(call find_include,SDL2/SDL)) ifeq (Darwin,$(OSTYPE)) @@ -604,6 +605,7 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin) VIDEO_FEATURES = - video capabilities provided by libSDL (Simple Directmedia Layer) DISPLAYL = ${DISPLAYD}/display.c $(DISPLAYD)/sim_ws.c DISPLAYVT = ${DISPLAYD}/vt11.c + DISPLAYNG = ${DISPLAYD}/ng.c DISPLAY_OPT += -DUSE_DISPLAY $(VIDEO_CCDEFS) $(VIDEO_LDFLAGS) $(info using libSDL: $(call find_include,SDL/SDL)) ifeq (Darwin,$(OSTYPE)) @@ -1277,7 +1279,8 @@ PDP11 = ${PDP11D}/pdp11_fp.c ${PDP11D}/pdp11_cpu.c ${PDP11D}/pdp11_dz.c \ ${PDP11D}/pdp11_ke.c ${PDP11D}/pdp11_dc.c ${PDP11D}/pdp11_dmc.c \ ${PDP11D}/pdp11_kmc.c ${PDP11D}/pdp11_dup.c ${PDP11D}/pdp11_rs.c \ ${PDP11D}/pdp11_vt.c ${PDP11D}/pdp11_td.c ${PDP11D}/pdp11_io_lib.c \ - ${PDP11D}/pdp11_rom.c ${PDP11D}/pdp11_ch.c $(DISPLAYL) $(DISPLAYVT) + ${PDP11D}/pdp11_rom.c ${PDP11D}/pdp11_ch.c $(DISPLAYL) $(DISPLAYVT) \ + ${PDP11D}/pdp11_ng.c $(DISPLAYNG) PDP11_OPT = -DVM_PDP11 -I ${PDP11D} ${NETWORK_OPT} $(DISPLAY_OPT)