summaryrefslogtreecommitdiff
path: root/xpp
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-11-28 13:36:03 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-11-28 13:36:03 +0000
commitd8bdfe8d82cf7c57b2a4061fc03b6e0a863064e1 (patch)
treeb67e786e441a4b6951e05552d533a924d5dacccf /xpp
parent6ecdbe426f0630c1ffb85e5e93758ae3e53aba22 (diff)
r1557@boole: tzafrir | 2006-11-06 20:12:16 +0200
Merging xpp driver release 1.2 (rev. 2569), originally team/tzafrir/xpp_1.2 * Should build well. Almost final. * genzaptelconf: Also work when zap_autoreg=0 * README.Astribank updated for rev. 1.2. * xpp/utils/Makefile: Use $< with cc -c * Get xpp/utils configuration from autoconf (without changesin top dir) git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@1648 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp')
-rw-r--r--xpp/Makefile16
-rw-r--r--xpp/README.Astribank326
-rwxr-xr-xxpp/calibrate_slics167
-rw-r--r--xpp/card_fxo.c548
-rw-r--r--xpp/card_fxo.h11
-rw-r--r--xpp/card_fxs.c593
-rw-r--r--xpp/card_fxs.h16
-rw-r--r--xpp/card_global.c149
-rw-r--r--xpp/card_global.h10
-rw-r--r--xpp/firmwares/FPGA_1151.hex576
-rw-r--r--xpp/firmwares/FPGA_FXS.hex (renamed from xpp/utils/FPGA_FXS.hex)0
-rw-r--r--xpp/firmwares/LICENSE.firmware (renamed from xpp/LICENSE.firmware)0
-rw-r--r--xpp/firmwares/README19
-rw-r--r--xpp/firmwares/USB_1130.hex (renamed from xpp/utils/USB_1130.hex)0
-rw-r--r--xpp/firmwares/USB_1150.hex308
-rwxr-xr-xxpp/init_card_3_23165
-rwxr-xr-xxpp/init_card_4_23143
-rw-r--r--xpp/init_data_3_19.cmd170
-rw-r--r--xpp/init_data_3_20.cmd173
-rw-r--r--xpp/init_data_4_19.cmd69
-rw-r--r--xpp/init_data_4_20.cmd64
-rwxr-xr-xxpp/initialize_registers77
-rw-r--r--xpp/slic.c176
-rw-r--r--xpp/slic.h81
-rw-r--r--xpp/utils/Makefile50
-rw-r--r--xpp/utils/USB_8613.hex301
-rw-r--r--xpp/utils/adj_clock.8144
-rw-r--r--xpp/utils/adj_clock.c228
-rw-r--r--xpp/utils/xpp_fxloader16
-rw-r--r--xpp/utils/xpp_fxloader.usermap4
-rw-r--r--xpp/xbus-core.c106
-rw-r--r--xpp/xbus-core.h6
-rw-r--r--xpp/xdefs.h15
-rw-r--r--xpp/xpd.h7
-rw-r--r--xpp/xpp_usb.c33
-rw-r--r--xpp/xpp_zap.c136
-rw-r--r--xpp/xpp_zap.h2
-rw-r--r--xpp/xproto.c46
-rw-r--r--xpp/xproto.h83
39 files changed, 2889 insertions, 2145 deletions
diff --git a/xpp/Makefile b/xpp/Makefile
index 3ecfdd9..bef84cf 100644
--- a/xpp/Makefile
+++ b/xpp/Makefile
@@ -1,9 +1,15 @@
-EXTRA_CFLAGS = -I$(SUBDIRS) -DDEBUG -DPOLL_DIGITAL_INPUTS -DWITH_ECHO_SUPPRESSION # -DSOFT_RING
+EXTRA_CFLAGS = -g3 -I$(SUBDIRS) -DDEBUG -DPOLL_DIGITAL_INPUTS -DWITH_ECHO_SUPPRESSION # -DSOFT_RING
-obj-m = xpp.o xpp_usb.o xpd_fxs.o xpd_fxo.o
-xpp-y += xbus-core.o xpp_zap.o xproto.o card_global.o
-xpd_fxs-y += card_fxs.o slic.o
-xpd_fxo-y += card_fxo.o slic.o
+obj-m += xpp.o xpd_fxs.o xpd_fxo.o
+
+# Build only supported modules
+ifneq (,$(filter y m,$(CONFIG_USB)))
+obj-m += xpp_usb.o
+endif
+
+xpp-y += xbus-core.o xpp_zap.o xproto.o card_global.o
+xpd_fxs-y += card_fxs.o
+xpd_fxo-y += card_fxo.o
ctags:
ctags *.[ch]
diff --git a/xpp/README.Astribank b/xpp/README.Astribank
index f6f995c..e45bde9 100644
--- a/xpp/README.Astribank
+++ b/xpp/README.Astribank
@@ -9,30 +9,20 @@ installing Zaptel with some additions.
Building drivers:
""""""""""""""""
-From the toplevel zaptel directory run a command similar to (I used line
-continuation to prevent line wrapping):
-
- $ make \
- KSRC=/usr/src/kernel-headers-2.6.12-1-386 \
- KVERS=2.6.12-1-386 \
- XPPMOD=xpp/ \
- EC_TYPE=CAN_KB1
-
- - The KSRC= points to a configured kernel source tree.
- - The KVERS= should match the relevant tree version.
- - The XPPMOD= instructs the Zaptel Makefile to descend into the xpp/
- subdirectory. The slash (/) in the end is mandatory.
- - The EC_TYPE= select the echo canceler.
-
-Building firmware utilities:
-"""""""""""""""""""""""""""
-Then you should compile the firmware loading utilities. Simply go
-to the zaptel/xpp/utils and run make.
-
-Those who don't use prepackaged drivers should make sure they also
-install the (externally available) fxload utility.
-
-Installation:
+Unlike earlier versions, the Astribank driver (xpp) will now build
+automatically. To build the drivers follow the usual Zaptel
+documentation. E.g: run:
+
+ make
+
+in the top-level directory.
+
+Next you will need to build the user-space tools needed for loading the
+firmware and initialization files for the Astribank:
+
+ make -C xpp/utils
+
+INSTALLATION:
""""""""""""
apart from the standard 'make install' in the zaptel directory,
@@ -45,7 +35,7 @@ Alternatively, do the following manually:
All firmware files should be copied to a new directory:
/usr/share/zaptel/
-The xpp_fxloader and xpp_fxloader.usbmap should be copied to:
+The xpp_fxloader and xpp_fxloader.usermap should be copied to:
/etc/hotplug/usb/
In addition, the file xpp/xpp_modprobe contains optional modprobe settings.
@@ -55,48 +45,242 @@ It may be copied verbatim into /etc/modprobe.conf or (better) copied to
Note that loading through udev is not yet provided. Run
- /etc/hotplug/usb/xpp_fxloader xppdetect
+ /etc/hotplug/usb/xpp_fxloader load
to load firmware.
+The FXS calibration script requires the perl module Time::HiRes. This
+modules is already packaged for most distributions including Debian, Fedora,
+RedHat and CentOS. To test for the existance of this module run:
+ perl -MTime::HiRes -e ''
-Loading Firmware Details:
-""""""""""""""""""""""""
-The Astribank needs a firmware loaded into it. Without the firmware,
-the device will appear in lsusb with vendor ID 04b4 and product ID 8613
-The firmware is provided in the Intel hex format. It can be loaded using
-the program fxload, which is typically part of the package 'fxload' or
-'hotplug-utils' .
+This should run cleanly (without output) if the module exists and issue
+a long error message otherwise. At least in RedHat, CentOS and Fedora-2
+until Fedora-5 it is in a package named perl-Time-HiRes. In Debian and
+Fedora-6 it is bundled with perl.
-To load the firmware automatically using the standard hotplug script,
-place xpp/utils/xpp_fxloader and xpp/utils/xpp_fxloader.usermap in
-/etc/hotplug/usb and place xpp/utils/*.hex in /usr/share/zaptel .
-Alternatively, xpp_fxloader when given the parameter 'xppdetect' will load
-the firmwares from /usr/share/zaptel/ . You can use it to load the
-firmware manually.
+DEVICE STARTUP:
+""""""""""""""
-You should then get in lsusb the vendor ID e4e4 and device ID 2121
-(those IDs are temporary and likely to change in upcoming versions).
-Once there is such a device, the xpp_usb driver should load
-automatically on hot-plugging. In fact, you may find it simpler to
-disconnect and reconnect the device than running 'modprobe xpp_usb'.
+Terminology:
+"""""""""""
+Some technical terms that are used throughout the document and in the
+driver / zaptel . Only used in the technical parts.
+span:
+Zaptel breaks the channels it knows bout to logical units called
+"spans". A port in a E1/T1/ISDN card is usually a span. So is a complete
+analog card. You can see the list of spans as the list of files under
+/proc/zaptel or the list in zttool.
-The driver has been separated into several modules: xpp.ko, xpd_fxs.ko and
-xpp_usb.ko . Generally you only need to modprobe xpp_usb, and it should also
-be loaded by hotplug when you connect the Astribank. However in order for it
-to load xpd_fks.ko correctly
+XBUS:
+A funny way to call an Astribank device.
-Refer to the instructions for Zaptel. After our small patches were applies,
-you get xpp.ko which is basically yet another zaptel driver, like wcfxo
-and wctdm.
+XPD:
+This is basically a logical unit of the Astribank. It will be registered to
+Zaptel as a single span. This will basically be 8 analog channels.
+
+
+Loading Firmware:
+""""""""""""""""
+Normally this is done using the script xpp_fxloader.If it works fine,
+you don't need to bother reading this section.
+Once the firmware is loaded the USB ID of the Astribank changes to e4e4
+1132, and the driver can pick it up. You'll also see the top led lit.
+
+First and foremost: the simplest and most useful tool to debug problems
+here is lsusb. The output of lsusb should show exactly if the device is
+connected and if its firmware is loaded.
+
+The firmware files are named *.hex. The are in the Intel hex format
+(read: plain text, but not readable) that is copied at install time from
+xpp/utils to /usr/share/zaptel .
+
+The Astribank needs a firmware loaded into it. Without the firmware,
+the device will appear in lsusb with vendor ID e4e4 and product ID 1130.
+The firmware is loaded in two stages. In the first stage we load the
+"USB" firmware using the program fxload. After the first stage the USB
+ID is e4e4 1131. In the second stage we load the "FPGA" firmware.
+
+The first is done using the the program fxload. To load it manually, use
+the command:
+
+ fxload -t fx2 -D /proc/bus/usb/MMM/NNN -I /usr/share/zaptel/USB_1130.hex
+
+fxload is standard program that is typically part of the package 'fxload'
+or 'hotplug-utils' . /proc/bus/usb is the mount point of the USB
+file-system (usbfs). MMM is the first number (bus number) and NNN is the
+second number (device number) you see for the device in lsusb, with full
+3 digits. If the load is successful, the device disconnects and
+reconnects with USB product ID 1131 (and a new device number).
+
+The second-stage loader is done using the program fpga_load, which is
+built in the directory xpp/utils and installed to /usr/sbin/fpga_load .
+Its syntax is based on fxload. To load with it manually, use:
+
+ fpga_load -D /proc/bus/usb/MMM/NNN -I /usr/share/zaptel/FPGA_FXS.hex
+
+Note that as the device has reconnected, it now has a new device
+number. So you need to re-check the value of NNN with lsusb. Typically
+this will be the old value + 1.
+
+
+Firmware Loading with UDEV:
+""""""""""""""""""""""""""
+Firmware loading with udev should work but is not installed
+automatically, yet. See the comments in the beginning of the script
+/etc/hotplug/usb/xpp_fxloader .
+
+Loading The Modules:
+"""""""""""""""""""
+Here is what should happen:
+In short: you should plug it or have it plugged at boot time, and all
+the modules should load. You will see xpp_usb , xpd_fxs and possibly
+xpd_fxo in the modules list (the output of lsmod).
+
+After the module xpp is loaded, you'll also be able to see the directory
+/proc/xpp . For any Astribank discovered there you will see a directory
+/prc/xpp/XBUS-n (where n is a number: typically 0). Once a unit have
+been discovered you'll see subdirectories: /proc/xpp/XBUS-n/XPD-m (where
+m may be another number: 0, 1 ,etc).
+
+Now to the ugly details:
+
+The driver of the Astribank is composed of several modules: xpp is the
+basic one, that contains the functionality to connect to Zaptel and other
+common functions. xpd_fxs is the module for controlling FXS spans.
+xpd_fxo is the module for controlling FXO spans. xpd_usb is the module
+that holds the functionality needed to connect to the USB bus.
+
+All modules depend on xpp, and modprobing them will install xpp as well.
+However the xpd_* modules are only installed on-demand: no need to
+install xpd_fxo if you only have FXS Astribank.
+
+You either plug in the Astribank , or start the hotplug/udev system
+while an Astribank is connected, after the firmware is loaded. The
+Vendor-ID/Product-ID of the device is e4e4/1132 . The handler for that
+combination is listed as the kernel module xpp_usb . Thus the system
+runs 'modprobe xpp_usb' if that module is not already loaded.
+
+The module xpp_usb depends on the modules zaptel and xpp . Both of which
+are loaded before xpp_usb is loaded. As usual, parameters and rules form
+/etc/modprobe.conf and/or /etc/modprobe.d/* will apply to the module, as
+modprobe is used.
+
+The modules to handle the specific span types (xpd_fxs, xpd_fxo) may or
+may not have been loaded yet at this stage (when the command 'modprobe
+xpp_usb' returns).
+
+At this point the xpp driver asks the box what logical units it has.
+According to the answers it gets, it will figure what xpd_* modules it will
+need, and modprobe for them. At some earlier version of the driver this has
+required some special modprobe.conf setup, but this is no longer
+the case.
+
+
+Device Initializations Scripts:
+""""""""""""""""""""""""""""""
+The chips in the device need to be initialized. This involves sending a
+bunch of values to certain registers in those chips. We decided that
+hardwiring those values in the driver itself would not be a good idea.
+
+before registering a XPD as a span in Zaptel, we run an initialization
+script: /usr/share/zaptel/initialize_registers . If this fails (e.g:
+because the script is not there, or is not executable), you will get an
+error message in the logs [FIXME: quote error message] that the
+invocation has failed. The XPD will then be removed (you won't see that
+a directory for that XPD under the relevant /proc/xpp/XBUS-* directory)
+and not be registered with Zaptel.
+
+Registering With Zaptel:
+"""""""""""""""""""""""
+Now we finally got to the "lights party" part: the lights in a unit
+(XPD) get lit before it registers with Zaptel and are turned off after
+that.
+
+You may choose not to register the XPDs to Zaptel automatically, to
+allow finer control of the process. This is done using the module
+parameter zap_autoreg. Set in the modprobe configuration file (e.g:
+/etc/modprobe.conf ) the line:
+
+ options xpp zap_autoreg=0
+
+to disable automatic registration at startup. You will then need to
+register the spans manually.
+
+
+SAMPLE CONFIGURATIONS:
+""""""""""""""""""""""
+
+/etc/zaptel.conf:
+
+ Astribank 8:
+
+ fxoks=1-14
+
+ Astribank 16: 8FXS/8FXO
+
+ fxoks=1-14
+ fksks=15-22
+
+/etc/asterisk/zapata.conf
+
+ Astribank 8:
+
+ [channels]
+ signalling=fxo_ks
+ ; The real analog ports:
+ context=from-internal
+ ; echocancel=yes
+ ; echocancelwhenbriged=yes
+ ; echotraining=9
+ channel => 1-8
+
+ ; output ports:
+ context=astribank-outputs
+ channel => 9-10
+ ; input ports:
+ immediate=yes
+ context=astribank-inputs
+ channel => 11-14
+ immediate=no
+
+ Astribank 16: 8FXS/8FXO
+
+ [channels]
+ signalling=fxo_ks
+ ; The real analog ports:
+ context=from-internal
+ ; echocancel=yes
+ ; echocancelwhenbriged=yes
+ ; echotraining=9
+ channel => 1-8
+
+ ; output ports:
+ context=astribank-outputs
+ channel => 9-10
+ ; input ports:
+ immediate=yes
+ context=astribank-inputs
+ channel => 11-14
+ immediate=no
+
+ ; FXO ports
+ signalling=fxs_ks
+ context=from-pstn
+ callerid=asreceived
+ channel => 15-22
+
+See also the output of genzaptelconf for examples of mailbox and
+callerid, and for channel numbers that will match your specific settings.
+For that reason I only give the above two sample configurations.
When loaded, you should get one span, of 8 extensions, 2 output ports and
4 input ports:
root@rapid:~# cat /proc/zaptel/2
- Span 1: XBUS-0/XPD-0 "Xorcom XPD #0/0: FXS" NOTOPEN
+ Span 1: XBUS-0/XPD-0 "Xorcom XPD #0/0: FXS"
1 XPP_FXS/0-0 FXOKS (In use)
2 XPP_FXS/0-1 FXOKS (In use)
@@ -113,36 +297,6 @@ When loaded, you should get one span, of 8 extensions, 2 output ports and
13 XPP_IN/0-12 FXOKS (In use)
14 XPP_IN/0-13 FXOKS (In use)
-For such a simple case you could use:
-
-/etc/zaptel.conf:
-
-fxoks=1-14
-loadzone=us
-tonezone=us
-
-/etc/asterisk/zapata.conf:
-
-[channels]
-group=1
-signalling=fxo_ks
-immediate=no
-
-context=from-internal
-channels => 1-8
-
-; actually they will never generate calls, so the context
-; here is irrelevant
-;context=outputs
-channels => 9-10
-
-; input ports should get an answer:
-immediate=yes
-context=inputs
-channels => 11-14
-
-;;;;;; end of zapata.conf
-
/proc Interface
"""""""""""""""
@@ -183,10 +337,10 @@ Unsetting this could be useful if you have several Astribanks and you
want to set their registration order manually using zt_registration in
the /proc interface.
-initialize_registers (xpd_fxs)
-The script that is run to initilize registers of the device. The default is
-/usr/share/zaptel/initialize_registers .
-Setting this value could be useful if that location is inconvient for you.
+initdir: (xpp)
+This is the directory containing the initialization scripts.
+The default is /usr/share/zaptel .
+Setting this value could be useful if that location is inconvenient for you.
print_dbg: (all modules)
It will make the driver print tons of debugging messages. Can be sometime
diff --git a/xpp/calibrate_slics b/xpp/calibrate_slics
index f5b45f3..72ca202 100755
--- a/xpp/calibrate_slics
+++ b/xpp/calibrate_slics
@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
#
-# $Id:$
+# $Id$
#
use strict;
@@ -22,7 +22,6 @@ sub logger($) {
sub write_to_slic_file($) {
my $write_str = shift;
- #print STDERR "[Writing string]\n".$write_str."[End String]\n";
open(SLICS,">$SlicsFile") or
die("Failed writing to slics file $SlicsFile");
@@ -38,19 +37,19 @@ sub read_reg($$$) {
my $direct = shift;
write_to_slic_file(
- sprintf("%02x 00 00 00 R%s %02X",
- 1<<$read_slic, $direct, $read_reg));
+ sprintf("%d R%s %02X", $read_slic, $direct, $read_reg));
sleep(0.001);
open(SLICS,$SlicsFile) or
die("Failed reading from slics file $SlicsFile");
+ #awk '/^SLIC_REPLY:/{print $5}' $SLICS | cut -dx -f2
my @reply = ();
while(<SLICS>){
- #if (/^[^#]/) {
+ #if (/^ /) {
# print STDERR "answer line: $_";
#}
- if (/^SLIC_REPLY:\s+[DI]\s+reg_num=0x[[:xdigit:]]+,\s+dataH=0x([[:xdigit:]]+)\s+dataL=0x([[:xdigit:]]+)/){
+ if (/^ \d*\s+[RW][DIS]\s+[[:xdigit:]]+\s+([[:xdigit:]]+)\s+([[:xdigit:]]+)/){
@reply = (hex($1), hex($2));
- #print STDERR "got [@reply]\n";
+ #print STDERR "got [$reply]\n";
last;
}
}
@@ -58,7 +57,7 @@ sub read_reg($$$) {
if ($direct eq 'I') {
return @reply;
} else {
- return $reply[1];
+ return $reply[0];
}
}
@@ -70,28 +69,11 @@ sub write_reg{#($$$$$) {
my $reg_val_low = shift;
my $reg_val_hi = shift;
- my $str = sprintf "%02x 00 00 00 W%s %02X %02X",
- 1<<$read_slic, $direct, $read_reg, $reg_val_low;
+ my $str = sprintf "%d W%s %02X %02X",
+ $read_slic, $direct, $read_reg, $reg_val_low;
if ($direct eq 'I') {
$str .= sprintf " %02X", $reg_val_hi;
}
- #printf STDERR "Writing: $str\n";
- write_to_slic_file($str);
-}
-
-# TODO: rearange arguments
-sub write_reg_all_slics{#($$$$) {
- my $read_reg = shift;
- my $direct = shift;
- my $reg_val_low = shift;
- my $reg_val_hi = shift;
-
- my $str = sprintf "FF FF 00 00 W%s %02X %02X",
- $direct, $read_reg, $reg_val_low;
- if ($direct eq 'I') {
- $str .= sprintf " %02X", $reg_val_hi;
- }
- printf STDERR "Writing: $str\n";
write_to_slic_file($str);
}
@@ -107,81 +89,81 @@ sub log_calib_params() {
sub init_indirect_registers() {
return write_to_slic_file("#
-FF FF 00 00 WI 00 C2 55
-FF FF 00 00 WI 01 E6 51
-FF FF 00 00 WI 02 85 4B
-FF FF 00 00 WI 03 37 49
+31 WI 00 C2 55
+31 WI 01 E6 51
+31 WI 02 85 4B
+31 WI 03 37 49
-FF FF 00 00 WI 04 33 33
-FF FF 00 00 WI 05 02 02
-FF FF 00 00 WI 06 02 02
-FF FF 00 00 WI 07 98 01
+31 WI 04 33 33
+31 WI 05 02 02
+31 WI 06 02 02
+31 WI 07 98 01
-FF FF 00 00 WI 08 98 01
-FF FF 00 00 WI 09 11 06
-FF FF 00 00 WI 0A 02 02
-FF FF 00 00 WI 0B E5 00
+31 WI 08 98 01
+31 WI 09 11 06
+31 WI 0A 02 02
+31 WI 0B E5 00
-FF FF 00 00 WI 0C 1C 0A
-FF FF 00 00 WI 0D 30 7B
-FF FF 00 00 WI 0E 63 00
-FF FF 00 00 WI 0F 00 00
+31 WI 0C 1C 0A
+31 WI 0D 30 7B
+31 WI 0E 63 00
+31 WI 0F 00 00
-FF FF 00 00 WI 10 70 78
-FF FF 00 00 WI 11 7D 00
-FF FF 00 00 WI 12 00 00
-FF FF 00 00 WI 13 00 00
+31 WI 10 70 78
+31 WI 11 7D 00
+31 WI 12 00 00
+31 WI 13 00 00
-FF FF 00 00 WI 14 F0 7E
-FF FF 00 00 WI 15 60 01
-FF FF 00 00 WI 16 00 00
-FF FF 00 00 WI 17 00 20
+31 WI 14 F0 7E
+31 WI 15 60 01
+31 WI 16 00 00
+31 WI 17 00 20
-FF FF 00 00 WI 18 00 20
-FF FF 00 00 WI 19 00 00
-FF FF 00 00 WI 1A 00 20
-FF FF 00 00 WI 1B 00 40
+31 WI 18 00 20
+31 WI 19 00 00
+31 WI 1A 00 20
+31 WI 1B 00 40
-FF FF 00 00 WI 1C 00 10
-FF FF 00 00 WI 1D 00 36
-FF FF 00 00 WI 1E 00 10
-FF FF 00 00 WI 1F 00 02
+31 WI 1C 00 10
+31 WI 1D 00 36
+31 WI 1E 00 10
+31 WI 1F 00 02
-FF FF 00 00 WI 20 C0 07
-FF FF 00 00 WI 21 00 26
-FF FF 00 00 WI 22 F4 0F
-FF FF 00 00 WI 23 00 80
+31 WI 20 C0 07
+31 WI 21 00 26
+31 WI 22 F4 0F
+31 WI 23 00 80
-#FF FF 00 00 WI 24 20 03
-#FF FF 00 00 WI 25 8C 08
-#FF FF 00 00 WI 26 00 01
-#FF FF 00 00 WI 27 10 00
+#31 WI 24 20 03
+#31 WI 25 8C 08
+#31 WI 26 00 01
+#31 WI 27 10 00
-FF FF 00 00 WI 24 00 08
-FF FF 00 00 WI 25 00 08
-FF FF 00 00 WI 26 00 08
-FF FF 00 00 WI 27 00 08
+31 WI 24 00 08
+31 WI 25 00 08
+31 WI 26 00 08
+31 WI 27 00 08
-FF FF 00 00 WI 28 00 0C
-FF FF 00 00 WI 29 00 0C
-FF FF 00 00 WI 2B 00 01
+31 WI 28 00 0C
+31 WI 29 00 0C
+31 WI 2B 00 01
-FF FF 00 00 WI 63 DA 00
-FF FF 00 00 WI 64 60 6B
-FF FF 00 00 WI 65 74 00
-FF FF 00 00 WI 66 C0 79
+31 WI 63 DA 00
+31 WI 64 60 6B
+31 WI 65 74 00
+31 WI 66 C0 79
-FF FF 00 00 WI 67 20 11
-FF FF 00 00 WI 68 E0 3B
+31 WI 67 20 11
+31 WI 68 E0 3B
#");
}
sub init_early_direct_regs() {
return write_to_slic_file("#
-FF FF 00 00 WD 08 00
-FF FF 00 00 WD 4A 34
-FF FF 00 00 WD 4B 10
-FF FF 00 00 WD 40 00
+31 WD 08 00
+31 WD 4A 34
+31 WD 4B 10
+31 WD 40 00
#")
}
@@ -221,7 +203,7 @@ sub manual_calibrate_loop($$) {
# start calibration:
my $calibration_in_progress = 1;
- write_reg_all_slics($write_reg, 'D', 0x1F);
+ write_reg(31, $write_reg, 'D', 0x1F);
sleep $ManualCalibrationSleepTime;
# wait until all slics have finished calibration, or for timeout
@@ -256,9 +238,9 @@ sub auto_calibrate($$) {
# start calibration:
write_to_slic_file(
sprintf
- "FF FF 00 00 WD 61 %02X\n".
- "FF FF 00 00 WD 60 %02X\n".
- "", $calib_97, $calib_96
+ "31 WD 61 %02X\n".
+ "31 WD 60 %02X\n".
+ "", $calib_96, $calib_97
);
# wait until all slics have finished calibration, or for timeout
@@ -267,19 +249,16 @@ sub auto_calibrate($$) {
CALIB_LOOP: for my $slic (@SlicNums) {
logger("checking slic $slic");
while(1) {
- my $reply;
- if (($reply=read_reg($slic, 96, 'D')) == 0) {
+ if ((read_reg($slic, 60, 'D')) == 0) {
# move to next register
logger("slic $slic calibrated");
last;
}
- print STDERR "reply: $reply\n";
my $time=time();
if ( $time > $end_time) {
$timeout=1;
- logger("Exiting on timeout: $time is after timeout $end_time .");
- exit 1;
- #last CALIB_LOOP;
+ logger("Exiting on timeout: $end_time < $time.");
+ last CALIB_LOOP;
}
logger("auto_calibrate not done yet: slic #$slic\n");
sleep(0.1);
diff --git a/xpp/card_fxo.c b/xpp/card_fxo.c
index ed77684..7672db3 100644
--- a/xpp/card_fxo.c
+++ b/xpp/card_fxo.c
@@ -33,8 +33,8 @@
static const char rcsid[] = "$Id$";
-DEF_PARM(int, print_dbg, 0, "Print DBG statements"); /* must be before zap_debug.h */
-DEF_PARM(uint, poll_battery_interval, 100, "Poll battery interval in milliseconds");
+DEF_PARM(int, print_dbg, 0, "Print DBG statements");
+DEF_PARM(uint, poll_battery_interval, 100, "Poll battery interval in milliseconds (0 - disable)");
DEF_PARM(bool, report_battery, 0, "Report battery status to zaptel");
/* Signaling is opposite (fxs signalling for fxo card) */
@@ -54,22 +54,30 @@ enum fxo_leds {
#define BAT_THRESHOLD 3
#define BAT_DEBOUNCE 3 /* compensate for battery voltage fluctuation (in poll_battery_interval's) */
+static /* 0x0F */ DECLARE_CMD(FXO, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high);
+/* Shortcuts */
+#define DAA_WRITE 1
+#define DAA_READ 0
+#define DAA_DIRECT_REQUEST(xbus,xpd,chipsel,writing,reg,dL) \
+ CALL_PROTO(FXO, REGISTER_REQUEST, (xbus), (xpd), (chipsel), (writing), 0, (reg), 0, (dL), 0)
+
+#define VALID_CHIPSEL(x) (((chipsel) >= 0 && (chipsel) <= 7) || (chipsel) == ALL_CHANS)
+
/*---------------- FXO Protocol Commands ----------------------------------*/
-static /* 0x0F */ DECLARE_CMD(FXO, CHAN_ENABLE, xpp_line_t lines, bool on);
-static /* 0x0F */ DECLARE_CMD(FXO, CHAN_CID, int pos);
-static /* 0x0F */ DECLARE_CMD(FXO, RING, int pos, bool on);
+static /* 0x0F */ DECLARE_CMD(FXO, XPD_STATE, bool on);
+static /* 0x0F */ DECLARE_CMD(FXO, CHAN_CID, lineno_t chan);
+static /* 0x0F */ DECLARE_CMD(FXO, RING, lineno_t chan, bool on);
static /* 0x0F */ DECLARE_CMD(FXO, RELAY_OUT, byte which, bool on);
-static /* 0x0F */ DECLARE_CMD(FXO, DAA_QUERY, int pos, byte reg_num);
static bool fxo_packet_is_valid(xpacket_t *pack);
-static void fxo_packet_dump(xpacket_t *pack);
+static void fxo_packet_dump(const char *msg, xpacket_t *pack);
static int proc_fxo_info_read(char *page, char **start, off_t off, int count, int *eof, void *data);
-static int proc_xpd_slic_read(char *page, char **start, off_t off, int count, int *eof, void *data);
-static int proc_xpd_slic_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
-static int process_slic_cmdline(xpd_t *xpd, char *cmdline);
+static int proc_xpd_register_read(char *page, char **start, off_t off, int count, int *eof, void *data);
+static int proc_xpd_register_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
+static int handle_register_command(xpd_t *xpd, char *cmdline);
-#define PROC_DAA_FNAME "slics"
+#define PROC_REGISTER_FNAME "slics"
#define PROC_FXO_INFO_FNAME "fxo_info"
#ifdef SOFT_RING
@@ -80,11 +88,9 @@ static int process_slic_cmdline(xpd_t *xpd, char *cmdline);
#define DAA_RING_REGISTER 0x05
struct FXO_priv_data {
- struct proc_dir_entry *xpd_slic;
+ struct proc_dir_entry *regfile;
struct proc_dir_entry *fxo_info;
uint poll_counter;
- slic_reply_t requested_reply;
- slic_reply_t last_reply;
xpp_line_t battery;
ushort battery_debounce[CHANNELS_PERXPD];
xpp_line_t ledstate[NUM_LEDS]; /* 0 - OFF, 1 - ON */
@@ -119,42 +125,29 @@ void MARK_LED(xpd_t *xpd, lineno_t pos, byte color, bool on)
/*
* LED control is done via DAA register 0x20
*/
-static int do_led(xpd_t *xpd, lineno_t pos, byte which, bool on)
+static int do_led(xpd_t *xpd, lineno_t chan, byte which, bool on)
{
int ret = 0;
- xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
struct FXO_priv_data *priv;
- xpp_line_t lines;
xbus_t *xbus;
BUG_ON(!xpd);
xbus = xpd->xbus;
priv = xpd->priv;
which = which % NUM_LEDS;
- if(IS_SET(xpd->digital_outputs, pos) || IS_SET(xpd->digital_inputs, pos))
+ if(IS_SET(xpd->digital_outputs, chan) || IS_SET(xpd->digital_inputs, chan))
goto out;
- if(pos == ALL_LINES) {
- lines = ~0;
+ if(chan == ALL_CHANS) {
priv->ledstate[which] = (on) ? ~0 : 0;
} else {
- lines = BIT(pos);
if(on) {
- BIT_SET(priv->ledstate[which], pos);
+ BIT_SET(priv->ledstate[which], chan);
} else {
- BIT_CLR(priv->ledstate[which], pos);
+ BIT_CLR(priv->ledstate[which], chan);
}
}
- if(!lines) // Nothing to do
- goto out;
- DBG("%s/%s: LED: lines=0x%04X which=%d -- %s\n", xbus->busname, xpd->xpdname, lines, which, (on) ? "on" : "off");
- XPACKET_NEW(pack, xbus, FXO, DAA_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXO, DAA_WRITE, slic_cmd);
- len = slic_cmd_direct_write(sc, lines, 0x20, on);
- // DBG("LED pack: line=%d %s\n", i, (on)?"on":"off");
- pack->datalen = len;
- packet_send(xbus, pack);
+ DBG("%s/%s/%d: LED: which=%d -- %s\n", xbus->busname, xpd->xpdname, chan, which, (on) ? "on" : "off");
+ ret = DAA_DIRECT_REQUEST(xbus, xpd, chan, DAA_WRITE, 0x20, on);
out:
return ret;
}
@@ -221,9 +214,6 @@ static int do_sethook(xpd_t *xpd, int pos, bool to_offhook)
struct FXO_priv_data *priv;
int ret = 0;
bool value;
- xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
BUG_ON(!xpd);
BUG_ON(xpd->direction == TO_PHONE); // We can SETHOOK state only on PSTN
@@ -238,11 +228,7 @@ static int do_sethook(xpd_t *xpd, int pos, bool to_offhook)
value = (to_offhook) ? 0x09 : 0x08; /* Bit 3 is for CID */
DBG("%s/%s/%d: SETHOOK: value=0x%02X %s\n", xbus->busname, xpd->xpdname, pos, value, (to_offhook)?"OFFHOOK":"ONHOOK");
MARK_LED(xpd, pos, LED_GREEN, (to_offhook)?LED_ON:LED_OFF);
- XPACKET_NEW(pack, xbus, FXO, DAA_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXO, DAA_WRITE, slic_cmd);
- len = slic_cmd_direct_write(sc, BIT(pos), DAA_RING_REGISTER, value);
- pack->datalen = len;
- packet_send(xbus, pack);
+ ret = DAA_DIRECT_REQUEST(xbus, xpd, pos, DAA_WRITE, DAA_RING_REGISTER, value);
#ifdef SOFT_RING
priv->ring_sig[pos] = 0;
#endif
@@ -282,10 +268,10 @@ static void clean_proc(xbus_t *xbus, xpd_t *xpd)
priv = xpd->priv;
DBG("%s/%s\n", xbus->busname, xpd->xpdname);
#ifdef CONFIG_PROC_FS
- if(priv->xpd_slic) {
+ if(priv->regfile) {
DBG("Removing xpd DAA file %s/%s\n", xbus->busname, xpd->xpdname);
- remove_proc_entry(PROC_DAA_FNAME, xpd->proc_xpd_dir);
- priv->xpd_slic = NULL;
+ remove_proc_entry(PROC_REGISTER_FNAME, xpd->proc_xpd_dir);
+ priv->regfile->data = NULL;
}
if(priv->fxo_info) {
DBG("Removing xpd FXO_INFO file %s/%s\n", xbus->busname, xpd->xpdname);
@@ -313,16 +299,16 @@ static int FXO_card_init(xbus_t *xbus, xpd_t *xpd)
}
priv->fxo_info->owner = THIS_MODULE;
DBG("Creating DAAs file for %s/%s\n", xbus->busname, xpd->xpdname);
- priv->xpd_slic = create_proc_entry(PROC_DAA_FNAME, 0644, xpd->proc_xpd_dir);
- if(!priv->xpd_slic) {
+ priv->regfile = create_proc_entry(PROC_REGISTER_FNAME, 0644, xpd->proc_xpd_dir);
+ if(!priv->regfile) {
ERR("Failed to create proc file for DAAs of %s/%s\n", xbus->busname, xpd->xpdname);
ret = -ENOENT;
goto err;
}
- priv->xpd_slic->owner = THIS_MODULE;
- priv->xpd_slic->write_proc = proc_xpd_slic_write;
- priv->xpd_slic->read_proc = proc_xpd_slic_read;
- priv->xpd_slic->data = xpd;
+ priv->regfile->owner = THIS_MODULE;
+ priv->regfile->write_proc = proc_xpd_register_write;
+ priv->regfile->read_proc = proc_xpd_register_read;
+ priv->regfile->data = xpd;
#endif
ret = run_initialize_registers(xpd);
if(ret < 0)
@@ -430,7 +416,7 @@ static void poll_battery(xbus_t *xbus, xpd_t *xpd)
int i;
for_each_line(xpd, i) {
- CALL_PROTO(FXO, DAA_QUERY, xbus, xpd, i, DAA_VBAT_REGISTER);
+ DAA_DIRECT_REQUEST(xbus, xpd, i, DAA_READ, DAA_VBAT_REGISTER, 0);
}
}
@@ -444,7 +430,7 @@ static void poll_ring(xbus_t *xbus, xpd_t *xpd)
BUG_ON(!priv);
for_each_line(xpd, i) {
if(priv->ring_sig[i])
- CALL_PROTO(FXO, DAA_QUERY, xbus, xpd, i, DAA_RING_REGISTER);
+ DAA_DIRECT_REQUEST(xbus, xpd, i, DAA_READ, DAA_RING_REGISTER, 0);
}
}
#endif
@@ -496,16 +482,11 @@ static int FXO_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
/* quick and dirty registers writing: */
for (i=0; i<sizeof(echotune_reg); i++) {
char buf[22];
- xpp_line_t lines = BIT(pos);
- sprintf(buf, "%02X %02X %02X %02X WD %2X %2X",
- (lines & 0xFF),
- ((lines >> 8) & 0xFF),
- ((lines >> 16) & 0xFF),
- ((lines >> 24) & 0xFF),
- echotune_reg[i],echoregs.coeff[i]
+ sprintf(buf, "%d WD %2X %2X",
+ pos,echotune_reg[i],echoregs.coeff[i]
);
/* FIXME: code duplicated from proc_xpd_register_write */
- ret = process_slic_cmdline(xpd, buf);
+ ret = handle_register_command(xpd, buf);
if(ret < 0)
return ret;
mdelay(1);
@@ -522,17 +503,46 @@ static int FXO_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
/*---------------- FXO: HOST COMMANDS -------------------------------------*/
-static /* 0x0F */ HOSTCMD(FXO, CHAN_ENABLE, xpp_line_t lines, bool on)
+/* 0x0F */ HOSTCMD(FXO, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high)
+{
+ int ret = 0;
+ xpacket_t *pack;
+ reg_cmd_t *reg_cmd;
+
+ if(!xbus) {
+ DBG("NO XBUS\n");
+ return -EINVAL;
+ }
+ XPACKET_NEW(pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->id);
+#if 0
+ DBG("%s/%s/%d: %c%c R%02X S%02X %02X %02X\n",
+ xbus->busname, xpd->xpdname, chipsel,
+ (writing)?'W':'R',
+ (do_subreg)?'S':'D',
+ regnum, subreg, data_low, data_high);
+#endif
+ reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
+ pack->datalen = sizeof(*reg_cmd);
+ reg_cmd->bytes = sizeof(*reg_cmd) - 1; // do not count the 'bytes' field
+ REG_FIELD(reg_cmd, chipsel) = chipsel;
+ REG_FIELD(reg_cmd, read_request) = (writing) ? 0 : 1;
+ REG_FIELD(reg_cmd, do_subreg) = do_subreg;
+ REG_FIELD(reg_cmd, regnum) = regnum;
+ REG_FIELD(reg_cmd, subreg) = subreg;
+ REG_FIELD(reg_cmd, data_low) = data_low;
+ REG_FIELD(reg_cmd, data_high) = data_high;
+ ret = packet_send(xbus, pack);
+ return ret;
+}
+
+static /* 0x0F */ HOSTCMD(FXO, XPD_STATE, bool on)
{
int ret = 0;
int i;
BUG_ON(!xbus);
BUG_ON(!xpd);
- if(!lines) {
- return 0;
- }
- DBG("Channel Activation: 0x%4X %s\n", lines, (on) ? "on" : "off");
+ DBG("%s/%s: %s\n", xbus->busname, xpd->xpdname, (on) ? "on" : "off");
if(on) {
for_each_line(xpd, i) {
MARK_LED(xpd, i, LED_GREEN, LED_ON);
@@ -546,42 +556,23 @@ static /* 0x0F */ HOSTCMD(FXO, CHAN_ENABLE, xpp_line_t lines, bool on)
return ret;
}
-static /* 0x0F */ HOSTCMD(FXO, CHAN_CID, int pos)
+static /* 0x0F */ HOSTCMD(FXO, CHAN_CID, lineno_t chan)
{
int ret = 0;
- xpp_line_t lines = BIT(pos);
BUG_ON(!xbus);
BUG_ON(!xpd);
- if(!lines) {
- return 0;
- }
- DBG("%s/%s/%d:\n", xbus->busname, xpd->xpdname, pos);
+ DBG("%s/%s/%d:\n", xbus->busname, xpd->xpdname, chan);
return ret;
}
-static /* 0x0F */ HOSTCMD(FXO, RING, int pos, bool on)
+static /* 0x0F */ HOSTCMD(FXO, RING, lineno_t chan, bool on)
{
- int ret = 0;
- xpacket_t *pack;
- slic_cmd_t *sc;
- xpp_line_t mask = BIT(pos);
- int len;
-
BUG_ON(!xbus);
BUG_ON(!xpd);
- if(!mask) {
- return 0;
- }
- DBG("%s/%s/%d %s\n", xpd->xbus->busname, xpd->xpdname, pos, (on) ? "on" : "off");
- XPACKET_NEW(pack, xbus, FXO, DAA_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXO, DAA_WRITE, slic_cmd);
- len = slic_cmd_direct_write(sc, mask, 0x40, (on)?0x04:0x01);
- pack->datalen = len;
-
- packet_send(xbus, pack);
- return ret;
+ DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, chan, (on) ? "on" : "off");
+ return DAA_DIRECT_REQUEST(xbus, xpd, chan, DAA_WRITE, 0x40, (on)?0x04:0x01);
}
static /* 0x0F */ HOSTCMD(FXO, RELAY_OUT, byte which, bool on)
@@ -589,26 +580,6 @@ static /* 0x0F */ HOSTCMD(FXO, RELAY_OUT, byte which, bool on)
return -ENOSYS;
}
-static /* 0x0F */ HOSTCMD(FXO, DAA_QUERY, int pos, byte reg_num)
-{
- int ret = 0;
- xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
-
- BUG_ON(!xbus);
- BUG_ON(!xpd);
- // DBG("\n");
- XPACKET_NEW(pack, xbus, FXO, DAA_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXO, DAA_WRITE, slic_cmd);
- len = slic_cmd_direct_read(sc, BIT(pos), reg_num);
-
- pack->datalen = len;
-
- packet_send(xbus, pack);
- return ret;
-}
-
/*---------------- FXO: Astribank Reply Handlers --------------------------*/
HANDLER_DEF(FXO, SIG_CHANGED)
@@ -658,10 +629,10 @@ HANDLER_DEF(FXO, SIG_CHANGED)
HANDLER_DEF(FXO, DAA_REPLY)
{
- slic_reply_t *info = &RPACKET_FIELD(pack, FXO, DAA_REPLY, info);
- xpp_line_t lines = RPACKET_FIELD(pack, FXO, DAA_REPLY, lines);
+ reg_cmd_t *info = &RPACKET_FIELD(pack, FXO, DAA_REPLY, regcmd);
unsigned long flags;
struct FXO_priv_data *priv;
+ lineno_t chipsel;
if(!xpd) {
NOTICE("%s: received %s for non-existing xpd: %d\n",
@@ -671,68 +642,62 @@ HANDLER_DEF(FXO, DAA_REPLY)
spin_lock_irqsave(&xpd->lock, flags);
priv = xpd->priv;
BUG_ON(!priv);
- if(!info->indirect && info->reg_num == DAA_VBAT_REGISTER) {
- byte bat = abs((signed char)info->data_low);
- int i;
-
- for_each_line(xpd, i) {
- if(!IS_SET(lines, i))
- continue;
- if(bat < BAT_THRESHOLD) {
- /*
- * Check for battery voltage fluctuations
- */
- if(IS_SET(priv->battery, i) && priv->battery_debounce[i]++ > BAT_DEBOUNCE) {
- DBG("%s/%s: BATTERY OFF (%04X) voltage=%d\n", xpd->xbus->busname, xpd->xpdname, lines, bat);
- BIT_CLR(priv->battery, i);
- update_line_status(xpd, i, 0);
- }
- } else {
- priv->battery_debounce[i] = 0;
- if(!IS_SET(priv->battery, i)) {
- DBG("%s/%s: BATTERY ON (%04X) voltage=%d\n", xpd->xbus->busname, xpd->xpdname, lines, bat);
- BIT_SET(priv->battery, i);
- }
+ chipsel = REG_FIELD(info, chipsel);
+
+ /*
+ * Update battery status
+ */
+ if(REG_FIELD(info, regnum) == DAA_VBAT_REGISTER) {
+ byte bat = abs((signed char)REG_FIELD(info, data_low));
+
+ if(bat < BAT_THRESHOLD) {
+ /*
+ * Check for battery voltage fluctuations
+ */
+ if(IS_SET(priv->battery, chipsel) && priv->battery_debounce[chipsel]++ > BAT_DEBOUNCE) {
+ DBG("%s/%s/%d: BATTERY OFF voltage=%d\n", xpd->xbus->busname, xpd->xpdname, chipsel, bat);
+ BIT_CLR(priv->battery, chipsel);
+ update_line_status(xpd, chipsel, 0);
+ }
+ } else {
+ priv->battery_debounce[chipsel] = 0;
+ if(!IS_SET(priv->battery, chipsel)) {
+ DBG("%s/%s/%d: BATTERY ON voltage=%d\n", xpd->xbus->busname, xpd->xpdname, chipsel, bat);
+ BIT_SET(priv->battery, chipsel);
}
}
}
#ifdef SOFT_RING
- if(!info->indirect && info->reg_num == DAA_RING_REGISTER) {
- bool ringit = (info->data_low & (0x20 | 0x40)) ? 1 : 0; /* Ring positive | Ring negative */
- int i;
-
- for_each_line(xpd, i) {
- if(!IS_SET(lines, i))
- continue;
- if (!priv->ring_sig[i])
- continue;
- if(ringit) {
- if(priv->ring_thresh[i] > RING_THRESHOLD) {
- mark_ring(xpd, i, 1);
- priv->noring_thresh[i] = 0;
- } else
- priv->ring_thresh[i]++;
- } else {
- if(priv->noring_thresh[i] > NORING_THRESHOLD) {
- mark_ring(xpd, i, 0);
- priv->ring_thresh[i] = 0;
- } else
- priv->noring_thresh[i]++;
- }
+ if(REG_FIELD(info, regnum) == DAA_RING_REGISTER && priv->ring_sig[chipsel]) {
+ bool ringit = (REG_FIELD(info, data_low) & (0x20 | 0x40)) ? 1 : 0; /* Ring positive | Ring negative */
+
+ if(ringit) {
+ if(priv->ring_thresh[chipsel] > RING_THRESHOLD) {
+ mark_ring(xpd, chipsel, 1);
+ priv->noring_thresh[chipsel] = 0;
+ } else
+ priv->ring_thresh[chipsel]++;
+ } else {
+ if(priv->noring_thresh[chipsel] > NORING_THRESHOLD) {
+ mark_ring(xpd, chipsel, 0);
+ priv->ring_thresh[chipsel] = 0;
+ } else
+ priv->noring_thresh[chipsel]++;
}
}
#endif
#if 0
- if (info->reg_num != 29)
DBG("DAA_REPLY: xpd #%d %s reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
- xpd->id, (info->indirect)?"I":"D",
+ xpd->id, (info->size == 3)?"I":"D",
info->reg_num, info->data_low, info->data_high);
#endif
/* Update /proc info only if reply relate to the last slic read request */
- if(priv->requested_reply.indirect == info->indirect &&
- priv->requested_reply.reg_num == info->reg_num) {
- priv->last_reply = *info;
+ if(
+ REG_FIELD(&xpd->requested_reply, regnum) == REG_FIELD(info, regnum) &&
+ REG_FIELD(&xpd->requested_reply, do_subreg) == REG_FIELD(info, do_subreg) &&
+ REG_FIELD(&xpd->requested_reply, subreg) == REG_FIELD(info, subreg)) {
+ xpd->last_reply = *info;
}
spin_unlock_irqrestore(&xpd->lock, flags);
return 0;
@@ -742,9 +707,9 @@ HANDLER_DEF(FXO, DAA_REPLY)
xproto_table_t PROTO_TABLE(FXO) = {
.owner = THIS_MODULE,
.entries = {
- /* Card Opcode */
- XENTRY( FXO, SIG_CHANGED ),
- XENTRY( FXO, DAA_REPLY ),
+ /* Prototable Card Opcode */
+ XENTRY( FXO, FXO, SIG_CHANGED ),
+ XENTRY( FXO, FXO, DAA_REPLY ),
},
.name = "FXO",
.type = XPD_TYPE_FXO,
@@ -760,7 +725,7 @@ xproto_table_t PROTO_TABLE(FXO) = {
.RING = XPROTO_CALLER(FXO, RING),
.RELAY_OUT = XPROTO_CALLER(FXO, RELAY_OUT),
- .CHAN_ENABLE = XPROTO_CALLER(FXO, CHAN_ENABLE),
+ .XPD_STATE = XPROTO_CALLER(FXO, XPD_STATE),
.CHAN_CID = XPROTO_CALLER(FXO, CHAN_CID),
.SYNC_SOURCE = XPROTO_CALLER(GLOBAL, SYNC_SOURCE),
@@ -779,9 +744,9 @@ static bool fxo_packet_is_valid(xpacket_t *pack)
return xe != NULL;
}
-static void fxo_packet_dump(xpacket_t *pack)
+static void fxo_packet_dump(const char *msg, xpacket_t *pack)
{
- DBG("\n");
+ DBG("%s\n", msg);
}
/*------------------------- DAA Handling --------------------------*/
@@ -809,11 +774,6 @@ static int proc_fxo_info_read(char *page, char **start, off_t off, int count, in
if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
len += sprintf(page + len, "%2d ", IS_SET(priv->ledstate[LED_GREEN], i));
}
- len += sprintf(page + len, "\n\t%-17s: ", "ledcontrol");
- for_each_line(xpd, i) {
- if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
- len += sprintf(page + len, "%2d ", IS_SET(priv->ledcontrol[LED_GREEN], i));
- }
len += sprintf(page + len, "\n\t%-17s: ", "blinking");
for_each_line(xpd, i) {
if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
@@ -833,17 +793,13 @@ static int proc_fxo_info_read(char *page, char **start, off_t off, int count, in
len += sprintf(page + len, "\n\t%-17s: ", "ring_sig");
for_each_line(xpd, i) {
if(!IS_SET(xpd->digital_outputs, i) && !IS_SET(xpd->digital_inputs, i))
- len += sprintf(page + len, "%d ", priv->ring_sig[i]);
+ len += sprintf(page + len, "%2d ", priv->ring_sig[i]);
}
#endif
len += sprintf(page + len, "\n\t%-17s: ", "battery");
for_each_line(xpd, i) {
len += sprintf(page + len, "%2d ", IS_SET(priv->battery, i));
}
- len += sprintf(page + len, "\n\t%-17s: ", "battery_debounce");
- for_each_line(xpd, i) {
- len += sprintf(page + len, "%2d ", priv->battery_debounce[i]);
- }
len += sprintf(page + len, "\n");
spin_unlock_irqrestore(&xpd->lock, flags);
if (len <= off+count)
@@ -857,113 +813,38 @@ static int proc_fxo_info_read(char *page, char **start, off_t off, int count, in
return len;
}
-
-static int proc_xpd_slic_read(char *page, char **start, off_t off, int count, int *eof, void *data)
-{
- int len = 0;
- unsigned long flags;
- xpd_t *xpd = data;
- slic_reply_t *info;
- struct FXO_priv_data *priv;
-
- BUG_ON(!xpd);
- spin_lock_irqsave(&xpd->lock, flags);
- priv = xpd->priv;
- BUG_ON(!priv);
- info = &priv->last_reply;
- len += sprintf(page + len, "# Writing bad data into this file may damage your hardware!\n");
- len += sprintf(page + len, "# Consult firmware docs first\n");
- len += sprintf(page + len, "DAA_REPLY: %s reg_num=0x%X, dataH=0x%X dataL=0x%X\n",
- (info->indirect)?"I":"D",
- info->reg_num, info->data_high, info->data_low);
- spin_unlock_irqrestore(&xpd->lock, flags);
- if (len <= off+count)
- *eof = 1;
- *start = page + off;
- len -= off;
- if (len > count)
- len = count;
- if (len < 0)
- len = 0;
- return len;
-}
-
/*
- * Direct/Indirect
- * v
- * FF FF FF FF WD 06 1
- * ^---------^ ^ Reg
- * | Write/Read
- * |
- * DAA #
+ *
+ * Direct/Indirect
+ * |
+ * | Reg#
+ * | |
+ * | | Data (only in Write)
+ * | | |
+ * | | +-+-+
+ * v v v v
+ * FF WD 06 01 05
+ * ^ ^
+ * | |
+ * | Write/Read
+ * |
+ * Chan#
+ *
*/
-static int parse_slic_cmd(const char *buf, slic_cmd_t *sc, slic_reply_t *requested_reply)
-{
- char op; /* [W]rite, [R]ead */
- char reg_type; /* [D]irect, [I]ndirect */
- int s1, s2, s3, s4;
- int reg_num;
- int data_low, data_high;
- xpp_line_t lines;
- int ret;
-
- ret = sscanf(buf, "%x %x %x %x %c%c %x %x %x",
- &s1, &s2, &s3, &s4, &op, &reg_type, &reg_num, &data_high, &data_low);
- lines = (s4 << 24) | (s3 << 16) | (s2 << 8) | (s1);
- switch(op) {
- case 'R':
- if(reg_type == 'D' && ret == 7) {
- // DBG("0x%X 0x%X 0x%X 0x%X %c %x\n", s1, s2, s3, s4, reg_type, reg_num);
- ret = slic_cmd_direct_read(sc, lines, reg_num);
- if(requested_reply) {
- requested_reply->indirect = 0;
- requested_reply->reg_num = reg_num;
- }
- } else if(reg_type == 'I' && ret == 7) {
- // DBG("0x%X 0x%X 0x%X 0x%X %c %x\n", s1, s2, s3, s4, reg_type, reg_num);
- ret = slic_cmd_indirect_read(sc, lines, reg_num);
- if(requested_reply) {
- requested_reply->indirect = 1;
- requested_reply->reg_num = reg_num;
- }
- } else {
- NOTICE("%s: Bad read input: ret=%d buf='%s' reg_type=%c\n", __FUNCTION__, ret, buf, reg_type);
- goto err;
- }
- break;
- case 'W':
- if(reg_type == 'D' && ret == 8) {
- // DBG("0x%X 0x%X 0x%X 0x%X %c %x %X\n", s1, s2, s3, s4, reg_type, reg_num, data_high);
- ret = slic_cmd_direct_write(sc, lines, reg_num, data_high);
- } else if(reg_type == 'I' && ret == 9) {
- // DBG("0x%X 0x%X 0x%X 0x%X %c %x %X %X\n", s1, s2, s3, s4, reg_type, reg_num, data_high, data_low);
- ret = slic_cmd_indirect_write(sc, lines, reg_num, data_low, data_high);
- } else {
- NOTICE("%s: Bad write input: ret=%d buf='%s' reg_type=%c\n", __FUNCTION__, ret, buf, reg_type);
- goto err;
- }
- break;
- default:
- NOTICE("%s: Bad input: ret=%d buf='%s' op=%c\n", __FUNCTION__, ret, buf, op);
- goto err;
- }
- return ret;
-err:
- return -EINVAL;
-}
-
-static int process_slic_cmdline(xpd_t *xpd, char *cmdline)
-{
- xbus_t *xbus;
- struct FXO_priv_data *priv;
- slic_cmd_t sc;
- xpacket_t *pack;
+static int handle_register_command(xpd_t *xpd, char *cmdline)
+{
+ unsigned chipsel;
+ unsigned data_low = 0;
+ char op; /* [W]rite, [R]ead */
+ char reg_type; /* [D]irect */
+ int reg_num;
+ int elements;
+ bool writing;
char *p;
- int len = strlen(cmdline);
+ reg_cmd_t regcmd;
+ xbus_t *xbus;
+ int ret;
- BUG_ON(!xpd);
- xbus = xpd->xbus;
- priv = xpd->priv;
if((p = strchr(cmdline, '#')) != NULL) /* Truncate comments */
*p = '\0';
if((p = strchr(cmdline, ';')) != NULL) /* Truncate comments */
@@ -972,22 +853,70 @@ static int process_slic_cmdline(xpd_t *xpd, char *cmdline)
;
if(*p == '\0')
return 0;
- len = parse_slic_cmd(p, &sc, &priv->requested_reply);
- if(len < 0)
- return len;
- if(!sc.lines) {
- NOTICE("%s: no channels are marked. Skip.\n", __FUNCTION__);
- return 0;
+
+ elements = sscanf(cmdline, "%d %c%c %x %x",
+ &chipsel,
+ &op, &reg_type, &reg_num,
+ &data_low);
+ // DBG("'%s': %d %c%c %02X %02X %02X\n", cmdline, chipsel, op, reg_type, reg_num, data_low);
+ if(elements < 4) { // At least: chipsel, op, reg_type, reg_num
+ ERR("Not enough arguments: (%d args) '%s'\n", elements, cmdline);
+ return -EINVAL;
+ }
+ if(!VALID_CHIPSEL(chipsel)) {
+ ERR("Bad chipsel number: %d\n", chipsel);
+ return -EINVAL;
+ }
+ REG_FIELD(&regcmd, chipsel) = chipsel;
+ REG_FIELD(&regcmd, do_subreg) = 0;
+ switch(op) {
+ case 'W':
+ writing = 1;
+ break;
+ case 'R':
+ writing = 0;
+ break;
+ default:
+ ERR("Unkown operation type '%c'\n", op);
+ return -EINVAL;
}
- dump_slic_cmd("WRITE_DAA", &sc);
- XPACKET_NEW(pack, xbus, FXO, DAA_WRITE, xpd->id);
- RPACKET_FIELD(pack, FXO, DAA_WRITE, slic_cmd) = sc;
- pack->datalen = len;
- packet_send(xbus, pack);
- return 0;
+ switch(reg_type) {
+ case 'D':
+ REG_FIELD(&regcmd, regnum) = reg_num;
+ REG_FIELD(&regcmd, subreg) = 0;
+ break;
+ default:
+ ERR("Unkown register type '%c'\n", reg_type);
+ return -EINVAL;
+ }
+ if(
+ (op == 'W' && reg_type == 'D' && elements != 5) ||
+ (op == 'R' && reg_type == 'D' && elements != 4)
+ ) {
+ ERR("%s: '%s' (%d elements): %d %c%c %02X %02X\n", __FUNCTION__,
+ cmdline, elements,
+ chipsel, op, reg_type, reg_num, data_low);
+ return -EINVAL;
+ }
+ regcmd.bytes = sizeof(regcmd) - 1;
+ REG_FIELD(&regcmd, data_low) = data_low;
+ REG_FIELD(&regcmd, data_high) = 0;
+ REG_FIELD(&regcmd, read_request) = writing;
+ BUG_ON(!xpd);
+ xbus = xpd->xbus;
+ if(!down_read_trylock(&xbus->in_use)) {
+ DBG("Dropped packet. %s is in_use\n", xbus->busname);
+ return -EBUSY;
+ }
+ xpd->requested_reply = regcmd;
+ if(print_dbg)
+ dump_reg_cmd("FXO", &regcmd);
+ ret = DAA_DIRECT_REQUEST(xpd->xbus, xpd, REG_FIELD(&regcmd, chipsel), writing, REG_FIELD(&regcmd, regnum), REG_FIELD(&regcmd, data_low));
+ up_read(&xbus->in_use);
+ return ret;
}
-static int proc_xpd_slic_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
+static int proc_xpd_register_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
{
xpd_t *xpd = data;
char buf[MAX_PROC_WRITE];
@@ -1010,7 +939,7 @@ static int proc_xpd_slic_write(struct file *file, const char __user *buffer, uns
if(p >= buf + MAX_PROC_WRITE)
return -E2BIG;
*p = '\0';
- ret = process_slic_cmdline(xpd, buf);
+ ret = handle_register_command(xpd, buf);
if(ret < 0)
return ret;
mdelay(1);
@@ -1018,6 +947,37 @@ static int proc_xpd_slic_write(struct file *file, const char __user *buffer, uns
return count;
}
+static int proc_xpd_register_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+ int len = 0;
+ unsigned long flags;
+ xpd_t *xpd = data;
+ reg_cmd_t *info;
+ byte regnum;
+
+ if(!xpd)
+ return -ENODEV;
+ spin_lock_irqsave(&xpd->lock, flags);
+ info = &xpd->last_reply;
+ regnum = REG_FIELD(info, regnum);
+ len += sprintf(page + len, "# Writing bad data into this file may damage your hardware!\n");
+ len += sprintf(page + len, "# Consult firmware docs first\n");
+ len += sprintf(page + len, "#\n");
+ len += sprintf(page + len, "#CH\tD/I\tReg.\tDL\n");
+ len += sprintf(page + len, "%2d\tRD\t%02X\t%02X\n",
+ REG_FIELD(info, chipsel),
+ regnum, REG_FIELD(info, data_low));
+ spin_unlock_irqrestore(&xpd->lock, flags);
+ if (len <= off+count)
+ *eof = 1;
+ *start = page + off;
+ len -= off;
+ if (len > count)
+ len = count;
+ if (len < 0)
+ len = 0;
+ return len;
+}
int __init card_fxo_startup(void)
{
diff --git a/xpp/card_fxo.h b/xpp/card_fxo.h
index 6e5186b..a22e193 100644
--- a/xpp/card_fxo.h
+++ b/xpp/card_fxo.h
@@ -23,19 +23,16 @@
*/
#include "xpd.h"
-#include "slic.h"
enum fxo_opcodes {
XPROTO_NAME(FXO, SIG_CHANGED) = 0x06,
/**/
XPROTO_NAME(FXO, DAA_WRITE) = 0x0F, /* Write to DAA */
- XPROTO_NAME(FXO, CHAN_ENABLE) = 0x0F, /* Write to DAA */
+ XPROTO_NAME(FXO, XPD_STATE) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, CHAN_CID) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, RING) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, LED) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, RELAY_OUT) = 0x0F, /* Write to DAA */
- XPROTO_NAME(FXO, DAA_INIT) = 0x0F, /* Write to DAA */
- XPROTO_NAME(FXO, DAA_QUERY) = 0x0F, /* Write to DAA */
/**/
XPROTO_NAME(FXO, DAA_REPLY) = 0x10,
};
@@ -47,11 +44,7 @@ DEF_RPACKET_DATA(FXO, SIG_CHANGED,
xpp_line_t sig_toggles; /* channels: lsb=1, msb=8 */
);
DEF_RPACKET_DATA(FXO, DAA_REPLY, /* Get status of a single DAA (for debugging) */
- xpp_line_t lines;
- slic_reply_t info;
- );
-DEF_RPACKET_DATA(FXO, DAA_WRITE,
- slic_cmd_t slic_cmd;
+ reg_cmd_t regcmd;
);
#define DAA_VBAT_REGISTER 29
diff --git a/xpp/card_fxs.c b/xpp/card_fxs.c
index 9aaef63..3d659fa 100644
--- a/xpp/card_fxs.c
+++ b/xpp/card_fxs.c
@@ -58,74 +58,50 @@ enum fxs_leds {
#define NUM_LEDS 2
-static int SLIC_DIRECT_REQUEST(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, byte reg, byte dL)
-{
- xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
-
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- len = slic_cmd_direct_write(sc, lines, reg, dL);
- pack->datalen = len;
- packet_send(xbus, pack);
- return 0;
-}
+static /* 0x0F */ DECLARE_CMD(FXS, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high);
+/* Shortcuts */
+#define SLIC_WRITE 1
+#define SLIC_READ 0
+#define SLIC_DIRECT_REQUEST(xbus,xpd,chipsel,writing,reg,dL) \
+ CALL_PROTO(FXS, REGISTER_REQUEST, (xbus), (xpd), (chipsel), (writing), 0, (reg), 0, (dL), 0)
+#define SLIC_INDIRECT_REQUEST(xbus,xpd,chipsel,writing,reg,dL,dH) \
+ PROTO(FXS, REGISTER_REQUEST, (xbus), (xpd), (chipsel), (writing), 1, (reg), 0, (dL), (dH))
+
+#define VALID_CHIPSEL(x) (((chipsel) >= 0 && (chipsel) <= 7) || (chipsel) == ALL_CHANS)
/*---------------- FXS Protocol Commands ----------------------------------*/
-static /* 0x0F */ DECLARE_CMD(FXS, CHAN_ENABLE, xpp_line_t lines, bool on);
-static /* 0x0F */ DECLARE_CMD(FXS, CHAN_CID, int pos);
-static /* 0x0F */ DECLARE_CMD(FXS, RING, int pos, bool on);
+static /* 0x0F */ DECLARE_CMD(FXS, XPD_STATE, bool on);
+static /* 0x0F */ DECLARE_CMD(FXS, CHAN_CID, lineno_t chan);
+static /* 0x0F */ DECLARE_CMD(FXS, RING, lineno_t chan, bool on);
static /* 0x0F */ DECLARE_CMD(FXS, RELAY_OUT, byte which, bool on);
-static /* 0x0F */ DECLARE_CMD(FXS, SLIC_QUERY, int pos, byte reg_num);
static bool fxs_packet_is_valid(xpacket_t *pack);
-static void fxs_packet_dump(xpacket_t *pack);
+static void fxs_packet_dump(const char *msg, xpacket_t *pack);
static int proc_fxs_info_read(char *page, char **start, off_t off, int count, int *eof, void *data);
-static int proc_xpd_slic_read(char *page, char **start, off_t off, int count, int *eof, void *data);
-static int proc_xpd_slic_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
+static int proc_xpd_register_read(char *page, char **start, off_t off, int count, int *eof, void *data);
+static int proc_xpd_register_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
-#define PROC_SLIC_FNAME "slics"
+#define PROC_REGISTER_FNAME "slics"
#define PROC_FXS_INFO_FNAME "fxs_info"
struct FXS_priv_data {
- struct proc_dir_entry *xpd_slic;
+ struct proc_dir_entry *regfile;
struct proc_dir_entry *fxs_info;
- slic_reply_t requested_reply;
- slic_reply_t last_reply;
xpp_line_t ledstate[NUM_LEDS]; /* 0 - OFF, 1 - ON */
xpp_line_t ledcontrol[NUM_LEDS]; /* 0 - OFF, 1 - ON */
int blinking[NUM_LEDS][CHANNELS_PERXPD];
};
/*---------------- FXS: Static functions ----------------------------------*/
-static int do_chan_power(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, bool on)
+static int do_chan_power(xbus_t *xbus, xpd_t *xpd, lineno_t chan, bool on)
{
- int ret = 0;
- xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
+ int value = (on) ? 0x06 : 0x00;
BUG_ON(!xbus);
BUG_ON(!xpd);
- if(!lines) {
- return 0;
- }
- DBG("%s/%s: 0x%04X %s\n", xbus->busname, xpd->xpdname, lines, (on) ? "up" : "down");
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- if(on) {
- // Power up
- len = slic_cmd_direct_write(sc, lines, 0x42, 0x06);
- } else {
- // Power down
- len = slic_cmd_direct_write(sc, lines, 0x42, 0x00);
- }
- pack->datalen = len;
-
- packet_send(xbus, pack);
- return ret;
+ DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, chan, (on) ? "up" : "down");
+ return SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x42, value);
}
#define IS_BLINKING(priv,pos,color) ((priv)->blinking[color][pos] != 0)
@@ -164,47 +140,34 @@ static const int led_register_vals[] = { BIT(4), BIT(1), BIT(0) };
* - A line number
* - ALL_LINES
*/
-static int do_led(xpd_t *xpd, lineno_t pos, byte which, bool on)
+static int do_led(xpd_t *xpd, lineno_t chan, byte which, bool on)
{
int ret = 0;
- xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
- int value;
struct FXS_priv_data *priv;
- xpp_line_t lines;
+ int value;
xbus_t *xbus;
BUG_ON(!xpd);
xbus = xpd->xbus;
priv = xpd->priv;
which = which % NUM_LEDS;
- if(IS_SET(xpd->digital_outputs, pos) || IS_SET(xpd->digital_inputs, pos))
+ if(IS_SET(xpd->digital_outputs, chan) || IS_SET(xpd->digital_inputs, chan))
goto out;
- if(pos == ALL_LINES) {
- lines = ~0;
+ if(chan == ALL_CHANS) {
priv->ledstate[which] = (on) ? ~0 : 0;
} else {
- lines = BIT(pos);
if(on) {
- BIT_SET(priv->ledstate[which], pos);
+ BIT_SET(priv->ledstate[which], chan);
} else {
- BIT_CLR(priv->ledstate[which], pos);
+ BIT_CLR(priv->ledstate[which], chan);
}
}
- if(!lines) // Nothing to do
- goto out;
- DBG("%s/%s: LED: lines=0x%04X which=%d -- %s\n", xbus->busname, xpd->xpdname, lines, which, (on) ? "on" : "off");
+ DBG("%s/%s/%d: LED: which=%d -- %s\n", xbus->busname, xpd->xpdname, chan, which, (on) ? "on" : "off");
value = BIT(2) | BIT(3);
value |= ((BIT(5) | BIT(6) | BIT(7)) & ~led_register_mask[which]);
if(on)
value |= led_register_vals[which];
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- len = slic_cmd_direct_write(sc, lines, 0x06, value);
- pack->datalen = len;
- packet_send(xbus, pack);
-
+ ret = SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x06, value);
out:
return ret;
}
@@ -212,14 +175,12 @@ out:
static void handle_fxs_leds(xpd_t *xpd)
{
int i;
- unsigned long flags;
const enum fxs_leds colors[] = { LED_GREEN, LED_RED };
int color;
unsigned int timer_count;
struct FXS_priv_data *priv;
BUG_ON(!xpd);
- spin_lock_irqsave(&xpd->lock, flags);
priv = xpd->priv;
timer_count = xpd->timer_count;
for(color = 0; color < ARRAY_SIZE(colors); color++) {
@@ -245,7 +206,6 @@ static void handle_fxs_leds(xpd_t *xpd)
}
}
- spin_unlock_irqrestore(&xpd->lock, flags);
}
/*---------------- FXS: Methods -------------------------------------------*/
@@ -277,11 +237,11 @@ static void clean_proc(xbus_t *xbus, xpd_t *xpd)
BUG_ON(!xpd);
priv = xpd->priv;
#ifdef CONFIG_PROC_FS
- if(priv->xpd_slic) {
+ if(priv->regfile) {
DBG("Removing xpd SLIC file %s/%s\n", xbus->busname, xpd->xpdname);
- priv->xpd_slic->data = NULL;
- remove_proc_entry(PROC_SLIC_FNAME, xpd->proc_xpd_dir);
- priv->xpd_slic = NULL;
+ priv->regfile->data = NULL;
+ remove_proc_entry(PROC_REGISTER_FNAME, xpd->proc_xpd_dir);
+ priv->regfile = NULL;
}
if(priv->fxs_info) {
DBG("Removing xpd FXS_INFO file %s/%s\n", xbus->busname, xpd->xpdname);
@@ -308,16 +268,16 @@ static int FXS_card_init(xbus_t *xbus, xpd_t *xpd)
}
priv->fxs_info->owner = THIS_MODULE;
DBG("Creating SLICs file for %s/%s\n", xbus->busname, xpd->xpdname);
- priv->xpd_slic = create_proc_entry(PROC_SLIC_FNAME, 0644, xpd->proc_xpd_dir);
- if(!priv->xpd_slic) {
+ priv->regfile = create_proc_entry(PROC_REGISTER_FNAME, 0644, xpd->proc_xpd_dir);
+ if(!priv->regfile) {
ERR("Failed to create proc file for SLICs of %s/%s\n", xbus->busname, xpd->xpdname);
ret = -ENOENT;
goto err;
}
- priv->xpd_slic->owner = THIS_MODULE;
- priv->xpd_slic->write_proc = proc_xpd_slic_write;
- priv->xpd_slic->read_proc = proc_xpd_slic_read;
- priv->xpd_slic->data = xpd;
+ priv->regfile->owner = THIS_MODULE;
+ priv->regfile->write_proc = proc_xpd_register_write;
+ priv->regfile->read_proc = proc_xpd_register_read;
+ priv->regfile->data = xpd;
#endif
ret = run_initialize_registers(xpd);
if(ret < 0)
@@ -326,7 +286,7 @@ static int FXS_card_init(xbus_t *xbus, xpd_t *xpd)
* Setup ring timers
*/
/* Software controled ringing (for CID) */
- ret = SLIC_DIRECT_REQUEST(xbus, xpd, ALL_LINES, 0x22, 0x00); /* Ringing Oscilator Control */
+ ret = SLIC_DIRECT_REQUEST(xbus, xpd, ALL_CHANS, SLIC_WRITE, 0x22, 0x00); /* Ringing Oscilator Control */
if(ret < 0)
goto err;
DBG("%s/%s: done\n", xbus->busname, xpd->xpdname);
@@ -495,9 +455,9 @@ static void poll_inputs(xbus_t *xbus, xpd_t *xpd)
BUG_ON(xpd->id != 0); // Only unit #0 has digital inputs
for(i = 0; i < ARRAY_SIZE(input_channels); i++) {
- int pos = input_channels[i];
+ byte pos = input_channels[i];
- CALL_PROTO(FXS, SLIC_QUERY, xbus, xpd, pos, 0x06);
+ SLIC_DIRECT_REQUEST(xbus, xpd, pos, SLIC_READ, 0x06, 0);
}
}
@@ -522,161 +482,125 @@ static int FXS_card_tick(xbus_t *xbus, xpd_t *xpd)
/*---------------- FXS: HOST COMMANDS -------------------------------------*/
-static /* 0x0F */ HOSTCMD(FXS, CHAN_ENABLE, xpp_line_t lines, bool on)
+/* 0x0F */ HOSTCMD(FXS, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high)
{
int ret = 0;
xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
- enum fxs_state value = (on) ? 0x01 : 0x00;
- unsigned long flags;
+ reg_cmd_t *reg_cmd;
+
+ if(!xbus) {
+ DBG("NO XBUS\n");
+ return -EINVAL;
+ }
+ XPACKET_NEW(pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->id);
+#if 0
+ DBG("%s/%s/%d: %c%c R%02X S%02X %02X %02X\n",
+ xbus->busname, xpd->xpdname, chipsel,
+ (writing)?'W':'R',
+ (do_subreg)?'S':'D',
+ regnum, subreg, data_low, data_high);
+#endif
+ reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
+ pack->datalen = sizeof(*reg_cmd);
+ reg_cmd->bytes = sizeof(*reg_cmd) - 1; // do not count the 'bytes' field
+ REG_FIELD(reg_cmd, chipsel) = chipsel;
+ REG_FIELD(reg_cmd, read_request) = (writing) ? 0 : 1;
+ REG_FIELD(reg_cmd, do_subreg) = do_subreg;
+ REG_FIELD(reg_cmd, regnum) = regnum;
+ REG_FIELD(reg_cmd, subreg) = subreg;
+ REG_FIELD(reg_cmd, data_low) = data_low;
+ REG_FIELD(reg_cmd, data_high) = data_high;
+ ret = packet_send(xbus, pack);
+ return ret;
+}
+
+static /* 0x0F */ HOSTCMD(FXS, XPD_STATE, bool on)
+{
+ int ret = 0;
int i;
+ enum fxs_state value = (on) ? 0x01 : 0x00;
+ unsigned long flags;
+ struct FXS_priv_data *priv;
BUG_ON(!xbus);
BUG_ON(!xpd);
- if(!lines) {
- return 0;
- }
- DBG("Channel Activation: 0x%4X %s\n", lines, (on) ? "on" : "off");
- // Make sure we use normal (low battery) power
- for_each_line(xpd, i)
- if (BIT_SET(lines,i))
- do_chan_power(xbus, xpd, BIT(i), 0);
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- len = slic_cmd_direct_write(sc, lines, 0x40, value);
- pack->datalen = len;
+ priv = xpd->priv;
+ spin_lock_irqsave(&xpd->lock, flags);
+ DBG("%s/%s: %s\n", xbus->busname, xpd->xpdname, (on) ? "on" : "off");
+ ret = SLIC_DIRECT_REQUEST(xbus, xpd, ALL_CHANS, SLIC_WRITE, 0x40, value);
for_each_line(xpd, i)
xpd->lasttxhook[i] = value;
-
- packet_send(xbus, pack);
- spin_lock_irqsave(&xpd->lock, flags);
if(on) {
- do_led(xpd, ALL_LINES, LED_GREEN, LED_ON);
+ MARK_LED(priv, ALL_CHANS, LED_GREEN, LED_ON);
} else {
- do_led(xpd, ALL_LINES, LED_GREEN, LED_OFF);
+ MARK_LED(priv, ALL_CHANS, LED_GREEN, LED_OFF);
}
spin_unlock_irqrestore(&xpd->lock, flags);
return ret;
}
-static /* 0x0F */ HOSTCMD(FXS, CHAN_CID, int pos)
+static /* 0x0F */ HOSTCMD(FXS, CHAN_CID, lineno_t chan)
{
int ret = 0;
- xpacket_t *pack;
- slic_cmd_t *sc;
int i;
- xpp_line_t lines = BIT(pos);
BUG_ON(!xbus);
BUG_ON(!xpd);
- if(!lines) {
- return 0;
- }
- DBG("%s/%s/%d:\n", xbus->busname, xpd->xpdname, pos);
- //do_chan_power(xbus, xpd, BIT(pos), 0); // Low battery for normal (non-ring) operation
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- pack->datalen = slic_cmd_direct_write(sc, lines, 0x40, FXS_LINE_CID);
- packet_send(xbus, pack);
+ DBG("%s/%s/%d:\n", xbus->busname, xpd->xpdname, chan);
+ ret = SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x40, FXS_LINE_CID);
for_each_line(xpd, i)
xpd->lasttxhook[i] = FXS_LINE_CID;
return ret;
}
-static /* 0x0F */ HOSTCMD(FXS, RING, int pos, bool on)
+static /* 0x0F */ HOSTCMD(FXS, RING, lineno_t chan, bool on)
{
- int ret = 0;
+ int ret = 0;
struct FXS_priv_data *priv;
- xpacket_t *pack;
- slic_cmd_t *sc;
- xpp_line_t mask = BIT(pos);
- int len;
- enum fxs_state value = (on) ? 0x04 : 0x01;
+ enum fxs_state value = (on) ? 0x04 : 0x01;
BUG_ON(!xbus);
BUG_ON(!xpd);
+ DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, chan, (on) ? "on" : "off");
priv = xpd->priv;
- if(!mask) {
- return 0;
- }
- DBG("%s/%s/%d %s\n", xbus->busname, xpd->xpdname, pos, (on) ? "on" : "off");
- do_chan_power(xbus, xpd, BIT(pos), on); // Power up (for ring)
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- len = slic_cmd_direct_write(sc, mask, 0x40, value);
- xpd->lasttxhook[pos] = value;
- pack->datalen = len;
-
- packet_send(xbus, pack);
+ do_chan_power(xbus, xpd, chan, on); // Power up (for ring)
+ ret = SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x40, value);
+ xpd->lasttxhook[chan] = value;
if(on) {
- MARK_BLINK(priv,pos,LED_GREEN,LED_BLINK);
+ MARK_BLINK(priv,chan,LED_GREEN,LED_BLINK);
} else {
- if(IS_BLINKING(priv, pos, LED_GREEN))
- MARK_BLINK(priv,pos,LED_GREEN,0);
+ if(IS_BLINKING(priv, chan, LED_GREEN))
+ MARK_BLINK(priv,chan,LED_GREEN,0);
}
return ret;
}
static /* 0x0F */ HOSTCMD(FXS, RELAY_OUT, byte which, bool on)
{
- int ret = 0;
- xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
int value;
- xpp_line_t lines;
int relay_channels[] = { 0, 4 };
BUG_ON(!xbus);
BUG_ON(!xpd);
-
DBG("RELAY_OUT: which=%d -- %s\n", which, (on) ? "on" : "off");
which = which % ARRAY_SIZE(relay_channels);
- lines = BIT(relay_channels[which]);
value = BIT(2) | BIT(3);
value |= ((BIT(5) | BIT(6) | BIT(7)) & ~led_register_mask[OUTPUT_RELAY]);
if(on)
value |= led_register_vals[OUTPUT_RELAY];
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- len = slic_cmd_direct_write(sc, lines, 0x06, value);
-
- DBG("RELAY_OUT pack: line=%d value=0x%04X\n", lines, value);
- pack->datalen = len;
- packet_send(xbus, pack);
- return ret;
-}
-
-static /* 0x0F */ HOSTCMD(FXS, SLIC_QUERY, int pos, byte reg_num)
-{
- int ret = 0;
- xpacket_t *pack;
- slic_cmd_t *sc;
- int len;
-
- BUG_ON(!xbus);
- BUG_ON(!xpd);
- // DBG("\n");
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- len = slic_cmd_direct_read(sc, BIT(pos), reg_num);
-
- pack->datalen = len;
-
- packet_send(xbus, pack);
- return ret;
+ return SLIC_DIRECT_REQUEST(xbus, xpd, relay_channels[which], SLIC_WRITE, 0x06, value);
}
/*---------------- FXS: Astribank Reply Handlers --------------------------*/
HANDLER_DEF(FXS, SIG_CHANGED)
{
- xpp_line_t sig_status = RPACKET_FIELD(pack, FXS, SIG_CHANGED, sig_status);
- xpp_line_t sig_toggles = RPACKET_FIELD(pack, FXS, SIG_CHANGED, sig_toggles);
+ xpp_line_t sig_status = RPACKET_FIELD(pack, FXS, SIG_CHANGED, sig_status);
+ xpp_line_t sig_toggles = RPACKET_FIELD(pack, FXS, SIG_CHANGED, sig_toggles);
struct FXS_priv_data *priv;
- int i;
+ int i;
+ unsigned long flags;
BUG_ON(!xpd);
BUG_ON(xpd->direction != TO_PHONE);
@@ -686,12 +610,19 @@ HANDLER_DEF(FXS, SIG_CHANGED)
NOTICE("%s: %s/%s is not registered. Skipping.\n", __FUNCTION__, xbus->busname, xpd->xpdname);
return -ENODEV;
}
+#if 0
+ Is this needed?
+ for_each_line(xpd, i) {
+ if(IS_SET(sig_toggles, i))
+ do_chan_power(xpd->xbus, xpd, BIT(i), 0); // Power down (prevent overheating!!!)
+ }
+#endif
+ spin_lock_irqsave(&xpd->lock, flags);
for_each_line(xpd, i) {
if(IS_SET(xpd->digital_outputs, i) || IS_SET(xpd->digital_inputs, i))
continue;
if(IS_SET(sig_toggles, i)) {
xpd->ringing[i] = 0; // No more ringing...
- do_chan_power(xpd->xbus, xpd, BIT(i), 0); // When not ringing, VBAT is always Low
MARK_BLINK(priv,i,LED_GREEN,0);
if(IS_SET(sig_status, i)) {
DBG("%s/%s/%d: OFFHOOK\n", xbus->busname, xpd->xpdname, i);
@@ -704,15 +635,17 @@ HANDLER_DEF(FXS, SIG_CHANGED)
}
}
}
+ spin_unlock_irqrestore(&xpd->lock, flags);
return 0;
}
-HANDLER_DEF(FXS, SLIC_REPLY)
+HANDLER_DEF(FXS, REGISTER_REPLY)
{
- slic_reply_t *info = &RPACKET_FIELD(pack, FXS, SLIC_REPLY, info);
- xpp_line_t lines = RPACKET_FIELD(pack, FXS, SLIC_REPLY, lines);
+ reg_cmd_t *info = &RPACKET_FIELD(pack, FXS, REGISTER_REPLY, reg_cmd);
unsigned long flags;
struct FXS_priv_data *priv;
+ byte regnum;
+ bool indirect;
if(!xpd) {
NOTICE("%s: received %s for non-existing xpd: %d\n",
@@ -722,14 +655,22 @@ HANDLER_DEF(FXS, SLIC_REPLY)
spin_lock_irqsave(&xpd->lock, flags);
priv = xpd->priv;
BUG_ON(!priv);
+ indirect = (REG_FIELD(info, regnum) == 0x1E);
+ regnum = (indirect) ? REG_FIELD(info, subreg) : REG_FIELD(info, regnum);
#if 0
- DBG("SLIC_REPLY: xpd #%d %s reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
- xpd->id, (info->indirect)?"I":"D",
- info->reg_num, info->data_low, info->data_high);
+ DBG("REGISTER_REPLY: xpd #%d %s reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
+ xpd->id, (indirect)?"I":"D",
+ regnum, REG_FIELD(info, data_low), REG_FIELD(info, data_high));
#endif
- if(xpd->id == 0 && info->indirect == 0 && info->reg_num == 0x06) { /* Digital Inputs Poll Result */
- int i;
- bool offhook = (info->data_low & 0x1) == 0;
+ if(!SPAN_REGISTERED(xpd))
+ goto out;
+ /*
+ * Process digital inputs polling results
+ */
+ if(xpd->id == 0 && regnum == 0x06) {
+ int i;
+ bool offhook = (REG_FIELD(info, data_low) & 0x1) == 0;
+ xpp_line_t lines = BIT(REG_FIELD(info, chipsel));
/* Map SLIC number into line number */
for(i = 0; i < ARRAY_SIZE(input_channels); i++) {
@@ -751,10 +692,13 @@ HANDLER_DEF(FXS, SLIC_REPLY)
}
}
}
+out:
/* Update /proc info only if reply relate to the last slic read request */
- if(priv->requested_reply.indirect == info->indirect &&
- priv->requested_reply.reg_num == info->reg_num) {
- priv->last_reply = *info;
+ if(
+ REG_FIELD(&xpd->requested_reply, regnum) == REG_FIELD(info, regnum) &&
+ REG_FIELD(&xpd->requested_reply, do_subreg) == REG_FIELD(info, do_subreg) &&
+ REG_FIELD(&xpd->requested_reply, subreg) == REG_FIELD(info, subreg)) {
+ xpd->last_reply = *info;
}
spin_unlock_irqrestore(&xpd->lock, flags);
return 0;
@@ -763,9 +707,9 @@ HANDLER_DEF(FXS, SLIC_REPLY)
xproto_table_t PROTO_TABLE(FXS) = {
.owner = THIS_MODULE,
.entries = {
- /* Card Opcode */
- XENTRY( FXS, SIG_CHANGED ),
- XENTRY( FXS, SLIC_REPLY ),
+ /* Prototable Card Opcode */
+ XENTRY( FXS, FXS, SIG_CHANGED ),
+ XENTRY( FXS, FXS, REGISTER_REPLY ),
},
.name = "FXS",
.type = XPD_TYPE_FXS,
@@ -780,7 +724,7 @@ xproto_table_t PROTO_TABLE(FXS) = {
.RING = XPROTO_CALLER(FXS, RING),
.RELAY_OUT = XPROTO_CALLER(FXS, RELAY_OUT),
- .CHAN_ENABLE = XPROTO_CALLER(FXS, CHAN_ENABLE),
+ .XPD_STATE = XPROTO_CALLER(FXS, XPD_STATE),
.CHAN_CID = XPROTO_CALLER(FXS, CHAN_CID),
.SYNC_SOURCE = XPROTO_CALLER(GLOBAL, SYNC_SOURCE),
@@ -799,9 +743,9 @@ static bool fxs_packet_is_valid(xpacket_t *pack)
return xe != NULL;
}
-static void fxs_packet_dump(xpacket_t *pack)
+static void fxs_packet_dump(const char *msg, xpacket_t *pack)
{
- DBG("\n");
+ DBG("%s\n", msg);
}
/*------------------------- SLIC Handling --------------------------*/
@@ -857,112 +801,39 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count, in
return len;
}
-static int proc_xpd_slic_read(char *page, char **start, off_t off, int count, int *eof, void *data)
-{
- int len = 0;
- unsigned long flags;
- xpd_t *xpd = data;
- slic_reply_t *info;
- struct FXS_priv_data *priv;
-
- BUG_ON(!xpd);
- spin_lock_irqsave(&xpd->lock, flags);
- priv = xpd->priv;
- BUG_ON(!priv);
- info = &priv->last_reply;
- len += sprintf(page + len, "# Writing bad data into this file may damage your hardware!\n");
- len += sprintf(page + len, "# Consult firmware docs first\n");
- len += sprintf(page + len, "SLIC_REPLY: %s reg_num=0x%X, dataH=0x%X dataL=0x%X\n",
- (info->indirect)?"I":"D",
- info->reg_num, info->data_high, info->data_low);
- spin_unlock_irqrestore(&xpd->lock, flags);
- if (len <= off+count)
- *eof = 1;
- *start = page + off;
- len -= off;
- if (len > count)
- len = count;
- if (len < 0)
- len = 0;
- return len;
-}
-
/*
- * Direct/Indirect
- * v
- * FF FF FF FF WD 06 1
- * ^---------^ ^ Reg
- * | Write/Read
- * |
- * SLIC #
+ *
+ * Direct/Indirect
+ * |
+ * | Reg#
+ * | |
+ * | | Data (only in Write)
+ * | | |
+ * | | +-+-+
+ * v v v v
+ * FF WD 06 01 05
+ * ^ ^
+ * | |
+ * | Write/Read
+ * |
+ * Chan#
+ *
*/
-static int parse_slic_cmd(const char *buf, slic_cmd_t *sc, slic_reply_t *requested_reply)
+static int handle_register_command(xpd_t *xpd, char *cmdline)
{
- char op; /* [W]rite, [R]ead */
- char reg_type; /* [D]irect, [I]ndirect */
- int s1, s2, s3, s4;
- int reg_num;
- int data_low, data_high;
- xpp_line_t lines;
- int ret;
-
- ret = sscanf(buf, "%x %x %x %x %c%c %x %x %x",
- &s1, &s2, &s3, &s4, &op, &reg_type, &reg_num, &data_high, &data_low);
- lines = (s4 << 24) | (s3 << 16) | (s2 << 8) | (s1);
- switch(op) {
- case 'R':
- if(reg_type == 'D' && ret == 7) {
- // DBG("0x%X 0x%X 0x%X 0x%X %c %x\n", s1, s2, s3, s4, reg_type, reg_num);
- ret = slic_cmd_direct_read(sc, lines, reg_num);
- if(requested_reply) {
- requested_reply->indirect = 0;
- requested_reply->reg_num = reg_num;
- }
- } else if(reg_type == 'I' && ret == 7) {
- // DBG("0x%X 0x%X 0x%X 0x%X %c %x\n", s1, s2, s3, s4, reg_type, reg_num);
- ret = slic_cmd_indirect_read(sc, lines, reg_num);
- if(requested_reply) {
- requested_reply->indirect = 1;
- requested_reply->reg_num = reg_num;
- }
- } else {
- NOTICE("%s: Bad read input: ret=%d buf='%s' reg_type=%c\n", __FUNCTION__, ret, buf, reg_type);
- goto err;
- }
- break;
- case 'W':
- if(reg_type == 'D' && ret == 8) {
- // DBG("0x%X 0x%X 0x%X 0x%X %c %x %X\n", s1, s2, s3, s4, reg_type, reg_num, data_high);
- ret = slic_cmd_direct_write(sc, lines, reg_num, data_high);
- } else if(reg_type == 'I' && ret == 9) {
- // DBG("0x%X 0x%X 0x%X 0x%X %c %x %X %X\n", s1, s2, s3, s4, reg_type, reg_num, data_high, data_low);
- ret = slic_cmd_indirect_write(sc, lines, reg_num, data_low, data_high);
- } else {
- NOTICE("%s: Bad write input: ret=%d buf='%s' reg_type=%c\n", __FUNCTION__, ret, buf, reg_type);
- goto err;
- }
- break;
- default:
- NOTICE("%s: Bad input: ret=%d buf='%s' op=%c\n", __FUNCTION__, ret, buf, op);
- goto err;
- }
- return ret;
-err:
- return -EINVAL;
-}
-
-static int process_slic_cmdline(xpd_t *xpd, char *cmdline)
-{
- xbus_t *xbus;
- struct FXS_priv_data *priv;
- slic_cmd_t sc;
- xpacket_t *pack;
+ unsigned chipsel;
+ unsigned data_low = 0;
+ unsigned data_high = 0;
+ char op; /* [W]rite, [R]ead */
+ char reg_type; /* [D]irect, [I]ndirect */
+ int reg_num;
+ int elements;
+ bool writing;
char *p;
- int len = strlen(cmdline);
+ reg_cmd_t regcmd;
+ xbus_t *xbus;
+ int ret;
- BUG_ON(!xpd);
- xbus = xpd->xbus;
- priv = xpd->priv;
if((p = strchr(cmdline, '#')) != NULL) /* Truncate comments */
*p = '\0';
if((p = strchr(cmdline, ';')) != NULL) /* Truncate comments */
@@ -971,22 +842,85 @@ static int process_slic_cmdline(xpd_t *xpd, char *cmdline)
;
if(*p == '\0')
return 0;
- len = parse_slic_cmd(p, &sc, &priv->requested_reply);
- if(len < 0)
- return len;
- if(!sc.lines) {
- NOTICE("%s: no channels are marked. Skip.\n", __FUNCTION__);
- return 0;
+
+ elements = sscanf(cmdline, "%d %c%c %x %x %x",
+ &chipsel,
+ &op, &reg_type, &reg_num,
+ &data_low,
+ &data_high);
+ // DBG("'%s': %d %c%c %02X %02X %02X\n", cmdline, chipsel, op, reg_type, reg_num, data_low, data_high);
+ if(elements < 4) { // At least: chipsel, op, reg_type, reg_num
+ ERR("Not enough arguments: (%d args) '%s'\n", elements, cmdline);
+ return -EINVAL;
}
- dump_slic_cmd("WRITE_SLIC", &sc);
- XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
- RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd) = sc;
- pack->datalen = len;
- packet_send(xbus, pack);
- return 0;
+ if(!VALID_CHIPSEL(chipsel)) {
+ ERR("Bad chipsel number: %d\n", chipsel);
+ return -EINVAL;
+ }
+ REG_FIELD(&regcmd, chipsel) = chipsel;
+ switch(op) {
+ case 'W':
+ writing = 1;
+ break;
+ case 'R':
+ writing = 0;
+ break;
+ default:
+ ERR("Unkown operation type '%c'\n", op);
+ return -EINVAL;
+ }
+ switch(reg_type) {
+ case 'I':
+ REG_FIELD(&regcmd, do_subreg) = 1;
+ REG_FIELD(&regcmd, regnum) = 0x1E; // FIXME: card dependent...
+ REG_FIELD(&regcmd, subreg) = reg_num;
+ break;
+ case 'D':
+ REG_FIELD(&regcmd, do_subreg) = 0;
+ REG_FIELD(&regcmd, regnum) = reg_num;
+ REG_FIELD(&regcmd, subreg) = 0;
+ break;
+ default:
+ ERR("Unkown register type '%c'\n", reg_type);
+ return -EINVAL;
+ }
+ if(
+ (op == 'W' && reg_type == 'D' && elements != 5) ||
+ (op == 'W' && reg_type == 'I' && elements != 6) ||
+ (op == 'R' && reg_type == 'D' && elements != 4) ||
+ (op == 'R' && reg_type == 'I' && elements != 4)
+ ) {
+ ERR("%s: '%s' (%d elements): %d %c%c %02X %02X %02X\n", __FUNCTION__,
+ cmdline, elements,
+ chipsel, op, reg_type, reg_num, data_low, data_high);
+ return -EINVAL;
+ }
+ regcmd.bytes = sizeof(regcmd) - 1;
+ REG_FIELD(&regcmd, data_low) = data_low;
+ REG_FIELD(&regcmd, data_high) = data_high;
+ REG_FIELD(&regcmd, read_request) = writing;
+ BUG_ON(!xpd);
+ xbus = xpd->xbus;
+ if(!down_read_trylock(&xbus->in_use)) {
+ DBG("Dropped packet. %s is in_use\n", xbus->busname);
+ return -EBUSY;
+ }
+ xpd->requested_reply = regcmd;
+ if(print_dbg)
+ dump_reg_cmd("FXS", &regcmd);
+ ret = CALL_PROTO(FXS, REGISTER_REQUEST, xpd->xbus, xpd,
+ REG_FIELD(&regcmd, chipsel),
+ writing,
+ REG_FIELD(&regcmd, do_subreg),
+ REG_FIELD(&regcmd, regnum),
+ REG_FIELD(&regcmd, subreg),
+ REG_FIELD(&regcmd, data_low),
+ REG_FIELD(&regcmd, data_high));
+ up_read(&xbus->in_use);
+ return ret;
}
-static int proc_xpd_slic_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
+static int proc_xpd_register_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
{
xpd_t *xpd = data;
char buf[MAX_PROC_WRITE];
@@ -1009,7 +943,7 @@ static int proc_xpd_slic_write(struct file *file, const char __user *buffer, uns
if(p >= buf + MAX_PROC_WRITE)
return -E2BIG;
*p = '\0';
- ret = process_slic_cmdline(xpd, buf);
+ ret = handle_register_command(xpd, buf);
if(ret < 0)
return ret;
mdelay(1);
@@ -1017,6 +951,41 @@ static int proc_xpd_slic_write(struct file *file, const char __user *buffer, uns
return count;
}
+static int proc_xpd_register_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+ int len = 0;
+ unsigned long flags;
+ xpd_t *xpd = data;
+ reg_cmd_t *info;
+ byte regnum;
+ bool indirect;
+
+ if(!xpd)
+ return -ENODEV;
+ spin_lock_irqsave(&xpd->lock, flags);
+ info = &xpd->last_reply;
+ indirect = (REG_FIELD(info, regnum) == 0x1E);
+ regnum = (indirect) ? REG_FIELD(info, subreg) : REG_FIELD(info, regnum);
+ len += sprintf(page + len, "# Writing bad data into this file may damage your hardware!\n");
+ len += sprintf(page + len, "# Consult firmware docs first\n");
+ len += sprintf(page + len, "#\n");
+ len += sprintf(page + len, "#CH\tD/I\tReg.\tDL DH\n");
+ len += sprintf(page + len, "%2d\tR%c\t%02X\t%02X %02X\n",
+ REG_FIELD(info, chipsel),
+ (indirect)?'I':'D',
+ regnum, REG_FIELD(info, data_low), REG_FIELD(info, data_high));
+ spin_unlock_irqrestore(&xpd->lock, flags);
+ if (len <= off+count)
+ *eof = 1;
+ *start = page + off;
+ len -= off;
+ if (len > count)
+ len = count;
+ if (len < 0)
+ len = 0;
+ return len;
+}
+
int __init card_fxs_startup(void)
{
diff --git a/xpp/card_fxs.h b/xpp/card_fxs.h
index bed1a4f..2af2884 100644
--- a/xpp/card_fxs.h
+++ b/xpp/card_fxs.h
@@ -23,22 +23,18 @@
*/
#include "xpd.h"
-#include "slic.h"
enum fxs_opcodes {
XPROTO_NAME(FXS, SIG_CHANGED) = 0x06,
/**/
- XPROTO_NAME(FXS, SLIC_WRITE) = 0x0F, /* Write to SLIC */
- XPROTO_NAME(FXS, CHAN_ENABLE) = 0x0F, /* Write to SLIC */
+ XPROTO_NAME(FXS, XPD_STATE) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, CHAN_POWER) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, CHAN_CID) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, RING) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, LED) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, RELAY_OUT) = 0x0F, /* Write to SLIC */
- XPROTO_NAME(FXS, SLIC_INIT) = 0x0F, /* Write to SLIC */
- XPROTO_NAME(FXS, SLIC_QUERY) = 0x0F, /* Write to SLIC */
/**/
- XPROTO_NAME(FXS, SLIC_REPLY) = 0x10,
+ XPROTO_NAME(FXS, REGISTER_REPLY) = 0x10,
};
@@ -47,12 +43,8 @@ DEF_RPACKET_DATA(FXS, SIG_CHANGED,
xpp_line_t sig_status; /* channels: lsb=1, msb=8 */
xpp_line_t sig_toggles; /* channels: lsb=1, msb=8 */
);
-DEF_RPACKET_DATA(FXS, SLIC_REPLY, /* Get status of a single SLIC (for debugging) */
- xpp_line_t lines;
- slic_reply_t info;
- );
-DEF_RPACKET_DATA(FXS, SLIC_WRITE,
- slic_cmd_t slic_cmd;
+DEF_RPACKET_DATA(FXS, REGISTER_REPLY, /* Get status of a single SLIC (for debugging) */
+ reg_cmd_t reg_cmd;
);
#endif /* CARD_FXS_H */
diff --git a/xpp/card_global.c b/xpp/card_global.c
index dda4480..4740eab 100644
--- a/xpp/card_global.c
+++ b/xpp/card_global.c
@@ -29,13 +29,24 @@
static const char rcsid[] = "$Id$";
+DEF_PARM(charp,initdir, "/usr/share/zaptel", "The directory of card initialization scripts");
+/*
+ * BRI: Temporary software workaround for firmware limitation:
+ * - The BRI firmware count PCM channel number globally across subunits.
+ * - The module parameter 'bri_pcmshift' enables us to cheat and shift
+ * each B-channel, 4 bits for each subsequent subunit.
+ * - Eventually, this should be fixed in the firmware, otherwise we won't
+ * handle PRI (all the space we have is 32bits).
+ */
+DEF_PARM(bool,bri_pcmshift, 1, "TESTING: shift bri PCM bits by subunit number");
+
extern int print_dbg;
static bool pcm_valid(xpd_t *xpd, xpacket_t *pack);
/*---------------- GLOBAL Protocol Commands -------------------------------*/
static bool global_packet_is_valid(xpacket_t *pack);
-static void global_packet_dump(xpacket_t *pack);
+static void global_packet_dump(const char *msg, xpacket_t *pack);
/*---------------- GLOBAL: HOST COMMANDS ----------------------------------*/
@@ -66,9 +77,6 @@ static void global_packet_dump(xpacket_t *pack);
BUG_ON(!xbus);
BUG_ON(!xpd);
lines &= ~xpd->no_pcm;
-// if(lines == 0)
-// return 0;
-
/*
* FIXME: Workaround a bug in sync code of the Astribank.
* Send dummy PCM for sync.
@@ -86,6 +94,10 @@ static void global_packet_dump(xpacket_t *pack);
}
buf += ZT_CHUNKSIZE;
}
+ if(bri_pcmshift) { /* workaround for pcm problem in BRI */
+ lines = lines << (xpd->addr.subunit * 4);
+ RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, lines) = lines;
+ }
pack->datalen = sizeof(xpp_line_t) + (pcm - start_pcm);
packet_send(xbus, pack);
XPD_COUNTER(xpd, PCM_WRITE)++;
@@ -176,6 +188,10 @@ HANDLER_DEF(GLOBAL, PCM_READ)
}
// DBG("lines=0x%04X\n", lines);
+ if(bri_pcmshift) { /* workaround for pcm problem in BRI */
+ lines = (lines >> (xpd->addr.subunit * 4)) & 0x7;
+ RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, lines) = lines;
+ }
if(!pcm_valid(xpd, pack)) {
return -EPROTO;
}
@@ -201,6 +217,7 @@ HANDLER_DEF(GLOBAL, PCM_READ)
XBUS_COUNTER(xpd->xbus, PCM_READ)++;
spin_unlock_irqrestore(&xpd->lock, flags);
xpp_tick((unsigned long)xpd);
+
return 0;
}
@@ -222,14 +239,44 @@ HANDLER_DEF(GLOBAL, SYNC_REPLY)
return 0;
}
+HANDLER_DEF(GLOBAL, ERROR_CODE)
+{
+ byte errorcode = RPACKET_FIELD(pack, GLOBAL, ERROR_CODE, errorcode);
+ reg_cmd_t *bad_cmd;
+ char xpdname[XPD_NAMELEN];
+
+ BUG_ON(!xbus);
+ if(!xpd) {
+ int xpd_num = XPD_NUM(pack->content.addr);
+ snprintf(xpdname, XPD_NAMELEN, "....#%d", xpd_num);
+ } else {
+ snprintf(xpdname, XPD_NAMELEN, "%s", xpd->xpdname);
+ }
+ NOTICE("%s/%s: %s CODE = 0x%X\n", xbus->busname, xpdname, cmd->name, errorcode);
+ switch(errorcode) {
+ case 1:
+ bad_cmd = &RPACKET_FIELD(pack, GLOBAL, ERROR_CODE, info.bad_spi_cmd);
+ dump_packet("BAD_SPI_CMD", pack, 1);
+ break;
+ default:
+ NOTICE("%s/%s: %s UNKNOWN CODE = 0x%X\n", xbus->busname, xpdname, cmd->name, errorcode);
+ dump_packet("PACKET", pack, 1);
+ }
+ /*
+ * FIXME: Should implement an error recovery plan
+ */
+ return 0;
+}
+
xproto_table_t PROTO_TABLE(GLOBAL) = {
.entries = {
- /* Card Opcode */
- XENTRY( GLOBAL, NULL_REPLY ),
- XENTRY( GLOBAL, DEV_DESC ),
- XENTRY( GLOBAL, PCM_READ ),
- XENTRY( GLOBAL, SYNC_REPLY ),
+ /* Prototable Card Opcode */
+ XENTRY( GLOBAL, GLOBAL, NULL_REPLY ),
+ XENTRY( GLOBAL, GLOBAL, DEV_DESC ),
+ XENTRY( GLOBAL, GLOBAL, PCM_READ ),
+ XENTRY( GLOBAL, GLOBAL, SYNC_REPLY ),
+ XENTRY( GLOBAL, GLOBAL, ERROR_CODE ),
},
.name = "GLOBAL",
.packet_is_valid = global_packet_is_valid,
@@ -245,9 +292,9 @@ static bool global_packet_is_valid(xpacket_t *pack)
return xe != NULL;
}
-static void global_packet_dump(xpacket_t *pack)
+static void global_packet_dump(const char *msg, xpacket_t *pack)
{
- DBG("\n");
+ DBG("%s\n", msg);
}
static bool pcm_valid(xpd_t *xpd, xpacket_t *pack)
@@ -267,9 +314,89 @@ static bool pcm_valid(xpd_t *xpd, xpacket_t *pack)
XPD_COUNTER(xpd, RECV_ERRORS)++;
if((rate_limit++ % 1000) <= 10) {
ERR("BAD PCM REPLY: pack->datalen=%d, count=%d\n", pack->datalen, count);
+ dump_packet("BAD PCM REPLY", pack, 1);
}
return 0;
}
return 1;
}
+#define MAX_ENV_STR 20
+#define MAX_PATH_STR 60
+
+int run_initialize_registers(xpd_t *xpd)
+{
+ int ret;
+ xbus_t *xbus;
+ char busstr[MAX_ENV_STR];
+ char xpdstr[MAX_ENV_STR];
+ char unitstr[MAX_ENV_STR];
+ char subunitstr[MAX_ENV_STR];
+ char typestr[MAX_ENV_STR];
+ char revstr[MAX_ENV_STR];
+ char init_card[MAX_PATH_STR];
+ char *argv[] = {
+ init_card,
+ NULL
+ };
+ char *envp[] = {
+ busstr,
+ xpdstr,
+ unitstr,
+ subunitstr,
+ typestr,
+ revstr,
+ NULL
+ };
+
+ BUG_ON(!xpd);
+ xbus = xpd->xbus;
+ if(!initdir || !initdir[0]) {
+ NOTICE("%s/%s: Missing initdir parameter\n", xbus->busname, xpd->xpdname);
+ return -EINVAL;
+ }
+ snprintf(busstr, MAX_ENV_STR, "XPD_BUS=%s", xbus->busname);
+ snprintf(xpdstr, MAX_ENV_STR, "XPD_NAME=%s", xpd->xpdname);
+ snprintf(unitstr, MAX_ENV_STR, "XPD_UNIT=%d", xpd->addr.unit);
+ snprintf(subunitstr, MAX_ENV_STR, "XPD_SUBUNIT=%d", xpd->addr.subunit);
+ snprintf(typestr, MAX_ENV_STR, "XPD_TYPE=%d", xpd->type);
+ snprintf(revstr, MAX_ENV_STR, "XPD_REVISION=%d", xpd->revision);
+ if(snprintf(init_card, MAX_PATH_STR, "%s/init_card_%d_%d",
+ initdir, xpd->type, xpd->revision) > MAX_PATH_STR) {
+ NOTICE("%s/%s: Cannot initialize. pathname is longer than %d characters.\n",
+ xbus->busname, xpd->xpdname, MAX_PATH_STR);
+ return -E2BIG;
+ }
+ if(!down_read_trylock(&xbus->in_use)) {
+ ERR("Skipped register initialization. %s is going down\n", xbus->busname);
+ return -ENODEV;
+ }
+ DBG("%s/%s: running '%s' for type=%d revision=%d\n",
+ xbus->busname, xpd->xpdname, init_card, xpd->type, xpd->revision);
+ ret = call_usermodehelper(init_card, argv, envp, 1);
+ /*
+ * Carefully report results
+ */
+ if(ret == 0)
+ DBG("%s/%s: '%s' finished OK\n", xbus->busname, xpd->xpdname, init_card);
+ else if(ret < 0) {
+ ERR("%s/%s: Failed running '%s' (errno %d)\n",
+ xbus->busname, xpd->xpdname, init_card, ret);
+ } else {
+ byte exitval = ((unsigned)ret >> 8) & 0xFF;
+ byte sigval = ret & 0xFF;
+
+ if(!exitval) {
+ ERR("%s/%s: '%s' killed by signal %d\n",
+ xbus->busname, xpd->xpdname, init_card, sigval);
+ } else {
+ ERR("%s/%s: '%s' aborted with exitval %d\n",
+ xbus->busname, xpd->xpdname, init_card, exitval);
+ }
+ ret = -EINVAL;
+ }
+ up_read(&xbus->in_use);
+ return ret;
+}
+
+EXPORT_SYMBOL(run_initialize_registers);
diff --git a/xpp/card_global.h b/xpp/card_global.h
index 5ab8124..94e073b 100644
--- a/xpp/card_global.h
+++ b/xpp/card_global.h
@@ -31,6 +31,9 @@ DEF_RPACKET_DATA(GLOBAL, DEV_DESC,
byte type; /* LSB: 1 - to_phone, 0 - to_line */
xpp_line_t line_status; /* hook/ring status, depending on unit */
);
+DEF_RPACKET_DATA(GLOBAL, REGISTER_REQUEST,
+ reg_cmd_t reg_cmd;
+ );
DEF_RPACKET_DATA(GLOBAL, PCM_WRITE,
xpp_line_t lines;
byte pcm[PCM_CHUNKSIZE];
@@ -45,6 +48,12 @@ DEF_RPACKET_DATA(GLOBAL, SYNC_SOURCE,
DEF_RPACKET_DATA(GLOBAL, SYNC_REPLY,
byte mask;
);
+DEF_RPACKET_DATA(GLOBAL, ERROR_CODE,
+ byte errorcode;
+ union {
+ reg_cmd_t bad_spi_cmd;
+ } info;
+ );
/* 0x04 */ DECLARE_CMD(GLOBAL, DESC_REQ, int xpd_num);
@@ -52,5 +61,6 @@ DEF_RPACKET_DATA(GLOBAL, SYNC_REPLY,
/* 0x11 */ DECLARE_CMD(GLOBAL, PCM_WRITE, xpp_line_t lines, volatile byte *buf);
extern xproto_table_t PROTO_TABLE(GLOBAL);
+int run_initialize_registers(xpd_t *xpd);
#endif /* CARD_GLOBAL_H */
diff --git a/xpp/firmwares/FPGA_1151.hex b/xpp/firmwares/FPGA_1151.hex
new file mode 100644
index 0000000..e554933
--- /dev/null
+++ b/xpp/firmwares/FPGA_1151.hex
@@ -0,0 +1,576 @@
+#
+# $Id: FPGA_1151.hex 2478 2006-10-17 13:50:18Z dima $
+#
+:020000040000FA
+:80000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6AD6FF4000E0E508006AD6FF4000E0E508006AD6FF4000E0E5080000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4455544455557475577775577675577775577765566665563625523235D2E37C2B511115511115511115511167
+:80008000155111155111155111155111155111155111155111155111155111155111155111155111155111155111155111155111000000000000000000000000000000000000002552222552222552220025522225522200000000001AA1111AA1110025522200001AA1111AA111001AA11100001AA1111AA11100001AA1111AA1111AA113
+:80010000110000002552222552222F21F112122F21F112122552222552222552222552221AA1111AA111001AA1112552222552222F21F112122F21F112122F21F112122552222F21F112122F21F112122F21F11212255222000000002F21F112122F21F1121200002552222552221AA1111AA1112552222F21F1121200001AA1112F21F149
+:8001800012121AA111002F21F112122F21F112121AA11100255222255222000000000025522200001AA1111AA11125522200255222000025522200000000EFEAFAAEAE5F56F66565000000000000000000000000001AA1111AA1110000000000000000000000000000255222000000002552222552220000255222255222255222255222E0
+:800200002552222552222552222552222552220025522200000000000000000000004F44F444444F45F554541AA1114F44F444440000000000000000255222255222000000004554446F61F116162F21F11212000000CAACCC2F2DFDD2D22F21F112124F48F884846F61F116164554444AA4446F65F556566F61F116164F41F11414455491
+:80028000446F65F556566F65F556566F65F5565600000000002F21F112122F21F112120000004F4CFCC4C46F6DFDD6D62F21F112128AA8882F21F11212004F44F444446F65F556562F21F112122F21F11212006F65F556563F3FFFF3F3EFE5F55E5E006F65F556566F65F55656000000008F8CFCC8C8AFACFCCACA255222000000CFCCFC12
+:80030000CCCCCFCCFCCCCC008F8CFCC8C825522200CFCCFCCCCCCFCCFCCCCC000000CFCCFCCCCCCFCCFCCCCCCFCCFCCCCC00000000CFC4F44C4CCFC4F44C4C000000008F8CFCC8C8AFACFCCACA255222CFCCFCCCCCC55CCCC55CCC4AA444EFE4F44E4EE55EEEC55CCCC55CCCEFE4F44E4EEFE4F44E4EEFE4F44E4E00000000C55CCCC55C42
+:80038000CC000000008F8CFCC8C8AFACFCCACA255222CFC8F88C8CC55CCCC55CCC4AA444EFE4F44E4EE55EEEC55CCCC55CCCEFE4F44E4EEFE4F44E4EEFE4F44E4E00000000C55CCCC55CCC000000008F8CFCC8C8AFACFCCACA255222CFC8F88C8CC55CCCC55CCC4AA444EFE4F44E4EE55EEEC55CCCC55CCCEFE4F44E4EEFE4F44E4EEFE4FD
+:80040000F44E4E00000000C55CCCCFC3F33C3C3AA3330000008F8CFCC8C8AFAFFFFAFA2F23F33232CFC8F88C8CCFC3F33C3CC55CCC4AA444EFE7F77E7EEFE3F33E3ECFC3F33C3CC55CCCCAACCCDFD6F66D6D00EFE7F77E7EEFE7F77E7EEFE7F77E7E000000008AA888BAABBB3AA333000000CFCCFCCCCCEFEEFEEEEE2F22F222228AA88867
+:800480003AA33300CFCCFCCCCCEFEEFEEEEE2F22F222220000EFEEFEEEEEEFEEFEEEEEEFEEFEEEEE000000004AA4441F14F44141155111000000CFCCFCCCCCFFFFFFFFFF3F33F333334AA44415511100CFCCFCCCCCFFFFFFFFFF3F33F3333315511100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000008F84F448489F95F559591F11F11169
+:8005000011000000CFCCFCCCCCFFFEFEEFEF3F32F223238F84F448489F91F119198558884F4CFCC4C4FFFEFEEFEFBFB2F22B2B955999855888FFFEFEEFEFFFFEFEEFEFFFFEFEEFEF00000000CFC4F44C4CFFF4F44F4F3553330000008F8CFCC8C8BFBFFFFBFB3F33F33333CFC4F44C4CF55FFFC55CCCCAACCCFFFFFFFFFFFFF3F33F3FF50A
+:800580005FFFC55CCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000004554444F42F224242AA2220000008F8CFCC8C8BFBFFFFBFB3F33F333334554444F42F224244554448F8CFCC8C8FFFFFFFFFF7F73F337374F42F22424EFE6F66E6E2F2EFEE2E200455444FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000004AA4446AA6662AA2220000D5
+:8006000000CFCCFCCCCCFFFFFFFFFF3F33F333334AA4442AA22200CFCCFCCCCCFFFFFFFFFF3F33F333332AA22200FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000CFC4F44C4CCFC6F66C6C2AA2220000008F8CFCC8C8BFBFFFFBFB3F33F33333CFC4F44C4CCFC2F22C2CC55CCCCAACCCFFFFFFFFFFFFF3F33F3FCFC2F22C2CC55CCCFFFFEF
+:80068000FFFFFFFFFFFFFFFFFFFFFFFFFF000000004F48F884846F68F886862552220000008F8CFCC8C8BFBFFFFBFB3F33F333334F48F88484255222008F8CFCC8C8BFBFFFFBFB3F33F333330000BFBFFFFBFBBFBFFFFBFBBFBFFFFBFB000000008AA8882F28F88282255222000000CFCCFCCCCCFFFFFFFFFF3F33F333334F48F884842552
+:800700005222008F8CFCC8C8BFBFFFFBFB3F33F3333325522200BFBFFFFBFBBFBFFFFBFBBFBFFFFBFB00000000455444655666255222000000CFCCFCCCCCFFFFFFFFFF3F33F333334F48F884846556664554448F84F44848FFF7F77F7F7F73F33737DFDAFAADAD4F44F4444400655666455444FFF7F77F7FFFF7F77F7FFFF7F77F7F00005D
+:8007800000004F44F444447F75F557573F31F11313000000CFCCFCCCCCDFDFFFFDFD1F13F331314F44F444447F75F557574F44F444448F88F88888DFDFFFFDFD5F57F775754F44F444444F44F44444DFDFFFFDFDDFDFFFFDFDDFDFFFFDFD000000004F44F444445F55F555551F11F111110000008F8CFCC8C88F8FFFF8F83AA3334AA4445F
+:800800001F15F551514AA4448F88F888888F8FFFF8F87AA7774AA4444AA4448F8FFFF8F88F8FFFF8F88F8FFFF8F8000000004F44F444445F57F775751F13F33131000000CFCCFCCCCCDFDEFEEDED1F12F221214F44F444441F17F771714AA444CFC8F88C8CDFDEFEEDED1F16F661614AA4444AA444DFDEFEEDEDDFDEFEEDEDDFDEFEEDED3A
+:80088000000000004AA4445AA5551AA111000000CFCCFCCCCCDFDFFFFDFD1F13F331314F44F444441F17F771714AA4448F88F888888F8DFDD8D85AA5554AA4444AA4448F8DFDD8D88F8DFDD8D88F8DFDD8D80000000000000000000000000000000000005F5BFBB5B52F2FFFF2F2000080010000000000000000000000000000000000000D
+:800900000000000000000000D0510F480000000000000000000000000000400100000000000000000000000000708F0D0000000000000000000000000000000000000000000000000000000000F04FFE8004001800000000000000000000000040010000000000000000000000000070C10600000000000000000000000000000000000061
+:800980000000000000000000000000F04FFE8002004001008004148002800414800200008002800400002148000000484001002148000010F277C2000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE808401800200000071
+:800A0000100200001002400140110240010000400128140000882800008088028002E08207008084010000200100000000000000120000400100000000000014000000000050358084410128004840818102214860118002211A01148002211A041400B01281041480028004148828108204808802214800CF5506481800280000000021CD
+:800A8000000000210014001002400100004001280000808802000088280000F08CBF000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000000000000100200000000002800008008000000280000F0AA2100002002000000100200001002000080018001000000000000002200002008E7
+:800B00000000F09F5D00000000000040020000000000000000000000000000000000000082000000DFE20D000000000000000000000000000000120000000000000000000000000000CFE70B000000000000000000000000008001000000000000000000000000280000F0F5FA0000800200000000000000210000002100000000000000D8
+:800B80000000000000000000F051E8000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000000000002002000082000000000000F0B1AA000000000000000000000000000000000000000000000020020000000000F0644100000000000000000000000000000000000034
+:800C000000002200000000000082000000FFB40A0000000000000000000000002002000020022424000000000000000000000070FC0F000000000000000000000000000000000000210000000000000020080000F0EFA70000000000000000000000000028000000284002008002000000000000000000CF490D0000000000200100820061
+:800C800000200100001C01000000000000000000000000002028021F23010000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000240000000000000000280000000000004F6409000000480000200100000012000000000000000000000000000000000000007BD700000017
+:800D00008004000012000000200100000000210000000000000080020000000000F0DA9A000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FF87
+:800D8000E40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000000020020000000000000080040000F03C530020040000000000000000002001000000000000000000000000000067
+:800E0000000000AF420A000000000000002001000000000000000000008001000000000000000000D0E30E00000000000000200100000000000000000022001800000000000000000000EF38080000000000000000000000000000000000000000000000000000480000001FEB030000000000000000000000000000000000000000000035
+:800E800000000000000000F04FFE00000000000000001200000000180000000000008001000000000000000000F0F17E000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000012200112200100200100000000000000000000000000000000DF880900000000000000000000000000000000C2
+:800F00000000000000000000000000000014EFE8030000000000000000000000000000000000000000000000000000000000F04FFE00000000000080810100120012000000000000000000000000000000000000005FF7020000000000000000000000000000000000000000000000000000000000F04FFE00800400000000800200000085
+:800F800010021880080000140000480000000000280000000021143FD803000000000000182001121812200100200100000000000000000000000000000014F0F3FC00000000000000000000800100000000000000001800000000000000000000AFA30F000000000000800112000000000000000000000000000000000000000000F0B98C
+:80100000B50000008004000000800118800100000000000000000000000000000000000000AE1B000000A0444A0400A0111A011212A0111A0100000000000000A0111AA1111A010000000000000000004F290CA0448004A0444A0400A033A03112121AA1111A4112022B11A098800800150114005AA5111AA511000000A02280020000243F
+:801080002110F2824F004800000000001AA31180011A01A011218001880000400100A0511A0100000000280000000021009FAC0F800442000000001A033A8101A011A011212418A081200800141001A0511A21040000008002220000002124F0DFAA000000000000000000000000000000000000001880010000000000000000008F2F06C4
+:80110000820000000000000000000000000000000000001800000000000000000000141F340E481B21B01122B411324219B24291212B9419B24239112B94322F1429F34291322D912AC4912E421CE82264112E4296E12264192CA4292CB491C2421B29241B29421B2923B481324219B24298212B84112B84222B84222B842229A842882E9A
+:8011800042CFFE0D481B61481B21421B212119B64291212B941B212BA41B212B84322F1428F34281322D812B422D912E521CE922EC11E82264192E4296C1439E212CB491C2421B692CB49122B49132421B282394212B8419B2429A212B84222B84222B842229B82294822E422FB40800480000000000280000000021800188000040010089
+:80120000800400000000800200000010022FD40F82000000000012000000000000000000000000008001000000000000000040F13449008200000000000000000000000000000000000000000000000000000040013736004200000000802102000000240012A018000010010020040000000020020000002400F0D2CE0000000000000073
+:801280000000000000000000000000000018000000000000000000F0D73E000000000000000000000000000000000000000000000000000000000000FFE40F0000000000001200000000000000000000000000000000000000000000008F740F0000000000001800000000000000000000000000000000000000000000002F9503000000DC
+:801300000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0088000000000000000000000000000000000000000000000000000000005FD702008800000000000000000000000000000000000000000000000000420000F074123E
+:80138000000000000000000000000000000000000000000000000000000000480000F01A3F000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000000000000000000000000000000000000000000000002D
+:80140000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000E
+:801480000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00820082000000000000000000000000000000000000000000000000000014149F7F02004800000000002800000000218001880000400100800400000000800200000010022FD40F2008000000000000000000000000000000000044
+:801500000000000000000000000014706303200820080000000000000000000000000000000000000000000000000040018F730E0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000B1
+:801580000000000000000000000000000000F04FFE00CA0448000000002A022800004012022B11A098800800150114004A0448000000002A02280000401202214F5F0280040000000080020000001002188008000014000048000000000028000000002100BD6F008A0442000000002820020000104282011A0882004001110048200400E1
+:8016000000008002220000002124F0739F000000200800000000000000000000000000000000000000000000000000B0910C000000000000000000000000000000000000000000000000000000000014EFE803481B21B01122B411324219B24291212B9419B24219B14229F24291222F1429D212A9421CE922C4812E4216E12264192E42B8
+:8016800096C1429AC2421B292CB49142B29122B49132421B282394212B8419B24218B14228B24228B2422892822A84E822B42C01481B61481B21421B212394212B1419B24299212BB419B24229F24291222F1429D212B922D412E922C5912EC21E812E4296E12264193CE419C2421B292CB491C6421B29421B2923B481324219B242982132
+:801700002BA419B24228B24228B2422892822B4229E822F465822022880400000000800200000010021880080000140000480000000000280000000021B0470E82008002000000A014000028000000000000000000000000008008002008000040B14F0D20080000000000008800800400200200000000000022000020080000004800002D
+:8017800014F0211D00C20000000000220082002848240012288200001001002004000000008222002028044002004F8507000022000000001A0400000000000000000000008002000082000000000000006F4204000000000000200100000020040000000000000000008028088200008004000070A40200000000000000200820820820B3
+:801800000200000080080082121800000000000000000088008BA5000000000000001800002282004A0200000000000018180000802808000000000000D03F080000000000000020080000000000000082008008000000008008000042008008100A000000002001280012224880820220810400480040020000004218000000008088047F
+:801880000000006FE7018004220048000080020082480000202182080020041A040048000000480080040000008200486F3C0400000000202201000000120000000000004200000000000000000000000000F049E90000280042002880022081A284482800200128004800422C2404000080840120040042008842000000D0360200000055
+:80190000002081010000001822008004000000200100000000000000000000800880F4B172000000000020040022280000000088008001202128082028080000800400800880040000F07BAD008004002002428028222488A8488882288082248801881288202224015842184820218401C28882A0484280280C8A0400008F7E0542008063
+:80198000044800202A0200004A82020080012004004200820020A8840080040088000000800C88002D7B0000004A02426822A0418A0448009200A041824A0222A02480840A000000800448882024840420042004202824A8849F260900208402280028880080080000A0C200882218923A248A2129019220018A21812101000082000020A0
+:801A000004882048F1B96420248404488024010000000000008008808908000000A08442480000000000000000002004AF210E000000004888004818A0282200800600228002200400000000C20080084A084888428008004200B0110C000020044A022006004220042800000000228280280400000000422004000088200488000088CF50
+:801A8000D50D004820220200928026A828A0412002324290226218808A24040086018028880488000000008A024820080048211C748108484200424AA4244A26A42882AAA16818A049828A02226AA4A4A02E2A086828B2E2C8CA24892881288DA88418A05442C8A0C4A0C4800448202C044886A1C8DBF92004002A064880A6426A8E24A4F2
+:801B0000484A0A2218AA220122C200B212724A08921A8109C28009929AAC411288C282008248CAA848CA0888A0C842008F46020020042A022A011A084A82088AA4A24AA486800258A8588228228A8585A422008218CA0482200400A044824A088A0800CA84840888C842CF3A0100008200808401188A8401188218823880014A028001187C
+:801B8000800118802184011848188008200848002008002004426FBC084A0480A4664AA6447A2724A9276AA6959AA1354AA5773AA331185AA5519A8B84A8123AA2E6CAA855BAA8448AA899A0D18AA8991AA484124A044AA444884AA48C824A84A4C4CAA444A088A0888AF817DA80A44480A46C684AA4447AA389FAAA377A2BA8246AAFB377
+:801C00002AAAA22AE3219542282B7388AAA81388A0773A51118AE819A1889AADCC9AA9D9CAA81120A84C4AA4C44AA4268AA8EC484AAC4C00242B44B0C2FCC3B8A04448004AA6644AA4734AA47262FAA3EC8AAC8CD2CAA52AAA22A1722B62EAAADC2AAA82327AA6995AA58B5E419AA9995AA1D59AAD99125AA4415A84A8C4CAA488A0EC4807
+:801C80004A24A8C8CAACCCA0CC21CAAC883FB3054A8404A0644AA6666AA677AAAFAEEAA2FD9AAD8CFAAAFEFAAFAA3AA2722BFBFEB2EAAFA22AA8577AA7BBFAAFDFDED19AB991A99DDAADD91AA999DAAD515AA5CCCAAC48CAACCCCAAEC8EA2CA8CCCAACCCCAACCC2BCCCEC2CAEC390E00002248221A242228A24120081A8482840242822890
+:801D000082004A024A82A82488800888800888004880048A048280048A048A0482001F470A0000000000180080010018120018000000000000000000000000000000000060183F2E0E481B21B01122B411324219B24291612B941B282B9419B44229FA4291A22F1429D212AB424E912E421CEA2264112E4296E12265192CA4292CB5D1C2F5
+:801D8000521B292CB19122B49136421B282B841B282B8419B24298412B84A22B84222B84222B842AA4842E422F290F481B61481B21421B212394212991612B941B282993612B94A22F1421FA4211D012BB22F442912CC1B12EC21CE82265182E5286C1538E212CB5C1C2121B682CB58182B181B64291212B841B28239421299A612B84A209
+:801E00002324B24228B24238222B8426B28E0F20880400000000800200000010021880080000140000480000000000280000000021B03F0C1A820200002842A0818A0480A44288229200802684228202808188218801000018486842002004008820A448C8004A68148F7F012008824800482004A0854288202404200812000028200488AF
+:801E80000000240080880920088820A4842004004A0814F06DCB00A280840480024212888842A8282026082C081248222A018820813881820040024820A4434280088822428A048084286C24A04842FF8A0F2A0180080048428088A4142084A4848001004A020028228004188001000018828800004800202804428008007F21090000005B
+:801F000000000000000000290242000022281800008008002A0100888A0400480000002008F04FAE00200220041A84010000008004C200000000420082423A0880220120A4214A22220248800882202C24044200FFD40B0000008081010000000080342280040020222401009A0288221220013242222200800482A08448482008B0A50CC4
+:801F800000220048200400000000422008000000200280280400008082042882C22004820000008004F0B7C42001002084042004004800420000188082080000002008008002822004002288000000800880D4CF02482A0400000000008848C8A2A028000048228812528812002084B152081220240420088280840880040000004DF600E6
+:802000000020040048182004800120048004488004000042A01880020020822108480000420000004800F04D4A8025020042004812002084A184E8200A800168882021051242A01842B0820400624A09488A048280240C0000800880F44C4C00002004420048800482420048004220044A0200820000881A8201182800880000288800204A
+:8020800004004200B01F05800400002004004248002004004A020020019A840400200400004880240200008800002004001B9B008004008004202408188004880048A0184280240400880048888A862888A82420088220040000828888A0282828F0C3D8000012A0120000008024048001185200808808001800C2000000008008000080DB
+:80210000044880240A80027F640D4800284842480020080012C24A08D2820080080048480048A028001200808804422008C800002800684288F0747900008002008008C2488842200800828232480000820000000020080000420000000088222006147F8B050022420048004800000048000000800C4842002026882404800200282004E7
+:80218000200448A0486280220420082FFC020020218181010000200100C82004200400008028040080280880084A880400A0848200822A080000882FFA07202822A243221220040082000012421A0828A800008820040000421800000000C88880044800008008F0D39A800448004800A0848248A02892008021848134428858488812201D
+:80220000880C1C240800480000004A0842A028C200A0248008211CF8FEDB202428026AA4114A812424084A88A4491A84A8C892D2921A88AC69802404184288C24A868484ACC2800A008A8C2824882428A4444AA8C4C822C86A8AA82814F0CD43008228621A21A24180A4C48A2888A8944A88044A858485042A8804C84A2424084800282044
+:80228000A89920080042484AA48C4A2428880462288A02684AA48A8AF888378084041A83A26400004848428021248488A1844AA1264AA18CCA0818C8D8DA8408CAA88C42420088AA84AC24482A0800C8888220A88862202E8202CFDC0D000000480000000000200800000000008002288828882880828802288002000082000000F0D8475C
+:8023000000A0222A27A13152A044CAA4444AA488DAAD940020A4D55AA577FAAF88CAAC44121AA8111AA9CCEAAEEEEAAE444AA63B3A03CAAE662AA288CAAE66EAA66E82A0444AA466EAA6466A26A2A8AA08EF6B06A0442AA2731AA1314A014AA444424AA8A24AADF44AA488884AA9D5DED22B777AB792AD88CA29A1815AA551CAFCC1C1CA69
+:80238000EC1CAC6ECAA67F1AA1624AA66ECAA4AACAAE66EAA66EAAA2848AAA26CAACEEEAAECE2E222BAAAA1AF216F92084A4223AA315125AA1444AA4CCCA28A4A88AADD4CA2C2428A8D45AB552A7EC8AAD4C4AAC111AA5999AA944CE81CAACCC4AACC6AAAC918AA8CA2AAC84886AACC6CAAC4C8AAACCCAACCCAAAA666AA6668ABAE2AA2A98
+:80240000F0D85BA044482AA2125AA4745AA14448CAAC8C4A88AAD46AADCCCAAC88CAA8D5DABDF2EB2CAED88AA8C51AA551CAACCC4AE41EAEC41BAECAAC8EAAACB3CAA8CAAAACEE882AACC6CAAC488AAACCEAA8268AA8EEAAAAECAABAC26E2AF0389E0000800118008A048A048A048A04009A0482288242200442984222422A0822A012A094
+:802480008248224822822008828084A248A048288228828F3A0B8220026200000000800142120080A41448008001200842200400000082802482044800808482048A04F0C8D480B411021B21421B212394612B1419B24299212B94112B94222F1429FA4291222D912AC4912E421CE82264112E4296E12264192CA4292CB491C2C21B292C03
+:80250000B89122B491B242B881324219B24298212B84112B84A22B84222B842229A842882E421FD30F481B61481B21421B212119B64291212B9419B2429B212B94222F1429FA4211222D912B422D912E521CE922EC11E82264192E4296C1439E212CB411C2C21B612CBC9122B411B242B881324219B24298212BA419B242283A42222B84B1
+:802580002229B82294822E427F470400480000000000280000000021800188000040010080040000000080020000005012142FDD0F8200008004002002200C421222000000002081818421090080282804000028800800000000004F6D0BA01A80A1142A01488084020080068004424882004800828008A08222001800A24A010088C82086
+:8026000084A82880828222284881F8BD6500188025A412480020222202422848184A0246220412800488008819A11820024282002242008028AC824280022880C2824001FFCB04800280018004480000884800000088000020892104A082008021282488010022008028088002200882CF870F000022A0140000008200208102004220040A
+:802680000028800282482888000000004888008242004828200428F0DC32008002184200288828C800800442486822622842822002420082004880020080A484888222884200C8002008A048883F2705002820828401228082048200808184840248484880024800008022880200004A28A88422884888428820242228044A02DF6F0C0001
+:8027000000182004800888008004422822A024228008002280822888240400002004008800004800000088829F7B0242488082040020044A022904888A02004821484A084A0200200182820000380048288200800A824880080000C89F320D80068002208204002820818284248802210080288102422004A0428A8404884200808482A84F
+:80278000246888002004428008F0C67B80010000000000800800182200000020022082080000800800824220040048004A080088A048F04FC6002280020028424220048A24A182C2188222004888001A2202289848888084048818482008422288284848824882422024882888FC624C8005006200000028240080828402420048A0420020
+:80280000800400882888008A022084868804488882004282000042F0264A00802182040048008800482800E288002820020088800400882200E8480000002004008848420028882AF4D3B8A042122001122002284A01002A2104220018C218220088281A0488200428888022012880A24800288024282224022A2402003F47012800002017
+:8028800004008220822408488082042148808208004848800400280028C8000088200880044222004222F0216200224800004AA1210028CA01008A21842108222024A8421282422812421A882621A48100208124082004A084420020282408005FA2074242004818488025A9418248821A8481014812921A2829048042A2124A012001C0C0
+:8029000042C21A8AA31CA0852024A828200A822882200882888214DF320220A242202204004822380000C8180000808A24041280A22812820012904200000000484200002084080048EFDC0618002224800200001602800A29180268800200230524821888802925082488002084880400A042000020842484F264B700004A012100228A43
+:802980008328048A8108210018424A0100C02228200100008002202188880200A200000000002282AFEC0D0068002C022800222C012C0200CAA181280021A01C80A84180282241018212184820888582088004008028840820843242F029C42024A422682CB64282A212283A23890A23A119222B912B848AAC135AA8311A8CAC884622B1AB
+:802A000022C2929AA16A428A25A9C84AA89582989A8B290288884828CA84AC482242484A84A4686246217E66012838181A011A0180248C052B48C280288C06822A1182A3244A84884222A3C2528242283224AA22A2614232C84A8824A428A220044AA248CA22A82442482A86F6ACECA043222022042B444AA217886AAA5B5A83B8428E8700
+:802A8000A4192B374A88A4CC22222A82A6529AA5444A82A9111A2884A15B241E22A248CA24AD2AC2A084422A086A2888082A888888AA88F0F95820040048244822488004488044220848000020082100800888004221000048800482200882200882200882F0A466A051523AA2732E222B3321A033AAAA2F1E9229E829F952B22F22F27265
+:802B0000722BFF2AAA913E326AA4822B666AE622E626F672F22F29BCE2AE73481A01E023F9B2B22F22B2B2AFC4DAADA8AAAA88A0446AA6C6424AA66688A0C46A24A6224AA266FF92043AA5631AA2316AB612B142A4337AA7AADAEA21F162622F29F9D2B22F23F3F2F22F27BF62AEB3BEB22BEE2ABA32A3EA8EF24E622F21B992A46A9A5B03
+:802B8000119AED13A7AAFAAD773E122BEA6AA6FFDAAFAACA0CEAAE224AAC44EAAE22882AA2E662EEC22B668AB862F678DBA0511AA5333AA3332F27B732A3551AA3EECAE8259DA2DED22B8DDED22F27B772AD825AAD372B663AAAFEAAEC22FE62627E722F2CB4E2A6738EC15AA5FF6AE621F1B2F22F23B3B2AB66FAA7BBEAAE88CAAC66AAD3
+:802C0000AAE4CAAC44AAAAA2AAAAE6EAAE222BAA4AA4EE3F87041AA5331AA1317E722F25B572A7777AA7EECAE92CFDC2F22F2DBDD2E82DFDB2F22F26BF62AFF7BABAE2AEF76AA7EA3EE22F27E623B2B2A66AFAEE1DACD91BFBFAEE2DBCB2EF29B9B2AA62FAAFFF6AAECCCAACEEAAAAC4CAACCEAAAAA6AAAAE6EAAEEE2BEECEC2CAFC4C2563
+:802C8000800100220020222922080080228922A9249242A0242084A124984A82210480092A0898488800004800800400484220047FBA0E2200284228A041228A2424212419A24324484222808422028082040000180012004212200880088848888280840888824AE218F4132A80B411021B21421B612396612B1419B64299612B9419B486
+:802D000042A94A2F1429F242912AD412A9421CE92AC4812E4216E12264192E4296C1C29AC2C21B2D2E421B29241B29421B2923B68136421B682B861B282B8413B84228BA4228BA42289A82AA84E82AF441BE001B61581B214E121B616A91412B1419D6229961299B612D92AAE41421F242912AD412B922D412E92AC5112AEC11F822429672
+:802D8000F1224216C1C31E212EC21B2D26B291D422B49132621B2923B28114B281366213B842B281B24228BA422ABA422A9AA22B4A21AE42AF9E0D00000000000080020000001042820188000040010080040000000080020000200821F05F8D001814A024581800241218C21A840842388008288A850400288820880448E022850820A463
+:802E00002400A88A0600482088084AA8282268A822AF3E0A1122000042424252420020812401882B42988A041022842221A214200129012122121221802222048A24228808420000888214822F340DA024148024A54142420080248403183288E286822A241502808A2A85384180044A222AC142482A242222AE424A8822A284A0848280A4
+:802E800084CA224222226F55011412002200001AB4422181288188240424808184098084820100189012D02201200100008200880000800888A288826F930400000020812121044200480000004200004810022A010022008200002088082008822882004A02004306422001124832A0484880011848238168244E82003820A248282021D1
+:802F00002801422C84012081032B21286A81882284820C00428220222C882822F6C6258004122021A421A018200480612458004221A01280228802129012004200202121B81202488822820000802C228802228880F4F86300000000124252202104008242230800422004802408A04330122002220022380048A84A08880088004AA8849B
+:802F80008082F27AAC808205202104212004181A04000048249022481A48A224128024220200282880020000422828800E82282228C220060057C88081041A02230200A04842284A8801222128481022A8218008220012202104800428802404004882284A288404008088A842F0FD47000080020068218002800420040080010040020023
+:803000008022084821200100000000000042000080F8DB848081011830420048200812881A0430422AC4422022012480218204182021240280820120044822288842888AA424224282208A08823DA2200280A2122824602248421A268404800200004A280A2A04242082022888E0220480024800004280880400224220044A029B71008AA8
+:80308000012001484248128001245220010058800520048005808204002C048002002A0428200888200880042880F2E3F98003200812242C81016280810222A012212280041012324228004A0200903200420018000020040020840C424842F08A5500822880042800181220A4412021042004182C242224820122181880082824002212AF
+:8031000080810248480088004248000082482F250F4880240310A2122222282901211082024A81012228421800468204224682220448602220840280228228024A22048002428880021F5C01484A01208424044220044A02422004422004000000001880280A488021020000222A288208888028828E82888868188F4C0918281A84822174
+:80318000819122124220022818481842001800202282292301243200282821402222012200488002482242828028024828FD9C200200000024000020022001001002002D421092222084311248182424184200000048002004000000425D470082124200124002200423412201249012208401204C82012B1400904248800300480048005D
+:8032000082208422280228208202F0544120084818000022262201182C0224248042822211A2214212A80010022712282301A061002200800C00000000003022F09C5A00922818A0141A822431521A031E5210A2311AA421243829A521244AB242A42CA0242E121E1222F0B2829E422AA453483A2121250280A444424282A02482C26AA8D3
+:80328000442A24A48446A126AF8F015AA51818125A054A21A234286AA44142247A25F442122024A521182A250225B21274122201287E6228425A022F2102A0221A8601288288282A88A4C8800A8A88A8A82AA2A848A7F4A0224A22A16260212CF412322E422A119232222B152421224E122B6120A4445212222AE524A3122B442B425E12E4
+:8033000020B422022F24022D222F228604122A22A622AA268AA484208684A6224222A042885FD40F4222008A04482448244826820448A042242A0422001002200428214288901280011800000082200882200882A04820083FF203BAA3261AA1511AA1195E1227212B111AA1372A83D122B112F322322B333AE323C1322F21A3112AB3329B
+:80338000B242B462B532E121A8117AE323B322A6335A61253E222A021AA5773A27A1224AA444884AA4C64A84A2642AAE44484AA462484AA462E78CA0451AA6111AA1C51AE1257112F252522B117AA3326AA7115E522F21B152A5337E521E322B752B774AB172B242B4F2AD531E522B113AE421F33371BA6B142CE223A2752CD222B462A4EF
+:80340000731AA1224AA4444AAC444AAC44EAAE646AAE44CAAC46AEE22B62CABC22D6FE081AA1713AA3331AA1547E322F27B612B152F572322F26B712F352522B112F25B512F172422F21E225B57211A2732AA7444AAC177E323E327AE327F372712B732F2DEF21A2273A27A1116AA6773AA2224AA4EC88AAAAA4CA088AAAE6EA8EA4CC6AF8
+:80348000B2C2A844AA3E3DA07F3AA3331AA155DAE527E325E525B562B552A3555AF752522F25F552522B772F27F552725E522B173AE325A544485AAC575E522F23F332722F27F152732BFB3F2CEC21E223A2711AE223B362A6773AA3226AA2EC4AAEEC4AACCCEAACEC6AAECEAAACCAEABAE2E82AA8AA8F43020000001820022001000000BB
+:80350000202421040010220400420022001002000080044880848204800242F0F1C28005008AA1414E1220044A014A21011A2404230400400248800158A01212884224280022481800488880888428820A4A2888220814FF850A481B21181B2146B2117642B211B64291612B9419B64299412B942AF442B33AF442B13AD412AB421CEB2236
+:80358000C4812F2264152E4296E122641D2CA4292CBC91C2421B29241B29421B2923B68132421B282B841B282B8413B84228BA4228BA4228BA42A84A88AE42990E2A94412A351146B21136621B4190616A99414A9B6198481CAB414EA11AC4A129C4B12D521CDB22EC150A9E2148DE21141E212ABC81C2521B692E521B284AB19132621382
+:8036000038621B2823B681B242BA81B242283A42A22B24A22334A229E22AF42FCE00820000000000800242000000001800000022140000480084000000800200000010026EB440444204296181450280C44258881246844482842141048242450824002829AA121227232820C112008329A421200AA28882C880084B8222A800886FF20E98
+:80368000A018407861028283314483088034480040C84820058D24400244E041041A4434484384341221418400182094484A88011688B118840480142CD814084F530E201C0233C11841292134884823A58489C1240027845688C1463088522482001E44222B581B2184284662213014A904811A2421C488821AAA82A04884C220226228B4
+:80370000884928F8318A102411446826204818840400484248000018C0245048401402801224D526850212002009288026046089181A04C084488D240070CB0B1880010000202104000000812200200224004200002200800821001004A0410040088281604480025FFA022218442470122801800400298128842142249518001008006172
+:80378000458221831C8494122812814C21242304800888884A280100A8818281F0B428A012005022838101004200218800224448008042480224484118388A444422011800808204802801884A88018820420C005F660580C1140000001A040018202401813883010000004424008082042882846321840141004288008100848242888C26
+:8038000002B7120048124341342200102C013844412A114422C2544828604121004400824004411AC254814308128480420428284440648826088C0260428A71260C68482800444A2184054C022829911841200480110212444C042382112822A114108884848221242202424004B852812A040088852424A1344FA6091240028494D0841B
+:803880000216028901244002441200400400222448282100160410120412841842208444088C08004182A0928184F0A4EC80071E2241C493A24149024721388140361C38001844800244614924922629113822301410A4434481492925A121801484242261C9812A14C82C828CB2A4415884E867580000122444C0484A4108122C210141F9
+:8039000025944429A2414A014400002024228821941440223124008C128824820484884810840820188884033FEB0221230242223024104284018444304480468402408201280010A4214841450800414C040010140400428244008844604210F4AD3C00418D24304C4142222438002F2411A8141881C012644C3124290300162441042134
+:803980003012212381220100124400428B18608110A412A018818A820100AFA60A42008D4428200200000020014C8102288420049022858201100812A012000080010042811008401808008140D8380D004D42100225440424800124478200304418484850246041484C0484001014084C8214120444002800803218A0122818840086087E
+:803A00007FAD0727488D128322C142C9242422820448904C424449142804002C0240044410141404000010C248201484A21482824488A01880C188896148C243F2A4116F8E048C2484041240A841522046840480142214824428014912140880C112805182240024121A840100C08418A08228431488282882280288F06B4C0022484444A3
+:803A8000221006288421800221D04202612564C249048052848449048B42C042811014844402422064412860442024284408422842874218D09A09001018180812001684341812182011282121213114008001A0521818184AC1144C8181011843C1182880118808892892A418411818490541485F780A451884240200482698442226044B
+:803B000028008504222A84841422C416E082984242214618689400A44A021086044862008D4489C424844843C2289044849022847F420244274860213AE2C482A21460652242167844E4836545C74420A145562C415244214341985412C1448B144D184D18184C81B11421051A114C84B16482880845A8A88F4808AE88B668424B868B82CA
+:803B800047581AD82A44B246142852464E4441442D424E122283C43248249054212F4431262C31268F44B714A24441844B12878443F4324262163C428F615482436164C04256C444424828888CA5488B8448424B428F8308A0E84C052A8BF455C4004F27D2CCF24868C5582ACB464F43B22892644B3129F4481287814314C218CF82E66476
+:803C0000F726245847822E542B12442F42F21A6425D442C514AF8147F218422116E422B2344212961E421E144A7264E4413598878447838B8CC7C15AC334CB318B94CF8131184D6C84C7C22FB80B0030248223821402613022504248004448008504400224002841811018040000411084244208406488004C2288028B2410F82CBBE02C85
+:803C8000F4763E6D2665F65A52AF24FC6E2C4F62F24E6E4F64F468484E422F64F444464F655146C7E46F467664F626222B44CFC4F464646F635222CD1C2F44F6464E4F45B142F44422E74447444E48246552A6614B518F84A451CFC4A4625AA1A81E588F88FCE884CB448F84A6CA8FC8F828288F84FCACE8CFC5F9ECC89AA9EF3FB10F4E9D
+:803D0000426F63F7262CCFC1A15D83F26C6E6F23F15E6E4F64F26C6E2F25F1527245F654766F61F1524E2F27F7525627212F25F426444F46F4667625F28C8CEF42F24ECE4B542B644E4A7FD4F44C54CF54D5ACD122B126D124B144F5484C4AF44C4C6AA6154F4EFADCCC4AEC4CFE44C4CAACC68FC808CAFC84C4CFE9F82A288F89B966F7E1
+:803D80001C1E242B664B734D262D266B554AFE6C2E2F46F24C6C2B758FE7B462E484F6464C2725674447646F46F664266F26B262F67E6C4F47F66476D0CEFA4C7ECFE57544F442466F66F74A51424E4A255A222D6265F414148F8484F54C4C2E645AB784FAC8CC8F8CBCC8BA4CFCCCC89ABC98F83CA48F85FCACECCFC4F8E6CCBAF9E4F42C
+:803E00009F8D4FF2E2626F63F326266F63F352522B66CFC6F67476EFC5B652F3786C7E322B446FC4F476466F65F556466F67F766626F27F66868EF87F464464F6616F42EACCFE6F7DC5E4F44F46666EFE4F44E5FCFC4F44D5E65DE22B122D264F14614CFC4F44444CFC4F464647AB7E4FEC8CC4ABCCCFC44C4CFCCFC78C88B8ACF4BEA8E88
+:803E8000FEA4E4CFCEFEE6ECBEB24F4EFE1C13302600841884430222000084444044C8241008000081001018120810060021001024018400608144128922C1245048F08C3A00104294124480044400004449542222244934422A441404412840040044214002400400002800818200608842002608145FC5062CF41124C5F2112487241FAA
+:803F000041724AD241F64E121D24AF249921AF2419F54A944F82F44A9143F242954F82D41AF924485CF9244A1CF8264A56F1264A87192FA27498C54A8F49C24A1F49C2421F4952281F4932481F49324A1F48B26AD141B24AF91128AB9453B94A7924B84A39A42BB44782A9FB244889FB244A6F6C0CACD141F62C121F812672112CF4116CBF
+:803F8000C9F111284C79118C7B11F848B44F83D41A69832F54F93448ADA12B435CF826588DB14BC25E814F827188D124F588213CF588252CF581282E5A1F48D628F191644AF181286B161789A3F2114427441F81F24A341B292B844783AB24922BB44781A93316AB344D1217F50082002008000000280000000021800188000040011002FE
+:8040000048000000004400000020021002DE6E00244410028183141248088C04E02112440420440400704422C224222A14C214182821004381020085048820018400A0828AF4881485048A725206433582A0A12C0524448863040043D48454486828400442428A442C8643028120040043844208CC2412C81430848904A081488A816184C0
+:804080008184001C18749F0E4A31C2211E224821844C245886C1306849944883E242C42410C44243042B81C1A23E442D224184621384213128424281184C048418C1444F8804228A818401842E88C6481A84E843F8AA2410044188184042188204004034142100002084044800282210420410860244838202442008800181821848004CCC
+:804100004908F0A6E5000012180050240084004008484490284183044224422128614222400261008081041A1468812088489888004144128800223F1907434242144A1428345883EA41A624521048642849D22A28A141481288288522426841C9042823C8682E9448284443E1221114E242014C2104420042890C8394488A4438288482E7
+:80418000EFBF0E430244A11280C4488E242B12284E181048145824463A149048C048C04A2C4232144D42C042C0484B122C44442481731602162465C118A0844088A48460844818848C4228F2484C00108241440812844C840400209822888025C2148228008904261824A282222C0822100420840260840088308884105484C8880088FF3E
+:80420000E2094AA1418481402148820160249012460821411818102A32188285040080184824118CA441222302A1883088C184421A0281440020117442849218CD7640860618568212180A422594184A120420618488463822238161652C86682349041E246243041008682021848182A5416048842843041004A22A241882A158CD37140C
+:804280004002004D182A28E28492341220881454820000412244220000289012128008104604604283518200008888128C81489814448008F0DD4C14D02243381846D218322827223AC424121823B81644442A41A88183742234284CE3224452843632442816B4327C58148408E042C1242923D48461AB18484130481243484804814B29D7
+:804300002E5443288493881F350E4B58008061414018A841218C2404872400490412200145A8A4000022008041C442004082028C949884890888481816C8840000430848AFFE081304202116146142222420D12249044C61442C1248C2161228286044812D2426082D282C94189014248444224C04214996C4840042845844825084E04439
+:804380000140F4CE83C016002260A4281281304842481221423042222B4148006022241A6421408C2459244868C42C2201214242809144224A084E84A0844286044C0CCCA884883F330A82D02A0281200290482048084A01A490682A8488E428052902008C0422252CC822304298C014400418A02848248081885284004A0140E221F49238
+:80440000B940140860418648041280018001822311041828201204218004B01404842518484824022301008312488492B88122A0120080088126F82A7810220147844042A12124121002002311E48228084188200218002281888006006028C84426128848048820080089A824CC1128C82840F47F7F602100206244814140242124094BC5
+:804480001442484244414AB11424084A112494186150844E181286384441A98BA1214248284902688C820EC842C8200888C14928A182EF6B07100450822B28803428242216182804249244308200214280544828E04204880020026120084842D20012001280410880042744846FB50C6028C490822148244162460848244482002B148137
+:804500008200181008400400295C2400412220C9141008A041B01804860420A448328442471814CFBD052D48C062836244114429A44125C822874A21C9121846388844A22982FA42144418244C994452242C0154C8F02248A04844102282216248C01480034C2154841024012588F4CE3F341E1482282F86B3623A8881183258588F88EBE2
+:80458000297514AC544D92442C88E9A4B282A5182C86044D4689F436462A7428B892F39A448F21DE86EA82D56432244BA34F2B21A4258926FB7414A6C874528BC456E843AD253A31488524E444C1444D5346F8C4CA503227684342D648D444F626211E442C7142ECA6C242A142C7214CF444888E44CB626B8247472AE84A39142F2242289E
+:80460000C438E784446E482CF144188A644423E228F88214D046CD422364C48AB24CA884AE42928B48C24F4874C4E8C89414AE448D88C78A9CF8885457B1B0443418A51A78147A437A41B664F24E288D22A331524E882C514223FD1A52EF867242AE59A86B45522E244823F5161C421E244D42C5E6847882744852264AF41A3C244E2496D8
+:8046800052442249C7C84C3628B88CC3948098C84B824E884F81B9948478C8B424FA275A201404806412008C24C2486081A041C048201828A1241242001883044A8229840120A412A0924841A08212228A24A249A0492892A04820292488F2867250212F85F12C2ACFE3F11C1475F76F2E6F42F24E4441AF23F3A2922FE819F61E1C4B8816
+:80470000C768EF62F27674CEE44F6BFB84944B996F63F64262EFA495166B324F63D346F4141C1E426FE7FFE4E8CF42C222CE9E2F28EB2113B234D3CEE484E7C4F544EC8F810B8FC1D148C114A0454F46F65818CFC2D368A1228F85F57A4E1FDA4BB257B512752CF83C5ECF65756EFF6A2E6F46D7CE3524EF46F6F2BA2FEABB46F44E7E6FCC
+:804780006CF8DCD66F64FA767CEAEE42FFC4F44B986F62E326F6CCCE6F41F56EF84F63932643F1D5454F4FFFE4E14FE2A6444FCBFFA4B41E64CAB474F36E6C4E488FCFF448E8CFC7A7A78F8DFB48CCDEC46AFAF4E42EE48F81F124ACCFC9F86EACCFCDDDEEFD8DD8143F74F414544FA2F23C3ECFE5F54727F7E66F42F24E56C5FA7A76AF5F
+:804800002EF9DAFAEF61F15E5E6F6CF8CE5EEFE6F27EB88FEDFD34F46F4EBD94F924766F66D6AEF8125AEFE7F73636EFC2F4125C4FF1F47676EF8FFF24684E622F29F592B23E326F45F57436ED4C4D7CCFC4F34CEC8FC5AFB68F8DFB4CDC4F4CADB6CF4FFF6C6CCFC5F12CBCCFC8F92AA8DAEDE2FDFC6A347F55F51414CF82F26C2CCFE493
+:80488000F46327FFE6F26674EFC4B734F37A748FAFF3DEFAEF64F56A5E6F6CF8DEDC6F66FA76BC8F8EEB42FFF4744F29FD24666F66F64ECE6FE1F5EE5E2FE3F72A6E4FCDFDD45F6F6FFFDF9849E426F6BAB22BBAFEA4DAF47436EFC6F6E4FCCFCFF34CAC8FC7AFB78F8DF94CDC4F4DADB6CFCFFF6CECCFCDF964BCCFC9FC68EC4F6DFD2CC3
+:80490000EE8FB50C290122008447221A542460229648C2482049066CA2484C2209A0246044188912269412839484100249094130248C04482008922081C24844120042827F360A8603C112414C041042AC145022124448242E4824A014000000611002241222422642742202184860818302224889810449840A4098884308846B2BC0527D
+:804980001F4152281F417248F21164A3D441B24AD1C1B24AF91168AB945781AB944B42AF14F924482F147934F842914F83C4914FA2D418F8264A56F1245A96E1A2645DACE549C25A1F4DE222F591248F22F19124CB141F49366A1F49B26AD141F26A921F89B64AB995B44AB9B4B44A3B242B94478B29F9A448984FAAF49A6CD0A49561892A
+:804A0000F51124A7261F417442D1C1B222D1C1F44A941FC1B642FB15282B844F82E414F9B448271443F342812F81E454FB221A8D956FA2FC48814F22651CACF148254FB26D18ACF5C9242E5A1F48F4285215B46CB981B4687111B46E3991A7461FC9B448BA91F64A944B4BABA44399229E482F447A9688FA865A8FDE0800000000004004DA
+:804A80002800000000210080080000140084000000000000000000004041F1D2BD001245129841188904260C4A08C8D0224882042C0180874204904889A481C942642218410020B81298A483828439548C024A4208006DA84181CCF82884446084CF840B428284412122142011048B811081C42828428324741218688C48234408242608FA
+:804B0000895B484922912480418802411014981480884994C818D082A2682442128641F285132024556864482A11084D2890C489284691C28902E08411522A5E2826B8149442828446B288C2282618A1124189024E18A418A6942C80D148E1C112A4282A49348818272AC4AAD468D8A48E61188725DF8C0200404801460118442081082431
+:804B8000B04282044818A0840084428412419674244A84410480A828004286240480140842504822810041006B26100421204208204208400120C122451888041281004004442110044981029012702A82048441008240088400A0484A0280F451F4100153435225C01110845121C212211F41946AC8D02484C16C8842904480143268E03B
+:804C00008214926489068A020010A418B0884288B842011A58A41A686418A850844228826F830900794252140090241648314210C2421628148634428C0400444002450A2244B028840224184048A481814C1828B842081245EA81181422A284490220D4D707450112C02281160100809811701481264A182C912492890442304480068D80
+:804C80004230644C018A02002D2242002608200186082024210883242482F8E2B2602249041658281428211880C118308490882230148400321225184C082A01281E448A0244C68244688144848A1102800818488911A24126648424106641F0291EA0146819522238442183C621C3444482C2124004A04850422D142001882CE462C482FE
+:804D000000004A9128284828200481411A02288428478849A4422883044EA449180218BFB5068041342190188400212004890448122902402864448148000043321440648830148051223608440083218101009200221840688428FFD10D2AB52201A5C218742889A22146244118C25E604C2A81329481615634248184C48466823224495E
+:804D8000A341A62494241E242138A18B253088411A02388190C447812B876A012A646682453844288FA60B407424B1116222165828483484A04120088424200481A0142442201426190241C098800C811261844D120016882881412804F024488192449018F05E99402214C94280459811292494428C8201D02C8481048C4482014481589A
+:804E000000408841088B6843184416644443C2248638821084648810C4C42D1420088E1C188E442487481B5B00000028CE224224138201A142411054824880024148482622C114621848D082042C448A811118180280A186206184C884890800A028C02848EF3B0A181C024542288871249818CC51811448418489012C51483088418F44FD
+:804E80000110081A22218202181220240222220040446281241800A018A01400221226F2DFDE00D0249411114501211D240010914880C2884118108203A418001042C4444846048902E0A2444222813424299452882180341222A1414126821218029FF10A823227128D4448522061842004830124422842420061128C220450422014127E
+:804F000082C12488828140488802888228C0C22001582688084AD842B14828A2821F1943C14844001244444C420232250C611843D8840840221408484C93422066840048895A8276C2442A41342244891C8C028684C5188092548912C45A86983242284A49F87FF2501280143124211C22244104004004424D282A812822844204B042411E
+:804F80006242A94108A0482002230148A0A42B148B24400842834898821220048110087F6B0A17411485265248288B143440524825714201896422284034848E142289825142444220810284101204840021105424122C81982283418A48C2848923714204184449F5D86E24260A2B4316E81251211460421362122E44902821232801237E
+:8050000022220400182982184A4CD4485222544D1260A8442E4844C04C28124B28004624BA140243A424491418481C3442F03BA110F2B1435D141A7678F87131A784BB12AB34E3F2412B2CB4484158AA8B264D94C7462F44A488EE142E381E54D048B42216D2265222414F2414E8A9D4A8EA8D62482F83C32C8D6246EC8A72A4BAC2F3BE7C
+:80508000145E242BC58CD88881BC4EACA26BA2CF4198182AAC623EC47AF864E2AFC8091F334154B8DFF4D14493443E254F35D6C5D421B63C143B118F44F444148E428782ACA4218B42292A51841E4E4722A0452E144F46D2C8F1283C46982449E1423C44701C026982A4444D864AB2A6A4182B5C4AF4C81AECE16D7598AC1A6F24B89CF115
+:80510000841C8E28C4929FCC4B934429B22212521325D4214564235C91122E292D4961D0C6F9D222184F825124ACD446B428326C23F44C122CE181F418583E62D022F44A142F4F54242DE2C5B62271267C28F24E148DA432C82C59A88F21B232781424598E4AE184E481F4422EA3314C8957CA7F230B000080C148002001480020C1241257
+:805180002820042800184220142284092242222082E422080020080082288A04C0228002284F120B6F24F4562EAF21F121258FC7F63C7EAF86F22B2BFF94F54747BB77BF37F75B1E65F65A586F68FEFEFC48AFA5F5AACCCFCBF91C784B3227A1AF24F46E762F23F31C2E2F23F33A7A844D4EAFA6F6486C4F49F984C667E44F615266676434
+:805200004F62F2484AAF86FEB8DA6F45F558D88F8FF3D8D26F64F54ECEAF44F464944F6AF3D6D46F49F1B612CF89B1F4F9EE2CFFBA4BF346437F71F61B32FF51F3787AEFE7F66A6A6F63F173737F76F46F6FBFB7F77B7985F25E7AEFEEFEEEECCF44F66E6AAFC8FCB496CFC3B334D3E8F16A66EF6EFE3262AFA3FA3232AF83C3485D4FAFDF
+:8052800087F7DC6DEFEBFFA6E26D46EFE3F22A6665D624F2E84AAFAEFFBABA6F65F7DEDC8F8FFFEABE6F25F5D2D66F66F6BE94CF6BFBD694EFCAFBB6B46BBB4B9F6FEFF9C7FA246F27F716668F61F13B262F47F43C5EEFE7F36B2BFFB47547F77B7F3F36F25B3BE764AF85B5AEFEFEFEAD442F65F5E246EFC3F13E7C4F87E7A6F74A4AEFC8
+:80530000E4FC3232EFA3B226C24E45FE4C4F6FE6F65E7C4FCBFBC4C66F63D766E262F26E2ECFE25264AF8EFEF8DA2F67FD4AC62F2FF7DAB2EBD4CFC5FD6EA4CF47E92BF3D6D46FCFFFB69C6F8AA3DFCFCEF34875347F37F71727FF71F31F376F67F57F6FFFE7F77F6FFFF7F67F3FBFF7776BFB5B79CF64F47E5AEF6FFF7EFEEF47F77E7A0A
+:80538000AFEEFCB6D4EFC3F73C38CFE6F66A2ECFE4FC3272EFEFF73676AFA3F4484ACFF4F4FEBEFFCDF6F6FE6F66FE3636EFE3F36C2ECF66F2C6A66F6EF6FAFCAFAFFFF6F6AFCDACFFEFADFBDEDCCFCDFDEEE6AF4FF9FCB66F6DFDFEFCEFCBFBECF88FAFFDE4DE4FC4014B12E012415812844362814712166832123440668944128526588C
+:8054000048128744604480129228B0480283342242230223022284248C948448241E48C048E081C424164886E44422F14824F065BB308290161243E281228254126022848D124820522A101804844AC242508212C0246901411260484116542C00442296342490920043592282004E141E48402844F1B5E5C0521F4152281F417248F21129
+:8054800024AB141D6CAF24F11124AB9419B24A9945AB9443F34A9143F3429547822D914F82C4914FA2C4814FA27418F1245A96E1A2645DACE549E2A2F5D1242E421F497228F2912483F69124AB141F48B24AF1812CAB9419B24A3985AB9443BA4A3B242F24792498B24F8284FB244A5FC40DACF1116485F2116485D241E234D1C1D628F174
+:8055000011248D841D24ABB45B61A93834AD81122DB547812F147A26D812D9A4C5B12ECA5E854F22611D26685D2FB245E5A27DC1EC22F5914C8F22749134281D448B941F48B242F18124AF465941AB345B28AB944398BA49A4344588D38684D38675EF0D000000000000800200000010020088000040014008000000004004000000000084
+:80558000F085A82014C21459D22A941884111548210A1015084226189A2242804202845084208278120A48124224000052004184B01808A1A24226420418226012BF6B44021B1824004424478170240823C38A002C1358421887418AC14449488C4404287044A8412624122C32242184169644161244840498004024514280112428611B61
+:80560000C42F744F8234511662228C341884C71115382D4922A2821514883242876285D284C182496442161C328C7024082684DC2101818B212C64A484432104214410D48401260845881A22624160282A21E9C1F2251F4002411544424402002C2851280012850218224A0188200400C04812678228490443020061124B142004888009E0
+:805680002112460421411880028FF6030041122411A041800480014480029860442004101448185884282282221604802141E2810630242888001200008524A18410086BDF2422182351282E18833214812A0800408AC148448130182218284244100442288CE8C40143012B244912043220B22401832822018C98848C811288A5844982B5
+:805700008326F45A9B2428184C012F828112B448812A0400901283144488012800484004008D2426C85488441684041604187228182624A28212209884124038444AC9A41AC248488F5F02002189415218180000801148042220C8184684A142100445483848803828204382C22420612281C024908800901840880289014220025F1E4934
+:8057800091224887618284891408231A18020018218187242002122E9842842608A042002810081812001A1408443044406882882042A42482444528C1144AF2BA9F6021482843A1250081001D842548088142104208F042284416821404216044636121414C416264480030428A64842902960C22188301004828286180F13EFA00008E9D
+:80580000224480B22281384212002D444C040000408434214C024A1204A9024C8484042241830120123812C22220010025880A18421A28C448882FFF06272150486B124614C8282E124022598290461A14125822810056EC417661922C26AC42414AF2482463C14644489072121608306A8B481A84262281418891182508228A34241A2828
+:80588000C5484AF839DF200A2A01AB1248248426C2481410088584048C04222092882004100221A012424D18502444004A0124C429C8448948088220C2A44818488D24414C6122CF9B042881241828442CE34184224164828C0110C818481812258802212228482284418124182A4504122200004243A12900004446420448002280F4411A
+:805900002F4068220000101828642200002422C0622A844148088440C8482100A11026B32251422181250A40088420E988E5851848849888818981481424F843C3604C50842480914820518412842904812A844482021032243604842800268402100441406AC2A021C144850482820020440884411692484BC1223F6E0122874148444568
+:80598000C82241831294328C82016412C921922C844F8401444048042B14411E281E484442CC42081222001004284094388B21108C21883124412AC42800C4E7D8602400201124354240042183C148402264246400840024814028448201D02202002824C3028442808928220924124C0188A0140045F19BC17012682218264808222081AC
+:805A00000200301420011249420C84C484C01848A042C4C0541822004004813018288D244044081008C1B02408C8221E483B4200188081C8882149838214022118460241690284230300200249C112812082428801450200442A9424211008B014A81C20228A8301228078EF0A2028628418894104840012008416140881004C82014022AE
+:805A800082428421C22C004084012A018C92241822E04201420085140843C2888AE481E82102DF2A05254CB41804412942086D4281122684F41A6645825624814C04490225042D14412C88A1422120744881144418C2484004008301400C2881382B828084648241298CF23BFA60418E2685C87A8D8864A9D34CF5543A2B24448351888460
+:805B00001AB11492148F42A43189B21802184190288B754D58364CF4142443E423F648281E24293116878245C422C4C13A62424F4861819281857418E441B918A92249F8445CD2A5E41983FCFB1EF022224F8901C361414F82DA44A427444F8394122D2823D5681156683E684F2432686F655482457C2498288C52A426E847E224E2832528
+:805B80005288E5A41210C41250A245B82463844F8491221E88CB2A608D4B999881AE2CC748B09862824B486A747AF86C7D244B4483F23214214F22B11861A725382A8D143E2A2E122CB5547448FE6258A76425D8E6E482F12414AB2285D4E2516C2221A1A9F54E2285B822E684F116464B1236664229B238524A812E248D44CF81B1288297
+:805C0000F928B8D88C64846FA614C6888FC6A78289EF87DA44F884247B660000002C08241A04120024480000200100002100008001004302008014060000A048280082200882F06A18E026F6661CAFA2F3321AAF43EB63E325F54A4C2B232F42B238B238F35A544E528F84E423F37E7CCF23B752E1847612F82428CB33AFA2F2262E65BC8A
+:805C800062F65C286B312FA3F37476AFC6E644F7644E4F63B332A3222B111AF3282A44AF22922ACFC2F3ACA48BBBBAFBB8D445B418F11C34CFC8F92C243E188F87F734F4CF81F15CC8EF88FC3171242F26F6A676AFA2F23A5AAF83F3383E8F25F54C7C3E64AFE3721E3618AB774F24D588F73A32EFC7F67E5EAF85F15E4EE7E1EF82F23C46
+:805D0000388FE3B32EF28C8CAF85F65CE84B318FA3E3E7F7436DAFC4F74A5BC7A12F42F2646C8F21F118728F22F22C24AFE2F63E34CF43F3B8A4CFCBFBB8388F8357448FA9F71E3C4FC9F924284F8FF778D84F63FF1698CF85FC9C9CCFB348F222622F42F62E2EEFE3F1AA3C2F63F156542F61367E6F42E341F33232AF85F7125AEFE5F512
+:805D80003C16EFE7F5747265EA84F71A38EF82F238388D36ED2EED8EAFA7F37C3E8FA5F6282ACFE7F72A2B4FE6F7344E4FE3F316366F61A7116F41F32A2ACFC2F24E2CCD2EEFC3F33CB48F4BB9A8BAC81F7C4CF8181AAFC1B12CB23CF36C544F4AFD3A384F4FFF8CD8CFC845F226626F6AF22A288F87F13C38EFE2B95AF55676AF47F43A30
+:805E00001EAFE1F11A1AAB756F61F17E5EAF63F15A5EEFE7774EFE5E5E2F4151CE8FC3D3AC932ECD8E2FA7F7D47EAFA5F61A6ACFE7F72A2BEFE2F73B5E4FE3F21226EF61F71A1AEF65F12A2ACFC2F24A6CCF61F33E3CCFCBF9B8BC8F8AFBC8F8CD88CFAEFDB2B2AF8BFB2CACCFCFFBECDCCF4BFDBEFC4F4DFF2CFC2E51003026846B128406
+:805E80002AA14124122484C0484484441AC422128D24D048028912B248024E246991286142230229016B12008460814322296289A0414486084024F94824928F4422F84E48001E24C5022100C4814C022818C012328744412344080045080018442608481A424814A421CD12004443821228081008244189014A5284001847925FC1052C13
+:805F0000F4112485F2112487241F41324A1F41B24AF11124AB9419F24A9251AB9443F24A9143F2429147832D914F82C4914FA2C4814FA264116FA264192E4A96C54A9E24ACF591244F22F4912485F2912483F49124EB141F48B24AD141B24A9921AB9451AB9443B24A39342B94478A29F9A448984FA2F41A97C0421FC1D628F411248724D1
+:805F80001F417248F21124811F41F64A841D24AF249B2589B924F44A9143F2429147832D816F83D412F8245A1CE982EC51F8264A96E1A26458BCE558C25A1FC9F2244A1B498D421F48B2687181941C1B688B141D24AF44D941B24ABB85921A4B42ABB443BA4272A498926F8A84F9265A9F710784820000000040042800001800100200893B
+:8060000008000014204208480000000000000000001002DFDF086412008144818002840011C1262404184582314470840A008742102241444262424126064C31323028202412182808C200448A8102260422CF4D04204852242C1448322C1285031058482B418502644283029C02002D4400274122218112164802400884280085848101F7
+:806080008110088301109C14C011414F480244D648126484618449A21250843028D4EB14AC02644A712844C2413096218E443028632132129544425A48444726846412C02820A4214901830A830884441A982C64268431143FEC012400104248420815180200102404002971240884100241100220818112022031282800C11048082004D0
+:806100001800800120D28D0D0000008042020018000040021440048121005082000044000000000000000081000000F0F4BF00230121000000004004254404101444042244415042104402001221288122404238240082100812002880120441F0447A0000210080020000441014042444444024420C1004650821002400812800844C02D4
+:8061800080088480012002284400F0A6CE406281000000240060414002000011610010062100000047818002002400000044001008000041F0BC41004400184018028100100425424402450244CC54844426088504104404446120417488440400228182188484412041584812401454484F74020044604200102204248001004200408878
+:80620000020040821118024512082400208102000000440010A41881830216086FA1091002400810081100101218080000003042000020020000440028008100100892812141000012006EAA40120460C21058287048012440441802001042BC4452244C9428502C1860424441251C0663018C082800100881814F8158842112848E148C9F
+:806280001128D14811FCCF78001004184002000024124058424821410081840000400A00000041444B120084228028010040141408284100EF820A0000002410080000002400450800244002002400004002000060810000000000400800F0AED90000008161400200212440044002508484008140542284401204250640062100301412A3
+:8063000084180040040000454808FFAA0D4008001014420A404204002400441002000000A1004440081014020016080012440000000044005BBF5088830400A400004554444342024400508224E552A21221872840144202150224C558AA8304100200168451C445342400440040481248A8115F7308000010041002210000008400004076
+:80638000040000810000210000100400000010088441000000DF3309818C24841402000044414C72288202400400249012129882491802405121148485C24842480000004441CC228202001800250229F1A6CA400A48211002002140042881400800002190148008000025012484801402000000449028004008001012A4410000005022EC
+:80640000005064000000004012020044000024005088000000000045040000000000A011DF2845420210020000100224000000000000001014080000001002000000000000000000B0CC0A1028240421100250645084222224000024212460411282824100101151881028240400005044814126280200120024241E149DAC4058884848D5
+:806480000000244054484584922200000021251282819188880000254101848588840400004044544428280000001012F2689F10020000210000008100000000444100400424004002101202210000004008841210080040045FD209004124004002000000000000000044000010020000410000000000001008000000CEAD004014124207
+:80650000022121254212082400844400000000841004002124101202240000000085088011480C0000417F850D21400224412400005028001002000010544445044121854A02004002440041000000508884002001004144CF3C4F4212022410124242022121508825084008001044040044440025022121404212020000008100814018DA
+:8065800088010000EFD406672225A2122B119012C0122582F8121117118B889659888F18E484041D4911489518F84448874445B444E242024C02286514E442722652222E122B11882B98C0922582E8317111B188699985B888E484048C04488518F84448FFDA0E6F2252241812231102182592823CB11391818E88818D4142464859114819
+:80660000848588F44844C1492262424480425444286F22522418121A388282182592821CB11191819E888391484246480848848588F4D956000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000026
+:8066800000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000003C
+:80670000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000BB
+:806780000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000003B
+:8068000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000BA
+:80688000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE003A
+:806900000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FB7
+:80698000FE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000000000000000000000000000000078
+:806A0000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000000000000000000000000000B8
+:806A80000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000038
+:806B000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000B7
+:806B8000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000000000000000000000000000037
+:806C00000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000000000000000000000000B6
+:806C800000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000000036
+:806D0000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000B5
+:806D80000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000035
+:806E000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000B4
+:806E8000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000034
+:806F00000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000B3
+:806F800000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000033
+:80700000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000B2
+:807080000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0032
+:8071000000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE4C0
+:807180000F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000000000000000000000000000000000000000000000000014
+:80720000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000000000000000000000000000000000000000000000B0
+:807280000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000030
+:8073000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000AF
+:80738000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000002F
+:807400000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000000000000000000000000000AE
+:8074800000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000000000000000000000002E
+:80750000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000000000000000000000AD
+:807580000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000000000000000002D
+:8076000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE004008410045181404000000AE
+:807680004004004008002100818144810000008484004118004400441200200145F8CB81241008A48445180C004450848514141454240085124808442100855448104448440C81818552844144C91184110449014144109414181648C818122FC502000021000000100400004410481848181402400C8441000010080044100416040000C6
+:807700004112001881836181BF89062100400850484100105848100400400200000040048441414410082400848C0112001800440041188400411ED1000000448100410000414004210000000021100800810000844004000000000041002001F072EF008484814484440040040000400400000000000010088400008514084110044014E8
+:80778000140400180000F044BF2004000000000000000012004008000000000000210000800200000000000000D02201180025040000008100C0148C0240024141200200004004000000844181504840081004440010088001CF284E4214140810848214181C01844481840040088428101204841008844008446021801208200280018204
+:807800002028634818440084D094042D1444810044004044110841D048C128002410144402000084400C844004182184C4004C0281120040A41241100420015EB6004042042082144808100881000084408802284140080000000000221008810000430882208841081008CF28062420024048020040081648022480412814040000250820
+:80788000610010044110020000008180A1410020011246741408847FD8086124502C50221483016508312424C01400604220312400812002D026722842424202694214026244435184008440886141430160428002445F670E6480022121901A50825083C018212301211241000000244042440221212542441604201224110840088440B7
+:8079000044240144604140F42A4C104202C4401A011004400210040026289414260440088C0224436282400424281002481044048180A114181218001A32442608843FD84A024612140422182420447814880200004028224408005048444120912400A1200460821881000022491884284122880100D0A403204402480000004128901871
+:80798000000050820016020000000000830242210000128444200200001200256441187FDF0D0000008121280024848110315200001004200200100824004094140044001084028160812128000000F0C27E2440120480420222404802811608420084A38214440228104C144408008042241102260C80112C028141CC812842222901C0A4
+:807A000014F0E7160040422404890121486081810011290100008100000000184C1202211004001884000020480218000041005FDF04248304420040420200404202244022020000002518024129410441002004100840040000124412000020F187AF2002002A841408E082141208009042484848212800241002120000004054424160F3
+:807A800042C0141624088282820018434804C24400BF6C0300400824404408100840086062001008C31292280060812181101202230421450841400C00184141410018002011F878C7001008814014025048C028009028000000100400400424400800410000008001209198908880081800F02E48004008400845084002401848040044CD
+:807B0000304440040049020018264C0A2440820400440044124130188181814818122844F02EC20041904600815082508210820240082121210010022C4282113214241004C4840000002001440080418411040021F0673300800246022082C268008504102204422228282800210020020010185224002100126048408418448208640067
+:807B800088168405EFEC0B100281A40000C022C022000022000022200222205282220040040044400400208121014480011200214582F198870080440284231422046042D028020081002810021828880041001441508680042304001218884480034100002011024FB3092429148844528825D84C4262842684922881212485E8C20223B6
+:807C00008282A422C5860228807338C8245044851C1C04412460428041E84129A1117014749818768C18240D4A411494182FE30B22C424C48C5422851452822E62A18467228410844492424512322C0065A22223522C164234128D12254812425662246D442304847014240830848A514487414483118641A2134C3512DFEE0C008C3248C1
+:807C8000A3866424248B2481A4A18424851A622648468226820228104A322221614123C122416421C9544242C44144474118414929A8918081A9118E144C019A182401C786800228800228800400000000000000000000182002000000000020080080082908800448F0C3CB602267C285FA26268F86B46254CECFC6B622B2625284265833
+:807D00004A85528AC5FC686A87A46AF26464224F44064D266D24182845E421C32425F436248558E8E54652E62425A4664F420245D444718404829E944748CDAEEFC8F8889AEFC189A8DDDAA9371AB14274860426F226448F22F226668F26F46A4AE5FE6664AF82B22A427E22382224A7A2CFE2F2484A87A46AF266662CF24644F012326D1B
+:807D8000262F2849D264F812324D2425F42725855AFA254ED2664452622B662A02800145A418AABB94A1B1855EEAEFC189A8DDDE926B374B555AF4FAA6C0226D46AFA252EE8F84D6A8F42A28EFE4F42A68AFA656C222AD2821A55846AF26F648482F24F464442AF24644D0645164882165D68AC2264F6161316F4252E8654CD24644526209
+:807E00004F4454444554444D144F49E941A9999A7B84D4ECF81E1CCFC1F19C1E2B18CAAC512B224A85F15DC2C022655622EFE6F24862AD4AEFC2F24E4EAF86F64A4A257A22D88A528AA5FA2626AF24F448482F24F446662AF24644244D1665F61282257286F61A3A6F61F314161E13EFE252EF65562225566225A64400E041F194948E9468
+:807E80008AA9B843F93C98CFE9F91E1C4F293182DAAD516F4293144AF5FC9400104208844542682284248424404248424882840200448012026100100600411004411241122001404448648120091244F076DF0040028034420000008400802404200200210012A410140850224002222800002008008001000040F13715E022F411248798
+:807F0000221F4132681F41326A1D24AB141D24AB9419B24A19B54A3924AF143B242F547924D81AF924488D914FA2D418F8244A87114FA264192E4A8759ACE449C24A1F49C2421F4952281F4932481FC9324A1FC8B24AD1C1B24A9921AB9453B94A39A4AB9443BA427924B842F924488B944FA2F4A94AF0244217C5CF223411837611346AF0
+:807F80001D44A9D141F66A9415B44A9B25AB94F04AB543F242B54782AD952F82D45AF924528DB14F22FC18814FA2E459C24A8F58E2326559ACF4912CACB49156281F4916F8912C23F4812CAB141FC8F24A1419F24AB459324A43B24821827124B8427926B848FB26126FCB09848004002008000028000081001002188008000014000048B2
+:80800000000000004448280000000021F0A87A004008001008C1250881810041182868800181210022418982120452800210041844440080011008810041184484812FB20C25022D1210028C41441281022442A4C9420A242044080010344400442B244440140481100880240588221800A012481210041441ABD90023448804101808550F
+:80808000922C3028834468828412224A42820116182208484181225B42805148414281100840A4149084282A0184303880115424443018FFDA0821D02201218041444208400224416440024284000044430222442144482002400412414800200100004800181018F45ED400442001001200000081450800124A01288602224008002240BA
+:80810000420400440000811289010089088148188C048042F8869C3021211481B6022B2984264418CA188484008444224450844144108862211062444334242882280081236A4420A1924128BAC418803114282110A6417212F01727C02140011E222438C024248410088444844122004140060018004246C42422690800100200A280224E
+:808180000300442608122D482086022FA80524446081882038181008160881100800492145684282608228A42410840200220045289A442031184991184A381860891824424084252111F815E124644E148062212248238811183824A40010040026384612242221C3084D8218188810028148890321892888A2210041284148221228401A
+:808200000827842283D2F90A800420044144284304C13820010080022120014362282828C12220E482141488042921248244140282488C42880848848922012180F14B8620040022008A02005229C4448400420018831118840422601180081812802202002001908820020000004C0480089F910646C414005A22C24241181018B842C13D
+:8082800044160820042218C991184126624222222247813A085827820022281223A48252262201826284458888220483C2546084A883F2FBD65022002824108422C24CA061850200440090284840220485146259218008584422D02801408848246288440020041826088400002F7C01288280021840A821842942080022004420022844A6
+:8083000020024488200282608200A02842001200001880E12201121890181210F276190016048240280100184008102426820218414602000040080000428120011A1408200200000000008044F8B4968022982840082982428842881202008400260222000023810A22008002800200002001120000800300202481F47791102282150807
+:808380002884000020048C012A1184010023A324208C682448A021000026880100420080010000418005008421F0D588002885C22120018721181A021A322812892103122A2183A141802122222106328081014AA34142182383818104000080812401000048421CF1F3BC40C8112014280242818189524880020000426810021800A012C3
+:808400004848808401002A0448004A81A124A014414A2222240420041829018B95002448A028862801222001419410289128420020A44242486A0800120000000000128004408404000080210400CF470A2088132802898202000085028421450A8420020080022224004002221A020000001258301818184922031A2481410848FFD844B5
+:80848000410848460480041041C41412280084004124182341A816844A280912804481276481800481001008C01426840210440260244421D05A4C22729162224AE288B218287448E8831348982818911E18C0184CA21466A212442AB312A264E823A1441A248103A0212AA22728A011A01412181220044B1420E74321A2112041B24C61B6
+:8085000011814F560328A289332983A2123A21127821B82CE383B12C0481891212C8248C82A271528420A46618299838008024812502100884124AA133181A313818184D2238425A018B45124A61245F2A07903416C84CC02A8D2838212C234142C818212E1C8B634F82313249E1212482E44624628218AEA42AE222A4431AA4C12E124E22
+:8085800048E085E121A2A25AA441424281421242445220644510A214188C84B412749C4B021800821800000000000000000000000000002220020000000000002800000041F024F9342358B12FA2D25752883AAB225E52AF8151994B338D1816F419132B3187222B33CF21F37654CFC1E123A3573AF76A68488F86A5536AA5332E322B555C
+:8086000080E127B61AA75484242B118F85A5154A048F85054A058FC7044A7524D444C11229A154ACF41C1C5A55668F184CE122F233511E1AFD4587821AA3338FA2F21A189F93E3C2F228283E3895B312F13812AF82722CF23614CFC2A2332B137AF75858428F86AE176AA5773E32211F1121E133F252385AA7663E322B118F8484A411125F
+:808680008F81A1114F4181D1C823A121474347415E522B11E085F15E5C5AE525F5FBA514F03163AFA3D25712A8338F81F25872AF837321F1183C8D388B219F31F11A1826F21A184F63F37654CFC3A1132B454AF568586AD688AC573AA5112CB3524581E125F472782AA5533E322B338F85A1444AA4118F87A7114E44188F85074AA5114B1D
+:80870000332CB112A1548D48AF81D144C452FF584BF3A2223F13F3282AFF56B228F8B8388D288F21F33A381F92F218388D288F81F31913AF817128FA3A384F63F13614CFC3A1133AA3668F86A7668F86A2577AA1773E322B3314121F23B272A7353A47B232F318585AA5111AF138381AE14181D18CA1111AA1334B334E5229A1118F85F558
+:8087800058584F41C452CF570422A01284402802222002400880024480022820044A02288002802124020080040012002001122001100842F0542900000080410812200110281108002001480000008001182800182800180028001800220000181240F13BE2D024F411248D121F417248F21124AB141D24AF24D141F24A9219B24A99455D
+:80880000AB9443F24A954B422F347924D812F924485CF9244A5CF8244A16F1264A87592FA26C59ACE449E2A2FC91242E421F4952281F49B248F89124A3F4812CAB141D24AB9419B24A19F54A9243B24A3B242B94478229F9244889F9244A1FF90C4D491F41D63CB111766A53418D121F416624CCF242971D2CAF24BB14F2488322AF74391A
+:8088800014ADA34F83F442856782AD954D5A8DB54BC2142FA27DC8F52212D6D5B2E45DE2827481FC225A1F49D428D441B242F1912CA11FC916DAC1F64A941996B25D68AD924B42ADB64B424AF924482B942782A9A9521F260684820000000000800200002004288001000000140000481800000040040000000000B0510720130280410286
+:8089000024121881818110082820028001A024210000264222A212182400180000808104100444A9820300C0414F1F0641821216129828DC231304911800440084001243022200602245C8441A04412C040080420280820114901800160800244A215718414FEE04201F82013899922200478130288110082220622128121A0282C02245C8
+:808980008884145162248901460200210018100483034140342A12C0424830145F9C0E418001A184492151241214160840044008004100E0220400411222A04228180028180028001C8104001608800229211388E4980D008280080088000000000000000000000000000000000000000010010011400170E70525821245A41289422104D3
+:808A000047C12981643284A908418AA492507884281A6848494443B848A2413083D088C1646A0871442A91285C2804451882E432A188211698148AA4824006289E88AF520468215B11448782285442D084F23311482484A97814A454822A0885071EB88A4435458D2284621A0437888594142429A82451448F82A1A814461444381258AECD
+:808A80008384A14F458421A882C01687812843FCD32F002008880080080000000000000000000000000000000000000000110010011400775E502200302A0010280128140000002228806222004A02422081012011020000000000001860242240882308F0AFDA3024121220C11836110830232C11481EB98861429C0118418C0100D04A8E
+:808B000061256C42A242103832200216420420C1C800A08118C04218228E482832423044F03C79800212241283811118C8121982125268918A91248400004002D082A2414C44A224128421240012210012890C00881220044223226281488244F02B3550261800890219020020110940081C012A31248C212202B0144482122201A0121202
+:808B80002200440000002001C0121228890C223820043DDB004D128024416843004508188D648C418813442161429022C0128A42048800400100283E488088060082004A880220020020922228F09D3E248014086021842881008CC224800110140910828101882026280414460283042C0400202282024C02280000281838822149C17268
+:808C00008FA207009011000000000000000080044242224810022C010000002A1108100420014021014200008100EF330310548218D028614328100C836284181608504119C124A042184823C624A024232884012C0442281A021AC82820624222A012881081014828008228E022F463E5102201111810088100124008324410080000888A
+:808C8000200400100200002128420080088004002200183228844C03BE9F240022242230318140082A21022832800343222105188002410018A02100001226081C8281024E18200184800283022289013A047DF9C0141245080081504838004608811100893111002819020083012228008022A42820018042018048C12120022242838329
+:808D0000011028D2B707210011211D282200111A021800004100420023044324622420042420840142208424512258292491221A02100258002466820646F2D7ED1024D22494388112801204C14490284C41341C100230281210443214224118902850184021018400422061821880C1294200100881502841FFD501821302488A830414BA
+:808D80002608008001288440D484C612488006484880040028904880A221A0148B14102822048100901818831402006016DF6A0F8C022828008082C5381C11A114421218400820829142812A64421288122218122084821608183C1281840219C8C100002A040018808443F423CD1420914818413014240025C818812400C011281241145D
+:808E000022001901138142820220112281011480321234142490411121110038120000F0714630218001C183324420022284218511082D24C93214244982024428004B28200122423218180022920020091148290118A40080220480F173CF4008488CA44116031240014C428402852401680030129012812A88942489148161110024C0C9
+:808E800061298842088E181C12A212260C3CC3411200002A811302BF350545A11A26C8582E14843A4238428F811172389818428F81B1117218742C14F814184B511A22B14403661134482F42E285A411892226A422283A43A23E78BB242AB449A2531BC21AF1186816119B438B2229B728942A26A2122361142E222FE2092E1413C124A7E2
+:808F000014C3B56172461C712824A232284E681D18214514C2394D241384228202684D2823E31A03601230129985A15489A41384121AA11426D813F21818CAEA141143882325814388C148628D1844EF7542932228C9E123D282F218111CA1234D381D2197C11971121498242E184D3816A2172E2427628F14E522F5214A43E24184F714A4
+:808F8000C44B412E32283A8163238B411721881C32191B86263B122F39C1824672233121381663148C0146A8111AB25882E623B254F4AB194004444084410C4400000014404148011440011440814101000011008150181008811008811028114808842816082F75427112F4151D47224F21F178545D13EF86F41D1FAF45F615372B131740
+:809000003227C31FB4F41E3C2E1BBF92F3391197137E5B7F77F531111F17751EFF47459F92F361714B465F16F5494B2B133AA3452E623F13F321233B373E2BBF11F421A91FB5762BF96973AF96FEE1EBAF9AFF2923BF82F1111BBF85F638322F85E7A4362A89E2A6F638788B57EF62F41ED3144B231F53F5282EEFE1B57EF74D5FAFC6F7C3
+:80908000191F6F85F6111F2F83F3213B6FC4F74547AF81F1341BFF93B33CB318C31B7F57B572A575CFF4F663618F862DF375C15D359FB696321E315AE633B662E622F23B788FB1F313198F84FC4943BF17F5717BBF16FAF9A3FF56F3716BBD359F31711BE1A7F75A388F24F232188F81B348F532787E58CFE3557690351F51F6281EAF23CA
+:80910000F36E589FA3F3734C1FF3B35EE663F3121C1F32F15A789FB5F51E1C9FA2F322393E183E18DF26F46E4DAF87A557DFE6F566458F86FE5858DF97B474F5585AB7928F92F278788FA4F772685E423B733E333F93F271F19F17B668F661799F17FDEBD1AF5AFF212BBF11F319119F15E4A3B372F7686225A8228B112F83E785F464568F
+:809180007F3F0A1F42F33121CFA2F37E3AAFC7F77D7A7F87F7313BAFC5F6393B3F91F221336F84F54547AF81F13D3AEFD2F33D194F83F12D26EFD6F679596AF76D6E2F16F67D6D8F85F4FC485F16F6787ABF92D288F258689FA5B632F37173BB331E3BBF13E3A4FC535B2F27F77B733F17FFF3F93F5EFB79437F31F1131B3F15F438322F37
+:8092000086E7A616BA38E384A5718B45CF66F5CB71A012A012A01220628122122284E0810484441244C024120028C0240011000000800122C0111214122212141214122081024A0200DF5C0782128180618118804108001210941800414C21014004000080810242008022020022A08600001A042220013260124FCB014D421F41522C1F44
+:8092800041724CF11124EB141D2CEB141D24AB9419B24A19F54A9443F24A9343F24A9147822D914F82C4914FA2C4814FA264116FA264192FA26559ACE449D2A2F491242CF491248D821FC932481FC9724AF1812CAB141D2CAB941D28AB9455B84A7934B84A7924F84A924782A9F9344889FB244A5F72066D4B1F41561C1F41563E1E644F3A
+:8093000034D1C1F24C134CF248971F41F24AB35B218F7419F54AB353D23AFB2548AF143927AF14BB25F148917F227858F123928F5CB222F198252D438F5DB2227591FC225B1F49D41AF4112CAD939E6C87361D4C8D92CCF648971D2CAF24DB85F248924781ADA24F82F44A924782A9F93648ABA42E184E4E00800400200400448002000017
+:8093800000008001000012000084800400000040040000000000F0C47D4041141C012A518589D21802847018512342280000811281100885425828301821A301221200211226C8628D2124E024010000008B4322816800FF5F0842864101111418205116128503301818B026810128662C614442441844437444822228C21427218019849C
+:809400004102122418460222000032002418811601BFA50D1974444109111E211604326531149187221512A812D0420340CA141668458486C41825442AC418356281128D2212CA11341210AA6125225122432122020022C0282CC21A8B2420F19B650010140150188C521810082D11A014008001282E480042008446542428882845220108
+:80948000008081021D28806424000080014A010018B0470B3C01210040638121842001008400282229226344240090428004225604422480018084018084010080041A04801104F0872B201241029012292222123222212583012123F34222809148412826B44C4294423694441E22435422282723640045C2128564C1C018228382648597
+:80950000460818411A52862A04222844F0AF66A01200002321121A522A281082012091222890628046324490422B1249E42102244C13D22404211052825608842242188C0180614418422A042AC12444F016954051232400241432220029111102A1296224201338344143922841C0448094442382A41221004C8141448481018922243456
+:809580004800602247810000001F2507484889120881440081002D248604102414180423614289018158421883240160828C21034CC258004881485084421A120481121004002218ED468081444221048410081884281502222484124227412524C11222000060229024C04880058012022828442D248128102822240441100218BDF900D9
+:8096000044140020312824200200121002802202A0424944140422102485450400C024124400214214004200418081266284007F720610C428A52104853428812003211D8618224481897144128441742882428824A41246E842819434845818902449235142488168C02883044C0422528081044608F0A9AA80051400841840424844089E
+:80968000005022482082138483644441160400901242430222124028028012C24425011810484884443424288002EF15012038280040080044104408188062828C0148001022018001468A0200580018892204602100481018084400121218F03BC1008344220212611822222120042951260080A24189C242A40022424062844068244059
+:80970000081602280000702498288420014018082002F0A24640A4182881818110C81800814C11082011343C410000000080121822410800A04240082682818104188044081880031884F042B7C0282001800210048C01902400848100C430424846BC2854843014892487120800302812203122002608000000281884818904F0E6F5005F
+:80978000144422601100000000004528120212402804584022014430240029140840280100A024800422008002808412B4420384001024021223721201301228162401122081F61A44218118282A811408188001488421188400424A23248681055A924843042290240021F0149500400800442041041270120220011200100421008981B5
+:80980000C412202464A18180012A810100184048880112008116084008B06B07208941014008001098688002200183322400800423240128608320210400002001C048200400200144243840C9118F78014588924460C88812002C83C114A02143042544C84410AA122983811188088189240246210484818C141282420800C034221E2852
+:8098800000844100242821F0ED4C40A42826B8212298214D1CC02C39E38141385884126460C24B2412A76458499142412B4541848B112CA144188B2485280484A46A3218324AE122028B2346A82448848941182852C88362818B211621E1530449F281181250883A19A811606220B1227112D622A311121A63C28B324781424E48842F848C
+:8099000054A81E284692448F84D68AF348483E1458A12489A121A123D2889168A0148CD44822A212E0851408281A912425E2844411F4AD26001AD44C135A448502812B13122594184D4489714404ED1C81AB11C42AF73C28288725A0226AA151843236A6222D4856C242481A94181A81C122A014124E122AF5185856A815224384D1CC218B
+:809980008281A3128782F0436E4004442244400444000010044128412880024241424181A0240000000000008100480000400884408802F0415D50445FD3F32C3C5F1252CC5F53721C5CAC2B311F32B31241F24A4C85FE465445F41E1C8D2E6F44F6283E6F66F76C3C8F85F55A4A2B44CFE2F53E6C87A465FC787A6FC6E785F444645E4227
+:809A0000A9C4422F8151A82B22288B136AF728288B551E183E387AF5784C8F81F1584845A4114F42F23C38CFE1B332F378788F81711EF4938950441F55D544D3DD52449FD3721CDC647126F431332FC1E1A1F14A7CCF61F1466441ED1CCFE3F3667CCFE2724EFC7E7CCFC1D5EC5546EEC22B624F65598A8FA7F7465C9F97F67C748FB4742E
+:809A80004AC8422B418FA2F21A588F81B23881F168685E188CF57C7C8B578F81F258588F81F34C448B114F43F32C284D2E2F23B362D788D1CCF12D5550441F52D7CCF12121C57C11D5CC51A86F43F311318FC151A8AF85F748484F645524EFC1F1282AEF477528FE7E546FC6F11838CFE4F544462EE2AF81D4A8F44E4C8783CFC7E596F484
+:809B000064645AC4482CB41255A88FA2A2118B338F87A7338B443E387E5C7AB258B718F1585845BC18F12424CFC1F1341EAF83F31A188F83D34CF1AB2F50441D41CFC2F22521C57C11D1CCD1ACF136367F73B11AF11812EFA4F55A566F65E521D1C6F1383EEFC6F53C3E6FC7F7741CCFC5E724E424E426FE3674CFE9558A8FA7F73E7EAFD6
+:809B800096F67C7C9FA57142DA2234128FA1F1383A87818B338F87A7225E182E788FC7B778B158B418F15858C5BC18F12424CFC3F334162B33AF83F31818C5EC12040018844008000016081200608189028324210483040083841188314820040084228400800412C048C04820010000F06F95200881288112002A418441080012200280F9
+:809C00003224188C24041A8224A512124828200412802202421242284228830418482001226082005F5B0A2CF4112487221F41724AF21124A3D441B24AD1C1B24A9921AB9451AF443924AF5439242F547B24D852FB24484EB14FA2E414F8244A16F1244AD6E1A2E459C24A9E242D4A1F49C2421F4952281F497248F29124A7241F48F24AA4
+:809C8000121D24AB941D68AB9451AB9443B24A3924AB944782A9F92448B84FA2F4CB9BF0224A1E648F126441A7361E2427341D2CAF24C12C8F34D941F242B25D688D924B428F3419D432FB14482DB16F81F442B12E184E952FA2EC51F8224AD655869E216D4B9E212D581FC9D222F4916CA9F49124AF24F181246E121F48E224F111248DD1
+:809D0000841D6CABB459B24A29F34A9443F242B636E844F8164829EAA2F5993B008004000000000000000000001880080000140084000000000000000000004041F12D19207824312244008460A18502502224C028004C9328284C226482CC52844C91449048122588A124184CA221A1121AA41248209124106A8448302241100221C0241B
+:809D8000425FE10D208828582960418128288C410881840041004A012004280064412872224141003885440220820220018004842800804421F2F795006694224181218C419818A5321C8522028126086042C05280B4181234A84361444187442E121903466441416E181E28184A118284223124458221024622420400252264121A74420F
+:809E0000061081284801412082024042180210846182284302488912040021C0481A22022210420C1A0220024038484800812221004024F24C4B00001A0212000000810000410060820028000000000000000040040080010000001004227F8D018002000028812280020030180020016046B04C024180044228290490240000208201819E
+:809E800000800481289024182810F413B90022A02120010028008400804104806182B024044F82040042003042004C0200004118100812200484004112226042BFEE010000008042082002001008000000220044002024020000000022000000008002284004F01E55100100002100000012002001480000000080058002000000400212CF
+:809F000020820100211222002001F0991B8042028420010040080000400818842822508422612002228025010000200218000000420081000022F06F54000000142221000000200400200200420044000000008818100A12004200000080010000F05CAC400140083C612200400820014290188034282800490421448021020000821250B0
+:809F80008222241818488001C042809138008001F02CA62002210000000000000000120028102842042848005A820100000018002002000000000028D0C5060000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F800400001A
+:80A0000000400428000000002180018800004001400848000000004480020000001002183F5F0B0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000000000000000000000000000000000000000000B1
+:80A0800000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000000000000000000000000002
+:80A10000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000088000000001008000000000000000000E1
+:80A18000000000000000E066050014000081008041212481410200004100002042040040020000424400000000008422800241F011F310024042021602248361120000421088022200009044124904100218902480410860228140880200100800100800CE28004001001008001814004A414208001004004C8421020020012302008044EB
+:80A200000400000010088428800241F0892410020025022C01241668120048180080022800000060444110020041804108602284402802000000008100F0D64B100245415822408112220100120020110818480044004094443022202221021800100440180800208202A1224200D011094C0180C1143038A12884282C11411811D222325E
+:80A280002C4460421828462884D48292182C064E18121A0444002722806282004C052C2247180881248C21A214208624F42CE93012001800188429428802218400D08212044C82013044003044614E1821582081021A0200004484284048088128218382052800DF460B415014812D167028830212201181411132224341081248288C0498
+:80A30000422782168822042A012244002502228C12044A01812B52008002160A2242424248FF550118181048CC24000028431228120823110218508248004C22234498644452001883151298644222480062444200282884005883724288C4447FE403101418010028400411442280028400100212221008108802106882008005000040B4
+:80A380006481008902F01428120021002F9C010044280083012902182440040020A22422008004402202420022201204302200000028004004002200001F4E0F1218C41782102421024128148444001825084800004A6242830125C828492201812AC13210F824126222480042E0820100264478380442228904E0C2074004108C1208237C
+:80A4000002182821102812022832288442008082849244424820024844000000800248008100802113084249F4574E60221818120044802211880120810289011624518283040018200441188051482418A0142222222A0190248041043012811A1204382842BFD50B12004C12C82429022110824218942200220020522426026860A2E0D1
+:80A4800022045048A400008440A41481814A2211081281008024028C04F07737202202211200411648080000C01800833222441248E400003018200100411004818144428034180018444002801124016DAF00100C10418C02398211889121840080010025140400608100004002C068102831129012108A5282100284430212830223749D
+:80A5000024F28E6F201801100828801284012416180884811008E0840148840042160884848100403822200112224B2189024F81921822608112C0288021E114F2DD19002D241E28142821D0820128283480224124022222802122A1120080024302413016904448811A02508442420080024C012002489022C42FB30118008C0100243054
+:80A5800011212042038118400881001002818C022400000018008410429218A40000834108000000F0AD4A00902485840381360D8428848118801242220232C321022A24341280B21264232412001881001800008021018480012200A97422880487861484124828C023008901814C82810284224312088122212E488C419488D0822142B6
+:80A60000081400848004C0288120220126042C020000122A815422F0BDF9C012A23E1CB5B4281146D44CC1283331228123111242782218F812288C721898144F845642495284C0226A46C82C84450447C17042048C6281C9F21848874221281824400845648124122A61A58CC1316722D7B62041044D18164832281D2283F2281A1213C1A8
+:80A68000188F21E18191248962814002841E1446D282A4641A7128F81218293516297118C81821008C1298282E18184B118F8687D1C224F1141885743A08182AA14216B82A721824A6248F9A4BA1223B31C9A223281F12D2867232B812C1258D382E288352518932281AB124322887432AF33A2483E283766842528810E827B2284182514A
+:80A700002824184F81512849A512163222A4128F67B438F2283883E22181F1181281CC82C224586AA641CCF4EC980021000020220100008002000000830481800281418141100441000010842402220040042880020046D4C249B312F315176F42F325258F82F2292BE57C157F1AD8FDF232289FB3331217312B11CD2629F21C3EAB338F93
+:80A780008361218FC3F354346F66F626244FE4548A8FA1B152F16C6E2B134FE1F112184FE131124F41012E222B338B133E12EFC3F2282A2B11C55E8E8F814154A8A5F818184F41818252A8AFA7F618781A53AA2F7B45B332F3757FEF42D355F6282897B265D4F1F13A385FF3F33E1C9FB3F312241731AF81F124262782CFE3F33A388F83EE
+:80A80000E183F22E2C4FC3F63C7E6F46F4CCCEA5E8A1B912F5247E2B33DFF1B112F11C1FA3F114148CE422B212B118F33822EFC3F2282AA781C55E4A8F81F1183885BA127118F814143AA3138FA2F27A48AF87A7338FA3F3B74C343F31F237676FC3F2212DCFC2F2252555F51D158F83D3DDF3393D9FB3D38A73157515F52C26AB33CFE2BA
+:80A88000F32A38CFC3F2343CEFC3F2742C8F86E782D6E4FC1A181E1A8FA5F17C6E4FE3D2F4F1161C4D1C47C14F41F114542E222B328FA2F33A3AE7E3E7E2AFA1F11E1EAFC1F118188D32AFA1B112F11C1CCFC1B138A3338FA2F26A682F87A712CFE2F37722343F33F23F77EFC3F3752DCFE2F22727F5DF7FF33A3AFFF3F33B3D9FB3D3AE68
+:80A9000051FFF5FD2C2EAF83F12C3EAF82F33C2C4FC3F32C2C4FC7F66C7EEFE6F64ECEAF81E1ABE1A5F5747ECFE3D2FCF11E1CDD1E67E16F41F11C148F22B212F1183AAFA3F33E1EEF62F15A1AEFE1931A8B318D12AD1A29F11C1CCFC1B138A3138FA3F27A488F87A713CFE2F7B465200222842284400884608160810040081281124460CD
+:80A98000440000001881000000400884202162816081608120010012004F2F03AA21110E188422162402181A020016882203221880828482042A21B42401492191148061418342888192141A228204000050482200382E484245F18898D022F41124A5F21124A3F41124A3F61124AB141D24AB9419B24A19B54A3924AF143B242F347924FC
+:80AA0000D812F924488F14F9244A8D814FA2E411F2244A8F19F2244A87594D4A9E244D4A1F49D224F49124E5F29124C3F49124E3F48164AB161D64AF269961AB9451AF643924AF6439242F44FB24482DB44F82E444F9244ABF26076F92F41164AD431F41724EE34172687311746CC3248F74D941F24AB349F2489743F24AB743F24297439E
+:80AA8000D252BB26F44A912E188F54D9A2E8519A468F19F2264887196D4B9E216D481F89D226F49168ED421F49724EF29124C7241B684F26D141F468961D44AF249B258F6429F24A9643F24AB64F82D442FB2648AF44E982F1B8BF4008480000000044000000000000008800004001400800000000000000000000003F7C024D11165414D4
+:80AB0000901A6012503411850281218D14400C2D248942148843887248447422024B124165D228D42462422E121221304244C5322881385A42622400400C812002832572EC0D2286C11800260228811800184214C41283628100402802228C11484C229118B048018002103828188092828132209142492101124321214391486FC9075CA5
+:80AB8000315481208112834267114508362A341D1014983C8952248436688322A63C1C81841624516985D248322CB042032448266841818382D884A51223162284911CC0181826028CE183644E2012D11401A12002814002005084892112020000800427224426429412422C052A01211048542828241A2202201112040041183242A0C6BA
+:80AC00000080018092181200002C0821902216480483240200410028000018120041800180028418800142008001A04242F0162E808262824138A42012682222001890628004AF241314E8840225C822288C1222F442281E22282D242926042A014C02322189A3282220B49244886344812A84AB241008DBF2808202411018880128008220
+:80AC800021242280012E48C0286840982421228064821828411200442003008392A828208468842844842AA412482848F061E300E08201322C822142082902201182342289542418E3048424002885224222C422242CA3424280034460232812800116220512482021888214084F510E8924C4280000804214A42420024028044C012534A0
+:80AD00001810124898248C149824124A02102822A2410020C12818CC0480A8212212184100290541CFAE4511E84401444481282223014382018B4248241644044821218081942412000085042034384124890650682011442482018B244400811014A2414AF23A9B8021524200224812850110080083220420423848222826024890128020
+:80AD800081045608001034184D28482820024A01812442812232121A282822B8A5071843D28442143428481E22164984B2280184428D224D1841E04245384884282C466C8144A90560812024044126923C16D884C2421AE281A2124822128446E2443218288021A118124EA6AFC3074812210020022200488004208404101284430222421E
+:80AE00002240E84192444AC218A012280000C10044811A0482890120D148034C88A424F02AF9808222822221334424242240C212C012422C8162260040828412221122914283548212290221848012028002008844828088820880B948392842DF320C184046F44428842220840421832431240030144141404848480A00280000280020FE
+:80AE800081120818488B2538891308108411848821128481F2D7230085042C81421828C224143304281002211002293442400210D4A4022C012E42222418204302894102200287428028218B32240084802208EF38074418490449012847841225040029624461842D1C26746208122921421204702442682140424802841224800280213A
+:80AF000001852401008818122A480221819F5B0D8212222084C1422848282C044344118204414883010080021002812124902832A042241A84021880241428882308432828C88420AA288A64135F4F0F16082C040012106214100184841200001248122400404828922860820032802602A98182018C2285428802120022800443037FCE25
+:80AF800005284C24411418142421018156041842400C1054424441811008560600810000000010020080012028020080311881F029D91004A021800412224129A1141248121823012301804124024418D0482181839418001A22013018282022020088008011841188849444F0BC3240889258482122126954840044A1890244443608687F
+:80B00000002180418288010022141042081A06002860810044800212442241A281412592481F960330C48B11412F84E182D444F542544F4142839442C3C5522554646781CF21C364CFE6863546304A21855824CC74127868983A8427828D2823A222832412B228721A322228488B315E149A72A824084328234AB488B8A8F38C1C8F93CC18
+:80B08000281F6606182E24642F43F3346489E181F23422222219F1511248139154128544B82601611AF118142632283012E932282C63874E228321A211183A83A2211E182688A211522A04268889A1812E248EB449B1348882B412E44493487FC8094F43B218B124C242811E246612F84A527F44764A022D3AA5F858222B542C71226425BF
+:80B1000029418414C4282C5266181E124D162341B22AC43225C2222341E821E12611822221B22863848F829298168828AA91414CA81836A8856A3A8423F7D8E800222042382484802482048444484088020044000000001008000020022220E281240222822009822089220182F0945F50444741C7A22D22AF84F4581C4F46E726767EFCE8
+:80B180003537A5F85311AF85F54D4BE5E865F11E1C87A2EFC6F75C1A2B445A85D1A29222455CECCFE7F63A3887A12B551E5AAF81F1282A2B331AA1113E122B338F83F1383A2B133AA37385F8687889C89488D044D844A9B34F43ABBB8F2DEFC2FA78ACAF84F44CF5A0114F41F43C2A6F21F24A485E185E766F64F74E3E7F71F74A4E3F316C
+:80B20000F15A7E3FB4F45A5A6F61F11E1EAFA3F34A4EEFA5B556F552541E141E3A2F22F2869EEFE1F17EFEEF63731AFA5A52BFB3F73A3AA7B22FA3B112E181E721F31232AF81F2183A29A2315E387E388FC4B728A239A0884F43F184141E144F4BA39B8BDF6FC4F7D8348F86F5769650444F41F42C1E2E228F45F5585C4F64F16466E78760
+:80B280006F2753EA3F15B14AF75F1BEF84F55616ED1CA7A22F46F77E7E216B55CFC1D1A8D1AAD2A858AA6F67F73A2A87A12FA5E5B4F41A3A8FA1F1323A3AA27336F232328F83F138383AA1332AF728288FC7A7A38DB8888AB824BA34BB34FB34B48F83BB98FE6AFCCDDC8F8257D1E041F11424CFE3F336348FC5F5586CCFE7F67E7EEF8722
+:80B30000F37777BFB4F45353EF85F55F1BEF84F51616EFC1F13A322F47F77E7E6F45B554F51C1C8D1AAFA2F21C8EAFA1F1D646AFE1F1381AAFA5F5484BAF23F3393A2F23A3118B333E322F23F3383A2FA3B322A2338F85F768688F85B738FA98981AA1994F42AA994F41F9A4A48F8BBBB8FE6CFCCFCEFF68487774B02401001890148C146D
+:80B380000420011A04122041242124018002441088212412A812A01280011884180000824008822882289281828902EEBE2028118422C248A021622004C048425048B048024A020000D08481021AC24812840020022220026A2121220180091880013848181CF4CE3FE022F4112487221F4132681FC1324A1D2CAB161D64AB9419B64A5972
+:80B4000085AB944B42AF147924F842B147822D914F82E414F9244A1CF8244A16F1244AD6E1A27498C54A9E24ACF491242CF4912487221F4932681F49326A1F49B26AD141B66AB981B24A3995AB9443BA4A39B42B94478329FBA448984FA2F41ECEE0A2F411442AF4112C2376117842D2C1F222121E6C7CD881F642B75D287CF924484E936C
+:80B4800047824EB326E814F922482F14F924581CF926CA5E812F82641D2782875D25E159D282F4912C2D421FC9B628F49124A726174983769134221F41F66A941F49B44ABB95324AB2AF4439B4AF44383429FAB6482D944FA2F512B9000000000000440000000000218001880000400100000000000044000000000021702104504100808F
+:80B5000082A124184009180083220429944242A02440682284C48428002880020010A2242A2402444A020030221843324426028420F24293A0148A4328013C11CC128410C222812CC14400844042A4248422222116046044848372122656224223616200218110382288228A0586484C14921800488691449D6C2074744128011323E1264C
+:80B5800001245128A3622149C428002446C2424A22A421262A285148846644D881723622D42A22B4424146024AB228244298244B24222A08A428412624C422242028F5B27580010000E19018100818002044384240048902602285040000200200224002002480084A018845C812D04801C04830244F69070000414440180A890124000005
+:80B60000304820242204460400831122444204302244214C0200A0120000001688914428412082028FFD03419012901226826141242250821224906846A224167248322484848421101A94464954A68F41622526044C04412592242826A612C44212588481450843240330384A08F043560000244CC124D048118812186821100242621A72
+:80B68000C448430200441048945E46944C2D1E582302624092244428641A32140000402431142828E0822122028FF2094130120024121012622100008C4602854222342889448A44020025022844445042442504230228608242185281818181424B1410044A08F089C530184602608100A10061428422902820022448290400848448217E
+:80B700008484428C6441248122904889023022212C614100A021264288214A7824384200DFCF0581428181422249042781C1450830688C0484508426C4282932241618024094140012302A8C845242282924A442208102441840C4282015648143022901F0928C00402411D42811880100840000701428021088044A0200220020012842AA
+:80B780000028000012448002890800002041482CF4C372001048784408C9542A18448484008C04F01428452802A042858216086CA4128120C11A478266223624248982021032124118183084162872524824792824C318458864D380016112181E28211281842148818C042618082841AB242E484400100844108824840124200283840690
+:80B800001A222211820284002091285048480037682400402201272444848324245442814240522C006042491208108204464C1814782204434442062542C8248C020084008304411A3214848125982C213D720012C01485410110024048181208000021480081850484A4002C044824248942284288324260C41A22E121628100818C0411
+:80B880004A02410012FFD70F1250288180012140422204105224818034222800000024812444502485C22450284C52486302002220022812100445084120328843F285B74052481A04214444604410080022214048180C8122240048C04280544868008C428404400C460446444808414921020022100484EFBC0E821210C21290114260CE
+:80B9000044434418080000204208240010280440288611480628008421224548083022120041100442400CF0B1C20044290481C440460281642CC42440121842542448422180111A12140221216128A14558424821902441109426814441C420A62842812249022644F87FAB10063014D0210100842100848144440081448181004444A169
+:80B98000100400444008842604100A12181240084260C1184B420000E09F0E42901815082528216424400228241002454214021088012110024648D4822206222200100480062904001243012A048B18A0122810F4553540CA424848008304450840042800441008852612129812D0480C4880041448408884C6482820044A42922444C0F1
+:80BA00002820044E286044002301DBD980A418A19568811C81016548426284A3144208650284D08294688502A1D0A4542C8D488744AD446E628B4427624C724462422C922A474281CB224E6C4F22F142542A5128163818122AA2C2224ABE2422628228F079D640741642A2513463F112442B448F24F44A4C469848404A1256C825586C2F8F
+:80BA800042722C2424424A522EA53442212450464F62C228272244CFA4024782284546342C4C3214ED2822414D1C8C044F84714C588C004CF22414C9D1E44172127248E4815166A951E99724454604E95422261EBC2A4406C59642C54A62C2CC3218402CC44846D28674445A8823B14C14BC2212722ECC46A5FA22282B44F048482A22F11C
+:80BB0000122889034F44F1444C8D241E743E148F44D44C137E88D8C2A21400404801004110840400844008100889028100304820044222810040280224200224126081E081048C84A2410000284FBD082B441AF1141C395146D751CFC5F446462FA4F442422D4225B24A5466255262255C4445FC22222B66CB464B22A55AAAA54CD66E442D
+:80BB8000D28E5424AD46AFE5F56C626F22F224266F625224ED26AF82722AFA4A48CFC6E267F77276AFA3F33A3A2FC301522E24FEBC3E34FEB44F42F2343CCD28CF8353C8FF574AF246444F41F51C1E3721E7C15751CFC5F442422F847444F24C4CA18F2456E625526225584C45FC2A262FC4B46E56841A518A8FC87842FA4E86A7A4E7C463
+:80BC0000E764B736EFE3F76C676D2E67626F6276249A2CCF42F22E2EAF84F6444C7E362F65F71A3E2FA3F3323889A1544F42F2F4FCCF43F2D4F44F42E2A3F32E28CF83D3CCF11317F042426F41C51ABB11774183F14C4E6764EF64F44A462D46A7A4AF845664A548548A4554E42FE2B222F26E4C4F42D2A851AAAD8624ED4C246D4A45D60E
+:80BC8000FAF65A7EEFA6F6262C2E226F62562EEF62F22A2C6FC2F24A488F86F6787A6F67F72A1C8F83F11828305CCF42F6F8BC4F43E74EFB2444CFC3F32E2CCFC3D3C4F1F2E4F056564F61F1181AB3711FFC1919EFC4F54646EFC4F44E4EAFC4744AF24A4A655EAA25548A8554C6AFE2F2626CCFC6F6242C8D1AA5DA68F8424AEFECF442AD
+:80BD00004A6FA4F44E4EEFF6F47E7EDFA6F626262F62F22226C7E2CF62F22A2CEFE2F24A6C6E6CCFE7F77674AFA1F33A3AAF81F21C14CB55CF42F6F8DCCF43E7CFFF2468CF83F32E2C8F83F32C2CD76280014110048004480000404842480442400400420020048100000000228C048C04120000000000007FB50543084184496181611079
+:80BD80000842844008400481431288D4480281414018880426088C040083022484400880C128A921118814A8424A41180840F8CD38C0521F4152281FC132481F41324E1D24AB141D24AB9419B64A19B54AF92448AF147924F84A914F82D41AF924488DB14FA2C4814FA27458F1244AD6E1A2645D2E4A8F49C24A1F4DC2421F497228F29154
+:80BE00002C87241F49326A1F48B24AF11124AB941B21AB945781AB944F82B44AF934482BB44F8294924F8A84F9244AFFE4042D5A1F4196521FC1324A1FC17242D2C1F24E121D2C8D961D68ADB61D682F64F924482F147924D83AF92448AF145B86ADB14F82C5916F82FC588127A2D67526681D67B286F52652178D6F22F4914CEF22749126
+:80BE8000386E1F49326E1749E72617418F44F81124ABA45F81F242849AF44AA49E482F44E283D442FAB6484CFA825A1BB700000000000000000000001002188008008044010000004400004004000000004041F1FD66108192284441248110441258180048A8C44921921284224100101648A241604424004422851462822062424440A8F8
+:80BF0000213044822AC128414B21103448C301CF540730862001290158A12100105281841028542844C4002400104C5A2C2638248D4465020045024443811198261882309829414424024C82982414CCF2243B1031428932140025884106418122704831288116CC2212653A2441122018042489417C4374241218084A52846502441844A1
+:80BF8000459824C120C214924933244443C124244D48471187439F2B02C0240045220148A1101A4102204804428440080025028485C4426082D02444140600830243A2212480A129E0881402812228C0842281F0FA24400221104414843224000012008502A524024904260824448400B0221588040000410010CC6842001002008962825E
+:80C000004A01A042CF8D43A224E0C2012CE112612218247012224108842321C21848844483810344284A92124E2E46B4465248701C02690100288D12831104241A22CC12856481848934280090488504FF46062724702804443F4241244104212311881108248014081E4C122608202631683064A9014D1A20010000214181482983485277
+:80C0800028816084842222188C442472220A22241880012682C2228001002418897218122C12042210C422412558246C044C4688042504004C32188301448322242411841108288184481088F43361004224450218004110542820028112200210C238128CC22C4844002E1810721244A43844411A0443C4420062B024084181A8282821E9
+:80C1000000521225F461F330184212184C4808859112814140288204414284448C5482448F411206122C0244902884008180924889342241405884901C30181E228024044C82528200CF3F063024009E2820A412818001C04800106841282149060000A122890180148842220200402802C04810084048D8481104450822709F04182684DF
+:80C1800031161E288C0119931200106284004981C4284D2248688D344522922458A74228181289D282941A438238264C9218482746E4006614E8821148C4182DA846C8361044A41412F0E518000010064284C184188481204408844C018145082658488440024598280041A012001008422881844282608100288C442492288428412F1FA7
+:80C200000C29111182118A21942C00000080410460A141801142C42400124118490143229114301845F82418301441478220022901444418C024184C0244419F18031054241014021062814088110284701A040010644224401C582840224202286042441290282002206142821200108801003018EF150E4C1212314949131C12684264B4
+:80C28000301844106841448140C41812428400214100260248100221181002898131240021818482180020921218434472AF09180044108211420838508216941221230129B122014421466282211642924816022C818201221824C054182A84048312E8412402124888380026082168CFCF0B8248811100834424514281004421104884B4
+:80C3000012880280420418450244182694122604210042265848004A41840241808818141454486954841889F4152B00C06400242006801102800320D148110427C421412189810412904484400812244088040000400449188C820822480040F218C3000040981420018301442481451808210049058514888432241A1494428448268A38
+:80C380008404280020144818A8248181841212841266988800228428CFEE0B44519014002606A744250225321840546212704A5422811258424668412D22008481102CE122612289012761A01220068441222941084548081828804141F1637F6082322A648232262821212222E242011E2848002828224210022A21A4848921A4212B24C0
+:80C400006014244C6484248C240248228301481216448406122011088324141AD2470867437759E3725DFC22129048CB246F2651468F23528A242F417114D2425128A14F254252A84961448544F226341E3467815863722818D64892262867224F82321A4F2492564A361C8C9714F014188D228CB214CC1447C489E8844224624418DC95CB
+:80C48000583F2209184A0229A3216FA1323416149838213883512822C5D8446163837224AC511A94544D6AAD68126B428D42E11E582D342E4227812AA552121260C12A62812E68C331286E288B22728B188C212821B818F12C38F02A288C4461644FC24381021D2414C5DC48F142122FA2C12C168A61216D1845F84A1C1632124D182D1C82
+:80C50000AB316746C41638624746AC7448C214564AE625E4C1E32664E12765782D124D1AA97158FC281418624E2C8D449012674181CB818B924B1143A2814FA5B2143434C12F82B2DB0730228463022A4128222142280200408802008304004220044A1234484B1283342442430200430243A24143026220442844E844028D24704824E1D5
+:80C5800044F29CB81435F13311E57833718BFF381EAF85F52436EFC4752C5EAA26F2181A85FA48488F81F1181E24CF84041A45D8CCD4CE52CA6FC4F21E54ED1CEF41D562F136542F82B33653C24F437144F214328F81F13C3C5E5C7E584B114912A8358FA1F13A1A2B511E548BDD4F43B358A5754F29F95E56EF83F168284B1187E27FB4C8
+:80C600004D51133F51157A1351FB8FE1F118124F63F35E5CC5DE6A5122AFE152AAAF84F71A18AF61D166F24E5E2F43A311E5F84C4CCFE6772AFE8AB8AF61F11E9E6F61512261BFB2F22662A5FB2E3A67224FA1F7181ACFE3F65C5CCF87B7349134C9B134F3585EAFA7F73A68CFC1F55C584F4F3F188F43F1F4CEAFE3B13AF12A244F44F58A
+:80C680007276AF1747D322F33373BD2BBFB2F21EBE8FE3F25E4AEFE4F75E74EFC2D2EAF23A3A8F2153ECEF24741A58E8CFE2F26E6C212F81F542488D58CFE6F72A6C6FE6FC3E5EEFE5F51E542F47F7365C2FB5F756782FE4F6365E4F65F5267485FC282E2FC4E646F454244F45A3465E348FE4F67A588B21DE848B99CF4FFF98884B314FBB
+:80C7000089F85C6EEF83F47E784B114FE2F15E53342F62F33337AF22F23B33AF23F33A3EEF25F45E76EFE7F72E2AAF22F23A32EFA151A8AFA6548AA5F22C26EF667412F45A5CCF84F44C484F26F66A68EFE7FE7E7EAFADF556542F66F66E6EAFF4F62E7CBFE4F7767E4F67F52E26A5EEE7F21E7C4F46F62C244F41B36CF574742CF23A2AF0
+:80C78000AD38CFCDF9DCD8CFCBFA8C9CCFC7F6E4FCCFE3F27E48CF46D764F1647647F61004148041188414042001402441044412281283044C02440018800122800118841848184820216281200892441220810281F0C5B280014501411222484008100881001008445048102812180484200200800284428C2642284208008498822002E7
+:80C800000000482F440D2D521F41522E1F41324A1F41B26AF11124AB141D24AB9419B24A19B54A3924AF1439242F147924D812F924481CF9244A1CF8244A16F1244A96E1A264592E4A9E242E5A1F49F224421F4952281F4932681F49326E1F48B26AD141B26AB981B24A19B54A3924AB9443B2427B2498B24F82A4944FA2742A0B2F92D549
+:80C8800041B42675117C6A53416E121FC1766AF211442F665981AF64BB15D228B924F4429347813CFB24482F1439262D914F82E514F9268A4E816F82611D65E81D7226611C6F2271D17826F29148EF227491346E13396E13392E19F46A961F48B448BB85F642144B482B348AF442B6482F443B122F44CA5AFF9B01848200000000000000DD
+:80C900000000002180018800004001400848000000004400000000002541F19BC430442400128902481391426012001008203122444054248352280012388904100A80214A244202184280322881C648EA4801C1A8280044E0DF0424824C412314C2183C018512C8128464604446F818244816E2848182813444442C415C864829D224C91C
+:80C980001828444722491224A14165E841C2428427228A011002893248000084144D485FB20F2C642C44144A41688156911123148472224806464488E22441F214424074147224E8C891122574120829348127812D2885D42462474C62414E32C5A2124E12422C229228261648E242098122404248E5C1D475044180012582021042183AC8
+:80CA0000110040287414083281221848420084442A9528490100008800100485029810A8488184831484280200F021440044344C621220820600400118C03410084484000081221218122A011860224421C421844008124220041884460420088420F2499C604222430223E162C1182C41CA1200122C45280C1662428B141A22332881E37F
+:80CA80006284F0184467266082422B1281124240068C9444126A01C9025280289C848483839118424281F0E6FB200215C6241B211A922252A522110220D582218C2131224812288484444884ACE1421582C21212841222101218D24804890389024A0188484C48C828E088210484223F940D414C2242024483810200C011009024109C18F8
+:80CB00004C628128902A8460468061812A2422012C4444544246081242C014422004988443248101608400CF33028442301216048128102881024424284A89823144003A0420348420828104412810088045042443440880028828800818448C8402213F410C8D124A1168822C04224E128904C91208221200248C8202C18427814344249F
+:80CB80000800814E280028C1412E8C484284488043C24484008C824888440821C014AD426F54050012804238140000400810088100220080420821E04482218124888101124110040080088440C21810042800001DE1801112F82218461468C1666284902828408411A281843638241044488856844121224E14844A428482C314444F8216
+:80CC0000886144842C14E48102C881815028188C0816481482C21485F27826001218E022012212408841180860824222214828844A034448002022C518428800804104448004108202826088904420324800481FD4040044422042F4441881002418842180024846228301450810082A012001814004400C20012243248288024122001075
+:80CC800084A18400DF1F0B18009012000041188D214001188091880000401C288201404488010041229014824044148228044440286A82281822444914F4EEC5501400128504200210880118004361431881841A04422004482304238144C8421800121A024C21051008A048818A01208101102828B2AC042416C16228102C24A11400101D
+:80CD000004CC01008100200100182A21424828614A8082820360818C42E8888282C2282800A441A441800228211235058200181130641100288400180060422084440840A8148A1408584242482001000048420000A84A284188120862824280F2F2E510522449C42284414004128422124481163C48CC22410410321818888D8426483499
+:80CD800028001200101448182404001218442412008911349820141806F75FA021290225214131184249C22D401408202202426638242222228742222220C154414D28902458448443C27442218504852404C608E048644420346449E1C132842AC444BF4807492204411028022A01282C012426044C08C0124425C8264304434404A50496
+:80CE000021448110A2521608008941021058848084011024020021008B377042C9114840844301456881164125C4210000260458442D48A052804C24644181222E45604684224830282E44262486E4428174220C4B848168421A44D828944C282FA812B8E40319A71841D0C52131385F85F1146417812E2885334484853818CBA2814B5BD6
+:80CE80001668A24E482267448B2283B428B34464844D18AF81346C8FC3E144E646E14264821AF2142885F822C44F433468628FC2E18EB128A848CB81439542C6F42844124B42CD96282E64218E567026745146E4623112D9C2252E448C911C1E111B31839115499114124B328784C9E44495148D2C4845A8484FC4E481D24EF7384449E10C
+:80CF000081B6440C68414B318187464AB158734898E4CD244A9624CA2624A4884283B256B164A82123778C34444CF271842416D312C2223B618126BC440483C22481269812342F4122624416C42466B216222375386844478212AE123224444C81522823A13185644218474345C8124032148542A8A22F48D5C8F12C2C8CC3288D384E1C4B
+:80CF80008CE686BC88F824584F860930245014008C04122240628164124C02A0416C22D1482281024C8251482142290149012142188449811406218C148614628821482148258414022028F46E2AE0347422F613133F71F1212195D95CF615358B1197128D23AD289F34B416F111114B318F8D7D2CFC641E6F83A151CF840628B044B258F9
+:80D00000B534E7A37156FC6466EFC4F4545C5E584F637326B434F3141C45C4626F23F24E68EFA6F62A222E328B322F2272CAFA1E1AEF8159646F61F13616EFC8FF283AAF8EDFCCD48CF868224FAD4DF353562D463F31F11616AF83F319198F12F675358F815151CD17AD289F76B616F11D394B114BDDCFC2F144126B514F25B55624B11845
+:80D0800041F84C88CF85F57C784FA3F116144F66F64F4DCFC5F53C7D4FE7B336F3347CCFC3F32C6CCD2C8FC3F25C6CEFE6F622264F22F73C3C2FA2BEE2E444F414126F62F43E5C3AF1AC9C8F22F3CEF8EF8CD4CCF83C36AE42F052637F73F713173F73B3125119CFD6F635351AF321217CD333F24B6B7F71F11B19CFC3F3F8D8C7C24F2795
+:80D10000F53E3EAF84F76664226AB368F46CE48F87F5745E2FA3F5565E6FE77736F544485E5A6FE1B466F43454CFC311F848685AF34C6ECFC4F26268AF86F168768B242BAC4B54CFA47D4AF454144F46F4ECCEEFC6F2FCECEFC6F6ACEC8F26F7EEDD345F47F735377F71F11717A3F11915CF96F671358F83F229298F72D3BBF24F7B7F7159
+:80D18000712FFD3C2C4F4FFE3C1CCFA7F73E7E6F46F776743AB364E386F66C6CCFC7F77C6E6F67F7565E2FE7F75E594FC4F4757E6F67B676F62C24CFC1F37C2CCF64F65E744F65F74C6C2F46F642548F67B768FEC2E26BC44BD46E66EFE7F57E54CFEEFD6E748FCDFDCC64CFCEFE6C76EFE30714B022016184414800400812608160818580
+:80D2000024011283040000890283A412833424800143022642A8122022018648A241248424164826018289028F6C0923082C01221222901C1222120081128122421280048485842481250144484CA252302480014B1220461C62412502004C0844004782812A4444F974D8C0421F4152281F4132481F41324A1F41B64AD141F64A921B21D8
+:80D28000AF243915AB9443F24A9143FB42934F83D412F934481CF9244A1CF8244A16F1245A96F1224A96D5A6E549C2DA1F49D222F49124CD121F49B24CF19124AB841F48B24EF98124AB941B28AB9451AB9443BA4A39242F447B2498924F8A84F9244A6FD2092E1A19D438A5218F14F1112425E1C1766AD141F44A971B214EA71F81F4482C
+:80D30000A182AD314B4B25E381D418FA12482DA14D5A4EB1ACCCA12A651D2568586D5B8E218CFDD12C25F2816C4D521B28C9B191B64AD841929E1F88F62A941F48B44AD385929A4B49A9A34A2DB44F8894326F8AB442F1A41ADFF90784000000000044800200210000210000000040014008480000000000280000000021F019FB20018C38
+:80D380000218206441174112848021118C22018812188C0246084823011608128418222216C21230184963482C01248428890884840044586088284988F4AC8D403285441682041189824214E12102259441100C16084144842C129C24848D26E04441A42548442448418480B41A8484112218A81288009048608A8118401174C70D166296
+:80D40000548418480083F3211418C12823D242118CC2181008124C022315E828227128548248121B434A0189A241464698184696542C042489782438A8A28184004138818E1A908416F4167E00302490126014444044218101460144802941441868A24449140812494144084302252201A01286882111022001003048B04808200248CF06
+:80D480002502218001803224191208000014412140A441184142484604280021128CA12122124116140440044481822180618944484C0810544820045F170A4942024522D242512187452C6287A05290129052709844D84A4284311481A42CE284B11E9478202204412042028991665238896262C12A7842180210C2686E88CB42002A05B7
+:80D5000042475350429012902238284C84C258800212245821C48594121843C11460C4245E2A16C82821284A81420460414018E24421436C828D8429C24A400829E4CCB2A8D4481444A44220F416A4200240042554143D388582021A44021441A081306C4480C4483022604452201128212261421086E14204804206882118984400200247
+:80D58000811842F0B198B0582246816241818C42410C44421002A554422420164224B21414028B1A00C1848485328849A26120A1C16042842110C448411261502252428144A28061249FBE455248274412612042D2240218654182A18218284A9114821004581245028A7428042480441484118811B822E481220844004128209424895804
+:80D6000084A82200444183F213670080C2182C02004A2244081001008126140888848140480241901428004022C2A484008A02128140181208804804281668842260783446062E1349426682AC922427C44612092131122522341C828312028C518410829128101806C46122A0128F628849B884E2884224018CC42A128914046B814EA440
+:80D6800084443668444468CFFE092AC12460812A01102122014818827024C814D042824434844AC24244848B2461444183E182048C68412E5280C1282A012400C400244124863848802282488843D8B50B104222B2261421321123C31266022800244D28608227442818188042888211224408212608224100188004D02812081812210009
+:80D70000611820850228AD22A0244144004A218112141B81042D1242A0414A01800184002C81041E461280C2444224A01228108832188904214210042084016242800888DF5A0880040000181480512116828121018B211883010000824048D42201C4220080D42822018741C0268141000089042548820A00002F4E07F01822414149520C
+:80D780002400284480030026044483042F42280326A8144C242304A0182218241A2203A04220088242004C82089014902890144820B81874760B40014870129724242C0500174460215026C02284120050C20088890181814912922242101202604481228480012400800100222074AC04CC0211181162124942A4121A22062880A2824202
+:80D80000214A42883628CCE222C12C8001A444218422400818AA311820314244A024892492221284404244048B846889F87461402A814194424002002D4121401414243424421042341400304C252884242121244102008542048400212100004E2485048162814088F1968D20684821230260A411408448F31428002100184400221270AC
+:80D8800042122404004634824284100284463414100428828936588148256A4C85240189081C44D19E0F46889241118602001414C014C02825846121001244842584E484018F214846082412164108841E248C44028141702A4414480429C2880022C914480423081F690D4C32A345D224E246BE11227723F632261AF323412E7123A711C6
+:80D900006D522E326C23F1285826BA262282F124224E684B562E68AFA9C518242F81A8226CA1662682C4228416C21C4CC8584644F22A26428C0484AF846C2646842248E48484E61A6884EF4B0766B294416444F04614441A5215144E92372564250A45F45488CF4615B248E1C8A1418F82821444FE1E12D062F412488D144D5427898391E4
+:80D9800022224F41012F8C311A12418D82894618B248E2462181419C8EC7626F8445B818E88AE894B498EC7703488D6637113353273CD42AC3114A51E71A02D913644123B12294225E226F4124D184731474187828928A463444C3A51424A7A14B66A489F112222AF438228B2243F42C1887456F8274261CD488AE1287292542925C16CAB5
+:80DA0000188F43B264450480F3383820840180844108844148204104800448004400208461441842188021A412A012200200000022001A04808214088182707B014D641F13A3111F73F3A1633D236F44F631214F57F52624EA2AF248484588A133FEB22724ED4C8F82F228388F8414FC6C666F62F626266F42F2441A1A6184C5FC48488EBE
+:80DA8000A44652226E626F62F222222BBB5A65418784508885A8CC5AE58555888B89AB262BCC25B212F5343C8BDD4AD888D888E8FA0F4F46F235751F61F132341F36F263276F44F635356F67F72734FEF43F32F27B4D45B814F136222F2BCF12EFE5F16A38AFA2B146D48CF16A7A4F42F264E6AD6C47C48F81D588D4C4F149494F4AFE58EF
+:80DB0000198D286AF62466AF23B3B8AB551E148145568A85F8C2C46AE6C7578A8BC9EF47B3D6FD12122F85F1743C8F2DBD4224785AF8F777F024665F53A7331F33F3E1613F54F24F6D1F13F27855EF42F3F2B41F16F648684D1C29F132322F2FF94616EFE5B56EF32A38AF845644CF64F726666FE2FA2636CFA4B514E18551CC8FD4F68829
+:80DB8000AC8FA6F6222A4F66F62666AFA2F2B2BAEF4524715C5E622D2885FCC8C48B625E788781DE882F67F3DAD6EFA3B112F52C28CF8CFC4A888D888F84F9CD3FF064667F52F231362F63F363233F57F24F4F7771AF77F72B372F2FFF2323FFB5F7161E6F41F13632EFAFFF6C1EEFE5F16E3CAF82F146644FE1F3686ACFC6F66C6C6D64E5
+:80DC0000CFE4F45C5C8FA5F41C1CCFF7F6BEFC9FA7F7323A4F47F71436AFA3E3ABF95C5CCFC1F15C5E25D68AD2ECF2CAC88B664F85771AF8DAC8EF67F3D6D26F63F17A58CF87B7DCBD62FE888A8F84F9CEEA1004250165014522412201402141026412441008008514624429314818103448218001219016844D128441008C0484248C448B
+:80DC800044C8241220384820092A24818122962129912149816216901A1022B148024E243618220380A242400A002D18281828214CB228010042204238620010021830424321A442005F7A0D2E521F41D228F1112483F41164AB141D24EB141D24AB941B61AB9451AB944B42AF14B924F442914F8AD412F924481CF9244A4E814FA26415E0
+:80DD00004FA2651D2E5A96C5DADE242E5A1F49E222F591248F22F1912483F69124AB861F48B24AD941B66AB981B24A3915AB944B42AB9443BA42FB244829F9A448984FAAF4D638E022D1C1D428952189D141961A1D64EB141F48D64AB111D64A9B61AB944B4AAD914B422D91AE482F14F92248AF14F924124E914FA2E815E8A2611C4FA284
+:80DD80006115BCE95DE2A279D1FC241A1F49F4285217418B861F49B46A5841A9F98164AF467191942A5B69A9B984943A4B4929BA8494326B4A29F1845ABF41042788820000000000800200000010020000000014008400000000004400000000002541E18F04224180412402C0144421001142800118812883211118020012842981618399
+:80DE0000382224406248C01C10240228800883849158418012442414F49F8D14428A5142204812649183880226092135448804AD44A041418748412489F228140043141828889412204368A12822C33518008CC8284824400824D08401501C81F72C1468434C849184001C31144912C42122140042204548D2482131186088122011183230
+:80DE80001189A12189022B258129296281124128B08C82224A8284114806835124414661815F430820110280124638881042480227548418504AA034D048582430228D2400493418848AC2421200401CC224C364810040280481844A013024008514F477E780810200104C5422114008150810020000502440020024002825020024102223
+:80DF0000010000122100222400410044F0F8760024008126020000701203180044002100002508410000004C025048400200808181020012880020314800BF8109182200812C12480400243C0112004100210044000000002821260410440212008001280020210800188C4404AF780C400A0010042512018144150810020010022424852C
+:80DF8000024440020024008485022400003014122100282400411002D01208114002842144254241082410022150240000002441004004446184442416140400100224202101432408450A58844400BD4A0000401404159418228280C18145C81A8021022140C4280081844112254228011844221221444440E2886182A8840081808121B7
+:80E00000110400C0C22400114100002004110000120000810010480200002602248200002283A8410000252241020000449084F0118C100300444144248D11662848810184258A4106241018C4282484848441412502222149415442160444288229719268A2A284168251A48218450243440886043FE80600344485022415040050221369
+:80E0800048240112280000004110021850A416440829A8212400448148002011024200168821411404F0BCA8004001250214004001141008850200000010040021400200214421100224100800248001000000005FEC0D1004100410020011401102008410184418044004848544184242020040444402602100210000181241128410089E
+:80E100001FBF01401841022124004041411501000000618144004110480C1002250284400210021810041002808101101842089FCF0F85784804400411005044453424248440181208A4255222123084001012184302855888C31412440424400A45544643021200108441522225A2118FD1070000000000008481002100000000000000AA
+:80E1800000000000000024400281000000000041FDC210C84842484002400244414C2282020000101292121684298848042114111484818C24840424000044414C62222810120800212129F1934B400A4824104408210025042C0200000024214418418800810014008480044004240021442489021008000021F021E400000000210065D9
+:80E2000004244008100800210000000000008508000000005044000000800110021AF1322F1002002400000000240000000000000000000000000010020000004042080000003F17051028240400005044102E220281004002454224614183281804001131850881462444020000454412342826880181002440B214F1CDFF5082858884E6
+:80E28000441244022502405444282800000010128281818808004041018485888404442400008554442828000000109212AEA300101403240014244008100821810000004400411008000000000000001012080000000044F0668440020021000000211008000000000000000000000000004002000010020000000057D22410421241122A
+:80E30000424812421212184A1208400800004441004144812100000000400440021048120800000000F02F62502200105224001042120281250810080000410084100400000000002121250224104248022C518A81120000419F4C0C00442440542221150200A48440120A0000414054440040084002004004502400214002A184A10084D8
+:80E3800000004144CF1B0E672225A2122B119012C0123582F8121317319B88179985F888414E48D09114815489814F84744854444B242E24C024805264412E24672225E222B11281B882092C5922882F317111B388699985B888E484048C04488518F84448BF83076F22522418122311021C512229D832B11191811F8818D8182464849494
+:80E400001581445888488F44149C242226440428255444286F2252242C21A181232888512229D832B11191819E888391484246480848848588F48179000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000043
+:80E480000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000BE
+:80E5000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000003D
+:80E58000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00BD
+:80E600000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04F3A
+:80E68000FE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000FB
+:80E70000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000003B
+:80E780000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000000000000000000000000000000000000BB
+:80E8000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000000000000000000000000000000003A
+:80E88000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000000000000000000000000BA
+:80E900000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000039
+:80E9800000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000B9
+:80EA0000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000000000000000038
+:80EA80000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000000000000000000000000B8
+:80EB000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000000037
+:80EB8000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F000000000000000000B7
+:80EC00000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000036
+:80EC800000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000B6
+:80ED0000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00000035
+:80ED80000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F00B5
+:80EE000000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE443
+:80EE80000F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000000000000000000000000000000000000000000000000097
+:80EF0000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000000000000000000000000000000000000000000033
+:80EF80000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000000000000000000000000000000000000000B3
+:80F0000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000000000000000000000000000000000000032
+:80F08000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000000000000000000000000000000000B2
+:80F100000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000031
+:80F1800000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000B1
+:80F20000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000000000000000000030
+:80F280000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000000000000000B0
+:80F3000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE0000000000000000000000002F
+:80F38000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE00000000000000000000AF
+:80F400000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000000000000000000000000F04FFE14218414942518048C
+:80F48000001004002444444424240010041002A1C1001018080084100440321441100800241644060012F08C184041110815465868C542160440548444812502A504A481101212420641218181C12444218481248514582C8D14612480911441446512149812122D1289418AE1C80621104802A100612141004100214008240000504200B7
+:80F500004100418464008150424400101224010040941200218481F03DE24051811440014425084100100881440050828140140200448400401208004008C1276130142190180000814112184042B2BA09001018141408000000444124100400240040022100818400004008008400004014140460214002009FD104001011084004004069
+:80F580000410024542020000240010184208000084004008400400414002214421001812121F5E070000000000000000000000000000000000000000000000000000000000F04FFE4002841181000041840044100400A4400C1002100884100889022C012821441008008400100422101298284144413F394F0111004044484C480824C0B1
+:80F6000042800424800400415084211024110C0000004481641224122418001606644084410200B02A46410284104804448144810041210000812144502450A440489418C18190288011821256482481240084006C1144264204902800441F550E100111008184400810820449041082048400000000000000000044188001290100000088
+:80F68000294118124404DFC5090010019012009012800100008100000010080012221042A41210224122080010021810022C01004200707E06902226140219114882921880011042420C1224478160818484842902105882844B128D24210018A1408A626284C10000182284848480C2148D44441FE80120121402182901294218024002A4
+:80F7000050C2301850860084812422002481222424410029110A86084425181802002321421A1808621845089FFC0C2480120114840018121218000000800189011048084028113834C3022A0120414222820244001200800100108414F44BB21045040000A021127018043212184341020021200181004004122400221618040010021832
+:80F780004004D084121A244288411842086F6B030042124001D41008448126054012040025041200902410084400C0484664822B214912022200C024002880028002214489F5B114241A2211210200004100001004810000848441005024100841814112001002810024404808120024440044005DCAB0239114111A0200C11A9214401810
+:80F80000981412492151680010441848048012144A6841101AA41441833212274240280224608281105C82222C02124014C4482F2204450800100111400812100140060000004008411004400420221184420224001200001840048524120881F0C18B00002001000000008001400410CC288184818483010084848C0100187014184828AE
+:80F880000140280110880200440020F1C73E0044486400284138002021018041222321822401001844184D288C82024180018D24422441702448B284821248220884832281012002225F9805000046044220042F24014220243146414A0200842400800100C0280010021800400880288208888008840000F0CF3B6014890240C8680000B3
+:80F900008006808304210018222432204128021800800112002D24128B2141001216849424E04112080000862CAA48AFAF0A4C11142454824122001840228101004400D0480200002800200200004110281208260832840012A0211200261408A7113FFC0800200100442A0118002818008091488C0222228100200200000018100400002B
+:80F98000504800000024604200003B7C6082006122108411082118830200214A418601D0424102211221C127821E28440000441285421484932200F012840040824848048110081F4B0E1200002441001810020080014002000081218421122001841224000020011A02001A0228008001002C02C731704418D21404454248A842242A245A
+:80FA000062418006002880321812618418218844182140480140088C8401184312840400801408C44014482838CA86F4AF638022522447412183722294343A81A211222383A411521266F414343AF122388F41F234148F824258288CD1286323C12042A81180014D1881AC2161814932284B1A2688014880D28AA2116341440826A9241F2D
+:80FA8000310E4F21114844D2C8429824442C824532428981210249512250821250A81885721218088CE18291288D3422C52861212187434321F12C1CCB12A7814E32F018348B874923F81818A012400C43A288422B98FFC20E1F44544414424D52469448488964212B421A812481C4122994142A24147864884212021672341CB4126283EE
+:80FB00008481006041F02256C584C2242604308425682AB0A452888E8481184782818D2C8F287A14F8A8BA1001100247242006626024200446044E22C02200000021104204441844408401002110022B84B04208291894824120110800F0176D141F3555431416B64AE4A4F448486AD2A8F432726B64388D58484E4225B252B564068F870D
+:80FB8000A7114FC3E38141A822A4212A12528C4B118F83F2242C45B81421F11416AF81A111CF41D16E512E6F61F17A682F23FBEAE2AF2EFEC2946F61FD8A822F4BFB282C45B6160180F888C8EFEBBEF30F7E663F4646E541B42AF228268FC4E446F2185A2F23F756744AD7CA87E524F556466F61F122226F64F43A3883F13E183E1825FACD
+:80FC000022222FA859822EA86F42528C4F81F1152D4D24C5F91C181AF1444EAFE1F11252EF41F11E16E5FC141C8F85D622FA9EB81AA3156F61FD8E8E2FCB79285C2425F42828C5FC82A88F88FEBED4EF1C0D4F27F723644561418B22AF22F24E2C4F42D6A8E227F232246AD7882384E125F512126F2333228F8666826FC121B128B328D227
+:80FC800028B81AF11C1C2341A4114F53A2331E141E1847612F21F516366F61731EF62424E5F41C14CFE3F2E4642F42AA224E328AF41E948F21B186D864B1160145F48EACCFCCFEECFCBD97F075373F42565456F42C24EF26F66A284F43F7383A7E322F47B732D38EA1144AE521F112126F67F77676AFA2F222284F817114FE282AAF82F26B
+:80FD00001A8AAF21719EFE1E1EA7C28F81F13829CFC37219EC81F11416AF21F41E3EEFE5F31E1A4FC2526EEF41F33C2E4F4FF73ABEAF8FEF25F18444AB918F21F18E88CD1AA5AC22C5FC84ACCFECFEECF4EFA50D411004400800122001402201124410088D2490281088810281188100000041844961812001842001842800400428F024A8
+:80FD800095200800004100000000C012008001180000002200000050261004A0210000180012288001818260984F21012CF4112485F211248B141F41364A1F41B64AD141B64A9961AB945B41AB944B42AF34B924F442914F82F442914F82C4914FA2C4814FA264114FA264194FA264594D4A9E244D5A1F49D224F4912487221F4932681F8D
+:80FE000049324A1F48B24AF18124AB941B28AB9453F84A9443FA4A9443F34294478229FB2448984FA23498F022421FC1D42AD441B22CF1114483F21164A3D241F628941D4489BB15968A4B42AD954B428DB14F82E4147B26C8916FA2C5916F82EC11E8827498F5245296D1B4E418D2A4F581284D5A1B682E1217C88B161749A3F48124E941
+:80FE8000F1812CAD141B28AD3413F84A34A22F6461838F44588429FB26484E946FA271620D0048000000004480020000000080018800004001400800000000400428000000002170FD010000000010010000844448800400000000008400002821202101100881008220110812812008D09B0EA01890140080A1144484281200804202415A
+:80FF00000012A41002855442840040981220110800800141204208802241388880A1211601DF9109A014C05400001815148C22020044460243440212164A2208451806100984A30166120812001881414122220028126089C012A812127FFF0400000020210400180084280000000000008400000012002001001008818220114808842014
+:80FF800001F0B16A001141440020010000001200004210081002001008C0120010421404002302201802000010045048F0FA6100444002004400104208004142840000C100446444808622021880429412000084890822800889E121440A8800008F9D054044440600180010420820112414080084C10040068084022C01404214460400F4
+:020000040001F9
+:800000008982088880088901A130840084D0C6071001000041000000000000420040024140048302282001222001001012082821008005210010047FC1050042100810042011148801400810082149220144004088018012084245081840480440240180021224004004849DA8E0814424044400004410240210024100100A1602810021A0
+:8000800000008481A014804208800124C024002833020000A100EFDB49024004000000000000002001C018000000180000A0120024004100801488088111802121420820F4B3DA90420000000041184088014048048110884202001012080083022A01C46081409C1400488C22088422122C012884C1003F6C0E8C411404C10044000000D3
+:8001000024000012008D1400450800181200002001282100001022014002001800008CF43BAF000000410000004901001A8404608228004100002200000040080000400440080000100C8282844FCE0E624441402201181602002400854208484E2E44004428002800212100188C019022258A12A8212CA2828A224102841883223118A0FE
+:8001800024848118DFC10D84810010084110942420020010040040020000008400000020040080044200000000180024F0EF9E400116440C2904002588810445C81C444C0200448129818213420216121414180200A121100200811008824C222228294108926084F0BE2F208C0400000020010010044884890441000000000000818004E9
+:8002000081100881B088849228428110088188008228146B45000080010020021004004E12400281000000810000100284800400004C04414C040000884A02109292F0FFE1C01C80829424B024311241123012A01484A901244A3234288429634241008042C2222A01282D1220C2222AA1122013228281388280C2121812241840082188E5
+:800280006783000000400212400218800144800118008410022001120000000020010084001008816088000080F8FA85508400100449C148411A2462C38046741242421474120228291282818198222829922885420324849042812A412842084848862C88222228082031981002DFDF09433584004F6182D12492144118248C43D448C594
+:800300001845E444042FC4A1142E1487823026282140A82122A321110224188184A3433238228323B228ACC68DA85088106A8187888B81818F24098E81F0E258A042836441004054821E12CB412624B5140387411E186901246F411212E4214268420022182D242CD28A42122201242C22F43218405882ACE4849124124A48041A8829D1FE
+:8003800082216189D0A885F833A450419024C304E3A4111A4494221A1342225424A562A36F44A4428FA2D48C82A2124C5224182429622224478224C0228911B24212C22A28841A024E24436888236CA8E082E388A12898624C81B28828B288F15ECFE041021E24818E24A3C424A3C424A304A3062100226081200100244002004981022857
+:8004000021280081100AA901A901AB12901A102A126A8A142E48E082042F56095F14E643F3383CCFC2F61C1A3E363E7C4FE2F74E5A6E264E484E5A2F24D1ACF4181C8B226AA6556AF66A2A2B221AF114148FA2B2220221A50A2552222E222B22B022F23222248B221E188FA3F338328B332E3AEFE7F33CB68B99CEDAAFADFD181281BEBA2D
+:80048000AFABB9AAE38FFFA8B88B536EE8FEF88F8FFE7EEB145E744FC212B454F5E86ECFC7F6164A6D4AAFE4F47C2C2FE3F3222AAFA6F75416CF81D188A1557AF74A4A2F26B722B212F11434AFA2F322222F2809AD882952666D263F3151222F12F22A282F23D222F42A288B321E3A1E3A8D2AAD322FA1E3A8FAACAEAF2AFBD2FA1E1A8D1F
+:800500002AAF2BFBB29A2F89B1D8BDB8EBA3F5CAC88B998F2BFBBC79F031556841417E74AF85F51412E3F47234AD582E16A9B142F31E58AFC17118A8454B448FA6F672722B222B334F42F2283A2C9282248FA2A2226F63F326262F31012F22F2121827212F22B622B238E383F332383E32AB234FC2F3262C6CB2BAEA845F821E12AB1A9E33
+:80058000389E1AABDD8B9BDEB82BC88B9989F1FCD5144B428D243E348F85518C2F43E343F35812CF87F312443AF378628F85F75614EFA1D18CA1734B662F24F47E4A2B223E384F62F22C282B221A48F2A8282B226F63F326262FB24252212FA37312F22222AF22E282A333AB338B223E2A6F42F33E348D24BEAA2BDCA18B13BE1A2B318FFD
+:8006000029F9F2F8BE918BBD2F88EC8FEF2AFBE2D9800100220012200112002412444824C02400C024000018302230220010022901002008820020088022890220F8C7460012200100200200004048042B240016880100000085040012220012001800008200200A8001200A489FFB084D421F41522C1F41324C1F41364E1D64EB141D64FD
+:80068000AB9419B64A9945AF443924AF147924F84A9147822D914F82C4914FA2C4814FA264114FA264194FA26459ACE449C24A1F49C2421F4952281FC932481FC9324A1FC8B24AD1C1B24AD981B24A5985AF447924B84A7924B84A7924D84AF9244889F9244A7F390F4F22F411484F22741138441F8136661D486B141D682F46D9C1B44258
+:80070000FB1168AF4418F442B14783AF5439342D916D488DB56FA2C5914FA2FC18814D4A9E214D4A9E25BCE559C2481FC9C24A1F49C6421FC922F4912C421FC912F411684CF8114C4AFA15484EA447834A78A4B848A142AF44392689B926F5F9E7202888040000004004280000000021800188000040014008480000000000280000000082
+:8007800025018F270D000010452802000044004444282860822200000000002002326081424284480000860884840000100870840A42828008001008004800442230184C21020020048440020000422001002200C24608002001809448008E41844FE10442C22008000000E04244044141448CC314260220018A048400100100424E1830F1
+:800800001848422848201404A608848100428124818E4183F18162000000151488120800000028002260822800000024000028808201008100828304002001004800007FCE06400420022200000000000048000000002800000000000041000082210000000082008F1A012880020010392884210000004222442A0432440000412422009E
+:8008800080040028809128248142838102002C488888828C0400BF3D0F284128008052182608210000002062444A022A41040060423022000000800212C15082488CA182210088258808808408E03B03000028000084000000200400000000000000200400008002000000000022C20000BFC60200840000000000608100004400004800CE
+:8009000000420048800442280000001882800200800100008CF1C779002004002800004922020000800244001200004008002024044008001200C0641880820182001180F1AA1800000040080012008A440116081800002200000022420000004110020090480000804808204801F02FE20040080022002081024813018480C12440042223
+:8009800000002064820080240422400800008E4800182022981882200810F84498000000100800002018081800000020040000802404000044240080210120040018000000F01E9D00260400200400000000000068000020020022000000180042200400000048000000C8F0B6178004000000422220218402120042444400128084042238
+:800A000048480048181218800100008A0442A048000088428200F0254E000020110800008100000000002200808221220100000000000000A02100008004001842F095A8004800800483040000608284000000000000002004180000808101000080010000008088019F920E00000000000000000080614420042848800448000000004AF7
+:800A8000014818488004488004480048420018D0430B12220000006842484248002002684228200100000000004280010041000028002800C0848282C80082CEA9004824004180011800800541200100004800480028430200121A1484018001441004882800188800810020F25FCF202808008024243228000000280000800228000000B6
+:800B000000000080040000001212000000808428086F5407461812282101009044C0448042480820820410024A018820048061140084800418800100C024800244128200C01421F06D3D00A220012084A142481028040028184A62442E648004002A02420000001A0112181AA154184604C6044A2321044B14184328480880A8824F8C08C6
+:800B8000428A0600004A24A432A0454842508822A0421841A022184280A4412022A21420A11140045200124880041A0C828004428842884B8858F08598E021344485021A714884148862C4420018878243010048428081A4224A24042AA2454E2420248484A41118486041000028222A810480882884AC4C1A210DB75400008901819018D1
+:800C0000901880011880218221C2142A84A14220022252A0212001000000200442A084A084A084A08412804481044870840A7E722B22859A128F88F14C4C8F8424E483F3343C1AD588A1551AF11818CD3C3AA3317AF744244F47A3372AA2666A26A2373AA3336AF664344AA1445AA5555AF514141A014AF55414584D444A74C4A46A2AA7B9
+:800C8000DFC2CA7244A4DD4F44A4448D48CAFCC494DA29F52BD9E027F7622885BA42A1C445F448488F85E583D1C4F44C4C4AE547A7448CF22C3C3AA3226AF674744F63B772A5662B136AA6AA6A86AA335AF544141F14A1554E418F85A5114FC1A51148424F41A5444744424F48F4C444DAE94FAB48CAD444A4884F44048F88E82CFCD6D40E
+:800D0000DABDF2FF6667E027974224AF81A1114F44A4448F85A522CF42C24487814AA74485781CAC32A0665E542E6423A2772AA162C86AA2662AA6734F46E61584A4514E585AF514541AA1115AF11454704424D4444CA4BF5A830C4F49AD444F4CA4448D49CAFC96949AA9981FC3067E72A944F21A184A54CC8F84A4443AF13C148FC4A48D
+:800D8000454B745A7528F81C2C2AA3316AB644B67433423E324AA5622AAC66DAA773684F44E415A45119E485A511CF4121A1151AF15414484D44F044844CA4514BB94A28F4D4941AF144444AF44848CAFCD694DE12EADBA70722008440081E48228C048C04484008004820210400000000008001180000488024820448002008008242823F
+:800E00008FEC0B48000000000020040000B0140448000080011800008005180048000022800180040082208128E8130A4D421F4152281F4132481F41364A1D24AB141D24AB9419B24A19B54A3924AF1439242F147924D852F924481CF9244A1CF8244A16F1244A96E1A2E459C24A9E24ACF491242CF4912485F2912483F49124A3F4812463
+:800E8000AB141F48B24AB981B24A3985AB9443BA4A39242B94478229F92448984FA2F46183D084B51196421FC192161F8136421D2C6B141F81F24A841F41B24ABA15B24A28F34A8543F3428126D852F926482D914FA2C5914FA2EC1178246A194D4A8E21BCE558C25A1FC9D2A4B49156281F48B64CB181B24EB181B24EB181F24A141F49C2
+:800F0000B24AB385B24A217B4A24D24A392429F922482D944D5A9F290B848248000000000028000000211002188008000014008480040000004004280000000025012F9407000081C02800400800204228022200200200004820040000000000002028010080040000F074710082008008004100128004000020260120840100380048005A
+:800F80000080040000000000002002481C04EFDC0A200C40082200414120024A820222804222242101821800482A1101100842004800001084280300000024C041125FFF020000801808008180010081000022200248000080044800000000000000000048200248003FB90A22000000000080010000200100008002800118000000000096
+:801000000000820040084881828100F0A2190020020012221008000080020062200284800400220012200412000048200C008890814008003028F0BFAF00000080210281000000008081040081000012281220010012000048A08480088880088180081008AF5707288002000000001800200200222002006800000000480000000000000B
+:801080000015084281100822708306002008004902004100680000004A220112002002800490482004008004000028000000008820F1D987A0412004428004001004220010044A0200A04120010081004028A12400420020842188828208202404400118183F230700201812040000002001000020018002200242180020220420024212E3
+:801100004004420081200400100100BB4480044022044800000080050020064A230128202102422004802404802284240146048002002024040080016FFE0918000044C0240000000010040000200400283018008082810200200420A1840086084800002008F077930000000000002800440028200422000080020022000028008110080D
+:80118000000082000081000048F0C99110A4244120028081420448801188C444D048040081482095485200301800282200002001008428002200820048830242DE8F00000000000080021A0200000000001800485800488148000018000000000000208404008FC402224190248002002800808104444014041812444C0120210220850239
+:801200000000002001208422042882008004814840F8693710044100002800000044008004442004004280042004004200800400001008880000480010086F97072084042200200300001A0442004100000020040000420000000000840000000000004284FF4D064200408414844484942822414B24200410A8248C842442240400200404
+:80128000260800002014484848080088008048088493088A02F02BC420280A288222002002004008800210A421120000000020022200800400400800204408800400429442A7146082414841414110141484420428400C4C2402002382D448A1241A0842818305460140084800000040482CA82888420081488110023F4E08308430248857
+:8013000040240142892202C0148C344428C1430220120418802284B4181408422222000000818142B02828A84881488004194C88621446F8566C9024A61444E442E242024E244F423224222890148334444CA442CC82C448128966444822485A8464844256A826C0284800201438180081890280280881C04846B848B448CC4148BF2709DF
+:801380002E444A468412240480C124809424524F830410A4444654442AA71148C5A4448B15182280A17280044222A0448588C1180040688488808A0886384800228518F881F900002038442024210442400444400440A8248440088440080000000080042044A884200442844284889088802881F8D62DA0662A52444F42B264A6224AA43D
+:801400006745F444448D4848F05444CF45D5C4D4448452C48F8256888F83E181518885B428E281F168788F8222F458188D386A86A4224A8602F0484887811285A844F048488F8424A6488AAEC8428B48CA94498AA8BB9A099F9D064F46F6442C45F464244F44FC6464F034244A048D4C686E64448B554FC4D444C424CD444FC2F644462B8D
+:80148000321E18AFC415B8E8EF81F568E88F82028F81F529296AC6418B224AC66880F448481AF1181885A8448F84F42C2C8F8AEA44A2C88A8EA48C8B48CAA4CC8F28B83AE385F112185F72072A82564445C4244F46062AF314144554C842284F44F41C5489A4444F42C6688F86062B558B554E5845A8E68B116E682AD288F418186E292A7A
+:80150000A6222E282AA2620085A8115AA544A0CC8FCAFAA8A8284285A88C8394C88D488F98082B626AA2985D5E40944C44414F44D444024F46B714A1648528B44446F45C54C9E444F42464CB646E6CCFC4B472F518124F8444A8E78B11CE4850888F81E192A6621B222E282AB228024285A8118F85F548488F84F488888FCABAE8BE842820
+:80158000FCA888428B8C89AC44E088FCE2E86E2ACAF9C6B230240000484148224880044840084828002004874420048B24304820040000008081048A048E48A048000080344800D09C020041200200002200200400800480030080040000002200000000000000484200003048F0A52AC0421F4152281F4132481F41324A1D24AB141D24D6
+:80160000AB9419B24A19B54A3924AF1439242F147924D812F924481CFB244A1CF8244A16F1244A96E1A26459ACE449C24A1F49C2421F4952281F4932481F49324A1F48B24AD141B24A9921AB9451AB94478AAB9443BA4279A498924F8A84F9A44A3FD10DA41F41F628421741C3B411326A1741E394212F44D9C1B24A3B11AF442BF24A9502
+:8016800022AF545984ADB56782AD914FA2C5914DCA8F11FA245A96E1A264592E5B96E5A2F4912CACF4916485F2916483F4912CA3F4812C2B141D2CAF46D941B24A9B252B94478AAB14478AAB14439A126F8B943A4FAAD51E0D848248000000004400000000002180018800004001400848000000004480020000005012F0723F000000000B
+:80170000000000000000008D24800200000000004200000000200400820000802804F048C800A20000880000000000000000004200000000000000006084000000200442004001BF6F0AA02C00000000412002000000244C0232A048000010011028240400002004412002820000C082481412FDA100000080080000000000004008000020
+:801780000000000000000000812004000042200400008F870280020040010000000000000000800400000000001800000000000000000000F09D4500004120020000000000000028000000000000802402008800002002000020040010E83F028002448012010000000000002002004200000000808482010000000000000042000084DF74
+:801800003306000000000000000000000000000000000000000082000080020000000000F0EADC0000000000180000000000218002000000000000001800000000000012000000F0FB3500000000002210080000004200008004200200004002200200006081000000C048008081F87621000000000000002400000000000000410000000C
+:801880000000000000001288840020080089047FD804000000002003000000004602800280043024000000240038000000122021180818608800C05888DFAC0400000000004008100200000000000000000000000000001008000000420000F07F1A00000000810000000000000000000000000080020000000000000000000000BED60023
+:801900000000000000000000400200000000000000000000000000000000000000F0C66E000000000000000000001008000000000000000000000000000000000000F045FA000000000000000000002181000000000000000000000000000000000000004F280B000000000000000000000000000000000000000000000000000000000096
+:80198000F04FFE00000040080000000000002100000000000000000000000000810000000000F04E9800008100000000000000000000000080010010020000840000000000002A010000CFC1010000000000000000000000000000000000000000000000000000000000F04FFE000000000014000000000000000000000000000000000045
+:801A000000000000000000F084D3000000000000000000000000000000000000200100000000000000000000F04737000000000000000000000000004002000000000000000000000000000000F02E9E000000000000000000000000000000000000000000000000000000000000FFE40F0000000040010000000000000000001800002126
+:801A800020010084000000000000220000F0398B0000840084000000000000100200001002000000000000000000840000800100001F6A080000000000000000000000000000000000000000000000000000000000F04FFE0040010080045400004800001002400400218001882810021880088400008042080000280000F07DFF0040018E
+:801B0000008004548588022148400428100240042810828401882810828441848842188204441828842148E041012810A21140C43500000000000000000000440000000000000080020000880000008002000000004F11020014001480045448400448004800210044004421800188289082800188400800002884000080020000FF360C4F
+:801B80000000000000000000000000000000000000000000000000000000000000F04FFE000000000000000000000000000000000000000000000000000000000000FFE40F0021000000000080022100448002000080028004000080044480022148400400214840040021CF9E0A00000000000000000000000000000000000000000000EA
+:801C000000000000000000F04FFE00000000000000000000000000000000000028008800000000002800000000C037000000000000000000000000000000000000000000000000000000000000FFE40F0000000000000000000000000000000000000088000000000000000000008FD10300000000000000000000000000000000008002F9
+:3E1C80000000000000002800000000F057F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFFFFFFFFFFB3
+:00000001FF
diff --git a/xpp/utils/FPGA_FXS.hex b/xpp/firmwares/FPGA_FXS.hex
index d3b6c8d..d3b6c8d 100644
--- a/xpp/utils/FPGA_FXS.hex
+++ b/xpp/firmwares/FPGA_FXS.hex
diff --git a/xpp/LICENSE.firmware b/xpp/firmwares/LICENSE.firmware
index b9bb89f..b9bb89f 100644
--- a/xpp/LICENSE.firmware
+++ b/xpp/firmwares/LICENSE.firmware
diff --git a/xpp/firmwares/README b/xpp/firmwares/README
new file mode 100644
index 0000000..e423aa6
--- /dev/null
+++ b/xpp/firmwares/README
@@ -0,0 +1,19 @@
+This distribution includes the firmware files required by the Xorcom[tm]
+Astribank[tm].
+
+This distribution inlcudes just the firmware files. Be sure to use a
+zaptel distribution/package of a matching version.
+
+INSTALLATION
+""""""""""""
+run "make install" as root. (which will simply copy all the *.hex files
+to /usr/share/zaptel )
+
+USAGE
+"""""
+When the firmware files are in place everything should work
+automagically. Consult the xpp documentation included in the package
+zaptel (or the debian package zaptel) that you use for further information.
+
+
+For further information contact support@xorcom.com http://xorcom.com
diff --git a/xpp/utils/USB_1130.hex b/xpp/firmwares/USB_1130.hex
index 5f97b5f..5f97b5f 100644
--- a/xpp/utils/USB_1130.hex
+++ b/xpp/firmwares/USB_1130.hex
diff --git a/xpp/firmwares/USB_1150.hex b/xpp/firmwares/USB_1150.hex
new file mode 100644
index 0000000..da0c541
--- /dev/null
+++ b/xpp/firmwares/USB_1150.hex
@@ -0,0 +1,308 @@
+#
+# $Id: USB_1150.hex 2135 2006-09-05 09:16:11Z oron $
+#
+:100E2800000102030405060708090A0B0C0D0E0F42
+:080E380041001000410011000F
+:1009B80090E600E054E74410F000000090E604746C
+:1009C80080F00000007406F0000000E4F000000071
+:1009D80090E6107420F000000090E611F00000008E
+:1009E80090E61274A2F000000090E61374A0F000E4
+:1009F800000090E61474E2F000000090E61574E040
+:100A0800F000000090E6047480F00000007404F028
+:100A1800000000E4F000000090E6497482F0000055
+:100A280000F000000090E6187410F000000090E656
+:100A38001A740CF000000090E619E054FEF0000073
+:100A48000090E61BE054FEF000000090E6917480F0
+:100A5800F0000000F000000090E695F0000000F0C3
+:070A680000000043AF012272
+:1005A10078007C007D017BFF7A0E79287E007F1028
+:1005B1001204FBC205E5AA30E2030206E2E5AA3015
+:1005C100E7030206E275310075320490F400E0247D
+:1005D100FE700302067524FA700302069124F87076
+:1005E100030206BA240F60030206BE90FC007401E8
+:1005F100F090F401E090FC01F090F402E090FC0234
+:10060100F0D2B690F401E0701AA3E0701630B01386
+:1006110074C0120D44C2B67F08120D4AD2B67F08CB
+:10062100120D4A30B04690E694E0FE90E695E07CEB
+:10063100002400FFEC3ECF24FCCF34FFFE7B017A87
+:10064100F47904120AFB501C90FC0330B4117408B5
+:10065100F07FE87E03120D4C7403120D44806A741E
+:1006610004F0806590FC037402F0805D90FC0374DB
+:1006710001F0805590FC007402F0E4A3F0A3F03087
+:10068100B406A37410F0804190FC037420F080390B
+:1006910075310075321190FC007408F07A007B000E
+:1006A1007D017F50120D9E7F50120BCC7AFC7B0195
+:1006B1007D107F50120D828010D202800C753100A6
+:1006C10075320190FC0074AAF0E53190E69CF000CF
+:1006D1000000E53290E69DF000000090E695748000
+:0106E100F028
+:0106E20022F5
+:0C0D440090E601F07F147E007D007C0032
+:100D50008F368E358D348C33783374FF120583ECE7
+:060D60004D4E4F70F3221E
+:0A0AFB008E338F348B358A3689372D
+:100B0500E4F538F539C3E5399534E538953350338F
+:100B1500AB35AA36A937853982853883120521FF79
+:100B2500E4FEC2B2EF1392B7EFC313FFD2B20EBE0B
+:100B350008F0C2B220B002C3220539E53970C605F6
+:040B45003880C2D35F
+:010B49002289
+:02004100D322C8
+:02004E00D322BB
+:02005000D322B9
+:080E460090E6BAE0F53BD3226F
+:1007EB0090E740E53BF0E490E68AF090E68B04F06E
+:0207FB00D32207
+:080E4E0090E6BAE0F53AD32268
+:100E160090E740E53AF0E490E68AF090E68B04F03D
+:020E2600D322D5
+:0207FD00D32205
+:0208FB00D32206
+:0208FD00D32204
+:100CF70090E6B9E0242F600D04701990E604E0FF38
+:100D0700430780800890E604E0FF53077F00000058
+:070D1700EFF08002D322C3BC
+:010D1E0022B2
+:100DBA00C0E0C083C082D2015391EF90E65D740116
+:080DCA00F0D082D083D0E032AA
+:100DEA00C0E0C083C0825391EF90E65D7404F0D0F6
+:060DFA0082D083D0E0323C
+:100E0000C0E0C083C0825391EF90E65D7402F0D0E1
+:060E100082D083D0E03225
+:100C0400C0E0C083C08285130F85141085108285CF
+:100C14000F83A37402F0850B11850C128512828553
+:100C24001183A37407F05391EF90E65D7410F0D034
+:060C340082D083D0E03203
+:100DD200C0E0C083C082D2045391EF90E65D7408F4
+:080DE200F0D082D083D0E03292
+:1008BE00C0E0C083C08290E680E030E720850B0F59
+:1008CE00850C10851082850F83A37402F085131199
+:1008DE00851412851282851183A37407F05391EF4C
+:0D08EE0090E65D7420F0D082D083D0E0321F
+:01003200329B
+:01004A003283
+:01005200327B
+:0107FF0032C7
+:0108FF0032C6
+:010E5E003261
+:010E5F003260
+:010E6000325F
+:010E6100325E
+:010E6200325D
+:010E6300325C
+:010E6400325B
+:010E6500325A
+:010E66003259
+:010E67003258
+:010E68003257
+:010E69003256
+:010E6A003255
+:010E6B003254
+:010E6C003253
+:010E6D003252
+:010E6E003251
+:010E6F003250
+:010E7000324F
+:010E7100324E
+:010E7200324D
+:010E7300324C
+:010E7400324B
+:010E7500324A
+:010E76003249
+:010E77003248
+:010E78003247
+:010E79003246
+:010E7A003245
+:100B9000C0E0C083C08290E6D1E0900010F090E603
+:100BA000D0E4F000000090E6D17402F000000053A1
+:100BB00091BF00000090E66104F000000090E6990B
+:0C0BC00004F075BB06D082D083D0E03278
+:010E7B003244
+:100D66001201000200000040E4E45211000001021A
+:0C0D760000010001020203030404050553
+:050E40000308FF0D6630
+:10028D00E4F52CF52BF52AF529C204C200C203C2F0
+:10029D0001C202D2B675B5C4D2B61209B8120E5645
+:1002AD007E087F008E0D8F0E751508751612750B55
+:1002BD0008750C1C75130875144A75170875187890
+:1002CD00EE54C07003020398752D00752E808E2F8D
+:1002DD008F30C374BC9FFF74089ECF2402CF3400AF
+:1002ED00FEE48F288E27F526F525F524F523F52236
+:1002FD00F521AF28AE27AD26AC25AB24AA23A92224
+:10030D00A821C31205705031AE23AF24E5302FF56F
+:10031D0082E52F3EF583E0FDE52E2FF582E52D3E9E
+:10032D00F583EDF0EF2401F524E43EF523E43522C9
+:10033D00F522E43521F52180B9852D0D852E0E741C
+:10034D00002480FF740834FFFEC3E5169FF516E503
+:10035D00159EF515C3E5109FF510E50F9EF50FC31E
+:10036D00E5129FF512E5119EF511C3E50C9FF50CF5
+:10037D00E50B9EF50BC3E5149FF514E5139EF513E0
+:10038D00C3E5189FF518E5179EF517D2E843D82059
+:10039D0090E668E0440BF090E65CE0443DF0000030
+:1003AD0000E4F5A2000000D2AF90E680E020E10568
+:1003BD00D20512000390E680E054F7F0538EF8C298
+:1003CD00041205A130022190E680E054FDF0E054C6
+:1003DD00F7F0750D0D750E66D20512000390E680CF
+:1003ED00E04402F0C204C202300105120056C201FF
+:1003FD003004CE12004150C9C204120D1F20001648
+:10040D0090E682E030E704E020E1EF90E682E03014
+:0E041D00E604E020E0E4120CA012004E80A3E2
+:0B00360090E50DE030E402C322D3226D
+:1000560090E6B9E0700302011514700302019224C0
+:10006600FE700302021524FB700302010F147003D5
+:100076000201091470030200FD1470030201032437
+:10008600056003020279120050400302028590E6E1
+:10009600BBE024FE602A14603B24FD601114602A34
+:1000A60024067050E50D90E6B3F0E50E803C120094
+:1000B60036503EE51590E6B3F0E516802D02027443
+:1000C600E50F90E6B3F0E5108020E51190E6B3F079
+:1000D600E512801690E6BAE0FF120CCCAA06A90734
+:1000E600EA49600DEE90E6B3F0EF90E6B4F0020256
+:1000F60085020274020274120E16020285120E4E58
+:10010600020285120E460202851207EB02028512D2
+:1001160007FD400302028590E6B8E0247F601514CF
+:10012600601924027063A200E43325E0FFA203E411
+:10013600334F8041E490E740F0803F90E6BCE054C6
+:100146007EFF7E00E0D394807C0040047D01800227
+:100156007D00EC4EFEED4F2478F582740D3EF5835E
+:10016600E493FF3395E0FEEF24A1FFEE34E68F82A1
+:10017600F583E0540190E740F0E4A3F090E68AF0BE
+:1001860090E68B7402F00202850202741208FB40AC
+:100196000302028590E6B8E024FE6016240260039E
+:1001A60002028590E6BAE0B40105C20002028502A9
+:1001B600027490E6BAE0705590E6BCE0547EFF7E8D
+:1001C60000E0D394807C0040047D0180027D00EC39
+:1001D6004EFEED4F2478F582740D3EF583E493FFD1
+:1001E6003395E0FEEF24A1FFEE34E68F82F583E03F
+:1001F60054FEF090E6BCE05480131313541FFFE046
+:10020600540F2F90E683F0E04420F08072805F1256
+:1002160008FD506B90E6B8E024FE60192402704E8B
+:1002260090E6BAE0B40104D200805490E6BAE064E5
+:1002360002604C803990E6BCE0547EFF7E00E0D33D
+:1002460094807C0040047D0180027D00EC4EFEED32
+:100256004F2478F582740D3EF583E493FF3395E0E1
+:10026600FEEF24A1FFEE34E68F82F583800D90E643
+:10027600A08008120CF7500790E6A0E04401F09029
+:06028600E6A0E04480F058
+:01028C00224F
+:0300330002004682
+:0400460053D8EF326A
+:100CA00090E682E030E004E020E60B90E682E0305F
+:100CB000E119E030E71590E680E04401F07F147E12
+:0C0CC00000120B4A90E680E054FEF02287
+:1000030030050990E680E0440AF0800790E680E03E
+:100013004408F07FDC7E05120B4A90E65D74FFF026
+:0F00230090E65FF05391EF90E680E054F7F02203
+:080E5600E4F51ED2E9D2AF223F
+:100BCC00AD0790E678E020E6F9C2E990E678E044DB
+:100BDC0080F0ED25E090E679F090E678E030E0F9F1
+:100BEC0090E678E04440F090E678E020E6F990E674
+:080BFC0078E030E1D6D2E922D5
+:100C6E00AC0790E678E020E6F9E51E702390E67872
+:100C7E00E04480F0EC25E090E679F08D19AF03A901
+:100C8E0007751A018A1B891CE4F51D751E01D322F6
+:020C9E00C3226F
+:100C3A00AC0790E678E020E6F9E51E702590E678A4
+:100C4A00E04480F0EC25E0440190E679F08D19AF9C
+:100C5A0003A907751A018A1B891CE4F51D751E0371
+:040C6A00D322C322AC
+:03004B000206E3C7
+:1006E300C0E0C083C082C085C084C086758600C058
+:1006F300D075D000C000C001C002C003C006C0074F
+:1007030090E678E030E206751E060207CD90E678A3
+:10071300E020E10CE51E64026006751E070207CDAA
+:10072300E51E24FE605F14603624FE70030207BEDC
+:1007330024FC70030207CA240860030207CDAB1A26
+:10074300AA1BA91CAF1D051D8F82758300120521ED
+:1007530090E679F0E51D65197070751E05806B9044
+:10076300E679E0AB1AAA1BA91CAE1D8E8275830025
+:1007730012054E751E02E5196401704E90E678E08D
+:100783004420F08045E51924FEB51D0790E678E086
+:100793004420F0E51914B51D0A90E678E04440F0D2
+:1007A300751E0090E679E0AB1AAA1BA91CAE1D8E3C
+:1007B3008275830012054E051D800F90E678E04494
+:1007C30040F0751E008003751E005391DFD007D0E3
+:1007D30006D003D002D001D000D0D0D086D084D0B0
+:0807E30085D082D083D0E03202
+:020CCC00A90776
+:100CCE00AE17AF188F828E83A3E064037017AD0149
+:100CDE0019ED7001228F828E83E07C002FFDEC3E99
+:080CEE00FEAF0580DFE4FEFF0C
+:010CF60022DB
+:100D8200120C3AE51E24FA600E146006240770F372
+:0C0D9200D322E4F51ED322E4F51ED32288
+:100D9E00120C6EE51E24FA600E146006240770F322
+:0C0DAE00D322E4F51ED322E4F51ED3226C
+:100D1F0090E682E044C0F090E681F0438701000046
+:040D2F00000000229E
+:100B4A008E318F3290E600E054187012E53224019B
+:100B5A00FFE43531C313F531EF13F532801590E612
+:100B6A0000E05418FFBF100BE53225E0F532E531FD
+:100B7A0033F531E5321532AE31700215314E60056A
+:060B8A00120D3380EE2283
+:100D33007400F58690FDA57C05A3E582458370F9D3
+:010D4300228D
+:100800001201000200000040E4E451110000010286
+:1008100000010A06000200000040010009022E004B
+:1008200001010080320904000004FF0000000705F8
+:10083000020200020007050402000200070586020A
+:100840000002000705880200020009022E000101D3
+:100850000080320904000004FF00000007050202C6
+:100860004000000705040240000007058602400022
+:10087000000705880240000004030904180358001B
+:100880006F00720063006F006D0020004C00740068
+:1008900064002E0028035800500044002800420045
+:1008A000610073006500640020006F006E0020008E
+:0E08B000410058005500500050002900000083
+:03004300020900AF
+:030053000209009F
+:10090000020DBA00020E0000020DEA00020DD20034
+:10091000020C04000208BE000200320002004A007D
+:10092000020052000207FF000208FF00020E5E00F4
+:10093000020E5F00020E6000020E6100020E6200F5
+:10094000020E630002004A00020E6400020E6500FF
+:10095000020E6600020E6700020E6800020E6900B9
+:10096000020E6A0002004A0002004A0002004A0029
+:10097000020E6B00020E6C00020E6D00020E6E0085
+:10098000020E6F00020E7000020E7100020E720065
+:10099000020E7300020E7400020E7500020E760045
+:1009A000020E7700020E7800020E7900020E7A0025
+:0809B000020B9000020E7B0017
+:03000000020A6F82
+:0C0A6F00787FE4F6D8FD75813B020AB6E2
+:10042B00E709F608DFFA8046E709F208DFFA803EB3
+:10043B0088828C83E709F0A3DFFA8032E309F608A0
+:10044B00DFFA8078E309F208DFFA807088828C8308
+:10045B00E309F0A3DFFA806489828A83E0A3F608BC
+:10046B00DFFA805889828A83E0A3F208DFFA804C96
+:10047B0080D280FA80C680D4806980F2803380106D
+:10048B0080A680EA809A80A880DA80E280CA8033D6
+:10049B0089828A83ECFAE493A3C8C582C8CCC5834E
+:1004AB00CCF0A3C8C582C8CCC583CCDFE9DEE7801E
+:1004BB000D89828A83E493A3F608DFF9ECFAA9F09D
+:1004CB00EDFB2289828A83ECFAE0A3C8C582C8CCF3
+:1004DB00C583CCF0A3C8C582C8CCC583CCDFEADE0C
+:1004EB00E880DB89828A83E493A3F208DFF980CC6E
+:1004FB0088F0EF60010E4E60C388F0ED2402B40467
+:10050B000050B9F582EB2402B4040050AF2323450D
+:06051B00822390047B73B3
+:10052100BB010CE58229F582E5833AF583E022508F
+:1005310006E92582F8E622BBFE06E92582F8E222D9
+:0D054100E58229F582E5833AF583E49322F3
+:10054E00F8BB010DE58229F582E5833AF583E8F0E3
+:10055E00225006E92582C8F622BBFE05E92582C88F
+:02056E00F22277
+:10057000EB9FF5F0EA9E42F0E99D42F0E89C45F0E1
+:010580002258
+:100581007401FF3395E0FEFDFC080808E6CF2FF665
+:1005910018E6CE3EF618E6CD3DF618E6CC3CF6223E
+:100A7B0002028DE493A3F8E493A34003F68001F202
+:100A8B0008DFF48029E493A3F85407240CC8C3337C
+:100A9B00C4540F4420C8834004F456800146F6DF4B
+:100AAB00E4800B0102040810204080900E38E47E95
+:100ABB00019360BCA3FF543F30E509541FFEE49340
+:100ACB00A360010ECF54C025E060A840B8E493A307
+:100ADB00FAE493A3F8E493A3C8C582C8CAC583CA32
+:100AEB00F0A3C8C582C8CAC583CADFE9DEE780BEEA
+:010E450000AC
+:00000001FF
diff --git a/xpp/init_card_3_23 b/xpp/init_card_3_23
new file mode 100755
index 0000000..07b059a
--- /dev/null
+++ b/xpp/init_card_3_23
@@ -0,0 +1,165 @@
+#! /bin/sh
+#
+# Written by Oron Peled <oron@actcom.co.il>
+# Copyright (C) 2006, Xorcom
+#
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# See the file LICENSE in the top level of this tarball.
+#
+
+#
+# $Id$
+#
+# Data format:
+# - A comment start with ';' or '#' until the end of line
+# - Blank lines are ignored
+# - Fields are whitespace separated (spaces or tabs)
+#
+# The fields are (in command line order):
+# 1. SLIC select in decimal (range 0-7).
+# 31 is a special value which means ALL SLICS (only some registers
+# accept settings for ALL SLICS).
+# 2. Command word:
+# - RD Read Direct register.
+# - RI Read Indirect register.
+# - WD Write Direct register.
+# - WI Write Indirect register.
+# 3. Register number in hexadecimal.
+# 4. Low data byte in hexadecimal. (for WD and WI commands).
+# 5. High data byte in hexadecimal. (for WI command only).
+#
+#
+
+# ----------------------------------==== 8-channel FXS unit initialization ===-----------------------------------------
+
+set -e
+
+me=`basename $0`
+INIT_DIR=`dirname $0`
+export XPP_BASE=/proc/xpp
+LOGGER="logger -s -t $me"
+
+exec 2> /tmp/results
+exec 1> "$XPP_BASE/$XPD_BUS/$XPD_NAME/slics"
+
+$LOGGER -p kern.info "$XPD_BUS/$XPD_NAME: Calibrating '$0'"
+
+"$INIT_DIR/calibrate_slics"
+
+$LOGGER -p kern.info "$XPD_BUS/$XPD_NAME: Continue '$0'"
+
+sed -e 's/[;#].*$//' -e '/^[ ]*$/d' <<END_OF_FILE
+
+# Change SLICs states to "Open state"s (Off,all transfers tristated to avoid data collision), Voltage sense
+31 WD 40 00
+
+# Flush out energy accumulators
+31 WI 58 00 00
+31 WI 59 00 00
+31 WI 5A 00 00
+31 WI 5B 00 00
+31 WI 5C 00 00
+31 WI 5D 00 00
+31 WI 5E 00 00
+31 WI 5F 00 00
+31 WI 61 00 00
+31 WI 58 00 00
+31 WI C1 00 00
+31 WI C2 00 00
+31 WI C3 00 00
+31 WI C4 00 00
+31 WI C5 00 00
+31 WI C6 00 00
+31 WI C7 00 00
+31 WI C8 00 00
+31 WI C9 00 00
+31 WI CA 00 00
+31 WI CB 00 00
+31 WI CC 00 00
+31 WI CD 00 00
+31 WI CE 00 00
+31 WI CF 00 00
+31 WI D0 00 00
+31 WI D1 00 00
+31 WI D2 00 00
+31 WI D3 00 00
+
+# Setting of SLICs offsets
+# New card initialization
+0 WD 02 00
+0 WD 04 00
+1 WD 02 08
+1 WD 04 08
+2 WD 02 10
+2 WD 04 10
+3 WD 02 18
+3 WD 04 18
+4 WD 02 20
+4 WD 04 20
+5 WD 02 28
+5 WD 04 28
+6 WD 02 30
+6 WD 04 30
+7 WD 02 38
+7 WD 04 38
+31 WD 03 00
+31 WD 05 00
+
+# Audio path. (also initialize 0A and 0B here if necessary)
+31 WD 08 00
+31 WD 09 00
+
+31 WD 17 00
+
+# Automatic/Manual Control: defaults - Cancel Power Alarm
+31 WD 43 1E
+
+# Loop Closure Debounce Interval
+31 WD 45 0A
+
+# Ring Detect Debounce Interval
+31 WD 46 0B
+
+# Battery Feed Control: Battery low (DCSW low)
+31 WD 42 00
+
+# Loop Current Limit
+31 WD 47 00
+
+31 WD 6C 01
+
+31 WI 23 00 80
+31 WI 24 20 03
+31 WI 25 8C 08
+31 WI 26 00 01
+31 WI 27 10 00
+
+
+# ------------------------------------- Initialization of direct registers --------------------------------------------
+
+# Mode(8-bit,u-Law,1 PCLK ) setting, Loopbacks and Interrupts clear
+
+31 WD 01 29
+#31 WD 0E 00
+
+#31 WD 15 00
+#31 WD 16 03
+
+# Clear pending interrupts
+31 WD 12 FF
+31 WD 13 FF
+31 WD 14 FF
+
+#31 WD 4A 34
+#31 WD 4B 10
+
+END_OF_FILE
+
+$LOGGER -p kern.info "$XPD_BUS/$XPD_NAME: Ending '$0'"
+exit 0
diff --git a/xpp/init_card_4_23 b/xpp/init_card_4_23
new file mode 100755
index 0000000..a0e17bd
--- /dev/null
+++ b/xpp/init_card_4_23
@@ -0,0 +1,143 @@
+#! /bin/sh
+#
+# Written by Oron Peled <oron@actcom.co.il>
+# Copyright (C) 2006, Xorcom
+#
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# See the file LICENSE in the top level of this tarball.
+#
+
+#
+# $Id$
+#
+# Data format:
+# - A comment start with ';' or '#' until the end of line
+# - Blank lines are ignored
+# - Fields are whitespace separated (spaces or tabs)
+#
+# The fields are (in command line order):
+# 1. DAA select in decimal (range 0-7).
+# 31 is a special value which means ALL DAAs (only some registers
+# accept settings for ALL DAAs).
+# 2. Command word:
+# - RD Read Direct register.
+# - WD Write Direct register.
+# 3. Register number in hexadecimal.
+# 4. Data byte in hexadecimal. (for WD command).
+#
+
+# ----------------------------------==== 8-channel FXO unit initialization ===-----------------------------------------
+
+set -e
+
+opermode='FCC'
+
+me=`basename $0`
+INIT_DIR=`dirname $0`
+XPP_BASE=/proc/xpp
+export XPP_BASE
+SLICS="$XPP_BASE/$XPD_BUS/$XPD_NAME/slics"
+LOGGER="logger -s -t $me"
+
+# set -x
+exec 2> /tmp/results #FIXME: temporary debugging file
+# redirect script output to the "slics" (registers command) file:
+exec 1> $SLICS
+
+$LOGGER -p kern.info "$XPD_BUS/$XPD_NAME: Initializing '$0'"
+
+set_daa_country_params() {
+ # based on fxo_modes from wctdm.c . TODO: more decent calculation?
+ reg16=00; reg26=00; reg30=00; reg31=A3; ring_osc=; ring_x=;
+ mode="$1"
+ # TODO: a saner fall-back in case of an unknown mode
+ if [ "$mode" = '' ]; then mode='FCC'; fi
+ if [ -r $INIT_DIR/init_fxo_modes ]; then
+ . $INIT_DIR/init_fxo_modes
+ fi
+ # Our register numbers are HEXADECIMAL!
+ cat <<EOF >$SLICS
+31 WD 10 $reg16
+31 WD 1A $reg26
+31 WD 1E $reg30
+31 WD 1F $reg31
+EOF
+ # for the FXS:
+ #if [ "$ring_osc" != '' ]; then
+ # /bin/echo "31 WI __ $ring_osc"
+ #fi
+ #if [ "$ring_x" != '' ]; then
+ # /bin/echo "31 WI __ $ring_x"
+ #fi
+}
+
+# Remove empty lines and commets. Not strictly necessary
+# but works around some limitations of the proc interface:
+sed -e 's/[;#].*$//' -e '/^[ ]*$/d' <<END_OF_FILE
+
+
+31 WD 21 28
+31 WD 18 99
+31 WD 06 00
+
+# ----------- DAA PCM start offset ----------
+
+0 WD 22 00
+0 WD 23 00
+0 WD 24 00
+0 WD 25 00
+
+1 WD 22 08
+1 WD 23 00
+1 WD 24 08
+1 WD 25 00
+
+2 WD 22 10
+2 WD 23 00
+2 WD 24 10
+2 WD 25 00
+
+3 WD 22 18
+3 WD 23 00
+3 WD 24 18
+3 WD 25 00
+
+4 WD 22 20
+4 WD 23 00
+4 WD 24 20
+4 WD 25 00
+
+5 WD 22 28
+5 WD 23 00
+5 WD 24 28
+5 WD 25 00
+
+6 WD 22 30
+6 WD 23 00
+6 WD 24 30
+6 WD 25 00
+
+7 WD 22 38
+7 WD 23 00
+7 WD 24 38
+7 WD 25 00
+
+# ----------- DAA ONHOOK --------------------
+31 WD 05 00
+
+# Set tip to ring voltage to 3.5 volts while off-hook
+# instead of default of 3.1
+31 WD 1A C0
+
+END_OF_FILE
+
+set_daa_country_params "$opermode"
+
+$LOGGER -p kern.info "$XPD_BUS/$XPD_NAME: Ending '$0'"
+exit 0
diff --git a/xpp/init_data_3_19.cmd b/xpp/init_data_3_19.cmd
deleted file mode 100644
index 3f57660..0000000
--- a/xpp/init_data_3_19.cmd
+++ /dev/null
@@ -1,170 +0,0 @@
-#
-# Written by Oron Peled <oron@actcom.co.il>
-# Copyright (C) 2006, Xorcom
-#
-# All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# See the file LICENSE in the top level of this tarball.
-#
-
-;
-; $Id$
-;
-; SLICS CMD Reg High Low
-
-; -------------------------------------- 8-channel FXS unit initialization
-; INTERNAL PS
-; Change SLICs states to "Open state"s (Off,all transfers tristated to avoid
-; data collision), Voltage sense
-
-FF 00 00 00 WD 40 00
-FF 00 00 00 WD 6C 01
-
-; ------------------------------------- Initialization of indirect registers
-
-FF 00 00 00 WI 00 55 C2
-FF 00 00 00 WI 01 51 E6
-FF 00 00 00 WI 02 4B 85
-FF 00 00 00 WI 03 49 37
-
-FF 00 00 00 WI 04 33 33
-FF 00 00 00 WI 05 02 02
-FF 00 00 00 WI 06 02 02
-FF 00 00 00 WI 07 01 98
-
-FF 00 00 00 WI 08 01 98
-FF 00 00 00 WI 09 06 11
-FF 00 00 00 WI 0A 02 02
-FF 00 00 00 WI 0B 00 E5
-
-FF 00 00 00 WI 0C 0A 1C
-FF 00 00 00 WI 0D 7B 30
-FF 00 00 00 WI 0E 00 63
-FF 00 00 00 WI 0F 00 00
-
-FF 00 00 00 WI 10 78 70
-FF 00 00 00 WI 11 00 7D
-FF 00 00 00 WI 12 00 00
-FF 00 00 00 WI 13 00 00
-
-FF 00 00 00 WI 14 7E F0
-FF 00 00 00 WI 15 01 60
-FF 00 00 00 WI 16 00 00
-FF 00 00 00 WI 17 20 00
-
-FF 00 00 00 WI 18 20 00
-FF 00 00 00 WI 19 00 00
-FF 00 00 00 WI 1A 40 00
-FF 00 00 00 WI 1B 40 00
-
-FF 00 00 00 WI 1C 18 00
-FF 00 00 00 WI 1D 40 00
-FF 00 00 00 WI 1E 10 00
-FF 00 00 00 WI 1F 00 80
-
-FF 00 00 00 WI 20 0F F4
-FF 00 00 00 WI 21 6E 7E
-FF 00 00 00 WI 22 0F F4
-FF 00 00 00 WI 23 88 00
-
-FF 00 00 00 WI 24 03 20
-FF 00 00 00 WI 25 00 12
-FF 00 00 00 WI 26 00 12
-FF 00 00 00 WI 27 00 12
-
-FF 00 00 00 WI 28 0C 00
-FF 00 00 00 WI 29 0C 00
-FF 00 00 00 WI 2B 08 00
-
-FF 00 00 00 WI 63 00 DA
-FF 00 00 00 WI 64 6B 60
-FF 00 00 00 WI 65 00 74
-FF 00 00 00 WI 66 79 C0
-
-FF 00 00 00 WI 67 11 20
-FF 00 00 00 WI 68 3B E0
-
-; ------------------------------------- Initialization of direct registers
-
-; Mode(8-bit,u-Law,1 PCLK ) setting, Loopbacks and Interrupts clear
-
-FF 00 00 00 WD 01 29
-FF 00 00 00 WD 08 00
-FF 00 00 00 WD 09 00
-FF 00 00 00 WD 0E 00
-
-FF 00 00 00 WD 15 00
-FF 00 00 00 WD 16 03
-FF 00 00 00 WD 17 00
-FF 00 00 00 WD 12 FF
-FF 00 00 00 WD 13 FF
-FF 00 00 00 WD 14 FF
-
-; Automatic/Manual Control: defaults - Cancel Power Alarm
-FF 00 00 00 WD 43 1E
-
-FF 00 00 00 WD 4A 31
-FF 00 00 00 WD 4B 10
-
-; Battery Feed Control: Battery low (DCSW low)
-FF 00 00 00 WD 42 00
-
-; Slic Calibration
-FF 00 00 00 WD 61 1F
-FF 00 00 00 WD 60 5F
-
-; Loop Closure Debounce Interval
-FF 00 00 00 WD 45 0A
-
-; Ring Detect Debounce Interval
-FF 00 00 00 WD 46 0B
-
-; Loop Current Limit
-FF 00 00 00 WD 47 07
-
-; Setting of SLICs offsets
-
-01 00 00 00 WD 02 01
-01 00 00 00 WD 03 00
-01 00 00 00 WD 04 01
-01 00 00 00 WD 05 00
-
-02 00 00 00 WD 02 09
-02 00 00 00 WD 03 00
-02 00 00 00 WD 04 09
-02 00 00 00 WD 05 00
-
-04 00 00 00 WD 02 11
-04 00 00 00 WD 03 00
-04 00 00 00 WD 04 11
-04 00 00 00 WD 05 00
-
-08 00 00 00 WD 02 19
-08 00 00 00 WD 03 00
-08 00 00 00 WD 04 19
-08 00 00 00 WD 05 00
-
-10 00 00 00 WD 02 21
-10 00 00 00 WD 03 00
-10 00 00 00 WD 04 21
-10 00 00 00 WD 05 00
-
-20 00 00 00 WD 02 29
-20 00 00 00 WD 03 00
-20 00 00 00 WD 04 29
-20 00 00 00 WD 05 00
-
-40 00 00 00 WD 02 31
-40 00 00 00 WD 03 00
-40 00 00 00 WD 04 31
-40 00 00 00 WD 05 00
-
-80 00 00 00 WD 02 39
-80 00 00 00 WD 03 00
-80 00 00 00 WD 04 39
-80 00 00 00 WD 05 00
diff --git a/xpp/init_data_3_20.cmd b/xpp/init_data_3_20.cmd
deleted file mode 100644
index 01d801d..0000000
--- a/xpp/init_data_3_20.cmd
+++ /dev/null
@@ -1,173 +0,0 @@
-#
-# Written by Oron Peled <oron@actcom.co.il>
-# Copyright (C) 2006, Xorcom
-#
-# All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# See the file LICENSE in the top level of this tarball.
-#
-
-;
-; $Id$
-;
-; SLICS CMD Reg High Low
-
-; -------------------------------------- 8-channel FXS unit initialization
-; INTERNAL PS
-; Change SLICs states to "Open state"s (Off,all transfers tristated to avoid
-; data collision), Voltage sense
-
-FF 00 00 00 WD 40 00
-FF 00 00 00 WD 6C 01
-
-; ------------------------------------- Initialization of indirect registers
-
-FF 00 00 00 WI 00 55 C2
-FF 00 00 00 WI 01 51 E6
-FF 00 00 00 WI 02 4B 85
-FF 00 00 00 WI 03 49 37
-
-FF 00 00 00 WI 04 33 33
-FF 00 00 00 WI 05 02 02
-FF 00 00 00 WI 06 02 02
-FF 00 00 00 WI 07 01 98
-
-FF 00 00 00 WI 08 01 98
-FF 00 00 00 WI 09 06 11
-FF 00 00 00 WI 0A 02 02
-FF 00 00 00 WI 0B 00 E5
-
-FF 00 00 00 WI 0C 0A 1C
-FF 00 00 00 WI 0D 7B 30
-FF 00 00 00 WI 0E 00 63
-FF 00 00 00 WI 0F 00 00
-
-FF 00 00 00 WI 10 78 70
-FF 00 00 00 WI 11 00 7D
-FF 00 00 00 WI 12 00 00
-FF 00 00 00 WI 13 00 00
-
-FF 00 00 00 WI 14 7E F0
-FF 00 00 00 WI 15 01 60
-FF 00 00 00 WI 16 00 00
-FF 00 00 00 WI 17 20 00
-
-FF 00 00 00 WI 18 20 00
-FF 00 00 00 WI 19 00 00
-FF 00 00 00 WI 1A 40 00
-FF 00 00 00 WI 1B 40 00
-
-FF 00 00 00 WI 1C 18 00
-FF 00 00 00 WI 1D 40 00
-FF 00 00 00 WI 1E 10 00
-FF 00 00 00 WI 1F 00 80
-
-FF 00 00 00 WI 20 0F F4
-FF 00 00 00 WI 21 6E 7E
-FF 00 00 00 WI 22 0F F4
-FF 00 00 00 WI 23 88 00
-
-FF 00 00 00 WI 24 03 20
-FF 00 00 00 WI 25 00 12
-FF 00 00 00 WI 26 00 12
-FF 00 00 00 WI 27 00 12
-
-FF 00 00 00 WI 28 0C 00
-FF 00 00 00 WI 29 0C 00
-FF 00 00 00 WI 2B 08 00
-
-FF 00 00 00 WI 63 00 DA
-FF 00 00 00 WI 64 6B 60
-FF 00 00 00 WI 65 00 74
-FF 00 00 00 WI 66 79 C0
-
-FF 00 00 00 WI 67 11 20
-FF 00 00 00 WI 68 3B E0
-
-; ------------------------------------- Initialization of direct registers
-
-; Mode(8-bit,u-Law,1 PCLK ) setting, Loopbacks and Interrupts clear
-
-FF 00 00 00 WD 01 29
-FF 00 00 00 WD 08 00
-FF 00 00 00 WD 09 00
-FF 00 00 00 WD 0E 00
-
-FF 00 00 00 WD 15 00
-FF 00 00 00 WD 16 03
-FF 00 00 00 WD 17 00
-FF 00 00 00 WD 12 FF
-FF 00 00 00 WD 13 FF
-FF 00 00 00 WD 14 FF
-
-; Automatic/Manual Control:
-; Manual BATL/BATH select. NOTE: bit 08 switches VBAT to Low AND to High!
-FF 00 00 00 WD 43 16
-
-FF 00 00 00 WD 4A 31
-FF 00 00 00 WD 4B 10
-
-; Battery Feed Control: Battery low (DCSW low)
-FF 00 00 00 WD 42 00
-
-; Slic Calibration
-FF 00 00 00 WD 61 1F
-FF 00 00 00 WD 60 5F
-
-; Loop Closure Debounce Interval
-FF 00 00 00 WD 45 0A
-
-; Ring Detect Debounce Interval
-FF 00 00 00 WD 46 0B
-
-; Loop Current Limit
-; 23 milliampere for line current
-FF 00 00 00 WD 47 01
-
-; Setting of SLICs offsets
-
-# New card initialization
-01 00 00 00 WD 02 00
-01 00 00 00 WD 03 00
-01 00 00 00 WD 04 00
-01 00 00 00 WD 05 00
-
-02 00 00 00 WD 02 08
-02 00 00 00 WD 03 00
-02 00 00 00 WD 04 08
-02 00 00 00 WD 05 00
-
-04 00 00 00 WD 02 10
-04 00 00 00 WD 03 00
-04 00 00 00 WD 04 10
-04 00 00 00 WD 05 00
-
-08 00 00 00 WD 02 18
-08 00 00 00 WD 03 00
-08 00 00 00 WD 04 18
-08 00 00 00 WD 05 00
-
-10 00 00 00 WD 02 20
-10 00 00 00 WD 03 00
-10 00 00 00 WD 04 20
-10 00 00 00 WD 05 00
-
-20 00 00 00 WD 02 28
-20 00 00 00 WD 03 00
-20 00 00 00 WD 04 28
-20 00 00 00 WD 05 00
-
-40 00 00 00 WD 02 30
-40 00 00 00 WD 03 00
-40 00 00 00 WD 04 30
-40 00 00 00 WD 05 00
-
-80 00 00 00 WD 02 38
-80 00 00 00 WD 03 00
-80 00 00 00 WD 04 38
-80 00 00 00 WD 05 00
diff --git a/xpp/init_data_4_19.cmd b/xpp/init_data_4_19.cmd
deleted file mode 100644
index ba439a3..0000000
--- a/xpp/init_data_4_19.cmd
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# Written by Oron Peled <oron@actcom.co.il>
-# Copyright (C) 2006, Xorcom
-#
-# All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# See the file LICENSE in the top level of this tarball.
-#
-
-;
-; $Id$
-;
-; DAA's CMD Reg High Low
-
-; -------------------------------------- 8-channel FXO unit initialization
-
-FF FF 00 00 WD 21 28
-FF FF 00 00 WD 18 99
-FF FF 00 00 WD 06 00
-
-; ----------- DAA PCM start offset ----------
-
-01 00 00 00 WD 22 01
-01 00 00 00 WD 23 00
-01 00 00 00 WD 24 01
-01 00 00 00 WD 25 00
-
-02 00 00 00 WD 22 09
-02 00 00 00 WD 23 00
-02 00 00 00 WD 24 09
-02 00 00 00 WD 25 00
-
-04 00 00 00 WD 22 11
-04 00 00 00 WD 23 00
-04 00 00 00 WD 24 11
-04 00 00 00 WD 25 00
-
-08 00 00 00 WD 22 19
-08 00 00 00 WD 23 00
-08 00 00 00 WD 24 19
-08 00 00 00 WD 25 00
-
-10 00 00 00 WD 22 21
-10 00 00 00 WD 23 00
-10 00 00 00 WD 24 21
-10 00 00 00 WD 25 00
-
-20 00 00 00 WD 22 29
-20 00 00 00 WD 23 00
-20 00 00 00 WD 24 29
-20 00 00 00 WD 25 00
-
-40 00 00 00 WD 22 31
-40 00 00 00 WD 23 00
-40 00 00 00 WD 24 31
-40 00 00 00 WD 25 00
-
-80 00 00 00 WD 22 39
-80 00 00 00 WD 23 00
-80 00 00 00 WD 24 39
-80 00 00 00 WD 25 00
-
-; ----------- DAA ONHOOK --------------------
-FF FF 00 00 WD 05 00
diff --git a/xpp/init_data_4_20.cmd b/xpp/init_data_4_20.cmd
deleted file mode 100644
index 3f809c2..0000000
--- a/xpp/init_data_4_20.cmd
+++ /dev/null
@@ -1,64 +0,0 @@
-#
-# Written by Oron Peled <oron@actcom.co.il>
-# Copyright (C) 2006, Xorcom
-#
-# All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# See the file LICENSE in the top level of this tarball.
-#
-
-;
-; $Id$
-;
-; DAA's CMD Reg High Low
-
-; Start with a software reset:
-FF FF 00 00 WD 01 80
-
-; -------------------------------------- 8-channel FXO unit initialization
-
-FF FF 00 00 WD 21 28
-; 99 also sets ring validation
-;FF FF 00 00 WD 18 99
-FF FF 00 00 WD 06 00
-
-; ----------- DAA PCM start offset ----------
-
-FF FF 00 00 WD 23 00
-FF FF 00 00 WD 25 00
-
-01 00 00 00 WD 22 00
-01 00 00 00 WD 24 00
-
-02 00 00 00 WD 22 08
-02 00 00 00 WD 24 08
-
-04 00 00 00 WD 22 10
-04 00 00 00 WD 24 10
-
-08 00 00 00 WD 22 18
-08 00 00 00 WD 24 18
-
-10 00 00 00 WD 22 20
-10 00 00 00 WD 24 20
-
-20 00 00 00 WD 22 28
-20 00 00 00 WD 24 28
-
-40 00 00 00 WD 22 30
-40 00 00 00 WD 24 30
-
-80 00 00 00 WD 22 38
-80 00 00 00 WD 24 38
-
-; ----------- DAA ONHOOK --------------------
-FF FF 00 00 WD 05 08
-
-; Set tip to ring voltage to 3.5 volts while off-hook
-; instead of default of 3.1
-FF FF 00 00 WD 1A C0
diff --git a/xpp/initialize_registers b/xpp/initialize_registers
deleted file mode 100755
index 6c07e94..0000000
--- a/xpp/initialize_registers
+++ /dev/null
@@ -1,77 +0,0 @@
-#! /bin/sh
-#
-# $Id$
-#
-# This script is run from the xpp kernel module upon detection
-# of a new XPD.
-#
-# Expects the following environment variables to be set:
-# XPD_BUS - bus name
-# XPD_NAME - xpd name
-# XPD_TYPE - xpd type number (from protocol reply):
-# 3 - FXS
-# 4 - FXO
-# XPD_REVISION - xpd revision number
-
-set -e
-
-LOGGER="logger -i -t `basename $0`"
-opermode='FCC'
-INIT_DIR=`dirname $0`
-XPP_BASE=/proc/xpp
-
-if [ -r /etc/default/zaptel ]
-then . /etc/default/zaptel
-fi
-
-export XPP_BASE
-
-SLICS="$XPP_BASE/$XPD_BUS/$XPD_NAME/slics"
-FILE="$INIT_DIR/init_data_${XPD_TYPE}_${XPD_REVISION}.cmd"
-set_daa_country_params() {
- # based on fxo_modes from wctdm.c . TODO: more decent calculation?
- reg16=00; reg26=00; reg30=00; reg31=A3; ring_osc=; ring_x=;
- mode="$1"
- # TODO: a saner fall-back in case of an unknown mode
- if [ "$mode" = '' ]; then mode='FCC'; fi
- if [ -r $INIT_DIR/init_fxo_modes ]; then
- . $INIT_DIR/init_fxo_modes
- fi
- cat <<EOF >$SLICS
-FF FF 00 00 WD 10 $reg16
-FF FF 00 00 WD 1A $reg26
-FF FF 00 00 WD 1E $reg30
-FF FF 00 00 WD 1F $reg31
-EOF
- # for the FXS:
- #if [ "$ring_osc" != '' ]; then
- # /bin/echo "31 WI __ $ring_osc" >$SLICS
- #fi
- #if [ "$ring_x" != '' ]; then
- # /bin/echo "31 WI __ $ring_x" >$SLICS
- #fi
-}
-
-if [ ! -f "$SLICS" ]; then
- $LOGGER "missing register file '$SLICS'"
- exit 1
-fi
-
-if [ ! -f "$FILE" ]; then
- $LOGGER "missing register initialization file '$FILE'"
- exit 1
-fi
-
-case "$XPD_TYPE" in
-3|4)
- if [ "$XPD_TYPE" = 3 ]; then "$INIT_DIR/calibrate_slics"; fi
- cat "$FILE" > "$SLICS"
- if [ "$XPD_TYPE" = 4 ]; then set_daa_country_params "$opermode"; fi
- ;;
-*)
- $LOGGER "Unknown type '$XPD_TYPE'"
- exit 2
-esac
-$LOGGER "Wrote '$FILE' into '$SLICS'"
-
-exit 0
diff --git a/xpp/slic.c b/xpp/slic.c
deleted file mode 100644
index b019766..0000000
--- a/xpp/slic.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Written by Oron Peled <oron@actcom.co.il>
- * Copyright (C) 2004-2006, Xorcom
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "xproto.h"
-#include "slic.h"
-
-static const char rcsid[] = "$Id$";
-
-#ifdef __KERNEL__
-#include <linux/module.h>
-
-extern int print_dbg;
-#include "zap_debug.h"
-
-DEF_PARM(charp,initialize_registers, "/usr/share/zaptel/initialize_registers", "The script to initialize detected cards slics");
-
-#else
-#include <stdio.h>
-#endif
-
-int slic_cmd_direct_write(slic_cmd_t *sc, xpp_line_t lines, byte reg, byte data)
-{
- struct slic_reg_d *p = (struct slic_reg_d *)&sc->content;
-
- sc->lines = lines;
- sc->bytes = sizeof(struct slic_reg_d);
- SLIC_REG_INIT(p, 0, reg, data);
- return sizeof(xpp_line_t) + 1 + sc->bytes;
-}
-
-int slic_cmd_direct_read(slic_cmd_t *sc, xpp_line_t lines, byte reg)
-{
- struct slic_reg_d *p = (struct slic_reg_d *)&sc->content;
-
- sc->lines = lines;
- sc->bytes = sizeof(struct slic_reg_d);
- SLIC_REG_INIT(p, 1, reg, 0);
- return sizeof(xpp_line_t) + 1 + sc->bytes;
-}
-
-int slic_cmd_indirect_write(slic_cmd_t *sc, xpp_line_t lines, byte reg, byte data_low, byte data_high)
-{
- struct slic_reg_iw *p = (struct slic_reg_iw *)&sc->content;
-
- sc->lines = lines;
- sc->bytes = sizeof(struct slic_reg_iw);
- SLIC_REG_INIT(&p->iw_data_low, 0, 0x1C, data_low);
- SLIC_REG_INIT(&p->iw_data_high, 0, 0x1D, data_high);
- SLIC_REG_INIT(&p->iw_reg, 0, 0x1E, reg);
- return sizeof(xpp_line_t) + 1 + sc->bytes;
-}
-
-int slic_cmd_indirect_read(slic_cmd_t *sc, xpp_line_t lines, byte reg)
-{
- struct slic_reg_ir *p = (struct slic_reg_ir *)&sc->content;
-
- sc->lines = lines;
- sc->bytes = sizeof(struct slic_reg_ir);
- SLIC_REG_INIT(&p->ir_reg, 0, 0x1E, reg);
- return sizeof(xpp_line_t) + 1 + sc->bytes;
-}
-
-void dump_slic_cmd(const char msg[], slic_cmd_t *sc)
-{
- int i;
- struct slic_reg_d *sr;
- int last_data_low = -1;
- int last_data_high = -1;
-
- sr = (struct slic_reg_d *)&sc->content;
- if(sc->bytes > sizeof(sc->content)) {
- NOTICE("%s: Bug: sc->bytes = %d\n", __FUNCTION__, sc->bytes);
- return;
- }
- if(sc->bytes % 2) {
- NOTICE("%s: Bug: ODD sc->bytes = %d\n", __FUNCTION__, sc->bytes);
- return;
- }
- for(i = 0; i < sc->bytes/2; i++, sr++) {
- if(sr->reg_num == 0x1C) {
- last_data_low = sr->reg_data;
- continue;
- }
- if(sr->reg_num == 0x1D) {
- last_data_high = sr->reg_data;
- continue;
- }
- if(sr->reg_num == 0x1E) {
- if(last_data_low == -1 && last_data_high == -1) // Indirect Read
- DBG("%s: LINES=0x%08X bytes=%d INDIRECT READ: register=0x%02X\n", msg, sc->lines, sc->bytes, sr->reg_data);
- else if(last_data_low == -1 || last_data_high == -1) {
- NOTICE("%s: BUG: PARTIAL INDIRECT: register=%d last_data_low=0x%X last_data_high=0x%X\n",
- msg, sr->reg_data, last_data_low, last_data_high);
- } else
- DBG("%s: LINES=0x%08X bytes=%d INDIRECT WRITE: register=%d data_low=0x%02x data_high=0x%02X\n",
- msg, sc->lines, sc->bytes, sr->reg_data, (byte)last_data_low, (byte)last_data_high);
- last_data_low = last_data_high = -1;
- } else {
- DBG("%s: LINES=0x%08X bytes=%d DIRECT %s: register=%d data=0x%02X\n",
- msg, sc->lines, sc->bytes, (sr->read) ? "READ" : "WRITE", sr->reg_num, sr->reg_data);
- }
- }
-}
-
-#ifdef __KERNEL__
-
-#define MAX_ENV_STR 20
-
-int run_initialize_registers(xpd_t *xpd)
-{
- int ret;
- xbus_t *xbus;
- char busstr[MAX_ENV_STR];
- char xpdstr[MAX_ENV_STR];
- char typestr[MAX_ENV_STR];
- char revstr[MAX_ENV_STR];
- char *argv[] = {
- initialize_registers,
- NULL
- };
- char *envp[] = {
- busstr,
- xpdstr,
- typestr,
- revstr,
- NULL
- };
-
- BUG_ON(!xpd);
- xbus = xpd->xbus;
- if(!initialize_registers || !initialize_registers[0]) {
- NOTICE("%s/%s: No runtime register initialization\n", xbus->busname, xpd->xpdname);
- return 0;
- }
- DBG("%s/%s: running: '%s'\n", xbus->busname, xpd->xpdname, initialize_registers);
- snprintf(busstr, MAX_ENV_STR, "XPD_BUS=%s", xbus->busname);
- snprintf(xpdstr, MAX_ENV_STR, "XPD_NAME=%s", xpd->xpdname);
- snprintf(typestr, MAX_ENV_STR, "XPD_TYPE=%d", xpd->type);
- snprintf(revstr, MAX_ENV_STR, "XPD_REVISION=%d", xpd->revision);
- DBG("%s/%s: type=%d revision=%d\n", xbus->busname, xpd->xpdname, xpd->type, xpd->revision);
- ret = call_usermodehelper(initialize_registers, argv, envp, 1);
- if(ret != 0) {
- ERR("%s/%s: Failed running '%s' (errno %d, sig=%d)\n",
- xbus->busname, xpd->xpdname, initialize_registers,
- ((unsigned)ret >> 8) & 0xFF, ret & 0xFF);
- ret = -EFAULT;
- }
- return ret;
-}
-
-EXPORT_SYMBOL(slic_cmd_direct_write);
-EXPORT_SYMBOL(slic_cmd_direct_read);
-EXPORT_SYMBOL(slic_cmd_indirect_write);
-EXPORT_SYMBOL(slic_cmd_indirect_read);
-EXPORT_SYMBOL(dump_slic_cmd);
-
-#endif
diff --git a/xpp/slic.h b/xpp/slic.h
deleted file mode 100644
index ea49441..0000000
--- a/xpp/slic.h
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef SLIC_H
-#define SLIC_H
-/*
- * Written by Oron Peled <oron@actcom.co.il>
- * Copyright (C) 2004-2006, Xorcom
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "xdefs.h"
-
-/*------------------------------ SLIC Data Structures ----------------------*/
-
-struct slic_reg_d { /* SLIC Register Direct Read/Write */
- byte reg_num:7;
- byte read:1;
- byte reg_data;
-} __attribute__((packed));
-
-struct slic_reg_iw { /* SLIC Register Indirect-Write */
- struct slic_reg_d iw_data_low;
- struct slic_reg_d iw_data_high;
- struct slic_reg_d iw_reg;
-} __attribute__((packed));
-
-struct slic_reg_ir { /* SLIC Register Indirect-Read */
- struct slic_reg_d ir_reg;
-} __attribute__((packed));
-
-typedef struct slic_cmd {
- xpp_line_t lines;
- byte bytes;
- union {
- struct slic_reg_d direct;
- struct slic_reg_iw indirect_write;
- struct slic_reg_ir indirect_read;
- } content;
-} __attribute__((packed)) slic_cmd_t;
-
-typedef struct slic_reply {
- byte size;
- byte reg_num:7;
- byte indirect:1;
- byte data_low;
- byte data_high;
-} __attribute__((packed)) slic_reply_t;
-
-#define SLIC_REG_INIT(slic_reg, reading, num, data) \
- do { \
- (slic_reg)->read = reading; \
- (slic_reg)->reg_num = num; \
- (slic_reg)->reg_data = data; \
- } while(0);
-
-
-/*------------------------------ SLIC Initializers -------------------------*/
-
-int slic_cmd_direct_write(slic_cmd_t *sc, xpp_line_t lines, byte reg, byte data);
-int slic_cmd_direct_read(slic_cmd_t *sc, xpp_line_t lines, byte reg);
-int slic_cmd_indirect_write(slic_cmd_t *sc, xpp_line_t lines, byte reg, byte data_low, byte data_high);
-int slic_cmd_indirect_read(slic_cmd_t *sc, xpp_line_t lines, byte reg);
-void dump_slic_cmd(const char msg[], slic_cmd_t *sc);
-int run_initialize_registers(xpd_t *xpd);
-
-
-#endif /* SLIC_H */
diff --git a/xpp/utils/Makefile b/xpp/utils/Makefile
index b7d77f3..a278a80 100644
--- a/xpp/utils/Makefile
+++ b/xpp/utils/Makefile
@@ -1,33 +1,51 @@
PEDANTIC = -ansi -pedantic -std=c99
-CC = gcc
RANLIB = ranlib
-INSTALL = install
-INSTALL_DATA = install -m 644
-BINDIR = /usr/sbin
-DATADIR = /usr/share/zaptel
-MANDIR = /usr/share/man/man8
+TOPDIR ?= ../..
+
+-include $(TOPDIR)/makeopts
+
+INSTALL_DATA = $(INSTALL) -m 644
+
+SBINDIR = $(prefix)/sbin
+DATADIR = $(datadir)/zaptel
+MANDIR = $(mandir)/man8
HOTPLUG_USB_DIR = /etc/hotplug/usb
-DATA_FILES = $(wildcard ../init_data_*.cmd *.hex) init_fxo_modes
+XPD_FIRMWARE = $(wildcard ../firmwares/*.hex)
+XPD_INIT_DATA = $(XPD_FIRMWARE) init_fxo_modes
+XPD_INIT = $(wildcard ../init_card_?_*) ../calibrate_slics
+
+# Variables that should be defined above, but need sane defaults:
+# FIXME: Are those values really sane?
+HOSTCC ?= $(CC)
+PBX_LIBUSB ?= 1
+DRIVER_DIR ?= $(TOPDIR)
-WCTDM=../../wctdm.c
+WCTDM=$(DRIVER_DIR)/wctdm.c
CFLAGS = -g -Wall $(EXTRA_CFLAGS)
-TARGETS = libhexfile.a fpga_load test_parse init_fxo_modes
+TARGETS = init_fxo_modes print_modes adj_clock
+PROG_INSTALL = genzaptelconf adj_clock
+MAN_INSTALL = genzaptelconf.8 adj_clock.8
+ifeq ($(PBX_LIBUSB),1)
+TARGETS += libhexfile.a fpga_load test_parse
+PROG_INSTALL += fpga_load
+MAN_INSTALL += fpga_load.8
+endif
all: $(TARGETS)
install: all
$(INSTALL) -d $(DESTDIR)$(BINDIR)
- $(INSTALL) genzaptelconf fpga_load $(DESTDIR)$(BINDIR)/
+ $(INSTALL) $(PROG_INSTALL) $(DESTDIR)$(BINDIR)/
$(INSTALL) -d $(DESTDIR)$(DATADIR)
- $(INSTALL_DATA) $(DATA_FILES) $(DESTDIR)$(DATADIR)/
- $(INSTALL) ../initialize_registers ../calibrate_slics $(DESTDIR)$(DATADIR)/
+ $(INSTALL_DATA) $(XPD_INIT_DATA) $(DESTDIR)$(DATADIR)/
+ $(INSTALL) $(XPD_INIT) $(DESTDIR)$(DATADIR)/
$(INSTALL) -d $(DESTDIR)$(MANDIR)
- $(INSTALL_DATA) fpga_load.8 genzaptelconf.8 $(DESTDIR)$(MANDIR)/
+ $(INSTALL_DATA) $(MAN_INSTALL) $(DESTDIR)$(MANDIR)/
$(INSTALL) -d $(DESTDIR)$(HOTPLUG_USB_DIR)
$(INSTALL_DATA) xpp_fxloader.usermap $(DESTDIR)$(HOTPLUG_USB_DIR)/
$(INSTALL) xpp_fxloader $(DESTDIR)$(HOTPLUG_USB_DIR)/
@@ -40,16 +58,16 @@ fpga_load: fpga_load.o libhexfile.a
$(CC) -L. -o $@ $@.o $(EXTRA_LIBS) -lhexfile -lusb
hexfile.o: hexfile.c hexfile.h
- $(CC) $(CFLAGS) $(PEDANTIC) -c $*.c
+ $(CC) $(CFLAGS) $(PEDANTIC) -c $<
test_parse.o: test_parse.c hexfile.h
- $(CC) $(CFLAGS) $(PEDANTIC) -c $*.c
+ $(CC) $(CFLAGS) $(PEDANTIC) -c $<
test_parse: test_parse.o libhexfile.a
$(CC) -L. -o $@ $@.o $(EXTRA_LIBS) -lhexfile -lusb
print_modes.o: print_modes.c wctdm_fxomodes.h
- $(HOSTCC) $(CFLAGS) -c $^
+ $(HOSTCC) $(CFLAGS) -c $<
wctdm_fxomodes.h: $(WCTDM)
perl -n -e 'print if (/^static struct fxo_mode {$$/ .. /};$$/)' $(WCTDM) >$@
diff --git a/xpp/utils/USB_8613.hex b/xpp/utils/USB_8613.hex
deleted file mode 100644
index 424c072..0000000
--- a/xpp/utils/USB_8613.hex
+++ /dev/null
@@ -1,301 +0,0 @@
-:100E0700000102030405060708090A0B0C0D0E0F63
-:080E1700410010004100110030
-:1009B80090E600E054E74410F000000090E604746C
-:1009C80080F00000007406F0000000E4F000000071
-:1009D80090E6107420F000000090E611F00000008E
-:1009E80090E61274A2F000000090E61374A0F000E4
-:1009F800000090E61474E2F000000090E61574E040
-:100A0800F000000090E6047480F00000007404F028
-:100A1800000000E4F000000090E6497482F0000055
-:100A280000F000000090E6187410F000000090E656
-:100A38001A7408F090E6917480F0000000F000004D
-:100A48000090E695F0000000F000000043AF01229E
-:1005B30078007C007D017BFF7A0E79077E007F1037
-:1005C30012050DC204E5AA30E2030206E9E5AA30EA
-:1005D300E7030206E975310075320490F400E02464
-:1005E300FE700302068024FA700302069C2407604F
-:1005F300030206C590FC007401F090F401E090FC46
-:1006030001F090F402E090FC02F0D2B690F401E025
-:10061300701AA3E0701630B01374C0120D2DC2B659
-:100623007F08120D33D2B67F08120D3330B04690D7
-:10063300E694E0FE90E695E07C002400FFEC3ECFDC
-:1006430024FCCF34FFFE7B017AF47904120AE450D0
-:100653001C90FC0330B4117408F07FE87E03120D84
-:10066300357403120D2D80667404F0806190FC03D1
-:100673007402F0805990FC037401F0805190FC00E7
-:100683007402F0E4A3F0A3F030B406A37410F08076
-:100693003D90FC037420F080357531007532119064
-:1006A300FC007408F07A007B007D017F50120D6B13
-:1006B3007F50120BB57AFC7B017D107F50120D4FDA
-:1006C300800C75310075320190FC0074AAF0E5319D
-:1006D30090E69CF0000000E53290E69DF0000000FB
-:0606E30090E6957480F022
-:0106E90022EE
-:0C0D2D0090E601F07F147E007D007C0049
-:100D39008F368E358D348C33783374FF120595ECEC
-:060D49004D4E4F70F32235
-:0A0AE4008E338F348B358A36893744
-:100AEE00E4F538F539C3E5399534E53895335033A7
-:100AFE00AB35AA36A937853982853883120533FF7F
-:100B0E00E4FEC2B2EF1392B7EFC313FFD2B20EBE22
-:100B1E0008F0C2B220B002C3220539E53970C6050D
-:040B2E003880C2D376
-:010B320022A0
-:02004100D322C8
-:02004E00D322BB
-:02005000D322B9
-:080E200090E6BAE0F51DD322B3
-:100DE30090E740E51DF0E490E68AF090E68B04F08E
-:020DF300D32209
-:080E280090E6BAE0F51CD322AC
-:100DF50090E740E51CF0E490E68AF090E68B04F07D
-:020E0500D322F6
-:0207FC00D32206
-:0207FE00D32204
-:0208FB00D32206
-:100CE00090E6B9E0242F600D04701990E604E0FF4F
-:100CF000430780800890E604E0FF53077F00000070
-:070D0000EFF08002D322C3D3
-:010D070022C9
-:100D8700C0E0C083C082D2015391EF90E65D740149
-:080D9700F0D082D083D0E032DD
-:100DB700C0E0C083C0825391EF90E65D7404F0D029
-:060DC70082D083D0E0326F
-:100DCD00C0E0C083C0825391EF90E65D7402F0D015
-:060DDD0082D083D0E03259
-:100BED00C0E0C083C08285100C85110D850D8285F6
-:100BFD000C83A37402F085080E85090F850F82857D
-:100C0D000E83A37407F05391EF90E65D7410F0D04E
-:060C1D0082D083D0E0321A
-:100D9F00C0E0C083C082D2035391EF90E65D740828
-:080DAF00F0D082D083D0E032C5
-:1008BE00C0E0C083C08290E680E030E72085080C5F
-:1008CE0085090D850D82850C83A37402F085100EAB
-:1008DE0085110F850F82850E83A37407F05391EF58
-:0D08EE0090E65D7420F0D082D083D0E0321F
-:01003200329B
-:01004A003283
-:01005200327B
-:0108FD0032C8
-:0108FE0032C7
-:0108FF0032C6
-:010E38003287
-:010E39003286
-:010E3A003285
-:010E3B003284
-:010E3C003283
-:010E3D003282
-:010E3E003281
-:010E3F003280
-:010E4000327F
-:010E4100327E
-:010E4200327D
-:010E4300327C
-:010E4400327B
-:010E4500327A
-:010E46003279
-:010E47003278
-:010E48003277
-:010E49003276
-:010E4A003275
-:010E4B003274
-:010E4C003273
-:010E4D003272
-:010E4E003271
-:010E4F003270
-:010E5000326F
-:010E5100326E
-:010E5200326D
-:010E5300326C
-:100B7900C0E0C083C08290E6D1E0900010F090E61A
-:100B8900D0E4F000000090E6D17402F000000053B8
-:100B990091BF00000090E66104F000000090E69922
-:0C0BA90004F075BB06D082D083D0E0328F
-:010E5400326B
-:0A07F20000010202030304040505E0
-:10028D00E4F52CF52BF52AF529C203C200C202C2F2
-:10029D0001D2B675B5C4D2B61209B8120E307E08A9
-:1002AD007F008E0A8F0B751208751312750808756D
-:1002BD00091C75100875114A751408751578EE54DA
-:1002CD00C07003020396752D00752E808E2F8F3012
-:1002DD00C374BC9FFF74089ECF2402CF3400FEE48C
-:1002ED008F288E27F526F525F524F523F522F52102
-:1002FD00AF28AE27AD26AC25AB24AA23A922A82171
-:10030D00C31205825031AE23AF24E5302FF582E5BF
-:10031D002F3EF583E0FDE52E2FF582E52D3EF5838D
-:10032D00EDF0EF2401F524E43EF523E43522F5222A
-:10033D00E43521F52180B9852D0A852E0B74002415
-:10034D0080FF740834FFFEC3E5139FF513E5129E7D
-:10035D00F512C3E50D9FF50DE50C9EF50CC3E50FEC
-:10036D009FF50FE50E9EF50EC3E5099FF509E5080E
-:10037D009EF508C3E5119FF511E5109EF510C3E537
-:10038D00159FF515E5149EF514D2E843D82090E697
-:10039D0068E0440BF090E65CE0443DF0000000E4C2
-:1003AD00F5A2000000D2AFD20412000390E680E067
-:1003BD0054F7F0538EF8C20390E6C2E054FBF00000
-:1003CD00000000000090E619E054FEF000000090DF
-:1003DD00E61BE054FEF000000090E6187410F000EB
-:1003ED00000090E61A740CF0000000000000000000
-:1003FD000090E6017403F01205B3300105120056AA
-:10040D00C2013003F212004150EDC203120D08205B
-:10041D00001690E682E030E704E020E1EF90E682FE
-:10042D00E030E604E020E0E4120C8912004E80C7B3
-:0B00360090E50DE030E402C322D3226D
-:1000560090E6B9E0700302011514700302019224C0
-:10006600FE700302021524FB700302010F147003D5
-:100076000201091470030200FD1470030201032437
-:10008600056003020279120050400302028590E6E1
-:10009600BBE024FE602A14603B24FD601114602A34
-:1000A60024067050E50A90E6B3F0E50B803C12009A
-:1000B60036503EE51290E6B3F0E513802D02027449
-:1000C600E50C90E6B3F0E50D8020E50E90E6B3F082
-:1000D600E50F801690E6BAE0FF120CB5AA06A9074E
-:1000E600EA49600DEE90E6B3F0EF90E6B4F0020256
-:1000F60085020274020274120DF5020285120E28A0
-:10010600020285120E20020285120DE302028512FA
-:1001160007FC400302028590E6B8E0247F601514D0
-:10012600601924027063A200E43325E0FFA202E412
-:10013600334F8041E490E740F0803F90E6BCE054C6
-:100146007EFF7E00E0D394807C0040047D01800227
-:100156007D00EC4EFEED4F24F2F58274073EF583EA
-:10016600E493FF3395E0FEEF24A1FFEE34E68F82A1
-:10017600F583E0540190E740F0E4A3F090E68AF0BE
-:1001860090E68B7402F00202850202741207FE40AA
-:100196000302028590E6B8E024FE6016240260039E
-:1001A60002028590E6BAE0B40105C20002028502A9
-:1001B600027490E6BAE0705590E6BCE0547EFF7E8D
-:1001C60000E0D394807C0040047D0180027D00EC39
-:1001D6004EFEED4F24F2F58274073EF583E493FF5D
-:1001E6003395E0FEEF24A1FFEE34E68F82F583E03F
-:1001F60054FEF090E6BCE05480131313541FFFE046
-:10020600540F2F90E683F0E04420F08072805F1256
-:1002160008FB506B90E6B8E024FE60192402704E8D
-:1002260090E6BAE0B40104D200805490E6BAE064E5
-:1002360002604C803990E6BCE0547EFF7E00E0D33D
-:1002460094807C0040047D0180027D00EC4EFEED32
-:100256004F24F2F58274073EF583E493FF3395E06D
-:10026600FEEF24A1FFEE34E68F82F583800D90E643
-:10027600A08008120CE0500790E6A0E04401F09040
-:06028600E6A0E04480F058
-:01028C00224F
-:0300330002004682
-:0400460053D8EF326A
-:100C890090E682E030E004E020E60B90E682E03076
-:100C9900E119E030E71590E680E04401F07F147E29
-:0C0CA90000120B3390E680E054FEF022B5
-:1000030030040990E680E0440AF0800790E680E03F
-:100013004408F07FDC7E05120B3390E65D74FFF03D
-:0F00230090E65FF05391EF90E680E054F7F02203
-:080E3000E4F51BD2E9D2AF2268
-:100BB500AD0790E678E020E6F9C2E990E678E044F2
-:100BC50080F0ED25E090E679F090E678E030E0F908
-:100BD50090E678E04440F090E678E020E6F990E68B
-:080BE50078E030E1D6D2E922EC
-:100C5700AC0790E678E020E6F9E51B702390E6788C
-:100C6700E04480F0EC25E090E679F08D16AF03A91B
-:100C7700077517018A188919E4F51A751B01D3221C
-:020C8700C32286
-:100C2300AC0790E678E020E6F9E51B702590E678BE
-:100C3300E04480F0EC25E0440190E679F08D16AFB6
-:100C430003A9077517018A188919E4F51A751B0397
-:040C5300D322C322C3
-:03004B000206EAC0
-:1006EA00C0E0C083C082C085C084C086758600C051
-:1006FA00D075D000C000C001C002C003C006C00748
-:10070A0090E678E030E206751B060207D490E67898
-:10071A00E020E10CE51B64026006751B070207D4A2
-:10072A00E51B24FE605F14603624FE70030207C5D1
-:10073A0024FC70030207D1240860030207D4AB1714
-:10074A00AA18A919AF1A051A8F82758300120533E0
-:10075A0090E679F0E51A65167070751B05806B9046
-:10076A00E679E0AB17AA18A919AE1A8E827583002A
-:10077A00120560751B02E5166401704E90E678E07A
-:10078A004420F08045E51624FEB51A0790E678E085
-:10079A004420F0E51614B51A0A90E678E04440F0D1
-:1007AA00751B0090E679E0AB17AA18A919AE1A8E44
-:1007BA0082758300120560051A800F90E678E0447E
-:1007CA0040F0751B008003751B005391DFD007D0E2
-:1007DA0006D003D002D001D000D0D0D086D084D0A9
-:0807EA0085D082D083D0E032FB
-:020CB500A9078D
-:100CB700AE14AF158F828E83A3E064037017AD0166
-:100CC70019ED7001228F828E83E07C002FFDEC3EB0
-:080CD700FEAF0580DFE4FEFF23
-:010CDF0022F2
-:100D4F00120C23E51B24FA600E146006240770F3BF
-:0C0D5F00D322E4F51BD322E4F51BD322C1
-:100D6B00120C57E51B24FA600E146006240770F36F
-:0C0D7B00D322E4F51BD322E4F51BD322A5
-:100D080090E682E044C0F090E681F043870100005D
-:040D180000000022B5
-:100B33008E318F3290E600E054187012E5322401B2
-:100B4300FFE43531C313F531EF13F532801590E629
-:100B530000E05418FFBF100BE53225E0F532E53114
-:100B630033F531E5321532AE31700215314E600581
-:060B7300120D1C80EE22B1
-:100D1C007400F58690FDA57C05A3E582458370F9EA
-:010D2C0022A4
-:03004300020900AF
-:030053000209009F
-:10090000020D8700020DCD00020DB700020D9F0001
-:10091000020BED000208BE000200320002004A0095
-:10092000020052000208FD000208FE000208FF005B
-:10093000020E3800020E3900020E3A00020E3B0091
-:10094000020E3C0002004A00020E3D00020E3E0074
-:10095000020E3F00020E4000020E4100020E420055
-:10096000020E430002004A0002004A0002004A0050
-:10097000020E4400020E4500020E4600020E470021
-:10098000020E4800020E4900020E4A00020E4B0001
-:10099000020E4C00020E4D00020E4E00020E4F00E1
-:1009A000020E5000020E5100020E5200020E5300C1
-:0809B000020B7900020E540055
-:100800001201000200000040E4E411220000010295
-:1008100000010A06000200000040010009022E004B
-:1008200001010080320904000004FF0000000705F8
-:10083000020200020007050402000200070586020A
-:100840000002000705880200020009022E000101D3
-:100850000080320904000004FF00000007050202C6
-:100860004000000705040240000007058602400022
-:10087000000705880240000004030904180358001B
-:100880006F00720063006F006D0020004C00740068
-:1008900064002E0028035800500044002800420045
-:1008A000610073006500640020006F006E0020008E
-:0E08B000410058005500500050002900000083
-:03000000020A5899
-:0C0A5800787FE4F6D8FD758139020A9F12
-:10043D00E709F608DFFA8046E709F208DFFA803EA1
-:10044D0088828C83E709F0A3DFFA8032E309F6088E
-:10045D00DFFA8078E309F208DFFA807088828C83F6
-:10046D00E309F0A3DFFA806489828A83E0A3F608AA
-:10047D00DFFA805889828A83E0A3F208DFFA804C84
-:10048D0080D280FA80C680D4806980F2803380105B
-:10049D0080A680EA809A80A880DA80E280CA8033C4
-:1004AD0089828A83ECFAE493A3C8C582C8CCC5833C
-:1004BD00CCF0A3C8C582C8CCC583CCDFE9DEE7800C
-:1004CD000D89828A83E493A3F608DFF9ECFAA9F08B
-:1004DD00EDFB2289828A83ECFAE0A3C8C582C8CCE1
-:1004ED00C583CCF0A3C8C582C8CCC583CCDFEADEFA
-:1004FD00E880DB89828A83E493A3F208DFF980CC5C
-:10050D0088F0EF60010E4E60C388F0ED2402B40454
-:10051D000050B9F582EB2402B4040050AF232345FB
-:06052D00822390048D738F
-:10053300BB010CE58229F582E5833AF583E022507D
-:1005430006E92582F8E622BBFE06E92582F8E222C7
-:0D055300E58229F582E5833AF583E49322E1
-:10056000F8BB010DE58229F582E5833AF583E8F0D1
-:10057000225006E92582C8F622BBFE05E92582C87D
-:02058000F22265
-:10058200EB9FF5F0EA9E42F0E99D42F0E89C45F0CF
-:010592002246
-:100593007401FF3395E0FEFDFC080808E6CF2FF653
-:1005A30018E6CE3EF618E6CD3DF618E6CC3CF6222C
-:100A640002028DE493A3F8E493A34003F68001F219
-:100A740008DFF48029E493A3F85407240CC8C33393
-:100A8400C4540F4420C8834004F456800146F6DF62
-:100A9400E4800B0102040810204080900E17E47ECD
-:100AA400019360BCA3FF543F30E509541FFEE49357
-:100AB400A360010ECF54C025E060A840B8E493A31E
-:100AC400FAE493A3F8E493A3C8C582C8CAC583CA49
-:100AD400F0A3C8C582C8CAC583CADFE9DEE780BE01
-:010E1F0000D2
-:00000001FF
diff --git a/xpp/utils/adj_clock.8 b/xpp/utils/adj_clock.8
new file mode 100644
index 0000000..0e9cf71
--- /dev/null
+++ b/xpp/utils/adj_clock.8
@@ -0,0 +1,144 @@
+." $Id:$
+.TH adj_clock 8 "2006-10-18"
+.SH "NAME"
+adj_clock \(em Synchronize system clock to zaptel clock
+.SH "SYNOPSIS"
+.B adj_clock
+.I [ -c
+.B count
+.I ] [ -i
+.B interval
+.I ] [ -t
+.B period
+.I ] [ -v ]
+
+.SH "DESCRIPTION"
+.B adj_clock
+compares synchronizes the system clock from Zaptel's clock: in each cycle
+It will read 1024 *
+.B interval
+ticks from a Zaptel pseudo channel, which should take exactly
+.B interval
+seconds. It measures the time it did take, and uses
+.I adjtimex(3)
+to fix the system clock accordingly.
+
+Note that NTP servers usually use adjtimex. You may get strange behaviour
+if you have a NTP server (such as ntpd(8)) running on the system.
+
+Output is sent to both the standard error and to the syslog. Syslog
+messages are with facility daemon.
+
+.SH OPTIONS
+.I -c
+.B count
+.RS
+Run just
+.B count
+synchronization cycles. Default is to run forever.
+.RE
+
+.I -i
+.B interval
+.RS
+Loop interval (in seconds). Optional, as program should provide a sane value.
+
+Small values allow faster synchronization when the system is quiet. Even
+a value as low as 10 should work. However they are much more suspectable
+to short interruptions.
+
+.RE
+
+.I -t
+.B period
+.RS
+Set the synchronization tolerance priod (micro-seconds). The default
+is 100. Don't touch it unless you know what you're doing.
+.RE
+
+.I -v
+.RS
+Be more verbose: log status messages even when synchronized.
+.RE
+
+.SH FILES
+.B /dev/zap/pseudo
+.RS
+.RE
+The device file used to open a "pseudo" channel (a channels that
+constantly streams voice and is synchronized by the master Zaptel
+device).
+
+.SH SYNCHRONIZATION
+Some more technical details. This explains the strange numbers the
+program prints.
+
+In each cycle
+.B adj_clock
+measures
+.B interval
+seconds using Zaptel ticks. It then compares that to the system time
+from gettimeofday(2). It then calls adjtimex(2) to slightly change the
+rate of the system clock. It uses two parameters:
+.B ticks,
+which is a more
+coarse one (1 tick will give roughly a change of rate of 9 seconds per
+day) and
+.I frequency,
+which allows much finer settings.
+
+The program tries to set what it can by ticks, and the rest through
+frequency. It considers itself "synchronized" when the rate difference
+is small enough so
+.I (a)
+It does not have to use ticks anymore. And
+.I (b)
+The rest of the interval to change is smaller than the tolerance period
+(100 micro-seconds, by default).
+
+The meaning of the parameters it prints is, thus:
+
+.I interval
+.RS
+The current interval parameter (seconds).
+.RE
+
+.I diff_tick
+.RS
+The number of ticks it tries to set through adjtimex(2).
+Anything different than 0 means we're still way off mark.
+.RE
+
+.I diff_usec
+.RS
+The time difference (micro-seconds) that we need to overcome in the
+first place. This is the difference between the system clock and the
+measured zaptel clock.
+.RE
+
+.I usec_left
+.RS
+How much of this difference (microseconds) we still need to adjust
+after using ticks. This should be low enough (less than the tolerance
+period).
+.RE
+
+.SH SIGNALS
+.B adj_clock
+is so far an interactive program, and thus killed by SIGHUP. SIGUSR is
+used to increase verbosity level and SIGUSR2 is used to reset verbosity
+level to 0. When SIGUSR1 is recieved a status message will also be sent
+to the logs.
+
+.SH SEE ALSO
+ztcfg(8), zttest(8), adjtimex(2), gettimeofday(2), adjtimex(8)
+
+.SH AUTHOR
+
+This manual page was written by Tzafrir Cohen <tzafrir.cohen@xorcom.com>
+Permission is granted to copy, distribute and/or modify this document under
+the terms of the GNU General Public License, Version 2 any
+later version published by the Free Software Foundation.
+
+On Debian systems, the complete text of the GNU General Public
+License can be found in /usr/share/common-licenses/GPL.
diff --git a/xpp/utils/adj_clock.c b/xpp/utils/adj_clock.c
new file mode 100644
index 0000000..6dfa483
--- /dev/null
+++ b/xpp/utils/adj_clock.c
@@ -0,0 +1,228 @@
+/*
+ * Written by Tzafrir Cohen <tzafrir.cohen@xorcom.com>
+ * Copyright (C) 2006, Xorcom
+ *
+ * Derived from zttest.c
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <sys/timex.h>
+#include <linux/param.h>
+#include <syslog.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/signal.h>
+#include <math.h>
+
+static const char *rcsid = "$Id$";
+
+#define FREQ_PER_TICK (64*1024)
+#define USEC_PER_ZAP_TICK 1000 /* Zaptel tick in usec */
+#define USER_HZ 100
+#define SYNC_TOLERANCE 100
+#define DEFAULT_INTERVAL 60
+
+static const char *program;
+static int synced_time; /* time (seconds) we are so far synced */
+static int verbose = 0;
+static int sync_tolerance = 100;
+
+void usage() {
+ fprintf(stderr, "%s: synchronize system clock from zaptel clock.\n"
+ "Version: %s\n"
+ "\n"
+ "Usage: %s [ -c COUNT ] [-i INTERVAL] [ -t PERIOD ] [-v]\n"
+ " %s -h\n"
+ "\n"
+ "Options:\n"
+ " -c only run COUNT cycles of synchronization (default: forever).\n"
+ " -i set cycle Interval to INTERVAL (in seconds. Default: %d).\n"
+ " -t sync tolerance to PERIOD (in usec. Default: %d). For debugging.\n"
+ " -v Be more Verbose\n"
+ " -h Print this Help text and exit.\n"
+ "", program, rcsid, program, program, DEFAULT_INTERVAL,
+ sync_tolerance);
+}
+
+/* based on zttest.c */
+
+/*
+ * Print a message to the log according to the value of synced_time
+ *
+ * All parameters are for the "Not Synced" warning message.
+ * TODO: Find a better way.
+ */
+void status_message(void) {
+ if (synced_time == 0)
+ syslog(LOG_NOTICE, "Not Synced.\n");
+ else
+ syslog(LOG_INFO, "Good Sync for %d seconds\n", synced_time);
+
+ return;
+}
+
+/*
+ * interval: period, in seconds
+ * diff_usec: Current offset, in micro-seconds.
+ */
+int clock_sync(int interval, int diff_usec)
+{
+ struct timex cur_time = {.modes=0}; /* just query */
+ int diff_tick; /* Difference in adjtimex ticks */
+ int req_tick; /* Required adjtimex tick value */
+ long long diff_freq;
+ long long req_freq;
+ int usec_left; /* Usec adjusted by frequency */
+ int ret;
+
+ ret = adjtimex(&cur_time);
+
+ diff_tick = diff_usec / (interval * USER_HZ);
+ usec_left = diff_usec - diff_tick * (interval * USER_HZ);
+ diff_freq = usec_left * FREQ_PER_TICK / interval;
+
+ req_tick = cur_time.tick - diff_tick;
+ req_freq = cur_time.freq - diff_freq;
+
+ if(!diff_tick && abs(usec_left) < sync_tolerance)
+ synced_time += interval;
+ else
+ synced_time = 0;
+ status_message();
+ if (verbose || !synced_time)
+ syslog(LOG_INFO, "interval: %d, diff_tick: %d, diff_usec: %d, usec_left: %d.\n",
+ interval, diff_tick, diff_usec, usec_left);
+
+ /* set the clock rate */
+ cur_time.freq = req_freq;
+ cur_time.tick = req_tick;
+ cur_time.modes = ADJ_TICK | ADJ_FREQUENCY;
+ ret = adjtimex(&cur_time);
+ if (ret < 0)
+ syslog(LOG_ERR, "Adjtimex failed to set frequency. New frequency: %lld. Error: %d (%s)\n",
+ req_freq, errno, strerror(errno));
+ return 0;
+}
+
+static int pass = 0;
+
+void hup_handler(int sig)
+{
+ if (verbose > 0) {
+ syslog(LOG_INFO, "--- Results after %d passes ---\n", pass);
+ status_message();
+ }
+ closelog();
+ exit(0);
+}
+
+void sigusr1_handler(int sig) {
+ verbose++;
+ syslog(LOG_INFO, "Increased verbosity to %d (increase: SIGUSR1, reset: SIGUSR2).\n", verbose);
+ status_message();
+}
+
+void sigusr2_handler(int sig) {
+ verbose = 0;
+ syslog(LOG_INFO, "Set verbosity to 0 (increase: SIGUSR1, reset: SIGUSR2).\n");
+}
+
+void sync_cycle(int fd, int interval)
+{
+ char buf[1024]; /* TODO: why 1024 and not 1000? */
+ struct timeval start;
+ struct timeval end;
+ long long usec;
+ int count = 0;
+ int i;
+ int res;
+
+ gettimeofday(&start, NULL);
+ for (i=0; i < interval*8; i++) {
+ res = read(fd, buf, sizeof(buf));
+ if (res < 0) {
+ syslog(LOG_ERR, "Failed to read from pseudo interface: %s\n", strerror(errno));
+ exit(1);
+ }
+ count += res/8;
+ }
+ gettimeofday(&end, NULL);
+
+ /* time difference in microseconds: */
+ usec = (end.tv_sec - start.tv_sec) * 1000000;
+ usec += end.tv_usec - start.tv_usec;
+
+ clock_sync(interval, usec - (count * USEC_PER_ZAP_TICK));
+
+ pass++;
+}
+
+int main(int argc, char *argv[])
+{
+ int fd;
+ int opt;
+ int interval = DEFAULT_INTERVAL;
+ int cycles_to_run = 0;
+ int i;
+
+ program = argv[0];
+ while((opt = getopt(argc, argv, "c:hi:t:v")) != -1) {
+ switch (opt) {
+ case 'h': usage(); exit(0); break;
+ case 'c': cycles_to_run = atoi(optarg); break;
+ case 'i': interval = atoi(optarg); break; /* number of seconds */
+ case 't': sync_tolerance = atoi(optarg); break; /* usec */
+ case 'v': verbose++; break;
+ default:
+ fprintf(stderr, "%s: Unknown option: %c. Aborting\n", argv[0], opt);
+ usage();
+ exit(1);
+ }
+ }
+
+ openlog(program, LOG_PERROR | LOG_PID, LOG_DAEMON);
+ fd = open("/dev/zap/pseudo", O_RDWR);
+ if (fd < 0) {
+ fprintf(stderr, "Unable to open zap interface: %s\n", strerror(errno));
+ exit(1);
+ }
+ if (verbose >=1)
+ syslog(LOG_INFO, "Opened pseudo zap interface, measuring accuracy...\n");
+
+ signal(SIGHUP, hup_handler);
+ signal(SIGINT, hup_handler);
+ signal(SIGUSR1, sigusr1_handler);
+ signal(SIGUSR2, sigusr2_handler);
+
+ if (cycles_to_run > 0) {
+ for(i=0; i<cycles_to_run; i++) {
+ sync_cycle(fd, interval);
+ }
+ hup_handler(0); /* exit */;
+ }
+
+ /* else (option -c not provided): run forever. */
+ for(;;) {
+ sync_cycle(fd, interval);
+ }
+}
diff --git a/xpp/utils/xpp_fxloader b/xpp/utils/xpp_fxloader
index f584266..8c54370 100644
--- a/xpp/utils/xpp_fxloader
+++ b/xpp/utils/xpp_fxloader
@@ -29,12 +29,8 @@
#
# BUS!="usb", ACTION!="add", GOTO="zaptel_usb_add_end"
#
-# SYSFS{idVendor}=="04b4", SYSFS{idProduct}=="8613", \
-# RUN+="/etc/hotplug/usb/xpp_fxloader udev $sysfs{idVendor}/$sysfs{idProduct}/"
-# SYSFS{idVendor}=="e4e4", SYSFS{idProduct}=="1130", \
-# RUN+="/etc/hotplug/usb/xpp_fxloader udev $sysfs{idVendor}/$sysfs{idProduct}/"
-# SYSFS{idVendor}=="e4e4", SYSFS{idProduct}=="1131", \
-# RUN+="/etc/hotplug/usb/xpp_fxloader udev $sysfs{idVendor}/$sysfs{idProduct}/"
+# SYSFS{idVendor}=="e4e4", SYSFS{idProduct}=="11[345][01]", \
+# RUN+="/etc/hotplug/usb/xpp_fxloader udev $sysfs{idVendor}/$sysfs{idProduct}/$sysfs{bcdDevice}"
#
# LABEL="zaptel_usb_add_end"
#
@@ -151,9 +147,13 @@ xppdetect|load|usb)
load_fw 04b4 8613 USB_8613.hex
load_fw e4e4 1130 USB_1130.hex
+ load_fw e4e4 1140 USB_1140.hex
+ load_fw e4e4 1150 USB_1150.hex
if [ "$1" != 'usb' ]
then
load_fpga e4e4 1131 FPGA_FXS.hex
+ load_fpga e4e4 1141 FPGA_1141.hex
+ load_fpga e4e4 1151 FPGA_1151.hex
fi
sleep 3 # Let it stabilize
@@ -182,12 +182,12 @@ then
$LOGGER "Trying to find what to do for product $PRODUCT, device $DEVICE"
prod_id=`echo "$PRODUCT" | cut -d/ -f2`
case "$PRODUCT" in
- 4b4/8613/*|e4e4/1130/*|e4e4/1140/*)
+ 4b4/8613/*|e4e4/11[345]0/*)
FIRM_USB="$FIRMWARE_DIR/USB_$prod_id.hex"
$LOGGER "Loading firmware '$FIRM_USB' into '$DEVICE'"
do_fxload -D "$DEVICE" -I "$FIRM_USB"
;;
- e4e4/1131/*|e4e4/1141/*)
+ e4e4/11[345]1/*)
if [ "$prod_id" = 1131 ]; then
FIRM_FPGA="$FIRMWARE_DIR/FPGA_FXS.hex" # Legacy
else
diff --git a/xpp/utils/xpp_fxloader.usermap b/xpp/utils/xpp_fxloader.usermap
index bdfa861..70ca68a 100644
--- a/xpp/utils/xpp_fxloader.usermap
+++ b/xpp/utils/xpp_fxloader.usermap
@@ -2,3 +2,7 @@
xpp_fxloader 0x0003 0x04b4 0x8613 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
xpp_fxloader 0x0003 0xe4e4 0x1130 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
xpp_fxloader 0x0003 0xe4e4 0x1131 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1140 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1141 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1150 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
+xpp_fxloader 0x0003 0xe4e4 0x1151 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x0
diff --git a/xpp/xbus-core.c b/xpp/xbus-core.c
index 961c361..9f73a86 100644
--- a/xpp/xbus-core.c
+++ b/xpp/xbus-core.c
@@ -55,7 +55,6 @@ static int proc_xbus_command_write(struct file *file, const char __user *buffer,
/* Command line parameters */
extern int print_dbg;
-extern int max_queue_len;
/* Forward declarations */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
@@ -133,105 +132,6 @@ void xbus_packet_free(xbus_t *xbus, xpacket_t *p)
// xbus->busname, atomic_read(&xbus->packet_counter));
}
-/*------------------------- Packet Queues --------------------------*/
-void init_xbus_packet_queue(packet_queue_t *q, const char name[])
-{
- INIT_LIST_HEAD(&q->head);
- spin_lock_init(&q->lock);
- q->count = 0;
- q->worst_count = 0;
- q->overflows = 0;
- snprintf(q->qname, XPD_NAMELEN, "%s", name);
-}
-
-#if 0
-/*
- * Assume the queue is locked
- */
-void __dump_packet_queue(const char *msg, packet_queue_t *q)
-{
- xpacket_t *tmp;
-
- list_for_each_entry(tmp, &q->head, list) {
- dump_packet(msg, tmp);
- }
-}
-#endif
-
-void drain_xbus_packet_queue(xbus_t *xbus, packet_queue_t *q)
-{
- unsigned long flags;
- xpacket_t *pack;
- xpacket_t *next;
-
- spin_lock_irqsave(&q->lock, flags);
- DBG("queue=%s count=%d\n", q->qname, q->count);
- DBG(" total packets count=%d\n", atomic_read(&xpacket_count));
- list_for_each_entry_safe(pack, next, &q->head, list) {
- list_del(&pack->list);
- q->count--;
- xbus->ops->packet_free(xbus, pack);
- }
- if(q->count != 0)
- ERR("drain_xbus_packet_queue: queue %s still has %d packets\n",
- q->qname, q->count);
- spin_unlock_irqrestore(&q->lock, flags);
-}
-
-void xbus_enqueue_packet(xbus_t *xbus, packet_queue_t *q, xpacket_t *pack)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&q->lock, flags);
-
- if(q->count >= max_queue_len) {
- static unsigned long last_notice = 0; // rate limit
-
- if((jiffies - last_notice) < HZ) {
- NOTICE("xbus_enqueue_packet: dropping packet (queue len = %d, max=%d)\n",
- q->count, max_queue_len);
- last_notice = jiffies;
- }
- q->overflows++;
- xbus->ops->packet_free(xbus, pack);
- goto out;
- }
- list_add_tail(&pack->list, &q->head);
- q->count++;
-
- if(q->count > q->worst_count)
- q->worst_count = q->count;
-
- if(q->count < max_queue_len/100 && q->worst_count > q->count) // Decay worst_count
- q->worst_count--;
-
- // dump_packet("ENQUEUED", pack, print_dbg);
-out:
- spin_unlock_irqrestore(&q->lock, flags);
-}
-
-xpacket_t *xbus_dequeue_packet(packet_queue_t *q)
-{
- unsigned long flags;
- struct list_head *p;
- xpacket_t *pack = NULL;
-
- spin_lock_irqsave(&q->lock, flags);
-
- if(list_empty(&q->head)) {
- // DBG("LIST EMPTY (count=%d)\n", q->count);
- goto out;
- }
- p = q->head.next;
- list_del(p);
- q->count--;
- pack = list_entry(p, xpacket_t, list);
- // dump_packet("DEQUEUED", pack, print_dbg);
-out:
- spin_unlock_irqrestore(&q->lock, flags);
- return pack;
-}
-
/*------------------------- Bus Management -------------------------*/
xbus_t *xbus_of(int xbus_num)
@@ -430,7 +330,6 @@ void xbus_activate(xbus_t *xbus)
BUG_ON(!xbus);
ops = xbus->ops;
BUG_ON(!ops);
- BUG_ON(!xbus->priv);
/* Sanity checks */
BUG_ON(!ops->packet_send);
BUG_ON(!ops->packet_new || !ops->packet_free);
@@ -504,6 +403,7 @@ static void xbus_free(xbus_t *xbus)
if(!xbus)
return;
spin_lock_irqsave(&xbuses_lock, flags);
+ BUG_ON(!xbus_of(xbus->num));
BUG_ON(xbus != xbus_of(xbus->num));
xbuses_array[xbus->num] = NULL;
bus_count--;
@@ -658,6 +558,10 @@ void xbus_remove(xbus_t *xbus)
int ret;
BUG_ON(!xbus);
+ if(!xbus_of(xbus->num)) {
+ DBG("XBUS #%d was already removed. Skip.\n", xbus->num);
+ return;
+ }
DBG("%s\n", xbus->busname);
/* Block until no one use */
diff --git a/xpp/xbus-core.h b/xpp/xbus-core.h
index 19f9fd7..f2bac8c 100644
--- a/xpp/xbus-core.h
+++ b/xpp/xbus-core.h
@@ -33,12 +33,6 @@ void xbus_core_shutdown(void); /* Terminator */
xpacket_t *xbus_packet_new(xbus_t *xbus, gfp_t flags);
void xbus_packet_free(xbus_t *xbus, xpacket_t *p);
-/* packet queues */
-void init_xbus_packet_queue(packet_queue_t *q, const char name[]);
-void drain_xbus_packet_queue(xbus_t *xbus, packet_queue_t *q);
-void xbus_enqueue_packet(xbus_t *xbus, packet_queue_t *q, xpacket_t *pack);
-xpacket_t *xbus_dequeue_packet(packet_queue_t *q);
-
/* XBUS handling */
xbus_t *xbus_of(int xbus_num);
xpd_t *xpd_of(xbus_t *xbus, int xpd_num);
diff --git a/xpp/xdefs.h b/xpp/xdefs.h
index ab3670e..d7c7032 100644
--- a/xpp/xdefs.h
+++ b/xpp/xdefs.h
@@ -67,11 +67,11 @@ struct list_head { struct list_head *next; struct list_head *prev; };
#define XBUS_NAMELEN 20 /* must be <= from maximal workqueue name */
#define XBUS_DESCLEN 40
-#define UNIT_BITS 4 /* Bit for Astribank unit number */
-#define SUBUNIT_BITS 4 /* Bit for Astribank subunit number */
+#define UNIT_BITS 3 /* Bit for Astribank unit number */
+#define SUBUNIT_BITS 3 /* Bit for Astribank subunit number */
-#define MAX_UNIT 4 /* 1 FXS + 3 FXS/FXO */
-#define MAX_SUBUNIT 1 /* Firmware does not support subunits yet */
+#define MAX_UNIT BIT(UNIT_BITS) /* 1 FXS + 3 FXS/FXO | 1 BRI + 3 FXS/FXO */
+#define MAX_SUBUNIT BIT(SUBUNIT_BITS) /* 8 port BRI */
/*
* Compile time sanity checks
@@ -88,6 +88,11 @@ struct list_head { struct list_head *next; struct list_head *prev; };
#define VALID_XPD_NUM(x) ((x) < MAX_XPDS && (x) >= 0)
+#define CHAN_BITS 5 /* 0-30 for E1, 31 = ALL_CHANS */
+#define ALL_CHANS BITMASK(CHAN_BITS)
+#define MAX_CHAN (ALL_CHANS - 1)
+#define VALID_CHAN_NUM(x) ((x) < MAX_CHAN)
+
typedef char *charp;
typedef unsigned char byte;
typedef int bool;
@@ -97,7 +102,7 @@ typedef struct xpacket_raw xpacket_raw_t;
typedef struct xpacket xpacket_t;
typedef struct xops xops_t;
typedef __u32 xpp_line_t; /* at most 31 lines for E1 */
-typedef int lineno_t;
+typedef byte lineno_t;
#endif /* XDEFS_H */
diff --git a/xpp/xpd.h b/xpp/xpd.h
index 71db99e..74b759d 100644
--- a/xpp/xpd.h
+++ b/xpp/xpd.h
@@ -191,8 +191,8 @@ struct xbus {
#endif
typedef enum xpd_direction {
- TO_PHONE = 0,
- TO_PSTN = 1,
+ TO_PSTN = 0,
+ TO_PHONE = 1,
} xpd_direction_t;
#ifdef __KERNEL__
@@ -255,6 +255,7 @@ struct xpd {
xpp_line_t cid_on;
xpp_line_t digital_outputs; /* 0 - no, 1 - yes */
xpp_line_t digital_inputs; /* 0 - no, 1 - yes */
+ xpp_line_t digital_signalling; /* PRI/BRI signalling channels */
int ringing[CHANNELS_PERXPD];
bool ringer_on[CHANNELS_PERXPD]; /* For ring toggling */
@@ -286,6 +287,8 @@ struct xpd {
const xops_t *xops; /* Card level operations */
void *priv; /* Card level private data */
bool card_present;
+ reg_cmd_t requested_reply;
+ reg_cmd_t last_reply;
unsigned long last_response; /* in jiffies */
unsigned id;
diff --git a/xpp/xpp_usb.c b/xpp/xpp_usb.c
index 89571c3..bc8af46 100644
--- a/xpp/xpp_usb.c
+++ b/xpp/xpp_usb.c
@@ -229,6 +229,7 @@ void xusb_packet_free(xbus_t *xbus, xpacket_t *p)
#else
+/* FIXME FIXME FIXME: should move code to card methods */
static void packet_debug(const char msg[], xusb_t *xusb, xpacket_t *pack)
{
char title[XBUS_DESCLEN];
@@ -261,16 +262,26 @@ static void packet_debug(const char msg[], xusb_t *xusb, xpacket_t *pack)
dump_packet("USB SEND PCM", pack, print_dbg);
#endif
return;
- } else if(pack->content.opcode == XPROTO_NAME(FXS, SLIC_WRITE)) {
- slic_cmd_t *sc;
+ } else if(pack->content.opcode == XPROTO_NAME(GLOBAL, REGISTER_REQUEST)) {
+ reg_cmd_t *regcmd;
- sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
- if(sc->bytes == 2 && sc->content.direct.reg_num == 0x06 && sc->content.direct.read) /* ignore SLIC_QUERY */
+ regcmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
+ if(REG_FIELD(regcmd, regnum) == 0x06) /* ignore SLIC_QUERY */
return;
- if(sc->bytes == 2 && sc->content.direct.reg_num == DAA_VBAT_REGISTER && sc->content.direct.read) /* ignore DAA_QUERY */
+ if(REG_FIELD(regcmd, regnum) == DAA_VBAT_REGISTER) /* ignore DAA_QUERY */
return;
- } else if(pack->content.opcode == XPROTO_NAME(FXS, SLIC_REPLY)) {
+ if(REG_FIELD(regcmd, regnum) == 0x30) { /* ignore BRI query */
+#if 0
+ static int rate_limit;
+ if((rate_limit++ % 1000) < 10)
+ dump_packet("BRI STATE REG", pack, print_dbg);
+#endif
+ return;
+ }
+#if 0
+ } else if(pack->content.opcode == XPROTO_NAME(FXS, REGISTER_REPLY)) {
return;
+#endif
}
snprintf(title, XBUS_DESCLEN, "%s: %s", msg, xusb->xbus->busname);
dump_packet(title, pack, print_dbg);
@@ -405,16 +416,16 @@ static const struct xusb_model_info {
struct xusb_endpoint out;
xbus_type_t bus_type;
} model_table[] = {
- XUSB_MODEL(0x86, 0x02, FIRMWARE_LOOPBACK, "bulkloop.hex"),
- XUSB_MODEL(0x86, 0x02, FIRMWARE_LOOPBACK, "FPGA_bulkloop.hex"),
- XUSB_MODEL(0x86, 0x02, FIRMWARE_XPP, "FPGA_XPD.hex"),
+ XUSB_MODEL(0x86, 0x02, FIRMWARE_XPP, "FPGA_XPD"),
};
/* table of devices that work with this driver */
static const struct usb_device_id xusb_table [] = {
// { USB_DEVICE(0x04B4, 0x8613) }, // default of cypress
- { USB_DEVICE(0xE4E4, 0x2211), .driver_info=(kernel_ulong_t)&model_table[2] }, // FPGA_XPD.hex
- { USB_DEVICE(0xE4E4, 0x1132), .driver_info=(kernel_ulong_t)&model_table[2] }, // FPGA_XPD.hex
+ { USB_DEVICE(0xE4E4, 0x2211), .driver_info=(kernel_ulong_t)&model_table[0] }, // OLD FPGA
+ { USB_DEVICE(0xE4E4, 0x1132), .driver_info=(kernel_ulong_t)&model_table[0] }, // FPGA_FXS
+ { USB_DEVICE(0xE4E4, 0x1142), .driver_info=(kernel_ulong_t)&model_table[0] }, // FPGA_1141
+ { USB_DEVICE(0xE4E4, 0x1152), .driver_info=(kernel_ulong_t)&model_table[0] }, // FPGA_1151
/* "Gadget Zero" firmware runs under Linux */
//{ USB_DEVICE(0x0525, 0xa4a0) },
{ } /* Terminating entry */
diff --git a/xpp/xpp_zap.c b/xpp/xpp_zap.c
index 33ec4c6..0512dcc 100644
--- a/xpp/xpp_zap.c
+++ b/xpp/xpp_zap.c
@@ -38,9 +38,7 @@
#include <linux/delay.h> /* for udelay */
#include <linux/workqueue.h>
#include <linux/proc_fs.h>
-
-#include "zaptel.h"
-
+#include <zaptel.h>
#include <version.h> /* For zaptel version */
#include "xbus-core.h"
#include "xproto.h"
@@ -66,13 +64,13 @@ static unsigned int xpp_timer_count = 0;
static unsigned int xpp_last_jiffies = 0;
DEF_PARM(int, print_dbg, 0, "Print DBG statements");
-DEF_PARM(int, max_queue_len, MAX_QUEUE_LEN, "Maximum Queue Length.");
-DEF_PARM(bool, have_sync_bus, 0, "True if all Astribank(TM) devices are connected via a sync-cable");
DEF_PARM(bool, zap_autoreg, 1, "Register spans automatically (1) or not (0)");
+DEF_PARM(bool, prefmaster, 1, "Do we want to be zaptel preferred sync master");
+// DEF_ARRAY(int, pcmtx, 4, 0, "Forced PCM values to transmit");
#include "zap_debug.h"
#ifdef XPP_EC_CHUNK
-#include "echo_supress/ec_xpp.h"
+#include "supress/ec_xpp.h"
#endif
@@ -89,7 +87,7 @@ static void external_sync(xpd_t *the_xpd)
{
int i, j;
- DBG("SYNC %s (%s sync cable)\n", (the_xpd)?"Astribanks":"HOST", (have_sync_bus)?"with":"without");
+ DBG("SYNC %s\n", (the_xpd)?"Astribanks":"HOST");
// Shut all down
for(i = 0; i < MAX_BUSES; i++) {
xbus_t *xbus = xbus_of(i);
@@ -173,11 +171,15 @@ void xpp_tick(unsigned long param)
if(!xpd->card_present)
continue;
xpd->timer_count++;
+ if(SPAN_REGISTERED(xpd))
+ xpp_transmitprep(xpd);
+ if(SPAN_REGISTERED(xpd))
+ xpp_receiveprep(xpd);
+ /*
+ * Must be called *after* tx/rx so
+ * D-Chan counters may be cleared
+ */
CALL_XMETHOD(card_tick, xbus, xpd);
- if(!SPAN_REGISTERED(xpd))
- continue;
- xpp_transmitprep(xpd);
- xpp_receiveprep(xpd);
}
up_read(&xbus->in_use);
}
@@ -229,8 +231,7 @@ static void xpd_free(xpd_t *xpd)
#define REV(x,y) (10 * (x) + (y))
static byte good_revs[] = {
- REV(1,9),
- REV(2,0),
+ REV(2,3),
};
#undef REV
@@ -341,10 +342,10 @@ void card_detected(struct card_desc_struct *card_desc)
if(CALL_XMETHOD(card_init, xbus, xpd) < 0)
goto err;
// Turn off all channels
- CALL_XMETHOD(CHAN_ENABLE, xbus, xpd, ~0, 0);
+ CALL_XMETHOD(XPD_STATE, xbus, xpd, 0);
xpd->card_present = 1;
// Turn on all channels
- CALL_XMETHOD(CHAN_ENABLE, xbus, xpd, ALL_LINES, 1);
+ CALL_XMETHOD(XPD_STATE, xbus, xpd, 1);
if(zap_autoreg)
zaptel_register_xpd(xpd);
@@ -389,6 +390,7 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count, int *eo
(xpd == sync_master) ? "SYNC MASTER" : "SYNC SLAVE",
xpd->timer_count, xpd->span.mainttimer
);
+ len += sprintf(page + len, "Address: U=%d S=%d\n\n", xpd->addr.unit, xpd->addr.subunit);
len += sprintf(page + len, "STATES:");
len += sprintf(page + len, "\n\t%-17s: ", "output_relays");
for_each_line(xpd, i) {
@@ -424,6 +426,7 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count, int *eo
}
#if 1
if(SPAN_REGISTERED(xpd)) {
+ len += sprintf(page + len, "\nzaptel state: %s RUNNING\n", (xpd->span.flags & ZT_FLAG_RUNNING)?"IS":"IS NOT");
len += sprintf(page + len, "\nPCM:\n | [readchunk] | [writechunk] | delay");
for_each_line(xpd, i) {
struct zt_chan *chans = xpd->span.chans;
@@ -437,7 +440,9 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count, int *eo
continue;
if(IS_SET(xpd->digital_inputs, i))
continue;
-#if 1
+ if(IS_SET(xpd->digital_signalling, i))
+ continue;
+#if 0
rp = chans[i].readchunk;
wp = chans[i].writechunk;
#else
@@ -700,8 +705,9 @@ int proc_sync_read(char *page, char **start, off_t off, int count, int *eof, voi
xpp_timer_rate = 0;
now = jiffies;
if(now - xpp_last_jiffies > 0) {
- xpp_timer_rate = ((xpp_timer_count % SAMPLE_TICKS) * 1000) / (now - xpp_last_jiffies);
- len += sprintf(page + len, "tick rate: %4d/second (average over %d seconds)\n", xpp_timer_rate, SAMPLE_TICKS/HZ);
+ unsigned long delta = (now - xpp_last_jiffies);
+ xpp_timer_rate = (xpp_timer_count % SAMPLE_TICKS) * HZ / delta;
+ len += sprintf(page + len, "tick rate: %4d/second (SAMPLE_TICKS=%d)\n", xpp_timer_rate, SAMPLE_TICKS);
}
if (len <= off+count)
*eof = 1;
@@ -893,8 +899,10 @@ static void xpp_transmitprep(xpd_t *xpd)
int channels = xpd->channels;
struct zt_chan *chans = xpd->span.chans;
unsigned long flags;
+ bool digital_telephony;
spin_lock_irqsave(&xpd->lock, flags);
+ digital_telephony = (xpd->type == XPD_TYPE_BRI_NT) || (xpd->type == XPD_TYPE_BRI_TE);
// if((xpd->timer_count % PREP_REPORT_RATE) < 10)
// DBG("%d\n", xpd->timer_count);
@@ -912,7 +920,13 @@ static void xpp_transmitprep(xpd_t *xpd)
zt_transmit(&xpd->span);
spin_lock_irqsave(&xpd->lock, flags);
- for (i = 0; i < channels; i++) {
+ for (i = 0; i < channels; i++, w += ZT_CHUNKSIZE) {
+ /*
+ * We don't copy signalling buffers (they may be
+ * longer than ZT_CHUNKSIZE).
+ */
+ if(IS_SET(xpd->digital_signalling, i))
+ continue;
if (xpd->delay_until_dialtone[i] > 0) {
xpd->delay_until_dialtone[i]--;
if (xpd->delay_until_dialtone[i] <= 0) {
@@ -920,11 +934,12 @@ static void xpp_transmitprep(xpd_t *xpd)
wake_up_interruptible(&xpd->txstateq[i]);
}
}
- if(IS_SET(xpd->offhook, i) || IS_SET(xpd->cid_on, i)) {
+ if(IS_SET(xpd->offhook, i) || IS_SET(xpd->cid_on, i) || digital_telephony) {
+
memcpy((u_char *)w, chans[i].writechunk, ZT_CHUNKSIZE);
- // fill_beep((u_char *)w, 5);
+ // fill_beep((u_char *)w, xpd->addr.subunit, 2);
+ // memset((u_char *)w, pcmtx[xpd->addr.subunit % 4], ZT_CHUNKSIZE);
}
- w += ZT_CHUNKSIZE;
}
// if(xpd->offhook != 0 || sync_master != xpd) {
ret = CALL_XMETHOD(PCM_WRITE, xpd->xbus, xpd, xpd->offhook | xpd->cid_on, writechunk);
@@ -935,21 +950,30 @@ static void xpp_transmitprep(xpd_t *xpd)
spin_unlock_irqrestore(&xpd->lock, flags);
}
-void fill_beep(u_char *buf, int duration)
+void fill_beep(u_char *buf, int num, int duration)
{
- int which = (jiffies/(duration*HZ)) & 0x3;
+ bool alternate = (duration) ? (jiffies/(duration*HZ)) & 0x1 : 0;
+ int which;
+ u_char *snd;
/*
* debug tones
*/
static u_char beep[] = {
-// 0x7F, 0xBE, 0xD8, 0xBE, 0x80, 0x41, 0x24, 0x41, /* Dima */
-// 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, /* silence */
-// 0x67, 0x90, 0x89, 0x90, 0xFF, 0x10, 0x09, 0x10, /* Izzy */
-// 0x67, 0xCD, 0xC5, 0xCD, 0xFF, 0x49, 0x41, 0x49, /* Dima 2 */
+ 0x7F, 0xBE, 0xD8, 0xBE, 0x80, 0x41, 0x24, 0x41, /* Dima */
+ 0x67, 0x90, 0x89, 0x90, 0xFF, 0x10, 0x09, 0x10, /* Izzy */
+ };
+ static u_char beep_alt[] = {
0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, /* silence */
};
- memcpy(buf, &beep[(which*8) % ARRAY_SIZE(beep)], ZT_CHUNKSIZE);
+ if(alternate) {
+ which = num % ARRAY_SIZE(beep_alt);
+ snd = &beep_alt[which];
+ } else {
+ which = num % ARRAY_SIZE(beep);
+ snd = &beep[which];
+ }
+ memcpy(buf, snd, ZT_CHUNKSIZE);
}
#ifdef XPP_EC_CHUNK
@@ -958,9 +982,9 @@ void fill_beep(u_char *buf, int duration)
*/
static inline void xpp_ec_chunk(struct zt_chan *chan, unsigned char *rxchunk, const unsigned char *txchunk)
{
- short rxlin;
- int x;
- unsigned long flags;
+ int16_t rxlin;
+ int x;
+ unsigned long flags;
/* Perform echo cancellation on a chunk if necessary */
if (!chan->ec)
@@ -983,8 +1007,10 @@ static void xpp_receiveprep(xpd_t *xpd)
int channels = xpd->channels;
struct zt_chan *chans = xpd->span.chans;
unsigned long flags;
+ bool digital_telephony;
spin_lock_irqsave(&xpd->lock, flags);
+ digital_telephony = (xpd->type == XPD_TYPE_BRI_NT) || (xpd->type == XPD_TYPE_BRI_TE);
// if((xpd->timer_count % PREP_REPORT_RATE) == 0)
// DBG("%d\n", xpd->timer_count);
@@ -995,20 +1021,27 @@ static void xpp_receiveprep(xpd_t *xpd)
readchunk = xpd->readchunk + ZT_CHUNKSIZE * CHANNELS_PERXPD;
}
- for (i = 0; i < channels; i++) {
- if(IS_SET(xpd->offhook, i) || IS_SET(xpd->cid_on, i)) {
+ for (i = 0; i < channels; i++, readchunk += ZT_CHUNKSIZE) {
+ /*
+ * We don't copy signalling buffers (they may be
+ * longer than ZT_CHUNKSIZE).
+ */
+ if(IS_SET(xpd->digital_signalling, i))
+ continue;
+ if(IS_SET(xpd->offhook, i) || IS_SET(xpd->cid_on, i) || digital_telephony) {
// memset((u_char *)readchunk, 0x5A, ZT_CHUNKSIZE); // DEBUG
- // fill_beep((u_char *)readchunk, 1); // DEBUG: BEEP
+ // fill_beep((u_char *)readchunk, 1, 1); // DEBUG: BEEP
memcpy(chans[i].readchunk, (u_char *)readchunk, ZT_CHUNKSIZE);
} else {
memset(chans[i].readchunk, 0x7F, ZT_CHUNKSIZE); // SILENCE
}
- readchunk += ZT_CHUNKSIZE;
}
#if WITH_ECHO_SUPPRESSION
/* FIXME: need to Echo cancel double buffered data */
for (i = 0;i < xpd->span.channels; i++) {
+ if(IS_SET(xpd->digital_signalling, i)) /* Don't echo cancel PRI/BRI D-chans */
+ continue;
#ifdef XPP_EC_CHUNK
xpp_ec_chunk(&chans[i], chans[i].readchunk, xpd->ec_chunk2[i]);
#else
@@ -1058,12 +1091,15 @@ int xpp_open(struct zt_chan *chan)
{
xpd_t *xpd = chan->pvt;
xbus_t *xbus = xpd->xbus;
+ int pos = chan->chanpos - 1;
unsigned long flags;
spin_lock_irqsave(&xbus->lock, flags);
xbus->open_counter++;
atomic_inc(&xpd->open_counter);
- DBG("chan=%d (open_counter=%d)\n", chan->chanpos, xbus->open_counter);
+ if(IS_SET(xpd->digital_signalling, pos)) /* D-chan offhook */
+ BIT_SET(xpd->offhook, pos);
+ DBG("chan=%d (open_counter=%d)\n", pos, xbus->open_counter);
spin_unlock_irqrestore(&xbus->lock, flags);
return 0;
}
@@ -1072,6 +1108,7 @@ int xpp_close(struct zt_chan *chan)
{
xpd_t *xpd = chan->pvt;
xbus_t *xbus = xpd->xbus;
+ int pos = chan->chanpos - 1;
unsigned long flags;
bool should_remove = 0;
@@ -1079,13 +1116,21 @@ int xpp_close(struct zt_chan *chan)
xbus->open_counter--;
atomic_dec(&xpd->open_counter);
if(xpd->direction == TO_PHONE) { /* Hangup phone */
- xpd->idletxhookstate[chan->chanpos - 1] = FXS_LINE_ENABLED;
+ xpd->idletxhookstate[pos] = FXS_LINE_ENABLED;
}
if (!xbus->hardware_exists && xbus->open_counter == 0)
should_remove = 1;
+ if(IS_SET(xpd->digital_signalling, pos)) /* D-chan onhook */
+ BIT_CLR(xpd->offhook, pos);
spin_unlock_irqrestore(&xbus->lock, flags);
-
- DBG("chan=%d (open_counter=%d, should_remove=%d)\n", chan->chanpos, xbus->open_counter, should_remove);
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
+ /* Clear D-Channel pending data */
+ chan->bytes2receive = 0;
+ chan->eofrx = 0;
+ chan->bytes2transmit = 0;
+ chan->eoftx = 0;
+#endif
+ DBG("chan=%d (open_counter=%d, should_remove=%d)\n", pos, xbus->open_counter, should_remove);
if(should_remove) {
DBG("Going to remove: %s\n", xbus->busname);
xbus_remove(xbus);
@@ -1353,7 +1398,7 @@ static int zaptel_register_xpd(xpd_t *xpd)
DBG("Registering span of %s.\n", xpd->xpdname);
xpd->xops->card_zaptel_preregistration(xpd, 1);
- if(zt_register(&xpd->span, 1)) {
+ if(zt_register(&xpd->span, prefmaster)) {
xbus_t *xbus = xpd->xbus;
ERR("%s/%s: Failed to zt_register span\n", xbus->busname, xpd->xpdname);
return -ENODEV;
@@ -1397,8 +1442,8 @@ int __init xpp_zap_init(void)
int ret;
struct proc_dir_entry *ent;
- INFO("%s revision %s MAX_XPDS=%d\n", THIS_MODULE->name, ZAPTEL_VERSION,
- MAX_XPDS);
+ INFO("%s revision %s MAX_XPDS=%d (%d*%d)\n", THIS_MODULE->name, ZAPTEL_VERSION,
+ MAX_XPDS, MAX_UNIT, MAX_SUBUNIT);
#if WITH_ECHO_SUPPRESSION
INFO("FEATURE: %s (with ECHO_SUPPRESSION)\n", THIS_MODULE->name);
#else
@@ -1409,6 +1454,11 @@ int __init xpp_zap_init(void)
#else
INFO("FEATURE: %s (without XPP_EC_CHUNK)\n", THIS_MODULE->name);
#endif
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
+ INFO("FEATURE: %s (with BRISTUFF support)\n", THIS_MODULE->name);
+#else
+ INFO("FEATURE: %s (without BRISTUFF support)\n", THIS_MODULE->name);
+#endif
#ifdef CONFIG_PROC_FS
xpp_proc_toplevel = proc_mkdir(PROC_DIR, NULL);
diff --git a/xpp/xpp_zap.h b/xpp/xpp_zap.h
index 39608c0..4cd3a8b 100644
--- a/xpp/xpp_zap.h
+++ b/xpp/xpp_zap.h
@@ -34,7 +34,7 @@ void xpd_remove(xpd_t *xpd);
void update_xpd_status(xpd_t *xpd, int alarm_flag);
void update_zap_ring(xpd_t *xpd, int pos, bool on);
void update_line_status(xpd_t *xpd, int pos, bool good);
-void fill_beep(u_char *buf, int duration);
+void fill_beep(u_char *buf, int num, int duration);
void xpp_tick(unsigned long param);
int xpp_open(struct zt_chan *chan);
int xpp_close(struct zt_chan *chan);
diff --git a/xpp/xproto.c b/xpp/xproto.c
index ff91c58..ebd9bba 100644
--- a/xpp/xproto.c
+++ b/xpp/xproto.c
@@ -26,6 +26,7 @@
#include "xbus-core.h"
#include "zap_debug.h"
#include <linux/module.h>
+#include <linux/delay.h>
static const char rcsid[] = "$Id$";
@@ -40,19 +41,19 @@ static const xproto_table_t *xprotocol_tables[XPD_TYPE_NOMODULE];
bool valid_xpd_addr(const xpd_addr_t *addr)
{
- return ((addr->subunit & ~0x1) == 0) && ((addr->unit & ~0x3) == 0);
+ return ((addr->subunit & ~BITMASK(SUBUNIT_BITS)) == 0) && ((addr->unit & ~BITMASK(UNIT_BITS)) == 0);
}
int xpd_addr2num(const xpd_addr_t *addr)
{
BUG_ON(!valid_xpd_addr(addr));
- return addr->unit + addr->subunit * MAX_UNIT;
+ return addr->unit | (addr->subunit << UNIT_BITS);
}
void xpd_set_addr(xpd_addr_t *addr, int xpd_num)
{
- addr->unit = xpd_num % MAX_UNIT;
- addr->subunit = xpd_num / MAX_UNIT;
+ addr->unit = xpd_num & BITMASK(UNIT_BITS);
+ addr->subunit = (xpd_num >> UNIT_BITS) & BITMASK(SUBUNIT_BITS);
}
@@ -224,13 +225,15 @@ out:
void dump_packet(const char *msg, xpacket_t *packet, bool print_dbg)
{
byte op = packet->content.opcode;
+ byte *addr = (byte *)&packet->content.addr;
if(!print_dbg)
return;
- DBG("%s: U=0x%1X S=0x%1X OP=0x%02X LEN=%d\n",
+ DBG("%s: XPD=%1X-%1X (0x%X) OP=0x%02X LEN=%d\n",
msg,
packet->content.addr.unit,
packet->content.addr.subunit,
+ *addr,
op,
(byte)packet->datalen);
#if VERBOSE_DEBUG
@@ -258,6 +261,36 @@ void dump_packet(const char *msg, xpacket_t *packet, bool print_dbg)
#endif
}
+void dump_reg_cmd(const char msg[], reg_cmd_t *regcmd)
+{
+ char action;
+ char mode;
+ byte chipsel;
+ byte regnum;
+ byte data_low;
+ byte data_high;
+
+ if(regcmd->bytes != sizeof(*regcmd) - 1) { /* The size byte is not included */
+ NOTICE("%s: Wrong size: regcmd->bytes = %d\n", __FUNCTION__, regcmd->bytes);
+ return;
+ }
+ action = (REG_FIELD(regcmd, chipsel) & 0x80) ? 'R' : 'W';
+ chipsel = REG_FIELD(regcmd, chipsel) & ~0x80;
+ if(REG_FIELD(regcmd, regnum) == 0x1E) {
+ mode = 'I';
+ regnum = REG_FIELD(regcmd, subreg);
+ data_low = REG_FIELD(regcmd, data_low);
+ data_high = REG_FIELD(regcmd, data_high);
+ } else {
+ mode = 'D';
+ regnum = REG_FIELD(regcmd, regnum);
+ data_low = REG_FIELD(regcmd, data_low);
+ data_high = 0;
+ }
+ DBG("%d %c%c %02X %02X %02X # m=%d eof=%d\n", chipsel, action, mode, regnum,
+ data_low, data_high, regcmd->multibyte, regcmd->eoframe);
+}
+
const char *xproto_name(xpd_type_t xpd_type)
{
const xproto_table_t *proto_table;
@@ -302,7 +335,7 @@ int xproto_register(const xproto_table_t *proto_table)
// CHECK_XOP(card_ioctl); // optional method -- call after testing
CHECK_XOP(SYNC_SOURCE);
CHECK_XOP(PCM_WRITE);
- CHECK_XOP(CHAN_ENABLE);
+ CHECK_XOP(XPD_STATE);
CHECK_XOP(CHAN_CID);
CHECK_XOP(RING);
CHECK_XOP(RELAY_OUT);
@@ -330,6 +363,7 @@ void xproto_unregister(const xproto_table_t *proto_table)
}
EXPORT_SYMBOL(dump_packet);
+EXPORT_SYMBOL(dump_reg_cmd);
EXPORT_SYMBOL(packet_receive);
EXPORT_SYMBOL(valid_xpd_addr);
EXPORT_SYMBOL(xpd_addr2num);
diff --git a/xpp/xproto.h b/xpp/xproto.h
index 7255e09..377c06e 100644
--- a/xpp/xproto.h
+++ b/xpp/xproto.h
@@ -26,6 +26,7 @@
#ifdef __KERNEL__
#include <linux/list.h>
+#include <linux/proc_fs.h>
#include <zaptel.h>
#endif
@@ -38,6 +39,8 @@
*/
#define XPD_TYPE_FXS 3 // TO_PHONE
#define XPD_TYPE_FXO 4 // TO_PSTN
+#define XPD_TYPE_BRI_TE 6 // TO_PSTN
+#define XPD_TYPE_BRI_NT 7 // TO_PHONE
#define XPD_TYPE_NOMODULE 15
typedef byte xpd_type_t;
@@ -52,6 +55,7 @@ typedef byte xpd_type_t;
typedef struct xpd_addr {
byte unit:UNIT_BITS;
byte subunit:SUBUNIT_BITS;
+ byte reserved:(8-UNIT_BITS-SUBUNIT_BITS);
} PACKED xpd_addr_t;
bool valid_xpd_addr(const xpd_addr_t *addr);
@@ -100,15 +104,16 @@ void xpd_set_addr(xpd_addr_t *addr, int xpd_num);
#define PACKET_LEN(p) \
((p)->datalen + sizeof(xpd_addr_t) + 1)
-#define XENTRY(card,op) \
- [ XPROTO_NAME(card,op) ] = { \
- .handler = XPROTO_HANDLER(card,op), \
- .datalen = RPACKET_DATALEN(card,op), \
+#define XENTRY(prototab,module,op) \
+ [ XPROTO_NAME(module,op) ] = { \
+ .handler = XPROTO_HANDLER(module,op), \
+ .datalen = RPACKET_DATALEN(module,op), \
.name = #op, \
- .table = &PROTO_TABLE(card) \
+ .table = &PROTO_TABLE(prototab) \
}
+
#define XPACKET_INIT(p, card, op) \
do { \
p->content.opcode = XPROTO_NAME(card,op); \
@@ -124,6 +129,57 @@ void xpd_set_addr(xpd_addr_t *addr, int xpd_num);
xpd_set_addr(&p->content.addr, to); \
} while(0);
+/*--------------------------- register handling --------------------------------*/
+/*
+ * After the opcode, there are always:
+ * * A size (in bytes) of the rest. Only 6 bits are counted:
+ * - The MSB signifies a multibyte write (to BRI fifo)
+ * - The MSB-1 signifies end of frame to multibyte writes in BRI.
+ * A normal register command (not multibyte) than contains:
+ * * A channel selector byte:
+ * - ALL_CHANS (currently 31) is a broadcast request to set a
+ * register for all channels.
+ * - Smaller numbers (0-30) represent the addressed channel number.
+ * - The MSB signifies:
+ * 1 - register [R]ead request
+ * 0 - register [W]rite request
+ * * Register number
+ * * Subregister number -- 0 when there is no subregister
+ * * Data low
+ * * Data high -- 0 for single byte registers (direct registers)
+ * A multibyte register command than contains a sequence of bytes.
+ */
+
+#define MULTIBYTE_MAX_LEN 5 /* FPGA firmware limitation */
+
+typedef struct reg_cmd {
+ byte bytes:6;
+ byte eoframe:1; /* For BRI -- end of frame */
+ byte multibyte:1; /* For BRI -- fifo data */
+ union {
+ struct {
+ byte chipsel:CHAN_BITS; /* chip select */
+ byte reserved:1;
+ byte do_subreg:1;
+ byte read_request:1;
+ byte regnum;
+ byte subreg;
+ byte data_low;
+ byte data_high;
+ } PACKED r;
+ /* For Write-Multibyte commands in BRI */
+ struct {
+ byte xdata[MULTIBYTE_MAX_LEN];
+ } PACKED d;
+ } PACKED alt;
+} PACKED reg_cmd_t;
+
+/* Shortcut access macros */
+#define REG_FIELD(regptr,member) ((regptr)->alt.r.member)
+#define REG_XDATA(regptr) ((regptr)->alt.d.xdata)
+
+/*--------------------------- protocol tables ----------------------------------*/
+
typedef struct xproto_entry xproto_entry_t;
typedef struct xproto_table xproto_table_t;
@@ -157,9 +213,9 @@ struct xops {
int (*SYNC_SOURCE)(xbus_t *xbus, xpd_t *xpd, bool setit, bool is_master);
int (*PCM_WRITE)(xbus_t *xbus, xpd_t *xpd, xpp_line_t offhook, volatile byte *buf);
- int (*CHAN_ENABLE)(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, bool on);
- int (*CHAN_CID)(xbus_t *xbus, xpd_t *xpd, int pos);
- int (*RING)(xbus_t *xbus, xpd_t *xpd, int pos, bool on);
+ int (*XPD_STATE)(xbus_t *xbus, xpd_t *xpd, bool on);
+ int (*CHAN_CID)(xbus_t *xbus, xpd_t *xpd, lineno_t chan);
+ int (*RING)(xbus_t *xbus, xpd_t *xpd, lineno_t chan, bool on);
int (*RELAY_OUT)(xbus_t *xbus, xpd_t *xpd, byte which, bool on);
};
@@ -177,7 +233,7 @@ struct xproto_table {
xpd_type_t type;
const char *name;
bool (*packet_is_valid)(xpacket_t *pack);
- void (*packet_dump)(xpacket_t *pack);
+ void (*packet_dump)(const char *msg, xpacket_t *pack);
};
#include "card_global.h"
@@ -188,12 +244,15 @@ enum opcodes {
XPROTO_NAME(GLOBAL, NULL_REPLY) = 0xFE,
XPROTO_NAME(GLOBAL, DESC_REQ) = 0x04,
XPROTO_NAME(GLOBAL, DEV_DESC) = 0x05,
+ XPROTO_NAME(GLOBAL, REGISTER_REQUEST) = 0x0F,
/**/
XPROTO_NAME(GLOBAL, PCM_WRITE) = 0x11,
XPROTO_NAME(GLOBAL, PCM_READ) = 0x12,
/**/
XPROTO_NAME(GLOBAL, SYNC_SOURCE) = 0x19,
XPROTO_NAME(GLOBAL, SYNC_REPLY) = 0x1A,
+/**/
+ XPROTO_NAME(GLOBAL, ERROR_CODE) = 0x22,
};
@@ -209,14 +268,13 @@ struct xpacket_raw {
MEMBER(GLOBAL, PCM_WRITE);
MEMBER(GLOBAL, PCM_READ);
MEMBER(GLOBAL, SYNC_REPLY);
+ MEMBER(GLOBAL, ERROR_CODE);
MEMBER(FXS, SIG_CHANGED);
- MEMBER(FXS, SLIC_REPLY);
- MEMBER(FXS, SLIC_WRITE);
+ MEMBER(FXS, REGISTER_REPLY);
MEMBER(FXO, SIG_CHANGED);
MEMBER(FXO, DAA_REPLY);
- MEMBER(FXO, DAA_WRITE);
byte data[0];
};
@@ -230,6 +288,7 @@ struct xpacket {
};
void dump_packet(const char *msg, xpacket_t *packet, bool print_dbg);
+void dump_reg_cmd(const char msg[], reg_cmd_t *regcmd);
int packet_receive(xbus_t *xbus, xpacket_t *pack);
int xproto_register(const xproto_table_t *proto_table);
void xproto_unregister(const xproto_table_t *proto_table);