Description of NXSYS scenario definition language.

Copyright (c) Bernard S. Greenberg 1994, 1995, 1996, 1997
18 June 1995 (upd: 10 November 1996, 2 February 1997. 19 Feb 97, 18 Nov1997,
2 Dec97.

This file provides the barest information about the language used
with NXSYS to define track scenarios and interlockings. Using
this language, and looking at the supplied example(s), you should
be able to define your own layouts pretty easily.

However, making the signals and switches actually work is not so
easy: one must design all the signal circuitry, which is not easily
explained in a short (or even long) helpfile - that is a whole study.
The authoritative source document for that study is NYCTA/MTA
drawing-set 733-33, their "typical signal/interlocking prints", not
readily available.

Of course, you are free and encouraged to study and mimic the
circuitry provided in the examples; you can start with what we supply
and modify until it becomes something else.  With NXSYS, you can
actually -watch- the relays in operation and experiment with
modifying their circuits, privileges I never had when learning this
material from paper in the mid-1960's.  (However, I warn and declare
unequivocally that my designs are for entertainment and educational
purposes only and include certain simplifications and possible
errors, and are not fit for use for controlling real railroads or
other life-critical systems, and I assume no risk or responsibility
should any of this information, or designs correctly or incorrecty
derived from it, be faulty and lead to harm, damage, loss, or injury.
Use it at your own risk.)

The NXSYS web page is http://www.basistech.com/bsg/nxsys.htm
Critical updates/information will be posted there.

==================================================================

The relay-compiler input language is a modified subset of Lisp; in
effect this means little more than parentheses define "forms"
recursively and extant Lisp editing tools work.  All whitespace is
equivalent, case is insignificant except in quoted strings, and
semicolons start a rest-of-line comment.

A FORM is either an ATOM or a LIST.  A LIST starts and ends with an
open parenthesis and starts with a close parenthesis, and contains
zero or more forms as its ELEMENTS. Here are the known types of atoms
in NXSYS Lisp, with examples

   2345    Numeric, must be 16-bit (signed), decimal
   foobar  Symbol (string of alphanumerics starting with alpha).
           Used to cause references to same thing.  CASE INSIGNIFICANT!
   17NWK   Relay Symbol.  Starts with number, ends with alphas and/or numbers.
           CASE IS INSIGNIFICANT!
   "Title" Quoted string.  Used where text must appear.  Backslash escapes
           backslash or quote.
   #\A     Single character - used for line designations.
   !24HY   Back contact Relay Symbol. Used for back (closed when dropped)
            contacts.
   782.3   Floating-point number - not supported yet in compiler (10/96)
   355/113 Rational number - not supported yet in compiler (10/96)

Top-level (not contained in other forms) forms define the track layout,
its signals, and its relays.
 
