From 450a244c88533a20cd1a1a256fc357cc01117671 Mon Sep 17 00:00:00 2001 From: Richard Cornwell Date: Thu, 15 Feb 2024 17:34:34 -0500 Subject: [PATCH] SCP: Updated to current. --- makefile | 284 +++++++++++++++++++++++++++++++++------------- scp.c | 279 +++++++++++++++++++++++++++++---------------- scp.h | 6 +- sim_card.c | 28 ++--- sim_console.c | 20 ++-- sim_defs.h | 34 +++--- sim_ether.c | 10 +- sim_fio.c | 13 ++- sim_imd.c | 11 +- sim_printf_fmts.h | 94 +++++++++++++++ sim_sock.c | 2 +- sim_tape.c | 69 ++++++----- sim_timer.c | 46 +++++--- 13 files changed, 622 insertions(+), 274 deletions(-) create mode 100644 sim_printf_fmts.h diff --git a/makefile b/makefile index 8826ddb..fa777f0 100644 --- a/makefile +++ b/makefile @@ -44,6 +44,22 @@ # If debugging is desired, then GNU make can be invoked with # DEBUG=1 on the command line. # +# When building compiler optimized binaries with the gcc or clang +# compilers, invoking GNU make with LTO=1 on the command line will +# cause the build to use Link Time Optimization to maximally optimize +# the results. Link Time Optimization can report errors which aren't +# otherwise detected and will also take significantly longer to +# complete. Additionally, non debug builds default to build with an +# optimization level of -O2. This optimization level can be changed +# by invoking GNU OPTIMIZE=-O3 (or whatever optimize value you want) +# on the command line if desired. +# +# The default setup will fail simulator build(s) if the compile +# produces any warnings. These should be cleaned up before new +# or changd code is accepted into the code base. This option +# can be overridden if GNU make is invoked with WARNINGS=ALLOWED +# on the command line. +# # The default build will run per simulator tests if they are # available. If building without running tests is desired, # then GNU make should be invoked with TESTS=0 on the command @@ -82,10 +98,14 @@ # # CC Command (and platform available options). (Poor man's autoconf) # + +OS_CCDEFS= +AIO_CCDEFS= + ifneq (,${GREP_OPTIONS}) $(info GREP_OPTIONS is defined in your environment.) $(info ) - $(info This variable interfers with the proper operation of this script.) + $(info This variable interferes with the proper operation of this script.) $(info ) $(info The GREP_OPTIONS environment variable feature of grep is deprecated) $(info for exactly this reason and will be removed from future versions of) @@ -95,12 +115,35 @@ ifneq (,${GREP_OPTIONS}) $(info unset the GREP_OPTIONS environment variable to use this makefile) $(error 1) endif -ifeq (old,$(shell gmake --version /dev/null 2>&1 | grep 'GNU Make' | awk '{ if ($$3 < "3.81") {print "old"} }')) - GMAKE_VERSION = $(shell gmake --version /dev/null 2>&1 | grep 'GNU Make' | awk '{ print $$3 }') +ifneq ($(findstring Windows,${OS}),) + # Cygwin can return SHELL := C:/cygwin/bin/sh.exe cygwin is OK & NOT WIN32 + ifeq ($(findstring /cygwin/,$(SHELL)),) + ifeq ($(findstring .exe,${SHELL}),.exe) + # MinGW + WIN32 := 1 + # Tests don't run under MinGW + TESTS := 0 + else # Msys or cygwin + ifeq (MINGW,$(findstring MINGW,$(shell uname))) + $(info *** This makefile can not be used with the Msys bash shell) + $(error Use build_mingw.bat ${MAKECMDGOALS} from a Windows command prompt) + endif + endif + endif +endif +ifeq ($(WIN32),) + SIM_MAJOR=$(shell grep SIM_MAJOR sim_rev.h | awk '{ print $$3 }') + GMAKE_VERSION = $(shell $(MAKE) --version /dev/null 2>&1 | grep 'GNU Make' | awk '{ print $$3 }') + OLD = $(shell echo $(GMAKE_VERSION) | awk '{ if ($$1 < "3.81") {print "old"} }') +else + SIM_MAJOR=$(shell for /F "tokens=3" %%i in ('findstr /c:"SIM_MAJOR" sim_rev.h') do echo %%i) + GMAKE_VERSION = $(shell for /F "tokens=3" %%i in ('$(MAKE) --version ^| findstr /c:"GNU Make"') do echo %%i) + OLD = $(shell cmd /e:on /c "if $(GMAKE_VERSION) LSS 3.81 echo old") +endif +ifeq ($(OLD),old) $(warning *** Warning *** GNU Make Version $(GMAKE_VERSION) is too old to) $(warning *** Warning *** fully process this makefile) endif -SIM_MAJOR=$(shell grep SIM_MAJOR sim_rev.h | awk '{ print $$3 }') BUILD_SINGLE := ${MAKECMDGOALS} $(BLANK_SUFFIX) BUILD_MULTIPLE_VERB = is # building the pdp1, pdp11, tx-0, or any microvax simulator could use video support @@ -125,6 +168,14 @@ ifneq (3,${SIM_MAJOR}) ifneq (,$(or $(findstring pdp6,${MAKECMDGOALS}),$(findstring pdp10-ka,${MAKECMDGOALS}),$(findstring pdp10-ki,${MAKECMDGOALS}))) VIDEO_USEFUL = true endif + # building the AltairZ80 could use video support + ifneq (,$(findstring altairz80,${MAKECMDGOALS})) + VIDEO_USEFUL = true + endif +endif +# building the SEL32 networking can be used +ifneq (,$(findstring sel32,${MAKECMDGOALS})) + NETWORK_USEFUL = true endif # building the PDP-7 needs video support ifneq (,$(findstring pdp7,${MAKECMDGOALS})) @@ -163,18 +214,24 @@ ifneq ($(NOVIDEO),) VIDEO_USEFUL = endif ifneq ($(findstring Windows,${OS}),) - ifeq ($(findstring .exe,${SHELL}),.exe) - # MinGW - WIN32 := 1 - # Tests don't run under MinGW - TESTS := 0 - else # Msys or cygwin - ifeq (MINGW,$(findstring MINGW,$(shell uname))) - $(info *** This makefile can not be used with the Msys bash shell) - $(error Use build_mingw.bat ${MAKECMDGOALS} from a Windows command prompt) + ifeq ($(findstring /cygwin/,$(SHELL)),) + ifeq ($(findstring .exe,${SHELL}),.exe) + # MinGW + WIN32 := 1 + # Tests don't run under MinGW + TESTS := 0 + else # Msys or cygwin + ifeq (MINGW,$(findstring MINGW,$(shell uname))) + $(info *** This makefile can not be used with the Msys bash shell) + $(error Use build_mingw.bat ${MAKECMDGOALS} from a Windows command prompt) + endif endif endif endif +ifeq (3,${SIM_MAJOR}) + # simh v3 DOES not have any video support + VIDEO_USEFUL = +endif find_exe = $(abspath $(strip $(firstword $(foreach dir,$(strip $(subst :, ,${PATH})),$(wildcard $(dir)/$(1)))))) find_lib = $(firstword $(abspath $(strip $(firstword $(foreach dir,$(strip ${LIBPATH}),$(foreach ext,$(strip ${LIBEXT}),$(wildcard $(dir)/lib$(1).$(ext)))))))) @@ -253,6 +310,7 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin) endif endif else + OS_CCDEFS += $(if $(findstring ALLOWED,$(WARNINGS)),,-Werror) ifeq (,$(findstring ++,${GCC})) CC_STD = -std=gnu99 else @@ -260,6 +318,7 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin) endif endif else + OS_CCDEFS += $(if $(findstring ALLOWED,$(WARNINGS)),,-Werror) ifeq (Apple,$(shell ${GCC} -v /dev/null 2>&1 | grep 'Apple' | awk '{ print $$1 }')) COMPILER_NAME = $(shell ${GCC} -v /dev/null 2>&1 | grep 'Apple' | awk '{ print $$1 " " $$2 " " $$3 " " $$4 }') CLANG_VERSION = $(word 4,$(COMPILER_NAME)) @@ -306,7 +365,8 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin) LTO_EXCLUDE_VERSIONS = PCAPLIB = pcap ifeq (agcc,$(findstring agcc,${GCC})) # Android target build? - OS_CCDEFS += -D_GNU_SOURCE -DSIM_ASYNCH_IO + OS_CCDEFS += -D_GNU_SOURCE + AIO_CCDEFS += -DSIM_ASYNCH_IO OS_LDFLAGS = -lm else # Non-Android (or Native Android) Builds ifeq (,$(INCLUDES)$(LIBRARIES)) @@ -479,7 +539,7 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin) endif OS_CCDEFS += -D_HPUX_SOURCE -D_LARGEFILE64_SOURCE OS_LDFLAGS += -Wl,+b: - NO_LTO = 1 + override LTO = else LIBEXT = a endif @@ -503,14 +563,6 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin) endif export CPATH = $(subst $() $(),:,$(INCPATH)) export LIBRARY_PATH = $(subst $() $(),:,$(LIBPATH)) - # Some gcc versions don't support LTO, so only use LTO when the compiler is known to support it - ifeq (,$(NO_LTO)) - ifneq (,$(GCC_VERSION)) - ifeq (,$(shell ${GCC} -v /dev/null 2>&1 | grep '\-\-enable-lto')) - LTO_EXCLUDE_VERSIONS += $(GCC_VERSION) - endif - endif - endif endif $(info lib paths are: ${LIBPATH}) $(info include paths are: ${INCPATH}) @@ -526,23 +578,23 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin) endif ifneq (,$(call find_include,pthread)) ifneq (,$(call find_lib,pthread)) - OS_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO + AIO_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO OS_LDFLAGS += -lpthread $(info using libpthread: $(call find_lib,pthread) $(call find_include,pthread)) else LIBEXTSAVE := ${LIBEXT} LIBEXT = a ifneq (,$(call find_lib,pthread)) - OS_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO + AIO_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO OS_LDFLAGS += -lpthread $(info using libpthread: $(call find_lib,pthread) $(call find_include,pthread)) else ifneq (,$(findstring Haiku,$(OSTYPE))) - OS_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO + AIO_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO $(info using libpthread: $(call find_include,pthread)) else ifeq (Darwin,$(OSTYPE)) - OS_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO + AIO_CCDEFS += -DUSE_READER_THREAD -DSIM_ASYNCH_IO OS_LDFLAGS += -lpthread $(info using macOS libpthread: $(call find_include,pthread)) endif @@ -650,19 +702,15 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin) endif endif endif + ifeq (cygwin,$(OSTYPE)) + LIBEXTSAVE := ${LIBEXT} + LIBEXT = dll.a + endif ifneq (,$(VIDEO_USEFUL)) - ifeq (cygwin,$(OSTYPE)) - LIBEXTSAVE := ${LIBEXT} - LIBEXT = dll.a - endif ifneq (,$(call find_include,SDL2/SDL)) ifneq (,$(call find_lib,SDL2)) - ifneq (,$(findstring Haiku,$(OSTYPE))) - ifneq (,$(shell which sdl2-config)) - SDLX_CONFIG = sdl2-config - endif - else - SDLX_CONFIG = $(realpath $(dir $(call find_include,SDL2/SDL))../../bin/sdl2-config) + ifneq (,$(shell which sdl2-config)) + SDLX_CONFIG = sdl2-config endif ifneq (,$(SDLX_CONFIG)) VIDEO_CCDEFS += -DHAVE_LIBSDL -DUSE_SIM_VIDEO `$(SDLX_CONFIG) --cflags` @@ -672,19 +720,73 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin) DISPLAYVT = ${DISPLAYD}/vt11.c DISPLAY340 = ${DISPLAYD}/type340.c DISPLAYNG = ${DISPLAYD}/ng.c - DISPLAYIMLAC = ${DISPLAYD}/imlac.c - DISPLAYTT2500 = ${DISPLAYD}/tt2500.c + DISPLAYIII = ${DISPLAYD}/iii.c DISPLAY_OPT += -DUSE_DISPLAY $(VIDEO_CCDEFS) $(VIDEO_LDFLAGS) $(info using libSDL2: $(call find_include,SDL2/SDL)) ifeq (Darwin,$(OSTYPE)) VIDEO_CCDEFS += -DSDL_MAIN_AVAILABLE endif + ifneq (,$(and $(BESM6_BUILD), $(or $(and $(call find_include,SDL2/SDL_ttf),$(call find_lib,SDL2_ttf)), $(and $(call find_include,SDL/SDL_ttf),$(call find_lib,SDL_ttf))))) + FONTPATH += /usr/share/fonts /Library/Fonts /usr/lib/jvm /System/Library/Frameworks/JavaVM.framework/Versions /System/Library/Fonts C:/Windows/Fonts + FONTPATH := $(dir $(foreach dir,$(strip $(FONTPATH)),$(wildcard $(dir)/.))) + FONTNAME += DejaVuSans.ttf LucidaSansRegular.ttf FreeSans.ttf AppleGothic.ttf tahoma.ttf + $(info font paths are: $(FONTPATH)) + $(info font names are: $(FONTNAME)) + find_fontfile = $(strip $(firstword $(foreach dir,$(strip $(FONTPATH)),$(wildcard $(dir)/$(1))$(wildcard $(dir)/*/$(1))$(wildcard $(dir)/*/*/$(1))$(wildcard $(dir)/*/*/*/$(1))))) + find_font = $(abspath $(strip $(firstword $(foreach font,$(strip $(FONTNAME)),$(call find_fontfile,$(font)))))) + ifneq (,$(call find_font)) + FONTFILE=$(call find_font) + else + $(info ***) + $(info *** No font file available, BESM-6 video panel disabled.) + $(info ***) + $(info *** To enable the panel display please specify one of:) + $(info *** a font path with FONTPATH=path) + $(info *** a font name with FONTNAME=fontname.ttf) + $(info *** a font file with FONTFILE=path/fontname.ttf) + $(info ***) + endif + endif + ifeq (,$(and ${VIDEO_LDFLAGS}, ${FONTFILE}, $(BESM6_BUILD))) + $(info *** No SDL ttf support available. BESM-6 video panel disabled.) + $(info ***) + ifeq (Darwin,$(OSTYPE)) + ifeq (/opt/local/bin/port,$(shell which port)) + $(info *** Info *** Install the MacPorts libSDL2-ttf development package to provide this) + $(info *** Info *** functionality for your OS X system:) + $(info *** Info *** # port install libsdl2-ttf-dev) + endif + ifeq (/usr/local/bin/brew,$(shell which brew)) + ifeq (/opt/local/bin/port,$(shell which port)) + $(info *** Info ***) + $(info *** Info *** OR) + $(info *** Info ***) + endif + $(info *** Info *** Install the HomeBrew sdl2_ttf package to provide this) + $(info *** Info *** functionality for your OS X system:) + $(info *** Info *** $$ brew install sdl2_ttf) + endif + else + ifneq (,$(and $(findstring Linux,$(OSTYPE)),$(call find_exe,apt-get))) + $(info *** Info *** Install the development components of libSDL2-ttf) + $(info *** Info *** packaged for your Linux operating system distribution:) + $(info *** Info *** $$ sudo apt-get install libsdl2-ttf-dev) + else + $(info *** Info *** Install the development components of libSDL2-ttf packaged by your) + $(info *** Info *** operating system distribution and rebuild your simulator to) + $(info *** Info *** enable this extra functionality.) + endif + endif + else + ifneq (,$(call find_include,SDL2/SDL_ttf),$(call find_lib,SDL2_ttf)) + $(info using libSDL2_ttf: $(call find_lib,SDL2_ttf) $(call find_include,SDL2/SDL_ttf)) + $(info ***) + BESM6_PANEL_OPT = -DFONTFILE=${FONTFILE} $(filter-out -DSDL_MAIN_AVAILABLE,${VIDEO_CCDEFS}) ${VIDEO_LDFLAGS} -lSDL2_ttf + endif + endif endif endif endif - ifeq (cygwin,$(OSTYPE)) - LIBEXT = $(LIBEXTSAVE) - endif ifeq (,$(findstring HAVE_LIBSDL,$(VIDEO_CCDEFS))) $(info *** Info ***) $(info *** Info *** The simulator$(BUILD_MULTIPLE) you are building could provide more functionality) @@ -726,6 +828,14 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin) $(info *** Info ***) endif endif + ifeq (cygwin,$(OSTYPE)) + LIBEXT = $(LIBEXTSAVE) + LIBPATH += /usr/lib/w32api + ifneq (,$(call find_lib,winmm)) + OS_CCDEFS += -DHAVE_WINMM + OS_LDFLAGS += -lwinmm + endif + endif ifneq (,$(NETWORK_USEFUL)) ifneq (,$(call find_include,pcap)) ifneq (,$(shell grep 'pcap/pcap.h' $(call find_include,pcap) | grep include)) @@ -987,12 +1097,12 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin) $(info *** Error *** There are ONLY two supported ways to acquire and build) $(info *** Error *** the simh source code:) $(info *** Error *** 1: directly with git via:) - $(info *** Error *** $$ git clone https://github.com/simh/simh) + $(info *** Error *** $$ git clone https://github.com/rcornwell/sims) $(info *** Error *** $$ cd simh) $(info *** Error *** $$ make {simulator-name}) $(info *** Error *** OR) $(info *** Error *** 2: download the source code zip archive from:) - $(info *** Error *** $$ wget(or via browser) https://github.com/simh/simh/archive/master.zip) + $(info *** Error *** $$ wget(or via browser) https://github.com/rcornwell/sims/archive/master.zip) $(info *** Error *** $$ unzip master.zip) $(info *** Error *** $$ cd simh-master) $(info *** Error *** $$ make {simulator-name}) @@ -1026,11 +1136,13 @@ else $(info include paths are: ${INCPATH}) # Give preference to any MinGW provided threading (if available) ifneq (,$(call find_include,pthread)) - PTHREADS_CCDEFS = -DUSE_READER_THREAD -DSIM_ASYNCH_IO + PTHREADS_CCDEFS = + AIO_CCDEFS = -DUSE_READER_THREAD -DSIM_ASYNCH_IO PTHREADS_LDFLAGS = -lpthread else ifeq (pthreads,$(shell if exist ..\windows-build\pthreads\Pre-built.2\include\pthread.h echo pthreads)) - PTHREADS_CCDEFS = -DUSE_READER_THREAD -DPTW32_STATIC_LIB -D_POSIX_C_SOURCE -I../windows-build/pthreads/Pre-built.2/include -DSIM_ASYNCH_IO + PTHREADS_CCDEFS = -DPTW32_STATIC_LIB -D_POSIX_C_SOURCE -I../windows-build/pthreads/Pre-built.2/include + AIO_CCDEFS = -DUSE_READER_THREAD -DSIM_ASYNCH_IO PTHREADS_LDFLAGS = -lpthreadGC2 -L..\windows-build\pthreads\Pre-built.2\lib endif endif @@ -1134,18 +1246,20 @@ else $(info Cloning the windows-build dependencies into $(abspath ..)/windows-build) $(shell git clone https://github.com/simh/windows-build ../windows-build) else - $(info ***********************************************************************) - $(info ***********************************************************************) - $(info ** This build is operating without the required windows-build **) - $(info ** components and therefore will produce less than optimal **) - $(info ** simulator operation and features. **) - $(info ** Download the file: **) - $(info ** https://github.com/simh/windows-build/archive/windows-build.zip **) - $(info ** Extract the windows-build-windows-build folder it contains to **) - $(info ** $(abspath ..\) **) - $(info ***********************************************************************) - $(info ***********************************************************************) - $(info .) + ifneq (3,${SIM_MAJOR}) + $(info ***********************************************************************) + $(info ***********************************************************************) + $(info ** This build is operating without the required windows-build **) + $(info ** components and therefore will produce less than optimal **) + $(info ** simulator operation and features. **) + $(info ** Download the file: **) + $(info ** https://github.com/simh/windows-build/archive/windows-build.zip **) + $(info ** Extract the windows-build-windows-build folder it contains to **) + $(info ** $(abspath ..\) **) + $(info ***********************************************************************) + $(info ***********************************************************************) + $(info .) + endif endif else # Version check on windows-build @@ -1205,23 +1319,18 @@ endif ifneq (,$(UNSUPPORTED_BUILD)) CFLAGS_GIT += -DSIM_BUILD=Unsupported=$(UNSUPPORTED_BUILD) endif +OPTIMIZE ?= -O2 -DNDEBUG=1 ifneq ($(DEBUG),) - CFLAGS_G = -g -ggdb -g3 + CFLAGS_G = -g -ggdb -g3 -D_DEBUG=1 CFLAGS_O = -O0 BUILD_FEATURES = - debugging support + LTO = else ifneq (,$(findstring clang,$(COMPILER_NAME))$(findstring LLVM,$(COMPILER_NAME))) - CFLAGS_O = -O2 -fno-strict-overflow - GCC_OPTIMIZERS_CMD = ${GCC} --help - NO_LTO = 1 + CFLAGS_O = $(OPTIMIZE) -fno-strict-overflow + GCC_OPTIMIZERS_CMD = ${GCC} --help 2>&1 else - NO_LTO = 1 - ifeq (Darwin,$(OSTYPE)) - CFLAGS_O += -O4 -flto -fwhole-program - else -# CFLAGS_O := -O2 -fprofile-arcs -ftest-coverage - CFLAGS_O := -O2 - endif + CFLAGS_O := $(OPTIMIZE) endif LDFLAGS_O = GCC_MAJOR_VERSION = $(firstword $(subst ., ,$(GCC_VERSION))) @@ -1237,9 +1346,6 @@ else ifneq (,$(GCC_COMMON_CMD)) GCC_OPTIMIZERS += $(shell $(GCC_COMMON_CMD)) endif - ifneq (,$(findstring $(GCC_VERSION),$(LTO_EXCLUDE_VERSIONS))) - NO_LTO = 1 - endif ifneq (,$(findstring -finline-functions,$(GCC_OPTIMIZERS))) CFLAGS_O += -finline-functions endif @@ -1258,13 +1364,16 @@ else ifneq (,$(findstring -fstrict-overflow,$(GCC_OPTIMIZERS))) CFLAGS_O += -fno-strict-overflow endif - ifeq (,$(NO_LTO)) + ifneq (,$(findstring $(GCC_VERSION),$(LTO_EXCLUDE_VERSIONS))) + override LTO = + endif + ifneq (,$(LTO)) ifneq (,$(findstring -flto,$(GCC_OPTIMIZERS))) - CFLAGS_O += -flto -fwhole-program - LDFLAGS_O += -flto -fwhole-program + CFLAGS_O += -flto + LTO_FEATURE = , with Link Time Optimization, endif endif - BUILD_FEATURES = - compiler optimizations and no debugging support + BUILD_FEATURES = - compiler optimizations$(LTO_FEATURE) and no debugging support endif ifneq (3,$(GCC_MAJOR_VERSION)) ifeq (,$(GCC_WARNINGS_CMD)) @@ -1394,7 +1503,6 @@ SEL32 = ${SEL32D}/sel32_cpu.c ${SEL32D}/sel32_sys.c ${SEL32D}/sel32_chan.c \ ${SEL32D}/sel32_hsdp.c ${SEL32D}/sel32_mfp.c ${SEL32D}/sel32_scsi.c \ ${SEL32D}/sel32_ec.c ${SEL32D}/sel32_ipu.c SEL32_OPT = -I $(SEL32D) -DSEL32 ${NETWORK_OPT} -#SEL32_OPT = -I $(SEL32D) -DUSE_INT64 -DSEL32 ICL1900D = ${SIMHD}/ICL1900 ICL1900 = ${ICL1900D}/icl1900_cpu.c ${ICL1900D}/icl1900_sys.c \ @@ -1411,7 +1519,7 @@ IBM360 = ${IBM360D}/ibm360_cpu.c ${IBM360D}/ibm360_sys.c ${IBM360D}/ibm360_con.c ${IBM360D}/ibm360_mt.c ${IBM360D}/ibm360_lpr.c ${IBM360D}/ibm360_dasd.c \ ${IBM360D}/ibm360_com.c ${IBM360D}/ibm360_scom.c ${IBM360D}/ibm360_scon.c \ ${IBM360D}/ibm360_vma.c -IBM360_OPT = -I $(IBM360D) -DIBM360 -DUSE_INT64 -DUSE_SIM_CARD +IBM360_OPT = -I $(IBM360D) -DIBM360 -DUSE_INT64 -DUSE_SIM_CARD -DDONT_USE_AIO_INTRINSICS PDP6D = ${SIMHD}/PDP10 ifneq (,${DISPLAY_OPT}) @@ -1423,13 +1531,17 @@ PDP6 = ${PDP6D}/kx10_cpu.c ${PDP6D}/kx10_sys.c ${PDP6D}/kx10_cty.c \ ${PDP6D}/pdp6_mtc.c ${PDP6D}/pdp6_dsk.c ${PDP6D}/pdp6_dcs.c \ ${PDP6D}/kx10_dpy.c ${PDP6D}/pdp6_slave.c ${PDP6D}/pdp6_ge.c \ ${DISPLAYL} ${DISPLAY340} -PDP6_OPT = -DPDP6=1 -DUSE_INT64 -I ${PDP6D} -DUSE_SIM_CARD ${DISPLAY_OPT} ${PDP6_DISPLAY_OPT} +PDP6_OPT = -DPDP6=1 -DUSE_INT64 -I ${PDP6D} -DUSE_SIM_CARD ${DISPLAY_OPT} ${PDP6_DISPLAY_OPT} ${AIO_CCDEFS} ifneq (${PANDA_LIGHTS},) # ONLY for Panda display. PDP6_OPT += -DPANDA_LIGHTS PDP6 += ${PDP6D}/kx10_lights.c PDP6_LDFLAGS += -lusb-1.0 endif +ifneq (${PIDP10},) +PDP6_OPT += -DPIDP10=1 +PDP6 += ${PDP6D}/ka10_pipanel.c +endif PDP10D = ${SIMHD}/PDP10 KA10D = ${SIMHD}/PDP10 @@ -1483,6 +1595,10 @@ KI10_OPT += -DPANDA_LIGHTS KI10 += ${KA10D}/kx10_lights.c KI10_LDFLAGS = -lusb-1.0 endif +ifneq (${PIDP10},) +KI10_OPT += -DPIDP10=1 +KI10 += ${KI10D}/ka10_pipanel.c +endif KL10D = ${SIMHD}/PDP10 KL10 = ${KL10D}/kx10_cpu.c ${KL10D}/kx10_sys.c ${KL10D}/kx10_df.c \ @@ -1492,8 +1608,12 @@ KL10 = ${KL10D}/kx10_cpu.c ${KL10D}/kx10_sys.c ${KL10D}/kx10_df.c \ ${KL10D}/kx10_rp.c ${KL10D}/kx10_tu.c ${KL10D}/kx10_rs.c \ ${KL10D}/kx10_imp.c ${KL10D}/kl10_fe.c ${KL10D}/ka10_pd.c \ ${KL10D}/ka10_ch10.c ${KL10D}/kl10_nia.c ${KL10D}/kx10_disk.c \ - ${KL10D}/kl10_dn.c + ${KL10D}/kl10_dn.c ${KL10D}/kl10_ci.c KL10_OPT = -DKL=1 -DUSE_INT64 -I $(KL10D) -DUSE_SIM_CARD ${NETWORK_OPT} +ifneq (${PIDP10},) +KS10_OPT += -DPIDP10=1 +KS10 += ${KS10D}/ka10_pipanel.c +endif KS10D = ${SIMHD}/PDP10 KS10 = ${KS10D}/kx10_cpu.c ${KS10D}/kx10_sys.c ${KS10D}/kx10_disk.c \ @@ -1502,6 +1622,10 @@ KS10 = ${KS10D}/kx10_cpu.c ${KS10D}/kx10_sys.c ${KS10D}/kx10_disk.c \ ${KS10D}/ks10_tcu.c ${KS10D}/ks10_lp.c ${KS10D}/ks10_ch11.c \ ${KS10D}/ks10_kmc.c ${KS10D}/ks10_dup.c ${KS10D}/kx10_imp.c KS10_OPT = -DKS=1 -DUSE_INT64 -I $(KS10D) ${NETWORK_OPT} +ifneq (${PIDP10},) +KS10_OPT += -DPIDP10=1 +KS10 += ${KS10D}/ka10_pipanel.c +endif # diff --git a/scp.c b/scp.c index 7acd1f1..59796b7 100644 --- a/scp.c +++ b/scp.c @@ -335,6 +335,7 @@ #define SIM_DBG_DO 0x01000000 /* do activities */ #define SIM_DBG_SAVE 0x00800000 /* save activities */ #define SIM_DBG_RESTORE 0x00400000 /* restore activities */ +#define SCP_LOG_TESTING 0x00200000 /* test_scp_debug_logging() debug */ static DEBTAB scp_debug[] = { {"EVENT", SIM_DBG_EVENT, "Event Dispatch Activities"}, @@ -347,6 +348,7 @@ static DEBTAB scp_debug[] = { {"DO", SIM_DBG_DO, "Do Command/Expansion Activities"}, {"SAVE", SIM_DBG_SAVE, "Save Activities"}, {"RESTORE", SIM_DBG_RESTORE, "Restore Activities"}, + {"LOG TEST", SCP_LOG_TESTING, "Log testing"}, {0} }; @@ -3088,7 +3090,7 @@ t_stat set_prompt (int32 flag, CONST char *cptr) { char gbuf[CBUFSIZE], *gptr; -if ((!cptr) || (*cptr == '\0')) +if ((NULL == cptr) || (*cptr == '\0')) return SCPE_ARG; cptr = get_glyph_nc (cptr, gbuf, '"'); /* get quote delimited token */ @@ -3146,10 +3148,10 @@ void fprint_help (FILE *st) { CTAB *cmdp; CTAB **hlp_cmdp = NULL; -int cmd_cnt = 0; -int cmd_size = 0; +size_t cmd_cnt = 0; +size_t cmd_size = 0; size_t max_cmdname_size = 0; -int i, line_offset; +size_t i, line_offset; for (cmdp = sim_vm_cmd; cmdp && (cmdp->name != NULL); cmdp++) { if (cmdp->help) { @@ -3164,7 +3166,7 @@ for (cmdp = sim_vm_cmd; cmdp && (cmdp->name != NULL); cmdp++) { } } for (cmdp = cmd_table; cmdp && (cmdp->name != NULL); cmdp++) { - if (cmdp->help && (!sim_vm_cmd || !find_ctab (sim_vm_cmd, cmdp->name))) { + if (cmdp->help && (NULL == sim_vm_cmd || NULL == find_ctab (sim_vm_cmd, cmdp->name))) { if (cmd_cnt >= cmd_size) { cmd_size += 20; hlp_cmdp = (CTAB **)realloc (hlp_cmdp, sizeof(*hlp_cmdp)*cmd_size); @@ -3213,7 +3215,7 @@ const char *end; if ((strlen (buf) >= max_width) && (NULL != strchr (buf, '=')) && (NULL != strchr (strchr (buf, '='), ';')) ) { - int chunk_size; + size_t chunk_size; const char *front_gap = strchr (buf, '='); size_t front_gap_size = front_gap - buf + 1; @@ -3230,18 +3232,18 @@ if ((strlen (buf) >= max_width) && --chunk_size; if (chunk_size == 0) chunk_size = strlen (buf); - fprintf (st, "%*s%*.*s\n", (int)(line_pos), "", chunk_size, chunk_size, buf); + fprintf (st, "%*s%*.*s\n", (int) line_pos, "", (int) chunk_size, (int) chunk_size, buf); buf += chunk_size; while (isspace (buf[0])) ++buf; if (buf < end) line_pos = front_gap_size; } - fprintf (st, "%*s%*.*s", (int)(line_pos), "", chunk_size, chunk_size, buf); + fprintf (st, "%*s%*.*s", (int) line_pos, "", (int) chunk_size, (int) chunk_size, buf); line_pos = width + 1; } else - fprintf (st, "%*s", -((int)width), buf); + fprintf (st, "%*s", -((int) width), buf); if (line_pos > width) { fprintf (st, "\n"); if (extra == NULL) @@ -3253,7 +3255,7 @@ if (line_pos > width) { end = extra + (extra ? strlen (extra) : 0); line_pos += (gap ? strlen (gap) : 0); if (line_pos + (end - extra) >= max_width) { - int chunk_size; + size_t chunk_size; while (1) { chunk_size = (end - extra); @@ -3266,13 +3268,13 @@ if (line_pos + (end - extra) >= max_width) { --chunk_size; if (chunk_size == 0) chunk_size = strlen (extra); - fprintf (st, "%s%*.*s\n", gap ? gap : "", chunk_size, chunk_size, extra); + fprintf (st, "%s%*.*s\n", gap ? gap : "", (int) chunk_size, (int) chunk_size, extra); extra += chunk_size; while (isspace (extra[0])) ++extra; if (extra < end) { line_pos = width; - fprintf (st, "%*s", -((int)width), ""); + fprintf (st, "%*s", -((int) width), ""); line_pos += (gap ? strlen (gap) : 0); } else @@ -3535,7 +3537,7 @@ if ((dptr->modifiers) && (dptr->units)) { /* handle unit specific modifiers */ for (mptr = dptr->modifiers; mptr->mask != 0; mptr++) { if ((!MODMASK(mptr,MTAB_VUN)) && MODMASK(mptr,MTAB_XTD)) continue; /* skip device only modifiers */ - if ((!mptr->valid) && MODMASK(mptr,MTAB_XTD)) + if ((NULL == mptr->valid) && MODMASK(mptr,MTAB_XTD)) continue; /* skip show only modifiers */ if ((enabled_units == 1) && (found_unit == 0)) continue; @@ -5313,22 +5315,27 @@ return SCPE_OK; static uint32 get_default_env_parameter (const char *dev_name, const char *param_name, uint32 default_value) { char varname[CBUFSIZE]; -uint32 val; +unsigned long val; char *endptr; const char *colon = strchr (dev_name, ':'); +char *env_val; if (colon) snprintf (varname, sizeof(varname), "%s_%*.*s_%s", param_name, (int)(colon-dev_name), (int)(colon-dev_name), dev_name, colon + 1); else snprintf (varname, sizeof(varname), "%s_%s", param_name, dev_name); -if (!getenv (varname)) + +env_val = getenv(varname); + +if (NULL == env_val) val = default_value; else { - val = strtoul (getenv (varname), &endptr, 0); + val = strtoul (env_val, &endptr, 0); if (*endptr) val = default_value; } -return val; +/* Should really ensure val fits into uint32 when sizeof(uint32) < sizeof(unsigned long). */ +return ((uint32) val); } static void set_default_env_parameter (const char *dev_name, const char *param_name, uint32 value) @@ -5760,6 +5767,16 @@ if (cptr && (*cptr != 0)) /* now eol? */ #ifdef SIM_ASYNCH_IO if (flag == sim_asynch_enabled) /* already set correctly? */ return SCPE_OK; +if (1) { + uint32 i; + DEVICE *dptr; + + for (i = 1; (dptr = sim_devices[i]) != NULL; i++) { /* flush attached files */ + if ((DEV_TYPE(dptr) == DEV_ETHER) && + (dptr->units->flags & UNIT_ATT)) + return sim_messagef (SCPE_ALATT, "Can't change asynch mode with %s device attached\n", dptr->name); + } + } sim_asynch_enabled = flag; tmxr_change_async (); sim_timer_change_asynch (); @@ -6923,11 +6940,11 @@ return SCPE_OK; t_stat show_config (FILE *st, DEVICE *dnotused, UNIT *unotused, int32 flag, CONST char *cptr) { -int32 i; +size_t i; DEVICE *dptr; t_bool only_enabled = (sim_switches & SWMASK ('E')); -if (cptr && (*cptr != 0)) +if (NULL != cptr && (*cptr != 0)) return SCPE_2MARG; fprintf (st, "%s simulator configuration%s\n\n", sim_name, only_enabled ? " (enabled devices)" : ""); for (i = dev_name_len = unit_name_len = 0; (dptr = sim_devices[i]) != NULL; i++) @@ -7461,15 +7478,15 @@ char lbuf[4*CBUFSIZE]; sim_type_file_offset = 0; /* beginning of file */ sim_type_line_count = 0X7FFFFFFF; /* output many lines */ -GET_SWITCHES (cptr); /* get switches */ -if ((!cptr) || (*cptr == 0)) +GET_SWITCHES (cptr); /* get switches */ +if ((NULL == cptr) || (*cptr == 0)) return SCPE_2FARG; if (sim_switches & SWMASK ('O')) { /* Specify Offset in file */ char gbuf[CBUFSIZE]; char *eptr; cptr = get_glyph (cptr, gbuf, 0); - if ((!cptr) || (*cptr == 0)) + if ((NULL == cptr) || (*cptr == 0)) return SCPE_2FARG; sim_type_file_offset = strtol (gbuf, &eptr, 0); if ((*eptr) || (sim_type_file_offset < 0)) @@ -7480,7 +7497,7 @@ if (sim_switches & SWMASK ('N')) { /* Specify Line Count to display */ char *eptr; cptr = get_glyph (cptr, gbuf, 0); - if ((!cptr) || (*cptr == 0)) + if ((NULL == cptr) || (*cptr == 0)) return SCPE_2FARG; sim_type_line_count = strtol (gbuf, &eptr, 0); if ((*eptr) || (sim_type_line_count < 0)) @@ -10724,9 +10741,9 @@ return SCPE_OK; */ -char *sim_encode_quoted_string (const uint8 *iptr, uint32 size) +char *sim_encode_quoted_string (const uint8 *iptr, size_t size) { -uint32 i; +size_t i; t_bool double_quote_found = FALSE; t_bool single_quote_found = FALSE; char quote = '"'; @@ -10785,7 +10802,7 @@ while (size--) { return optr; } -void fprint_buffer_string (FILE *st, const uint8 *buf, uint32 size) +void fprint_buffer_string (FILE *st, const uint8 *buf, size_t size) { char *string; @@ -11275,25 +11292,28 @@ return pptr; SCHTAB *get_rsearch (CONST char *cptr, int32 radix, SCHTAB *schptr) { -int32 c, logop, cmpop; +int32 c; +size_t logop, cmpop; t_value logval, cmpval; const char *sptr; CONST char *tptr; const char logstr[] = "|&^", cmpstr[] = "=!><"; +/* Using a const instead of a #define. */ +const size_t invalid_op = (size_t) -1; logval = cmpval = 0; if (*cptr == 0) /* check for clause */ return NULL; -for (logop = cmpop = -1; (c = *cptr++); ) { /* loop thru clauses */ +for (logop = cmpop = invalid_op; (c = *cptr++); ) { /* loop thru clauses */ if ((sptr = strchr (logstr, c))) { /* check for mask */ - logop = (int32)(sptr - logstr); + logop = sptr - logstr; logval = strtotv (cptr, &tptr, radix); if (cptr == tptr) return NULL; cptr = tptr; } else if ((sptr = strchr (cmpstr, c))) { /* check for boolop */ - cmpop = (int32)(sptr - cmpstr); + cmpop = sptr - cmpstr; if (*cptr == '=') { cmpop = cmpop + strlen (cmpstr); cptr++; @@ -11311,11 +11331,11 @@ if (schptr->count != 1) { free (schptr->comp); schptr->comp = (t_value *)calloc (sim_emax, sizeof(*schptr->comp)); } -if (logop >= 0) { +if (logop != invalid_op) { schptr->logic = logop; schptr->mask[0] = logval; } -if (cmpop >= 0) { +if (cmpop != invalid_op) { schptr->boolop = cmpop; schptr->comp[0] = cmpval; } @@ -11336,21 +11356,24 @@ return schptr; SCHTAB *get_asearch (CONST char *cptr, int32 radix, SCHTAB *schptr) { -int32 c, logop, cmpop; +int32 c; +size_t logop, cmpop; t_value *logval, *cmpval; t_stat reason = SCPE_OK; CONST char *ocptr = cptr; const char *sptr; char gbuf[CBUFSIZE]; const char logstr[] = "|&^", cmpstr[] = "=!><"; +/* Using a const instead of a #define. */ +const size_t invalid_op = (size_t) -1; if (*cptr == 0) /* check for clause */ return NULL; logval = (t_value *)calloc (sim_emax, sizeof(*logval)); cmpval = (t_value *)calloc (sim_emax, sizeof(*cmpval)); -for (logop = cmpop = -1; (c = *cptr++); ) { /* loop thru clauses */ - if ((sptr = strchr (logstr, c))) { /* check for mask */ - logop = (int32)(sptr - logstr); +for (logop = cmpop = invalid_op; (c = *cptr++); ) { /* loop thru clauses */ + if (NULL != (sptr = strchr (logstr, c))) { /* check for mask */ + logop = sptr - logstr; cptr = get_glyph (cptr, gbuf, 0); reason = parse_sym (gbuf, 0, sim_dfunit, logval, sim_switches); if (reason > 0) { @@ -11359,8 +11382,8 @@ for (logop = cmpop = -1; (c = *cptr++); ) { /* loop thru clauses */ return get_rsearch (ocptr, radix, schptr); } } - else if ((sptr = strchr (cmpstr, c))) { /* check for boolop */ - cmpop = (int32)(sptr - cmpstr); + else if (NULL != (sptr = strchr (cmpstr, c))) { /* check for boolop */ + cmpop = sptr - cmpstr; if (*cptr == '=') { cmpop = cmpop + strlen (cmpstr); cptr++; @@ -11386,7 +11409,7 @@ if (schptr->count != (uint32)(1 - reason)) { free (schptr->comp); schptr->comp = (t_value *)calloc (sim_emax, sizeof(*schptr->comp)); } -if (logop >= 0) { +if (logop != invalid_op) { schptr->logic = logop; free (schptr->mask); schptr->mask = logval; @@ -11394,7 +11417,7 @@ if (logop >= 0) { else { free (logval); } -if (cmpop >= 0) { +if (cmpop != invalid_op) { schptr->boolop = cmpop; free (schptr->comp); schptr->comp = cmpval; @@ -11648,11 +11671,11 @@ return val * negate; */ t_stat sprint_val (char *buffer, t_value val, uint32 radix, - uint32 width, uint32 format) + size_t width, uint32 format) { t_value owtest, wtest; t_bool negative = FALSE; -int32 d, digit, ndigits, commas = 0; +size_t d, digit, ndigits, commas = 0; char dbuf[MAX_WIDTH + 1]; if (((format == PV_LEFTSIGN) || (format == PV_RCOMMASIGN)) && @@ -11692,7 +11715,8 @@ switch (format) { dbuf[--d] = '-'; if (width > MAX_WIDTH) { if (!buffer) - return width; + /* Note: Potentially unsafe wraparound if sizeof(t_stat) < sizeof(size_t) */ + return ((t_stat) width); sprintf (buffer, "%*s", -((int)width), dbuf); return SCPE_OK; } @@ -11713,8 +11737,9 @@ switch (format) { d = MAX_WIDTH - (ndigits + commas); break; } -if (!buffer) - return strlen(dbuf+d); +if (NULL == buffer) + /* Note: Potentially unsafe wraparound if sizeof(t_stat) < sizeof(size_t) */ + return ((t_stat) strlen(dbuf+d)); *buffer = '\0'; if (width < strlen(dbuf+d)) return SCPE_IOERR; @@ -12961,11 +12986,11 @@ return sim_exp_clr (exp, gbuf); /* clear one rule */ /* Search for an expect rule in an expect context */ -CONST EXPTAB *sim_exp_fnd (CONST EXPECT *exp, const char *match, int32 start_rule) +CONST EXPTAB *sim_exp_fnd (CONST EXPECT *exp, const char *match, size_t start_rule) { -int32 i; +size_t i; -if (!exp->rules) +if (NULL == exp->rules) return NULL; for (i=start_rule; isize; i++) if (!strcmp (exp->rules[i].match_pattern, match)) @@ -12977,9 +13002,9 @@ return NULL; t_stat sim_exp_clr_tab (EXPECT *exp, EXPTAB *ep) { -int32 i; +size_t i; -if (!ep) /* not there? ok */ +if (NULL == ep) /* not there? ok */ return SCPE_OK; free (ep->match); /* deallocate match string */ free (ep->match_pattern); /* deallocate the display format match string */ @@ -13002,7 +13027,7 @@ t_stat sim_exp_clr (EXPECT *exp, const char *match) { EXPTAB *ep = (EXPTAB *)sim_exp_fnd (exp, match, 0); -while (ep) { +while (NULL != ep) { sim_exp_clr_tab (exp, ep); ep = (EXPTAB *)sim_exp_fnd (exp, match, ep - exp->rules); } @@ -13013,7 +13038,7 @@ return SCPE_OK; t_stat sim_exp_clrall (EXPECT *exp) { -int32 i; +size_t i; for (i=0; isize; i++) { free (exp->rules[i].match); /* deallocate match string */ @@ -13041,7 +13066,7 @@ t_stat sim_exp_set (EXPECT *exp, const char *match, int32 cnt, uint32 after, int EXPTAB *ep; uint8 *match_buf; uint32 match_size; -int i; +size_t i; /* Validate the match string */ match_buf = (uint8 *)calloc (strlen (match) + 1, 1); @@ -13144,7 +13169,7 @@ if ((act != NULL) && (*act != 0)) { /* new action? */ } /* Make sure that the production buffer is large enough to detect a match for all rules including a NUL termination byte */ for (i=0; isize; i++) { - uint32 compare_size = (exp->rules[i].switches & EXP_TYP_REGEX) ? MAX(10 * strlen(ep->match_pattern), 1024) : exp->rules[i].size; + size_t compare_size = (exp->rules[i].switches & EXP_TYP_REGEX) ? MAX(10 * strlen(ep->match_pattern), 1024) : exp->rules[i].size; if (compare_size >= exp->buf_size) { exp->buf = (uint8 *)realloc (exp->buf, compare_size + 2); /* Extra byte to null terminate regex compares */ exp->buf_size = compare_size + 1; @@ -13191,11 +13216,11 @@ uint32 default_haltafter = get_default_env_parameter (dev_name, "SIM_EXPECT_HALT if (exp->buf_size) { char *bstr = sim_encode_quoted_string (exp->buf, exp->buf_ins); - fprintf (st, " Match Buffer Size: %d\n", exp->buf_size); - fprintf (st, " Buffer Insert Offset: %d\n", exp->buf_ins); + fprintf (st, " Match Buffer Size: %" SIZE_T_FMT "d\n", exp->buf_size); + fprintf (st, " Buffer Insert Offset: %" SIZE_T_FMT "d\n", exp->buf_ins); fprintf (st, " Buffer Contents: %s\n", bstr); if (default_haltafter) - fprintf (st, " Default HaltAfter: %u %s\n", (unsigned)default_haltafter, sim_vm_interval_units); + fprintf (st, " Default HaltAfter: %u %s\n", (unsigned) default_haltafter, sim_vm_interval_units); free (bstr); } if (exp->dptr && (exp->dbit & exp->dptr->dctrl)) @@ -13218,7 +13243,7 @@ return SCPE_OK; t_stat sim_exp_showall (FILE *st, const EXPECT *exp) { -int32 i; +size_t i; for (i=0; i < exp->size; i++) sim_exp_show_tab (st, exp, &exp->rules[i]); @@ -13229,7 +13254,7 @@ return SCPE_OK; t_stat sim_exp_check (EXPECT *exp, uint8 data) { -int32 i; +size_t i; EXPTAB *ep = NULL; int regex_checks = 0; char *tstr = NULL; @@ -13274,7 +13299,9 @@ for (i=0; i < exp->size; i++) { sim_debug (exp->dbit, exp->dptr, "Against RegEx Match Rule: %s\n", ep->match_pattern); free (estr); } - rc = pcre_exec (ep->regex, NULL, cbuf, exp->buf_ins, 0, PCRE_NOTBOL, ovector, ovector_elts); + /* exp->buf_ins is never going to exceed 1024 (current limit), so this is safe to + downcast to int. */ + rc = pcre_exec (ep->regex, NULL, cbuf, (int) exp->buf_ins, 0, PCRE_NOTBOL, ovector, ovector_elts); if (rc >= 0) { size_t j; char *buf = (char *)malloc (1 + exp->buf_ins); @@ -13321,12 +13348,12 @@ for (i=0; i < exp->size; i++) { * First compare the newly deposited data at the beginning * of buffer with the end of the match string */ - if (exp->buf_ins) { + if (exp->buf_ins > 0) { if (sim_deb && exp->dptr && (exp->dptr->dctrl & exp->dbit)) { char *estr = sim_encode_quoted_string (exp->buf, exp->buf_ins); char *mstr = sim_encode_quoted_string (&ep->match[ep->size-exp->buf_ins], exp->buf_ins); - sim_debug (exp->dbit, exp->dptr, "Checking String[0:%d]: %s\n", exp->buf_ins, estr); + sim_debug (exp->dbit, exp->dptr, "Checking String[0:%" SIZE_T_FMT "d]: %s\n", exp->buf_ins, estr); sim_debug (exp->dbit, exp->dptr, "Against Match Data: %s\n", mstr); free (estr); free (mstr); @@ -13338,7 +13365,8 @@ for (i=0; i < exp->size; i++) { char *estr = sim_encode_quoted_string (&exp->buf[exp->buf_size-(ep->size-exp->buf_ins)], ep->size-exp->buf_ins); char *mstr = sim_encode_quoted_string (ep->match, ep->size-exp->buf_ins); - sim_debug (exp->dbit, exp->dptr, "Checking String[%d:%d]: %s\n", exp->buf_size-(ep->size-exp->buf_ins), ep->size-exp->buf_ins, estr); + sim_debug (exp->dbit, exp->dptr, "Checking String[%" SIZE_T_FMT "d:%" SIZE_T_FMT "d]: %s\n", + exp->buf_size - ep->size - exp->buf_ins, ep->size-exp->buf_ins, estr); sim_debug (exp->dbit, exp->dptr, "Against Match Data: %s\n", mstr); free (estr); free (mstr); @@ -13352,7 +13380,8 @@ for (i=0; i < exp->size; i++) { char *estr = sim_encode_quoted_string (&exp->buf[exp->buf_ins-ep->size], ep->size); char *mstr = sim_encode_quoted_string (ep->match, ep->size); - sim_debug (exp->dbit, exp->dptr, "Checking String[%d:%d]: %s\n", exp->buf_ins-ep->size, ep->size, estr); + sim_debug (exp->dbit, exp->dptr, "Checking String[%" SIZE_T_FMT "u:%" SIZE_T_FMT "u]: %s\n", + exp->buf_ins - ep->size, ep->size, estr); sim_debug (exp->dbit, exp->dptr, "Against Match Data: %s\n", mstr); free (estr); free (mstr); @@ -13373,7 +13402,8 @@ if (exp->buf_ins == exp->buf_size) { /* At end of match buffe memmove (exp->buf, &exp->buf[exp->buf_size/2], exp->buf_size-(exp->buf_size/2)); exp->buf_ins -= exp->buf_size/2; exp->buf_data = exp->buf_ins; - sim_debug (exp->dbit, exp->dptr, "Buffer Full - sliding the last %d bytes to start of buffer new insert at: %d\n", (exp->buf_size/2), exp->buf_ins); + sim_debug (exp->dbit, exp->dptr, "Buffer Full - sliding the last %" SIZE_T_FMT "d bytes to start of buffer new insert at: %" SIZE_T_FMT "d\n", + exp->buf_size / 2, exp->buf_ins); } else { exp->buf_ins = 0; /* wrap around to beginning */ @@ -13422,10 +13452,10 @@ return SCPE_OK; t_stat sim_send_input (SEND *snd, uint8 *data, size_t size, uint32 after, uint32 delay) { if (snd->extoff != 0) { - if (snd->insoff-snd->extoff > 0) + if (snd->insoff > snd->extoff) memmove(snd->buffer, snd->buffer+snd->extoff, snd->insoff-snd->extoff); snd->insoff -= snd->extoff; - snd->extoff -= snd->extoff; + snd->extoff = 0; } if (snd->insoff+size > snd->bufsize) { snd->bufsize = snd->insoff+size; @@ -13463,7 +13493,7 @@ uint32 after = get_default_env_parameter (dev_name, "SIM_SEND_AFTER", delay); fprintf (st, "%s\n", tmxr_send_line_name (snd)); if (snd->extoff < snd->insoff) { - fprintf (st, " %d bytes of pending input Data:\n ", snd->insoff-snd->extoff); + fprintf (st, " %" SIZE_T_FMT "d bytes of pending input Data:\n ", snd->insoff-snd->extoff); fprint_buffer_string (st, snd->buffer+snd->extoff, snd->insoff-snd->extoff); fprintf (st, "\n"); } @@ -13493,7 +13523,7 @@ return SCPE_OK; t_bool sim_send_poll_data (SEND *snd, t_stat *stat) { -if (snd && (snd->extoff < snd->insoff)) { /* pending input characters available? */ +if ((NULL != snd) && (snd->extoff < snd->insoff)) { /* pending input characters available? */ if (sim_gtime() < snd->next_time) { /* too soon? */ *stat = SCPE_OK; sim_debug (snd->dbit, snd->dptr, "Too soon to inject next byte\n"); @@ -13531,7 +13561,7 @@ return msgbuf; t_stat sim_string_to_stat (const char *cptr, t_stat *stat) { char gbuf[CBUFSIZE]; -int32 cond; +t_stat cond; *stat = SCPE_ARG; cptr = get_glyph (cptr, gbuf, 0); @@ -13545,8 +13575,10 @@ for (cond=0; cond <= (SCPE_MAX_ERR-SCPE_BASE); cond++) if (0 == strcmp(gbuf, "OK")) cond = SCPE_OK; if (cond == (1+SCPE_MAX_ERR-SCPE_BASE)) { /* not found? */ - if (0 == (cond = strtol(gbuf, NULL, 0))) /* try explicit number */ + unsigned long numeric_cond = strtol(gbuf, NULL, 0); + if (0 == numeric_cond) /* try explicit number */ return SCPE_ARG; + cond = (t_stat) numeric_cond; } *stat = cond; if (cond > SCPE_MAX_ERR) @@ -13560,6 +13592,7 @@ const char *debug_bstates = "01_^"; AIO_TLS char debug_line_prefix[256]; int32 debug_unterm = 0; char *debug_line_buf_last = NULL; +size_t debug_line_buf_last_len = 0; size_t debug_line_buf_last_endprefix_offset = 0; AIO_TLS char debug_line_last_prefix[256]; char *debug_line_buf = NULL; @@ -13622,15 +13655,25 @@ if (sim_deb_switches & SWMASK ('F')) { /* filtering disabled? */ } AIO_LOCK; if (debug_line_offset + len + 1 > debug_line_bufsize) { + /* realloc(NULL, size) == malloc(size). Initialize the malloc()-ed space. Only + need to test debug_line_buf since SIMH allocates both buffers at the same + time. */ + const int do_init = (NULL == debug_line_buf); + debug_line_bufsize += MAX(1024, debug_line_offset + len + 1); debug_line_buf = (char *)realloc (debug_line_buf, debug_line_bufsize); debug_line_buf_last = (char *)realloc (debug_line_buf_last, debug_line_bufsize); + + if (do_init) { + memset(debug_line_buf, 0, debug_line_bufsize); + memset(debug_line_buf_last, 0, debug_line_bufsize); + } } memcpy (&debug_line_buf[debug_line_offset], buf, len); debug_line_buf[debug_line_offset + len] = '\0'; debug_line_offset += len; -while ((eol = strchr (debug_line_buf, '\n')) || flush) { - char *endprefix = strstr (debug_line_buf, ")> "); +while (NULL != (eol = strchr (debug_line_buf, '\n')) || flush) { + const char *endprefix = strstr (debug_line_buf, ")> "); size_t linesize = (eol - debug_line_buf) + 1; if ((0 != memcmp ("DBG(", debug_line_buf, 4)) || (endprefix == NULL)) { @@ -13657,12 +13700,18 @@ while ((eol = strchr (debug_line_buf, '\n')) || flush) { debug_line_buf_last_endprefix_offset = endprefix - debug_line_buf; memcpy (debug_line_buf_last, debug_line_buf, linesize); debug_line_buf_last[linesize] = '\0'; + debug_line_buf_last_len = (NULL != eol) ? eol - endprefix + 1 : linesize; debug_line_count = 1; } else { - if (0 == memcmp (&debug_line_buf[endprefix - debug_line_buf], - &debug_line_buf_last[debug_line_buf_last_endprefix_offset], - (eol - endprefix)+ 1)) { + const size_t compare_len = eol - endprefix + 1; + + /* Ensure SIMH only executes memcmp() if the last message's comparison length + is the same as the current debug line's comparison length. */ + if (debug_line_buf_last_len == compare_len && + 0 == memcmp (&debug_line_buf[endprefix - debug_line_buf], + &debug_line_buf_last[debug_line_buf_last_endprefix_offset], + compare_len)) { ++debug_line_count; memcpy (debug_line_last_prefix, debug_line_buf, (endprefix - debug_line_buf) + 3); debug_line_last_prefix[(endprefix - debug_line_buf) + 3] = '\0'; @@ -13679,6 +13728,7 @@ while ((eol = strchr (debug_line_buf, '\n')) || flush) { debug_line_buf_last_endprefix_offset = endprefix - debug_line_buf; memcpy (debug_line_buf_last, debug_line_buf, linesize); debug_line_buf_last[linesize] = '\0'; + debug_line_buf_last_len = (NULL != eol) ? compare_len : linesize; debug_line_count = 1; } } @@ -13941,9 +13991,9 @@ sim_printf ("%s: %s\n", msg, strerror (saved_errno)); t_stat sim_messagef (t_stat stat, const char* fmt, ...) { char stackbuf[STACKBUFSIZE]; -int32 bufsize = sizeof(stackbuf); +size_t bufsize = sizeof(stackbuf); char *buf = stackbuf; -int32 len; +size_t len; va_list arglist; t_bool inhibit_message = (!sim_show_message || (stat & SCPE_NOMESSAGE)); char msg_prefix[32] = ""; @@ -13968,7 +14018,7 @@ while (1) { /* format passed string, arg /* If the formatted result didn't fit into the buffer, then grow the buffer and try again */ - if ((len < 0) || (len >= bufsize-1)) { + if (len >= bufsize-1) { if (buf != stackbuf) free (buf); bufsize = bufsize * 2; @@ -14142,7 +14192,7 @@ void sim_data_trace(DEVICE *dptr, UNIT *uptr, const uint8 *data, const char *pos if (sim_deb && ((dptr->dctrl | (uptr ? uptr->dctrl : 0)) & reason)) { _sim_debug_unit (reason, uptr, "%s %s %slen: %08X\n", sim_uname(uptr), txt, position, (unsigned int)len); if (data && len) { - unsigned int i, same, group, sidx, oidx, ridx, eidx, soff; + size_t i, same, group, sidx, oidx, ridx, eidx, soff; char outbuf[80], strbuf[28], rad50buf[36], ebcdicbuf[32]; static char hex[] = "0123456789ABCDEF"; static char rad50[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$._0123456789"; @@ -14187,7 +14237,8 @@ if (sim_deb && ((dptr->dctrl | (uptr ? uptr->dctrl : 0)) & reason)) { continue; } if (same > 0) { - _sim_debug_unit (reason, uptr, "%04X thru %04X same as above\n", i-(16*same), i-1); + _sim_debug_unit (reason, uptr, "%04" SIZE_T_FMT "X thru %04" SIZE_T_FMT "X same as above\n", + i-(16*same), i - 1); same = 0; } group = (((len - i) > 16) ? 16 : (len - i)); @@ -14235,10 +14286,11 @@ if (sim_deb && ((dptr->dctrl | (uptr ? uptr->dctrl : 0)) & reason)) { strbuf[soff+sidx] = '\0'; ebcdicbuf[eidx] = '\0'; rad50buf[ridx] = '\0'; - _sim_debug_unit (reason, uptr, "%04X%-48s %s%s%s\n", i, outbuf, strbuf, ebcdicbuf, rad50buf); + _sim_debug_unit (reason, uptr, "%04" SIZE_T_FMT "X%-48s %s%s%s\n", i, outbuf, strbuf, ebcdicbuf, rad50buf); } if (same > 0) { - _sim_debug_unit (reason, uptr, "%04X thru %04X same as above\n", i-(16*same), (unsigned int)(len-1)); + _sim_debug_unit (reason, uptr, "%04" SIZE_T_FMT "X thru %04" SIZE_T_FMT "X same as above\n", + (i-(16*same)), len - 1); } } } @@ -14365,7 +14417,7 @@ return _process_cmd ("curl", cptr); #define blankch(x) ((x) == ' ' || (x) == '\t') typedef struct topic { - uint32 level; + size_t level; char *title; char *label; struct topic *parent; @@ -14374,7 +14426,7 @@ typedef struct topic { char *text; size_t len; uint32 flags; - uint32 kidwid; + size_t kidwid; #define HLP_MAGIC_TOPIC 1 } TOPIC; @@ -14580,7 +14632,7 @@ for (hblock = astrings; (htext = *hblock) != NULL; hblock++) { topic = topic->parent; } else { - if (n > topic->level +1) { /* Skipping down more than 1 */ + if (n > topic->level + 1) { /* Skipping down more than 1 */ FAIL (SCPE_ARG, Level not contiguous, htext); /* E.g. 1 3, not reasonable */ } } @@ -14632,7 +14684,7 @@ for (hblock = astrings; (htext = *hblock) != NULL; hblock++) { children = (TOPIC **) realloc (topic->children, (topic->kids +1) * sizeof (TOPIC *)); - if (!children) { + if (NULL == children) { free (newt->title); free (newt); FAIL (SCPE_MEM, No memory, NULL); @@ -14647,7 +14699,7 @@ for (hblock = astrings; (htext = *hblock) != NULL; hblock++) { sprintf (nbuf, ".%u", topic->kids); n = strlen (topic->label) + strlen (nbuf) + 1; newt->label = (char *) malloc (n); - if (!newt->label) { + if (NULL == newt->label) { free (newt->title); topic->children[topic->kids -1] = NULL; free (newt); @@ -15009,7 +15061,7 @@ while (TRUE) { w = 4 + topic->kidwid; fputc ('\n', st); } - fprintf (st, " %-*s", topic->kidwid, tbuf); + fprintf (st, " %-*s", (int) topic->kidwid, tbuf); } fprintf (st, "\n\n"); if (flag & SCP_HELP_ONECMD) { @@ -15816,7 +15868,7 @@ if (sim_isalpha (*data) || (*data == '_')) { return TRUE; } gptr = _sim_get_env_special (data, string, string_size - 1); - if (gptr) { + if (NULL != gptr) { *svalue = strtotsv(string, &gptr, 0); sprint_val (string, *svalue, 10, string_size - 1, PV_LEFTSIGN); sim_debug (SIM_DBG_EXP_EVAL, &sim_scp_dev, "[Value: %s=%s]\n", data, string); @@ -16021,10 +16073,13 @@ MFlush (MFILE *f) f->pos = 0; } +/* FMwrite() returns 1 (TRUE) if all data was writting, 0 (FALSE) indicates + fewer than the requested number of bytes were written. N.B. this function + is only called in one place and its return value isn't checked.*/ static int FMwrite (FILE *fout, MFILE *fdata) { -int ret = fwrite (fdata->buf, 1, fdata->pos, fout); +int ret = fwrite (fdata->buf, 1, fdata->pos, fout) == fdata->pos; MFlush (fdata); return ret; @@ -16047,7 +16102,7 @@ free (f); static t_stat sim_sanity_check_register_declarations (DEVICE **devices) { t_stat stat = SCPE_OK; -int i; +size_t i; DEVICE *dptr; MFILE *f = MOpen (); @@ -16058,8 +16113,8 @@ for (i = 0; (dptr = devices[i]) != NULL; i++) { REG *rptr; for (rptr = dptr->registers; (rptr != NULL) && (rptr->name != NULL); rptr++) { - uint32 rsz = SZ_R(rptr); - uint32 memsize = ((rptr->flags & REG_FIT) || (rptr->depth > 1)) ? rptr->depth * rsz : 4; + size_t rsz = SZ_R(rptr); + size_t memsize = ((rptr->flags & REG_FIT) || (rptr->depth > 1)) ? rptr->depth * rsz : 4; t_bool Bad; if (((rptr->width + rptr->offset + CHAR_BIT - 1) / CHAR_BIT) >= sizeof(size_map) / sizeof(size_map[0])) { @@ -16072,8 +16127,8 @@ for (i = 0; (dptr = devices[i]) != NULL; i++) { } if (sim_switches & SWMASK ('R')) /* Debug output */ - sim_printf ("%5s:%-9.9s %s(rdx=%u, wd=%u, off=%u, dep=%u, strsz=%u, objsz=%u, elesz=%u, rsz=%u, %s %s%s membytes=%u, macro=%s)\n", dptr->name, rptr->name, rptr->macro, - rptr->radix, rptr->width, rptr->offset, rptr->depth, (uint32)rptr->stride, (uint32)rptr->obj_size, (uint32)rptr->size, rsz, rptr->desc ? rptr->desc : "", + sim_printf ("%5s:%-9.9s %s(rdx=%u, wd=%u, off=%u, dep=%u, strsz=%" SIZE_T_FMT "u, objsz=%" SIZE_T_FMT "u, elesz=%" SIZE_T_FMT "u, rsz=%" SIZE_T_FMT "u, %s %s%s membytes=%" SIZE_T_FMT "u, macro=%s)\n", dptr->name, rptr->name, rptr->macro, + rptr->radix, rptr->width, rptr->offset, rptr->depth, rptr->stride, rptr->obj_size, rptr->size, rsz, rptr->desc ? rptr->desc : "", (rptr->flags & REG_FIT) ? "REG_FIT" : "", (rptr->flags & REG_VMIO) ? " REG_VMIO" : "", memsize, rptr->macro ? rptr->macro : ""); @@ -16442,6 +16497,36 @@ sim_set_deb_switches (start_deb_switches); return r; } +static t_stat test_scp_debug_logging() +{ +uint32 saved_scp_dev_dbits = sim_scp_dev.dctrl; +FILE *saved_sim_deb = sim_deb; + +sim_scp_dev.dctrl = SCP_LOG_TESTING; +sim_deb = stderr; + +_sim_debug_device (SCP_LOG_TESTING, &sim_scp_dev, "Log message (repeats 3x)\n"); +_sim_debug_device (SCP_LOG_TESTING, &sim_scp_dev, "Log message (repeats 3x)\n"); +_sim_debug_device (SCP_LOG_TESTING, &sim_scp_dev, "Log message (repeats 3x)\n"); +_sim_debug_device (SCP_LOG_TESTING, &sim_scp_dev, "Log message (repeats 3x)\n"); + +if (debug_line_count != 4) + return sim_messagef(SCPE_IERR, "expected debug_line_count == 4, actual %d\n", (int) debug_line_count); + +_sim_debug_device (0xffffffff, &sim_scp_dev, "Different message.\n"); +_sim_debug_flush (); + +if (debug_line_count > 0) + return sim_messagef(SCPE_IERR, "expected debug_line_count == 0, actual %d\n", (int) debug_line_count); + +sim_deb = saved_sim_deb; +sim_scp_dev.dctrl = saved_scp_dev_dbits; + +sim_printf ("Log de-duplication successful.\n"); + +return SCPE_OK; +} + /* * Compiled in unit tests for the various device oriented library * modules: sim_card, sim_disk, sim_tape, sim_ether, sim_tmxr, etc. @@ -16486,6 +16571,8 @@ if ((strcmp (gbuf, "ALL") == 0) || (strcmp (gbuf, "SCP") == 0)) { return sim_messagef (SCPE_IERR, "SCP argument parsing test failed\n"); if (test_scp_event_sequencing () != SCPE_OK) return sim_messagef (SCPE_IERR, "SCP event sequencing test failed\n"); + if (test_scp_debug_logging () != SCPE_OK) + return sim_messagef (SCPE_IERR, "SCP debug logging test failed\n"); } for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { t_stat tstat = SCPE_OK; diff --git a/scp.h b/scp.h index 1c2527c..5ef3bde 100644 --- a/scp.h +++ b/scp.h @@ -184,8 +184,8 @@ CONST char *get_range (DEVICE *dptr, CONST char *cptr, t_addr *lo, t_addr *hi, uint32 rdx, t_addr max, char term); t_stat sim_set_environment (int32 flag, CONST char *cptr); t_stat sim_decode_quoted_string (const char *iptr, uint8 *optr, uint32 *osize); -char *sim_encode_quoted_string (const uint8 *iptr, uint32 size); -void fprint_buffer_string (FILE *st, const uint8 *buf, uint32 size); +char *sim_encode_quoted_string (const uint8 *iptr, size_t size); +void fprint_buffer_string (FILE *st, const uint8 *buf, size_t size); t_value strtotv (CONST char *cptr, CONST char **endptr, uint32 radix); t_svalue strtotsv (CONST char *inptr, CONST char **endptr, uint32 radix); int Fprintf (FILE *f, const char *fmt, ...) GCC_FMT_ATTR(2, 3); @@ -196,7 +196,7 @@ int Fprintf (FILE *f, const char *fmt, ...) GCC_FMT_ATTR(2, 3); t_stat sim_set_memory_load_file (const unsigned char *data, size_t size); int Fgetc (FILE *f); t_stat fprint_val (FILE *stream, t_value val, uint32 rdx, uint32 wid, uint32 fmt); -t_stat sprint_val (char *buf, t_value val, uint32 rdx, uint32 wid, uint32 fmt); +t_stat sprint_val (char *buf, t_value val, uint32 rdx, size_t wid, uint32 fmt); t_stat sim_print_val (t_value val, uint32 radix, uint32 width, uint32 format); const char *sim_fmt_secs (double seconds); const char *sim_fmt_numeric (double number); diff --git a/sim_card.c b/sim_card.c index 0b74611..30e59e6 100644 --- a/sim_card.c +++ b/sim_card.c @@ -250,7 +250,10 @@ static const uint16 ascii_to_dec_029[128] = { 0x604, 0x602, 0x601, 0xA00, 0xC00, 0x600, 0x700,0xf000 }; - +#if SIMH_EVER_USES_THIS +/* This is a static const that isn't referenced in this code. + * Kept for historical refernce. + */ static const uint16 ascii_to_hol_ebcdic[128] = { /* Control */ 0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, /*0-37*/ @@ -294,6 +297,7 @@ static const uint16 ascii_to_hol_ebcdic[128] = { /* X18 X78 Y18 XYT18 */ 0x604, 0x602, 0x601, 0x902, 0x806, 0x502, 0xF02,0xf000 }; +#endif const char sim_ascii_to_six[128] = { /* Control */ @@ -662,8 +666,8 @@ sim_card_eof(UNIT *uptr) struct _card_buffer { uint8 buffer[8192+500]; /* Buffer data */ - int len; /* Amount of data in buffer */ - int size; /* Size of last card read */ + size_t len; /* Amount of data in buffer */ + size_t size; /* Size of last card read */ }; static int _cmpcard(const uint8 *p, const char *s) { @@ -681,9 +685,9 @@ t_stat _sim_parse_card(UNIT *uptr, DEVICE *dptr, struct _card_buffer *buf, uint16 (*image)[80]) { unsigned int mode; uint16 temp; - int i; + size_t i; char c; - int col; + size_t col; sim_debug(DEBUG_CARD, dptr, "Read card "); memset(image, 0, 160); @@ -836,7 +840,7 @@ _sim_parse_card(UNIT *uptr, DEVICE *dptr, struct _card_buffer *buf, uint16 (*ima } } end_card: - sim_debug(DEBUG_CARD, dptr, "-%d-", i); + sim_debug(DEBUG_CARD, dptr, "-%" SIZE_T_FMT "u-", i); /* Scan to end of line, ignore anything after last column */ while (buf->buffer[i] != '\n' && buf->buffer[i] != '\r' && i < buf->len) { @@ -969,9 +973,9 @@ _sim_read_deck(UNIT * uptr, int eof) struct _card_buffer buf; struct card_context *data; DEVICE *dptr; - int i; - int j; - int l; + size_t i; + size_t j; + size_t l; int cards = 0; t_stat r = SCPE_OK; @@ -989,10 +993,7 @@ _sim_read_deck(UNIT * uptr, int eof) do { if (buf.len < 500 && !feof(uptr->fileref)) { l = sim_fread(&buf.buffer[buf.len], 1, 8192, uptr->fileref); - if (l < 0) - r = SCPE_OPENERR; - else - buf.len += l; + buf.len += l; } /* Allocate space for some more cards if needed */ @@ -1019,6 +1020,7 @@ _sim_read_deck(UNIT * uptr, int eof) j = buf.size; for(i = 0; i < l; i++, j++) buf.buffer[i] = buf.buffer[j]; + buf.buffer[i] = '\0'; buf.len -= buf.size; } while (buf.len > 0 && r == SCPE_OK); diff --git a/sim_console.c b/sim_console.c index 59ae607..71e2710 100644 --- a/sim_console.c +++ b/sim_console.c @@ -530,8 +530,8 @@ struct BITSAMPLE_REG { }; typedef struct REMOTE REMOTE; struct REMOTE { - int32 buf_size; - int32 buf_ptr; + size_t buf_size; + size_t buf_ptr; char *buf; char *act_buf; size_t act_buf_size; @@ -908,7 +908,7 @@ if ((!sim_oline) && (sim_log)) { sim_oline = NULL; if ((rem->act == NULL) && (!tmxr_input_pending_ln (lp))) { - int32 unwritten; + size_t unwritten; do { unwritten = tmxr_send_buffered_data (lp); @@ -952,7 +952,7 @@ sim_switches = saved_switches; /* restore original switches */ /* Clear pending actions */ -static char *sim_rem_clract (int32 line) +static char *sim_rem_clract (size_t line) { REMOTE *rem = &sim_rem_consoles[line]; @@ -962,7 +962,7 @@ return rem->act = NULL; /* Set up pending actions */ -static void sim_rem_setact (int32 line, const char *action) +static void sim_rem_setact (size_t line, const char *action) { if (action) { size_t act_size = strlen (action) + 1; @@ -981,7 +981,7 @@ else /* Get next pending action, if any */ -static char *sim_rem_getact (int32 line, char *buf, int32 size) +static char *sim_rem_getact (size_t line, char *buf, size_t size) { char *ep; size_t lnt; @@ -1296,10 +1296,10 @@ return stat; t_stat sim_rem_con_repeat_svc (UNIT *uptr) { -int line = uptr - rem_con_repeat_units; +size_t line = uptr - rem_con_repeat_units; REMOTE *rem = &sim_rem_consoles[line]; -sim_debug (DBG_REP, &sim_remote_console, "sim_rem_con_repeat_svc(line=%d) - interval=%d usecs\n", line, rem->repeat_interval); +sim_debug (DBG_REP, &sim_remote_console, "sim_rem_con_repeat_svc(line=%" SIZE_T_FMT "u) - interval=%d usecs\n", line, rem->repeat_interval); if (rem->repeat_interval) { rem->repeat_pending = TRUE; sim_activate_after (uptr, rem->repeat_interval); /* reschedule */ @@ -1362,10 +1362,10 @@ for (line = 0; line < sim_rem_con_tmxr.lines; line++) t_stat sim_rem_con_smp_collect_svc (UNIT *uptr) { -int line = uptr - rem_con_smp_smpl_units; +size_t line = uptr - rem_con_smp_smpl_units; REMOTE *rem = &sim_rem_consoles[line]; -sim_debug (DBG_SAM, &sim_remote_console, "sim_rem_con_smp_collect_svc(line=%d) - interval=%d, dither=%d%%\n", line, rem->smp_sample_interval, rem->smp_sample_dither_pct); +sim_debug (DBG_SAM, &sim_remote_console, "sim_rem_con_smp_collect_svc(line=%" SIZE_T_FMT "u) - interval=%d, dither=%d%%\n", line, rem->smp_sample_interval, rem->smp_sample_dither_pct); if (rem->smp_sample_interval && (rem->smp_reg_count != 0)) { int32 event_time = rem->smp_sample_interval; diff --git a/sim_defs.h b/sim_defs.h index 1f81625..3954ca0 100644 --- a/sim_defs.h +++ b/sim_defs.h @@ -274,11 +274,9 @@ typedef uint32 t_value; #if defined (USE_INT64) && defined (USE_ADDR64) /* 64b address */ typedef t_uint64 t_addr; #define T_ADDR_W 64 -#define T_ADDR_FMT LL_FMT #else /* 32b address */ typedef uint32 t_addr; #define T_ADDR_W 32 -#define T_ADDR_FMT "" #endif /* end 64b address */ #if defined (_WIN32) @@ -294,14 +292,11 @@ typedef uint32 t_addr; #endif #if defined (_WIN32) /* Actually, a GCC issue */ -#define LL_FMT "I64" #define LL_TYPE long long #else #if defined (__VAX) /* No 64 bit ints on VAX */ -#define LL_FMT "l" #define LL_TYPE long #else -#define LL_FMT "ll" #define LL_TYPE long long #endif #endif @@ -615,7 +610,7 @@ struct UNIT { uint16 us10; /* device specific */ uint32 disk_type; /* Disk specific info */ void *tmxr; /* TMXR linkage */ - uint32 recsize; /* Tape specific info */ + size_t recsize; /* Tape specific info */ t_addr tape_eom; /* Tape specific info */ t_bool (*cancel)(UNIT *); double usecs_remaining; /* time balance for long delays */ @@ -800,8 +795,8 @@ struct MTAB { /* Search table */ struct SCHTAB { - int32 logic; /* logical operator */ - int32 boolop; /* boolean operator */ + size_t logic; /* logical operator */ + size_t boolop; /* boolean operator */ uint32 count; /* value count in mask and comp arrays */ t_value *mask; /* mask for logical */ t_value *comp; /* comparison for boolean */ @@ -836,7 +831,7 @@ struct BRKTYPTAB { struct EXPTAB { uint8 *match; /* match string */ - uint32 size; /* match string size */ + size_t size; /* match string size */ char *match_pattern; /* match pattern for format */ int32 cnt; /* proceed count */ uint32 after; /* delay before halting */ @@ -859,11 +854,11 @@ struct EXPECT { DEVICE *dptr; /* Device (for Debug) */ uint32 dbit; /* Debugging Bit */ EXPTAB *rules; /* match rules */ - int32 size; /* count of match rules */ + size_t size; /* count of match rules */ uint8 *buf; /* buffer of output data which has produced */ - uint32 buf_ins; /* buffer insertion point for the next output data */ - uint32 buf_size; /* buffer size */ - uint32 buf_data; /* count of data in buffer */ + size_t buf_ins; /* buffer insertion point for the next output data */ + size_t buf_size; /* buffer size */ + size_t buf_data; /* count of data in buffer */ }; /* Send Context */ @@ -877,8 +872,8 @@ struct SEND { double next_time; /* execution time when next data can be sent */ uint8 *buffer; /* buffer */ size_t bufsize; /* buffer size */ - int32 insoff; /* insert offset */ - int32 extoff; /* extra offset */ + size_t insoff; /* insert offset */ + size_t extoff; /* extra offset */ }; /* Debug table */ @@ -1137,6 +1132,15 @@ struct MEMFILE { #include "sim_console.h" #include "sim_timer.h" #include "sim_fio.h" +#include "sim_printf_fmts.h" + +/* General-purpose error value for size_t types; check using + equality.*/ + +#define GENERIC_SIZE_T_ERROR ((size_t) -1) + +#define SIZE_T_IO_ERROR GENERIC_SIZE_T_ERROR +#define IS_SIZE_T_IO_ERROR(thing) ((thing) == GENERIC_SIZE_T_ERROR) /* Macro to ALWAYS execute the specified expression and fail if it evaluates to false. */ /* This replaces any references to "assert()" which should never be invoked */ diff --git a/sim_ether.c b/sim_ether.c index 3d4ca07..e1013bc 100644 --- a/sim_ether.c +++ b/sim_ether.c @@ -2177,6 +2177,10 @@ return NULL; } #endif +/* eth_set_async + * + * Turn on reciever processing which can be either asynchronous or polled + */ t_stat eth_set_async (ETH_DEV *dev, int latency) { #if !defined(USE_READER_THREAD) || !defined(SIM_ASYNCH_IO) @@ -2186,7 +2190,7 @@ return sim_messagef (SCPE_NOFNC, "%s", msg); #else int wakeup_needed; -dev->asynch_io = 1; +dev->asynch_io = sim_asynch_enabled; dev->asynch_io_latency = latency; pthread_mutex_lock (&dev->lock); wakeup_needed = (dev->read_queue.count != 0); @@ -2199,6 +2203,10 @@ if (wakeup_needed) { return SCPE_OK; } +/* eth_clr_async + * + * Turn off reciever processing + */ t_stat eth_clr_async (ETH_DEV *dev) { #if !defined(USE_READER_THREAD) || !defined(SIM_ASYNCH_IO) diff --git a/sim_fio.c b/sim_fio.c index 5032140..f096b81 100644 --- a/sim_fio.c +++ b/sim_fio.c @@ -161,8 +161,7 @@ return c; void sim_buf_copy_swapped (void *dbuf, const void *sbuf, size_t size, size_t count) { -size_t j; -int32 k; +size_t j, k; const unsigned char *sptr = (const unsigned char *)sbuf; unsigned char *dptr = (unsigned char *)dbuf; @@ -171,8 +170,12 @@ if (sim_end || (size == sizeof (char))) { return; } for (j = 0; j < count; j++) { /* loop on items */ - for (k = (int32)(size - 1); k >= 0; k--) - *(dptr + k) = *sptr++; + /* Unsigned countdown loop. Predecrement k before it's used inside the + loop so that k == 0 in the loop body to process the last item, then + terminate. Initialize k to size for the same reason: the predecrement + gives us size - 1 in the loop body. */ + for (k = size; k > 0; /* empty */) + *(dptr + --k) = *sptr++; dptr = dptr + size; } } @@ -953,6 +956,8 @@ char *sim_getcwd (char *buf, size_t buf_size) { #if defined (VMS) return getcwd (buf, buf_size, 0); +#elif defined(__MINGW64__) ||defined(_MSC_VER) || defined(__MINGW32__) +return _getcwd (buf, (int) buf_size); #else return getcwd (buf, buf_size); #endif diff --git a/sim_imd.c b/sim_imd.c index b9794d2..45c1019 100644 --- a/sim_imd.c +++ b/sim_imd.c @@ -123,7 +123,8 @@ static t_stat diskParse(DISK_INFO *myDisk, uint32 isVerbose) uint8 sectorHeadMap[256]; uint8 sectorCylMap[256]; uint32 sectorSize, sectorHeadwithFlags, sectRecordType; - uint32 hdrBytes, i; + size_t hdrBytes; + uint32 i; uint8 start_sect; uint32 TotalSectorCount = 0; @@ -160,7 +161,7 @@ static t_stat diskParse(DISK_INFO *myDisk, uint32 isVerbose) break; /* detected end of IMD file */ if (hdrBytes != 5) { - sim_printf("SIM_IMD: Header read returned %d bytes instead of 5.\n", hdrBytes); + sim_printf("SIM_IMD: Header read returned %" SIZE_T_FMT "u bytes instead of 5.\n", hdrBytes); return (SCPE_OPENERR); } @@ -361,7 +362,8 @@ t_stat diskCreate(FILE *fileref, const char *ctlr_comment) char *curptr; char *result; uint8 answer; - int32 len, remaining; + size_t len; + size_t remaining; if(fileref == NULL) { return (SCPE_OPENERR); @@ -386,7 +388,8 @@ t_stat diskCreate(FILE *fileref, const char *ctlr_comment) remaining = MAX_COMMENT_LEN; do { sim_printf("IMD> "); - result = fgets(curptr, remaining - 3, stdin); + /* ISO C says that the 2nd argument is an int, not size_t. */ + result = fgets(curptr, (int) (remaining - 3), stdin); if ((result == NULL) || (strcmp(curptr, ".\n") == 0)) { remaining = 0; } else { diff --git a/sim_printf_fmts.h b/sim_printf_fmts.h new file mode 100644 index 0000000..14f9eca --- /dev/null +++ b/sim_printf_fmts.h @@ -0,0 +1,94 @@ +/*~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~ + * sim_printf_fmts.h + * + * Cross-platform printf() formats for simh data types. Refactored out to + * this header so that these formats are avaiable to more than SCP. + * + * Author: B. Scott Michel + * + * "scooter me fecit" + *~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~*/ + +#pragma once +#if !defined(SIM_PRINTF_H) + +/* cross-platform printf() format specifiers: + * + * Note: MS apparently does recognize "ll" as "l" in its printf() routines, but "I64" is + * preferred for 64-bit types. + * + * MinGW note: __MINGW64__ and __MINGW32__ are both defined by 64-bit gcc. Check + * for __MINGW64__ before __MINGW32__. + * + * + * LL_FMT: long long format modifier, e.g. "%016" LL_FMT "x" + * SIZE_T: size_t format modifier, e.g., "%" SIZE_T_FMT "u" (can use "d", but you will + * probably get a warning.) + * T_UINT64_FMT: t_uint64 format modifier, e.g. "%016" T_UINT64_FMT "x" + * T_INT64_FMT: t_int64 format modifier, e.g., "%" T_INT64_FMT "d" + * POINTER_FMT: Format modifier for pointers, e.g. "%08" POINTER_FMT "X" +*/ + +#if defined (_WIN32) || defined(_WIN64) + +# if defined(__MINGW64__) +# define LL_FMT "I64" +# define SIZE_T_FMT "I64" +# elif defined(_MSC_VER) || defined(__MINGW32__) +# define LL_FMT "ll" +# define SIZE_T_FMT "z" +# else + /* Graceful fail -- shouldn't ever default to this on a Windows platform. */ +# define LL_FMT "ll" +# define SIZE_T_FMT "I32" +# endif + +# define T_UINT64_FMT "I64" +# define T_INT64_FMT "I64" +# define POINTER_FMT "p" + +#elif defined(__GNU_LIBRARY__) || defined(__GLIBC__) || defined(__GLIBC_MINOR__) || \ + defined(__APPLE__) + +/* GNU libc (Linux) and macOS */ +# define LL_FMT "ll" +# define SIZE_T_FMT "z" +# define T_UINT64_FMT "ll" +# define T_INT64_FMT "ll" +# define POINTER_FMT "p" + +#elif defined(__VAX) + +/* No 64 bit ints on VAX, nothing special about size_t */ +# define LL_FMT "l" +# define SIZE_T_FMT "" +# define T_UINT64_FMT "" +# define T_INT64_FMT "" +# define POINTER_FMT "" + +#else +/* Defaults. */ +# define LL_FMT "ll" +# define SIZE_T_FMT "" +# define T_UINT64_FMT "" +# define T_INT64_FMT "" +# define POINTER_FMT "" +#endif + + +#if defined (USE_INT64) && defined (USE_ADDR64) +# define T_ADDR_FMT T_UINT64_FMT +#else +# define T_ADDR_FMT "" +#endif + +#if defined (USE_INT64) +# define T_VALUE_FMT T_UINT64_FMT +# define T_SVALUE_FMT T_INT64_FMT +#else +# define T_VALUE_FMT "" +# define T_SVALUE_FMT "" +#endif + +#define SIM_PRINTF_H +#endif diff --git a/sim_sock.c b/sim_sock.c index 1d834ab..cd67895 100644 --- a/sim_sock.c +++ b/sim_sock.c @@ -721,7 +721,7 @@ if (c != NULL) { if ((c - validate_addr) > sizeof (v_cpy) - 1) return status; memcpy (v_cpy, validate_addr, c - validate_addr); /* Copy everything before the / */ - v_cpy[1 + c - validate_addr] = '\0'; /* NUL terminate the result */ + v_cpy[c - validate_addr] = '\0'; /* NUL terminate the result */ validate_addr = v_cpy; /* Use the original string minus the prefix specifier */ } if (p_getaddrinfo(validate_addr, NULL, NULL, &ai_validate)) diff --git a/sim_tape.c b/sim_tape.c index 4dd0c89..20347ff 100644 --- a/sim_tape.c +++ b/sim_tape.c @@ -439,7 +439,7 @@ typedef struct HDR4 { /* Also EOF4, EOV4 */ } HDR4; typedef struct TAPE_RECORD { - uint32 size; + size_t size; uint8 data[1]; } TAPE_RECORD; @@ -448,7 +448,7 @@ typedef struct MEMORY_TAPE { uint32 file_count; /* number of labeled files */ uint32 record_count; /* number of entries in the record array */ uint32 array_size; /* allocated size of records array */ - uint32 block_size; /* tape block size */ + size_t block_size; /* tape block size */ TAPE_RECORD **records; VOL1 vol1; } MEMORY_TAPE; @@ -505,7 +505,7 @@ static struct ansi_tape_parameters { }; -static MEMORY_TAPE *ansi_create_tape (const char *label, uint32 block_size, uint32 ansi_type); +static MEMORY_TAPE *ansi_create_tape (const char *label, size_t block_size, uint32 ansi_type); static MEMORY_TAPE *memory_create_tape (void); static void memory_free_tape (void *vtape); static void sim_tape_add_ansi_entry (const char *directory, @@ -513,7 +513,7 @@ static void sim_tape_add_ansi_entry (const char *directory, t_offset FileSize, const struct stat *filestat, void *context); -static t_bool memory_tape_add_block (MEMORY_TAPE *tape, uint8 *block, uint32 size); +static t_bool memory_tape_add_block (MEMORY_TAPE *tape, uint8 *block, size_t size); typedef struct DOS11_HDR { uint16 fname[2]; /* File name (RAD50 - 6 characters) */ @@ -810,7 +810,8 @@ switch (MT_GET_FMT (uptr)) { tape->block_size = uptr->recsize; block = (uint8 *)calloc (1, tape->block_size + 3); while (!feof (f) && !error) { - if (fgets ((char *)block, tape->block_size + 3, f)) { + /* fgest() read size is int, cast accordingly. */ + if (fgets ((char *)block, (int) (tape->block_size + 3), f)) { size_t len = strlen ((char *)block); while ((len > 0) && @@ -890,7 +891,7 @@ switch (MT_GET_FMT (uptr)) { if (uptr->recsize == 0) uptr->recsize = TAR_DFLT_RECSIZE; /* Apply default block size */ if ((uptr->recsize % 512) != 0) - return sim_messagef (SCPE_ARG, "TAR format block size of %u is not a multiple of 512\n", uptr->recsize); + return sim_messagef (SCPE_ARG, "TAR format block size of %" SIZE_T_FMT "u is not a multiple of 512\n", uptr->recsize); sim_switches |= SWMASK ('E'); /* The TAR file must exist */ /* fall through */ default: @@ -1228,7 +1229,7 @@ t_awshdr awshdr; size_t rdcnt; t_mtrlnt buffer [256]; /* local tape buffer */ t_addr saved_pos = uptr->pos; -uint32 bufcntr, bufcap; /* buffer counter and capacity */ +size_t bufcntr, bufcap; /* buffer counter and capacity */ int32 runaway_counter, sizeof_gap; /* bytes remaining before runaway and bytes per gap */ t_stat status = MTSE_OK; @@ -1524,7 +1525,8 @@ switch (f) { /* otherwise the read method if (tape->records[uptr->pos]->size == 0) status = MTSE_TMK; else - *bc = tape->records[uptr->pos]->size; + /* Should check range here. */ + *bc = (t_mtrlnt) tape->records[uptr->pos]->size; ++uptr->pos; } } @@ -1602,7 +1604,7 @@ t_tpclnt tpcbc; t_awshdr awshdr; size_t rdcnt; t_mtrlnt buffer [256]; /* local tape buffer */ -uint32 bufcntr, bufcap; /* buffer counter and capacity */ +size_t bufcntr, bufcap; /* buffer counter and capacity */ int32 runaway_counter, sizeof_gap; /* bytes remaining before runaway and bytes per gap */ t_stat status = MTSE_OK; @@ -1643,7 +1645,7 @@ switch (f) { /* otherwise the read me bufcap = 1; /* then start with just one marker */ else if (uptr->pos < sizeof (buffer)) /* otherwise if less than a full buffer remains */ - bufcap = (uint32) uptr->pos /* then reduce the capacity accordingly */ + bufcap = (size_t) uptr->pos /* then reduce the capacity accordingly */ / sizeof (t_mtrlnt); else /* otherwise reset the capacity */ @@ -1859,7 +1861,8 @@ switch (f) { /* otherwise the read me if (tape->records[uptr->pos]->size == 0) status = MTSE_TMK; else - *bc = tape->records[uptr->pos]->size; + /* Should check range here. */ + *bc = (t_mtrlnt) tape->records[uptr->pos]->size; } break; @@ -2152,7 +2155,7 @@ if (bc) (void)sim_fwrite (buf, sizeof (uint8), bc, uptr->fileref); uptr->pos += sizeof (awshdr) + bc; if ((!replacing_record) || (bc == 0)) { - awshdr.prelen = bc; + awshdr.prelen = (t_awslnt) bc; awshdr.nxtlen = 0; awshdr.rectyp = AWS_TMK; (void)sim_fwrite (&awshdr, sizeof (t_awslnt), 3, uptr->fileref); @@ -2178,13 +2181,13 @@ if (ctx == NULL) /* if not properly attac if (sim_tape_wrp (uptr)) /* write prot? */ return MTSE_WRP; (void)sim_tape_seek (uptr, uptr->pos); /* set pos */ -(void)sim_fwrite (&dat, sizeof (t_mtrlnt), 1, uptr->fileref); +(void)sim_fwrite (&dat, sizeof (uint32), 1, uptr->fileref); if (ferror (uptr->fileref)) { /* error? */ MT_SET_PNU (uptr); return sim_tape_ioerr (uptr); } sim_debug_unit (MTSE_DBG_STR, uptr, "wr_lnt: lnt: %d, pos: %" T_ADDR_FMT "u\n", dat, uptr->pos); -uptr->pos = uptr->pos + sizeof (t_mtrlnt); /* move tape */ +uptr->pos = uptr->pos + sizeof (uint32); /* move tape */ if (uptr->pos > uptr->tape_eom) uptr->tape_eom = uptr->pos; /* update EOM */ return MTSE_OK; @@ -3503,7 +3506,7 @@ return msgbuf; static t_stat sim_tape_validate_tape (UNIT *uptr) { t_addr saved_pos = uptr->pos; -uint32 data_total = 0; +size_t data_total = 0; uint32 tapemark_total = 0; uint32 record_total = 0; uint32 unique_record_sizes = 0; @@ -3638,7 +3641,7 @@ if (!stop_cpu) { /* if SIGINT didn't interrupt the scan */ if ((r != MTSE_EOM) || (sim_switches & SWMASK ('V')) || (sim_switches & SWMASK ('L')) || (remaining_data > 0) || (unique_record_sizes > 2 * tapemark_total)) { - sim_messagef (SCPE_OK, "%s %u bytes of tape data (%u record%s, %u tapemark%s)\n", + sim_messagef (SCPE_OK, "%s %" SIZE_T_FMT "u bytes of tape data (%u record%s, %u tapemark%s)\n", (r != MTSE_EOM) ? "After processing" : "contains", data_total, record_total, (record_total == 1) ? "" : "s", tapemark_total, (tapemark_total == 1) ? "" : "s"); @@ -3889,7 +3892,8 @@ FILE *fTAR2 = NULL; FILE *fBIN = NULL; FILE *fTXT = NULL; FILE *fVAR = NULL; -int i, j, k; +int i; +size_t j, k; t_tpclnt tpclnt; t_mtrlnt mtrlnt; t_awslnt awslnt; @@ -3986,13 +3990,16 @@ if (aws_stat != MTSE_OK) { sim_switches = saved_switches; stat = SCPE_OK; for (i=0; i 0, otherwise, this test becomes interesting. */ + for (j=0; j < (size_t) records; j++) { awsrec_typ = AWS_REC; if (sim_switches & SWMASK ('V')) - sim_printf ("Writing %d byte record\n", rec_size); + sim_printf ("Writing %" SIZE_T_FMT "u byte record\n", rec_size); for (k=0; kfileref); (void)sim_fwrite (&mtrlnt, sizeof (mtrlnt), 1, uptr->fileref); (void)sim_fwrite (&mtrlnt, sizeof (mtrlnt), 1, uptr->fileref); -for (j=0; jhz) { /* running? */ - rtc->currd = (int32)(sim_throt_cps / rtc->hz);/* use throttle calibration */ - rtc->ticks = rtc->hz - 1; /* force clock calibration on next tick */ - rtc->rtime = sim_throt_ms_start - 1000 + 1000/rtc->hz;/* adjust calibration parameters to reflect throttled rate */ - rtc->gtime = sim_throt_inst_start - sim_throt_cps + sim_throt_cps/rtc->hz; - rtc->nxintv = 1000; - rtc->based = rtc->currd; - if (rtc->clock_unit) - sim_activate_abs (rtc->clock_unit, rtc->currd);/* reschedule next tick */ - } - } + _sim_timer_adjust_cal(); /* adjust timer calibrations */ } break; @@ -2038,6 +2026,30 @@ sim_activate (uptr, sim_throt_wait); /* reschedule */ return SCPE_OK; } +/* Run through all timers and adjust the calibration for each */ +/* one that is running to reflect the throttle rate */ +static void _sim_timer_adjust_cal(void) +{ + int32 tmr; + RTC *rtc = NULL; + + for (tmr=0; tmr<=SIM_NTIMERS; tmr++) { + rtc = &rtcs[tmr]; + + if (rtc->hz) { /* running? */ + rtc->currd = (int32)(sim_throt_cps / rtc->hz);/* use throttle calibration */ + rtc->ticks = rtc->hz - 1; /* force clock calibration on next tick */ + rtc->rtime = sim_throt_ms_start - 1000 + 1000/rtc->hz;/* adjust calibration parameters to reflect throttled rate */ + rtc->gtime = sim_throt_inst_start - sim_throt_cps + sim_throt_cps/rtc->hz; + rtc->nxintv = 1000; + rtc->based = rtc->currd; + + if (rtc->clock_unit) + sim_activate_abs (rtc->clock_unit, rtc->currd);/* reschedule next tick */ + } + } +} + /* Clock assist activites */ t_stat sim_timer_tick_svc (UNIT *uptr) {