From b1766b6dcfd858baec538e4fbe91dd1d7a551ba1 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Tue, 23 Apr 2019 10:41:10 -0700 Subject: [PATCH] VAX8200: Fix access to watch chip wtc_rd() and wtc_wr() - Recent changes in vax_watch.c changed the input parameter from a physical address to a register address within the watch chip. - vax630_sysdev.c called the older wtc_wr() with the new parameter, but the length argument has been removed. - The watch chip never starts as valid. Make it valid when the TODR is attached (i.e. reflecting a connected battery). - 64 bytes of bus addresses for the watch chip can sometimes be dispatched to wtc_rd() and wtc_wr(). Make sure that reasonable memory is always referenced for all potential accesses. - restore vax8200 to makefile which got lost in a prior merge. --- VAX/vax4nn_stddev.c | 5 -- VAX/vax4xx_stddev.c | 5 -- VAX/vax630_sysdev.c | 7 +-- VAX/vax820_bi.c | 6 +- VAX/vax820_stddev.c | 6 ++ VAX/vax820_syslist.c | 2 + VAX/vax_defs.h | 2 + VAX/vax_watch.c | 130 +++++++++++++++++++++++++++---------------- VAX/vax_watch.h | 47 ++++++++++++++++ makefile | 27 ++++++++- 10 files changed, 168 insertions(+), 69 deletions(-) create mode 100644 VAX/vax_watch.h diff --git a/VAX/vax4nn_stddev.c b/VAX/vax4nn_stddev.c index 830e2c8d..abefca58 100644 --- a/VAX/vax4nn_stddev.c +++ b/VAX/vax4nn_stddev.c @@ -30,7 +30,6 @@ */ #include "vax_defs.h" -#include #define UNIT_V_NODELAY (UNIT_V_UF + 0) /* ROM access equal to RAM access */ #define UNIT_NODELAY (1u << UNIT_V_NODELAY) @@ -66,10 +65,6 @@ const char *clk_description (DEVICE *dptr); extern int32 sysd_hlt_enb (void); extern int32 nar_rd (int32 pa); -extern int32 wtc_rd (int32 rg); -extern void wtc_wr (int32 rg, int32 val); -extern void wtc_set_valid (void); -extern void wtc_set_invalid (void); /* ROM data structures diff --git a/VAX/vax4xx_stddev.c b/VAX/vax4xx_stddev.c index b17d8eed..af3c4700 100644 --- a/VAX/vax4xx_stddev.c +++ b/VAX/vax4xx_stddev.c @@ -31,7 +31,6 @@ */ #include "vax_defs.h" -#include #define UNIT_V_NODELAY (UNIT_V_UF + 0) /* ROM access equal to RAM access */ #define UNIT_NODELAY (1u << UNIT_V_NODELAY) @@ -69,10 +68,6 @@ t_stat clk_reset (DEVICE *dptr); const char *clk_description (DEVICE *dptr); extern int32 sysd_hlt_enb (void); -extern int32 wtc_rd (int32 rg); -extern void wtc_wr (int32 rg, int32 val); -extern void wtc_set_valid (void); -extern void wtc_set_invalid (void); /* ROM data structures diff --git a/VAX/vax630_sysdev.c b/VAX/vax630_sysdev.c index b5bf3ddb..ee75a245 100644 --- a/VAX/vax630_sysdev.c +++ b/VAX/vax630_sysdev.c @@ -34,7 +34,6 @@ */ #include "vax_defs.h" -#include #ifdef DONT_USE_INTERNAL_ROM #if defined(VAX_620) @@ -165,10 +164,6 @@ extern int32 qbmap_rd (int32 pa); extern void qbmap_wr (int32 pa, int32 val, int32 lnt); extern int32 qbmem_rd (int32 pa); extern void qbmem_wr (int32 pa, int32 val, int32 lnt); -extern int32 wtc_rd (int32 pa); -extern void wtc_wr (int32 pa, int32 val, int32 lnt); -extern void wtc_set_valid (void); -extern void wtc_set_invalid (void); extern int32 iccs_rd (void); extern int32 todr_rd (void); extern int32 rxcs_rd (void); @@ -411,7 +406,7 @@ void nvr_wr (int32 pa, int32 val, int32 lnt) int32 rg = (pa + 1 - NVRBASE) >> 1; if (rg < 14) /* watch chip */ - wtc_wr (rg, val, lnt); + wtc_wr (rg, val); else { int32 orig_nvr = (int32)nvr[rg]; diff --git a/VAX/vax820_bi.c b/VAX/vax820_bi.c index fc482525..f7e45f7b 100644 --- a/VAX/vax820_bi.c +++ b/VAX/vax820_bi.c @@ -88,8 +88,6 @@ t_stat cpu_boot (int32 unitno, DEVICE *dptr); extern void uba_eval_int (void); extern int32 uba_get_ubvector (int32 lvl); -extern void wtc_set_valid (void); -extern void wtc_set_invalid (void); extern int32 iccs_rd (void); extern int32 nicr_rd (void); extern int32 icr_rd (void); @@ -98,7 +96,6 @@ extern int32 rxcs_rd (void); extern int32 rxdb_rd (void); extern int32 txcs_rd (void); extern int32 rxcd_rd (void); -extern int32 wtc_rd (int32 pa); extern int32 pcsr_rd (int32 pa); extern int32 fl_rd (int32 pa); extern void iccs_wr (int32 dat); @@ -108,7 +105,6 @@ extern void rxcs_wr (int32 dat); extern void txcs_wr (int32 dat); extern void txdb_wr (int32 dat); extern void rxcd_wr (int32 val); -extern void wtc_wr (int32 pa, int32 val, int32 lnt); extern void pcsr_wr (int32 pa, int32 val, int32 lnt); extern void fl_wr (int32 pa, int32 val, int32 lnt); extern void init_ubus_tab (void); @@ -488,7 +484,7 @@ struct reglink { /* register linkage */ }; struct reglink regtable[] = { - { WATCHBASE, WATCHBASE+WATCHSIZE, &wtc_rd, &wtc_wr }, + { WATCHBASE, WATCHBASE+WATCHSIZE, &wtc_rd_pa, &wtc_wr_pa }, { 0x20088000, 0x20088004, &pcsr_rd, &pcsr_wr }, { 0x200B0000, 0x200B0020, &fl_rd, &fl_wr }, { 0, 0, NULL, NULL } diff --git a/VAX/vax820_stddev.c b/VAX/vax820_stddev.c index b307257c..0cd16552 100644 --- a/VAX/vax820_stddev.c +++ b/VAX/vax820_stddev.c @@ -776,6 +776,10 @@ if (clk_unit.filebuf == NULL) { /* make sure the TODR is return SCPE_MEM; } todr_resync (); +if (clk_unit.flags & UNIT_ATT) /* battery backup hooked up? */ + wtc_set_valid (); +else + wtc_set_invalid (); return SCPE_OK; } @@ -843,6 +847,8 @@ if (r != SCPE_OK) else { TOY *toy = (TOY *)uptr->filebuf; + wtc_set_valid (); + wtc_set (NULL, 0, "STD", NULL); uptr->hwmark = (uint32) uptr->capac; if ((toy->toy_endian_plus2 < 2) || (toy->toy_endian_plus2 > 3)) memset (uptr->filebuf, 0, (size_t)uptr->capac); diff --git a/VAX/vax820_syslist.c b/VAX/vax820_syslist.c index dcbefd6d..1f3d99c3 100644 --- a/VAX/vax820_syslist.c +++ b/VAX/vax820_syslist.c @@ -43,6 +43,7 @@ extern DEVICE ka_dev[KA_NUM]; extern DEVICE mctl_dev[MCTL_NUM]; extern DEVICE uba_dev; extern DEVICE clk_dev; +extern DEVICE wtc_dev; extern DEVICE tmr_dev; extern DEVICE tti_dev, tto_dev; extern DEVICE fl_dev; @@ -77,6 +78,7 @@ DEVICE *sim_devices[] = { &mctl_dev[1], &uba_dev, &clk_dev, + &wtc_dev, &tmr_dev, &tti_dev, &tto_dev, diff --git a/VAX/vax_defs.h b/VAX/vax_defs.h index d451bd2c..0d8960e6 100644 --- a/VAX/vax_defs.h +++ b/VAX/vax_defs.h @@ -934,6 +934,8 @@ extern void rom_wr_B (int32 pa, int32 val); #define CPU_MODEL_MODIFIERS /* No model specific CPU modifiers */ #endif +#include "vax_watch.h" /* Watch chip definitions */ + #ifdef DONT_USE_INTERNAL_ROM #define BOOT_CODE_ARRAY NULL #define BOOT_CODE_SIZE 0 diff --git a/VAX/vax_watch.c b/VAX/vax_watch.c index 5598c55b..ae366d25 100644 --- a/VAX/vax_watch.c +++ b/VAX/vax_watch.c @@ -106,6 +106,7 @@ int32 wtc_csrb = 0; int32 wtc_csrc = 0; int32 wtc_csrd = 0; int32 wtc_mode = WTC_MODE_VMS; +uint8 wtc_ram[64]; t_stat wtc_set (UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat wtc_show (FILE *st, UNIT *uptr, int32 val, CONST void *desc); @@ -123,6 +124,7 @@ REG wtc_reg[] = { { HRDATADF (CSRC, wtc_csrc, 8, "CSRC", wtc_csrc_bits) }, { HRDATADF (CSRD, wtc_csrd, 8, "CSRD", wtc_csrd_bits) }, { HRDATADF (MODE, wtc_mode, 8, "Watch Mode", wtc_mode_bits) }, + { BRDATAD (RAM, wtc_ram, 8, 8, sizeof (wtc_ram), "RAM") }, { NULL } }; @@ -153,7 +155,7 @@ static const char *wtc_regs[] = {"SEC ", "SECA", "MIN ", "MINA", "HR ", "HRA ", "DOW ", "DOM ", "MON ", "YEAR", "CSRA", "CSRB", - "CSRC", "CSRD" }; + "CSRC", "CSRD"}; @@ -191,70 +193,81 @@ if (rg < 10) { /* time reg? */ } } -switch(rg) { +val = wtc_ram[rg]; /* start with RAM data */ - case 0: /* seconds */ - val = ctm->tm_sec; - break; +if (rg < 14) { + switch(rg) { - case 2: /* minutes */ - val = ctm->tm_min; - break; + case 0: /* seconds */ + val = ctm->tm_sec; + break; - case 4: /* hours */ - val = ctm->tm_hour; - break; + case 2: /* minutes */ + val = ctm->tm_min; + break; - case 6: /* day of week */ - val = ctm->tm_wday; - break; + case 4: /* hours */ + val = ctm->tm_hour; + break; - case 7: /* day of month */ - val = ctm->tm_mday; - break; + case 6: /* day of week */ + val = ctm->tm_wday; + break; - case 8: /* month */ - val = ctm->tm_mon + 1; - break; + case 7: /* day of month */ + val = ctm->tm_mday; + break; - case 9: /* year */ - if (wtc_mode == WTC_MODE_VMS) - val = 82; /* always 1982 for VMS */ - else - val = (int32)(ctm->tm_year % 100); - break; + case 8: /* month */ + val = ctm->tm_mon + 1; + break; - case 10: /* CSR A */ - val = wtc_csra; - break; + case 9: /* year */ + if (wtc_mode == WTC_MODE_VMS) + val = 82; /* always 1982 for VMS */ + else + val = (int32)(ctm->tm_year % 100); + break; - case 11: /* CSR B */ - val = wtc_csrb; - break; + case 10: /* CSR A */ + val = wtc_csra; + break; - case 12: /* CSR C */ - val = wtc_csrc; - break; + case 11: /* CSR B */ + val = wtc_csrb; + break; - case 13: /* CSR D */ - val = wtc_csrd & WTC_CSRD_RD; - wtc_set_valid (); - break; - } + case 12: /* CSR C */ + val = wtc_csrc; + break; -sim_debug(DBG_REG, &wtc_dev, "wtc_rd(rg=%d [%s], data=0x%X) ", rg, wtc_regs[rg], val); -sim_debug_bits(DBG_REG, &wtc_dev, wtc_bitdefs[rg], (uint32)val, (uint32)val, TRUE); + case 13: /* CSR D */ + val = wtc_csrd & WTC_CSRD_RD; + wtc_set_valid (); + break; + } + sim_debug(DBG_REG, &wtc_dev, "wtc_rd(rg=%d [%s], data=0x%X) ", rg, wtc_regs[rg], val); + sim_debug_bits(DBG_REG, &wtc_dev, wtc_bitdefs[rg], (uint32)val, (uint32)val, TRUE); + } +else + sim_debug(DBG_REG, &wtc_dev, "wtc_rd(rg=%d [RAM], data=0x%X)\n", rg, val); return val; } +int32 wtc_rd_pa (int32 pa) +{ +return wtc_rd ((pa & (sizeof (wtc_ram) - 1)) >> 1); +} + void wtc_wr (int32 rg, int32 val) { int32 new_val = val; val = val & 0xFF; -switch(rg) { +wtc_ram[rg] = val; /* Save data in RAM */ +switch(rg) { /* register behaviors */ case 10: /* CSR A */ val = val & WTC_CSRA_WR; @@ -275,9 +288,19 @@ switch(rg) { break; } -sim_debug(DBG_REG, &wtc_dev, "wtc_wr(rg=%d [%s], data=0x%X) ", rg, wtc_regs[rg], val); -sim_debug_bits(DBG_REG, &wtc_dev, wtc_bitdefs[rg], (uint32)new_val, (uint32)new_val, TRUE); +if (rg < 14) { + sim_debug(DBG_REG, &wtc_dev, "wtc_wr(rg=%d [%s], data=0x%X) ", rg, wtc_regs[rg], val); + sim_debug_bits(DBG_REG, &wtc_dev, wtc_bitdefs[rg], (uint32)new_val, (uint32)new_val, TRUE); + } +else + sim_debug(DBG_REG, &wtc_dev, "wtc_wr(rg=%d [RAM], data=0x%X)\n", rg, val); +} +void wtc_wr_pa (int32 pa, int32 val, int32 lnt) +{ +wtc_wr ((pa & (sizeof (wtc_ram) - 1)) >> 1, val); +if (lnt == 4) + wtc_wr (((pa + 2) & (sizeof (wtc_ram) - 1)) >> 1, val); } t_stat wtc_reset (DEVICE *dptr) @@ -294,8 +317,21 @@ return SCPE_OK; t_stat wtc_set (UNIT *uptr, int32 val, CONST char *cptr, void *desc) { -if (cptr != NULL) - wtc_mode = ((strcmp(cptr, "STD") != 0) ? WTC_MODE_VMS : WTC_MODE_STD); +char gbuf[CBUFSIZE]; + +if (cptr != NULL) { + cptr = get_glyph (cptr, gbuf, 0); + if (*cptr) + return SCPE_2MARG; + if (strcmp (gbuf, "STD") == 0) + wtc_mode = WTC_MODE_STD; + else { + if (strcmp (gbuf, "VMS") == 0) + wtc_mode = WTC_MODE_VMS; + else + return SCPE_ARG; + } + } return SCPE_OK; } diff --git a/VAX/vax_watch.h b/VAX/vax_watch.h new file mode 100644 index 00000000..1e714fe0 --- /dev/null +++ b/VAX/vax_watch.h @@ -0,0 +1,47 @@ +/* vax_watch.h: VAX watch chip + + Copyright (c) 2019, Mark Pizzolato + This module incorporates code from SimH: + Copyright (c) 1998-2008, Robert M Supnik, + Copyright (c) 2019, Matt Burke + + 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 AUTHOR(S) 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(s) of the author(s) 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 author(s). + + This file covers the watch chip (MC146818) + +*/ + +#ifndef _VAX_WATCH_H_ +#define _VAX_WATCH_H_ 1 + +#include "vax_defs.h" + +extern t_stat wtc_set (UNIT *uptr, int32 val, CONST char *cptr, void *desc); +extern t_stat wtc_show (FILE *st, UNIT *uptr, int32 val, CONST void *desc); +extern void wtc_set_valid (void); +extern void wtc_set_invalid (void); +extern int32 wtc_rd (int32 rg); +extern int32 wtc_rd_pa (int32 pa); +extern void wtc_wr (int32 rg, int32 val); +extern void wtc_wr_pa (int32 pa, int32 val, int32 lnt); + +#endif diff --git a/makefile b/makefile index 3fa53a5b..889e16fc 100644 --- a/makefile +++ b/makefile @@ -1444,6 +1444,21 @@ VAX780 = ${VAXD}/vax_cpu.c ${VAXD}/vax_cpu1.c ${VAXD}/vax_fpa.c \ VAX780_OPT = -DVM_VAX -DVAX_780 -DUSE_INT64 -DUSE_ADDR64 -I VAX -I ${PDP11D} ${NETWORK_OPT} +VAX8200 = ${VAXD}/vax_cpu.c ${VAXD}/vax_cpu1.c ${VAXD}/vax_fpa.c \ + ${VAXD}/vax_cis.c ${VAXD}/vax_octa.c ${VAXD}/vax_cmode.c \ + ${VAXD}/vax_mmu.c ${VAXD}/vax_sys.c ${VAXD}/vax_syscm.c \ + ${VAXD}/vax_watch.c ${VAXD}/vax820_stddev.c ${VAXD}/vax820_bi.c \ + ${VAXD}/vax820_mem.c ${VAXD}/vax820_uba.c ${VAXD}/vax820_ka.c \ + ${VAXD}/vax820_syslist.c \ + ${PDP11D}/pdp11_rl.c ${PDP11D}/pdp11_rq.c ${PDP11D}/pdp11_ts.c \ + ${PDP11D}/pdp11_dz.c ${PDP11D}/pdp11_lp.c ${PDP11D}/pdp11_tq.c \ + ${PDP11D}/pdp11_xu.c ${PDP11D}/pdp11_ry.c ${PDP11D}/pdp11_cr.c \ + ${PDP11D}/pdp11_hk.c ${PDP11D}/pdp11_vh.c ${PDP11D}/pdp11_dmc.c \ + ${PDP11D}/pdp11_td.c ${PDP11D}/pdp11_tc.c ${PDP11D}/pdp11_rk.c \ + ${PDP11D}/pdp11_io_lib.c ${PDP11D}/pdp11_ch.c +VAX8200_OPT = -DVM_VAX -DVAX_820 -DUSE_INT64 -DUSE_ADDR64 -I VAX -I ${PDP11D} ${NETWORK_OPT} + + VAX8600 = ${VAXD}/vax_cpu.c ${VAXD}/vax_cpu1.c ${VAXD}/vax_fpa.c \ ${VAXD}/vax_cis.c ${VAXD}/vax_octa.c ${VAXD}/vax_cmode.c \ ${VAXD}/vax_mmu.c ${VAXD}/vax_sys.c ${VAXD}/vax_syscm.c \ @@ -1911,7 +1926,8 @@ ATT3B2_OPT = -DUSE_INT64 -DUSE_ADDR64 -I ${ATT3B2D} ${NETWORK_OPT} # Build everything (not the unsupported/incomplete or experimental simulators) # ALL = pdp1 pdp4 pdp7 pdp8 pdp9 pdp15 pdp11 pdp10 \ - vax microvax3900 microvax1 rtvax1000 microvax2 vax730 vax750 vax780 vax8600 \ + vax microvax3900 microvax1 rtvax1000 microvax2 vax730 vax750 vax780 \ + vax8200 vax8600 \ microvax2000 infoserver100 infoserver150vtx microvax3100 microvax3100e \ vaxstation3100m30 vaxstation3100m38 microvax3100m76 vaxstation4000m60 \ microvax3100m80 vaxstation4000vlc infoserver1000 \ @@ -2179,6 +2195,15 @@ ifneq (,$(call find_test,$(VAXD),vax-diag)) $@ $(call find_test,$(VAXD),vax-diag) $(TEST_ARG) endif +vax8200 : ${BIN}vax8200${EXE} + +${BIN}vax8200${EXE} : ${VAX8200} ${SIM} ${BUILD_ROMS} + ${MKDIRBIN} + ${CC} ${VAX8200} ${SIM} ${VAX8200_OPT} $(CC_OUTSPEC) ${LDFLAGS} +ifneq (,$(call find_test,$(VAXD),vax-diag)) + $@ $(call find_test,$(VAXD),vax-diag) $(TEST_ARG) +endif + vax8600 : ${BIN}BuildROMs${EXE} ${BIN}vax8600${EXE} ${BIN}vax8600${EXE} : ${VAX8600} ${SIM} ${BUILD_ROMS}