Compare commits

...

58 Commits

Author SHA1 Message Date
David Given
73419704c2 Merge pull request #118 from davidgiven/fixing
Fix a few minor build tweaks.
2019-12-13 23:56:12 +01:00
David Given
a8b92d4780 This works; final tweaking. 2019-12-13 23:53:42 +01:00
David Given
98140b0646 More testing. 2019-12-13 23:50:33 +01:00
David Given
4429ce1f84 More build tweaks. 2019-12-13 23:48:17 +01:00
David Given
1f50941a2c Merge from trunk. 2019-12-13 23:45:17 +01:00
David Given
a7de04848c Merge pull request #117 from davidgiven/githubci
Convert to Github CI instead of Travis.
2019-12-13 23:43:03 +01:00
David Given
c264fec6e9 The Windows stuff doesn't work, so let's shelve it for now. 2019-12-13 23:38:49 +01:00
David Given
4488b2542f Update MSYS build environment. 2019-12-13 23:24:23 +01:00
David Given
2f1a5189d6 Oh, yeah, let's actually check out our project! 2019-12-13 23:21:58 +01:00
David Given
effaeff51e Something's not right --- test. 2019-12-13 23:19:48 +01:00
David Given
1210549f59 Try Windows builds on github. 2019-12-13 23:12:29 +01:00
David Given
7200de9702 Add more Homebrew packages. 2019-12-13 23:02:13 +01:00
David Given
5dd5c8516a Don't do builds on push_request, because these always coincide with pushes. 2019-12-13 23:01:08 +01:00
David Given
f7fb2a844b Github's OSX doesn't install pkg-config by default? 2019-12-13 23:00:10 +01:00
David Given
20b1b2a4a8 More YAML syntax fiddling? 2019-12-13 22:58:28 +01:00
David Given
f8b8bc2295 Fiddle with YAML syntax. 2019-12-13 22:57:29 +01:00
David Given
2d4d56d09f Try Github CI for OSX builds instead of Travis. 2019-12-13 22:55:37 +01:00
David Given
39599b76c8 Stop building the Ubuntu version with Travis. 2019-12-13 22:52:30 +01:00
David Given
c2c40ccfbb Also remember to install ninja-build. 2019-12-13 22:48:48 +01:00
David Given
ab42eb23f4 Remember to run apt as sudo. 2019-12-13 22:47:20 +01:00
David Given
05eff0e528 Try to build using github CI. 2019-12-13 22:44:58 +01:00
David Given
23311b4b68 Start looking at Github CI. 2019-12-13 22:41:19 +01:00
David Given
5e97df8d15 Better diagnostics when a package can't be found. 2019-12-13 22:39:58 +01:00
David Given
898e8c551c Produce a build-time error if the pkg-config packages aren't available. 2019-12-13 22:34:24 +01:00
David Given
ad69c6bd27 Fix stupid (but thankfully harmless) typo. 2019-12-13 22:33:39 +01:00
David Given
661399cc83 Update document with the new flippy mod doc; explain how Mac disks are broken. 2019-12-12 21:04:42 +01:00
David Given
edbb4b1daa Merge pull request #115 from davidgiven/reading
Rewrite the entire sampler.
2019-12-12 20:46:12 +01:00
David Given
6389e8a756 Update pin number (which was wrong). 2019-12-12 20:35:20 +01:00
David Given
c187b79d80 Add a 300RPM clock on 3[0] and a 360RPM clock on 3[1], for use with faking
index pulses to the drive.
2019-12-12 20:34:44 +01:00
David Given
edbe624c5a Hopefully, finally, fix the hang-on-read issue. 2019-12-12 20:09:49 +01:00
David Given
44e2334815 Typo fix. Make sure that both drives get deselected when the motor stops (to
make the LEDs go out).
2019-12-12 00:17:59 +01:00
David Given
b448ab7917 Finally squeeze everything in to the Verilog sampler. It does seem to work
better... the the USB hangup problem persists. Mac disks are still
nigh-unreadable.
2019-12-12 00:12:20 +01:00
David Given
072a097003 Archival (non-functioning) checkin of Verilog-based sampler code. Sadly, we've
run into size limits for the device, and I need to slim down.
2019-12-11 22:51:27 +01:00
David Given
a66e704bab Start ripping out the awful UDB-based sampler code, replacing it with a Verilog
one and a standalone FIFO. This gets the FIFO working.
2019-12-11 21:13:57 +01:00
David Given
ed0d578b18 Merge pull request #114 from davidgiven/fixing1
Add support for measuring signal line voltages.
2019-12-11 00:28:13 +01:00
David Given
32bb956710 Detect voltage levels *correctly*. 2019-12-11 00:05:34 +01:00
David Given
f436d6b582 Add a feature where we can measure the FDD bus signal voltages using the PSoC's
ADCs. Increase the track step pulse width to 6us, because.
2019-12-10 22:36:18 +01:00
David Given
8ee6eed4dc Merge pull request #112 from davidgiven/fixing
Rework the sequencer completely, because bizarrely writing disks just stopped working
2019-11-29 22:02:44 +01:00
David Given
3094c5c919 Add missing files. 2019-11-29 18:49:22 +01:00
David Given
1e012699af Clean up the Verilog a bit. 2019-11-25 20:54:13 +01:00
David Given
91d6e9aeb9 Rewrite the sequencer engine with a separate fifo component and a pure verilog
sequencer --- much easier to understand. We can write disks again!
2019-11-25 20:52:13 +01:00
David Given
a40b26ff46 Archival checkin for trying to figure out why writes no longer work. 2019-11-24 15:14:32 +01:00
David Given
ebcb9c4bb0 Switch the output lines to open-drain drive low. 2019-11-24 02:06:45 +01:00
David Given
2520834b18 Add the brother240tool program. 2019-11-24 01:46:02 +01:00
David Given
a1f3087046 Add an 8" drive datasheet. 2019-11-24 01:45:43 +01:00
David Given
e9670e205e Don't erroneously crash out if the t and s parameters are omitted from the rpm
command.
2019-10-14 22:25:43 +02:00
David Given
658e2b7295 Properly initialise flags.
Fixes: #109
2019-09-22 21:55:37 +02:00
David Given
7b4a8d6de2 Merge pull request #108 from davidgiven/scp
Add very beta support for scp import and export
2019-09-21 22:32:52 +02:00
David Given
e8f7b51aef Another documentation tweak. 2019-09-21 22:15:44 +02:00
David Given
9d6bc57a5f Update documentation. 2019-08-31 12:32:52 +02:00
David Given
73766f92b4 Fix the flux to scp converter. 2019-08-31 12:31:33 +02:00
David Given
80badf3b54 Remember to check in the build file changes... 2019-08-31 12:09:11 +02:00
David Given
116529f85a Archival, non-working checkin of the flux to scp converter (it appears to
produce garbage).
2019-08-31 01:41:11 +02:00
David Given
5a2b2bc07a Allow support for command lines with non-argument filenames. 2019-08-31 01:40:44 +02:00
David Given
41070395c0 Merge pull request #105 from davidgiven/scp
Add conversion support for Supercard Pro scp files.
2019-08-28 23:52:27 +02:00
David Given
4304d1eede Add the Supercard Pro decoder. 2019-08-28 23:32:09 +02:00
David Given
46f1b0aef4 Merge pull request #104 from davidgiven/sampler
Fix a nasty sampler bug leading to corrupted data
2019-08-28 00:23:21 +02:00
David Given
c266779433 Fix a bug where index pulses where being turned into flux pulses on read,
leading to completely broken data whenever an index pulse happened.
2019-08-27 23:58:07 +02:00
46 changed files with 3918 additions and 2506 deletions

34
.github/workflows/ccpp.yml vendored Normal file
View File

@@ -0,0 +1,34 @@
name: C/C++ CI
on: [push]
jobs:
build-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: apt
run: sudo apt install libusb-1.0-0-dev libsqlite3-dev ninja-build
- name: make
run: make
build-macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v1
- name: brew
run: brew install sqlite pkg-config libusb ninja
- name: make
run: make
# build-windows:
# runs-on: windows-latest
# steps:
# - uses: numworks/setup-msys2@v1
# with:
# msystem: MSYS
# - uses: actions/checkout@v1
# - name: pacman
# run: msys2do pacman -S --noconfirm --needed make ninja mingw-w64-i686-libusb mingw-w64-i686-sqlite3 mingw-w64-i686-zlib mingw-w64-i686-gcc zip
# - name: make
# run: msys2do make

View File

@@ -1,39 +0,0 @@
language: shell
git:
depth: 1
matrix:
include:
-
os: linux
sudo: false
dist: xenial
compiler: gcc
env: CXX=g++-8
script:
- make
-
os: osx
osx_image: xcode10.2
compiler: clang
env:
- HOMEBREW_NO_INSTALL_CLEANUP=1
addons:
apt:
sources:
- llvm-toolchain-precise-3.8
- ubuntu-toolchain-r-test
packages:
- ninja-build
- libusb-1.0-0-dev
- libsqlite3-dev
- g++-8
homebrew:
packages:
- ninja
script:
- make

View File

