This document assumes that you have read, and understand, the panel
users manual. It gives a brief overview of the most important data
structures used in the PAWS software. Along with the description of the
data structure, some information on how it is used in the system is
provided. Understanding the data structures and their use is crucial to
trouble shooting and modifing the PAWS software.

Message structures

Size = 87 (MS_SZ)

Message buffer for panels: MS_XX (ie MS_00 - MS_7f)

Message buffer for DUARTS: URM_A URM_B

Offset SYM Function

0 MS_ST Message Status

1 MS_INS Insertion index

2 MS_END Completion index

3 CRC_HI High byte of CRC

4 CRC_LO Low byte of CRC

5 MS_BF Message buffer (40 bytes)

44 PBB_CT Push back count

45 PBB_XT Push back extraction index

46 PBB_BF Push back buffer (40 bytes)

MS_ST values:

SYM Value Function

MS_LK fc Locked

MS_ND fd Need data

MS_NL fe Need length

MS_NS ff Need SOM

MS_CMP 0 Message assembled

As bytes are received from a serial port, the code tries to assemble
them into a legal message. This structure is where the assembly and
validation occurs.

The message status field (MS_ST) indicates the state of this structure.

MS_NS means that the code is looking for the start of message character.
(SOM) In this state, only the SOM character is acceptable, other
characters are considered to be garbage bytes in front of the message.

MS_NL indicates that the SOM has been received, and the code expects the
next byte to be the optional data length. Once the optional data length
has been received the code can compute the total message length. With
this information in hand the code can record the completion index. When
the insertion index is equal to the completion index, the complete
message has been received. (The received bytes are stored in the MS_BF
buffer.) After the data length has been received, the code is buffering
the message data itself.

MS_ND indicates that we buffering the message data. Once the last byte
of the message has been received, the structure state is set to MS_CMP
to indicate that a complete message has been assembled.

MS_CMP indicates that the message has been assembled.

MS_LK indicates that the message buffer is locked.

Certain messages (such as page requests containing new trays) take a
long time to fully process. When one of these messages is being
processed, the structure is locked. A locked structure prevents the
assembly of any additional message. At a later time, when the message
processing is complete, the structure is unlocked so another message may
be received.

The insertion index (MS_INS) indicates where in the buffer the next byte
received will be stored.

Once the SOM character has been received, the code expects to receive
the optional data length byte. This byte indicates how many bytes of
optional data are contained in the message being assembled.

MS_END indicates where the insertion index will be when we have received
the last byte of the message. We can not calculate the completion index
until after we have received the optional data length byte of the
message.

In order to detect and reject corrupted messages the code runs a CRC
across all bytes in the message except for the SOM and EOM (End of
Message) characters. The CRC on the bytes received so far is kept in the
CRC_HI and CRC_LO fields.

The message itself ends with a CRC and EOM. The calculated CRC is
compared to the received CRC. If they do not match, then an error has
occurred, and the message is rejected.

(The message is also rejected if the character stored at the completion
index is not the EOM character.)

If a corrupt message is detected, the SOM character is thrown away and
the bytes remaining in the MS_BF are saved in the push back buffer.
(PBB_BF) Bytes stored here are read in first, before any bytes are
processed from the serial port.

The extraction index (PBB_XT) indicates where the next byte is to be
read from, while the push back count (PBB_CT) indicates how many bytes
are left in the push back buffer.

MS_00 is used to buffer messages from panel 0 while MS_01 is used to
buffer messages from panel 1 and so forth.

UART receive structures

Size = 259 (URB_SZ)

A side UART rcv buffer: URB_A

B side UART rcv buffer: URB_B

Offset SYM Function

0 URB_ST Buffer state

1 URB_IN Insertion index

2 URB_EX Extraction index

3 URB_BF Circular buffer (256 bytes, URB_DS)

URB_ST values:

SYM Value Function

URB_MT 00 Empty

URB_PR 80 Partially filled

URB_FL ff Full

This structure is used to store all bytes received by the dual UART.
Since dropping even a single byte will corrupt a message, and cause it
to be discarded, dual UART reception is interrupt driven. When a byte is
received by the dual UART it is stored in this circular buffer.

URB_IN is the insertion index, it indicates where the next byte will be
stored.

URB_EX is the extraction index. This indicates where a byte will be
removed from when attempting to build a message.

URB_BF is the circular buffer itself. This is where the received bytes
are stored.

If the insertion index and extraction index are equal, then the buffer
is either full or empty. URB_ST will be equal to URB_MT if the buffer is
empty, and URB_FL when the buffer is full. If the buffer is not empty or
full, URB_ST will be equal to URB_PR. (partial)

UART reception is a bit tricky because of the memory devices used by
PAWS. The main memory device is a XICOR EEPROM, which stores the
majority of the executable code, along with the configuration data the
system consoles download to the system.

You cannot read from the EEPROM while it is undergoing a programming
cycle. This means that you cannot run any code from the EEPROM while you
are recording configuration data.

The upshot is that the interrupt handler that services the dual UART
must be stored in the EEPROM that is in the CPU, since we cannot stop
servicing the dual UART for the 10 milliseconds or so that it takes to
program new configuration information into the XICOR EEPROM. This EEPROM
is about 500 bytes, and the interrupt vector tables take up part of that
space. The dual UART interrupt handler is optimized for small size and
high speed, which is why the routine uses a circular queue. The
reception routines just store the bytes in the circular buffer, the
bytes are extracted later by mainline routines that assemble and process
messages.

Panel Comm structures

Size = 10

Panel comm records: PA_XX (ie PA_00 - PA_7f)

Offset SYM Function

0 PS_FAD FIFO address

2 PS_SRA FIFO status address

4 PS_RSM Receive mask

5 PS_TSM Transmit mask

6 PS_RSC Reset command

7 PS_PSA Pull Station Status address

9 PS_PSM Pull Station Status Mask

These structures are only present on the matrix. All traffic that flows
between the matrix and the panels flows through FIFOs that are present
in the matrix\'s memory map. The hardware actually resides on the PPIC.
(Paging Panel Input Card.)

When the matrix is ready to send a byte to a panel, it has to find the
address of the FIFO registers used to talk to that panel. There are two
FIFO addresses in each panel\'s record. One is the address of the FIFO
status register, and the second is the address of the data registers.
Within the status register is a bit to indicate if the receive buffer
has any data, and a bit to indicate if there is any room left in the
transmit buffer.

The status register contains bits for four FIFOs. Since four FIFOs share
a single status register, each panel has its own transmit status mask
and receive status mask. There is also a bit value used in resetting the
FIFO. (The address of the reset register is \"known\" because it is a
fixed offset from the FIFO status register.)

Please note that the read FIFO and write FIFO for panel communication
are mapped to the same address. Reading the FIFO address will return a
byte received from the panel, while writing to the FIFO address will
send a byte to the panel via the UART connected to the read/write FIFOs.

Another function that is supported on the PPIC is the remote area
warning input. There are fields to identify the address and bit within
the address that is used to sense the state of a remote area warning
station.

(As of this date, 10/23/95, discussion is underway on replacing the
remote area warning stations with a modified panel. If this occurs,
these fields will become unused. No software changes will be required as
you can simply download an empty pull station map to disable pull
station processing, but if you pull the pull station support code out of
the matrix, the matrix code will be a little faster, and it\'ll free up
some memory.)

The information in the table built from these records is fixed. It
supports rapid look up of addresses and masks needed to interface with
the panels. The file containing the PA_XX records is actually built by a
\"C\" program, mktab.exe.

Message output structure

Size = 87 (OUT_SZ)

Buffer for message to panels: OUTP

Buffer for message to DUART: OUTC

Offset SYM Function

0 OUT_ST Status

1 OUT_LEN Template length

2 OUT_BEG SOM byte

3 OUT_DL Optional data length

4 OUT_CH High byte of command

5 OUT_CL Low byte of command

6 OUT_OD Start of optional data

OUT_ST values:

SYM Value Function

OUT_FR 00 Free

OUT_BZ ff Busy