A "route" form must appear first:

  (route "Progman St. Interlocking  --  of 12/8/94" #\A     700   north)
   ROUTE  "String to be displayed"                  Line ID Origin  direction
   "Origin" is the station number (100's sim feet) of left-hand edge
     of the initial window - it may or may not be the leftmost station #
     in the layout.
   "north" had probably better always be "north" for the time being...

(10/96) After "north", zero or more "property pairs" can appear, each
being a Symbol and a value. The names of the properties are reserved,
but unknown/unsupported/misspelled properties are GUARANTEED to be ignored.
Currently known are

                :SIM-FEET-PER-SCREEN   number

This controls the horizontal scale of the display. The default is
3000 simulated right-of-way feet per the width of your screen.
The following are available to parameterize the "train" system:

		:CRUISING-FEET-PER-SECOND number
		:TRAIN-LENGTH-FEET number
		:YELLOW-FEET-PER-SECOND number

The spec
		:TORONTO T

causes Toronto-style signal numbering to be displayed on the signal plates.

Following this must appear "track" forms defining tracks from panel
top to panel bottom:

  (track 1 (tlabel 701)
;  TRACK #  [optional TLABEL form - places legend "TRACK A3 <-" at st. 701]
      (700 707 714 720 725 735))
; this is a list of all the insulated joints by station# on that track.

Next you must define all the switches of the layout, in no particular order.

You can define platforms:
   (platform <type> x1 x2 y1 y2 {"Label"})
<type> is either island, top, or bottom. x1 and x2 are measured in
(hundred sim feet) station#'s, y1 and y2 are hundredths of an inter-track
distance down from the top track, optional "Label" is the text on it.

(switch 3 716 4 718 17)
 SWITCH pos1  pos2  lev#

This says, "Switch 17 goes from st# A3-716 to A4-718, which ends are
to be considered 17A and 17B respectively."  Adding the symbol
SINGLETON as a sixth argument (after the switch number) says that
it "has no" B, but only an A, i.e., is a single turnout, at which
point the A end will be numbered with the number, and the B end, which
may actually coincide with the end of another switch from another
track, with no number.

To define tracks that end in other tracks, or split in a Y (crotch)
layout, end the track one or two (hundred) station points beyond
where it is supposed to end, and use SINGLETON, which will truncate
the track which would have been its "B" end.  See Islington interlocking
for an example of this.

Next you must define all the signals with SIGNAL forms:
({} means optional, not really part of Lisp syntax).

(signal 2      700 (GYR)            {2} {nostop})
 SIGNAL track# st# List of heads    optional lever#
 Note that list of heads is made up of symbols, not strings:  known colors:
    GYRWSDZT. S and D are "S" and "D" lights, Z is a blank plate, no lens.
	      W is lunar white. T is an "ST20" light (20 currently constant).
	      (btw, no, Gyrwsdz was not near Bialystok.)
 The station number can also be
    (displace 707 708)
    (revdir 707 708), where the two numbers are respectively
    the actual station position and the number to appear on the plate,
    which may differ.
    "revdir" puts the signal in the reverse direction on the track, and
     is the only means for doing so.

  NOSTOP is added after the lever number for dwarf signals.

Next exit lights must be defined.  They do not all have to be defined now
(before the relays):  they can be defined anywhere.

   (exitlight  4      2     707 south)
    EXITLIGHT  lev#   trk#  st# direction of traffic for this exit.

Finally one defines the relays.  I will give brief descriptions of
the known relays nomenclatures below, although the technique of
interlocking design will not be explained here, although much may be
inferred from my prototype.

Relays are defined by RELAY forms, which look like this:

(relay 4PBS expression1 expression2 expression3 .... )
 RELAY name  expressions.

The name must be a Relay Symbol for the relay being defined.  The
"expressions" are zero or more terms to be "and"'ed, i.e., wired in series.
Valid expressions are:

     type                 example

   Front contact          13RWC
   Back contact           !22XS
   expr.'s in parallel    (OR 22XS 22XR .... )
   expr.'s in series      (AND 15NWC 17NWC !10AS)
   Label definition       (LABEL L4HY01 exprs to be wired in series)
   Reference to label     L4HY01                  ;SYMBOL, NOT RELAY SYM!!!
   Macro call             (SWIF2 7 10AS 12AS)

Labels are used to define common subexpressions that would implemented
in real relays by shared wires.  (LABEL name expr1 expr2 ....) defines
the AND (series wiring) of all the expr's in it as NAME, and allows that
name to be used as a synonym in subsequent relay definitions.

Macros are used to define standardized identical relay definitions,
identical in shape but not in relay numbers.  For example.

(defrmacro SWIFNC 3 (AND (OR 1NWC (arg 2)) (OR 1RWC (arg 3))));8 Dec 1994
 DEFRMACRO  name  n template
The name must be a symbol, n is the number of arguments expected.
The actual arguments may be numbers or relay names:
  (SWIFINC 23 10AS 12AS)
           1   2    3
In the TEMPLATE, (arg 2) substitutes all of arg 2, and references to
relay symbols cause the switch or signal numbers of the corresponding
argument to be substituted, i.e., (OR 1NWC... becomes (OR 23NWC
in the above.

Note that macros may be used both as top-level forms or as subforms
of other relay definitions.

TIMER forms are just like other relay forms, except that a time in seconds
appears after the timer name:
  (timer 4U 7 (OR 4AS......
This defines a timer relay that closes its named contacts after 7 continuous
seconds of its defining terms being true.

The following relays are known to the simulator.  Some are read by it
to update the panel, and others are operated by it to reflect interaction.
If you don't have them, the corresponding feature will not be implemented
for the object in question.  If you have them, they be used as expected.

THE FOLLOWING ARE THE RELAYS READ BY THE SIMULATOR TO DRIVE THE PANEL
which the (your) relay logic must drive to make the panel "work":

Note that signal nomenclature is lever# for those that have it, else IJ#
(signal) H   Home - when picked, signal is clear
         D   Distant. When signal is clear, picked if signal is green.
      (if HV and/or DV are found, they will be used instead of
          H and/or D, although H will be used for the GK light).
         FL  Fleeting relay.  Created and read by simulator.
         DR  For home signal, picked when cleared to divering route.
         CO  For home signal, call-on when picked.
         SK  Yellow "S" light in advance of GT signals.
	 STR "ST20" light, only displayed if signal is red.
         V   Stop (trip).  When picked, stop is held clear.
         K   Exit light at signal.
	 PBS Push button stick.  Fundamental initiation relay.
	     Only read by the simulator to light GK light, and enable
	     dropping by mouse click (see below).
         LS  Switch lock (stick) - switch free when picked, locked (and red
             lock light lit) when dropped. Gates RLP/NLP to RWZ/NWZ.

(track)  T   Track.  When picked, track section is vacant.
         K   Route.  When picked, white route line-of-light is shown.

(switch) (A and B operated together)
         NWZ Normal switch control - picked when switch wants to be normal
	 RWZ Reverse switch control -picked when switch wants to be reverse.

THE FOLLOWING ARE THE RELAYS OPERATED BY THE SIMULATOR IN RESPONSE TO THE PANEL,
providing input to rest of the relay system from the user interface:

         The "pb"'s are pulsed by the simulator.

         0CPB is a huge sim-relay which is pulsed to drop every signal in the
         simulator, so a back contact appears in all PBS's. As of
	 19 Feb 97, this is no longer necessary, the simulator drops
	 all PBS's known to its signals when required.  0CPB is still pulsed,
	 though, and can be used elsewhere.

	 0RAS is similar, and pulsed to release up all approach locking
	 on menu command.

(signal) PB   Push button (initiate or exit) at signal on control panel.
	 COPB Trackside call-on push-button on home signals.
         FL   Fleeting - turned on or off by simulator
	 XPB  Exit push button - click on lit exit light.
	 PBS  Push button stick.  Picked when successful initiation at
              signal. Only operated by the simulator to drop when GK clicked
              on.

(switch) NL   Normal lever - pulsed to request switch normal (r click or aux key)
         RL   Reverse lever - pulsed to request switch reverse (ditto)
	 NWP  Norm. Switch repeater - switch actually in that position.
         RWP  rev.. etc

(track)  T    Track - picked when track section vacant- can be generarted by mouse,
              train system, etc.

(stop)   NVP  The train stop has come fully to the normal (tripping) pos'n.
         RVP  The train stop has come fully to the clear position.

THE SIMULATOR INITIALIZES ALL RELAYS NAMED " ... AS" OR "..  D" or ".. DV"
or "..RGP" at interlocking load time by computing their state by
evaluating their expressions - this fairly inelegant solution to a
fairly massive initial-state problem not yet solved in general.

Here are some other relays, not known to the simulator proper:

(signal)

   XS  - exit stick - picked when exit at this signal selected.
   R   - route relay. Picked when complete route at signal established.
   HY  - slotting (control section) - home signal - picked when ctl sec. clear.
   COS - call on stick - picked when call on is selected by towerman.
   AS  - approach stick - picked when approach locking is clear.  Most
         general test for signal considered to be at stop.
   U   - approach locking timer (also called U for track grade timer, though).
   VS  - stop stick.  Forces train stop down in reverse direction.
   XL  - exit lockout.  Sometimes used. When dropped, prohibits exit there.
   XR  - end-to-end routing, forward probe from one subnetwork to next.
   ZS  - end-to-end routing, successful matching in reverse direction.

(switch)
 (all "when picked")
   RWZ, NWZ - switch control -- switch legitimately wants to be that position.
   RWC, NWC - switch in correspondence in that position.
   RLP, NLP - switch called for in that position, even if locked otherwise.
   RWK, NWK - switch in corresp, and locked OR called for in that position.
   ANN, BNN, ANS, BNS, RN, RS -- NX route selection magic relays:
    Ex. 17ANS = "contemplating a move over 17A, Normal pos, South direction."
    When corresponding pair (e.g., 17BNN/17BNS, 17RN/17RS) picked, NLP or
    RLP is called for to make the switch move.  This is the heart of NX/UR.

(track)
   NS, SS North/South stick.  Implements "route locking" (see helpfile).
      Normally picked.  Dropped in linked chains over a route to lock
      switches, prevent opposing movement, and put white lines of light
      on board. Held stuck either by train in it or previous section's
      identical relay or signal AS.
   U  GT signal timing.

You can define any other relays you want, freely.

There is a new class of "optional" relays, currently including

(switch)
  CLK - If picked, which should only happen when the switch track section
        is neither occupied nor routed, the points of the switch will flash
        in white in whatever position they are in.
(signal)
  CLK - If picked, the GK light for the signal, if lit, will flash.
        If this relay exists for the signal, the builtin call-on processing
        that flashes the GK light will not be performed - the CLK relay
        assumes this responsibility and must be programmed for it.

  BPBS - If the simulator can't find PBS for a signal, but can find BPBS,
	 which is used with ST signals, it will use it instead of PBS
	 for GK light indication, fleeting, and cancelling.

(switch)
  LK  -  The simulator will look for this, and if not found, use LS. It
         will use the back contact of the one found to drive the switch
         lock light, lock out the switch auxiliary key and switch control
         motion.  LK must be used (as in 1957, but not 1994, 733-33 standard)
 	 if there are conditional crosslocks in NWZ/RWZ that do not appear in
	 LS.

These optional relays need not be coded, but if they are, they will
be utilized as indicated above.

With one exception, relay definitions may appear in the source file
in any order.  If the circuit is correctly designed and race-free,
the order of relays will not matter.  There is, however, one case in
the standard interlocking design where relative timing is critical,
and thus the detail of the simulator's algorithm, and hence, source
order, become considerations:

"SPECIAL CONSIDERATION":
  The simulator's relay algorithm is as follows: when a relay is picked
  or dropped, AND this is really a change from its previous state, i.e.,
  a real transition, the identities of all relays that depend on that
  relay are put in a queue in the order they appear in the source file.
  Then all of these relays are inspected, their states recomputed, and
  if their states change, their "dependents" are added at the end of the
  queue.  This procedure is continued until the queue is empty.

This algorithm works pretty well most of the time, far better than
simply recursing over relays.  Computation of new state is done in
machine language, so it is fast.  The only time this simulation is
not transparent is when relay B repeats relay A, and a third relay,
C, has a stick circuit broken over (OR !B A), such as home signal
PBS.  The real circuit drops A, which drops B: in the time interval
between A's breaking and B's picking up, C drops.  This will not work
in the simulator by the algorithm described above, and one must
ensure that C is defined before B in the source file, to make sure
that C sees the change of A before B does.  This is the case with HY
(and COS) and PBS: The PBS for a home signal must be defined before
its HY or COS. Dwarves, having no HY, require TP and TPP to repeat T
to make the same circuit work, for the same reason.

================================================
Additional special forms (19 February 1997)

The Common Lisp special forms COMMENT, EVAL-WHEN, and INCLUDE are
supported by NXSYS and the compiler.
  COMMENT   all subforms are read, but ignored when it appears at top
            level. Example
             (COMMENT (RELAY 240R 240PBS 125RWK 127NWK 212XS)) ;;old 240R
             (RELAY 240R ...                       ;;real definition.
  (EVAL-WHEN  tags form1 form2 form3 ....)
            "tags" is a list, either (), (EVAL), (LOAD), (LOAD EVAL) etc.
             if EVAL appears among the keys, the forms will be processed
             when the interpreted file is loaded.  If LOAD appears among
             the keys, the forms will be processed by the compiler as though
	     they had appeared at top level, but (unless EVAL appears) ignored
             when the file is loaded interpreted.
  INCLUDE    e.g., (INCLUDE "stdmacs.trk").  The single argument is a pathname
             relative to the file which contains the INCLUDE.  The forms
             and defintions in the file will be treated by NXSYS and by
             the compiler as though they appeared in the file at the point
             of the INCLUDE form.

A special relay called 0LogicHalt has been defined.  If you provide
a definition for this relay, and it ever picks, at that time a message
box will pop up stating this: if you press "Yes", the relay simulator
engine will halt and allow you to examine its state in detail with the
draftsman and other tools.  You must (currently) reload the interlocking
after such a breakpoint.
          
========================================================================
COMPILING WITH THE 32-BIT COMPILER FOR EITHER TARGET ARCHITECTURE:

To compile .TRK files into open code for either the 80386 (32-bit NXSYS),
or the 8086 (16-bit NXSYS), use the 32-bit command line app RLYCMP32:

    RLYCMP32 name{.trk}

Here is its usage message:

    BSG Relay Compiler Version 2 (32-bit) of Oct 14 1996 20:08:31
    Copyright (c) Bernard S. Greenberg 1994, 1996
    Usage: rlycmp32 source{.trk} {args}
    Args:
      /L    Make listing to source.lst
      /32   Produce 32-bit object file (default)
      /16   Produce 16-bit Version 1 object file
      /Fo:nondefault_outputpath (default is source.tko)
      /Fl:nondefault_listingpath (default is source.lst)
      /C    Special debug checking.
      /T    Internal compiler tracing to listing

The 16-bit version of the compiler is obsolete and no longer
distributed, but note that /16 causes the 32-bit compiler to produce
8086 object files for 16-bit NXSYS.

Use DISPTK32 to display compiled code data; it can display 16 and 32
bit files.  DISPTKO is supplied with 16-bit NXSYS, but to be considered
obsolete by interlocking developers.


=======================================
(END)