@@ -1,244 +1,244 @@
:4000000000800020110000005D0D00005D0D0000064A08B5136843F020031360044B1A6803F53F5302331A6000F0B6FEE8460040FA46004010B5054C237833B9044B13B19E
:400040000448AFF300800123237010BD6081FF1F00000000242E0000084B10B51BB108490848AFF300800848036803B910BD074B002BFBD0BDE81040184700BF00000000F7
:400080006481FF1F242E0000C880FF1F0000000072B6034A13680133136062B6704700BF8081FF1F0A4A0B4B516801310B40002BBEBF03F1FF3363F00F030133536051688E
:4000C0009368994202BF024B01221A73704700BF8081FF1F0F0000800A4A0B4B916801310B40002BBEBF03F1FF3363F00F030133936091685368994202BF024B01221A7381
:40010000704700BF8081FF1F0F000080024B012200205A7302F024B98081FF1F10B5C4B2204601F007FA0128FAD110BD70B5C4B220460E4601F006FA314605460246204646
:4001400001F066FA204601F0F5F90128FAD0284670BD000038B5094CA57B3DB9012002F0A5F84FF47A7000F08FFFE573236823610123A373BDE8384000F0C4BF8081FF1F58
:4001800038B50446C5B2284602F09CF8012000F091FF44F00200C0B202F094F8012000F089FF284602F08EF8BDE83840062000F06BBF000038B5044D0024285D013400F0EE
:4001C00029FF102CF9D138BD9481FF1F0FB400B593B014AB53F8042B402102A8019302F013FA02A802F04DF802F057F813B05DF804EB04B07047000010B5044601780648AD
:40020000FFF7E4FF0420FFF789FF62782146BDE81040042001F0AAB9362E000007B50023ADF804308DF80600032301A88DF80530FFF7E2FF03B05DF804FB0000F8B5234C6B
:400240000646FFF787FFE37B93B92148FFF7BEFF02F032F818B90120FFF792FFF8E70120FFF78EFF01200023E073636200F022FF3246616A1748FFF7A9FF144D0027636AD6
:400280009E421BD002F018F828B16B6A13B11248FFF79CFF6762636A9E4205DD0020FFF76FFF6B6A013305E005DA0120FFF768FF6B6A013B6B6200F025FFE0E7322000F0F2
:4002C000E3FEBDE8F8400548FFF780BF8081FF1F432E00004A2E0000672E0000852E00002DE9F04F97B062B600F076FFBE49042000F09AFFBD4801F0EBFFBD4802F018F8BA
:40030000BC4802F061F8002002F030F801F0B8FF0221002001F0C4F8B74D0321084600F0D1FE2E462C4600F0EDFEAB7B5BB12A692B689B1A41F28832934204D9002001F0E9
:40034000B5FF0023AB7301F0E3F818B9AB48FFF73DFF04E001F0E2F80028F7D109E001F0D7F80028FBD0A648FFF730FF032001F03BF9032001F0DEF80128D4D1A14903206B
:40038000FFF7D4FE94F828109F48FFF71FFF94F82830023B102B00F24B83DFE813F0110049031A00490320004903380049035C004903A4014903100349032F0349033B0369
:4003C00003238DF818308DF8193008238DF81A301CE394F82A00FFF731FF8C4B13E3FFF7B9FE00236373637B002BFCD0002373733268637B002BFCD0336807218DF8181037
:400400009B1A04218DF81910ADF81A30FEE20220FFF784FE4FF000090DF1180A4FF480780027C8EB0903DA1907F80A200137402FF9D10220FFF772FE3A465146022001F003
:4004400095F8B8F10108EBD109F10109B9F1400FE4D16F4BAEE294F82A0001F07BFF606AFFF7ECFE012001F087FF01F0D9FF694BDFF8A8811A78002742F004021A701A7898
:4004800042F001021A701A7802F0FE021A701A7802F0FE021A7001F0C7FF0220FFF73EFE41F6FF734FF480420121022001F024FF84F8680000F094FD08F807000137102F6D
:4004C000F8D1DFF85CA100270AF15D081FFA88F90137102F14BF3A4600221AF8010F22440623127D402100F0AFFD4A4646F24C419AF8000000F0BAFD09F14009102F1FFAEC
:4005000089F9E5D14448FFF761FE00237373637B002BFCD000271422394606A87773DFF8049102F03EF84023099338464FF0FF337760CDF82090B360377301F01DFF012097
:4005400001F060FF736896F868003344197D00F0FFFC96F8680000F0BDFC012196F8680000F090FC636813B96B7B002BFAD0002794F82BA0A76094F80CB0BBF1000F6CD1F8
:4005800000F0C0FD6B7B43B1BAF1010A85F80DB003D162E02B7B002B5FD1A26863689A42F8D04FF0000BA36806A808EB83135B440693CBF14003079300F054FA079B0137BF
:4005C000C3F140039B44099B5FFA8BFB002B34D1022000F0AFFF012826D0637B002B3CD12B7B002BF4D038E0910000000D010000A5000000D90000008081FF1F932E0000D3
:40060000A62E0000A881FF1FB02E0000282E00002A2E00009C640040BF2E00009481FF1F9381FF1FF085FF1F4022BE49022000F09DFF4023CDF820900993BBF13F0FB2D9DE
:40064000A268B94B01321340002BBEBF03F1FF3363F00F030133A3608DE7002001F0D2FE042194F8680000F07FFC94F8680000F08BFC0028F9D106A800F028FA0220FFF76E
:400680004DFDDDF82480B8F1400F06D0C8F1400292B2A449022000F069FF099A32F0400203D11146022000F061FF0220FFF736FDFFF780FD237B33B19C48FFF787FD02209F
:4006C000FFF7ACFD06E09A4B05A81B88ADF81430FFF792FD627B3946237B9648CDF80080FFF774FDA7E1E76A17F03F0701D003209FE195F82A0001F02DFE012001F042FE8F
:4007000001F08EFE8C4BDFF834821A7802F0FB021A701A7842F001021A701A7802F0FE021A701A7802F0FE021A7001F07DFE686AFFF784FD01214FF4804341F6FF7208468D
:4007400001F026FE85F8680000F04AFC08F807000137102FF8D1DFF8E891002709F15D031FFA83F803930137102F14BF3A46002219F8010F22440523127D402100F064FC2C
:40078000414646F24A4299F8000000F06FFC08F14008102F1FFA88F8E5D1F36A00279B09142239464FF0FF3806A877600293C6F80880377301F0F5FE402301200993B946D3
:4007C00000F012FFBA466268574B01321340002BBCBF03F1FF3363F00F03A168B8BF01338B4200F08F80BAF1000F07D0237B002B40F0A8806B7B002B40F0A480079B002B71
:4008000034D1B9F1000F0BD07F2246495A540133402BFAD10691079328E0BAF1000F06D1012000F087FE01288346F6D107E0237B002B40F087806B7B002BF1D082E0394921
:40084000FFF774FC8146374B07905846069300F0CBFEB9F13F0F07F1010706DD029BDB1BD3F1000949EB030900E0D946079BDBB16368039A06A802EB8312099BC3F1400367
:400880001344089300F031F9099B6BB96A68264B01321340002BBEBF03F1FF3363F00F030133636040230993A36801332AD16B680F2B27D14FF00008C5F8088001F096FD23
:4008C00085F80C80AB6895F868002B44197D00F03FFB95F8680000F0FDFA012195F8680000F0D0FA85F80D80637B002BFCD04FF00008012086F80D8001F032FD404601F022
:4009000041FD02E0BAF1000F05D0237BD3B96B7BC3B94FF0010AA36843453FF454AFD5F8088050E7F085FF1F0F000080C42E00002C2E0000DE2E00009A6400409481FF1FF2
:400940009381FF1F01F058FD012001F01BFD002001F006FD042194F8680000F005FB94F8680000F011FB0028F9D196F8680000F09FFAB9F1000F16D1029BBB420ADD012015
:4009800000F0D8FD01288046F6D12E49FFF7CEFB3F2803DC012000F061FE04E0404600F023FE0137E8E7FFF705FC237B0BB102203FE0254B1B8805A8ADF8143027E094F880
:4009C0002A0001F0C7FC606AFFF738FC1F48FFF7FDFB00236373637B002BFCD0012001F0BFFC00237373637B002BFCD0002001F0B7FC1748FFF7EAFB164B04E00020E073A1
:400A0000FFF71CFC144B1B88ADF8183006A8FFF7F3FB10E094F82A0094F8B034834205D085F8B00401F0A2FC0023EB730B4BEAE70120FFF7F3FB032000F0D6FD0848FFF7DE
:400A4000C5FB70E4F085FF1F2E2E0000F72E0000052F0000302E0000322E0000342E0000122F000010B54268002A2ED0C368002B2BD00368048A591C01601B78013A13F031
:400A8000800F817C42601DBF03F0010242EA84030231083114BF43F0020343EA0423817414BF03820382837C072BDCD9028A083B42FA03F38268511C81601370C368013BDD
:400AC000C360837C083B8374CDE710BD07B5827C42B102AA002102F8011D026001224260FFF7C0FF03B05DF804FB30B543686BB3C2685AB3827C072A0CD8046890F9105057
:400B0000611C01602178013B41EA05210832018243608274827C018AA2F108042141CBB2090608D5C3F3801363F07F03023A03F08103827402E08474002BD7D08268511C9E
:400B400081601370C368013BC360CFE730BD0000F8B572B6634B61221A70A3F5F06301221A80192406229C7083F88022522203F5C0731A705C4B5D4A1B785D4EDBB2137059
:400B800040F618025B4B00251A8041F2512223F8022C33784FF4F07003F0010343EA450501F036FC013C05F0030521D0032DF0D1514B4FF480721A8007221A704F4A0024BB
:400BC00048211470917002221C705C7103F8032C4B4A4C4D1378062643F001031370414B01221A70484A137843F02003137000E0FEE706FB045300219A881868013401F08C
:400C0000D0FC082CF5D180224049414801F0BEFC404D4148002450F8041F04F1105303F1400221F0FF064133C9B20B4452005B0002329A4206D012F8027C12F801EC07F8F7
:400C400006E0F5E7A8420C44E5D1344B00221A60334B34491A68344B344C1A60344A137843F002031370137C43F002031374314B1A7842F040021A700A7842F010020A7053
:400C80002D4A07CA03C42D49228008682C4A28341060097911712B4A07CA03C422802A4AE83C07CA03C42280284A083407CA03C4274922800A78A4F6785442F008020A70E0
:400CC000244A01F5AA5112780C31D2B202F00700120908704A70204A442111700FCB07C42380F8BD004800400F010049A1460040254200402242004004400040064000405A
:400D0000A2430040172F0000E846004054050048000C01407C000048FCFFFF47007600400C060048C243004008760040C051004003500140A0430040D4050048E00500487E
:400D4000CB510040E8050048F40500480006004822430040CF0100497658004008B501F0E9FB03680C2B00D1FEE7FEE7084908B50B68084A1844821A802A01DC086005E019
:400D800001F0D8FB0C2303604FF0FF33184608BDCC80FF1F1087FF1F80B51148114B0025C0B1A3F1100192C922460439161BB74204D051F8046F42F8046BF7E7114653F822
:400DC000046C8C1AA64202D041F8045BF9E701381033E5E701F0B4FBFFF782FAFEE700BF01000000D8300000124A134B10B51A60124A134C1368134843F4007313600023DA
:400E0000032B98BF54F823204FEA830188BF0E4A0133302B4250F3D10C4B1A780C4B1A700C4B084A1A60FFF793FEBDE8104000F013B800BF0004FA050CED00E014ED00E0BD
:400E4000000000000080FF1F5D0D0000BC760040C080FF1F08ED00E0074A7F23802113705170064A013BDBB202F80839002BF9D1034A1370704700BFD080FF1FF87B00403D
:400E80000078004017280FD8084B0001C25C11B142F0200201E002F0DF02C254C25C42F00102C25400207047012070471070004017280BD8064B0001C25C02F0FE02C25490
:400EC000C25C02F0DF02C25400207047012070471070004017280DD8074900010B4603441A7942F004021A71435C43F00103435400207047012070471070004017280BD81B
:400F0000064A0001835C490003F0F10301F00E011943815400207047012070471070004041F6FF73994208BF4FF400519A4208BF4FF4005217289FBFC00000F1804000F597
:400F4000EC4081809ABFC280002001207047000017289FBF034B00011954002088BF0120704700BF1970004017289FBF054B00011A5C01F007019DBF1143195400200120D6
:400F8000704700BF1470004017289FBF034B0001185C00F0070088BFFF20704714700040172810B51AD8C00001F07F0100F1804441EAC21204F5EC44D2B222709DF80820E8
:400FC00003F00F0343EA0213DBB263709DF80C30002003F00F03A370E07010BD012010BD10B501F01DFA0A4A5378182B0AD91478013B5370E30003F1804303F5F0431B7841
:40100000137000E0FF2401F00FFA204610BD00BFD080FF1F030610B5044611D401F000FA084AE300117803F1804303F5F04319705378147001335370BDE8104001F0F4B9E6
:4010400010BD00BFD080FF1F30B504060CD411F4704509D1C40004F1804404F5F0442180A270E370284630BD012030BD03065FBFC00000F1804000F5F04081805ABFC280E1
:40108000002001207047000038B50446084DB4F5004F05D9286801F0BBF9A4F50044F6E7034B58686043BDE8384001F0B1B900BFD880FF1F024B1B7A584301F0A9B900BFFA
:4010C000D880FF1F0E4B00F003001A78490102F0FC02104318701A7801F0600142F080021A701A7802F07F021A701A7802F09F020A431A701A7842F010021A70704700BF04
:4011000083430040014B01221A70704784430040044B00F00F021B6853F8220043F82210704700BF08ED00E0054A00F01F00126800F1100352F8230042F82310704700BFCE
:4011400008ED00E000F01F0000F16040490100F56440C9B2017070470F4B10B50F4900240F205C609C60DC601C615C61FFF7D0FF0B4A136843F0040313600A4B4FF47A72B6
:40118000DB68B3FBF2F3084A1360084B4FF400421C60C3F8E82010BD3486FF1F0512000010E000E0D880FF1F14E000E018E000E0024A136843F002031360704710E000E0D6
:4011C00008B5FFF7F5FF034A136843F00103136008BD00BF10E000E010B5054CA3691BB9FFF7BAFF0123A361BDE81040FFF7E8BF3486FF1F024B1868C0F30040704700BF15
:4012000010E000E038B5FFF7F5FF012808D1054D002455F8243003B198470134052CF8D138BD00BF3886FF1F024B03EB80035868596070473486FF1F134B144A1B78DBB2FA
:401240000360127843EA0223114A0360127843EA0243104A0360127843EA026303600E4B0E4A1B78DBB24360127843EA02230C4A4360127843EA02430A4A4360127843EA46
:4012800002634360704700BF0301004904010049EC4600400201004901010049000100490501004906010049F8B501F0B9F8444A01271378022643F001031370137C414C95
:4012C00043F001031374404B02F5E3521F700B3203F8946C1378054603F07F0313700020FFF7E8FE2378394A03F0F90323701378384603F0DF03137023783B432370FFF745
:40130000D9FE2820FFF7D6FE314B30461A7802F07F021A701A7802F0BF021A70237833432370FFF7C7FE23782A4A43F004032370002313702846537001F076F807211720A4
:40134000FFF700FF24491720FFF7EEFE07211820FFF7F8FE21491820FFF7E6FE07211520FFF7F0FE1E491520FFF7DEFE07210320FFF7E8FE1B490320FFF7D6FE07210420B7
:40138000FFF7E0FE18490420FFF7CEFE07210520FFF7D8FE15490520FFF7C6FE07210620FFF7D0FE12490620FFF7BEFE07210C20FFF7C8FEBDE8F8400E490C20FFF7B4BE9F
:4013C000A5430040944300409D60004012600040F851004084600040031B00003D190000011B0000351A0000611A0000911A0000C91A0000071B000008B51D4B1D4A1870F4
:40140000002313701C4A13701C4A13701C4A13701C4A13701C4A13701C4A13701C4B4FF400021A604FF080721A604FF400121A6008221A6010221A6020221A6040221A6008
:40144000144B19B91A7802F0FE0202E01A7842F001021A70104B03221A70802203F8202C012000F0D5FF0D4B04221A7008BD00BF6C86FF1F7286FF1F7086FF1F7186FF1FD1
:401480006D86FF1F5C86FF1F6F86FF1FE486FF1F00E100E009600040286000401260004070B5074C054623780E461BB9FFF7FCFE0123237031462846BDE87040FFF79CBFE4
:4014C0005086FF1F0A4A002313700A4A13700A4A13700A4A13700A4A13700A4A13700A4A13700A4B03221A70802203F8202C70477286FF1F7086FF1F7186FF1F6D86FF1F00
:401500005C86FF1F6F86FF1FE486FF1F28600040014B1878704700BF7186FF1F044B1A7802F0FF001AB118780022C0B21A7070477086FF1F024A0C2303FB002040787047C3
:401540007886FF1F431E072B0CD8074A064B00010344805C5B7800F00F0043EA0020023880B2704700207047FC5F0040431E072BF0B531D8194B0C2505FB0035EC88184F78
:40158000A4B2C4F50074A2424FF00C0404FB003488BFEA88E67884BFC2F5007292B2104C46EA12260501EE552C44D6B2667041B90C2202FB0030002343704379DBB2A37019
:4015C000F0BD0E46074F2F44751AADB2AA42EFD916F8015B3D72F7E7F0BD00BF7886FF1FFC5F004070600040431E072B0AD8064A0C2303FB002300225A705A79034BD2B2AF
:4016000000011A54704700BF7886FF1FFE5F004038B505461446D1B1431E072B19D8FFF791FFA04203D22846FFF78CFF04460A4609482B011844531A9BB29C4203D9037AE4
:4016400002F8013BF7E72846FFF7CEFF02E00C4600E00024204638BD70600040431E072B9FBF024B000108221A547047FE5F004030B51A4A1A491B4D0878138803449BB294
:401680001380194A00231488D8B2A4B27CB1082B0CD050680078C0B2E85450680133013050601088013880B21080ECE718460B780E4C082B0E4A00D040B10E4D2B7883F050
:4016C00080032B700F232370022301E0022323701370094B1870087030BD00BFE886FF1FE486FF1F006000406086FF1F5D86FF1F7286FF1F6E86FF1FE586FF1F074B0222E6
:401700001A70074B80221A70064B0F221A70064A00231370054A0120137070477286FF1F6E86FF1F5D86FF1FE486FF1FE586FF1F30B5164B16491B780A8803F00F03023BAF
:40174000DBB21A4492B20A80124C134A0020118889B279B173B15568215C013BC9B229705168DBB20131516011880130013989B21180ECE7094A1370094A137883F08003B3
:401780001370084B0B221A7030BD00BF29600040E886FF1F006000406086FF1FE586FF1F6E86FF1F5D86FF1F064A06231370064A01201370054B80221A70054B00221A70F3
:4017C000704700BF7286FF1F5D86FF1F6E86FF1FE586FF1F054B9A683AB19A68044910709A680988518000229A6070476086FF1FE886FF1F08B5124B1A78D2B21A701B78A1
:40180000DBB21A0602D50F4A137008BD0220FFF7E1FF0D4B1B7803F06003202B05D0402B06D043B900F0D4FB04E000F057FE01E000F008FD10B9034B03221A7008BD00BFE5
:40184000286000405D86FF1F0060004008B5084A084B0120197813880B449BB21380064B00221A70FFF7B6FF044B03221A7008BDE886FF1FE486FF1F7286FF1F5D86FF1F8B
:4018800008B50C4B1B78DBB2042B07D0062B09D0022B0DD1BDE80840FFF7D8BFBDE80840FFF746BF0320FFF795FF034B03221A7008BD00BF7286FF1F5D86FF1F08B5054B25
:4018C000002201201A70FFF785FF034B03221A7008BD00BF7286FF1F5D86FF1F08B50A4B1A7832B11A78094942F080020A7000221A70074B002201201A70FFF76BFF054BF5
:4019000003221A7008BD00BF5C86FF1F086000407286FF1F5D86FF1F074B1B78DBB2042B05D0062B05D0022B05D1FFF7A1BEFFF7C5BFFFF7D3BF70477286FF1F38B51D4CBC
:401940002378DBB2DD0634D518060AD503F00F03012B2ED1FFF74EFF174B1B78190609D538BD5A0602D5FFF7D7FF03E09D0620D5FFF786FF23781B061BD4104B1A78104B10
:401980001B7813430F4A13701278934211D10A4A0849154613782078DBB2000605D41378DBB20B700B7803F00F0328788342F1D138BD38BD286000405D86FF1F6E86FF1F8B
:4019C000E586FF1F29600040054A00231380054A916819B191680B7092685380704700BFE886FF1F6086FF1F0E4808B503889BB213B9FFF783FE13E00B4B02221A700B4BBC
:401A000000221A70FFF7E0FF094AD1799379028843EA012392B2934238BF0380FFF728FE012008BD6086FF1F7286FF1F6E86FF1F00600040084B01221A700F3B9B7C074B8D
:401A40001A7B02F00302012A1EBFDA7B82F08002DA7301225A7370470B6000407886FF1F094B02221A700F3B93F82230074B1A7E02F00302012A1EBFDA7E82F08002DA7620
:401A800001225A76704700BF0B6000407886FF1F0B4B04221A700F3B93F83230094B93F8242002F00302012A1EBF93F8272082F0800283F82720012283F82520704700BFB6
:401AC0000B6000407886FF1F0B4B08221A700F3B93F84230094B93F8302002F00302012A1EBF93F8332082F0800283F83320012283F83120704700BF0B6000407886FF1FD4
:401B00007047FFF7DFBC00F0B3BB000070B50446184B88B003AA03F11006154618685968083303C5B3422A46F7D11B782B70FCB12223237001AD032328466370FFF77CFB3D
:401B4000002220461146AB5C08AC04EB131414F8144C03F00F03847008AC234413F8143C0132082AC1700371417100F10400EAD108B070BD472F00002DE9F0411A4D012242
:401B80002E460C2080274FF0080E184B00FB025C14012344187016499CF805802144B8F1000F07D09CF8044024064CBF887081F802E000E08F7000FB0261CC880132E4B2A3
:401BC0009C71CC88092AC4F30724DC71CC88E4B21C71C988C1F307215971D6D1054BFF221A70BDE8F08100BF7886FF1F70600040FC5F00400A600040064B074A1B7802EBAA
:401C0000C30253681A7C824286BF03EBC0035869002070476C86FF1F942F00002DE9F84F424B1A78002A7ED01878414D0138C0B2FFF7E2FFA8463F4AC3681478007ADFF856
:401C400000C1E4B203EBC0000C2600274FF0010E834268D01A78A24263D11CF80420597891425ED19A7893F8039002F07F0206FB02FA05EB0A01CF7093F802B009F00309EA
:401C800081F804B093F803B005F80AB0B3F804A0A1F808A093F902A0BAF1000F0BDAB9F1010F0CBF4FF007094FF00D0981F8059081F801E009E0B9F1010F0CBF4FF0050959
:401CC0004FF0090981F805904F704FEA02191A4906FB0282494481F802E0B2F808A0CAF3072A81F800A0B2F808A05FFA8AFA81F801A0B2F806A011495FFA8AFA494481F873
:401D000006A0B2F80690C9F3072981F80790B2F806905FFA89F981F80490D288C2F307224A71083394E7BDE8F88F00BF7186FF1F7886FF1F6D86FF1FFC5F00407060004018
:401D40005E86FF1F08B5064B18780138C0B2FFF753FF20B143681B7900EBC300406908BD7186FF1F00212DE9F84F0B464E4E0C2707FB01F401313219092933554FF000057F
:401D80009370494CD3701381937253705371EFD118B1464B1D70464B1D70464B1A78002A7FD0187801250138C0B2FFF725FFA8464368DFF8F8E0DB790C2713F0400F3E4BA2
:401DC0004FF0000C1A7814BF42F0010202F0FE021A70027AD20007FB0541C36803EB02094B4531D093F802A00AF07F06AE4229D10E89B3F804B0B6B25E4538BFA1F808B058
:401E00001E7893F801B01EF80660B3451AD181F804A0DE780E7093F902A0DE78BAF1000F06F0030607DA012E0CBF07260D264E7181F8018006E0012E0CBF052609264E7156
:401E400081F801C00833CBE70135092DC3D1C1680A328B1C0A440C200833934209D013F8081C13F80A5C01F07F0100FB01418D72F2E7FFF767FF114B0121186000230C2005
:401E800000FB0142D3801289013113449BB203F00102134409299BB2F2D1BDE8F84FFFF76BBEBDE8F88F00BF7886FF1F5E86FF1FE686FF1F7186FF1F6F86FF1F7486FF1FB3
:401EC000114B1B7903F07F035A1E072A19D80F490C2202FB031291781B0141F0010191700021D170517841F002015170127912F0800F074A1A4414BF8D2389239370FFF7DF
:401F000053BC0020704700BF006000407886FF1FFC5F004030B4194B1A7902F07F02531E072B27D8164B0C2404FB02339978154D01F0FE0199700021D97029461201505DEB
:401F4000114400F07F0050555A7802F0FD025A701A795B78120605D5012B01D18C7006E00D2303E0012B0CBF082309238B7030BCFFF71ABC002030BC704700BF00600040FD
:401F80007886FF1FFC5F004010B50D4B0D4C21791878C9B20138C0B2FFF72EFE43681B798B4201D2012909D8074A0848535CDBB24354A3780120DBB2535410BD002010BDFA
:401FC0007186FF1F006000405E86FF1FE686FF1F38B58A4A8A4C13780021DBB221801806517840F18D800A2900F20581DFE811F05D00030103010301030103010B00030117
:402000007E0003018200D3787C49012B09D17D4B1A787D4B03EBC2035B685B686360122310E0CB78022B12D18878FFF7E5FD002800F0E180436863606368DA7863689B7836
:4020400043EA02232380BDE83840FFF7CDBCCB78032B26D16D4B00228878D5B2854209D3664A91786A4AEE2908BF1346634A917881B106E0187801320028F1D0187803446E
:40208000EAE764499278097C914203D16248FFF73DFD614B1A78002A00F0AD801A78228018E0BDE8384000F019BA13F0030313D0022B40F0A0802380504B0C211B7903F0A6
:4020C0007F02564B01FB02339A78554BD2B21A7000225A706360B6E702222280514A11784F4AC9B2117053706260ACE7012323804D4BEFE70123238013794C4A1344E9E7A5
:4021000001390A2977D8DFE801F037764F76067676760A7620009378454ADBB25AE0937803F0FF0153B9404B1A7891425FD01970404B01201870FFF715FE58E0481EC0B251
:40214000FFF75AFD0028EED155E0FFF71DFF002851D02A4A384913791279DBB2D2B20A70364A3249D25CCB5C9A4240D0314B01221A70FFF753FD3AE003F00303012B2BD01F
:4021800009D3022B37D11D4B9B78002B33D1BDE83840FFF7BFBE194B9B78012B2BD1214A137803F0FD0315E003F00303012B13D008D3022B1FD1114B9B78E3B9BDE838402F
:4021C000FFF77EBE0D4B9B78012B14D1154A137843F0020313700AE0084B1A795AB998781B791749DBB2CA5C22EA0002CA54BDE83840FFF7D9BA002038BD00BF00600040AC
:402200006086FF1F6C86FF1F942F0000F82F0000802F00006B300000EA86FF1F7886FF1F5186FF1F6F86FF1F7186FF1F5E86FF1F5C86FF1F7086FF1F6D86FF1FE686FF1FDE
:402240007386FF1F074B1A78120609D55B78012B06D1054B054A5A6012781A80FFF7C4BB00207047006000406086FF1F582F0000024B1878C0F38010704700BF8F450040F9
:40228000704738B505460078012428B100F0D0F8285D0134E4B2F8E738BD08B50D2000F0C7F8BDE808400A2000F0C2B8014B1870704700BF7D640040014B1878704700BF06
:4022C0006B640040014B1870704700BF78650040074A0223136002F688321268E0215064044A11706FF440710A441360704700BF80E100E001E400E073B515461E460B4C40
:402300000023019300930A46014618462370FEF747FE324629462078FEF702FE02212078FEF7ECFD207802B070BD00BFF480FF1F064A0123136002F688321268E021106434
:40234000034A1170A2F540721360704780E100E000E400E0014B1870704700BF7B640040014B1870704700BF79650040014B1870704700BF7A640040014B1870704700BF94
:402380007C640040014B1870704700BF7E64004073B515461E460B4C01230022019200920A46014618462370FEF7FAFD324629462078FEF7B5FD02212078FEF79FFD20786A
:4023C00002B070BDF580FF1F064A0423136002F688321268E0219064034A1170A2F202321360704780E100E002E400E0014B04221A60704700E100E0014B04221A60704792
:4024000080E100E0014B1870704700BF7F6400400230800803D000BF01380046FCD17047EFF3108072B6704780F31088704700BFFEB5494652465B460EB407462449096865
:402440008A46244A12682448022100F05FF8030020480068C018204900F058F8143883460121C9430C4601250026FFF7D9FF814651460B7823400B7058460130FFF7C8FF80
:402480003800F04028400B78234003430B705846FFF7BEFF0136072EF2D9002001300138013001200B78234003430B7058460430FFF7AEFF4846FFF7B7FF00BF00BF00BFAE
:4024C0000EBC894692469B46FEBD00BFAFF30080E880FF1FE480FF1F00C20100094A137803F00303012B0AD0022B09D113790C2103F07F02044B01FB02339B7A00E0137911
:4025000000207047006000407886FF1F002902D0B0FBF1F0704708B14FF0FF3000F008B80029F8D00246B0FBF1F000FB11217047704700BF014B1868704700BF5881FF1F9B
:402540000E4B70B51E460E4C0025E41AA410A54204D056F8253098470135F8E700F0A2FD084B094C1E46E41AA4100025A54204D056F8253098470135F8E770BDB030000025
:40258000B0300000B0300000B830000010B5431E0A44914204D011F8014B03F8014FF8E710BD03460244934202D003F8011BFAE7704730B5141E05469BB0184604DA8B2390
:4025C0002B604FF0FF301DE04FF40273ADF80C300CBF234604F1FF33029305934FF6FF7300910491ADF80E3002461E9B6946284600F072F8431CBCBF8B232B6014B1009B19
:4026000000221A701BB030BD07B5009313460A46014603480068FFF7CCFF03B05DF804FB5881FF1F2DE9F0478E6882469E420C46914698463ED88A8912F4906F3AD02568CE
:40264000096902236F1A656905EB450595FBF3F57B1C43449D4238BF1D4653050FD5294600F040FB064698B13A462169FFF78EFFA38923F4906343F08003A38113E02A46F8
:4026800000F08EFB064670B92169504600F0DEFA0C23CAF80030A3894FF0FF3043F04003A381BDE8F08726613E44266046466561ED1BA560464528BF464649463246206858
:4026C00000F0A8FAA36800209B1BA36023681E442660BDE8F08700002DE9F04F9DB003938B8980461C060D4616460DD50B695BB9402100F0F7FA2860286118B90C23C8F875
:402700000030CDE040236B610023099320238DF82930DFF89CB130238DF82A3037463C4614F8013B1BB9B7EB060910D003E0252BF9D02746F3E74B46324629464046FFF774
:4027400071FF013000F0A780099B4B4409933B78002B00F0A08000234FF0FF3204930793059206938DF853301A930126052221784E4800F041FA671C049B38B14B4A3C4671
:40278000801A06FA00F018430490EFE7D90644BF20228DF853201A0744BF2B228DF8532022782A2A03D0079A00210A200BE0039A111D12680391002A10DA524243F00200F7
:4027C000079204900BE027463B780134303B092B03D800FB02320121F5E701B107923B782E2B1ED17B782A2B0AD1039B02371A1D1B680392002BB8BF4FF0FF33059310E09B
:40280000002319460593781C0A2407463A780130303A092A03D804FB01210123F5E703B1059103223978224800F0E6F940B14023CBEB000003FA00F0049B013718430490DD
:40284000397806221B487E1C8DF8281000F0D4F988B1194B33B9039B073323F007030833039314E003AB00932A46144B04A94046AFF3008007E003AB00932A460F4B04A9C1
:40288000404600F093F8B0F1FF3F824603D0099B5344099342E7AB895B0601D4099801E04FF0FF301DB0BDE8F08F00BF7F300000853000008930000000000000252600002B
:4028C0002DE9F04791461F460A698B6806469342B8BF1346C9F8003091F843200C46DDF8208012B10133C9F800302368990642BFD9F800300233C9F80030256815F006057D
:4029000010D104F1190A07E00123524639463046C04701301AD00135E368D9F800209B1A9D42F1DB94F843302268003318BF012392060FD5E118302081F843005A1C94F8D8
:4029400045102244023382F8431003E04FF0FF30BDE8F08704F1430239463046C0470130F4D02268D9F80050E36802F00602042A08BF5D1B2269A3680CBF25EAE5750025B6
:402980009342C4BF9B1AED184FF000091A344D4509D00123224639463046C0470130D5D009F10109F3E70020BDE8F0872DE9F04317460A7E85B06E2A984606460C460C9B6E
:4029C00001F1430E00F0AE8011D8632A22D009D8002A00F0BB80582A40F0CA8081F84520834955E0642A1ED0692A1CD0C0E0732A00F0B08009D86F2A2ED0702A40F0B8802B
:402A00000A6842F020020A603EE0752A24D0782A3AD0ADE01A6801F14205111D1960136884F84230A8E021681A6811F0800F02D0111D196008E011F0400F02F1040119606C
:402A400002D0B2F9003000E01368002B3CDA2D225B4284F8432037E021681A6811F0800F02D0111D196007E011F0400F02F10401196001D0138800E01368227E5C496F2ACA
:402A800014BF0A2208221BE078225A4984F845202268186812F0800F00F104051D6003D1550601D5038800E00368D00744BF42F0200222601BB9226822F0200222601022F1
:402AC000002084F8430001E049490A226568002DA56008DB206820F0040020602BB9002D7DD175460CE0002B79D07546B3FBF2F002FB1033CB5C05F8013D03460028F5D1BC
:402B0000082A0BD12368DA0708D5236962689A42DEBF302305F8013C05F1FF35C5EB0E0323612EE008681A6810F0800F496903D0101D1860136808E010F0400F02F1040011
:402B40001860136801D0198000E0196000232361754616E01A68111D1960156800216268284600F049F808B1401B6060636804E004F1420584F8422001232361002384F833
:402B80004330CDF800803B4603AA21463046FFF797FE013002D14FF0FF3026E023692A4639463046C0470130F5D023689B0710D5002504F1190907E001234A463946304683
:402BC000C0470130E7D00135E368039A9B1A9D42F2DBE068039B9842B8BF184605E00B7804F1420584F842308AE705B0BDE8F083472F00009030000010B5C9B20244904274
:402C0000034605D01C7801308C42F8D1184610BD002010BD884210B501EB020301D8421E0BE09842FBD28118D21AD34204D013F8014D01F8014DF8E710BD994204D011F845
:402C4000014B02F8014FF8E710BD000038B50546002944D051F8043C0C1F002BB8BFE41800F0D4F81E4A1368114613B96360146030E0A3420DD92268A018834201BF186830
:402C80005B681218226063600C6023E0A24203D813465A68002AF9D118681918A1420BD12168014458188242196013D110685268014419605A600DE002D90C232B6009E0C1
:402CC00021686018824201BF106852680918216062605C602846BDE8384000F098B838BD5886FF1F70B5CD1C25F0030508350C2D38BF0C25002D064601DBA94202D90C232E
:402D0000336046E000F082F8234B1C681A462146A1B10B685B1B0ED40B2B03D90B60CC18CD501EE08C420BBF63684B681360636018BF0C4615E00C464968E9E7174C2368F3
:402D40001BB9304600F052F820602946304600F04DF8431C18D0C41C24F00304A0420DD12560304600F053F804F10B00231D20F00700C31A0ED05A42E25070BD211A30463F
:402D800000F034F80130EBD10C233360304600F03EF8002070BD00BF5886FF1F5486FF1FF8B5074615460E4621B91146BDE8F840FFF798BF1AB9FFF749FF2846F8BD00F084
:402DC00027F885420ED929463846FFF78BFF044650B131462A46FFF7D9FB31463846FFF735FF01E03046F8BD2046F8BD38B5064C0023054608462360FDF7B8FF431C02D1FC
:402E0000236803B12B6038BD0C87FF1F7047704751F8040C0028BEBF091851F8043CC0180438704700000000050209020B020D020F02110213027265706C79203078253091
:402E4000327800686F6D696E6700626567696E6E696E67207365656B2066726F6D20256420746F20256400756E65787065637465646C7920646574656374656420747261A1
:402E8000636B20300066696E6973686564207365656B0057616974696E6720666F72205553422E2E2E0055534220726561647900636F6D6D616E64203078253032780077D8
:402EC00061697400756E64657272756E206166746572202564207061636B65747300636F756E743D256420693D256420643D2564207A7A3D25640073746172742065726153
:402F000073696E670073746F702065726173696E670069646C650000510040100030510040400000000140000C800C0140800300140140000800400140000A004C014000BF
:402F400002005001402000303132333435363738394142434445460028000000000104000100000000000000000157494E5553420000303030303100000000000000000004
:402F800012034D0053004600540031003000300001000000010000009C2F0000010000006B300000000000000000000001000000B42F0000010000003D3000000400000072
:402FC000D62F0000000000000000000000000000D42F0000FF00000001024000FF00000082024000FF00000003034000FF00000084034000FF000203040309041603460042
:403000006C007500780045006E00670069006E0065002A0343006F0077006C00610072006B00200054006500630068006E006F006C006F0067006900650073000009022EA4
:403040000001010080320904000004FF00000007050102400000070582024000000705030340000A0705840340000A12010002FF0001080912006E010002018001430023A3
:403080002D302B2000686C4C00656667454647003031323334353637383961626364656600000000F8B500BFF8BC08BC9E46704759000000E90D0000F8B500BFF8BC08BC30
:4030C0009E46704735000000D8300000C880FF1F98000000B0050000000000001087FF1F7F800000030000000000007D00FA0000400000000090D0031550004002000000CD
:4031000005000000FFFF000000000000000000000000000000000000000000000000000000000000000000007D3000000000000000000000000000000000000000000000DF
:4031400000000000000000000000000000000000000000000000000000000000000000000000000000000000F880FF1F0000000000000000000000000000000000000000B9
:40318000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F
:4031C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CF
:40320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008E
:40324000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004E
:40328000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E
:4032C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CE
:40330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008D
:40334000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004D
:40338000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D
:4033C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CD
:40340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008C
:40344000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C
:40348000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C
:4034C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CC
:40350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008B
:40354000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004B
:40358000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B
:4035C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CB
:40360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008A
:40364000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004A
:40368000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A
:4036C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CA
:403700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000089
:403740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049
:403780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009
:4037C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C9
:403800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000088
:403840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000048
:403880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008
:4038C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C8
:403900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087
:403940000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000047
:403980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007
:4039C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C7
:403A00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086
:403A40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046
:403A80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006
:403AC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C6
:403B00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000085
:403B40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045
:403B80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005
:403BC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C5
:403C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084
:4000000000800020110000003510000035100000064A08B5136843F020031360044B1A6803F53F5302331A6001F022F8E8460040FA46004010B5054C237833B9044B13B181
:400040000448AFF300800123237010BD6881FF1F0000000098380000084B10B51BB108490848AFF300800848036803B910BD074B002BFBD0BDE81040184700BF0000000071
:400080006C81FF1F98380000C880FF1F0000000072B6034A13680133136062B6704700BF8881FF1F0A4A0B4B516801310B40002BBEBF03F1FF3363F00F0301335360516800
:4000C0009368994202BF024B01221A73704700BF8881FF1F0F0000800A4A0B4B916801310B40002BBEBF03F1FF3363F00F030133936091685368994202BF024B01221A7379
:40010000704700BF8881FF1F0F000080024B012200205A7302F052B98881FF1F10B5C4B2204601F067F90128FAD110BD10B50446094B9A7B987382421CBF0022DA7310F0CE
:40014000010F14BF0220012002F064FE6008BDE8104002F059BE00BF8881FF1F70B5C4B220460E4601F04EF9314605460246204601F00AFA204601F03DF90128FAD02846D9
:4001800070BD000038B50B4C257C55B9A07BFFF7CDFF012002F0A8F84FF47A7002F0BAFAE5732368636101232374BDE8384002F0EFBA00BF8881FF1F38B50446C5B22846A0
:4001C00002F09EF8062002F0BBFA44F00200C0B202F096F8062002F0B3FA284602F090F8BDE83840062002F095BA10B5642402F081F820B10120BDE81040FFF7DDBF0120FF
:40020000FFF7DAFF013CF2D1F4E7000038B5044D0024285D013402F043FA102CF9D138BDA081FF1F08B502F05DFC002002F066FC02F078FC02F082FC80B208BD10B5044637
:40024000012002F075F8642002F064FAFFF7EAFF2080002002F06CF8642002F05BFAFFF7E1FF608010BD08B502F068FD002002F071FD02F083FD02F08DFD80B208BD10B5A9
:400280000446FFF7B2FF322002F044FAFFF7EBFF20800020FFF790FF322002F03BFAFFF7E2FF608010BD0FB400B593B014AB53F8042B402102A8019302F0D6FE02A802F0B4
:4002C00084F802F08EF813B05DF804EB04B0704710B5044601780648FFF7E5FF0420FFF71DFF62782146BDE81040042001F0DAB8AA38000007B50023ADF804308DF80600B0
:40030000032301A88DF80530FFF7E2FF03B05DF804FB0000F8B51D4C0646FFF733FFE37B03B156B91A48FFF7BEFFFFF75EFF01200023E073A36202F003FA3246A16A1548D8
:40034000FFF7B1FF114D0027A36A9E4216D001F0D1FF00B1AF62A36A9E4205DD0020FFF72BFFAB6A013305E005DA0120FFF724FFAB6A013BAB6202F00BFAE5E7322002F041
:40038000C9F9BDE8F8400448FFF78DBF8881FF1FB7380000BE380000DB3800002DE9F04F9BB062B602F05EFABE49042002F082FABD4801F0ABFFBD4802F04EFDBC4801F07F
:4003C000DFFF02F02FFC02F001FB002002F022FD01F0FAFF0221002000F0C2FFB54D0321084602F0B5F92E462C4602F0D1F92B7C73B16A692B689B1A41F28832934207D9C7
:40040000002001F071FF002002F004FD00232B7400F0DEFF18B9A848FFF745FF04E000F0DDFF0028F7D109E000F0D2FF0028FBD0A248FFF738FF032001F0FAF8032000F031
:40044000D9FF0128D1D1A07BFFF770FE9C490320FFF784FE94F82C109A48FFF724FF94F82C30023B122B00F2DF83DFE813F01300DD031C00DD032200DD033A00DD035E002E
:40048000DD039301DD031E03DD033D03DD034303DD034F0303238DF828308DF8293008238DF82A302EE394F82E00FFF733FF864B25E3FFF767FE00236373637B002BFCD06F
:4004C000002373733268637B002BFCD0336807218DF828109B1A04218DF82910ADF82A3010E30220FFF71AFE4FF000090DF1280A4FF480780027C8EB0903DA1907F80A2095
:400500000137402FF9D10220FFF708FE3A465146022000F0C7FFB8F10108EBD109F10109B9F1400FE4D1694BBAE294F82E0001F0FFFEA06AFFF7EEFE02F002FD644BDFF8C2
:4005400094811A78002742F004021A701A7842F001021A701A7802F0FE021A701A7802F0FE021A7002F0F0FC0220FFF7D7FD41F6FF734FF480420121022002F051FC84F807
:400580006C0002F073F808F807000137102FF8D1DFF844A100270AF159081FFA88F90137102F14BF3A4600221AF8010F22440623127E402102F08EF84A4646F243419AF86E
:4005C000000002F099F809F14009102F1FFA89F9E5D100237373637B002BFCD00027142239460AA8777302F00BFD40230D934FF0FF337760B36037737368DFF8E0903344B4
:40060000197E96F86C00CDF8309001F0E7FF96F86C0001F0A5FF012196F86C0001F078FF636813B96B7B002BFAD0002794F82FA0A76094F80CB0BBF1000F6AD102F0A8F8EF
:400640006B7B43B1BAF1010A85F80DB003D160E02B7B002B5DD1A26863689A42F8D04FF0000BA3680AA808EB83135B440A93CBF140030B9300F0F8FA0B9B0137C3F1400304
:400680009B440D9B5FFA8BFB9BBB022000F0B2FE012825D0637B002B3BD12B7B002BF4D037E000BF910000000D010000A5000000D90000008881FF1FE9380000FC38000085
:4006C000B481FF1F063900009C3800009E38000093640040A081FF1F9F81FF1FF885FF1F4022B849022000F0DDFE4023CDF830900D93BBF13F0FB4D9A268B34B0132134082
:40070000002BBEBF03F1FF3363F00F030133A3608FE7042194F86C0001F06CFF94F86C0001F078FF0028F9D10AA800F0D1FA0220FFF7F4FC337B63B90D9A402A06D0C2F135
:40074000400292B29F49022000F0ACFE0220FFF7E5FC0D9A32F0400203D11146022000F0A1FEFFF753FD237B33B19848FFF79BFD0220FFF7BFFD06E0954B09A81B88ADF8A6
:400780002430FFF7A5FD627B3946237B9148FFF78AFD4CE29048FFF786FD276B17F03F0701D0032041E2012001F0C8FD95F82E0001F0BEFD02F0C4FB884BDFF824821A78B7
:4007C00002F0FB021A701A7842F001021A701A7802F0FE021A701A7802F0FE021A7002F0B3FBA86AFFF796FD01214FF4804341F6FF72084601F0A8FD85F86C0001F036FF15
:4008000008F807000137102FF8D1DFF8D891002709F159031FFA83F807930137102F14BF3A46002219F8010F22440523127E402101F050FF414646F2475299F8000001F0E0
:400840005BFF08F14008102F1FFA88F8E5D10027BB46B946BA46336B4FF0FF389B09142239460AA877600593C6F80880377302F0C7FB402301200D9300F0DAFECDF81880AD
:400880006268514B01321340002BBCBF03F1FF3363F00F03A168B8BF01338B4200F0A480BAF1000F07D0237B002B40F0B0806B7B002B40F0AC800B9B002B34D1B9F1000FD0
:4008C0000BD07F223F495A540133402BFAD10A910B9328E0BAF1000F06D1012000F08AFD01288046F6D107E0237B002B40F08F806B7B002BF1D08AE03249FFF72FFC81462E
:40090000304B0B9040460A9300F092FEB9F13F0F07F1010706DD059BDB1BD3F1000949EB030900E0C1460B9BDBB16368079A0AA802EB83120D9BC3F1400313440C9300F042
:40094000D6F90D9B6BB96A681F4B01321340002BBEBF03F1FF3363F00F030133636040230D93A36801333FD16B680F2B3CD14FF00008C5F8088001F015FD85F80C80AB68D9
:4009800095F86C002B44197E01F028FE95F86C0001F0E6FD012195F86C0001F0B9FD85F80D80637B002BFCD04FF00008012086F80D8001F003FD404601F0C0FCCDF81880BF
:4009C00015E000BFF885FF1F0F00008015390000A03800002F3900004239000097650040A081FF1F9F81FF1FBAF1000F05D0237B6BB96B7B5BB94FF0010AA368069A934242
:400A00003FF43EAFAB680BF1010B069338E701F0CFFC012001F092FC002001F0CFFC042194F86C0001F0E6FD94F86C0001F0F2FD0028F9D196F86C0001F080FD737B327BCD
:400A40000293012303920193CDF800905B463A4605997B48FFF727FCB9F1000F16D1059BBB420ADD012000F0C5FC01288046F6D17449FFF773FB3F2803DC012000F0ECFD97
:400A800004E0404600F0D4FD0137E8E7FFF7BEFB6D48FFF708FC237B0BB10220C5E06B4B1B8809A8ADF824302DE094F82E0001F03FFCA06AFFF72EFC6548FFF7F4FB0023B0
:400AC0006373637B002BFCD0012001F077FC00237373637B002BFCD0002001F06FFC5D48FFF7E1FB5C4B0AE00020E073FFF712FC5A4B04E094F82E00FFF718FB584B1B885B
:400B0000ADF828300AA8FFF7E3FB90E0237C3BB1002001F0E9FB002002F07CF900232B7402F0FEF8002002F0A1F82A2701F0CCFF002001F06FFF3A4600210AA802F060FA3B
:400B400015238DF828308DF8297001F021FE002001F0CAFB002002F05DF9C82001F0DAFD0DEB0700FFF76AFB0DF13E00FFF787FB01F00EFE012002F04DF9322001F0CAFDD6
:400B80000DF12E00FFF75AFB0DF14200FFF777FB012001F0A9FB4FF4967001F0BBFD01F0F7FD0DF13600FFF749FB0DF14A00FFF766FB002001F098FB4FF4967001F0AAFDF7
:400BC00001F0E6FD022002F025F9322001F0A2FD0DF13200FFF732FB0DF14600FFF74FFB012001F081FB4FF4967001F093FD01F0CFFD0DF13A00FFF721FB0DF14E00FFF795
:400C00003EFB002001F070FB4FF4967001F082FD01F0BEFD002002F0FDF80023E37302F001F801F0D3FE6DE70120FFF763FB032000F0FEFC0B48FFF736FBFFF7D6BB00BFD7
:400C40004C390000F885FF1F7C390000A23800008B39000099390000A4380000A6380000A8380000A639000010B54268002A2ED0C368002B2BD00368048A591C01601B786C
:400C8000013A13F0800F817C42601DBF03F0010242EA84030231083114BF43F0020343EA0423817414BF03820382837C072BDCD9028A083B42FA03F38268511C8160137004
:400CC000C368013BC360837C083B8374CDE710BD07B5827C42B102AA002102F8011D026001224260FFF7C0FF03B05DF804FB30B543686BB3C2685AB3827C072A0CD80468D7
:400D000090F91050611C01602178013B41EA05210832018243608274827C018AA2F108042141CBB2090608D5C3F3801363F07F03023A03F08103827402E08474002BD7D00A
:400D40008268511C81601370C368013BC360CFE730BD00002DE9F04172B644F21A118E4B61221A70A3F5F06301221A8019244FF443729C709A80894A1B231370518044F633
:400D80001F611371D1801372854A864B92E80300062283F8002283E80300522203F580731A70814B814A1B78814EDBB2137040F61802804B00251A8041F2512223F8022C4E
:400DC00033784FF4F07003F0010343EA450502F0AFF8013C05F003052ED0032DF0D1764B4FF480721A8007221A70744A002548211570917002221D705D7103F8032C042291
:400E0000DA716F4A6F4C13786F4E43F00F03137012F8013C062743F0030302F8013C2378012243F0800323705B4B1A70674A137843F02003137000E0FEE707FB0563002163
:400E40009A881868013502F0DBF8072DF5D16048604E002550F8041F05F1105303F1560221F0FF075733C9B20B4452005B0002329A4206D012F802EC12F801CC0EF807C0B6
:400E8000F5E7B0420D44E5D1534A00231360936013619361514B524F1A68524BDFF890811A60514B1A68514B1A60514A137843F002031370137C43F0020313742378A2F57C
:400EC000863243F040032370413A137843F010031370484A484B07CA03C31A80474A2833106843F8250C127903F8212C444A07CA03C31A80434AE83B07CA03C31A80424A3D
:400F0000083307CA03C31A80404A414BA2F5616203CBC2F8100EC2F8141E1378042043F0080313703B4B02F5AA521B783D78DBB298F80060EDB203F007010C321B09117018
:400F4000F6B2537045F003033B7046F0030388F80030314B48221A70304A402313703049937013729372082382F81F3220220A7048710A722B4A0A20137001F0E1FB2A4B13
:400F800088F8006044223D70284D1A7094E80F0007C52B80BDE8F081004800408640004070100048004100400F010049A1460040254200402242004004400040064000407B
:400FC000A2430040A0430040AB390000E8460040FCFFFF47A80000480076004078100048F8460040207600407C100048287600400350014030100048C05100403C10004899
:4010000044100048501000485C1000483251004068100048CF0100491D51004001590040235B0040585B004076580040B0430040F946004008B501F0B7FF03680C2B00D18C
:40104000FEE7FEE7084908B50B68084A1844821A802A01DC086005E001F0A6FF0C2303604FF0FF33184608BDCC80FF1F4887FF1F80B51148114B0025C0B1A3F1100192C974
:4010800022460439161BB74204D051F8046F42F8046BF7E7114653F8046C8C1AA64202D041F8045BF9E701381033E5E701F082FFFFF774F9FEE700BF010000007C3B0000E7
:4010C000124A134B10B51A60124A134C1368134843F4007313600023032B98BF54F823204FEA830188BF0E4A0133302B4250F3D10C4B1A780C4B1A700C4B084A1A60FFF7EE
:4011000029FEBDE8104001F0EDB900BF0004FA050CED00E014ED00E0000000000080FF1F35100000BC760040C080FF1F08ED00E0F8B501F005FF4B4A01271378022643F0B3
:4011400001031370137C484C43F001031374474B02F5E3521F700B3203F8946C1378054603F07F031370002001F0EAFA2378404A03F0F90323701378384603F0DF031370B7
:4011800023783B43237001F0DBFA282001F0D8FA384B30461A7802F07F021A701A7802F0BF021A7023783343237001F0C9FA2378314A43F0040323700023137053702F4A3E
:4011C000FF2199540133092BFBD1284601F0BCFE0721172001F0FCFA2949172001F0EAFA0721182001F0F4FA2649182001F0E2FA0721152001F0ECFA2349152001F0DAFA84
:401200000721052001F0E4FA2049052001F0D2FA0721062001F0DCFA1D49062001F0CAFA0721084601F0D4FA1A49072001F0C2FA0721082001F0CCFA1749082001F0BAFA51
:401240000021162001F0C4FA1449162001F0B2FA07210C2001F0BCFABDE8F84010490C2001F0A8BAA5430040944300409D60004012600040F8510040846000406D86FF1F9C
:40128000FF1A000039190000FD1A0000311A00005D1A00008D1A0000C51A0000051B0000791B0000214B224A10B5187000231370204A40201370204A0F2413701F4A13708C
:4012C0001F4A13701F4A13701F4A13701F4B4FF400021A604FF080721A604FF400121A6020221A601860802018604FF480701860174804704FF480001860164B1A70933BC9
:4013000019B91A7802F0FE0202E01A7842F001021A70114B03221A70802203F8202C012001F006FE0D4B04221A7010BD8886FF1F8E86FF1F8C86FF1F8D86FF1F8986FF1F59
:401340007886FF1F8B86FF1F0087FF1F00E100E09E6000409C600040286000401260004070B5074C054623780E461BB9FFF7E0FE0123237031462846BDE87040FFF792BF36
:401380003886FF1F0A4A002313700A4A13700A4A13700A4A13700A4A13700A4A13700A4A13700A4B03221A70802203F8202C70478E86FF1F8C86FF1F8D86FF1F8986FF1FE9
:4013C0007886FF1F8B86FF1F0087FF1F28600040014B1878704700BF8D86FF1F044B1A7802F0FF001AB118780022C0B21A7070478C86FF1F024A0C2303FB00204078704778
:401400009486FF1F431E072B0CD8074A064B00010344805C5B7800F00F0043EA0020023880B2704700207047FC5F00401A4A38B50C2303FB00231B79090C13F0800F00F1B6
:40144000FF35044619BF8AB24FF480438BB24FF48042032D18D8DFE805F002070C110021084601F01BF80DE00021084600F0FAFF08E00021084600F0D9FF03E00021084667
:4014800000F0B8FF054B1855EDB2072D03D801F0EDF8034B185538BD9486FF1F6486FF1F6D86FF1F431E072B2DE9F0470446894615465CD82F4F0C2202FB0072D388DFF86E
:4014C000B8A09BB2C3F500739D424FF00C0303FB007388BFD588DB7884BFC5F50075ADB2254A43EA15230601B354B244EBB28AF80130224B1A5C9846FF2A01D1FFF796FF47
:401500000C2303FB047200215170B9F1000F28D03DB31B4F385D01F011F811232946FE2218F8040001F0D6F806F5C04278321FFA89F118F8040001F0DFF8124D18F804105D
:40154000385D01F04BF80121385D00F0E1FF735D43F002037355735D03F0FD037355BDE8F08703FB04746379DBB28AF80230BDE8F08700BF9486FF1FFC5F00406D86FF1F52
:401580006486FF1F706000402DE9F047044615468846002940D0431E072B3FD8FFF732FFA84203D22046FFF72DFF05461D4E335DFF2B03D141462046FFF738FFDFF868A0C5
:4015C00027011AF8040000F0B9FF1223FE222946305D01F07FF807F5C0411FFA88F27831305D01F089F8DFF84490315D1AF8040000F0F4FF01211AF8040000F089FF17F823
:40160000093043F0020307F8093017F8093003F0FD0307F8093002E00D4600E000252846BDE8F0876D86FF1F6486FF1F70600040431E072B0AD8064A0C2303FB002300226A
:401640005A705A79034BD2B200011A54704700BF9486FF1FFE5F0040431E072B9FBF024B000108221A547047FE5F004030B51A4A1A491B4D0878138803449BB21380194A5D
:4016800000231488D8B2A4B27CB1082B0CD050680078C0B2E85450680133013050601088013880B21080ECE718460B780E4C082B0E4A00D040B10E4D2B7883F080032B7028
:4016C0000F232370022301E0022323701370094B1870087030BD00BF0487FF1F0087FF1F006000407C86FF1F7986FF1F8E86FF1F8A86FF1F0187FF1F074B02221A70074B61
:4017000080221A70064B0F221A70064A00231370054A0120137070478E86FF1F8A86FF1F7986FF1F0087FF1F0187FF1F30B5164B16491B780A8803F00F03023BDBB21A4412
:4017400092B20A80124C134A0020118889B279B173B15568215C013BC9B229705168DBB20131516011880130013989B21180ECE7094A1370094A137883F080031370084BC8
:401780000B221A7030BD00BF296000400487FF1F006000407C86FF1F0187FF1F8A86FF1F7986FF1F064A06231370064A01201370054B80221A70054B00221A70704700BFC5
:4017C0008E86FF1F7986FF1F8A86FF1F0187FF1F054B9A683AB19A68044910709A680988518000229A6070477C86FF1F0487FF1F08B5124B1A78D2B21A701B78DBB21A06C0
:4018000002D50F4A137008BD0220FFF7E1FF0D4B1B7803F06003202B05D0402B06D043B900F012FC04E001F093FB01E000F046FD10B9034B03221A7008BD00BF2860004013
:401840007986FF1F0060004008B5084A084B0120197813880B449BB21380064B00221A70FFF7B6FF044B03221A7008BD0487FF1F0087FF1F8E86FF1F7986FF1F08B50C4BB1
:401880001B78DBB2042B07D0062B09D0022B0DD1BDE80840FFF7D8BFBDE80840FFF746BF0320FFF795FF034B03221A7008BD00BF8E86FF1F7986FF1F08B5054B00220120BE
:4018C0001A70FFF785FF034B03221A7008BD00BF8E86FF1F7986FF1F08B50A4B1A7832B11A78094942F080020A7000221A70074B002201201A70FFF76BFF054B03221A7051
:4019000008BD00BF7886FF1F086000408E86FF1F7986FF1F074B1B78DBB2042B05D0062B05D0022B05D1FFF7A1BEFFF7C5BFFFF7D3BF70478E86FF1F38B51D4C2378DBB2D3
:40194000DD0634D518060AD503F00F03012B2ED1FFF74EFF174B1B78190609D538BD5A0602D5FFF7D7FF03E09D0620D5FFF786FF23781B061BD4104B1A78104B1B7813434F
:401980000F4A13701278934211D10A4A0849154613782078DBB2000605D41378DBB20B700B7803F00F0328788342F1D138BD38BD286000407986FF1F8A86FF1F0187FF1F96
:4019C00029600040054A00231380054A916819B191680B7092685380704700BF0487FF1F7C86FF1F0E4808B503889BB213B9FFF783FE13E00B4B02221A700B4B00221A7060
:401A0000FFF7E0FF094AD1799379028843EA012392B2934238BF0380FFF728FE012008BD7C86FF1F8E86FF1F8A86FF1F00600040084B01221A700F3B9B7C074B1A7B02F05E
:401A40000302012A1EBFDA7B82F08002DA7301225A7370470B6000409486FF1F094B02221A700F3B93F82230074B1A7E02F00302012A1EBFDA7E82F08002DA7601225A7698
:401A8000704700BF0B6000409486FF1F0B4B04221A700F3B93F83230094B93F8242002F00302012A1EBF93F8272082F0800283F82720012283F82520704700BF0B600040E2
:401AC0009486FF1F0B4B08221A700F3B93F84230094B93F8302002F00302012A1EBF93F8332082F0800283F83320012283F83120704700BF0B6000409486FF1F7047FFF79A
:401B000041BC0000F0B5184B184E19780C27C9B201234FF0000C31B3CA0720D5144A4FEA031E7244947850782040C5070DD507FB03652C79240608D5147804F0FE04147076
:401B40006D790C4CEDB204F80E50840706D507FB036425792D0658BF84F801C090700133DBB24908D7E7F0BD9F6000409486FF1F70600040FE5F004000F0ACBC70B50446D2
:401B8000184B88B003AA03F11006154618685968083303C5B3422A46F7D11B782B70FCB12223237001AD03232846637000F08AFE002220461146AB5C08AC04EB131414F80B
:401BC000144C03F00F03847008AC234413F8143C0132082AC1700371417100F10400EAD108B070BDD53900002DE9F0431C4D01222E460C201F274FF0800E4FF0080C194B78
:401C000000FB02581401234418705F70164998F805902144B9F1000F07D098F8044024064CBF887081F802C001E081F802E000FB0261CC880132E4B29C71CC88092AC4F3C5
:401C40000724DC71CC88E4B21C71C988C1F307215971D4D1054BFF221A70BDE8F08300BF9486FF1F70600040FC5F00400A600040064B074A1B7802EBC30253681A7C82427E
:401C800086BF03EBC0035869002070478886FF1F383A00002DE9F84F424B1A78002A7ED01878414D0138C0B2FFF7E2FFA8463F4AC3681478007ADFF800C1E4B203EBC000E0
:401CC0000C2600274FF0010E834268D01A78A24263D11CF80420597891425ED19A7893F8039002F07F0206FB02FA05EB0A01CF7093F802B009F0030981F804B093F803B004
:401D000005F80AB0B3F804A0A1F808A093F902A0BAF1000F0BDAB9F1010F0CBF4FF007094FF00D0981F8059081F801E009E0B9F1010F0CBF4FF005094FF0090981F80590E4
:401D40004F704FEA02191A4906FB0282494481F802E0B2F808A0CAF3072A81F800A0B2F808A05FFA8AFA81F801A0B2F806A011495FFA8AFA494481F806A0B2F80690C9F3AF
:401D8000072981F80790B2F806905FFA89F981F80490D288C2F307224A71083394E7BDE8F88F00BF8D86FF1F9486FF1F8986FF1FFC5F0040706000407A86FF1F08B5064BBA
:401DC00018780138C0B2FFF753FF20B143681B7900EBC300406908BD8D86FF1F00212DE9F84F0B464E4E0C2707FB01F401313219092933554FF000059370494CD370138184
:401E0000937253705371EFD118B1464B1D70464B1D70464B1A78002A7FD0187801250138C0B2FFF725FFA8464368DFF8F8E0DB790C2713F0400F3E4B4FF0000C1A7814BFE0
:401E400042F0010202F0FE021A70027AD20007FB0541C36803EB02094B4531D093F802A00AF07F06AE4229D10E89B3F804B0B6B25E4538BFA1F808B01E7893F801B01EF89F
:401E80000660B3451AD181F804A0DE780E7093F902A0DE78BAF1000F06F0030607DA012E0CBF07260D264E7181F8018006E0012E0CBF052609264E7181F801C00833CBE797
:401EC0000135092DC3D1C1680A328B1C0A440C200833934209D013F8081C13F80A5C01F07F0100FB01418D72F2E7FFF767FF114B0121186000230C2000FB0142D380128980
:401F0000013113449BB203F00102134409299BB2F2D1BDE8F84FFFF767BEBDE8F88F00BF9486FF1F7A86FF1F0287FF1F8D86FF1F8B86FF1F9086FF1F114B1B7903F07F0354
:401F40005A1E072A19D80F490C2202FB031291781B0141F0010191700021D170517841F002015170127912F0800F074A1A4414BF8D2389239370FFF715BC0020704700BF5C
:401F8000006000409486FF1FFC5F004030B4194B1A7902F07F02531E072B27D8164B0C2404FB02339978154D01F0FE0199700021D97029461201505D114400F07F0050558B
:401FC0005A7802F0FD025A701A795B78120605D5012B01D18C7006E00D2303E0012B0CBF082309238B7030BCFFF7DCBB002030BC704700BF006000409486FF1FFC5F004052
:4020000010B50D4B0D4C21791878C9B20138C0B2FFF72EFE43681B798B4201D2012909D8074A0848535CDBB24354A3780120DBB2535410BD002010BD8D86FF1F006000405F
:402040007A86FF1F0287FF1F38B58A4A8A4C13780021DBB221801806517840F18D800A2900F20581DFE811F05D00030103010301030103010B0003017E0003018200D378C3
:402080007C49012B09D17D4B1A787D4B03EBC2035B685B686360122310E0CB78022B12D18878FFF7E5FD002800F0E180436863606368DA7863689B7843EA02232380BDE86B
:4020C0003840FFF78FBCCB78032B26D16D4B00228878D5B2854209D3664A91786A4AEE2908BF1346634A917881B106E0187801320028F1D018780344EAE764499278097CB9
:40210000914203D16248FFF739FD614B1A78002A00F0AD801A78228018E0BDE8384000F017BF13F0030313D0022B40F0A0802380504B0C211B7903F07F02564B01FB0233E0
:402140009A78554BD2B21A7000225A706360B6E702222280514A11784F4AC9B2117053706260ACE7012323804D4BEFE70123238013794C4A1344E9E701390A2977D8DFE8F4
:4021800001F037764F76067676760A7620009378454ADBB25AE0937803F0FF0153B9404B1A7891425FD01970404B01201870FFF715FE58E0481EC0B2FFF75AFD0028EED120
:4021C00055E0FFF71DFF002851D02A4A384913791279DBB2D2B20A70364A3249D25CCB5C9A4240D0314B01221A70FFF753FD3AE003F00303012B2BD009D3022B37D11D4B5A
:402200009B78002B33D1BDE83840FFF7BFBE194B9B78012B2BD1214A137803F0FD0315E003F00303012B13D008D3022B1FD1114B9B78E3B9BDE83840FFF77EBE0D4B9B788A
:40224000012B14D1154A137843F0020313700AE0084B1A795AB998781B791749DBB2CA5C22EA0002CA54BDE83840FFF79BBA002038BD00BF006000407C86FF1F8886FF1FBA
:40228000383A00009C3A0000243A00000F3B00002087FF1F9486FF1F3986FF1F8B86FF1F8D86FF1F7A86FF1F7886FF1F8C86FF1F8986FF1F0287FF1F8F86FF1F074B1A789F
:4022C000120609D55B78012B06D1054B054A5A6012781A80FFF786BB00207047006000407C86FF1FFC390000014B1870704700BF72640040014B1878704700BF6D640040CF
:40230000014B1870704700BF7A650040064A0123136002F688321268E0211064034A1170A2F540721360704780E100E000E400E0014B1870704700BF76650040014B18702D
:40234000704700BF7965004073B515461E460B4C05230022019200920A4601461846237000F064F932462946207800F01FF90221207800F009F9207802B070BDD080FF1F2E
:40238000064A0423136002F688321268E0219064034A1170A2F202321360704780E100E002E400E0014B04221A60704700E100E0014B04221A60704780E100E0014B18702F
:4023C000704700BF7C640040704738B505460078012428B100F054FD285D0134E4B2F8E738BD08B50D2000F04BFDBDE808400A2000F046BDF7B516461F460B4C0023032542
:40240000019300930A4601462846257000F00EF93A463146207800F0C9F80221207800F0B3F8207803B0F0BDE080FF1FF7B516461F460B4C00230225019300930A4601460C
:402440002846257000F0F2F83A463146207800F0ADF82946207800F097F8207803B0F0BDE180FF1FF7B516461F460B4C00230125019300930A4601462846257000F0D6F8D2
:402480003A463146207800F091F80221207800F07BF8207803B0F0BDE280FF1F73B515461E460B4C0023019300930A4601461846237000F0BBF832462946207800F076F8EE
:4024C0000221207800F060F8207802B070BD00BFE380FF1F024B1878C0F38010704700BF8F450040074A7F23802113705170064A013BDBB202F80839002BF9D1034A137087
:40250000704700BFE480FF1FF87B00400078004017280FD8084B0001C25C11B142F0200201E002F0DF02C254C25C42F00102C25400207047012070471070004017280BD8C6
:40254000064B0001C25C02F0FE02C254C25C02F0DF02C25400207047012070471070004017280DD8074900010B4603441A7942F004021A71435C43F00103435400207047C6
:40258000012070471070004017280BD8064A0001835C490003F0F10301F00E011943815400207047012070471070004041F6FF73994208BF4FF400519A4208BF4FF400524A
:4025C00017289FBFC00000F1804000F5EC4081809ABFC280002001207047000017289FBF034B00011954002088BF0120704700BF1970004017289FBF054B00011A5C01F0A3
:4026000007019DBF1143195400200120704700BF1470004017289FBF034B0001185C00F0070088BFFF20704714700040172810B51AD8C00001F07F0100F1804441EAC212E7
:4026400004F5EC44D2B222709DF8082003F00F0343EA0213DBB263709DF80C30002003F00F03A370E07010BD012010BD10B500F067FC0A4A5378182B0AD91478013B5370BB
:40268000E30003F1804303F5F0431B78137000E0FF2400F059FC204610BD00BFE480FF1F030610B5044611D400F04AFC084AE300117803F1804303F5F043197053781470D8
:4026C00001335370BDE8104000F03EBC10BD00BFE480FF1F30B504060CD411F4704509D1C40004F1804404F5F0442180A270E370284630BD012030BD03065FBFC00000F1A2
:40270000804000F5F04081805ABFC280002001207047000038B50446084DB4F5004F05D9286800F005FCA4F50044F6E7034B58686043BDE8384000F0FBBB00BFEC80FF1F06
:40274000024B1B7A584300F0F3BB00BFEC80FF1F0E4B00F003001A78490102F0FC02104318701A7801F0600142F080021A701A7802F07F021A701A7802F09F020A431A7055
:402780001A7842F010021A70704700BF83430040014B01221A70704784430040044B00F00F021B6853F8220043F82210704700BF08ED00E0054A00F01F00126800F11003B2
:4027C00052F8230042F82310704700BF08ED00E000F01F0000F16040490100F56440C9B2017070470F4B10B50F4900240F205C609C60DC601C615C61FFF7D0FF0B4A136801
:4028000043F0040313600A4B4FF47A72DB68B3FBF2F3084A1360084B4FF400421C60C3F8E82010BD3C86FF1F9128000010E000E0EC80FF1F14E000E018E000E0024A136882
:4028400043F002031360704710E000E008B5FFF7F5FF034A136843F00103136008BD00BF10E000E010B5054CA3691BB9FFF7BAFF0123A361BDE81040FFF7E8BF3C86FF1F7A
:40288000024B1868C0F30040704700BF10E000E038B5FFF7F5FF012808D1054D002455F8243003B198470134052CF8D138BD00BF4086FF1F024B03EB8003586859607047DA
:4028C0003C86FF1F134B144A1B78DBB20360127843EA0223114A0360127843EA0243104A0360127843EA026303600E4B0E4A1B78DBB24360127843EA02230C4A4360127814
:4029000043EA02430A4A4360127843EA02634360704700BF0301004904010049EC460040020100490101004900010049050100490601004910B500F003FB204A044613787A
:402940000A2043F002031370137C43F00203137412F80A3C43F0010302F80A3C937943F00103937102F5AB52137843F003031370134B18221A7013F8012C42F0400203F812
:40298000012C13F8012C02F0FC0203F8012CCE2203F8062CA3F597530222183B1A70094A137843F008031370FFF7CAFE064B10222046BDE810401A6000F0C6BAAB430040A7
:4029C0000E5900402F5B004080E200E008B500F0B7FA0F4A137803F0FE031370A2F5AA521D3A137803F0FD031370137C03F0FD03137412F80A3C03F0FE0302F80A3C9379E7
:402A000003F0FE039371BDE8084000F09DBA00BF08590040044A137803F03F0343EA8010C0B21070704700BF08590040082804D00A280CBF8223C22300E0422308380E4ACE
:402A4000C0B20428137098BF0C4B4FF0000298BF33F910100A4B88BF11461A8042F210734B4341F2883103F6C41393FBF1F305490B60054B1A8070470A590040E639000087
:402A80000A87FF1F0C87FF1F1087FF1F08B5102000F0A6F907210420FFF79AFE07490420FFF788FE064A0C20137843F006031370FFF7BCFF034B00221A8008BD852B0000C5
:402AC000095900400887FF1F10B5054C23781BB9FFF7DCFF01232370BDE81040FFF72ABF5886FF1F044B1A7802F0FB021A701A7842F001021A7070470859004010B5084B8F
:402B00001C7814F0010403D10028F9D0002404E02046FFF715FE024B1B78204610BD00BF09590040034A044B1B881088181A00B2704700BF1087FF1FA25B00400E4A138832
:402B40001BB223B111880A2309B2594301E00B4B19680B4B1B88C01A42F2107300B203FB00F2022391FBF3F30028D8BF5B42134493FBF1F000B270470A87FF1F0C87FF1F31
:402B80000887FF1F7047000010B500F0D9F9214A044613780A2043F001031370137C43F00103137412F80A3C43F0020302F80A3C937943F00203937102F5AA5218321378E1
:402BC00043F003031370144B18221A7013F8012C42F0400203F8012C13F8012C02F0FC0203F8012CCE2203F8062CA3F597530222123B1A70094A137843F008031370FFF7A3
:402C00009FFD074B08222046BDE810401A6000F09BB900BFAB43004006590040275B004080E200E008B500F08BF90F4A137803F0FE031370A2F5AA52153A137803F0FE03E6
:402C40001370137C03F0FE03137412F80A3C03F0FD0302F80A3C937903F0FD039371BDE8084000F071B900BF00590040044A137803F03F0343EA8010C0B21070704700BFAF
:402C800000590040082804D00A280CBF8223C22300E0422308380E4AC0B20428137098BF0C4B4FF0000298BF33F910100A4B88BF11461A8042F210734B4341F2883103F6A9
:402CC000C41393FBF1F305490B60054B1A80704702590040F03900001687FF1F1C87FF1F1487FF1F08B5102000F084F807210320FFF76EFD07490320FFF75CFD064A0C20F5
:402D0000137843F006031370FFF7BCFF034B00221A8008BDDD2D0000015900401887FF1F10B5054C23781BB9FFF7DCFF01232370BDE81040FFF728BF5986FF1F044B1A78AB
:402D400002F0FB021A701A7842F001021A7070470059004010B5084B1C7814F0010403D10028F9D0002404E02046FFF7E9FC024B1B78204610BD00BF01590040034A044B6E
:402D80001B881088181A00B2704700BF1487FF1FA05B00400E4A13881BB223B111880A2309B2594301E00B4B19680B4B1B88C01A42F2107300B203FB00F2022391FBF3F35E
:402DC0000028D8BF5B42134493FBF1F000B270471687FF1F1C87FF1F1887FF1F70470000034A00F0F800137803431370704700BF02410040034A00F0F8001378034313704D
:402E0000704700BF06410040014B1870704700BF78650040014B1870704700BF7564004073B515461E460B4C04230022019200920A46014618462370FFF7F8FB32462946C7
:402E40002078FFF7B3FB02212078FFF79DFB207802B070BDFC80FF1F074A0223136002F688321268E0215064044A11706FF440710A441360704700BF80E100E001E400E0D2
:402E8000FEB5494652465B460EB40746244909688A46244A12682448022100F071F8030020480068C018204900F06AF8143883460121C9430C460125002600F041F88146D3
:402EC00051460B7823400B705846013000F030F83800F04028400B78234003430B70584600F026F80136072EF2D9002001300138013001200B78234003430B705846043044
:402F000000F016F8484600F01FF800BF00BF00BF0EBC894692469B46FEBD00BFAFF30080D480FF1FF880FF1F00C20100000000000230800803D000BF01380046FCD17047B9
:402F4000EFF3108072B6704780F31088704700BF094A137803F00303012B0AD0022B09D113790C2103F07F02044B01FB02339B7A00E0137900207047006000409486FF1FBE
:402F8000002902D0B0FBF1F0704708B14FF0FF3000F008B80029F8D00246B0FBF1F000FB11217047704700BF014B1868704700BF6081FF1F0E4B70B51E460E4C0025E41A3D
:402FC000A410A54204D056F8253098470135F8E700F0BAFD084B094C1E46E41AA4100025A54204D056F8253098470135F8E770BD543B0000543B0000543B00005C3B00007E
:4030000003460244934202D003F8011BFAE7704730B5141E05469BB0184604DA8B232B604FF0FF301DE04FF40273ADF80C300CBF234604F1FF33029305934FF6FF730091B5
:403040000491ADF80E3002461E9B6946284600F073F8431CBCBF8B232B6014B1009B00221A701BB030BD000007B5009313460A46014603480068FFF7CBFF03B05DF804FBCF
:403080006081FF1F2DE9F0478E6882469E420C46914698463ED88A8912F4906F3AD02568096902236F1A656905EB450595FBF3F57B1C43449D4238BF1D4653050FD52946B8
:4030C00000F04AFB064698B13A46216900F0D2FAA38923F4906343F08003A38113E02A4600F098FB064670B92169504600F0E8FA0C23CAF80030A3894FF0FF3043F04003B2
:40310000A381BDE8F08726613E44266046466561ED1BA560464528BF464649463246206800F0B3FAA36800209B1BA36023681E442660BDE8F08700002DE9F04F9DB003938C
:403140008B8980461C060D4616460DD50B695BB9402100F001FB2860286118B90C23C8F80030CDE040236B610023099320238DF82930DFF89CB130238DF82A3037463C46DB
:4031800014F8013B1BB9B7EB060910D003E0252BF9D02746F3E74B46324629464046FFF771FF013000F0A780099B4B4409933B78002B00F0A08000234FF0FF3204930793F2
:4031C000059206938DF853301A930126052221784E4800F041FA671C049B38B14B4A3C46801A06FA00F018430490EFE7D90644BF20228DF853201A0744BF2B228DF853204C
:4032000022782A2A03D0079A00210A200BE0039A111D12680391002A10DA524243F00200079204900BE027463B780134303B092B03D800FB02320121F5E701B107923B782E
:403240002E2B1ED17B782A2B0AD1039B02371A1D1B680392002BB8BF4FF0FF33059310E0002319460593781C0A2407463A780130303A092A03D804FB01210123F5E703B1C9
:40328000059103223978224800F0E6F940B14023CBEB000003FA00F0049B013718430490397806221B487E1C8DF8281000F0D4F988B1194B33B9039B073323F007030833A3
:4032C000039314E003AB00932A46144B04A94046AFF3008007E003AB00932A460F4B04A9404600F093F8B0F1FF3F824603D0099B5344099342E7AB895B0601D4099801E0D9
:403300004FF0FF301DB0BDE8F08F00BF233B0000293B00002D3B000000000000853000002DE9F04791461F460A698B6806469342B8BF1346C9F8003091F843200C46DDF8AC
:40334000208012B10133C9F800302368990642BFD9F800300233C9F80030256815F0060510D104F1190A07E00123524639463046C04701301AD00135E368D9F800209B1AFC
:403380009D42F1DB94F843302268003318BF012392060FD5E118302081F843005A1C94F845102244023382F8431003E04FF0FF30BDE8F08704F1430239463046C047013097
:4033C000F4D02268D9F80050E36802F00602042A08BF5D1B2269A3680CBF25EAE57500259342C4BF9B1AED184FF000091A344D4509D00123224639463046C0470130D5D04C
:4034000009F10109F3E70020BDE8F0872DE9F04317460A7E85B06E2A984606460C460C9B01F1430E00F0AE8011D8632A22D009D8002A00F0BB80582A40F0CA8081F845207B
:40344000834955E0642A1ED0692A1CD0C0E0732A00F0B08009D86F2A2ED0702A40F0B8800A6842F020020A603EE0752A24D0782A3AD0ADE01A6801F14205111D1960136882
:4034800084F84230A8E021681A6811F0800F02D0111D196008E011F0400F02F10401196002D0B2F9003000E01368002B3CDA2D225B4284F8432037E021681A6811F0800F13
:4034C00002D0111D196007E011F0400F02F10401196001D0138800E01368227E5C496F2A14BF0A2208221BE078225A4984F845202268186812F0800F00F104051D6003D1DE
:40350000550601D5038800E00368D00744BF42F0200222601BB9226822F0200222601022002084F8430001E049490A226568002DA56008DB206820F0040020602BB9002D01
:403540007DD175460CE0002B79D07546B3FBF2F002FB1033CB5C05F8013D03460028F5D1082A0BD12368DA0708D5236962689A42DEBF302305F8013C05F1FF35C5EB0E0320
:4035800023612EE008681A6810F0800F496903D0101D1860136808E010F0400F02F104001860136801D0198000E0196000232361754616E01A68111D196015680021626886
:4035C000284600F049F808B1401B6060636804E004F1420584F8422001232361002384F84330CDF800803B4603AA21463046FFF797FE013002D14FF0FF3026E023692A4686
:4036000039463046C0470130F5D023689B0710D5002504F1190907E001234A4639463046C0470130E7D00135E368039A9B1A9D42F2DBE068039B9842B8BF184605E00B784F
:4036400004F1420584F842308AE705B0BDE8F083D5390000343B000010B5C9B202449042034605D01C7801308C42F8D1184610BD002010BD10B5431E0A44914204D011F857
:40368000014B03F8014FF8E710BD884210B501EB020301D8421E0BE09842FBD28118D21AD34204D013F8014D01F8014DF8E710BD994204D011F8014B02F8014FF8E710BDC8
:4036C00038B50546002944D051F8043C0C1F002BB8BFE41800F0D4F81E4A1368114613B96360146030E0A3420DD92268A018834201BF18685B681218226063600C6023E047
:40370000A24203D813465A68002AF9D118681918A1420BD12168014458188242196013D110685268014419605A600DE002D90C232B6009E021686018824201BF1068526820
:403740000918216062605C602846BDE8384000F098B838BD6086FF1F70B5CD1C25F0030508350C2D38BF0C25002D064601DBA94202D90C23336046E000F082F8234B1C683D
:403780001A462146A1B10B685B1B0ED40B2B03D90B60CC18CD501EE08C420BBF63684B681360636018BF0C4615E00C464968E9E7174C23681BB9304600F052F8206029460B
:4037C000304600F04DF8431C18D0C41C24F00304A0420DD12560304600F053F804F10B00231D20F00700C31A0ED05A42E25070BD211A304600F034F80130EBD10C2333605D
:40380000304600F03EF8002070BD00BF6086FF1F5C86FF1FF8B5074615460E4621B91146BDE8F840FFF798BF1AB9FFF749FF2846F8BD00F027F885420ED929463846FFF704
:403840008BFF044650B131462A46FFF713FF31463846FFF735FF01E03046F8BD2046F8BD38B5064C0023054608462360FDF7EAFB431C02D1236803B12B6038BD4487FF1F0D
:403880007047704751F8040C0028BEBF091851F8043CC0180438704700000000050209020B020D020F02110213027265706C792030782530327800686F6D696E6700626584
:4038C00067696E6E696E67207365656B2066726F6D20256420746F2025640066696E6973686564207365656B0057616974696E6720666F72205553422E2E2E005553422003
:40390000726561647900636F6D6D616E642030782530327800756E64657272756E206166746572202564207061636B65747300636F756E743D256420693D256420643D254F
:403940006400636D645F777269746500703D25642063723D25642063773D256420663D256420773D256420696E6465783D256420756E64657272756E3D25640077726974AE
:40398000652066696E69736865640073746172742065726173696E670073746F702065726173696E670069646C65000051004010004051004030000000014000100014018C
:4039C00040000800400140000A004C0140000200500140200030313233343536373839414243444546000001000000040000001000010000000400000010000028000000C0
:403A0000000104000100000000000000000157494E5553420000303030303100000000000000000012034D005300460054003100300030000100000001000000403A00005A
:403A4000010000000F3B0000000000000000000001000000583A000001000000E13A0000040000007A3A0000000000000000000000000000783A0000FF00000001024000A0
:403A8000FF00000082024000FF00000003034000FF00000084034000FF00020304030904160346006C007500780045006E00670069006E0065002A0343006F0077006C0050
:403AC000610072006B00200054006500630068006E006F006C006F0067006900650073000009022E0001010080320904000004FF0000010705010240000007058202400067
:403B0000000705030340000A0705840340000A12010002FF0001080912006E0100020180014300232D302B2000686C4C00656667454647003031323334353637383961621F
:403B40006364656600000000F8B500BFF8BC08BC9E46704759000000C1100000F8B500BFF8BC08BC9E46704735000000803B0000C880FF1FA0000000E005000000000000B0
:403B8000000000004887FF1FFF000000675000400C00000007000000FFFFFFFF7F8000003F0000000000007D00FA0000400000000090D003FF0000000000000000000000BC
:403BC000000000000000000000000000000000000000000000000000213B000000000000000000000000000000000000000000000000000000000000000000000000000069
:403C00000000000000000000000000000000000000000000000000000081FF1F000000000000000000000000000000000000000000000000000000000000000000000000E5
:403C40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044
:403C80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004
:403CC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C4
@@ -4098,72 +4098,72 @@
:40FF80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041
:40FFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
:0200000480007A
:4000000001450040075200400564004002030140030501400107014006090140500A01404B0B0140270C0140510D01404B0E0140330F01400115014003170140161801404D
:4000400025190140041B0140094001400A4101400E42014005430140044401401645014006460140094701400848014005490140164C0140034D01400550014003510140AF
:400080007E020806094410861115600B610E7C402C802D0A3A803C7E7E01E202EE02E201E621EC02EE02964099209D40A140A220EE020201050107060D040E010F01130742
:4000C0001501170219071C0228042F07300132043307340238023B083E1540654104430145044602475E483549FF4AFF4BFF4D204EF051105608580459045A045B045C9002
:400100005D995F0161086280630C64406540664067A8684069A86B086D08800281018205860F880F8A208C0F8E1096409C029E34A001A20AA480AC40AF01B007B101B2C048
:40014000B638B902BA02BF01D804D904DB04DC09DF010002014005010604072209800E22100816501740188019201A201D011E221F09210C25012B022D40311032053908BC
:400180003A403C024201430249144B485080520A582059405E406180630468096D807C207E08804081018B049140920B9340948095089620970A99109A549B629D05A2205A
:4001C000A302A480A508A602A708AA10AC80B380C0F9C2A1C4B2CA18CC07CE8AD009D20CD61CD80CE620EC04810188058A0A8C02900B96049A029C029E0DA002B008B40797
:40020000B601B701BE41BF40C041C720C820C9FFCAFFCBFFCD20CEF0D110D608D804D904DA04DB04DC09DD99DF01E108E240E340E480E640E74001200202050106010720D3
:4002400009080A820B080D200EA00F0110801711184019301A011D201F60200125C02648272A2F213608371138023D803E103F2040414560460447084E0850015601571050
:4002800058A05E105F8062706680670569406F01831087048B408C01928A934094809508970898209B509D149ED09F20A210A302A480A5A8A622A708AA40B020B440C0B326
:4002C000C2FFC458CA50CCE0CE11D079D220D63CD83CE004E804EE020080010402400410050808400A800B200C280D080F011007113112F8130A1420150418021C181D04E1
:400300001EC1200628F829092A072B162D072E042F38303F313F34C03A203B03580459045B045C995D905F01808086408840890D8C018D708E329140940195019606980FB5
:4003400099A09A209C0F9E10A004A209A705AA0FAB50AD0AB1C0B207B30CB4C0B503B638B730BA08D804D90BDB04DC99DF01016002D0040405400680070809080A820B0866
:400380000DA00E2010841203172119201A881B021C041D401E201F20220123402440251026082759280429102B022E802F283080310432013628370139483A113C403D20D8
:4003C00069406E407E80C0FFC2EFC45BCA7CCCEBCE3FDE80EA04E280EA02EE040D021901330237013F4459045B045F01850191029C01B001B102B501BE01BF11D608D80435
:40040000D904DB04DD90DF0109801A4022012308268027103002362038083D8058205A805C405D206008618068026C046F0285408A818C488F10964099209D40A140A220CF
:40044000C201CC21CE12D63CD80CE280E608EA02EE04AB02B420B640B70817043304340236803B443D80C420CCE0CE703380372085409744A540A680AC02CC30E240EE409B
:4004800050085710800883108B0497449F20A6C0A780AE40D460E280E680EC409F20A6C0A780AF40EE4014407380C404DC01500A56405D8062086640670280028A088F2038
:4004C00097209980A980AF10B040B780D407D605D802E002E401EA01EC089720A320A408AB01B008EE040B220E800F049720A320A408A640AE40C20F26408A80A6C0AB80D1
:40050000AF20C820EA40EE2077109B10AB10DE20EA20041008080C080F02508057205E80620187018A408E01A320A408AB01AF04C001C20DD406D604D802E004E402B49823
:40054000EA0AEC0201010D010F0111011D0100BD012A10050200000019006200000000001017002803400C02104828150300740480000000000001000063001C10004000CF
:40058000000000010000000F7F3080702008000000004010260103000000E04028FFFFFF0020F00120100100000018000404040499990001000800004020800840200008B0
:4005C000000040A8000000000000000000000000000000003F00003F1F001F000000000000000000100000004000000000000000C0000000FF0020FF47004700000100009A
:40060000A00000BFBF009F000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FC
:40064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007A
:40068000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003A
:4006C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FA
:4007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B9
:400740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000079
:400780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039
:4007C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F9
:4008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B8
:400840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000078
:400880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038
:4008C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F8
:4009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B7
:400940000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077
:400980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037
:4009C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F7
:400A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B6
:400A40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076
:400A80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036
:400AC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F6
:400B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B5
:400B40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000075
:400B80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035
:400BC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F5
:400C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B4
:400C40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074
:400C80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034
:400CC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F4
:400D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B3
:400D40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000073
:400D80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033
:400DC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F3
:400E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B2
:400E40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000072
:400E80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032
:400EC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F2
:400F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B1
:400F40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000071
:400F80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031
:400FC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F1
:4010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0
:401040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070
:400000000145004008520040015B00400164004001650040410001403E0101404102014054030140470401404C0501404A0601404E0701404A08014051090140430A01409A
:40004000500B0140520C0140560D0140500E01403A0F0140461401404C1501404A1601405C170140521801405F1901403D1A0140561B01400D4001400E4101400D4201408A
:400080000C430140074401400C450140074601400F4701400A4801400D490140164C0140044D014008500140045101407E0208420901100211821901600C610A7C40272171
:4000C0003F01290A0006010302010310050C06010703080509030A020B1C0E010F20110F12011601174019801A011E011F0F2201230A260127052A012C032D402E04300152
:4001000033C03406353F3B203E115608580459045B045C905D905F0183018AA08C709402980E9B029C40A205A502A650AA0AB0C0B20CB303B403B630D608D80BD904DB0470
:40014000DC99DD90DF010180020803600440070409220A110E2A10891104134016A01720188019101C401E2A1F1021382304272028022A042B402F10300131083220334088
:400180003720388039283A013F0158405B105D4061806220668067017D0280C0823084028A108C108D448F40C0CFC2EFC47FCA4BCC2FCE8FD61CD81CDE80E040E205E40512
:4001C000E622023F043F0A3F0E3F103F16021A101E042001243F2A202E08363F3E4058045B045F01817F820484088701880189018A088B288D318E108F029001953196024A
:40020000974E98289D409E019F3DA008A201A501A601A714A809AC01B007B10FB218B372B420B620BA0ABE10C206C70EC810C9FFCAFFCBFFCF83D804D904DA04DB04DC9961
:40024000DD09DF010040010803880492050408100AA20E840F1110011120130A151016801788188019441A901B2D1F8020802104220C23402A0432043340382039043A0193
:400280003B4049105008588859216004628263206D40812082048408854889048A808D018E108F289020950C9740989099109E259F44A080A104A203A501A608A888A98090
:4002C000AD02AE01B050B180B202B304B508B730C0FFC2FFC4FFCA02CC0ACE0FD204D60FD80FE241E408E601EA1FEE0100C0010D0440050D090D0A070C180D010E010F185B
:400300001002110412181312150D162018181B071F0D2218230D2404250D26102804290D2A082C1F2D0D32803303343F351C36403E403F14580459045C095F0181018501E5
:40034000870289018F019006920993019409950196069B019D01A101A501A901AD01AE03AF02B002B103B204B408B601B8AABE55BF01D804D904DB04DF0100810128080616
:400380000A080C0A1080110812051540180219A81A021B101D411E201F10202022102440288029042B062C012D112E0430013288332036A1370A388039243B023E403F191C
:4003C0006C0A800281018340840489408B4090809140920894529510962697119A049C019EA19FCEA0C0A104A30CA511A640A710A80CAA01AF01B040B104C00FC23EC48F76
:40040000CAFFCCFFCEFFE004E288E681EA04EC08EE0400100101040805010601080209010C020F011002130214021704180319011A041C1C1D011E032202240225012802B9
:4004400029012C022F01341F3507370739A03E10580459045C905F0180488210837F86498710893F8A028C408D018E308F40900193089401953F98489A209B029C499D3F71
:40048000A204A320A449A73FAA01AB3FAE01AF04B038B407B540B640B73FBA20BF50D804D904DC09DF010061010804820528080509400B040C200D8A0F081020120113125A
:4004C00014881584184919201B201E0822202302240425D026C0284429682D102E44311032813308340135503604380239083A813B103C043D013E803F10811882108512C5
:40050000881289049082940195359644979399809C819EA09F8CA010A210A30CA511A6E8A722AA01AF10B201B410B504B601C0FFC2FFC4FFCA7FCCFFCEFFE081E208E60EAE
:40054000EA0401020501062009020A180F02101F1103140215021618181819021A011E072004210222102502281829022C042E082F033503363F3F10580459045C095F01DA
:400580008201831385138604884089038A068E028F02905691039221931096019708987F99039C069F04A007A103A208A406A678A701A806AB03AC11AD03AE26B10FB31078
:4005C000B47FB50FBE10BF04D608D804D904DB04DC90DD90DF010004010102010308050407040A850B200E420F24111212321404158016801A081E0221052220251028111D
:400600002B882C022F64302231013204334034013719380139403A143C083D813E1059405C085D0462C0800181028202884089418C208D40918092C09324952096209824F0
:4006400099279A869B049C81A004A101A208A310A408A510A683AA40B005B310B661C06FC2FFC4DFCAFFCCEFCEFFD608D808E080E228E60AE820EA10000104080519080106
:400680000B090E1010011504160219011A081C012208262029122A042C013007330334383518370438203F4056085804590B5B045C995D905F0182018301860187018904CD
:4006C0008A018B038D038E018F04900193019601970198019B019C019F01A101A201A304A601A701AA01AB01AE01AF02B201B507B601BE44BF10D804D904DB04DF010166A1
:400700000486078808410A240C800E400F641120122213021601171519031A841B101C211D041E201F40200221242208262029202CA02EA02F0130083120379539283C045F
:400740003D813F3058805D045F0463016D406E407A80831087C0908691819306940196409751986499209A269B1F9D04A0A0A141A380A410A520A691A710A980AB04AC20E9
:40078000B084B140B304C0FFC2FFC4FFCAF4CCF6CEF6D608D808DE01E004E408ECA00318051806200701081809020B180C040D040E100F10101F110413081402161817070A
:4007C00018181A011B201C041E08211822182A072C402D1F323F333F36403E40580459045B045C995F0181228220853386188A078B028D028F20901F912893509418958288
:400800009705981899109A019B089C409D019F80A004A122A208A344A733A802A913AA18AB20AC04AE10B170B23FB307B580B640B708BB0ABE40BF50D804D904DB04DC9924
:40084000DF01001103100514060108040A400B050D400F6412011312140815401701181019401B041F84200C21582241230225042608280429102B502C802E4031283281A0
:400880003618370239A03A013B063C803D013F244FC05940640867086D4081408201844088048B048D058E049082910193029680974499A09A229B1D9C049D04A060A410BC
:4008C000A680A710A810AB14ACA0B120B401B680C0EEC2FFC4DBCA97CCEFCEFFD608E010E2A0E410E640E820EAD0EC10EE400328053807010A200B070D3F100412081418FD
:40090000174018181A011C041D041E101F30213422072308250226182738280229082A182B102C1F337F363F580459045C995F0181608205850B87F0880D89188BC38D0210
:400940008F04981099029B059C019E10A101A80AA9F1AB0AAF02B010B180B307B403B540B60CB738B980BB08BE01BF50C024C9FFCAFFCBFFD004D601D80BD904DA04DB0429
:40098000DC99DD09DF01E080E240E440E56400200510068008040A800B060C100E0A106011101340160819801C801D111E421F512010252126042702280429012B102C04B8
:4009C0002F4131043240341038123B443D123F6445204702584059806C416D016F1474A0762077097E808040822A87108E40C052C2CFC44FCAB7CC2ACEFFD0A0DE80E08003
:400A0000E660003F013F063F073F083F0B200D010E3F10011308160217021A101B101C3F1D3F2208233F26042704293F2A202E3F2F3F333F363F3E403F04580459045F0101
:400A4000810582028406852C86018702880689108E018F05900391139208932095059606980799059C019D0F9E069F10A105A201A401A505A60CA806A905AC06AD08AF0286
:400A8000B13FB40FBE10BF01D804D904DF01018102200308040805860604084409400A040B500C410F28111012011309142A15011B401F202204260129822A082B0C2D11AD
:400AC0002E4430443201331034453510380839103B413C043F6189408C088D048E208F05900491119246935196089702982399929A0D9B189C089F04A140A318A601A760CD
:400B0000A880A966AA05AB10AC10AE80B040B111C0FFC2FFC4FFCAFFCCFFCEFFE402E640E80FEC04EE01000604060A060D020E04110112061602180619021C0120012406CE
:400B4000250228062C06300132063302340137013A223B0C3E043F40580459045B045C995F01800181808580860289A98D808E01915695809601990C9A049B409D3D9E010B
:400B80009FC0A001A180A401A580AB03AC01AD30B007B1FFBA02BF01C001C50CC60EC805C9FFCAFFCBFFD004D601D804D904DA04DB04DC09DD09DF01E2C00182022004800A
:400BC00005290A280B010C240E8210011290140A1502161019021B021C041D031E201F102101258C2608281029822A102B082F203001310832903610370138883B223F80B0
:400C00004001442045044B045340681069596A466B906F01701071507288735979807B02822083028421858087108A208C108D018F01908992209599964697979816998874
:400C40009CC99D509EA09F8CA140A2C0A308A50BA608A702B120B210C0FDC2F7C4FDCA4FCCAFCE1FD008E00CE202E422E601EA80EE0802100301050409080D0F100411080B
:400C800015081A081B0F1C011D031F0C21082203270229082C082F083004310F3201341836023E053F015608580459045B045C095D905F018027842788278B018C208E0CA7
:400CC000903792C09501962798209A029C209E01A0F3A208A427A837A902AA40AC10AE87B2F0B40FB503BE14C034C620C808C9FFCAFFCBFFCD20CEF0D110D608D804D90455
:400D0000DA04DB04DC90DD99DF01E108E240E340E480E640E7400004011002010384058006800701082009080A820C020D200E021226130216421A201B101CA01D281E0268
:400D40001F082110274029202C212F4430403248344035013620370839203C083E5140404104501059405F80628064026A406B036C0278047A2082018310854086048709E0
:400D800089208B808C028D018E108F109108928293209404953196359788982899209A469E019F59A004A101A22AA468A540A7A8A880B010B104B201C01FC2DFC49FCAF44B
:400DC000CCF2CEF4D003D618D818E210E472E688E820EE09000E0270060409020A0E0E02102E124116011A011C7F1D01200F2210240E2A082C212E4E307F310235013E01EF
:400E00003F11580459045B045F018108820885048603880389018E048F089003930F95089603980399089C039D0FA003A108A602A702A908AA01AD03AF0CB60FB70FBF40A7
:400E4000D608D804D904DB04DC09DD90DF0100040201038805020604072108410A800B280C210D080E021024110212021428170219021E031F802040221027012C212E10D7
:400E80002F403280344035803601371838203C283D8158805A205C105F40652066806701680A80108740888089208B208C028E408F8190249101929093A894409601982C55
:400EC00099809A059B1A9E80A034A149A282A308A408A780A824AB2CAC01AD41B344B410C0FFC2FFC47FCAF0CCF8CEF4D63CD830E250E420E651E880EC801A401F083210ED
:400F0000330837123A106A406B108A108E04C630CCF0CE10300431803440350839013D8085408E109620A604B702CCF0CE60E2405280570889018A80928095019C449D08FB
:400F4000A580A604AA40D460EE80844485808A1092809C449D08A580A604AF08E210E650EE4014407B028A06C404DC01E001E6045602620296449A02A70AB040B640B708E3
:400F8000D604D802EA09EE021B08830286809644A602A70AC6080A010B200E200F02861187108A0296449840A280A602B040C20FE404E801238026148B8092809902A6145F
:400FC000AD08B102C8E0EE101A025A807220750286018E2092809902C640D480DC80DE20E44004100A800E400F021E045280548058405D0485048701941096449840A280E3
:40100000A810AF01C001C20DC601D407D60182409280B480EC02010109010B010D010F0111011B011D0100FF01AB020211050000BF0000A09F001F000000000000000000E5
:40104000100000004000000000000000C0000000FF0000B8470047000001000080000002820082000000000000010100010000002700180127001801000400000005000008
:401080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030
:4010C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0
:4011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AF
@@ -4615,12 +4615,12 @@
:0200000490105A
:04000000BC90ACAF55
:0200000490303A
:0200000033F2D9
:020000006F2D62
:0200000490402A
:4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0
:400040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080
:400080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040
:4000C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
:0200000490501A
:0C00000000012E16106900002E2A445B3F
:0C00000000012E16106900002E317F96C2
:00000001FF