OUTC is present on the matrix and the panels, while OUTP is only present
on the matrix. On the matrix, OUTC is used for sending messages to the
systems console, while on the panels, OUTC is used for sending messages
to the matrix. The matrix uses OUTP for sending messages to the panels.

Messages that originate on the panel or matrix are stored as a message
template. This contains the message itself, along with several bytes
used for transmission of the message.

When a message needs to be sent to a system console, matrix, or panel,
the message template is copied to the message output structure and any
required optional data is filled in.

For OUTC, transmission is initiated by software that reads the first
byte of the message (the SOM byte) and writes it to a UART transmission
register. As part of this sequence, the UART transmission interrupts are
enabled. This causes transmission interrupts from the UART which result
in the rest of the bytes of the message being written to the UART
transmission register.

The buffer status byte, at offset OUT_ST, is used to indicate the state
of the message output structure. OUT_FR indicates that the buffer is
idle while a value of OUT_BZ indicates that the buffer is still in use.

(Some messages are sent to just the A side or just the B side system
console or matrix, while other messages are sent to both the A and the B
sides. If a message is going to both sides, transmission may be
completed on one side or the other, but the buffer can\'t be freed until
transmission is completed on both sides.)

The value stored at OUT_LEN is the number of bytes in the template,
which contains the message itself along with several buffer associated
values. (Including OUT_ST and OUT_LEN.) This is the total number of
bytes copied to OUTC or OUTP.

The fields starting with OUT_BEG are part of the message itself. OUT_DL
is the number of optional data bytes in the message. This value is used
in figuring out how many bytes will be used in computing the CRC prior
to sending the message. It determines how many bytes to include in the
CRC, and where in the buffer to store the calculated CRC. When the
actual transmission is set up, it is also used to compute the number of
bytes that must be written to the UART transmission register. (This is
simply the number of optional data bytes, plus the size of the fixed
message fields.)

OUT_CH and OUT_CL are the high byte and low byte of the command field.
They are not usually changed in message transmission.

OUT_OD is the offset to the optional data area. Any variable message
data will be recorded starting at this offset.

On the matrix, for messages being sent to the panels, transmission
interrupts are not generated. For these messages, polled output is used.
When the matrix wishes to send a message to a panel, it writes each byte
of the message to a 1K FIFO which feeds a UART without CPU intervention.
A status register indicates if the FIFO register is full. In the
unlikely event that the FIFO register fills up, the matrix CPU will poll
the status register until it can write another byte.

Output module structures

Size = 5

Tray control records: TA_XX (ie TA_00 - TA_bf)

Offset SYM Function

0 OM_RA Register address

2 OM_IA Image address

4 OM_BM Bit masks

Bit extraction masks:

SYM Value Function

OM_VKM f0 Voice Key control bit mask

OM_AWM 0f Area Warning control bit mask

A tray is a device used to distribute audio to an area. Each tray has
two control signals. The first is used to key (activate) audio
distribution within a given area, while the second removes a 10 db pad
from the audio feed when activated, thereby increasing the audio level.

In the matrix, these control signals are referred to as the voice key
and the area warning key. (Area Warning controls the 10 db pad.)

When a page, or other audio, needs to be sent to a given area on KSC the
matrix must route the required audio feed through a crossbar switch to
the tray and then activate the tray. In order to activate the correct
tray, it uses the tray number to index into a table of tray control
records.

Each record indicates the memory address of the register used to control
the tray, (OM_RA) the memory address of the image of the register,
(OM_IA) and a pair of bit masks packed into a byte. (OM_BM)

