1
0
mirror of https://github.com/PDP-10/klh10.git synced 2026-03-11 04:37:05 +00:00

Merge branch 'master' into mmcm-tuntap

Merged these small conflicts:
	src/dpni20.c
	src/osdnet.c
	src/osdnet.h
Compile-tested on NetBSD and Linux, but not run-tested.
This commit is contained in:
Olaf Seibert
2015-07-22 00:02:26 +02:00
45 changed files with 617 additions and 21050 deletions

61
bld/MAKE-ALL Executable file
View File

@@ -0,0 +1,61 @@
#!/bin/sh
#
# Simple build script to build all 3 cpu models in one go.
#
# Usage: MAKE-ALL buildtarget
#
# where buildtarget is for example nbaxp (NetBSD for Alpha AXP, or
# any other little-endian 64-bit CPU).
DEFBUILD=nbaxp
# TOP=/some/where/klh10
# Remove "/bld" or "/bld/nbaxp" from current directory, if it's there.
# In the latter case, assume that as the build type by default.
# If none of these current directories apply, this script must be run
# from the $TOP directory, and the build will be for the host as
# indicated on the command line, or nbaxp by default.
case "${PWD}" in
*/bld)
TOP="${PWD%/bld}"
;;
*/bld/*)
DEFBUILD="${PWD##*/}"
TOP="${PWD%/bld/*}"
;;
*)
TOP="$PWD"
;;
esac
BUILD=${1-$DEFBUILD}
cd $TOP || exit 1
echo "This script builds all PDP-10 variants for host $BUILD."
buildone() {
(
model="$1"
export KLH10_HOME=$TOP/new/${BUILD}-${model}
mkdir -p ${KLH10_HOME}
cd bld/$BUILD
make clean
make base-${model} CONFFLAGS_AUX=-DKLH10_I_CIRC=1
make tapedd vdkfmt wxtest enaddr
make install
)
}
echo "Building KL"
buildone kl
echo "Building KS"
buildone ks
echo "Building KS-ITS"
buildone ks-its

1
bld/lnaxp/Makefile Symbolic link
View File

@@ -0,0 +1 @@
../../src/Mk-lnaxp.mk

View File

@@ -1,2 +1,5 @@
#!/bin/sh
make base-kl CONFFLAGS_AUX=-DKLH10_I_CIRC=1
# or
# make base-ks CONFFLAGS_AUX=-DKLH10_I_CIRC=1
# make base-ks-its CONFFLAGS_AUX=-DKLH10_I_CIRC=1

View File

@@ -1,2 +1,4 @@
#!/bin/sh
export KL10HOME=/scratch/tops20/emulators/panda-dist/i386
make base-kl CONFFLAGS_AUX=-DKLH10_I_CIRC=1
#make base-ks-its CONFFLAGS_AUX=-DKLH10_I_CIRC=1

View File

@@ -53,8 +53,10 @@ for other ports such as MacOS or Windows have not yet been written.
$ cd <distrib>/bld/<platform>
$ make base-kl ;;; or base-ks or base-ks-its
or to make all variants, installing to <distrib>/new/<platform>-<model>:
$ ../MAKE-ALL
Or see the "Building" section farther on.
Or see the "BUILDING FROM SOURCES" section farther on.
Read "doc/dfkfb.txt" if you want to do a quick KL performance test now.
@@ -175,6 +177,16 @@ config file if they don't already exist (correct as of FreeBSD 4.2):
pseudo-device bpf 1 # Need at least one for NI20 or IMP
pseudo-device tun 1 # Need at least one for IMP
NetBSD
------
See The NetBSD Guide, chapter 17.9 "Kernel Tuning" for information on
how to recompile a kernel. You need at least these options (as of 3.0):
options SYSVSHM # System V-like memory sharing
options SHMMAXPGS=10240 # 2048 pages is the default, >8192 for KLH10
pseudo-device tap # cloning device for NI20
pseudo-device bridge # cloning device for NI20
Linux
-----
@@ -223,6 +235,11 @@ BUILDING FROM SOURCES
Notes:
The "*axp" directories are not only useful for Alpha AXP hosts, but also
for any other little-endian 64-bit CPU. That includes amd64 aka x86_64.
While the x86 configuration may work on amd64, it is likely to be
a bit less efficient.
Solaris has two possible Makefiles; the default uses GCC, but you
can change the link to Mk-solsparc-cc.mk which uses Sun's C compiler.
@@ -1116,6 +1133,36 @@ mistakenly "fixed" to disallow it (FreeBSD).
other host before telnetting back into the KN10. A better solution
would be to fix those OSes that are open-source, and push to have
these fixes incorporated in the standard releases.
For NetBSD (it may work on FreeBSD too) there exists a better
solution. A special configuration is created with a virtual ethernet
segment that has its host-side in the form of the interface tap0 (as in
the example below). The tap0 interface is bridged to the real network
interface. The NI20 is at the "other end" of the virtual ethernet.
(This differs from the other connectivity methods where the named
interface is the one that is basically used as the NI20). The NI20 is
therefore a dedicated interface:
devdef ni0 564 ni20 ipaddr=10.0.0.51 ifc=tap0 dedic=true
If the named tap interface already exists, no further changes to its
configuration are made. You can use this for alternative connectivity,
such as routed on the 10.0.1.0/24 subnet (instead of bridged):
# To the shell, suppose your real network is 10.0.0.0/24,
# create a 10.0.1.0/24 network for KLH:
ifconfig tap0 create inet 10.0.1.1 netmask 255.255.255.0 up
; in .ini file:
devdef ni0 564 ni20 ipaddr=10.0.1.51 ifc=tap0 dedic=true
! in SYSTEM:INTERNET.ADDRESS on TOPS-20 v7.0
IPNI#0,10 0 1 51,PACKET-SIZE:1500,DEFAULT,PREFERRED
! in SYSTEM:INTERNET.ADDRESS on TOPS-20 v7.1
IPNI#0,10.0.1.51,PACKET-SIZE:1500,LOGICAL-HOST-MASK:255.255.255.0,DEFAULT,PREFERRED
! in SYSTEM:INTERNET.GATEWAYS on TOPS-20 v7.x
PRIME 10.0.1.1
(If TOPS-20 v7.0 can't do subnetting it might be better to use a
192.168.2.0/24 network)
LHDH (IMP): (KS-ITS only)

View File

@@ -12,7 +12,12 @@ devdef mta0 rh1.0 tm03 type=tu45
; Need KLNI to avoid LAPRBF BUGCHKs - use valid address if known
;
devdef ni0 564 ni20 ipaddr=10.0.0.51
; devdef ni0 564 ni20 ipaddr=10.0.0.51
; The (NetBSD/FreeBSD) version with tap(4) and bridge(4) creates the named
; tap device dynamically and bridges it to the default interface.
; If you want it differently (for instance routed instead of bridged),
; you can create the tap yourself and it will be used as it is.
devdef ni0 564 ni20 ipaddr=10.0.0.51 ifc=tap0 dedic=true
; Load disk bootstrap directly
load boot.sav

12
run/ksits/setvt100 Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/sh
# This is a shell script for running in an XTerm
# to set the opposite of the settings from the setvt52 script.
# Reverse the settings from setvt52 (SET <-> RESET)
printf '\e< ' # Exit VT52 mode (Enter VT100 mode).
printf '\e[?67h' # Ps = 6 7 -> Backarrow key sends delete (DECBKM)
printf '\e[?1036h' # Ps = 1 0 3 6 -> Send ESC when Meta modifies a key (enables the metaSendsEscape resource).
stty intr ^C

24
run/ksits/setvt52 Executable file
View File

@@ -0,0 +1,24 @@
#!/bin/sh
#
# This is a shell script for running in an XTerm
# to set it to better modes to run ITS in:
#
# - VT52 mode;
# - the backarrow key sends DEL (not backspace);
# - the meta key sends ESC before a key instead of setting its 8th bit;
# - correct terminal size.
printf '\e< ' # Exit VT52 mode (Enter VT100 mode).
# CSI ? Pm l DEC Private Mode Reset (DECRST)
printf '\e[?67l' # Ps = 6 7 -> Backarrow key sends delete (DECBKM)
# CSI ? Pm h DEC Private Mode Set (DECSET)
printf '\e[?1036l' # Ps = 1 0 3 6 -> Send ESC when Meta modifies a key
# (enables the metaSendsEscape resource).
# CSI Ps ; Ps ; Ps t Window manipulation
# May be disabled using the allowWindowOps resource.
printf '\e[8;24;80t' # Ps = 8 ; height ; width -> Resize the text area to [height;width] in characters.
printf '\e[?2l' # Ps = 2 -> Designate VT52 mode (DECANM).
# After this, run ITS, then setvt100.

View File

@@ -359,6 +359,30 @@ base-kl:
-DKLH10_CLIENT=\\\"MyKL\\\" \
$(CONFFLAGS_AUX) "
###
# On Sat, 26 Dec 2009, Jean-Marc Bourguet posted:
#
# > [DTE: Bad to-10 BP 442200,,733000][dte_10xfrbeg: 10cnt left: 4086][dte_10xfrbeg: out of data, no I bit]
#
# This is a known problem on some Linux systems with high performance
# hardware. As far as I know, Ken has not found a fix for it.
#
# The workaround is to rebuild klh10 with a special configuration that
# avoids the esoteric real-time-interrupt mechanisms.
#
# In klh20-2.0h/src/Makefile, lines 357 and 358, you will find:
# -DKLH10_ITIME_INTRP=1 \
# -DKLH10_CTYIO_INT=1 \
#
# Change both of these lines so they now read:
# -DKLH10_ITIME_SYNC=1 \
# -DKLH10_CTYIO_INT=0 \
#
# You should only do this on a system which has this problem. It will run
# on other systems, but will eat up CPU unnecessarily.
#
# -- Mark --
####################################################################
## Lintish versions to see how many compiler warnings we can generate
##

View File

@@ -1,726 +0,0 @@
# KLH10 Makefile.
# $Id: Makefile.mk,v 2.6 2002/03/21 09:44:05 klh Exp $
#
# Copyright © 1992, 1993, 2001 Kenneth L. Harrenstien
# All Rights Reserved
#
# This file is part of the KLH10 Distribution. Use, modification, and
# re-distribution is permitted subject to the terms in the file
# named "LICENSE", which contains the full text of the legal notices
# and should always accompany this Distribution.
#
# This software is provided "AS IS" with NO WARRANTY OF ANY KIND.
#
# This notice (including the copyright and warranty disclaimer)
# must be included in all copies or derivations of this software.
#
#####################################################################
# KLH10 Makefile scheme
#
# <dist>/src/
# Makefile - Top-level makefile for in-src build (not recommended)
# Makefile.mk - All generic rules and definitions
# Mk-<plat>.mk - Platform-specific definitions
#
# <dist>/bld/<plat>
# Makefile -> ../../src/Mk-<plat>.mk
# (or local version thereof)
# [any locally munged .h files]
#
# Each top-level makefile should define at least the following:
# SRC = <location of source dir>
#
#####################################################################
# Basic default definitions.
# Normally these will be overridden by build-specific make
# invocations, by both or either of:
# (1) concatenation of a platform-specific makefile of the
# form "Mk-<plat>.mk"
# (the most recent defs override these defaults)
# (2) command line definitions, which override those from any files.
# Generic compile/link flags
# Suitable for plain vanilla Unix but normally overridden.
CC = cc
CFLAGS = -c -I. -I$(SRC)
CFLAGS_AUX =
CFLAGS_LINT =
LINKER = $(CC)
LDFLAGS =
LDOUTF = -o
LIBS =
# Variables specific to this makefile setup
# SRC and MAKE_CENV are normally overridden.
SRC = ../../src
MAKE_CENV =
CENVFLAGS =
CONFFLAGS =
CONFFLAGS_AUX =
MAKER = make -f $(SRC)/Makefile.mk $(MAKE_CENV)
BUILDMOD = $(CC) $(CFLAGS) $(CFLAGS_AUX) \
$(CENVFLAGS) $(CONFFLAGS) $(CONFFLAGS_AUX)
## Default if no target given to make.
##
default:
@echo 'Intended to be invoked from a bld/<conf>/ directory, look'
@echo 'at bld/*/Makefile for examples.'
## Default if no target given to bld/<conf> invocation
##
usage:
@echo 'Use "make <target>", eg "make base-kl"'
@echo 'Normally the target is one of these 3 base configs:'
@echo ' base-kl KL10 version for TOPS (kn10-kl and utils)'
@echo ' base-ks KS10 version for TOPS (kn10-ks and utils)'
@echo ' base-ks-its KS10 version for ITS (kn10-ks and utils)'
@echo 'Or these utilities:'
@echo ' tapedd Tape copy & conversion'
@echo ' vdkfmt Virtual disk copy & conversion'
@echo ' wxtest Test w10_t internals'
@echo ' enaddr Show and manage ether interfaces'
@echo 'Or these actions:'
@echo ' clean Clean binaries from build directory'
@echo ' install Install binaries in $$KLH10_HOME'
## Help for makefile debugging
##
showdefs:
@echo "Showing target defs:"
@echo "SRC = $(SRC)"
@echo "MAKER = $(MAKER)"
@echo "CFLAGS = $(CFLAGS)"
@echo "CFLAGS_AUX = $(CFLAGS_AUX)"
@echo "CENVFLAGS = $(CENVFLAGS)"
@echo "CONFFLAGS = $(CONFFLAGS)"
@echo "CONFFLAGS_AUX = $(CONFFLAGS_AUX)"
@echo "BUILDMOD = $(BUILDMOD)"
# Generally applicable rules
# It would be nice to use the .c.o inference rule for all the .o files,
# but the DECOSF "make" chokes when sources are in a different directory,
# never even invoking .c.o at all. Their /usr/bin/posix/make loses too
# because its MAKEARGS macro prevents recursive makes from accepting
# args with spaces in them.
#
# Thus, for max portability every module target must have explicit
# build commands, and due to the same DECOSF lossage cannot use $<
# in those commands. Sigh!
.SUFFIXES: $(SUFFIXES) .i
.c.o:
$(BUILDMOD) $<
.c.s:
$(BUILDMOD) -S $<
.c.i:
$(BUILDMOD) -E $< > $*.i
# Don't flush these files if interrupted.
# Currently no intermediate source files are generated, so
# this can be empty, but hang on to last binary anyway.
.PRECIOUS: kn10-ks kn10-kl
#######################################################################
##
## Define sources constituting the KLH10. I have not bothered
## to derive a full set of dependencies for each module since
## there are too many possible combinations; safest to always
## recompile everything.
##
## Also, note the KS and KL have two independent module lists in order
## to allow controlling the order in which modules are loaded; this
## can help improve locality.
# Generic header files
CONFS = cenv.h klh10.h word10.h wfio.h fecmd.h feload.h \
kn10mac.h kn10def.h kn10pag.h kn10clk.h kn10dev.h kn10ops.h \
opcods.h opdefs.h osdsup.h \
dvcty.h dvuba.h dvrh11.h dvlhdh.h dvdz11.h dvch11.h \
dvrh20.h dvrpxx.h dvtm03.h dvni20.h dvhost.h \
vmtape.h vdisk.h
# Modules needed for KL10 version.
OFILES_KL = klh10.o prmstr.o fecmd.o feload.o wfio.o osdsup.o \
kn10cpu.o kn10pag.o kn10clk.o opdata.o kn10ops.o \
inmove.o inhalf.o inblsh.o intest.o \
infix.o inflt.o inbyte.o injrst.o \
inexts.o inio.o kn10dev.o \
dvcty.o dvdte.o \
vdisk.o dvrpxx.o dvrh20.o \
vmtape.o dvtm03.o \
dvni20.o dpsup.o \
dvhost.o
# Modules needed for KS10 version.
OFILES_KS = klh10.o prmstr.o fecmd.o feload.o wfio.o osdsup.o \
kn10cpu.o kn10pag.o kn10clk.o opdata.o kn10ops.o \
inmove.o inhalf.o inblsh.o intest.o \
infix.o inflt.o inbyte.o injrst.o \
inexts.o inio.o kn10dev.o dvuba.o \
dvcty.o \
vdisk.o dvrpxx.o dvrh11.o \
vmtape.o dvtm03.o \
dvlhdh.o dvdz11.o dvch11.o \
dpsup.o \
dvhost.o
# Device Processes (DPs) built concurrently with KN10
DPROCS_KL = dprpxx dptm03 dpni20
DPROCS_KS = dprpxx dptm03
DPROCS_KSITS = dprpxx dptm03 dpimp
# Base utility programs, independent of KN10
# (there are others not included in the base configs)
BASE_UTILS = wfconv tapedd vdkfmt wxtest
ALL_UTILS = $(BASE_UTILS) udlconv uexbconv enaddr
############################################################
## KLH10 config - helper definitions
##
# Subflags for fully synchronous time emulation
# These are good for debugging, or on a slow machine.
TSYNCFLAGS = \
-DKLH10_RTIME_SYNCH=1 \
-DKLH10_ITIME_SYNCH=1 \
-DKLH10_QTIME_SYNCH=1
# Subflags for fully OS-interrupt-driven time emulation
# These are best for high performance on a fast machine.
TINTFLAGS = \
-DKLH10_RTIME_OSGET=1 \
-DKLH10_ITIME_INTRP=1 \
-DKLH10_QTIME_OSVIRT=1
# Subflags for synchronous polling versions of certain device drivers.
# These are good for debugging.
DSYNCFLAGS = \
-DKLH10_IMPIO_INT=0 \
-DKLH10_CTYIO_INT=0
# Subflags for interrupt-driven versions of certain device drivers.
# These are best for high performance.
DINTFLAGS = \
-DKLH10_IMPIO_INT=1 \
-DKLH10_CTYIO_INT=1
####################################################################
##
## Basic KN10 configurations
##
kn10-ks: $(OFILES_KS)
$(LINKER) $(LDFLAGS) $(LDOUTF) kn10-ks $(OFILES_KS) $(LIBS)
kn10-kl: $(OFILES_KL)
$(LINKER) $(LDFLAGS) $(LDOUTF) kn10-kl $(OFILES_KL) $(LIBS)
####################################################################
## Auxiliary action targets
clean:
@rm -f kn10-ks kn10-kl *.o \
$(DPROCS_KL) $(DPROCS_KS) $(DPROCS_KSITS) \
$(ALL_UTILS)
# Install. This should really use a shell script instead.
#
install-unix:
@echo "Copying binaries into ${KLH10_HOME}"
@-rm -rf ${KLH10_HOME}/flushed
@-mkdir ${KLH10_HOME}/flushed
@if [ -x ${KLH10_HOME}/kn10-ks ]; then \
mv ${KLH10_HOME}/kn10-ks ${KLH10_HOME}/flushed; fi
@if [ -x ${KLH10_HOME}/kn10-kl ]; then \
mv ${KLH10_HOME}/kn10-kl ${KLH10_HOME}/flushed; fi
@if [ -x ${KLH10_HOME}/dprpxx ]; then \
mv ${KLH10_HOME}/dprpxx ${KLH10_HOME}/flushed; fi
@if [ -x ${KLH10_HOME}/dptm03 ]; then \
mv ${KLH10_HOME}/dptm03 ${KLH10_HOME}/flushed; fi
@if [ -x ${KLH10_HOME}/dpni20 ]; then \
mv ${KLH10_HOME}/dpni20 ${KLH10_HOME}/flushed; fi
@if [ -x ${KLH10_HOME}/dpimp ]; then \
mv ${KLH10_HOME}/dpimp ${KLH10_HOME}/flushed; fi
@if [ -x kn10-ks ]; then cp -p kn10-ks ${KLH10_HOME}/; fi
@if [ -x kn10-kl ]; then cp -p kn10-kl ${KLH10_HOME}/; fi
@if [ -x dprpxx ]; then cp -p dprpxx ${KLH10_HOME}/; fi
@if [ -x dptm03 ]; then cp -p dptm03 ${KLH10_HOME}/; fi
@if [ -x dpni20 ]; then cp -p dpni20 ${KLH10_HOME}/; fi
@if [ -x dpimp ]; then cp -p dpimp ${KLH10_HOME}/; fi
@if [ -x enaddr ]; then cp -p enaddr ${KLH10_HOME}/; fi
@if [ -x tapedd ]; then cp -p tapedd ${KLH10_HOME}/; fi
@if [ -x udlconv ]; then cp -p udlconv ${KLH10_HOME}/; fi
@if [ -x uexbconv ]; then cp -p uexbconv ${KLH10_HOME}/; fi
@if [ -x vdkfmt ]; then cp -p vdkfmt ${KLH10_HOME}/; fi
@if [ -x wfconv ]; then cp -p wfconv ${KLH10_HOME}/; fi
@if [ -x wxtest ]; then cp -p wxtest ${KLH10_HOME}/; fi
@echo "Done!"
####################################################################
## Specific KLH10 configurations
##
## Provided as a convenience, not intended to satisfy all
## possible platforms or configurations.
# Standard setup for KS ITS
#
base-ks-its:
$(MAKER) kn10-ks $(DPROCS_KSITS) $(BASE_UTILS) udlconv \
"SRC = $(SRC)" \
"CC = $(CC)" \
"CFLAGS = $(CFLAGS) $(CFLAGS_AUX)" \
"LDFLAGS = $(LDFLAGS)" \
"LIBS = $(LIBS)" \
"CENVFLAGS = $(CENVFLAGS)" \
"CONFFLAGS = \
-DKLH10_CPU_KS=1 \
-DKLH10_SYS_ITS=1 \
-DKLH10_EVHS_INT=1 \
-DKLH10_DEV_DPTM03=1 \
-DKLH10_DEV_DPRPXX=1 \
-DKLH10_DEV_DPIMP=1 \
-DKLH10_SIMP=0 \
-DKLH10_NET_TUN=SYS_FREEBSD \
-DKLH10_MEM_SHARED=1 \
$(TINTFLAGS) \
$(DINTFLAGS) \
-DKLH10_APRID_SERIALNO=759 -DKLH10_DEVMAX=12 \
-DKLH10_CLIENT=\\\"MyITS\\\" \
$(CONFFLAGS_AUX) \
-DVMTAPE_ITSDUMP=1 "
# Standard setup for KS (TOPS-20, maybe TOPS-10)
#
base-ks:
$(MAKER) kn10-ks $(DPROCS_KS) $(BASE_UTILS) \
"SRC = $(SRC)" \
"CC = $(CC)" \
"CFLAGS = $(CFLAGS) $(CFLAGS_AUX)" \
"LDFLAGS = $(LDFLAGS)" \
"LIBS = $(LIBS)" \
"CENVFLAGS = $(CENVFLAGS)" \
"CONFFLAGS = \
-DKLH10_CPU_KS=1 \
-DKLH10_SYS_T20=1 \
-DKLH10_EVHS_INT=1 \
-DKLH10_DEV_DPTM03=1 \
-DKLH10_DEV_DPRPXX=1 \
-DKLH10_MEM_SHARED=1 \
$(TINTFLAGS) \
$(DINTFLAGS) \
-DKLH10_APRID_SERIALNO=759 -DKLH10_DEVMAX=12 \
-DKLH10_CLIENT=\\\"MyKS\\\" \
$(CONFFLAGS_AUX) "
# Standard setup for KL (TOPS-10 and TOPS-20)
#
base-kl:
$(MAKER) kn10-kl $(DPROCS_KL) $(BASE_UTILS) uexbconv \
"SRC = $(SRC)" \
"CC = $(CC)" \
"CFLAGS = $(CFLAGS) $(CFLAGS_AUX)" \
"LDFLAGS = $(LDFLAGS)" \
"LIBS = $(LIBS)" \
"CENVFLAGS = $(CENVFLAGS)" \
"CONFFLAGS = \
-DKLH10_CPU_KLX=1 \
-DKLH10_SYS_T20=1 \
-DKLH10_EVHS_INT=1 \
-DKLH10_DEV_DPNI20=1 \
-DKLH10_DEV_DPTM03=1 \
-DKLH10_DEV_DPRPXX=1 \
-DKLH10_MEM_SHARED=1 \
-DKLH10_RTIME_OSGET=1 \
-DKLH10_ITIME_INTRP=1 \
-DKLH10_CTYIO_INT=1 \
-DKLH10_APRID_SERIALNO=1 \
-DKLH10_CLIENT=\\\"MyKL\\\" \
$(CONFFLAGS_AUX) "
####################################################################
## Lintish versions to see how many compiler warnings we can generate
##
lint-ks-its:
$(MAKER) kn10-ks $(DPROCS_KSITS) $(BASE_UTILS) udlconv \
"SRC = $(SRC)" \
"CC = $(CC)" \
"CFLAGS = $(CFLAGS) $(CFLAGS_AUX) $(CFLAGS_LINT)" \
"LDFLAGS = $(LDFLAGS)" \
"LIBS = $(LIBS)" \
"CENVFLAGS = $(CENVFLAGS)" \
"CONFFLAGS = $(CONFFLAGS) $(CONFFLAGS_AUX)"
lint-ks:
$(MAKER) kn10-ks $(DPROCS_KS) $(BASE_UTILS) \
"SRC = $(SRC)" \
"CC = $(CC)" \
"CFLAGS = $(CFLAGS) $(CFLAGS_AUX) $(CFLAGS_LINT)" \
"LDFLAGS = $(LDFLAGS)" \
"LIBS = $(LIBS)" \
"CENVFLAGS = $(CENVFLAGS)" \
"CONFFLAGS = $(CONFFLAGS) $(CONFFLAGS_AUX)"
lint-kl:
$(MAKER) kn10-kl $(DPROCS_KL) $(BASE_UTILS) uexbconv \
"SRC = $(SRC)" \
"CC = $(CC)" \
"CFLAGS = $(CFLAGS) $(CFLAGS_AUX) $(CFLAGS_LINT)" \
"LDFLAGS = $(LDFLAGS)" \
"LIBS = $(LIBS)" \
"CENVFLAGS = $(CENVFLAGS)" \
"CONFFLAGS = $(CONFFLAGS) $(CONFFLAGS_AUX)"
####################################################################
## KLH10 versions for diagnostics and debugging.
##
# "Port"-friendly KS, for helping port to a new platform.
# Simplest possible configuration:
# No shared memory
# No device subprocs
# No realtime interrupts or clock - synchronous emulation
port-ks:
$(MAKER) kn10-ks $(BASE_UTILS) \
"SRC = $(SRC)" \
"CC = $(CC)" \
"CFLAGS = $(CFLAGS) $(CFLAGS_AUX)" \
"LDFLAGS = $(LDFLAGS)" \
"LIBS = $(LIBS)" \
"CENVFLAGS = $(CENVFLAGS)" \
"CONFFLAGS = \
-DKLH10_CPU_KS=1 \
-DKLH10_SYS_T20=1 \
-DKLH10_RTIME_SYNCH=1 \
-DKLH10_APRID_SERIALNO=759 -DKLH10_DEVMAX=12 \
-DKLH10_CLIENT=\\\"MyKS\\\" \
$(CONFFLAGS_AUX) "
# Build KL0 with KI paging, for running diagnostics.
# Two versions, one synch and one realtime.
# Note: The diags tend to fail miserably when faced with a KLX using KI
# paging, so don't try that.
# KL0 with KI paging - synchronous, good for debugging with diagnostics.
# NOTE: CFLAGS for this one should be set up for NO optimization!!!
kl0i-sync:
$(MAKER) kn10-kl $(DPROCS_KL) \
"SRC = $(SRC)" \
"CC = $(CC)" \
"CFLAGS = $(CFLAGS) $(CFLAGS_AUX)" \
"LDFLAGS = $(LDFLAGS)" \
"LIBS = $(LIBS)" \
"CENVFLAGS = $(CENVFLAGS)" \
"CONFFLAGS = \
-DKLH10_CPU_KL0=1 \
-DKLH10_SYS_T10=1 \
-DKLH10_PAG_KI=1 \
-DKLH10_EVHS_INT=1 \
-DKLH10_DEV_DPNI20=1 \
-DKLH10_DEV_DPTM03=1 \
-DKLH10_DEV_DPRPXX=1 \
-DKLH10_RTIME_SYNCH=1 \
-DKLH10_ITIME_SYNCH=1 \
-DKLH10_CTYIO_INT=0 \
$(CONFFLAGS_AUX) "
# KL0 with KI paging - Realtime & optimized, good for timing diagnostics.
#
kl0i-rtmopt:
$(MAKER) kn10-kl $(DPROCS_KL) \
"SRC = $(SRC)" \
"CC = $(CC)" \
"CFLAGS = $(CFLAGS) $(CFLAGS_AUX)" \
"LDFLAGS = $(LDFLAGS)" \
"LIBS = $(LIBS)" \
"CENVFLAGS = $(CENVFLAGS)" \
"CONFFLAGS = \
-DKLH10_CPU_KL0=1 \
-DKLH10_SYS_T10=1 \
-DKLH10_PAG_KI=1 \
-DKLH10_EVHS_INT=1 \
-DKLH10_DEV_DPNI20=1 \
-DKLH10_DEV_DPTM03=1 \
-DKLH10_DEV_DPRPXX=1 \
-DKLH10_RTIME_OSGET=1 \
-DKLH10_ITIME_INTRP=1 \
-DKLH10_CTYIO_INT=0 \
$(CONFFLAGS_AUX) "
####################################################################
## Device Process (DP) programs
##
## These cannot be made individually - they are expected to be
## built as byproducts of building the KLH10, in order to share
## a common set of config parameters.
##
# --------- RPXX disk drive subprocess
#
dprpxx.o: $(SRC)/dprpxx.c $(SRC)/dprpxx.h $(SRC)/dpsup.h $(SRC)/vdisk.c
$(BUILDMOD) $(SRC)/dprpxx.c
dprpxx: dprpxx.o dpsup.o
$(LINKER) $(LDFLAGS) $(LDOUTF) dprpxx dprpxx.o dpsup.o $(LIBS)
# --------- TM03 tape drive subprocess
#
dptm03.o: $(SRC)/dptm03.c $(SRC)/dptm03.h $(SRC)/dpsup.h $(SRC)/vmtape.c
$(BUILDMOD) $(SRC)/dptm03.c
OFILES_DPTM03=dptm03.o dpsup.o wfio.o prmstr.o
dptm03: $(OFILES_DPTM03)
$(LINKER) $(LDFLAGS) $(LDOUTF) dptm03 $(OFILES_DPTM03) $(LIBS)
# --------- NI20 Network Interface subprocess (KL only)
#
dpni20.o: $(SRC)/dpni20.c $(SRC)/dpni20.h $(SRC)/dpsup.h
$(BUILDMOD) $(SRC)/dpni20.c
dpni20: dpni20.o dpsup.o
$(LINKER) $(LDFLAGS) $(LDOUTF) dpni20 dpni20.o dpsup.o $(LIBS)
# --------- IMP subprocess (ITS KS only; counterpart for dvlhdh)
#
dpimp.o: $(SRC)/dpimp.c $(SRC)/dpimp.h $(SRC)/dpsup.h
$(BUILDMOD) $(SRC)/dpimp.c
dpimp: dpimp.o dpsup.o
$(LINKER) $(LDFLAGS) $(LDOUTF) dpimp dpimp.o dpsup.o $(LIBS)
####################################################################
## UTILITIES
##
## These can be built independently, and normally do not require
## any CONFFLAGS.
##
## TAPEDD - Tape device-to-device copy
## Needs CONFFLAGS just for optional VMTAPE_ITSDUMP.
##
tapedd.o: $(SRC)/tapedd.c $(SRC)/vmtape.c $(SRC)/vmtape.h
$(CC) $(CFLAGS) $(CENVFLAGS) $(CONFFLAGS) $(SRC)/tapedd.c
tapedd: tapedd.o wfio.o prmstr.o
$(LINKER) $(LDFLAGS) $(LDOUTF) tapedd tapedd.o wfio.o prmstr.o $(LIBS)
## VDKFMT - Virtual Disk Format & copy
##
vdkfmt.o: $(SRC)/vdkfmt.c $(SRC)/vdisk.c $(SRC)/vdisk.h
$(CC) $(CFLAGS) $(CENVFLAGS) $(SRC)/vdkfmt.c
vdkfmt: vdkfmt.o
$(LINKER) $(LDFLAGS) $(LDOUTF) vdkfmt vdkfmt.o $(LIBS)
## WXTEST - word10.h tester
##
wxtest.o: $(SRC)/wxtest.c $(SRC)/word10.h
$(CC) $(CFLAGS) $(CENVFLAGS) $(SRC)/wxtest.c
wxtest: wxtest.o
$(LINKER) $(LDFLAGS) $(LDOUTF) wxtest wxtest.o $(LIBS)
## WFCONV - Word-File Conversion
##
wfconv.o: $(SRC)/wfconv.c $(SRC)/wfio.c $(SRC)/wfio.h $(SRC)/word10.h
$(CC) $(CFLAGS) $(CENVFLAGS) $(SRC)/wfconv.c
wfconv: wfconv.o
$(LINKER) $(LDFLAGS) $(LDOUTF) wfconv wfconv.o $(LIBS)
## UDLCONV - DIR.LIST Conversion (of ITS interest only)
##
udlconv.o: $(SRC)/udlconv.c
$(CC) $(CFLAGS) $(CENVFLAGS) $(SRC)/udlconv.c
udlconv: udlconv.o
$(LINKER) $(LDFLAGS) $(LDOUTF) udlconv udlconv.o $(LIBS)
## UEXBCONV - Convert .EXB file into .SAV (of KL interest only)
##
uexbconv.o: $(SRC)/uexbconv.c $(SRC)/wfio.c $(SRC)/wfio.h $(SRC)/word10.h
$(CC) $(CFLAGS) $(CENVFLAGS) $(SRC)/uexbconv.c
uexbconv: uexbconv.o
$(LINKER) $(LDFLAGS) $(LDOUTF) uexbconv uexbconv.o $(LIBS)
## ENADDR - Ethernet interface test & manipulation
## May require CONFFLAGS to force a particular osdnet config.
enaddr.o: $(SRC)/enaddr.c $(SRC)/osdnet.h $(SRC)/osdnet.c
$(CC) $(CFLAGS) $(CENVFLAGS) $(CONFFLAGS) $(SRC)/enaddr.c
enaddr: enaddr.o
$(LINKER) $(LDFLAGS) $(LDOUTF) enaddr enaddr.o $(LIBS)
####################################################################
## KN10 modules. In order to build into a directory other than the
## one the sources are located, must specify the location of
## each and every source file. Ugh. Some but not all dependencies
## are included here.
##
## Sorted alphabetically.
##
dpsup.o: $(SRC)/dpsup.c $(SRC)/dpsup.h
$(BUILDMOD) $(SRC)/dpsup.c
dvch11.o: $(SRC)/dvch11.c $(SRC)/dvch11.h
$(BUILDMOD) $(SRC)/dvch11.c
dvcty.o: $(SRC)/dvcty.c $(SRC)/dvcty.h
$(BUILDMOD) $(SRC)/dvcty.c
dvdte.o: $(SRC)/dvdte.c $(SRC)/dvdte.h
$(BUILDMOD) $(SRC)/dvdte.c
dvdz11.o: $(SRC)/dvdz11.c $(SRC)/dvdz11.h
$(BUILDMOD) $(SRC)/dvdz11.c
dvhost.o: $(SRC)/dvhost.c $(SRC)/dvhost.h
$(BUILDMOD) $(SRC)/dvhost.c
dvlhdh.o: $(SRC)/dvlhdh.c $(SRC)/dvlhdh.h
$(BUILDMOD) $(SRC)/dvlhdh.c
dvni20.o: $(SRC)/dvni20.c $(SRC)/dvni20.h
$(BUILDMOD) $(SRC)/dvni20.c
dvrh11.o: $(SRC)/dvrh11.c $(SRC)/dvrh11.h
$(BUILDMOD) $(SRC)/dvrh11.c
dvrh20.o: $(SRC)/dvrh20.c $(SRC)/dvrh20.h
$(BUILDMOD) $(SRC)/dvrh20.c
dvrpxx.o: $(SRC)/dvrpxx.c $(SRC)/dvrpxx.h
$(BUILDMOD) $(SRC)/dvrpxx.c
dvtm03.o: $(SRC)/dvtm03.c $(SRC)/dvtm03.h
$(BUILDMOD) $(SRC)/dvtm03.c
dvuba.o: $(SRC)/dvuba.c $(SRC)/dvuba.h
$(BUILDMOD) $(SRC)/dvuba.c
fecmd.o: $(SRC)/fecmd.c $(SRC)/fecmd.h
$(BUILDMOD) $(SRC)/fecmd.c
feload.o: $(SRC)/feload.c $(SRC)/feload.h
$(BUILDMOD) $(SRC)/feload.c
inblsh.o: $(SRC)/inblsh.c
$(BUILDMOD) $(SRC)/inblsh.c
inbyte.o: $(SRC)/inbyte.c
$(BUILDMOD) $(SRC)/inbyte.c
inexts.o: $(SRC)/inexts.c
$(BUILDMOD) $(SRC)/inexts.c
infix.o: $(SRC)/infix.c
$(BUILDMOD) $(SRC)/infix.c
inflt.o: $(SRC)/inflt.c
$(BUILDMOD) $(SRC)/inflt.c
inhalf.o: $(SRC)/inhalf.c
$(BUILDMOD) $(SRC)/inhalf.c
inio.o: $(SRC)/inio.c
$(BUILDMOD) $(SRC)/inio.c
injrst.o: $(SRC)/injrst.c
$(BUILDMOD) $(SRC)/injrst.c
inmove.o: $(SRC)/inmove.c
$(BUILDMOD) $(SRC)/inmove.c
intest.o: $(SRC)/intest.c
$(BUILDMOD) $(SRC)/intest.c
kn10clk.o: $(SRC)/kn10clk.c $(SRC)/kn10clk.h
$(BUILDMOD) $(SRC)/kn10clk.c
kn10cpu.o: $(SRC)/kn10cpu.c $(SRC)/klh10.h $(SRC)/klh10s.h $(SRC)/klh10.c
$(BUILDMOD) $(SRC)/kn10cpu.c
kn10dev.o: $(SRC)/kn10dev.c $(SRC)/kn10dev.h
$(BUILDMOD) $(SRC)/kn10dev.c
kn10ops.o: $(SRC)/kn10ops.c $(SRC)/kn10ops.h
$(BUILDMOD) $(SRC)/kn10ops.c
kn10pag.o: $(SRC)/kn10pag.c $(SRC)/kn10pag.h
$(BUILDMOD) $(SRC)/kn10pag.c
klh10.o: $(SRC)/klh10.c $(SRC)/klh10.h $(SRC)/klh10s.h
$(BUILDMOD) $(SRC)/klh10.c
opdata.o: $(SRC)/opdata.c $(SRC)/kn10def.h $(SRC)/opcods.h
$(BUILDMOD) $(SRC)/opdata.c
osdsup.o: $(SRC)/osdsup.c $(SRC)/osdsup.h
$(BUILDMOD) $(SRC)/osdsup.c
prmstr.o: $(SRC)/prmstr.c $(SRC)/prmstr.h
$(BUILDMOD) $(SRC)/prmstr.c
vdisk.o: $(SRC)/vdisk.c $(SRC)/vdisk.h
$(BUILDMOD) $(SRC)/vdisk.c
vmtape.o: $(SRC)/vmtape.c $(SRC)/vmtape.h
$(BUILDMOD) $(SRC)/vmtape.c
wfio.o: $(SRC)/wfio.c $(SRC)/wfio.h
$(BUILDMOD) $(SRC)/wfio.c
####################################################################
## OLD STUFF
## Misc crocks kept around just in case.
##
optest: optest.o
$(LINKER) $(LDFLAGS) -o optest optest.o $(LIBS)
# This is only for munching Alan's ITS DUMP tape info format
dlmunch: dlmunch.o lread.o
$(LINKER) -o dlmunch dlmunch.o lread.o
####################################################################

View File

@@ -1,5 +1,5 @@
# KLH10 Makefile for Linux on i386
# $Id: Mk-lnx86.mk,v 2.5 2002/04/24 18:03:04 klh Exp $
# KLH10 Makefile for Linux on amd64 / x86_64 / Alpha
# (or any other little-endian 64-bit cpu)
#
# Copyright © 2001 Kenneth L. Harrenstien
# All Rights Reserved
@@ -27,7 +27,7 @@ CFLAGS_LINT = -ansi -pedantic -Wall -Wshadow \
-Wmissing-declarations -Wredundant-decls
# Source definitions
CENVFLAGS = -DCENV_CPU_I386=1 -DCENV_SYS_LINUX=1 \
CENVFLAGS = -DCENV_CPU_ALPHA=1 -DCENV_SYS_LINUX=1 -DKLH10_DEV_LITES=1 \
-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
# Any target with no customized rule here is simply passed on to the

View File

@@ -1,5 +1,5 @@
# KLH10 Makefile for NetBSD on Alpha
# $Id: Mk-nbaxp.mk,v 2.5 2002/04/26 05:59:32 klh Exp $
# KLH10 Makefile for NetBSD on amd64 / x86_64 / Alpha
# (or any other little-endian 64-bit cpu)
#
# Copyright © 2001 Kenneth L. Harrenstien
# All Rights Reserved

View File

@@ -21,7 +21,7 @@
# Build definitions
SRC = ../../src
CFLAGS = -c -g3 -O3
CFLAGS = -c -g3 -O3 -ggdb
CFLAGS_LINT = -ansi -pedantic -Wall -Wshadow \
-Wstrict-prototypes -Wmissing-prototypes \
-Wmissing-declarations -Wredundant-decls

View File

@@ -1,4 +1,5 @@
# KLH10 Makefile for OSF/1 (DU, Tru64) on Alpha
# KLH10 Makefile for OSF/1 (DU, Tru64) on amd64 / x86_64 / Alpha
# (or any other little-endian 64-bit cpu)
# $Id: Mk-osfaxp.mk,v 2.3 2001/11/10 21:28:59 klh Exp $
#
# Copyright © 2001 Kenneth L. Harrenstien

View File

@@ -228,6 +228,10 @@ default for every OS that implements /dev/tun.
#include <sys/resource.h> /* For setpriority() */
#include <sys/mman.h> /* For mlockall() */
#if CENV_SYS_NETBSD
#include <poll.h>
#endif
#include "dpimp.h" /* DPIMP specific defs, grabs DPSUP if needed */
#ifdef RCSID

View File

@@ -169,6 +169,7 @@ The following general situations are possible:
RCSID(dpni20_c,"$Id: dpni20.c,v 2.7 2003/02/23 18:07:50 klh Exp $")
#endif
/* Globals */
int chpid; /* PID of child, handles input (net-to-10). */
@@ -443,6 +444,8 @@ main(int argc, char **argv)
progname = progname_w; /* Reset progname to indicate identity */
tentoeth(dpni); /* Parent process handles output to net */
osn_pfdeinit();
return 1; /* Never returns, but placate compiler */
}
@@ -520,6 +523,7 @@ void net_init(register struct dpni20_s *dpni)
#endif
}
/* Now set any return info values in shared struct.
*/
memcpy(dpni->dpni_eth, (char *)&ihost_ea, 6); /* Copy ether addr */
@@ -1018,7 +1022,7 @@ pfshow(struct OSN_PFSTRUCT *pf)
/* LNX packetfilter initialization */
#if KLH10_NET_LNX
#if KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE
/*
The Linux PF_PACKET interface is described to some extent
@@ -1114,6 +1118,10 @@ int lnx_filter(register struct dpni20_s *dpni,
*/
void eth_adrset(register struct dpni20_s *dpni)
{
#if OSN_USE_IPONLY
dbprintln("\"%s\" multicast table ignored - IP-only interface",
dpni->dpni_ifnam);
#else
unsigned char rdea[ETHER_ADRSIZ];
char old[OSN_EASTRSIZ];
char new[OSN_EASTRSIZ];
@@ -1179,6 +1187,7 @@ void eth_adrset(register struct dpni20_s *dpni)
}
}
#endif
/* Assume succeeded since call succeeded, and clobber our address! */
memcpy(dpni->dpni_eth, dpni->dpni_rqeth, ETHER_ADRSIZ);
}
@@ -1197,6 +1206,10 @@ void eth_adrset(register struct dpni20_s *dpni)
void eth_mcatset(register struct dpni20_s *dpni)
{
#if OSN_USE_IPONLY
dbprintln("\"%s\" multicast table ignored - IP-only interface",
dpni->dpni_ifnam);
#else
ossock_t s;
int i, n, j;
char ethstr[OSN_EASTRSIZ];
@@ -1271,6 +1284,7 @@ void eth_mcatset(register struct dpni20_s *dpni)
nmcats = n;
memcpy(ethmcat[0], dpni->dpni_mcat[0], (n * 6));
#endif
}
/* ARP Hackery */
@@ -1383,7 +1397,9 @@ int arp_myreply(register unsigned char *buf, register int cnt)
/* Now send it! Ignore any errors. */
if (swstatus) {
char ipstr[OSN_IPSTRSIZ];
dbprintln("ARP MyReply %s", ip_adrsprint(ipstr, ife->ife_ipchr));
char ethstr[OSN_EASTRSIZ];
dbprintln("ARP MyReply %s %s", ip_adrsprint(ipstr, ife->ife_ipchr),
eth_adrsprint(ethstr, ife->ife_ea));
}
#if KLH10_NET_DLPI
@@ -1394,6 +1410,9 @@ int arp_myreply(register unsigned char *buf, register int cnt)
(void) putmsg(pffd, NULL, &data, 0);
}
#else
/* XXX
* Why is this sent to the packet filter (= host) and not to the -10?????
*/
(void)write(pffd, pktbuf, sizeof(pktbuf));
#endif
return TRUE;
@@ -1521,14 +1540,17 @@ void ethtoten(register struct dpni20_s *dpni)
else
dbprint("Read=%d", cnt);
}
#if KLH10_NET_LNX
#if KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE
/* Linux has no packet filtering, thus must apply manual check to
each and every packet read, unless dedicated. Ugh!
*/
if (!dpni->dpni_dedic) {
if (KLH10_NET_TAP_BRIDGE || !dpni->dpni_dedic) {
/* Sharing interface. Check for IP, DECNET, 802.3 */
if (!lnx_filter(dpni, buff, cnt))
if (!lnx_filter(dpni, buff, cnt)) {
if (DBGFLG)
dbprint("Dropped");
continue; /* Drop packet, continue reading */
}
}
#endif /* KLH10_NET_LNX */
#if !KLH10_NET_BPF
@@ -1615,7 +1637,11 @@ void tentoeth(register struct dpni20_s *dpni)
/* Must check for outbound ARP requests if asked to and have
** at least one entry in our table of host's IP interfaces.
*/
#if KLH10_NET_TAP_BRIDGE
doarpchk = 0;
#else
doarpchk = (dpni->dpni_doarp & DPNI_ARPF_OCHK) && (osn_nifents() > 0);
#endif
dpx = dp_dpxto(&dp); /* Get ptr to "To-DP" xfer stuff */
buff = dp_xrbuff(dpx, &max);
@@ -1661,7 +1687,7 @@ void tentoeth(register struct dpni20_s *dpni)
}
#else
cnt = write(pffd, buff, rcnt);
#endif
#endif /* else KLH10_NET_DLPI */
if (cnt != rcnt) {
if ((cnt < 0) && (errno == EINTR)) {
continue; /* Start over, may have new cmd */
@@ -1722,6 +1748,9 @@ void dumppkt(unsigned char *ucp, int cnt)
fprintf(stderr, "\r\n");
}
}
/* Add OSDNET shared code here */

View File

@@ -40,6 +40,7 @@ static int decosfcclossage;
#if KLH10_DEV_DP /* Moby conditional for entire file */
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* For strerror() if present */
#include "dpsup.h"

View File

@@ -1,334 +0,0 @@
/* DVHOST.C - Fake "Host" device to provide access to native host platform
*/
/* $Id: dvhost.c,v 2.3 2001/11/10 21:28:59 klh Exp $
*/
/* Copyright © 1994, 2001 Kenneth L. Harrenstien
** All Rights Reserved
**
** This file is part of the KLH10 Distribution. Use, modification, and
** re-distribution is permitted subject to the terms in the file
** named "LICENSE", which contains the full text of the legal notices
** and should always accompany this Distribution.
**
** This software is provided "AS IS" with NO WARRANTY OF ANY KIND.
**
** This notice (including the copyright and warranty disclaimer)
** must be included in all copies or derivations of this software.
*/
/*
* $Log: dvhost.c,v $
* Revision 2.3 2001/11/10 21:28:59 klh
* Final 2.0 distribution checkin
*
*/
/*
*/
#include "klh10.h"
#if !KLH10_DEV_HOST && CENV_SYS_DECOSF
/* Stupid gubbish needed to prevent OSF/1 AXP compiler from
** halting merely because compiled file is empty!
*/
static int decosfcclossage;
#endif
#if KLH10_DEV_HOST /* Moby conditional for entire file */
#include <stddef.h> /* For size_t etc */
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "kn10def.h" /* This includes OSD defs */
#include "kn10dev.h"
#include "kn10ops.h"
#include "dvhost.h"
#include "kn10clk.h" /* Need access to clock stuff */
#include "prmstr.h" /* For parameter parsing */
#ifdef RCSID
RCSID(dvhost_c,"$Id: dvhost.c,v 2.3 2001/11/10 21:28:59 klh Exp $")
#endif
struct host {
struct device hst_dv; /* Generic 10 device structure */
};
static int nhosts = 0;
#define DVHOST_NSUP 1 /* Should never be anything else! */
struct host dvhost[DVHOST_NSUP];
/* Function predecls */
static int hst_conf(FILE *f, char *s, struct host *hst);
#if KLH10_CPU_KS
static void hst_write(struct device *, /* Unibus register write */
uint18, dvureg_t);
#else
static void hst_cono(struct device *, h10_t); /* CONO 18-bit conds out */
# if 0
static w10_t hst_coni(); /* CONI 36-bit conds in */
static void hst_datao(); /* DATAO word out */
static w10_t hst_datai(); /* DATAI word in */
# endif
#endif /* !KLH10_CPU_KS */
/* Configuration Parameters */
#if KLH10_CPU_KS
# define DVHOST_PARAMS \
prmdef(HSTP_DBG, "debug"), /* Initial debug value */\
prmdef(HSTP_BR, "br"), /* BR priority */\
prmdef(HSTP_VEC, "vec"), /* Interrupt vector */\
prmdef(HSTP_ADDR,"addr") /* Unibus address */
#else
# define DVHOST_PARAMS \
prmdef(HSTP_DBG, "debug") /* Initial debug value */
#endif /* KLH10_CPU_KS */
enum {
# define prmdef(i,s) i
DVHOST_PARAMS
# undef prmdef
};
static char *hstprmtab[] = {
# define prmdef(i,s) s
DVHOST_PARAMS
# undef prmdef
, NULL
};
/* HST_CONF - Parse configuration string and set defaults.
** At this point, device has just been created, but not yet bound
** or initialized.
** NOTE that some strings are dynamically allocated! Someday may want
** to clean them up nicely if config fails or device is uncreated.
*/
static int hst_conf(FILE *f, char *s, struct host *hst)
{
int i, ret = TRUE;
struct prmstate_s prm;
char buff[200];
#if KLH10_CPU_KS
long lval;
#endif
/* First set defaults for all configurable parameters
Unfortunately there's currently no way to access the UBA # that
we're gonna be bound to, otherwise could set up defaults. Later
fix this by giving dvhost_create() a ptr to an arg structure, etc.
*/
DVDEBUG(hst) = FALSE;
prm_init(&prm, buff, sizeof(buff),
s, strlen(s),
hstprmtab, sizeof(hstprmtab[0]));
while ((i = prm_next(&prm)) != PRMK_DONE) {
switch (i) {
case PRMK_NONE:
fprintf(f, "Unknown HOST parameter \"%s\"\n", prm.prm_name);
ret = FALSE;
continue;
case PRMK_AMBI:
fprintf(f, "Ambiguous HOST parameter \"%s\"\n", prm.prm_name);
ret = FALSE;
continue;
default: /* Handle matches not supported */
fprintf(f, "Unsupported HOST parameter \"%s\"\n", prm.prm_name);
ret = FALSE;
continue;
case HSTP_DBG: /* Parse as true/false boolean or number */
if (!prm.prm_val) /* No arg => default to 1 */
DVDEBUG(hst) = 1;
else if (!s_tobool(prm.prm_val, &DVDEBUG(hst)))
break;
continue;
#if KLH10_CPU_KS
case HSTP_BR: /* Parse as octal number */
if (!prm.prm_val || !s_tonum(prm.prm_val, &lval))
break;
if (lval < 4 || lval > 7) {
fprintf(f, "HOST BR must be one of 4,5,6,7\n");
ret = FALSE;
} else
hst->hst_dv.dv_brlev = lval;
continue;
case HSTP_VEC: /* Parse as octal number */
if (!prm.prm_val || !s_tonum(prm.prm_val, &lval))
break;
if (lval < 4 || lval > 0400 || (lval&03)) {
fprintf(f, "HOST VEC must be valid multiple of 4\n");
ret = FALSE;
} else
hst->hst_dv.dv_brvec = lval;
continue;
case HSTP_ADDR: /* Parse as octal number */
if (!prm.prm_val || !s_tonum(prm.prm_val, &lval))
break;
#if 0
if (lval < (DVHOST_REG_N<<1) || (lval&037)) {
fprintf(f, "HOST ADDR must be valid Unibus address\n");
ret = FALSE;
} else
#endif
hst->hst_dv.dv_addr = lval;
continue;
#endif /* KLH10_CPU_KS */
}
ret = FALSE;
fprintf(f, "HOST param \"%s\": ", prm.prm_name);
if (prm.prm_val)
fprintf(f, "bad value syntax: \"%s\"\n", prm.prm_val);
else
fprintf(f, "missing value\n");
}
/* Param string all done, do followup checks or cleanup */
#if KLH10_CPU_KS
# if 0
if (!hst->hst_dv.dv_brlev || !hst->hst_dv.dv_brvec || !hst->hst_dv.dv_addr) {
fprintf(f, "HOST missing one of BR, VEC, ADDR params\n");
# else
if (!hst->hst_dv.dv_addr) {
fprintf(f, "HOST missing ADDR param\n");
# endif
ret = FALSE;
}
/* Set 1st invalid addr */
hst->hst_dv.dv_aend = hst->hst_dv.dv_addr + (DVHOST_REG_N * 2);
#endif /* KLH10_CPU_KS */
return ret;
}
/* HOST interface routines to KLH10 */
struct device * dvhost_create(FILE *f, char *s)
{
register struct host *hst;
/* Parse string to determine which device to use, config, etc etc
** But for now, just allocate sequentially. Hack.
*/
if (nhosts >= DVHOST_NSUP) {
fprintf(f, "Too many HOSTs, max: %d\n", DVHOST_NSUP);
return NULL;
}
hst = &dvhost[nhosts++]; /* Pick unused dev */
memset((char *)hst, 0, sizeof(*hst)); /* Clear it out */
/* Initialize generic device part of HOST struct */
iodv_setnull(&hst->hst_dv); /* Initialize as null device */
#if KLH10_CPU_KS
/* Operate as new-style Unibus device */
hst->hst_dv.dv_write = hst_write; /* Write unibus register */
#else
/* Operate as old-style IO-bus device */
hst->hst_dv.dv_cono = hst_cono; /* Do CONO only */
#endif
/* Configure from parsed string and remember for init
*/
if (!hst_conf(f, s, hst))
return NULL;
return &hst->hst_dv;
}
#if !KLH10_CPU_KS
/* CONO 18-bit conds out
** Args D, ERH
** Returns nothing
*/
static insdef_cono(hst_cono)
{
register struct host *hst = (struct host *)d;
register uint18 cond = erh;
if (DVDEBUG(hst))
fprintf(DVDBF(hst), "[hst_cono: %lo]\r\n", (long)erh);
if (cond == DVHOST_CO_IDLE)
clk_idle(); /* Invoke CLK_IDLE! */
}
#if 0 /* Nothing else needed for now */
/* CONI 36-bit conds in
** Args D
** Returns condition word
*/
static insdef_coni(hst_coni)
{
register w10_t w;
register struct host *hst = (struct host *)d;
if (DVDEBUG(hst))
fprintf(DVDBF(hst), "[hst_coni: %lo,,%lo]\r\n",
(long)hst->hst_lhcond, (long)hst->hst_cond);
return w;
}
/* DATAO word out
** Args D, W
** Returns nothing
*/
static insdef_datao(hst_datao)
{
register struct host *hst = (struct host *)d;
if (DVDEBUG(hst))
fprintf(DVDBF(hst), "[hst_datao: %lo,,%lo]\r\n",
(long)LHGET(w), (long)RHGET(w));
}
/* DATAI word in
** Args D
** Returns data word
*/
static insdef_datai(hst_datai)
{
register struct host *hst = (struct host *)d;
register w10_t w;
if (DVDEBUG(hst))
fprintf(DVDBF(hst), "[hst_datai: %lo,,%lo]\r\n",
(long)LHGET(w), (long)RHGET(w));
return w;
}
#endif /* 0 */ /* Nothing else needed for now */
#endif /* !KLH10_CPU_KS */
#if KLH10_CPU_KS
/* Unibus interface routines */
static void hst_write(struct device *d, uint18 addr, register dvureg_t val)
{
register struct host *hst = (struct host *)d;
if (DVDEBUG(hst))
fprintf(DVDBF(hst), "[hst_write: %lo]\r\n", (long)val);
if (val == DVHOST_CO_IDLE)
clk_idle(); /* Invoke CLK_IDLE! */
}
#endif /* KLH10_CPU_KS */
#endif /* KLH10_DEV_HOST */

View File

@@ -1,46 +0,0 @@
/* DVHOST.H - HOST native platform access defniitions
*/
/* $Id: dvhost.h,v 2.3 2001/11/10 21:28:59 klh Exp $
*/
/* Copyright © 1994, 2001 Kenneth L. Harrenstien
** All Rights Reserved
**
** This file is part of the KLH10 Distribution. Use, modification, and
** re-distribution is permitted subject to the terms in the file
** named "LICENSE", which contains the full text of the legal notices
** and should always accompany this Distribution.
**
** This software is provided "AS IS" with NO WARRANTY OF ANY KIND.
**
** This notice (including the copyright and warranty disclaimer)
** must be included in all copies or derivations of this software.
*/
/*
* $Log: dvhost.h,v $
* Revision 2.3 2001/11/10 21:28:59 klh
* Final 2.0 distribution checkin
*
*/
#ifndef DVHOST_INCLUDED
#define DVHOST_INCLUDED 1
#ifdef RCSID
RCSID(dvhost_h,"$Id: dvhost.h,v 2.3 2001/11/10 21:28:59 klh Exp $")
#endif
/* Only externally visible entry point for HOST driver
*/
#include "kn10dev.h"
extern struct device * dvhost_create(FILE *f, char *s);
#define DVHOST_NSUP 1 /* Should be only 1! */
/* CONO bits
** Preliminary hackery...
*/
#define DVHOST_CO_IDLE 01 /* "Op-code" to do idle hackery */
#define DVHOST_REG_N 1 /* If on a Unibus, only one register */
#endif /* ifndef DVHOST_INCLUDED */

View File

@@ -31,7 +31,7 @@ static int decosfcclossage;
#if KLH10_DEV_LITES /* Moby conditional for entire file */
#include <asm/io.h>
#include <sys/io.h>
#include "dvlites.h"

View File

@@ -48,6 +48,7 @@ static int decosfcclossage;
#if KLH10_CPU_KS /* Moby conditional for entire file */
#include <stdio.h> /* For stderr if buggy */
#include <string.h>
#include "kn10def.h"
#include "kn10ops.h"

View File

@@ -52,6 +52,7 @@
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
@@ -90,6 +91,8 @@ int promiscon = FALSE; /* Desired mode (True = on) */
unsigned char pa_cur[6];
unsigned char pa_def[6];
int swstatus = 1;
static char *sprinteth(char *, unsigned char *);
static void penetaddr(char *ifc, unsigned char *cur, unsigned char *def);
static int pareth(char *, unsigned char *);
@@ -168,7 +171,7 @@ char *log_strerror(err)
static void log(char *fmt, ...)
static void logit(char *fmt, ...)
{
fprintf(stderr, "[%s: ", log_progname);
{
@@ -252,7 +255,7 @@ static void logfatal_ser(int num, char *fmt, ...)
#define dp_strerror log_strerror
#define dbprint log
#define dbprint logit
#define dbprintln logln
#define error logerror
#define syserr logerror_ser

File diff suppressed because it is too large Load Diff

View File

@@ -1,760 +0,0 @@
/* INJRST.C - Jump (and Stack) instruction routines
*/
/* $Id: injrst.c,v 2.4 2002/03/21 09:50:55 klh Exp $
*/
/* Copyright © 1992, 1993, 2001 Kenneth L. Harrenstien
** All Rights Reserved
**
** This file is part of the KLH10 Distribution. Use, modification, and
** re-distribution is permitted subject to the terms in the file
** named "LICENSE", which contains the full text of the legal notices
** and should always accompany this Distribution.
**
** This software is provided "AS IS" with NO WARRANTY OF ANY KIND.
**
** This notice (including the copyright and warranty disclaimer)
** must be included in all copies or derivations of this software.
*/
/*
* $Log: injrst.c,v $
* Revision 2.4 2002/03/21 09:50:55 klh
* Fixed refs of fe_debug to use mr_debug
*
* Revision 2.3 2001/11/10 21:28:59 klh
* Final 2.0 distribution checkin
*
*/
/* See CODING.TXT for guidelines to coding instruction routines. */
#include "klh10.h"
#include "kn10def.h"
#include "kn10ops.h"
#include <stdio.h> /* For debug output */
#ifdef RCSID
RCSID(injrst_c,"$Id: injrst.c,v 2.4 2002/03/21 09:50:55 klh Exp $")
#endif
/* Imported functions */
extern void pishow(FILE *);
extern void pcfshow(FILE *, h10_t flags);
insdef(i_jffo) /* JFFO */
{
register int i = op10ffo(ac_get(ac));
if (i < 36) { /* Found a bit? */
ac_setlrh(ac_off(ac,1), 0, i); /* Yep, set AC+1 */
PC_JUMP(e); /* and take the jump! */
return PCINC_0;
}
ac_setlrh(ac_off(ac,1), 0, 0); /* Empty, don't jump */
return PCINC_1;
}
insdef(i_jfcl)
{
if (ac) { /* See which flags we're asking for */
register h10_t flags;
flags = (h10_t)ac << (18-4); /* Shift to match PC flags */
if (PCFTEST(flags)) { /* Any of them match? */
PCFCLEAR(flags); /* Yes, clear them */
PC_JUMP(e); /* and take the jump! */
return PCINC_0;
}
}
return PCINC_1;
}
insdef(i_jsr) /* JSR */
{
register w10_t w;
PC_1WORD(w); /* Make PC-word in w (PC+1, plus flags if sect 0) */
vm_write(e, w); /* Store it at E */
PCFCLEAR(PCF_FPD|PCF_AFI|PCF_TR2|PCF_TR1); /* Clear these flags */
va_inc(e); /* Jump to E+1 (local or global) */
PC_JUMP(e);
return PCINC_0;
}
insdef(i_jsp) /* JSP */
{
register w10_t w;
PC_1WORD(w); /* Cons up PC+1 word in w */
ac_set(ac, w); /* Store it in AC */
PCFCLEAR(PCF_FPD|PCF_AFI|PCF_TR2|PCF_TR1); /* Clear these flags */
PC_JUMP(e); /* Jump to E */
return PCINC_0;
}
/* Note for JSA and JRA that there is no difference in their behavior
** when executed in non-zero sections.
*/
insdef(i_jsa) /* JSA */
{
register w10_t w;
vm_write(e, ac_get(ac)); /* Store c(AC) into E */
PC_XWDPC1(w, va_insect(e)); /* Cons up word: <e>,,<PC+1> */
ac_set(ac, w); /* Store that JSA-word in AC */
va_inc(e); /* Jump to E+1 */
PC_JUMP(e);
return PCINC_0;
}
insdef(i_jra) /* JRA */
{
register vaddr_t va;
va_lmake(va, PC_SECT,ac_getlh(ac)); /* Make AC.lh a local address */
ac_set(ac, vm_read(va)); /* Get c(AC.lh) into AC */
PC_JUMP(e); /* Jump to E */
return PCINC_0;
}
/* JRST hackery */
/* Declare subvariants of JRST */
pcinc_t ij_jrstf (int, int, vaddr_t);
pcinc_t ij_halt (int, int, vaddr_t);
pcinc_t ij_jen (int, int, vaddr_t);
pcinc_t ij_jrst10(int, int, vaddr_t);
#if !KLH10_SYS_ITS
pcinc_t ij_portal(int, int, vaddr_t);
pcinc_t ij_xjrstf(int, int, vaddr_t);
pcinc_t ij_xjen (int, int, vaddr_t);
pcinc_t ij_xpcw (int, int, vaddr_t);
pcinc_t ij_sfm (int, int, vaddr_t);
#endif
#if KLH10_CPU_KLX
pcinc_t ij_xjrst (int, int, vaddr_t);
#endif
insdef(i_jrst)
{
switch (ac) {
case 0: /* JRST */
PC_JUMP(e);
return PCINC_0;
#if !KLH10_SYS_ITS
case 1: return ij_portal(op, ac, e); /* PORTAL - not used by ITS */
#endif /* DEC */
case 2: return ij_jrstf(op, ac, e); /* JRSTF - Used */
case 4: return ij_halt(op, ac, e); /* HALT - Used */
#if !KLH10_SYS_ITS && (KLH10_CPU_KS||KLH10_CPU_KLX)
case 5: return ij_xjrstf(op, ac, e); /* XJRSTF - not used by ITS */
case 6: return ij_xjen(op, ac, e); /* XJEN - not used by ITS */
case 7: return ij_xpcw(op, ac, e); /* XPCW - not used by ITS */
#endif /* DEC KS || KLX */
case 010: return ij_jrst10(op, ac, e); /* JRST 10, - used once (?) */
case 012: return ij_jen(op, ac, e); /* JEN - used frequently */
#if !KLH10_SYS_ITS && (KLH10_CPU_KS||KLH10_CPU_KLX)
case 014: return ij_sfm(op, ac, e); /* SFM - not used by ITS */
# if KLH10_CPU_KLX
case 015: return ij_xjrst(op, ac, e); /* XJRST - not used by ITS */
# endif /* KLX */
#endif /* DEC */
#if KLH10_SYS_ITS
case 017: break; /* - used once by KL10 ITS */
#endif
}
/* Illegal - MUUO (3,11,13,16,17) */
return i_muuo(op, ac, e);
}
/* DORSTF - Actually carry out flag restoration for JRSTF/XJRSTF/XJEN/XPCW.
** Restore flags from the top 12 bits of the word in w.
**
** All flags are restored verbatim with these exceptions:
** USER cannot be cleared by a new setting of 0 (no effect), although
** a 1 will always set it.
** UIO can always be cleared, but new setting of 1 will only have
** an effect if the old mode is EXEC. (Note that if old
** mode is user, 1 merely has no effect; the bit may already
** be set and will remain so.)
** PUBLIC can always be set by a 1, but a 0 only has effect if
** old mode is EXEC and new mode is USER.
**
** No special actions are taken for PrevCtxtPublic or PrevCtxtUser.
**
** The wording of the DEC PRM (6/82 p.2-71) is a little misleading, as it
** implies that bit 6 (User-IO) cannot be set to 1 while in user mode; however,
** it appears in reality that it *can* be, if it was *already* 1.
** This is a rather subtle point.
*/
/* LH(w) contains flags to restore */
#if KLH10_EXTADR
static pcinc_t dorstf(register w10_t w, vaddr_t e, int pcsf)
# define IJ_DO_RSTF(w, e, pcsf) dorstf(w, e, pcsf)
#else
static pcinc_t dorstf(register w10_t w, vaddr_t e)
# define IJ_DO_RSTF(w, e, pcsf) dorstf(w, e)
#endif
{
register uint18 newf; /* New flags to restore */
#if KLH10_DEBUG
if (cpu.mr_debug) {
putc('[', stderr);
pishow(stderr); pcfshow(stderr, cpu.mr_pcflags);
#if KLH10_EXTADR
if (pcsf) fprintf(stderr, "(PCS:%o)", pag_pcsget());
#endif
fprintf(stderr,"%lo: -> ", (long) PC_30);
}
#endif
newf = LHGET(w); /* Get flags into easy-access reg */
if (PCFTEST(PCF_USR)) { /* Currently in user mode? */
newf |= PCF_USR; /* Never permit USR clearing */
if (!PCFTEST(PCF_UIO)) /* If not already in UIO, */
newf &= ~PCF_UIO; /* don't permit UIO setting */
}
#if KLH10_CPU_KL || KLH10_CPU_KI
if (PCFTEST(PCF_PUB) /* If trying to clear Public, */
&& (newf & PCF_PUB)==0) { /* Must be EXEC, setting USER too. */
if (PCFTEST(PCF_USR) || !(newf&PCF_USR))
newf |= PCF_PUB; /* Nope, don't clear it */
}
#endif /* KL || KI */
/* For XJRSTF/XJEN, a new PCS is loaded from the flag word only if
** the new flags specify EXEC mode.
** (PRM 2-66, 2nd sentence from bottom).
*/
#if KLH10_EXTADR /* If going into EXEC mode, restore PCS */
if (pcsf && !(newf & PCF_USR)) {
pag_pcsset(RHGET(w) & UBR_PCS); /* For now, ignore too-big PCS */
}
#endif
cpu.mr_pcflags = newf & PCF_MASK; /* Set new flags!! */
PC_JUMP(e); /* Take the jump... */
apr_pcfcheck(); /* Check flags for any changes. */
/* NOTE! It is important to check AFTER the PC has changed, so that
** if there is a user/exec context change, the saved JPC will be the
** appropriate one for the previous context.
*/
#if KLH10_DEBUG
if (cpu.mr_debug) {
pishow(stderr); pcfshow(stderr, cpu.mr_pcflags);
#if KLH10_EXTADR
if (pcsf) fprintf(stderr, "(PCS:%o)", pag_pcsget());
#endif
fprintf(stderr,"%lo:]\r\n", (long) PC_30);
}
#endif
return PCINC_0;
}
#if !KLH10_SYS_ITS
/* PORTAL (JRST 1,) - Clear Public and jump to E
** On KS10, equivalent to JRST.
*/
insdef(ij_portal)
{
#if KLH10_CPU_KI || KLH10_CPU_KL
PCFCLEAR(PCF_PUB); /* Always clear public, nothing else needed */
#endif
PC_JUMP(e);
return PCINC_0;
}
#endif /* !KLH10_SYS_ITS */
/* JRSTF (JRST 2,)- Jump and Restore Flags from final word used in calc of E.
**
** Because this word isn't saved by the normal instruction loop,
** it needs to be recomputed. This is painful, but I judged that
** it was better to make JRSTF slower so that every other instruction could
** be slightly faster.
**
** The "mr_injrstf" flag is set solely so any page faults which occur can
** avoid being faked out. No faults should in fact happen at this point;
** if any do there is a horrible error somewhere.
*/
insdef(ij_jrstf)
{
register w10_t w;
register vaddr_t ea;
#if KLH10_EXTADR
if (PC_ISEXT) /* A JRSTF in non-zero section is a MUUO */
return i_muuo(op, ac, e);
#endif
cpu.mr_injrstf = TRUE;
/* Assume that our execution started at mr_PC. This will be untrue
** only if we're being executed as a trap or interrupt instruction.
** XCT is allowed, but PXCT is fortunately illegal.
*/
ea = PC_VADDR; /* Get PC as a virtual address */
for (;;) {
w = vm_fetch(ea); /* Get instr */
if (iw_op(w) != I_XCT)
break;
ea = ea_calc(w); /* Is XCT, track chain */
}
if (iw_op(w) != op /* Must match original instr */
|| iw_ac(w) != ac) /* both in OP and AC */
panic("ij_jrstf: cannot duplicate op");
/* Now get to the point of this stupid exercise! */
w = ea_wcalc(w, cpu.acblk.xea, cpu.vmap.xea); /* Do full EA calc */
if (RHGET(w) != va_insect(e)) /* One more check... */
panic("ij_jrstf: cannot duplicate E");
cpu.mr_injrstf = FALSE; /* No more pagefault risk */
return IJ_DO_RSTF(w, e, FALSE);
}
/* JEN (JRST 12,) - Combination of JRST10 and JRSTF.
** Lets those routines do the work. JRSTF's hack to find the PC flags
** will work, because the opcode & AC are all passed along to it.
** If user mode, only legal if User-IOT is set.
*/
insdef(ij_jen)
{
#if KLH10_EXTADR
if (PC_ISEXT)
return i_muuo(op, ac, e);
#endif
#if KLH10_CPU_KS || KLH10_CPU_KA
if (PCFTEST(PCF_USR) && !PCFTEST(PCF_UIO))
#elif KLH10_CPU_KL
if ((PCFTEST(PCF_USR) && !PCFTEST(PCF_UIO)) /* User-IOT or Kernel */
|| (!PCFTEST(PCF_USR) && PCFTEST(PCF_PUB)))
#elif KLH10_CPU_KI
if (PCFTEST(PCF_USR | PCF_PUB)) /* Kernel mode only */
#endif
return i_muuo(op, ac, e);
pi_dismiss(); /* Tell PI to dismiss current int */
return ij_jrstf(op, ac, e);
}
/* JRST 10, - Dismisses current interrupt ("restores the level on which the
** highest priority interrupt is currently being held").
** If user mode, only legal if User-IOT is set.
*/
insdef(ij_jrst10)
{
#if KLH10_CPU_KS || KLH10_CPU_KA
if (PCFTEST(PCF_USR) && !PCFTEST(PCF_UIO)) /* User-IOT or Exec */
#elif KLH10_CPU_KL
if ((PCFTEST(PCF_USR) && !PCFTEST(PCF_UIO)) /* User-IOT or Kernel */
|| (!PCFTEST(PCF_USR) && PCFTEST(PCF_PUB)))
#elif KLH10_CPU_KI
if (PCFTEST(PCF_USR | PCF_PUB)) /* Kernel mode only */
#endif
return i_muuo(op, ac, e);
pi_dismiss(); /* Tell PI to dismiss current int */
PC_JUMP(e); /* Take the jump... */
#if KLH10_DEBUG
if (cpu.mr_debug) {
fprintf(stderr,"[ -> ");
pishow(stderr); pcfshow(stderr, cpu.mr_pcflags);
fprintf(stderr,"%lo:]\r\n", (long) PC_30);
}
#endif
return PCINC_0;
}
/* HALT (JRST 4,) - Halt the processor.
*/
insdef(ij_halt)
{
#if KLH10_CPU_KS || KLH10_CPU_KA
if (!PCFTEST(PCF_USR)) /* Exec mode can halt */
#elif KLH10_CPU_KL || KLH10_CPU_KI
if (!PCFTEST(PCF_USR|PCF_PUB)) /* Only Kernel mode can halt */
#endif
{
cpu.mr_haltpc = cpu.mr_PC; /* Remember loc of the HALT instr */
PC_JUMP(e); /* Update PC as if jumped */
apr_halt(HALT_PROG); /* Halt processor! */
/* Never returns */
}
return i_muuo(op, ac, e);
}
/* DEC extended variants of JRST, never used on ITS or a single-section KL */
#if !KLH10_SYS_ITS && (KLH10_CPU_KS||KLH10_CPU_KLX)
/* XJRSTF (JRST 5,)
** Pretty much the same as JRSTF except the flags and PC come from
** a pair of memory locations. On the KS10 no section addressing
** is possible (wonder what happens if tried on a real KS10?)
**
** XJRSTF and XJEN don't save anything.
** A new PCS is loaded from the flag word only if a KLX and the new
** flags specify exec mode (PRM 2-66, 2nd sentence from bottom).
** The new flags are used verbatim, except for the same restrictions
** as JRSTF (that is, USER, UIO, PUBLIC flags are special-cased).
** (PRM 2-71)
** See dorstf() for more comments.
*/
insdef(ij_xjrstf)
{
register dw10_t dpcw;
vm_dread(e, dpcw); /* Fetch double-wd from E, E+1 (may pageflt) */
va_lfrword(e, LOGET(dpcw)); /* New PC from c(E+1) */
return IJ_DO_RSTF(HIGET(dpcw), e, TRUE); /* Use flags from c(E) */
}
/* XJEN (JRST 6,)
** See comments for XJRSTF -- essentially the same.
** To XJRSTF as JEN is to JRSTF, but only allowed in Exec mode.
** However, one special precaution is taken; the PCW at E, E+1 is fetched
** prior to restoring an interrupt level, to ensure any page fault
** happens before clobbering the PI status!
** This is why the XJRSTF code is duplicated, rather than calling
** it after dismissing the interrupt.
*/
insdef(ij_xjen)
{
register dw10_t dpcw;
#if KLH10_CPU_KS
if (PCFTEST(PCF_USR)) /* Ensure we're in exec mode */
#elif KLH10_CPU_KLX
if ((PCFTEST(PCF_USR) && !PCFTEST(PCF_UIO)) /* User-IOT or Kernel */
|| (!PCFTEST(PCF_USR) && PCFTEST(PCF_PUB)))
#endif
return i_muuo(op, ac, e);
vm_dread(e, dpcw); /* Fetch double-wd from E, E+1 (may pageflt) */
pi_dismiss(); /* Tell PI to dismiss current int */
va_lfrword(e, LOGET(dpcw)); /* New PC from E+1 */
return IJ_DO_RSTF(HIGET(dpcw), e, TRUE); /* Use flags from E */
}
/* XPCW (JRST 7,)
** Note special precaution as for XJEN to ensure any page faults happen
** prior to changing flags or PC.
**
** PCS is saved in the flag word ONLY if old mode was exec (the flag
** test is on old flags, not new ones).
** No new PCS is set.
** The new flags are taken from the new flag word, subject to
** same restrictions as JRSTF. It doesn't appear that
** either PCP or PCU is specially set.
** PRM says XPCW should only be used as interrupt instr, but T20
** monitor does use it as regular instr (in SCHED).
** This code only implements its "regular" behavior; the KLH10
** PI interrupt code special-cases XPCW itself and never calls
** this routine.
*/
insdef(ij_xpcw)
{
register w10_t w;
register vaddr_t e2;
dw10_t dpcw;
#if KLH10_CPU_KS
if (PCFTEST(PCF_USR)) /* Ensure we're in exec mode */
#elif KLH10_CPU_KLX
if ((PCFTEST(PCF_USR) && !PCFTEST(PCF_UIO)) /* User-IOT or Kernel */
|| (!PCFTEST(PCF_USR) && PCFTEST(PCF_PUB)))
#endif
return i_muuo(op, ac, e);
e2 = e;
va_add(e2, 2); /* Get E+2 */
vm_dread(e2, dpcw); /* Fetch double from E+2, E+3 (may pageflt) */
LRHSET(w, cpu.mr_pcflags, 0); /* Set up 1st word of PCW */
#if KLH10_EXTADR
if (!PCFTEST(PCF_USR)) /* If in exec mode */
RHSET(w, pag_pcsget()); /* then OK to add pager's PrevContextSection */
#endif
vm_write(e, w); /* Store in E */
PC_1TOWORD(w); /* Set up PC+1 word */
va_inc(e);
vm_write(e, w); /* Store in E+1 */
va_lfrword(e2, LOGET(dpcw)); /* New PC from E+3 */
return IJ_DO_RSTF(HIGET(dpcw), e2, FALSE); /* Use flags from E+2 */
}
/* SFM (JRST 14,)
** This is now legal in user mode, but the PCS info is only stored if in
** exec mode. (PRM 2-72)
** Additionally, PRM 2-73 says on an extended KL, SFM is only legal in
** NZ section. However, this was changed as of KL ucode 331 to
** allow 0-section as well, and there is no IO-legal test;
** PCS is still only saved if in exec mode, though.
*/
insdef(ij_sfm)
{
register w10_t w;
#if KLH10_CPU_KS /* KS10 requires exec mode (kernel) */
if (PCFTEST(PCF_USR)) /* Ensure we're in exec mode */
return i_muuo(op, ac, e);
#endif
/* Don't need to mung flags since not changing modes */
LRHSET(w, cpu.mr_pcflags, 0); /* Set up 1st word of PCW */
#if KLH10_EXTADR
if (!PCFTEST(PCF_USR)) /* If in exec mode, */
RHSET(w, pag_pcsget()); /* add PCS to the flag word */
#endif
vm_write(e, w); /* Store in E */
return PCINC_1; /* That's all, no jump! */
}
#if KLH10_CPU_KLX
/* XJRST (JRST 15,)
** This is yet another late addition to the KL that was never
** documented in the PRM. It seems to have been added as of ucode
** 301 and is used extensively in the T20 monitor.
** Basically appears to jump to c(E) rather than E, treating
** the contents of E as a full 30-bit global virtual address. It's
** not clear whether the high 6 bits matter, but I'll assume they are
** ignored.
** This also appears to be legal in any section, in any mode.
** Not a bad idea, actually.
*/
insdef(ij_xjrst)
{
register w10_t w;
register vaddr_t va;
w = vm_read(e); /* Fetch c(E) */
va_gfrword(va, w); /* Turn into a virtual address */
PC_JUMP(va); /* Jump there! */
return PCINC_0;
}
#endif /* KLX */
#endif /* !ITS && (KS || KLX) */
/* Stack instructions */
/* Note: on the KA10 the push and pop operations are done by
** adding or subtracting 1,,1 as a word entity (ie not independent halves).
** Also, there are no trap flags, so Pushdown Overflow is set instead.
** These actions are not yet coded for, to avoid clutter.
*/
/* Note special page map context references for stack instructions.
** These are so PXCT can work by twiddling the context pointers.
** For:
** Computing E - normal ea_calc() using XEA map
** R/W of c(E) for PUSH, POP - normal XRW map
** R/W of stack data - special XBRW map
*/
#define vm_stkread(a) (vm_pget(vm_xbrwmap((a), VMF_READ)))
#define vm_stkwrite(a, w) (vm_pset(vm_xbrwmap((a), VMF_WRITE), (w)))
#define vm_stkmap(a, f) vm_xbrwmap((a), (f))
/* No other special actions are needed for PXCT; the test for running
** extended is always made using PC section (regardless of context).
** However, on an extended KL Uhler claims stack references should
** always be made in the current context. What isn't clear is whether
** a KLX is expected to ignore the stack-context AC bit (12), or if it
** does undefined things as a result.
** For generality this code does implement stack reference mapping even
** on a KLX, which corresponds to the latter option. As long as the
** monitor only uses valid AC bit combinations we'll be fine.
**
** HOWEVER - it appears from the DFKED diagnostic that bit 12 DOES
** operate in a real KL and it affects both the test for PC section AND the
** mapping used for the stack pointer. Ugh!!!!
** Don't know yet whether it is used by a real monitor.
*/
insdef(i_push)
{
register w10_t w;
register vaddr_t sloc;
w = ac_get(ac);
#if KLH10_EXTADR
/* Determine if stack pointer is local or global */
if (PC_ISEXT && op10m_skipge(w) && op10m_tlnn(w, VAF_SMSK)) {
/* Global format */
op10m_inc(w); /* Increment entire word */
va_gfrword(sloc, w); /* Get global addr from wd */
vm_stkwrite(sloc, vm_read(e)); /* Push c(E) on stack */
} else
#endif
{
/* Local format */
RHSET(w, (RHGET(w)+1)&H10MASK); /* Increment RH only */
va_lmake(sloc, PC_SECT, RHGET(w)); /* Get local address */
vm_stkwrite(sloc, vm_read(e)); /* Push c(E) on stack */
/* All mem refs won, safe to store AC and test for setting Trap 2 */
LHSET(w, (LHGET(w)+1)&H10MASK); /* Increment LH */
if (LHGET(w) == 0) /* If became 0, */
PCFTRAPSET(PCF_TR2); /* set Trap 2! */
}
ac_set(ac, w);
return PCINC_1;
}
insdef(i_pushj)
{
register w10_t pcw, w;
register vaddr_t sloc;
w = ac_get(ac);
PC_1WORD(pcw); /* Make PC+1 word */
#if KLH10_EXTADR
/* Determine if stack pointer is local or global */
if (PC_ISEXT && op10m_skipge(w) && op10m_tlnn(w, VAF_SMSK)) {
/* Global format */
op10m_inc(w); /* Increment entire word */
va_gfrword(sloc, w); /* Get global addr from wd */
vm_stkwrite(sloc, pcw); /* Push PC word on stack */
PCFCLEAR(PCF_FPD|PCF_AFI|PCF_TR2|PCF_TR1); /* Clear these flags */
} else
#endif
{
/* Local format */
RHSET(w, (RHGET(w)+1)&H10MASK); /* Increment RH only */
va_lmake(sloc, PC_SECT, RHGET(w)); /* Get local address */
vm_stkwrite(sloc, pcw); /* Push PC word on stack */
/* All mem refs won, safe to store AC and test for setting Trap 2 */
PCFCLEAR(PCF_FPD|PCF_AFI|PCF_TR2|PCF_TR1); /* Clear these flags */
LHSET(w, (LHGET(w)+1)&H10MASK); /* Increment LH */
if (LHGET(w) == 0) /* If became 0, */
PCFTRAPSET(PCF_TR2); /* set Trap 2! */
}
ac_set(ac, w);
PC_JUMP(e); /* Jump to new PC */
return PCINC_0;
}
insdef(i_pop)
{
register w10_t w;
register vaddr_t sloc;
w = ac_get(ac);
#if KLH10_EXTADR
/* Determine if stack pointer is local or global */
if (PC_ISEXT && op10m_skipge(w) && op10m_tlnn(w, VAF_SMSK)) {
/* Global format */
va_gfrword(sloc, w); /* Get global addr from wd */
vm_write(e, vm_stkread(sloc)); /* Pop stack to c(E) */
op10m_dec(w); /* Decrement entire word */
} else
#endif
{
/* Local format */
va_lmake(sloc, PC_SECT, RHGET(w)); /* Get local address */
vm_write(e, vm_stkread(sloc)); /* Pop stack to c(E) */
/* All mem refs won, safe to store AC and test for setting Trap 2 */
RHSET(w, (RHGET(w)-1)&H10MASK); /* Decrement RH only */
if (LHGET(w) == 0) { /* If decrement will wrap, */
PCFTRAPSET(PCF_TR2); /* set Trap 2! */
LHSET(w, H10MASK);
} else
LHSET(w, LHGET(w)-1); /* Decr LH, no mask needed */
}
ac_set(ac, w);
return PCINC_1;
}
insdef(i_popj)
{
register w10_t pcw, w;
register vaddr_t sloc;
w = ac_get(ac);
#if KLH10_EXTADR
/* Determine if stack pointer is local or global */
if (PC_ISEXT && op10m_skipge(w) && op10m_tlnn(w, VAF_SMSK)) {
/* Global format */
va_gfrword(sloc, w); /* Get global addr from wd */
pcw = vm_stkread(sloc); /* Pop PC word off stack */
op10m_dec(w); /* Decrement entire word */
} else
#endif
{
/* Local format */
va_lmake(sloc, PC_SECT, RHGET(w)); /* Get local address */
pcw = vm_stkread(sloc); /* Pop PC word off stack */
/* All mem refs won, safe to store AC and test for setting Trap 2 */
RHSET(w, (RHGET(w)-1)&H10MASK); /* Decrement RH only */
if (LHGET(w) == 0) { /* If decrement will wrap, */
PCFTRAPSET(PCF_TR2); /* set Trap 2! */
LHSET(w, H10MASK);
} else
LHSET(w, LHGET(w)-1); /* Decr LH, no mask needed */
}
/* Build correct new PC from PC word popped off */
if (PC_ISEXT)
va_lfrword(e, pcw);
else va_lmake(e, PC_SECT, RHGET(pcw));
ac_set(ac, w);
PC_JUMP(e); /* Now jump to restored PC */
return PCINC_0;
}
insdef(i_adjsp)
{
register w10_t w;
register h10_t h;
w = ac_get(ac); /* Get stack pointer */
#if KLH10_EXTADR
/* Determine if stack pointer is local or global */
if (PC_ISEXT && op10m_skipge(w) && op10m_tlnn(w, VAF_SMSK)) {
/* Global format */
if (H10SIGN & va_insect(e)) { /* Negative adjustment? */
register w10_t wadj;
LRHSET(wadj, H10MASK, va_insect(e)); /* Set up word */
op10m_add(w, wadj); /* Add negative adj */
} else
op10m_addi(w, va_insect(e)); /* Can just add immediately */
} else
#endif
{
/* Local format */
register h10_t adj = va_insect(e);
RHSET(w, (RHGET(w)+adj)&H10MASK); /* Add offset to RH */
if ((h = LHGET(w)+adj) & H10SIGN) { /* New count negative? */
if ((adj & H10SIGN) && (LHGET(w) & H10SIGN)==0)
PCFTRAPSET(PCF_TR2); /* Neg E made cnt pos -> neg */
} else { /* New count positive */
if ((adj & H10SIGN)==0 && (LHGET(w) & H10SIGN))
PCFTRAPSET(PCF_TR2); /* Pos E made cnt neg -> pos */
}
LHSET(w, (h & H10MASK)); /* Store new count */
}
ac_set(ac, w);
return PCINC_1;
}

View File

@@ -1,718 +0,0 @@
/* INMOVE.C - Word move instruction routines
*/
/* $Id: inmove.c,v 2.3 2001/11/10 21:28:59 klh Exp $
*/
/* Copyright © 1992, 1993, 2001 Kenneth L. Harrenstien
** All Rights Reserved
**
** This file is part of the KLH10 Distribution. Use, modification, and
** re-distribution is permitted subject to the terms in the file
** named "LICENSE", which contains the full text of the legal notices
** and should always accompany this Distribution.
**
** This software is provided "AS IS" with NO WARRANTY OF ANY KIND.
**
** This notice (including the copyright and warranty disclaimer)
** must be included in all copies or derivations of this software.
*/
/*
* $Log: inmove.c,v $
* Revision 2.3 2001/11/10 21:28:59 klh
* Final 2.0 distribution checkin
*
*/
#include "klh10.h"
#include "kn10def.h" /* Machine defs */
#include "kn10ops.h" /* PDP-10 ops */
#ifdef RCSID
RCSID(inmove_c,"$Id: inmove.c,v 2.3 2001/11/10 21:28:59 klh Exp $")
#endif
/* See CODING.TXT for guidelines to coding instruction routines. */
/* Full-word data stuff */
insdef(i_exch) /* EXCH AC,E */
{
register vmptr_t p = vm_modmap(e); /* Check access, get pointer */
register w10_t w;
w = vm_pget(p); /* Save mem in temporary loc */
vm_pset(p, ac_get(ac)); /* Move c(AC) to E */
ac_set(ac, w); /* Move c(E) to AC */
return PCINC_1;
}
/* MOVEx group - MOVE, MOVEI, MOVEM, MOVES */
insdef(i_move) /* MOVE AC,E */
{
ac_set(ac, vm_read(e));
return PCINC_1;
}
insdef(i_movei) /* MOVEI AC,E */
{
ac_setlrh(ac, 0, va_insect(e));
return PCINC_1;
}
insdef(i_movem) /* MOVEM AC,E */
{
vm_write(e, ac_get(ac));
return PCINC_1;
}
insdef(i_moves) /* MOVES AC,E */
{
register vmptr_t p = vm_modmap(e); /* Make write access ref */
if (ac) ac_set(ac, vm_pget(p));
return PCINC_1;
}
/* MOVSx group - MOVS, MOVSI, MOVSM, MOVSS */
insdef(i_movs) /* MOVS AC,E */
{
register w10_t w;
w = vm_read(e);
ac_setlrh(ac, RHGET(w), LHGET(w));
return PCINC_1;
}
insdef(i_movsi) /* MOVSI AC,E */
{
ac_setlrh(ac, va_insect(e), 0);
return PCINC_1;
}
insdef(i_movsm) /* MOVSM AC,E */
{
register w10_t w;
LRHSET(w, ac_getrh(ac), ac_getlh(ac));
vm_write(e, w);
return PCINC_1;
}
insdef(i_movss) /* MOVSS AC,E */
{
register vmptr_t p = vm_modmap(e); /* Make R/W access ref */
register w10_t w;
LRHSET(w, vm_pgetrh(p), vm_pgetlh(p));
vm_pset(p, w); /* Store back in mem */
if (ac) ac_set(ac, w);
return PCINC_1;
}
/* MOVNx group - MOVN, MOVNI, MOVNM, MOVNS */
insdef(i_movn) /* MOVN AC,E */
{
register w10_t w;
w = vm_read(e);
op10mf_movn(w); /* Negate, setting flags if necessary */
ac_set(ac, w);
return PCINC_1;
}
insdef(i_movni) /* MOVNI AC,E */
{
register w10_t w;
LRHSET(w, 0, va_insect(e));
op10mf_movn(w); /* Negate, setting flags if 0 */
ac_set(ac, w);
return PCINC_1;
}
insdef(i_movnm) /* MOVNM AC,E */
{
register vmptr_t p = vm_wrtmap(e); /* Check mem ref first */
register w10_t w;
w = ac_get(ac);
op10mf_movn(w); /* Negate, setting flags if necessary */
vm_pset(p, w);
return PCINC_1;
}
insdef(i_movns) /* MOVNS AC,E */
{
register vmptr_t p = vm_modmap(e); /* Check mem ref first */
register w10_t w;
w = vm_pget(p);
op10mf_movn(w); /* Negate, setting flags if necessary */
vm_pset(p, w);
if (ac) ac_set(ac, w);
return PCINC_1;
}
/* MOVMx group - MOVM, MOVMI, MOVMM, MOVMS */
insdef(i_movm) /* MOVM AC,E */
{
register w10_t w;
w = vm_read(e);
op10mf_movm(w); /* Make pos, setting flags if necessary */
ac_set(ac, w);
return PCINC_1;
}
#if 0
insdef(i_movmi) /* MOVMI AC,E is identical to MOVEI AC,E */
#endif
insdef(i_movmm) /* MOVMM AC,E */
{
register vmptr_t p = vm_wrtmap(e); /* Check mem ref first */
register w10_t w;
w = ac_get(ac);
op10mf_movm(w); /* Make pos, setting flags if necessary */
vm_pset(p, w);
return PCINC_1;
}
insdef(i_movms) /* MOVMS AC,E */
{
register vmptr_t p = vm_modmap(e); /* Check mem ref first */
register w10_t w;
w = vm_pget(p);
op10mf_movm(w); /* Make pos, setting flags if necessary */
vm_pset(p, w);
if (ac) ac_set(ac, w);
return PCINC_1;
}
/* Double-word data move instructions.
** DMOVE and DMOVEM are handled differently from the other instructions
** that manipulate double words, for greater efficiency.
**
** There is a large fuzzy gray area surrounding the question of page fails
** for double-word operands. In general the KLH10 tries not to do anything
** at all if a page fail would happen on either the first or second word,
** thus avoiding the issue of intermediate results.
**
** BUT! Examination of the ucode indicates otherwise:
** KL DMOVE/DMOVN: Atomic; both words are fetched before any ACs are set.
** A pagefail on read of 2nd word leaves no ACs changed.
** KL DMOVEM/DMOVNM: First gets both ACs, then stores.
** 1st (high) word is stored, then 2nd (low);
** A pagefail on write of 2nd word leaves 1st already stored.
**
** KS DMOVE/DMOVN: same as KL.
** KS DMOVEM/DMOVNM: 2nd word is stored, then 1st!?
**
** The KL diag (DFKEA) agrees with the KL for DMOVE and DMOVEM (DMOVN/M is
** not tested).
**
** Given this discrepancy, the KLH10's approach isn't so bad. But just to
** be ultra safe, I'll attempt to emulate the KS/KL lossage.
*/
/* DMOVE checks to see if the double can be copied directly into the
** ACs. If not, intermediate storage must be used to allow for the
** possibility of a page fault between words, or AC/address wraparound, or
** AC overlap if mem ref is to ACs.
*/
insdef(i_dmove) /* DMOVE AC,E */
{
/* See if fast move OK, normally true. Hope the testing doesn't end up
** using more time than the conservative case!
** NOTE this assumes C structure copies are done sequentially. If this
** is not true, must test for e == ac+1 instead.
*/
if (ac_issafedouble(ac) /* ACs contiguous? */
&& vm_issafedouble(e) /* Mem locs safe too? */
&& (va_insect(e) != ac_off(ac,-1))) /* no AC overlap with Mem? */
*ac_mapd(ac) = vm_pgetd(vm_xrwmap(e,VMF_READ)); /* Yep! */
else {
register dw10_t d; /* Conservative case, use intermed stg */
vm_dread(e, d); /* Fetch the double */
ac_dset(ac, d); /* Set in ACs */
}
return PCINC_1;
}
insdef(i_dmovem) /* DMOVEM AC,E */
{
/* See if fast move OK, normally true. Hope the testing doesn't end up
** using more time than the conservative case!
** NOTE this assumes C structure copies are done sequentially. If this
** is not true, must test for e == ac-1 instead.
*/
if (ac_issafedouble(ac) /* ACs contiguous? */
&& vm_issafedouble(e) /* Mem locs safe too? */
&& (va_insect(e) != ac_off(ac,1))) /* no AC overlap with Mem? */
vm_psetd(vm_xrwmap(e,VMF_WRITE), *ac_mapd(ac)); /* Yep! */
else {
register dw10_t d; /* Conservative case, use intermed stg */
#if KLH10_CPU_KL
ac_dget(ac, d); /* Get from ACs */
vm_write(e, d.w[0]); /* Do first word */
va_inc(e);
vm_write(e, d.w[1]); /* Do second word */
#elif KLH10_CPU_KS
register vaddr_t va;
ac_dget(ac, d); /* Get from ACs */
va = e;
va_inc(va);
vm_write(va, d.w[1]); /* Do second word first! */
vm_write(e, d.w[0]); /* Do first word last! */
#else /* What I'd really prefer to use - atomic double write */
register vmptr_t p0, p1;
p0 = vm_xrwmap(e, VMF_WRITE); /* Check access for 1st word */
va_inc(e); /* Bump E by 1, may wrap funnily */
p1 = vm_xrwmap(e, VMF_WRITE); /* Check access for 2nd word */
ac_dget(ac, d); /* Get from ACs */
vm_pset(p0, d.w[0]); /* Set 1st from AC */
vm_pset(p1, d.w[1]); /* Set 2nd from AC+1 */
#endif
}
return PCINC_1;
}
/* DMOVN is a vanilla double-precision arithmetic instruction.
** May set flags.
*/
insdef(i_dmovn) /* D_MOVN AC,E */
{
register dw10_t d;
vm_dread(e, d); /* Fetch into D */
op10mf_dmovn(d); /* Negate in place, with flags */
ac_dset(ac, d); /* Store in ACs */
return PCINC_1;
}
/* DMOVNM requires special-casing due to differing order of operation
** for the double-word memory store.
** May set flags. Note flags are set prior to possible page fail,
** thus potentially losing just like the ucode.
*/
insdef(i_dmovnm) /* DMOVNM AC,E */
{
register dw10_t d;
ac_dget(ac, d); /* Fetch AC, AC+1 into D */
op10mf_dmovn(d); /* Negate in place, with flags! */
if (vm_issafedouble(e)) /* Fast move OK? */
vm_psetd(vm_xrwmap(e,VMF_WRITE), d); /* Yep! */
else {
#if KLH10_CPU_KL
vm_write(e, HIGET(d)); /* Do first word */
va_inc(e);
vm_write(e, LOGET(d)); /* Do second word */
#elif KLH10_CPU_KS
register vaddr_t va;
va = e;
va_inc(va);
vm_write(va, LOGET(d)); /* Do second word first! */
vm_write(e, HIGET(d)); /* Do first word last! */
#else /* What I'd really prefer to use - atomic double write */
register vmptr_t p0, p1;
p0 = vm_xrwmap(e, VMF_WRITE); /* Check access for 1st word */
va_inc(e); /* Bump E by 1, may wrap funnily */
p1 = vm_xrwmap(e, VMF_WRITE); /* Check access for 2nd word */
vm_pset(p0, HIGET(d)); /* Set 1st (high) */
vm_pset(p1, LOGET(d)); /* Set 2nd (low) */
#endif
}
return PCINC_1;
}
/* BLT. (XBLT is handled by the EXTEND instr code) */
/* BLT - with optimization for case where dest is source+1.
** Note test for using same mapping, since BLT can be used for
** transfers between user and exec maps!
*/
/* Note special page map context references for BLT.
** These are so PXCT can work by twiddling the context pointers.
** For:
** Computing E - normal ea_calc() using XEA map
** Store word to destination - normal XRW map
** Read word from source - special XBRW map
*/
#define vm_srcread(a) (vm_pget(vm_xbrwmap((a), VMF_READ)))
/* Additional PXCT note for KLX:
** Uhler claims both source and dest must use the same (previous)
** context (thus the only valid AC values are 5 and 15 -- bits 10 and 12
** must always be set!)
** It isn't clear whether a KLX is expected to ignore those bits
** and always use previous context, or if it simply does undefined things
** if those bits are off (requesting current context).
** For simplicity this code does implement current context mapping
** even on a KLX, which corresponds to the latter option. As long as
** the monitor only uses valid AC bit combinations this is okay.
*/
/* There are some ambiguities in the DEC PRM p.2-8 description of BLT.
* Do the KI/KA test for RH[AC] >= RH(E) just as the KS/KL do, or can
the destination block wrap around?
[Assume yes, no dest wraparound]
* What happens if AC *is* in the destination block?
[Assume value indeterminate unless last word of xfer, then is
that value.]
* What happens if AC is in the source block?
[Assume value indeterminate, but if no pager/int, is original value]
[WRONG!!!! Turns out that for KS/KL, the AC is updated immediately
with the final src,,cnt value! So any copy involving that AC as
source will contain the "final" value. Aborts due to pagefail
or PI will re-clobber it with the correct intermediate value.
Exhibited by this test: MOVE 1,[1,,1] ? BLT 1,1
which leaves 2,,2 in AC1.]
* Exactly what is left in the AC for the KL case of RH[AC] > RH(E)?
The PRM says as if the "reverse xfer" happened, but does this
mean the last locs that wd have been referenced, or the next ones?
[Assume latter - the "next" ones.]
* The footnote on PRM p.2-8 claims an extended KL will count from section
0 up into 1. Exactly what does this mean? That a source block
could consist of stuff from sect 0 mem, then the ACs (cuz 1,,0-17 is
used to ref the ACs), then sect 1 mem? What about the optimized
case where dest == src+1, would this still use the original
word value or would the BLT start reading from the sect 1 source?
[Assume we don't need to emulate this lossage. Yeech.]
* !! Note from Uhler document that source and dest are incremented in-section
only, even if addresses are global, without altering local/global flag
that pager uses.
*/
insdef(i_blt)
{
register int32 cnt; /* Note signed */
register vaddr_t src, dst;
register vmptr_t vp;
#if KLH10_EXTADR
src = dst = e; /* E sets default section & l/g flag */
va_setinsect(src, ac_getlh(ac)); /* Set up source addr */
va_setinsect(dst, ac_getrh(ac)); /* Set up dest addr */
#else
va_lmake(src, 0, ac_getlh(ac));
va_lmake(dst, 0, ac_getrh(ac));
#endif
cnt = (va_insect(e) - va_insect(dst)); /* # words to move, less 1 */
if (cnt <= 0) {
/* Special case, either just 1 word or dest block would wrap
** (So-called "reverse transfer" attempt). Main reason for
** handling this specially is to emulate KL rev-xfer weirdness.
*/
register vmptr_t rp;
/* First ensure we can carry out the single xfer expected */
if (!(rp = vm_xbrwmap(src, VMF_READ|VMF_NOTRAP))
|| !(vp = vm_xrwmap(dst, VMF_WRITE|VMF_NOTRAP))) {
pag_fail(); /* Ugh, take page-fail trap */
}
/* OK, now if KL or KS, pre-clobber AC appropriately *before*
** the copy, so that if AC is involved, behavior will emulate
** the machines. Sigh.
*/
#if KLH10_CPU_KL
/* KL always updates as if the full reverse xfer happened */
ac_setlrh(ac, (va_insect(src)+cnt+1) & H10MASK,
(va_insect(dst)+cnt+1) & H10MASK);
#elif KLH10_CPU_KS
/* KS only reflects what actually got xfered (according to PRM;
** it may in fact behave like the KL for all I know!)
*/
ac_setlrh(ac, (va_insect(src)+1) & H10MASK,
(va_insect(dst)+1) & H10MASK);
#endif
vm_pset(vp, vm_pget(rp)); /* Copy directly from source */
return PCINC_1;
}
#if KLH10_CPU_KS || KLH10_CPU_KL
/* Before starting xfer, clobber AC to final value. This emulates
** the peculiar way the KS/KL do things. Note that due to this
** pre-clobberage, there is no need to store a final value at the
** end of a successful BLT. Any aborts MUST TAKE CARE to store the proper
** intermediate value!!
*/
ac_setlrh(ac, (va_insect(src)+cnt+1) & H10MASK,
(va_insect(dst)+cnt+1) & H10MASK);
#endif /* KS || KL */
if ((va_insect(src)+1) == va_insect(dst) /* Special case? */
&& (cpu.vmap.xrw == cpu.vmap.xbrw)) { /* Must have same mapping! */
/* Simple set-memory-to-value BLT */
register w10_t w;
/* Get first word and remember that. Just in case it helps the
** compiler optimize, use xrw map instead of xbrw since we only
** come here if they're the same.
*/
if (!(vp = vm_xrwmap(src, VMF_READ|VMF_NOTRAP))) {
ac_setlrh(ac, va_insect(src), /* Oops, save AC */
va_insect(dst));
pag_fail(); /* Take page-fail trap */
}
w = vm_pget(vp); /* Get word, remember it */
do {
CLOCKPOLL(); /* Keep clock going */
if (INSBRKTEST()) { /* Watch for interrupt */
ac_setlrh(ac, va_insect(src), /* Oops, save AC */
va_insect(dst));
apr_int(); /* Take interrupt */
}
if (!(vp = vm_xrwmap(dst, VMF_WRITE|VMF_NOTRAP))) {
ac_setlrh(ac, va_insect(src), /* Oops, save AC */
va_insect(dst));
pag_fail(); /* Take page-fail trap */
}
vm_pset(vp, w); /* Store word value */
va_linc(src); /* Do LOCAL increment of addrs! */
va_linc(dst);
} while (--cnt >= 0);
}
else do {
/* Normal BLT transfer */
register vmptr_t rp;
CLOCKPOLL(); /* Keep clock going */
if (INSBRKTEST()) { /* Watch for interrupt */
ac_setlrh(ac, va_insect(src), /* Oops, save AC */
va_insect(dst));
apr_int(); /* Take interrupt */
}
if (!(rp = vm_xbrwmap(src, VMF_READ|VMF_NOTRAP))
|| !(vp = vm_xrwmap(dst, VMF_WRITE|VMF_NOTRAP))) {
ac_setlrh(ac, va_insect(src), /* Oops, save AC */
va_insect(dst));
pag_fail(); /* Take page-fail trap */
}
vm_pset(vp, vm_pget(rp)); /* Copy directly from source */
va_linc(src); /* Add 1 to both addrs */
va_linc(dst); /* Again, LOCAL increment only */
} while (--cnt >= 0);
#if 0 /* No longer needed, code done inline to avoid this check */
/* Broke out of loop, see if page-failed or not */
if (cnt >= 0) { /* Use this as indicator */
ac_setlrh(ac, va_insect(src), /* Oops, save AC */
va_insect(dst));
pag_fail(); /* Ugh, take page-fail trap */
}
#endif
#if 0 /* KLH10_CPU_KS || KLH10_CPU_KL */
/* This is no longer used. Instead, to more accurately emulate the
** KS/KL, the final AC value is stored immediately at the start of
** the BLT code, so if nothing goes wrong, nothing needs to be done.
*/
/* End of BLT, but KS/KL must leave AC pointing
** to what would be the next transfer... unless AC happens
** to be the last destination!
**
** vp still points to last destination, so we can use that for testing,
** avoiding hassle of determining whether dst is an ac reference!
*/
if (ac_map(ac) != vp)
ac_setlrh(ac, va_insect(src), va_insect(dst));
#endif /* KS || KL */
return PCINC_1;
}
#if 0 /* Old version, saved in memory of simpler times */
insdef(i_blt)
{
register w10_t w, val;
register int optim;
e &= H10MASK;
w = ac_get(ac); /* Get src,,dst */
if ((LHGET(w)+1)&H10MASK == RHGET(w)) /* Special case? */
&& (cpu.vmap.xrw == cpu.vmap.xbrw)) { /* Must be same mapping! */
val = vm_srcread(LHGET(w));
optim = TRUE;
} else optim = FALSE;
for (;;) {
vm_write(RHGET(w), (optim ? val : vm_srcread(LHGET(w))));
if (RHGET(w) >= e) { /* Last word? Note also stop if AC.rh > E */
break; /* Win! */
}
LHSET(w, (LHGET(w)+1)&H10MASK); /* Add 1 to both halves */
RHSET(w, (RHGET(w)+1)&H10MASK);
ac_set(ac, w); /* Store back in AC in case of pagefail */
CLOCKPOLL(); /* Keep clock going */
if (INSBRKTEST()) apr_int(); /* Watch for interrupt */
}
/* End of BLT, but to emulate KS10 exactly must leave AC pointing
** to what would be the next transfer... unless AC is last destination.
*/
if (ac != RHGET(w)) {
LHSET(w, (LHGET(w)+1)&H10MASK); /* Add 1 to both halves */
RHSET(w, (RHGET(w)+1)&H10MASK);
ac_set(ac, w); /* Store back in AC */
}
return PCINC_1;
}
#endif /* 0 - old version */
/* BLTBU and BLTUB
**
** New KS10 instructions, not documented in PRM; behavior here is based
** on description from Alan. These are like BLT but transfer blocks of 8-bit
** bytes, packing or unpacking between "Byte format" and "Unibus format".
**
** "Byte format" is the normal PDP-10 format:
** <byte0><byte1><byte2><byte3><4 unused bits>
**
** "Unibus format" is sort of like the screwy PDP-11 byte order:
** <2-bits><byte1><byte0><2-bits><byte3><byte2>
**
** It isn't clear whether the <2-bits> fields are meaningful or whether they
** are mapped to and from the 4-bit field in Byte format.
** [Assume not mapped; extra bits are cleared in both directions]
**
** [Alan sez:
** Of course in the case of a device that can put 18 bits of data on the
** Unibus, the extra bits show up where the diagram says "2 BITS". (There is
** a bit in the UBA map that says whether the UBA should expect 18-bit data to
** be written to that page. I have no idea what happens if you set it wrong,
** perhaps it just controls whether the extra bits are passed through or
** written as 0.)]
*/
#if KLH10_CPU_KS
/* BLTBU - Like BLT but transforms each word from Byte to Unibus format.
** BLTUB - Ditto, Unibus to Byte format.
** For more explanation of the code, see BLT.
*/
#define defblt(name) \
insdef(name) { register w10_t w, val; \
register vaddr_t src, dst; \
register uint18 stop = va_insect(e); \
w = ac_get(ac); \
va_lmake(src, 0, LHGET(w)); \
va_lmake(dst, 0, RHGET(w)); \
for (;;) { \
val = vm_srcread(src); \
blttransform(val); \
vm_write(dst, val); \
if (RHGET(w) >= stop) \
break; \
LHSET(w, (LHGET(w)+1)&H10MASK); \
RHSET(w, (RHGET(w)+1)&H10MASK); \
ac_set(ac, w); \
CLOCKPOLL(); \
if (INSBRKTEST()) apr_int(); \
va_inc(src); \
va_inc(dst); \
} \
if (ac != RHGET(w)) { \
LHSET(w, (LHGET(w)+1)&H10MASK); \
RHSET(w, (RHGET(w)+1)&H10MASK); \
ac_set(ac, w); \
} \
return PCINC_1; \
}
/* Byte fmt to Unibus fmt, clears extra bits */
#define blttransform(v) \
RHSET(v, ((RHGET(v)<<4)&(0377<<8)) \
| ((LHGET(v)&03)<<6) | ((RHGET(v)>>12)&077) ); \
LHSET(v, ((LHGET(v)>>10)&0377) | ((LHGET(v)<<6)&(0377<<8)) )
defblt(i_bltbu)
#undef blttransform
/* Unibus fmt to Byte fmt, clears extra bits */
#define blttransform(v) \
LHSET(v, ((LHGET(v)&0377)<<10) \
| ((LHGET(v)&(0377<<8))>>6) \
| ((RHGET(v)>>6)&03) ); \
RHSET(v, ((RHGET(v)>>4)&(0377<<4)) \
| ((RHGET(v)&&077)<<12) )
defblt(i_bltub)
#undef blttransform
#endif /* KS */
#if KLH10_EXTADR
/* XMOVEI and XHLLI.
** These two instructions are not as straightforward as they
** might seem. One might expect them to simply:
** (1) use whatever the section number of the EA is, or
** (2) always set LH = 1 if reference is to an AC.
**
** In fact, they do neither.
** The use of LH=1 to represent a global AC address happens ONLY if:
** (a) EA is local, (b) section # is non-zero, and (c) in-section
** address is 0-17 inclusive.
**
** In particular, a local reference to 0,,AC (even if made while PC_ISEXT)
** will be stored as 0,,AC and not 1,,AC.
** Likewise, a global reference to 0,,AC is stored as 0,,AC even though
** it *DOES* reference the ACs, just like 1,,AC!
**
** The following table sums it up:
**
** LOCAL 0,,AC => 0,,AC
** LOCAL NZ,,AC => 1,,AC
** LOCAL *,,NAC => *,,NAC
** GLOBAL *,,* => *,,*
**
** This behavior is coded into the va_iscvtacref() macro.
**
** Finally, this same conversion is also done for the EA stored as a result
** of a LUUO, MUUO, or pagefail trap.
** (what about PC?)
*/
/* XMOVEI - Actually an extended SETMI.
** Special boolean variant when using extended addressing
*/
insdef(i_xmovei)
{
if (va_iscvtacref(e))
ac_setlrh(ac, 1, va_insect(e)); /* Global AC reference */
else
ac_setlrh(ac, va_sect(e), va_insect(e));
return 1;
}
/* XHLLI - Actually an extended HLLI.
** Special halfword variant when using extended addressing
*/
insdef(i_xhlli)
{
if (va_iscvtacref(e))
ac_setlh(ac, 1); /* Global AC reference */
else
ac_setlh(ac, va_sect(e));
return 1;
}
#endif /* KLH10_EXTADR */

View File

@@ -337,6 +337,7 @@ CMDDEF(cd_lights, fc_lights, CMRF_TLIN, "<hexaddr>",
KEYSBEGIN(fectbkeys)
KEYDEF("?", cd_ques)
KEYDEF("help", cd_help)
KEYDEF("exit", cd_quit)
KEYDEF("quit", cd_quit)
KEYDEF("load", cd_load)
KEYDEF("dump", cd_dump)
@@ -2765,6 +2766,7 @@ fc_dump(struct cmd_s *cm)
static void
fc_lights(struct cmd_s *cm)
{
#if KLH10_DEV_LITES /* Moby conditional for entire file */
unsigned long port = 0;
int c;
char *sloc = cm->cmd_arglin;
@@ -2783,6 +2785,7 @@ fc_lights(struct cmd_s *cm)
}
}
printf("?Bad address\n");
#endif /* KLH10_DEV_LITES */
}
/* Instruction printing routines */

File diff suppressed because it is too large Load Diff

View File

@@ -1,410 +0,0 @@
/* KLH10.H - General Configuration Definitions
*/
/* $Id: klh10.h,v 2.10 2003/02/23 18:23:38 klh Exp $
*/
/* Copyright © 1992, 1993, 2001 Kenneth L. Harrenstien
** All Rights Reserved
**
** This file is part of the KLH10 Distribution. Use, modification, and
** re-distribution is permitted subject to the terms in the file
** named "LICENSE", which contains the full text of the legal notices
** and should always accompany this Distribution.
**
** This software is provided "AS IS" with NO WARRANTY OF ANY KIND.
**
** This notice (including the copyright and warranty disclaimer)
** must be included in all copies or derivations of this software.
*/
/*
* $Log: klh10.h,v $
* Revision 2.10 2003/02/23 18:23:38 klh
* Bump version: 2.0H
*
* Revision 2.9 2002/05/21 16:54:32 klh
* Add KLH10_I_CIRC to allow any sys to have CIRC
*
* Revision 2.8 2002/05/21 09:41:58 klh
* Bump version: 2.0G
*
* Revision 2.7 2002/04/24 07:40:10 klh
* Bump version to 2.0E
*
* Revision 2.6 2002/03/28 16:51:39 klh
* Version 2.0D update
*
* Revision 2.5 2002/03/21 09:50:38 klh
* New version
*
* Revision 2.4 2001/11/19 10:39:05 klh
* Bump version: 2.0A
*
* Revision 2.3 2001/11/10 21:28:59 klh
* Final 2.0 distribution checkin
*
*/
#ifndef KLH10_INCLUDED
#define KLH10_INCLUDED 1
#ifndef KLH10_USE_RCSID /* For now, default to always on */
# define KLH10_USE_RCSID 1
#endif
#if KLH10_USE_RCSID
# include "rcsid.h"
#endif
#ifdef RCSID
RCSID(klh10_h,"$Id: klh10.h,v 2.10 2003/02/23 18:23:38 klh Exp $")
#endif
/* Preliminary legalisms (heavy sigh) */
#ifndef KLH10_COPYRIGHT
# define KLH10_COPYRIGHT "\
Copyright © 2002 Kenneth L. Harrenstien -- All Rights Reserved."
#endif
#ifndef KLH10_WARRANTY
# define KLH10_WARRANTY "This program comes \"AS IS\" with ABSOLUTELY NO WARRANTY."
#endif
#ifndef KLH10_VERSION
# define KLH10_VERSION "V2.0H"
#endif
#ifndef KLH10_CLIENT
# define KLH10_CLIENT "Generic"
#endif
/* C environment setup definitions.
*/
#include "cenv.h" /* Get CENV_CPU_ and CENV_SYS_ */
/* Canonical C true/false values */
#define TRUE 1
#define FALSE 0
/* For convenience when passing/setting a function pointer to NULL, to
show its nature without specifying the entire prototype. NULL alone
is sufficient in ANSI C.
*/
#define NULLPROC (NULL)
/* Compilation switches defining desired emulation target */
/* Define CPU type to emulate.
** For now, ignore peculiarities such as Foonly and Systems Concepts
** since they were primarily emulations of some DEC type.
*/
#ifndef KLH10_CPU_6 /* DEC PDP-6 (Model 166 processor) */
# define KLH10_CPU_6 0
#endif
#ifndef KLH10_CPU_KA /* DEC KA10 */
# define KLH10_CPU_KA 0
#endif
#ifndef KLH10_CPU_KI /* DEC KI10 */
# define KLH10_CPU_KI 0
#endif
#ifndef KLH10_CPU_KS /* DEC KS10 (2020) */
# define KLH10_CPU_KS 0
#endif
#ifndef KLH10_CPU_KL0 /* DEC KL10 (single section - KL10A?) */
# define KLH10_CPU_KL0 0
#endif
#ifndef KLH10_CPU_KLX /* DEC KL10 (extended KL10B, 0 or non-0 section) */
# define KLH10_CPU_KLX 0
#endif
#ifndef KLH10_CPU_KN /* KLH KN10 (placeholder for non-HW features) */
# define KLH10_CPU_KN 0
#endif
#ifndef KLH10_CPU_XKL /* XKL XKL-1 (TOAD-1 System), a super-extended KL */
# define KLH10_CPU_XKL 0
#endif
#if !(KLH10_CPU_6|KLH10_CPU_KA|KLH10_CPU_KI \
|KLH10_CPU_KS|KLH10_CPU_KL0|KLH10_CPU_KLX|KLH10_CPU_KN|KLH10_CPU_XKL)
# undef KLH10_CPU_KS
# define KLH10_CPU_KS 1 /* Use KS10 as default */
#endif
#define KLH10_CPU_KL (KLH10_CPU_KL0 || KLH10_CPU_KLX || KLH10_CPU_XKL)
/* Define SYSTEM type emulated machine supports.
** Primarily affects paging, but sometimes a few other things.
** These switches are comparable to KS/KL ucode conditionals, since
** each system tends to have its own peculiar variety of ucode (or
** even different hardware, for KA/KI).
*/
#ifndef KLH10_SYS_ITS /* MIT ITS system */
# define KLH10_SYS_ITS 0
#endif
#ifndef KLH10_SYS_WTS /* Stanford WAITS system */
# define KLH10_SYS_WTS 0
#endif
#ifndef KLH10_SYS_10X /* BBN TENEX system */
# define KLH10_SYS_10X 0
#endif
#ifndef KLH10_SYS_T10 /* DEC TOPS-10 system */
# define KLH10_SYS_T10 0
#endif
#ifndef KLH10_SYS_T20 /* DEC TOPS-20 system */
# define KLH10_SYS_T20 0
#endif
#if !(KLH10_SYS_ITS|KLH10_SYS_WTS|KLH10_SYS_10X|KLH10_SYS_T10|KLH10_SYS_T20)
# undef KLH10_SYS_ITS
# define KLH10_SYS_ITS 1 /* Default for now is ITS (yeah!) */
#endif
/* Now define additional flags peculiar to each system/CPU, which
** describe the hardware features emulated ("what" as opposed to "how").
** These could go into kn10*.h config files, where
** * = 3-letter CPU or SYS identifier.
*/
/* Select pager to use.
** DEC has had 3 different varieties of memory mgt:
** KA relocation (not emulated)
** KI paging (emulated; also called "Tops-10 paging")
** KL paging (emulated; also called "Tops-20 paging")
** For ITS this depended on the machine. Only the KS is emulated here.
** For TENEX a special BBN pager was used. This is not emulated,
** but would be quite similar to KL paging.
*/
#ifndef KLH10_PAG_KI
# define KLH10_PAG_KI 0
#endif
#ifndef KLH10_PAG_KL
# define KLH10_PAG_KL 0
#endif
#ifndef KLH10_PAG_ITS
# define KLH10_PAG_ITS 0
#endif
/* If no paging scheme explicitly selected, pick default */
#if !(KLH10_PAG_KI | KLH10_PAG_KL | KLH10_PAG_ITS)
# undef KLH10_PAG_KI
# define KLH10_PAG_KI KLH10_SYS_T10
# undef KLH10_PAG_KL
# define KLH10_PAG_KL KLH10_SYS_T20
# undef KLH10_PAG_ITS
# define KLH10_PAG_ITS KLH10_SYS_ITS
#endif
#if KLH10_SYS_ITS /* ITS normally includes all of these */
# ifndef KLH10_ITS_JPC
# define KLH10_ITS_JPC 1 /* Include ITS JPC feature */
# endif
# if KLH10_ITS_JPC
# undef KLH10_JPC
# define KLH10_JPC 1 /* Include general-purpose JPC, for debug */
# endif
# ifndef KLH10_ITS_1PROC
# define KLH10_ITS_1PROC 1 /* Include ITS 1-proceed feature */
# endif
#endif
#ifndef KLH10_I_CIRC /* True to include ITS CIRC instruction */
# define KLH10_I_CIRC (KLH10_SYS_ITS)
#endif
#ifndef KLH10_MCA25 /* MCA25 KL Cache/Paging Upgrade */
# define KLH10_MCA25 (KLH10_CPU_KL && KLH10_SYS_T20)
#endif
#ifndef KLH10_EXTADR /* True to support extended addressing */
# define KLH10_EXTADR (KLH10_CPU_KLX || KLH10_CPU_XKL)
#endif
/* Peripheral Devices
** Determine here which ones will be available for use.
** Further configuration is done at runtime.
*/
/* KL10 devices (old-style IO bus devices) */
#ifndef KLH10_DEV_DTE
# define KLH10_DEV_DTE KLH10_CPU_KL
#endif
#ifndef KLH10_DEV_RH20
# define KLH10_DEV_RH20 KLH10_CPU_KL
#endif
#ifndef KLH10_DEV_NI20
# define KLH10_DEV_NI20 KLH10_CPU_KL
#endif
/* KS10 devices (new-style Unibus devices) */
#ifndef KLH10_DEV_RH11
# define KLH10_DEV_RH11 KLH10_CPU_KS
#endif
#ifndef KLH10_DEV_DZ11 /* KS10 DZ11 also part of basic system? */
# define KLH10_DEV_DZ11 KLH10_SYS_ITS /* Try just ITS for now */
#endif
#ifndef KLH10_DEV_LHDH /* KS10 LHDH IMP interface */
# define KLH10_DEV_LHDH KLH10_SYS_ITS /* Only on ITS for now */
#endif
#ifndef KLH10_DEV_CH11 /* KS10 CH11 Chaosnet interface? */
# define KLH10_DEV_CH11 KLH10_SYS_ITS /* Only on ITS for now */
#endif
/* Generic controller drive devices - work for either bus */
#ifndef KLH10_DEV_RPXX
# define KLH10_DEV_RPXX (KLH10_DEV_RH20 | KLH10_DEV_RH11)
#endif
#ifndef KLH10_DEV_TM03
# define KLH10_DEV_TM03 (KLH10_DEV_RH20 | KLH10_DEV_RH11)
#endif
/* Universal devices - currently just one pseudo-dev */
#ifndef KLH10_DEV_HOST
# define KLH10_DEV_HOST 1
#endif
/* CPU and PI configuration (PI includes IO)
** The parameters defined earlier specify WHAT to emulate; by contrast,
** these specify HOW the emulation should be done.
*/
#ifndef KLH10_PCCACHE /* True to include experimental PC cache stuff */
# define KLH10_PCCACHE 1
#endif
#ifndef KLH10_JPC /* True to include JPC feature */
# define KLH10_JPC 1 /* For now, always - helps debug! */
#endif
/* MEMORY - Select emulation method
** Sharable memory has pitfalls but is useful for subproc DMA and
** perhaps future SMP implementation.
*/
#ifndef KLH10_MEM_SHARED /* TRUE to use sharable memory segment */
# define KLH10_MEM_SHARED 0
#endif
/* REAL-TIME CLOCK - Select emulation method
*/
#ifndef KLH10_RTIME_SYNCH /* Synchronized - use count */
# define KLH10_RTIME_SYNCH 0
#endif
#ifndef KLH10_RTIME_OSGET /* OS value used for all references */
# define KLH10_RTIME_OSGET 0
#endif
#ifndef KLH10_RTIME_INTRP /* Interrupt-driven (not implemented) */
# define KLH10_RTIME_INTRP 0
#endif
#if !(KLH10_RTIME_SYNCH|KLH10_RTIME_OSGET|KLH10_RTIME_INTRP)
# undef KLH10_RTIME_OSGET
# define KLH10_RTIME_OSGET 1 /* Default to asking system */
#endif
/* INTERVAL-TIME CLOCK - Select emulation method
*/
#ifndef KLH10_ITIME_SYNCH /* Synchronized - use count */
# define KLH10_ITIME_SYNCH 0
#endif
#ifndef KLH10_ITIME_INTRP /* Interrupt-driven */
# define KLH10_ITIME_INTRP 0
#endif
#if !(KLH10_ITIME_SYNCH|KLH10_ITIME_INTRP)
# undef KLH10_ITIME_SYNCH
# define KLH10_ITIME_SYNCH 1 /* Default to synchronous counter */
#endif
/* INTERVAL-TIME CLOCK - set default interval in HZ
** This is the actual interval time in HZ that will be enforced
** unless the user explicitly does a "set clk_ithzfix".
** A value of 0 allows the 10 to set it to anything.
** 60 is a good default; 30 may be needed on slower/older hardware.
*/
#ifndef KLH10_CLK_ITHZFIX
# define KLH10_CLK_ITHZFIX 60
#endif
/* QUANTUM COUNTER - Select emulation method (ITS only)
*/
#ifndef KLH10_QTIME_SYNCH /* Synchronized - use count */
# define KLH10_QTIME_SYNCH 0
#endif
#ifndef KLH10_QTIME_OSREAL /* Use OS realtime */
# define KLH10_QTIME_OSREAL 0
#endif
#ifndef KLH10_QTIME_OSVIRT /* Use OS virtual (user CPU) time */
# define KLH10_QTIME_OSVIRT 0
#endif
#if KLH10_SYS_ITS /* Only default if ITS */
# if !(KLH10_QTIME_SYNCH|KLH10_QTIME_OSREAL|KLH10_QTIME_OSVIRT)
# undef KLH10_QTIME_SYNCH
# define KLH10_QTIME_SYNCH 1 /* Default to synchronous counter */
# endif
#endif
/* DEVICE I/O WAKEUP - Select I/O checking method for various devices.
** These parameters select interrupt-driven methods if TRUE;
** otherwise polling is used.
** Future alternatives may use threads or subprocesses.
*/
#ifndef KLH10_CTYIO_INT /* True to use CTY interrupts */
# define KLH10_CTYIO_INT 0
#endif
#ifndef KLH10_IMPIO_INT /* True to use IMP interrupts */
# define KLH10_IMPIO_INT 0
#endif
#ifndef KLH10_EVHS_INT /* True to use new event handling scheme */
# define KLH10_EVHS_INT 0
#endif
/* DEVICE SUBPROCESS - Select basic implementation method for various devices
** These parameters select an asynchronous sub-process method if TRUE;
** otherwise a blocking method is used.
** Not all devices will work without subprocesses (e.g. NI20)
** Future alternatives may use threads.
*/
#ifndef KLH10_DEV_DPNI20 /* True to use dev subproc for NI20 net */
# define KLH10_DEV_DPNI20 KLH10_DEV_NI20
#endif
#ifndef KLH10_DEV_DPRPXX /* True to use dev subproc for RPxx disk */
# define KLH10_DEV_DPRPXX 0
#endif
#ifndef KLH10_DEV_DPTM03 /* True to use dev subproc for TM03 tape */
# define KLH10_DEV_DPTM03 0
#endif
/* Two different ways to implement IMP subproc */
#ifndef KLH10_DEV_DPIMP /* True to use dev subproc for IMP (net) */
# define KLH10_DEV_DPIMP KLH10_DEV_LHDH
#endif
#ifndef KLH10_DEV_SIMP /* True to use pipe subproc for IMP (net) */
# define KLH10_DEV_SIMP (KLH10_DEV_LHDH && !KLH10_DEV_DPIMP)
#endif
#ifndef KLH10_DEV_DP /* True to include DP subproc support */
# define KLH10_DEV_DP (KLH10_DEV_DPNI20 \
|KLH10_DEV_DPRPXX|KLH10_DEV_DPTM03|KLH10_DEV_DPIMP)
#endif
/* Miscellaneous config vars */
#ifndef KLH10_INITFILE /* Default initialization command file */
# define KLH10_INITFILE "klh10.ini"
#endif
#ifndef KLH10_DEBUG /* TRUE to include debug output code */
# define KLH10_DEBUG 1
#endif
/* Hack for KS T20 CTY output. (see cty_addint() in dvcty.c)
*/
#ifndef KLH10_CTYIO_ADDINT /* Set 1 to use hack */
# define KLH10_CTYIO_ADDINT (KLH10_CPU_KS && KLH10_SYS_T20 && KLH10_CTYIO_INT)
#elif KLH10_CTYIO_ADDINT
# if !KLH10_CPU_KS || !KLH10_SYS_T20 /* Unless a KS T20, */
# undef KLH10_CTYIO_ADDINT /* force this to 0 */
# define KLH10_CTYIO_ADDINT 0
# endif
#endif
#endif /* ifndef KLH10_INCLUDED */

File diff suppressed because it is too large Load Diff

View File

@@ -235,7 +235,8 @@ typedef int pcinc_t; /* Type of all instruction routines */
#if KLH10_EXTADR
# define PC_ADDXCT(x) { register pcinc_t i__ = (x); if (i__) PC_ADD(i__); }
#else
# define PC_ADDXCT(x) (cpu.mr_PC += (x)) /* For now; fix up later? */
# define PC_ADDXCT(x) { volatile pcinc_t i__ = (x); cpu.mr_PC += i__; }
/*# define PC_ADDXCT(x) (cpu.mr_PC += (x)) / * For now; fix up later? */
#endif
/* Macros for putting PC into a word.

View File

@@ -1,971 +0,0 @@
/* KLH10 CPU state and register definitions
*/
/* $Id: kn10def.h,v 2.5 2002/05/21 10:02:31 klh Exp $
*/
/* Copyright © 1992, 1993, 2001 Kenneth L. Harrenstien
** All Rights Reserved
**
** This file is part of the KLH10 Distribution. Use, modification, and
** re-distribution is permitted subject to the terms in the file
** named "LICENSE", which contains the full text of the legal notices
** and should always accompany this Distribution.
**
** This software is provided "AS IS" with NO WARRANTY OF ANY KIND.
**
** This notice (including the copyright and warranty disclaimer)
** must be included in all copies or derivations of this software.
*/
/*
* $Log: kn10def.h,v $
* Revision 2.5 2002/05/21 10:02:31 klh
* Fix SYNCH implementation of KL timebase
*
* Revision 2.4 2002/03/21 09:50:08 klh
* Mods for CMDRUN (concurrent mode)
*
* Revision 2.3 2001/11/10 21:28:59 klh
* Final 2.0 distribution checkin
*
*/
#ifndef KN10DEF_INCLUDED
#define KN10DEF_INCLUDED 1
#ifdef RCSID
RCSID(kn10def_h,"$Id: kn10def.h,v 2.5 2002/05/21 10:02:31 klh Exp $")
#endif
#include "osdsup.h" /* Ensure any OS-dependent stuff is available */
#include "word10.h" /* Basic PDP-10 word definitions & facilities */
#ifndef EXTDEF
# define EXTDEF extern /* Default is to declare (not define) vars */
#endif
/* INSBRK - Sum of all interrupt flags. This is invoked whenever something
** (PI interrupt, trap, device I/O, etc) wants to break out of the normal
** instruction execution loop once the current instruction is done.
** See the INTF macros in osdsup.h.
*/
#define INSBRK_INIT() INTF_INIT(cpu.mr_insbreak)
#define INSBRKSET() INTF_SET(cpu.mr_insbreak)
#define INSBRKTEST() INTF_TEST(cpu.mr_insbreak)
#define INSBRK_ACTBEG() INTF_ACTBEG(cpu.mr_insbreak)
#define INSBRK_ACTEND() INTF_ACTEND(cpu.mr_insbreak)
/* Accumulator reference definitions */
#define AC_BITS 4
#define AC_N (1<<AC_BITS)
#define AC_MASK (AC_N-1)
#define AC_0 0
#define AC_17 017 /* Last AC - same as AC_MASK */
/* For speed, the current AC block is always kept in a fixed place at the
** start of the cpu struct. A different array contains all ac blocks,
** including the "shadow" ac block; when the current ac block is changed,
** the acs are copied back into this array and the newly selected block
** restored to the "current ACs".
** The various pointers to specific blocks are needed for making
** mapped memory references, which may or may not involve the previous
** context ACs. Whenever the reference is to the current ACs the pointer
** is always to the actual cpu.acs block, not its shadow in cpu.acblks.
*/
#define ACBLKS_N 8 /* Max # of AC blocks supported */
/* AC blocks are allocated as cpu.acblks in the cpu struct farther on. */
typedef w10_t *acptr_t; /* Pointer to an AC */
typedef struct {
w10_t ac[AC_N];
} acblk_t; /* AC block - 16 words */
struct acregs { /* Pointers to specific AC blocks */
acptr_t cur, /* Current AC block, always points to cpu.acs */
prev, /* Previous context AC block */
xea, /* AC block for EA calc */
xrw, /* AC block for mem access */
xbea, /* AC block for byte ptr EA calc */
xbrw; /* AC block for byte ptr mem access */
};
/* Macro to simplify the setting of new AC block mappings
*/
#define acmap_set(new, old) ( \
(cpu.acblk.xea = cpu.acblk.xrw = \
cpu.acblk.xbea = cpu.acblk.xbrw = \
cpu.acblk.cur = (new)), \
(cpu.acblk.prev = (old)) )
/* Fundamental macro to get pointer to AC, given mapping and AC #.
** No arg checking is done; the AC # MUST be (AC_0 <= # <= AC_17).
*/
#define ac_xmap(a,p) (&((p)[(a)]))
/* Derive new AC # given offset - implements wraparound of AC # */
#define ac_off(a,i) (((a)+(i))&AC_MASK)
/* Standard macro used for all AC references (NOT indexing or fast memory)
*/
#define ac_map(a) ac_xmap((a),cpu.acs.ac)
#define ac_mapd(a) ((dw10_t *)ac_map(a)) /* Only use if safedouble */
/* Given pointer to AC entry, convert to and from words and halfwords.
** These work for either kind of AC reference.
*/
#define ac_pget(p) (*(p))
#define ac_pgetlh(p) LHPGET(p)
#define ac_pgetrh(p) RHPGET(p)
#define ac_pset(p,w) (*(p) = (w))
#define ac_psetlh(p,h) LHPSET(p,h)
#define ac_psetrh(p,h) RHPSET(p,h)
/* Define standard AC read/write operations
** (again, NOT for use with indexing or fast-memory refs)
*/
#define ac_get(a) (*ac_map(a))
#define ac_getlh(a) LHPGET(ac_map(a))
#define ac_getrh(a) RHPGET(ac_map(a))
#define ac_set(a,w) (*ac_map(a) = (w))
#define ac_setlh(a,v) LHPSET(ac_map(a), (v))
#define ac_setrh(a,v) RHPSET(ac_map(a), (v))
#define ac_setlrh(a,l,r) XWDPSET(ac_map(a),l,r)
/* Macros to fetch AC contents when indexing or as fast memory. These
** require an AC block mapping pointer in addition to the AC #.
*/
#define ac_xget(a,p) (*ac_xmap(a,p))
#define ac_xgetrh(a,p) RHPGET(ac_xmap(a,p))
/* Facilities for handling double-word AC refs.
** Note that an AC # of AC_17 is unsafe and always indicates a wrapped
** double-word of AC17 and AC0.
**
** NOTE: ac_dpget and ac_dget CANNOT be used in the same way as ac_get()
** (ie the value cannot be used in an assignment), because for the slow
** case there is no way to assemble an anonymous structure value.
**
** p.s. The reason for the stupid "value" of integer 0 is because some
** so-called C compilers botch conditional expressions that have
** type void. Better ones just optimize it away.
*/
#define ac_issafedouble(a) ((a)!=AC_17) /* TRUE unless last AC */
#define ac_dpget(dp,a) ( ac_issafedouble(a) \
? ((*(dp) = *ac_mapd(a)),0) \
: ((dp)->w[0] = ac_get(AC_17), (dp)->w[1] = ac_get(AC_0), 0 ))
#define ac_dpset(dp,a) ( ac_issafedouble(a) \
? ((*ac_mapd(a) = *(dp)), 0) \
: (ac_set(AC_17, (dp)->w[0]), ac_set(AC_0, (dp)->w[1]), 0) )
#define ac_dget(a,d) (ac_issafedouble(a) \
? (((d) = *ac_mapd(a)),0) \
: ((d).w[0] = ac_get(AC_17), (d).w[1] = ac_get(AC_0), 0 ))
#define ac_dset(a,d) (ac_issafedouble(a) \
? ((*ac_mapd(a) = (d)), 0) \
: (ac_set(AC_17, (d).w[0]), ac_set(AC_0, (d).w[1]), 0) )
/* Memory definitions */
/* Get virtual addressing and virtual memory definitions */
#include "kn10pag.h" /* Include pager definitions */
/* Well, they used to take up a few pages here... */
/* Program Counter (PC) macros
**
** All references to and manipulations of PC should use a PC_ macro.
** This permits relatively straightforward experimentation with
** different PC implementations.
*/
/* Likewise, the type used to hold a PC may be different from that
** for a virtual address, although for the time being they are still
** the same.
** NOTE: Later when questing for speed, attention needs to be given to the
** cases of mr_bkpt and klh10.c's setting of pcva_t variables.
**
** NOTE also: possibility of a vm_PCfetch() macro to fetch c(PC)
** specially (knows PC is local, no vaddr_t conversion, etc).
*/
typedef vaddr_t pcva_t; /* Type of PC virt addr */
typedef int pcinc_t; /* Type of all instruction routines */
# define PCINC_0 0 /* Instr jumped */
# define PCINC_1 1 /* Instr normal */
# define PCINC_2 2 /* Instr skipped */
/* Macros to obtain a PC attribute.
*/
#define PC_VADDR cpu.mr_PC /* Get PC as a vaddr_t */
#define PC_30 va_30(cpu.mr_PC) /* Full 30-bit PC value */
#define PC_SECT va_sect(cpu.mr_PC) /* PC section # (right-justified) */
#define PC_SECTF va_sectf(cpu.mr_PC) /* PC section as a field value */
#define PC_INSECT va_insect(cpu.mr_PC) /* PC in-section part */
#define PC_ISEXT PC_SECTF /* TRUE if PC in NZ section */
#define PC_PAGE va_xapage(cpu.mr_PC) /* Full XA page # of PC */
#define PC_PAGOFF va_pagoff(cpu.mr_PC)
#define PC_AC va_ac(cpu.mr_PC)
#if KLH10_EXTADR
# define PC_ISACREF ((cpu.mr_PC & (VAF_SBAD|VAF_NNOTA))==0)
#else
# define PC_ISACREF ((cpu.mr_PC & VAF_NNOTA)==0)
#endif
/* Macros to set or change the PC.
** It would be possible to optimize the SETs if all PC refs
** (vm_fetch in particular) always knew it was local-format.
*/
#define PC_ADD(n) va_ladd(cpu.mr_PC,n) /* Add n to PC (always local) */
#define PC_SET30(a) va_lmake30(cpu.mr_PC,a) /* Set PC from int w/o JPC */
#define PC_SET(va) va_lmake30(cpu.mr_PC,va_30(va)) /* " from vaddr_t */
#if KLH10_JPC /* Take a jump. Special so can set JPC if desired */
# define PC_JUMP(e) (cpu.mr_jpc = cpu.mr_PC, PC_SET(e))
#else
# define PC_JUMP(e) PC_SET(e)
#endif
/* Special macro to increment PC based on instruction execution.
** This must NOT be replaced by an expression such as
** (PC = (PC+(x)) & H10MASK)
** because C can't guarantee whether PC or (x) is evaluated first!
*/
#if KLH10_EXTADR
# define PC_ADDXCT(x) { register pcinc_t i__ = (x); if (i__) PC_ADD(i__); }
#else
# define PC_ADDXCT(x) (cpu.mr_PC += (x)) /* For now; fix up later? */
#endif
/* Macros for putting PC into a word.
*/
#define PC_TOWORD(w) LRHSET(w, PC_SECT, PC_INSECT) /* Put PC in wd */
#define PC_XWDPC1(w,l) LRHSET(w,l,(cpu.mr_PC+1)&H10MASK) /* <l>,,<PC+1> */
#define PC_1TOWORD(w) PC_XWDPC1(w, PC_SECT) /* <sect>,,<PC+1> */
#define PC_F1WORD(w) PC_XWDPC1(w, cpu.mr_pcflags) /* <flags>,,<PC+1> */
/* Macro to put "PC-word" in word: PC+1 plus flags if sect 0
*/
#if KLH10_EXTADR
# define PC_1WORD(w) (PC_ISEXT ? PC_1TOWORD(w) : PC_F1WORD(w))
#else
# define PC_1WORD(w) PC_F1WORD(w)
#endif
/* Processor Map change macros
** This macro should be invoked whenever something happens to
** change the address space mapping, either the page map or
** AC block selection.
*/
#if KLH10_PCCACHE
# define PCCACHE_RESET() (cpu.mr_cachevp = NULL)
#else
# define PCCACHE_RESET()
#endif
/* Processor PC Flag (PCF) macros */
#define PCFSET(f) (cpu.mr_pcflags |= (f))
#define PCFTRAPSET(f) (cpu.mr_pcflags |= (f), INSBRKSET())
#define PCFCLEAR(f) (cpu.mr_pcflags &= ~(f))
#define PCFTEST(f) (cpu.mr_pcflags & (f))
/* Macro for OP10 facilities (from kn10ops) to use for flag setting */
#define OP10_PCFSET(f) (cpu.mr_pcflags |= (f), \
(((f)&(PCF_TR1|PCF_TR2)) ? INSBRKSET() : 0))
/* PDP-10 processor flags
** These defs are the left half bit values of PDP-10 PC flags.
** Unless otherwise specified, all exist on all models.
*/
#define PCF_ARO 0400000 /* Arithmetic Overflow (or Prev Ctxt Public) */
#define PCF_CR0 0200000 /* Carry 0 - Carry out of bit 0 */
#define PCF_CR1 0100000 /* Carry 1 - Carry out of bit 1 */
#define PCF_FOV 040000 /* Floating Overflow */
#define PCF_FPD 020000 /* First Part Done */
#define PCF_USR 010000 /* User Mode */
#define PCF_UIO 04000 /* User In-Out (or Prev Ctxt User) */
#define PCF_PUB 02000 /* [KL/KI] Public Mode */
#define PCF_AFI 01000 /* [KL/KI] Addr Failure Inhibit */
#define PCF_TR2 0400 /* [KL/KI/KS] Trap 2 (PDL overflow) */
#define PCF_TR1 0200 /* [KL/KI/KS] Trap 1 (Arith overflow) */
#define PCF_FXU 0100 /* Floating Exponent Underflow */
#define PCF_DIV 040 /* No Divide */
#define PCF_MASK (H10MASK&~037) /* Can't mung low 5 bits, save for I(X) */
/* Duplicate flag meanings in exec mode */
#define PCF_PCP PCF_ARO /* [KL/KI] Previous Context Public */
#define PCF_PCU PCF_UIO /* [KL/KI/KS] Previous Context User */
#if KLH10_ITS_1PROC
# define PCF_1PR PCF_AFI /* KS10 One-proceed flag - re-use AFI */
#else
# define PCF_1PR 0
#endif
/* Instruction opcode macros and defs */
/* These cannot come earlier because they depend on some typedefs such
** as vaddr_t and pcinc_t.
*/
#include "opdefs.h" /* PDP-10 instruction opcodes and declarations */
/* Includes IW_ facilities */
/* Processor/microcode configuration */
/* APRID bit definitions.
** It appears that some monitors actually pay attention to these bits.
** While the KS and KL have superficially similar APRID fields, the
** meanings of the bits are completely different, so each needs its
** own specific definitions.
*/
/* KS notes:
** The PRM originally had no option bits defined; all of the options
** defined below were later additions.
*/
#if KLH10_CPU_KS
# define AIF_UCOPT 0777000 /* LH: Microcode options field */
# if KLH10_SYS_ITS
# define AIF_ITS 020000 /* ITS ucode [ITS KS10 only!] */
# else
# define AIF_INHCST 0400000 /* "Inhibit CST update" supported */
# define AIF_NOCST 0200000 /* No CST */
# define AIF_SEX 0100000 /* "Exotic uCode" (ie non-standard) */
# define AIF_UBLT 040000 /* BLTUB, BLTBU supported */
# define AIF_KIPG 020000 /* KI paging (old T10) */
# define AIF_KLPG 010000 /* KL paging (T20) */
# endif
# define AIF_UCVER 0777 /* LH: ucode version # field */
# define AIF_HWOPT 0700000 /* RH: Hardware options field */
# define AIF_SNO 077777 /* RH: Processor serial # (15 bits!) */
/* Default the ucode version and APR serial number */
# ifndef KLH10_APRID_UCVER
# if KLH10_SYS_ITS
# define KLH10_APRID_UCVER 0262 /* Last ITS KS ucode version */
# else
# define KLH10_APRID_UCVER 0130 /* Last DEC KS ucode version? */
# endif
# endif
# ifndef KLH10_APRID_SERIALNO
# define KLH10_APRID_SERIALNO 4097 /* This is popular for some reason */
# endif /* (maybe cuz an impossible SN for a KL) */
#endif /* KS */
/* KL notes:
** Most of the KL bits are documented in the PRM, but
** AIF_KLB, AIF_PMV, and AIF_MCA were later additions.
** When ITS ran on a KL10A, it used the same bit as the KS10 (AIF_ITS)
** to indicate it was non-standard ucode. But there's no need to
** resurrect MC, so don't worry about it.
*/
#if KLH10_CPU_KL
# define AIF_UCOPT 0777000 /* LH: Microcode options field */
# define AIF_T20 0400000 /* 0 UCode supports T20 paging */
# define AIF_EXA 0200000 /* 1 uCode supports Extended Addressing */
# define AIF_SEX 0100000 /* 2 "Exotic uCode" (ie non-standard) */
# define AIF_KLB 040000 /* 3 KL10B CPU (?) */
# define AIF_PMV 020000 /* 4 PMOVE/PMOVEM */
# define AIF_VER 0777 /* LH: ucode version # field */
# define AIF_HWOPT 0770000 /* RH: Hardware options field */
# define AIF_50H 0400000 /* 18 50Hz power */
# define AIF_CCA 0200000 /* 19 Cache */
# define AIF_CHN 0100000 /* 20 "Channel" - has RH20s? */
# define AIF_KLX 040000 /* 21 Extended KL10, else Single-section KL */
# define AIF_OSC 020000 /* 22 "Master Oscillator" (golly) */
# define AIF_MCA 010000 /* 23 MCA25 Keep Bit (per MCA25 doc p.A-10) */
# define AIF_SNO 07777 /* RH: Hardware Serial Number (only 12 bits) */
/* Default the ucode version and APR serial number */
# ifndef KLH10_APRID_UCVER
# if KLH10_SYS_ITS
# define KLH10_APRID_UCVER 02-- /* Last ITS KL ucode version? */
# else
# define KLH10_APRID_UCVER 0442 /* Last DEC KL ucode version? */
# endif
# endif
# ifndef KLH10_APRID_SERIALNO
# define KLH10_APRID_SERIALNO 759 /* Well, what else to use? */
# endif
#endif /* KL */
/* APR "device" definitions
*/
struct aprregs {
int aprf_set; /* APR flag settings & chan # */
int aprf_ena; /* APR flags enabled for interrupt */
int aprf_lev; /* APR level bit to interrupt on */
};
/* APR device flags. Note these all fit within 16 bits on the KS.
** The KL is a bit messier but can still be managed.
*/
#if KLH10_CPU_KL
# define APRW_IORST 0200000 /* 19 W: Clear all external I/O devices */
# define APRR_SWPBSY 0200000 /* 19 R: Sweep busy */
#endif
#define APRW_ENA 0100000 /* 20 Enable ints on selected flags */
#define APRW_DIS 040000 /* 21 Disable ints on selected flags */
#define APRW_CLR 020000 /* 22 Clear flags */
#define APRW_SET 010000 /* 23 Set flags */
#define APRF_MASK 07760 /* Flag mask */
#if KLH10_CPU_KL
# define APRF_SBUS 04000 /* 24 S-Bus Error */
# define APRF_NXM 02000 /* 25 No Memory (locks ERA) */
# define APRF_IOPF 01000 /* 26 IO Page Failure */
# define APRF_MBPAR 0400 /* 27 MB Parity (locks ERA) */
# define APRF_CDPAR 0200 /* 28 Cache Dir Parity */
# define APRF_ADPAR 0100 /* 29 Address Parity (locks ERA) */
# define APRF_PWR 040 /* 30 Nuclear Parity (ok, Power Failure) */
# define APRF_SWPDON 020 /* 31 Sweep Done */
#elif KLH10_CPU_KS
# define APRF_24 04000 /* 24 Unused? */
# define APRF_INT80 02000 /* 25 Interrupt 8080 FE when set */
# define APRF_PWR 01000 /* 26 Power failure */
# define APRF_NXM 0400 /* 27 Non-ex memory */
# define APRF_BMD 0200 /* 28 Bad Memory data */
# define APRF_ECC 0100 /* 29 Corrected memory data */
# define APRF_TIM 040 /* 30 Timer Interval done */
# define APRF_FEINT 020 /* 31 Interrupt from 8080 FE */
#endif
#define APRR_INTREQ 010 /* Something's requesting an int */
#define APRF_CHN 07 /* Mask for APR channel */
/* PI System definitions
**
** Terminology note: ITS still uses the word "channel" to mean the same thing
** as what DEC now calls "level".
*/
/* PI device flags, written by CONO PI, (KS: WRPI)
** Note all fit within 16 bits, except for high-order KL bits that
** aren't really part of the PI system.
*/
#if KLH10_CPU_KL
# define PIF_WEPADR 0400000 /* Write Even Parity - Address */
# define PIF_WEPDAT 0200000 /* Write Even Parity - Data */
# define PIF_WEPDIR 0100000 /* Write Even Parity - Directory */
#endif
#define PIW_LDRQ 020000 /* Drop IRQs on selected levels */
#define PIW_CLR 010000 /* Clear PI system */
#define PIW_LIRQ 04000 /* Initiate interrupt on selected levels */
#define PIW_LON 02000 /* Turn on selected levels (enable) */
#define PIW_LOFF 01000 /* Turn off " " (disable) */
#define PIW_OFF 0400 /* Turn off PI system */
#define PIW_ON 0200 /* Turn on " " */
#define PILEVS 0177 /* Mask for all PI level select bits */
#define PILEV1 0100 /* Bits used to select particular PI levels */
#define PILEV2 040
#define PILEV3 020
#define PILEV4 010
#define PILEV5 04
#define PILEV6 02
#define PILEV7 01
/* Flags read by CONI PI, (KS: RDPI)
** LH 0177 bits contain levels with program requests active (preq)
** RH 0177 bits contain levels turned on (enabled)
** RH 0177<<8 contain levels being held (PI In Progress)
*/
#define PIR_PIPSHIFT 8 /* Shift arg to find PIP bits in RH */
#define PIR_ON PIW_ON /* PI system on */
#if KLH10_CPU_KL
/* PI Function Word fields */
#define PIFN_ASP 0700000 /* LH: Address space to use for fns 4 & 5 */
#define PIFN_ASPEPT 0 /* Exec Process Table */
#define PIFN_ASPEVA 0100000 /* Exec virtual address */
#define PIFN_ASPPHY 0400000 /* Physical address */
#define PIFN_FN 070000 /* LH: Function code */
#define PIFN_F0 0 /* Internal device or zero word */
#define PIFN_FSTD 010000 /* Standard interrupt EPT+(40+2N) */
#define PIFN_FVEC 020000 /* Vector interrupt (dev/adr) */
#define PIFN_FINC 030000 /* Increment */
#define PIFN_FEXA 040000 /* DTE20 Examine */
#define PIFN_FDEP 050000 /* DTE20 Deposit */
#define PIFN_FBYT 060000 /* DTE20 Byte Transfer */
#define PIFN_FAOS 070000 /* IPA20-L (NIA20, CI) inc & return val */
#define PIFN_Q 04000 /* LH: Q bit */
#define PIFN_DEV 03600 /* LH: Physical Device # */
#define PIFN_LHADR 037 /* LH: High 5 bits of address */
/* RH: Low 18 bits of address */
#endif /* KL */
struct piregs {
int pisys_on; /* PIR_ON bit set if PI system on, else 0 */
int pilev_on; /* Levels active (enabled) - can take ints */
int pilev_pip; /* Levels holding ints (PI in Progress) */
int pilev_preq; /* Levels to initiate prog reqs on */
/* (these take effect even if pilev_on is off!) */
int pilev_dreq; /* Device PI requests outstanding */
int pilev_aprreq; /* "Devices" in APR */
#if KLH10_CPU_KL
int pilev_timreq; /* Interval timer PI request */
int pilev_rhreq; /* RH20 device requests */
int pilev_dtereq; /* DTE20 device requests */
int pilev_diareq; /* DIA20 device requests */
#elif KLH10_CPU_KS
int pilev_ub1req; /* Devices on UBA #1 */
int pilev_ub3req; /* Devices on UBA #3 */
#endif
};
/* Defined & initialized in kn10cpu.c PI code; later make EXTDEFs */
extern int pilev_bits[]; /* Bit masks indexed by PI level number */
extern unsigned char pilev_nums[]; /* PI level nums indexed by PI bit mask */
/* Timing system definitions */
#if KLH10_CPU_KL
/* Bits for CONO MTR, (those marked [I] are also read on CONI)
*/
# define MTR_SUA 0400000 /* Set Up Accounts */
# define MTR_AEPI 040000 /* [I] Acct: Executive PI Account */
# define MTR_AENPI 020000 /* [I] Acct: Executive Non-PI Account */
# define MTR_AON 010000 /* [I] Acct: Turn on */
# define MTR_TBON 04000 /* [I] Time Base: turn on */
# define MTR_TBOFF 02000 /* Time Base: turn off */
# define MTR_TBCLR 01000 /* Time Base: clear */
# define MTR_ICPIA 07 /* [I] Interval Counter: PI Assignment */
/* Bits for CONO TIM,
*/
# define TIM_WCLR 0400000 /* Clear Interval Counter */
# define TIM_ON 040000 /* Turn on Interval Counter */
# define TIM_WFCLR 020000 /* Clear Interval Flags */
# define TIM_RDONE 020000 /* Interval Done */
# define TIM_ROVFL 010000 /* Interval Overflow */
# define TIM_PERIOD 07777 /* Interval Period */
/* Note: LH of CONI has current interval counter in its TIM_PERIOD field */
/* According to the PRM, all hardware counters are 16 bits except
** the interval counter (12 bits).
**
** All "doubleword" counts are 59-bit unsigned quantities with the
** hardware counter at the low end.
** The representation in a PDP-10 doubleword has the high 36 bits
** in the high-order word, and the low 23 in bits 1-23 of the low word,
** with bit 0 zero.
** The low 12 bits of the doubleword are reserved for
** extensibility to future faster machines (!).
*/
#endif /* KL */
struct timeregs {
#if KLH10_CPU_KS
w10_t tim_intreg; /* Interval Time reg set by WRINT */
uint32 tim_base[3]; /* 71-bit time base, native form */
dw10_t wrbase; /* Time Base of last WRTIM */
osrtm_t osbase; /* OS Time Base of last WRTIM */
#elif KLH10_CPU_KL
unsigned mtr_flgs; /* MTR condition flags */
int mtr_on; /* TRUE if accounting on */
int mtr_ifexe; /* TRUE to include exec non-PI */
int mtr_ifexepi; /* TRUE to include exec PI */
uint32 mtr_eact; /* Execution acct hardware cntr */
uint32 mtr_mact; /* Mem ref acct hardware cntr */
int tim_on; /* TRUE if interval counter on */
int tim_lev; /* PI level bit to interrupt on, if any */
unsigned int tim_flgs; /* TIM condition flags and PIA */
unsigned int tim_intper; /* Interval counter period */
unsigned int tim_intcnt; /* Interval countdown */
int tim_tbon; /* Time base on/off flag */
# if KLH10_RTIME_SYNCH
/* Time base - virt usec since last RDTIME */
uint32 tim_ibased; /* usec due to done interval interrupt */
uint32 tim_ibaser; /* usec due to rem ticks since last interval */
# elif KLH10_RTIME_OSGET
osrtm_t tim_osbase; /* OS Time Base of last WRTIME reset */
# endif
uint32 tim_perf; /* Performance analysis hardware cntr */
#endif
};
#define TIMEBASEFILE "APR.TIMEBASE" /* Change this name later */
/* Determine whether any clock countdown is needed at all */
#define IFCLOCKED (KLH10_RTIME_SYNCH || KLH10_ITIME_SYNCH || KLH10_QTIME_SYNCH)
#define IFPOLLED (!KLH10_CTYIO_INT || !KLH10_IMPIO_INT)
#include "kn10clk.h" /* New clock stuff */
/* Stuff needed for ITS pager quantum counter, used by both kn10cpu and kn10pag.
See time code comments in KN10CPU.
*/
#if KLH10_SYS_ITS
# if KLH10_QTIME_SYNCH
# define quant_unfreeze(q) ((q) + (CLK_USEC_UNTIL_ITICK()<<2))
# define quant_freeze(q) ((q) - (CLK_USEC_UNTIL_ITICK()<<2))
# elif KLH10_QTIME_OSREAL || KLH10_QTIME_OSVIRT
extern int32 quant_freeze(int32), quant_unfreeze(int32);
# endif
#endif
/* UPT/EPT definitions
*/
/* UPT Offsets
** ITS: In non-time sharing and at clock level, UPT=EPT.
*/
#if KLH10_PAG_KI
# define UPT_PMU 0 /* 000-377: T10 User page map table (pages 0-777) */
# define UPT_PME340 0400 /* 400-417: T10 Exec page map table (pages 340-377) */
#endif
#if KLH10_CPU_KI
# define UPT_PFT 0420 /* User page failure trap instr */
#elif KLH10_CPU_KLX
# define UPT_LUU 0420 /* 30-bit addr of LUUO dispatch block */
#endif
#define UPT_TR1 0421 /* User mode arith ovfl trap. */
#define UPT_TR2 0422 /* User mode pdl ov trap. */
#define UPT_TR3 0423 /* User mode trap 3 in non-one-proceed microcode. */
/* Although MUUO trapping is not logically related to paging,
** in practice the MUUO algorithm is a function of the pager being
** used, as well as the CPU, so the different versions here are
** selected likewise. These categories correspond to those in
** PRM 2-126 (fig 2.3)
*/
#if KLH10_CPU_KLX || (KLH10_CPU_KS && KLH10_PAG_KL) /* KLX or T20 KS */
# define UPT_UUO 0424 /* MUUO PC flags, opcode, A, and PCS stored here. */
# define UPT_UPC 0425 /* MUUO old PC */
# define UPT_UEA 0426 /* MUUO Effective Address */
# define UPT_UCX 0427 /* MUUO process context (from RDUBR) */
#elif KLH10_CPU_KL0 && KLH10_PAG_KL /* T20 KL0 */
# define UPT_UUO 0425 /* MUUO opcode, A, PC and Eff Addr */
# define UPT_UPC 0426 /* MUUO old PC and flags */
# define UPT_UCX 0427 /* MUUO process context (from RDUBR) */
#elif (KLH10_CPU_KL0 || KLH10_CPU_KS) && (KLH10_PAG_KI || KLH10_PAG_ITS)
# define UPT_UUO 0424 /* MUUO opcode, A, PC and Eff Addr */
# define UPT_UPC 0425 /* MUUO old PC and flags */
# define UPT_UCX 0426 /* MUUO process context (from RDUBR) */
#elif KLH10_CPU_KI
# define UPT_UUO 0424 /* MUUO opcode, A, PC and Eff Addr */
# define UPT_UPC 0425 /* MUUO old PC and flags */
#endif
#define UPT_UEN 0430 /* MUUO new PC - Exec mode, no trap */
#define UPT_UET 0431 /* MUUO new PC - Exec mode, trap instr */
#if KLH10_SYS_ITS && KLH10_CPU_KS
# define UPT_1PO 0432 /* One-proceed old PC stored here (if 1proc ucode) */
# define UPT_1PN 0433 /* One-proceed new PC obtained from here (if " ) */
#elif KLH10_CPU_KI || KLH10_CPU_KL
# define UPT_USN 0432 /* MUUO new PC - Supv mode, no trap */
# define UPT_UST 0433 /* MUUO new PC - Supv mode, trap instr */
#endif
#define UPT_UUN 0434 /* MUUO new PC - User mode, no trap */
#define UPT_UUT 0435 /* MUUO new PC - User mode, trap instr */
#if KLH10_CPU_KI || KLH10_CPU_KL
# define UPT_UPN 0436 /* MUUO new PC - Public mode, no trap */
# define UPT_UPT 0437 /* MUUO new PC - Public mode, trap instr */
#endif
#if KLH10_CPU_KS || KLH10_CPU_KL
# if KLH10_PAG_KI /* T10 paging */
# define UPT_PFW 0500 /* Page Fail Word */
# define UPT_PFO 0501 /* Page Fail Old PC+flags word */
# define UPT_PFN 0502 /* Page Fail New PC+flags word */
# elif KLH10_PAG_KL /* T20 paging */
# define UPT_SC0 0540 /* T20 User Section 0 pointer */
# if KLH10_CPU_KS || KLH10_CPU_KLX
# define UPT_PFW 0500 /* Page Fail Word */
# define UPT_PFF 0501 /* Page Fail Flags */
# define UPT_PFO 0502 /* Page Fail Old PC */
# define UPT_PFN 0503 /* Page Fail New PC */
# elif KLH10_CPU_KL0
# define UPT_PFW 0501 /* Page Fail Word */
# define UPT_PFO 0502 /* Page Fail Old PC+flags word */
# define UPT_PFN 0503 /* Page Fail New PC+flags word */
# endif
# endif
#endif /* KS+KL */
#if KLH10_CPU_KL
# define UPT_PXT 0504 /* User Process Execution Time (doubleword) */
# define UPT_MRC 0506 /* User Memory Reference Count (doubleword) */
#endif
/* EPT Locations */
#if KLH10_CPU_KL
# define EPT_CL0 0 /* Channel Logout Area 0 (of 8) (quadword) */
#endif
#if KLH10_CPU_KI
# define EPT_UUO 040 /* Exec LUUO stored here */
# define EPT_UUH 041 /* Exec LUUO handler instruction */
#endif
#define EPT_PI0 040 /* PI0LOC+2*PICHN = Addr of instr pair for PICHN. */
/* Note KL has a PI0! Otherwise, locs */
/* actually used are 42-57 inclusive. */
#if KLH10_CPU_KL
# define EPT_CB0 060 /* Channel Block Fill Word 0 (of 4) */
#endif
#if KLH10_CPU_KS
# define EPT_UIT 0100 /* EPT_UIT+N contains addr of the interrupt */
/* table for unibus adapter N. Only */
/* adapters 1 and 3 ever exist. */
#endif /* KS */
#if KLH10_CPU_KL
# define EPT_DT0 0140 /* DTE20 Control Block 0 (of 4) (8 wds each) */
#endif
#if KLH10_PAG_KI
# define EPT_PME400 0200 /* 200-377: T10 Exec page map table (pages 400-777) */
#endif
#if KLH10_CPU_KLX
# define EPT_LUU 0420 /* Exec mode 30-bit LUUO block location */
#elif KLH10_CPU_KI
# define EPT_PFT 0420 /* Exec page failure trap instr */
#endif
#define EPT_TR1 0421 /* Exec mode arith ovfl trap. */
#define EPT_TR2 0422 /* Exec mode pdl ov trap. */
#define EPT_TR3 0423 /* Exec mode trap 3 (1 proceed?). */
#if KLH10_SYS_ITS
/*
In the ITS microcode the three words used to deliver a page fail are
determined from the current interrupt level. At level I, the page fail
word is stored in EPTPFW+<3*I>, the old PC is stored in EPTPFO+<3*I>,
and the new PC is obtained from EPTPFN+<3*I>. If no interrupts are in
progress we just use EPTPFW, EPTPFO and EPTPFN.
*/
#define EPT_PFW 0440 /* Page fail word stored here. */
#define EPT_PFO 0441 /* Page fail old PC stored here. */
#define EPT_PFN 0442 /* Page fail new PC obtained from here. */
#endif /* ITS */
#if KLH10_CPU_KL
/* The PRM doesn't mention this, but it appears that TOPS-20 (at least) uses
** EPT locations 444-457 inclusive as a special communication area with
** the Master DTE. See dvdte.h for more details.
*/
#endif
#if KLH10_CPU_KL
# define EPT_TBS 0510 /* Time Base (doubleword) */
# define EPT_PRF 0512 /* Performance Analysis Counter (doubleword) */
# define EPT_ICI 0514 /* Interval Counter Interrupt Instruction */
#endif
#if KLH10_PAG_KL
# define EPT_SC0 0540 /* T20 Exec Section 0 pointer */
#endif
#if KLH10_PAG_KI
# define EPT_PME0 0600 /* 600-757: T10 Exec page map table (pages 0-337) */
/* (note pages 340-377 are in UPT!) */
#endif
/* FE (console) stuff needed for interaction */
/* Halt codes returned to FE when KLH10 CPU stops.
*/
enum haltcode { /* Must not be zero */
HALT_PROG=1, /* Program halt (JRST 4,) */
HALT_FECTY, /* FE Console interrupt */
HALT_FECMD, /* FE Console command ready to execute */
HALT_BKPT, /* Hit breakpoint */
HALT_STEP, /* Single-Stepping */
HALT_EXSAFE, /* Badness in exec mode */
HALT_PANIC /* Panic - internal error, bad state */
};
/* FE command mode */
enum femode { /* runnable running ctyon Description */
FEMODE_CMDCONF, /* 0 0 0 not inited, cmd i/o */
FEMODE_CMDHALT, /* 1 0 0 halted, cmd i/o */
FEMODE_CMDRUN, /* 1 1 0 running, cmd i/o */
FEMODE_CTYRUN /* 1 1 1 running, CTY I/O */
};
struct feregs {
enum femode fe_mode; /* FE input handling mode */
int fe_cmdready; /* TRUE if FE cmd input buff ready to exeute */
int fe_runenable; /* TRUE to run KN10 during cmd input */
int fe_intchr; /* If non-zero, FE interrupt/cmd escape char */
int fe_intcnt; /* # times intchr seen before handled */
int fe_ctyon; /* TRUE if passing input to PDP-10 CTY */
int fe_ctyinp; /* # chars CTY input waiting, if any */
int fe_debug; /* TRUE to print debug info */
int fe_ctydebug; /* TRUE to print CTY debugging info */
#if KLH10_CPU_KS
int fe_iowait; /* # usec clock ticks to delay I/O response */
# if KLH10_CTYIO_ADDINT
int cty_lastint; /* # 1ms ticks after last output to give int */
int cty_prevlastint; /* Previous value of above */
struct clkent *cty_lastclk; /* Clock timer for last-output int */
# endif
#endif /* KLH10_CPU_KS */
};
#if KLH10_CPU_KS
/* FE <-> KS10 Communications Area locations */
#define FECOM_SWIT0 030 /* Simulated switch 0. Set by 8080 SH cmd. */
#define FECOM_KALIV 031 /* Keep Alive & Status. */
#define FECOM_CTYIN 032 /* CTY input. */
#define FECOM_CTYOT 033 /* CTY output. */
#define FECOM_KLKIN 034 /* KLINIK user input word (from 8080). */
#define FECOM_KLKOT 035 /* KLINIK user output word (to 8080). */
#define FECOM_RHBAS 036 /* BOOT RH11 base address. */
#define FECOM_QNUM 037 /* BOOT Unit Number. */
#define FECOM_BOOTP 040 /* Magtape Boot Format and Slave Number. */
#endif /* KS */
#if KLH10_CPU_KL /* Low core locs checked by T20 scheduler */
# define FECOM_SWIT0 030 /* SHLTW - Halt request if NZ, see SCHED.MAC */
/* 020 */ /* SCTLW - Request word, various bits */
#endif
/* Global Machine state variables
** This is a structure so references to the contents can all be made
** as offsets from a base address (which may be in a register). On
** some architectures such as the SPARC this allows a 1-instruction
** reference as opposed to the usual 3-instruction sequence for a
** random global reference.
** On other architectures it doesn't matter but doesn't hurt either.
*/
struct machstate {
/* Current ACs; at start of struct to make indexing faster.
** This block is swapped with cpu.acblks[n]
** whenever the current AC block changes.
*/
acblk_t acs;
int mr_acbcur; /* AC block # of current acs above */
/* General internal machine registers */
h10_t mr_pcflags; /* Current PC flags */
pcva_t mr_PC; /* Current virtual PC */
#if KLH10_PCCACHE
vmptr_t mr_cachevp; /* Current cached PC map pointer */
#endif
#if KLH10_JPC
pcva_t mr_jpc; /* Virtual PC of last jump instruction */
pcva_t mr_ujpc; /* Last JPC when user mode left */
pcva_t mr_ejpc; /* Last JPC when exec mode left */
#endif
#if KLH10_CPU_KS
w10_t mr_hsb; /* Halt Status Block base address */
#elif KLH10_CPU_KI || KLH10_CPU_KL
w10_t mr_adrbrk; /* Address Break register */
#endif
w10_t mr_aprid; /* Processor ID */
w10_t mr_ebr; /* Executive Base Register */
w10_t mr_ubr; /* User Base Register */
paddr_t mr_ebraddr, mr_ubraddr; /* Word addresses for above */
int mr_paging; /* TRUE if paging & traps enabled */
int mr_usrmode; /* TRUE if in USER mode (else EXEC mode) */
int mr_inpxct; /* TRUE if executing PXCT operand */
#if KLH10_CPU_KLX
pcva_t mr_pxctpc; /* Saved PC if PXCT bit 12 set */
#endif
h10_t mr_intrap; /* NZ (Trap flags set) if XCTing trap instr */
#if KLH10_ITS_1PROC
int mr_in1proc; /* TRUE if executing one-proceed instr */
#elif KLH10_CPU_KI || KLH10_CPU_KL
int mr_inafi; /* TRUE if executing AFI instruction */
#endif
int mr_injrstf; /* TRUE if executing JRSTF/JEN */
int mr_inpi; /* TRUE if executing PI instruction */
osintf_t mr_insbreak; /* See INSBRKSET, INSBRKTEST */
osintf_t intf_fecty; /* For FE CTY interrupts */
#if KLH10_EVHS_INT
osintf_t intf_evsig; /* For event-reg signals */
#endif
osintf_t intf_ctyio; /* For CTY I/O */
osintf_t intf_clk; /* Clock interval interrupt */
vmptr_t physmem; /* Ptr to physical memory area */
struct acregs acblk; /* AC block mappings */
struct vmregs vmap; /* Pager context mappings */
struct pagregs pag; /* Paging registers */
struct aprregs aprf; /* APR device stuff */
struct piregs pi; /* PI system stuff */
struct timeregs tim; /* Timer and clock stuff */
struct clkregs clk; /* Internal Clock stuff */
w10_t mr_dsw; /* Console Data Switches */
/* Debugging stuff */
int mr_debug; /* TRUE to print general CPU debug info */
int mr_dotrace; /* TRUE if doing execution trace */
int mr_1step; /* TRUE to stop after next instr */
int mr_exsafe; /* NZ does exec-mode safety checks; 2 = halt */
pcva_t mr_bkpt; /* Non-zero to stop when mr_PC == mr_bkpt */
pcva_t mr_haltpc; /* PC of a halt instruction */
/* Miscellaneous cruft */
int mr_runnable; /* TRUE if CPU runnable (ie init complete) */
int mr_running; /* TRUE if CPU running (not halted) */
int mm_shared; /* TRUE if using shared phys memory */
int mm_locked; /* TRUE if want memory locked */
osmm_t mm_physegid; /* Phys memory shared segment ID (can be 0) */
struct feregs fe; /* FE stuff */
#if KLH10_CPU_KS
int io_ctydelay; /* Ugh. To emulate I/O device delays. */
#endif
/* Bulk storage, at end so it's less annoying when debugging. */
w10_t acblks[ACBLKS_N][16]; /* Actual AC blocks! 16 wds each */
opfp_t opdisp[I_N]; /* I_xxx Routine dispatch table */
pment_t pr_umap[PAG_MAXVIRTPGS]; /* Internal user mode map table */
pment_t pr_emap[PAG_MAXVIRTPGS]; /* " exec " " " */
};
EXTDEF struct machstate cpu;
/* Processor function declarations - from kn10cpu.c */
extern void apr_picheck(void); /* Check for pending PI */
extern void apr_pcfcheck(void); /* Check PC flags for side effects */
extern void apr_int(void); /* Invoke interrupt system */
extern void apr_halt(enum haltcode); /* Halt processor */
extern void pi_dismiss(void); /* Dismiss current interrupt */
#if KLH10_CPU_KL
extern void mtr_update(void); /* Update accounts */
#endif
/* Finally, declare panic routine to call when all else fails. */
extern void panic(char *, ...);
#endif /* ifndef KN10DEF_INCLUDED */

View File

@@ -1348,7 +1348,7 @@ dev_boot(FILE *of,
return FALSE;
if (op10m_camn(vm_pget(vp), w6hom)) {
if (of) fprintf(of, "Bad HOM check, val = %lo,,%lo\n",
1, (long)LHGET(w), (long)RHGET(w));
(long)LHGET(w), (long)RHGET(w));
return FALSE;
}
if (of) fprintf(of, "OK\nReading HOM sector 010 ...");
@@ -1357,7 +1357,7 @@ dev_boot(FILE *of,
return FALSE;
if (op10m_camn(vm_pget(vp), w6hom)) {
if (of) fprintf(of, "Bad HOM check, val = %lo,,%lo\n",
010, (long)LHGET(w), (long)RHGET(w));
(long)LHGET(w), (long)RHGET(w));
return FALSE;
}
w = vm_pget(vm_physmap(FE_BOOTLOC+0103)); /* Get ptrs pag addr */

View File

@@ -759,7 +759,7 @@ dw10_t op10ashc(register dw10_t d,
** must be done to the argument prior to the call!
*/
static dw10_t
x_ashc(register dw10_t d,
x_ashc(/*register*/ dw10_t d,
register int i)
{
#endif /* IFFLAGS */
@@ -3238,7 +3238,7 @@ static int qdivstep(qw10_t *aq,
register dw10_t d,
register int nmagbits)
{
register qw10_t qw;
/*register*/ qw10_t qw;
dw10_t quot;
register int qbit;

File diff suppressed because it is too large Load Diff

View File

@@ -1,973 +0,0 @@
/* KN10PAG.H - Pager state and register definitions
*/
/* $Id: kn10pag.h,v 2.3 2001/11/10 21:28:59 klh Exp $
*/
/* Copyright © 1992, 1993, 2001 Kenneth L. Harrenstien
** All Rights Reserved
**
** This file is part of the KLH10 Distribution. Use, modification, and
** re-distribution is permitted subject to the terms in the file
** named "LICENSE", which contains the full text of the legal notices
** and should always accompany this Distribution.
**
** This software is provided "AS IS" with NO WARRANTY OF ANY KIND.
**
** This notice (including the copyright and warranty disclaimer)
** must be included in all copies or derivations of this software.
*/
/*
* $Log: kn10pag.h,v $
* Revision 2.3 2001/11/10 21:28:59 klh
* Final 2.0 distribution checkin
*
*/
#ifndef KN10PAG_INCLUDED
#define KN10PAG_INCLUDED 1
#ifdef RCSID
RCSID(kn10pag_h,"$Id: kn10pag.h,v 2.3 2001/11/10 21:28:59 klh Exp $")
#endif
/* Address space definitions, in terms of bits */
/* Naming note:
** Use: For:
** PA Physical Address.
** NA "iN-section" or "Normal" 18-bit Address.
** XA full eXtended virt Address (30-bit).
** VA Virtual Address actually supported (18 or 23-bit).
**
** XS full eXtended Section # (12-bit)
** VS Virtual Section # actually supported (5-bit)
*/
#ifndef PAG_PABITS /* # bits of address physically available */
# if KLH10_CPU_KLX
# define PAG_PABITS 22 /* 22 MAX! Can set less for debugging */
# else
# define PAG_PABITS 19 /* True for KS10 anyway */
# endif
#endif
#define PAG_NABITS 18 /* Normal in-section virtual address bits */
#define PAG_XSBITS 12 /* # bits virtual section possible */
#define PAG_XABITS 30 /* # virtual bits possible in extended mode (18+12) */
#if KLH10_CPU_KLX
# define PAG_VSBITS 5 /* # bits virtual section actually supported */
# define PAG_MAXBITS PAG_XABITS /* Max address of any kind */
#else
# define PAG_VSBITS 0 /* # bits virtual section actually supported */
# define PAG_MAXBITS PAG_PABITS /* Max address of any kind */
#endif
/* # virtual address bits actually supported! (18 or 23) */
#define PAG_VABITS (PAG_VSBITS+PAG_NABITS)
#if KLH10_PAG_ITS
# define PAG_BITS 10 /* # bits of address encompassed by a page */
#else
# define PAG_BITS 9
#endif
#define PAG_VMFBITS 2 /* # of access bits needed in page table */
/* (See VMF_ flags) */
/* The remaining definitions are more or less all derived
** from the above parameters.
** Note some of the defs should be unsigned but aren't, as they are
** used in some #if tests and some preprocs don't like 1UL.
** Still guaranteed positive since long is >= 32 bits.
*/
/* Max # of pages the KLH10 emulates in physical memory.
*/
#ifndef PAG_MAXPHYSPGS
# define PAG_MAXPHYSPGS (1L<<(PAG_PABITS-PAG_BITS))
#endif
/* Max # of virtual pages this pager will support.
*/
#define PAG_MAXVIRTPGS (1L<<(PAG_VABITS-PAG_BITS))
/* # bits needed in a page table entry.
** Only have to support available phys mem.
*/
#define PAG_PMEBITS (PAG_VMFBITS+PAG_PABITS-PAG_BITS)
/* Now declare three types:
** paddr_t - fast type big enough to hold the biggest phys/virt address.
** pagno_t - fast type big enough to hold a physical page #.
** pment_t - compact type for holding a hardware page table entry.
**
** For explanation of the #if tests, see similar code in word10.h that
** defines WORD10_INT18.
*/
#ifndef INT_MAX
# include <limits.h>
#endif
/* paddr_t - Physical address (always integral type)
** This is a macro instead of the typedef it should be, because
** on some Nazi U-boxes it is cleverly typedefed in <sys/types.h>, and
** C has no way to undefine (or even test) for such things.
*/
#ifndef KLH10_PADDR_T /* Permit compile-time override */
# if (INT_MAX > (1L<<(PAG_MAXBITS-2)))
# define KLH10_PADDR_T int /* Assume int is fastest if it's big enough */
# else
# define KLH10_PADDR_T long
# endif
#endif
/* typedef unsigned KLH10_PADDR_T paddr_t; */
#define paddr_t unsigned KLH10_PADDR_T
#ifndef KLH10_PAGNO_T /* Permit compile-time override */
# if (INT_MAX > (PAG_MAXPHYSPGS>>2))
# define KLH10_PAGNO_T int
# else
# define KLH10_PAGNO_T long
# endif
#endif
typedef unsigned KLH10_PAGNO_T pagno_t;
#ifndef KLH10_PMENT_T /* Permit compile-time override */
# if (SHRT_MAX > (1L<<(PAG_PMEBITS-2)))
# define KLH10_PMENT_T short
# elif (INT_MAX > (1L<<(PAG_PMEBITS-2)))
# define KLH10_PMENT_T int
# else
# define KLH10_PMENT_T long
# endif
#endif
typedef unsigned KLH10_PMENT_T pment_t;
#define PAG_SIZE (1<<PAG_BITS) /* # words in a page */
#define PAG_MASK (PAG_SIZE-1) /* Mask for address bits within page */
/* Note: These masks are for right-justified page numbers! */
#define PAG_NAMSK ((1UL<<(PAG_NABITS-PAG_BITS))-1) /* Mask for # in-sect pgs */
#define PAG_PAMSK ((1UL<<(PAG_PABITS-PAG_BITS))-1) /* Mask for # phys pgs */
#define PAG_XAMSK ((1UL<<(PAG_XABITS-PAG_BITS))-1) /* for XA max # virt */
#define PAG_VAMSK ((1UL<<(PAG_VABITS-PAG_BITS))-1) /* for supported # virt */
#define PAG_NXSMSK (PAG_XAMSK & ~PAG_VAMSK) /* Non-ex sect bits in pg # */
/* Extract page # from, and turn page # into, a physical address. */
#define pag_patopg(a) ((pagno_t)((a)>>PAG_BITS)&PAG_PAMSK) /* Phy to page */
#define pag_pgtopa(p) (((paddr_t)(p)) << PAG_BITS) /* Page to phy */
/* To extract page # from given virtual address,
** see va_page(va) and va_xapage(va).
*/
/* Virtual Address Facilities (includes EA calculation)
**
** vaddr_t is the object type used to store a full PDP-10
** virtual address. This is NOT the same as a physical
** address and may not even be an integral type.
**
** Both extended and non-extended definitions are integrated here.
** There are complicated enough however that perhaps a separate file
** would be a good idea (vaddr.h?).
*/
typedef int32 vaddr_t; /* Later make unsigned */
typedef int32 vaint_t; /* For future code */
typedef uint32 vauint_t;
#if !KLH10_EXTADR
# define va_lh(va) ((va) >> H10BITS)
# define va_ac(va) ((va) & AC_MASK)
# define va_sect(va) (0)
# define va_sectf(va) (0)
# define va_insect(va) ((va) & H10MASK)
# define va_pagoff(va) ((va) & PAG_MASK) /* Get offset within page */
# define va_page(va) ((pagno_t)((va)>>PAG_BITS)&PAG_VAMSK) /* Get page # */
# define va_xapage(va) ((pagno_t)((va)>>PAG_BITS)&PAG_XAMSK) /* FULL page!! */
# define va_30(va) (va)
# define va_ladd(va,n) ((va) = ((va)+(n))&H10MASK)
# define va_linc(va) va_ladd(va,1) /* Local increment by 1 */
# define va_add(va,n) va_ladd(va,n) /* General same as local */
# define va_inc(va) va_linc(va) /* Ditto */
# define va_dec(va) va_ladd(va,-1)
# define va_lmake(va, s, n) ((va) = (n))
# define va_gmake(va, s, n) ((va) = (n))
# define va_lmake30(va, pa) ((va) = (pa))
# define va_hmake(va, lh, rh) ((va) = ((lh)<<H10BITS) | (rh))
# define va_setlocal(va) (0) /* No-op */
# define va_isodd(va) ((va) & 01) /* Address is odd (low bit set) */
# define va_isglobal(va) (0) /* Never true */
# define va_Vmake(f,s,n) (n)
# define va_lfrword(va, w) va_lmake(va, 0, RHGET(w))
# define va_gfrword(va, w) va_gmake(va, 0, RHGET(w))
#endif /* !KLH10_EXTADR */
#if 1 /* Always include, even if EXTADR. */
/* Effective Address calculation.
** The ea_calc() macro should be used everyplace an effective address
** must be computed from a word in the I(X)Y format.
** The one exception is byte pointers, which use ea_bpcalc() in order
** to use the correct context for the ac/mem mapping.
**
** WARNING: This macro is an exception to the general rule of returning
** correctly masked results. E will have garbage high bits for a (X)Y
** reference. The masking is currently left out to bum a little more speed.
**
** TEMPORARY WARNING: For XA the (X)Y stuff *must* be masked!
*/
#define ea_calc(i) ea_mxcalc(i, cpu.acblk.xea, cpu.vmap.xea) /* Normal E */
#define ea_bpcalc(i) ea_mxcalc(i, cpu.acblk.xbea, cpu.vmap.xbea) /* BytPtr E */
#if 0
# define ea_mxcalc(iw, acp, m) \
(op10m_tlnn(iw, IW_I|IW_X) \
? (op10m_tlnn(iw, IW_I) ? RHGET(ea_wcalc(iw,acp,m)) /* I set, use fn */\
: (RHGET(iw) + ac_xgetrh(LHGET(iw)&IW_X,acp))) /* X only, add in */\
: RHGET(iw)) /* Simple case, no I or X */
#else
# define ea_mxcalc(iw, acp, m) \
(op10m_tlnn(iw, IW_I|IW_X) \
? (op10m_tlnn(iw, IW_I) ? ea_fncalc(iw,acp,m) /* I set, use fn */\
: va_Vmake(VAF_LOCAL, 0, \
(RHGET(iw) + ac_xgetrh(LHGET(iw)&IW_X,acp)) & H10MASK)) \
: va_Vmake(VAF_LOCAL, 0, RHGET(iw))) /* Simple case, no I or X */
extern vaddr_t ea_fncalc(w10_t, acptr_t, pment_t *);
#endif
/* Do full EA calc, returning last word */
extern w10_t ea_wcalc(w10_t, acptr_t, pment_t *);
#endif /* Was !KLH10_EXTADR, now 1 */
#if !KLH10_EXTADR
/* Provide for code compatibility when not using extended
** addressing. Later invent some generic name for these
** either-config facilities.
*/
# define xea_calc(iw,s) ea_calc(iw)
# define va_xeacalc(va,iw,s) ((va) = ea_calc(iw))
#endif
#if KLH10_EXTADR
#define VAF_LGFLAG (~((~(vauint_t)0)>>1))
#define VAF_GLOBAL VAF_LGFLAG
#define VAF_LOCAL 0
#define VAF_NBITS PAG_NABITS /* 18 bits in-section */
#define VAF_SBITS PAG_XSBITS /* 12 bits section # */
/* (Even though pager may only support 5) */
#define VAF_VSBITS PAG_VSBITS /* # bits virtual section possible */
#define VAF_SPOS VAF_NBITS
#define VAF_SMSK (((vauint_t)1<<VAF_SBITS)-1)
#define VAF_VSMSK (((vauint_t)1<<VAF_VSBITS)-1)
#define VAF_NMSK H10MASK
#define VAF_SFLD (VAF_SMSK<<VAF_SPOS)
#define VAF_VSFLD (VAF_VSMSK<<VAF_SPOS)
#define VAF_NFLD VAF_NMSK
#define VAF_AFLD 017
#define VAF_30MSK MASK30
#define VAF_S1 ((vauint_t)1<<VAF_SPOS) /* S Low bit in S field */
#define VAF_NNOTA (VAF_NFLD&~VAF_AFLD) /* Non-AC bits in N field */
#define VAF_SBAD (VAF_SFLD & ~VAF_VSFLD) /* Bad sect bits in S field */
/* Stuff with counterparts in !EXTADR */
# define va_lh(va) (((va) >> H10BITS)&H10MASK)
# define va_ac(va) ((va) & AC_MASK)
# define va_sect(va) (((va)>>VAF_SPOS)&VAF_SMSK)
# define va_sectf(va) ((va) & VAF_SFLD)
# define va_insect(va) ((va) & H10MASK)
# define va_pagoff(va) ((va) & PAG_MASK) /* Get offset within page */
# define va_page(va) ((pagno_t)((va)>>PAG_BITS)&PAG_VAMSK) /* Get page # */
# define va_xapage(va) ((pagno_t)((va)>>PAG_BITS)&PAG_XAMSK) /* FULL page!! */
# define va_30(va) ((va) & VAF_30MSK)
# define va_ladd(va,n) ((va) = (((va)&~VAF_NFLD)|(((va)+(n))&VAF_NFLD)))
# define va_linc(va) va_ladd(va,1) /* Local increment by 1 */
# define va_add(va,n) (va_islocal(va) ? va_ladd(va,n) : va_gadd(va,n))
# define va_inc(va) (va_islocal(va) ? va_linc(va) : va_ginc(va))
# define va_dec(va) (va_islocal(va) ? va_ladd(va,-1) : va_gadd(va,-1))
# define va_lmake(va, s, n) ((va) = ((s)<<VAF_SPOS) | (n))
# define va_gmake(va, s, n) ((va) = VAF_GLOBAL | ((s)<<VAF_SPOS) | (n))
# define va_lmake30(va, pa) ((va) = (pa))
# define va_hmake(va, lh, rh) ((va) = ((lh)<<H10BITS) | (rh))
# define va_setlocal(va) ((va) &= ~VAF_GLOBAL)
# define va_isodd(va) ((va) & 01) /* Address is odd (low bit set) */
# define va_isglobal(va) ((va) & VAF_GLOBAL)
/* New stuff with no counterpart in !EXTADR */
# define va_gadd(va,n) ((va) = ((va)+(n)) | VAF_GLOBAL)
# define va_ginc(va) va_gadd(va,1)
# define va_gdec(va) va_gadd(va,-1)
# define va_islocal(va) (!va_isglobal(va))
# define va_isext(va) ((va)&VAF_SFLD)
# define va_setinsect(va, h) ((va) = ((va)&~VAF_NFLD) | (h))
# define va_toword(va, w) LRHSET(w, va_sect(va), va_insect(va))
# define va_gmake30(va, pa) ((va) = VAF_GLOBAL | (pa))
# define va_Vmake(f,s,n) ((f)|((s)<<VAF_SPOS)|(n))
# define va_30frword(w) ((((uint32)(LHGET(w)&MASK12))<<H10BITS) | RHGET(w))
#define va_lfrword(va, w) va_lmake(va, LHGET(w)&VAF_SMSK, RHGET(w))
#define va_gfrword(va, w) va_gmake(va, LHGET(w)&VAF_SMSK, RHGET(w))
/* True if in-section part is an AC # */
#define va_isacinsect(va) (((va)&VAF_NNOTA)==0) /* TRUE if N part is AC */
/* True if is an AC ref that must be converted to 1,,AC
** Note global ref of 0,,AC does refer to ACs, but is *NOT* converted
** to 1,,AC. See i_xmovei() for more comments.
*/
#define va_iscvtacref(va) (va_isacinsect(va) && va_islocal(va) && va_isext(va))
/* True if section # is 0 or 1 */
#define va_issect01(va) (((va)&(VAF_SFLD&~VAF_S1))==0)
/* True if is an AC ref */
#define va_isacref(va) (va_isacinsect(va) \
&& (va_islocal(va) || va_issect01(va)))
/* True if no unsupported section bits are set (high 7 of 12) */
#define va_isoksect(va) (((va) & (VAF_SFLD&~VAF_VSFLD))==0)
/* Store VA in word, canonicalizing AC ref to 1,,AC if necessary */
#define va_toword_acref(va, w) (va_iscvtacref(va) \
? (LRHSET(w, 1, va_insect(va)), 0) \
: (LRHSET(w, va_sect(va), va_insect(va)), 0) )
#endif /* KLH10_EXTADR */
#if KLH10_EXTADR
#define xea_calc(iw,s) xea_mxcalc(iw,s,cpu.acblk.xea, cpu.vmap.xea)
#define va_xeacalc(va,iw,s) \
((va) = xea_mxcalc(iw, s, cpu.acblk.xea, cpu.vmap.xea))
#define va_xeabpcalc(va,iw,s) \
((va) = xea_mxcalc(iw, s, cpu.acblk.xbea, cpu.vmap.xbea))
#define xea_mxcalc(iw, s, acp, m) \
(op10m_tlnn(iw, IW_I|IW_X) \
? ((op10m_tlnn(iw,IW_I) || (s)) \
? xea_xcalc(iw, (unsigned)s, acp, m) /* I, or X in NZ S, use fn */\
: va_Vmake(VAF_LOCAL, s, H10MASK & /* Has X only, add in */\
(RHGET(iw) + ac_xgetrh(iw_x(iw),acp)))) \
: va_Vmake(VAF_LOCAL, s, RHGET(iw))) /* Simple case, no I or X */
/* Extended EA calc if starting with EFIW */
#define va_xeaefcalc(va, iw, acp, m) \
(op10m_tlnn(iw, IW_EI) /* See if Indirect bit set */\
? ((va) = xea_fnefcalc(iw,acp,m)) /* Ugh, use function to handle @ */\
: (op10m_tlnn(iw, IW_EX) /* Do simple X inline */\
? va_gmake30(va, (va_30frword(iw) \
+ va_30frword(ac_xget(iw_ex(iw),acp))) & VAF_30MSK) \
: va_gmake30(va, va_30frword(iw)) /* Simple Y is all */\
))
/* Normal full EA calculation, extended */
extern vaddr_t xea_xcalc(w10_t, unsigned, acptr_t, pment_t *);
/* Special EA calc for PXCT */
extern vaddr_t xea_pxctcalc(w10_t, unsigned, acptr_t, pment_t *, int, int);
/* Special for byte ptr EFIWS */
extern vaddr_t xea_fnefcalc(w10_t, acptr_t, pment_t *);
#endif /* KLH10_EXTADR */
/* Virtual Memory Mapping definitions
**
** In theory, the format used to store PDP-10
** word data in the "physical memory" area doesn't necessarily have to
** be equivalent to the w10_t data type. Two distinct sets of macros
** are provided to manipulate register-words and phys-memory-words for
** this reason: ac_xxx() and vm_xxx().
** However, making them equivalent simplifies the job of vm_xmap(),
** which is responsible for taking a vaddr_t virtual address and returning a
** vmptr_t that can be used to manipulate a physical memory word, because
** it can then return the same kind of pointer if the reference is actually to
** a fast-memory AC rather than to physical memory.
** If they were different data types then either vmptr_t would
** have to somehow distinguish between pointing to an AC and pointing
** to a memory word, or pointers would have to be avoided in favor
** of word fetch/store macros. Ugh.
*/
/* Note that the following definitions are parallel to those for the ACs. */
typedef w10_t *vmptr_t; /* Set type of data in phys mem */
struct vmregs {
pment_t *cur, /* Current context page map */
*prev, /* Previous context map */
/* Following maps always set to one of above two (current or prev) */
*xea, /* PXCT bit 9 - Eff Addr calc */
*xrw, /* PXCT bit 10 - c(E) read/write */
*xbea, /* PXCT bit 11 - Byte Ptr EA calc, others */
*xbrw, /* PXCT bit 12 - Byte data, others */
/* Following maps are for picking appropriate mode map without
** having to test whether paging is on or off.
*/
*user, /* cpu.pr_umap if paging, else pr_pmap */
*exec; /* cpu.pr_emap if paging, else pr_pmap */
};
/* Macro to simplify changing of map pointers */
#define vmap_set(new, old) \
((cpu.vmap.xea = cpu.vmap.xrw = \
cpu.vmap.xbea = cpu.vmap.xbrw = cpu.vmap.cur = (new)), \
(cpu.vmap.prev = (old)))
/* Access flags used in the vm_xmap() macro MUST be only ONE of VMF_READ
** or VMF_WRITE. Combining them doesn't work; VMF_WRITE implies
** both read and write.
** The hairy definitions are intended to result in the smallest possible
** bit usage for the "hardware" page table entries, both to save storage
** (cache) space and to permit immediate-mode operations for platforms
** that benefit from them (eg the SPARC has 13-bit immediate operands).
*/
#define VMF_READ ((pment_t)1<<(PAG_PMEBITS-1)) /* Read access ("Valid") */
#define VMF_WRITE ((pment_t)1<<(PAG_PMEBITS-2)) /* Write access */
#define VMF_ACC (VMF_READ|VMF_WRITE) /* Both, for masking */
#if 0 /* Cannot do this check at compile time due to typedefs in exprs */
# if (VMF_ACC & PAG_PAMSK)
/*#*/error "Pager access bits overlap phys page number!!"
# endif
#endif
#define VMF_NOTRAP ((pment_t)1<<(PAG_PMEBITS-3)) /* Flag for pag_refill() */
/* NOT used in map entry! */
/* Synonym for VMF_READ to distinguish instruction fetch references in case
** that ever becomes important. For example, it might provide a way
** of indicating that the address (ie PC) is forcibly interpreted as
** local.
*/
#define VMF_FETCH (VMF_READ)
/* VM_XMAP - Map virtual address in given context to physical address.
** Page faults if requested access cannot be granted, unless
** the VMF_NOTRAP flag is supplied.
** Returns a vmptr_t pointer to physical memory containing word value.
** This may be a "fast memory AC".
** vm_xtrymap - similar but never invokes the page refill routine; it
** only checks out the "hardware" map. This is useful for examining
** things from the console without altering anything.
*/
#if !KLH10_EXTADR
#define vm_xmap(v,f,a,m) /* Vaddr, AccessFlags, ACblock, MapPointer */\
(((v) & (H10MASK&(~AC_MASK)))==0 \
? ac_xmap((v)&AC_MASK, (a)) /* AC ref, use AC block */\
: ( ((m)[va_page(v)] & ((f)&VMF_ACC)) /* Mem ref, check map */\
? vm_physmap(pag_pgtopa((m)[va_page(v)]&PAG_PAMSK) \
| ((v) & PAG_MASK)) \
: pag_refill((pment_t *)(m),(vaddr_t)(v),(pment_t)(f)) \
))
#define vm_xtrymap(v,f,a,m) /* Vaddr, AccessFlags, ACblock, MapPointer */\
(((v) & (H10MASK&(~AC_MASK)))==0 \
? ac_xmap((v)&AC_MASK, (a)) /* AC ref, use AC block */\
: ( ((m)[va_page(v)] & ((f)&VMF_ACC)) /* Mem ref, check map */\
? vm_physmap(pag_pgtopa((m)[va_page(v)]&PAG_PAMSK) \
| ((v) & PAG_MASK)) \
: (vmptr_t)0 \
))
#endif /* !KLH10_EXTADR */
#if KLH10_EXTADR /* Hairy extended-addressing mapping! */
#define vm_xmap(v,f,a,m) /* Vaddr, AccessFlags, ACblock, MapPointer */\
(va_isacref(v) \
? ac_xmap(va_ac(v), (a)) /* AC ref, use AC block */\
: ((va_isoksect(v) /* Verify section OK */\
&& ((m)[va_page(v)] & ((f)&VMF_ACC))) /* Mem ref, check map */\
? vm_physmap(pag_pgtopa((m)[va_page(v)]&PAG_PAMSK) \
| va_pagoff(v)) \
: pag_refill((pment_t *)(m),(vaddr_t)(v),(pment_t)(f)) \
))
#define vm_xtrymap(v,f,a,m) /* Vaddr, AccessFlags, ACblock, MapPointer */\
(va_isacref(v) \
? ac_xmap(va_ac(v), (a)) /* AC ref, use AC block */\
: ((va_isoksect(v) /* Verify section OK */\
&& ((m)[va_page(v)] & ((f)&VMF_ACC))) /* Mem ref, check map */\
? vm_physmap(pag_pgtopa((m)[va_page(v)]&PAG_PAMSK) \
| va_pagoff(v)) \
: (vmptr_t) 0 \
))
/* Special map for doing fetch of c(PC).
** Uses PC_ macros to obtain address parts, and knows that it is always
** local-format, which simplifies test for AC reference.
** However, AC-ref test must also test for valid section #.
** Note use of PC_VADDR; will need to encapsulate call to pag_refill
** if a non-vaddr format is used for PC.
*/
#define vm_PCmap(f, a, m) \
(PC_ISACREF \
? ac_xmap(PC_AC, (a)) /* AC ref, use AC block */\
: ( ((PC_PAGE & PAG_NXSMSK)==0 /* Verify section OK */\
&& ((m)[PC_PAGE] & ((f)&VMF_ACC))) /* Mem ref, check map */\
? vm_physmap(pag_pgtopa((m)[PC_PAGE]&PAG_PAMSK) | PC_PAGOFF) \
: pag_refill((pment_t *)(m),(vaddr_t)PC_VADDR,(pment_t)(f)) \
))
#define vm_PCfetch() \
vm_pget(vm_PCmap(VMF_FETCH,cpu.acblk.xea,cpu.vmap.xea))
#endif /* KLH10_EXTADR */
#define vm_xeamap(v,f) vm_xmap(v,f,cpu.acblk.xea,cpu.vmap.xea)
#define vm_xrwmap(v,f) vm_xmap(v,f,cpu.acblk.xrw,cpu.vmap.xrw)
#define vm_xbeamap(v,f) vm_xmap(v,f,cpu.acblk.xbea,cpu.vmap.xbea)
#define vm_xbrwmap(v,f) vm_xmap(v,f,cpu.acblk.xbrw,cpu.vmap.xbrw)
#define vm_execmap(v,f) vm_xmap(v,f,cpu.acs.ac,cpu.vmap.exec)
#define vm_usermap(v,f) vm_xmap(v,f,cpu.acs.ac,cpu.vmap.user)
#define vm_physmap(a) (&cpu.physmem[(a)]) /* Physical address mapping */
/* Given pointer to phys mem, convert to and from words and halfwords */
#define vm_pget(p) (*(p))
#define vm_pgetlh(p) LHPGET(p)
#define vm_pgetrh(p) RHPGET(p)
#define vm_pset(p,w) (*(p) = (w))
#define vm_psetlh(p,h) LHPSET(p,h)
#define vm_psetrh(p,h) RHPSET(p,h)
#define vm_psetxwd(p,l,r) XWDPSET(p,l,r)
#define vm_padd(p,i) ((p)+(i)) /* To formalize word offsets */
/* Define default memory read/write operations. Note that most of these
** use the XRW map context, not the "current" context, in case of PXCT.
*/
#define vm_fetch(a) vm_pget(vm_xeamap(a, VMF_FETCH))
#define vm_read(a) vm_pget(vm_xrwmap(a, VMF_READ))
#define vm_readlh(a) vm_pgetlh(vm_xrwmap(a, VMF_READ))
#define vm_readrh(a) vm_pgetrh(vm_xrwmap(a, VMF_READ))
#define vm_write(a, w) vm_pset(vm_xrwmap(a, VMF_WRITE), w)
#define vm_writelh(a,v) vm_psetlh(vm_xrwmap(a, VMF_WRITE), v)
#define vm_writerh(a,v) vm_psetrh(vm_xrwmap(a, VMF_WRITE), v)
#define vm_redmap(a) vm_xrwmap(a, VMF_READ)
#define vm_modmap(a) vm_xrwmap(a, VMF_WRITE)
#define vm_wrtmap(a) vm_xrwmap(a, VMF_WRITE)
/* Facilities for handling double-word refs.
** Do not use vm_dpread for reading directly into an AC pair because
** there may be a page fault on the second word. vm_issafedouble
** is TRUE if the reference crosses neither AC17/MEM20 or page boundaries.
** Note how the test checks to see if all word-offset addr bits are 1,
** i.e. if address points to last word in a page.
*/
#define vm_issafedouble(a) (((a)&H10MASK) != AC_17 && ((~(a))&PAG_MASK))
#define vm_pgetd(p) (*(dw10_t *)(p)) /* Use only if issafedouble */
#define vm_psetd(p,d) (*(dw10_t *)(p) = (d)) /* Use only if issafedouble */
/* NOTE: vm_dread is a special macro for reading a double-word, which
** CANNOT be used in the same way as vm_read() (ie its value cannot
** be used in an assignment), because for the slow case there is no
** way to assemble an anonymous structure value. (Yes, I know GNU C
** has extensions for this, but ANSI doesn't yet.)
** ALSO:
** The address must be an lvalue, and MAY BE CLOBBERED!!!
** A page fault can happen between the two word reads.
**
** p.s. The reason for the stupid "value" of integer 0 is because some
** so-called C compilers botch conditional expressions that have
** type void. Better ones just optimize it away.
*/
#define vm_dread(a,d) \
(vm_issafedouble(a) /* If safe double, */\
? ((d) = vm_pgetd(vm_xrwmap(a,VMF_READ)), 0) /* use fast way */\
: ((d).w[0] = vm_read(a), /* Ugh, slow way */\
va_inc(a), (d).w[1] = vm_read(a), 0))
/* vm_dwrite() - similar cautions to vm_dread().
** In this case, a statement is necessary in order to get some
** temporary pointer variables.
** This code makes sure that both words can be written into before
** writing anything. That way, if a page fault happens nothing
** has been changed yet.
**
** p.s. The reason for the silly if (1) is so a semicolon can follow
** the macro invocation without screwing up code that thinks it really
** is a void expression rather than a statement.
*/
#define vm_dwrite(a,d) \
if (vm_issafedouble(a)) { /* If safe double, */\
vm_psetd(vm_xrwmap(a,VMF_WRITE), (d)); /* use fast way */\
} else if (1) { \
register vmptr_t p0__, p1__; /* Ugh, slow way */\
p0__ = vm_xrwmap(a, VMF_WRITE); \
va_inc(a); \
p1__ = vm_xrwmap(a, VMF_WRITE); \
vm_pset(p0__, (d).w[0]); \
vm_pset(p1__, (d).w[1]); \
} else
/* Paging hardware definitions */
/* Executive Base Register */
#if KLH10_CPU_KL
# define EBR_CCALK 0400000 /* 18 Cache strategy - look */
# define EBR_CCALD 0200000 /* 19 Cache strategy - load */
#else
# define EBR_CCALK 0
# define EBR_CCALD 0
#endif
#define EBR_T20 040000 /* 21 "Tops-20 paging" - off for ITS */
#define EBR_ENABLE 020000 /* 22 Enable pager */
#if KLH10_CPU_KS
# define EBR_BASEPAG 03777 /* 25-35 Physical DEC page # of EPT */
#elif KLH10_CPU_KL
# define EBR_BASEPAG 017777 /* 23-35 Physical DEC page # of EPT */
#endif
/* User Base Register */
#define UBR_SETACB 0400000 /* 0 Set AC blocks to those selected */
#if KLH10_CPU_KL
# define UBR_SETPCS 0200000 /* 1 Set PCS (Prev Sect) to that given */
#endif
#define UBR_SET 0100000 /* 2 Set UBR page # to that given */
#if KLH10_MCA25
# define UBR_KEEP 040000 /* 3 Don't invalidate "Kept" pages */
#endif
#define UBR_ACBCUR 07000 /* Current AC block */
#define UBR_ACBPREV 0700 /* Previous Context AC block */
#if KLH10_CPU_KL
# define UBR_PCS 037 /* Previous Context Section */
#endif
#if KLH10_CPU_KS
# define UBR_BASEPAG 03777 /* (RH) Physical DEC page # of UPT */
#elif KLH10_CPU_KL
# define UBR_DNUA 0400000 /* (RH) Do Not Update Accounts */
# define UBR_BASEPAG 017777 /* (RH) Physical DEC page # of UPT */
#endif
#if KLH10_PAG_ITS /* ITS version of UBR uses full physical addr */
# define UBR_BASELH 03 /* (LH) High bits of UPT phys addr */
# define UBR_BASERH 0777777 /* (RH) Low bits of " " " */
# define UBR_RHMASK UBR_BASERH /* Bits to keep in UBR RH */
#else
# define UBR_RHMASK UBR_BASEPAG /* Bits to keep in UBR RH */
#endif /* !ITS */
/* Internal "hardware" page tables.
** The user and exec maps are now in the "cpu" struct for locality.
** The physical map is rarely used so is left here.
*/
#ifndef EXTDEF
# define EXTDEF extern /* Default is to declare (not define) vars */
#endif
#if 0
EXTDEF pment_t pr_umap[PAG_MAXVIRTPGS]; /* Internal user mode map table */
EXTDEF pment_t pr_emap[PAG_MAXVIRTPGS]; /* " exec " " " */
#endif
EXTDEF pment_t pr_pmap[PAG_MAXVIRTPGS]; /* " physical " " */
/* ITS Pager definitions */
#if KLH10_PAG_ITS
/*
On a DEC KS10 the page tables are either included in the UPT
and EPT (for TOPS-10) or pointed to by a complicated mechanism (for
TOPS-20). ITS however uses a different arrangement based on the
original MAC-10 pager built by Holloway for the KA-10.
There are 4 page map registers, called "Descriptor Base Registers". Each
points to a table of at most 64 words (128 halfwords), with one page
map entry per halfword.
DBR1 -> User low mem ( 0-377777)
DBR2 -> User high (400000-777777)
DBR3 -> EXEC high
DBR4 -> EXEC low (didn't exist on KA-10s)
*/
/* Page table entry format */
#define PM_29 0400000 /* Bit 2.9 of ITS map entry halfword */
#define PM_28 0200000 /* Bit 2.8 */
#define PM_ACC (PM_29|PM_28) /* Mask for ITS access bits: */
/* Note: h/w treats RWF the same as RO. */
#define PM_ACCNON ((h10_t)00<<16) /* 00 - invalid, inaccessible */
#define PM_ACCRO ((h10_t)01<<16) /* 01 - Read Only */
#define PM_ACCRWF ((h10_t)02<<16) /* 10 - Read/Write/First (== RO) */
#define PM_ACCRW ((h10_t)03<<16) /* 11 - Read/Write */
#define PM_AGE 020000 /* Age bit */
#define PM_CSH 010000 /* Cache enable bit */
#define PM_PAG PAG_PAMSK /* Physical ITS page number (max 1777?) */
#if (PM_PAG & PM_CSH)
* ERROR * "ITS page number field too large"
#endif
/* Format of ITS page fail word */
#define PF_USR 0400000 /* 4.9 Indicates user address space. */
#define PF_NXI 0200000 /* 4.8 Nonexistent IO register. */
#define PF_NXM 0100000 /* 4.7 Nonexistent memory. */
#define PF_PAR 0040000 /* 4.6 Uncorrectable memory error. */
/* (AC0 in block 7 has the word unless 4.7 is */
/* also set.) */
/* 4.5 unused */
#define PF_WRT 0010000 /* 4.4 Soft fault reference called for writing. */
#define PF_29 004000 /* 4.3 - 4.2 Access bits for referenced page in soft */
#define PF_28 002000 /* fault. (from 2.9 & 2.8 of page entry) */
#define PF_PHY 0001000 /* 4.1 Address given was physical. */
/* 3.9 unused */
#define PF_IO 0000200 /* 3.8 Indicates an IO operation. */
/* 3.7-3.6 unused */
#define PF_BYT 0000020 /* 3.5 Indicates a byte IO operation. */
/* 3.4 - 1.1 IO address */
/* or */
/* 3.1 - 1.1 Memory address */
#define PF_PNO 0776000 /* 2.9 - 2.2 Virtual page number */
/* Format of the area read and written by LPMR, SPM: */
#define LPMR_DBR1 0 /* User low DBR */
#define LPMR_DBR2 1 /* User high DBR */
#define LPMR_QUANT 2 /* Quantum timer */
#define LPMR_UJPC 3 /* User JPC (if supported) */
#define LPMR_EJPC 4 /* Exec JPC (if supported) */
/* The quantum timer appears to be incremented approximately every
** millisecond (2^12 the KS10 internal clock rate) whenever
** not holding an interrupt (ie no PI in progress).
*/
/* Paging register variables */
struct pagregs {
int32 pr_dbr1, pr_dbr2, pr_dbr3, pr_dbr4; /* DBR regs */
int32 pr_quant;
vaddr_t pr_ujpc, pr_ejpc;
/* Common to all systems */
h10_t pr_flh; /* Fail word LH bits */
paddr_t pr_fref; /* Failing virtual/physical address */
char *pr_fstr; /* Failure reason (for debugging) */
pment_t *pr_fmap; /* Failing map pointer */
h10_t pr_facf; /* Failing ref access bits */
};
#endif /* ITS */
/* T10 (KI) Pager definitions */
#if KLH10_PAG_KI
/* Page table entry format */
#define PM_ACC 0400000 /* B0 - Access allowed (R or RW) */
#define PM_PUB 0200000 /* B1 - Public (not used in KS10) */
#define PM_WRT 0100000 /* B2 - Writable */
#define PM_SFT 0040000 /* B3 - Software (not used by page refill) */
#define PM_CSH 0020000 /* B4 - Cacheable */
#define PM_PAG 0017777 /* Physical DEC page number - 13 bits */
#if (PM_PAG < PAG_PAMSK)
/*#*/ * ERROR * "T10 page number field too small"
#endif
/* Page fail bits as returned by MAP or page failure trap */
#define PF_USER ((h10_t)1<<17) /* B0 - User space reference (else exec) */
#define PF_HARD ((h10_t)1<<16) /* B1 - Hardware or IO failure (else soft) */
#define PF_ACC ((h10_t)1<<15) /* B2 - 'Access' bit from page map entry */
#define PF_WRT (1<<14) /* B3 - 'Writable' bit from page map entry */
#define PF_SFT (1<<13) /* B4 - 'Soft' bit from page map entry */
#define PF_WREF (1<<12) /* B5 - Reference was write */
#define PF_PUB (1<<11) /* B6 - 'Public' bit from refill eval */
#define PF_CSH (1<<10) /* B7 - 'Cacheable' bit from refill eval */
#define PF_VIRT (1<<9) /* B8 - Physical or Virtual reference */
/* (1<<8) */ /* B9 - */
#define PF_IOREF (1<<7) /* B10 - IO Bus reference */
/* (1<<6) (1<<5) */ /* B11,B12 - */
#define PF_IOBYTE (1<<4) /* B13 - Byte mode in failing IO ref */
#if KLH10_CPU_KL /* Sufficient for now, later merge */
# define PMF_IIERR ((h10_t)024<<12) /* Illegal Indirect (EFIW) */
# define PMF_NXMERR ((h10_t)036<<12) /* AR parity error (pretend NXM) */
#endif /* DFKDA diag expects this */
struct pagregs {
#if KLH10_CPU_KL
int pr_pcs; /* Previous Context Section */
paddr_t pr_pcsf; /* PCS, shifted into field position */
paddr_t pr_era; /* Error Address Register */
#endif /* KL */
paddr_t pr_physnxm; /* 1st physical NXM address */
/* Common to all systems */
h10_t pr_flh; /* Page fail code, or refill access bits */
paddr_t pr_fref; /* If phys failure, holds phys addr of ref */
char *pr_fstr; /* Failure string for debugging */
pment_t *pr_fmap; /* Failing hardware map pointer */
h10_t pr_facf; /* Failing ref access bits */
};
#endif /* KLH10_PAG_KI */
/* T20 (KL) Pager definitions */
#if KLH10_PAG_KL
/* Bits for page map entry LH as returned by MAP or page failure.
** Source for this is DEC PRM p.4-26 to p.4-28.
** Same bits for KL, PRM p.3-40.
*/
#define PF_USER ((h10_t)1<<17) /* B0 U - User space reference (else exec) */
#define PF_HARD ((h10_t)1<<16) /* B1 H - Hardware or IO failure (else soft) */
#define PF_ACC (1<<15) /* B2 A - Accessible, refill eval completed */
#define PF_MOD (1<<14) /* B3 M - 'Modified' bit from h/w page table */
#define PF_WRT (1<<13) /* B4 S - 'Writable' bit from refill eval */
#define PF_WREF (1<<12) /* B5 T - Reference was write */
#define PF_PUB (1<<11) /* B6 P - 'Public' bit from refill eval */
#define PF_CSH (1<<10) /* B7 C - 'Cacheable' bit from refill eval */
#define PF_VIRT (1<<9) /* B8 V - Physical or Virtual reference */
#if KLH10_MCA25
# define PF_KEEP (1<<9) /* B8 K - Keep page during WRUBR */
#endif
#if KLH10_CPU_KS
/* (1<<8) */
# define PF_IOREF (1<<7) /* B10 - IO Bus reference */
/* (1<<6) (1<<5) */
# define PF_IOBYTE (1<<4) /* B13 - Byte mode in failing IO ref */
#endif /* KS */
/* Special hardware failure codes in high 6 bits. */
#if KLH10_CPU_KS
# define PMF_PARERR ((h10_t)036<<12) /* Uncorrectable memory error */
# define PMF_NXMERR ((h10_t)037<<12) /* Nonexistent memory */
# define PMF_IOERR ((h10_t)020<<12) /* Nonexistent IO register */
#elif KLH10_CPU_KL
# define PMF_PUBERR ((h10_t)021<<12) /* Proprietary violation */
# define PMF_ADRERR ((h10_t)023<<12) /* Address break */
# define PMF_IIERR ((h10_t)024<<12) /* Illegal Indirect (EFIW) */
# define PMF_PGTERR ((h10_t)025<<12) /* Page table parity error */
# define PMF_ISCERR ((h10_t)027<<12) /* Illegal Address (sect > 037) */
# define PMF_NXMERR ((h10_t)036<<12) /* AR parity error (pretend NXM) */
# define PMF_ARXERR ((h10_t)037<<12) /* ARX parity error */
#endif
#define PMF_WRTERR ((h10_t)011<<12) /* Write violation (soft) */
#define PMF_OTHERR ((h10_t)000<<12) /* Random inaccessibility (soft) */
/* Section and Map pointer format */
#define PT_PACC (1<<14) /* B3 - 'P' bit, public */
#define PT_WACC (1<<13) /* B4 - 'W' bit, writeable */
#define PT_KEEP (1<<12) /* B5 - 'K' bit, Keep (KL MCA25) */
#define PT_CACHE (1<<11) /* B6 - 'C' bit, cacheable */
#define PT_TYPE ((h10_t)07<<15) /* High 3 bits are pointer type */
#define PTT_NOACC 0 /* Inaccessible pointer */
#define PTT_IMMED 1 /* Immediate pointer (see SPT fields) */
#define PTT_SHARED 2 /* Shared pointer */
/* RH: Index into SPT */
#define PTT_INDIRECT 3 /* Indirect pointer */
#define PT_IIDX 0777 /* LH: B9-17 Next index */
/* RH: Index into SPT (like shared) */
/* Format of SPT (Special Page Table) entries.
** The "Page Address" defined here is also used in
** immediate section/map pointers (type PTT_IMMED).
*/
#define SPT_MDM 077 /* LH: B12-17 Storage medium (0=mem) */
#define SPT_RSVD 0760000 /* RH: B18-22 Reserved */
#define SPT_PGN 0017777 /* RH: B23-35 Page Number */
/* Format of CST (Core Status Table) entry.
** There is one entry for every physical page on the machine.
*/
#define CST_AGE 0770000 /* LH: Page age - if zero, trap on ref. */
#define CST_HWBITS 017 /* RH: Hardware bits, s/w shouldn't hack */
#define CST_MBIT 01 /* RH: referenced page modified */
/* Paging registers
** Note that on the KL the "registers" are stored in AC block 6.
** Assumption is that this is NEVER the current ac block; known
** to be true for T20 monitor at least.
*/
struct pagregs {
#if KLH10_CPU_KS
paddr_t pr_spb; /* SPT Base address (not aligned, unknown size) */
paddr_t pr_csb; /* CST Base address (not aligned, # = phys pages) */
w10_t pr_cstm; /* CST Mask word */
w10_t pr_pur; /* CST Process Use Register */
# define PAG_PR_SPBPA cpu.pag.pr_spb
# define PAG_PR_CSBPA cpu.pag.pr_csb
# define PAG_PR_CSTMWD cpu.pag.pr_cstm
# define PAG_PR_PURWD cpu.pag.pr_pur
#elif KLH10_CPU_KL
# define PAG_PR_SPB (cpu.acblks[6][3])
# define PAG_PR_CSB (cpu.acblks[6][2])
# define PAG_PR_SPBPA (((paddr_t)LHGET(PAG_PR_SPB)<<18) \
| RHGET(PAG_PR_SPB))
# define PAG_PR_CSBPA (((paddr_t)LHGET(PAG_PR_CSB)<<18) \
| RHGET(PAG_PR_CSB))
# define PAG_PR_CSTMWD (cpu.acblks[6][0])
# define PAG_PR_PURWD (cpu.acblks[6][1])
int pr_pcs; /* Previous Context Section */
paddr_t pr_pcsf; /* PCS, shifted into field position */
paddr_t pr_era; /* Error Address Register */
#endif /* KL */
paddr_t pr_physnxm; /* 1st physical NXM address */
/* Common to all systems */
h10_t pr_flh; /* Page fail code, or refill access bits */
paddr_t pr_fref; /* If phys failure, holds phys addr of ref */
char *pr_fstr; /* Failure string for debugging */
pment_t *pr_fmap; /* Failing map pointer */
h10_t pr_facf; /* Failing ref access bits */
};
#endif /* KLH10_PAG_KL */
#if KLH10_CPU_KL
# define pag_pcsget() cpu.pag.pr_pcs
# define pag_pcsfget() cpu.pag.pr_pcsf
# define pag_pcsset(s) (cpu.pag.pr_pcsf = ((paddr_t)(s)<<18),\
cpu.pag.pr_pcs = (s))
#endif
/* Pager function declarations - exported from kn10pag.c */
extern void pag_init(void); /* Initialize pager stuff */
/* Called if vm_xmap mapping macros fail. Refill, trap if page-fail */
extern vmptr_t pag_refill(pment_t *, vaddr_t, pment_t);
extern void pag_fail(void); /* Effect page-fail trap */
#if KLH10_CPU_KS
extern void pag_iofail(paddr_t, int); /* PF trap for IO unibus ref */
#endif
#if KLH10_EXTADR /* PF trap for Illegal-Indirect ref */
extern void pag_iifail(vaddr_t, pment_t *);
extern void pag_iiset(vaddr_t, pment_t *); /* Set up vars for above */
#endif
#endif /* ifndef KN10PAG_INCLUDED */

View File

@@ -1,797 +0,0 @@
/* OPCODS.H - Definitions of all PDP-10 instruction opcodes
*/
/* $Id: opcods.h,v 2.4 2002/05/21 16:54:32 klh Exp $
*/
/* Copyright © 1992, 1993, 2001 Kenneth L. Harrenstien
** All Rights Reserved
**
** This file is part of the KLH10 Distribution. Use, modification, and
** re-distribution is permitted subject to the terms in the file
** named "LICENSE", which contains the full text of the legal notices
** and should always accompany this Distribution.
**
** This software is provided "AS IS" with NO WARRANTY OF ANY KIND.
**
** This notice (including the copyright and warranty disclaimer)
** must be included in all copies or derivations of this software.
*/
/*
* $Log: opcods.h,v $
* Revision 2.4 2002/05/21 16:54:32 klh
* Add KLH10_I_CIRC to allow any sys to have CIRC
*
* Revision 2.3 2001/11/10 21:28:59 klh
* Final 2.0 distribution checkin
*
*/
#ifndef OPCODS_RCSID
# define OPCODS_RCSID \
RCSID(opcods_h,"$Id: opcods.h,v 2.4 2002/05/21 16:54:32 klh Exp $")
#endif
/* This file is intended to be included multiple times, always within
** a specific context that defines the macros "idef", "ixdef", and "iodef"
** suitably so as to declare or define various parts of the bindings
** represented in this file.
**
** Normal instructions are defined with:
** idef(opval, name, enum, rtn, flags)
**
** and EXTEND opcodes are defined with:
** ixdef(xopval, name, enum, rtn, flags)
**
** IO instructions (with internal or external devices) are
** defined with:
** iodef(iocod, name, enum, rtn, flags)
** where "iocod" is built with IOINOP or IOEXOP.
**
** Operations not specified here are all initialized at startup to
** an appropriate default value, usually "i_muuo" so the monitor
** can handle them.
** Only one opcode is truly illegal: 0 in EXEC mode, which currently
** stops the KLH10 rather than trapping. To change this,
** remove the definition for "ILLEG".
*/
idef(000, "ILLEG", I_ILLEG, i_illegal, IF_SPEC)
idef(001, "LUUO", I_LUUO, i_luuo, IF_OPN|IF_1X1) /* 001-037 inclusive */
idef(040, "MUUO", I_MUUO, i_muuo, IF_OPN|IF_1X1) /* all others */
/* Opcodes 040-0101 inclusive default to i_muuo */
/* Late KL additions, note opcodes formerly UUOs "reserved for DEC" */
#if KLH10_CPU_KLX
idef(052, "PMOVE", I_PMOVE, i_pmove, IF_1S) /* KL PMOVE */
idef(053, "PMOVEM",I_PMOVEM,i_pmovem,IF_1SM) /* KL PMOVEM */
#endif
#if KLH10_SYS_ITS /* ITS pager XCT */
idef(0102, "XCTRI", I_XCTRI, i_pxct, IF_SPEC|IF_MR|IF_MIN)
idef(0103, "XCTR", I_XCTR, i_pxct, IF_SPEC|IF_MR|IF_MIN)
#elif KLH10_CPU_KL
idef(0102, "GFAD", I_GFAD, i_gfad, IF_2X) /* KL GFAD */
idef(0103, "GFSB", I_GFSB, i_gfsb, IF_2X) /* KL GFSB */
#endif
#if KLH10_SYS_T10 || KLH10_SYS_T20
idef(0104, "JSYS", I_JSYS, i_muuo, IF_ME) /* BBN PAGER INSTRUCTION */
#endif
#if KLH10_CPU_KS || KLH10_CPU_KL
idef(0105, "ADJSP", I_ADJSP, i_adjsp, IF_1XI) /* KL/KS */
#endif
#if KLH10_CPU_KL
idef(0106, "GFMP", I_GFMP, i_gfmp, IF_2X) /* KL GFMP */
idef(0107, "GFDV", I_GFDV, i_gfdv, IF_2X) /* KL GFDV */
#endif
#if !KLH10_CPU_KA
idef(0110, "DFAD", I_DFAD, i_dfad, IF_2X) /* KI+ */
idef(0111, "DFSB", I_DFSB, i_dfsb, IF_2X) /* KI+ */
idef(0112, "DFMP", I_DFMP, i_dfmp, IF_2X) /* KI+ */
idef(0113, "DFDV", I_DFDV, i_dfdv, IF_2X) /* KI+ */
# if KLH10_CPU_KS || KLH10_CPU_KL
idef(0114, "DADD", I_DADD, i_dadd, IF_2X) /* KL/KS */
idef(0115, "DSUB", I_DSUB, i_dsub, IF_2X) /* KL/KS */
idef(0116, "DMUL", I_DMUL, i_dmul, IF_AS|IF_A4|IF_MR|IF_M2) /* KL/KS */
idef(0117, "DDIV", I_DDIV, i_ddiv, IF_AS|IF_A4|IF_MR|IF_M2) /* KL/KS */
# endif /* KL/KS */
idef(0120, "DMOVE", I_DMOVE, i_dmove, IF_2S) /* KI+ */
idef(0121, "DMOVN", I_DMOVN, i_dmovn, IF_2S) /* KI+ */
idef(0122, "FIX", I_FIX, i_fix, IF_1S) /* KI+ */
# if KLH10_CPU_KS || KLH10_CPU_KL
idef(0123,"EXTEND",I_EXTEND,i_extend,IF_SPEC|IF_AS|IF_A4|IF_MR|IF_M1) /* KL/KS */
# endif /* KL/KS */
idef(0124, "DMOVEM",I_DMOVEM,i_dmovem, IF_2SM) /* KI+ */
idef(0125, "DMOVNM",I_DMOVNM,i_dmovnm, IF_2SM) /* KI+ */
idef(0126, "FIXR", I_FIXR, i_fixr, IF_1S) /* KI+ */
idef(0127, "FLTR", I_FLTR, i_fltr, IF_1S) /* KI+ */
#endif /* !KA */
idef(0130, "UFA", I_UFA, i_ufa, IF_AS|IF_A2|IF_MR|IF_M1) /* KA/KI */
idef(0131, "DFN", I_DFN, i_dfn, IF_1XB) /* KA/KI only */
idef(0132, "FSC", I_FSC, i_fsc, IF_1XI)
idef(0133, "IBP", I_IBP, i_ibp, IF_AS|IF_A0|IF_MS|IF_M1)
idef(0134, "ILDB", I_ILDB, i_ildb, IF_AW|IF_A1|IF_MS|IF_M1)
idef(0135, "LDB", I_LDB, i_ldb, IF_AW|IF_A1|IF_MR|IF_M1)
idef(0136, "IDPB", I_IDPB, i_idpb, IF_AR|IF_A1|IF_MS|IF_M1)
idef(0137, "DPB", I_DPB, i_dpb, IF_AR|IF_A1|IF_MS|IF_M1)
idef(0140, "FAD", I_FAD, i_fad, IF_1X)
idef(0141, "FADL", I_FADL, i_fadl, IF_1XFL) /* PDP6/KA/KI (not KL/KS) */
idef(0142, "FADM", I_FADM, i_fadm, IF_1XM)
idef(0143, "FADB", I_FADB, i_fadb, IF_1XB)
idef(0144, "FADR", I_FADR, i_fadr, IF_1X)
idef(0145, "FADRI", I_FADRI, i_fadri, IF_1XFI) /* KA+ INSTR (PDP6: FADRL) */
idef(0146, "FADRM", I_FADRM, i_fadrm, IF_1XM)
idef(0147, "FADRB", I_FADRB, i_fadrb, IF_1XB)
idef(0150, "FSB", I_FSB, i_fsb, IF_1X)
idef(0151, "FSBL", I_FSBL, i_fsbl, IF_1XFL) /* PDP6/KA/KI (not KL/KS) */
idef(0152, "FSBM", I_FSBM, i_fsbm, IF_1XM)
idef(0153, "FSBB", I_FSBB, i_fsbb, IF_1XB)
idef(0154, "FSBR", I_FSBR, i_fsbr, IF_1X)
idef(0155, "FSBRI", I_FSBRI, i_fsbri, IF_1XFI) /* KA+ INSTR (PDP6: FSBRL) */
idef(0156, "FSBRM", I_FSBRM, i_fsbrm, IF_1XM)
idef(0157, "FSBRB", I_FSBRB, i_fsbrb, IF_1XB)
idef(0160, "FMP", I_FMP, i_fmp, IF_1X)
idef(0161, "FMPL", I_FMPL, i_fmpl, IF_1XFL) /* PDP6/KA/KI (not KL/KS) */
idef(0162, "FMPM", I_FMPM, i_fmpm, IF_1XM)
idef(0163, "FMPB", I_FMPB, i_fmpb, IF_1XB)
idef(0164, "FMPR", I_FMPR, i_fmpr, IF_1X)
idef(0165, "FMPRI", I_FMPRI, i_fmpri, IF_1XFI) /* KA+ INSTR (PDP6: FMPRL) */
idef(0166, "FMPRM", I_FMPRM, i_fmprm, IF_1XM)
idef(0167, "FMPRB", I_FMPRB, i_fmprb, IF_1XB)
idef(0170, "FDV", I_FDV, i_fdv, IF_1X)
idef(0171, "FDVL", I_FDVL, i_fdvl, IF_1XFL) /* PDP6/KA/KI (not KL/KS) */
idef(0172, "FDVM", I_FDVM, i_fdvm, IF_1XM)
idef(0173, "FDVB", I_FDVB, i_fdvb, IF_1XB)
idef(0174, "FDVR", I_FDVR, i_fdvr, IF_1X)
idef(0175, "FDVRI", I_FDVRI, i_fdvri, IF_1XFI) /* KA+ INSTR (PDP6: FDVRL) */
idef(0176, "FDVRM", I_FDVRM, i_fdvrm, IF_1XM)
idef(0177, "FDVRB", I_FDVRB, i_fdvrb, IF_1XB)
/* ; 200-277 (MOVE - SUBB) */
idef(0200, "MOVE", I_MOVE, i_move, IF_1S)
idef(0201, "MOVEI", I_MOVEI, i_movei, IF_1SI)
idef(0202, "MOVEM", I_MOVEM, i_movem, IF_1SM)
idef(0203, "MOVES", I_MOVES, i_moves, IF_1SS)
idef(0204, "MOVS", I_MOVS, i_movs, IF_1S)
idef(0205, "MOVSI", I_MOVSI, i_movsi, IF_1SI)
idef(0206, "MOVSM", I_MOVSM, i_movsm, IF_1SM)
idef(0207, "MOVSS", I_MOVSS, i_movss, IF_1SS)
idef(0210, "MOVN", I_MOVN, i_movn, IF_1S)
idef(0211, "MOVNI", I_MOVNI, i_movni, IF_1SI)
idef(0212, "MOVNM", I_MOVNM, i_movnm, IF_1SM)
idef(0213, "MOVNS", I_MOVNS, i_movns, IF_1SS)
idef(0214, "MOVM", I_MOVM, i_movm, IF_1S)
idef(0215, "MOVMI", I_MOVMI, i_movei, IF_1SI) /* Same as MOVEI */
idef(0216, "MOVMM", I_MOVMM, i_movmm, IF_1SM)
idef(0217, "MOVMS", I_MOVMS, i_movms, IF_1SS)
idef(0220, "IMUL", I_IMUL, i_imul, IF_1X)
idef(0221, "IMULI", I_IMULI, i_imuli, IF_1XI)
idef(0222, "IMULM", I_IMULM, i_imulm, IF_1XM)
idef(0223, "IMULB", I_IMULB, i_imulb, IF_1XB)
idef(0224, "MUL", I_MUL, i_mul, IF_AS|IF_A2|IF_X1)
idef(0225, "MULI", I_MULI, i_muli, IF_AS|IF_A2|IF_XI)
idef(0226, "MULM", I_MULM, i_mulm, IF_1XM)
idef(0227, "MULB", I_MULB, i_mulb, IF_AS|IF_A2|IF_MS|IF_M1)
idef(0230, "IDIV", I_IDIV, i_idiv, IF_AS|IF_A2|IF_X1)
idef(0231, "IDIVI", I_IDIVI, i_idivi, IF_AS|IF_A2|IF_XI)
idef(0232, "IDIVM", I_IDIVM, i_idivm, IF_AR|IF_A1|IF_MS|IF_M1)
idef(0233, "IDIVB", I_IDIVB, i_idivb, IF_AS|IF_A2|IF_MS|IF_M1)
idef(0234, "DIV", I_DIV, i_div, IF_AS|IF_A2|IF_X1)
idef(0235, "DIVI", I_DIVI, i_divi, IF_AS|IF_A2|IF_XI)
idef(0236, "DIVM", I_DIVM, i_divm, IF_AR|IF_A1|IF_MS|IF_M1)
idef(0237, "DIVB", I_DIVB, i_divb, IF_AS|IF_A2|IF_MS|IF_M1)
idef(0240, "ASH", I_ASH, i_ash, IF_AS|IF_A1|IF_ME8)
idef(0241, "ROT", I_ROT, i_rot, IF_AS|IF_A1|IF_ME8)
idef(0242, "LSH", I_LSH, i_lsh, IF_AS|IF_A1|IF_ME8)
idef(0243, "JFFO", I_JFFO, i_jffo, IF_AR|IF_A1|IF_ME|IF_JMP) /* KA+ */
idef(0244, "ASHC", I_ASHC, i_ashc, IF_AR|IF_A2|IF_ME8)
idef(0245, "ROTC", I_ROTC, i_rotc, IF_AR|IF_A2|IF_ME8)
idef(0246, "LSHC", I_LSHC, i_lshc, IF_AR|IF_A2|IF_ME8)
#if KLH10_I_CIRC /* AI-KA and KL/KS: ROTC WITH AC+1 GOING THE WRONG WAY */
idef(0247, "CIRC", I_CIRC, i_circ, IF_AR|IF_A2|IF_ME8)
#endif
idef(0250, "EXCH", I_EXCH, i_exch, IF_1XB)
idef(0251, "BLT", I_BLT, i_blt, IF_SPEC|IF_1XB)
idef(0252, "AOBJP", I_AOBJP, i_aobjp, IF_AS|IF_A1|IF_ME|IF_JMP)
idef(0253, "AOBJN", I_AOBJN, i_aobjn, IF_AS|IF_A1|IF_ME|IF_JMP)
idef(0254, "JRST", I_JRST, i_jrst, IF_SPEC|IF_ME|IF_JMP)
idef(0255, "JFCL", I_JFCL, i_jfcl, IF_SPEC|IF_ME|IF_JMP)
idef(0256, "XCT", I_XCT, i_xct, IF_SPEC|IF_MR|IF_MIN)
#if !KLH10_CPU_KA && (KLH10_PAG_KI || KLH10_PAG_KL)
idef(0257, "MAP", I_MAP, i_map, IF_1C|IF_X1) /* KI+ (DEC pager) */
#endif
idef(0260, "PUSHJ", I_PUSHJ, i_pushj, IF_SPEC|IF_1C|IF_ME|IF_JMP)
idef(0261, "PUSH", I_PUSH, i_push, IF_SPEC|IF_1X)
idef(0262, "POP", I_POP, i_pop, IF_SPEC|IF_AS|IF_A1|IF_MW|IF_M1)
idef(0263, "POPJ", I_POPJ, i_popj, IF_SPEC|IF_AS|IF_A1|IF_ME|IF_JMP)
idef(0264, "JSR", I_JSR, i_jsr, IF_MW|IF_M1|IF_JMP)
idef(0265, "JSP", I_JSP, i_jsp, IF_1C|IF_ME|IF_JMP)
idef(0266, "JSA", I_JSA, i_jsa, IF_AS|IF_A1|IF_MW|IF_M1|IF_JMP)
idef(0267, "JRA", I_JRA, i_jra, IF_SPEC|IF_AS|IF_A1|IF_ME|IF_JMP)
idef(0270, "ADD", I_ADD, i_add, IF_1X)
idef(0271, "ADDI", I_ADDI, i_addi, IF_1XI)
idef(0272, "ADDM", I_ADDM, i_addm, IF_1XM)
idef(0273, "ADDB", I_ADDB, i_addb, IF_1XB)
idef(0274, "SUB", I_SUB, i_sub, IF_1X)
idef(0275, "SUBI", I_SUBI, i_subi, IF_1XI)
idef(0276, "SUBM", I_SUBM, i_subm, IF_1XM)
idef(0277, "SUBB", I_SUBB, i_subb, IF_1XB)
/* ; 300-377 (CAI - SOSG) */
idef(0300, "CAI", I_CAI, i_cai, IF_NOP)
idef(0301, "CAIL", I_CAIL, i_cail, IF_SKP|IF_AR|IF_A1|IF_ME)
idef(0302, "CAIE", I_CAIE, i_caie, IF_SKP|IF_AR|IF_A1|IF_ME)
idef(0303, "CAILE", I_CAILE, i_caile, IF_SKP|IF_AR|IF_A1|IF_ME)
idef(0304, "CAIA", I_CAIA, i_caia, IF_SKP)
idef(0305, "CAIGE", I_CAIGE, i_caige, IF_SKP|IF_AR|IF_A1|IF_ME)
idef(0306, "CAIN", I_CAIN, i_cain, IF_SKP|IF_AR|IF_A1|IF_ME)
idef(0307, "CAIG", I_CAIG, i_caig, IF_SKP|IF_AR|IF_A1|IF_ME)
idef(0310, "CAM", I_CAM, i_cam, IF_MR|IF_M1)
idef(0311, "CAML", I_CAML, i_caml, IF_SKP|IF_AR|IF_A1|IF_MR|IF_M1)
idef(0312, "CAME", I_CAME, i_came, IF_SKP|IF_AR|IF_A1|IF_MR|IF_M1)
idef(0313, "CAMLE", I_CAMLE, i_camle, IF_SKP|IF_AR|IF_A1|IF_MR|IF_M1)
idef(0314, "CAMA", I_CAMA, i_cama, IF_SKP|IF_MR|IF_M1)
idef(0315, "CAMGE", I_CAMGE, i_camge, IF_SKP|IF_AR|IF_A1|IF_MR|IF_M1)
idef(0316, "CAMN", I_CAMN, i_camn, IF_SKP|IF_AR|IF_A1|IF_MR|IF_M1)
idef(0317, "CAMG", I_CAMG, i_camg, IF_SKP|IF_AR|IF_A1|IF_MR|IF_M1)
idef(0320, "JUMP", I_JUMP, i_jump, IF_NOP)
idef(0321, "JUMPL", I_JUMPL, i_jumpl, IF_JMP|IF_AR|IF_A1|IF_ME)
idef(0322, "JUMPE", I_JUMPE, i_jumpe, IF_JMP|IF_AR|IF_A1|IF_ME)
idef(0323, "JUMPLE",I_JUMPLE,i_jumple, IF_JMP|IF_AR|IF_A1|IF_ME)
idef(0324, "JUMPA", I_JUMPA, i_jumpa, IF_JMP|IF_ME)
idef(0325, "JUMPGE",I_JUMPGE,i_jumpge, IF_JMP|IF_AR|IF_A1|IF_ME)
idef(0326, "JUMPN", I_JUMPN, i_jumpn, IF_JMP|IF_AR|IF_A1|IF_ME)
idef(0327, "JUMPG", I_JUMPG, i_jumpg, IF_JMP|IF_AR|IF_A1|IF_ME)
idef(0330, "SKIP", I_SKIP, i_skip, IF_AW|IF_A0|IF_MR|IF_M1)
idef(0331, "SKIPL", I_SKIPL, i_skipl, IF_SKP|IF_AW|IF_A0|IF_MR|IF_M1)
idef(0332, "SKIPE", I_SKIPE, i_skipe, IF_SKP|IF_AW|IF_A0|IF_MR|IF_M1)
idef(0333, "SKIPLE",I_SKIPLE,i_skiple, IF_SKP|IF_AW|IF_A0|IF_MR|IF_M1)
idef(0334, "SKIPA", I_SKIPA, i_skipa, IF_SKP|IF_AW|IF_A0|IF_MR|IF_M1)
idef(0335, "SKIPGE",I_SKIPGE,i_skipge, IF_SKP|IF_AW|IF_A0|IF_MR|IF_M1)
idef(0336, "SKIPN", I_SKIPN, i_skipn, IF_SKP|IF_AW|IF_A0|IF_MR|IF_M1)
idef(0337, "SKIPG", I_SKIPG, i_skipg, IF_SKP|IF_AW|IF_A0|IF_MR|IF_M1)
idef(0340, "AOJ", I_AOJ, i_aoj, IF_AS|IF_A1|IF_ME)
idef(0341, "AOJL", I_AOJL, i_aojl, IF_JMP|IF_AS|IF_A1|IF_ME)
idef(0342, "AOJE", I_AOJE, i_aoje, IF_JMP|IF_AS|IF_A1|IF_ME)
idef(0343, "AOJLE", I_AOJLE, i_aojle, IF_JMP|IF_AS|IF_A1|IF_ME)
idef(0344, "AOJA", I_AOJA, i_aoja, IF_JMP|IF_AS|IF_A1|IF_ME)
idef(0345, "AOJGE", I_AOJGE, i_aojge, IF_JMP|IF_AS|IF_A1|IF_ME)
idef(0346, "AOJN", I_AOJN, i_aojn, IF_JMP|IF_AS|IF_A1|IF_ME)
idef(0347, "AOJG", I_AOJG, i_aojg, IF_JMP|IF_AS|IF_A1|IF_ME)
idef(0350, "AOS", I_AOS, i_aos, IF_AW|IF_A0|IF_MS|IF_M1)
idef(0351, "AOSL", I_AOSL, i_aosl, IF_SKP|IF_AW|IF_A0|IF_MS|IF_M1)
idef(0352, "AOSE", I_AOSE, i_aose, IF_SKP|IF_AW|IF_A0|IF_MS|IF_M1)
idef(0353, "AOSLE", I_AOSLE, i_aosle, IF_SKP|IF_AW|IF_A0|IF_MS|IF_M1)
idef(0354, "AOSA", I_AOSA, i_aosa, IF_SKP|IF_AW|IF_A0|IF_MS|IF_M1)
idef(0355, "AOSGE", I_AOSGE, i_aosge, IF_SKP|IF_AW|IF_A0|IF_MS|IF_M1)
idef(0356, "AOSN", I_AOSN, i_aosn, IF_SKP|IF_AW|IF_A0|IF_MS|IF_M1)
idef(0357, "AOSG", I_AOSG, i_aosg, IF_SKP|IF_AW|IF_A0|IF_MS|IF_M1)
idef(0360, "SOJ", I_SOJ, i_soj, IF_AS|IF_A1|IF_ME)
idef(0361, "SOJL", I_SOJL, i_sojl, IF_JMP|IF_AS|IF_A1|IF_ME)
idef(0362, "SOJE", I_SOJE, i_soje, IF_JMP|IF_AS|IF_A1|IF_ME)
idef(0363, "SOJLE", I_SOJLE, i_sojle, IF_JMP|IF_AS|IF_A1|IF_ME)
idef(0364, "SOJA", I_SOJA, i_soja, IF_JMP|IF_AS|IF_A1|IF_ME)
idef(0365, "SOJGE", I_SOJGE, i_sojge, IF_JMP|IF_AS|IF_A1|IF_ME)
idef(0366, "SOJN", I_SOJN, i_sojn, IF_JMP|IF_AS|IF_A1|IF_ME)
idef(0367, "SOJG", I_SOJG, i_sojg, IF_JMP|IF_AS|IF_A1|IF_ME)
idef(0370, "SOS", I_SOS, i_sos, IF_AW|IF_A0|IF_MS|IF_M1)
idef(0371, "SOSL", I_SOSL, i_sosl, IF_SKP|IF_AW|IF_A0|IF_MS|IF_M1)
idef(0372, "SOSE", I_SOSE, i_sose, IF_SKP|IF_AW|IF_A0|IF_MS|IF_M1)
idef(0373, "SOSLE", I_SOSLE, i_sosle, IF_SKP|IF_AW|IF_A0|IF_MS|IF_M1)
idef(0374, "SOSA", I_SOSA, i_sosa, IF_SKP|IF_AW|IF_A0|IF_MS|IF_M1)
idef(0375, "SOSGE", I_SOSGE, i_sosge, IF_SKP|IF_AW|IF_A0|IF_MS|IF_M1)
idef(0376, "SOSN", I_SOSN, i_sosn, IF_SKP|IF_AW|IF_A0|IF_MS|IF_M1)
idef(0377, "SOSG", I_SOSG, i_sosg, IF_SKP|IF_AW|IF_A0|IF_MS|IF_M1)
/* ; 400-477 (SETZ - SETOB) */
idef(0400, "SETZ", I_SETZ, i_setz, IF_1C)
idef(0401, "SETZI", I_SETZI, i_setzi, IF_1C)
idef(0402, "SETZM", I_SETZM, i_setzm, IF_1CM)
idef(0403, "SETZB", I_SETZB, i_setzb, IF_1CB)
idef(0404, "AND", I_AND, i_and, IF_1X)
idef(0405, "ANDI", I_ANDI, i_andi, IF_1XI)
idef(0406, "ANDM", I_ANDM, i_andm, IF_1XM)
idef(0407, "ANDB", I_ANDB, i_andb, IF_1XB)
idef(0410, "ANDCA", I_ANDCA, i_andca, IF_1X)
idef(0411, "ANDCAI",I_ANDCAI,i_andcai, IF_1XI)
idef(0412, "ANDCAM",I_ANDCAM,i_andcam, IF_1XM)
idef(0413, "ANDCAB",I_ANDCAB,i_andcab, IF_1XB)
idef(0414, "SETM", I_SETM, i_setm, IF_1S)
#if KLH10_EXTADR
idef(0415,"XMOVEI",I_XMOVEI,i_xmovei, IF_1SI) /* Extended version */
#else
idef(0415,"SETMI", I_SETMI, i_setmi, IF_1SI)
#endif
idef(0416, "SETMM", I_SETMM, i_setmm, IF_MS|IF_M1)
idef(0417, "SETMB", I_SETMB, i_setmb, IF_1SB)
idef(0420, "ANDCM", I_ANDCM, i_andcm, IF_1X)
idef(0421, "ANDCMI",I_ANDCMI,i_andcmi, IF_1XI)
idef(0422, "ANDCMM",I_ANDCMM,i_andcmm, IF_1XM)
idef(0423, "ANDCMB",I_ANDCMB,i_andcmb, IF_1XB)
idef(0424, "SETA", I_SETA, i_seta, IF_NOP)
idef(0425, "SETAI", I_SETAI, i_setai, IF_NOP)
idef(0426, "SETAM", I_SETAM, i_setam, IF_1SM)
idef(0427, "SETAB", I_SETAB, i_setab, IF_1SM)
idef(0430, "XOR", I_XOR, i_xor, IF_1X)
idef(0431, "XORI", I_XORI, i_xori, IF_1XI)
idef(0432, "XORM", I_XORM, i_xorm, IF_1XM)
idef(0433, "XORB", I_XORB, i_xorb, IF_1XB)
idef(0434, "IOR", I_IOR, i_ior, IF_1X)
idef(0435, "IORI", I_IORI, i_iori, IF_1XI)
idef(0436, "IORM", I_IORM, i_iorm, IF_1XM)
idef(0437, "IORB", I_IORB, i_iorb, IF_1XB)
idef(0440, "ANDCB", I_ANDCB, i_andcb, IF_1X)
idef(0441, "ANDCBI",I_ANDCBI,i_andcbi, IF_1XI)
idef(0442, "ANDCBM",I_ANDCBM,i_andcbm, IF_1XM)
idef(0443, "ANDCBB",I_ANDCBB,i_andcbb, IF_1XB)
idef(0444, "EQV", I_EQV, i_eqv, IF_1X)
idef(0445, "EQVI", I_EQVI, i_eqvi, IF_1XI)
idef(0446, "EQVM", I_EQVM, i_eqvm, IF_1XM)
idef(0447, "EQVB", I_EQVB, i_eqvb, IF_1XB)
idef(0450, "SETCA", I_SETCA, i_setca, IF_AS|IF_A1)
idef(0451, "SETCAI",I_SETCAI,i_setcai, IF_AS|IF_A1)
idef(0452, "SETCAM",I_SETCAM,i_setcam, IF_1SM)
idef(0453, "SETCAB",I_SETCAB,i_setcab, IF_AS|IF_A1|IF_MW|IF_M1)
idef(0454, "ORCA", I_ORCA, i_orca, IF_1X)
idef(0455, "ORCAI", I_ORCAI, i_orcai, IF_1XI)
idef(0456, "ORCAM", I_ORCAM, i_orcam, IF_1XM)
idef(0457, "ORCAB", I_ORCAB, i_orcab, IF_1XB)
idef(0460, "SETCM", I_SETCM, i_setcm, IF_1X)
idef(0461, "SETCMI",I_SETCMI,i_setcmi, IF_1XI)
idef(0462, "SETCMM",I_SETCMM,i_setcmm, IF_1XM)
idef(0463, "SETCMB",I_SETCMB,i_setcmb, IF_1XB)
idef(0464, "ORCM", I_ORCM, i_orcm, IF_1X)
idef(0465, "ORCMI", I_ORCMI, i_orcmi, IF_1XI)
idef(0466, "ORCMM", I_ORCMM, i_orcmm, IF_1XM)
idef(0467, "ORCMB", I_ORCMB, i_orcmb, IF_1XB)
idef(0470, "ORCB", I_ORCB, i_orcb, IF_1X)
idef(0471, "ORCBI", I_ORCBI, i_orcbi, IF_1XI)
idef(0472, "ORCBM", I_ORCBM, i_orcbm, IF_1XM)
idef(0473, "ORCBB", I_ORCBB, i_orcbb, IF_1XB)
idef(0474, "SETO", I_SETO, i_seto, IF_1C)
idef(0475, "SETOI", I_SETOI, i_setoi, IF_1C)
idef(0476, "SETOM", I_SETOM, i_setom, IF_1CM)
idef(0477, "SETOB", I_SETOB, i_setob, IF_1CB)
/* ; 500-577 (HLL - HLRES) */
idef(0500, "HLL", I_HLL, i_hll, IF_1S)
#if KLH10_EXTADR
idef(0501,"XHLLI", I_XHLLI, i_xhlli, IF_1C) /* Extended version */
#else
idef(0501,"HLLI", I_HLLI, i_hlli, IF_1C)
#endif
idef(0502, "HLLM", I_HLLM, i_hllm, IF_1SM)
idef(0503, "HLLS", I_HLLS, i_hlls, IF_1SS)
idef(0504, "HRL", I_HRL, i_hrl, IF_1S)
idef(0505, "HRLI", I_HRLI, i_hrli, IF_1SI)
idef(0506, "HRLM", I_HRLM, i_hrlm, IF_1SM)
idef(0507, "HRLS", I_HRLS, i_hrls, IF_1SS)
idef(0510, "HLLZ", I_HLLZ, i_hllz, IF_1S)
idef(0511, "HLLZI", I_HLLZI, i_hllzi, IF_1C)
idef(0512, "HLLZM", I_HLLZM, i_hllzm, IF_1SM)
idef(0513, "HLLZS", I_HLLZS, i_hllzs, IF_1SS)
idef(0514, "HRLZ", I_HRLZ, i_hrlz, IF_1S)
idef(0515, "HRLZI", I_HRLZI, i_hrlzi, IF_1C)
idef(0516, "HRLZM", I_HRLZM, i_hrlzm, IF_1SM)
idef(0517, "HRLZS", I_HRLZS, i_hrlzs, IF_1SS)
idef(0520, "HLLO", I_HLLO, i_hllo, IF_1S)
idef(0521, "HLLOI", I_HLLOI, i_hlloi, IF_1C)
idef(0522, "HLLOM", I_HLLOM, i_hllom, IF_1SM)
idef(0523, "HLLOS", I_HLLOS, i_hllos, IF_1SS)
idef(0524, "HRLO", I_HRLO, i_hrlo, IF_1S)
idef(0525, "HRLOI", I_HRLOI, i_hrloi, IF_1C)
idef(0526, "HRLOM", I_HRLOM, i_hrlom, IF_1SM)
idef(0527, "HRLOS", I_HRLOS, i_hrlos, IF_1SS)
idef(0530, "HLLE", I_HLLE, i_hlle, IF_1S)
idef(0531, "HLLEI", I_HLLEI, i_hllei, IF_1C)
idef(0532, "HLLEM", I_HLLEM, i_hllem, IF_1SM)
idef(0533, "HLLES", I_HLLES, i_hlles, IF_1SS)
idef(0534, "HRLE", I_HRLE, i_hrle, IF_1S)
idef(0535, "HRLEI", I_HRLEI, i_hrlei, IF_1SI)
idef(0536, "HRLEM", I_HRLEM, i_hrlem, IF_1SM)
idef(0537, "HRLES", I_HRLES, i_hrles, IF_1SS)
idef(0540, "HRR", I_HRR, i_hrr, IF_1S)
idef(0541, "HRRI", I_HRRI, i_hrri, IF_1SI)
idef(0542, "HRRM", I_HRRM, i_hrrm, IF_1SM)
idef(0543, "HRRS", I_HRRS, i_hrrs, IF_1SS)
idef(0544, "HLR", I_HLR, i_hlr, IF_1S)
idef(0545, "HLRI", I_HLRI, i_hlri, IF_1C)
idef(0546, "HLRM", I_HLRM, i_hlrm, IF_1SM)
idef(0547, "HLRS", I_HLRS, i_hlrs, IF_1SS)
idef(0550, "HRRZ", I_HRRZ, i_hrrz, IF_1S)
idef(0551, "HRRZI", I_HRRZI, i_hrrzi, IF_1SI)
idef(0552, "HRRZM", I_HRRZM, i_hrrzm, IF_1SM)
idef(0553, "HRRZS", I_HRRZS, i_hrrzs, IF_1SS)
idef(0554, "HLRZ", I_HLRZ, i_hlrz, IF_1S)
idef(0555, "HLRZI", I_HLRZI, i_hlrzi, IF_1C)
idef(0556, "HLRZM", I_HLRZM, i_hlrzm, IF_1SM)
idef(0557, "HLRZS", I_HLRZS, i_hlrzs, IF_1SS)
idef(0560, "HRRO", I_HRRO, i_hrro, IF_1S)
idef(0561, "HRROI", I_HRROI, i_hrroi, IF_1SI)
idef(0562, "HRROM", I_HRROM, i_hrrom, IF_1SM)
idef(0563, "HRROS", I_HRROS, i_hrros, IF_1SS)
idef(0564, "HLRO", I_HLRO, i_hlro, IF_1S)
idef(0565, "HLROI", I_HLROI, i_hlroi, IF_1C)
idef(0566, "HLROM", I_HLROM, i_hlrom, IF_1SM)
idef(0567, "HLROS", I_HLROS, i_hlros, IF_1SS)
idef(0570, "HRRE", I_HRRE, i_hrre, IF_1S)
idef(0571, "HRREI", I_HRREI, i_hrrei, IF_1SI)
idef(0572, "HRREM", I_HRREM, i_hrrem, IF_1SM)
idef(0573, "HRRES", I_HRRES, i_hrres, IF_1SS)
idef(0574, "HLRE", I_HLRE, i_hlre, IF_1S)
idef(0575, "HLREI", I_HLREI, i_hlrei, IF_1C)
idef(0576, "HLREM", I_HLREM, i_hlrem, IF_1SM)
idef(0577, "HLRES", I_HLRES, i_hlres, IF_1SS)
/* ; 600-677 (TRN - TSON) */
idef(0600, "TRN", I_TRN, i_trn, IF_NOP)
idef(0601, "TLN", I_TLN, i_tln, IF_NOP)
idef(0602, "TRNE", I_TRNE, i_trne, IF_SKP|IF_AR|IF_A1|IF_ME)
idef(0603, "TLNE", I_TLNE, i_tlne, IF_SKP|IF_AR|IF_A1|IF_ME)
idef(0604, "TRNA", I_TRNA, i_trna, IF_SKP)
idef(0605, "TLNA", I_TLNA, i_tlna, IF_SKP)
idef(0606, "TRNN", I_TRNN, i_trnn, IF_SKP|IF_AR|IF_A1|IF_ME)
idef(0607, "TLNN", I_TLNN, i_tlnn, IF_SKP|IF_AR|IF_A1|IF_ME)
idef(0610, "TDN", I_TDN, i_tdn, IF_MR|IF_M1)
idef(0611, "TSN", I_TSN, i_tsn, IF_MR|IF_M1)
idef(0612, "TDNE", I_TDNE, i_tdne, IF_SKP|IF_AR|IF_A1|IF_MR|IF_M1)
idef(0613, "TSNE", I_TSNE, i_tsne, IF_SKP|IF_AR|IF_A1|IF_MR|IF_M1)
idef(0614, "TDNA", I_TDNA, i_tdna, IF_SKP|IF_AR|IF_A1|IF_MR|IF_M1)
idef(0615, "TSNA", I_TSNA, i_tsna, IF_SKP|IF_AR|IF_A1|IF_MR|IF_M1)
idef(0616, "TDNN", I_TDNN, i_tdnn, IF_SKP|IF_AR|IF_A1|IF_MR|IF_M1)
idef(0617, "TSNN", I_TSNN, i_tsnn, IF_SKP|IF_AR|IF_A1|IF_MR|IF_M1)
idef(0620, "TRZ", I_TRZ, i_trz, IF_AS|IF_A1|IF_ME)
idef(0621, "TLZ", I_TLZ, i_tlz, IF_AS|IF_A1|IF_ME)
idef(0622, "TRZE", I_TRZE, i_trze, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0623, "TLZE", I_TLZE, i_tlze, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0624, "TRZA", I_TRZA, i_trza, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0625, "TLZA", I_TLZA, i_tlza, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0626, "TRZN", I_TRZN, i_trzn, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0627, "TLZN", I_TLZN, i_tlzn, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0630, "TDZ", I_TDZ, i_tdz, IF_AS|IF_A1|IF_MR|IF_M1)
idef(0631, "TSZ", I_TSZ, i_tsz, IF_AS|IF_A1|IF_MR|IF_M1)
idef(0632, "TDZE", I_TDZE, i_tdze, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
idef(0633, "TSZE", I_TSZE, i_tsze, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
idef(0634, "TDZA", I_TDZA, i_tdza, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
idef(0635, "TSZA", I_TSZA, i_tsza, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
idef(0636, "TDZN", I_TDZN, i_tdzn, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
idef(0637, "TSZN", I_TSZN, i_tszn, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
idef(0640, "TRC", I_TRC, i_trc, IF_AS|IF_A1|IF_ME)
idef(0641, "TLC", I_TLC, i_tlc, IF_AS|IF_A1|IF_ME)
idef(0642, "TRCE", I_TRCE, i_trce, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0643, "TLCE", I_TLCE, i_tlce, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0644, "TRCA", I_TRCA, i_trca, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0645, "TLCA", I_TLCA, i_tlca, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0646, "TRCN", I_TRCN, i_trcn, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0647, "TLCN", I_TLCN, i_tlcn, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0650, "TDC", I_TDC, i_tdc, IF_AS|IF_A1|IF_MR|IF_M1)
idef(0651, "TSC", I_TSC, i_tsc, IF_AS|IF_A1|IF_MR|IF_M1)
idef(0652, "TDCE", I_TDCE, i_tdce, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
idef(0653, "TSCE", I_TSCE, i_tsce, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
idef(0654, "TDCA", I_TDCA, i_tdca, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
idef(0655, "TSCA", I_TSCA, i_tsca, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
idef(0656, "TDCN", I_TDCN, i_tdcn, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
idef(0657, "TSCN", I_TSCN, i_tscn, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
idef(0660, "TRO", I_TRO, i_tro, IF_AS|IF_A1|IF_ME)
idef(0661, "TLO", I_TLO, i_tlo, IF_AS|IF_A1|IF_ME)
idef(0662, "TROE", I_TROE, i_troe, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0663, "TLOE", I_TLOE, i_tloe, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0664, "TROA", I_TROA, i_troa, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0665, "TLOA", I_TLOA, i_tloa, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0666, "TRON", I_TRON, i_tron, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0667, "TLON", I_TLON, i_tlon, IF_SKP|IF_AS|IF_A1|IF_ME)
idef(0670, "TDO", I_TDO, i_tdo, IF_AS|IF_A1|IF_MR|IF_M1)
idef(0671, "TSO", I_TSO, i_tso, IF_AS|IF_A1|IF_MR|IF_M1)
idef(0672, "TDOE", I_TDOE, i_tdoe, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
idef(0673, "TSOE", I_TSOE, i_tsoe, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
idef(0674, "TDOA", I_TDOA, i_tdoa, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
idef(0675, "TSOA", I_TSOA, i_tsoa, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
idef(0676, "TDON", I_TDON, i_tdon, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
idef(0677, "TSON", I_TSON, i_tson, IF_SKP|IF_AS|IF_A1|IF_MR|IF_M1)
/* I/O INSTRUCTION DISPATCH */
/* Opcodes 0700-0777 inclusive default to either i_muuo or i_diodisp */
#if KLH10_CPU_KS || KLH10_CPU_KL /* "Internal" devices; AC-dispatched */
idef(0700, "IO700", I_IOV0, i_io700disp, IF_IO)
idef(0701, "IO701", I_IOV1, i_io701disp, IF_IO)
idef(0702, "IO702", I_IOV2, i_io702disp, IF_IO)
#endif /* KS || KL */
/* idef(0703, NULL, I_IO03, i_703, IF_IO) */
#if KLH10_CPU_KS /* Only KS, sigh... */
idef(0704, "UMOVE", I_UMOVE, i_umove, IF_SPEC) /* KS = PXCT 4,[MOVE] */
idef(0705, "UMOVEM", I_UMOVEM, i_umovem, IF_SPEC) /* KS = PXCT 4,[MOVEM] */
#endif /* KS */
/* idef(0706, NULL, I_IO06, i_706, IF_IO) */
/* idef(0707, NULL, I_IO07, i_707, IF_IO) */
#if KLH10_CPU_KS
# if KLH10_SYS_ITS
idef(0710, "IORDI", I_IORDI, i_iordi, IF_MEIO)
idef(0711, "IORDQ", I_IORDQ, i_iordq, IF_MEIO)
idef(0712, "IORD", I_IORD, i_iord, IF_MEIO)
idef(0713, "IOWR", I_IOWR, i_iowr, IF_MEIO)
idef(0714, "IOWRI", I_IOWRI, i_iowri, IF_MEIO)
idef(0715, "IOWRQ", I_IOWRQ, i_iowrq, IF_MEIO)
# else /* DEC */
idef(0710, "TIOE", I_TIOE, i_tioe, IF_MEIO)
idef(0711, "TION", I_TION, i_tion, IF_MEIO)
idef(0712, "RDIO", I_RDIO, i_rdio, IF_MEIO)
idef(0713, "WRIO", I_WRIO, i_wrio, IF_MEIO)
idef(0714, "BSIO", I_BSIO, i_bsio, IF_MEIO)
idef(0715, "BCIO", I_BCIO, i_bcio, IF_MEIO)
# endif /* DEC */
idef(0716, "BLTBU", I_BLTBU, i_bltbu, IF_SPEC|IF_AS|IF_A1|IF_MW|IF_M1)
idef(0717, "BLTUB", I_BLTUB, i_bltub, IF_SPEC|IF_AS|IF_A1|IF_MW|IF_M1)
# if KLH10_SYS_ITS
idef(0720, "IORDBI", I_IORDBI, i_iordbi, IF_MEIO)
idef(0721, "IORDBQ", I_IORDBQ, i_iordbq, IF_MEIO)
idef(0722, "IORDB", I_IORDB, i_iordb, IF_MEIO)
idef(0723, "IOWRB", I_IOWRB, i_iowrb, IF_MEIO)
idef(0724, "IOWRBI", I_IOWRBI, i_iowrbi, IF_MEIO)
idef(0725, "IOWRBQ", I_IOWRBQ, i_iowrbq, IF_MEIO)
# else /* DEC */
idef(0720, "TIOEB", I_TIOEB, i_tioeb, IF_MEIO)
idef(0721, "TIONB", I_TIONB, i_tionb, IF_MEIO)
idef(0722, "RDIOB", I_RDIOB, i_rdiob, IF_MEIO)
idef(0723, "WRIOB", I_WRIOB, i_wriob, IF_MEIO)
idef(0724, "BSIOB", I_BSIOB, i_bsiob, IF_MEIO)
idef(0725, "BCIOB", I_BCIOB, i_bciob, IF_MEIO)
# endif /* DEC */
#endif /* KLH10_CPU_KS */
/*
idef(0726, NULL, I_IO26, i_726, IF_IO)
idef(0727, NULL, I_IO27, i_727, IF_IO)
idef(0730, NULL, I_IO30, i_730, IF_IO)
idef(0731, NULL, I_IO31, i_731, IF_IO)
idef(0732, NULL, I_IO32, i_732, IF_IO)
idef(0733, NULL, I_IO33, i_733, IF_IO)
idef(0734, NULL, I_IO34, i_734, IF_IO)
idef(0735, NULL, I_IO35, i_735, IF_IO)
idef(0736, NULL, I_IO36, i_736, IF_IO)
idef(0737, NULL, I_IO37, i_737, IF_IO)
idef(0740, NULL, I_IO40, i_740, IF_IO)
idef(0741, NULL, I_IO41, i_741, IF_IO)
idef(0742, NULL, I_IO42, i_742, IF_IO)
idef(0743, NULL, I_IO43, i_743, IF_IO)
idef(0744, NULL, I_IO44, i_744, IF_IO)
idef(0745, NULL, I_IO45, i_745, IF_IO)
idef(0746, NULL, I_IO46, i_746, IF_IO)
idef(0747, NULL, I_IO47, i_747, IF_IO)
idef(0750, NULL, I_IO50, i_750, IF_IO)
idef(0751, NULL, I_IO51, i_751, IF_IO)
idef(0752, NULL, I_IO52, i_752, IF_IO)
idef(0753, NULL, I_IO53, i_753, IF_IO)
idef(0754, NULL, I_IO54, i_754, IF_IO)
idef(0755, NULL, I_IO55, i_755, IF_IO)
idef(0756, NULL, I_IO56, i_756, IF_IO)
idef(0757, NULL, I_IO57, i_757, IF_IO)
idef(0760, NULL, I_IO60, i_760, IF_IO)
idef(0761, NULL, I_IO61, i_761, IF_IO)
idef(0762, NULL, I_IO62, i_762, IF_IO)
idef(0763, NULL, I_IO63, i_763, IF_IO)
idef(0764, NULL, I_IO64, i_764, IF_IO)
idef(0765, NULL, I_IO65, i_765, IF_IO)
idef(0766, NULL, I_IO66, i_766, IF_IO)
idef(0767, NULL, I_IO67, i_767, IF_IO)
idef(0770, NULL, I_IO70, i_770, IF_IO)
idef(0771, NULL, I_IO71, i_771, IF_IO)
idef(0772, NULL, I_IO72, i_772, IF_IO)
idef(0773, NULL, I_IO73, i_773, IF_IO)
idef(0774, NULL, I_IO74, i_774, IF_IO)
idef(0775, NULL, I_IO75, i_775, IF_IO)
idef(0776, NULL, I_IO76, i_776, IF_IO)
idef(0777, NULL, I_IO77, i_777, IF_IO)
*/
/* "INTERNAL" DEVICE IO INSTRUCTIONS (0700-0702 inclusive) */
/* APR */
iodef(IOINOP(0700, 0), "APRID", IO_APRID, io_aprid, IF_IO) /* BI APR, */
#if KLH10_CPU_KL
/* DATAI APR, - (KA/KI: Read console switches) */
iodef(IOINOP(0700, 01), NULL, IO_DI_APR, io_di_apr, IF_IO) /* DI APR, */
iodef(IOINOP(0700, 02), "WRFIL", IO_WRFIL, io_wrfil, IF_IO) /* BO APR, */
/* DATAO APR, - (KA: set relocs) (KI: set maint) */
iodef(IOINOP(0700, 03), NULL, IO_DO_APR, io_do_apr, IF_IO) /* DO APR, */
#endif
iodef(IOINOP(0700, 04), "WRAPR", IO_WRAPR, io_wrapr, IF_IO) /* CO APR, */
iodef(IOINOP(0700, 05), "RDAPR", IO_RDAPR, io_rdapr, IF_IO) /* CI APR, */
iodef(IOINOP(0700, 06), NULL, IO_SZ_APR, io_sz_apr, IF_IO) /* SZ APR, */
iodef(IOINOP(0700, 07), NULL, IO_SO_APR, io_so_apr, IF_IO) /* SO APR, */
/* PI */
#if KLH10_CPU_KL
iodef(IOINOP(0700, 010), "RDERA", IO_RDERA, io_rdera, IF_IO) /* BI PI, */
#endif
#if 0
iodef(IOINOP(0700, 011), NULL, IO_DI_PI, NULL, IF_IO) /* DI PI, */
#endif
#if KLH10_CPU_KL
iodef(IOINOP(0700, 012),"SBDIAG",IO_SBDIAG,io_sbdiag,IF_IO) /* BO PI, */
#endif
#if 0 /* DATAO PI, - (KA/KI: Disp data on console lites) */
iodef(IOINOP(0700, 013), NULL, IO_DO_PI, NULL, IF_IO) /* DO PI, */
#endif
iodef(IOINOP(0700, 014), "WRPI", IO_WRPI, io_wrpi, IF_IO) /* CO PI, */
iodef(IOINOP(0700, 015), "RDPI", IO_RDPI, io_rdpi, IF_IO) /* CI PI, */
iodef(IOINOP(0700, 016), NULL, IO_SZ_PI, io_sz_pi, IF_IO) /* SZ PI, */
iodef(IOINOP(0700, 017), NULL, IO_SO_PI, io_so_pi, IF_IO) /* SO PI, */
/* PAG */
#if KLH10_CPU_KS || KLH10_CPU_KL
# if KLH10_SYS_ITS
iodef(IOINOP(0701, 0),"CLRCSH",IO_CLRCSH,io_clrcsh,IF_IO) /* BI PAG, */
# endif
iodef(IOINOP(0701, 01), "RDUBR", IO_RDUBR, io_rdubr, IF_IO) /* DI PAG, */
iodef(IOINOP(0701, 02), "CLRPT", IO_CLRPT, io_clrpt, IF_IO) /* BO PAG, */
iodef(IOINOP(0701, 03), "WRUBR", IO_WRUBR, io_wrubr, IF_IO) /* DO PAG, */
iodef(IOINOP(0701, 04), "WREBR", IO_WREBR, io_wrebr, IF_IO) /* CO PAG, */
iodef(IOINOP(0701, 05), "RDEBR", IO_RDEBR, io_rdebr, IF_IO) /* CI PAG, */
# if KLH10_CPU_KL
iodef(IOINOP(0701, 06), NULL, IO_SZ_PAG, io_sz_pag, IF_IO) /* SZ PAG, */
iodef(IOINOP(0701, 07), NULL, IO_SO_PAG, io_so_pag, IF_IO) /* SO PAG, */
# endif
#endif /* KS || KL */
/* CCA */
#if KLH10_CPU_KL
iodef(IOINOP(0701, 010), NULL, IO_BI_CCA,io_swp, IF_IO) /* BI CCA, */
iodef(IOINOP(0701, 011), "SWPIA", IO_SWPIA, io_swpia, IF_IO) /* DI CCA, */
iodef(IOINOP(0701, 012), "SWPVA", IO_SWPVA, io_swpva, IF_IO) /* BO CCA, */
iodef(IOINOP(0701, 013), "SWPUA", IO_SWPUA, io_swpua, IF_IO) /* DO CCA, */
iodef(IOINOP(0701, 014), NULL, IO_CO_CCA,io_swp, IF_IO) /* CO CCA, */
iodef(IOINOP(0701, 015), "SWPIO", IO_SWPIO, io_swpio, IF_IO) /* CI CCA, */
iodef(IOINOP(0701, 016), "SWPVO", IO_SWPVO, io_swpvo, IF_IO) /* SZ CCA, */
iodef(IOINOP(0701, 017), "SWPUO", IO_SWPUO, io_swpuo, IF_IO) /* SO CCA, */
#elif KLH10_SYS_ITS && KLH10_CPU_KS
iodef(IOINOP(0701, 011), "RDPCST",IO_RDPCST,io_rdpcst,IF_IO) /* DI CCA, */
iodef(IOINOP(0701, 013), "WRPCST",IO_WRPCST,io_wrpcst,IF_IO) /* DO CCA, */
#endif
/* TIM */
#if KLH10_CPU_KS
# if KLH10_PAG_ITS
iodef(IOINOP(0702, 0), "SDBR1", IO_SDBR1, io_sdbr1, IF_IO) /* BI TIM, */
iodef(IOINOP(0702, 01), "SDBR2", IO_SDBR2, io_sdbr2, IF_IO) /* DI TIM, */
iodef(IOINOP(0702, 02), "SDBR3", IO_SDBR3, io_sdbr3, IF_IO) /* BO TIM, */
iodef(IOINOP(0702, 03), "SDBR4", IO_SDBR4, io_sdbr4, IF_IO) /* DO TIM, */
iodef(IOINOP(0702, 07), "SPM", IO_SPM, io_spm, IF_IO) /* SO TIM, */
# elif KLH10_PAG_KL /* DEC-specific hacks */
iodef(IOINOP(0702, 0), "RDSPB", IO_RDSPB, io_rdspb, IF_IO) /* BI TIM, */
iodef(IOINOP(0702, 01), "RDCSB", IO_RDCSB, io_rdcsb, IF_IO) /* DI TIM, */
iodef(IOINOP(0702, 02), "RDPUR", IO_RDPUR, io_rdpur, IF_IO) /* BO TIM, */
iodef(IOINOP(0702, 03), "RDCSTM",IO_RDCSTM,io_rdcstm,IF_IO) /* DO TIM, */
# endif
iodef(IOINOP(0702, 04), "RDTIM", IO_RDTIM, io_rdtim, IF_IO) /* CO TIM, */
iodef(IOINOP(0702, 05), "RDINT", IO_RDINT, io_rdint, IF_IO) /* CI TIM, */
iodef(IOINOP(0702, 06), "RDHSB", IO_RDHSB, io_rdhsb, IF_IO) /* SZ TIM, */
#endif /* KS */
#if KLH10_CPU_KL
iodef(IOINOP(0702, 0), "RDPERF", IO_RDPERF, io_rdperf, IF_IO) /* BI TIM, */
iodef(IOINOP(0702, 01), "RDTIME", IO_RDTIME, io_rdtime, IF_IO) /* DI TIM, */
iodef(IOINOP(0702, 02), "WRPAE", IO_WRPAE, io_wrpae, IF_IO) /* BO TIM, */
# if 0
iodef(IOINOP(0702, 03), NULL, IO_DO_TIM, NULL, IF_IO) /* DO TIM, */
# endif
iodef(IOINOP(0702, 04), NULL, IO_CO_TIM, io_co_tim, IF_IO) /* CO TIM, */
iodef(IOINOP(0702, 05), NULL, IO_CI_TIM, io_ci_tim, IF_IO) /* CI TIM, */
iodef(IOINOP(0702, 06), NULL, IO_SZ_TIM, io_sz_tim, IF_IO) /* SZ TIM, */
iodef(IOINOP(0702, 07), NULL, IO_SO_TIM, io_so_tim, IF_IO) /* SO TIM, */
#endif /* KL */
/* MTR */
#if KLH10_CPU_KS
# if KLH10_PAG_ITS
iodef(IOINOP(0702, 010), "LDBR1", IO_LDBR1, io_ldbr1, IF_IO) /* BI MTR, */
iodef(IOINOP(0702, 011), "LDBR2", IO_LDBR2, io_ldbr2, IF_IO) /* DI MTR, */
iodef(IOINOP(0702, 012), "LDBR3", IO_LDBR3, io_ldbr3, IF_IO) /* BO MTR, */
iodef(IOINOP(0702, 013), "LDBR4", IO_LDBR4, io_ldbr4, IF_IO) /* DO MTR, */
iodef(IOINOP(0702, 017), "LPMR", IO_LPMR, io_lpmr, IF_IO) /* SO MTR, */
# elif KLH10_PAG_KL /* DEC-specific hacks */
iodef(IOINOP(0702, 010), "WRSPB", IO_WRSPB, io_wrspb, IF_IO) /* BI MTR, */
iodef(IOINOP(0702, 011), "WRCSB", IO_WRCSB, io_wrcsb, IF_IO) /* DI MTR, */
iodef(IOINOP(0702, 012), "WRPUR", IO_WRPUR, io_wrpur, IF_IO) /* BO MTR, */
iodef(IOINOP(0702, 013), "WRCSTM",IO_WRCSTM,io_wrcstm,IF_IO) /* DO MTR, */
# endif
iodef(IOINOP(0702, 014), "WRTIM", IO_WRTIM, io_wrtim, IF_IO) /* CO MTR, */
iodef(IOINOP(0702, 015), "WRINT", IO_WRINT, io_wrint, IF_IO) /* CI MTR, */
iodef(IOINOP(0702, 016), "WRHSB", IO_WRHSB, io_wrhsb, IF_IO) /* SZ MTR, */
#endif /* KS */
#if KLH10_CPU_KL
iodef(IOINOP(0702, 010), "RDMACT",IO_RDMACT, io_rdmact, IF_IO) /* BI MTR, */
iodef(IOINOP(0702, 011), "RDEACT",IO_RDEACT, io_rdeact, IF_IO) /* DI MTR, */
# if 0
iodef(IOINOP(0702, 012), NULL, IO_BO_MTR, NULL, IF_IO) /* BO MTR, */
iodef(IOINOP(0702, 013), NULL, IO_DO_MTR, NULL, IF_IO) /* DO MTR, */
# endif
iodef(IOINOP(0702, 014), "WRTIME",IO_WRTIME, io_wrtime, IF_IO) /* CO MTR, */
iodef(IOINOP(0702, 015), NULL, IO_CI_MTR, io_ci_mtr, IF_IO) /* CI MTR, */
iodef(IOINOP(0702, 016), NULL, IO_SZ_MTR, io_sz_mtr, IF_IO) /* SZ MTR, */
iodef(IOINOP(0702, 017), NULL, IO_SO_MTR, io_so_mtr, IF_IO) /* SO MTR, */
#endif /* KL */
/* NOTE!! Check the IO_N def in opdefs.h if more IO-class ops are added! */
/* EXTENDED INSTRUCTIONS */
#if (KLH10_CPU_KS || KLH10_CPU_KL) \
&& (KLH10_SYS_T10 || KLH10_SYS_T20) /* DEC systems only */
ixdef(IXOP(000), "ILLEG", IX_ILLEG, ix_undef, IF_SPEC)
ixdef(IXOP(001), "CMPSL", IX_CMPSL, ix_cmps, IF_SPEC) /* Common rtn */
ixdef(IXOP(002), "CMPSE", IX_CMPSE, ix_cmps, IF_SPEC) /* " */
ixdef(IXOP(003), "CMPSLE", IX_CMPSLE, ix_cmps, IF_SPEC) /* " */
ixdef(IXOP(004), "EDIT", IX_EDIT, ix_edit, IF_SPEC)
ixdef(IXOP(005), "CMPSGE", IX_CMPSGE, ix_cmps, IF_SPEC) /* Common rtn */
ixdef(IXOP(006), "CMPSN", IX_CMPSN, ix_cmps, IF_SPEC) /* " */
ixdef(IXOP(007), "CMPSG", IX_CMPSG, ix_cmps, IF_SPEC) /* " */
ixdef(IXOP(010), "CVTDBO", IX_CVTDBO, ix_cvtdb, IF_SPEC) /* Common rtn */
ixdef(IXOP(011), "CVTDBT", IX_CVTDBT, ix_cvtdb, IF_SPEC) /* " */
ixdef(IXOP(012), "CVTBDO", IX_CVTBDO, ix_cvtbd, IF_SPEC) /* Common rtn */
ixdef(IXOP(013), "CVTBDT", IX_CVTBDT, ix_cvtbd, IF_SPEC) /* " */
ixdef(IXOP(014), "MOVSO", IX_MOVSO, ix_movso, IF_SPEC)
ixdef(IXOP(015), "MOVST", IX_MOVST, ix_movst, IF_SPEC)
ixdef(IXOP(016), "MOVSLJ", IX_MOVSLJ, ix_movslj,IF_SPEC)
ixdef(IXOP(017), "MOVSRJ", IX_MOVSRJ, ix_movsrj,IF_SPEC)
#if KLH10_CPU_KLX /* Always MUUO if not on extended KL */
ixdef(IXOP(020), "XBLT", IX_XBLT, ix_xblt, IF_SPEC)
#endif
#if KLH10_CPU_KL
ixdef(IXOP(021), "GSNGL", IX_GSNGL, ix_gsngl, IF_SPEC)
ixdef(IXOP(022), "GDBLE", IX_GDBLE, ix_gdble, IF_SPEC)
# if 0 /* Simulated in T10+T20 monitor */
ixdef(IXOP(023), "GDFIX", IX_GDFIX, ix_gdfix, IF_SPEC)
ixdef(IXOP(024), "GFIX", IX_GFIX, ix_gfix, IF_SPEC)
ixdef(IXOP(025), "GDFIXR", IX_GDFIXR, ix_gdfixr,IF_SPEC)
ixdef(IXOP(026), "GFIXR", IX_GFIXR, ix_gfixr, IF_SPEC)
# endif /* 0 */
ixdef(IXOP(027), "DGFLTR", IX_DGFLTR, ix_dgfltr,IF_SPEC)
ixdef(IXOP(030), "GFLTR", IX_GFLTR, ix_gfltr, IF_SPEC)
ixdef(IXOP(031), "GFSC", IX_GFSC, ix_gfsc, IF_SPEC)
#endif /* KL only */
#endif /* (KL||KS) && (T10||T20) */
/* NOTE!! Check the IX_N def in opdefs.h if more EXTEND ops are added! */
/* Other cruft for dubious posterity */
/*
;OLD PROGRAMS USE THESE NAMES
CLEAR==SETZ
CLEARI==SETZI
CLEARM==SETZM
CLEARB==SETZB
;RANDOM ALIAS NAMES
ERJMP==JUMP 16, ; TOPS-20 JSYS-error dispatch (becomes JRST)
ERCAL==JUMP 17, ; TOPS-20 JSYS-error call (becomes PUSHJ 17,)
ADJBP==IBP ;KL10 FORM OF IBP WITH VARIABLE NUMBER TO INCREMENT
JFOV==JFCL 1, ;PDP10 INSTRUCTION (PC CHANGE ON PDP6)
JCRY1==JFCL 2,
JCRY0==JFCL 4,
JCRY==JFCL 6,
JOV==JFCL 10,
PORTAL==JRST 1, ; KI/KL
JRSTF==JRST 2,
HALT==JRST 4,
XJRSTF==JRST 5, ; KL/KS
XJEN==JRST 6, ; KL/KS
XPCW==JRST 7, ; KL/KS
JEN==JRST 12,
SFM==JRST 14, ; KL/KS
XMOVEI==SETMI ; KL only
XHLLI==HLLI ; KL only
;PDP6 HAS LONG FORM ROUNDED INSTEAD OF IMMEDIATES (FADRL, not FADRI, etc)
*/

View File

@@ -68,7 +68,7 @@ int
osn_ifsock(char *ifnam, ossock_t *as)
{
#if (KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_BPF || KLH10_NET_PFLT || \
KLH10_NET_TUN || KLH10_NET_LNX)
KLH10_NET_TUN || KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE)
return ((*as = socket(AF_INET, SOCK_DGRAM, 0)) >= 0);
#else
# error OSD implementation needed for osn_ifsock
@@ -79,7 +79,7 @@ int
osn_ifclose(ossock_t s)
{
#if (KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_BPF || KLH10_NET_PFLT || \
KLH10_NET_TUN || KLH10_NET_LNX)
KLH10_NET_TUN || KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE)
return (close(s) >= 0);
#else
# error OSD implementation needed for osn_ifclose
@@ -161,6 +161,12 @@ or alternatively:
? (sizeof(struct ifreq) - sizeof(struct sockaddr) + (ifr).ifr_addr.sa_len) \
: sizeof(struct ifreq))
This has been made trickier by NetBSD 5.0, which doesn't put a sockaddr
but a (union with as largest member a) sockaddr_storage in the ifreq.
Now the size is always the same again, but not sizeof(struct sockaddr).
This can (probably) be recognised by the existence of
#define ifr_space ifr_ifru.ifru_space / * sockaddr_storage * /
*/
/*
Note that searching for AF_INET or IP addresses only finds interfaces that
@@ -288,7 +294,7 @@ osn_iftab_pass(int opts, int npass, int s, struct ifconf *ifc)
uses a variable-size "ifreq" entry! Choke...
*/
ifnext = ifp + 1; /* Assume normal entry at first */
#if NETIF_HAS_SALEN
#if NETIF_HAS_SALEN && !defined(ifr_space)
if (ifp->ifr_addr.sa_len > sizeof(struct sockaddr)) {
offset = ifp->ifr_addr.sa_len - sizeof(struct sockaddr);
ifnext = (struct ifreq *)((char *)ifnext + offset);
@@ -382,6 +388,8 @@ osn_iftab_pass(int opts, int npass, int s, struct ifconf *ifc)
}
}
#include <stddef.h>
void
osn_ifctab_show(FILE *f, struct ifconf *ifc)
{
@@ -393,8 +401,17 @@ osn_ifctab_show(FILE *f, struct ifconf *ifc)
int nents = 0;
int nvary = 0;
fprintf(f, "Interface table: %ld bytes (%d entries if std addr len %d)\n",
(long)ifc->ifc_len, ifc->ifc_len/sizeof(struct ifreq),
fprintf(f, "sizeof struct ifreq = %d\r\n", (int) sizeof(struct ifreq));
fprintf(f, "IFNAMSIZ = %d\r\n", (int) IFNAMSIZ);
#if CENV_SYS_NETBSD
fprintf(f, "offset of struct sockaddr_storage = %d\r\n", (int) offsetof(struct ifreq, ifr_space));
#endif
fprintf(f, "sizeof struct sockaddr = %d\r\n", (int) sizeof(struct sockaddr));
fprintf(f, "sizeof struct sockaddr_storage = %d\r\n", (int) sizeof(struct sockaddr_storage));
fprintf(f, "sizeof union ifr_ifru = %d\r\n", (int) sizeof(ifr->ifr_ifru));
fprintf(f, "Interface table: %ld bytes (%d entries if std addr len %d)\r\n",
(long)ifc->ifc_len, (int)(ifc->ifc_len/sizeof(struct ifreq)),
(int)sizeof(struct sockaddr));
ifr = ifc->ifc_req;
@@ -408,18 +425,19 @@ osn_ifctab_show(FILE *f, struct ifconf *ifc)
len = sizeof(struct sockaddr);
#endif
fprintf(f, "offset: %d\r\n", (int)((char *)ifr - (char *)ifc->ifc_req));
/* Output entry data */
fprintf(f, "%2d: \"%.*s\" fam %d, len %d",
fprintf(f, "%2d: \"%.*s\" sockaddr.sa_family %d, .sa_len %d",
i, (int)sizeof(ifr->ifr_name), ifr->ifr_name,
ifr->ifr_addr.sa_family, len);
if (len) {
cp = (unsigned char *) ifr->ifr_addr.sa_data;
fprintf(f, " = %x", *cp);
fprintf(f, " = (sockaddr.sa_data) %x", *cp);
for (--len; len > 0; --len) {
fprintf(f, ":%x", *++cp);
}
}
fprintf(f, "\n");
fprintf(f, "\r\n");
cp = (unsigned char *) ifr->ifr_addr.sa_data;
switch (ifr->ifr_addr.sa_family) {
@@ -429,7 +447,7 @@ osn_ifctab_show(FILE *f, struct ifconf *ifc)
struct in_addr *in = &skin->sin_addr;
unsigned char *ucp = (unsigned char *) &in->s_addr;
fprintf(f, " AF_INET = port %d, IP %d.%d.%d.%d\n",
fprintf(f, " AF_INET = port %d, IP %d.%d.%d.%d\r\n",
(int)skin->sin_port,
ucp[0], ucp[1], ucp[2], ucp[3]);
}
@@ -439,7 +457,7 @@ osn_ifctab_show(FILE *f, struct ifconf *ifc)
case AF_LINK:
{
struct sockaddr_dl *dla = (struct sockaddr_dl *) &ifr->ifr_addr;
fprintf(f, " AF_LINK = type %d, alen %d",
fprintf(f, " AF_LINK = type %d, sdl_alen %d",
dla->sdl_type, dla->sdl_alen);
if (len = dla->sdl_alen) {
cp = (unsigned char *) LLADDR(dla);
@@ -448,18 +466,23 @@ osn_ifctab_show(FILE *f, struct ifconf *ifc)
fprintf(f, ":%x", *++cp);
}
}
fprintf(f, "\n");
fprintf(f, "\r\n");
}
break;
#endif
#if defined(AF_INET6)
case AF_INET6:
fprintf(f, " AF_INET6 (No handler for this)\r\n");
break;
#endif
default:
fprintf(f, " No handler for this family\n");
fprintf(f, " No handler for this family\r\n");
}
/* Move onto next entry */
#if NETIF_HAS_SALEN
#if NETIF_HAS_SALEN && !defined(ifr_space)
if (ifr->ifr_addr.sa_len > sizeof(struct sockaddr)) {
++nvary;
ifr = (struct ifreq *)((char *)(ifr + 1) +
@@ -469,10 +492,10 @@ osn_ifctab_show(FILE *f, struct ifconf *ifc)
ifr++;
}
if (nvary)
fprintf(f, "Interface summary: %d entries of varying length\n",
fprintf(f, "Interface summary: %d entries of varying length\r\n",
nents);
else
fprintf(f, "Interface summary: %d entries of std length %d\n",
fprintf(f, "Interface summary: %d entries of std length %d\r\n",
nents, (int)sizeof(struct ifreq));
}
@@ -483,7 +506,7 @@ osn_iftab_show(FILE *f, struct ifent *ifents, int nents)
register struct ifent *ife;
int i;
fprintf(f, "Filtered IFE table: %d entries\n", nents);
fprintf(f, "Filtered IFE table: %d entries\r\n", nents);
for (i = 0, ife = ifents; i < nents; ++i, ++ife) {
fprintf(f, "%2d: \"%s\"", i, ife->ife_name);
@@ -502,7 +525,7 @@ osn_iftab_show(FILE *f, struct ifent *ifents, int nents)
fprintf(f, " (Other: fam %d)",
ife->ife_pother->ifr_addr.sa_family);
}
fprintf(f, "\n");
fprintf(f, "\r\n");
}
}
@@ -897,6 +920,9 @@ osn_ifeaget(int s, /* Socket for (AF_INET, SOCK_DGRAM, 0) */
return TRUE;
}
static struct eth_addr emhost_ea = /* Emulated host ether addr for tap */
{ 0xf2, 0x0b, 0xa4, 0xff, 0xff, 0xff };
/* OSN_PFEAGET - get physical ethernet address for an open packetfilter FD.
*
* Also not well documented, but generally easier to perform.
@@ -945,8 +971,20 @@ osn_pfeaget(int pfs, /* Packetfilter socket or FD */
}
ea_set(eap, endp.end_addr);
#elif KLH10_NET_BPF && !CENV_SYS_NETBSD && !CENV_SYS_FREEBSD
/* NetBSD no longer seems to support this */
#elif KLH10_NET_TAP_BRIDGE
/* If we do tap(4) + bridge(4), the ether address of the tap is wholly
* irrelevant, it is on the other side of the "wire".
* Our own address is something we can make up completely.
*/
if (emhost_ea.ea_octets[5] == 0xFF) {
time_t t = time(NULL);
emhost_ea.ea_octets[5] = t & 0xFE;
emhost_ea.ea_octets[4] = (t >> 8) & 0xFF;
emhost_ea.ea_octets[3] = (t >> 16) & 0xFF;
}
ea_set(eap, &emhost_ea); /* Return the ether address */
#elif (KLH10_NET_BPF && !CENV_SYS_NETBSD && !CENV_SYS_FREEBSD)
/* NetBSD no longer seems to support this (on bpf) */
struct ifreq ifr;
strncpy(ifr.ifr_name, ifnam, sizeof(ifr.ifr_name));
@@ -1131,7 +1169,7 @@ osn_ifeaset(int s, /* Socket for (AF_INET, SOCK_DGRAM, 0) */
char *ifnam, /* Interface name */
unsigned char *newpa) /* New ether address */
{
#if CENV_SYS_DECOSF || CENV_SYS_LINUX \
#if CENV_SYS_DECOSF || CENV_SYS_LINUX || KLH10_NET_TAP_BRIDGE \
|| (CENV_SYS_FREEBSD && defined(SIOCSIFLLADDR))
/* Common preamble code */
@@ -1190,6 +1228,8 @@ osn_ifeaset(int s, /* Socket for (AF_INET, SOCK_DGRAM, 0) */
if (ownsock) close(s);
return FALSE;
}
# elif KLH10_NET_TAP_BRIDGE
ea_set(&emhost_ea, newpa);
# else
# error "Unimplemented OS routine osn_ifeaset()"
# endif
@@ -1338,6 +1378,7 @@ pfopen(void)
}
#endif /* KLH10_NET_PFLT || KLH10_NET_BPF */
#if KLH10_NET_PFLT
@@ -1974,6 +2015,212 @@ osn_pfinit(struct osnpf *osnpf, void *arg)
}
#endif /* KLH10_NET_NIT */
/*
* Too bad that this is never called...
*/
osn_pfdeinit()
{
#if KLH10_NET_TAP_BRIDGE
void tap_bridge_close();
tap_bridge_close();
#endif
}
#if KLH10_NET_TAP_BRIDGE
osn_pfinit(register struct osnpf *osnpf, void *arg)
{
int fd;
char *ifnam = osnpf->osnpf_ifnam;
/* No "default interface" concept here */
if (!ifnam || !ifnam[0])
esfatal(1, "Packetfilter interface must be specified");
fd = tap_bridge_open(ifnam);
/* Now get our fresh new virtual interface's ethernet address.
*/
(void) osn_pfeaget(fd, ifnam, (unsigned char *)&(osnpf->osnpf_ea));
return fd;
}
#include <net/if_tap.h>
#include <net/if_bridgevar.h>
#include <stdint.h>
static struct ifreq br_ifr;
static struct ifreq tap_ifr;
static int my_tap;
/*
* A TAP is a virtual ethernet interface, much like TUN is a virtual IP
* interface. We can use it to inject packets into the Unix input stream,
* provided it is UP and the host side has a matching IP address and
* netmask (also much like TUN), or that it is bridged to another interface.
*
* Here we try to create the user-given interface and then bridge it to
* the "default" interface. This is probably the most common configuration.
* If something else is desired, the user can set up the tap herself,
* and we'll just use it as it is. This is useful for a routed approach,
* for instance.
*/
int
tap_bridge_open(char *ifnam)
{
int tapfd;
int res;
union ipaddr netmask;
char cmdbuff[128];
struct ifent *ife;
int s;
int i;
struct ifbreq br_req;
struct ifdrv br_ifd;
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
esfatal(1, "tap_bridge_open: socket() failed");
}
/* try to create tapN as specified by the user */
memset(&tap_ifr, 0, sizeof(tap_ifr));
strcpy(tap_ifr.ifr_name, ifnam);
res = ioctl(s, SIOCIFCREATE, &tap_ifr);
if (res == 0) {
my_tap = 1;
dbprintln("Created host-side tap \"%s\"", ifnam);
} else {
if (errno != EEXIST)
esfatal(1, "tap_bridge_open: can't create tap \"%s\"?", ifnam);
my_tap = 0;
dbprintln("Host-side tap \"%s\" alread exists; use it as-is", ifnam);
}
sprintf(cmdbuff, "/dev/%s", ifnam);
tapfd = open(cmdbuff, O_RDWR, 0);
if (tapfd < 0) {
/* Note possible error meanings:
ENOENT - no such filename
ENXIO - not configured in kernel
*/
esfatal(1, "Couldn't find or open 10-side tap \"%s\"", cmdbuff);
}
dbprintln("Opened 10-side tap \"%s\"", cmdbuff);
/* Finally, turn on IFF_UP just in case the above didn't do it.
Note interface name is still there from the SIOCIFCREATE.
*/
if (ioctl(s, SIOCGIFFLAGS, &tap_ifr) < 0) {
esfatal(1, "tap_bridge_open tap SIOCGIFFLAGS failed");
}
if (!(tap_ifr.ifr_flags & IFF_UP)) {
tap_ifr.ifr_flags |= IFF_UP;
if (ioctl(s, SIOCSIFFLAGS, &tap_ifr) < 0) {
esfatal(1, "tap_bridge_open tap SIOCSIFFLAGS failed");
}
if (DP_DBGFLG)
dbprint("tap_bridge_open tap did SIOCSIFFLAGS");
}
if (my_tap) {
for (i = 0; i < 1000; i++) {
/* try to create bridge%d */
memset(&br_ifr, 0, sizeof(br_ifr));
sprintf(br_ifr.ifr_name, "bridge%d", i);
res = ioctl(s, SIOCIFCREATE, &br_ifr);
if (res == 0)
break;
if (errno != EEXIST)
esfatal(1, "tap_bridge_open: can't create bridge \"%s\"?", br_ifr.ifr_name);
}
dbprintln("Created bridge \"%s\"", br_ifr.ifr_name);
/*
* Find default IP interface to bridge with.
* It might find the wrong one if there is more than one.
*/
ife = osn_ipdefault();
if (!ife)
esfatal(0, "Couldn't find default interface");
if (swstatus)
dbprintln("Bridging with default interface \"%s\"", ife->ife_name);
if (1) {
sprintf(cmdbuff, "/sbin/brconfig %s add %s add %s up",
br_ifr.ifr_name, ife->ife_name, ifnam);
res = system(cmdbuff);
dbprintln("%s => %d", cmdbuff, res);
} else {
/* do whatever brconfig bridge0 add intf0 does... */
memset(&br_ifd, 0, sizeof(br_ifd));
memset(&br_req, 0, sizeof(br_req));
/* set name of the bridge */
strcpy(br_ifd.ifd_name, br_ifr.ifr_name);
br_ifd.ifd_cmd = BRDGADD;
br_ifd.ifd_len = sizeof(br_req);
br_ifd.ifd_data = &br_req;
/* brconfig bridge0 add tap0 (the virtual interface) */
strcpy(br_req.ifbr_ifsname, ifnam);
res = ioctl(s, SIOCSDRVSPEC, &br_ifd);
if (res == -1)
esfatal(1, "tap_bridge_open: can't add virtual intf to bridge?");
/* brconfig bridge0 add vr0 (the hardware interface) */
strcpy(br_req.ifbr_ifsname, ife->ife_name);
res = ioctl(s, SIOCSDRVSPEC, &br_ifd);
if (res == -1)
esfatal(1, "tap_bridge_open: can't add real intf to bridge?");
/* Finally, turn on IFF_UP just in case the above didn't do it.
* Note interface name is still there.
*/
if (ioctl(s, SIOCGIFFLAGS, &br_ifr) < 0) {
esfatal(1, "tap_bridge_open bridge SIOCGIFFLAGS failed");
}
if (!(br_ifr.ifr_flags & IFF_UP)) {
br_ifr.ifr_flags |= IFF_UP;
if (ioctl(s, SIOCSIFFLAGS, &br_ifr) < 0) {
esfatal(1, "tap_bridge_open bridge SIOCSIFFLAGS failed");
}
if (DP_DBGFLG)
dbprint("tap_bridge_open bridge did SIOCSIFFLAGS");
}
}
}
close(s);
return tapfd; /* Success! */
}
void
tap_bridge_close()
{
if (my_tap) {
int s, res;
struct ifreq tap_ifr;
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
esfatal(1, "tap_bridge_close: socket() failed");
}
/* Destroy bridge */
res = ioctl(s, SIOCIFDESTROY, &br_ifr);
res = ioctl(s, SIOCIFDESTROY, &tap_ifr);
close(s);
}
}
#endif /* KLH10_NET_TAP_BRIDGE */
#if KLH10_NET_DLPI
/* DLPI packetfilter initialization */

File diff suppressed because it is too large Load Diff

View File

@@ -59,6 +59,9 @@
#ifndef KLH10_NET_DLPI /* Solaris Data Link Provider Interface */
# define KLH10_NET_DLPI 0
#endif
#ifndef KLH10_NET_TAP_BRIDGE /* BSD Ethernet Tunnel device + a bridge */
# define KLH10_NET_TAP_BRIDGE 0
#endif
#ifndef KLH10_NET_TUN /* BSD IP Tunnel device */
# define KLH10_NET_TUN 0
#endif
@@ -67,14 +70,18 @@
#endif
#if !(KLH10_NET_NIT || KLH10_NET_DLPI || KLH10_NET_BPF || KLH10_NET_PFLT || \
KLH10_NET_TUN || KLH10_NET_LNX)
KLH10_NET_TUN || KLH10_NET_LNX || KLH10_NET_TAP_BRIDGE)
/* None explicitly specified, pick a reasonable default */
# if ((CENV_SYS_FREEBSD || CENV_SYS_LINUX) && OSN_USE_IPONLY)
# if ((CENV_SYS_NETBSD || CENV_SYS_FREEBSD || CENV_SYS_LINUX) && OSN_USE_IPONLY)
# undef KLH10_NET_TUN
# define KLH10_NET_TUN 1
# elif (CENV_SYS_NETBSD || CENV_SYS_FREEBSD)
# undef KLH10_NET_BPF
# define KLH10_NET_BPF 1
/*
* # undef KLH10_NET_BPF
* # define KLH10_NET_BPF 1
*/
# undef KLH10_NET_TAP_BRIDGE
# define KLH10_NET_TAP_BRIDGE 1
# elif CENV_SYS_DECOSF
# undef KLH10_NET_PFLT
# define KLH10_NET_PFLT 1

View File

@@ -44,6 +44,7 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* For strrchr */
#include "klh10.h"

File diff suppressed because it is too large Load Diff

View File

@@ -243,7 +243,7 @@ long sw_recskip = 0;
long sw_fileskip = 0;
rsiz_t sw_bothsiz = 0;
char *sw_logpath = NULL;
FILE *logf = NULL;
FILE *logfile = NULL;
struct dev {
char *d_pname; /* Print name, "In" or "Out" */
@@ -363,7 +363,7 @@ os_strerror(int err)
void errhan(void *arg, struct vmtape *t, char *s)
{
fprintf(logf, "; %s: %s\n", t->mt_devname, s);
fprintf(logfile, "; %s: %s\n", t->mt_devname, s);
}
@@ -371,7 +371,7 @@ void efatal(char *errmsg) /* print error message and exit */
/* error message string */
{
fflush(stdout);
fprintf(logf, "\n?%s\n",errmsg);
fprintf(logfile, "\n?%s\n",errmsg);
exit(1);
}
@@ -384,7 +384,7 @@ main(int argc, char **argv)
register struct dev *d;
int ret;
logf = stderr;
logfile = stderr;
signal(SIGINT, exit); /* Allow int to terminate log files etc */
vmt_init(&dvi.d_vmt, "TapeIn");
@@ -399,11 +399,11 @@ main(int argc, char **argv)
if (!sw_logpath)
logf = stderr;
logfile = stderr;
else {
if ((logf = fopen(sw_logpath, "w")) == NULL) {
logf = stderr;
fprintf(logf, "; Cannot open log file \"%s\", using stderr.\n",
if ((logfile = fopen(sw_logpath, "w")) == NULL) {
logfile = stderr;
fprintf(logfile, "; Cannot open log file \"%s\", using stderr.\n",
sw_logpath);
}
}
@@ -420,26 +420,26 @@ main(int argc, char **argv)
if (!dvo.d_recsiz) dvo.d_recsiz = sw_bothsiz;
if (sw_verbose) {
#define LOGTAPE(d,name) \
fprintf(logf, "; %s tape spec \"%s\" (Type: %s", \
fprintf(logfile, "; %s tape spec \"%s\" (Type: %s", \
name, (d).d_path, mtypstr[(d).d_istape]); \
if ((d).d_istape == MTYP_VIRT) \
fprintf(logf, " format: %s", vmt_fmtname((d).d_vfmt)); \
fprintf(logf, ")\n")
fprintf(logfile, " format: %s", vmt_fmtname((d).d_vfmt)); \
fprintf(logfile, ")\n")
LOGTAPE(dvi, " Input");
LOGTAPE(dvo, "Output");
#undef LOGTAPE
if (dvi.d_recsiz)
fprintf(logf, "; Input record size %ld\n", (long)dvi.d_recsiz);
fprintf(logfile, "; Input record size %ld\n", (long)dvi.d_recsiz);
if (dvo.d_recsiz)
fprintf(logf, "; Output record size %ld\n", (long)dvo.d_recsiz);
fprintf(logfile, "; Output record size %ld\n", (long)dvo.d_recsiz);
if (sw_maxfile)
fprintf(logf, "; Max tapemarks (files) to process: %ld\n", sw_maxfile);
fprintf(logfile, "; Max tapemarks (files) to process: %ld\n", sw_maxfile);
if (sw_maxrec)
fprintf(logf, "; Max records to process: %ld\n", sw_maxrec);
fprintf(logfile, "; Max records to process: %ld\n", sw_maxrec);
if (sw_logpath)
fprintf(logf, "; Using logging path %s\n", sw_logpath);
fprintf(logfile, "; Using logging path %s\n", sw_logpath);
}
/* Open I/O files as appropriate */
@@ -472,25 +472,25 @@ main(int argc, char **argv)
/* Do it! */
fprintf(logf, "; Copying from \"%s\" to \"%s\"...\n", dvi.d_path,
fprintf(logfile, "; Copying from \"%s\" to \"%s\"...\n", dvi.d_path,
dvo.d_path ? dvo.d_path : NULLDEV);
if (!docopy()) {
fprintf(logf, "; Stopped unexpectedly.\n");
fprintf(logfile, "; Stopped unexpectedly.\n");
ret = FALSE;
}
if (!devclose(&dvo)) {
fprintf(logf, "; Error closing output.\n");
fprintf(logfile, "; Error closing output.\n");
ret = FALSE;
}
for (d = &dvi; d; d = (d == &dvi) ? &dvo : NULL) {
if (d->d_istape)
fprintf(logf, "; %3s: %ld+%ld errs, %ld files, %ld recs, %"
fprintf(logfile, "; %3s: %ld+%ld errs, %ld files, %ld recs, %"
VMTAPE_POS_FMT "d bytes\n",
d->d_pname, d->mta_herr, d->mta_serr,
d->d_files, d->d_recs, d->d_tloc);
}
fclose(logf);
fclose(logfile);
exit(ret ? 0 : 1);
}
@@ -537,7 +537,7 @@ int docopy(void)
if (vmt_framecnt(&dvi.d_vmt)) {
if (!devwrite(&dvo, dvi.d_buff,
(rsiz_t)vmt_framecnt(&dvi.d_vmt))) {
fprintf(logf, "; Stopped due to output write error: %s\n",
fprintf(logfile, "; Stopped due to output write error: %s\n",
os_strerror(-1));
ret = FALSE;
break;
@@ -576,7 +576,7 @@ int docopy(void)
}
if (err < 0) {
fprintf(logf, "; Stopped due to input read error: %s\n",
fprintf(logfile, "; Stopped due to input read error: %s\n",
os_strerror(-1));
ret = FALSE;
}
@@ -603,11 +603,11 @@ do_tdtest(void)
char *errstr = NULL;
if (!dvi.d_cpath) {
fprintf(logf, "; No input tape directory specified\n");
fprintf(logfile, "; No input tape directory specified\n");
return 1;
}
if (!dvo.d_cpath) {
fprintf(logf, "; No output tape directory specified\n");
fprintf(logfile, "; No output tape directory specified\n");
return 1;
}
@@ -629,7 +629,7 @@ do_tdtest(void)
}
if (errstr) {
fprintf(logf,"; Problem with tape desc file \"%s\": %s\n",
fprintf(logfile,"; Problem with tape desc file \"%s\": %s\n",
dvi.d_cpath, errstr);
return 1;
}
@@ -638,7 +638,7 @@ do_tdtest(void)
if (strcmp(dvo.d_cpath, "") == 0) {
tdof = stdout;
} else if ((tdof = fopen(dvo.d_cpath, "w")) == NULL) {
fprintf(logf,"Cannot open tape desc file \"%s\": %s\n",
fprintf(logfile,"Cannot open tape desc file \"%s\": %s\n",
dvo.d_cpath, os_strerror(-1));
return FALSE;
}
@@ -880,7 +880,7 @@ int devopen(register struct dev *d, int wrtf)
strncpy(v.vmta_datpath, d->d_rpath, sizeof(v.vmta_datpath));
}
if (!vmt_attrmount(&d->d_vmt, &v)) { /* Try mounting it */
fprintf(logf, "; Couldn't mount %sput virtual tape: %s\n",
fprintf(logfile, "; Couldn't mount %sput virtual tape: %s\n",
d->d_pname, d->d_path);
return FALSE;
}
@@ -898,7 +898,7 @@ int devopen(register struct dev *d, int wrtf)
char *s;
rpath = malloc(strlen(d->d_path)+4+1);
if (!rpath) {
fprintf(logf, "; Cannot malloc data filename\n");
fprintf(logfile, "; Cannot malloc data filename\n");
return FALSE;
}
strcpy(rpath, d->d_path);
@@ -915,7 +915,7 @@ int devopen(register struct dev *d, int wrtf)
** the tapedesc or rawdata path was explicitly given.
*/
if (!vmt_xmount(&(d->d_vmt), d->d_cpath, d->d_rpath, wrtf)) {
fprintf(logf, "; Couldn't mount %sput virtual tape: %s\n",
fprintf(logfile, "; Couldn't mount %sput virtual tape: %s\n",
d->d_pname, d->d_path);
return FALSE;
}
@@ -937,7 +937,7 @@ int devopen(register struct dev *d, int wrtf)
if (strcmp(d->d_rpath, "") == 0) {
d->d_fd = wrtf ? FD_STDOUT : FD_STDIN;
} else if (!os_mtopen(d, wrtf)) {
fprintf(logf, "; Cannot open %sput: %s\n",
fprintf(logfile, "; Cannot open %sput: %s\n",
d->d_pname, os_strerror(-1));
return FALSE;
}
@@ -962,27 +962,27 @@ int devopen(register struct dev *d, int wrtf)
if (d->d_cpath) {
if (!(d->d_vmt.mt_filename = dupcstr(d->d_cpath))) {
fprintf(logf, "; malloc failed for cpath dupcstr\n");
fprintf(logfile, "; malloc failed for cpath dupcstr\n");
return FALSE;
}
if (strcmp(d->d_cpath, "") == 0) {
d->d_vmt.mt_ctlf = (wrtf ? stdout : stdin);
} else if ((d->d_vmt.mt_ctlf =
fopen(d->d_cpath, (wrtf ? "w" : "r"))) == NULL) {
fprintf(logf,"Cannot open tape desc file \"%s\": %s\n",
fprintf(logfile,"Cannot open tape desc file \"%s\": %s\n",
d->d_cpath, os_strerror(-1));
return FALSE;
}
/* Tape-desc file open, now parse it if reading */
if (!wrtf && !tdr_scan(&(d->d_vmt), d->d_vmt.mt_ctlf, d->d_cpath)) {
fprintf(logf, "; Cannot parse tape desc\n");
fprintf(logfile, "; Cannot parse tape desc\n");
return FALSE;
}
/* Do final setup if writing */
if (wrtf && d->d_rpath) {
if (!(d->d_vmt.mt_datpath = dupcstr(d->d_rpath))) {
fprintf(logf, "; malloc failed for rpath dupcstr\n");
fprintf(logfile, "; malloc failed for rpath dupcstr\n");
return FALSE;
}
}
@@ -997,7 +997,7 @@ int devopen(register struct dev *d, int wrtf)
if (d->d_blen <= d->d_recsiz) /* If it's bigger, */
d->d_blen = d->d_recsiz; /* adjust quietly */
else /* else warn user */
fprintf(logf, "; Tapedir forcing larger %sput record size (%ld instead of %ld)\n",
fprintf(logfile, "; Tapedir forcing larger %sput record size (%ld instead of %ld)\n",
d->d_pname, (long)d->d_blen, (long)d->d_recsiz);
}
@@ -1029,7 +1029,7 @@ int devbuffer(struct dev *d, char *buffp, rsiz_t blen)
*/
blen = (blen + 511) & ~511; /* Relies on fact 512 is power of 2 */
if ((buffp = malloc(blen)) == NULL) {
fprintf(logf, "; Cannot malloc %sput buffer (size %ld)\n",
fprintf(logfile, "; Cannot malloc %sput buffer (size %ld)\n",
d->d_pname, blen);
return FALSE;
}
@@ -1091,7 +1091,7 @@ int devread(struct dev *d)
/* Still to do? Handle dir-only case, plus dir+dev case? */
ret = os_mtread(d); /* Attempt read from device */
if (ret < 0) {
fprintf(logf, "; %sput device read error: %s\n",
fprintf(logfile, "; %sput device read error: %s\n",
d->d_pname, os_strerror(-1));
return ret;
}
@@ -1161,7 +1161,7 @@ int devwerr(struct dev *d, int err)
if (d->d_cpath) { /* Have tapedir? */
if (!td_recapp(&d->d_vmt.mt_tdr, (long)0, 0, err)) {
fprintf(logf, "devwerr: td_recapp malloc failed");
fprintf(logfile, "devwerr: td_recapp malloc failed");
return FALSE;
}
@@ -1178,7 +1178,7 @@ int devweof(struct dev *d)
else {
if (d->d_cpath) { /* Have tapedir? */
if (!td_recapp(&d->d_vmt.mt_tdr, (long)0, 1, 0)) {
fprintf(logf, "devweof: td_recapp malloc failed");
fprintf(logfile, "devweof: td_recapp malloc failed");
ret = FALSE;
}
}
@@ -1276,7 +1276,7 @@ int os_mtread(struct dev *dp)
acs[1] = dp->d_fd;
acs[2] = (int)&iov;
if (jsys(DUMPI, acs) > 0) {
fprintf(logf, "; Warning: DUMPI won for max rec size %ld!\n",
fprintf(logfile, "; Warning: DUMPI won for max rec size %ld!\n",
(long)dp->d_blen);
dp->mta_frms = dp->d_blen;
return 1;
@@ -1287,14 +1287,14 @@ int os_mtread(struct dev *dp)
case monsym("IOX5"): /* Device or data error (rec length) */
acs[1] = dp->d_fd;
if (jsys(GDSTS, acs) <= 0) {
fprintf(logf, "; Tape GDSTS%% error: %s\n", os_strerror(-1));
fprintf(logfile, "; Tape GDSTS%% error: %s\n", os_strerror(-1));
os_mtclrerr(dp->d_fd);
dp->mta_herr++;
return 0;
}
break;
default:
fprintf(logf, "; Tape DUMPI%% error: %s\n", os_strerror(-1));
fprintf(logfile, "; Tape DUMPI%% error: %s\n", os_strerror(-1));
os_mtclrerr(dp->d_fd);
dp->mta_herr++;
return 0;
@@ -1302,7 +1302,7 @@ int os_mtread(struct dev *dp)
/* Analyze "error". acs[2] has flags, [3] has count in LH */
flgs = acs[2];
t20status(dp, logf, flgs, acs[3]);
t20status(dp, logfile, flgs, acs[3]);
dp->mta_frms = ((unsigned)acs[3]) >> 18; /* Find cnt of data */
/* Opening in industry-compatible mode apparently works to force use of
@@ -1310,7 +1310,7 @@ int os_mtread(struct dev *dp)
/* dp->mta_frms *= sizeof(int); */
os_mtclrerr(dp->d_fd);
if (flgs & (MT_DVE|MT_DAE)) {
fprintf(logf, "; Tape error: %s\n",
fprintf(logfile, "; Tape error: %s\n",
(flgs & MT_DVE) ? "Device" : "Data");
dp->mta_serr++;
continue; /* Try again */
@@ -1339,14 +1339,14 @@ int os_mtread(struct dev *dp)
if (dp->mta_frms <= 0) {
case -1: /* Error */
dp->mta_serr++;
fprintf(logf, "; Tape read error: %s\n", os_strerror(-1));
os_mtstatus(dp, logf); /* Show full status */
fprintf(logfile, "; Tape read error: %s\n", os_strerror(-1));
os_mtstatus(dp, logfile); /* Show full status */
if (retry <= 0) {
if (os_mtfsr(dp)) { /* Try spacing over 1 rec */
retry = dp->mta_retry;
dp->mta_herr++;
} else {
fprintf(logf, "; Cannot proceed past read error, aborting...\n");
fprintf(logfile, "; Cannot proceed past read error, aborting...\n");
return -1;
}
}
@@ -1365,7 +1365,7 @@ int os_mtread(struct dev *dp)
}
} else
if (dp->mta_frms >= dp->d_blen)
fprintf(logf, "; Warning: read max rec size %ld!\n",
fprintf(logfile, "; Warning: read max rec size %ld!\n",
dp->mta_frms);
@@ -1397,7 +1397,7 @@ int os_mtwrite(struct dev *dp)
}
/* Error return */
dp->mta_serr++;
fprintf(logf, "; Tape DUMPO%% error: %s\n", os_strerror(-1));
fprintf(logfile, "; Tape DUMPO%% error: %s\n", os_strerror(-1));
os_mtclrerr(dp->d_fd);
dp->mta_herr++;
return 0;
@@ -1415,10 +1415,10 @@ int os_mtwrite(struct dev *dp)
if (dp->d_istape == MTYP_QIC) {
full = (used + 0777) & ~0777; /* Round up to 512-byte boundary */
if (used < dp->d_recsiz)
fprintf(logf, "; Warning: partial record padded out (%ld => %ld)\n",
fprintf(logfile, "; Warning: partial record padded out (%ld => %ld)\n",
(long)used, (long)full);
if (full > dp->d_blen) {
fprintf(logf, "; Internal bug: padout exceeds buffer (%ld > %ld)\n",
fprintf(logfile, "; Internal bug: padout exceeds buffer (%ld > %ld)\n",
(long)full, (long)dp->d_blen);
full = dp->d_blen;
}
@@ -1437,12 +1437,12 @@ int os_mtwrite(struct dev *dp)
}
/* Error of some kind */
dp->mta_serr++;
fprintf(logf, "; (Rec %ld, try %d) ",
fprintf(logfile, "; (Rec %ld, try %d) ",
dp->d_recs, dp->mta_retry - retry);
if (ret < 0) {
fprintf(logf, "Tape write error: %s\n", os_strerror(-1));
fprintf(logfile, "Tape write error: %s\n", os_strerror(-1));
} else {
fprintf(logf, "Tape write truncated: %d, shd be %ld\n",
fprintf(logfile, "Tape write truncated: %d, shd be %ld\n",
ret, (long)used);
if (ret > 0) {
used -= ret; /* Update to write out rest */
@@ -1452,7 +1452,7 @@ int os_mtwrite(struct dev *dp)
dp->mta_frms += ret;
}
}
os_mtstatus(dp, logf); /* Show full status */
os_mtstatus(dp, logfile); /* Show full status */
} while (--retry > 0); /* Continue N times */
dp->mta_herr++;
#endif
@@ -1471,7 +1471,7 @@ int os_mtweof(struct dev *dp) /* Write a tapemark */
mtcmd.mt_op = MTWEOF;
mtcmd.mt_count = 1;
if (ioctl(dp->d_fd, MTIOCTOP, &mtcmd) < 0) {
fprintf(logf, "; MTWEOF ioctl failed: %s\n", os_strerror(-1));
fprintf(logfile, "; MTWEOF ioctl failed: %s\n", os_strerror(-1));
dp->mta_herr++;
return FALSE;
}
@@ -1491,7 +1491,7 @@ int os_mtfsr(struct dev *dp) /* Forward Space Record (to inter-record gap)*/
mtcmd.mt_op = MTFSR;
mtcmd.mt_count = 1;
if (ioctl(dp->d_fd, MTIOCTOP, &mtcmd) < 0) {
fprintf(logf, "; MTFSR ioctl failed: %s\n", os_strerror(-1));
fprintf(logfile, "; MTFSR ioctl failed: %s\n", os_strerror(-1));
dp->mta_herr++;
return FALSE;
}
@@ -1546,7 +1546,7 @@ void os_mtstatus(struct dev *dp, FILE *f)
return;
}
fprintf(f, "; Status for magtape %s:\n", dp->d_path);
fprintf(f, "; Type: %#x (vals in sys/mtio.h)\n", mtstatb.mt_type);
fprintf(f, "; Type: %#x (vals in sys/mtio.h)\n", (int)mtstatb.mt_type);
# if CENV_SYS_SUN
fprintf(f, "; Flags: %#o ->", mtstatb.mt_flags);
if (mtstatb.mt_flags & MTF_SCSI) fprintf(f, " SCSI");
@@ -1556,8 +1556,8 @@ void os_mtstatus(struct dev *dp, FILE *f)
fprintf(f, "; Optim blkfact: %d\n", mtstatb.mt_bf);
# endif
fprintf(f, "; Drive status: %#o (dev dep)\n", mtstatb.mt_dsreg);
fprintf(f, "; Error status: %#o (dev dep)\n", mtstatb.mt_erreg);
fprintf(f, "; Drive status: %#o (dev dep)\n", (int)mtstatb.mt_dsreg);
fprintf(f, "; Error status: %#o (dev dep)\n", (int)mtstatb.mt_erreg);
fprintf(f, "; Err - Cnt left: %ld\n", (long)mtstatb.mt_resid);
# if CENV_SYS_SUN
fprintf(f, "; Err - File num: %ld\n", (long)mtstatb.mt_fileno);

View File

@@ -97,7 +97,7 @@ main(int argc, char **argv)
switch (arg[1]) {
case 'v': swverb = 1; break;
default:
fprintf(stderr, usage);
fprintf(stderr, usage, argv[0]);
exit(1);
}
}

View File

@@ -130,7 +130,7 @@ int sw_verbose;
int sw_maxsec;
int sw_maxfile;
char *sw_logpath;
FILE *logf;
FILE *logfile;
#define DBGFLG sw_verbose
@@ -244,7 +244,7 @@ os_strerror(int err)
void errhan(struct vdk_unit *t, char *s)
{
fprintf(logf, "; %s: %s\n", t->dk_devname, s);
fprintf(logfile, "; %s: %s\n", t->dk_devname, s);
}
@@ -252,7 +252,7 @@ void efatal(char *errmsg) /* print error message and exit */
/* error message string */
{
fflush(stdout);
fprintf(logf, "\n?%s\n",errmsg);
fprintf(logfile, "\n?%s\n",errmsg);
exit(1);
}
@@ -262,7 +262,7 @@ main(int argc, char **argv)
{
int ret;
logf = stderr;
logfile = stderr;
signal(SIGINT, exit); /* Allow int to terminate log files etc */
dvi.d_fmt = dvo.d_fmt = -1;
@@ -272,11 +272,11 @@ main(int argc, char **argv)
if (!sw_logpath)
logf = stderr;
logfile = stderr;
else {
if ((logf = fopen(sw_logpath, "w")) == NULL) {
logf = stderr;
fprintf(logf, "; Cannot open log file \"%s\", using stderr.\n",
if ((logfile = fopen(sw_logpath, "w")) == NULL) {
logfile = stderr;
fprintf(logfile, "; Cannot open log file \"%s\", using stderr.\n",
sw_logpath);
}
}
@@ -287,23 +287,23 @@ main(int argc, char **argv)
dvi.d_dcf.dcf_ntrk *
dvi.d_dcf.dcf_ncyl;
if (sw_verbose) {
fprintf(logf, "; Input disk spec \"%s\" (Type: %s) Format: %s\n",
fprintf(logfile, "; Input disk spec \"%s\" (Type: %s) Format: %s\n",
dvi.d_path, mtypstr[dvi.d_isdisk],
fmttab[dvi.d_fmt]);
fprintf(logf, "; Output disk spec \"%s\" (Type: %s) Format: %s\n",
fprintf(logfile, "; Output disk spec \"%s\" (Type: %s) Format: %s\n",
dvo.d_path, mtypstr[dvo.d_isdisk],
fmttab[dvo.d_fmt]);
/* Show config info here */
fprintf(logf, "; Drive type: %s\n", dvi.d_dcf.dcf_name);
fprintf(logf, "; %ld sectors, %d wds/sec\n", dvi.d_totsec,
fprintf(logfile, "; Drive type: %s\n", dvi.d_dcf.dcf_name);
fprintf(logfile, "; %ld sectors, %d wds/sec\n", dvi.d_totsec,
dvi.d_dcf.dcf_nwds);
fprintf(logf, "; (%d secs, %d trks, %d cyls\n",
fprintf(logfile, "; (%d secs, %d trks, %d cyls\n",
dvi.d_dcf.dcf_nsec,
dvi.d_dcf.dcf_ntrk,
dvi.d_dcf.dcf_ncyl);
if (sw_logpath)
fprintf(logf, "; Using logging path %s\n", sw_logpath);
fprintf(logfile, "; Using logging path %s\n", sw_logpath);
}
/* Open I/O files as appropriate */
@@ -313,27 +313,27 @@ main(int argc, char **argv)
exit(1);
/* Do it! */
fprintf(logf, "; Copying from \"%s\" to \"%s\"...\n", dvi.d_path,
fprintf(logfile, "; Copying from \"%s\" to \"%s\"...\n", dvi.d_path,
dvo.d_path ? dvo.d_path : NULLDEV);
if (ret = docopy())
ret = devclose(&dvo);
else (void) devclose(&dvo);
if (!ret) fprintf(logf, "; Stopped unexpectedly.\n");
if (!ret) fprintf(logfile, "; Stopped unexpectedly.\n");
#if 0
{
register struct devdk *d;
for (d = &dvi; d; d = (d == &dvi) ? &dvo : NULL) {
if (d->d_isdisk)
fprintf(logf, "; %s: %d+%d errs, %d secs, %ld bytes\n",
fprintf(logfile, "; %s: %d+%d errs, %d secs, %ld bytes\n",
d->d_pname, d->mta_herr, d->mta_serr,
d->d_secs, d->d_tloc);
}
}
#endif
fclose(logf);
fclose(logfile);
exit(ret ? 0 : 1);
}
@@ -347,13 +347,13 @@ int docopy(void)
int nwrt = 0;
if (DBGFLG)
fprintf(logf, "; Pages:\n");
fprintf(logfile, "; Pages:\n");
for (; nsect <= dvi.d_totsec;) {
err = devread(&dvi, nsect, wbuff); /* Get a sector */
if (!err) {
fprintf(logf, "; Aborting loop, last err: %s\n", os_strerror(-1));
fprintf(logfile, "; Aborting loop, last err: %s\n", os_strerror(-1));
return 0;
}
@@ -366,7 +366,7 @@ int docopy(void)
nwrt++;
err = devwrite(&dvo, nsect, wbuff); /* Write a sector */
if (!err) {
fprintf(logf, "; Aborting loop, last err: %s\n",
fprintf(logfile, "; Aborting loop, last err: %s\n",
os_strerror(-1));
return 0;
}
@@ -377,14 +377,14 @@ int docopy(void)
/* Hack to show nice pattern, one char per 4-sector page */
if (DBGFLG) {
if ((nsect & 03) == 0) {
putc(pagsym[nwrt&03], logf);
putc(pagsym[nwrt&03], logfile);
nwrt = 0;
}
}
}
if (DBGFLG)
fprintf(logf, "\n");
fprintf(logfile, "\n");
return TRUE;
}
@@ -515,7 +515,7 @@ int devopen(register struct devdk *d, int wrtf)
char *opath, *path;
if (!(opath = d->d_path) || !*opath) {
fprintf(logf, "; Null mount path\n");
fprintf(logfile, "; Null mount path\n");
return FALSE;
}
path = malloc(strlen(opath)+1);
@@ -532,7 +532,7 @@ int devopen(register struct devdk *d, int wrtf)
d->d_vdk.dk_nwds = d->d_dcf.dcf_nwds;
if (!vdk_mount(&(d->d_vdk), path, wrtf)) {
fprintf(logf, "; Cannot mount device \"%s\": %s\n",
fprintf(logfile, "; Cannot mount device \"%s\": %s\n",
path, os_strerror(d->d_vdk.dk_err));
free(path);
return FALSE;
@@ -547,7 +547,7 @@ int devclose(struct devdk *d)
int res = TRUE;
if (DBGFLG && d->d_path)
fprintf(logf, "; Closing \"%s\"\n", d->d_path);
fprintf(logfile, "; Closing \"%s\"\n", d->d_path);
if (d->d_isdisk) {
res = vdk_unmount(&(d->d_vdk)); /* Close real disk */
@@ -570,14 +570,14 @@ int devread(struct devdk *d, long int daddr, w10_t *buff)
#if 0
if (DBGFLG)
fprintf(logf, "; read daddr=%ld\n", daddr);
fprintf(logfile, "; read daddr=%ld\n", daddr);
#endif
nsec = vdk_read(&d->d_vdk, buff, (uint32)daddr, 1);
if (d->d_vdk.dk_err
|| (nsec != 1)) {
fprintf(logf, "; read error on %s: %s\n",
fprintf(logfile, "; read error on %s: %s\n",
d->d_vdk.dk_filename, os_strerror(d->d_vdk.dk_err));
return FALSE;
}
@@ -592,14 +592,14 @@ int devwrite(struct devdk *d, long int daddr, w10_t *buff)
#if 0
if (DBGFLG)
fprintf(logf, "; write daddr=%ld\n", daddr);
fprintf(logfile, "; write daddr=%ld\n", daddr);
#endif
nsec = vdk_write(&d->d_vdk, buff, (uint32)daddr, 1);
if (d->d_vdk.dk_err
|| (nsec != 1)) {
fprintf(logf, "; write error on %s: %s\n",
fprintf(logfile, "; write error on %s: %s\n",
d->d_vdk.dk_filename, os_strerror(d->d_vdk.dk_err));
return FALSE;
}

View File

@@ -84,7 +84,7 @@ main(int argc, char **argv)
w10_t w;
if (argc != 2 || strlen(typestr = argv[1]) != 3) {
fprintf(stderr, usage);
fprintf(stderr, "%s", usage);
exit(1);
}
if (typestr[0] != '-'