View File

@@ -0,0 +1,27 @@
#include "cyfitter_cfg.h"
#include "cydevice_trm.h"
#include "cyfitter.h"
#include "`$INSTANCE_NAME`_h.h"
void `$INSTANCE_NAME`_Start()
{
`$INSTANCE_NAME`_Init();
}
void `$INSTANCE_NAME`_Stop()
{
`$INSTANCE_NAME`_Disable();
}
void `$INSTANCE_NAME`_Init()
{
`$INSTANCE_NAME`_Enable();
}
void `$INSTANCE_NAME`_Enable()
{
}
void `$INSTANCE_NAME`_Disable()
{
}

View File

@@ -0,0 +1,50 @@
#if !defined(`$INSTANCE_NAME`_H)
#define `$INSTANCE_NAME`_H
#include "cytypes.h"
#include "cyfitter.h"
#include "CyLib.h"
#define `$INSTANCE_NAME`_FIFO_PTR ((reg8 *) `$INSTANCE_NAME`_dp__F0_REG)
/* Macros to clear DP FIFOs.*/
#define `$INSTANCE_NAME`_CLEAR do { \
CY_SET_XTND_REG8(\
((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG), 0x01u | \
CY_GET_XTND_REG8(((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG)));\
CY_SET_XTND_REG8(\
((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG), 0xfeu & \
CY_GET_XTND_REG8(((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG)));\
} while(0)
/* Macros to set FIFO level mode. See the TRM for details */
#define `$INSTANCE_NAME`_SET_LEVEL_NORMAL \
CY_SET_XTND_REG8(\
((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG), 0xfbu & \
CY_GET_XTND_REG8(((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG)))
#define `$INSTANCE_NAME`_SET_LEVEL_MID \
CY_SET_XTND_REG8(\
((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG), 0x04u | \
CY_GET_XTND_REG8(((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG)))
/* Macros to set FIFO to single-buffer mode. */
#define `$INSTANCE_NAME`_SINGLE_BUFFER_SET \
CY_SET_XTND_REG8(\
((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG), 0x01u | \
CY_GET_XTND_REG8(((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG)))
/* Macros to return the FIFO to normal mode. */
#define `$INSTANCE_NAME`_SINGLE_BUFFER_UNSET \
CY_SET_XTND_REG8(\
((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG), 0xfeu & \
CY_GET_XTND_REG8(((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG)))
void `$INSTANCE_NAME`_Enable();
void `$INSTANCE_NAME`_Disable();
void `$INSTANCE_NAME`_Start();
void `$INSTANCE_NAME`_Stop();
void `$INSTANCE_NAME`_Init();
#endif
/* [] END OF FILE */

View File

Binary file not shown.

View File

@@ -0,0 +1,128 @@
//`#start header` -- edit after this line, do not edit this line
`include "cypress.v"
//`#end` -- edit above this line, do not edit this line
/* Ultra-simple FIFO in component: a byte is shifted in every clock when req
* is high. */
module FIFOin (drq, clk, d, req);
output drq;
input clk;
input [7:0] d;
input req;
//`#start body` -- edit after this line, do not edit this line
wire [7:0] pi;
assign pi = d;
wire load;
assign load = req;
cy_psoc3_dp #(.cy_dpconfig(
{
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM0: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM1: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM2: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM3: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM4: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM5: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM6: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM7: */
8'hFF, 8'h00, /*CFG9: */
8'hFF, 8'hFF, /*CFG11-10: */
`SC_CMPB_A1_D1, `SC_CMPA_A1_D1, `SC_CI_B_ARITH,
`SC_CI_A_ARITH, `SC_C1_MASK_DSBL, `SC_C0_MASK_DSBL,
`SC_A_MASK_DSBL, `SC_DEF_SI_0, `SC_SI_B_DEFSI,
`SC_SI_A_DEFSI, /*CFG13-12: */
`SC_A0_SRC_PIN, `SC_SHIFT_SL, 1'h0,
1'h0, `SC_FIFO1_BUS, `SC_FIFO0_ALU,
`SC_MSB_DSBL, `SC_MSB_BIT0, `SC_MSB_NOCHN,
`SC_FB_NOCHN, `SC_CMP1_NOCHN,
`SC_CMP0_NOCHN, /*CFG15-14: */
10'h00, `SC_FIFO_CLK__DP,`SC_FIFO_CAP_AX,
`SC_FIFO_LEVEL,`SC_FIFO__SYNC,`SC_EXTCRC_DSBL,
`SC_WRK16CAT_DSBL /*CFG17-16: */
}
)) dp(
/* input */ .clk(clk),
/* input [02:00] */ .cs_addr(3'b0), // Program counter
/* input */ .route_si(1'b0), // Shift in
/* input */ .route_ci(1'b0), // Carry in
/* input */ .f0_load(load), // Load FIFO 0
/* input */ .f1_load(1'b0), // Load FIFO 1
/* input */ .d0_load(1'b0), // Load Data Register 0
/* input */ .d1_load(1'b0), // Load Data Register 1
/* output */ .ce0(), // Accumulator 0 = Data register 0
/* output */ .cl0(), // Accumulator 0 < Data register 0
/* output */ .z0(), // Accumulator 0 = 0
/* output */ .ff0(), // Accumulator 0 = FF
/* output */ .ce1(), // Accumulator [0|1] = Data register 1
/* output */ .cl1(), // Accumulator [0|1] < Data register 1
/* output */ .z1(), // Accumulator 1 = 0
/* output */ .ff1(), // Accumulator 1 = FF
/* output */ .ov_msb(), // Operation over flow
/* output */ .co_msb(), // Carry out
/* output */ .cmsb(), // Carry out
/* output */ .so(), // Shift out
/* output */ .f0_bus_stat(drq), // not empty
/* output */ .f0_blk_stat(full),// full
/* output */ .f1_bus_stat(), // FIFO 1 status to uP
/* output */ .f1_blk_stat(), // FIFO 1 status to DP
/* input */ .ci(1'b0), // Carry in from previous stage
/* output */ .co(), // Carry out to next stage
/* input */ .sir(1'b0), // Shift in from right side
/* output */ .sor(), // Shift out to right side
/* input */ .sil(1'b0), // Shift in from left side
/* output */ .sol(), // Shift out to left side
/* input */ .msbi(1'b0), // MSB chain in
/* output */ .msbo(), // MSB chain out
/* input [01:00] */ .cei(2'b0), // Compare equal in from prev stage
/* output [01:00] */ .ceo(), // Compare equal out to next stage
/* input [01:00] */ .cli(2'b0), // Compare less than in from prv stage
/* output [01:00] */ .clo(), // Compare less than out to next stage
/* input [01:00] */ .zi(2'b0), // Zero detect in from previous stage
/* output [01:00] */ .zo(), // Zero detect out to next stage
/* input [01:00] */ .fi(2'b0), // 0xFF detect in from previous stage
/* output [01:00] */ .fo(), // 0xFF detect out to next stage
/* input [01:00] */ .capi(2'b0), // Capture in from previous stage
/* output [01:00] */ .capo(), // Capture out to next stage
/* input */ .cfbi(1'b0), // CRC Feedback in from previous stage
/* output */ .cfbo(), // CRC Feedback out to next stage
/* input [07:00] */ .pi(pi), // Parallel data port
/* output [07:00] */ .po() // Parallel data port
);
//`#end` -- edit above this line, do not edit this line
endmodule
//`#start footer` -- edit after this line, do not edit this line
//`#end` -- edit above this line, do not edit this line

View File

@@ -0,0 +1,27 @@
#include "cyfitter_cfg.h"
#include "cydevice_trm.h"
#include "cyfitter.h"
#include "`$INSTANCE_NAME`_h.h"
void `$INSTANCE_NAME`_Start()
{
`$INSTANCE_NAME`_Init();
}
void `$INSTANCE_NAME`_Stop()
{
`$INSTANCE_NAME`_Disable();
}
void `$INSTANCE_NAME`_Init()
{
`$INSTANCE_NAME`_Enable();
}
void `$INSTANCE_NAME`_Enable()
{
}
void `$INSTANCE_NAME`_Disable()
{
}

View File

@@ -0,0 +1,50 @@
#if !defined(`$INSTANCE_NAME`_H)
#define `$INSTANCE_NAME`_H
#include "cytypes.h"
#include "cyfitter.h"
#include "CyLib.h"
#define `$INSTANCE_NAME`_FIFO_PTR ((reg8 *) `$INSTANCE_NAME`_dp__F0_REG)
/* Macros to clear DP FIFOs.*/
#define `$INSTANCE_NAME`_CLEAR do { \
CY_SET_XTND_REG8(\
((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG), 0x01u | \
CY_GET_XTND_REG8(((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG)));\
CY_SET_XTND_REG8(\
((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG), 0xfeu & \
CY_GET_XTND_REG8(((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG)));\
} while(0)
/* Macros to set FIFO level mode. See the TRM for details */
#define `$INSTANCE_NAME`_SET_LEVEL_NORMAL \
CY_SET_XTND_REG8(\
((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG), 0xfbu & \
CY_GET_XTND_REG8(((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG)))
#define `$INSTANCE_NAME`_SET_LEVEL_MID \
CY_SET_XTND_REG8(\
((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG), 0x04u | \
CY_GET_XTND_REG8(((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG)))
/* Macros to set FIFO to single-buffer mode. */
#define `$INSTANCE_NAME`_SINGLE_BUFFER_SET \
CY_SET_XTND_REG8(\
((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG), 0x01u | \
CY_GET_XTND_REG8(((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG)))
/* Macros to return the FIFO to normal mode. */
#define `$INSTANCE_NAME`_SINGLE_BUFFER_UNSET \
CY_SET_XTND_REG8(\
((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG), 0xfeu & \
CY_GET_XTND_REG8(((reg8 *) `$INSTANCE_NAME`_dp__DP_AUX_CTL_REG)))
void `$INSTANCE_NAME`_Enable();
void `$INSTANCE_NAME`_Disable();
void `$INSTANCE_NAME`_Start();
void `$INSTANCE_NAME`_Stop();
void `$INSTANCE_NAME`_Init();
#endif
/* [] END OF FILE */

View File

Binary file not shown.

View File

@@ -0,0 +1,168 @@
//`#start header` -- edit after this line, do not edit this line
`include "cypress.v"
//`#end` -- edit above this line, do not edit this line
// Generated on 11/16/2017 at 15:44
// Component: FIFOout
module FIFOout (
input req,
input clk,
output [7:0] d,
output drq,
output empty,
output ack
);
//`#start body` -- edit after this line, do not edit this line
/* Reads from the FIFO are done based on the FIFO being not empty. */
wire [7:0] po;
assign d = po;
localparam STATE_WAIT = 1'b0;
localparam STATE_READ = 1'b1;
reg state;
reg oldreq;
assign ack = (state != STATE_READ);
always @(posedge clk)
begin
case (state)
STATE_WAIT:
begin
if (!empty)
begin
if (req && !oldreq)
begin
state <= STATE_READ;
end
oldreq <= req;
end
end
STATE_READ:
begin
state <= STATE_WAIT;
end
endcase
end
cy_psoc3_dp #(.cy_dpconfig(
{
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM0: STATE_WAITFORREQ*/
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC___F0, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM1: STATE_LOAD*/
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM2: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM3: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM4: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM5: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM6: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM7: */
8'hFF, 8'h00, /*CFG9: */
8'hFF, 8'hFF, /*CFG11-10: */
`SC_CMPB_A1_D1, `SC_CMPA_A1_D1, `SC_CI_B_ARITH,
`SC_CI_A_ARITH, `SC_C1_MASK_DSBL, `SC_C0_MASK_DSBL,
`SC_A_MASK_DSBL, `SC_DEF_SI_0, `SC_SI_B_DEFSI,
`SC_SI_A_DEFSI, /*CFG13-12: */
`SC_A0_SRC_ACC, `SC_SHIFT_SL, 1'h0,
1'h0, `SC_FIFO1_BUS, `SC_FIFO0_BUS,
`SC_MSB_DSBL, `SC_MSB_BIT0, `SC_MSB_NOCHN,
`SC_FB_NOCHN, `SC_CMP1_NOCHN,
`SC_CMP0_NOCHN, /*CFG15-14: */
10'h00, `SC_FIFO_CLK__DP,`SC_FIFO_CAP_AX,
`SC_FIFO_LEVEL,`SC_FIFO_ASYNC,`SC_EXTCRC_DSBL,
`SC_WRK16CAT_DSBL /*CFG17-16: */
}
)) dp(
/* input */ .reset(1'b0),
/* input */ .clk(clk),
/* input [02:00] */ .cs_addr({2'b0, state}),
/* input */ .route_si(1'b0),
/* input */ .route_ci(1'b0),
/* input */ .f0_load(1'b0),
/* input */ .f1_load(1'b0),
/* input */ .d0_load(1'b0),
/* input */ .d1_load(1'b0),
/* output */ .ce0(),
/* output */ .cl0(),
/* output */ .z0(),
/* output */ .ff0(),
/* output */ .ce1(),
/* output */ .cl1(),
/* output */ .z1(),
/* output */ .ff1(),
/* output */ .ov_msb(),
/* output */ .co_msb(),
/* output */ .cmsb(),
/* output */ .so(),
/* output */ .f0_bus_stat(drq), // not full
/* output */ .f0_blk_stat(empty), // empty
/* output */ .f1_bus_stat(),
/* output */ .f1_blk_stat(),
/* input */ .ci(1'b0), // Carry in from previous stage
/* output */ .co(),// Carry out to next stage
/* input */ .sir(1'b0), // Shift in from right side
/* output */ .sor(), // Shift out to right side
/* input */ .sil(1'b0), // Shift in from left side
/* output */ .sol(), // Shift out to left side
/* input */ .msbi(1'b0), // MSB chain in
/* output */ .msbo(), // MSB chain out
/* input [01:00] */ .cei(2'b0), // Compare equal in from prev stage
/* output [01:00] */ .ceo(), // Compare equal out to next stage
/* input [01:00] */ .cli(2'b0), // Compare less than in from prv stage
/* output [01:00] */ .clo(), // Compare less than out to next stage
/* input [01:00] */ .zi(2'b0), // Zero detect in from previous stage
/* output [01:00] */ .zo(), // Zero detect out to next stage
/* input [01:00] */ .fi(2'b0), // 0xFF detect in from previous stage
/* output [01:00] */ .fo(), // 0xFF detect out to next stage
/* input [01:00] */ .capi(2'b0), // Software capture from previous stage
/* output [01:00] */ .capo(), // Software capture to next stage
/* input */ .cfbi(1'b0), // CRC Feedback in from previous stage
/* output */ .cfbo(), // CRC Feedback out to next stage
/* input [07:00] */ .pi(8'b0), // Parallel data port
/* output [07:00] */ .po(po) // Parallel data port
);
//`#end` -- edit above this line, do not edit this line
endmodule
//`#start footer` -- edit after this line, do not edit this line
//`#end` -- edit above this line, do not edit this line

View File

@@ -28,6 +28,54 @@
<Data key="sync_with_bus_clk" value="True" />
<Data key="user_set_domain" value="False" />
</Group>
<Group key="1a7e8637-3b6b-4e84-839c-0dfc18fdaf5b">
<Data key="check_tolerance" value="True" />
<Data key="clock_version" value="v1" />
<Data key="derive_type" value="NAMED_DIVIDER" />
<Data key="desired_freq" value="0" />
<Data key="desired_unit" value="15" />
<Data key="divider" value="0" />
<Data key="domain" value="DIGITAL" />
<Data key="enabled" value="True" />
<Data key="minus_accuracy" value="0.25" />
<Data key="minus_tolerance" value="5" />
<Data key="name" value="Clock_5" />
<Data key="named_src_direct_connect" value="True" />
<Data key="netlist_name" value="Clock_5" />
<Data key="placement" value="AUTO" />
<Data key="plus_accuracy" value="0.25" />
<Data key="plus_tolerance" value="5" />
<Data key="scope" value="LOCAL" />
<Data key="src_clk_id" value="75C2148C-3656-4d8a-846D-0CAE99AB6FF7" />
<Data key="src_clk_name" value="BUS_CLK" />
<Data key="start_on_reset" value="True" />
<Data key="sync_with_bus_clk" value="True" />
<Data key="user_set_domain" value="False" />
</Group>
<Group key="3f3708ae-fb62-4012-919b-9a3b9a1dfbc2">
<Data key="check_tolerance" value="True" />
<Data key="clock_version" value="v1" />
<Data key="derive_type" value="NAMED_DIVIDER" />
<Data key="desired_freq" value="0" />
<Data key="desired_unit" value="15" />
<Data key="divider" value="0" />
<Data key="domain" value="DIGITAL" />
<Data key="enabled" value="True" />
<Data key="minus_accuracy" value="0.25" />
<Data key="minus_tolerance" value="5" />
<Data key="name" value="Clock_8" />
<Data key="named_src_direct_connect" value="True" />
<Data key="netlist_name" value="Clock_8" />
<Data key="placement" value="AUTO" />
<Data key="plus_accuracy" value="0.25" />
<Data key="plus_tolerance" value="5" />
<Data key="scope" value="LOCAL" />
<Data key="src_clk_id" value="75C2148C-3656-4d8a-846D-0CAE99AB6FF7" />
<Data key="src_clk_name" value="BUS_CLK" />
<Data key="start_on_reset" value="True" />
<Data key="sync_with_bus_clk" value="True" />
<Data key="user_set_domain" value="False" />
</Group>
<Group key="4eef02b9-8ad1-43c4-85f1-b3335faa5fc4">
<Data key="check_tolerance" value="True" />
<Data key="clock_version" value="v1" />
@@ -147,6 +195,54 @@
<Data key="sync_with_bus_clk" value="True" />
<Data key="user_set_domain" value="False" />
</Group>
<Group key="71bc291d-84a7-40a8-b7b2-1c8a34326a31">
<Data key="check_tolerance" value="True" />
<Data key="clock_version" value="v1" />
<Data key="derive_type" value="NAMED_FREQ" />
<Data key="desired_freq" value="300" />
<Data key="desired_unit" value="0" />
<Data key="divider" value="65536" />
<Data key="domain" value="DIGITAL" />
<Data key="enabled" value="True" />
<Data key="minus_accuracy" value="0.25" />
<Data key="minus_tolerance" value="5" />
<Data key="name" value="CLOCK300" />
<Data key="named_src_direct_connect" value="False" />
<Data key="netlist_name" value="CLOCK300" />
<Data key="placement" value="AUTO" />
<Data key="plus_accuracy" value="0.25" />
<Data key="plus_tolerance" value="5" />
<Data key="scope" value="LOCAL" />
<Data key="src_clk_id" value="CEF43CFB-0213-49b9-B980-2FFAB81C5B47" />
<Data key="src_clk_name" value="IMO" />
<Data key="start_on_reset" value="True" />
<Data key="sync_with_bus_clk" value="True" />
<Data key="user_set_domain" value="False" />
</Group>
<Group key="90ce0c72-9f10-44ef-a049-f0f525d59bea">
<Data key="check_tolerance" value="True" />
<Data key="clock_version" value="v1" />
<Data key="derive_type" value="NAMED_FREQ" />
<Data key="desired_freq" value="128" />
<Data key="desired_unit" value="0" />
<Data key="divider" value="65536" />
<Data key="domain" value="DIGITAL" />
<Data key="enabled" value="True" />
<Data key="minus_accuracy" value="0.25" />
<Data key="minus_tolerance" value="5" />
<Data key="name" value="CLOCK8" />
<Data key="named_src_direct_connect" value="False" />
<Data key="netlist_name" value="CLOCK8" />
<Data key="placement" value="AUTO" />
<Data key="plus_accuracy" value="0.25" />
<Data key="plus_tolerance" value="5" />
<Data key="scope" value="LOCAL" />
<Data key="src_clk_id" value="CEF43CFB-0213-49b9-B980-2FFAB81C5B47" />
<Data key="src_clk_name" value="IMO" />
<Data key="start_on_reset" value="True" />
<Data key="sync_with_bus_clk" value="True" />
<Data key="user_set_domain" value="False" />
</Group>
<Group key="349ffa20-8576-4ac3-9a6f-34ef606de6cf">
<Data key="check_tolerance" value="True" />
<Data key="clock_version" value="v1" />
@@ -170,6 +266,29 @@
<Data key="sync_with_bus_clk" value="True" />
<Data key="user_set_domain" value="False" />
</Group>
<Group key="4033c29d-f4bc-4e94-ac95-aa587e869f88/696a0979-21fc-4185-bf38-6c79febcde7a">
<Data key="check_tolerance" value="False" />
<Data key="clock_version" value="v1" />
<Data key="derive_type" value="AUTO" />
<Data key="desired_freq" value="1600000" />
<Data key="desired_unit" value="0" />
<Data key="divider" value="40" />
<Data key="domain" value="DIGITAL" />
<Data key="enabled" value="True" />
<Data key="minus_accuracy" value="0.25" />
<Data key="minus_tolerance" value="5" />
<Data key="name" value="OUTPUT_VOLTAGE_ADC_theACLK" />
<Data key="netlist_name" value="\OUTPUT_VOLTAGE_ADC:theACLK\" />
<Data key="placement" value="AUTO" />
<Data key="plus_accuracy" value="0.25" />
<Data key="plus_tolerance" value="5" />
<Data key="scope" value="LOCAL" />
<Data key="src_clk_id" value="61737EF6-3B74-48f9-8B91-F7473A442AE7" />
<Data key="src_clk_name" value="MASTER_CLK" />
<Data key="start_on_reset" value="True" />
<Data key="sync_with_bus_clk" value="True" />
<Data key="user_set_domain" value="False" />
</Group>
<Group key="6616e828-6611-4893-a674-66c861d79d6c">
<Data key="check_tolerance" value="True" />
<Data key="clock_version" value="v1" />
@@ -241,6 +360,53 @@
<Data key="sync_with_bus_clk" value="True" />
<Data key="user_set_domain" value="False" />
</Group>
<Group key="09974428-e912-491f-8d2f-361ba50e7599">
<Data key="check_tolerance" value="True" />
<Data key="clock_version" value="v1" />
<Data key="derive_type" value="NAMED_DIVIDER" />
<Data key="desired_freq" value="0" />
<Data key="desired_unit" value="15" />
<Data key="divider" value="0" />
<Data key="domain" value="DIGITAL" />
<Data key="enabled" value="True" />
<Data key="minus_accuracy" value="0.25" />
<Data key="minus_tolerance" value="5" />
<Data key="name" value="Clock_6" />
<Data key="named_src_direct_connect" value="True" />
<Data key="netlist_name" value="Clock_6" />
<Data key="placement" value="AUTO" />
<Data key="plus_accuracy" value="0.25" />
<Data key="plus_tolerance" value="5" />
<Data key="scope" value="LOCAL" />
<Data key="src_clk_id" value="75C2148C-3656-4d8a-846D-0CAE99AB6FF7" />
<Data key="src_clk_name" value="BUS_CLK" />
<Data key="start_on_reset" value="True" />
<Data key="sync_with_bus_clk" value="True" />
<Data key="user_set_domain" value="False" />
</Group>
<Group key="a5825a94-fa18-4e4f-a843-bc687cacbd56/696a0979-21fc-4185-bf38-6c79febcde7a">
<Data key="check_tolerance" value="False" />
<Data key="clock_version" value="v1" />
<Data key="derive_type" value="AUTO" />
<Data key="desired_freq" value="1600000" />
<Data key="desired_unit" value="0" />
<Data key="divider" value="40" />
<Data key="domain" value="DIGITAL" />
<Data key="enabled" value="True" />
<Data key="minus_accuracy" value="0.25" />
<Data key="minus_tolerance" value="5" />
<Data key="name" value="INPUT_VOLTAGE_ADC_theACLK" />
<Data key="netlist_name" value="\INPUT_VOLTAGE_ADC:theACLK\" />
<Data key="placement" value="AUTO" />
<Data key="plus_accuracy" value="0.25" />
<Data key="plus_tolerance" value="5" />
<Data key="scope" value="LOCAL" />
<Data key="src_clk_id" value="61737EF6-3B74-48f9-8B91-F7473A442AE7" />
<Data key="src_clk_name" value="MASTER_CLK" />
<Data key="start_on_reset" value="True" />
<Data key="sync_with_bus_clk" value="True" />
<Data key="user_set_domain" value="False" />
</Group>
<Group key="b762c287-7f87-4b21-982e-84be01dc5115">
<Data key="check_tolerance" value="True" />
<Data key="clock_version" value="v1" />
@@ -288,6 +454,30 @@
<Data key="sync_with_bus_clk" value="True" />
<Data key="user_set_domain" value="False" />
</Group>
<Group key="b722443b-8f81-46dc-bf9b-c95eb62bc181">
<Data key="check_tolerance" value="True" />
<Data key="clock_version" value="v1" />
<Data key="derive_type" value="NAMED_DIVIDER" />
<Data key="desired_freq" value="0" />
<Data key="desired_unit" value="15" />
<Data key="divider" value="0" />
<Data key="domain" value="DIGITAL" />
<Data key="enabled" value="True" />
<Data key="minus_accuracy" value="0.25" />
<Data key="minus_tolerance" value="5" />
<Data key="name" value="Clock_1" />
<Data key="named_src_direct_connect" value="True" />
<Data key="netlist_name" value="Clock_1" />
<Data key="placement" value="AUTO" />
<Data key="plus_accuracy" value="0.25" />
<Data key="plus_tolerance" value="5" />
<Data key="scope" value="LOCAL" />
<Data key="src_clk_id" value="75C2148C-3656-4d8a-846D-0CAE99AB6FF7" />
<Data key="src_clk_name" value="BUS_CLK" />
<Data key="start_on_reset" value="True" />
<Data key="sync_with_bus_clk" value="True" />
<Data key="user_set_domain" value="False" />
</Group>
<Group key="cb7e877c-9fb4-4fc1-a708-f1e48eb5a68c">
<Data key="check_tolerance" value="True" />
<Data key="clock_version" value="v1" />
@@ -312,6 +502,30 @@
<Data key="sync_with_bus_clk" value="True" />
<Data key="user_set_domain" value="False" />
</Group>
<Group key="d3075dc6-05c8-4dc9-9959-cf7014c0e66f">
<Data key="check_tolerance" value="True" />
<Data key="clock_version" value="v1" />
<Data key="derive_type" value="NAMED_DIVIDER" />
<Data key="desired_freq" value="0" />
<Data key="desired_unit" value="15" />
<Data key="divider" value="0" />
<Data key="domain" value="DIGITAL" />
<Data key="enabled" value="True" />
<Data key="minus_accuracy" value="0.25" />
<Data key="minus_tolerance" value="5" />
<Data key="name" value="Clock_7" />
<Data key="named_src_direct_connect" value="True" />
<Data key="netlist_name" value="Clock_7" />
<Data key="placement" value="AUTO" />
<Data key="plus_accuracy" value="0.25" />
<Data key="plus_tolerance" value="5" />
<Data key="scope" value="LOCAL" />
<Data key="src_clk_id" value="75C2148C-3656-4d8a-846D-0CAE99AB6FF7" />
<Data key="src_clk_name" value="BUS_CLK" />
<Data key="start_on_reset" value="True" />
<Data key="sync_with_bus_clk" value="True" />
<Data key="user_set_domain" value="False" />
</Group>
<Group key="e4a53a4c-40e1-4747-a72a-10193ffdf31c">
<Data key="check_tolerance" value="True" />
<Data key="clock_version" value="v1" />
@@ -609,18 +823,27 @@
<Group key="DWRInstGuidMapping">
<Group key="Clock">
<Data key="0b2f9bbb-00ce-4115-a788-ffb9d046a9e5" value="Clock_4" />
<Data key="1a7e8637-3b6b-4e84-839c-0dfc18fdaf5b" value="Clock_5" />
<Data key="3f3708ae-fb62-4012-919b-9a3b9a1dfbc2" value="Clock_8" />
<Data key="4eef02b9-8ad1-43c4-85f1-b3335faa5fc4" value="Clock_3" />
<Data key="06c4d5d4-f15f-4b29-a1d0-c24b2e38b1ec" value="CounterClock" />
<Data key="24cd38f7-f472-4403-837f-86807c8f5333" value="PULSE_CLOCK" />
<Data key="63ed4137-0b09-4256-8a27-35c9a2653f1a" value="Clock_2" />
<Data key="66f14071-bddd-4b4d-a9aa-a129cceaa7b6" value="Clock_3" />
<Data key="71bc291d-84a7-40a8-b7b2-1c8a34326a31" value="CLOCK300" />
<Data key="90ce0c72-9f10-44ef-a049-f0f525d59bea" value="CLOCK8" />
<Data key="349ffa20-8576-4ac3-9a6f-34ef606de6cf" value="Clock_1" />
<Data key="4033c29d-f4bc-4e94-ac95-aa587e869f88/696a0979-21fc-4185-bf38-6c79febcde7a" value="OUTPUT_VOLTAGE_ADC_theACLK" />
<Data key="6616e828-6611-4893-a674-66c861d79d6c" value="SignalSamplingClock" />
<Data key="12664fc6-9d70-44b1-8a49-887a292e1b7f" value="Clock_3" />
<Data key="75187c05-9501-4450-b306-6ccdd3bb77db" value="Clock_5" />
<Data key="09974428-e912-491f-8d2f-361ba50e7599" value="Clock_6" />
<Data key="a5825a94-fa18-4e4f-a843-bc687cacbd56/696a0979-21fc-4185-bf38-6c79febcde7a" value="INPUT_VOLTAGE_ADC_theACLK" />
<Data key="b762c287-7f87-4b21-982e-84be01dc5115" value="Clock_2" />
<Data key="b0162966-0060-4af5-82d1-fcb491ad7619/be0a0e37-ad17-42ca-b5a1-1a654d736358" value="UART_IntClock" />
<Data key="b722443b-8f81-46dc-bf9b-c95eb62bc181" value="Clock_1" />
<Data key="cb7e877c-9fb4-4fc1-a708-f1e48eb5a68c" value="CounterClock" />
<Data key="d3075dc6-05c8-4dc9-9959-cf7014c0e66f" value="Clock_7" />
<Data key="e4a53a4c-40e1-4747-a72a-10193ffdf31c" value="Clock_1" />
<Data key="efd5f185-0c32-4824-ba72-3ceb5356f5a7" value="Clock_1" />
</Group>
@@ -638,16 +861,18 @@
<Data key="a5d987c6-e45b-45b9-ad93-656fab06d720" value="TRK00" />
<Data key="a93ef5b3-00f4-42c0-8fad-0e275a7e2537" value="MOTEB" />
<Data key="b8380fb7-fdb8-449f-bd8d-c4ca96cdf55a" value="DEBUG_PINS" />
<Data key="bc2e8987-db82-469c-bf6f-22fd3464cc70" value="DEBUG_PINS" />
<Data key="bc5d52a1-1b25-4aa0-9ba9-3f81d122772f" value="DEBUG_PINS" />
<Data key="beca5e2d-f70f-4900-a4db-7eca1ed3126e/8b77a6c4-10a0-4390-971c-672353e2a49c" value="USBFS_Dm" />
<Data key="beca5e2d-f70f-4900-a4db-7eca1ed3126e/618a72fc-5ddd-4df5-958f-a3d55102db42" value="USBFS_Dp" />
<Data key="c5367cde-21d5-4866-9a32-d16abfea0c61" value="WPT" />
<Data key="d19368c5-6855-41bb-a9ff-808938abef00" value="INDEX" />
<Data key="e9f14b5a-b2bf-49b8-98f3-d7b5a43ace8d" value="DRVSB" />
<Data key="e851a3b9-efb8-48be-bbb8-b303b216c393" value="LED" />
<Data key="e851a3b9-efb8-48be-bbb8-b303b216c393" value="INDEX300" />
<Data key="e51063a9-4fad-40c7-a06b-7cc4b137dc18" value="DSKCHG" />
<Data key="ea7ee228-8b3f-426c-8bb8-cd7a81937769" value="DIR" />
<Data key="ed092b9b-d398-4703-be89-cebf998501f6" value="UartTx" />
<Data key="f9a7371a-8a7d-4144-8b08-69e3d2a3a663" value="INDEX360" />
<Data key="fbd1f839-40f9-498e-a48b-5f3048ea5c3d/52f31aa9-2f0a-497d-9a1f-1424095e13e6" value="UART_tx" />
<Data key="fede1767-f3fd-4021-b3d7-8f9d88f36f9b" value="DRVSA" />
<Data key="fff78075-035e-43d7-8577-bc5be4d21926" value="WGATE" />
@@ -3859,6 +4084,32 @@
<Data key="Port Format" value="2,3" />
</Group>
</Group>
<Group key="bc2e8987-db82-469c-bf6f-22fd3464cc70">
<Group key="0">
<Data key="Port Format" value="0,0" />
</Group>
<Group key="1">
<Data key="Port Format" value="0,1" />
</Group>
<Group key="2">
<Data key="Port Format" value="0,2" />
</Group>
<Group key="3">
<Data key="Port Format" value="0,3" />
</Group>
<Group key="4">
<Data key="Port Format" value="0,4" />
</Group>
<Group key="5">
<Data key="Port Format" value="0,5" />
</Group>
<Group key="6">
<Data key="Port Format" value="0,6" />
</Group>
<Group key="7">
<Data key="Port Format" value="0,7" />
</Group>
</Group>
<Group key="bc5d52a1-1b25-4aa0-9ba9-3f81d122772f">
<Group key="0">
<Data key="Port Format" value="0,5" />
@@ -3894,7 +4145,7 @@
</Group>
<Group key="e851a3b9-efb8-48be-bbb8-b303b216c393">
<Group key="0">
<Data key="Port Format" value="2,1" />
<Data key="Port Format" value="3,0" />
</Group>
</Group>
<Group key="e51063a9-4fad-40c7-a06b-7cc4b137dc18">
@@ -3912,9 +4163,14 @@
<Data key="Port Format" value="12,7" />
</Group>
</Group>
<Group key="f9a7371a-8a7d-4144-8b08-69e3d2a3a663">
<Group key="0">
<Data key="Port Format" value="3,1" />
</Group>
</Group>
<Group key="fbd1f839-40f9-498e-a48b-5f3048ea5c3d/52f31aa9-2f0a-497d-9a1f-1424095e13e6">
<Group key="0">
<Data key="Port Format" value="2,5" />
<Data key="Port Format" value="12,7" />
</Group>
</Group>
<Group key="fede1767-f3fd-4021-b3d7-8f9d88f36f9b">

View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,134 @@
//`#start header` -- edit after this line, do not edit this line
`include "cypress.v"
`include "../SuperCounter/SuperCounter.v"
//`#end` -- edit above this line, do not edit this line
// Generated on 12/11/2019 at 21:18
// Component: Sampler
module Sampler (
output [2:0] debug_state,
output reg [7:0] opcode,
output req,
input clock,
input index,
input rdata,
input reset,
input sampleclock
);
//`#start body` -- edit after this line, do not edit this line
localparam STATE_RESET = 0;
localparam STATE_WAITING = 1;
localparam STATE_INTERVAL = 2;
localparam STATE_DISPATCH = 3;
localparam STATE_OPCODE = 4;
localparam STATE_COUNTING = 5;
reg [2:0] state;
wire [6:0] counter;
wire countnow;
assign countnow = (state == STATE_COUNTING);
wire counterreset;
assign counterreset = (state == STATE_INTERVAL) || (state == STATE_OPCODE);
SuperCounter #(.Delta(1), .ResetValue(0)) Counter
(
/* input */ .clk(clock),
/* input */ .reset(counterreset),
/* input */ .count(countnow),
/* output */ .d(counter)
);
reg oldsampleclock;
wire sampleclocked;
assign sampleclocked = !oldsampleclock && sampleclock;
reg oldindex;
wire indexed;
assign indexed = !oldindex && index;
wire rdataed;
reg oldrdata;
assign rdataed = !oldrdata && rdata;
assign req = (state == STATE_INTERVAL) || (state == STATE_OPCODE);
always @(posedge clock)
begin
if (reset)
begin
state <= STATE_RESET;
opcode <= 0;
oldsampleclock <= 0;
oldindex <= 0;
oldrdata <= 0;
end
else
case (state)
STATE_RESET:
state <= STATE_WAITING;
STATE_WAITING:
begin
if (rdataed || indexed)
begin
opcode <= {0, counter};
state <= STATE_INTERVAL;
end
else if (sampleclocked)
begin
oldsampleclock <= 1;
if (counter == 7'h7f)
begin
opcode <= {0, counter};
state <= STATE_OPCODE;
end
else
state <= STATE_COUNTING;
end
if (oldrdata && !rdata)
oldrdata <= 0;
if (oldindex && !index)
oldindex <= 0;
if (oldsampleclock && !sampleclock)
oldsampleclock <= 0;
end
STATE_INTERVAL: /* interval byte sent here; counter reset */
state <= STATE_DISPATCH;
STATE_DISPATCH: /* relax after interval byte, dispatch for opcode */
begin
if (rdataed)
begin
oldrdata <= 1;
opcode <= 8'h80;
state <= STATE_OPCODE;
end
else if (indexed)
begin
oldindex <= 1;
opcode <= 8'h81;
state <= STATE_OPCODE;
end
else
state <= STATE_WAITING;
end
STATE_OPCODE: /* opcode byte sent here */
state <= STATE_WAITING;
STATE_COUNTING:
state <= STATE_WAITING;
endcase
end
//`#end` -- edit above this line, do not edit this line
endmodule
//`#start footer` -- edit after this line, do not edit this line
//`#end` -- edit above this line, do not edit this line

View File

@@ -0,0 +1,103 @@
//`#start header` -- edit after this line, do not edit this line
`include "cypress.v"
//`#end` -- edit above this line, do not edit this line
// Generated on 11/24/2019 at 17:25
// Component: Sequencer
module Sequencer (
output req, /* request new data on leading edge */
output wdata,
output [2:0] debug_state,
input clock,
input dataclock, /* incoming data on leading edge */
input [7:0] opcode,
input index,
input sampleclock,
input reset
);
//`#start body` -- edit after this line, do not edit this line
localparam STATE_IDLE = 0;
localparam STATE_LOAD = 1;
localparam STATE_WAITING = 2;
localparam STATE_PULSING = 3;
localparam STATE_INDEXING = 4;
localparam OPCODE_PULSE = 8'h80;
localparam OPCODE_INDEX = 8'h81;
reg [2:0] state;
reg [6:0] countdown;
assign req = (state == STATE_LOAD);
assign wdata = (state == STATE_PULSING);
assign debug_state = state;
reg olddataclock;
wire dataclocked;
always @(posedge clock) olddataclock <= dataclock;
assign dataclocked = !olddataclock && dataclock;
reg oldsampleclock;
wire sampleclocked;
always @(posedge clock) oldsampleclock <= sampleclock;
assign sampleclocked = !oldsampleclock && sampleclock;
reg oldindex;
wire indexed;
always @(posedge clock) oldindex <= index;
assign indexed = !oldindex && index;
always @(posedge clock)
begin
if (reset)
begin
state <= STATE_IDLE;
countdown <= 0;
end
else
case (state)
STATE_IDLE:
state <= STATE_LOAD;
STATE_LOAD:
if (dataclocked)
case (opcode)
OPCODE_PULSE:
state <= STATE_PULSING;
OPCODE_INDEX:
state <= STATE_INDEXING;
default:
begin
countdown <= opcode[6:0];
state <= STATE_WAITING;
end
endcase
STATE_WAITING:
if (sampleclocked)
begin
if (countdown == 0)
state <= STATE_LOAD;
else
countdown <= countdown - 1;
end
STATE_PULSING:
state <= STATE_LOAD;
STATE_INDEXING:
if (indexed)
state <= STATE_LOAD;
else
state <= STATE_INDEXING;
endcase
end
//`#end` -- edit above this line, do not edit this line
endmodule
//`#start footer` -- edit after this line, do not edit this line
//`#end` -- edit above this line, do not edit this line

View File

Binary file not shown.

View File

@@ -0,0 +1,156 @@
//`#start header` -- edit after this line, do not edit this line
`include "cypress.v"
//`#end` -- edit above this line, do not edit this line
// Generated on 11/16/2017 at 15:44
// Component: FIFOout
module SuperCounter (
input clk,
input reset,
input count,
output [7:0] d,
output drq,
output empty,
output ack
);
//`#start body` -- edit after this line, do not edit this line
parameter ResetValue = 0;
parameter Delta = 1;
wire [7:0] po;
assign d = po;
localparam STATE_RESET = 0;
localparam STATE_WAIT = 1;
localparam STATE_ADD = 2;
reg oldcount;
wire counted;
assign counted = count && !oldcount;
always @(posedge clk) oldcount <= count;
wire [2:0] cs;
assign cs = reset ? STATE_RESET : (counted ? STATE_ADD : STATE_WAIT);
cy_psoc3_dp #(.d0_init(ResetValue), .d1_init(Delta),
.cy_dpconfig(
{
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC___D0, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM0: STATE_RESET*/
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM1: STATE_WAIT*/
`CS_ALU_OP__ADD, `CS_SRCA_A0, `CS_SRCB_D1,
`CS_SHFT_OP_PASS, `CS_A0_SRC__ALU, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM2: STATE_ADD*/
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM3: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM4: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM5: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM6: */
`CS_ALU_OP_PASS, `CS_SRCA_A0, `CS_SRCB_D0,
`CS_SHFT_OP_PASS, `CS_A0_SRC_NONE, `CS_A1_SRC_NONE,
`CS_FEEDBACK_DSBL, `CS_CI_SEL_CFGA, `CS_SI_SEL_CFGA,
`CS_CMP_SEL_CFGA, /*CFGRAM7: */
8'hFF, 8'h00, /*CFG9: */
8'hFF, 8'hFF, /*CFG11-10: */
`SC_CMPB_A1_D1, `SC_CMPA_A1_D1, `SC_CI_B_ARITH,
`SC_CI_A_ARITH, `SC_C1_MASK_DSBL, `SC_C0_MASK_DSBL,
`SC_A_MASK_DSBL, `SC_DEF_SI_0, `SC_SI_B_DEFSI,
`SC_SI_A_DEFSI, /*CFG13-12: */
`SC_A0_SRC_ACC, `SC_SHIFT_SL, 1'h0,
1'h0, `SC_FIFO1_BUS, `SC_FIFO0_BUS,
`SC_MSB_DSBL, `SC_MSB_BIT0, `SC_MSB_NOCHN,
`SC_FB_NOCHN, `SC_CMP1_NOCHN,
`SC_CMP0_NOCHN, /*CFG15-14: */
10'h00, `SC_FIFO_CLK__DP,`SC_FIFO_CAP_AX,
`SC_FIFO_LEVEL,`SC_FIFO_ASYNC,`SC_EXTCRC_DSBL,
`SC_WRK16CAT_DSBL /*CFG17-16: */
}
)) dp(
/* input */ .reset(1'b0),
/* input */ .clk(clk),
/* input [02:00] */ .cs_addr(cs),
/* input */ .route_si(1'b0),
/* input */ .route_ci(1'b0),
/* input */ .f0_load(1'b0),
/* input */ .f1_load(1'b0),
/* input */ .d0_load(1'b0),
/* input */ .d1_load(1'b0),
/* output */ .ce0(),
/* output */ .cl0(),
/* output */ .z0(),
/* output */ .ff0(),
/* output */ .ce1(),
/* output */ .cl1(),
/* output */ .z1(),
/* output */ .ff1(),
/* output */ .ov_msb(),
/* output */ .co_msb(),
/* output */ .cmsb(),
/* output */ .so(),
/* output */ .f0_bus_stat(),
/* output */ .f0_blk_stat(),
/* output */ .f1_bus_stat(),
/* output */ .f1_blk_stat(),
/* input */ .ci(1'b0), // Carry in from previous stage
/* output */ .co(),// Carry out to next stage
/* input */ .sir(1'b0), // Shift in from right side
/* output */ .sor(), // Shift out to right side
/* input */ .sil(1'b0), // Shift in from left side
/* output */ .sol(), // Shift out to left side
/* input */ .msbi(1'b0), // MSB chain in
/* output */ .msbo(), // MSB chain out
/* input [01:00] */ .cei(2'b0), // Compare equal in from prev stage
/* output [01:00] */ .ceo(), // Compare equal out to next stage
/* input [01:00] */ .cli(2'b0), // Compare less than in from prv stage
/* output [01:00] */ .clo(), // Compare less than out to next stage
/* input [01:00] */ .zi(2'b0), // Zero detect in from previous stage
/* output [01:00] */ .zo(), // Zero detect out to next stage
/* input [01:00] */ .fi(2'b0), // 0xFF detect in from previous stage
/* output [01:00] */ .fo(), // 0xFF detect out to next stage
/* input [01:00] */ .capi(2'b0), // Software capture from previous stage
/* output [01:00] */ .capo(), // Software capture to next stage
/* input */ .cfbi(1'b0), // CRC Feedback in from previous stage
/* output */ .cfbo(), // CRC Feedback out to next stage
/* input [07:00] */ .pi(8'b0), // Parallel data port
/* output [07:00] */ .po(po) // Parallel data port
);
//`#end` -- edit above this line, do not edit this line
endmodule
//`#start footer` -- edit after this line, do not edit this line
//`#end` -- edit above this line, do not edit this line

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

@@ -85,10 +85,21 @@ static void print(const char* msg, ...)
UART_PutCRLF();
}
static void set_drive_flags(uint8_t flags)
{
if (current_drive_flags != flags)
homed = false;
current_drive_flags = flags;
DRIVESELECT_REG_Write((flags & 1) ? 2 : 1); /* select drive 1 or 0 */
DENSITY_REG_Write(flags >> 1); /* density bit */
}
static void start_motor(void)
{
if (!motor_on)
{
set_drive_flags(current_drive_flags);
MOTOR_REG_Write(1);
CyDelay(1000);
homed = false;
@@ -99,6 +110,16 @@ static void start_motor(void)
CyWdtClear();
}
static void stop_motor(void)
{
if (motor_on)
{
MOTOR_REG_Write(0);
DRIVESELECT_REG_Write(0); /* deselect all drives */
motor_on = false;
}
}
static void wait_until_writeable(int ep)
{
while (USBFS_GetEPState(ep) != USBFS_IN_BUFFER_EMPTY)
@@ -138,25 +159,36 @@ static void cmd_get_version(struct any_frame* f)
static void step(int dir)
{
STEP_REG_Write(dir);
CyDelayUs(1);
STEP_REG_Write(dir | 2);
CyDelayUs(1);
STEP_REG_Write(dir);
STEP_REG_Write(dir); /* step high */
CyDelayUs(6);
STEP_REG_Write(dir | 2); /* step low */
CyDelayUs(6);
STEP_REG_Write(dir); /* step high again, drive moves now */
CyDelay(STEP_INTERVAL_TIME);
}
static void home(void)
{
for (int i=0; i<100; i++)
{
/* Don't keep stepping forever, because if a drive's
* not connected bad things happen. */
if (TRACK0_REG_Read())
break;
step(STEP_TOWARDS0);
}
/* Step to -1, which should be a nop, to reset the disk on disk change. */
step(STEP_TOWARDS0);
}
static void seek_to(int track)
{
start_motor();
if (!homed)
if (!homed || (track == 0))
{
print("homing");
while (!TRACK0_REG_Read())
step(STEP_TOWARDS0);
/* Step to -1, which should be a nop, to reset the disk on disk change. */
step(STEP_TOWARDS0);
home();
homed = true;
current_track = 0;
@@ -167,11 +199,7 @@ static void seek_to(int track)
while (track != current_track)
{
if (TRACK0_REG_Read())
{
if (current_track != 0)
print("unexpectedly detected track 0");
current_track = 0;
}
if (track > current_track)
{
@@ -249,7 +277,7 @@ static void deinit_dma(void)
static void init_capture_dma(void)
{
dma_channel = CAPTURE_DMA_DmaInitialize(
dma_channel = SAMPLER_DMA_DmaInitialize(
2 /* bytes */,
true /* request per burst */,
HI16(CYDEV_PERIPH_BASE),
@@ -264,8 +292,8 @@ static void init_capture_dma(void)
nexti = 0;
CyDmaTdSetConfiguration(td[i], BUFFER_SIZE, td[nexti],
CY_DMA_TD_INC_DST_ADR | CAPTURE_DMA__TD_TERMOUT_EN);
CyDmaTdSetAddress(td[i], LO16((uint32)&SAMPLER_DATAPATH_F0_REG), LO16((uint32)&dma_buffer[i]));
CY_DMA_TD_INC_DST_ADR | SAMPLER_DMA__TD_TERMOUT_EN);
CyDmaTdSetAddress(td[i], LO16((uint32)SAMPLER_FIFO_FIFO_PTR), LO16((uint32)&dma_buffer[i]));
}
}
@@ -276,13 +304,11 @@ static void cmd_read(struct read_frame* f)
/* Do slow setup *before* we go into the real-time bit. */
SAMPLER_CONTROL_Write(1); /* reset */
{
uint8_t i = CyEnterCriticalSection();
SAMPLER_DATAPATH_F0_SET_LEVEL_MID;
SAMPLER_DATAPATH_F0_CLEAR;
SAMPLER_DATAPATH_F0_SINGLE_BUFFER_UNSET;
SAMPLER_FIFO_SET_LEVEL_MID;
SAMPLER_FIFO_CLEAR;
SAMPLER_FIFO_SINGLE_BUFFER_UNSET;
CyExitCriticalSection(i);
}
@@ -291,7 +317,6 @@ static void cmd_read(struct read_frame* f)
/* Wait for the beginning of a rotation. */
print("wait");
index_irq = false;
while (!index_irq)
;
@@ -305,8 +330,6 @@ static void cmd_read(struct read_frame* f)
dma_reading_from_td = -1;
dma_underrun = false;
int count = 0;
SAMPLER_CONTROL_Write(0); /* !reset */
CAPTURE_CONTROL_Write(1);
CyDmaChSetInitialTd(dma_channel, td[dma_writing_to_td]);
CyDmaClearPendingDrq(dma_channel);
CyDmaChEnable(dma_channel, 1);
@@ -366,19 +389,20 @@ static void cmd_read(struct read_frame* f)
dma_reading_from_td = NEXT_BUFFER(dma_reading_from_td);
}
abort:;
CAPTURE_CONTROL_Write(0);
CyDmaChSetRequest(dma_channel, CY_DMA_CPU_TERM_CHAIN);
while (CyDmaChGetRequest(dma_channel))
;
donecrunch(&cs);
wait_until_writeable(FLUXENGINE_DATA_IN_EP_NUM);
unsigned zz = cs.outputlen;
if (cs.outputlen != BUFFER_SIZE)
USBFS_LoadInEP(FLUXENGINE_DATA_IN_EP_NUM, usb_buffer, BUFFER_SIZE-cs.outputlen);
if (!dma_underrun)
{
if (cs.outputlen != BUFFER_SIZE)
USBFS_LoadInEP(FLUXENGINE_DATA_IN_EP_NUM, usb_buffer, BUFFER_SIZE-cs.outputlen);
wait_until_writeable(FLUXENGINE_DATA_IN_EP_NUM);
}
if ((cs.outputlen == BUFFER_SIZE) || (cs.outputlen == 0))
USBFS_LoadInEP(FLUXENGINE_DATA_IN_EP_NUM, NULL, 0);
wait_until_writeable(FLUXENGINE_DATA_IN_EP_NUM);
deinit_dma();
if (dma_underrun)
@@ -391,7 +415,7 @@ abort:;
DECLARE_REPLY_FRAME(struct any_frame, F_FRAME_READ_REPLY);
send_reply(&r);
}
print("count=%d i=%d d=%d zz=%d", count, index_irq, dma_underrun, zz);
print("count=%d i=%d d=%d", count, index_irq, dma_underrun);
}
static void init_replay_dma(void)
@@ -412,25 +436,28 @@ static void init_replay_dma(void)
CyDmaTdSetConfiguration(td[i], BUFFER_SIZE, td[nexti],
CY_DMA_TD_INC_SRC_ADR | SEQUENCER_DMA__TD_TERMOUT_EN);
CyDmaTdSetAddress(td[i], LO16((uint32)&dma_buffer[i]), LO16((uint32)&SEQUENCER_DATAPATH_F0_REG));
CyDmaTdSetAddress(td[i], LO16((uint32)&dma_buffer[i]), LO16((uint32)REPLAY_FIFO_FIFO_PTR));
}
}
static void cmd_write(struct write_frame* f)
{
print("cmd_write");
if (f->bytes_to_write % FRAME_SIZE)
{
send_error(F_ERROR_INVALID_VALUE);
return;
}
SEQUENCER_CONTROL_Write(1); /* put the sequencer into reset */
SIDE_REG_Write(f->side);
SEQUENCER_CONTROL_Write(1); /* reset */
{
uint8_t i = CyEnterCriticalSection();
SEQUENCER_DATAPATH_F0_SET_LEVEL_NORMAL;
SEQUENCER_DATAPATH_F0_CLEAR;
SEQUENCER_DATAPATH_F0_SINGLE_BUFFER_UNSET;
uint8_t i = CyEnterCriticalSection();
REPLAY_FIFO_SET_LEVEL_NORMAL;
REPLAY_FIFO_CLEAR;
REPLAY_FIFO_SINGLE_BUFFER_UNSET;
CyExitCriticalSection(i);
}
seek_to(current_track);
@@ -555,7 +582,7 @@ abort:
CyDmaChDisable(dma_channel);
}
//debug("p=%d cr=%d cw=%d f=%d l=%d w=%d index=%d underrun=%d", packets, count_read, count_written, finished, listening, writing, index_irq, dma_underrun);
print("p=%d cr=%d cw=%d f=%d w=%d index=%d underrun=%d", packets, count_read, count_written, finished, writing, index_irq, dma_underrun);
if (!finished)
{
while (count_read < packets)
@@ -573,6 +600,7 @@ abort:
}
deinit_dma();
print("write finished");
if (dma_underrun)
{
@@ -607,17 +635,101 @@ static void cmd_erase(struct erase_frame* f)
static void cmd_set_drive(struct set_drive_frame* f)
{
if (current_drive_flags != f->drive_flags)
{
current_drive_flags = f->drive_flags;
DRIVE_REG_Write(current_drive_flags);
homed = false;
}
set_drive_flags(f->drive_flags);
DECLARE_REPLY_FRAME(struct any_frame, F_FRAME_SET_DRIVE_REPLY);
send_reply((struct any_frame*) &r);
}
static uint16_t read_output_voltage_mv(void)
{
OUTPUT_VOLTAGE_ADC_StartConvert();
OUTPUT_VOLTAGE_ADC_IsEndConversion(OUTPUT_VOLTAGE_ADC_WAIT_FOR_RESULT);
uint16_t samples = OUTPUT_VOLTAGE_ADC_GetResult16();
return OUTPUT_VOLTAGE_ADC_CountsTo_mVolts(samples);
}
static void read_output_voltages(struct voltages* v)
{
SIDE_REG_Write(1); /* set DIR to low (remember this is inverted) */
CyDelay(100);
v->logic0_mv = read_output_voltage_mv();
SIDE_REG_Write(0);
CyDelay(100);
v->logic1_mv = read_output_voltage_mv();
}
static uint16_t read_input_voltage_mv(void)
{
INPUT_VOLTAGE_ADC_StartConvert();
INPUT_VOLTAGE_ADC_IsEndConversion(INPUT_VOLTAGE_ADC_WAIT_FOR_RESULT);
uint16_t samples = INPUT_VOLTAGE_ADC_GetResult16();
return INPUT_VOLTAGE_ADC_CountsTo_mVolts(samples);
}
static void read_input_voltages(struct voltages* v)
{
home();
CyDelay(50);
v->logic0_mv = read_input_voltage_mv();
step(STEP_AWAYFROM0);
CyDelay(50);
v->logic1_mv = read_input_voltage_mv();
}
static void cmd_measure_voltages(void)
{
stop_motor();
INPUT_VOLTAGE_ADC_Start();
INPUT_VOLTAGE_ADC_SetPower(INPUT_VOLTAGE_ADC__HIGHPOWER);
OUTPUT_VOLTAGE_ADC_Start();
OUTPUT_VOLTAGE_ADC_SetPower(OUTPUT_VOLTAGE_ADC__HIGHPOWER);
DECLARE_REPLY_FRAME(struct voltages_frame, F_FRAME_MEASURE_VOLTAGES_REPLY);
CyWdtClear();
MOTOR_REG_Write(0); /* should be ignored anyway */
DRIVESELECT_REG_Write(0); /* deselect both drives */
CyDelay(200); /* wait for things to settle */
read_output_voltages(&r.output_both_off);
read_input_voltages(&r.input_both_off);
CyWdtClear();
DRIVESELECT_REG_Write(1); /* select drive 0 */
CyDelay(50);
read_output_voltages(&r.output_drive_0_selected);
read_input_voltages(&r.input_drive_0_selected);
MOTOR_REG_Write(1);
CyDelay(300);
CyWdtClear();
read_output_voltages(&r.output_drive_0_running);
read_input_voltages(&r.input_drive_0_running);
MOTOR_REG_Write(0);
CyDelay(300);
CyWdtClear();
DRIVESELECT_REG_Write(2); /* select drive 1 */
CyDelay(50);
read_output_voltages(&r.output_drive_1_selected);
read_input_voltages(&r.input_drive_1_selected);
MOTOR_REG_Write(1);
CyDelay(300);
CyWdtClear();
read_output_voltages(&r.output_drive_1_running);
read_input_voltages(&r.input_drive_1_running);
MOTOR_REG_Write(0);
CyDelay(300);
CyWdtClear();
DRIVESELECT_REG_Write(0);
homed = false;
INPUT_VOLTAGE_ADC_Stop();
OUTPUT_VOLTAGE_ADC_Stop();
send_reply((struct any_frame*) &r);
}
static void handle_command(void)
{
static uint8_t input_buffer[FRAME_SIZE];
@@ -662,6 +774,10 @@ static void handle_command(void)
case F_FRAME_SET_DRIVE_CMD:
cmd_set_drive((struct set_drive_frame*) f);
break;
case F_FRAME_MEASURE_VOLTAGES_CMD:
cmd_measure_voltages();
break;
default:
send_error(F_ERROR_BAD_COMMAND);
@@ -674,9 +790,11 @@ int main(void)
CySysTickStart();
CySysTickSetCallback(4, system_timer_cb);
INDEX_IRQ_StartEx(&index_irq_cb);
CAPTURE_DMA_FINISHED_IRQ_StartEx(&capture_dma_finished_irq_cb);
SAMPLER_DMA_FINISHED_IRQ_StartEx(&capture_dma_finished_irq_cb);
SEQUENCER_DMA_FINISHED_IRQ_StartEx(&replay_dma_finished_irq_cb);
DRIVE_REG_Write(0);
INPUT_VOLTAGE_ADC_Stop();
OUTPUT_VOLTAGE_ADC_Stop();
DRIVESELECT_REG_Write(0);
UART_Start();
USBFS_Start(0, USBFS_DWR_VDDD_OPERATION);
@@ -692,10 +810,7 @@ int main(void)
{
uint32_t time_on = clock - motor_on_time;
if (time_on > MOTOR_ON_TIME)
{
MOTOR_REG_Write(0);
motor_on = false;
}
stop_motor();
}
if (!USBFS_GetConfiguration() || USBFS_IsConfigurationChanged())
@@ -709,6 +824,7 @@ int main(void)
if (USBFS_GetEPState(FLUXENGINE_CMD_OUT_EP_NUM) == USBFS_OUT_BUFFER_FULL)
{
set_drive_flags(current_drive_flags);
handle_command();
USBFS_EnableOutEP(FLUXENGINE_CMD_OUT_EP_NUM);
print("idle");

View File

@@ -1,8 +1,8 @@
PACKAGES = zlib sqlite3 libusb-1.0
export CFLAGS = -O3 -g --std=c++14 \
export CFLAGS = -Os -g --std=c++14 \
-ffunction-sections -fdata-sections
export LDFLAGS = -O3
export LDFLAGS = -Os
ifeq ($(OS), Windows_NT)
export CXX = /mingw32/bin/g++
@@ -13,6 +13,13 @@ export LDFLAGS +=
export LIBS = -static -lz -lsqlite3 -lusb-1.0
export EXTENSION = .exe
else
packages-exist = $(shell pkg-config --exists $(PACKAGES) && echo yes)
ifneq ($(packages-exist),yes)
$(warning These pkg-config packages are installed: $(shell pkg-config --list-all | sort | awk '{print $$1}'))
$(error You must have these pkg-config packages installed: $(PACKAGES))
endif
export CXX = g++
export AR = ar rcs
export STRIP = strip

View File

@@ -89,7 +89,7 @@ people who've had it work).
| [Brother 120kB](doc/disk-brother.md) | 🦄 | | |
| [Brother 240kB](doc/disk-brother.md) | 🦄 | 🦄 | |
| [Brother FB-100](doc/disk-fb100.md) | 🦖 | | Tandy Model 100, Husky Hunter, knitting machines |
| [Macintosh 800kB](doc/disk-macintosh.md) | 🦄 | | and probably the 400kB too |
| [Macintosh 800kB](doc/disk-macintosh.md) | 🦖 | | and probably the 400kB too |
| [TRS-80](doc/disk-trs80.md) | 🦖 | | a minor variation of the IBM scheme |
{: .datatable }

View File

Binary file not shown.

View File

@@ -129,8 +129,8 @@ reverse engineered it to find out.
Standard Linux mtools will access the filesystem image and allow you to move
files in and out. However, you'll need to change the media type bytes at
offsets 0x015 and 0x100 from 0x58 to 0xf0 before mtools will touch it. Once
done, this will work:
offsets 0x015 and 0x100 from 0x58 to 0xf0 before mtools will touch it. The
supplied `brother240tool` will do this. Once done, this will work:
```
mdir -i brother.img

View File

@@ -28,8 +28,16 @@ for example the Commodore 64 1541 drive, changed bitrate this way.
But Macintosh disks used a constant bitrate and changed the speed that the
disk spun instead to achieve the same effect...
_Anyway_: FluxEngine will read them fine on a conventional drive. Because
it's clever.
_Anyway_: FluxEngine will read them fine on conventional drives.
Because it's clever.
**Big note.** Apparently --- and I'm still getting to the bottom of this ---
some drives work and some don't. My drives produce about 90% good reads of
known good disks. One rumour I've heard is that drives sometimes include
filters which damage the signals at very particular intervals which Mac disks
use, but frankly this seems unlikely; it could be a software issue at my end
and I'm investigating. If you have any insight, please [get in
touch](https://github.com/davidgiven/fluxengine/issues/new).
Reading discs
-------------

View File

@@ -48,7 +48,7 @@ haven't had the chance to try it end-for-end. I really need a hard-sectored
**Q.** Does it work with flippy disks?
Uhhh... probably not.
Uhhh... maybe?
So the problem with flippy disks (5.25" single-sided disks which could be
inserted upside down to read the second side) is the index hole. Trouble is,
@@ -79,16 +79,21 @@ the other. But a flippy disk has both sets of tracks in the same place,
because they're both accessed using the side 0 head...
The only real way round this is to modify a 5.25" drive. That's _seriously_
not in FluxEngine's remit. Sorry.
not in FluxEngine's remit, but I've had some [excellent documentation
contributed](Index_sensor_mod_FDD_1.1.pdf) on how to do this. I've never done
it myself; if you try this and it works/doesn't work, as always, [get in
touch](https://github.com/davidgiven/fluxengine/issues/new).
**Q.** Is this like KryoFlux / Catweasel / DiskFerret? Do you support KryoFlux
**Q.** Is this like Supercard Pro / KryoFlux / Catweasel / DiskFerret? Do you
*support KryoFlux
stream files?
**A.** It's very like all of these; the idea's old, and lots of people have
tried it (you can get away with any sufficiently fast microcontroller and
enough RAM). FluxEngine can read from KryoFlux stream files natively, and
there's a tool which will let you convert at least one kind of Catweasel file
to FluxEngine's native flux file format.
there's a tool which will let you convert at least one kind of Catweasel
files and Supercard Pro files to and from FluxEngine's native flux file
format.
**Q.** Can I use this to make exact copies of disks?

View File

@@ -123,8 +123,12 @@ admittedly expensive.)
sheet](http://www.bitsavers.org/pdf/mitsubishi/floppy/M4851/TJ2-G30211A_M4851_DSHH_48TPI_OEM_Manual_Nov83.pdf):
the equivalent data sheet for a representative 5.25" drive.
- [The DRG Business Machines YD-174 manual](https://electrickery.hosting.philpem.me.uk/comp/divcomp/doc/YE_Data_YD-174_8inchFloppyDriveTechnicalManual.pdf):
the equivalent manual (data sheets hadn't been invented then) for a
representative 8" drive.
- [KryoFlux stream file
documentation](https://www.kryoflux.com/download/kryoflux_stream_protocol_rev1.1.pdf):
the format of KryoFlux stream files (partially supported by FluxEngine)

View File

@@ -51,7 +51,7 @@ In order to do anything useful, you have to plug it in to a floppy disk drive (o
rpm for a 3.5" disk, or 360 rpm for a 5.25" disk. If it doesn't, please
[get in touch](https://github.com/davidgiven/fluxengine/issues/new).
7. Do `fluxengine testbulktransport` from the shell. It'll measure your USB
7. Do `fluxengine test bulktransport` from the shell. It'll measure your USB
bandwidth. Ideally you should be getting above 900kB/s. FluxEngine needs
about 850kB/s, so if you're getting less than this, try a different USB
port.
@@ -213,14 +213,31 @@ directory.
- `fluxengine seek`: moves the head. Mainly useful for finding out whether
your drive can seek to track 82. (Mine can't.)
- `fluxengine testbulktransport`: measures your USB throughput. You need
- `fluxengine test bulktransport`: measures your USB throughput. You need
about 600kB/s for FluxEngine to work. You don't need a disk in the drive
for this one.
- `fluxengine test voltages`: measures your FDD bus signal voltages, which
is useful for testing for termination issues.
- `fluxengine upgradefluxfile`: occasionally I need to upgrade the flux
file format in a non-backwards-compatible way; this tool will upgrade flux
files to the new format.
- `fluxengine convert`: converts flux files from various formats to various
other formats. You can use this to convert Catweasel flux files to
FluxEngine's native format, FluxEngine flux files to various other formats
useful for debugging (including VCD which can be loaded into
[sigrok](http://sigrok.org)), and bidirectional conversion to and from
Supercard Pro `.scp` format.
**Important SCP note:** import (`fluxengine convert scptoflux`) should be
fairly robust, but export (`fluxengine convert fluxtoscp`) should only be
done with great caution as FluxEngine files contain features which can't be
represented very well in `.scp` format and they're probably pretty dubious.
As ever, please [get in
touch](https://github.com/davidgiven/fluxengine/issues/new) with any reports.
Commands which normally take `--source` or `--dest` get a sensible default if
left unspecified. `fluxengine read ibm` on its own will read drive 0 and
write an `ibm.img` file.
@@ -247,25 +264,24 @@ wrote to do useful things. These are built alongside FluxEngine.
- `brother120tool`: extracts files from a 120kB Brother filesystem image.
- `cwftoflux`: converts (one flavour of) CatWeasel flux file into a
FluxEngine flux file.
## The recommended workflow
So you've just received, say, a huge pile of old Brother word processor disks containing valuable historical data, and you want to read them.
So you've just received, say, a huge pile of old Brother word processor disks
containing valuable historical data, and you want to read them.
Typically I do this:
```
$ fluxengine read brother -s :d=0 -o brother.img --write-flux=brother.flux
$ fluxengine read brother -s :d=0 -o brother.img --write-flux=brother.flux --write-svg=brother.svg
```
This will read the disk in drive 0 and write out a filesystem image. It'll
also copy the flux to brother.flux. If I then need to tweak the settings, I
can rerun the decode without having to physically touch the disk like this:
also copy the flux to brother.flux and write out an SVG visualisation. If I
then need to tweak the settings, I can rerun the decode without having to
physically touch the disk like this:
```
$ fluxengine read brother -s brother.flux -o brother.img
$ fluxengine read brother -s brother.flux -o brother.img --write-svg=brother.svg
```
Apart from being drastically faster, this avoids touching the (potentially

View File

@@ -29,7 +29,7 @@ void FlagGroup::addFlag(Flag* flag)
_flags.push_back(flag);
}
void FlagGroup::parseFlags(int argc, const char* argv[])
std::vector<std::string> FlagGroup::parseFlagsWithFilenames(int argc, const char* argv[])
{
if (_initialised)
throw std::runtime_error("called parseFlags() twice");
@@ -66,6 +66,7 @@ void FlagGroup::parseFlags(int argc, const char* argv[])
/* Now actually parse them. */
std::vector<std::string> filenames;
int index = 1;
while (index < argc)
{
@@ -76,52 +77,73 @@ void FlagGroup::parseFlags(int argc, const char* argv[])
std::string value;
bool usesthat = false;
if ((thisarg.size() == 0) || (thisarg[0] != '-'))
Error() << "non-option parameter " << thisarg << " seen (try --help)";
if ((thisarg.size() > 1) && (thisarg[1] == '-'))
if (thisarg.size() == 0)
{
/* Long option. */
auto equals = thisarg.rfind('=');
if (equals != std::string::npos)
{
key = thisarg.substr(0, equals);
value = thisarg.substr(equals+1);
}
else
{
key = thisarg;
value = thatarg;
usesthat = true;
}
/* Ignore this argument. */
}
else if (thisarg[0] != '-')
{
/* This is a filename. */
filenames.push_back(thisarg);
}
else
{
/* Short option. */
/* This is a flag. */
if (thisarg.size() > 2)
if ((thisarg.size() > 1) && (thisarg[1] == '-'))
{
key = thisarg.substr(0, 2);
value = thisarg.substr(2);
/* Long option. */
auto equals = thisarg.rfind('=');
if (equals != std::string::npos)
{
key = thisarg.substr(0, equals);
value = thisarg.substr(equals+1);
}
else
{
key = thisarg;
value = thatarg;
usesthat = true;
}
}
else
{
key = thisarg;
value = thatarg;
usesthat = true;
/* Short option. */
if (thisarg.size() > 2)
{
key = thisarg.substr(0, 2);
value = thisarg.substr(2);
}
else
{
key = thisarg;
value = thatarg;
usesthat = true;
}
}
auto flag = flags_by_name.find(key);
if (flag == flags_by_name.end())
Error() << "unknown flag '" << key << "'; try --help";
flag->second->set(value);
if (usesthat && flag->second->hasArgument())
index++;
}
auto flag = flags_by_name.find(key);
if (flag == flags_by_name.end())
Error() << "unknown flag '" << key << "'; try --help";
flag->second->set(value);
index++;
if (usesthat && flag->second->hasArgument())
index++;
}
return filenames;
}
void FlagGroup::parseFlags(int argc, const char* argv[])
{
auto filenames = parseFlagsWithFilenames(argc, argv);
if (!filenames.empty())
Error() << "non-option parameter " << *filenames.begin() << " seen (try --help)";
}
void FlagGroup::checkInitialised() const

View File

@@ -14,6 +14,7 @@ public:
public:
void parseFlags(int argc, const char* argv[]);
std::vector<std::string> parseFlagsWithFilenames(int argc, const char* argv[]);
void addFlag(Flag* flag);
void checkInitialised() const;

View File

@@ -265,3 +265,37 @@ void usbSetDrive(int drive, bool high_density)
await_reply<struct any_frame>(F_FRAME_SET_DRIVE_REPLY);
}
/* Hacky: the board always operates in little-endian mode. */
static uint16_t read_short_from_usb(uint16_t usb)
{
uint8_t* p = (uint8_t*)&usb;
return p[0] | (p[1] << 8);
}
static void convert_voltages_from_usb(const struct voltages& vin, struct voltages& vout)
{
vout.logic0_mv = read_short_from_usb(vin.logic0_mv);
vout.logic1_mv = read_short_from_usb(vin.logic1_mv);
}
void usbMeasureVoltages(struct voltages_frame* voltages)
{
usb_init();
struct any_frame f = {
{ .type = F_FRAME_MEASURE_VOLTAGES_CMD, .size = sizeof(f) },
};
usb_cmd_send(&f, f.f.size);
struct voltages_frame* r = await_reply<struct voltages_frame>(F_FRAME_MEASURE_VOLTAGES_REPLY);
convert_voltages_from_usb(r->input_both_off, voltages->input_both_off);
convert_voltages_from_usb(r->input_drive_0_selected, voltages->input_drive_0_selected);
convert_voltages_from_usb(r->input_drive_1_selected, voltages->input_drive_1_selected);
convert_voltages_from_usb(r->input_drive_0_running, voltages->input_drive_0_running);
convert_voltages_from_usb(r->input_drive_1_running, voltages->input_drive_1_running);
convert_voltages_from_usb(r->output_both_off, voltages->output_both_off);
convert_voltages_from_usb(r->output_drive_0_selected, voltages->output_drive_0_selected);
convert_voltages_from_usb(r->output_drive_1_selected, voltages->output_drive_1_selected);
convert_voltages_from_usb(r->output_drive_0_running, voltages->output_drive_0_running);
convert_voltages_from_usb(r->output_drive_1_running, voltages->output_drive_1_running);
}

View File

@@ -13,5 +13,6 @@ extern Bytes usbRead(int side, int revolutions);
extern void usbWrite(int side, const Bytes& bytes);
extern void usbErase(int side);
extern void usbSetDrive(int drive, bool high_density);
extern void usbMeasureVoltages(struct voltages_frame* voltages);
#endif

View File

@@ -190,6 +190,7 @@ buildlibrary libfrontend.a \
src/fe-cwftoflux.cc \
src/fe-erase.cc \
src/fe-fluxtoau.cc \
src/fe-fluxtoscp.cc \
src/fe-fluxtovcd.cc \
src/fe-inspect.cc \
src/fe-readadfs.cc \
@@ -208,8 +209,10 @@ buildlibrary libfrontend.a \
src/fe-readvictor9k.cc \
src/fe-readzilogmcz.cc \
src/fe-rpm.cc \
src/fe-scptoflux.cc \
src/fe-seek.cc \
src/fe-testbulktransport.cc \
src/fe-testvoltages.cc \
src/fe-upgradefluxfile.cc \
src/fe-writebrother.cc \
src/fe-writeflux.cc \
@@ -231,6 +234,13 @@ buildsimpleprogram brother120tool \
libemu.a \
libfmt.a \
buildsimpleprogram brother240tool \
-Idep/emu \
tools/brother240tool.cc \
libbackend.a \
libemu.a \
libfmt.a \
runtest bitaccumulator-test tests/bitaccumulator.cc
runtest bytes-test tests/bytes.cc
runtest compression-test tests/compression.cc

View File

@@ -62,6 +62,8 @@ enum
F_FRAME_RECALIBRATE_REPLY, /* any_frame */
F_FRAME_SET_DRIVE_CMD, /* setdrive_frame */
F_FRAME_SET_DRIVE_REPLY, /* any_frame */
F_FRAME_MEASURE_VOLTAGES_CMD, /* any_frame */
F_FRAME_MEASURE_VOLTAGES_REPLY, /* voltages_frame */
};
enum
@@ -146,4 +148,25 @@ struct set_drive_frame
uint8_t drive_flags;
};
struct voltages
{
uint16_t logic0_mv;
uint16_t logic1_mv;
};
struct voltages_frame
{
struct frame_header f;
struct voltages output_both_off;
struct voltages output_drive_0_selected;
struct voltages output_drive_1_selected;
struct voltages output_drive_0_running;
struct voltages output_drive_1_running;
struct voltages input_both_off;
struct voltages input_drive_0_selected;
struct voltages input_drive_1_selected;
struct voltages input_drive_0_running;
struct voltages input_drive_1_running;
};
#endif

View File

@@ -3,7 +3,7 @@
#include "fluxmap.h"
#include "writer.h"
static FlagGroup flags;
static FlagGroup flags { &writerFlags };
int mainErase(int argc, const char* argv[])
{

188
src/fe-fluxtoscp.cc Normal file
View File

@@ -0,0 +1,188 @@
#include "globals.h"
#include "flags.h"
#include "fluxmap.h"
#include "sql.h"
#include "bytes.h"
#include "protocol.h"
#include "dataspec.h"
#include "fmt/format.h"
#include "decoders/fluxmapreader.h"
#include "scp.h"
#include <fstream>
#include <algorithm>
static FlagGroup flags { };
static SettableFlag fortyTrackMode(
{ "--48", "-4" },
"set 48 tpi mode; only every other physical track is emitted"
);
static SettableFlag singleSided(
{ "--single-sided", "-s" },
"only emit side 0"
);
static IntFlag diskType(
{ "--disk-type" },
"sets the SCP disk type byte",
0xff
);
static sqlite3* inputDb;
static void syntax()
{
std::cout << "Syntax: fluxengine convert fluxtoscp <fluxfile> <scpfile>\n";
exit(0);
}
static void write_le32(uint8_t dest[4], uint32_t v)
{
dest[0] = v;
dest[1] = v >> 8;
dest[2] = v >> 16;
dest[3] = v >> 24;
}
static int strackno(int track, int side)
{
if (fortyTrackMode)
track /= 2;
if (singleSided)
return track;
else
return (track << 1) | side;
}
int mainConvertFluxToScp(int argc, const char* argv[])
{
auto filenames = flags.parseFlagsWithFilenames(argc, argv);
if (filenames.size() != 2)
syntax();
inputDb = sqlOpen(filenames[0], SQLITE_OPEN_READONLY);
auto tracks = sqlFindFlux(inputDb);
int maxTrack = 0;
int maxSide = 0;
for (auto p : tracks)
{
if (singleSided && (p.second == 1))
continue;
maxTrack = std::max(maxTrack, (int)p.first);
maxSide = std::max(maxSide, (int)p.second);
}
int maxStrack = strackno(maxTrack, maxSide);
std::cout << fmt::format("Writing {} {} SCP file containing {} SCP tracks\n",
fortyTrackMode ? "48 tpi" : "96 tpi",
singleSided ? "single sided" : "double sided",
maxStrack + 1
);
ScpHeader fileheader = {0};
fileheader.file_id[0] = 'S';
fileheader.file_id[1] = 'C';
fileheader.file_id[2] = 'P';
fileheader.version = 0x18; /* Version 1.8 of the spec */
fileheader.type = diskType;
fileheader.revolutions = 5;
fileheader.start_track = 0;
fileheader.end_track = maxStrack;
fileheader.flags = SCP_FLAG_INDEXED | (fortyTrackMode ? 0 : SCP_FLAG_96TPI);
fileheader.cell_width = 0;
fileheader.heads = singleSided ? 1 : 0;
Bytes trackdata;
ByteWriter trackdataWriter(trackdata);
int trackstep = 1 + fortyTrackMode;
int maxside = singleSided ? 0 : 1;
for (int track = 0; track <= maxTrack; track += trackstep)
{
for (int side = 0; side <= maxside; side++)
{
int strack = strackno(track, side);
std::cout << fmt::format("FE track {}.{}, SCP track {}: ", track, side, strack) << std::flush;
auto fluxmap = sqlReadFlux(inputDb, track, side);
ScpTrack trackheader = {0};
trackheader.track_id[0] = 'T';
trackheader.track_id[1] = 'R';
trackheader.track_id[2] = 'K';
trackheader.strack = strack;
FluxmapReader fmr(*fluxmap);
Bytes fluxdata;
ByteWriter fluxdataWriter(fluxdata);
int revolution = 0;
unsigned revTicks = 0;
unsigned totalTicks = 0;
unsigned ticksSinceLastPulse = 0;
uint32_t startOffset = 0;
while (revolution < 5)
{
unsigned ticks;
int opcode = fmr.readOpcode(ticks);
if (ticks)
{
ticksSinceLastPulse += ticks;
totalTicks += ticks;
revTicks += ticks;
}
switch (opcode)
{
case -1: /* end of flux, treat like an index marker */
case F_OP_INDEX:
{
auto* revheader = &trackheader.revolution[revolution];
write_le32(revheader->offset, startOffset + sizeof(ScpTrack));
write_le32(revheader->length, (fluxdataWriter.pos - startOffset) / 2);
write_le32(revheader->index, revTicks * NS_PER_TICK / 25);
revolution++;
revheader++;
revTicks = 0;
startOffset = fluxdataWriter.pos;
break;
}
case F_OP_PULSE:
{
unsigned t = ticksSinceLastPulse * NS_PER_TICK / 25;
while (t >= 0x10000)
{
fluxdataWriter.write_be16(0);
t -= 0x10000;
}
fluxdataWriter.write_be16(t);
ticksSinceLastPulse = 0;
break;
}
}
}
write_le32(fileheader.track[strack], trackdataWriter.pos + sizeof(ScpHeader));
trackdataWriter += Bytes((uint8_t*)&trackheader, sizeof(trackheader));
trackdataWriter += fluxdata;
std::cout << fmt::format("{} ms in {} bytes\n",
totalTicks * MS_PER_TICK,
fluxdata.size());
}
}
sqlClose(inputDb);
std::cout << "Writing output file...\n";
std::ofstream of(filenames[1], std::ios::out | std::ios::binary);
if (!of.is_open())
Error() << "cannot open output file";
of.write((const char*) &fileheader, sizeof(fileheader));
of.write((const char*) trackdata.begin(), trackdata.size());
of.close();
return 0;
}

View File

@@ -8,7 +8,6 @@
#include "sector.h"
#include "sectorset.h"
#include "record.h"
#include <fmt/format.h>
static FlagGroup flags { &readerFlags };

View File

@@ -8,7 +8,7 @@ static FlagGroup flags;
static DataSpecFlag source(
{ "--source", "-s" },
"source for data",
":d=0");
":d=0:t=0:s=0");
int mainRpm(int argc, const char* argv[])
{

142
src/fe-scptoflux.cc Normal file
View File

@@ -0,0 +1,142 @@
#include "globals.h"
#include "fluxmap.h"
#include "sql.h"
#include "bytes.h"
#include "protocol.h"
#include "fmt/format.h"
#include "scp.h"
#include <fstream>
static std::ifstream inputFile;
static sqlite3* outputDb;
static ScpHeader header;
static nanoseconds_t resolution;
static int startSide;
static int endSide;
static void syntax()
{
std::cout << "Syntax: fluxengine convert cwftoflux <cwffile> <fluxfile>\n";
exit(0);
}
static void check_for_error()
{
if (inputFile.fail())
Error() << fmt::format("I/O error: {}", strerror(errno));
}
static int trackno(int strack)
{
if (startSide == endSide)
return strack;
return strack >> 1;
}
static int headno(int strack)
{
if (startSide == endSide)
return startSide;
return strack & 1;
}
static void read_header()
{
inputFile.read((char*) &header, sizeof(header));
check_for_error();
if ((header.file_id[0] != 'S')
|| (header.file_id[1] != 'C')
|| (header.file_id[2] != 'P'))
Error() << "input not a SCP file";
resolution = 25 * (header.resolution + 1);
startSide = (header.heads == 2) ? 1 : 0;
endSide = (header.heads == 1) ? 0 : 1;
if ((header.cell_width != 0) && (header.cell_width != 16))
Error() << "currently only 16-bit cells are supported";
std::cout << fmt::format("tracks {}-{}, heads {}-{}\n",
trackno(header.start_track), trackno(header.end_track), startSide, endSide);
std::cout << fmt::format("sample resolution: {} ns\n", resolution);
}
static void read_track(int strack)
{
uint32_t offset = Bytes(header.track[strack], 4).reader().read_le32();
ScpTrack trackheader;
inputFile.seekg(offset, std::ios::beg);
inputFile.read((char*) &trackheader, sizeof(trackheader));
check_for_error();
if ((trackheader.track_id[0] != 'T')
|| (trackheader.track_id[1] != 'R')
|| (trackheader.track_id[2] != 'K'))
Error() << "corrupt SCP file";
std::cout << fmt::format("{}.{}: ", trackno(strack), headno(strack))
<< std::flush;
Fluxmap fluxmap;
nanoseconds_t pending = 0;
unsigned inputBytes = 0;
for (int revolution = 0; revolution < header.revolutions; revolution++)
{
if (revolution != 0)
fluxmap.appendIndex();
uint32_t datalength = Bytes(trackheader.revolution[revolution].length, 4).reader().read_le32();
uint32_t dataoffset = Bytes(trackheader.revolution[revolution].offset, 4).reader().read_le32();
Bytes data(datalength*2);
inputFile.seekg(dataoffset + offset, std::ios::beg);
inputFile.read((char*) data.begin(), data.size());
check_for_error();
ByteReader br(data);
for (int cell = 0; cell < datalength; cell++)
{
uint16_t interval = br.read_be16();
if (interval)
{
fluxmap.appendInterval((interval + pending) * resolution / NS_PER_TICK);
fluxmap.appendPulse();
pending = 0;
}
else
pending += 0x10000;
}
inputBytes += datalength*2;
}
std::cout << fmt::format(" {} ms in {} input bytes and {} output bytes\n",
fluxmap.duration() / 1e6, inputBytes, fluxmap.bytes());
sqlWriteFlux(outputDb, trackno(strack), headno(strack), fluxmap);
}
int mainConvertScpToFlux(int argc, const char* argv[])
{
if (argc != 3)
syntax();
inputFile.open(argv[1], std::ios::in | std::ios::binary);
if (!inputFile.is_open())
Error() << fmt::format("cannot open input file '{}'", argv[1]);
outputDb = sqlOpen(argv[2], SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
sqlPrepareFlux(outputDb);
sqlWriteIntProperty(outputDb, "version", FLUX_VERSION_CURRENT);
sqlStmt(outputDb, "BEGIN;");
read_header();
inputFile.seekg(sizeof(header), std::ios::beg);
for (unsigned i=header.start_track; i<=header.end_track; i++)
read_track(i);
sqlStmt(outputDb, "COMMIT;");
sqlClose(outputDb);
return 0;
}

47
src/fe-testvoltages.cc Normal file
View File

@@ -0,0 +1,47 @@
#include "globals.h"
#include "flags.h"
#include "usb.h"
#include "protocol.h"
#include <fmt/format.h>
static FlagGroup flags;
static std::string display_voltages(struct voltages& v)
{
return fmt::format(
" Logic 1 / 0: {:.2f}V / {:.2f}V\n",
v.logic0_mv / 1000.0,
v.logic1_mv / 1000.0);
}
int mainTestVoltages(int argc, const char* argv[])
{
flags.parseFlags(argc, argv);
struct voltages_frame f;
usbMeasureVoltages(&f);
std::cout << "Output voltages:\n"
<< " Both drives deselected\n"
<< display_voltages(f.output_both_off)
<< " Drive 0 selected\n"
<< display_voltages(f.output_drive_0_selected)
<< " Drive 1 selected\n"
<< display_voltages(f.output_drive_1_selected)
<< " Drive 0 running\n"
<< display_voltages(f.output_drive_0_running)
<< " Drive 1 running\n"
<< display_voltages(f.output_drive_1_running)
<< "Input voltages:\n"
<< " Both drives deselected\n"
<< display_voltages(f.input_both_off)
<< " Drive 0 selected\n"
<< display_voltages(f.input_drive_0_selected)
<< " Drive 1 selected\n"
<< display_voltages(f.input_drive_1_selected)
<< " Drive 0 running\n"
<< display_voltages(f.input_drive_0_running)
<< " Drive 1 running\n"
<< display_voltages(f.input_drive_1_running);
return 0;
}

View File

@@ -5,7 +5,9 @@ typedef int command_cb(int agrc, const char* argv[]);
extern command_cb mainErase;
extern command_cb mainConvertCwfToFlux;
extern command_cb mainConvertFluxToAu;
extern command_cb mainConvertFluxToScp;
extern command_cb mainConvertFluxToVcd;
extern command_cb mainConvertScpToFlux;
extern command_cb mainInspect;
extern command_cb mainReadADFS;
extern command_cb mainReadAESLanier;
@@ -25,6 +27,7 @@ extern command_cb mainReadZilogMCZ;
extern command_cb mainRpm;
extern command_cb mainSeek;
extern command_cb mainTestBulkTransport;
extern command_cb mainTestVoltages;
extern command_cb mainUpgradeFluxFile;
extern command_cb mainWriteBrother;
extern command_cb mainWriteFlux;
@@ -40,6 +43,7 @@ struct Command
static command_cb mainRead;
static command_cb mainWrite;
static command_cb mainConvert;
static command_cb mainTest;
static std::vector<Command> commands =
{
@@ -49,7 +53,7 @@ static std::vector<Command> commands =
{ "read", mainRead, "Reads a disk, producing a sector image.", },
{ "rpm", mainRpm, "Measures the disk rotational speed.", },
{ "seek", mainSeek, "Moves the disk head.", },
{ "testbulktransport", mainTestBulkTransport, "Measures your USB bandwidth.", },
{ "test", mainTest, "Various testing commands.", },
{ "upgradefluxfile", mainUpgradeFluxFile, "Upgrades a flux file from a previous version of this software.", },
{ "write", mainWrite, "Writes a sector image to a disk.", },
{ "writeflux", mainWriteFlux, "Writes a raw flux file. Warning: you can't use this to copy disks.", },
@@ -83,10 +87,18 @@ static std::vector<Command> writeables =
static std::vector<Command> convertables =
{
{ "cwftoflux", mainConvertCwfToFlux, "Converts CatWeasel stream files to flux.", },
{ "scptoflux", mainConvertScpToFlux, "Converts Supercard Pro stream files to flux.", },
{ "fluxtoau", mainConvertFluxToAu, "Converts (one track of a) flux file to an .au audio file.", },
{ "fluxtoscp", mainConvertFluxToScp, "Converrt a flux file to a Supercard Pro file.", },
{ "fluxtovcd", mainConvertFluxToVcd, "Converts (one track of a) flux file to a VCD file.", },
};
static std::vector<Command> testables =
{
{ "bulktransport", mainTestBulkTransport, "Measures your USB bandwidth.", },
{ "voltages", mainTestVoltages, "Measures the FDD bus voltages.", },
};
static void extendedHelp(std::vector<Command>& subcommands, const std::string& command)
{
std::cout << "fluxengine: syntax: fluxengine " << command << " <format> [<flags>...]\n"
@@ -127,6 +139,9 @@ static int mainWrite(int argc, const char* argv[])
static int mainConvert(int argc, const char* argv[])
{ return mainExtended(convertables, "convert", argc, argv); }
static int mainTest(int argc, const char* argv[])
{ return mainExtended(testables, "test", argc, argv); }
static void help()
{
std::cout << "fluxengine: syntax: fluxengine <command> [<flags>...]\n"

43
src/scp.h Normal file
View File

@@ -0,0 +1,43 @@
#ifndef SCP_H
#define SCP_H
struct ScpHeader
{
char file_id[3]; // file ID - 'SCP'
uint8_t version; // major/minor in nibbles
uint8_t type; // disk type - subclass/class in nibbles
uint8_t revolutions; // up to 5
uint8_t start_track; // 0..165
uint8_t end_track; // 0..165
uint8_t flags; // see below
uint8_t cell_width; // in bits, 0 meaning 16
uint8_t heads; // 0 = both, 1 = side 0 only, 2 = side 1 only
uint8_t resolution; // 25ns * (resolution+1)
uint8_t checksum[4]; // of data after this point
uint8_t track[165][4]; // track offsets, not necessarily 165
};
enum
{
SCP_FLAG_INDEXED = (1<<0),
SCP_FLAG_96TPI = (1<<1),
SCP_FLAG_360RPM = (1<<2),
SCP_FLAG_NORMALIZED = (1<<3),
SCP_FLAG_READWRITE = (1<<4),
SCP_FLAG_FOOTER = (1<<5)
};
struct ScpTrack
{
char track_id[3]; // 'TRK'
uint8_t strack; // SCP track number
struct
{
uint8_t index[4]; // time for one revolution
uint8_t length[4]; // number of bitcells
uint8_t offset[4]; // offset to bitcell data, relative to track header
}
revolution[5];
};
#endif

56
tools/brother240tool.cc Normal file
View File

@@ -0,0 +1,56 @@
#include "globals.h"
#include "fmt/format.h"
#include <fstream>
static std::fstream inputFile;
void syntax()
{
std::cout << "Syntax: brother240tool <image>\n"
"The disk image will be flipped from Brother to DOS format and back\n"
"again.\n";
exit(0);
}
uint8_t getbyte(uint32_t offset)
{
inputFile.seekg(offset, std::ifstream::beg);
return inputFile.get();
}
void putbyte(uint32_t offset, uint8_t value)
{
inputFile.seekp(offset, std::ifstream::beg);
inputFile.put(value);
}
int main(int argc, const char* argv[])
{
if (argc < 2)
syntax();
inputFile.open(argv[1], std::ios::in | std::ios::out | std::ios::binary);
if (!inputFile.is_open())
Error() << fmt::format("cannot open input file '{}'", argv[1]);
uint8_t b1 = getbyte(0x015);
uint8_t b2 = getbyte(0x100);
if ((b1 == 0x58) && (b2 == 0x58))
{
std::cerr << "Flipping from Brother to DOS.\n";
putbyte(0x015, 0xf0);
putbyte(0x100, 0xf0);
}
else if ((b1 == 0xf0) && (b2 == 0xf0))
{
std::cerr << "Flipping from DOS to Brother.\n";
putbyte(0x015, 0x58);
putbyte(0x100, 0x58);
}
else
Error() << "Unknown image format.";
inputFile.close();
return 0;
}