An image of the tray control register is required as there are control
bits for four trays packed into a single byte, (by the hardware design
of the control tray output cards, CTOC\'s) and you can not read the
current contents of the control register.

In order to control one of the four trays, independently of the other 3
trays, you must OR in or AND out a bit, without disturbing the bits for
the other trays. By keeping an image of the contents of the tray control
register, we can manipulate the bits for a given tray, and keep the bit
values for the other trays intact.

The OM_BM field contains a bit mask for the voice key in the upper
nybble, and a bit mask for the area warning key in the lower nybble. By
ANDing the OM_BM contents with OM_VKM, you are left with the single bit
that controls voice keying. OM_AWM is used to extract the area warning
bit from the OM_BM contents.

The sequence used to key a tray is as follows:

Index into the tray table using the tray number.

Grab the image address.

AND the OM_BM field with OM_VKM to get the voice key bit.

OR the voice key bit with the image to \"key\" the tray.

Save the new value at the image address.

Write the new value to the register address.

The sequence used to unkey a tray is as follows:

Index into the tray table using the tray number.

Grab the image address.

AND the OM_BM field with OM_VKM to get the voice key bit.

Invert the voice key bit value. (and all other bits)

AND the voice key bit inverse with the image to \"unkey\" the tray.

Save the new value at the image address.

Write the new value to the register address.

List structures

Size = 258 (LST_SZ)

Panel polling list: PL_LST

Pull station list: PS_LST

Offset SYM Function

0 LST_FR Free index

1 LST_SC Scanning index

2 LST_DT buffer

This structure is used to hold two lists, a list of the active panels
present in the system and a list of pull stations present in the system.

In order to make the system as responsive as possible, yet allow
expansion, the system will only attempt \"reception\" from devices that
are identified as being present.

Specifically, the matrix will only check those panels listed in the
PL_LST for input. (Messages being sent to a panel will be forwarded to
the panel even if it is not listed in PL_LST.)

Only those pull stations listed in PS_LST are checked to see if their
state has changed.

Once each pass through the main loop of the matrix program, the matrix
will get a new panel number from the PL_LST and check that panel\'s FIFO
to see if the panel has sent any data to the matrix.

Any received data is stored in a message buffer where the matrix
attempts to build a valid message. There is a limit to the number of
bytes that the matrix will fetch from a single panel in a pass. The
matrix will also stop fetching data from the panel as soon as a
complete, legal, message has been assembled.

On the next pass through the main loop, the matrix will get a different
panel number, and check for input from that panel.

The upshot is the matrix receives messages from all the panels listed as
being in the system in a round robin fashion.

In addition to a panel list, the matrix contains a pull station list.
Once each loop the matrix software gets a pull station number from the
pull station list and checks to see if the pull station has changed
states.

A pull station is used to activate a local area warning from within a
area. When someone activates a pull station mounted on the wall in an
area that performs hazardous operations, an area warning tone is
generated and distributed to that area. Local beacons may be activated
as well.

An important fact to note is that there are several reasons why a panel
that is present in the system may not appear in the PL_LST. If a panel
request will take some time to fulfill, the matrix will remove the panel
from the PL_LST until processing of the request is completed. This is
required because each panel has only one message buffer, and any
reception of a new message from the panel would overwrite the old
message that the matrix was working on.

Panels can also be removed from the polling list (PL_LST) under software
command. This may be required when the comm link to the panel fails,
which can cause the matrix to spend a lot of time polling the panel on
the failed link, trying to assemble a valid message. A temporary fix
would be to remove the panel from the polling list until the comm
problem can be corrected.

The system will tolerate several down comm links, but system response
drops off with each failure, and eventually a point is reached where
page attempts will start failing due to the matrix not responding to a
working panel in time.

It is a good idea to temporarily remove any panels you know are having
comm problems from the polling list until the problem is fixed. This
will result in a more robust system.

The lists are large enough to hold the maximum number of units (panels
or pull stations) with room to spare.

The LST_FR field indicates which slot in the list is the first open
(unused) slot. When a panel is returned to the list after having been
removed to service a long request, it will be added to the list in the
LST_FR slot, and the LST_FR value is incremented.

LST_SC is the scanning index. It is used to index into the list on each
pass to see which panel (or pull station) to check that pass. LST_SC is
bumped after each pass, so that on the next pass, a different panel or
pull station will be checked. (When LST_SC reaches LST_FR, it wraps back
to 0, the top of the list.)

LST_DT is the unit number buffer. Each slot in the list will contain a
panel or pull station number. The collection of slots (and their
contents) form the LST_DT.

Matrix Bit Maps

PN_TBL 16 bytes Panel present map

PS_TBL 16 bytes Pull Station present map

NT_TBL 24 bytes New trays present map

OT_TBL 24 bytes Old trays present map

PP_MAP 16 bytes Panel preempted map

IP_MAP 16 bytes Page in progress map

Panel Bit maps

BSMAP 8 bytes Button state map (1 is active)

AWT_A 24 bytes Area Warning Trays, A side

AWT_B 24 bytes Area Warning Trays, B side

AWZ_A 8 bytes Affected Zones, A side

AWZ_B 8 bytes Affected Zones, B side

If a bit is set, that unit is present or marked.

Matrix Structures

The PN_TBL is a list of panels that the system console has indicated are
installed in the system. It is used to build the initial polling list
(PL_LST) but panels can be added to, or removed from the PL_LST for
various reasons.

The PS_TBL is a list of pull stations that the system console has
indicated are installed in the system. It is used to build the PS_LST.
Pull stations can be added to, or removed from the PS_LST only by
downloading a new PS_TBL.

NT_TBL is a list of new style trays that the system console has
indicated are installed in the system. New style trays contain a
feedback circuit that indicates the current state of the tray, active or
idle. Whenever the matrix keys or unkeys a new tray, it will test the
state of the tray a short period of time later to insure that the tray
went to the desired state. (The system has to allow about 40
milliseconds for the tray to physically reach the desired state, due to
propagation delays and mechanical inertia.

OT_TBL is a list of old style trays that the system console has
indicated are installed in the system. Old style trays do not contain a
feedback circuit, so their state can not be checked.

All trays in a panel\'s page request or zone select must appear in
either the new tray table or the old tray table. If a request contains
one or more trays that don\'t appear in either list, the matrix rejects
the request as an illegal request.

PP_MAP is a list of all panels that have already received a cutoff
message from the matrix. It is used to reduce the amount of traffic that
the matrix sends to the panel when a higher priority page overrides a
page from another panel.

IP_MAP is a list of all panels that are currently performing a page.
This list is used in page preemption. When the system grabs a tray for a
high priority page, the matrix checks to see if a panel that it thinks
owns the tray in question is active. If the panel does not have a page
in progress, the owning panel number is stale, or leftover from an
earlier page. In this case, the matrix does not have to send a cutoff
message to the panel.

Panel Structures

BSMAP is a list of all zone buttons that are active. (depressed)

AWT_A is a list of trays that are in the area warning mode on the A side
of the system.

Whenever a panel or a pull station initiates an area warning, all panels
are notified because they must blink the zones that are affected by the
area warning. This is accomplished by each matrix sending a list of
trays that are in area warning mode to all panels. The panel stores this
list and checks selected zones against it to see which zones it should
blink.

AWT_B is a list of trays that are in the area warning mode on the B side
of the system.

AWZ_A is a list of zones affected by area warnings on the A side of the
panel. The panel builds this list each time it receives a new AWT_A list
from the matrix.

AWZ_B is a list of zones affected by area warnings on the B side of the
system. The panel builds this list each time it receives a new AWT_B
list from the matrix.

When the matrix receives information that one or more devices have
activated area warning, it builds a map of trays that are currently in
area warning mode. This map is sent to each panel present in the system.
The panel stores the map in memory.

A panel will receive an area warning map from both the A matrix and the
B matrix. The panel compares the area warning maps to the zone tray maps
programmed on each button and builds a list of zones affected by A side
area warnings and a list of zones affected by B side area warnings.

Using the A side affected zone map and the B side affected zone map, the
panel blinks all zones affected by area warnings.

Every time a panel changes area warning states or a pull station changes
state, the matrix builds and distributes a new area warning tray map.

Circular queue structures

Size = 259 (CRQ_RS)

TON_CQ Timer on (new trays waiting to close)

VON_CQ Verify on (new trays that should be closed)

TOF_CQ Timer off (new trays waiting to open)

VOF_CQ Verify off (new trays that should be open)

PON_CQ Pending on zones (map numbers)

AS_LST Assembled panel messages

TMP_CQ Temporary, used in compaction

Offset SYM Function

0 CRQ_IN Insertion index

1 CRQ_EX Extraction index

2 CRQ_CT Count

3 CRQ_DT Data (256 bytes, CRQ_SZ)

Circular queue structures are mainly used for keeping track of the
states of new style trays as they cycle from inactive to active and back
to inactive.

When the matrix keys a new style tray, it places the tray number on the
timer on circular queue. (TON_CQ) In the outer loop of the matrix
software, the matrix will check the tray at the top of the queue to see
if enough time has passed that the tray should be in the active state.

The TON_CQ contains the tray number. Each tray has a record that
contains the time the tray should reach its next state. When the matrix
keys the tray, it adds the tray to the TON_CQ and records the current
time plus the amount of time required for a tray to pull in the tray\'s
time field.

If the current time is less than time when the tray is supposed to reach
the active state, then the other trays on the TON_CQ do not need to be
checked since all trays take the same time to reach the active state and
they are placed on TON_CQ in the order that they were activated.

If the tray at the top of TON_CQ has reached the time where it should be
engaged, the tray is removed from the TON_CQ and added to the verify on
circular queue. (VON_CQ) If the top tray is moved to the VON_CQ, the new
top tray on the TON_CQ is checked to see if it has reached the time
where it should be engaged. (Since a single page can often pull in
several trays, trays are usually added to the TON_CQ as a block.)

The TON_CQ is checked until we reach a tray that has not yet reached the
time where it should be engaged. Once that happens, we stop checking the
TON_CQ since the rest of the trays are also still waiting.

The VON_CQ contains a list of trays that should have reached the engaged
state. In the outer loop of the matrix software, we check the VON_CQ to
see if there are any trays on it. For each tray listed on the VON_CQ,
the matrix checks the tray\'s feedback circuit to see if the tray is
actually engaged. The results of the test are then recorded in each
panel\'s record. If the tray failed to close, the failure is recorded in
an error table the matrix maintains. Only one tray is processed each
pass.

A panel always instigates closure of a tray. It is possible for the tray
to be \"in use\" by more than one panel. Each time a zone select button
is pressed on a panel, the panel asks the matrix to test all the trays
associated with that button. For each page performed by any panel, the
matrix will also test all new trays associated with the page.

The matrix will return the test results to the panel so the panel can
indicate to the operator if any problems exist. If more than one panel
requests a zone select test, or one panel requests a page, and one or
more other panels request a zone test at nearly the same time, there can
be many panels waiting for the results of the tray activation.

After a tray\'s feedback circuit is checked, the tray is removed from
VON_CQ.

When the matrix unkeys a tray, it places the tray number on the timer
off circular queue. (TOF_CQ) In the outer loop, the matrix code checks
the top tray on the TOF_CQ list. If enough time has passed that the tray
should be disengaged, the tray number is removed from the TOF_CQ and
placed on the verify off circular queue. (VOF_CQ)

The matrix code will check the VOF_CQ, and for each tray on it, it will
check the tray\'s feedback circuit to see if the tray really opened. If
the tray failed to open, the failure is recorded in an error table the
matrix maintains. Panels are not notified of failures to open.

After each tray is checked, it is removed from the VOF_CQ.

The system console does a periodic read of the matrix error table and
notifies the system console operator of any new failures since the last
time the error table was checked. The errors count up to 255, and stop.
There is a command that can be sent to the matrix that causes it to
reset all the error counts.

PON_CQ is a circular queue that contains a list of maps that are
pending. Zone buttons are translated to map numbers in the panel. When
the user presses a zone select button, the panel translates the zone
number to a map number, and adds the map number to the pending on list.
The zone select lamp is turned on, and the panel requests a tray test
from the matrix. It also records the time it expects an answer back from
the matrix in the map record.

The panel\'s outer loop checks the PON_CQ, and if a map is present, and
the map\'s time field indicates that the matrix answers should have been
received by now, the map is removed from the PON_CQ and the panel looks
at the response from both the A and B side matrix and either leaves the
lamp on, leaves the lamp on but beeps, or beeps and turns the lamp off.

If the lamp is left on, the trays associated with the map are added to
the panel\'s global tray maps. (one for the A side and one for the B
side.)

AS_LST is a circular queue used on the matrix to maintain a list of
panels that have been removed from the polling list because a complete,
valid message has been received from the panel, but the message has not
been processed yet. In the outer loop of the matrix, we check the AS_LST
and if any panels are listed, the message in the panel\'s message buffer
is processed.

TMP_CQ is a temporary circular queue. If a record is deleted from the
middle of a list, the list is compacted by copying all the records,
except for the one being removed, to the temporary buffer, and the
original buffer is overwritten by the temporary buffer. (This could be
cleaned up if we ever do a garbage collection drop, but right now the
customer does not want to change the code much. It is used
infrequently.)

CRQ_IN is the insertion index. This is where the next item added to the
list will go. It wraps around the end to the top.

CRQ_EX is the extraction index. This is where the top record lives.

CRQ_CT is the count of the number of items on the list.

CRQ_DT is the circular buffer itself.

Normally, an item is removed from the list by decrementing the CRQ_CT
field, and incrementing the CRQ_EX field.

Tray structures

Size = 22 (TR_SZ)

Tray state records: TR_XX (ie TR_00 - TR_bf)

Offset SYM Function

0 TR_ST Tray State

1 TR_FLG Tray bit flags

2 TR_PRI Request priority

3 TR_OWN \"Owning\" panel

4 TR_TMR Time relay S/B open/closed

5 TR_CT Bits set count

6 TR_TM test map (16 bytes)

TR_ST values:

SYM Value Function

TR_FRE 00 Free

TR_PON 02 Pending on

TR_VON 03 Verify on

TR_ACT ff Active

TR_POF 11 Pending off

TR_VOF 10 Verify off

Flag bits:

SYM Value Function

TR_IV 00 Not installed, unused

TR_TST 80 Testing

TR_OP 40 Pass audio

TR_NW 20 New tray

TR_OL 10 Old tray

TR_AT 08 AW tray too

TR_PA 04 Pending AW

TR_WT 02 WWT required

TR_PW 01 Pending WW

TR_XX records are used to track tray operations.

The TR_ST field indicates the current state the tray is in.

TR_FRE indicates that the tray is idle, ie, no panel has requested the
tray for anything.

TR_PON indicates that the tray has been keyed, and in a short time
should be closed. (active) Trays with a state of TR_PON should be on the
PON_CQ.

TR_VON indicates that enough time has elapsed for the tray to close, and
it is awaiting testing of its feedback circuit to verify that the tray
closed. Trays with a state equal to TR_VON should be on the VON_CQ.

TR_ACT indicates that the tray is being used for a page. (And the
feedback circuit has already been tested if it\'s a new style tray. Old
style trays do not have a feedback circuit, so when keyed, they go
directly from TR_FRE to TR_ACT.)

TR_POF indicates that the tray has been unkeyed, and the matrix is
waiting for the tray to have enough time to open. Trays that have a
state of TR_POF should be on the POF_CQ.

TR_VOF indicates that the tray has been unkeyed long enough that it
should now be open, and is awaiting testing of its feedback circuit to
verify that it has opened. Trays with a status of TR_VOF should be on
the VOF_CQ. (Old trays don\'t have a feedback circuit, so when unkeyed,
they go directly from TR_ACT to TR_FRE.)

The second field, TR_FLG is a collection of flag bits.

TR_IV is the value that indicates that the tray is not listed as being
present.

TR_TST is a bit indicating that one or more panels have requested that
the tray be tested as a result of an operator\'s zone selection. (A map
of the panels waiting on the test is contained in the structure.)

TR_OP is a bit indicating that a panel has requested that the tray pass
audio in support of a page operation by that panel. (Only a single panel
can use a tray for passing audio because there is no provision to sum
audio from more than one panel to feed to the tray. Since a zone select
does not require passing audio, any number of panels can request a zone
select test, even in parallel with a page.)

TR_NW is a bit that indicates that the tray is a new style tray that
features the feedback circuit. (Which allows the matrix to determine the
actual state the tray is in at any given time.)

TR_OL is a bit that indicates the tray is an old style tray, and has no
feedback circuit. Without the feedback circuit, the matrix has no way of
checking the actual state of the tray, so old style trays are assumed to
be good whenever a test is required.

TR_AT is a bit that indicates an area warning operation is being
performed with the tray. This means that in addition setting and
clearing the voice key bit, the matrix should also set and clear the
area warning key bit. (In addition, the audio for the tray may be coming
from the panel or from an area warning tone generator in the matrix. The
audio source is controlled by message sent by the panel.)

TR_WT is a bit that indicates a weather warning operation is being
performed with the tray. This means that instead of audio from the panel
being fed to the tray, the tray\'s audio comes from a weather warning
tone generator in the matrix.

The next two bits indicate operations that are requested between the
time the tray was released and when it actually became free. These
indicate that as soon as the tray is verified off (since it had already
been unkeyed when the request came in) it should be keyed in support of
another operation.

TR_PA indicates that a panel wants to use the tray in support of an area
warning operation.

TR_PW indicates that a panel wants to use the tray in support of a
weather warning operation.

TR_PRI indicates the priority of the page. All pages have an associated
priority. If a request comes in from a panel requesting a page at a
higher priority than the priority the tray is currently being used at,
the tray will be taken away from the panel currently using it and given
to the new, higher priority, panel.

If a page request comes in from a new panel that is the same or lower
priority than the current operation, the new request is rejected.

The current priority must be stored so the matrix can decide which panel
gets the tray when it is requested by two or more panels.

TR_OWN indicates which panel \"owns\" the tray. Normally the audio being
fed to the tray will come from the owning panel, but the audio source
may be one of the tone generators in the matrix.

In the event that a higher priority page request comes in, the owning
panel is sent a cutoff message, and the owner of the tray is changed to
the new panel.

The owning panel also serves to help the matrix decide when to send the
page request granted/page request rejected messages.

When a tray is taken off the VOF_CQ, the matrix looks at the TR_OWN
field to see which panel was waiting for the tray for a page. The
panel\'s record contains a list of all the trays that the panel needs
for its current page. The matrix will remove the tray it just verified
from the panel\'s tray map. When the last tray is removed from the
panel\'s tray map, the results of all of the tests are used to determine
what kind of page request response to send to the panel.

TR_TMR contains the time when the tray should reach its commanded state.
The tray will remain on one of the two pending lists until this time.

TR_CT contains a count of the number of panels waiting on the tray to
close. (The number of panels that are waiting on a zone select tray
test.) A tray can pass audio on behalf of only a single panel, but
several panels can request the tray be tested to see if it is
operational, so a bit map of the panels requesting the tray be tested is
stored in the tray record. When all of the panels requesting a tray test
have been notified of the results the tray can be released. (Unless a
panel is using the tray for a page.)

TR_TM is a bit map of the panels that have requested the tray be tested
in support of a zone selection by a panel operator.

Panel/tray structures

Size = 28 (PT_SZ)

Panel tray records: PTR_XX (ie PTR_00 - PTR_7F)

Offset SYM Function

0 PT_OP Op field

1 PT_BN Button number

2 PT_FL Flags

3 PT_BC Bit count

4 PT_DA Data area (24 bytes)

PT_OP values:

SYM Value Function

PT_TT 00 Tray test

PT_PG ff Page

Flag bits:

SYM Value Function

PT_TP 20 Tray(s) passed

PT_TF 80 Tray(s) failed

PT_AR 40 AW request

PT_WR 10 WW request

Panel tray records (PTR_XX) are used to keep track of what trays a panel
is working with, and what it\'s doing with them.

PT_OP is the operation field.

If the panel has requested a tray test, PT_OP will be PT_TT.

If the panel is performing a page, PT_OP will be PT_PG.

PT_BN is the button number.

This field is used for tray tests. When a panel operator presses a zone
select button, the panel sends a tray test request to the matrix. The
request contains the button number along with a list of trays assigned
to the button.

Button numbers consist of a row and a column packed into the upper and
lower nybble of a byte.

When the matrix returns the tray test results, it includes the button
number. (Internally, all panel operations are performed on maps, which
act as an index into tables in memory, but outside the panel, everything
is done in terms of button numbers. Map numbers are contiguous, button
numbers are not.)

PT_FL is the flags field. This consists of a number of bits that
indicate specific things.

PT_TP is a bit set if one or more trays have passed. This is used for
both tray tests and pages.

PT_TF is a bit set if one or more trays have failed. This is used for
both tray tests and pages.

PT_AR is a bit set if the page is an area warning request.

PT_WR is a bit set if the page is a weather warning request.

PT_BC is a count of the number of trays that are still waiting for test
results. It is a count of the number of bits set in the tray map field.

PT_DA is the data area. It contains a bit map of the trays that are
still waiting on test results.

When a tray reaches the time that its activation can be verified, its
state is checked, and one of the flags, PT_TP or PT_TF, is set, and the
bit is removed from the bit map and PT_BC is decremented.

When PT_BC reaches 0, the matrix sends a response to the panel based on
PT_TP, PT_TF, PT_OP and PT_AR and PT_WR.

(Different opcodes are used for normal pages, area warning pages and
weather warning pages.)

Error Tables

Error count table: E_TBL

Size = 64 (EC_SZ)

Offset SYM Function

0 ERR_00 Garbage in front of message

1 ERR_01 Unused

2 ERR_02 Unused

3 ERR_03 Unused

4 ERR_04 Unused

5 ERR_05 No response from matrix A

6 ERR_06 No response from matrix B

7 ERR_07 Invalid tray number in tracking write

8 ERR_08 Panel polling deletion error, panel not there

9 ERR_09 Invalid panel number in forwarding

10 ERR_0A Large buffer overflow, side A

11 ERR_0B Large buffer overflow, side B

12 ERR_0C Unused

13 ERR_0D Unused

14 ERR_0E Unused

15 ERR_0F Unused

16 ERR_10 Undefined tray state during page attempt

17 ERR_11 Free tray type undefined, page attempt

18 ERR_12 Active tray type undefined, page attempt

19 ERR_13 Attempt to release free tray

20 ERR_14 Tray type undefined during release

21 ERR_15 Invalid message from system console

22 ERR_16 Invalid write command

23 ERR_17 Invalid map number, write command

24 ERR_18 Invalid request

25 ERR_19 Invalid map number, read command

26 ERR_1A Illegal command

27 ERR_1B Message from panel not addressed to matrix/console

28 ERR_1C Invalid message type from panel

29 ERR_1D Invalid request from panel

30 ERR_1E Invalid command from panel

31 ERR_1F Invalid tracking number

32 ERR_20 Invalid message type

33 ERR_21 Invalid write command

34 ERR_22 Bad map number, zone write

35 ERR_23 Invalid response

36 ERR_24 Bad map number, tray test response

37 ERR_25 Invalid request

38 ERR_26 Invalid command

39 ERR_27 Invalid announcement

40 ERR_28 Unused

41 ERR_29 Unused

42 ERR_2A Unused

43 ERR_2B Unused

44 ERR_2C Unused

45 ERR_2D Unused

46 ERR_2E Unused

47 ERR_2F Unused

48 ERR_30 Not addressed to me

49 ERR_31 False start or corrupted length

50 ERR_32 Invalid EOM

51 ERR_33 Invalid CRC

52 ERR_34 Unused

53 ERR_35 Unused

54 ERR_36 Unused

55 ERR_37 Unused

56 ERR_38 Unused

57 ERR_39 Unused

58 ERR_3A Unused

59 ERR_3B Unused

60 ERR_3C Unused

61 ERR_3D Unused

62 ERR_3E Unused

63 ERR_3F Unused

The error count table contains a count of the number of errors of a
given type that have occurred since the table was last zeroed. (The
table is zeroed by any reset, and there is a command that will zero
several tables, including the error table.)

Each different type of error has its own position within the table. For
a list of the errors, look at ETYPE.H. Not all errors can occur on all
devices. As an example, the \"No response from matrix A\" errors occur
on the panels, and should not occur on either matrix.

The best way to determine exactly what each error \"means\" is to
examine where the error occurs in the source code. As an example, to
figure out what \"Undefined tray state during page attempt\" means, find
where ERR_10 occurs in the source code. (zgrep ERR_10 \*.asm while in
the root source directory, RS)

Interrupt handler error table: IHE_TBL

Size = 4 (IHE_SZ)

The interrupt handler error table records the count of certain errors
that are detected during dual UART interrupt handler execution.

Due to hardware constraints, we can\'t run the normal error recording
code for these errors. (You can\'t read from the XICOR chip while it\'s
in a programming cycle, or you\'ll corrupt the Xicor contents, so the
dual UART interrupt handlers live in a small block of EEPROM in the
CPU.)

The dual UART is used in the matrix for communication with the systems
consoles. The panel uses the dual UART for communications with the
matrices.

It is not unusual to get a break detected error when power is cycled on
the matrix or panel, or when cable connections are disturbed. Breaks
that occur at other times are usually signs of hardware related
communication link problems. Receive buffer overflows should never
occur.

Offset Function

0 Break detected, A side

1 Break detected, B side

2 Receive buffer overflow, A side

3 Receive buffer overflow, B side

Zone Map structures

Size = 25

A side zone maps: ZMXXA (ie ZM00A - ZM3FA)

B side zone maps: ZMXXB (ie ZM00B - ZM3FB)

Offset Function

0 Zone priority

1 Tray map, first byte

Zone maps are used to store panel configuration. Each zone map stores
the trays associated with one side of one zone select button. These are
recorded in the panel\'s Xicor chip. The system console performs a
download to record new zone maps when the configuration is altered.

Each zone select button has an associated priority, and a list of trays
assigned to that zone. A page can be performed with many zones selected.

When a page is performed, the panel looks at the zone maps for all of
the selected zones, and uses the highest priority it finds as the global
priority. All of the selected zone\'s trays are ORed together to
generate a global tray map. The global priority and global tray map are
used in the page request.

There are actually separate priorities and global tray maps for the A
side and the B side, since not all areas have redundant trays.

The system consoles must lock the panel before a new configuration can
be downloaded. If the panel is performing a page, or awaiting the
results of a tray test, it will wave off the lock and the download
cannot be performed.

If the panel is idle, the lock is performed. No other operations can be
performed while the panel is locked. A timer is started on the panel
when it is locked, and if the system console does not perform an unlock
within a reasonable amount of time (about 10 seconds for all panels
except the admin) the panel will unlock itself.

If the panel is not locked, any download messages that arrive are not
processed.

When the panel receives a download message, it checks the message
contents against the Xicor contents. If there is no difference, the
message is discarded. If the message and the Xicor differ, a write cycle
is initiated to program the Xicor.

After the zone record has been updated, the global priority and the
global tray maps are updated.

Zone Records

Size = 3 (ZR_SZ)

Zone lamp states: ZLSXX (ie ZLS00 - ZLS3F)

Offset SYM Function

0 ZS_OFF Zone State

1 ZT_OFF Time field

2 ZR_OFF Response byte

State values:

SYM Value Function

IN_OFF \$00 Indicator off

IN_ON \$01 Indicator on

IN_AWS \$80 AW selected

Response byte bits:

SYM Value Function

ZR_RST \$00 No responses

ZR_SAG \$80 Side A good

ZR_SAI \$40 Side A Illegal

ZR_SAP \$20 Side A partial

ZR_SAB \$10 Side A busy

ZR_SBG \$08 Side B good

ZR_SBI \$04 Side B Illegal

ZR_SBP \$02 Side B partial

ZR_SBB \$01 Side B busy

Zone records contain information about zone buttons and zone button
operation state.

ZS_OFF contains information about the zone button\'s lamp state and a
flag for an area warning select. (Which requires special processing.)

IN_ON indicates the zone button lamp is on.

IN_OFF indicates that the zone button lamp is off.

IN_AWS is ORed in when a zone selection is performed while the panel has
area warning tone active. (Normally, the panel will not allow any zone
select operations while audio is being routed to trays, but area warning
is a special case.)

ZT_OFF contains the time when all responses should have been received
from both matrices. When this time arrives, the panel checks the
responses it received from the matrices and leaves the lamp on, beeps
and leaves the lamp on, or beeps and turns the lamp off.

ZR_OFF contains flags that record the response received from each
matrix.

When the panel receives a page request response from the matrix, it
records the information in the ZR_OFF field. When the response timer
expires, the panel will check these flags.

There are two blocks of flags in this field, one for the A side, and one
for the B side. For the A side flags, the fifth character is A while
it\'s a B for the B side flags. As an example, ZR_SAG is the good flag
for the A side.

ZR_RST is the value recorded in ZR_OFF to clear the response byte.

ZR_SAG, ZR_SBG indicate that the page was good, that all the trays
requested are available and working.

ZR_SAI, ZR_SBI indicate that one or more trays in the panel\'s request
are not listed as being installed.

The matrix has a list of old style trays and a list of new style trays
that are installed. If a panel asks for a tray that does not appear on
one of these two lists, the matrix rejects the request as illegal. This
can happen if operations are performed during a download when the matrix
and the panels may have different configurations on them.

ZR_SAP, ZR_SBP indicate that one or more trays the panel requested are
not working. It is only sent if there is one or more trays that did
work.

In the event that there are no working trays in the panel\'s request,
the matrix sends a message indicating that there are no trays. There is
no bit in this field for this condition, as the occurrence is handled
the same as no matrix response. (In the event that there really isn\'t
any response received from a matrix, the panel code will bump the no
matrix response received error count. This count is not bumped if the
matrix sends a \"no trays\" response.)

ZR_SAB, ZR_SBB these values are not used in zone selects. They are used
for pages. (In other structures.)

Version Detection

SIG 2 bytes

MAGIC 2 bytes

The software compares these two values to determine if it needs to
reprogram the CPU EEPROM. The value is generated by running the CRC
across UART.ASM. If they differ, the CPU EEPROM is reprogrammed to
contain the new interrupt handlers.

(The interrupt handlers have to live in the CPU EEPROM because they have
to run during the 10 milliseconds of the Xicor programming cycle as you
can\'t read (and therefore can\'t run any code in) the Xicor during this
period. If interrupts were disabled for the time it takes to program the
Xicor, we would loose bytes coming from the matrix.)

Look up and translation tables

Zone Map Look up tables

64 words (128 bytes)

MAATAB, MABTAB

These tables are used to translate a map number into the address of a
zone map. (ZMXXA/ZMXXB) They are lists of addresses. Given a map number,
use it (the map number) as an index into the table to get the address of
the record for that map.

Zone Lamp State Look up table

64 words (128 bytes)

ZLMAP

This table is used to translate a zone lamp record number into the
address of a zone lamp record structure. (ZLSXX) Given a zone lamp
record number, use it to index into the table to get the address of the
actual zone lamp record.

Compressed zone number to map number translation tables

Size = 64 bytes

ADMZ2M, WRNZ2M, OPSZ2M

These tables are used to translate button numbers into map numbers. Pack
the 3 bits of the row number and the 3 bits of the column number from a
button number into the low order 6 bits of a byte. Use the result to
index into the table. The value fetched is the map number. The emergency
warning and area warning panels share a table.

Key scan code to map number translation tables

Size = 108 bytes

ADMK2M, WRNK2M, OPSK2M

The tables are used to translate a key scan code to a map number. The
zone select buttons are interfaced to the panel CPU through a keyboard
encoder. The keyboard encoder handles debouncing the contact closures,
and reports key hits via a scan code. The panel code uses the scan code
as an index into a table to fetch the map number, which is how all the
internal routines refer to a \"button.\" The table varies with the panel
type, because the actual mapping of button position to scan code varies
with the panel type due to wiring differences.

Map Number to button number translation tables

Size = 64 bytes

ADMM2B, WRNM2B, OPSM2B

These tables are used to translate a map number to a button number. When
the panel needs to communicate with the outside world it has to
translate the map number (which is how all internal operations refer to
a button) back into a button number. The panel code uses the map number
to index into this table to fetch the button number. Button numbers are
used in zone selects.

Button numbers are based on physical position on the panel, while map
numbers are \"logical\" button numbers that are mapped to the physical
button numbers.

Translation table addresses

2 bytes

ZMTAB, KMTAB, MBTAB

These values are set when the panel code determines what type of panel
it is running on. These are the addresses of tables used to do the
following translations:

ZMTAB Compressed Zone (button) to map number

KMTAB Key scan code to map number

MBTAB Map number to button number

There are actually several tables for translating button numbers to map
numbers, one for each type of panel. (The emergency warning panel and
area warning panels share most maps due to the zone select buttons being
wired the same way.)

ZMTAB, KMTAB and MBTAB are the addresses of the correct tables to use
for the panel the code is running on.

By setting up the variables in the initialization phase, we can avoid
code to test what type of panel the software is running on. This saves
considerable room in memory and execution time. During the
initialization phase the panel code checks to see what type of panel it
is running on, and records the panel type and then sets the table
variables.

Control byte

CTLB

SYM Value Function

ZLOCK \$80 Zone selections Locked

DL_A \$01 Download in progress, A side

DL_B \$02 Download in progress, B side

The control byte contains lock bits to prevent certain operations.

The zone lock bit, ZLOCK is set when a weather warning is initiated, and
it is cleared when the weather warning completes. (or is terminated.)

There are two download locks, one for the A side, DL_A, and one for the
B side, DL_B. DL_X (A or B depending on the side.) is set when the panel
goes into a download lock, and is cleared when the download unlock
command is received from the system console, or when the panel times out
without receiving an unlock command.

The weather warning tone is actually a type of page. Normally, the
operator will select his zones, then hit the weather warning tone
activate button. The weather warning tone is sent out, and the weather
warning tone lamp illuminates. When the weather warning lamp goes out on
the panel, the operator keys the microphone and makes the weather
announcement. When the announcement is completed, the operator releases
the mic PTT key, and the page terminates.

When the weather warning tone is activated on an emergency warning
panel, the panel sends a weather warning tone page request to the
matrices. The matrices pull in the trays listed in the request, and
route the output of the weather warning tone generator to the trays.

At the time the panel sent the weather warning tone page request to the
matrices, it also started a timer. The weather warning tone takes two
seconds to complete a full cycle. While the tone is active, the weather
warning tone lamp on the panel is illuminated. Two seconds after the
panel sent the weather warning tone page request, the panel will send a
tone release. This shuts off the weather warning tone, but does not
release the trays. Four seconds after the panel sent the weather warning
tone page request, it will send a page release to return the trays to
use. (If the cycle has not been overridden by the operator pressing the
mic PTT.)

During the four seconds of a weather warning cycle, zone selection
operations are locked by the ZLOCK bit. The weather warning tone can be
terminated before completion of a full cycle by overriding the tone with
mic audio.

PMOD

Panel mode

Indicates if the panel is hot or cold.

SYM Value Function

PHOT \$ff Panel Hot

PCLD \$00 Panel Cold

The operator at the system console can call up a display of any given
panel in the system. This display visually indicates the state of the
panel, including panel type, which zones are selected, and the state of
the special lamps. In order to keep the system console display up to
date while it is examining the panel, the panel is made \"hot.\" This is
accomplished by the system console sending a hot command to the panel.

A hot panel will send a notice to the system console every time a lamp
changes state. These messages are used to update the system console\'s
display of the panel so that the system console display tracks the
actual appearance of the panel.

When the system console display of the panel is terminated, the system
console sends a panel cold command to the panel. This causes the panel
to cease sending the lamp state updates to the system console.

(On area warning panels, any time the position of the area warning key
switch changes state, the panel will send a message to the system
console, wether the panel is hot or not. These changes appear in the
system console\'s log file.)

Lamp state change messages are only sent by hot panels in order to keep
down the number of messages the system must process. PAWS is limited by
the bandwidth of the link between the matrix and the system console, so
this traffic is kept to a minimum.

PNL_TYP

This indicates what type of panel it is

SYM Value Function

AW_PNL \$00 Area Warning

AD_PNL \$01 Administrative

EW_PNL \$02 Emergency Warning

OP_PNL \$03 Operational

When the panel code starts up, one of the tasks it performs before
entering the main loop is to determine and record the panel type.

Each panel has two lines that connect the CPU to the front panel. These
two lines carry the panel type ID. The CPU reads the panel ID lines, and
then records the information in the panel type byte. (It also sets up
pointers to several tables that vary based on the panel type.)

DUART transmitter variables

These variables are used for sending messages out the Dual UART. There
are two sets, one for the A side and one for the B side.

XA_BSA, XB_BSA 2 bytes

XA_BEA, XB_BEA 2 bytes

XA_BML, XB_BML 1 byte

XA_TS, XB_TS 1 byte

XX_BSA is the buffer status address. This variable contains the address
of the buffer status value.

Some messages transmitted will go to only one side of the system, and
others are sent to both sides.

There is only one output buffer. When a message must go to both sides
there is only one copy of the message but it is sent to both sides of
the dual UART.

When a message is being sent to both sides, the buffer can not be freed
until both sides are finished transmitting the buffer. The buffer status
byte keeps track of the status of the buffer.

Values are:

SYM Value Function

OUT_FR \$00 Free

OUT_BZ \$ff Busy

If the buffer status is OUT_BZ one or both of the sides of the dual UART
is still using the contents of the buffer, so the buffer can not be used
to hold a new message.

When both sides are done with the buffer (when the message is being sent
to both sides) the last one to finish will set the buffer status to
OUT_FR, which indicates that a new message can be copied to the buffer.

XX_BEA is the buffer extraction address. This is where the next byte to
be sent comes from.

The first byte of the message is written to the dual UART transmit
register and the transmit interrupts are enabled. Since the dual UART
used has an 8 byte buffer, as soon as the transmit interrupt is enabled,
a series of transmit interrupts will hit that load the next seven bytes
of the message into the dual UART transmit buffer. After that, as a
character is shifted out of the dual UART, a space becomes available in
the dual UART\'s transmit FIFO, and a transmit interrupt occurs, which
will load another byte.

The buffer extraction address field gives the address that the next byte
will be fetched from. The value is incremented each time a byte is read
from the buffer and sent to the dual UART.

XX_BML is the number of bytes in the message left to send.

This starts out as the message length and every time a byte is fetched
from the buffer this value is decremented.

When a transmit interrupt occurs, the interrupt handler will check
XX_BML. If XX_BML is zero, then the message has completed transmission.
In this case, the transmit interrupt for that side of the dual UART is
disabled. If the other side has completed (or was not being used) the
buffer is marked as free as well.

XX_TS is the transmitter status.

XX_TS indicates if that side of the dual UART is in use, or is free. The
transmitter status is marked as Idle as soon as the last byte of the
message has been transmitted. When both transmitters are idle, the
output buffer can be released.

The values are:

SYM Value Function

UTS_ID \$00 Idle (Free)

UTS_BZ \$ff Busy

SIDE

This indicates which side of the dual UART the last message was received
from.

(Please note that reading this value with pds sends a message to the
matrix or panel, and receipt of this message will indicate what side of
the device pds is talking to. It is much more useful when using the
logic analyzer of in-circuit emulator.)

The side the message came from becomes important when data needs to be
recorded in the XICOR, when errors need to be recorded, or when certain
messages need to be returned.

SYM Value

SIDE_A \$01

SIDE_B \$02

Global tray maps

Size = TT_LEN (24 bytes)

GMA,GMB,OGMA,OGMB,DGMA,DGMB

GMA,GMB are the global tray maps. Each zone button has a tray map for
the A side and for the B side. These trays are assigned to the zone
button by the system console. The console operator can edit a tray map
for any given button on any given panel. After adding and deleting trays
as desired, he can perform a download. The panel will record the new
tray map in the button\'s tray record.

For each selected button, the panel will add the trays associated with
that button to the global tray map for that side by ORing the button
tray map contents with the current global tray map. (The panel maintains
two global tray maps, one for the A side and one for the B side. Each
button has an A side record and a B side record.)

When the panel operator initiates a page request, the panel copies the
global tray map into the page request.

When the system console performs a download to a panel, the panel will
regenerate a new global tray map.

Normally, the zones that are selected can only change when there are no
pages going on, but in the event that the panel operator has initiated
an area warning, the system is required to allow the operator to select
and deselect zones while the area warning tone is flowing.

(The system will not allow zone selection and deselection while the
microphone is keyed, even when the panel is in area warning mode. The
only time you can select and deselect zones in area warning mode is when
the microphone is unkeyed and the trays are receiving audio from the
area warning tone generator.)

When area warning has been activated, the area warning tone can be
overridden by keying the microphone PTT. This causes the panel to send a
source select message to the matrices. The source select message does
not alter which trays are pulled in, but it does result in the audio
going to the trays to come from a different source.

When the microphone PTT switch is keyed the panel sends a source select
message switching the trays to the microphone audio from the panel. When
the PTT switch is released, the panel sends a source select message to
switch the tray\'s audio source back to the matrix\'s area warning tone
generator.

OGMA,OGMB are temporary copies of the global maps used in computing
deltas. (For AW mode zone selections and deselections while tone is
flowing.) When a zone is deselected while area warning tone is flowing,
the panel has to release the trays that had been in area warning mode,
but are no longer required.

You cannot simply send the contents of the button\'s tray map, because a
tray can appear on more than one button on a panel.

Instead, the panel copies the old (before the zone deselect) global tray
map to the temporary tray map. It then generates a new global tray map
based on the new set of selected zone buttons. (Without the newly
deselected zone button.)

Next it computes the difference between the two maps, and sends the
results as a page release.

This frees only those trays that were on the recently deselected button
that are not on any of the other selected zone buttons.

When a zone is selected while area warning tone is flowing, the panel
will copy the old (before the zone button selection takes affect) global
tray map to the temporary global tray map.

It then generates a new global tray map (Actually two, one for the A
side and one for the B side.) and computes the difference between the
two maps.

This delta contains only the trays that are on the new button that were
not on any of the other (selected) zone buttons.

Finally it sends this delta map as an area warning request to the
matrices.

DGMA,DGMB contain the differences (in selected trays) when doing zone
selects with AW Tone active.

In simple terms, they contain the delta tray maps after the panel has
computed new sets after a zone selection or deselection when area
warning tone is active. These maps are copied to the output message
buffer when the panel gets ready to send the tray release or page
requests.

LHTAB

Size = 130

This table keeps track of serial link failures.

When a message assembly error occurs, the entry in the link health table
is incremented.

On the matrix there is one entry for each panel plus one for each side
of the dual UART. The panels only use the DUART slots. (The matrix uses
the DUART to talk to the system consoles. On the panels, the DUART is
used to talk to the matrices.)

Panel 0 errors are stored in slot 0, while panel 127\'s error count is
stored in slot 127. The A side of the DUART\'s errors are stored in slot
in 128, while the B side errors are stored in slot 129.

This table is reset with the zero command. (Which also resets other
error tables.)

When the error count for any given link reaches 255, it stays there. (If
allowed to roll over, you may be fooled into believing that a link is
healthier than it really is.)

Examples of the type of errors that are recorded in the table include:
garbage bytes in the front of messages, invalid lengths, bad CRCs,
invalid/corrupted End Of Message, etc.

Tracking Trays

Size = 1 byte

TRG_TR, MON_TR, GBL_TR, NWA_TR

Each of these contains a tray number.

TRG_TR is the monitor input tray.

MON_TR is the monitor output tray.

NWA_TR is the global input tray.

GBL_TR is the global output tray.

In order to allow the system operators to monitor certain areas, PAWS
provides a way of monitoring the activity of any given tray.

To do this, the matrix software implements a monitor tray. The monitor
tray operates in parallel with the tray being monitored.

To define the operation, the system console needs to download the tray
number that the operators want to monitor to TRG_TR, the monitor input
tray. You also need to record the tray number the operators use to
monitor the activity by downloading a tray number to MON_TR, the monitor
output tray.

After these steps are performed, every time the TRG_TR is keyed, the
MON_TR tray will be keyed as well. Every time the TRG_TR is unkeyed, the
MON_TR is unkeyed as well. In addition to following the keying, the
MON_TR also gets the same audio that is routed to the TRG_TR.

GBL_TR. Another capability supplied by the system is a system activity
monitoring function.

With this feature, the system console downloads a tray number to the
global output tray, GBL_TR. The global output tray allows the operators
to monitor PAWS activity by always outputting the audio from the most
recent page.

Every time the matrix starts processing a page, it takes the first tray
used in the new page and records it in the newest available tray
variable, NWA_TR.

The global output tray is slaved to the NWA_TR just like the monitor
output tray is slaved to the monitor input tray. The only difference is
that the global tray is slaved to the newest available tray, which
changes each time a page is initiated.

(NWA_TR is stored in RAM since it changes so often. The three other tray
numbers are stored in EEPROM.)

Pull station tray lists

Size = 24

PSM_XX (ie PSM_00 - PSM_7f)

Each pull station (remote area warning panel) has an associated set of
trays that are affected when that station is activated.

The matrix is responsible for notifying all panels in the system of all
trays affected by area warning, whether panel initiated or pull station
initiated. In order to do this, the matrix requires a list of trays that
are affected by each pull station activation.

The panel sends a tray map to the matrix when it requests an area
warning, but the pull stations only provide active/inactive indications
to the matrix.

The system console is responsible for downloading a bit map of trays
affected by a pull station activation for each pull station in the
system.

The matrix builds a map of trays affected by area warning by ORing all
the trays affected by panel initiated area warnings with all the trays
affected by pull station activation. This map is sent to each panel
every time there is a change in the trays affected by area warnings.
(adding or removing trays from area warning mode)

The pull station tray maps are bit maps. When a pull station is
activated, you can tell which trays are affected by looking at its tray
map. If a bit is set, then the indicated tray will be in area warning
mode. (And the indicated tray will appear in the matrix\'s area warning
tray list.)

Pull Station Status

Size = 128 (PSMAX)

PS_ST

This table contains the status of the pull stations.

If a byte is TRUE (\$ff) then the pull station is active. If the byte is
FALSE (\$00) then the pull station is inactive.

This table is used to detect state changes of pull stations. Every time
there is a pull station state change, the matrix generates a new area
warning tray map. If there is any delta from the old area warning tray
map, the new, updated, area warning tray map is sent to all the panels.

The table also serves as input when building the list of trays affected
by pull station initiated area warnings.

Active Pull Station Count

Size = 1

PS_AC

This is the number of active pull stations. (Pull stations that are in
area warning mode.)

Active Area Warning Tray map

Size = 24 (TT_LEN)

AA_MAP, LA_MAP

These maps contain the trays that are in area warning mode.

AA_MAP trays are in area warning mode due to an area warning panel
activating them.

LA_MAP trays are in area warning mode due to a pull station being
activated.

AA_MAP is updated each time a panel initiates an area warning page, or
terminates an area warning page. This includes the operator selecting an
additional zone when area warning tone is active as this results in the
panel sending a new area warning page request with additional trays
listed.

Source selects that result from a panel\'s operator keying and unkeying
the microphone do not result in area warning tray maps being sent from
the matrices to the panels as this does not cause any changes in which
trays are involved in the area warning, only the source of audio being
distributed to the trays.

LA_MAP is updated each time a pull station changes state, both from
active to inactive and inactive to active.

The area warning tray maps the matrices distribute to the panels are
generated by ORing the AA_MAP with the LA_MAP.

Page count table

Size = 256 (MAXPNL \* 2)

PC_TBL

This table contains the number of pages that each panel has performed
since the last zero page count command.

Each count is a word, giving a max count of 65535. When the page count
maxes out, the matrix stops incrementing the page count for that panel
in order to keep the count from rolling over.

Matrix response flags

Size = 1

GOT_A, GOT_B

If the byte is FALSE (\$00) then no response was received from the
matrix for that side. If a response is received from the matrix, the
byte will be TRUE. (\$ff)

When a panel sends a request to the matrix, (either a tray test request,
or a page request) it resets both of these variables to FALSE. When a
response arrives from the matrix, the panel sets the variable for that
side to TRUE.

These results are checked when the panel\'s response timer expires,
which is the time that a matrix response should have been received by.

If no response is received from one or both matrices, the no matrix
response error count is incremented for the side or sides that failed to
respond.

LARGE buffer structures

Size = 2053 (LRG_SZ)

A side large buffer LBA

B side large buffer LBB

Offset SYM Function

0 LRG_ST Buffer state

1 LRG_IN Insertion index

3 LRG_EX Extraction index

5 LRG_BF Circular buffer (2048 bytes, LRG_DS)

LRG_ST values:

SYM Value Function

LRG_MT 00 Empty

LRG_PR 80 Partially filled

LRG_FL ff Full

The large buffers are used to buffer characters that are received from
the DUART. Received messages come in the DUART which has an 8 byte FIFO
built into it.

When a receive interrupt hits, the interrupt handler gets the character
from the DUART and saves it in a small circular buffer that holds 256
bytes. Because writes to the XICOR take so long, and a download can
require 135 writes, the circular buffer may overflow during a full
download.

In order to avoid the circular buffer from overflowing, in the outer
loop, before any time consuming operation is performed, the contents of
the circular buffer is moved into the large buffer.

The size of the circular buffer could have been increased, but due to
limitations of the 68HC11 instruction set, the code to store characters
into a larger buffer would have been larger and taken longer. Since the
interrupt handler is memory and time limited, this approach is not
practical.

The outer loop actually drains the circular buffers several times to
insure that the maximum amount of storage is available when we enter
code sections that may take a long time to execute.

The message assembly code actually goes to the large buffers to get
system console / matrix messages. (Because each panel has a 1K hardware
FIFO in the matrix, the matrix only uses the large buffers for the
system console messages.)

LRG_ST is the buffer status.

It has the values:

LRG_MT Empty

LRG_PR Partially filled

LRG_FL Full

LRG_IN is the insertion index.

LRG_IN indicates where the next byte should be stored. Note that the
buffer is used as a circular queue, so the insertion index wraps around
to 0 when it reaches the physical end of the buffer.

LRG_EX is the extraction index.

LRG_EX indicates where the next byte should be removed from the buffer.
It also wraps around to the beginning of the buffer when it reaches the
physical end of the buffer.

LRG_BF is the actual buffer itself.

VER

This buffer contains a null terminated ASCII string that gives the date
and time the code was linked to produce the version installed in the
matrix or panel in question.

SSS

Seconds Since Starting

4 bytes

This field gives an approximation of the number of seconds that the code
has been running.

The basic unit of time in PAWS is a 4 millisecond real time interrupt.
This is referred to as a tick. Every time a real time interrupt hits, a
variable, ticks, is incremented.

In the outer loop, a routine, CK_TMR, will process these ticks by
decrementing the ticks, and incrementing the tick count. The tick count
is our basic timer. The tick count is an 8 bit variable, and wraps from
255 to 0. Short duration intervals are based directly on the tick count,
while longer duration intervals are based on counts derived from the
tick count.As an example, the maximum interval for the tick count is
1.024 seconds.

For each 16 ticks, we bump a click counter. (KLIKS) Clicks give a
maximum time interval of 16.384 seconds. Clicks are used for download
lock timers, and other timers that require a duration in excess of a
second.

Finally, for every 16 clicks, we bump our seconds count. This results in
our second being 1024 milliseconds long, so the seconds since starting
is only an approximation.

SSS is a very useful variable to check to see if the system has hit any
snags. There is a watchdog timer that causes a reset when the code gets
wrapped, and most other error vectors, (such as illegal instruction)
also vector to a reset. This keeps the panel or matrix available, at the
danger of missing some bugs. For this reason, the panel and the matrix
code will send a reset message to the system console every time they go
through a reset. These messages can be lost if the console are not up
and running, so the seconds since starting gives you a backup method to
spot problems.

RST

2 bytes

Reason for last reset

When the CPU on a panel or a matrix goes through a reset, it will record
the reason for the reset in the reset variable. This is actually the
reset vector number and its complement. You can inspect this variable
and determine the reason for the reset by looking at an MC68HC11 manual.
You can also look at the file UART.ASM, which has a comment on each
vector in the table.

\_